1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
// ArchiveOpenCallback.h
#ifndef ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H
#define ZIP7_INC_ARCHIVE_OPEN_CALLBACK_H
#include "../../../Common/MyCom.h"
#include "../../../Windows/FileFind.h"
#include "../../Common/FileStreams.h"
#ifndef Z7_NO_CRYPTO
#include "../../IPassword.h"
#endif
#include "../../Archive/IArchive.h"
Z7_PURE_INTERFACES_BEGIN
#ifdef Z7_NO_CRYPTO
#define Z7_IFACEM_IOpenCallbackUI_Crypto(x)
#else
#define Z7_IFACEM_IOpenCallbackUI_Crypto(x) \
virtual HRESULT Open_CryptoGetTextPassword(BSTR *password) x \
/* virtual HRESULT Open_GetPasswordIfAny(bool &passwordIsDefined, UString &password) x */ \
/* virtual bool Open_WasPasswordAsked() x */ \
/* virtual void Open_Clear_PasswordWasAsked_Flag() x */ \
#endif
#define Z7_IFACEN_IOpenCallbackUI(x) \
virtual HRESULT Open_CheckBreak() x \
virtual HRESULT Open_SetTotal(const UInt64 *files, const UInt64 *bytes) x \
virtual HRESULT Open_SetCompleted(const UInt64 *files, const UInt64 *bytes) x \
virtual HRESULT Open_Finished() x \
Z7_IFACEM_IOpenCallbackUI_Crypto(x)
Z7_IFACE_DECL_PURE(IOpenCallbackUI)
Z7_PURE_INTERFACES_END
class CMultiStreams Z7_final
{
public:
struct CSubStream
{
CMyComPtr<IInStream> Stream;
CInFileStream *FileSpec;
FString Path;
// UInt64 Size;
UInt64 LocalPos;
int Next; // next older
int Prev; // prev newer
// bool IsOpen;
CSubStream():
FileSpec(NULL),
// Size(0),
LocalPos(0),
Next(-1),
Prev(-1)
// IsOpen(false)
{}
};
CObjectVector<CSubStream> Streams;
private:
// we must use critical section here, if we want to access from different volumnes simultaneously
int Head; // newest
int Tail; // oldest
unsigned NumListItems;
unsigned NumOpenFiles_AllowedMax;
public:
CMultiStreams();
void Init();
HRESULT PrepareToOpenNew();
void InsertToList(unsigned index);
void RemoveFromList(CSubStream &s);
void CloseFile(unsigned index);
HRESULT EnsureOpen(unsigned index);
};
/*
We need COpenCallbackImp class for multivolume processing.
Also we use it as proxy from COM interfaces (IArchiveOpenCallback) to internal (IOpenCallbackUI) interfaces.
If archive is multivolume:
COpenCallbackImp object will exist after Open stage.
COpenCallbackImp object will be deleted when last reference
from each volume object (CInFileStreamVol) will be closed (when archive will be closed).
*/
class COpenCallbackImp Z7_final:
public IArchiveOpenCallback,
public IArchiveOpenVolumeCallback,
public IArchiveOpenSetSubArchiveName,
#ifndef Z7_NO_CRYPTO
public ICryptoGetTextPassword,
#endif
public IProgress, // IProgress is used for 7zFM
public CMyUnknownImp
{
Z7_COM_QI_BEGIN2(IArchiveOpenCallback)
Z7_COM_QI_ENTRY(IArchiveOpenVolumeCallback)
Z7_COM_QI_ENTRY(IArchiveOpenSetSubArchiveName)
#ifndef Z7_NO_CRYPTO
Z7_COM_QI_ENTRY(ICryptoGetTextPassword)
#endif
// Z7_COM_QI_ENTRY(IProgress) // the code doesn't require it
Z7_COM_QI_END
Z7_COM_ADDREF_RELEASE
Z7_IFACE_COM7_IMP(IArchiveOpenCallback)
Z7_IFACE_COM7_IMP(IArchiveOpenVolumeCallback)
Z7_IFACE_COM7_IMP(IProgress)
public:
Z7_IFACE_COM7_IMP(IArchiveOpenSetSubArchiveName)
private:
#ifndef Z7_NO_CRYPTO
Z7_IFACE_COM7_IMP(ICryptoGetTextPassword)
#endif
bool _subArchiveMode;
public:
bool PasswordWasAsked;
UStringVector FileNames;
CBoolVector FileNames_WasUsed;
CRecordVector<UInt64> FileSizes;
void AtCloseFile(unsigned fileIndex)
{
FileNames_WasUsed[fileIndex] = false;
Volumes.CloseFile(fileIndex);
}
/* we have two ways to Callback from this object
1) IArchiveOpenCallback * ReOpenCallback - for ReOpen function, when IOpenCallbackUI is not available
2) IOpenCallbackUI *Callback - for usual callback
we can't transfer IOpenCallbackUI pointer via internal interface,
so we use ReOpenCallback to callback without IOpenCallbackUI.
*/
/* we use Callback/ReOpenCallback only at Open stage.
So the CMyComPtr reference counter is not required,
and we don't want additional reference to unused object,
if COpenCallbackImp is not closed
*/
IArchiveOpenCallback *ReOpenCallback;
// CMyComPtr<IArchiveOpenCallback> ReOpenCallback;
IOpenCallbackUI *Callback;
// CMyComPtr<IUnknown> Callback_Ref;
private:
FString _folderPrefix;
UString _subArchiveName;
NWindows::NFile::NFind::CFileInfo _fileInfo;
public:
CMultiStreams Volumes;
// UInt64 TotalSize;
COpenCallbackImp():
_subArchiveMode(false),
PasswordWasAsked(false),
ReOpenCallback(NULL),
Callback(NULL) {}
HRESULT Init2(const FString &folderPrefix, const FString &fileName);
bool SetSecondFileInfo(CFSTR newName)
{
return _fileInfo.Find_FollowLink(newName) && !_fileInfo.IsDir();
}
};
#endif
|