summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp519
1 files changed, 394 insertions, 125 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
index 5499f2a1a9f..5e2860dd08d 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/UpdateCallback.cpp
@@ -2,7 +2,28 @@
#include "StdAfx.h"
-#ifndef _7ZIP_ST
+// #include <stdio.h>
+
+#ifndef _WIN32
+// #include <grp.h>
+// #include <pwd.h>
+/*
+inclusion of <sys/sysmacros.h> by <sys/types.h> is deprecated since glibc 2.25.
+Since glibc 2.3.3, macros have been aliases for three GNU-specific
+functions: gnu_dev_makedev(), gnu_dev_major(), and gnu_dev_minor()
+*/
+// for major()/minor():
+#include <sys/types.h>
+#if defined(__FreeBSD__) || defined(BSD) || defined(__APPLE__)
+#else
+#ifndef major
+#include <sys/sysmacros.h>
+#endif
+#endif
+
+#endif // _WIN32
+
+#ifndef Z7_ST
#include "../../../Windows/Synchronization.h"
#endif
@@ -10,6 +31,7 @@
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/Wildcard.h"
+#include "../../../Common/UTFConvert.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
@@ -20,14 +42,14 @@
#include "UpdateCallback.h"
#if defined(_WIN32) && !defined(UNDER_CE)
-#define _USE_SECURITY_CODE
+#define Z7_USE_SECURITY_CODE
#include "../../../Windows/SecurityUtils.h"
#endif
using namespace NWindows;
using namespace NFile;
-#ifndef _7ZIP_ST
+#ifndef Z7_ST
static NSynchronization::CCriticalSection g_CriticalSection;
#define MT_LOCK NSynchronization::CCriticalSectionLock lock(g_CriticalSection);
#else
@@ -35,12 +57,32 @@ static NSynchronization::CCriticalSection g_CriticalSection;
#endif
-#ifdef _USE_SECURITY_CODE
+#ifdef Z7_USE_SECURITY_CODE
bool InitLocalPrivileges();
#endif
CArchiveUpdateCallback::CArchiveUpdateCallback():
- _hardIndex_From((UInt32)(Int32)-1),
+ PreserveATime(false),
+ ShareForWrite(false),
+ StopAfterOpenError(false),
+ StdInMode(false),
+
+ KeepOriginalItemNames(false),
+ StoreNtSecurity(false),
+ StoreHardLinks(false),
+ StoreSymLinks(false),
+
+ #ifndef _WIN32
+ StoreOwnerId(false),
+ StoreOwnerName(false),
+ #endif
+
+ /*
+ , Need_ArcMTime_Report(false),
+ , ArcMTime_WasReported(false),
+ */
+ Need_LatestMTime(false),
+ LatestMTime_Defined(false),
Callback(NULL),
@@ -51,38 +93,33 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
ArcItems(NULL),
UpdatePairs(NULL),
NewNames(NULL),
+ Comment(NULL),
+ CommentIndex(-1),
- ShareForWrite(false),
- StdInMode(false),
-
- KeepOriginalItemNames(false),
- StoreNtSecurity(false),
- StoreHardLinks(false),
- StoreSymLinks(false),
-
- ProcessedItemsStatuses(NULL)
+ ProcessedItemsStatuses(NULL),
+ _hardIndex_From((UInt32)(Int32)-1)
{
- #ifdef _USE_SECURITY_CODE
+ #ifdef Z7_USE_SECURITY_CODE
_saclEnabled = InitLocalPrivileges();
#endif
}
-STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size)
+Z7_COM7F_IMF(CArchiveUpdateCallback::SetTotal(UInt64 size))
{
COM_TRY_BEGIN
return Callback->SetTotal(size);
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue)
+Z7_COM7F_IMF(CArchiveUpdateCallback::SetCompleted(const UInt64 *completeValue))
{
COM_TRY_BEGIN
return Callback->SetCompleted(completeValue);
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
+Z7_COM7F_IMF(CArchiveUpdateCallback::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize))
{
COM_TRY_BEGIN
return Callback->SetRatioInfo(inSize, outSize);
@@ -103,17 +140,17 @@ static const CStatProp kProps[] =
{ NULL, kpidIsAnti, VT_BOOL}
};
-STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
+Z7_COM7F_IMF(CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG **)
{
- return CStatPropEnumerator::CreateEnumerator(kProps, ARRAY_SIZE(kProps), enumerator);
+ return CStatPropEnumerator::CreateEnumerator(kProps, Z7_ARRAY_SIZE(kProps), enumerator);
}
*/
-STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
- Int32 *newData, Int32 *newProps, UInt32 *indexInArchive)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
+ Int32 *newData, Int32 *newProps, UInt32 *indexInArchive))
{
COM_TRY_BEGIN
- RINOK(Callback->CheckBreak());
+ RINOK(Callback->CheckBreak())
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (newData) *newData = BoolToInt(up.NewData);
if (newProps) *newProps = BoolToInt(up.NewProps);
@@ -121,35 +158,37 @@ STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index,
{
*indexInArchive = (UInt32)(Int32)-1;
if (up.ExistInArchive())
- *indexInArchive = (ArcItems == 0) ? up.ArcIndex : (*ArcItems)[up.ArcIndex].IndexInServer;
+ *indexInArchive = ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex;
}
return S_OK;
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value)
+
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootProp(PROPID propID, PROPVARIANT *value))
{
NCOM::CPropVariant prop;
switch (propID)
{
case kpidIsDir: prop = true; break;
- case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->Attrib; break;
- case kpidCTime: if (ParentDirItem) prop = ParentDirItem->CTime; break;
- case kpidATime: if (ParentDirItem) prop = ParentDirItem->ATime; break;
- case kpidMTime: if (ParentDirItem) prop = ParentDirItem->MTime; break;
+ case kpidAttrib: if (ParentDirItem) prop = ParentDirItem->GetWinAttrib(); break;
+ case kpidCTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->CTime); break;
+ case kpidATime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->ATime); break;
+ case kpidMTime: if (ParentDirItem) PropVariant_SetFrom_FiTime(prop, ParentDirItem->MTime); break;
+ case kpidArcFileName: if (!ArcFileName.IsEmpty()) prop = ArcFileName; break;
}
prop.Detach(value);
return S_OK;
}
-STDMETHODIMP CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetParent(UInt32 /* index */, UInt32 *parent, UInt32 *parentType))
{
*parentType = NParentType::kDir;
*parent = (UInt32)(Int32)-1;
return S_OK;
}
-STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps))
{
*numProps = 0;
if (StoreNtSecurity)
@@ -157,25 +196,27 @@ STDMETHODIMP CArchiveUpdateCallback::GetNumRawProps(UInt32 *numProps)
return S_OK;
}
-STDMETHODIMP CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawPropInfo(UInt32 /* index */, BSTR *name, PROPID *propID))
{
*name = NULL;
*propID = kpidNtSecure;
return S_OK;
}
-STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
- #ifdef _USE_SECURITY_CODE
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetRootRawProp(PROPID
propID
- #endif
- , const void **data, UInt32 *dataSize, UInt32 *propType)
+ , const void **data, UInt32 *dataSize, UInt32 *propType))
{
- *data = 0;
+ #ifndef Z7_USE_SECURITY_CODE
+ UNUSED_VAR(propID)
+ #endif
+
+ *data = NULL;
*dataSize = 0;
*propType = 0;
if (!StoreNtSecurity)
return S_OK;
- #ifdef _USE_SECURITY_CODE
+ #ifdef Z7_USE_SECURITY_CODE
if (propID == kpidNtSecure)
{
if (StdInMode)
@@ -185,7 +226,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
{
if (ParentDirItem->SecureIndex < 0)
return S_OK;
- const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[ParentDirItem->SecureIndex];
+ const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)ParentDirItem->SecureIndex];
*data = buf;
*dataSize = (UInt32)buf.Size();
*propType = NPropDataType::kRaw;
@@ -199,12 +240,10 @@ STDMETHODIMP CArchiveUpdateCallback::GetRootRawProp(PROPID
return S_OK;
}
-// #ifdef _USE_SECURITY_CODE
-// #endif
-STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType))
{
- *data = 0;
+ *data = NULL;
*dataSize = 0;
*propType = 0;
@@ -217,7 +256,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (up.UseArcProps && up.ExistInArchive() && Arc->GetRawProps)
return Arc->GetRawProps->GetRawProp(
- ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex,
+ ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex,
propID, data, dataSize, propType);
{
/*
@@ -227,29 +266,30 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con
if (up.IsAnti)
return S_OK;
- #ifndef UNDER_CE
- const CDirItem &di = DirItems->Items[up.DirIndex];
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
#endif
- #ifdef _USE_SECURITY_CODE
+ #ifdef Z7_USE_SECURITY_CODE
if (propID == kpidNtSecure)
{
if (!StoreNtSecurity)
return S_OK;
if (di.SecureIndex < 0)
return S_OK;
- const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[di.SecureIndex];
+ const CByteBuffer &buf = DirItems->SecureBlocks.Bufs[(unsigned)di.SecureIndex];
*data = buf;
*dataSize = (UInt32)buf.Size();
*propType = NPropDataType::kRaw;
}
else
#endif
+ if (propID == kpidNtReparse)
{
- // propID == kpidNtReparse
if (!StoreSymLinks)
return S_OK;
- #ifndef UNDER_CE
+ #if defined(_WIN32) && !defined(UNDER_CE)
+ // we use ReparseData2 instead of ReparseData for WIM format
const CByteBuffer *buf = &di.ReparseData2;
if (buf->Size() == 0)
buf = &di.ReparseData;
@@ -269,7 +309,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetRawProp(UInt32 index, PROPID propID, con
return S_OK;
}
-#ifndef UNDER_CE
+#if defined(_WIN32) && !defined(UNDER_CE)
static UString GetRelativePath(const UString &to, const UString &from)
{
@@ -300,7 +340,7 @@ static UString GetRelativePath(const UString &to, const UString &from)
unsigned k;
for (k = i + 1; k < partsFrom.Size(); k++)
- s += L".." WSTRING_PATH_SEPARATOR;
+ s += ".." STRING_PATH_SEPARATOR;
for (k = i; k < partsTo.Size(); k++)
{
@@ -314,7 +354,7 @@ static UString GetRelativePath(const UString &to, const UString &from)
#endif
-STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
{
COM_TRY_BEGIN
const CUpdatePair2 &up = (*UpdatePairs)[index];
@@ -337,21 +377,25 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
prop.Detach(value);
return S_OK;
}
+
+ #if !defined(UNDER_CE)
+
if (up.DirIndex >= 0)
{
- #ifndef UNDER_CE
- const CDirItem &di = DirItems->Items[up.DirIndex];
+ const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
+
+ #ifdef _WIN32
// if (di.IsDir())
{
CReparseAttr attr;
if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
{
- UString simpleName = attr.GetPath();
- if (attr.IsRelative())
+ const UString simpleName = attr.GetPath();
+ if (!attr.IsSymLink_WSL() && attr.IsRelative_Win())
prop = simpleName;
else
{
- const FString phyPath = DirItems->GetPhyPath(up.DirIndex);
+ const FString phyPath = DirItems->GetPhyPath((unsigned)up.DirIndex);
FString fullPath;
if (NDir::MyGetFullPathName(phyPath, fullPath))
{
@@ -362,8 +406,26 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
return S_OK;
}
}
- #endif
+
+ #else // _WIN32
+
+ if (di.ReparseData.Size() != 0)
+ {
+ AString utf;
+ utf.SetFrom_CalcLen((const char *)(const Byte *)di.ReparseData, (unsigned)di.ReparseData.Size());
+
+ UString us;
+ if (ConvertUTF8ToUnicode(utf, us))
+ {
+ prop = us;
+ prop.Detach(value);
+ return S_OK;
+ }
+ }
+
+ #endif // _WIN32
}
+ #endif // !defined(UNDER_CE)
}
else if (propID == kpidHardLink)
{
@@ -371,7 +433,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
{
const CKeyKeyValPair &pair = _map[_hardIndex_To];
const CUpdatePair2 &up2 = (*UpdatePairs)[pair.Value];
- prop = DirItems->GetLogPath(up2.DirIndex);
+ prop = DirItems->GetLogPath((unsigned)up2.DirIndex);
prop.Detach(value);
return S_OK;
}
@@ -395,30 +457,75 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
}
}
else if (propID == kpidPath && up.NewNameIndex >= 0)
- prop = (*NewNames)[up.NewNameIndex];
+ prop = (*NewNames)[(unsigned)up.NewNameIndex];
+ else if (propID == kpidComment
+ && CommentIndex >= 0
+ && (unsigned)CommentIndex == index
+ && Comment)
+ prop = *Comment;
else if (propID == kpidShortName && up.NewNameIndex >= 0 && up.IsMainRenameItem)
{
// we can generate new ShortName here;
}
else if ((up.UseArcProps || (KeepOriginalItemNames && (propID == kpidPath || propID == kpidIsAltStream)))
&& up.ExistInArchive() && Archive)
- return Archive->GetProperty(ArcItems ? (*ArcItems)[up.ArcIndex].IndexInServer : up.ArcIndex, propID, value);
+ return Archive->GetProperty(ArcItems ? (*ArcItems)[(unsigned)up.ArcIndex].IndexInServer : (UInt32)(Int32)up.ArcIndex, propID, value);
else if (up.ExistOnDisk())
{
- const CDirItem &di = DirItems->Items[up.DirIndex];
+ const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
switch (propID)
{
- case kpidPath: prop = DirItems->GetLogPath(up.DirIndex); break;
+ case kpidPath: prop = DirItems->GetLogPath((unsigned)up.DirIndex); break;
case kpidIsDir: prop = di.IsDir(); break;
- case kpidSize: prop = di.IsDir() ? (UInt64)0 : di.Size; break;
- case kpidAttrib: prop = di.Attrib; break;
- case kpidCTime: prop = di.CTime; break;
- case kpidATime: prop = di.ATime; break;
- case kpidMTime: prop = di.MTime; break;
+ case kpidSize: prop = (UInt64)(di.IsDir() ? (UInt64)0 : di.Size); break;
+ case kpidCTime: PropVariant_SetFrom_FiTime(prop, di.CTime); break;
+ case kpidATime: PropVariant_SetFrom_FiTime(prop, di.ATime); break;
+ case kpidMTime: PropVariant_SetFrom_FiTime(prop, di.MTime); break;
+ case kpidAttrib: prop = (UInt32)di.GetWinAttrib(); break;
+ case kpidPosixAttrib: prop = (UInt32)di.GetPosixAttrib(); break;
+
+ #if defined(_WIN32)
case kpidIsAltStream: prop = di.IsAltStream; break;
- #if defined(_WIN32) && !defined(UNDER_CE)
// case kpidShortName: prop = di.ShortName; break;
- #endif
+ #else
+
+ #if defined(__APPLE__)
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wsign-conversion"
+ #endif
+
+ case kpidDeviceMajor:
+ /*
+ printf("\ndi.mode = %o\n", di.mode);
+ printf("\nst.st_rdev major = %d\n", (unsigned)major(di.rdev));
+ printf("\nst.st_rdev minor = %d\n", (unsigned)minor(di.rdev));
+ */
+ if (S_ISCHR(di.mode) || S_ISBLK(di.mode))
+ prop = (UInt32)major(di.rdev);
+ break;
+
+ case kpidDeviceMinor:
+ if (S_ISCHR(di.mode) || S_ISBLK(di.mode))
+ prop = (UInt32)minor(di.rdev);
+ break;
+
+ #if defined(__APPLE__)
+ #pragma GCC diagnostic pop
+ #endif
+
+ // case kpidDevice: if (S_ISCHR(di.mode) || S_ISBLK(di.mode)) prop = (UInt64)(di.rdev); break;
+
+ case kpidUserId: if (StoreOwnerId) prop = (UInt32)di.uid; break;
+ case kpidGroupId: if (StoreOwnerId) prop = (UInt32)di.gid; break;
+ case kpidUser:
+ if (di.OwnerNameIndex >= 0)
+ prop = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex];
+ break;
+ case kpidGroup:
+ if (di.OwnerGroupIndex >= 0)
+ prop = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex];
+ break;
+ #endif
}
}
prop.Detach(value);
@@ -426,11 +533,22 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
COM_TRY_END
}
-#ifndef _7ZIP_ST
-static NSynchronization::CCriticalSection CS;
+#ifndef Z7_ST
+static NSynchronization::CCriticalSection g_CS;
#endif
-STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode)
+void CArchiveUpdateCallback::UpdateProcessedItemStatus(unsigned dirIndex)
+{
+ if (ProcessedItemsStatuses)
+ {
+ #ifndef Z7_ST
+ NSynchronization::CCriticalSectionLock lock(g_CS);
+ #endif
+ ProcessedItemsStatuses[dirIndex] = 1;
+ }
+}
+
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStream **inStream, UInt32 mode))
{
COM_TRY_BEGIN
*inStream = NULL;
@@ -438,7 +556,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
if (!up.NewData)
return E_FAIL;
- RINOK(Callback->CheckBreak());
+ RINOK(Callback->CheckBreak())
// RINOK(Callback->Finalize());
bool isDir = IsDir(up);
@@ -447,10 +565,10 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
{
UString name;
if (up.ArcIndex >= 0)
- name = (*ArcItems)[up.ArcIndex].Name;
+ name = (*ArcItems)[(unsigned)up.ArcIndex].Name;
else if (up.DirIndex >= 0)
- name = DirItems->GetLogPath(up.DirIndex);
- RINOK(Callback->GetStream(name, isDir, true, mode));
+ name = DirItems->GetLogPath((unsigned)up.DirIndex);
+ RINOK(Callback->GetStream(name, isDir, true, mode))
/* 9.33: fixed. Handlers expect real stream object for files, even for anti-file.
so we return empty stream */
@@ -465,7 +583,7 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
return S_OK;
}
- RINOK(Callback->GetStream(DirItems->GetLogPath(up.DirIndex), isDir, false, mode));
+ RINOK(Callback->GetStream(DirItems->GetLogPath((unsigned)up.DirIndex), isDir, false, mode))
if (isDir)
return S_OK;
@@ -482,32 +600,121 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
}
else
{
+ #if !defined(UNDER_CE)
+ const CDirItem &di = DirItems->Items[(unsigned)up.DirIndex];
+ if (di.AreReparseData())
+ {
+ /*
+ // we still need DeviceIoControlOut() instead of Read
+ if (!inStreamSpec->File.OpenReparse(path))
+ {
+ return Callback->OpenFileError(path, ::GetLastError());
+ }
+ */
+ // 20.03: we use Reparse Data instead of real data
+
+ CBufInStream *inStreamSpec = new CBufInStream();
+ CMyComPtr<ISequentialInStream> inStreamLoc = inStreamSpec;
+ inStreamSpec->Init(di.ReparseData, di.ReparseData.Size());
+ *inStream = inStreamLoc.Detach();
+
+ UpdateProcessedItemStatus((unsigned)up.DirIndex);
+ return S_OK;
+ }
+ #endif // !defined(UNDER_CE)
+
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
+ /*
+ // for debug:
+ #ifdef _WIN32
+ inStreamSpec->StoreOwnerName = true;
+ inStreamSpec->OwnerName = "user_name";
+ inStreamSpec->OwnerName += di.Name;
+ inStreamSpec->OwnerName += "11111111112222222222222333333333333";
+ inStreamSpec->OwnerGroup = "gname_";
+ inStreamSpec->OwnerGroup += inStreamSpec->OwnerName;
+ #endif
+ */
+
+ #ifndef _WIN32
+ inStreamSpec->StoreOwnerId = StoreOwnerId;
+ inStreamSpec->StoreOwnerName = StoreOwnerName;
+
+ // if (StoreOwner)
+ {
+ inStreamSpec->_uid = di.uid;
+ inStreamSpec->_gid = di.gid;
+ if (di.OwnerNameIndex >= 0)
+ inStreamSpec->OwnerName = DirItems->OwnerNameMap.Strings[(unsigned)di.OwnerNameIndex];
+ if (di.OwnerGroupIndex >= 0)
+ inStreamSpec->OwnerGroup = DirItems->OwnerGroupMap.Strings[(unsigned)di.OwnerGroupIndex];
+ }
+ #endif
+
inStreamSpec->SupportHardLinks = StoreHardLinks;
- inStreamSpec->Callback = this;
- inStreamSpec->CallbackRef = index;
+ const bool preserveATime = (PreserveATime
+ || mode == NUpdateNotifyOp::kAnalyze); // 22.00 : we don't change access time in Analyze pass.
+ inStreamSpec->Set_PreserveATime(preserveATime);
- const FString path = DirItems->GetPhyPath(up.DirIndex);
+ const FString path = DirItems->GetPhyPath((unsigned)up.DirIndex);
_openFiles_Indexes.Add(index);
_openFiles_Paths.Add(path);
+ // _openFiles_Streams.Add(inStreamSpec);
- #if defined(_WIN32) && !defined(UNDER_CE)
- if (DirItems->Items[up.DirIndex].AreReparseData())
+ /* 21.02 : we set Callback/CallbackRef after _openFiles_Indexes adding
+ for correct working if exception was raised in GetPhyPath */
+ inStreamSpec->Callback = this;
+ inStreamSpec->CallbackRef = index;
+
+ if (!inStreamSpec->OpenShared(path, ShareForWrite))
{
- if (!inStreamSpec->File.OpenReparse(path))
+ bool isOpen = false;
+ if (preserveATime)
{
- return Callback->OpenFileError(path, ::GetLastError());
+ inStreamSpec->Set_PreserveATime(false);
+ isOpen = inStreamSpec->OpenShared(path, ShareForWrite);
+ }
+ if (!isOpen)
+ {
+ const DWORD error = ::GetLastError();
+ const HRESULT hres = Callback->OpenFileError(path, error);
+ if (hres == S_OK || hres == S_FALSE)
+ if (StopAfterOpenError ||
+ // v23: we check also for some critical errors:
+ #ifdef _WIN32
+ error == ERROR_NO_SYSTEM_RESOURCES
+ #else
+ error == EMFILE
+ #endif
+ )
+ {
+ if (error == 0)
+ return E_FAIL;
+ return HRESULT_FROM_WIN32(error);
+ }
+ return hres;
}
}
- else
- #endif
- if (!inStreamSpec->OpenShared(path, ShareForWrite))
+
+ /*
+ {
+ // for debug:
+ Byte b = 0;
+ UInt32 processedSize = 0;
+ if (inStreamSpec->Read(&b, 1, &processedSize) != S_OK ||
+ processedSize != 1)
+ return E_FAIL;
+ }
+ */
+
+ if (Need_LatestMTime)
{
- return Callback->OpenFileError(path, ::GetLastError());
+ inStreamSpec->ReloadProps();
}
+ // #if defined(Z7_FILE_STREAMS_USE_WIN_FILE) || !defined(_WIN32)
if (StoreHardLinks)
{
CStreamFileProps props;
@@ -519,8 +726,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
pair.Key1 = props.VolID;
pair.Key2 = props.FileID_Low;
pair.Value = index;
- unsigned numItems = _map.Size();
- unsigned pairIndex = _map.AddToUniqueSorted2(pair);
+ const unsigned numItems = _map.Size();
+ const unsigned pairIndex = _map.AddToUniqueSorted2(pair);
if (numItems == _map.Size())
{
// const CKeyKeyValPair &pair2 = _map.Pairs[pairIndex];
@@ -532,14 +739,9 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
}
}
}
+ // #endif
- if (ProcessedItemsStatuses)
- {
- #ifndef _7ZIP_ST
- NSynchronization::CCriticalSectionLock lock(CS);
- #endif
- ProcessedItemsStatuses[(unsigned)up.DirIndex] = 1;
- }
+ UpdateProcessedItemStatus((unsigned)up.DirIndex);
*inStream = inStreamLoc.Detach();
}
@@ -547,14 +749,14 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 opRes)
+Z7_COM7F_IMF(CArchiveUpdateCallback::SetOperationResult(Int32 opRes))
{
COM_TRY_BEGIN
return Callback->SetOperationResult(opRes);
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream))
{
COM_TRY_BEGIN
return GetStream2(index, inStream,
@@ -564,10 +766,12 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op)
+Z7_COM7F_IMF(CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 index, UInt32 op))
{
COM_TRY_BEGIN
+ // if (op == NUpdateNotifyOp::kOpFinished) return Callback->ReportFinished(indexType, index);
+
bool isDir = false;
if (indexType == NArchive::NEventIndexType::kOutArcIndex)
@@ -578,11 +782,11 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
const CUpdatePair2 &up = (*UpdatePairs)[index];
if (up.ExistOnDisk())
{
- name = DirItems->GetLogPath(up.DirIndex);
- isDir = DirItems->Items[up.DirIndex].IsDir();
+ name = DirItems->GetLogPath((unsigned)up.DirIndex);
+ isDir = DirItems->Items[(unsigned)up.DirIndex].IsDir();
}
}
- return Callback->ReportUpdateOpeartion(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
+ return Callback->ReportUpdateOperation(op, name.IsEmpty() ? NULL : name.Ptr(), isDir);
}
wchar_t temp[16];
@@ -601,9 +805,9 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
}
else if (Arc)
{
- RINOK(Arc->GetItemPath(index, s2));
+ RINOK(Arc->GetItem_Path(index, s2))
s = s2;
- RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir));
+ RINOK(Archive_IsItem_Dir(Arc->Archive, index, isDir))
}
}
}
@@ -617,12 +821,12 @@ STDMETHODIMP CArchiveUpdateCallback::ReportOperation(UInt32 indexType, UInt32 in
if (!s)
s = L"";
- return Callback->ReportUpdateOpeartion(op, s, isDir);
+ return Callback->ReportUpdateOperation(op, s, isDir);
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes)
+Z7_COM7F_IMF(CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt32 index, Int32 opRes))
{
COM_TRY_BEGIN
@@ -656,12 +860,12 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3
s = (*ArcItems)[index].Name;
else if (Arc)
{
- RINOK(Arc->GetItemPath(index, s2));
+ RINOK(Arc->GetItem_Path(index, s2))
s = s2;
}
if (Archive)
{
- RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted));
+ RINOK(Archive_GetItemBoolProp(Archive, index, kpidEncrypted, isEncrypted))
}
}
}
@@ -677,7 +881,52 @@ STDMETHODIMP CArchiveUpdateCallback::ReportExtractResult(UInt32 indexType, UInt3
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
+
+/*
+Z7_COM7F_IMF(CArchiveUpdateCallback::DoNeedArcProp(PROPID propID, Int32 *answer))
+{
+ *answer = 0;
+ if (Need_ArcMTime_Report && propID == kpidComboMTime)
+ *answer = 1;
+ return S_OK;
+}
+
+Z7_COM7F_IMF(CArchiveUpdateCallback::ReportProp(UInt32 indexType, UInt32 index, PROPID propID, const PROPVARIANT *value))
+{
+ if (indexType == NArchive::NEventIndexType::kArcProp)
+ {
+ if (propID == kpidComboMTime)
+ {
+ ArcMTime_WasReported = true;
+ if (value->vt == VT_FILETIME)
+ {
+ Reported_ArcMTime.Set_From_Prop(*value);
+ Reported_ArcMTime.Def = true;
+ }
+ else
+ {
+ Reported_ArcMTime.Clear();
+ if (value->vt != VT_EMPTY)
+ return E_FAIL; // for debug
+ }
+ }
+ }
+ return Callback->ReportProp(indexType, index, propID, value);
+}
+
+Z7_COM7F_IMF(CArchiveUpdateCallback::ReportRawProp(UInt32 indexType, UInt32 index,
+ PROPID propID, const void *data, UInt32 dataSize, UInt32 propType))
+{
+ return Callback->ReportRawProp(indexType, index, propID, data, dataSize, propType);
+}
+
+Z7_COM7F_IMF(CArchiveUpdateCallback::ReportFinished(UInt32 indexType, UInt32 index, Int32 opRes))
+{
+ return Callback->ReportFinished(indexType, index, opRes);
+}
+*/
+
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size))
{
if (VolumesSizes.Size() == 0)
return S_FALSE;
@@ -687,35 +936,35 @@ STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
return S_OK;
}
-STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
+Z7_COM7F_IMF(CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream))
{
COM_TRY_BEGIN
- FChar temp[16];
+ char temp[16];
ConvertUInt32ToString(index + 1, temp);
- FString res = temp;
+ FString res (temp);
while (res.Len() < 2)
res.InsertAtFront(FTEXT('0'));
FString fileName = VolName;
- fileName += FTEXT('.');
+ fileName.Add_Dot();
fileName += res;
fileName += VolExt;
COutFileStream *streamSpec = new COutFileStream;
CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
if (!streamSpec->Create(fileName, false))
- return ::GetLastError();
+ return GetLastError_noZero_HRESULT();
*volumeStream = streamLoc.Detach();
return S_OK;
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
+Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password))
{
COM_TRY_BEGIN
return Callback->CryptoGetTextPassword2(passwordIsDefined, password);
COM_TRY_END
}
-STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
+Z7_COM7F_IMF(CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password))
{
COM_TRY_BEGIN
return Callback->CryptoGetTextPassword(password);
@@ -724,15 +973,18 @@ STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword(BSTR *password)
HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
{
- if (error == ERROR_LOCK_VIOLATION)
+ #ifdef _WIN32 // FIX IT !!!
+ // why did we check only for ERROR_LOCK_VIOLATION ?
+ // if (error == ERROR_LOCK_VIOLATION)
+ #endif
{
MT_LOCK
- UInt32 index = (UInt32)val;
+ const UInt32 index = (UInt32)val;
FOR_VECTOR(i, _openFiles_Indexes)
{
if (_openFiles_Indexes[i] == index)
{
- RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error));
+ RINOK(Callback->ReadingFileError(_openFiles_Paths[i], error))
break;
}
}
@@ -740,18 +992,35 @@ HRESULT CArchiveUpdateCallback::InFileStream_On_Error(UINT_PTR val, DWORD error)
return HRESULT_FROM_WIN32(error);
}
-void CArchiveUpdateCallback::InFileStream_On_Destroy(UINT_PTR val)
+void CArchiveUpdateCallback::InFileStream_On_Destroy(CInFileStream *stream, UINT_PTR val)
{
MT_LOCK
- UInt32 index = (UInt32)val;
+ if (Need_LatestMTime)
+ {
+ if (stream->_info_WasLoaded)
+ {
+ const CFiTime &ft = ST_MTIME(stream->_info);
+ if (!LatestMTime_Defined
+ || Compare_FiTime(&LatestMTime, &ft) < 0)
+ LatestMTime = ft;
+ LatestMTime_Defined = true;
+ }
+ }
+ const UInt32 index = (UInt32)val;
FOR_VECTOR(i, _openFiles_Indexes)
{
if (_openFiles_Indexes[i] == index)
{
_openFiles_Indexes.Delete(i);
_openFiles_Paths.Delete(i);
+ // _openFiles_Streams.Delete(i);
return;
}
}
- throw 20141125;
+ /* 21.02 : this function can be called in destructor.
+ And destructor can be called after some exception.
+ If we don't want to throw exception in desctructors or after another exceptions,
+ we must disable the code below that raises new exception.
+ */
+ // throw 20141125;
}