"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "CPP/7zip/Archive/NtfsHandler.cpp" between
p7zip_15.14.1_src_all.tar.gz and p7zip_16.02_src_all.tar.gz

About: p7zip is a command-line file archiver with a high compression ratio (a port of the Windows program 7za.exe).

NtfsHandler.cpp  (p7zip_15.14.1_src_all):NtfsHandler.cpp  (p7zip_16.02_src_all)
skipping to change at line 631 skipping to change at line 631
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition); STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
}; };
static size_t Lznt1Dec(Byte *dest, size_t outBufLim, size_t destLen, const Byte *src, size_t srcLen) static size_t Lznt1Dec(Byte *dest, size_t outBufLim, size_t destLen, const Byte *src, size_t srcLen)
{ {
size_t destSize = 0; size_t destSize = 0;
while (destSize < destLen) while (destSize < destLen)
{ {
if (srcLen < 2 || (destSize & 0xFFF) != 0) if (srcLen < 2 || (destSize & 0xFFF) != 0)
break; break;
UInt32 v = Get16(src); UInt32 comprSize;
if (v == 0)
break;
src += 2;
srcLen -= 2;
UInt32 comprSize = (v & 0xFFF) + 1;
if (comprSize > srcLen)
break;
srcLen -= comprSize;
if ((v & 0x8000) == 0)
{ {
if (comprSize != (1 << 12)) const UInt32 v = Get16(src);
if (v == 0)
break;
src += 2;
srcLen -= 2;
comprSize = (v & 0xFFF) + 1;
if (comprSize > srcLen)
break; break;
memcpy(dest + destSize, src, comprSize); srcLen -= comprSize;
src += comprSize; if ((v & 0x8000) == 0)
destSize += comprSize; {
if (comprSize != (1 << 12))
break;
memcpy(dest + destSize, src, comprSize);
src += comprSize;
destSize += comprSize;
continue;
}
} }
else
{ {
if (destSize + (1 << 12) > outBufLim || (src[0] & 1) != 0) if (destSize + (1 << 12) > outBufLim || (src[0] & 1) != 0)
return 0; return 0;
unsigned numDistBits = 4; unsigned numDistBits = 4;
UInt32 sbOffset = 0; UInt32 sbOffset = 0;
UInt32 pos = 0; UInt32 pos = 0;
do do
{ {
comprSize--; comprSize--;
skipping to change at line 673 skipping to change at line 676
if (sbOffset >= (1 << 12)) if (sbOffset >= (1 << 12))
return 0; return 0;
dest[destSize++] = src[pos++]; dest[destSize++] = src[pos++];
sbOffset++; sbOffset++;
comprSize--; comprSize--;
} }
else else
{ {
if (comprSize < 2) if (comprSize < 2)
return 0; return 0;
UInt32 v = Get16(src + pos); const UInt32 v = Get16(src + pos);
pos += 2; pos += 2;
comprSize -= 2; comprSize -= 2;
while (((sbOffset - 1) >> numDistBits) != 0) while (((sbOffset - 1) >> numDistBits) != 0)
numDistBits++; numDistBits++;
UInt32 len = (v & (0xFFFF >> numDistBits)) + 3; UInt32 len = (v & (0xFFFF >> numDistBits)) + 3;
if (sbOffset + len > (1 << 12)) if (sbOffset + len > (1 << 12))
return 0; return 0;
UInt32 dist = (v >> (16 - numDistBits)); UInt32 dist = (v >> (16 - numDistBits));
skipping to change at line 710 skipping to change at line 713
} }
STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{ {
if (processedSize) if (processedSize)
*processedSize = 0; *processedSize = 0;
if (_virtPos >= Size) if (_virtPos >= Size)
return (Size == _virtPos) ? S_OK: E_FAIL; return (Size == _virtPos) ? S_OK: E_FAIL;
if (size == 0) if (size == 0)
return S_OK; return S_OK;
UInt64 rem = Size - _virtPos; {
if (size > rem) const UInt64 rem = Size - _virtPos;
size = (UInt32)rem; if (size > rem)
size = (UInt32)rem;
}
if (_virtPos >= InitializedSize) if (_virtPos >= InitializedSize)
{ {
memset((Byte *)data, 0, size); memset((Byte *)data, 0, size);
_virtPos += size; _virtPos += size;
*processedSize = size; *processedSize = size;
return S_OK; return S_OK;
} }
rem = InitializedSize - _virtPos;
if (size > rem) {
size = (UInt32)rem; const UInt64 rem = InitializedSize - _virtPos;
if (size > rem)
size = (UInt32)rem;
}
while (_curRem == 0) while (_curRem == 0)
{ {
UInt64 cacheTag = _virtPos >> _chunkSizeLog; UInt64 cacheTag = _virtPos >> _chunkSizeLog;
UInt32 cacheIndex = (UInt32)cacheTag & (kNumCacheChunks - 1); UInt32 cacheIndex = (UInt32)cacheTag & (kNumCacheChunks - 1);
if (_tags[cacheIndex] == cacheTag) if (_tags[cacheIndex] == cacheTag)
{ {
UInt32 chunkSize = (UInt32)1 << _chunkSizeLog; UInt32 chunkSize = (UInt32)1 << _chunkSizeLog;
UInt32 offset = (UInt32)_virtPos & (chunkSize - 1); UInt32 offset = (UInt32)_virtPos & (chunkSize - 1);
UInt32 cur = MyMin(chunkSize - offset, size); UInt32 cur = MyMin(chunkSize - offset, size);
skipping to change at line 839 skipping to change at line 848
if (curVirt + numChunks > virtBlock2End) if (curVirt + numChunks > virtBlock2End)
numChunks = virtBlock2End - curVirt; numChunks = virtBlock2End - curVirt;
size_t compressed = (size_t)numChunks << BlockSizeLog; size_t compressed = (size_t)numChunks << BlockSizeLog;
RINOK(ReadStream_FALSE(Stream, _inBuf + offs, compressed)); RINOK(ReadStream_FALSE(Stream, _inBuf + offs, compressed));
curVirt += numChunks; curVirt += numChunks;
_physPos += compressed; _physPos += compressed;
offs += compressed; offs += compressed;
} }
size_t destLenMax = GetCuSize(); size_t destLenMax = GetCuSize();
size_t destLen = destLenMax; size_t destLen = destLenMax;
UInt64 rem = Size - (virtBlock2 << BlockSizeLog); const UInt64 rem = Size - (virtBlock2 << BlockSizeLog);
if (destLen > rem) if (destLen > rem)
destLen = (size_t)rem; destLen = (size_t)rem;
Byte *dest = _outBuf + (cacheIndex << _chunkSizeLog); Byte *dest = _outBuf + (cacheIndex << _chunkSizeLog);
size_t destSizeRes = Lznt1Dec(dest, destLenMax, destLen, _inBuf, offs); size_t destSizeRes = Lznt1Dec(dest, destLenMax, destLen, _inBuf, offs);
_tags[cacheIndex] = cacheTag; _tags[cacheIndex] = cacheTag;
// some files in Vista have destSize > destLen // some files in Vista have destSize > destLen
if (destSizeRes < destLen) if (destSizeRes < destLen)
{ {
skipping to change at line 896 skipping to change at line 905
_virtPos = offset; _virtPos = offset;
} }
if (newPosition) if (newPosition)
*newPosition = offset; *newPosition = offset;
return S_OK; return S_OK;
} }
static HRESULT DataParseExtents(unsigned clusterSizeLog, const CObjectVector<CAt tr> &attrs, static HRESULT DataParseExtents(unsigned clusterSizeLog, const CObjectVector<CAt tr> &attrs,
unsigned attrIndex, unsigned attrIndexLim, UInt64 numPhysClusters, CRecordVe ctor<CExtent> &Extents) unsigned attrIndex, unsigned attrIndexLim, UInt64 numPhysClusters, CRecordVe ctor<CExtent> &Extents)
{ {
CExtent e; {
e.Virt = 0; CExtent e;
e.Phy = kEmptyExtent; e.Virt = 0;
Extents.Add(e); e.Phy = kEmptyExtent;
Extents.Add(e);
}
const CAttr &attr0 = attrs[attrIndex]; const CAttr &attr0 = attrs[attrIndex];
if (attr0.AllocatedSize < attr0.Size || if (attr0.AllocatedSize < attr0.Size ||
(attrs[attrIndexLim - 1].HighVcn + 1) != (attr0.AllocatedSize >> clusterSi zeLog) || (attrs[attrIndexLim - 1].HighVcn + 1) != (attr0.AllocatedSize >> clusterSi zeLog) ||
(attr0.AllocatedSize & ((1 << clusterSizeLog) - 1)) != 0) (attr0.AllocatedSize & ((1 << clusterSizeLog) - 1)) != 0)
return S_FALSE; return S_FALSE;
for (unsigned i = attrIndex; i < attrIndexLim; i++) for (unsigned i = attrIndex; i < attrIndexLim; i++)
if (!attrs[i].ParseExtents(Extents, numPhysClusters, attr0.CompressionUnit)) if (!attrs[i].ParseExtents(Extents, numPhysClusters, attr0.CompressionUnit))
return S_FALSE; return S_FALSE;
skipping to change at line 1076 skipping to change at line 1088
for (i = ref.Start; i < ref.Start + ref.Num; i++) for (i = ref.Start; i < ref.Start + ref.Num; i++)
if (DataAttrs[i].NonResident) if (DataAttrs[i].NonResident)
numNonResident++; numNonResident++;
const CAttr &attr0 = DataAttrs[ref.Start]; const CAttr &attr0 = DataAttrs[ref.Start];
if (numNonResident != 0 || ref.Num != 1) if (numNonResident != 0 || ref.Num != 1)
{ {
if (numNonResident != ref.Num || !attr0.IsCompressionUnitSupported()) if (numNonResident != ref.Num || !attr0.IsCompressionUnitSupported())
return S_FALSE; return S_FALSE;
CInStream *streamSpec = new CInStream; CInStream *ss = new CInStream;
CMyComPtr<IInStream> streamTemp = streamSpec; CMyComPtr<IInStream> streamTemp2 = ss;
RINOK(DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + r RINOK(DataParseExtents(clusterSizeLog, DataAttrs, ref.Start, ref.Start + r
ef.Num, numPhysClusters, streamSpec->Extents)); ef.Num, numPhysClusters, ss->Extents));
streamSpec->Size = attr0.Size; ss->Size = attr0.Size;
streamSpec->InitializedSize = attr0.InitializedSize; ss->InitializedSize = attr0.InitializedSize;
streamSpec->Stream = mainStream; ss->Stream = mainStream;
streamSpec->BlockSizeLog = clusterSizeLog; ss->BlockSizeLog = clusterSizeLog;
streamSpec->InUse = InUse(); ss->InUse = InUse();
RINOK(streamSpec->InitAndSeek(attr0.CompressionUnit)); RINOK(ss->InitAndSeek(attr0.CompressionUnit));
*destStream = streamTemp.Detach(); *destStream = streamTemp2.Detach();
return S_OK; return S_OK;
} }
streamSpec->Buf = attr0.Data; streamSpec->Buf = attr0.Data;
} }
streamSpec->Init(); streamSpec->Init();
*destStream = streamTemp.Detach(); *destStream = streamTemp.Detach();
return S_OK; return S_OK;
} }
unsigned CMftRec::GetNumExtents(int dataIndex, unsigned clusterSizeLog, UInt64 n umPhysClusters) const unsigned CMftRec::GetNumExtents(int dataIndex, unsigned clusterSizeLog, UInt64 n umPhysClusters) const
{ {
if (dataIndex < 0) if (dataIndex < 0)
return 0; return 0;
{ {
skipping to change at line 1148 skipping to change at line 1162
Original values of these two bytes are stored in table. Original values of these two bytes are stored in table.
So we restore original data from table */ So we restore original data from table */
if ((usaOffset & 1) != 0 if ((usaOffset & 1) != 0
|| usaOffset + numUsaItems * 2 > ((UInt32)1 << sectorSizeLog) - 2 || usaOffset + numUsaItems * 2 > ((UInt32)1 << sectorSizeLog) - 2
|| numUsaItems == 0 || numUsaItems == 0
|| numUsaItems - 1 != numSectors) || numUsaItems - 1 != numSectors)
return false; return false;
if (usaOffset >= 0x30) // NTFS 3.1+ if (usaOffset >= 0x30) // NTFS 3.1+
if (Get32(p + 0x2C) != recNumber) {
return false; UInt32 iii = Get32(p + 0x2C);
if (iii != recNumber)
{
// ntfs-3g probably writes 0 (that probably is incorrect value) to this
field for unused records.
// so we support that "bad" case.
if (iii != 0)
return false;
}
}
UInt16 usn = Get16(p + usaOffset); UInt16 usn = Get16(p + usaOffset);
// PRF(printf("\nusn = %d", usn)); // PRF(printf("\nusn = %d", usn));
for (UInt32 i = 1; i < numUsaItems; i++) for (UInt32 i = 1; i < numUsaItems; i++)
{ {
void *pp = p + (i << sectorSizeLog) - 2; void *pp = p + (i << sectorSizeLog) - 2;
if (Get16(pp) != usn) if (Get16(pp) != usn)
return false; return false;
SetUi16(pp, Get16(p + usaOffset + i * 2)); SetUi16(pp, Get16(p + usaOffset + i * 2));
} }
skipping to change at line 1683 skipping to change at line 1705
if (!mftStream) if (!mftStream)
return S_FALSE; return S_FALSE;
} }
// CObjectVector<CAttr> SecurityAttrs; // CObjectVector<CAttr> SecurityAttrs;
UInt64 mftSize = mftRec.DataAttrs[0].Size; UInt64 mftSize = mftRec.DataAttrs[0].Size;
if ((mftSize >> 4) > Header.GetPhySize_Clusters()) if ((mftSize >> 4) > Header.GetPhySize_Clusters())
return S_FALSE; return S_FALSE;
UInt64 numFiles = mftSize >> RecSizeLog;
if (numFiles > (1 << 30))
return S_FALSE;
if (OpenCallback)
{
RINOK(OpenCallback->SetTotal(&numFiles, &mftSize));
}
const size_t kBufSize = (1 << 15); const size_t kBufSize = (1 << 15);
const size_t recSize = ((size_t)1 << RecSizeLog); const size_t recSize = ((size_t)1 << RecSizeLog);
if (kBufSize < recSize) if (kBufSize < recSize)
return S_FALSE; return S_FALSE;
ByteBuf.Alloc(kBufSize); {
Recs.ClearAndReserve((unsigned)numFiles); const UInt64 numFiles = mftSize >> RecSizeLog;
if (numFiles > (1 << 30))
return S_FALSE;
if (OpenCallback)
{
RINOK(OpenCallback->SetTotal(&numFiles, &mftSize));
}
ByteBuf.Alloc(kBufSize);
Recs.ClearAndReserve((unsigned)numFiles);
}
for (UInt64 pos64 = 0;;) for (UInt64 pos64 = 0;;)
{ {
if (OpenCallback) if (OpenCallback)
{ {
UInt64 numFiles = Recs.Size(); const UInt64 numFiles = Recs.Size();
if ((numFiles & 0x3FF) == 0) if ((numFiles & 0x3FF) == 0)
{ {
RINOK(OpenCallback->SetCompleted(&numFiles, &pos64)); RINOK(OpenCallback->SetCompleted(&numFiles, &pos64));
} }
} }
size_t readSize = kBufSize; size_t readSize = kBufSize;
UInt64 rem = mftSize - pos64; {
if (readSize > rem) const UInt64 rem = mftSize - pos64;
readSize = (size_t)rem; if (readSize > rem)
readSize = (size_t)rem;
}
if (readSize < recSize) if (readSize < recSize)
break; break;
RINOK(ReadStream_FALSE(mftStream, ByteBuf, readSize)); RINOK(ReadStream_FALSE(mftStream, ByteBuf, readSize));
pos64 += readSize; pos64 += readSize;
for (size_t i = 0; readSize >= recSize; i += recSize, readSize -= recSize) for (size_t i = 0; readSize >= recSize; i += recSize, readSize -= recSize)
{ {
PRF(printf("\n---------------------")); PRF(printf("\n---------------------"));
PRF(printf("\n%5d:", Recs.Size())); PRF(printf("\n%5d:", Recs.Size()));
skipping to change at line 2660 skipping to change at line 2686
{ {
CMyComPtr<IInStream> inStream; CMyComPtr<IInStream> inStream;
HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeL og, Header.NumClusters, &inStream); HRESULT hres = rec.GetStream(InStream, item.DataIndex, Header.ClusterSizeL og, Header.NumClusters, &inStream);
if (hres == S_FALSE) if (hres == S_FALSE)
res = NExtract::NOperationResult::kUnsupportedMethod; res = NExtract::NOperationResult::kUnsupportedMethod;
else else
{ {
RINOK(hres); RINOK(hres);
if (inStream) if (inStream)
{ {
HRESULT hres = copyCoder->Code(inStream, outStream, NULL, NULL, progre ss); hres = copyCoder->Code(inStream, outStream, NULL, NULL, progress);
if (hres != S_OK && hres != S_FALSE) if (hres != S_OK && hres != S_FALSE)
{ {
RINOK(hres); RINOK(hres);
} }
if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK) if (/* copyCoderSpec->TotalSize == item.GetSize() && */ hres == S_OK)
res = NExtract::NOperationResult::kOK; res = NExtract::NOperationResult::kOK;
} }
} }
} }
if (item.DataIndex >= 0) if (item.DataIndex >= 0)
 End of changes. 18 change blocks. 
55 lines changed or deleted 82 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS