rlm@1
|
1 // Archive/ZipItem.h
|
rlm@1
|
2
|
rlm@1
|
3 #ifndef __ARCHIVE_ZIP_ITEM_H
|
rlm@1
|
4 #define __ARCHIVE_ZIP_ITEM_H
|
rlm@1
|
5
|
rlm@1
|
6 #include "../../../Common/Types.h"
|
rlm@1
|
7 #include "../../../Common/MyString.h"
|
rlm@1
|
8 #include "../../../Common/Buffer.h"
|
rlm@1
|
9 #include "../../../Common/UTFConvert.h"
|
rlm@1
|
10 #include "../../../Common/StringConvert.h"
|
rlm@1
|
11
|
rlm@1
|
12 #include "ZipHeader.h"
|
rlm@1
|
13
|
rlm@1
|
14 namespace NArchive {
|
rlm@1
|
15 namespace NZip {
|
rlm@1
|
16
|
rlm@1
|
17 struct CVersion
|
rlm@1
|
18 {
|
rlm@1
|
19 Byte Version;
|
rlm@1
|
20 Byte HostOS;
|
rlm@1
|
21 };
|
rlm@1
|
22
|
rlm@1
|
23 bool operator==(const CVersion &v1, const CVersion &v2);
|
rlm@1
|
24 bool operator!=(const CVersion &v1, const CVersion &v2);
|
rlm@1
|
25
|
rlm@1
|
26 struct CExtraSubBlock
|
rlm@1
|
27 {
|
rlm@1
|
28 UInt16 ID;
|
rlm@1
|
29 CByteBuffer Data;
|
rlm@1
|
30 bool ExtractNtfsTime(int index, FILETIME &ft) const;
|
rlm@1
|
31 };
|
rlm@1
|
32
|
rlm@1
|
33 struct CWzAesExtraField
|
rlm@1
|
34 {
|
rlm@1
|
35 UInt16 VendorVersion; // 0x0001 - AE-1, 0x0002 - AE-2,
|
rlm@1
|
36 // UInt16 VendorId; // "AE"
|
rlm@1
|
37 Byte Strength; // 1 - 128-bit , 2 - 192-bit , 3 - 256-bit
|
rlm@1
|
38 UInt16 Method;
|
rlm@1
|
39
|
rlm@1
|
40 CWzAesExtraField(): VendorVersion(2), Strength(3), Method(0) {}
|
rlm@1
|
41
|
rlm@1
|
42 bool NeedCrc() const { return (VendorVersion == 1); }
|
rlm@1
|
43
|
rlm@1
|
44 bool ParseFromSubBlock(const CExtraSubBlock &sb)
|
rlm@1
|
45 {
|
rlm@1
|
46 if (sb.ID != NFileHeader::NExtraID::kWzAES)
|
rlm@1
|
47 return false;
|
rlm@1
|
48 if (sb.Data.GetCapacity() < 7)
|
rlm@1
|
49 return false;
|
rlm@1
|
50 const Byte *p = (const Byte *)sb.Data;
|
rlm@1
|
51 VendorVersion = (((UInt16)p[1]) << 8) | p[0];
|
rlm@1
|
52 if (p[2] != 'A' || p[3] != 'E')
|
rlm@1
|
53 return false;
|
rlm@1
|
54 Strength = p[4];
|
rlm@1
|
55 Method = (((UInt16)p[6]) << 16) | p[5];
|
rlm@1
|
56 return true;
|
rlm@1
|
57 }
|
rlm@1
|
58 void SetSubBlock(CExtraSubBlock &sb) const
|
rlm@1
|
59 {
|
rlm@1
|
60 sb.Data.SetCapacity(7);
|
rlm@1
|
61 sb.ID = NFileHeader::NExtraID::kWzAES;
|
rlm@1
|
62 Byte *p = (Byte *)sb.Data;
|
rlm@1
|
63 p[0] = (Byte)VendorVersion;
|
rlm@1
|
64 p[1] = (Byte)(VendorVersion >> 8);
|
rlm@1
|
65 p[2] = 'A';
|
rlm@1
|
66 p[3] = 'E';
|
rlm@1
|
67 p[4] = Strength;
|
rlm@1
|
68 p[5] = (Byte)Method;
|
rlm@1
|
69 p[6] = (Byte)(Method >> 8);
|
rlm@1
|
70 }
|
rlm@1
|
71 };
|
rlm@1
|
72
|
rlm@1
|
73 namespace NStrongCryptoFlags
|
rlm@1
|
74 {
|
rlm@1
|
75 const UInt16 kDES = 0x6601;
|
rlm@1
|
76 const UInt16 kRC2old = 0x6602;
|
rlm@1
|
77 const UInt16 k3DES168 = 0x6603;
|
rlm@1
|
78 const UInt16 k3DES112 = 0x6609;
|
rlm@1
|
79 const UInt16 kAES128 = 0x660E;
|
rlm@1
|
80 const UInt16 kAES192 = 0x660F;
|
rlm@1
|
81 const UInt16 kAES256 = 0x6610;
|
rlm@1
|
82 const UInt16 kRC2 = 0x6702;
|
rlm@1
|
83 const UInt16 kBlowfish = 0x6720;
|
rlm@1
|
84 const UInt16 kTwofish = 0x6721;
|
rlm@1
|
85 const UInt16 kRC4 = 0x6801;
|
rlm@1
|
86 }
|
rlm@1
|
87
|
rlm@1
|
88 struct CStrongCryptoField
|
rlm@1
|
89 {
|
rlm@1
|
90 UInt16 Format;
|
rlm@1
|
91 UInt16 AlgId;
|
rlm@1
|
92 UInt16 BitLen;
|
rlm@1
|
93 UInt16 Flags;
|
rlm@1
|
94
|
rlm@1
|
95 bool ParseFromSubBlock(const CExtraSubBlock &sb)
|
rlm@1
|
96 {
|
rlm@1
|
97 if (sb.ID != NFileHeader::NExtraID::kStrongEncrypt)
|
rlm@1
|
98 return false;
|
rlm@1
|
99 const Byte *p = (const Byte *)sb.Data;
|
rlm@1
|
100 if (sb.Data.GetCapacity() < 8)
|
rlm@1
|
101 return false;
|
rlm@1
|
102 Format = (((UInt16)p[1]) << 8) | p[0];
|
rlm@1
|
103 AlgId = (((UInt16)p[3]) << 8) | p[2];
|
rlm@1
|
104 BitLen = (((UInt16)p[5]) << 8) | p[4];
|
rlm@1
|
105 Flags = (((UInt16)p[7]) << 8) | p[6];
|
rlm@1
|
106 return (Format == 2);
|
rlm@1
|
107 }
|
rlm@1
|
108 };
|
rlm@1
|
109
|
rlm@1
|
110 struct CExtraBlock
|
rlm@1
|
111 {
|
rlm@1
|
112 CObjectVector<CExtraSubBlock> SubBlocks;
|
rlm@1
|
113 void Clear() { SubBlocks.Clear(); }
|
rlm@1
|
114 size_t GetSize() const
|
rlm@1
|
115 {
|
rlm@1
|
116 size_t res = 0;
|
rlm@1
|
117 for (int i = 0; i < SubBlocks.Size(); i++)
|
rlm@1
|
118 res += SubBlocks[i].Data.GetCapacity() + 2 + 2;
|
rlm@1
|
119 return res;
|
rlm@1
|
120 }
|
rlm@1
|
121 bool GetWzAesField(CWzAesExtraField &aesField) const
|
rlm@1
|
122 {
|
rlm@1
|
123 for (int i = 0; i < SubBlocks.Size(); i++)
|
rlm@1
|
124 if (aesField.ParseFromSubBlock(SubBlocks[i]))
|
rlm@1
|
125 return true;
|
rlm@1
|
126 return false;
|
rlm@1
|
127 }
|
rlm@1
|
128
|
rlm@1
|
129 bool GetStrongCryptoField(CStrongCryptoField &f) const
|
rlm@1
|
130 {
|
rlm@1
|
131 for (int i = 0; i < SubBlocks.Size(); i++)
|
rlm@1
|
132 if (f.ParseFromSubBlock(SubBlocks[i]))
|
rlm@1
|
133 return true;
|
rlm@1
|
134 return false;
|
rlm@1
|
135 }
|
rlm@1
|
136
|
rlm@1
|
137 bool HasWzAesField() const
|
rlm@1
|
138 {
|
rlm@1
|
139 CWzAesExtraField aesField;
|
rlm@1
|
140 return GetWzAesField(aesField);
|
rlm@1
|
141 }
|
rlm@1
|
142
|
rlm@1
|
143 bool GetNtfsTime(int index, FILETIME &ft) const
|
rlm@1
|
144 {
|
rlm@1
|
145 for (int i = 0; i < SubBlocks.Size(); i++)
|
rlm@1
|
146 {
|
rlm@1
|
147 const CExtraSubBlock &sb = SubBlocks[i];
|
rlm@1
|
148 if (sb.ID == NFileHeader::NExtraID::kNTFS)
|
rlm@1
|
149 return sb.ExtractNtfsTime(index, ft);
|
rlm@1
|
150 }
|
rlm@1
|
151 return false;
|
rlm@1
|
152 }
|
rlm@1
|
153
|
rlm@1
|
154 /*
|
rlm@1
|
155 bool HasStrongCryptoField() const
|
rlm@1
|
156 {
|
rlm@1
|
157 CStrongCryptoField f;
|
rlm@1
|
158 return GetStrongCryptoField(f);
|
rlm@1
|
159 }
|
rlm@1
|
160 */
|
rlm@1
|
161
|
rlm@1
|
162 void RemoveUnknownSubBlocks()
|
rlm@1
|
163 {
|
rlm@1
|
164 for (int i = SubBlocks.Size() - 1; i >= 0; i--)
|
rlm@1
|
165 if (SubBlocks[i].ID != NFileHeader::NExtraID::kWzAES)
|
rlm@1
|
166 SubBlocks.Delete(i);
|
rlm@1
|
167 }
|
rlm@1
|
168 };
|
rlm@1
|
169
|
rlm@1
|
170
|
rlm@1
|
171 class CLocalItem
|
rlm@1
|
172 {
|
rlm@1
|
173 public:
|
rlm@1
|
174 CVersion ExtractVersion;
|
rlm@1
|
175 UInt16 Flags;
|
rlm@1
|
176 UInt16 CompressionMethod;
|
rlm@1
|
177 UInt32 Time;
|
rlm@1
|
178 UInt32 FileCRC;
|
rlm@1
|
179 UInt64 PackSize;
|
rlm@1
|
180 UInt64 UnPackSize;
|
rlm@1
|
181
|
rlm@1
|
182 AString Name;
|
rlm@1
|
183
|
rlm@1
|
184 CExtraBlock LocalExtra;
|
rlm@1
|
185
|
rlm@1
|
186 bool IsUtf8() const { return (Flags & NFileHeader::NFlags::kUtf8) != 0; }
|
rlm@1
|
187
|
rlm@1
|
188 bool IsEncrypted() const { return (Flags & NFileHeader::NFlags::kEncrypted) != 0; }
|
rlm@1
|
189 bool IsStrongEncrypted() const { return IsEncrypted() && (Flags & NFileHeader::NFlags::kStrongEncrypted) != 0; };
|
rlm@1
|
190
|
rlm@1
|
191 bool IsLzmaEOS() const { return (Flags & NFileHeader::NFlags::kLzmaEOS) != 0; }
|
rlm@1
|
192
|
rlm@1
|
193 bool IsDir() const;
|
rlm@1
|
194 bool IgnoreItem() const { return false; }
|
rlm@1
|
195 UInt32 GetWinAttributes() const;
|
rlm@1
|
196
|
rlm@1
|
197 bool HasDescriptor() const { return (Flags & NFileHeader::NFlags::kDescriptorUsedMask) != 0; }
|
rlm@1
|
198
|
rlm@1
|
199 UString GetUnicodeString(const AString &s) const
|
rlm@1
|
200 {
|
rlm@1
|
201 UString res;
|
rlm@1
|
202 if (IsUtf8())
|
rlm@1
|
203 if (!ConvertUTF8ToUnicode(s, res))
|
rlm@1
|
204 res.Empty();
|
rlm@1
|
205 if (res.IsEmpty())
|
rlm@1
|
206 res = MultiByteToUnicodeString(s, GetCodePage());
|
rlm@1
|
207 return res;
|
rlm@1
|
208 }
|
rlm@1
|
209
|
rlm@1
|
210 private:
|
rlm@1
|
211 void SetFlagBits(int startBitNumber, int numBits, int value);
|
rlm@1
|
212 void SetBitMask(int bitMask, bool enable);
|
rlm@1
|
213 public:
|
rlm@1
|
214 void ClearFlags() { Flags = 0; }
|
rlm@1
|
215 void SetEncrypted(bool encrypted);
|
rlm@1
|
216 void SetUtf8(bool isUtf8);
|
rlm@1
|
217
|
rlm@1
|
218 WORD GetCodePage() const { return CP_OEMCP; }
|
rlm@1
|
219 };
|
rlm@1
|
220
|
rlm@1
|
221 class CItem: public CLocalItem
|
rlm@1
|
222 {
|
rlm@1
|
223 public:
|
rlm@1
|
224 CVersion MadeByVersion;
|
rlm@1
|
225 UInt16 InternalAttributes;
|
rlm@1
|
226 UInt32 ExternalAttributes;
|
rlm@1
|
227
|
rlm@1
|
228 UInt64 LocalHeaderPosition;
|
rlm@1
|
229
|
rlm@1
|
230 FILETIME NtfsMTime;
|
rlm@1
|
231 FILETIME NtfsATime;
|
rlm@1
|
232 FILETIME NtfsCTime;
|
rlm@1
|
233
|
rlm@1
|
234 CExtraBlock CentralExtra;
|
rlm@1
|
235 CByteBuffer Comment;
|
rlm@1
|
236
|
rlm@1
|
237 bool FromLocal;
|
rlm@1
|
238 bool FromCentral;
|
rlm@1
|
239 bool NtfsTimeIsDefined;
|
rlm@1
|
240
|
rlm@1
|
241 bool IsDir() const;
|
rlm@1
|
242 UInt32 GetWinAttributes() const;
|
rlm@1
|
243
|
rlm@1
|
244 bool IsThereCrc() const
|
rlm@1
|
245 {
|
rlm@1
|
246 if (CompressionMethod == NFileHeader::NCompressionMethod::kWzAES)
|
rlm@1
|
247 {
|
rlm@1
|
248 CWzAesExtraField aesField;
|
rlm@1
|
249 if (CentralExtra.GetWzAesField(aesField))
|
rlm@1
|
250 return aesField.NeedCrc();
|
rlm@1
|
251 }
|
rlm@1
|
252 return (FileCRC != 0 || !IsDir());
|
rlm@1
|
253 }
|
rlm@1
|
254
|
rlm@1
|
255 WORD GetCodePage() const
|
rlm@1
|
256 {
|
rlm@1
|
257 return (WORD)((MadeByVersion.HostOS == NFileHeader::NHostOS::kFAT
|
rlm@1
|
258 || MadeByVersion.HostOS == NFileHeader::NHostOS::kNTFS
|
rlm@1
|
259 ) ? CP_OEMCP : CP_ACP);
|
rlm@1
|
260 }
|
rlm@1
|
261 CItem() : FromLocal(false), FromCentral(false), NtfsTimeIsDefined(false) {}
|
rlm@1
|
262 };
|
rlm@1
|
263
|
rlm@1
|
264 }}
|
rlm@1
|
265
|
rlm@1
|
266 #endif
|
rlm@1
|
267
|
rlm@1
|
268
|