rlm@1
|
1 // 7zHandler.cpp
|
rlm@1
|
2
|
rlm@1
|
3 #include "StdAfx.h"
|
rlm@1
|
4
|
rlm@1
|
5 extern "C"
|
rlm@1
|
6 {
|
rlm@1
|
7 #include "../../../../C/CpuArch.h"
|
rlm@1
|
8 }
|
rlm@1
|
9
|
rlm@1
|
10 #include "../../../Common/ComTry.h"
|
rlm@1
|
11 #include "../../../Common/IntToString.h"
|
rlm@1
|
12
|
rlm@1
|
13 #ifdef COMPRESS_MT
|
rlm@1
|
14 #include "../../../Windows/System.h"
|
rlm@1
|
15 #endif
|
rlm@1
|
16
|
rlm@1
|
17 #include "../Common/ItemNameUtils.h"
|
rlm@1
|
18
|
rlm@1
|
19 #include "7zHandler.h"
|
rlm@1
|
20 #include "7zProperties.h"
|
rlm@1
|
21
|
rlm@1
|
22 #ifdef __7Z_SET_PROPERTIES
|
rlm@1
|
23 #ifdef EXTRACT_ONLY
|
rlm@1
|
24 #include "../Common/ParseProperties.h"
|
rlm@1
|
25 #endif
|
rlm@1
|
26 #endif
|
rlm@1
|
27
|
rlm@1
|
28 using namespace NWindows;
|
rlm@1
|
29
|
rlm@1
|
30 extern UString ConvertMethodIdToString(UInt64 id);
|
rlm@1
|
31
|
rlm@1
|
32 namespace NArchive {
|
rlm@1
|
33 namespace N7z {
|
rlm@1
|
34
|
rlm@1
|
35 CHandler::CHandler()
|
rlm@1
|
36 {
|
rlm@1
|
37 _crcSize = 4;
|
rlm@1
|
38
|
rlm@1
|
39 #ifndef _NO_CRYPTO
|
rlm@1
|
40 _passwordIsDefined = false;
|
rlm@1
|
41 #endif
|
rlm@1
|
42
|
rlm@1
|
43 #ifdef EXTRACT_ONLY
|
rlm@1
|
44 #ifdef COMPRESS_MT
|
rlm@1
|
45 _numThreads = NSystem::GetNumberOfProcessors();
|
rlm@1
|
46 #endif
|
rlm@1
|
47 #else
|
rlm@1
|
48 Init();
|
rlm@1
|
49 #endif
|
rlm@1
|
50 }
|
rlm@1
|
51
|
rlm@1
|
52 STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
|
rlm@1
|
53 {
|
rlm@1
|
54 *numItems = _db.Files.Size();
|
rlm@1
|
55 return S_OK;
|
rlm@1
|
56 }
|
rlm@1
|
57
|
rlm@1
|
58 #ifdef _SFX
|
rlm@1
|
59
|
rlm@1
|
60 IMP_IInArchive_ArcProps_NO
|
rlm@1
|
61
|
rlm@1
|
62 STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
|
rlm@1
|
63 {
|
rlm@1
|
64 return E_NOTIMPL;
|
rlm@1
|
65 }
|
rlm@1
|
66
|
rlm@1
|
67 STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
|
rlm@1
|
68 BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
|
rlm@1
|
69 {
|
rlm@1
|
70 return E_NOTIMPL;
|
rlm@1
|
71 }
|
rlm@1
|
72
|
rlm@1
|
73
|
rlm@1
|
74 #else
|
rlm@1
|
75
|
rlm@1
|
76 STATPROPSTG kArcProps[] =
|
rlm@1
|
77 {
|
rlm@1
|
78 { NULL, kpidMethod, VT_BSTR},
|
rlm@1
|
79 { NULL, kpidSolid, VT_BOOL},
|
rlm@1
|
80 { NULL, kpidNumBlocks, VT_UI4},
|
rlm@1
|
81 { NULL, kpidPhySize, VT_UI8},
|
rlm@1
|
82 { NULL, kpidHeadersSize, VT_UI8},
|
rlm@1
|
83 { NULL, kpidOffset, VT_UI8}
|
rlm@1
|
84 };
|
rlm@1
|
85
|
rlm@1
|
86 STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
rlm@1
|
87 {
|
rlm@1
|
88 COM_TRY_BEGIN
|
rlm@1
|
89 NCOM::CPropVariant prop;
|
rlm@1
|
90 switch(propID)
|
rlm@1
|
91 {
|
rlm@1
|
92 case kpidMethod:
|
rlm@1
|
93 {
|
rlm@1
|
94 UString resString;
|
rlm@1
|
95 CRecordVector<UInt64> ids;
|
rlm@1
|
96 int i;
|
rlm@1
|
97 for (i = 0; i < _db.Folders.Size(); i++)
|
rlm@1
|
98 {
|
rlm@1
|
99 const CFolder &f = _db.Folders[i];
|
rlm@1
|
100 for (int j = f.Coders.Size() - 1; j >= 0; j--)
|
rlm@1
|
101 ids.AddToUniqueSorted(f.Coders[j].MethodID);
|
rlm@1
|
102 }
|
rlm@1
|
103
|
rlm@1
|
104 for (i = 0; i < ids.Size(); i++)
|
rlm@1
|
105 {
|
rlm@1
|
106 UInt64 id = ids[i];
|
rlm@1
|
107 UString methodName;
|
rlm@1
|
108 /* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
|
rlm@1
|
109 if (methodName.IsEmpty())
|
rlm@1
|
110 methodName = ConvertMethodIdToString(id);
|
rlm@1
|
111 if (!resString.IsEmpty())
|
rlm@1
|
112 resString += L' ';
|
rlm@1
|
113 resString += methodName;
|
rlm@1
|
114 }
|
rlm@1
|
115 prop = resString;
|
rlm@1
|
116 break;
|
rlm@1
|
117 }
|
rlm@1
|
118 case kpidSolid: prop = _db.IsSolid(); break;
|
rlm@1
|
119 case kpidNumBlocks: prop = (UInt32)_db.Folders.Size(); break;
|
rlm@1
|
120 case kpidHeadersSize: prop = _db.HeadersSize; break;
|
rlm@1
|
121 case kpidPhySize: prop = _db.PhySize; break;
|
rlm@1
|
122 case kpidOffset: if (_db.ArchiveInfo.StartPosition != 0) prop = _db.ArchiveInfo.StartPosition; break;
|
rlm@1
|
123 }
|
rlm@1
|
124 prop.Detach(value);
|
rlm@1
|
125 return S_OK;
|
rlm@1
|
126 COM_TRY_END
|
rlm@1
|
127 }
|
rlm@1
|
128
|
rlm@1
|
129 IMP_IInArchive_ArcProps
|
rlm@1
|
130
|
rlm@1
|
131 #endif
|
rlm@1
|
132
|
rlm@1
|
133 static void SetPropFromUInt64Def(CUInt64DefVector &v, int index, NCOM::CPropVariant &prop)
|
rlm@1
|
134 {
|
rlm@1
|
135 UInt64 value;
|
rlm@1
|
136 if (v.GetItem(index, value))
|
rlm@1
|
137 {
|
rlm@1
|
138 FILETIME ft;
|
rlm@1
|
139 ft.dwLowDateTime = (DWORD)value;
|
rlm@1
|
140 ft.dwHighDateTime = (DWORD)(value >> 32);
|
rlm@1
|
141 prop = ft;
|
rlm@1
|
142 }
|
rlm@1
|
143 }
|
rlm@1
|
144
|
rlm@1
|
145 #ifndef _SFX
|
rlm@1
|
146
|
rlm@1
|
147 static UString ConvertUInt32ToString(UInt32 value)
|
rlm@1
|
148 {
|
rlm@1
|
149 wchar_t buffer[32];
|
rlm@1
|
150 ConvertUInt64ToString(value, buffer);
|
rlm@1
|
151 return buffer;
|
rlm@1
|
152 }
|
rlm@1
|
153
|
rlm@1
|
154 static UString GetStringForSizeValue(UInt32 value)
|
rlm@1
|
155 {
|
rlm@1
|
156 for (int i = 31; i >= 0; i--)
|
rlm@1
|
157 if ((UInt32(1) << i) == value)
|
rlm@1
|
158 return ConvertUInt32ToString(i);
|
rlm@1
|
159 UString result;
|
rlm@1
|
160 if (value % (1 << 20) == 0)
|
rlm@1
|
161 {
|
rlm@1
|
162 result += ConvertUInt32ToString(value >> 20);
|
rlm@1
|
163 result += L"m";
|
rlm@1
|
164 }
|
rlm@1
|
165 else if (value % (1 << 10) == 0)
|
rlm@1
|
166 {
|
rlm@1
|
167 result += ConvertUInt32ToString(value >> 10);
|
rlm@1
|
168 result += L"k";
|
rlm@1
|
169 }
|
rlm@1
|
170 else
|
rlm@1
|
171 {
|
rlm@1
|
172 result += ConvertUInt32ToString(value);
|
rlm@1
|
173 result += L"b";
|
rlm@1
|
174 }
|
rlm@1
|
175 return result;
|
rlm@1
|
176 }
|
rlm@1
|
177
|
rlm@1
|
178 static const UInt64 k_Copy = 0x0;
|
rlm@1
|
179 static const UInt64 k_LZMA = 0x030101;
|
rlm@1
|
180 static const UInt64 k_PPMD = 0x030401;
|
rlm@1
|
181
|
rlm@1
|
182 static wchar_t GetHex(Byte value)
|
rlm@1
|
183 {
|
rlm@1
|
184 return (wchar_t)((value < 10) ? (L'0' + value) : (L'A' + (value - 10)));
|
rlm@1
|
185 }
|
rlm@1
|
186 static inline UString GetHex2(Byte value)
|
rlm@1
|
187 {
|
rlm@1
|
188 UString result;
|
rlm@1
|
189 result += GetHex((Byte)(value >> 4));
|
rlm@1
|
190 result += GetHex((Byte)(value & 0xF));
|
rlm@1
|
191 return result;
|
rlm@1
|
192 }
|
rlm@1
|
193
|
rlm@1
|
194 #endif
|
rlm@1
|
195
|
rlm@1
|
196 static const UInt64 k_AES = 0x06F10701;
|
rlm@1
|
197
|
rlm@1
|
198 bool CHandler::IsEncrypted(UInt32 index2) const
|
rlm@1
|
199 {
|
rlm@1
|
200 CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
rlm@1
|
201 if (folderIndex != kNumNoIndex)
|
rlm@1
|
202 {
|
rlm@1
|
203 const CFolder &folderInfo = _db.Folders[folderIndex];
|
rlm@1
|
204 for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
rlm@1
|
205 if (folderInfo.Coders[i].MethodID == k_AES)
|
rlm@1
|
206 return true;
|
rlm@1
|
207 }
|
rlm@1
|
208 return false;
|
rlm@1
|
209 }
|
rlm@1
|
210
|
rlm@1
|
211 STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
rlm@1
|
212 {
|
rlm@1
|
213 COM_TRY_BEGIN
|
rlm@1
|
214 NCOM::CPropVariant prop;
|
rlm@1
|
215
|
rlm@1
|
216 /*
|
rlm@1
|
217 const CRef2 &ref2 = _refs[index];
|
rlm@1
|
218 if (ref2.Refs.IsEmpty())
|
rlm@1
|
219 return E_FAIL;
|
rlm@1
|
220 const CRef &ref = ref2.Refs.Front();
|
rlm@1
|
221 */
|
rlm@1
|
222
|
rlm@1
|
223 const CFileItem &item = _db.Files[index];
|
rlm@1
|
224 UInt32 index2 = index;
|
rlm@1
|
225
|
rlm@1
|
226 switch(propID)
|
rlm@1
|
227 {
|
rlm@1
|
228 case kpidPath:
|
rlm@1
|
229 if (!item.Name.IsEmpty())
|
rlm@1
|
230 prop = NItemName::GetOSName(item.Name);
|
rlm@1
|
231 break;
|
rlm@1
|
232 case kpidIsDir: prop = item.IsDir; break;
|
rlm@1
|
233 case kpidSize:
|
rlm@1
|
234 {
|
rlm@1
|
235 prop = item.Size;
|
rlm@1
|
236 // prop = ref2.Size;
|
rlm@1
|
237 break;
|
rlm@1
|
238 }
|
rlm@1
|
239 case kpidPackSize:
|
rlm@1
|
240 {
|
rlm@1
|
241 // prop = ref2.PackSize;
|
rlm@1
|
242 {
|
rlm@1
|
243 CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
rlm@1
|
244 if (folderIndex != kNumNoIndex)
|
rlm@1
|
245 {
|
rlm@1
|
246 if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2)
|
rlm@1
|
247 prop = _db.GetFolderFullPackSize(folderIndex);
|
rlm@1
|
248 /*
|
rlm@1
|
249 else
|
rlm@1
|
250 prop = (UInt64)0;
|
rlm@1
|
251 */
|
rlm@1
|
252 }
|
rlm@1
|
253 else
|
rlm@1
|
254 prop = (UInt64)0;
|
rlm@1
|
255 }
|
rlm@1
|
256 break;
|
rlm@1
|
257 }
|
rlm@1
|
258 case kpidPosition: { UInt64 v; if (_db.StartPos.GetItem(index2, v)) prop = v; break; }
|
rlm@1
|
259 case kpidCTime: SetPropFromUInt64Def(_db.CTime, index2, prop); break;
|
rlm@1
|
260 case kpidATime: SetPropFromUInt64Def(_db.ATime, index2, prop); break;
|
rlm@1
|
261 case kpidMTime: SetPropFromUInt64Def(_db.MTime, index2, prop); break;
|
rlm@1
|
262 case kpidAttrib: if (item.AttribDefined) prop = item.Attrib; break;
|
rlm@1
|
263 case kpidCRC: if (item.CrcDefined) prop = item.Crc; break;
|
rlm@1
|
264 case kpidEncrypted: prop = IsEncrypted(index2); break;
|
rlm@1
|
265 case kpidIsAnti: prop = _db.IsItemAnti(index2); break;
|
rlm@1
|
266 #ifndef _SFX
|
rlm@1
|
267 case kpidMethod:
|
rlm@1
|
268 {
|
rlm@1
|
269 CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
rlm@1
|
270 if (folderIndex != kNumNoIndex)
|
rlm@1
|
271 {
|
rlm@1
|
272 const CFolder &folderInfo = _db.Folders[folderIndex];
|
rlm@1
|
273 UString methodsString;
|
rlm@1
|
274 for (int i = folderInfo.Coders.Size() - 1; i >= 0; i--)
|
rlm@1
|
275 {
|
rlm@1
|
276 const CCoderInfo &coderInfo = folderInfo.Coders[i];
|
rlm@1
|
277 if (!methodsString.IsEmpty())
|
rlm@1
|
278 methodsString += L' ';
|
rlm@1
|
279
|
rlm@1
|
280 {
|
rlm@1
|
281 UString methodName;
|
rlm@1
|
282 bool methodIsKnown = FindMethod(
|
rlm@1
|
283 EXTERNAL_CODECS_VARS
|
rlm@1
|
284 coderInfo.MethodID, methodName);
|
rlm@1
|
285
|
rlm@1
|
286 if (methodIsKnown)
|
rlm@1
|
287 {
|
rlm@1
|
288 methodsString += methodName;
|
rlm@1
|
289 if (coderInfo.MethodID == k_LZMA)
|
rlm@1
|
290 {
|
rlm@1
|
291 if (coderInfo.Props.GetCapacity() >= 5)
|
rlm@1
|
292 {
|
rlm@1
|
293 methodsString += L":";
|
rlm@1
|
294 UInt32 dicSize = GetUi32((const Byte *)coderInfo.Props + 1);
|
rlm@1
|
295 methodsString += GetStringForSizeValue(dicSize);
|
rlm@1
|
296 }
|
rlm@1
|
297 }
|
rlm@1
|
298 else if (coderInfo.MethodID == k_PPMD)
|
rlm@1
|
299 {
|
rlm@1
|
300 if (coderInfo.Props.GetCapacity() >= 5)
|
rlm@1
|
301 {
|
rlm@1
|
302 Byte order = *(const Byte *)coderInfo.Props;
|
rlm@1
|
303 methodsString += L":o";
|
rlm@1
|
304 methodsString += ConvertUInt32ToString(order);
|
rlm@1
|
305 methodsString += L":mem";
|
rlm@1
|
306 UInt32 dicSize = GetUi32((const Byte *)coderInfo.Props + 1);
|
rlm@1
|
307 methodsString += GetStringForSizeValue(dicSize);
|
rlm@1
|
308 }
|
rlm@1
|
309 }
|
rlm@1
|
310 else if (coderInfo.MethodID == k_AES)
|
rlm@1
|
311 {
|
rlm@1
|
312 if (coderInfo.Props.GetCapacity() >= 1)
|
rlm@1
|
313 {
|
rlm@1
|
314 methodsString += L":";
|
rlm@1
|
315 const Byte *data = (const Byte *)coderInfo.Props;
|
rlm@1
|
316 Byte firstByte = *data++;
|
rlm@1
|
317 UInt32 numCyclesPower = firstByte & 0x3F;
|
rlm@1
|
318 methodsString += ConvertUInt32ToString(numCyclesPower);
|
rlm@1
|
319 /*
|
rlm@1
|
320 if ((firstByte & 0xC0) != 0)
|
rlm@1
|
321 {
|
rlm@1
|
322 methodsString += L":";
|
rlm@1
|
323 return S_OK;
|
rlm@1
|
324 UInt32 saltSize = (firstByte >> 7) & 1;
|
rlm@1
|
325 UInt32 ivSize = (firstByte >> 6) & 1;
|
rlm@1
|
326 if (coderInfo.Props.GetCapacity() >= 2)
|
rlm@1
|
327 {
|
rlm@1
|
328 Byte secondByte = *data++;
|
rlm@1
|
329 saltSize += (secondByte >> 4);
|
rlm@1
|
330 ivSize += (secondByte & 0x0F);
|
rlm@1
|
331 }
|
rlm@1
|
332 }
|
rlm@1
|
333 */
|
rlm@1
|
334 }
|
rlm@1
|
335 }
|
rlm@1
|
336 else
|
rlm@1
|
337 {
|
rlm@1
|
338 if (coderInfo.Props.GetCapacity() > 0)
|
rlm@1
|
339 {
|
rlm@1
|
340 methodsString += L":[";
|
rlm@1
|
341 for (size_t bi = 0; bi < coderInfo.Props.GetCapacity(); bi++)
|
rlm@1
|
342 {
|
rlm@1
|
343 if (bi > 5 && bi + 1 < coderInfo.Props.GetCapacity())
|
rlm@1
|
344 {
|
rlm@1
|
345 methodsString += L"..";
|
rlm@1
|
346 break;
|
rlm@1
|
347 }
|
rlm@1
|
348 else
|
rlm@1
|
349 methodsString += GetHex2(coderInfo.Props[bi]);
|
rlm@1
|
350 }
|
rlm@1
|
351 methodsString += L"]";
|
rlm@1
|
352 }
|
rlm@1
|
353 }
|
rlm@1
|
354 }
|
rlm@1
|
355 else
|
rlm@1
|
356 {
|
rlm@1
|
357 methodsString += ConvertMethodIdToString(coderInfo.MethodID);
|
rlm@1
|
358 }
|
rlm@1
|
359 }
|
rlm@1
|
360 }
|
rlm@1
|
361 prop = methodsString;
|
rlm@1
|
362 }
|
rlm@1
|
363 }
|
rlm@1
|
364 break;
|
rlm@1
|
365 case kpidBlock:
|
rlm@1
|
366 {
|
rlm@1
|
367 CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
rlm@1
|
368 if (folderIndex != kNumNoIndex)
|
rlm@1
|
369 prop = (UInt32)folderIndex;
|
rlm@1
|
370 }
|
rlm@1
|
371 break;
|
rlm@1
|
372 case kpidPackedSize0:
|
rlm@1
|
373 case kpidPackedSize1:
|
rlm@1
|
374 case kpidPackedSize2:
|
rlm@1
|
375 case kpidPackedSize3:
|
rlm@1
|
376 case kpidPackedSize4:
|
rlm@1
|
377 {
|
rlm@1
|
378 CNum folderIndex = _db.FileIndexToFolderIndexMap[index2];
|
rlm@1
|
379 if (folderIndex != kNumNoIndex)
|
rlm@1
|
380 {
|
rlm@1
|
381 const CFolder &folderInfo = _db.Folders[folderIndex];
|
rlm@1
|
382 if (_db.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
|
rlm@1
|
383 folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
|
rlm@1
|
384 {
|
rlm@1
|
385 prop = _db.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
|
rlm@1
|
386 }
|
rlm@1
|
387 else
|
rlm@1
|
388 prop = (UInt64)0;
|
rlm@1
|
389 }
|
rlm@1
|
390 else
|
rlm@1
|
391 prop = (UInt64)0;
|
rlm@1
|
392 }
|
rlm@1
|
393 break;
|
rlm@1
|
394 #endif
|
rlm@1
|
395 }
|
rlm@1
|
396 prop.Detach(value);
|
rlm@1
|
397 return S_OK;
|
rlm@1
|
398 COM_TRY_END
|
rlm@1
|
399 }
|
rlm@1
|
400
|
rlm@1
|
401 STDMETHODIMP CHandler::Open(IInStream *stream,
|
rlm@1
|
402 const UInt64 *maxCheckStartPosition,
|
rlm@1
|
403 IArchiveOpenCallback *openArchiveCallback)
|
rlm@1
|
404 {
|
rlm@1
|
405 COM_TRY_BEGIN
|
rlm@1
|
406 Close();
|
rlm@1
|
407 #ifndef _SFX
|
rlm@1
|
408 _fileInfoPopIDs.Clear();
|
rlm@1
|
409 #endif
|
rlm@1
|
410 try
|
rlm@1
|
411 {
|
rlm@1
|
412 CMyComPtr<IArchiveOpenCallback> openArchiveCallbackTemp = openArchiveCallback;
|
rlm@1
|
413
|
rlm@1
|
414 #ifndef _NO_CRYPTO
|
rlm@1
|
415 CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
rlm@1
|
416 if (openArchiveCallback)
|
rlm@1
|
417 {
|
rlm@1
|
418 openArchiveCallbackTemp.QueryInterface(
|
rlm@1
|
419 IID_ICryptoGetTextPassword, &getTextPassword);
|
rlm@1
|
420 }
|
rlm@1
|
421 #endif
|
rlm@1
|
422 CInArchive archive;
|
rlm@1
|
423 RINOK(archive.Open(stream, maxCheckStartPosition));
|
rlm@1
|
424 #ifndef _NO_CRYPTO
|
rlm@1
|
425 _passwordIsDefined = false;
|
rlm@1
|
426 UString password;
|
rlm@1
|
427 #endif
|
rlm@1
|
428 HRESULT result = archive.ReadDatabase(
|
rlm@1
|
429 EXTERNAL_CODECS_VARS
|
rlm@1
|
430 _db
|
rlm@1
|
431 #ifndef _NO_CRYPTO
|
rlm@1
|
432 , getTextPassword, _passwordIsDefined
|
rlm@1
|
433 #endif
|
rlm@1
|
434 );
|
rlm@1
|
435 RINOK(result);
|
rlm@1
|
436 _db.Fill();
|
rlm@1
|
437 _inStream = stream;
|
rlm@1
|
438 }
|
rlm@1
|
439 catch(...)
|
rlm@1
|
440 {
|
rlm@1
|
441 Close();
|
rlm@1
|
442 return S_FALSE;
|
rlm@1
|
443 }
|
rlm@1
|
444 // _inStream = stream;
|
rlm@1
|
445 #ifndef _SFX
|
rlm@1
|
446 FillPopIDs();
|
rlm@1
|
447 #endif
|
rlm@1
|
448 return S_OK;
|
rlm@1
|
449 COM_TRY_END
|
rlm@1
|
450 }
|
rlm@1
|
451
|
rlm@1
|
452 STDMETHODIMP CHandler::Close()
|
rlm@1
|
453 {
|
rlm@1
|
454 COM_TRY_BEGIN
|
rlm@1
|
455 _inStream.Release();
|
rlm@1
|
456 _db.Clear();
|
rlm@1
|
457 return S_OK;
|
rlm@1
|
458 COM_TRY_END
|
rlm@1
|
459 }
|
rlm@1
|
460
|
rlm@1
|
461 #ifdef __7Z_SET_PROPERTIES
|
rlm@1
|
462 #ifdef EXTRACT_ONLY
|
rlm@1
|
463
|
rlm@1
|
464 STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
|
rlm@1
|
465 {
|
rlm@1
|
466 COM_TRY_BEGIN
|
rlm@1
|
467 #ifdef COMPRESS_MT
|
rlm@1
|
468 const UInt32 numProcessors = NSystem::GetNumberOfProcessors();
|
rlm@1
|
469 _numThreads = numProcessors;
|
rlm@1
|
470 #endif
|
rlm@1
|
471
|
rlm@1
|
472 for (int i = 0; i < numProperties; i++)
|
rlm@1
|
473 {
|
rlm@1
|
474 UString name = names[i];
|
rlm@1
|
475 name.MakeUpper();
|
rlm@1
|
476 if (name.IsEmpty())
|
rlm@1
|
477 return E_INVALIDARG;
|
rlm@1
|
478 const PROPVARIANT &value = values[i];
|
rlm@1
|
479 UInt32 number;
|
rlm@1
|
480 int index = ParseStringToUInt32(name, number);
|
rlm@1
|
481 if (index == 0)
|
rlm@1
|
482 {
|
rlm@1
|
483 if(name.Left(2).CompareNoCase(L"MT") == 0)
|
rlm@1
|
484 {
|
rlm@1
|
485 #ifdef COMPRESS_MT
|
rlm@1
|
486 RINOK(ParseMtProp(name.Mid(2), value, numProcessors, _numThreads));
|
rlm@1
|
487 #endif
|
rlm@1
|
488 continue;
|
rlm@1
|
489 }
|
rlm@1
|
490 else
|
rlm@1
|
491 return E_INVALIDARG;
|
rlm@1
|
492 }
|
rlm@1
|
493 }
|
rlm@1
|
494 return S_OK;
|
rlm@1
|
495 COM_TRY_END
|
rlm@1
|
496 }
|
rlm@1
|
497
|
rlm@1
|
498 #endif
|
rlm@1
|
499 #endif
|
rlm@1
|
500
|
rlm@1
|
501 IMPL_ISetCompressCodecsInfo
|
rlm@1
|
502
|
rlm@1
|
503 }}
|