This commit is contained in:
Igor Pavlov
2005-05-30 00:00:00 +00:00
committed by Kornel Lesiński
parent 8c1b5c7b7e
commit 3c510ba80b
926 changed files with 40559 additions and 23519 deletions

View File

@@ -2,8 +2,7 @@
#include "StdAfx.h"
#include <initguid.h>
#include "Common/MyInitGuid.h"
#include "Common/ComTry.h"
#include "Windows/PropVariant.h"
#include "../../ICoder.h"

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp
#include "stdafx.h"
#include "StdAfx.h"

View File

@@ -1,9 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include <time.h>
#include "../../../Common/MyWindows.h"
#endif
#endif

View File

@@ -126,6 +126,22 @@ SOURCE=.\Tar.ico
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\IntToString.h
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\NewHandler.cpp
# End Source File
# Begin Source File

View File

@@ -42,13 +42,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfProperties(UINT32 *numProperties)
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 *numProperties)
{
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
return S_OK;
}
STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
STDMETHODIMP CHandler::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
if(index >= sizeof(kProperties) / sizeof(kProperties[0]))
@@ -60,20 +60,20 @@ STDMETHODIMP CHandler::GetPropertyInfo(UINT32 index,
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UINT32 *numProperties)
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{
*numProperties = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UINT32 index,
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
return E_INVALIDARG;
}
STDMETHODIMP CHandler::Open(IInStream *stream,
const UINT64 *maxCheckStartPosition,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback)
{
COM_TRY_BEGIN
@@ -90,7 +90,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
if (openArchiveCallback != NULL)
{
RINOK(openArchiveCallback->SetTotal(NULL, NULL));
UINT64 numFiles = _items.Size();
UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
@@ -109,7 +109,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
archive.SkeepDataRecords(item.Size);
if (openArchiveCallback != NULL)
{
UINT64 numFiles = _items.Size();
UInt64 numFiles = _items.Size();
RINOK(openArchiveCallback->SetCompleted(&numFiles, NULL));
}
}
@@ -134,13 +134,13 @@ STDMETHODIMP CHandler::Close()
return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UINT32 *numItems)
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
{
*numItems = _items.Size();
return S_OK;
}
STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;
@@ -157,13 +157,13 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val
break;
case kpidSize:
case kpidPackedSize:
propVariant = (UINT64)item.Size;
propVariant = (UInt64)item.Size;
break;
case kpidLastWriteTime:
{
FILETIME utcFileTime;
if (item.ModificationTime != 0)
NTime::UnixTimeToFileTime(item.ModificationTime, utcFileTime);
NTime::UnixTimeToFileTime((UInt32)item.ModificationTime, utcFileTime);
else
{
utcFileTime.dwLowDateTime = 0;
@@ -186,24 +186,24 @@ STDMETHODIMP CHandler::GetProperty(UINT32 index, PROPID propID, PROPVARIANT *val
COM_TRY_END
}
STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
INT32 _aTestMode, IArchiveExtractCallback *extractCallback)
STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
Int32 _aTestMode, IArchiveExtractCallback *extractCallback)
{
COM_TRY_BEGIN
bool testMode = (_aTestMode != 0);
bool allFilesMode = (numItems == UINT32(-1));
bool allFilesMode = (numItems == UInt32(-1));
if (allFilesMode)
numItems = _items.Size();
UINT64 totalSize = 0;
UInt64 totalSize = 0;
if(numItems == 0)
return S_OK;
UINT32 i;
UInt32 i;
for(i = 0; i < numItems; i++)
totalSize += _items[allFilesMode ? i : indices[i]].Size;
extractCallback->SetTotal(totalSize);
UINT64 currentTotalSize = 0;
UINT64 currentItemSize;
UInt64 currentTotalSize = 0;
UInt64 currentItemSize;
CMyComPtr<ICompressCoder> copyCoder;
@@ -211,10 +211,10 @@ STDMETHODIMP CHandler::Extract(const UINT32* indices, UINT32 numItems,
{
RINOK(extractCallback->SetCompleted(&currentTotalSize));
CMyComPtr<ISequentialOutStream> realOutStream;
INT32 askMode;
Int32 askMode;
askMode = testMode ? NArchive::NExtract::NAskMode::kTest :
NArchive::NExtract::NAskMode::kExtract;
INT32 index = allFilesMode ? i : indices[i];
Int32 index = allFilesMode ? i : indices[i];
const CItemEx &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));

View File

@@ -1,7 +1,5 @@
// Tar/Handler.h
#pragma once
#ifndef __TAR_HANDLER_H
#define __TAR_HANDLER_H
@@ -25,28 +23,28 @@ public:
)
STDMETHOD(Open)(IInStream *stream,
const UINT64 *maxCheckStartPosition,
const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openArchiveCallback);
STDMETHOD(Close)();
STDMETHOD(GetNumberOfItems)(UINT32 *numItems);
STDMETHOD(GetProperty)(UINT32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(Extract)(const UINT32* indices, UINT32 numItems,
INT32 testMode, IArchiveExtractCallback *extractCallback);
STDMETHOD(GetNumberOfItems)(UInt32 *numItems);
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback);
STDMETHOD(GetArchiveProperty)(PROPID propID, PROPVARIANT *value);
STDMETHOD(GetNumberOfProperties)(UINT32 *numProperties);
STDMETHOD(GetPropertyInfo)(UINT32 index,
STDMETHOD(GetNumberOfProperties)(UInt32 *numProperties);
STDMETHOD(GetPropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType);
STDMETHOD(GetNumberOfArchiveProperties)(UINT32 *numProperties);
STDMETHOD(GetArchivePropertyInfo)(UINT32 index,
STDMETHOD(GetNumberOfArchiveProperties)(UInt32 *numProperties);
STDMETHOD(GetArchivePropertyInfo)(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType);
// IOutArchive
STDMETHOD(UpdateItems)(IOutStream *outStream, UINT32 numItems,
STDMETHOD(UpdateItems)(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback);
STDMETHOD(GetFileTimeType)(UINT32 *type);
STDMETHOD(GetFileTimeType)(UInt32 *type);
private:
CObjectVector<CItemEx> _items;

View File

@@ -20,23 +20,23 @@ using namespace NTime;
namespace NArchive {
namespace NTar {
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type)
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kUnix;
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
CObjectVector<CUpdateItemInfo> updateItems;
for(UINT32 i = 0; i < numItems; i++)
for(UInt32 i = 0; i < numItems; i++)
{
CUpdateItemInfo updateItem;
INT32 newData;
INT32 newProperties;
UINT32 indexInArchive;
Int32 newData;
Int32 newProperties;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(i,
@@ -51,7 +51,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
FILETIME utcTime;
UString name;
bool isDirectoryStatusDefined;
UINT32 attributes;
UInt32 attributes;
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
@@ -98,18 +98,19 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
updateItem.IsDirectory = ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
if (updateItem.IsDirectory)
updateItem.Name += '/';
if(!FileTimeToUnixTime(utcTime, updateItem.Time))
return E_INVALIDARG;
}
if (IntToBool(newData))
{
UINT64 size;
UInt64 size;
{
NCOM::CPropVariant propVariant;
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
if (propVariant.vt != VT_UI8)
return E_INVALIDARG;
size = *(UINT64 *)(&propVariant.uhVal);
size = propVariant.uhVal.QuadPart;
}
updateItem.Size = size;
}

View File

@@ -22,4 +22,3 @@ namespace NFileHeader {
}
}}}

View File

@@ -1,7 +1,5 @@
// Archive/Tar/Header.h
#pragma once
#ifndef __ARCHIVE_TAR_HEADER_H
#define __ARCHIVE_TAR_HEADER_H
@@ -10,9 +8,6 @@
namespace NArchive {
namespace NTar {
#pragma pack( push, PragmaTarHeaders)
#pragma pack( push, 1)
namespace NFileHeader
{
const int kRecordSize = 512;
@@ -20,6 +15,7 @@ namespace NFileHeader
const int kUserNameSize = 32;
const int kGroupNameSize = 32;
/*
struct CHeader
{
char Name[kNameSize];
@@ -36,17 +32,13 @@ namespace NFileHeader
char GroupName[kGroupNameSize];
char DeviceMajor[8];
char DeviceMinor[8];
/*
BYTE Padding[kRecordSize - (kNameSize + 8 + 8 + 12 + 12 + 8 + 1 + kNameSize + 8 +
kUserNameSize + kGroupNameSize + 8 + 8)];
*/
};
union CRecord
{
CHeader Header;
BYTE Padding[kRecordSize];
Byte Padding[kRecordSize];
};
*/
namespace NMode
{
@@ -99,9 +91,6 @@ namespace NFileHeader
}
#pragma pack(pop)
#pragma pack(pop, PragmaTarHeaders)
}}
#endif

View File

@@ -10,7 +10,7 @@
namespace NArchive {
namespace NTar {
HRESULT CInArchive::ReadBytes(void *data, UINT32 size, UINT32 &processedSize)
HRESULT CInArchive::ReadBytes(void *data, UInt32 size, UInt32 &processedSize)
{
RINOK(m_Stream->Read(data, size, &processedSize));
m_Position += processedSize;
@@ -24,7 +24,7 @@ HRESULT CInArchive::Open(IInStream *inStream)
return S_OK;
}
static UINT32 OctalToNumber(const char *srcString)
static UInt32 OctalToNumber(const char *srcString)
{
char *endPtr;
return(strtoul(srcString, &endPtr, 8));
@@ -47,86 +47,131 @@ static bool CheckOctalString(const char *srcString, int numChars)
#define ReturnIfBadOctal(x, y) { if (!CheckOctalString((x), (y))) return S_FALSE; }
static bool IsRecordLast(const NFileHeader::CRecord &record)
static bool IsRecordLast(const char *record)
{
for (int i = 0; i < sizeof(record); i++)
if (record.Padding[i] != 0)
for (int i = 0; i < NFileHeader::kRecordSize; i++)
if (record[i] != 0)
return false;
return true;
}
static void ReadString(const char *s, int size, AString &result)
{
if (size > NFileHeader::kNameSize)
size = NFileHeader::kNameSize;
char tempString[NFileHeader::kNameSize + 1];
strncpy(tempString, s, size);
tempString[size] = '\0';
result = tempString;
}
static char GetHex(Byte value)
{
return (value < 10) ? ('0' + value) : ('A' + (value - 10));
}
HRESULT CInArchive::GetNextItemReal(bool &filled, CItemEx &item)
{
item.LongLinkSize = 0;
NFileHeader::CRecord record;
// NFileHeader::CRecord record;
char record[NFileHeader::kRecordSize];
char *cur = record;
filled = false;
UINT32 processedSize;
UInt32 processedSize;
item.HeaderPosition = m_Position;
RINOK(ReadBytes(&record, sizeof(record), processedSize));
RINOK(ReadBytes(record, NFileHeader::kRecordSize, processedSize));
if (processedSize == 0 ||
(processedSize == sizeof(record) && IsRecordLast(record)))
(processedSize == NFileHeader::kRecordSize && IsRecordLast(record)))
return S_OK;
if (processedSize < sizeof(record))
if (processedSize < NFileHeader::kRecordSize)
return S_FALSE;
NFileHeader::CHeader &header = record.Header;
// NFileHeader::CHeader &header = record.Header;
char tempString[NFileHeader::kNameSize + 1];
strncpy(tempString, header.Name, NFileHeader::kNameSize);
tempString[NFileHeader::kNameSize] = '\0';
item.Name = tempString;
AString name;
ReadString(cur, NFileHeader::kNameSize, name);
cur += NFileHeader::kNameSize;
item.Name.Empty();
int i;
for (i = 0; i < item.Name.Length(); i++)
if (((BYTE)item.Name[i]) < 0x20)
for (i = 0; i < name.Length(); i++)
{
char c = name[i];
if (((Byte)c) < 0x08)
{
return S_FALSE;
item.LinkFlag = header.LinkFlag;
}
if (((Byte)c) < 0x20)
{
item.Name += '[';
item.Name += GetHex(((Byte)c) >> 4);
item.Name += GetHex(((Byte)c) & 0xF);
item.Name += ']';
}
else
item.Name += c;
}
BYTE linkFlag = item.LinkFlag;
ReturnIfBadOctal(cur, 8);
item.Mode = OctalToNumber(cur);
cur += 8;
ReturnIfBadOctal(header.Mode, 8);
ReturnIfBadOctal(header.UID, 8);
ReturnIfBadOctal(header.GID, 8);
ReturnIfBadOctal(header.Size, 12);
ReturnIfBadOctal(header.ModificationTime, 12);
ReturnIfBadOctal(header.CheckSum, 8);
ReturnIfBadOctal(header.DeviceMajor, 8);
ReturnIfBadOctal(header.DeviceMinor, 8);
ReturnIfBadOctal(cur, 8);
item.UID = OctalToNumber(cur);
cur += 8;
item.Mode = OctalToNumber(header.Mode);
item.UID = OctalToNumber(header.UID);
item.GID = OctalToNumber(header.GID);
ReturnIfBadOctal(cur, 8);
item.GID = OctalToNumber(cur);
cur += 8;
ReturnIfBadOctal(cur, 12);
item.Size = OctalToNumber(cur);
cur += 12;
ReturnIfBadOctal(cur, 12);
item.ModificationTime = OctalToNumber(cur);
cur += 12;
item.Size = OctalToNumber(header.Size);
ReturnIfBadOctal(cur, 8);
UInt32 checkSum = OctalToNumber(cur);
memmove(cur, NFileHeader::kCheckSumBlanks, 8);
cur += 8;
item.LinkFlag = *cur++;
Byte linkFlag = item.LinkFlag;
ReadString(cur, NFileHeader::kNameSize, item.LinkName);
cur += NFileHeader::kNameSize;
memmove(item.Magic, cur, 8);
cur += 8;
ReadString(cur, NFileHeader::kUserNameSize, item.UserName);
cur += NFileHeader::kUserNameSize;
ReadString(cur, NFileHeader::kUserNameSize, item.GroupName);
cur += NFileHeader::kUserNameSize;
ReturnIfBadOctal(cur, 8);
item.DeviceMajorDefined = (cur[0] != 0);
if (item.DeviceMajorDefined)
item.DeviceMajor = OctalToNumber(cur);
ReturnIfBadOctal(cur, 8);
item.DeviceMinorDefined = (cur[0] != 0);
if (item.DeviceMinorDefined)
item.DeviceMinor = OctalToNumber(cur);
cur += 8;
if (item.LinkFlag == NFileHeader::NLinkFlag::kLink)
item.Size = 0;
item.ModificationTime = OctalToNumber(header.ModificationTime);
item.LinkName = header.LinkName;
memmove(item.Magic, header.Magic, 8);
item.UserName = header.UserName;
item.GroupName = header.GroupName;
item.DeviceMajorDefined = (header.DeviceMajor[0] != 0);
if (item.DeviceMajorDefined)
item.DeviceMajor = OctalToNumber(header.DeviceMajor);
item.DeviceMinorDefined = (header.DeviceMinor[0] != 0);
if (item.DeviceMinorDefined)
item.DeviceMinor = OctalToNumber(header.DeviceMinor);
UINT32 checkSum = OctalToNumber(header.CheckSum);
memmove(header.CheckSum, NFileHeader::kCheckSumBlanks, 8);
UINT32 checkSumReal = 0;
UInt32 checkSumReal = 0;
for(i = 0; i < NFileHeader::kRecordSize; i++)
checkSumReal += BYTE(record.Padding[i]);
checkSumReal += Byte(record[i]);
if (checkSumReal != checkSum)
return S_FALSE;
@@ -145,12 +190,12 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
{
if (item.Name.Compare(NFileHeader::kLongLink) != 0)
return S_FALSE;
UINT64 headerPosition = item.HeaderPosition;
UInt64 headerPosition = item.HeaderPosition;
UINT32 processedSize;
UInt32 processedSize;
AString fullName;
char *buffer = fullName.GetBuffer((UINT32)item.Size + 1);
RINOK(ReadBytes(buffer, (UINT32)item.Size, processedSize));
char *buffer = fullName.GetBuffer((UInt32)item.Size + 1);
RINOK(ReadBytes(buffer, (UInt32)item.Size, processedSize));
buffer[item.Size] = '\0';
fullName.ReleaseBuffer();
if (processedSize != item.Size)
@@ -166,9 +211,9 @@ HRESULT CInArchive::GetNextItem(bool &filled, CItemEx &item)
return S_OK;
}
HRESULT CInArchive::Skeep(UINT64 numBytes)
HRESULT CInArchive::Skeep(UInt64 numBytes)
{
UINT64 newPostion;
UInt64 newPostion;
RINOK(m_Stream->Seek(numBytes, STREAM_SEEK_CUR, &newPostion));
m_Position += numBytes;
if (m_Position != newPostion)
@@ -177,15 +222,9 @@ HRESULT CInArchive::Skeep(UINT64 numBytes)
}
HRESULT CInArchive::SkeepDataRecords(UINT64 dataSize)
HRESULT CInArchive::SkeepDataRecords(UInt64 dataSize)
{
return Skeep((dataSize + 511) &
#if ( __GNUC__)
0xFFFFFFFFFFFFFE00LL
#else
0xFFFFFFFFFFFFFE00
#endif
);
return Skeep((dataSize + 0x1FF) & (~((UInt64)0x1FF)));
}
}}

View File

@@ -1,7 +1,5 @@
// Archive/TarIn.h
#pragma once
#ifndef __ARCHIVE_TAR_IN_H
#define __ARCHIVE_TAR_IN_H
@@ -16,15 +14,15 @@ namespace NTar {
class CInArchive
{
CMyComPtr<IInStream> m_Stream;
UINT64 m_Position;
UInt64 m_Position;
HRESULT ReadBytes(void *data, UINT32 size, UINT32 &processedSize);
HRESULT ReadBytes(void *data, UInt32 size, UInt32 &processedSize);
public:
HRESULT Open(IInStream *inStream);
HRESULT GetNextItemReal(bool &filled, CItemEx &itemInfo);
HRESULT GetNextItem(bool &filled, CItemEx &itemInfo);
HRESULT Skeep(UINT64 numBytes);
HRESULT SkeepDataRecords(UINT64 dataSize);
HRESULT Skeep(UInt64 numBytes);
HRESULT SkeepDataRecords(UInt64 dataSize);
};
}}

View File

@@ -1,7 +1,5 @@
// Archive/Tar/Item.h
#pragma once
#ifndef __ARCHIVE_TAR_ITEM_H
#define __ARCHIVE_TAR_ITEM_H
@@ -9,6 +7,8 @@
#include "Common/Types.h"
#include "Common/String.h"
#include "../Common/ItemNameUtils.h"
#include "TarHeader.h"
namespace NArchive {
@@ -18,11 +18,11 @@ class CItem
{
public:
AString Name;
UINT32 Mode;
UINT32 UID;
UINT32 GID;
UINT64 Size;
time_t ModificationTime;
UInt32 Mode;
UInt32 UID;
UInt32 GID;
UInt64 Size;
UInt32 ModificationTime;
char LinkFlag;
AString LinkName;
char Magic[8];
@@ -30,9 +30,9 @@ public:
AString GroupName;
bool DeviceMajorDefined;
UINT32 DeviceMajor;
UInt32 DeviceMajor;
bool DeviceMinorDefined;
UINT32 DeviceMinor;
UInt32 DeviceMinor;
bool IsDirectory() const
{
@@ -41,13 +41,7 @@ public:
if (LinkFlag == NFileHeader::NLinkFlag::kOldNormal ||
LinkFlag == NFileHeader::NLinkFlag::kNormal)
{
if (Name.IsEmpty())
return false;
#ifdef WIN32
return (*CharPrevExA(CP_OEMCP, Name, &Name[Name.Length()], 0) == '/');
#else
return (Name[Name.Length() - 1) == '/');
#endif
return NItemName::HasTailSlash(Name, CP_OEMCP);
}
return false;
}
@@ -56,10 +50,10 @@ public:
class CItemEx: public CItem
{
public:
UINT64 HeaderPosition;
UINT64 LongLinkSize;
UINT64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; };
UINT64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; };
UInt64 HeaderPosition;
UInt64 LongLinkSize;
UInt64 GetDataPosition() const { return HeaderPosition + LongLinkSize + NFileHeader::kRecordSize; };
UInt64 GetFullSize() const { return LongLinkSize + NFileHeader::kRecordSize + Size; };
};
}}

View File

@@ -5,14 +5,15 @@
#include "TarOut.h"
#include "TarHeader.h"
#include "Common/IntToString.h"
#include "Windows/Defs.h"
namespace NArchive {
namespace NTar {
HRESULT COutArchive::WriteBytes(const void *buffer, UINT32 size)
HRESULT COutArchive::WriteBytes(const void *buffer, UInt32 size)
{
UINT32 processedSize;
UInt32 processedSize;
RINOK(m_Stream->Write(buffer, size, &processedSize));
if(processedSize != size)
return E_FAIL;
@@ -24,14 +25,14 @@ void COutArchive::Create(ISequentialOutStream *outStream)
m_Stream = outStream;
}
static AString MakeOctalString(UINT64 value)
static AString MakeOctalString(UInt64 value)
{
char s[32];
_ui64toa(value, s, 8);
ConvertUInt64ToString(value, s, 8);
return AString(s) + ' ';
}
static bool MakeOctalString8(char *s, UINT32 value)
static bool MakeOctalString8(char *s, UInt32 value)
{
AString tempString = MakeOctalString(value);
@@ -45,7 +46,7 @@ static bool MakeOctalString8(char *s, UINT32 value)
return true;
}
static bool MakeOctalString12(char *s, UINT64 value)
static bool MakeOctalString12(char *s, UInt64 value)
{
AString tempString = MakeOctalString(value);
const int kMaxSize = 12;
@@ -70,45 +71,63 @@ static bool CopyString(char *dest, const AString &src, int maxSize)
HRESULT COutArchive::WriteHeaderReal(const CItem &item)
{
NFileHeader::CRecord record;
char record[NFileHeader::kRecordSize];
char *cur = record;
int i;
for (i = 0; i < NFileHeader::kRecordSize; i++)
record.Padding[i] = 0;
NFileHeader::CHeader &header = record.Header;
record[i] = 0;
// RETURN_IF_NOT_TRUE(CopyString(header.Name, item.Name, NFileHeader::kNameSize));
if (item.Name.Length() > NFileHeader::kNameSize)
return E_FAIL;
strncpy(header.Name, item.Name, NFileHeader::kNameSize);
strncpy(cur, item.Name, NFileHeader::kNameSize);
cur += NFileHeader::kNameSize;
RETURN_IF_NOT_TRUE(CopyString(header.LinkName, item.LinkName, NFileHeader::kNameSize));
RETURN_IF_NOT_TRUE(CopyString(header.UserName, item.UserName, NFileHeader::kUserNameSize));
RETURN_IF_NOT_TRUE(CopyString(header.GroupName, item.GroupName, NFileHeader::kGroupNameSize));
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.Mode));
cur += 8;
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.UID));
cur += 8;
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.GID));
cur += 8;
RETURN_IF_NOT_TRUE(MakeOctalString8(header.Mode, item.Mode));
RETURN_IF_NOT_TRUE(MakeOctalString8(header.UID, item.UID));
RETURN_IF_NOT_TRUE(MakeOctalString8(header.GID, item.GID));
RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.Size));
cur += 12;
RETURN_IF_NOT_TRUE(MakeOctalString12(cur, item.ModificationTime));
cur += 12;
memmove(cur, NFileHeader::kCheckSumBlanks, 8);
cur += 8;
*cur++ = item.LinkFlag;
RETURN_IF_NOT_TRUE(CopyString(cur, item.LinkName, NFileHeader::kNameSize));
cur += NFileHeader::kNameSize;
memmove(cur, item.Magic, 8);
cur += 8;
RETURN_IF_NOT_TRUE(CopyString(cur, item.UserName, NFileHeader::kUserNameSize));
cur += NFileHeader::kUserNameSize;
RETURN_IF_NOT_TRUE(CopyString(cur, item.GroupName, NFileHeader::kGroupNameSize));
cur += NFileHeader::kUserNameSize;
RETURN_IF_NOT_TRUE(MakeOctalString12(header.Size, item.Size));
RETURN_IF_NOT_TRUE(MakeOctalString12(header.ModificationTime, item.ModificationTime));
header.LinkFlag = item.LinkFlag;
memmove(header.Magic, item.Magic, 8);
if (item.DeviceMajorDefined)
RETURN_IF_NOT_TRUE(MakeOctalString8(header.DeviceMajor, item.DeviceMajor));
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMajor));
cur += 8;
if (item.DeviceMinorDefined)
RETURN_IF_NOT_TRUE(MakeOctalString8(header.DeviceMinor, item.DeviceMinor));
RETURN_IF_NOT_TRUE(MakeOctalString8(cur, item.DeviceMinor));
cur += 8;
memmove(header.CheckSum, NFileHeader::kCheckSumBlanks, 8);
UINT32 checkSumReal = 0;
UInt32 checkSumReal = 0;
for(i = 0; i < NFileHeader::kRecordSize; i++)
checkSumReal += BYTE(record.Padding[i]);
checkSumReal += Byte(record[i]);
RETURN_IF_NOT_TRUE(MakeOctalString8(header.CheckSum, checkSumReal));
RETURN_IF_NOT_TRUE(MakeOctalString8(record + 148, checkSumReal));
return WriteBytes(&record, sizeof(record));
return WriteBytes(record, NFileHeader::kRecordSize);
}
HRESULT COutArchive::WriteHeader(const CItem &item)
@@ -132,24 +151,24 @@ HRESULT COutArchive::WriteHeader(const CItem &item)
return WriteHeaderReal(modifiedItem);
}
HRESULT COutArchive::FillDataResidual(UINT64 dataSize)
HRESULT COutArchive::FillDataResidual(UInt64 dataSize)
{
UINT32 lastRecordSize = UINT32(dataSize & (NFileHeader::kRecordSize - 1));
UInt32 lastRecordSize = UInt32(dataSize & (NFileHeader::kRecordSize - 1));
if (lastRecordSize == 0)
return S_OK;
UINT32 residualSize = NFileHeader::kRecordSize - lastRecordSize;
BYTE residualBytes[NFileHeader::kRecordSize];
for (UINT32 i = 0; i < residualSize; i++)
UInt32 residualSize = NFileHeader::kRecordSize - lastRecordSize;
Byte residualBytes[NFileHeader::kRecordSize];
for (UInt32 i = 0; i < residualSize; i++)
residualBytes[i] = 0;
return WriteBytes(residualBytes, residualSize);
}
HRESULT COutArchive::WriteFinishHeader()
{
NFileHeader::CRecord record;
char record[NFileHeader::kRecordSize];
for (int i = 0; i < NFileHeader::kRecordSize; i++)
record.Padding[i] = 0;
return WriteBytes(&record, sizeof(record));
record[i] = 0;
return WriteBytes(record, NFileHeader::kRecordSize);
}
}}

View File

@@ -1,7 +1,5 @@
// Archive/TarOut.h
#pragma once
#ifndef __ARCHIVE_TAR_OUT_H
#define __ARCHIVE_TAR_OUT_H
@@ -16,12 +14,12 @@ namespace NTar {
class COutArchive
{
CMyComPtr<ISequentialOutStream> m_Stream;
HRESULT WriteBytes(const void *buffer, UINT32 size);
HRESULT WriteBytes(const void *buffer, UInt32 size);
public:
void Create(ISequentialOutStream *outStream);
HRESULT WriteHeaderReal(const CItem &item);
HRESULT WriteHeader(const CItem &item);
HRESULT FillDataResidual(UINT64 dataSize);
HRESULT FillDataResidual(UInt64 dataSize);
HRESULT WriteFinishHeader();
};

View File

@@ -13,14 +13,14 @@
#include "TarOut.h"
#include "TarUpdate.h"
static const UINT64 kOneItemComplexity = 512;
static const UInt64 kOneItemComplexity = 512;
namespace NArchive {
namespace NTar {
static HRESULT CopyBlock(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ICompressProgressInfo *progress,
UINT64 *totalSize = NULL)
UInt64 *totalSize = NULL)
{
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
@@ -38,7 +38,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
COutArchive outArchive;
outArchive.Create(outStream);
UINT64 complexity = 0;
UInt64 complexity = 0;
int i;
for(i = 0; i < updateItems.Size(); i++)
@@ -99,28 +99,31 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
if (updateItem.NewData)
{
item.Size = updateItem.Size;
if (item.Size == UInt64(Int64(-1)))
return E_INVALIDARG;
}
else
{
const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
item.Size = existItemInfo.Size;
}
if (updateItem.NewData || updateItem.NewProperties)
{
RINOK(outArchive.WriteHeader(item));
}
if (updateItem.NewData)
{
CMyComPtr<IInStream> fileInStream;
RINOK(updateCallback->GetStream(updateItem.IndexInClient, &fileInStream));
if (!updateItem.IsDirectory)
CMyComPtr<ISequentialInStream> fileInStream;
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
if (res != S_FALSE)
{
UINT64 totalSize;
RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize));
if (totalSize != item.Size)
return E_FAIL;
RINOK(outArchive.FillDataResidual(item.Size));
RINOK(res);
RINOK(outArchive.WriteHeader(item));
if (!updateItem.IsDirectory)
{
UInt64 totalSize;
RINOK(CopyBlock(fileInStream, outStream, compressProgress, &totalSize));
if (totalSize != item.Size)
return E_FAIL;
RINOK(outArchive.FillDataResidual(item.Size));
}
}
complexity += updateItem.Size;
RINOK(updateCallback->SetOperationResult(
@@ -133,6 +136,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
const CItemEx &existItemInfo = inputItems[updateItem.IndexInArchive];
if (updateItem.NewProperties)
{
RINOK(outArchive.WriteHeader(item));
RINOK(inStream->Seek(existItemInfo.GetDataPosition(),
STREAM_SEEK_SET, NULL));
streamSpec->Init(inStream, existItemInfo.Size);

View File

@@ -1,7 +1,5 @@
// Tar/Update.h
#pragma once
#ifndef __TAR_UPDATE_H
#define __TAR_UPDATE_H
@@ -22,8 +20,8 @@ struct CUpdateItemInfo
int IndexInArchive;
int IndexInClient;
time_t Time;
UINT64 Size;
UInt32 Time;
UInt64 Size;
AString Name;
bool IsDirectory;
};

View File

@@ -75,8 +75,8 @@ IDI_ICON1 ICON DISCARDABLE "Tar.ico"
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,9,2,0
PRODUCTVERSION 3,9,2,0
FILEVERSION 4,13,0,0
PRODUCTVERSION 4,13,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -94,14 +94,14 @@ BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "Tar Plugin for 7-Zip\0"
VALUE "FileVersion", "3, 9, 2, 0\0"
VALUE "FileVersion", "4, 13, 0, 0\0"
VALUE "InternalName", "tar\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2004 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "tar.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "3, 9, 2, 0\0"
VALUE "ProductVersion", "4, 13, 0, 0\0"
VALUE "SpecialBuild", "\0"
END
END