mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 12:07:08 -06:00
124 lines
3.4 KiB
C++
Executable File
124 lines
3.4 KiB
C++
Executable File
// Tar/HandlerOut.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "Common/StringConvert.h"
|
|
#include "Common/ComTry.h"
|
|
|
|
#include "Windows/PropVariant.h"
|
|
#include "Windows/Time.h"
|
|
|
|
#include "../Common/ItemNameUtils.h"
|
|
|
|
#include "TarHandler.h"
|
|
#include "TarUpdate.h"
|
|
|
|
using namespace NWindows;
|
|
using namespace NCOM;
|
|
using namespace NTime;
|
|
|
|
namespace NArchive {
|
|
namespace NTar {
|
|
|
|
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
|
|
{
|
|
*type = NFileTimeType::kUnix;
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
|
|
IArchiveUpdateCallback *updateCallback)
|
|
{
|
|
COM_TRY_BEGIN
|
|
CObjectVector<CUpdateItemInfo> updateItems;
|
|
for(UInt32 i = 0; i < numItems; i++)
|
|
{
|
|
CUpdateItemInfo updateItem;
|
|
Int32 newData;
|
|
Int32 newProperties;
|
|
UInt32 indexInArchive;
|
|
if (!updateCallback)
|
|
return E_FAIL;
|
|
RINOK(updateCallback->GetUpdateItemInfo(i,
|
|
&newData, &newProperties, &indexInArchive));
|
|
updateItem.NewProperties = IntToBool(newProperties);
|
|
updateItem.NewData = IntToBool(newData);
|
|
updateItem.IndexInArchive = indexInArchive;
|
|
updateItem.IndexInClient = i;
|
|
|
|
if (IntToBool(newProperties))
|
|
{
|
|
FILETIME utcTime;
|
|
UString name;
|
|
bool isDirectoryStatusDefined;
|
|
UInt32 attributes;
|
|
{
|
|
NCOM::CPropVariant propVariant;
|
|
RINOK(updateCallback->GetProperty(i, kpidAttributes, &propVariant));
|
|
if (propVariant.vt == VT_EMPTY)
|
|
attributes = 0;
|
|
else if (propVariant.vt != VT_UI4)
|
|
return E_INVALIDARG;
|
|
else
|
|
attributes = propVariant.ulVal;
|
|
}
|
|
{
|
|
NCOM::CPropVariant propVariant;
|
|
RINOK(updateCallback->GetProperty(i, kpidLastWriteTime, &propVariant));
|
|
if (propVariant.vt != VT_FILETIME)
|
|
return E_INVALIDARG;
|
|
utcTime = propVariant.filetime;
|
|
}
|
|
{
|
|
NCOM::CPropVariant propVariant;
|
|
RINOK(updateCallback->GetProperty(i, kpidPath, &propVariant));
|
|
if (propVariant.vt == VT_EMPTY)
|
|
name.Empty();
|
|
else if (propVariant.vt != VT_BSTR)
|
|
return E_INVALIDARG;
|
|
else
|
|
name = propVariant.bstrVal;
|
|
}
|
|
{
|
|
NCOM::CPropVariant propVariant;
|
|
RINOK(updateCallback->GetProperty(i, kpidIsFolder, &propVariant));
|
|
if (propVariant.vt == VT_EMPTY)
|
|
isDirectoryStatusDefined = false;
|
|
else if (propVariant.vt != VT_BOOL)
|
|
return E_INVALIDARG;
|
|
else
|
|
{
|
|
updateItem.IsDirectory = (propVariant.boolVal != VARIANT_FALSE);
|
|
isDirectoryStatusDefined = true;
|
|
}
|
|
}
|
|
updateItem.Name = UnicodeStringToMultiByte(
|
|
NItemName::MakeLegalName(name), CP_OEMCP);
|
|
if (!isDirectoryStatusDefined)
|
|
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;
|
|
{
|
|
NCOM::CPropVariant propVariant;
|
|
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
|
|
if (propVariant.vt != VT_UI8)
|
|
return E_INVALIDARG;
|
|
size = propVariant.uhVal.QuadPart;
|
|
}
|
|
updateItem.Size = size;
|
|
}
|
|
updateItems.Add(updateItem);
|
|
}
|
|
return UpdateArchive(_inStream, outStream, _items, updateItems, updateCallback);
|
|
COM_TRY_END
|
|
}
|
|
|
|
}}
|