diff options
Diffstat (limited to '')
-rw-r--r-- | CPP/7zip/Archive/Wim/WimHandlerOut.cpp | 450 |
1 files changed, 263 insertions, 187 deletions
diff --git a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp index 5e8365a..5d9dea2 100644 --- a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp +++ b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp | |||
@@ -27,8 +27,25 @@ using namespace NWindows; | |||
27 | namespace NArchive { | 27 | namespace NArchive { |
28 | namespace NWim { | 28 | namespace NWim { |
29 | 29 | ||
30 | static int AddUniqHash(const CStreamInfo *streams, CUIntVector &sorted, const Byte *h, int streamIndexForInsert) | 30 | static const unsigned k_NumSubVectors_Bits = 12; // must be <= 16 |
31 | |||
32 | struct CSortedIndex | ||
33 | { | ||
34 | CObjectVector<CUIntVector> Vectors; | ||
35 | |||
36 | CSortedIndex() | ||
37 | { | ||
38 | const unsigned k_NumSubVectors = 1 << k_NumSubVectors_Bits; | ||
39 | Vectors.ClearAndReserve(k_NumSubVectors); | ||
40 | for (unsigned i = 0; i < k_NumSubVectors; i++) | ||
41 | Vectors.AddNew(); | ||
42 | } | ||
43 | }; | ||
44 | |||
45 | static int AddUniqHash(const CStreamInfo *streams, CSortedIndex &sorted2, const Byte *h, int streamIndexForInsert) | ||
31 | { | 46 | { |
47 | const unsigned hash = (((unsigned)h[0] << 8) | (unsigned)h[1]) >> (16 - k_NumSubVectors_Bits); | ||
48 | CUIntVector &sorted = sorted2.Vectors[hash]; | ||
32 | unsigned left = 0, right = sorted.Size(); | 49 | unsigned left = 0, right = sorted.Size(); |
33 | while (left != right) | 50 | while (left != right) |
34 | { | 51 | { |
@@ -42,7 +59,7 @@ static int AddUniqHash(const CStreamInfo *streams, CUIntVector &sorted, const By | |||
42 | break; | 59 | break; |
43 | 60 | ||
44 | if (i == kHashSize) | 61 | if (i == kHashSize) |
45 | return index; | 62 | return (int)index; |
46 | 63 | ||
47 | if (h[i] < hash2[i]) | 64 | if (h[i] < hash2[i]) |
48 | right = mid; | 65 | right = mid; |
@@ -50,8 +67,8 @@ static int AddUniqHash(const CStreamInfo *streams, CUIntVector &sorted, const By | |||
50 | left = mid + 1; | 67 | left = mid + 1; |
51 | } | 68 | } |
52 | 69 | ||
53 | if (streamIndexForInsert >= 0) | 70 | if (streamIndexForInsert != -1) |
54 | sorted.Insert(left, streamIndexForInsert); | 71 | sorted.Insert(left, (unsigned)streamIndexForInsert); |
55 | 72 | ||
56 | return -1; | 73 | return -1; |
57 | } | 74 | } |
@@ -78,13 +95,13 @@ struct CMetaItem | |||
78 | FILETIME CTime; | 95 | FILETIME CTime; |
79 | FILETIME ATime; | 96 | FILETIME ATime; |
80 | FILETIME MTime; | 97 | FILETIME MTime; |
81 | UInt32 Attrib; | ||
82 | UInt64 FileID; | 98 | UInt64 FileID; |
83 | UInt64 VolID; | 99 | UInt64 VolID; |
84 | 100 | ||
85 | UString Name; | 101 | UString Name; |
86 | UString ShortName; | 102 | UString ShortName; |
87 | 103 | ||
104 | UInt32 Attrib; | ||
88 | int SecurityId; // -1: means no secutity ID | 105 | int SecurityId; // -1: means no secutity ID |
89 | bool IsDir; | 106 | bool IsDir; |
90 | bool Skip; | 107 | bool Skip; |
@@ -97,12 +114,19 @@ struct CMetaItem | |||
97 | CMetaItem(): | 114 | CMetaItem(): |
98 | UpdateIndex(-1) | 115 | UpdateIndex(-1) |
99 | , HashIndex(-1) | 116 | , HashIndex(-1) |
117 | , Size(0) | ||
100 | , FileID(0) | 118 | , FileID(0) |
101 | , VolID(0) | 119 | , VolID(0) |
120 | , Attrib(0) | ||
102 | , SecurityId(-1) | 121 | , SecurityId(-1) |
122 | , IsDir(false) | ||
103 | , Skip(false) | 123 | , Skip(false) |
104 | , NumSkipAltStreams(0) | 124 | , NumSkipAltStreams(0) |
105 | {} | 125 | { |
126 | FILETIME_Clear(CTime); | ||
127 | FILETIME_Clear(ATime); | ||
128 | FILETIME_Clear(MTime); | ||
129 | } | ||
106 | }; | 130 | }; |
107 | 131 | ||
108 | 132 | ||
@@ -128,7 +152,7 @@ static int AddToHardLinkList(const CObjectVector<CMetaItem> &metaItems, unsigned | |||
128 | const unsigned index = indexes[mid]; | 152 | const unsigned index = indexes[mid]; |
129 | const int comp = Compare_HardLink_MetaItems(mi, metaItems[index]); | 153 | const int comp = Compare_HardLink_MetaItems(mi, metaItems[index]); |
130 | if (comp == 0) | 154 | if (comp == 0) |
131 | return index; | 155 | return (int)index; |
132 | if (comp < 0) | 156 | if (comp < 0) |
133 | right = mid; | 157 | right = mid; |
134 | else | 158 | else |
@@ -220,7 +244,7 @@ bool CDir::FindDir(const CObjectVector<CMetaItem> &items, const UString &name, u | |||
220 | } | 244 | } |
221 | 245 | ||
222 | 246 | ||
223 | STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) | 247 | Z7_COM7F_IMF(CHandler::GetFileTimeType(UInt32 *type)) |
224 | { | 248 | { |
225 | *type = NFileTimeType::kWindows; | 249 | *type = NFileTimeType::kWindows; |
226 | return S_OK; | 250 | return S_OK; |
@@ -229,8 +253,8 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type) | |||
229 | 253 | ||
230 | HRESULT CHandler::GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value) | 254 | HRESULT CHandler::GetOutProperty(IArchiveUpdateCallback *callback, UInt32 callbackIndex, Int32 arcIndex, PROPID propID, PROPVARIANT *value) |
231 | { | 255 | { |
232 | if (arcIndex >= 0) | 256 | if (arcIndex != -1) |
233 | return GetProperty(arcIndex, propID, value); | 257 | return GetProperty((UInt32)arcIndex, propID, value); |
234 | return callback->GetProperty(callbackIndex, propID, value); | 258 | return callback->GetProperty(callbackIndex, propID, value); |
235 | } | 259 | } |
236 | 260 | ||
@@ -239,7 +263,7 @@ HRESULT CHandler::GetTime(IArchiveUpdateCallback *callback, UInt32 callbackIndex | |||
239 | { | 263 | { |
240 | ft.dwLowDateTime = ft.dwHighDateTime = 0; | 264 | ft.dwLowDateTime = ft.dwHighDateTime = 0; |
241 | NCOM::CPropVariant prop; | 265 | NCOM::CPropVariant prop; |
242 | RINOK(GetOutProperty(callback, callbackIndex, arcIndex, propID, &prop)); | 266 | RINOK(GetOutProperty(callback, callbackIndex, arcIndex, propID, &prop)) |
243 | if (prop.vt == VT_FILETIME) | 267 | if (prop.vt == VT_FILETIME) |
244 | ft = prop.filetime; | 268 | ft = prop.filetime; |
245 | else if (prop.vt != VT_EMPTY) | 269 | else if (prop.vt != VT_EMPTY) |
@@ -256,7 +280,7 @@ static HRESULT GetRootTime( | |||
256 | NCOM::CPropVariant prop; | 280 | NCOM::CPropVariant prop; |
257 | if (callback) | 281 | if (callback) |
258 | { | 282 | { |
259 | RINOK(callback->GetRootProp(propID, &prop)); | 283 | RINOK(callback->GetRootProp(propID, &prop)) |
260 | if (prop.vt == VT_FILETIME) | 284 | if (prop.vt == VT_FILETIME) |
261 | { | 285 | { |
262 | ft = prop.filetime; | 286 | ft = prop.filetime; |
@@ -267,7 +291,7 @@ static HRESULT GetRootTime( | |||
267 | } | 291 | } |
268 | if (arcRoot) | 292 | if (arcRoot) |
269 | { | 293 | { |
270 | RINOK(arcRoot->GetRootProp(propID, &prop)); | 294 | RINOK(arcRoot->GetRootProp(propID, &prop)) |
271 | if (prop.vt == VT_FILETIME) | 295 | if (prop.vt == VT_FILETIME) |
272 | { | 296 | { |
273 | ft = prop.filetime; | 297 | ft = prop.filetime; |
@@ -285,29 +309,29 @@ static HRESULT GetRootTime( | |||
285 | 309 | ||
286 | void CResource::WriteTo(Byte *p) const | 310 | void CResource::WriteTo(Byte *p) const |
287 | { | 311 | { |
288 | Set64(p, PackSize); | 312 | Set64(p, PackSize) |
289 | p[7] = Flags; | 313 | p[7] = Flags; |
290 | Set64(p + 8, Offset); | 314 | Set64(p + 8, Offset) |
291 | Set64(p + 16, UnpackSize); | 315 | Set64(p + 16, UnpackSize) |
292 | } | 316 | } |
293 | 317 | ||
294 | 318 | ||
295 | void CHeader::WriteTo(Byte *p) const | 319 | void CHeader::WriteTo(Byte *p) const |
296 | { | 320 | { |
297 | memcpy(p, kSignature, kSignatureSize); | 321 | memcpy(p, kSignature, kSignatureSize); |
298 | Set32(p + 8, kHeaderSizeMax); | 322 | Set32(p + 8, kHeaderSizeMax) |
299 | Set32(p + 0xC, Version); | 323 | Set32(p + 0xC, Version) |
300 | Set32(p + 0x10, Flags); | 324 | Set32(p + 0x10, Flags) |
301 | Set32(p + 0x14, ChunkSize); | 325 | Set32(p + 0x14, ChunkSize) |
302 | memcpy(p + 0x18, Guid, 16); | 326 | memcpy(p + 0x18, Guid, 16); |
303 | Set16(p + 0x28, PartNumber); | 327 | Set16(p + 0x28, PartNumber) |
304 | Set16(p + 0x2A, NumParts); | 328 | Set16(p + 0x2A, NumParts) |
305 | Set32(p + 0x2C, NumImages); | 329 | Set32(p + 0x2C, NumImages) |
306 | OffsetResource.WriteTo(p + 0x30); | 330 | OffsetResource.WriteTo(p + 0x30); |
307 | XmlResource.WriteTo(p + 0x48); | 331 | XmlResource.WriteTo(p + 0x48); |
308 | MetadataResource.WriteTo(p + 0x60); | 332 | MetadataResource.WriteTo(p + 0x60); |
309 | IntegrityResource.WriteTo(p + 0x7C); | 333 | IntegrityResource.WriteTo(p + 0x7C); |
310 | Set32(p + 0x78, BootIndex); | 334 | Set32(p + 0x78, BootIndex) |
311 | memset(p + 0x94, 0, 60); | 335 | memset(p + 0x94, 0, 60); |
312 | } | 336 | } |
313 | 337 | ||
@@ -315,25 +339,22 @@ void CHeader::WriteTo(Byte *p) const | |||
315 | void CStreamInfo::WriteTo(Byte *p) const | 339 | void CStreamInfo::WriteTo(Byte *p) const |
316 | { | 340 | { |
317 | Resource.WriteTo(p); | 341 | Resource.WriteTo(p); |
318 | Set16(p + 0x18, PartNumber); | 342 | Set16(p + 0x18, PartNumber) |
319 | Set32(p + 0x1A, RefCount); | 343 | Set32(p + 0x1A, RefCount) |
320 | memcpy(p + 0x1E, Hash, kHashSize); | 344 | memcpy(p + 0x1E, Hash, kHashSize); |
321 | } | 345 | } |
322 | 346 | ||
323 | 347 | ||
324 | class CInStreamWithSha1: | 348 | Z7_CLASS_IMP_NOQIB_1( |
325 | public ISequentialInStream, | 349 | CInStreamWithSha1 |
326 | public CMyUnknownImp | 350 | , ISequentialInStream |
327 | { | 351 | ) |
328 | CMyComPtr<ISequentialInStream> _stream; | 352 | CMyComPtr<ISequentialInStream> _stream; |
329 | UInt64 _size; | 353 | UInt64 _size; |
330 | // NCrypto::NSha1::CContext _sha; | 354 | // NCrypto::NSha1::CContext _sha; |
331 | CAlignedBuffer _sha; | 355 | CAlignedBuffer1 _sha; |
332 | CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; } | 356 | CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; } |
333 | public: | 357 | public: |
334 | MY_UNKNOWN_IMP1(IInStream) | ||
335 | STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); | ||
336 | |||
337 | CInStreamWithSha1(): _sha(sizeof(CSha1)) {} | 358 | CInStreamWithSha1(): _sha(sizeof(CSha1)) {} |
338 | void SetStream(ISequentialInStream *stream) { _stream = stream; } | 359 | void SetStream(ISequentialInStream *stream) { _stream = stream; } |
339 | void Init() | 360 | void Init() |
@@ -346,10 +367,10 @@ public: | |||
346 | void Final(Byte *digest) { Sha1_Final(Sha(), digest); } | 367 | void Final(Byte *digest) { Sha1_Final(Sha(), digest); } |
347 | }; | 368 | }; |
348 | 369 | ||
349 | STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize) | 370 | Z7_COM7F_IMF(CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize)) |
350 | { | 371 | { |
351 | UInt32 realProcessedSize; | 372 | UInt32 realProcessedSize; |
352 | HRESULT result = _stream->Read(data, size, &realProcessedSize); | 373 | const HRESULT result = _stream->Read(data, size, &realProcessedSize); |
353 | _size += realProcessedSize; | 374 | _size += realProcessedSize; |
354 | Sha1_Update(Sha(), (const Byte *)data, realProcessedSize); | 375 | Sha1_Update(Sha(), (const Byte *)data, realProcessedSize); |
355 | if (processedSize) | 376 | if (processedSize) |
@@ -360,8 +381,8 @@ STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedS | |||
360 | 381 | ||
361 | static void SetFileTimeToMem(Byte *p, const FILETIME &ft) | 382 | static void SetFileTimeToMem(Byte *p, const FILETIME &ft) |
362 | { | 383 | { |
363 | Set32(p, ft.dwLowDateTime); | 384 | Set32(p, ft.dwLowDateTime) |
364 | Set32(p + 4, ft.dwHighDateTime); | 385 | Set32(p + 4, ft.dwHighDateTime) |
365 | } | 386 | } |
366 | 387 | ||
367 | static size_t WriteItem_Dummy(const CMetaItem &item) | 388 | static size_t WriteItem_Dummy(const CMetaItem &item) |
@@ -372,15 +393,15 @@ static size_t WriteItem_Dummy(const CMetaItem &item) | |||
372 | // we write fileNameLen + 2 + 2 to be same as original WIM. | 393 | // we write fileNameLen + 2 + 2 to be same as original WIM. |
373 | unsigned fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2); | 394 | unsigned fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2); |
374 | 395 | ||
375 | unsigned shortNameLen = item.ShortName.Len() * 2; | 396 | const unsigned shortNameLen = item.ShortName.Len() * 2; |
376 | unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); | 397 | const unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); |
377 | 398 | ||
378 | size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7); | 399 | size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~(unsigned)7); |
379 | if (item.GetNumAltStreams() != 0) | 400 | if (item.GetNumAltStreams() != 0) |
380 | { | 401 | { |
381 | if (!item.IsDir) | 402 | if (!item.IsDir) |
382 | { | 403 | { |
383 | UInt32 curLen = (((0x26 + 0) + 6) & ~7); | 404 | const UInt32 curLen = (((0x26 + 0) + 6) & ~(unsigned)7); |
384 | totalLen += curLen; | 405 | totalLen += curLen; |
385 | } | 406 | } |
386 | FOR_VECTOR (i, item.AltStreams) | 407 | FOR_VECTOR (i, item.AltStreams) |
@@ -390,7 +411,7 @@ static size_t WriteItem_Dummy(const CMetaItem &item) | |||
390 | continue; | 411 | continue; |
391 | fileNameLen = ss.Name.Len() * 2; | 412 | fileNameLen = ss.Name.Len() * 2; |
392 | fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); | 413 | fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); |
393 | UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~7); | 414 | const UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~(unsigned)7); |
394 | totalLen += curLen; | 415 | totalLen += curLen; |
395 | } | 416 | } |
396 | } | 417 | } |
@@ -407,12 +428,12 @@ static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte | |||
407 | unsigned shortNameLen = item.ShortName.Len() * 2; | 428 | unsigned shortNameLen = item.ShortName.Len() * 2; |
408 | unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); | 429 | unsigned shortNameLen2 = (shortNameLen == 0 ? 2 : shortNameLen + 4); |
409 | 430 | ||
410 | size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~7); | 431 | size_t totalLen = ((kDirRecordSize + fileNameLen2 + shortNameLen2 + 6) & ~(unsigned)7); |
411 | 432 | ||
412 | memset(p, 0, totalLen); | 433 | memset(p, 0, totalLen); |
413 | Set64(p, totalLen); | 434 | Set64(p, totalLen) |
414 | Set64(p + 8, item.Attrib); | 435 | Set64(p + 8, item.Attrib) |
415 | Set32(p + 0xC, (Int32)item.SecurityId); | 436 | Set32(p + 0xC, (UInt32)(Int32)item.SecurityId) |
416 | SetFileTimeToMem(p + 0x28, item.CTime); | 437 | SetFileTimeToMem(p + 0x28, item.CTime); |
417 | SetFileTimeToMem(p + 0x30, item.ATime); | 438 | SetFileTimeToMem(p + 0x30, item.ATime); |
418 | SetFileTimeToMem(p + 0x38, item.MTime); | 439 | SetFileTimeToMem(p + 0x38, item.MTime); |
@@ -425,21 +446,21 @@ static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte | |||
425 | if (item.Reparse.Size() != 0) | 446 | if (item.Reparse.Size() != 0) |
426 | { | 447 | { |
427 | UInt32 tag = GetUi32(item.Reparse); | 448 | UInt32 tag = GetUi32(item.Reparse); |
428 | Set32(p + 0x58, tag); | 449 | Set32(p + 0x58, tag) |
429 | // Set32(p + 0x5C, 0); // probably it's always ZERO | 450 | // Set32(p + 0x5C, 0); // probably it's always ZERO |
430 | } | 451 | } |
431 | else if (item.FileID != 0) | 452 | else if (item.FileID != 0) |
432 | { | 453 | { |
433 | Set64(p + 0x58, item.FileID); | 454 | Set64(p + 0x58, item.FileID) |
434 | } | 455 | } |
435 | 456 | ||
436 | Set16(p + 0x62, (UInt16)shortNameLen); | 457 | Set16(p + 0x62, (UInt16)shortNameLen) |
437 | Set16(p + 0x64, (UInt16)fileNameLen); | 458 | Set16(p + 0x64, (UInt16)fileNameLen) |
438 | unsigned i; | 459 | unsigned i; |
439 | for (i = 0; i * 2 < fileNameLen; i++) | 460 | for (i = 0; i * 2 < fileNameLen; i++) |
440 | Set16(p + kDirRecordSize + i * 2, (UInt16)item.Name[i]); | 461 | Set16(p + kDirRecordSize + i * 2, (UInt16)item.Name[i]) |
441 | for (i = 0; i * 2 < shortNameLen; i++) | 462 | for (i = 0; i * 2 < shortNameLen; i++) |
442 | Set16(p + kDirRecordSize + fileNameLen2 + i * 2, (UInt16)item.ShortName[i]); | 463 | Set16(p + kDirRecordSize + fileNameLen2 + i * 2, (UInt16)item.ShortName[i]) |
443 | 464 | ||
444 | if (item.GetNumAltStreams() == 0) | 465 | if (item.GetNumAltStreams() == 0) |
445 | { | 466 | { |
@@ -448,14 +469,14 @@ static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte | |||
448 | } | 469 | } |
449 | else | 470 | else |
450 | { | 471 | { |
451 | Set16(p + 0x60, (UInt16)(item.GetNumAltStreams() + (item.IsDir ? 0 : 1))); | 472 | Set16(p + 0x60, (UInt16)(item.GetNumAltStreams() + (item.IsDir ? 0 : 1))) |
452 | p += totalLen; | 473 | p += totalLen; |
453 | 474 | ||
454 | if (!item.IsDir) | 475 | if (!item.IsDir) |
455 | { | 476 | { |
456 | UInt32 curLen = (((0x26 + 0) + 6) & ~7); | 477 | const UInt32 curLen = (((0x26 + 0) + 6) & ~(unsigned)7); |
457 | memset(p, 0, curLen); | 478 | memset(p, 0, curLen); |
458 | Set64(p, curLen); | 479 | Set64(p, curLen) |
459 | if (item.HashIndex >= 0) | 480 | if (item.HashIndex >= 0) |
460 | memcpy(p + 0x10, streams[item.HashIndex].Hash, kHashSize); | 481 | memcpy(p + 0x10, streams[item.HashIndex].Hash, kHashSize); |
461 | totalLen += curLen; | 482 | totalLen += curLen; |
@@ -470,15 +491,15 @@ static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte | |||
470 | 491 | ||
471 | fileNameLen = ss.Name.Len() * 2; | 492 | fileNameLen = ss.Name.Len() * 2; |
472 | fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); | 493 | fileNameLen2 = (fileNameLen == 0 ? 0 : fileNameLen + 2 + 2); |
473 | UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~7); | 494 | UInt32 curLen = (((0x26 + fileNameLen2) + 6) & ~(unsigned)7); |
474 | memset(p, 0, curLen); | 495 | memset(p, 0, curLen); |
475 | 496 | ||
476 | Set64(p, curLen); | 497 | Set64(p, curLen) |
477 | if (ss.HashIndex >= 0) | 498 | if (ss.HashIndex >= 0) |
478 | memcpy(p + 0x10, streams[ss.HashIndex].Hash, kHashSize); | 499 | memcpy(p + 0x10, streams[ss.HashIndex].Hash, kHashSize); |
479 | Set16(p + 0x24, (UInt16)fileNameLen); | 500 | Set16(p + 0x24, (UInt16)fileNameLen) |
480 | for (i = 0; i * 2 < fileNameLen; i++) | 501 | for (i = 0; i * 2 < fileNameLen; i++) |
481 | Set16(p + 0x26 + i * 2, (UInt16)ss.Name[i]); | 502 | Set16(p + 0x26 + i * 2, (UInt16)ss.Name[i]) |
482 | totalLen += curLen; | 503 | totalLen += curLen; |
483 | p += curLen; | 504 | p += curLen; |
484 | } | 505 | } |
@@ -529,7 +550,7 @@ void CDb::WriteTree(const CDir &tree, Byte *dest, size_t &pos) const | |||
529 | for (i = 0; i < tree.Dirs.Size(); i++) | 550 | for (i = 0; i < tree.Dirs.Size(); i++) |
530 | pos += WriteItem_Dummy(MetaItems[tree.Dirs[i].MetaIndex]); | 551 | pos += WriteItem_Dummy(MetaItems[tree.Dirs[i].MetaIndex]); |
531 | 552 | ||
532 | Set64(dest + pos, 0); | 553 | Set64(dest + pos, 0) |
533 | 554 | ||
534 | pos += 8; | 555 | pos += 8; |
535 | 556 | ||
@@ -544,7 +565,7 @@ void CDb::WriteTree(const CDir &tree, Byte *dest, size_t &pos) const | |||
544 | posStart += len; | 565 | posStart += len; |
545 | if (needCreateTree) | 566 | if (needCreateTree) |
546 | { | 567 | { |
547 | Set64(dest + posStart - len + 0x10, pos); // subdirOffset | 568 | Set64(dest + posStart - len + 0x10, pos) // subdirOffset |
548 | WriteTree(subDir, dest, pos); | 569 | WriteTree(subDir, dest, pos); |
549 | } | 570 | } |
550 | } | 571 | } |
@@ -557,18 +578,18 @@ void CDb::WriteOrderList(const CDir &tree) | |||
557 | { | 578 | { |
558 | const CMetaItem &mi = MetaItems[tree.MetaIndex]; | 579 | const CMetaItem &mi = MetaItems[tree.MetaIndex]; |
559 | if (mi.UpdateIndex >= 0) | 580 | if (mi.UpdateIndex >= 0) |
560 | UpdateIndexes.Add(mi.UpdateIndex); | 581 | UpdateIndexes.Add((unsigned)mi.UpdateIndex); |
561 | FOR_VECTOR (si, mi.AltStreams) | 582 | FOR_VECTOR (si, mi.AltStreams) |
562 | UpdateIndexes.Add(mi.AltStreams[si].UpdateIndex); | 583 | UpdateIndexes.Add((unsigned)mi.AltStreams[si].UpdateIndex); |
563 | } | 584 | } |
564 | 585 | ||
565 | unsigned i; | 586 | unsigned i; |
566 | for (i = 0; i < tree.Files.Size(); i++) | 587 | for (i = 0; i < tree.Files.Size(); i++) |
567 | { | 588 | { |
568 | const CMetaItem &mi = MetaItems[tree.Files[i]]; | 589 | const CMetaItem &mi = MetaItems[tree.Files[i]]; |
569 | UpdateIndexes.Add(mi.UpdateIndex); | 590 | UpdateIndexes.Add((unsigned)mi.UpdateIndex); |
570 | FOR_VECTOR (si, mi.AltStreams) | 591 | FOR_VECTOR (si, mi.AltStreams) |
571 | UpdateIndexes.Add(mi.AltStreams[si].UpdateIndex); | 592 | UpdateIndexes.Add((unsigned)mi.AltStreams[si].UpdateIndex); |
572 | } | 593 | } |
573 | 594 | ||
574 | for (i = 0; i < tree.Dirs.Size(); i++) | 595 | for (i = 0; i < tree.Dirs.Size(); i++) |
@@ -696,7 +717,7 @@ void CHeader::SetDefaultFields(bool useLZX) | |||
696 | static void AddTrees(CObjectVector<CDir> &trees, CObjectVector<CMetaItem> &metaItems, const CMetaItem &ri, int curTreeIndex) | 717 | static void AddTrees(CObjectVector<CDir> &trees, CObjectVector<CMetaItem> &metaItems, const CMetaItem &ri, int curTreeIndex) |
697 | { | 718 | { |
698 | while (curTreeIndex >= (int)trees.Size()) | 719 | while (curTreeIndex >= (int)trees.Size()) |
699 | trees.AddNew().Dirs.AddNew().MetaIndex = metaItems.Add(ri); | 720 | trees.AddNew().Dirs.AddNew().MetaIndex = (int)metaItems.Add(ri); |
700 | } | 721 | } |
701 | 722 | ||
702 | 723 | ||
@@ -704,7 +725,7 @@ static void AddTrees(CObjectVector<CDir> &trees, CObjectVector<CMetaItem> &metaI | |||
704 | 725 | ||
705 | 726 | ||
706 | 727 | ||
707 | STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 numItems, IArchiveUpdateCallback *callback) | 728 | Z7_COM7F_IMF(CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 numItems, IArchiveUpdateCallback *callback)) |
708 | { | 729 | { |
709 | COM_TRY_BEGIN | 730 | COM_TRY_BEGIN |
710 | 731 | ||
@@ -732,7 +753,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
732 | return E_NOTIMPL; | 753 | return E_NOTIMPL; |
733 | 754 | ||
734 | CMyComPtr<IOutStream> outStream; | 755 | CMyComPtr<IOutStream> outStream; |
735 | RINOK(outSeqStream->QueryInterface(IID_IOutStream, (void **)&outStream)); | 756 | RINOK(outSeqStream->QueryInterface(IID_IOutStream, (void **)&outStream)) |
736 | if (!outStream) | 757 | if (!outStream) |
737 | return E_NOTIMPL; | 758 | return E_NOTIMPL; |
738 | if (!callback) | 759 | if (!callback) |
@@ -744,7 +765,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
744 | CMetaItem ri; // default DIR item | 765 | CMetaItem ri; // default DIR item |
745 | FILETIME ftCur; | 766 | FILETIME ftCur; |
746 | NTime::GetCurUtcFileTime(ftCur); | 767 | NTime::GetCurUtcFileTime(ftCur); |
747 | ri.MTime = ri.ATime = ri.CTime = ftCur; | 768 | // ri.MTime = ri.ATime = ri.CTime = ftCur; |
748 | ri.Attrib = FILE_ATTRIBUTE_DIRECTORY; | 769 | ri.Attrib = FILE_ATTRIBUTE_DIRECTORY; |
749 | ri.IsDir = true; | 770 | ri.IsDir = true; |
750 | 771 | ||
@@ -765,7 +786,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
765 | { | 786 | { |
766 | UInt32 indexInArchive; | 787 | UInt32 indexInArchive; |
767 | Int32 newData, newProps; | 788 | Int32 newData, newProps; |
768 | RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); | 789 | RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) |
769 | if (newProps == 0) | 790 | if (newProps == 0) |
770 | { | 791 | { |
771 | if (indexInArchive >= _db.SortedItems.Size()) | 792 | if (indexInArchive >= _db.SortedItems.Size()) |
@@ -791,7 +812,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
791 | else | 812 | else |
792 | { | 813 | { |
793 | NCOM::CPropVariant prop; | 814 | NCOM::CPropVariant prop; |
794 | RINOK(callback->GetProperty(i, kpidPath, &prop)); | 815 | RINOK(callback->GetProperty(i, kpidPath, &prop)) |
795 | 816 | ||
796 | if (prop.vt != VT_BSTR) | 817 | if (prop.vt != VT_BSTR) |
797 | return E_INVALIDARG; | 818 | return E_INVALIDARG; |
@@ -851,11 +872,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
851 | UInt32 propType = 0; | 872 | UInt32 propType = 0; |
852 | if (getRootProps) | 873 | if (getRootProps) |
853 | { | 874 | { |
854 | RINOK(getRootProps->GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)); | 875 | RINOK(getRootProps->GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)) |
855 | } | 876 | } |
856 | if (dataSize == 0 && isUpdate) | 877 | if (dataSize == 0 && isUpdate) |
857 | { | 878 | { |
858 | RINOK(GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)); | 879 | RINOK(GetRootRawProp(kpidNtSecure, &data, &dataSize, &propType)) |
859 | } | 880 | } |
860 | if (dataSize != 0) | 881 | if (dataSize != 0) |
861 | { | 882 | { |
@@ -864,21 +885,21 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
864 | while (defaultImageIndex >= (int)secureBlocks.Size()) | 885 | while (defaultImageIndex >= (int)secureBlocks.Size()) |
865 | secureBlocks.AddNew(); | 886 | secureBlocks.AddNew(); |
866 | CUniqBlocks &secUniqBlocks = secureBlocks[defaultImageIndex]; | 887 | CUniqBlocks &secUniqBlocks = secureBlocks[defaultImageIndex]; |
867 | rootItem.SecurityId = secUniqBlocks.AddUniq((const Byte *)data, dataSize); | 888 | rootItem.SecurityId = (int)secUniqBlocks.AddUniq((const Byte *)data, dataSize); |
868 | } | 889 | } |
869 | } | 890 | } |
870 | 891 | ||
871 | IArchiveGetRootProps *thisGetRoot = isUpdate ? this : NULL; | 892 | IArchiveGetRootProps *thisGetRoot = isUpdate ? this : NULL; |
872 | 893 | ||
873 | RINOK(GetRootTime(getRootProps, thisGetRoot, kpidCTime, rootItem.CTime)); | 894 | if (_timeOptions.Write_CTime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidCTime, rootItem.CTime)) |
874 | RINOK(GetRootTime(getRootProps, thisGetRoot, kpidATime, rootItem.ATime)); | 895 | if (_timeOptions.Write_ATime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidATime, rootItem.ATime)) |
875 | RINOK(GetRootTime(getRootProps, thisGetRoot, kpidMTime, rootItem.MTime)); | 896 | if (_timeOptions.Write_MTime.Val) RINOK(GetRootTime(getRootProps, thisGetRoot, kpidMTime, rootItem.MTime)) |
876 | 897 | ||
877 | { | 898 | { |
878 | NCOM::CPropVariant prop; | 899 | NCOM::CPropVariant prop; |
879 | if (getRootProps) | 900 | if (getRootProps) |
880 | { | 901 | { |
881 | RINOK(getRootProps->GetRootProp(kpidAttrib, &prop)); | 902 | RINOK(getRootProps->GetRootProp(kpidAttrib, &prop)) |
882 | if (prop.vt == VT_UI4) | 903 | if (prop.vt == VT_UI4) |
883 | rootItem.Attrib = prop.ulVal; | 904 | rootItem.Attrib = prop.ulVal; |
884 | else if (prop.vt != VT_EMPTY) | 905 | else if (prop.vt != VT_EMPTY) |
@@ -886,7 +907,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
886 | } | 907 | } |
887 | if (prop.vt == VT_EMPTY && thisGetRoot) | 908 | if (prop.vt == VT_EMPTY && thisGetRoot) |
888 | { | 909 | { |
889 | RINOK(GetRootProp(kpidAttrib, &prop)); | 910 | RINOK(GetRootProp(kpidAttrib, &prop)) |
890 | if (prop.vt == VT_UI4) | 911 | if (prop.vt == VT_UI4) |
891 | rootItem.Attrib = prop.ulVal; | 912 | rootItem.Attrib = prop.ulVal; |
892 | else if (prop.vt != VT_EMPTY) | 913 | else if (prop.vt != VT_EMPTY) |
@@ -908,7 +929,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
908 | CUpdateItem ui; | 929 | CUpdateItem ui; |
909 | UInt32 indexInArchive; | 930 | UInt32 indexInArchive; |
910 | Int32 newData, newProps; | 931 | Int32 newData, newProps; |
911 | RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)); | 932 | RINOK(callback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive)) |
912 | 933 | ||
913 | if (newData == 0 || newProps == 0) | 934 | if (newData == 0 || newProps == 0) |
914 | { | 935 | { |
@@ -940,16 +961,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
940 | } | 961 | } |
941 | 962 | ||
942 | if (newData == 0) | 963 | if (newData == 0) |
943 | ui.InArcIndex = indexInArchive; | 964 | ui.InArcIndex = (Int32)indexInArchive; |
944 | } | 965 | } |
945 | 966 | ||
946 | // we set arcIndex only if we must use old props | 967 | // we set arcIndex only if we must use old props |
947 | Int32 arcIndex = (newProps ? -1 : indexInArchive); | 968 | const Int32 arcIndex = (newProps ? -1 : (Int32)indexInArchive); |
948 | 969 | ||
949 | bool isDir = false; | 970 | bool isDir = false; |
950 | { | 971 | { |
951 | NCOM::CPropVariant prop; | 972 | NCOM::CPropVariant prop; |
952 | RINOK(GetOutProperty(callback, i, arcIndex, kpidIsDir, &prop)); | 973 | RINOK(GetOutProperty(callback, i, arcIndex, kpidIsDir, &prop)) |
953 | if (prop.vt == VT_BOOL) | 974 | if (prop.vt == VT_BOOL) |
954 | isDir = (prop.boolVal != VARIANT_FALSE); | 975 | isDir = (prop.boolVal != VARIANT_FALSE); |
955 | else if (prop.vt != VT_EMPTY) | 976 | else if (prop.vt != VT_EMPTY) |
@@ -959,7 +980,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
959 | bool isAltStream = false; | 980 | bool isAltStream = false; |
960 | { | 981 | { |
961 | NCOM::CPropVariant prop; | 982 | NCOM::CPropVariant prop; |
962 | RINOK(GetOutProperty(callback, i, arcIndex, kpidIsAltStream, &prop)); | 983 | RINOK(GetOutProperty(callback, i, arcIndex, kpidIsAltStream, &prop)) |
963 | if (prop.vt == VT_BOOL) | 984 | if (prop.vt == VT_BOOL) |
964 | isAltStream = (prop.boolVal != VARIANT_FALSE); | 985 | isAltStream = (prop.boolVal != VARIANT_FALSE); |
965 | else if (prop.vt != VT_EMPTY) | 986 | else if (prop.vt != VT_EMPTY) |
@@ -986,11 +1007,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
986 | 1007 | ||
987 | if (newData) | 1008 | if (newData) |
988 | { | 1009 | { |
989 | RINOK(callback->GetProperty(i, kpidSize, &prop)); | 1010 | RINOK(callback->GetProperty(i, kpidSize, &prop)) |
990 | } | 1011 | } |
991 | else | 1012 | else |
992 | { | 1013 | { |
993 | RINOK(GetProperty(indexInArchive, kpidSize, &prop)); | 1014 | RINOK(GetProperty(indexInArchive, kpidSize, &prop)) |
994 | } | 1015 | } |
995 | 1016 | ||
996 | if (prop.vt == VT_UI8) | 1017 | if (prop.vt == VT_UI8) |
@@ -1002,7 +1023,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1002 | { | 1023 | { |
1003 | NCOM::CPropVariant propPath; | 1024 | NCOM::CPropVariant propPath; |
1004 | const wchar_t *path = NULL; | 1025 | const wchar_t *path = NULL; |
1005 | RINOK(GetOutProperty(callback, i, arcIndex, kpidPath, &propPath)); | 1026 | RINOK(GetOutProperty(callback, i, arcIndex, kpidPath, &propPath)) |
1006 | if (propPath.vt == VT_BSTR) | 1027 | if (propPath.vt == VT_BSTR) |
1007 | path = propPath.bstrVal; | 1028 | path = propPath.bstrVal; |
1008 | else if (propPath.vt != VT_EMPTY) | 1029 | else if (propPath.vt != VT_EMPTY) |
@@ -1056,8 +1077,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1056 | CAltStream ss; | 1077 | CAltStream ss; |
1057 | ss.Size = size; | 1078 | ss.Size = size; |
1058 | ss.Name = end + 1; | 1079 | ss.Name = end + 1; |
1059 | ss.UpdateIndex = db.UpdateItems.Size(); | 1080 | ss.UpdateIndex = (int)db.UpdateItems.Size(); |
1060 | ui.AltStreamIndex = db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); | 1081 | ui.AltStreamIndex = (int)db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); |
1061 | } | 1082 | } |
1062 | else if (c == WCHAR_PATH_SEPARATOR || c == L'/') | 1083 | else if (c == WCHAR_PATH_SEPARATOR || c == L'/') |
1063 | { | 1084 | { |
@@ -1082,7 +1103,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1082 | if (!curItem->FindDir(db.MetaItems, fileName, indexOfDir)) | 1103 | if (!curItem->FindDir(db.MetaItems, fileName, indexOfDir)) |
1083 | { | 1104 | { |
1084 | CDir &dir = curItem->Dirs.InsertNew(indexOfDir); | 1105 | CDir &dir = curItem->Dirs.InsertNew(indexOfDir); |
1085 | dir.MetaIndex = db.MetaItems.Add(ri); | 1106 | dir.MetaIndex = (int)db.MetaItems.Add(ri); |
1086 | db.MetaItems.Back().Name = fileName; | 1107 | db.MetaItems.Back().Name = fileName; |
1087 | } | 1108 | } |
1088 | curItem = &curItem->Dirs[indexOfDir]; | 1109 | curItem = &curItem->Dirs[indexOfDir]; |
@@ -1121,7 +1142,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1121 | // we want to support cases of c::substream, where c: is drive name | 1142 | // we want to support cases of c::substream, where c: is drive name |
1122 | if (colonPos == 1 && fileName[2] == L':' && IS_LETTER_CHAR(fileName[0])) | 1143 | if (colonPos == 1 && fileName[2] == L':' && IS_LETTER_CHAR(fileName[0])) |
1123 | colonPos = 2; | 1144 | colonPos = 2; |
1124 | const UString mainName = fileName.Left(colonPos); | 1145 | const UString mainName = fileName.Left((unsigned)colonPos); |
1125 | unsigned indexOfDir; | 1146 | unsigned indexOfDir; |
1126 | 1147 | ||
1127 | if (mainName.IsEmpty()) | 1148 | if (mainName.IsEmpty()) |
@@ -1132,11 +1153,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1132 | { | 1153 | { |
1133 | for (int j = (int)curItem->Files.Size() - 1; j >= 0; j--) | 1154 | for (int j = (int)curItem->Files.Size() - 1; j >= 0; j--) |
1134 | { | 1155 | { |
1135 | int metaIndex = curItem->Files[j]; | 1156 | const unsigned metaIndex = curItem->Files[j]; |
1136 | const CMetaItem &mi = db.MetaItems[metaIndex]; | 1157 | const CMetaItem &mi = db.MetaItems[metaIndex]; |
1137 | if (CompareFileNames(mainName, mi.Name) == 0) | 1158 | if (CompareFileNames(mainName, mi.Name) == 0) |
1138 | { | 1159 | { |
1139 | ui.MetaIndex = metaIndex; | 1160 | ui.MetaIndex = (int)metaIndex; |
1140 | break; | 1161 | break; |
1141 | } | 1162 | } |
1142 | } | 1163 | } |
@@ -1147,8 +1168,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1147 | CAltStream ss; | 1168 | CAltStream ss; |
1148 | ss.Size = size; | 1169 | ss.Size = size; |
1149 | ss.Name = fileName.Ptr(colonPos + 1); | 1170 | ss.Name = fileName.Ptr(colonPos + 1); |
1150 | ss.UpdateIndex = db.UpdateItems.Size(); | 1171 | ss.UpdateIndex = (int)db.UpdateItems.Size(); |
1151 | ui.AltStreamIndex = db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); | 1172 | ui.AltStreamIndex = (int)db.MetaItems[ui.MetaIndex].AltStreams.Add(ss); |
1152 | } | 1173 | } |
1153 | } | 1174 | } |
1154 | } | 1175 | } |
@@ -1158,7 +1179,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1158 | { | 1179 | { |
1159 | if (!isRootImageDir) | 1180 | if (!isRootImageDir) |
1160 | { | 1181 | { |
1161 | ui.MetaIndex = db.MetaItems.Size(); | 1182 | ui.MetaIndex = (int)db.MetaItems.Size(); |
1162 | db.MetaItems.AddNew(); | 1183 | db.MetaItems.AddNew(); |
1163 | } | 1184 | } |
1164 | 1185 | ||
@@ -1166,10 +1187,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1166 | mi.Size = size; | 1187 | mi.Size = size; |
1167 | mi.IsDir = isDir; | 1188 | mi.IsDir = isDir; |
1168 | mi.Name = fileName; | 1189 | mi.Name = fileName; |
1169 | mi.UpdateIndex = db.UpdateItems.Size(); | 1190 | mi.UpdateIndex = (int)db.UpdateItems.Size(); |
1170 | { | 1191 | { |
1171 | NCOM::CPropVariant prop; | 1192 | NCOM::CPropVariant prop; |
1172 | RINOK(GetOutProperty(callback, i, arcIndex, kpidAttrib, &prop)); | 1193 | RINOK(GetOutProperty(callback, i, arcIndex, kpidAttrib, &prop)) |
1173 | if (prop.vt == VT_EMPTY) | 1194 | if (prop.vt == VT_EMPTY) |
1174 | mi.Attrib = 0; | 1195 | mi.Attrib = 0; |
1175 | else if (prop.vt == VT_UI4) | 1196 | else if (prop.vt == VT_UI4) |
@@ -1179,13 +1200,17 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1179 | if (isDir) | 1200 | if (isDir) |
1180 | mi.Attrib |= FILE_ATTRIBUTE_DIRECTORY; | 1201 | mi.Attrib |= FILE_ATTRIBUTE_DIRECTORY; |
1181 | } | 1202 | } |
1182 | RINOK(GetTime(callback, i, arcIndex, kpidCTime, mi.CTime)); | 1203 | |
1183 | RINOK(GetTime(callback, i, arcIndex, kpidATime, mi.ATime)); | 1204 | if (arcIndex != -1 || _timeOptions.Write_CTime.Val) |
1184 | RINOK(GetTime(callback, i, arcIndex, kpidMTime, mi.MTime)); | 1205 | RINOK(GetTime(callback, i, arcIndex, kpidCTime, mi.CTime)) |
1206 | if (arcIndex != -1 || _timeOptions.Write_ATime.Val) | ||
1207 | RINOK(GetTime(callback, i, arcIndex, kpidATime, mi.ATime)) | ||
1208 | if (arcIndex != -1 || _timeOptions.Write_MTime.Val) | ||
1209 | RINOK(GetTime(callback, i, arcIndex, kpidMTime, mi.MTime)) | ||
1185 | 1210 | ||
1186 | { | 1211 | { |
1187 | NCOM::CPropVariant prop; | 1212 | NCOM::CPropVariant prop; |
1188 | RINOK(GetOutProperty(callback, i, arcIndex, kpidShortName, &prop)); | 1213 | RINOK(GetOutProperty(callback, i, arcIndex, kpidShortName, &prop)) |
1189 | if (prop.vt == VT_BSTR) | 1214 | if (prop.vt == VT_BSTR) |
1190 | mi.ShortName.SetFromBstr(prop.bstrVal); | 1215 | mi.ShortName.SetFromBstr(prop.bstrVal); |
1191 | else if (prop.vt != VT_EMPTY) | 1216 | else if (prop.vt != VT_EMPTY) |
@@ -1208,7 +1233,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1208 | 1233 | ||
1209 | if (arcIndex >= 0) | 1234 | if (arcIndex >= 0) |
1210 | { | 1235 | { |
1211 | GetRawProp(arcIndex, kpidNtSecure, &data, &dataSize, &propType); | 1236 | GetRawProp((UInt32)arcIndex, kpidNtSecure, &data, &dataSize, &propType); |
1212 | } | 1237 | } |
1213 | else | 1238 | else |
1214 | { | 1239 | { |
@@ -1219,7 +1244,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1219 | { | 1244 | { |
1220 | if (propType != NPropDataType::kRaw) | 1245 | if (propType != NPropDataType::kRaw) |
1221 | return E_FAIL; | 1246 | return E_FAIL; |
1222 | mi.SecurityId = secUniqBlocks.AddUniq((const Byte *)data, dataSize); | 1247 | mi.SecurityId = (int)secUniqBlocks.AddUniq((const Byte *)data, dataSize); |
1223 | } | 1248 | } |
1224 | 1249 | ||
1225 | data = NULL; | 1250 | data = NULL; |
@@ -1228,7 +1253,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1228 | 1253 | ||
1229 | if (arcIndex >= 0) | 1254 | if (arcIndex >= 0) |
1230 | { | 1255 | { |
1231 | GetRawProp(arcIndex, kpidNtReparse, &data, &dataSize, &propType); | 1256 | GetRawProp((UInt32)arcIndex, kpidNtReparse, &data, &dataSize, &propType); |
1232 | } | 1257 | } |
1233 | else | 1258 | else |
1234 | { | 1259 | { |
@@ -1254,7 +1279,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1254 | curItem->Dirs.InsertNew(indexOfDir).MetaIndex = ui.MetaIndex; | 1279 | curItem->Dirs.InsertNew(indexOfDir).MetaIndex = ui.MetaIndex; |
1255 | } | 1280 | } |
1256 | else | 1281 | else |
1257 | curItem->Files.Add(ui.MetaIndex); | 1282 | curItem->Files.Add((unsigned)ui.MetaIndex); |
1258 | } | 1283 | } |
1259 | } | 1284 | } |
1260 | 1285 | ||
@@ -1272,7 +1297,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1272 | if (!isChangedImage[i]) | 1297 | if (!isChangedImage[i]) |
1273 | numNewImages = i + 1; | 1298 | numNewImages = i + 1; |
1274 | 1299 | ||
1275 | AddTrees(trees, db.MetaItems, ri, numNewImages - 1); | 1300 | AddTrees(trees, db.MetaItems, ri, (int)numNewImages - 1); |
1276 | 1301 | ||
1277 | for (i = 0; i < trees.Size(); i++) | 1302 | for (i = 0; i < trees.Size(); i++) |
1278 | if (i >= isChangedImage.Size() || isChangedImage[i]) | 1303 | if (i >= isChangedImage.Size() || isChangedImage[i]) |
@@ -1354,7 +1379,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1354 | complexity += rs.PackSize; | 1379 | complexity += rs.PackSize; |
1355 | } | 1380 | } |
1356 | 1381 | ||
1357 | RINOK(callback->SetTotal(complexity)); | 1382 | RINOK(callback->SetTotal(complexity)) |
1358 | UInt64 totalComplexity = complexity; | 1383 | UInt64 totalComplexity = complexity; |
1359 | 1384 | ||
1360 | NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; | 1385 | NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder; |
@@ -1381,10 +1406,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1381 | header.ChunkSizeBits = srcHeader.ChunkSizeBits; | 1406 | header.ChunkSizeBits = srcHeader.ChunkSizeBits; |
1382 | } | 1407 | } |
1383 | 1408 | ||
1409 | CMyComPtr<IStreamSetRestriction> setRestriction; | ||
1410 | outSeqStream->QueryInterface(IID_IStreamSetRestriction, (void **)&setRestriction); | ||
1411 | if (setRestriction) | ||
1412 | RINOK(setRestriction->SetRestriction(0, kHeaderSizeMax)) | ||
1413 | |||
1384 | { | 1414 | { |
1385 | Byte buf[kHeaderSizeMax]; | 1415 | Byte buf[kHeaderSizeMax]; |
1386 | header.WriteTo(buf); | 1416 | header.WriteTo(buf); |
1387 | RINOK(WriteStream(outStream, buf, kHeaderSizeMax)); | 1417 | RINOK(WriteStream(outStream, buf, kHeaderSizeMax)) |
1388 | } | 1418 | } |
1389 | 1419 | ||
1390 | UInt64 curPos = kHeaderSizeMax; | 1420 | UInt64 curPos = kHeaderSizeMax; |
@@ -1393,7 +1423,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1393 | CMyComPtr<ISequentialInStream> inShaStream = inShaStreamSpec; | 1423 | CMyComPtr<ISequentialInStream> inShaStream = inShaStreamSpec; |
1394 | 1424 | ||
1395 | CLimitedSequentialInStream *inStreamLimitedSpec = NULL; | 1425 | CLimitedSequentialInStream *inStreamLimitedSpec = NULL; |
1396 | CMyComPtr<CLimitedSequentialInStream> inStreamLimited; | 1426 | CMyComPtr<ISequentialInStream> inStreamLimited; |
1397 | if (_volumes.Size() == 2) | 1427 | if (_volumes.Size() == 2) |
1398 | { | 1428 | { |
1399 | inStreamLimitedSpec = new CLimitedSequentialInStream; | 1429 | inStreamLimitedSpec = new CLimitedSequentialInStream; |
@@ -1403,7 +1433,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1403 | 1433 | ||
1404 | 1434 | ||
1405 | CRecordVector<CStreamInfo> streams; | 1435 | CRecordVector<CStreamInfo> streams; |
1406 | CUIntVector sortedHashes; // indexes to streams, sorted by SHA1 | 1436 | CSortedIndex sortedHashes; // indexes to streams, sorted by SHA1 |
1407 | 1437 | ||
1408 | // ---------- Copy unchanged data streams ---------- | 1438 | // ---------- Copy unchanged data streams ---------- |
1409 | 1439 | ||
@@ -1415,7 +1445,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1415 | const CStreamInfo &siOld = _db.DataStreams[i]; | 1445 | const CStreamInfo &siOld = _db.DataStreams[i]; |
1416 | const CResource &rs = siOld.Resource; | 1446 | const CResource &rs = siOld.Resource; |
1417 | 1447 | ||
1418 | unsigned numRefs = streamsRefs[i]; | 1448 | const unsigned numRefs = streamsRefs[i]; |
1419 | 1449 | ||
1420 | if (numRefs == 0) | 1450 | if (numRefs == 0) |
1421 | { | 1451 | { |
@@ -1426,9 +1456,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1426 | } | 1456 | } |
1427 | 1457 | ||
1428 | lps->InSize = lps->OutSize = complexity; | 1458 | lps->InSize = lps->OutSize = complexity; |
1429 | RINOK(lps->SetCur()); | 1459 | RINOK(lps->SetCur()) |
1430 | 1460 | ||
1431 | int streamIndex = streams.Size(); | 1461 | const unsigned streamIndex = streams.Size(); |
1432 | CStreamInfo s; | 1462 | CStreamInfo s; |
1433 | s.Resource = rs; | 1463 | s.Resource = rs; |
1434 | s.PartNumber = 1; | 1464 | s.PartNumber = 1; |
@@ -1462,16 +1492,16 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1462 | 1492 | ||
1463 | if (!rs.IsSolid() || rs.IsSolidSmall()) | 1493 | if (!rs.IsSolid() || rs.IsSolidSmall()) |
1464 | { | 1494 | { |
1465 | int find = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, streamIndex); | 1495 | const int find = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, (int)streamIndex); |
1466 | if (find >= 0) | 1496 | if (find != -1) |
1467 | return E_FAIL; // two streams with same SHA-1 | 1497 | return E_FAIL; // two streams with same SHA-1 |
1468 | } | 1498 | } |
1469 | 1499 | ||
1470 | if (!rs.IsSolid() || rs.IsSolidBig()) | 1500 | if (!rs.IsSolid() || rs.IsSolidBig()) |
1471 | { | 1501 | { |
1472 | RINOK(_volumes[siOld.PartNumber].Stream->Seek(rs.Offset, STREAM_SEEK_SET, NULL)); | 1502 | RINOK(InStream_SeekSet(_volumes[siOld.PartNumber].Stream, rs.Offset)) |
1473 | inStreamLimitedSpec->Init(rs.PackSize); | 1503 | inStreamLimitedSpec->Init(rs.PackSize); |
1474 | RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); | 1504 | RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)) |
1475 | if (copyCoderSpec->TotalSize != rs.PackSize) | 1505 | if (copyCoderSpec->TotalSize != rs.PackSize) |
1476 | return E_FAIL; | 1506 | return E_FAIL; |
1477 | s.Resource.Offset = curPos; | 1507 | s.Resource.Offset = curPos; |
@@ -1490,7 +1520,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1490 | for (i = 0; i < db.UpdateIndexes.Size(); i++) | 1520 | for (i = 0; i < db.UpdateIndexes.Size(); i++) |
1491 | { | 1521 | { |
1492 | lps->InSize = lps->OutSize = complexity; | 1522 | lps->InSize = lps->OutSize = complexity; |
1493 | RINOK(lps->SetCur()); | 1523 | RINOK(lps->SetCur()) |
1494 | const CUpdateItem &ui = db.UpdateItems[db.UpdateIndexes[i]]; | 1524 | const CUpdateItem &ui = db.UpdateItems[db.UpdateIndexes[i]]; |
1495 | CMetaItem &mi = db.MetaItems[ui.MetaIndex]; | 1525 | CMetaItem &mi = db.MetaItems[ui.MetaIndex]; |
1496 | UInt64 size = 0; | 1526 | UInt64 size = 0; |
@@ -1534,9 +1564,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1534 | 1564 | ||
1535 | const CStreamInfo &siOld = _db.DataStreams[item.StreamIndex]; | 1565 | const CStreamInfo &siOld = _db.DataStreams[item.StreamIndex]; |
1536 | 1566 | ||
1537 | int index = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, -1); | 1567 | const int index = AddUniqHash(&streams.Front(), sortedHashes, siOld.Hash, -1); |
1538 | // we must have written that stream already | 1568 | // we must have written that stream already |
1539 | if (index < 0) | 1569 | if (index == -1) |
1540 | return E_FAIL; | 1570 | return E_FAIL; |
1541 | 1571 | ||
1542 | if (ui.AltStreamIndex < 0) | 1572 | if (ui.AltStreamIndex < 0) |
@@ -1562,7 +1592,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1562 | } | 1592 | } |
1563 | else | 1593 | else |
1564 | { | 1594 | { |
1565 | RINOK(res); | 1595 | RINOK(res) |
1566 | 1596 | ||
1567 | int miIndex = -1; | 1597 | int miIndex = -1; |
1568 | 1598 | ||
@@ -1581,23 +1611,23 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1581 | if (getProps2->GetProps2(&props) == S_OK) | 1611 | if (getProps2->GetProps2(&props) == S_OK) |
1582 | { | 1612 | { |
1583 | mi.Attrib = props.Attrib; | 1613 | mi.Attrib = props.Attrib; |
1584 | mi.CTime = props.CTime; | 1614 | if (_timeOptions.Write_CTime.Val) mi.CTime = props.CTime; |
1585 | mi.ATime = props.ATime; | 1615 | if (_timeOptions.Write_ATime.Val) mi.ATime = props.ATime; |
1586 | mi.MTime = props.MTime; | 1616 | if (_timeOptions.Write_MTime.Val) mi.MTime = props.MTime; |
1587 | mi.FileID = props.FileID_Low; | 1617 | mi.FileID = props.FileID_Low; |
1588 | if (props.NumLinks <= 1) | 1618 | if (props.NumLinks <= 1) |
1589 | mi.FileID = 0; | 1619 | mi.FileID = 0; |
1590 | mi.VolID = props.VolID; | 1620 | mi.VolID = props.VolID; |
1591 | if (mi.FileID != 0) | 1621 | if (mi.FileID != 0) |
1592 | miIndex = AddToHardLinkList(db.MetaItems, ui.MetaIndex, hlIndexes); | 1622 | miIndex = AddToHardLinkList(db.MetaItems, (unsigned)ui.MetaIndex, hlIndexes); |
1593 | 1623 | ||
1594 | if (props.Size != size && props.Size != (UInt64)(Int64)-1) | 1624 | if (props.Size != size && props.Size != (UInt64)(Int64)-1) |
1595 | { | 1625 | { |
1596 | Int64 delta = (Int64)props.Size - (Int64)size; | 1626 | const Int64 delta = (Int64)props.Size - (Int64)size; |
1597 | Int64 newComplexity = totalComplexity + delta; | 1627 | const Int64 newComplexity = (Int64)totalComplexity + delta; |
1598 | if (newComplexity > 0) | 1628 | if (newComplexity > 0) |
1599 | { | 1629 | { |
1600 | totalComplexity = newComplexity; | 1630 | totalComplexity = (UInt64)newComplexity; |
1601 | callback->SetTotal(totalComplexity); | 1631 | callback->SetTotal(totalComplexity); |
1602 | } | 1632 | } |
1603 | mi.Size = props.Size; | 1633 | mi.Size = props.Size; |
@@ -1620,19 +1650,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1620 | return E_FAIL; | 1650 | return E_FAIL; |
1621 | NCrypto::NSha1::CContext sha1; | 1651 | NCrypto::NSha1::CContext sha1; |
1622 | sha1.Init(); | 1652 | sha1.Init(); |
1623 | size_t packSize = mi.Reparse.Size() - 8; | 1653 | const size_t packSize = mi.Reparse.Size() - 8; |
1624 | sha1.Update((const Byte *)mi.Reparse + 8, packSize); | 1654 | sha1.Update((const Byte *)mi.Reparse + 8, packSize); |
1625 | Byte hash[kHashSize]; | 1655 | Byte hash[kHashSize]; |
1626 | sha1.Final(hash); | 1656 | sha1.Final(hash); |
1627 | 1657 | ||
1628 | int index = AddUniqHash(&streams.Front(), sortedHashes, hash, streams.Size()); | 1658 | int index = AddUniqHash(&streams.Front(), sortedHashes, hash, (int)streams.Size()); |
1629 | 1659 | ||
1630 | if (index >= 0) | 1660 | if (index != -1) |
1631 | streams[index].RefCount++; | 1661 | streams[index].RefCount++; |
1632 | else | 1662 | else |
1633 | { | 1663 | { |
1634 | index = streams.Size(); | 1664 | index = (int)streams.Size(); |
1635 | RINOK(WriteStream(outStream, (const Byte *)mi.Reparse + 8, packSize)); | 1665 | RINOK(WriteStream(outStream, (const Byte *)mi.Reparse + 8, packSize)) |
1636 | CStreamInfo s; | 1666 | CStreamInfo s; |
1637 | s.Resource.PackSize = packSize; | 1667 | s.Resource.PackSize = packSize; |
1638 | s.Resource.Offset = curPos; | 1668 | s.Resource.Offset = curPos; |
@@ -1655,6 +1685,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1655 | else | 1685 | else |
1656 | { | 1686 | { |
1657 | inShaStreamSpec->SetStream(fileInStream); | 1687 | inShaStreamSpec->SetStream(fileInStream); |
1688 | |||
1689 | CMyComPtr<IInStream> inSeekStream; | ||
1690 | fileInStream.QueryInterface(IID_IInStream, (void **)&inSeekStream); | ||
1691 | |||
1658 | fileInStream.Release(); | 1692 | fileInStream.Release(); |
1659 | inShaStreamSpec->Init(); | 1693 | inShaStreamSpec->Init(); |
1660 | UInt64 offsetBlockSize = 0; | 1694 | UInt64 offsetBlockSize = 0; |
@@ -1670,54 +1704,88 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1670 | } | 1704 | } |
1671 | } | 1705 | } |
1672 | */ | 1706 | */ |
1707 | |||
1708 | // 22.02: we use additional read-only pass to calculate SHA-1 | ||
1709 | bool needWritePass = true; | ||
1710 | int index = -1; | ||
1673 | 1711 | ||
1674 | RINOK(copyCoder->Code(inShaStream, outStream, NULL, NULL, progress)); | 1712 | if (inSeekStream /* && !sortedHashes.IsEmpty() */) |
1675 | size = copyCoderSpec->TotalSize; | ||
1676 | |||
1677 | if (size != 0) | ||
1678 | { | 1713 | { |
1679 | Byte hash[kHashSize]; | 1714 | RINOK(copyCoder->Code(inShaStream, NULL, NULL, NULL, progress)) |
1680 | UInt64 packSize = offsetBlockSize + size; | 1715 | size = copyCoderSpec->TotalSize; |
1681 | inShaStreamSpec->Final(hash); | 1716 | if (size == 0) |
1682 | 1717 | needWritePass = false; | |
1683 | int index = AddUniqHash(&streams.Front(), sortedHashes, hash, streams.Size()); | ||
1684 | |||
1685 | if (index >= 0) | ||
1686 | { | ||
1687 | streams[index].RefCount++; | ||
1688 | outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos); | ||
1689 | outStream->SetSize(curPos); | ||
1690 | } | ||
1691 | else | 1718 | else |
1692 | { | 1719 | { |
1693 | index = streams.Size(); | 1720 | Byte hash[kHashSize]; |
1694 | CStreamInfo s; | 1721 | inShaStreamSpec->Final(hash); |
1695 | s.Resource.PackSize = packSize; | 1722 | |
1696 | s.Resource.Offset = curPos; | 1723 | index = AddUniqHash(&streams.Front(), sortedHashes, hash, -1); |
1697 | s.Resource.UnpackSize = size; | 1724 | if (index != -1) |
1698 | s.Resource.Flags = 0; | 1725 | { |
1699 | /* | 1726 | streams[index].RefCount++; |
1700 | if (useResourceCompression) | 1727 | needWritePass = false; |
1701 | s.Resource.Flags = NResourceFlags::Compressed; | 1728 | } |
1702 | */ | 1729 | else |
1703 | s.PartNumber = 1; | 1730 | { |
1704 | s.RefCount = 1; | 1731 | RINOK(InStream_SeekToBegin(inSeekStream)) |
1705 | memcpy(s.Hash, hash, kHashSize); | 1732 | inShaStreamSpec->Init(); |
1706 | curPos += packSize; | 1733 | } |
1707 | |||
1708 | streams.Add(s); | ||
1709 | } | 1734 | } |
1710 | 1735 | } | |
1736 | |||
1737 | if (needWritePass) | ||
1738 | { | ||
1739 | RINOK(copyCoder->Code(inShaStream, outStream, NULL, NULL, progress)) | ||
1740 | size = copyCoderSpec->TotalSize; | ||
1741 | } | ||
1742 | |||
1743 | if (size != 0) | ||
1744 | { | ||
1745 | if (needWritePass) | ||
1746 | { | ||
1747 | Byte hash[kHashSize]; | ||
1748 | const UInt64 packSize = offsetBlockSize + size; | ||
1749 | inShaStreamSpec->Final(hash); | ||
1750 | |||
1751 | index = AddUniqHash(&streams.Front(), sortedHashes, hash, (int)streams.Size()); | ||
1752 | |||
1753 | if (index != -1) | ||
1754 | { | ||
1755 | streams[index].RefCount++; | ||
1756 | outStream->Seek(-(Int64)packSize, STREAM_SEEK_CUR, &curPos); | ||
1757 | outStream->SetSize(curPos); | ||
1758 | } | ||
1759 | else | ||
1760 | { | ||
1761 | index = (int)streams.Size(); | ||
1762 | CStreamInfo s; | ||
1763 | s.Resource.PackSize = packSize; | ||
1764 | s.Resource.Offset = curPos; | ||
1765 | s.Resource.UnpackSize = size; | ||
1766 | s.Resource.Flags = 0; | ||
1767 | /* | ||
1768 | if (useResourceCompression) | ||
1769 | s.Resource.Flags = NResourceFlags::Compressed; | ||
1770 | */ | ||
1771 | s.PartNumber = 1; | ||
1772 | s.RefCount = 1; | ||
1773 | memcpy(s.Hash, hash, kHashSize); | ||
1774 | curPos += packSize; | ||
1775 | |||
1776 | streams.Add(s); | ||
1777 | } | ||
1778 | } // needWritePass | ||
1711 | if (ui.AltStreamIndex < 0) | 1779 | if (ui.AltStreamIndex < 0) |
1712 | mi.HashIndex = index; | 1780 | mi.HashIndex = index; |
1713 | else | 1781 | else |
1714 | mi.AltStreams[ui.AltStreamIndex].HashIndex = index; | 1782 | mi.AltStreams[ui.AltStreamIndex].HashIndex = index; |
1715 | } | 1783 | } // (size != 0) |
1716 | } | 1784 | } |
1717 | } | 1785 | } |
1718 | fileInStream.Release(); | 1786 | fileInStream.Release(); |
1719 | complexity += size; | 1787 | complexity += size; |
1720 | RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)); | 1788 | RINOK(callback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK)) |
1721 | } | 1789 | } |
1722 | 1790 | ||
1723 | while (secureBlocks.Size() < numNewImages) | 1791 | while (secureBlocks.Size() < numNewImages) |
@@ -1730,14 +1798,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1730 | for (i = 0; i < numNewImages; i++) | 1798 | for (i = 0; i < numNewImages; i++) |
1731 | { | 1799 | { |
1732 | lps->InSize = lps->OutSize = complexity; | 1800 | lps->InSize = lps->OutSize = complexity; |
1733 | RINOK(lps->SetCur()); | 1801 | RINOK(lps->SetCur()) |
1734 | if (i < isChangedImage.Size() && !isChangedImage[i]) | 1802 | if (i < isChangedImage.Size() && !isChangedImage[i]) |
1735 | { | 1803 | { |
1736 | CStreamInfo s = _db.MetaStreams[i]; | 1804 | CStreamInfo s = _db.MetaStreams[i]; |
1737 | 1805 | ||
1738 | RINOK(_volumes[1].Stream->Seek(s.Resource.Offset, STREAM_SEEK_SET, NULL)); | 1806 | RINOK(InStream_SeekSet(_volumes[1].Stream, s.Resource.Offset)) |
1739 | inStreamLimitedSpec->Init(s.Resource.PackSize); | 1807 | inStreamLimitedSpec->Init(s.Resource.PackSize); |
1740 | RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)); | 1808 | RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress)) |
1741 | if (copyCoderSpec->TotalSize != s.Resource.PackSize) | 1809 | if (copyCoderSpec->TotalSize != s.Resource.PackSize) |
1742 | return E_FAIL; | 1810 | return E_FAIL; |
1743 | 1811 | ||
@@ -1774,14 +1842,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1774 | 1842 | ||
1775 | CByteArr meta(pos); | 1843 | CByteArr meta(pos); |
1776 | 1844 | ||
1777 | Set32((Byte *)meta + 4, secBufs.Size()); // num security entries | 1845 | Set32((Byte *)meta + 4, secBufs.Size()) // num security entries |
1778 | pos = kSecuritySize; | 1846 | pos = kSecuritySize; |
1779 | 1847 | ||
1780 | if (secBufs.Size() == 0) | 1848 | if (secBufs.Size() == 0) |
1781 | { | 1849 | { |
1782 | // we can write 0 here only if there is no security data, imageX does it, | 1850 | // we can write 0 here only if there is no security data, imageX does it, |
1783 | // but some programs expect size = 8 | 1851 | // but some programs expect size = 8 |
1784 | Set32((Byte *)meta, 8); // size of security data | 1852 | Set32((Byte *)meta, 8) // size of security data |
1785 | // Set32((Byte *)meta, 0); | 1853 | // Set32((Byte *)meta, 0); |
1786 | } | 1854 | } |
1787 | else | 1855 | else |
@@ -1789,7 +1857,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1789 | unsigned k; | 1857 | unsigned k; |
1790 | for (k = 0; k < secBufs.Size(); k++, pos += 8) | 1858 | for (k = 0; k < secBufs.Size(); k++, pos += 8) |
1791 | { | 1859 | { |
1792 | Set64(meta + pos, secBufs[k].Size()); | 1860 | Set64(meta + pos, secBufs[k].Size()) |
1793 | } | 1861 | } |
1794 | for (k = 0; k < secBufs.Size(); k++) | 1862 | for (k = 0; k < secBufs.Size(); k++) |
1795 | { | 1863 | { |
@@ -1803,7 +1871,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1803 | } | 1871 | } |
1804 | while ((pos & 7) != 0) | 1872 | while ((pos & 7) != 0) |
1805 | meta[pos++] = 0; | 1873 | meta[pos++] = 0; |
1806 | Set32((Byte *)meta, (UInt32)pos); // size of security data | 1874 | Set32((Byte *)meta, (UInt32)pos) // size of security data |
1807 | } | 1875 | } |
1808 | 1876 | ||
1809 | db.Hashes = &streams.Front(); | 1877 | db.Hashes = &streams.Front(); |
@@ -1833,14 +1901,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1833 | header.BootIndex = _bootIndex; | 1901 | header.BootIndex = _bootIndex; |
1834 | } | 1902 | } |
1835 | 1903 | ||
1836 | RINOK(WriteStream(outStream, (const Byte *)meta, pos)); | 1904 | RINOK(WriteStream(outStream, (const Byte *)meta, pos)) |
1837 | meta.Free(); | 1905 | meta.Free(); |
1838 | curPos += pos; | 1906 | curPos += pos; |
1839 | } | 1907 | } |
1840 | } | 1908 | } |
1841 | 1909 | ||
1842 | lps->InSize = lps->OutSize = complexity; | 1910 | lps->InSize = lps->OutSize = complexity; |
1843 | RINOK(lps->SetCur()); | 1911 | RINOK(lps->SetCur()) |
1844 | 1912 | ||
1845 | header.OffsetResource.UnpackSize = header.OffsetResource.PackSize = (UInt64)streams.Size() * kStreamInfoSize; | 1913 | header.OffsetResource.UnpackSize = header.OffsetResource.PackSize = (UInt64)streams.Size() * kStreamInfoSize; |
1846 | header.OffsetResource.Offset = curPos; | 1914 | header.OffsetResource.Offset = curPos; |
@@ -1854,7 +1922,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1854 | { | 1922 | { |
1855 | Byte buf[kStreamInfoSize]; | 1923 | Byte buf[kStreamInfoSize]; |
1856 | streams[i].WriteTo(buf); | 1924 | streams[i].WriteTo(buf); |
1857 | RINOK(WriteStream(outStream, buf, kStreamInfoSize)); | 1925 | RINOK(WriteStream(outStream, buf, kStreamInfoSize)) |
1858 | curPos += kStreamInfoSize; | 1926 | curPos += kStreamInfoSize; |
1859 | } | 1927 | } |
1860 | 1928 | ||
@@ -1862,7 +1930,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1862 | AddTagUInt64_ToString(xml, "TOTALBYTES", curPos); | 1930 | AddTagUInt64_ToString(xml, "TOTALBYTES", curPos); |
1863 | for (i = 0; i < trees.Size(); i++) | 1931 | for (i = 0; i < trees.Size(); i++) |
1864 | { | 1932 | { |
1865 | CDir &tree = trees[i]; | 1933 | const CDir &tree = trees[i]; |
1866 | 1934 | ||
1867 | CXmlItem item; | 1935 | CXmlItem item; |
1868 | if (_xmls.Size() == 1) | 1936 | if (_xmls.Size() == 1) |
@@ -1905,16 +1973,19 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1905 | UString utf16; | 1973 | UString utf16; |
1906 | if (!ConvertUTF8ToUnicode(xml, utf16)) | 1974 | if (!ConvertUTF8ToUnicode(xml, utf16)) |
1907 | return S_FALSE; | 1975 | return S_FALSE; |
1908 | xmlSize = (utf16.Len() + 1) * 2; | 1976 | xmlSize = ((size_t)utf16.Len() + 1) * 2; |
1909 | 1977 | ||
1910 | CByteArr xmlBuf(xmlSize); | 1978 | CByteArr xmlBuf(xmlSize); |
1911 | Set16((Byte *)xmlBuf, 0xFEFF); | 1979 | Set16((Byte *)xmlBuf, 0xFEFF) |
1912 | for (i = 0; i < (unsigned)utf16.Len(); i++) | 1980 | for (i = 0; i < (unsigned)utf16.Len(); i++) |
1913 | Set16((Byte *)xmlBuf + 2 + i * 2, (UInt16)utf16[i]); | 1981 | { |
1914 | RINOK(WriteStream(outStream, (const Byte *)xmlBuf, xmlSize)); | 1982 | Set16((Byte *)xmlBuf + 2 + (size_t)i * 2, (UInt16)utf16[i]) |
1983 | } | ||
1984 | RINOK(WriteStream(outStream, (const Byte *)xmlBuf, xmlSize)) | ||
1915 | } | 1985 | } |
1916 | 1986 | ||
1917 | header.XmlResource.UnpackSize = header.XmlResource.PackSize = xmlSize; | 1987 | header.XmlResource.UnpackSize = |
1988 | header.XmlResource.PackSize = xmlSize; | ||
1918 | header.XmlResource.Offset = curPos; | 1989 | header.XmlResource.Offset = curPos; |
1919 | header.XmlResource.Flags = NResourceFlags::kMetadata; | 1990 | header.XmlResource.Flags = NResourceFlags::kMetadata; |
1920 | 1991 | ||
@@ -1923,9 +1994,14 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu | |||
1923 | { | 1994 | { |
1924 | Byte buf[kHeaderSizeMax]; | 1995 | Byte buf[kHeaderSizeMax]; |
1925 | header.WriteTo(buf); | 1996 | header.WriteTo(buf); |
1926 | return WriteStream(outStream, buf, kHeaderSizeMax); | 1997 | RINOK(WriteStream(outStream, buf, kHeaderSizeMax)) |
1927 | } | 1998 | } |
1928 | 1999 | ||
2000 | if (setRestriction) | ||
2001 | RINOK(setRestriction->SetRestriction(0, 0)) | ||
2002 | |||
2003 | return S_OK; | ||
2004 | |||
1929 | COM_TRY_END | 2005 | COM_TRY_END |
1930 | } | 2006 | } |
1931 | 2007 | ||