Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support password protected archive #1

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions include/libc7zip.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ typedef void (*set_completed_cb_t)(int64_t id, int64_t complete_value);
typedef out_stream *(*get_stream_cb_t)(int64_t id, int64_t index);
typedef void (*set_operation_result_cb_t)(int64_t id, int32_t operation_result);

// MultiVolumeCallback functions
typedef char *(*get_first_volume_name_cb_t)(int64_t id);
typedef int (*move_to_volume_cb_t)(int64_t id, char *volumeName);
typedef unsigned long long (*get_current_volume_size_cb_t)(int64_t id);
typedef in_stream *(*open_current_volume_stream_cb_t)(int64_t id);

typedef struct in_stream_def {
int64_t id;
seek_cb_t seek_cb;
Expand All @@ -65,6 +71,25 @@ MYEXPORT void out_stream_free(out_stream *s);
struct archive;
typedef struct archive archive;
MYEXPORT archive *archive_open(lib *l, in_stream *is, int32_t by_signature);
MYEXPORT archive *archive_open_ex(lib *l, in_stream *is, const char *password, int32_t by_signature);

struct multivolume_callback;
typedef struct multivolume_callback multivolume_callback;

typedef struct multivolume_callback_def {
int64_t id;
get_first_volume_name_cb_t get_first_volume_name_cb;
move_to_volume_cb_t move_to_volume_cb;
get_current_volume_size_cb_t get_current_volume_size_cb;
open_current_volume_stream_cb_t open_current_volume_stream_cb;
} multivolume_callback_def;

MYEXPORT multivolume_callback *multivolume_callback_new();
MYEXPORT multivolume_callback_def *multivolume_callback_get_def(multivolume_callback *ec);
MYEXPORT void multivolume_callback_free(multivolume_callback *ec);

MYEXPORT archive *archive_multiopen(lib *l, multivolume_callback *mc, const char *password, int32_t by_signature);

MYEXPORT void archive_close(archive *a);
MYEXPORT void archive_free(archive *a);
MYEXPORT int64_t archive_get_item_count(archive *a);
Expand Down
72 changes: 72 additions & 0 deletions src/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,37 @@ struct out_stream {
CbSequentialOutStream *strm;
};


class CbMultiVolumeCallback : public C7ZipMultiVolumes {
public:
multivolume_callback_def m_def;

CbMultiVolumeCallback() {
// muffin
}

virtual wstring GetFirstVolumeName() {
return FromCString(m_def.get_first_volume_name_cb(m_def.id));
}
virtual bool MoveToVolume(const wstring & volumeName) {
char *retVolCName = ToCString(volumeName);
std::string _volumeName = retVolCName;
free(retVolCName);
return (bool)m_def.move_to_volume_cb(m_def.id, (char *)_volumeName.c_str());
}
virtual unsigned __int64 GetCurrentVolumeSize() {
return m_def.get_current_volume_size_cb(m_def.id);
}
virtual C7ZipInStream * OpenCurrentVolumeStream() {
in_stream *is = m_def.open_current_volume_stream_cb(m_def.id);
return is->strm;
}

virtual ~CbMultiVolumeCallback() {
// muffin
}
};

class CbExtractCallback : public C7ZipExtractCallback {
public:
extract_callback_def m_def;
Expand Down Expand Up @@ -198,6 +229,47 @@ MYEXPORT archive *archive_open(lib *l, in_stream *s, int32_t by_signature) {
return a;
}

MYEXPORT archive *archive_open_ex(lib *l, in_stream *s, const char *password, int32_t by_signature) {
C7ZipArchive *arch = NULL;
if (!l->_lib->OpenArchive(s->strm, &arch, FromCString((char *)password), by_signature != 0)) {
return NULL;
}

archive *a = (archive*)calloc(1, sizeof(archive));
a->arch = arch;
return a;
}

struct multivolume_callback {
CbMultiVolumeCallback *cb;
};

MYEXPORT multivolume_callback *multivolume_callback_new() {
multivolume_callback *mc = (multivolume_callback *)calloc(1, sizeof(multivolume_callback));
mc->cb = new CbMultiVolumeCallback();
return mc;
}

MYEXPORT multivolume_callback_def *multivolume_callback_get_def(multivolume_callback *mc) {
return &mc->cb->m_def;
}

MYEXPORT void multivolume_callback_free(multivolume_callback *mc) {
delete mc->cb;
free(mc);
}

MYEXPORT archive *archive_multiopen(lib *l, multivolume_callback *mc, const char *password, int32_t by_signature) {
C7ZipArchive *arch = NULL;
if (!l->_lib->OpenMultiVolumeArchive(mc->cb, &arch, FromCString((char *)password), by_signature != 0)) {
return NULL;
}

archive *a = (archive*)calloc(1, sizeof(archive));
a->arch = arch;
return a;
}

MYEXPORT void archive_close(archive *a) {
a->arch->Close();
}
Expand Down
29 changes: 24 additions & 5 deletions vendor/lib7zip/Lib7Zip/7ZipArchive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,15 @@ class CCustomArchiveExtractCallback:
C7ZipSequentialOutStreamWrap * _outFileStreamSpec;
CMyComPtr<ISequentialOutStream> _outFileStream;
C7ZipSequentialOutStream * m_pSequentialOutStream;
public:
CCustomArchiveExtractCallback(C7ZipExtractCallback *pCallback) :
m_pCallback(pCallback) {

const C7ZipArchive * m_pArchive;
const C7ZipArchiveItem * m_pItem;
public:
CCustomArchiveExtractCallback(C7ZipExtractCallback *pCallback,const C7ZipArchive * pArchive,const C7ZipArchiveItem * pItem) :
m_pCallback(pCallback),
m_pArchive(pArchive),
m_pItem(pItem)
{
}
};

Expand Down Expand Up @@ -253,7 +258,8 @@ bool C7ZipArchiveImpl::Extract(const C7ZipArchiveItem * pArchiveItem, C7ZipSeque
}

bool C7ZipArchiveImpl::ExtractSeveral(unsigned int *indexList, int numIndices, C7ZipExtractCallback *pCallback) {
CCustomArchiveExtractCallback *extractCallbackSpec = new CCustomArchiveExtractCallback(pCallback);
C7ZipArchiveItem * pItem = dynamic_cast<C7ZipArchiveItem *>(m_ArchiveItems[0]);
CCustomArchiveExtractCallback *extractCallbackSpec = new CCustomArchiveExtractCallback(pCallback, this, pItem);
CMyComPtr<IArchiveExtractCallback> extractCallback(extractCallbackSpec);

return m_pInArchive->Extract(indexList, numIndices, false, extractCallbackSpec) == S_OK;
Expand Down Expand Up @@ -387,7 +393,20 @@ STDMETHODIMP CCustomArchiveExtractCallback::SetOperationResult(Int32 operationRe

STDMETHODIMP CCustomArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
{
return E_NOTIMPL;
wstring strPassword(L"");

if (m_pItem->IsPasswordSet())
strPassword = m_pItem->GetArchiveItemPassword();
else if (m_pArchive->IsPasswordSet())
strPassword = m_pArchive->GetArchivePassword();

#ifdef _WIN32
return StringToBstr(strPassword.c_str(), password);
#else
*password = ::SysAllocString(strPassword.c_str());

return S_OK;
#endif
}

// ------------------------------
Expand Down