1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// PropIDUtils.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../../C/CpuArch.h"
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
7cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/IntToString.h"
8cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Common/StringConvert.h"
9cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
10cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileFind.h"
11cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/FileIO.h"
12cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#include "../../../Windows/PropVariantConv.h"
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../../PropID.h"
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "PropIDUtils.h"
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
18cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define Get16(x) GetUi16(x)
19cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define Get32(x) GetUi32(x)
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
21cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyusing namespace NWindows;
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
23cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const char g_WinAttribChars[16 + 1] = "RHS8DAdNTsLCOnE_";
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/*
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync0 READONLY
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync1 HIDDEN
27cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky2 SYSTEM
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync4 DIRECTORY
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync5 ARCHIVE
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync6 DEVICE
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync7 NORMAL
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync8 TEMPORARY
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync9 SPARSE_FILE
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync10 REPARSE_POINT
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync11 COMPRESSED
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync12 OFFLINE
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync13 NOT_CONTENT_INDEXED
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync14 ENCRYPTED
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync16 VIRTUAL
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
44cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid ConvertWinAttribToString(char *s, UInt32 wa)
45cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
46cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (int i = 0; i < 16; i++)
47cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if ((wa & (1 << i)) && i != 7)
48cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      *s++ = g_WinAttribChars[i];
49cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  *s = 0;
50cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
51cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
52baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic const char kPosixTypes[16] = { '0', 'p', 'c', '3', 'd', '5', 'b', '7', '-', '9', 'l', 'B', 's', 'D', 'E', 'F' };
53cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_ATTR_CHAR(a, n, c) ((a) & (1 << (n))) ? c : '-';
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
55cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid ConvertPropertyToShortString(char *dest, const PROPVARIANT &prop, PROPID propID, bool full) throw()
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
57cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  *dest = 0;
58cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (prop.vt == VT_FILETIME)
59cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
60cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    FILETIME localFileTime;
61cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if ((prop.filetime.dwHighDateTime == 0 &&
62cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        prop.filetime.dwLowDateTime == 0) ||
63cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        !::FileTimeToLocalFileTime(&prop.filetime, &localFileTime))
64cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
65cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ConvertFileTimeToString(localFileTime, dest, true, full);
66cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
67cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
68cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  switch (propID)
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidCRC:
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_UI4)
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
74cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ConvertUInt32ToHex8Digits(prop.ulVal, dest);
75cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidAttrib:
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_UI4)
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
81cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ConvertWinAttribToString(dest, prop.ulVal);
82cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    case kpidPosixAttrib:
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (prop.vt != VT_UI4)
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        break;
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UString res;
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 a = prop.ulVal;
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
91cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dest[0] = kPosixTypes[(a >> 12) & 0xF];
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      for (int i = 6; i >= 0; i -= 3)
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
94cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        dest[7 - i] = MY_ATTR_CHAR(a, i + 2, 'r');
95cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        dest[8 - i] = MY_ATTR_CHAR(a, i + 1, 'w');
96cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        dest[9 - i] = MY_ATTR_CHAR(a, i + 0, 'x');
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
98cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if ((a & 0x800) != 0) dest[3] = ((a & (1 << 6)) ? 's' : 'S');
99cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if ((a & 0x400) != 0) dest[6] = ((a & (1 << 3)) ? 's' : 'S');
100cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if ((a & 0x200) != 0) dest[9] = ((a & (1 << 0)) ? 't' : 'T');
101cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dest[10] = 0;
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      a &= ~(UInt32)0xFFFF;
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (a != 0)
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
106cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        dest[10] = ' ';
107cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ConvertUInt32ToHex8Digits(a, dest + 11);
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
109cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
111cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case kpidINode:
112cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
113cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (prop.vt != VT_UI8)
114cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        break;
115cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ConvertUInt32ToString((UInt32)(prop.uhVal.QuadPart >> 48), dest);
116cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      dest += strlen(dest);
117cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      *dest++ = '-';
118cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 low = prop.uhVal.QuadPart & (((UInt64)1 << 48) - 1);
119cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      ConvertUInt64ToString(low, dest);
120cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
121cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
122cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    case kpidVa:
123cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
124cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt64 v = 0;
125cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      if (ConvertPropVariantToUInt64(prop, v))
126cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
127cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        dest[0] = '0';
128cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        dest[1] = 'x';
129cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        ConvertUInt64ToHex(prop.ulVal, dest + 2);
130cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        return;
131cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
132cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      break;
133cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
134cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
135cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ConvertPropVariantToShortString(prop, dest);
136cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
137cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
138cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid ConvertPropertyToString(UString &dest, const PROPVARIANT &prop, PROPID propID, bool full)
139cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
140cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (prop.vt == VT_BSTR)
141cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
142cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    dest = prop.bstrVal;
143cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
145cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  char temp[64];
146cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ConvertPropertyToShortString(temp, prop, propID, full);
147cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  int len = MyStringLen(temp);
148cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  wchar_t *str = dest.GetBuffer(len);
149cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (int i = 0; i < len; i++)
150cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    str[i] = temp[i];
151cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  dest.ReleaseBuffer(len);
152cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
153cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
154cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic inline char GetHex(Byte value)
155cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
156cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return (char)((value < 10) ? ('0' + value) : ('A' + (value - 10)));
157cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
158cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
159cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifndef _SFX
160cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
161cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic inline void AddHexToString(AString &res, Byte value)
162cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
163cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  res += GetHex((Byte)(value >> 4));
164cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  res += GetHex((Byte)(value & 0xF));
165cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  res += ' ';
166cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
167cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
168cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky/*
169cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic AString Data_To_Hex(const Byte *data, size_t size)
170cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
171cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  AString s;
172cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (size_t i = 0; i < size; i++)
173cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    AddHexToString(s, data[i]);
174cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return s;
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
176cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky*/
177cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
178cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const char *sidNames[] =
179cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
180cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "0",
181cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Dialup",
182cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Network",
183cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Batch",
184cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Interactive",
185cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Logon",  // S-1-5-5-X-Y
186cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Service",
187cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Anonymous",
188cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Proxy",
189cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "EnterpriseDC",
190cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Self",
191cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "AuthenticatedUsers",
192cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "RestrictedCode",
193cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "TerminalServer",
194cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "RemoteInteractiveLogon",
195cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "ThisOrganization",
196cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "16",
197cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "IUserIIS",
198cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "LocalSystem",
199cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "LocalService",
200cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "NetworkService",
201cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  "Domains"
202cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
203cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
204cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CSecID2Name
205cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
206cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 n;
207cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const char *sz;
208cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
209cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
210cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyconst CSecID2Name sid_32_Names[] =
211cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
212cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 544, "Administrators" },
213cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 545, "Users" },
214cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 546, "Guests" },
215cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 547, "PowerUsers" },
216cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 548, "AccountOperators" },
217cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 549, "ServerOperators" },
218cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 550, "PrintOperators" },
219cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 551, "BackupOperators" },
220cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 552, "Replicators" },
221cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 553, "Backup Operators" },
222cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 554, "PreWindows2000CompatibleAccess" },
223cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 555, "RemoteDesktopUsers" },
224cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 556, "NetworkConfigurationOperators" },
225cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 557, "IncomingForestTrustBuilders" },
226cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 558, "PerformanceMonitorUsers" },
227cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 559, "PerformanceLogUsers" },
228cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 560, "WindowsAuthorizationAccessGroup" },
229cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 561, "TerminalServerLicenseServers" },
230cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 562, "DistributedCOMUsers" },
231cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 569, "CryptographicOperators" },
232cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 573, "EventLogReaders" },
233cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 574, "CertificateServiceDCOMAccess" }
234cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
235cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
236cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const CSecID2Name sid_21_Names[] =
237cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
238cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 500, "Administrator" },
239cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 501, "Guest" },
240cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 502, "KRBTGT" },
241cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 512, "DomainAdmins" },
242cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 513, "DomainUsers" },
243cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 515, "DomainComputers" },
244cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 516, "DomainControllers" },
245cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 517, "CertPublishers" },
246cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 518, "SchemaAdmins" },
247cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 519, "EnterpriseAdmins" },
248cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 520, "GroupPolicyCreatorOwners" },
249cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 553, "RASandIASServers" },
250cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 553, "RASandIASServers" },
251cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 571, "AllowedRODCPasswordReplicationGroup" },
252cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { 572, "DeniedRODCPasswordReplicationGroup" }
253cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
254cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
255cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystruct CServicesToName
256cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
257cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 n[5];
258cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  const char *sz;
259cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
260cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
261cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic const CServicesToName services_to_name[] =
262cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
263cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  { { 0x38FB89B5, 0xCBC28419, 0x6D236C5C, 0x6E770057, 0x876402C0 } , "TrustedInstaller" }
264cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky};
265cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
266cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
267cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
268cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  sidSize = 0;
269cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (lim < 8)
270cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
271cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += "ERROR";
272cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
273cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
274cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 rev = p[0];
275cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (rev != 1)
276cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
277cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += "UNSUPPORTED";
278cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
279cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
280cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 num = p[1];
281cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (8 + num * 4 > lim)
282cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
283cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += "ERROR";
284cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
285cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
286cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  sidSize = 8 + num * 4;
287cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 authority = GetBe32(p + 4);
288cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
289cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (p[2] == 0 && p[3] == 0 && authority == 5 && num >= 1)
290cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
291cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 v0 = Get32(p + 8);
292cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (v0 < ARRAY_SIZE(sidNames))
293cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
294cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      s += sidNames[v0];
295cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
296cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
297cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (v0 == 32 && num == 2)
298cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
299cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt32 v1 = Get32(p + 12);
300cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (int i = 0; i < ARRAY_SIZE(sid_32_Names); i++)
301cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (sid_32_Names[i].n == v1)
302cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
303cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          s += sid_32_Names[i].sz;
304cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return;
305cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
306cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
307cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (v0 == 21 && num == 5)
308cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
309cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      UInt32 v4 = Get32(p + 8 + 4 * 4);
310cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (int i = 0; i < ARRAY_SIZE(sid_21_Names); i++)
311cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (sid_21_Names[i].n == v4)
312cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
313cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          s += sid_21_Names[i].sz;
314cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return;
315cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
316cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
317cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (v0 == 80 && num == 6)
318cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
319cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      for (int i = 0; i < ARRAY_SIZE(services_to_name); i++)
320cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      {
321cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        const CServicesToName &sn = services_to_name[i];
322cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        int j;
323cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        for (j = 0; j < 5 && sn.n[j] == Get32(p + 8 + 4 + j * 4); j++);
324cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        if (j == 5)
325cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        {
326cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          s += sn.sz;
327cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky          return;
328cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky        }
329cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      }
330cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
331cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
332cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
333cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  char sz[16];
334cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += "S-1-";
335cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (p[2] == 0 && p[3] == 0)
336cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
337cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ConvertUInt32ToString(authority, sz);
338cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += sz;
339cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
340cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  else
341cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
342cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += "0x";
343cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    for (int i = 2; i < 8; i++)
344cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      AddHexToString(s, p[i]);
345cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
346cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt32 i = 0; i < num; i++)
347cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
348cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += '-';
349cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    ConvertUInt32ToString(Get32(p + 8 + i * 4), sz);
350cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += sz;
351cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
352cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
353cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
354cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos)
355cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
356cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (pos > size)
357cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
358cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += "ERROR";
359cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
360cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
361cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 sidSize = 0;
362cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ParseSid(s, p + pos, size - pos, sidSize);
363cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
364cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
365cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void AddUInt32ToString(AString &s, UInt32 val)
366cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
367cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  char sz[16];
368cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ConvertUInt32ToString(val, sz);
369cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += sz;
370cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
371cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
372cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset)
373cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
374cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 control = Get16(p + 2);
375cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if ((flags & control) == 0)
376cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
377cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 pos = Get32(p + offset);
378cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += ' ';
379cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += strName;
380cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (pos >= size)
381cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
382cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  p += pos;
383cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size -= pos;
384cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size < 8)
385cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
386cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (Get16(p) != 2) // revision
387cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
388cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // UInt32 aclSize = Get16(p + 2);
389cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 num = Get32(p + 4);
390cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  AddUInt32ToString(s, num);
391cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  /*
392cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (num >= (1 << 16))
393cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
394cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (aclSize > size)
395cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
396cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size = aclSize;
397cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size -= 8;
398cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  p += 8;
399cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt32 i = 0 ; i < num; i++)
400cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
401cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (size <= 8)
402cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
403cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // Byte type = p[0];
404cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // Byte flags = p[1];
405cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // UInt32 aceSize = Get16(p + 2);
406cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    // UInt32 mask = Get32(p + 4);
407cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p += 8;
408cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    size -= 8;
409cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
410cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    UInt32 sidSize = 0;
411cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += ' ';
412cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += ParseSid(p, size, sidSize);
413cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (sidSize == 0)
414cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      return;
415cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    p += sidSize;
416cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    size -= sidSize;
417cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
418cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size != 0)
419cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += " ERROR";
420cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  */
421cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
422cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
423cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_OWNER_DEFAULTED       (0x0001)
424cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_GROUP_DEFAULTED       (0x0002)
425cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_DACL_PRESENT          (0x0004)
426cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_DACL_DEFAULTED        (0x0008)
427cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_SACL_PRESENT          (0x0010)
428cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_SACL_DEFAULTED        (0x0020)
429cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_DACL_AUTO_INHERIT_REQ (0x0100)
430cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_SACL_AUTO_INHERIT_REQ (0x0200)
431cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_DACL_AUTO_INHERITED   (0x0400)
432cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_SACL_AUTO_INHERITED   (0x0800)
433cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_DACL_PROTECTED        (0x1000)
434cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_SACL_PROTECTED        (0x2000)
435cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_RM_CONTROL_VALID      (0x4000)
436cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#define MY_SE_SELF_RELATIVE         (0x8000)
437cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
438cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckyvoid ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s)
439cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
440cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s.Empty();
441cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size < 20 || size > (1 << 18))
442cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
443cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += "ERROR";
444cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
445cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
446cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (Get16(data) != 1) // revision
447cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
448cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += "UNSUPPORTED";
449cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return;
450cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
451cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ParseOwner(s, data, size, Get32(data + 4));
452cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += ' ';
453cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ParseOwner(s, data, size, Get32(data + 8));
454cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12);
455cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16);
456cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += ' ';
457cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  AddUInt32ToString(s, size);
458cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // s += '\n';
459cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  // s += Data_To_Hex(data, size);
460cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
461cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
462cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#ifdef _WIN32
463cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
464cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic bool CheckSid(const Byte *data, UInt32 size, UInt32 pos)
465cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
466cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (pos >= size)
467cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
468cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size -= pos;
469cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size < 8)
470cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
471cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 rev = data[pos];
472cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (rev != 1)
473cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
474cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 num = data[pos + 1];
475cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return (8 + num * 4 <= size);
476cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
477cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
478cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckystatic bool CheckAcl(const Byte *p, UInt32 size, UInt32 flags, UInt32 offset)
479cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
480cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 control = Get16(p + 2);
481cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if ((flags & control) == 0)
482cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return true;
483cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 pos = Get32(p + offset);
484cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (pos >= size)
485cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
486cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  p += pos;
487cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  size -= pos;
488cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size < 8)
489cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
490cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 aclSize = Get16(p + 2);
491cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return (aclSize <= size);
492cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
493cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
494cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool CheckNtSecure(const Byte *data, UInt32 size)
495cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
496cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size < 20)
497cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
498cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (Get16(data) != 1) // revision
499cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return true; // windows function can handle such error, so we allow it
500cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size > (1 << 18))
501cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
502cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!CheckSid(data, size, Get32(data + 4))) return false;
503cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!CheckSid(data, size, Get32(data + 8))) return false;
504cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!CheckAcl(data, size, MY_SE_SACL_PRESENT, 12)) return false;
505cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (!CheckAcl(data, size, MY_SE_DACL_PRESENT, 16)) return false;
506cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return true;
507cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
508cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
509cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif
510cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
511cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbeckybool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
512cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky{
513cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s.Empty();
514cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  NFile::CReparseAttr attr;
515cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (attr.Parse(data, size))
516cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
517cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!attr.IsSymLink())
518cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      s += L"Junction: ";
519cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += attr.GetPath();
520cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    if (!attr.IsOkNamePair())
521cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    {
522cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      s += L" : ";
523cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky      s += attr.PrintName;
524cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    }
525cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return true;
526cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
527cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
528cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (size < 8)
529cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
530cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 tag = Get32(data);
531cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  UInt32 len = Get16(data + 4);
532cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (len + 8 > size)
533cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
534cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  if (Get16(data + 6) != 0) // padding
535cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    return false;
536cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
537cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  char hex[16];
538cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  ConvertUInt32ToHex8Digits(tag, hex);
539cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s.AddAsciiStr(hex);
540cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  s += L' ';
541cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
542cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  data += 8;
543cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
544cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  for (UInt32 i = 0; i < len; i++)
545cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  {
546cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    Byte b = ((const Byte *)data)[i];
547cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += (wchar_t)GetHex((Byte)((b >> 4) & 0xF));
548cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky    s += (wchar_t)GetHex((Byte)(b & 0xF));
549cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  }
550cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky  return true;
551cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky}
552cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky
553cd66d540cead3f8200b0c73bad9c276d67896c3dDavid Srbecky#endif
554