Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: third_party/lzma/v4_65/files/CPP/7zip/UI/Common/OpenArchive.cpp

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // OpenArchive.cpp
2
3 #include "StdAfx.h"
4
5 #include "OpenArchive.h"
6
7 #include "Common/Wildcard.h"
8
9 #include "Windows/FileName.h"
10 #include "Windows/FileDir.h"
11 #include "Windows/Defs.h"
12 #include "Windows/PropVariant.h"
13
14 #include "../../Common/FileStreams.h"
15 #include "../../Common/StreamUtils.h"
16
17 #include "Common/StringConvert.h"
18
19 #include "DefaultName.h"
20
21 using namespace NWindows;
22
23 HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, UString &result)
24 {
25 NCOM::CPropVariant prop;
26 RINOK(archive->GetProperty(index, kpidPath, &prop));
27 if(prop.vt == VT_BSTR)
28 result = prop.bstrVal;
29 else if (prop.vt == VT_EMPTY)
30 result.Empty();
31 else
32 return E_FAIL;
33 return S_OK;
34 }
35
36 HRESULT GetArchiveItemPath(IInArchive *archive, UInt32 index, const UString &def aultName, UString &result)
37 {
38 RINOK(GetArchiveItemPath(archive, index, result));
39 if (result.IsEmpty())
40 {
41 result = defaultName;
42 NCOM::CPropVariant prop;
43 RINOK(archive->GetProperty(index, kpidExtension, &prop));
44 if (prop.vt == VT_BSTR)
45 {
46 result += L'.';
47 result += prop.bstrVal;
48 }
49 else if (prop.vt != VT_EMPTY)
50 return E_FAIL;
51 }
52 return S_OK;
53 }
54
55 HRESULT GetArchiveItemFileTime(IInArchive *archive, UInt32 index,
56 const FILETIME &defaultFileTime, FILETIME &fileTime)
57 {
58 NCOM::CPropVariant prop;
59 RINOK(archive->GetProperty(index, kpidMTime, &prop));
60 if (prop.vt == VT_FILETIME)
61 fileTime = prop.filetime;
62 else if (prop.vt == VT_EMPTY)
63 fileTime = defaultFileTime;
64 else
65 return E_FAIL;
66 return S_OK;
67 }
68
69 HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
70 {
71 NCOM::CPropVariant prop;
72 RINOK(archive->GetProperty(index, propID, &prop));
73 if(prop.vt == VT_BOOL)
74 result = VARIANT_BOOLToBool(prop.boolVal);
75 else if (prop.vt == VT_EMPTY)
76 result = false;
77 else
78 return E_FAIL;
79 return S_OK;
80 }
81
82 HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
83 {
84 return IsArchiveItemProp(archive, index, kpidIsDir, result);
85 }
86
87 HRESULT IsArchiveItemAnti(IInArchive *archive, UInt32 index, bool &result)
88 {
89 return IsArchiveItemProp(archive, index, kpidIsAnti, result);
90 }
91
92 // Static-SFX (for Linux) can be big.
93 const UInt64 kMaxCheckStartPosition = 1 << 22;
94
95 HRESULT ReOpenArchive(IInArchive *archive, const UString &fileName, IArchiveOpen Callback *openArchiveCallback)
96 {
97 CInFileStream *inStreamSpec = new CInFileStream;
98 CMyComPtr<IInStream> inStream(inStreamSpec);
99 inStreamSpec->Open(fileName);
100 return archive->Open(inStream, &kMaxCheckStartPosition, openArchiveCallback);
101 }
102
103 #ifndef _SFX
104 static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
105 {
106 for (size_t i = 0; i < size; i++)
107 if (p1[i] != p2[i])
108 return false;
109 return true;
110 }
111 #endif
112
113 HRESULT OpenArchive(
114 CCodecs *codecs,
115 int arcTypeIndex,
116 IInStream *inStream,
117 const UString &fileName,
118 IInArchive **archiveResult,
119 int &formatIndex,
120 UString &defaultItemName,
121 IArchiveOpenCallback *openArchiveCallback)
122 {
123 *archiveResult = NULL;
124 UString extension;
125 {
126 int dotPos = fileName.ReverseFind(L'.');
127 if (dotPos >= 0)
128 extension = fileName.Mid(dotPos + 1);
129 }
130 CIntVector orderIndices;
131 if (arcTypeIndex >= 0)
132 orderIndices.Add(arcTypeIndex);
133 else
134 {
135
136 int i;
137 int numFinded = 0;
138 for (i = 0; i < codecs->Formats.Size(); i++)
139 if (codecs->Formats[i].FindExtension(extension) >= 0)
140 orderIndices.Insert(numFinded++, i);
141 else
142 orderIndices.Add(i);
143
144 #ifndef _SFX
145 if (numFinded != 1)
146 {
147 CIntVector orderIndices2;
148 CByteBuffer byteBuffer;
149 const size_t kBufferSize = (1 << 21);
150 byteBuffer.SetCapacity(kBufferSize);
151 RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
152 size_t processedSize = kBufferSize;
153 RINOK(ReadStream(inStream, byteBuffer, &processedSize));
154 if (processedSize == 0)
155 return S_FALSE;
156
157 const Byte *buf = byteBuffer;
158 Byte hash[1 << 16];
159 memset(hash, 0xFF, 1 << 16);
160 Byte prevs[256];
161 if (orderIndices.Size() > 255)
162 return S_FALSE;
163 int i;
164 for (i = 0; i < orderIndices.Size(); i++)
165 {
166 const CArcInfoEx &ai = codecs->Formats[orderIndices[i]];
167 const CByteBuffer &sig = ai.StartSignature;
168 if (sig.GetCapacity() < 2)
169 continue;
170 UInt32 v = sig[0] | ((UInt32)sig[1] << 8);
171 prevs[i] = hash[v];
172 hash[v] = (Byte)i;
173 }
174
175 processedSize--;
176 for (UInt32 pos = 0; pos < processedSize; pos++)
177 {
178 for (; pos < processedSize && hash[buf[pos] | ((UInt32)buf[pos + 1] << 8)] == 0xFF; pos++);
179 if (pos == processedSize)
180 break;
181 UInt32 v = buf[pos] | ((UInt32)buf[pos + 1] << 8);
182 Byte *ptr = &hash[v];
183 int i = *ptr;
184 do
185 {
186 int index = orderIndices[i];
187 const CArcInfoEx &ai = codecs->Formats[index];
188 const CByteBuffer &sig = ai.StartSignature;
189 if (sig.GetCapacity() != 0 && pos + sig.GetCapacity() <= processedSize + 1)
190 if (TestSignature(buf + pos, sig, sig.GetCapacity()))
191 {
192 orderIndices2.Add(index);
193 orderIndices[i] = 0xFF;
194 *ptr = prevs[i];
195 }
196 ptr = &prevs[i];
197 i = *ptr;
198 }
199 while (i != 0xFF);
200 }
201
202 for (i = 0; i < orderIndices.Size(); i++)
203 {
204 int val = orderIndices[i];
205 if (val != 0xFF)
206 orderIndices2.Add(val);
207 }
208 orderIndices = orderIndices2;
209
210 if (orderIndices.Size() >= 2)
211 {
212 int isoIndex = codecs->FindFormatForArchiveType(L"iso");
213 int udfIndex = codecs->FindFormatForArchiveType(L"udf");
214 int iIso = -1;
215 int iUdf = -1;
216 for (int i = 0; i < orderIndices.Size(); i++)
217 {
218 if (orderIndices[i] == isoIndex) iIso = i;
219 if (orderIndices[i] == udfIndex) iUdf = i;
220 }
221 if (iUdf == iIso + 1)
222 {
223 orderIndices[iUdf] = isoIndex;
224 orderIndices[iIso] = udfIndex;
225 }
226 }
227 }
228 else if (extension == L"000" || extension == L"001")
229 {
230 CByteBuffer byteBuffer;
231 const size_t kBufferSize = (1 << 10);
232 byteBuffer.SetCapacity(kBufferSize);
233 Byte *buffer = byteBuffer;
234 RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
235 size_t processedSize = kBufferSize;
236 RINOK(ReadStream(inStream, buffer, &processedSize));
237 if (processedSize >= 16)
238 {
239 Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00};
240 if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[1 0] & 1) != 0)
241 {
242 for (int i = 0; i < orderIndices.Size(); i++)
243 {
244 int index = orderIndices[i];
245 const CArcInfoEx &ai = codecs->Formats[index];
246 if (ai.Name.CompareNoCase(L"rar") != 0)
247 continue;
248 orderIndices.Delete(i--);
249 orderIndices.Insert(0, index);
250 break;
251 }
252 }
253 }
254 }
255 #endif
256 }
257
258 for(int i = 0; i < orderIndices.Size(); i++)
259 {
260 inStream->Seek(0, STREAM_SEEK_SET, NULL);
261
262 CMyComPtr<IInArchive> archive;
263
264 formatIndex = orderIndices[i];
265 RINOK(codecs->CreateInArchive(formatIndex, archive));
266 if (!archive)
267 continue;
268
269 #ifdef EXTERNAL_CODECS
270 {
271 CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
272 archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCo decsInfo);
273 if (setCompressCodecsInfo)
274 {
275 RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs));
276 }
277 }
278 #endif
279
280 HRESULT result = archive->Open(inStream, &kMaxCheckStartPosition, openArchiv eCallback);
281 if (result == S_FALSE)
282 continue;
283 RINOK(result);
284 *archiveResult = archive.Detach();
285 const CArcInfoEx &format = codecs->Formats[formatIndex];
286 if (format.Exts.Size() == 0)
287 {
288 defaultItemName = GetDefaultName2(fileName, L"", L"");
289 }
290 else
291 {
292 int subExtIndex = format.FindExtension(extension);
293 if (subExtIndex < 0)
294 subExtIndex = 0;
295 defaultItemName = GetDefaultName2(fileName,
296 format.Exts[subExtIndex].Ext,
297 format.Exts[subExtIndex].AddExt);
298 }
299 return S_OK;
300 }
301 return S_FALSE;
302 }
303
304 HRESULT OpenArchive(
305 CCodecs *codecs,
306 int arcTypeIndex,
307 const UString &filePath,
308 IInArchive **archiveResult,
309 int &formatIndex,
310 UString &defaultItemName,
311 IArchiveOpenCallback *openArchiveCallback)
312 {
313 CInFileStream *inStreamSpec = new CInFileStream;
314 CMyComPtr<IInStream> inStream(inStreamSpec);
315 if (!inStreamSpec->Open(filePath))
316 return GetLastError();
317 return OpenArchive(codecs, arcTypeIndex, inStream, ExtractFileNameFromPath(fil ePath),
318 archiveResult, formatIndex,
319 defaultItemName, openArchiveCallback);
320 }
321
322 static void MakeDefaultName(UString &name)
323 {
324 int dotPos = name.ReverseFind(L'.');
325 if (dotPos < 0)
326 return;
327 UString ext = name.Mid(dotPos + 1);
328 if (ext.IsEmpty())
329 return;
330 for (int pos = 0; pos < ext.Length(); pos++)
331 if (ext[pos] < L'0' || ext[pos] > L'9')
332 return;
333 name = name.Left(dotPos);
334 }
335
336 HRESULT OpenArchive(
337 CCodecs *codecs,
338 const CIntVector &formatIndices,
339 const UString &fileName,
340 IInArchive **archive0,
341 IInArchive **archive1,
342 int &formatIndex0,
343 int &formatIndex1,
344 UString &defaultItemName0,
345 UString &defaultItemName1,
346 IArchiveOpenCallback *openArchiveCallback)
347 {
348 if (formatIndices.Size() >= 3)
349 return E_NOTIMPL;
350
351 int arcTypeIndex = -1;
352 if (formatIndices.Size() >= 1)
353 arcTypeIndex = formatIndices[formatIndices.Size() - 1];
354
355 HRESULT result = OpenArchive(codecs, arcTypeIndex, fileName,
356 archive0, formatIndex0, defaultItemName0, openArchiveCallback);
357 RINOK(result);
358
359 if (formatIndices.Size() == 1)
360 return S_OK;
361 arcTypeIndex = -1;
362 if (formatIndices.Size() >= 2)
363 arcTypeIndex = formatIndices[formatIndices.Size() - 2];
364
365 HRESULT resSpec = (formatIndices.Size() == 0 ? S_OK : E_NOTIMPL);
366
367 CMyComPtr<IInArchiveGetStream> getStream;
368 result = (*archive0)->QueryInterface(IID_IInArchiveGetStream, (void **)&getStr eam);
369 if (result != S_OK || !getStream)
370 return resSpec;
371
372 CMyComPtr<ISequentialInStream> subSeqStream;
373 result = getStream->GetStream(0, &subSeqStream);
374 if (result != S_OK || !subSeqStream)
375 return resSpec;
376
377 CMyComPtr<IInStream> subStream;
378 result = subSeqStream.QueryInterface(IID_IInStream, &subStream);
379 if (result != S_OK || !subStream)
380 return resSpec;
381
382 UInt32 numItems;
383 RINOK((*archive0)->GetNumberOfItems(&numItems));
384 if (numItems < 1)
385 return resSpec;
386
387 UString subPath;
388 RINOK(GetArchiveItemPath(*archive0, 0, subPath))
389 if (subPath.IsEmpty())
390 {
391 MakeDefaultName(defaultItemName0);
392 subPath = defaultItemName0;
393 const CArcInfoEx &format = codecs->Formats[formatIndex0];
394 if (format.Name.CompareNoCase(L"7z") == 0)
395 {
396 if (subPath.Right(3).CompareNoCase(L".7z") != 0)
397 subPath += L".7z";
398 }
399 }
400 else
401 subPath = ExtractFileNameFromPath(subPath);
402
403 CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName;
404 openArchiveCallback->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void * *)&setSubArchiveName);
405 if (setSubArchiveName)
406 setSubArchiveName->SetSubArchiveName(subPath);
407
408 result = OpenArchive(codecs, arcTypeIndex, subStream, subPath,
409 archive1, formatIndex1, defaultItemName1, openArchiveCallback);
410 resSpec = (formatIndices.Size() == 0 ? S_OK : S_FALSE);
411 if (result != S_OK)
412 return resSpec;
413 return S_OK;
414 }
415
416 static void SetCallback(const UString &archiveName,
417 IOpenCallbackUI *openCallbackUI,
418 IArchiveOpenCallback *reOpenCallback,
419 CMyComPtr<IArchiveOpenCallback> &openCallback)
420 {
421 COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
422 openCallback = openCallbackSpec;
423 openCallbackSpec->Callback = openCallbackUI;
424 openCallbackSpec->ReOpenCallback = reOpenCallback;
425
426 UString fullName;
427 int fileNamePartStartIndex;
428 NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartI ndex);
429 openCallbackSpec->Init(
430 fullName.Left(fileNamePartStartIndex),
431 fullName.Mid(fileNamePartStartIndex));
432 }
433
434 HRESULT MyOpenArchive(
435 CCodecs *codecs,
436 int arcTypeIndex,
437 const UString &archiveName,
438 IInArchive **archive, UString &defaultItemName, IOpenCallbackUI *openCallbac kUI)
439 {
440 CMyComPtr<IArchiveOpenCallback> openCallback;
441 SetCallback(archiveName, openCallbackUI, NULL, openCallback);
442 int formatInfo;
443 return OpenArchive(codecs, arcTypeIndex, archiveName, archive, formatInfo, def aultItemName, openCallback);
444 }
445
446 HRESULT MyOpenArchive(
447 CCodecs *codecs,
448 const CIntVector &formatIndices,
449 const UString &archiveName,
450 IInArchive **archive0,
451 IInArchive **archive1,
452 UString &defaultItemName0,
453 UString &defaultItemName1,
454 UStringVector &volumePaths,
455 UInt64 &volumesSize,
456 IOpenCallbackUI *openCallbackUI)
457 {
458 volumesSize = 0;
459 COpenCallbackImp *openCallbackSpec = new COpenCallbackImp;
460 CMyComPtr<IArchiveOpenCallback> openCallback = openCallbackSpec;
461 openCallbackSpec->Callback = openCallbackUI;
462
463 UString fullName;
464 int fileNamePartStartIndex;
465 NFile::NDirectory::MyGetFullPathName(archiveName, fullName, fileNamePartStartI ndex);
466 UString prefix = fullName.Left(fileNamePartStartIndex);
467 UString name = fullName.Mid(fileNamePartStartIndex);
468 openCallbackSpec->Init(prefix, name);
469
470 int formatIndex0, formatIndex1;
471 RINOK(OpenArchive(codecs, formatIndices, archiveName,
472 archive0,
473 archive1,
474 formatIndex0,
475 formatIndex1,
476 defaultItemName0,
477 defaultItemName1,
478 openCallback));
479 volumePaths.Add(prefix + name);
480 for (int i = 0; i < openCallbackSpec->FileNames.Size(); i++)
481 volumePaths.Add(prefix + openCallbackSpec->FileNames[i]);
482 volumesSize = openCallbackSpec->TotalSize;
483 return S_OK;
484 }
485
486 HRESULT CArchiveLink::Close()
487 {
488 if (Archive1 != 0)
489 RINOK(Archive1->Close());
490 if (Archive0 != 0)
491 RINOK(Archive0->Close());
492 IsOpen = false;
493 return S_OK;
494 }
495
496 void CArchiveLink::Release()
497 {
498 IsOpen = false;
499 Archive1.Release();
500 Archive0.Release();
501 }
502
503 HRESULT OpenArchive(
504 CCodecs *codecs,
505 const CIntVector &formatIndices,
506 const UString &archiveName,
507 CArchiveLink &archiveLink,
508 IArchiveOpenCallback *openCallback)
509 {
510 HRESULT res = OpenArchive(codecs, formatIndices, archiveName,
511 &archiveLink.Archive0, &archiveLink.Archive1,
512 archiveLink.FormatIndex0, archiveLink.FormatIndex1,
513 archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
514 openCallback);
515 archiveLink.IsOpen = (res == S_OK);
516 return res;
517 }
518
519 HRESULT MyOpenArchive(CCodecs *codecs,
520 const CIntVector &formatIndices,
521 const UString &archiveName,
522 CArchiveLink &archiveLink,
523 IOpenCallbackUI *openCallbackUI)
524 {
525 HRESULT res = MyOpenArchive(codecs, formatIndices, archiveName,
526 &archiveLink.Archive0, &archiveLink.Archive1,
527 archiveLink.DefaultItemName0, archiveLink.DefaultItemName1,
528 archiveLink.VolumePaths,
529 archiveLink.VolumesSize,
530 openCallbackUI);
531 archiveLink.IsOpen = (res == S_OK);
532 return res;
533 }
534
535 HRESULT ReOpenArchive(CCodecs *codecs, CArchiveLink &archiveLink, const UString &fileName,
536 IArchiveOpenCallback *openCallback)
537 {
538 if (archiveLink.GetNumLevels() > 1)
539 return E_NOTIMPL;
540
541 if (archiveLink.GetNumLevels() == 0)
542 return MyOpenArchive(codecs, CIntVector(), fileName, archiveLink, 0);
543
544 CMyComPtr<IArchiveOpenCallback> openCallbackNew;
545 SetCallback(fileName, NULL, openCallback, openCallbackNew);
546
547 HRESULT res = ReOpenArchive(archiveLink.GetArchive(), fileName, openCallbackNe w);
548 archiveLink.IsOpen = (res == S_OK);
549 return res;
550 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698