mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-09 04:07:08 -06:00
18.00
This commit is contained in:
@@ -124,6 +124,7 @@ enum Enum
|
||||
kTechMode,
|
||||
|
||||
kShareForWrite,
|
||||
kStopAfterOpenError,
|
||||
kCaseSensitive,
|
||||
kArcNameMode,
|
||||
|
||||
@@ -245,6 +246,7 @@ static const CSwitchForm kSwitchForms[] =
|
||||
{ "slt" },
|
||||
|
||||
{ "ssw" },
|
||||
{ "sse" },
|
||||
{ "ssc", NSwitchType::kMinus },
|
||||
{ "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
|
||||
|
||||
@@ -1299,6 +1301,8 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
|
||||
|
||||
if (parser[NKey::kShareForWrite].ThereIs)
|
||||
updateOptions.OpenShareForWrite = true;
|
||||
if (parser[NKey::kStopAfterOpenError].ThereIs)
|
||||
updateOptions.StopAfterOpenError = true;
|
||||
|
||||
updateOptions.PathMode = censorPathMode;
|
||||
|
||||
|
||||
@@ -182,6 +182,7 @@ HRESULT CArchiveExtractCallback::PrepareHardLinks(const CRecordVector<UInt32> *r
|
||||
#endif
|
||||
|
||||
CArchiveExtractCallback::CArchiveExtractCallback():
|
||||
_arc(NULL),
|
||||
WriteCTime(true),
|
||||
WriteATime(true),
|
||||
WriteMTime(true),
|
||||
@@ -205,8 +206,8 @@ void CArchiveExtractCallback::Init(
|
||||
const UStringVector &removePathParts, bool removePartsForAltStreams,
|
||||
UInt64 packSize)
|
||||
{
|
||||
_extractedFolderPaths.Clear();
|
||||
_extractedFolderIndices.Clear();
|
||||
ClearExtractedDirsInfo();
|
||||
_outFileStream.Release();
|
||||
|
||||
#ifdef SUPPORT_LINKS
|
||||
_hardLinks.Clear();
|
||||
@@ -368,7 +369,7 @@ void CArchiveExtractCallback::CreateComplexDirectory(const UStringVector &dirPat
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CArchiveExtractCallback::GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
|
||||
HRESULT CArchiveExtractCallback::GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined)
|
||||
{
|
||||
filetimeIsDefined = false;
|
||||
NCOM::CPropVariant prop;
|
||||
@@ -734,7 +735,8 @@ STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStre
|
||||
return E_FAIL;
|
||||
UString s;
|
||||
CReparseAttr reparse;
|
||||
isOkReparse = reparse.Parse((const Byte *)data, dataSize);
|
||||
DWORD errorCode = 0;
|
||||
isOkReparse = reparse.Parse((const Byte *)data, dataSize, errorCode);
|
||||
if (isOkReparse)
|
||||
{
|
||||
isHardLink = false;
|
||||
@@ -1270,7 +1272,8 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
|
||||
if (FillLinkData(data, fs2us(existPath), !isJunction))
|
||||
{
|
||||
CReparseAttr attr;
|
||||
if (!attr.Parse(data, data.Size()))
|
||||
DWORD errorCode = 0;
|
||||
if (!attr.Parse(data, data.Size(), errorCode))
|
||||
{
|
||||
RINOK(SendMessageError("Internal error for symbolic link file", us2fs(_item.Path)));
|
||||
// return E_FAIL;
|
||||
@@ -1447,6 +1450,33 @@ STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
|
||||
}
|
||||
|
||||
|
||||
HRESULT CArchiveExtractCallback::CloseFile()
|
||||
{
|
||||
if (!_outFileStream)
|
||||
return S_OK;
|
||||
|
||||
HRESULT hres = S_OK;
|
||||
_outFileStreamSpec->SetTime(
|
||||
(WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
|
||||
(WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
|
||||
(WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
|
||||
|
||||
const UInt64 processedSize = _outFileStreamSpec->ProcessedSize;
|
||||
if (_fileLengthWasSet && _curSize > processedSize)
|
||||
{
|
||||
bool res = _outFileStreamSpec->File.SetLength(processedSize);
|
||||
_fileLengthWasSet = res;
|
||||
if (!res)
|
||||
hres = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path));
|
||||
}
|
||||
_curSize = processedSize;
|
||||
_curSizeDefined = true;
|
||||
RINOK(_outFileStreamSpec->Close());
|
||||
_outFileStream.Release();
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -1475,27 +1505,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 opRes)
|
||||
|
||||
#endif
|
||||
|
||||
if (_outFileStream)
|
||||
{
|
||||
HRESULT hres = S_OK;
|
||||
_outFileStreamSpec->SetTime(
|
||||
(WriteCTime && _fi.CTimeDefined) ? &_fi.CTime : NULL,
|
||||
(WriteATime && _fi.ATimeDefined) ? &_fi.ATime : NULL,
|
||||
(WriteMTime && _fi.MTimeDefined) ? &_fi.MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
|
||||
const UInt64 processedSize = _outFileStreamSpec->ProcessedSize;
|
||||
if (_fileLengthWasSet && _curSize > processedSize)
|
||||
{
|
||||
bool res = _outFileStreamSpec->File.SetLength(processedSize);
|
||||
_fileLengthWasSet = res;
|
||||
if (!res)
|
||||
hres = SendMessageError_with_LastError(kCantSetFileLen, us2fs(_item.Path));
|
||||
}
|
||||
_curSize = processedSize;
|
||||
_curSizeDefined = true;
|
||||
RINOK(_outFileStreamSpec->Close());
|
||||
_outFileStream.Release();
|
||||
RINOK(hres);
|
||||
}
|
||||
RINOK(CloseFile());
|
||||
|
||||
#ifdef _USE_SECURITY_CODE
|
||||
if (!_stdOutMode && _extractMode && _ntOptions.NtSecurity.Val && _arc->GetRawProps)
|
||||
@@ -1620,8 +1630,12 @@ static unsigned GetNumSlashes(const FChar *s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT CArchiveExtractCallback::SetDirsTimes()
|
||||
{
|
||||
if (!_arc)
|
||||
return S_OK;
|
||||
|
||||
CRecordVector<CExtrRefSortPair> pairs;
|
||||
pairs.ClearAndSetSize(_extractedFolderPaths.Size());
|
||||
unsigned i;
|
||||
@@ -1637,8 +1651,8 @@ HRESULT CArchiveExtractCallback::SetDirsTimes()
|
||||
|
||||
for (i = 0; i < pairs.Size(); i++)
|
||||
{
|
||||
int pairIndex = pairs[i].Index;
|
||||
int index = _extractedFolderIndices[pairIndex];
|
||||
unsigned pairIndex = pairs[i].Index;
|
||||
UInt32 index = _extractedFolderIndices[pairIndex];
|
||||
|
||||
FILETIME CTime;
|
||||
FILETIME ATime;
|
||||
@@ -1658,5 +1672,18 @@ HRESULT CArchiveExtractCallback::SetDirsTimes()
|
||||
(WriteATime && ATimeDefined) ? &ATime : NULL,
|
||||
(WriteMTime && MTimeDefined) ? &MTime : (_arc->MTimeDefined ? &_arc->MTime : NULL));
|
||||
}
|
||||
|
||||
ClearExtractedDirsInfo();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CArchiveExtractCallback::CloseArc()
|
||||
{
|
||||
HRESULT res = CloseFile();
|
||||
HRESULT res2 = SetDirsTimes();
|
||||
if (res == S_OK)
|
||||
res = res2;
|
||||
_arc = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@ class CArchiveExtractCallback:
|
||||
#endif
|
||||
|
||||
void CreateComplexDirectory(const UStringVector &dirPathParts, FString &fullPath);
|
||||
HRESULT GetTime(int index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
|
||||
HRESULT GetTime(UInt32 index, PROPID propID, FILETIME &filetime, bool &filetimeIsDefined);
|
||||
HRESULT GetUnpackSize();
|
||||
|
||||
HRESULT SendMessageError(const char *message, const FString &path);
|
||||
@@ -343,9 +343,44 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
HRESULT CloseArc();
|
||||
|
||||
private:
|
||||
void ClearExtractedDirsInfo()
|
||||
{
|
||||
_extractedFolderPaths.Clear();
|
||||
_extractedFolderIndices.Clear();
|
||||
}
|
||||
|
||||
HRESULT CloseFile();
|
||||
HRESULT SetDirsTimes();
|
||||
};
|
||||
|
||||
|
||||
struct CArchiveExtractCallback_Closer
|
||||
{
|
||||
CArchiveExtractCallback *_ref;
|
||||
|
||||
CArchiveExtractCallback_Closer(CArchiveExtractCallback *ref): _ref(ref) {}
|
||||
|
||||
HRESULT Close()
|
||||
{
|
||||
HRESULT res = S_OK;
|
||||
if (_ref)
|
||||
{
|
||||
res = _ref->CloseArc();
|
||||
_ref = NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
~CArchiveExtractCallback_Closer()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
bool CensorNode_CheckPath(const NWildcard::CCensorNode &node, const CReadArcItem &item);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -386,15 +386,27 @@ HRESULT CDirItems::SetLinkInfo(CDirItem &dirItem, const NFind::CFileInfo &fi,
|
||||
return S_OK;
|
||||
const FString path = phyPrefix + fi.Name;
|
||||
CByteBuffer &buf = dirItem.ReparseData;
|
||||
DWORD res = 0;
|
||||
if (NIO::GetReparseData(path, buf))
|
||||
{
|
||||
CReparseAttr attr;
|
||||
if (attr.Parse(buf, buf.Size()))
|
||||
if (attr.Parse(buf, buf.Size(), res))
|
||||
return S_OK;
|
||||
// we ignore unknown reparse points
|
||||
if (res != ERROR_INVALID_REPARSE_DATA)
|
||||
res = 0;
|
||||
}
|
||||
DWORD res = ::GetLastError();
|
||||
else
|
||||
{
|
||||
res = ::GetLastError();
|
||||
if (res == 0)
|
||||
res = ERROR_INVALID_FUNCTION;
|
||||
}
|
||||
|
||||
buf.Free();
|
||||
return AddError(path , res);
|
||||
if (res == 0)
|
||||
return S_OK;
|
||||
return AddError(path, res);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -865,7 +877,8 @@ void CDirItems::FillFixedReparse()
|
||||
continue;
|
||||
|
||||
CReparseAttr attr;
|
||||
if (!attr.Parse(item.ReparseData, item.ReparseData.Size()))
|
||||
DWORD errorCode = 0;
|
||||
if (!attr.Parse(item.ReparseData, item.ReparseData.Size(), errorCode))
|
||||
continue;
|
||||
if (attr.IsRelative())
|
||||
continue;
|
||||
|
||||
@@ -197,6 +197,9 @@ static HRESULT DecompressArchive(
|
||||
|
||||
HRESULT result;
|
||||
Int32 testMode = (options.TestMode && !calcCrc) ? 1: 0;
|
||||
|
||||
CArchiveExtractCallback_Closer ecsCloser(ecs);
|
||||
|
||||
if (options.StdInMode)
|
||||
{
|
||||
result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, ecs);
|
||||
@@ -206,8 +209,11 @@ static HRESULT DecompressArchive(
|
||||
}
|
||||
else
|
||||
result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, ecs);
|
||||
if (result == S_OK && !options.StdInMode)
|
||||
result = ecs->SetDirsTimes();
|
||||
|
||||
HRESULT res2 = ecsCloser.Close();
|
||||
if (result == S_OK)
|
||||
result = res2;
|
||||
|
||||
return callback->ExtractResult(result);
|
||||
}
|
||||
|
||||
|
||||
@@ -224,7 +224,6 @@ static inline void AddHexToString(AString &res, unsigned v)
|
||||
{
|
||||
res += (char)GetHex(v >> 4);
|
||||
res += (char)GetHex(v & 0xF);
|
||||
res += ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -269,6 +268,14 @@ struct CSecID2Name
|
||||
const char *sz;
|
||||
};
|
||||
|
||||
static int FindPairIndex(const CSecID2Name * pairs, unsigned num, UInt32 id)
|
||||
{
|
||||
for (unsigned i = 0; i < num; i++)
|
||||
if (pairs[i].n == id)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const CSecID2Name sid_32_Names[] =
|
||||
{
|
||||
{ 544, "Administrators" },
|
||||
@@ -359,22 +366,22 @@ static void ParseSid(AString &s, const Byte *p, UInt32 lim, UInt32 &sidSize)
|
||||
if (v0 == 32 && num == 2)
|
||||
{
|
||||
UInt32 v1 = Get32(p + 12);
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(sid_32_Names); i++)
|
||||
if (sid_32_Names[i].n == v1)
|
||||
{
|
||||
s += sid_32_Names[i].sz;
|
||||
return;
|
||||
}
|
||||
int index = FindPairIndex(sid_32_Names, ARRAY_SIZE(sid_32_Names), v1);
|
||||
if (index >= 0)
|
||||
{
|
||||
s += sid_32_Names[index].sz;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (v0 == 21 && num == 5)
|
||||
{
|
||||
UInt32 v4 = Get32(p + 8 + 4 * 4);
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(sid_21_Names); i++)
|
||||
if (sid_21_Names[i].n == v4)
|
||||
{
|
||||
s += sid_21_Names[i].sz;
|
||||
return;
|
||||
}
|
||||
int index = FindPairIndex(sid_21_Names, ARRAY_SIZE(sid_21_Names), v4);
|
||||
if (index >= 0)
|
||||
{
|
||||
s += sid_21_Names[index].sz;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (v0 == 80 && num == 6)
|
||||
{
|
||||
@@ -419,20 +426,13 @@ static void ParseOwner(AString &s, const Byte *p, UInt32 size, UInt32 pos)
|
||||
ParseSid(s, p + pos, size - pos, sidSize);
|
||||
}
|
||||
|
||||
static void AddUInt32ToString(AString &s, UInt32 val)
|
||||
{
|
||||
char sz[16];
|
||||
ConvertUInt32ToString(val, sz);
|
||||
s += sz;
|
||||
}
|
||||
|
||||
static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName, UInt32 flags, UInt32 offset)
|
||||
{
|
||||
UInt32 control = Get16(p + 2);
|
||||
if ((flags & control) == 0)
|
||||
return;
|
||||
UInt32 pos = Get32(p + offset);
|
||||
s += ' ';
|
||||
s.Add_Space();
|
||||
s += strName;
|
||||
if (pos >= size)
|
||||
return;
|
||||
@@ -443,7 +443,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName
|
||||
if (Get16(p) != 2) // revision
|
||||
return;
|
||||
UInt32 num = Get32(p + 4);
|
||||
AddUInt32ToString(s, num);
|
||||
s.Add_UInt32(num);
|
||||
|
||||
/*
|
||||
UInt32 aclSize = Get16(p + 2);
|
||||
@@ -466,7 +466,7 @@ static void ParseAcl(AString &s, const Byte *p, UInt32 size, const char *strName
|
||||
size -= 8;
|
||||
|
||||
UInt32 sidSize = 0;
|
||||
s += ' ';
|
||||
s.Add_Space();
|
||||
ParseSid(s, p, size, sidSize);
|
||||
if (sidSize == 0)
|
||||
return;
|
||||
@@ -508,12 +508,12 @@ void ConvertNtSecureToString(const Byte *data, UInt32 size, AString &s)
|
||||
return;
|
||||
}
|
||||
ParseOwner(s, data, size, Get32(data + 4));
|
||||
s += ' ';
|
||||
s.Add_Space();
|
||||
ParseOwner(s, data, size, Get32(data + 8));
|
||||
ParseAcl(s, data, size, "s:", MY_SE_SACL_PRESENT, 12);
|
||||
ParseAcl(s, data, size, "d:", MY_SE_DACL_PRESENT, 16);
|
||||
s += ' ';
|
||||
AddUInt32ToString(s, size);
|
||||
s.Add_Space();
|
||||
s.Add_UInt32(size);
|
||||
// s += '\n';
|
||||
// s += Data_To_Hex(data, size);
|
||||
}
|
||||
@@ -567,11 +567,38 @@ bool CheckNtSecure(const Byte *data, UInt32 size) throw()
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// IO_REPARSE_TAG_*
|
||||
|
||||
static const CSecID2Name k_ReparseTags[] =
|
||||
{
|
||||
{ 0xA0000003, "MOUNT_POINT" },
|
||||
{ 0xC0000004, "HSM" },
|
||||
{ 0x80000005, "DRIVE_EXTENDER" },
|
||||
{ 0x80000006, "HSM2" },
|
||||
{ 0x80000007, "SIS" },
|
||||
{ 0x80000008, "WIM" },
|
||||
{ 0x80000009, "CSV" },
|
||||
{ 0x8000000A, "DFS" },
|
||||
{ 0x8000000B, "FILTER_MANAGER" },
|
||||
{ 0xA000000C, "SYMLINK" },
|
||||
{ 0xA0000010, "IIS_CACHE" },
|
||||
{ 0x80000012, "DFSR" },
|
||||
{ 0x80000013, "DEDUP" },
|
||||
{ 0xC0000014, "APPXSTRM" },
|
||||
{ 0x80000014, "NFS" },
|
||||
{ 0x80000015, "FILE_PLACEHOLDER" },
|
||||
{ 0x80000016, "DFM" },
|
||||
{ 0x80000017, "WOF" }
|
||||
};
|
||||
|
||||
bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
|
||||
{
|
||||
s.Empty();
|
||||
NFile::CReparseAttr attr;
|
||||
if (attr.Parse(data, size))
|
||||
DWORD errorCode = 0;
|
||||
if (attr.Parse(data, size, errorCode))
|
||||
{
|
||||
if (!attr.IsSymLink())
|
||||
s += "Junction: ";
|
||||
@@ -593,19 +620,48 @@ bool ConvertNtReparseToString(const Byte *data, UInt32 size, UString &s)
|
||||
if (Get16(data + 6) != 0) // padding
|
||||
return false;
|
||||
|
||||
char hex[16];
|
||||
ConvertUInt32ToHex8Digits(tag, hex);
|
||||
s += hex;
|
||||
s.Add_Space();
|
||||
|
||||
data += 8;
|
||||
|
||||
for (UInt32 i = 0; i < len; i++)
|
||||
/*
|
||||
#define _my_IO_REPARSE_TAG_DEDUP (0x80000013L)
|
||||
if (tag == _my_IO_REPARSE_TAG_DEDUP)
|
||||
{
|
||||
unsigned b = ((const Byte *)data)[i];
|
||||
s += (char)GetHex((b >> 4) & 0xF);
|
||||
s += (char)GetHex(b & 0xF);
|
||||
}
|
||||
*/
|
||||
|
||||
{
|
||||
int index = FindPairIndex(k_ReparseTags, ARRAY_SIZE(k_ReparseTags), tag);
|
||||
if (index >= 0)
|
||||
s += k_ReparseTags[index].sz;
|
||||
else
|
||||
{
|
||||
s += "REPARSE:";
|
||||
char hex[16];
|
||||
ConvertUInt32ToHex8Digits(tag, hex);
|
||||
s += hex;
|
||||
}
|
||||
}
|
||||
|
||||
s += ":";
|
||||
s.Add_UInt32(len);
|
||||
|
||||
if (len != 0)
|
||||
{
|
||||
s.Add_Space();
|
||||
|
||||
data += 8;
|
||||
|
||||
for (UInt32 i = 0; i < len; i++)
|
||||
{
|
||||
if (i >= 8)
|
||||
{
|
||||
s += "...";
|
||||
break;
|
||||
}
|
||||
unsigned b = data[i];
|
||||
s += (char)GetHex((b >> 4) & 0xF);
|
||||
s += (char)GetHex(b & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -735,6 +735,7 @@ static HRESULT Compress(
|
||||
CMyComPtr<IArchiveUpdateCallback> updateCallback(updateCallbackSpec);
|
||||
|
||||
updateCallbackSpec->ShareForWrite = options.OpenShareForWrite;
|
||||
updateCallbackSpec->StopAfterOpenError = options.StopAfterOpenError;
|
||||
updateCallbackSpec->StdInMode = options.StdInMode;
|
||||
updateCallbackSpec->Callback = callback;
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ struct CUpdateOptions
|
||||
FString SfxModule;
|
||||
|
||||
bool OpenShareForWrite;
|
||||
bool StopAfterOpenError;
|
||||
|
||||
bool StdInMode;
|
||||
UString StdInFileName;
|
||||
@@ -127,6 +128,7 @@ struct CUpdateOptions
|
||||
EMailMode(false),
|
||||
EMailRemoveAfter(false),
|
||||
OpenShareForWrite(false),
|
||||
StopAfterOpenError(false),
|
||||
ArcNameMode(k_ArcNameMode_Smart),
|
||||
PathMode(NWildcard::k_RelatPath),
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ CArchiveUpdateCallback::CArchiveUpdateCallback():
|
||||
Comment(NULL),
|
||||
|
||||
ShareForWrite(false),
|
||||
StopAfterOpenError(false),
|
||||
StdInMode(false),
|
||||
|
||||
KeepOriginalItemNames(false),
|
||||
@@ -346,7 +347,8 @@ STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PR
|
||||
// if (di.IsDir())
|
||||
{
|
||||
CReparseAttr attr;
|
||||
if (attr.Parse(di.ReparseData, di.ReparseData.Size()))
|
||||
DWORD errorCode = 0;
|
||||
if (attr.Parse(di.ReparseData, di.ReparseData.Size(), errorCode))
|
||||
{
|
||||
UString simpleName = attr.GetPath();
|
||||
if (attr.IsRelative())
|
||||
@@ -512,7 +514,12 @@ STDMETHODIMP CArchiveUpdateCallback::GetStream2(UInt32 index, ISequentialInStrea
|
||||
#endif
|
||||
if (!inStreamSpec->OpenShared(path, ShareForWrite))
|
||||
{
|
||||
return Callback->OpenFileError(path, ::GetLastError());
|
||||
DWORD error = ::GetLastError();
|
||||
HRESULT hres = Callback->OpenFileError(path, error);
|
||||
if (StopAfterOpenError)
|
||||
if (hres == S_OK || hres == S_FALSE)
|
||||
return HRESULT_FROM_WIN32(error);
|
||||
return hres;
|
||||
}
|
||||
|
||||
if (StoreHardLinks)
|
||||
|
||||
@@ -136,6 +136,7 @@ public:
|
||||
const UString *Comment;
|
||||
|
||||
bool ShareForWrite;
|
||||
bool StopAfterOpenError;
|
||||
bool StdInMode;
|
||||
|
||||
bool KeepOriginalItemNames;
|
||||
|
||||
Reference in New Issue
Block a user