xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Common/PropIDUtils.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // PropIDUtils.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../../C/CpuArch.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/IntToString.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
9*f6dc9357SAndroid Build Coastguard Worker 
10*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileIO.h"
11*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/PropVariantConv.h"
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker #include "../../PropID.h"
14*f6dc9357SAndroid Build Coastguard Worker 
15*f6dc9357SAndroid Build Coastguard Worker #include "PropIDUtils.h"
16*f6dc9357SAndroid Build Coastguard Worker 
17*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
18*f6dc9357SAndroid Build Coastguard Worker #define Get16(x) GetUi16(x)
19*f6dc9357SAndroid Build Coastguard Worker #define Get32(x) GetUi32(x)
20*f6dc9357SAndroid Build Coastguard Worker #endif
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker static const unsigned kNumWinAtrribFlags = 30;
25*f6dc9357SAndroid Build Coastguard Worker static const char g_WinAttribChars[kNumWinAtrribFlags + 1] = "RHS8DAdNTsLCOIEVvX.PU.M......B";
26*f6dc9357SAndroid Build Coastguard Worker 
27*f6dc9357SAndroid Build Coastguard Worker /*
28*f6dc9357SAndroid Build Coastguard Worker FILE_ATTRIBUTE_
29*f6dc9357SAndroid Build Coastguard Worker 
30*f6dc9357SAndroid Build Coastguard Worker 0 READONLY
31*f6dc9357SAndroid Build Coastguard Worker 1 HIDDEN
32*f6dc9357SAndroid Build Coastguard Worker 2 SYSTEM
33*f6dc9357SAndroid Build Coastguard Worker 3 (Volume label - obsolete)
34*f6dc9357SAndroid Build Coastguard Worker 4 DIRECTORY
35*f6dc9357SAndroid Build Coastguard Worker 5 ARCHIVE
36*f6dc9357SAndroid Build Coastguard Worker 6 DEVICE
37*f6dc9357SAndroid Build Coastguard Worker 7 NORMAL
38*f6dc9357SAndroid Build Coastguard Worker 8 TEMPORARY
39*f6dc9357SAndroid Build Coastguard Worker 9 SPARSE_FILE
40*f6dc9357SAndroid Build Coastguard Worker 10 REPARSE_POINT
41*f6dc9357SAndroid Build Coastguard Worker 11 COMPRESSED
42*f6dc9357SAndroid Build Coastguard Worker 12 OFFLINE
43*f6dc9357SAndroid Build Coastguard Worker 13 NOT_CONTENT_INDEXED (I - Win10 attrib/Explorer)
44*f6dc9357SAndroid Build Coastguard Worker 14 ENCRYPTED
45*f6dc9357SAndroid Build Coastguard Worker 15 INTEGRITY_STREAM (V - ReFS Win8/Win2012)
46*f6dc9357SAndroid Build Coastguard Worker 16 VIRTUAL (reserved)
47*f6dc9357SAndroid Build Coastguard Worker 17 NO_SCRUB_DATA (X - ReFS Win8/Win2012 attrib)
48*f6dc9357SAndroid Build Coastguard Worker 18 RECALL_ON_OPEN or EA
49*f6dc9357SAndroid Build Coastguard Worker 19 PINNED
50*f6dc9357SAndroid Build Coastguard Worker 20 UNPINNED
51*f6dc9357SAndroid Build Coastguard Worker 21 STRICTLY_SEQUENTIAL  (10.0.16267)
52*f6dc9357SAndroid Build Coastguard Worker 22 RECALL_ON_DATA_ACCESS
53*f6dc9357SAndroid Build Coastguard Worker 29 STRICTLY_SEQUENTIAL  (10.0.17134+) (SMR Blob)
54*f6dc9357SAndroid Build Coastguard Worker */
55*f6dc9357SAndroid Build Coastguard Worker 
56*f6dc9357SAndroid Build Coastguard Worker 
57*f6dc9357SAndroid Build Coastguard Worker static const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
58*f6dc9357SAndroid Build Coastguard Worker #define MY_ATTR_CHAR(a, n, c) (((a) & (1 << (n))) ? c : '-')
59*f6dc9357SAndroid Build Coastguard Worker 
ConvertPosixAttribToString(char * s,UInt32 a)60*f6dc9357SAndroid Build Coastguard Worker static void ConvertPosixAttribToString(char *s, UInt32 a) throw()
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker   s[0] = kPosixTypes[(a >> 12) & 0xF];
63*f6dc9357SAndroid Build Coastguard Worker   for (int i = 6; i >= 0; i -= 3)
64*f6dc9357SAndroid Build Coastguard Worker   {
65*f6dc9357SAndroid Build Coastguard Worker     s[7 - i] = MY_ATTR_CHAR(a, i + 2, 'r');
66*f6dc9357SAndroid Build Coastguard Worker     s[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w');
67*f6dc9357SAndroid Build Coastguard Worker     s[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x');
68*f6dc9357SAndroid Build Coastguard Worker   }
69*f6dc9357SAndroid Build Coastguard Worker   if ((a & 0x800) != 0) s[3] = ((a & (1 << 6)) ? 's' : 'S'); // S_ISUID
70*f6dc9357SAndroid Build Coastguard Worker   if ((a & 0x400) != 0) s[6] = ((a & (1 << 3)) ? 's' : 'S'); // S_ISGID
71*f6dc9357SAndroid Build Coastguard Worker   if ((a & 0x200) != 0) s[9] = ((a & (1 << 0)) ? 't' : 'T'); // S_ISVTX
72*f6dc9357SAndroid Build Coastguard Worker   s[10] = 0;
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker   a &= ~(UInt32)0xFFFF;
75*f6dc9357SAndroid Build Coastguard Worker   if (a != 0)
76*f6dc9357SAndroid Build Coastguard Worker   {
77*f6dc9357SAndroid Build Coastguard Worker     s[10] = ' ';
78*f6dc9357SAndroid Build Coastguard Worker     ConvertUInt32ToHex8Digits(a, s + 11);
79*f6dc9357SAndroid Build Coastguard Worker   }
80*f6dc9357SAndroid Build Coastguard Worker }
81*f6dc9357SAndroid Build Coastguard Worker 
82*f6dc9357SAndroid Build Coastguard Worker 
ConvertWinAttribToString(char * s,UInt32 wa)83*f6dc9357SAndroid Build Coastguard Worker void ConvertWinAttribToString(char *s, UInt32 wa) throw()
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker   /*
86*f6dc9357SAndroid Build Coastguard Worker   some programs store posix attributes in high 16 bits.
87*f6dc9357SAndroid Build Coastguard Worker     p7zip - stores additional 0x8000 flag marker.
88*f6dc9357SAndroid Build Coastguard Worker     macos - stores additional 0x4000 flag marker.
89*f6dc9357SAndroid Build Coastguard Worker     info-zip - no additional marker.
90*f6dc9357SAndroid Build Coastguard Worker   But this code works with Attrib from internal 7zip code.
91*f6dc9357SAndroid Build Coastguard Worker   So we expect that 0x8000 marker is set, if there are posix attributes.
92*f6dc9357SAndroid Build Coastguard Worker   (DT_UNKNOWN == 0) type in high bits is possible in some case for linux files.
93*f6dc9357SAndroid Build Coastguard Worker   0x8000 flag is possible also in ReFS (Windows)?
94*f6dc9357SAndroid Build Coastguard Worker   */
95*f6dc9357SAndroid Build Coastguard Worker 
96*f6dc9357SAndroid Build Coastguard Worker   const bool isPosix = (
97*f6dc9357SAndroid Build Coastguard Worker       (wa & 0x8000) != 0 // FILE_ATTRIBUTE_UNIX_EXTENSION;
98*f6dc9357SAndroid Build Coastguard Worker       // && (wa & 0xFFFF0000u) != 0
99*f6dc9357SAndroid Build Coastguard Worker       );
100*f6dc9357SAndroid Build Coastguard Worker 
101*f6dc9357SAndroid Build Coastguard Worker   UInt32 posix = 0;
102*f6dc9357SAndroid Build Coastguard Worker   if (isPosix)
103*f6dc9357SAndroid Build Coastguard Worker   {
104*f6dc9357SAndroid Build Coastguard Worker     posix = wa >> 16;
105*f6dc9357SAndroid Build Coastguard Worker     if ((wa & 0xF0000000u) != 0)
106*f6dc9357SAndroid Build Coastguard Worker       wa &= (UInt32)0x3FFF;
107*f6dc9357SAndroid Build Coastguard Worker   }
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < kNumWinAtrribFlags; i++)
110*f6dc9357SAndroid Build Coastguard Worker   {
111*f6dc9357SAndroid Build Coastguard Worker     const UInt32 flag = (UInt32)1 << i;
112*f6dc9357SAndroid Build Coastguard Worker     if (wa & flag)
113*f6dc9357SAndroid Build Coastguard Worker     {
114*f6dc9357SAndroid Build Coastguard Worker       const char c = g_WinAttribChars[i];
115*f6dc9357SAndroid Build Coastguard Worker       if (c != '.')
116*f6dc9357SAndroid Build Coastguard Worker       {
117*f6dc9357SAndroid Build Coastguard Worker         wa &= ~flag;
118*f6dc9357SAndroid Build Coastguard Worker         // if (i != 7) // we can disable N (NORMAL) printing
119*f6dc9357SAndroid Build Coastguard Worker         *s++ = c;
120*f6dc9357SAndroid Build Coastguard Worker       }
121*f6dc9357SAndroid Build Coastguard Worker     }
122*f6dc9357SAndroid Build Coastguard Worker   }
123*f6dc9357SAndroid Build Coastguard Worker 
124*f6dc9357SAndroid Build Coastguard Worker   if (wa != 0)
125*f6dc9357SAndroid Build Coastguard Worker   {
126*f6dc9357SAndroid Build Coastguard Worker     *s++ = ' ';
127*f6dc9357SAndroid Build Coastguard Worker     ConvertUInt32ToHex8Digits(wa, s);
128*f6dc9357SAndroid Build Coastguard Worker     s += strlen(s);
129*f6dc9357SAndroid Build Coastguard Worker   }
130*f6dc9357SAndroid Build Coastguard Worker 
131*f6dc9357SAndroid Build Coastguard Worker   *s = 0;
132*f6dc9357SAndroid Build Coastguard Worker 
133*f6dc9357SAndroid Build Coastguard Worker   if (isPosix)
134*f6dc9357SAndroid Build Coastguard Worker   {
135*f6dc9357SAndroid Build Coastguard Worker     *s++ = ' ';
136*f6dc9357SAndroid Build Coastguard Worker     ConvertPosixAttribToString(s, posix);
137*f6dc9357SAndroid Build Coastguard Worker   }
138*f6dc9357SAndroid Build Coastguard Worker }
139*f6dc9357SAndroid Build Coastguard Worker 
140*f6dc9357SAndroid Build Coastguard Worker 
ConvertPropertyToShortString2(char * dest,const PROPVARIANT & prop,PROPID propID,int level)141*f6dc9357SAndroid Build Coastguard Worker void ConvertPropertyToShortString2(char *dest, const PROPVARIANT &prop, PROPID propID, int level) throw()
142*f6dc9357SAndroid Build Coastguard Worker {
143*f6dc9357SAndroid Build Coastguard Worker   *dest = 0;
144*f6dc9357SAndroid Build Coastguard Worker 
145*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_FILETIME)
146*f6dc9357SAndroid Build Coastguard Worker   {
147*f6dc9357SAndroid Build Coastguard Worker     const FILETIME &ft = prop.filetime;
148*f6dc9357SAndroid Build Coastguard Worker     unsigned ns100 = 0;
149*f6dc9357SAndroid Build Coastguard Worker     int numDigits = kTimestampPrintLevel_NTFS;
150*f6dc9357SAndroid Build Coastguard Worker     const unsigned prec = prop.wReserved1;
151*f6dc9357SAndroid Build Coastguard Worker     const unsigned ns100_Temp = prop.wReserved2;
152*f6dc9357SAndroid Build Coastguard Worker     if (prec != 0
153*f6dc9357SAndroid Build Coastguard Worker         && prec <= k_PropVar_TimePrec_1ns
154*f6dc9357SAndroid Build Coastguard Worker         && ns100_Temp < 100
155*f6dc9357SAndroid Build Coastguard Worker         && prop.wReserved3 == 0)
156*f6dc9357SAndroid Build Coastguard Worker     {
157*f6dc9357SAndroid Build Coastguard Worker       ns100 = ns100_Temp;
158*f6dc9357SAndroid Build Coastguard Worker       if (prec == k_PropVar_TimePrec_Unix ||
159*f6dc9357SAndroid Build Coastguard Worker           prec == k_PropVar_TimePrec_DOS)
160*f6dc9357SAndroid Build Coastguard Worker         numDigits = 0;
161*f6dc9357SAndroid Build Coastguard Worker       else if (prec == k_PropVar_TimePrec_HighPrec)
162*f6dc9357SAndroid Build Coastguard Worker         numDigits = 9;
163*f6dc9357SAndroid Build Coastguard Worker       else
164*f6dc9357SAndroid Build Coastguard Worker       {
165*f6dc9357SAndroid Build Coastguard Worker         numDigits = (int)prec - (int)k_PropVar_TimePrec_Base;
166*f6dc9357SAndroid Build Coastguard Worker         if (
167*f6dc9357SAndroid Build Coastguard Worker             // numDigits < kTimestampPrintLevel_DAY // for debuf
168*f6dc9357SAndroid Build Coastguard Worker             numDigits < kTimestampPrintLevel_SEC
169*f6dc9357SAndroid Build Coastguard Worker             )
170*f6dc9357SAndroid Build Coastguard Worker 
171*f6dc9357SAndroid Build Coastguard Worker           numDigits = kTimestampPrintLevel_NTFS;
172*f6dc9357SAndroid Build Coastguard Worker       }
173*f6dc9357SAndroid Build Coastguard Worker     }
174*f6dc9357SAndroid Build Coastguard Worker     if (ft.dwHighDateTime == 0 && ft.dwLowDateTime == 0 && ns100 == 0)
175*f6dc9357SAndroid Build Coastguard Worker       return;
176*f6dc9357SAndroid Build Coastguard Worker     if (level > numDigits)
177*f6dc9357SAndroid Build Coastguard Worker       level = numDigits;
178*f6dc9357SAndroid Build Coastguard Worker     ConvertUtcFileTimeToString2(ft, ns100, dest, level);
179*f6dc9357SAndroid Build Coastguard Worker     return;
180*f6dc9357SAndroid Build Coastguard Worker   }
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker   switch (propID)
183*f6dc9357SAndroid Build Coastguard Worker   {
184*f6dc9357SAndroid Build Coastguard Worker     case kpidCRC:
185*f6dc9357SAndroid Build Coastguard Worker     {
186*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI4)
187*f6dc9357SAndroid Build Coastguard Worker         break;
188*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt32ToHex8Digits(prop.ulVal, dest);
189*f6dc9357SAndroid Build Coastguard Worker       return;
190*f6dc9357SAndroid Build Coastguard Worker     }
191*f6dc9357SAndroid Build Coastguard Worker     case kpidAttrib:
192*f6dc9357SAndroid Build Coastguard Worker     {
193*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI4)
194*f6dc9357SAndroid Build Coastguard Worker         break;
195*f6dc9357SAndroid Build Coastguard Worker       const UInt32 a = prop.ulVal;
196*f6dc9357SAndroid Build Coastguard Worker 
197*f6dc9357SAndroid Build Coastguard Worker       /*
198*f6dc9357SAndroid Build Coastguard Worker       if ((a & 0x8000) && (a & 0x7FFF) == 0)
199*f6dc9357SAndroid Build Coastguard Worker         ConvertPosixAttribToString(dest, a >> 16);
200*f6dc9357SAndroid Build Coastguard Worker       else
201*f6dc9357SAndroid Build Coastguard Worker       */
202*f6dc9357SAndroid Build Coastguard Worker       ConvertWinAttribToString(dest, a);
203*f6dc9357SAndroid Build Coastguard Worker       return;
204*f6dc9357SAndroid Build Coastguard Worker     }
205*f6dc9357SAndroid Build Coastguard Worker     case kpidPosixAttrib:
206*f6dc9357SAndroid Build Coastguard Worker     {
207*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI4)
208*f6dc9357SAndroid Build Coastguard Worker         break;
209*f6dc9357SAndroid Build Coastguard Worker       ConvertPosixAttribToString(dest, prop.ulVal);
210*f6dc9357SAndroid Build Coastguard Worker       return;
211*f6dc9357SAndroid Build Coastguard Worker     }
212*f6dc9357SAndroid Build Coastguard Worker     case kpidINode:
213*f6dc9357SAndroid Build Coastguard Worker     {
214*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt != VT_UI8)
215*f6dc9357SAndroid Build Coastguard Worker         break;
216*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest);
217*f6dc9357SAndroid Build Coastguard Worker       dest += strlen(dest);
218*f6dc9357SAndroid Build Coastguard Worker       *dest++ = '-';
219*f6dc9357SAndroid Build Coastguard Worker       const UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1);
220*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt64ToString(low, dest);
221*f6dc9357SAndroid Build Coastguard Worker       return;
222*f6dc9357SAndroid Build Coastguard Worker     }
223*f6dc9357SAndroid Build Coastguard Worker     case kpidVa:
224*f6dc9357SAndroid Build Coastguard Worker     {
225*f6dc9357SAndroid Build Coastguard Worker       UInt64 v = 0;
226*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt == VT_UI4)
227*f6dc9357SAndroid Build Coastguard Worker         v = prop.ulVal;
228*f6dc9357SAndroid Build Coastguard Worker       else if (prop.vt == VT_UI8)
229*f6dc9357SAndroid Build Coastguard Worker         v = (UInt64)prop.uhVal.QuadPart;
230*f6dc9357SAndroid Build Coastguard Worker       else
231*f6dc9357SAndroid Build Coastguard Worker         break;
232*f6dc9357SAndroid Build Coastguard Worker       dest[0] = '0';
233*f6dc9357SAndroid Build Coastguard Worker       dest[1] = 'x';
234*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt64ToHex(v, dest + 2);
235*f6dc9357SAndroid Build Coastguard Worker       return;
236*f6dc9357SAndroid Build Coastguard Worker     }
237*f6dc9357SAndroid Build Coastguard Worker 
238*f6dc9357SAndroid Build Coastguard Worker     /*
239*f6dc9357SAndroid Build Coastguard Worker     case kpidDevice:
240*f6dc9357SAndroid Build Coastguard Worker     {
241*f6dc9357SAndroid Build Coastguard Worker       UInt64 v = 0;
242*f6dc9357SAndroid Build Coastguard Worker       if (prop.vt == VT_UI4)
243*f6dc9357SAndroid Build Coastguard Worker         v = prop.ulVal;
244*f6dc9357SAndroid Build Coastguard Worker       else if (prop.vt == VT_UI8)
245*f6dc9357SAndroid Build Coastguard Worker         v = (UInt64)prop.uhVal.QuadPart;
246*f6dc9357SAndroid Build Coastguard Worker       else
247*f6dc9357SAndroid Build Coastguard Worker         break;
248*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt32ToString(MY_dev_major(v), dest);
249*f6dc9357SAndroid Build Coastguard Worker       dest += strlen(dest);
250*f6dc9357SAndroid Build Coastguard Worker       *dest++ = ',';
251*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt32ToString(MY_dev_minor(v), dest);
252*f6dc9357SAndroid Build Coastguard Worker       return;
253*f6dc9357SAndroid Build Coastguard Worker     }
254*f6dc9357SAndroid Build Coastguard Worker     */
255*f6dc9357SAndroid Build Coastguard Worker     default: break;
256*f6dc9357SAndroid Build Coastguard Worker   }
257*f6dc9357SAndroid Build Coastguard Worker 
258*f6dc9357SAndroid Build Coastguard Worker   ConvertPropVariantToShortString(prop, dest);
259*f6dc9357SAndroid Build Coastguard Worker }
260*f6dc9357SAndroid Build Coastguard Worker 
ConvertPropertyToString2(UString & dest,const PROPVARIANT & prop,PROPID propID,int level)261*f6dc9357SAndroid Build Coastguard Worker void ConvertPropertyToString2(UString &dest, const PROPVARIANT &prop, PROPID propID, int level)
262*f6dc9357SAndroid Build Coastguard Worker {
263*f6dc9357SAndroid Build Coastguard Worker   if (prop.vt == VT_BSTR)
264*f6dc9357SAndroid Build Coastguard Worker   {
265*f6dc9357SAndroid Build Coastguard Worker     dest.SetFromBstr(prop.bstrVal);
266*f6dc9357SAndroid Build Coastguard Worker     return;
267*f6dc9357SAndroid Build Coastguard Worker   }
268*f6dc9357SAndroid Build Coastguard Worker   char temp[64];
269*f6dc9357SAndroid Build Coastguard Worker   ConvertPropertyToShortString2(temp, prop, propID, level);
270*f6dc9357SAndroid Build Coastguard Worker   dest = temp;
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_SFX
274*f6dc9357SAndroid Build Coastguard Worker 
AddHexToString(AString & res,unsigned v)275*f6dc9357SAndroid Build Coastguard Worker static inline void AddHexToString(AString &res, unsigned v)
276*f6dc9357SAndroid Build Coastguard Worker {
277*f6dc9357SAndroid Build Coastguard Worker   res.Add_Char((char)GET_HEX_CHAR_UPPER(v >> 4));
278*f6dc9357SAndroid Build Coastguard Worker   res.Add_Char((char)GET_HEX_CHAR_UPPER(v & 15));
279*f6dc9357SAndroid Build Coastguard Worker }
280*f6dc9357SAndroid Build Coastguard Worker 
281*f6dc9357SAndroid Build Coastguard Worker /*
282*f6dc9357SAndroid Build Coastguard Worker static AString Data_To_Hex(const Byte *data, size_t size)
283*f6dc9357SAndroid Build Coastguard Worker {
284*f6dc9357SAndroid Build Coastguard Worker   AString s;
285*f6dc9357SAndroid Build Coastguard Worker   for (size_t i = 0; i < size; i++)
286*f6dc9357SAndroid Build Coastguard Worker     AddHexToString(s, data[i]);
287*f6dc9357SAndroid Build Coastguard Worker   return s;
288*f6dc9357SAndroid Build Coastguard Worker }
289*f6dc9357SAndroid Build Coastguard Worker */
290*f6dc9357SAndroid Build Coastguard Worker 
291*f6dc9357SAndroid Build Coastguard Worker static const char * const sidNames[] =
292*f6dc9357SAndroid Build Coastguard Worker {
293*f6dc9357SAndroid Build Coastguard Worker     "0"
294*f6dc9357SAndroid Build Coastguard Worker   , "Dialup"
295*f6dc9357SAndroid Build Coastguard Worker   , "Network"
296*f6dc9357SAndroid Build Coastguard Worker   , "Batch"
297*f6dc9357SAndroid Build Coastguard Worker   , "Interactive"
298*f6dc9357SAndroid Build Coastguard Worker   , "Logon"  // S-1-5-5-X-Y
299*f6dc9357SAndroid Build Coastguard Worker   , "Service"
300*f6dc9357SAndroid Build Coastguard Worker   , "Anonymous"
301*f6dc9357SAndroid Build Coastguard Worker   , "Proxy"
302*f6dc9357SAndroid Build Coastguard Worker   , "EnterpriseDC"
303*f6dc9357SAndroid Build Coastguard Worker   , "Self"
304*f6dc9357SAndroid Build Coastguard Worker   , "AuthenticatedUsers"
305*f6dc9357SAndroid Build Coastguard Worker   , "RestrictedCode"
306*f6dc9357SAndroid Build Coastguard Worker   , "TerminalServer"
307*f6dc9357SAndroid Build Coastguard Worker   , "RemoteInteractiveLogon"
308*f6dc9357SAndroid Build Coastguard Worker   , "ThisOrganization"
309*f6dc9357SAndroid Build Coastguard Worker   , "16"
310*f6dc9357SAndroid Build Coastguard Worker   , "IUserIIS"
311*f6dc9357SAndroid Build Coastguard Worker   , "LocalSystem"
312*f6dc9357SAndroid Build Coastguard Worker   , "LocalService"
313*f6dc9357SAndroid Build Coastguard Worker   , "NetworkService"
314*f6dc9357SAndroid Build Coastguard Worker   , "Domains"
315*f6dc9357SAndroid Build Coastguard Worker };
316*f6dc9357SAndroid Build Coastguard Worker 
317*f6dc9357SAndroid Build Coastguard Worker struct CSecID2Name
318*f6dc9357SAndroid Build Coastguard Worker {
319*f6dc9357SAndroid Build Coastguard Worker   UInt32 n;
320*f6dc9357SAndroid Build Coastguard Worker   const char *sz;
321*f6dc9357SAndroid Build Coastguard Worker };
322*f6dc9357SAndroid Build Coastguard Worker 
FindPairIndex(const CSecID2Name * pairs,unsigned num,UInt32 id)323*f6dc9357SAndroid Build Coastguard Worker static int FindPairIndex(const CSecID2Name * pairs, unsigned num, UInt32 id)
324*f6dc9357SAndroid Build Coastguard Worker {
325*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < num; i++)
326*f6dc9357SAndroid Build Coastguard Worker     if (pairs[i].n == id)
327*f6dc9357SAndroid Build Coastguard Worker       return (int)i;
328*f6dc9357SAndroid Build Coastguard Worker   return -1;
329*f6dc9357SAndroid Build Coastguard Worker }
330*f6dc9357SAndroid Build Coastguard Worker 
331*f6dc9357SAndroid Build Coastguard Worker static const CSecID2Name sid_32_Names[] =
332*f6dc9357SAndroid Build Coastguard Worker {
333*f6dc9357SAndroid Build Coastguard Worker   { 544, "Administrators" },
334*f6dc9357SAndroid Build Coastguard Worker   { 545, "Users" },
335*f6dc9357SAndroid Build Coastguard Worker   { 546, "Guests" },
336*f6dc9357SAndroid Build Coastguard Worker   { 547, "PowerUsers" },
337*f6dc9357SAndroid Build Coastguard Worker   { 548, "AccountOperators" },
338*f6dc9357SAndroid Build Coastguard Worker   { 549, "ServerOperators" },
339*f6dc9357SAndroid Build Coastguard Worker   { 550, "PrintOperators" },
340*f6dc9357SAndroid Build Coastguard Worker   { 551, "BackupOperators" },
341*f6dc9357SAndroid Build Coastguard Worker   { 552, "Replicators" },
342*f6dc9357SAndroid Build Coastguard Worker   { 553, "Backup Operators" },
343*f6dc9357SAndroid Build Coastguard Worker   { 554, "PreWindows2000CompatibleAccess" },
344*f6dc9357SAndroid Build Coastguard Worker   { 555, "RemoteDesktopUsers" },
345*f6dc9357SAndroid Build Coastguard Worker   { 556, "NetworkConfigurationOperators" },
346*f6dc9357SAndroid Build Coastguard Worker   { 557, "IncomingForestTrustBuilders" },
347*f6dc9357SAndroid Build Coastguard Worker   { 558, "PerformanceMonitorUsers" },
348*f6dc9357SAndroid Build Coastguard Worker   { 559, "PerformanceLogUsers" },
349*f6dc9357SAndroid Build Coastguard Worker   { 560, "WindowsAuthorizationAccessGroup" },
350*f6dc9357SAndroid Build Coastguard Worker   { 561, "TerminalServerLicenseServers" },
351*f6dc9357SAndroid Build Coastguard Worker   { 562, "DistributedCOMUsers" },
352*f6dc9357SAndroid Build Coastguard Worker   { 569, "CryptographicOperators" },
353*f6dc9357SAndroid Build Coastguard Worker   { 573, "EventLogReaders" },
354*f6dc9357SAndroid Build Coastguard Worker   { 574, "CertificateServiceDCOMAccess" }
355*f6dc9357SAndroid Build Coastguard Worker };
356*f6dc9357SAndroid Build Coastguard Worker 
357*f6dc9357SAndroid Build Coastguard Worker static const CSecID2Name sid_21_Names[] =
358*f6dc9357SAndroid Build Coastguard Worker {
359*f6dc9357SAndroid Build Coastguard Worker   { 500, "Administrator" },
360*f6dc9357SAndroid Build Coastguard Worker   { 501, "Guest" },
361*f6dc9357SAndroid Build Coastguard Worker   { 502, "KRBTGT" },
362*f6dc9357SAndroid Build Coastguard Worker   { 512, "DomainAdmins" },
363*f6dc9357SAndroid Build Coastguard Worker   { 513, "DomainUsers" },
364*f6dc9357SAndroid Build Coastguard Worker   { 515, "DomainComputers" },
365*f6dc9357SAndroid Build Coastguard Worker   { 516, "DomainControllers" },
366*f6dc9357SAndroid Build Coastguard Worker   { 517, "CertPublishers" },
367*f6dc9357SAndroid Build Coastguard Worker   { 518, "SchemaAdmins" },
368*f6dc9357SAndroid Build Coastguard Worker   { 519, "EnterpriseAdmins" },
369*f6dc9357SAndroid Build Coastguard Worker   { 520, "GroupPolicyCreatorOwners" },
370*f6dc9357SAndroid Build Coastguard Worker   { 553, "RASandIASServers" },
371*f6dc9357SAndroid Build Coastguard Worker   { 553, "RASandIASServers" },
372*f6dc9357SAndroid Build Coastguard Worker   { 571, "AllowedRODCPasswordReplicationGroup" },
373*f6dc9357SAndroid Build Coastguard Worker   { 572, "DeniedRODCPasswordReplicationGroup" }
374*f6dc9357SAndroid Build Coastguard Worker };
375*f6dc9357SAndroid Build Coastguard Worker 
376*f6dc9357SAndroid Build Coastguard Worker struct CServicesToName
377*f6dc9357SAndroid Build Coastguard Worker {
378*f6dc9357SAndroid Build Coastguard Worker   UInt32 n[5];
379*f6dc9357SAndroid Build Coastguard Worker   const char *sz;
380*f6dc9357SAndroid Build Coastguard Worker };
381*f6dc9357SAndroid Build Coastguard Worker 
382*f6dc9357SAndroid Build Coastguard Worker static const CServicesToName services_to_name[] =
383*f6dc9357SAndroid Build Coastguard Worker {
384*f6dc9357SAndroid Build Coastguard Worker   { { 0x38FB89B5, 0xCBC28419, 0x6D236C5C, 0x6E770057, 0x876402C0 } , "TrustedInstaller" }
385*f6dc9357SAndroid Build Coastguard Worker };
386*f6dc9357SAndroid Build Coastguard Worker 
ParseSid(AString & s,const Byte * p,size_t lim)387*f6dc9357SAndroid Build Coastguard Worker static void ParseSid(AString &s, const Byte *p, size_t lim /* , unsigned &sidSize */)
388*f6dc9357SAndroid Build Coastguard Worker {
389*f6dc9357SAndroid Build Coastguard Worker   // sidSize = 0;
390*f6dc9357SAndroid Build Coastguard Worker   if (lim < 8)
391*f6dc9357SAndroid Build Coastguard Worker   {
392*f6dc9357SAndroid Build Coastguard Worker     s += "ERROR";
393*f6dc9357SAndroid Build Coastguard Worker     return;
394*f6dc9357SAndroid Build Coastguard Worker   }
395*f6dc9357SAndroid Build Coastguard Worker   if (p[0] != 1) // rev
396*f6dc9357SAndroid Build Coastguard Worker   {
397*f6dc9357SAndroid Build Coastguard Worker     s += "UNSUPPORTED";
398*f6dc9357SAndroid Build Coastguard Worker     return;
399*f6dc9357SAndroid Build Coastguard Worker   }
400*f6dc9357SAndroid Build Coastguard Worker   const unsigned num = p[1];
401*f6dc9357SAndroid Build Coastguard Worker   const unsigned sidSize_Loc = 8 + num * 4;
402*f6dc9357SAndroid Build Coastguard Worker   if (sidSize_Loc > lim)
403*f6dc9357SAndroid Build Coastguard Worker   {
404*f6dc9357SAndroid Build Coastguard Worker     s += "ERROR";
405*f6dc9357SAndroid Build Coastguard Worker     return;
406*f6dc9357SAndroid Build Coastguard Worker   }
407*f6dc9357SAndroid Build Coastguard Worker   // sidSize = sidSize_Loc;
408*f6dc9357SAndroid Build Coastguard Worker   const UInt32 authority = GetBe32(p + 4);
409*f6dc9357SAndroid Build Coastguard Worker 
410*f6dc9357SAndroid Build Coastguard Worker   if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1)
411*f6dc9357SAndroid Build Coastguard Worker   {
412*f6dc9357SAndroid Build Coastguard Worker     const UInt32 v0 = Get32(p + 8);
413*f6dc9357SAndroid Build Coastguard Worker     if (v0 < Z7_ARRAY_SIZE(sidNames))
414*f6dc9357SAndroid Build Coastguard Worker     {
415*f6dc9357SAndroid Build Coastguard Worker       s += sidNames[v0];
416*f6dc9357SAndroid Build Coastguard Worker       return;
417*f6dc9357SAndroid Build Coastguard Worker     }
418*f6dc9357SAndroid Build Coastguard Worker     if (v0 == 32 && num == 2)
419*f6dc9357SAndroid Build Coastguard Worker     {
420*f6dc9357SAndroid Build Coastguard Worker       const UInt32 v1 = Get32(p + 12);
421*f6dc9357SAndroid Build Coastguard Worker       const int index = FindPairIndex(sid_32_Names, Z7_ARRAY_SIZE(sid_32_Names), v1);
422*f6dc9357SAndroid Build Coastguard Worker       if (index >= 0)
423*f6dc9357SAndroid Build Coastguard Worker       {
424*f6dc9357SAndroid Build Coastguard Worker         s += sid_32_Names[(unsigned)index].sz;
425*f6dc9357SAndroid Build Coastguard Worker         return;
426*f6dc9357SAndroid Build Coastguard Worker       }
427*f6dc9357SAndroid Build Coastguard Worker     }
428*f6dc9357SAndroid Build Coastguard Worker     if (v0 == 21 && num == 5)
429*f6dc9357SAndroid Build Coastguard Worker     {
430*f6dc9357SAndroid Build Coastguard Worker       UInt32 v4 = Get32(p + 8 + 4 * 4);
431*f6dc9357SAndroid Build Coastguard Worker       const int index = FindPairIndex(sid_21_Names, Z7_ARRAY_SIZE(sid_21_Names), v4);
432*f6dc9357SAndroid Build Coastguard Worker       if (index >= 0)
433*f6dc9357SAndroid Build Coastguard Worker       {
434*f6dc9357SAndroid Build Coastguard Worker         s += sid_21_Names[(unsigned)index].sz;
435*f6dc9357SAndroid Build Coastguard Worker         return;
436*f6dc9357SAndroid Build Coastguard Worker       }
437*f6dc9357SAndroid Build Coastguard Worker     }
438*f6dc9357SAndroid Build Coastguard Worker     if (v0 == 80 && num == 6)
439*f6dc9357SAndroid Build Coastguard Worker     {
440*f6dc9357SAndroid Build Coastguard Worker       for (unsigned i = 0; i < Z7_ARRAY_SIZE(services_to_name); i++)
441*f6dc9357SAndroid Build Coastguard Worker       {
442*f6dc9357SAndroid Build Coastguard Worker         const CServicesToName &sn = services_to_name[i];
443*f6dc9357SAndroid Build Coastguard Worker         int j;
444*f6dc9357SAndroid Build Coastguard Worker         for (j = 0; j < 5 && sn.n[j] == Get32(p + 8 + 4 + j * 4); j++);
445*f6dc9357SAndroid Build Coastguard Worker         if (j == 5)
446*f6dc9357SAndroid Build Coastguard Worker         {
447*f6dc9357SAndroid Build Coastguard Worker           s += sn.sz;
448*f6dc9357SAndroid Build Coastguard Worker           return;
449*f6dc9357SAndroid Build Coastguard Worker         }
450*f6dc9357SAndroid Build Coastguard Worker       }
451*f6dc9357SAndroid Build Coastguard Worker     }
452*f6dc9357SAndroid Build Coastguard Worker   }
453*f6dc9357SAndroid Build Coastguard Worker 
454*f6dc9357SAndroid Build Coastguard Worker   s += "S-1-";
455*f6dc9357SAndroid Build Coastguard Worker   if (p[2] == 0 && p[3] == 0)
456*f6dc9357SAndroid Build Coastguard Worker     s.Add_UInt32(authority);
457*f6dc9357SAndroid Build Coastguard Worker   else
458*f6dc9357SAndroid Build Coastguard Worker   {
459*f6dc9357SAndroid Build Coastguard Worker     s += "0x";
460*f6dc9357SAndroid Build Coastguard Worker     for (int i = 2; i < 8; i++)
461*f6dc9357SAndroid Build Coastguard Worker       AddHexToString(s, p[i]);
462*f6dc9357SAndroid Build Coastguard Worker   }
463*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0; i < num; i++)
464*f6dc9357SAndroid Build Coastguard Worker   {
465*f6dc9357SAndroid Build Coastguard Worker     s.Add_Minus();
466*f6dc9357SAndroid Build Coastguard Worker     s.Add_UInt32(Get32(p + 8 + i * 4));
467*f6dc9357SAndroid Build Coastguard Worker   }
468*f6dc9357SAndroid Build Coastguard Worker }
469*f6dc9357SAndroid Build Coastguard Worker 
ParseOwner(AString & s,const Byte * p,size_t size,UInt32 pos)470*f6dc9357SAndroid Build Coastguard Worker static void ParseOwner(AString &s, const Byte *p, size_t size, UInt32 pos)
471*f6dc9357SAndroid Build Coastguard Worker {
472*f6dc9357SAndroid Build Coastguard Worker   if (pos > size)
473*f6dc9357SAndroid Build Coastguard Worker   {
474*f6dc9357SAndroid Build Coastguard Worker     s += "ERROR";
475*f6dc9357SAndroid Build Coastguard Worker     return;
476*f6dc9357SAndroid Build Coastguard Worker   }
477*f6dc9357SAndroid Build Coastguard Worker   // unsigned sidSize = 0;
478*f6dc9357SAndroid Build Coastguard Worker   ParseSid(s, p + pos, size - pos /* , sidSize */);
479*f6dc9357SAndroid Build Coastguard Worker }
480*f6dc9357SAndroid Build Coastguard Worker 
ParseAcl(AString & s,const Byte * p,size_t size,const char * strName,UInt32 flags,UInt32 offset)481*f6dc9357SAndroid Build Coastguard Worker static void ParseAcl(AString &s, const Byte *p, size_t size, const char *strName, UInt32 flags, UInt32 offset)
482*f6dc9357SAndroid Build Coastguard Worker {
483*f6dc9357SAndroid Build Coastguard Worker   const unsigned control = Get16(p + 2);
484*f6dc9357SAndroid Build Coastguard Worker   if ((flags & control) == 0)
485*f6dc9357SAndroid Build Coastguard Worker     return;
486*f6dc9357SAndroid Build Coastguard Worker   const UInt32 pos = Get32(p + offset);
487*f6dc9357SAndroid Build Coastguard Worker   s.Add_Space();
488*f6dc9357SAndroid Build Coastguard Worker   s += strName;
489*f6dc9357SAndroid Build Coastguard Worker   if (pos >= size)
490*f6dc9357SAndroid Build Coastguard Worker     return;
491*f6dc9357SAndroid Build Coastguard Worker   p += pos;
492*f6dc9357SAndroid Build Coastguard Worker   size -= (size_t)pos;
493*f6dc9357SAndroid Build Coastguard Worker   if (size < 8)
494*f6dc9357SAndroid Build Coastguard Worker     return;
495*f6dc9357SAndroid Build Coastguard Worker   if (Get16(p) != 2) // revision
496*f6dc9357SAndroid Build Coastguard Worker     return;
497*f6dc9357SAndroid Build Coastguard Worker   const UInt32 num = Get32(p + 4);
498*f6dc9357SAndroid Build Coastguard Worker   s.Add_UInt32(num);
499*f6dc9357SAndroid Build Coastguard Worker 
500*f6dc9357SAndroid Build Coastguard Worker   /*
501*f6dc9357SAndroid Build Coastguard Worker   UInt32 aclSize = Get16(p + 2);
502*f6dc9357SAndroid Build Coastguard Worker   if (num >= (1 << 16))
503*f6dc9357SAndroid Build Coastguard Worker     return;
504*f6dc9357SAndroid Build Coastguard Worker   if (aclSize > size)
505*f6dc9357SAndroid Build Coastguard Worker     return;
506*f6dc9357SAndroid Build Coastguard Worker   size = aclSize;
507*f6dc9357SAndroid Build Coastguard Worker   size -= 8;
508*f6dc9357SAndroid Build Coastguard Worker   p += 8;
509*f6dc9357SAndroid Build Coastguard Worker   for (UInt32 i = 0 ; i < num; i++)
510*f6dc9357SAndroid Build Coastguard Worker   {
511*f6dc9357SAndroid Build Coastguard Worker     if (size <= 8)
512*f6dc9357SAndroid Build Coastguard Worker       return;
513*f6dc9357SAndroid Build Coastguard Worker     // Byte type = p[0];
514*f6dc9357SAndroid Build Coastguard Worker     // Byte flags = p[1];
515*f6dc9357SAndroid Build Coastguard Worker     // UInt32 aceSize = Get16(p + 2);
516*f6dc9357SAndroid Build Coastguard Worker     // UInt32 mask = Get32(p + 4);
517*f6dc9357SAndroid Build Coastguard Worker     p += 8;
518*f6dc9357SAndroid Build Coastguard Worker     size -= 8;
519*f6dc9357SAndroid Build Coastguard Worker 
520*f6dc9357SAndroid Build Coastguard Worker     UInt32 sidSize = 0;
521*f6dc9357SAndroid Build Coastguard Worker     s.Add_Space();
522*f6dc9357SAndroid Build Coastguard Worker     ParseSid(s, p, size, sidSize);
523*f6dc9357SAndroid Build Coastguard Worker     if (sidSize == 0)
524*f6dc9357SAndroid Build Coastguard Worker       return;
525*f6dc9357SAndroid Build Coastguard Worker     p += sidSize;
526*f6dc9357SAndroid Build Coastguard Worker     size -= sidSize;
527*f6dc9357SAndroid Build Coastguard Worker   }
528*f6dc9357SAndroid Build Coastguard Worker 
529*f6dc9357SAndroid Build Coastguard Worker   // the tail can contain zeros. So (size != 0) is not ERROR
530*f6dc9357SAndroid Build Coastguard Worker   // if (size != 0) s += " ERROR";
531*f6dc9357SAndroid Build Coastguard Worker   */
532*f6dc9357SAndroid Build Coastguard Worker }
533*f6dc9357SAndroid Build Coastguard Worker 
534*f6dc9357SAndroid Build Coastguard Worker /*
535*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_OWNER_DEFAULTED       (0x0001)
536*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_GROUP_DEFAULTED       (0x0002)
537*f6dc9357SAndroid Build Coastguard Worker */
538*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_DACL_PRESENT          (0x0004)
539*f6dc9357SAndroid Build Coastguard Worker /*
540*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_DACL_DEFAULTED        (0x0008)
541*f6dc9357SAndroid Build Coastguard Worker */
542*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_SACL_PRESENT          (0x0010)
543*f6dc9357SAndroid Build Coastguard Worker /*
544*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_SACL_DEFAULTED        (0x0020)
545*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100)
546*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200)
547*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_DACL_AUTO_INHERITED   (0x0400)
548*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_SACL_AUTO_INHERITED   (0x0800)
549*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_DACL_PROTECTED        (0x1000)
550*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_SACL_PROTECTED        (0x2000)
551*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_RM_CONTROL_VALID      (0x4000)
552*f6dc9357SAndroid Build Coastguard Worker #define MY_SE_SELF_RELATIVE         (0x8000)
553*f6dc9357SAndroid Build Coastguard Worker */
554*f6dc9357SAndroid Build Coastguard Worker 
ConvertNtSecureToString(const Byte * data,size_t size,AString & s)555*f6dc9357SAndroid Build Coastguard Worker void ConvertNtSecureToString(const Byte *data, size_t size, AString &s)
556*f6dc9357SAndroid Build Coastguard Worker {
557*f6dc9357SAndroid Build Coastguard Worker   s.Empty();
558*f6dc9357SAndroid Build Coastguard Worker   if (size < 20 || size > (1 << 18))
559*f6dc9357SAndroid Build Coastguard Worker   {
560*f6dc9357SAndroid Build Coastguard Worker     s += "ERROR";
561*f6dc9357SAndroid Build Coastguard Worker     return;
562*f6dc9357SAndroid Build Coastguard Worker   }
563*f6dc9357SAndroid Build Coastguard Worker   if (Get16(data) != 1) // revision
564*f6dc9357SAndroid Build Coastguard Worker   {
565*f6dc9357SAndroid Build Coastguard Worker     s += "UNSUPPORTED";
566*f6dc9357SAndroid Build Coastguard Worker     return;
567*f6dc9357SAndroid Build Coastguard Worker   }
568*f6dc9357SAndroid Build Coastguard Worker   ParseOwner(s, data, size, Get32(data + 4));
569*f6dc9357SAndroid Build Coastguard Worker   s.Add_Space();
570*f6dc9357SAndroid Build Coastguard Worker   ParseOwner(s, data, size, Get32(data + 8));
571*f6dc9357SAndroid Build Coastguard Worker   ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12);
572*f6dc9357SAndroid Build Coastguard Worker   ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16);
573*f6dc9357SAndroid Build Coastguard Worker   s.Add_Space();
574*f6dc9357SAndroid Build Coastguard Worker   s.Add_UInt32((UInt32)size);
575*f6dc9357SAndroid Build Coastguard Worker   // s.Add_LF();
576*f6dc9357SAndroid Build Coastguard Worker   // s += Data_To_Hex(data, size);
577*f6dc9357SAndroid Build Coastguard Worker }
578*f6dc9357SAndroid Build Coastguard Worker 
579*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
580*f6dc9357SAndroid Build Coastguard Worker 
CheckSid(const Byte * data,size_t size,UInt32 pos)581*f6dc9357SAndroid Build Coastguard Worker static bool CheckSid(const Byte *data, size_t size, UInt32 pos) throw()
582*f6dc9357SAndroid Build Coastguard Worker {
583*f6dc9357SAndroid Build Coastguard Worker   if (pos >= size)
584*f6dc9357SAndroid Build Coastguard Worker     return false;
585*f6dc9357SAndroid Build Coastguard Worker   size -= pos;
586*f6dc9357SAndroid Build Coastguard Worker   if (size < 8)
587*f6dc9357SAndroid Build Coastguard Worker     return false;
588*f6dc9357SAndroid Build Coastguard Worker   if (data[pos] != 1) // rev
589*f6dc9357SAndroid Build Coastguard Worker     return false;
590*f6dc9357SAndroid Build Coastguard Worker   const unsigned num = data[pos + 1];
591*f6dc9357SAndroid Build Coastguard Worker   return (8 + num * 4 <= size);
592*f6dc9357SAndroid Build Coastguard Worker }
593*f6dc9357SAndroid Build Coastguard Worker 
CheckAcl(const Byte * p,size_t size,UInt32 flags,size_t offset)594*f6dc9357SAndroid Build Coastguard Worker static bool CheckAcl(const Byte *p, size_t size, UInt32 flags, size_t offset) throw()
595*f6dc9357SAndroid Build Coastguard Worker {
596*f6dc9357SAndroid Build Coastguard Worker   const unsigned control = Get16(p + 2);
597*f6dc9357SAndroid Build Coastguard Worker   if ((flags & control) == 0)
598*f6dc9357SAndroid Build Coastguard Worker     return true;
599*f6dc9357SAndroid Build Coastguard Worker   const UInt32 pos = Get32(p + offset);
600*f6dc9357SAndroid Build Coastguard Worker   if (pos >= size)
601*f6dc9357SAndroid Build Coastguard Worker     return false;
602*f6dc9357SAndroid Build Coastguard Worker   p += pos;
603*f6dc9357SAndroid Build Coastguard Worker   size -= pos;
604*f6dc9357SAndroid Build Coastguard Worker   if (size < 8)
605*f6dc9357SAndroid Build Coastguard Worker     return false;
606*f6dc9357SAndroid Build Coastguard Worker   const unsigned aclSize = Get16(p + 2);
607*f6dc9357SAndroid Build Coastguard Worker   return (aclSize <= size);
608*f6dc9357SAndroid Build Coastguard Worker }
609*f6dc9357SAndroid Build Coastguard Worker 
CheckNtSecure(const Byte * data,size_t size)610*f6dc9357SAndroid Build Coastguard Worker bool CheckNtSecure(const Byte *data, size_t size) throw()
611*f6dc9357SAndroid Build Coastguard Worker {
612*f6dc9357SAndroid Build Coastguard Worker   if (size < 20)
613*f6dc9357SAndroid Build Coastguard Worker     return false;
614*f6dc9357SAndroid Build Coastguard Worker   if (Get16(data) != 1) // revision
615*f6dc9357SAndroid Build Coastguard Worker     return true; // windows function can handle such error, so we allow it
616*f6dc9357SAndroid Build Coastguard Worker   if (size > (1 << 18))
617*f6dc9357SAndroid Build Coastguard Worker     return false;
618*f6dc9357SAndroid Build Coastguard Worker   if (!CheckSid(data, size, Get32(data + 4))) return false;
619*f6dc9357SAndroid Build Coastguard Worker   if (!CheckSid(data, size, Get32(data + 8))) return false;
620*f6dc9357SAndroid Build Coastguard Worker   if (!CheckAcl(data, size, MY_SE_SACL_PRESENT, 12)) return false;
621*f6dc9357SAndroid Build Coastguard Worker   if (!CheckAcl(data, size, MY_SE_DACL_PRESENT, 16)) return false;
622*f6dc9357SAndroid Build Coastguard Worker   return true;
623*f6dc9357SAndroid Build Coastguard Worker }
624*f6dc9357SAndroid Build Coastguard Worker 
625*f6dc9357SAndroid Build Coastguard Worker #endif
626*f6dc9357SAndroid Build Coastguard Worker 
627*f6dc9357SAndroid Build Coastguard Worker 
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker // IO_REPARSE_TAG_*
630*f6dc9357SAndroid Build Coastguard Worker 
631*f6dc9357SAndroid Build Coastguard Worker static const CSecID2Name k_ReparseTags[] =
632*f6dc9357SAndroid Build Coastguard Worker {
633*f6dc9357SAndroid Build Coastguard Worker   { 0xA0000003, "MOUNT_POINT" },
634*f6dc9357SAndroid Build Coastguard Worker   { 0xC0000004, "HSM" },
635*f6dc9357SAndroid Build Coastguard Worker   { 0x80000005, "DRIVE_EXTENDER" },
636*f6dc9357SAndroid Build Coastguard Worker   { 0x80000006, "HSM2" },
637*f6dc9357SAndroid Build Coastguard Worker   { 0x80000007, "SIS" },
638*f6dc9357SAndroid Build Coastguard Worker   { 0x80000008, "WIM" },
639*f6dc9357SAndroid Build Coastguard Worker   { 0x80000009, "CSV" },
640*f6dc9357SAndroid Build Coastguard Worker   { 0x8000000A, "DFS" },
641*f6dc9357SAndroid Build Coastguard Worker   { 0x8000000B, "FILTER_MANAGER" },
642*f6dc9357SAndroid Build Coastguard Worker   { 0xA000000C, "SYMLINK" },
643*f6dc9357SAndroid Build Coastguard Worker   { 0xA0000010, "IIS_CACHE" },
644*f6dc9357SAndroid Build Coastguard Worker   { 0x80000012, "DFSR" },
645*f6dc9357SAndroid Build Coastguard Worker   { 0x80000013, "DEDUP" },
646*f6dc9357SAndroid Build Coastguard Worker   { 0xC0000014, "APPXSTRM" },
647*f6dc9357SAndroid Build Coastguard Worker   { 0x80000014, "NFS" },
648*f6dc9357SAndroid Build Coastguard Worker   { 0x80000015, "FILE_PLACEHOLDER" },
649*f6dc9357SAndroid Build Coastguard Worker   { 0x80000016, "DFM" },
650*f6dc9357SAndroid Build Coastguard Worker   { 0x80000017, "WOF" },
651*f6dc9357SAndroid Build Coastguard Worker   { 0x80000018, "WCI" },
652*f6dc9357SAndroid Build Coastguard Worker   { 0x8000001B, "APPEXECLINK" },
653*f6dc9357SAndroid Build Coastguard Worker   { 0xA000001D, "LX_SYMLINK" },
654*f6dc9357SAndroid Build Coastguard Worker   { 0x80000023, "AF_UNIX" },
655*f6dc9357SAndroid Build Coastguard Worker   { 0x80000024, "LX_FIFO" },
656*f6dc9357SAndroid Build Coastguard Worker   { 0x80000025, "LX_CHR" },
657*f6dc9357SAndroid Build Coastguard Worker   { 0x80000026, "LX_BLK" }
658*f6dc9357SAndroid Build Coastguard Worker };
659*f6dc9357SAndroid Build Coastguard Worker 
ConvertNtReparseToString(const Byte * data,size_t size,UString & s)660*f6dc9357SAndroid Build Coastguard Worker bool ConvertNtReparseToString(const Byte *data, size_t size, UString &s)
661*f6dc9357SAndroid Build Coastguard Worker {
662*f6dc9357SAndroid Build Coastguard Worker   s.Empty();
663*f6dc9357SAndroid Build Coastguard Worker   NFile::CReparseAttr attr;
664*f6dc9357SAndroid Build Coastguard Worker 
665*f6dc9357SAndroid Build Coastguard Worker   if (attr.Parse(data, size))
666*f6dc9357SAndroid Build Coastguard Worker   {
667*f6dc9357SAndroid Build Coastguard Worker     if (attr.IsSymLink_WSL())
668*f6dc9357SAndroid Build Coastguard Worker     {
669*f6dc9357SAndroid Build Coastguard Worker       s += "WSL: ";
670*f6dc9357SAndroid Build Coastguard Worker       s += attr.GetPath();
671*f6dc9357SAndroid Build Coastguard Worker     }
672*f6dc9357SAndroid Build Coastguard Worker     else
673*f6dc9357SAndroid Build Coastguard Worker     {
674*f6dc9357SAndroid Build Coastguard Worker       if (!attr.IsSymLink_Win())
675*f6dc9357SAndroid Build Coastguard Worker         s += "Junction: ";
676*f6dc9357SAndroid Build Coastguard Worker       s += attr.GetPath();
677*f6dc9357SAndroid Build Coastguard Worker       if (s.IsEmpty())
678*f6dc9357SAndroid Build Coastguard Worker         s += "Link: ";
679*f6dc9357SAndroid Build Coastguard Worker       if (!attr.IsOkNamePair())
680*f6dc9357SAndroid Build Coastguard Worker       {
681*f6dc9357SAndroid Build Coastguard Worker         s += " : ";
682*f6dc9357SAndroid Build Coastguard Worker         s += attr.PrintName;
683*f6dc9357SAndroid Build Coastguard Worker       }
684*f6dc9357SAndroid Build Coastguard Worker     }
685*f6dc9357SAndroid Build Coastguard Worker     if (attr.MinorError)
686*f6dc9357SAndroid Build Coastguard Worker       s += " : MINOR_ERROR";
687*f6dc9357SAndroid Build Coastguard Worker     return true;
688*f6dc9357SAndroid Build Coastguard Worker     // s.Add_Space(); // for debug
689*f6dc9357SAndroid Build Coastguard Worker   }
690*f6dc9357SAndroid Build Coastguard Worker 
691*f6dc9357SAndroid Build Coastguard Worker   if (size < 8)
692*f6dc9357SAndroid Build Coastguard Worker     return false;
693*f6dc9357SAndroid Build Coastguard Worker   const UInt32 tag = Get32(data);
694*f6dc9357SAndroid Build Coastguard Worker   const UInt32 len = Get16(data + 4);
695*f6dc9357SAndroid Build Coastguard Worker   if (len + 8 > size)
696*f6dc9357SAndroid Build Coastguard Worker     return false;
697*f6dc9357SAndroid Build Coastguard Worker   if (Get16(data + 6) != 0) // padding
698*f6dc9357SAndroid Build Coastguard Worker     return false;
699*f6dc9357SAndroid Build Coastguard Worker 
700*f6dc9357SAndroid Build Coastguard Worker   /*
701*f6dc9357SAndroid Build Coastguard Worker   #define my_IO_REPARSE_TAG_DEDUP        (0x80000013L)
702*f6dc9357SAndroid Build Coastguard Worker   if (tag == my_IO_REPARSE_TAG_DEDUP)
703*f6dc9357SAndroid Build Coastguard Worker   {
704*f6dc9357SAndroid Build Coastguard Worker   }
705*f6dc9357SAndroid Build Coastguard Worker   */
706*f6dc9357SAndroid Build Coastguard Worker 
707*f6dc9357SAndroid Build Coastguard Worker   {
708*f6dc9357SAndroid Build Coastguard Worker     const int index = FindPairIndex(k_ReparseTags, Z7_ARRAY_SIZE(k_ReparseTags), tag);
709*f6dc9357SAndroid Build Coastguard Worker     if (index >= 0)
710*f6dc9357SAndroid Build Coastguard Worker       s += k_ReparseTags[(unsigned)index].sz;
711*f6dc9357SAndroid Build Coastguard Worker     else
712*f6dc9357SAndroid Build Coastguard Worker     {
713*f6dc9357SAndroid Build Coastguard Worker       s += "REPARSE:";
714*f6dc9357SAndroid Build Coastguard Worker       char hex[16];
715*f6dc9357SAndroid Build Coastguard Worker       ConvertUInt32ToHex8Digits(tag, hex);
716*f6dc9357SAndroid Build Coastguard Worker       s += hex;
717*f6dc9357SAndroid Build Coastguard Worker     }
718*f6dc9357SAndroid Build Coastguard Worker   }
719*f6dc9357SAndroid Build Coastguard Worker 
720*f6dc9357SAndroid Build Coastguard Worker   s.Add_Colon();
721*f6dc9357SAndroid Build Coastguard Worker   s.Add_UInt32(len);
722*f6dc9357SAndroid Build Coastguard Worker 
723*f6dc9357SAndroid Build Coastguard Worker   if (len != 0)
724*f6dc9357SAndroid Build Coastguard Worker   {
725*f6dc9357SAndroid Build Coastguard Worker     s.Add_Space();
726*f6dc9357SAndroid Build Coastguard Worker 
727*f6dc9357SAndroid Build Coastguard Worker     data += 8;
728*f6dc9357SAndroid Build Coastguard Worker 
729*f6dc9357SAndroid Build Coastguard Worker     for (UInt32 i = 0; i < len; i++)
730*f6dc9357SAndroid Build Coastguard Worker     {
731*f6dc9357SAndroid Build Coastguard Worker       if (i >= 16)
732*f6dc9357SAndroid Build Coastguard Worker       {
733*f6dc9357SAndroid Build Coastguard Worker         s += "...";
734*f6dc9357SAndroid Build Coastguard Worker         break;
735*f6dc9357SAndroid Build Coastguard Worker       }
736*f6dc9357SAndroid Build Coastguard Worker       const unsigned b = data[i];
737*f6dc9357SAndroid Build Coastguard Worker       s.Add_Char((char)GET_HEX_CHAR_UPPER(b >> 4));
738*f6dc9357SAndroid Build Coastguard Worker       s.Add_Char((char)GET_HEX_CHAR_UPPER(b & 15));
739*f6dc9357SAndroid Build Coastguard Worker     }
740*f6dc9357SAndroid Build Coastguard Worker   }
741*f6dc9357SAndroid Build Coastguard Worker 
742*f6dc9357SAndroid Build Coastguard Worker   return true;
743*f6dc9357SAndroid Build Coastguard Worker }
744*f6dc9357SAndroid Build Coastguard Worker 
745*f6dc9357SAndroid Build Coastguard Worker #endif
746