A small test to list files in 7z file.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <ole2.h>
#include "7z.h"
int printf(const char * restrict format, ...);
const GUID CLSID_CFormat7z = {0x23170F69,0x40C1,0x278A,0x10,0x00,0x00,0x01,0x10,0x07,0x00,0x00};
const GUID IID_IInArchive = {0x23170F69,0x40C1,0x278A,0x00,0x00,0x00,0x06,0x00,0x60,0x00,0x00};;
//const GUID IID_IOutArchive = {0x23170F69,0x40C1,0x278A,0x00,0x00,0x00,0x06,0x00,0xA0,0x00,0x00};
extern IInStream InStream;
extern IArchiveOpenCallback ArchiveOpenCallback;
//extern IArchiveExtractCallback ArchiveExtractCallback;
int __cdecl main(int argc, char **argv)
{
IInArchive *pArc = NULL;
LONGLONG maxCheckStartPosition = 0;
#ifdef _WIN64
HMODULE hMod = LoadLibrary("x64/7za.dll");
#else
HMODULE hMod = LoadLibrary("7za.dll");
#endif
if (hMod) {
PCREATEOBJECT CreateObject = (PCREATEOBJECT)GetProcAddress(hMod, "CreateObject");
CreateObject(&CLSID_CFormat7z, &IID_IInArchive, (void**)&pArc);
if (pArc) {
HRESULT hr;
//printf("pObj %p\n", pArc);
//InStream.hFile = CreateFile("test.7z", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
InStream.hFile = CreateFile("C.7z", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
OutputDebugString("*** Test start ***");
hr = pArc->lpVtbl->Open(pArc, &InStream, &maxCheckStartPosition, &ArchiveOpenCallback);
//CloseHandle(InStream.hFile);
DWORD numItems;
hr = pArc->lpVtbl->GetNumberOfItems(pArc, &numItems);
printf("numItems= %u\n", numItems);
for (DWORD i = 0; i < numItems; i++) {
PROPVARIANT pvPath;
hr = pArc->lpVtbl->GetProperty(pArc, i, 3, &pvPath); // kpidPath = 3
printf("path: %ls\t", pvPath.bstrVal);
hr = pArc->lpVtbl->GetProperty(pArc, i, 4, &pvPath); // kpidName = 4
printf("name: %ls\n", pvPath.bstrVal);
}
}
FreeLibrary(hMod);
}
return 0;
}
7zC.h
#ifndef _7ZC_H
#define _7ZC_H
#pragma once
#ifndef UInt32
typedef long Int32;
typedef unsigned long UInt32;
typedef long long Int64;
typedef unsigned long long UInt64;
#endif
#ifndef OLE2ANSI
typedef WCHAR OLECHAR;
typedef OLECHAR *BSTR;
typedef ULONG PROPID;
typedef struct tagPROPVARIANT PROPVARIANT;
typedef unsigned short VARTYPE;
#endif
//typedef struct IInStream IInStream;
typedef struct IOutStream IOutStream;
typedef struct IArchiveOpenCallback IArchiveOpenCallback;
typedef struct IArchiveExtractCallback IArchiveExtractCallback;
typedef struct ISequentialInStream ISequentialInStream;
typedef struct ISequentialOutStream ISequentialOutStream;
extern const GUID IID_ISequentialInStream;
typedef struct ISequentialInStream ISequentialInStream;
typedef struct ISequentialInStreamVtbl {
// IUnknown methods
HRESULT (STDMETHODCALLTYPE *QueryInterface) (ISequentialInStream *, REFIID riid, void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef) (ISequentialInStream *This);
ULONG (STDMETHODCALLTYPE *Release) (ISequentialInStream *This);
// ISequentialInStream methods
HRESULT (STDMETHODCALLTYPE *Read) (ISequentialInStream *This, void *data, UInt32 size, UInt32 * processedSize);
}ISequentialInStreamVtbl;
typedef struct ISequentialInStream {
const struct ISequentialInStreamVtbl *lpVtbl;
DWORD nRefCount;
HANDLE hFile;
}ISequentialInStream;
extern const GUID IID_ISequentialOutStream;
typedef struct ISequentialOutStream ISequentialOutStream;
typedef struct ISequentialOutStreamVtbl {
// IUnknown methods
HRESULT (STDMETHODCALLTYPE *QueryInterface) (ISequentialOutStream *, REFIID riid, void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef) (ISequentialOutStream *This);
ULONG (STDMETHODCALLTYPE *Release) (ISequentialOutStream *This);
// ISequentialOutStream methods
HRESULT (STDMETHODCALLTYPE *Write) (ISequentialOutStream *This, const void *data, UInt32 size, UInt32 * processedSize);
}ISequentialOutStreamVtbl;
typedef struct ISequentialOutStream {
const struct ISequentialOutStreamVtbl *lpVtbl;
DWORD nRefCount;
HANDLE hFile;
}ISequentialOutStream;
extern const GUID IID_IInStream;
typedef struct IInStream IInStream;
typedef struct IInStreamVtbl {
// IUnknown methods
HRESULT (STDMETHODCALLTYPE *QueryInterface) (IInStream *, REFIID riid, void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef) (IInStream *This);
ULONG (STDMETHODCALLTYPE *Release) (IInStream *This);
// ISequentialInStream methods
HRESULT (STDMETHODCALLTYPE *Read) (ISequentialInStream *This, void *data, UInt32 size, UInt32 * processedSize);
// IInStream methods
HRESULT (STDMETHODCALLTYPE *Seek) (IInStream *This, Int64 offset, UInt32 seekOrigin, UInt64 * newPosition);
}IInStreamVtbl;
typedef struct IInStream {
const struct IInStreamVtbl *lpVtbl;
DWORD nRefCount;
HANDLE hFile;
}IInStream;
extern const GUID IID_IOutStream;
typedef struct IOutStream IOutStream;
typedef struct IOutStreamVtbl {
// IUnknown methods
HRESULT (STDMETHODCALLTYPE *QueryInterface) (IOutStream *, REFIID riid, void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef) (IOutStream *This);
ULONG (STDMETHODCALLTYPE *Release) (IOutStream *This);
// ISequentialOutStream methods
HRESULT (STDMETHODCALLTYPE *Write) (ISequentialOutStream *This, const void *data, UInt32 size, UInt32 * processedSize);
// IOutStream methods
HRESULT (STDMETHODCALLTYPE *Seek) (IOutStream *This, Int64 offset, UInt32 seekOrigin, UInt64 * newPosition);
HRESULT (STDMETHODCALLTYPE *SetSize) (IOutStream *This, UInt64 newSize);
}IOutStreamVtbl;
typedef struct IOutStream {
const struct IOutStreamVtbl *lpVtbl;
DWORD nRefCount;
HANDLE hFile;
}IOutStream;
extern const GUID IID_IInArchive;
typedef struct IInArchive IInArchive;
typedef struct IInArchiveVtbl {
// IUnknown methods
HRESULT (STDMETHODCALLTYPE *QueryInterface) (IInArchive *, REFIID riid, void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef) (IInArchive *This);
ULONG (STDMETHODCALLTYPE *Release) (IInArchive *This);
// IInArchive methods
HRESULT (STDMETHODCALLTYPE *Open) (IInArchive *This, IInStream * stream, const UInt64 * maxCheckStartPosition, IArchiveOpenCallback * openCallback);
HRESULT (STDMETHODCALLTYPE *Close) (IInArchive *This);
HRESULT (STDMETHODCALLTYPE *GetNumberOfItems) (IInArchive *This, UInt32 * numItems);
HRESULT (STDMETHODCALLTYPE *GetProperty) (IInArchive *This, UInt32 index, PROPID propID, PROPVARIANT * value);
HRESULT (STDMETHODCALLTYPE *Extract) (IInArchive *This, const UInt32 * indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback * extractCallback);
HRESULT (STDMETHODCALLTYPE *GetArchiveProperty) (IInArchive *This, PROPID propID, PROPVARIANT * value);
HRESULT (STDMETHODCALLTYPE *GetNumberOfProperties) (IInArchive *This, UInt32 * numProps);
HRESULT (STDMETHODCALLTYPE *GetPropertyInfo) (IInArchive *This, UInt32 index, BSTR * name, PROPID * propID, VARTYPE * varType);
HRESULT (STDMETHODCALLTYPE *GetNumberOfArchiveProperties) (IInArchive *This, UInt32 * numProps);
HRESULT (STDMETHODCALLTYPE *GetArchivePropertyInfo) (IInArchive *This, UInt32 index, BSTR * name, PROPID * propID, VARTYPE * varType);
}IInArchiveVtbl;
typedef struct IInArchive {
const struct IInArchiveVtbl *lpVtbl;
}IInArchive;
extern const GUID IID_IArchiveOpenCallback;
typedef struct IArchiveOpenCallback IArchiveOpenCallback;
typedef struct IArchiveOpenCallbackVtbl {
// IUnknown methods
HRESULT (STDMETHODCALLTYPE *QueryInterface) (IArchiveOpenCallback *, REFIID riid, void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef) (IArchiveOpenCallback *This);
ULONG (STDMETHODCALLTYPE *Release) (IArchiveOpenCallback *This);
// IArchiveOpenCallback methods
HRESULT (STDMETHODCALLTYPE *SetTotal) (IArchiveOpenCallback *This, const UInt64 * files, const UInt64 * bytes);
HRESULT (STDMETHODCALLTYPE *SetCompleted) (IArchiveOpenCallback *This, const UInt64 * files, const UInt64 * bytes);
}IArchiveOpenCallbackVtbl;
typedef struct IArchiveOpenCallback {
const struct IArchiveOpenCallbackVtbl *lpVtbl;
DWORD nRefCount;
IInArchive *pIInArchive;
}IArchiveOpenCallback;
extern const GUID IID_IArchiveExtractCallback;
typedef struct IArchiveExtractCallback IArchiveExtractCallback;
typedef struct IArchiveExtractCallbackVtbl {
// IUnknown methods
HRESULT (STDMETHODCALLTYPE *QueryInterface) (IArchiveExtractCallback *, REFIID riid, void **ppvObject);
ULONG (STDMETHODCALLTYPE *AddRef) (IArchiveExtractCallback *This);
ULONG (STDMETHODCALLTYPE *Release) (IArchiveExtractCallback *This);
// IArchiveExtractCallback methods
HRESULT (STDMETHODCALLTYPE *SetTotal) (IArchiveExtractCallback *This, UInt64 total);
HRESULT (STDMETHODCALLTYPE *SetCompleted) (IArchiveExtractCallback *This, const UInt64 * completeValue);
HRESULT (STDMETHODCALLTYPE *GetStream) (IArchiveExtractCallback *This, UInt32 index, ISequentialOutStream ** outStream, Int32 askExtractMode);
HRESULT (STDMETHODCALLTYPE *PrepareOperation) (IArchiveExtractCallback *This, Int32 askExtractMode);
HRESULT (STDMETHODCALLTYPE *SetOperationResult) (IArchiveExtractCallback *This, Int32 opRes);
}IArchiveExtractCallbackVtbl;
typedef struct IArchiveExtractCallback {
const struct IArchiveExtractCallbackVtbl *lpVtbl;
DWORD nRefCount;
IInArchive *pIInArchive;
}IArchiveExtractCallback;
typedef int (WINAPI CREATEOBJECT)(const GUID *clsid, const GUID *iid, void **outObject);
typedef CREATEOBJECT *PCREATEOBJECT;
#endif // _7ZC_H
7zDll.c
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
//#include <ole2.h>
#include <propidl.h>
#include "7zC1.h"
const GUID IID_IArchiveExtractCallback = {0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x20, 0x00, 0x00};
//const GUID IID_CompressProgressInfo = {0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00};
//const GUID IID_IArchiveExtractCallbackMessage = {0x23170F69, 0x40C1, 0x278A, 0x00, 0x00, 0x00, 0x06, 0x00, 0x21, 0x00, 0x00};
HRESULT WINAPI IInStream_QueryInterface(IInStream * This, REFIID riid, void **ppvObject)
{
return E_NOINTERFACE;
}
ULONG WINAPI IInStream_AddRef(IInStream * This)
{
return This->nRefCount;
}
ULONG WINAPI IInStream_Release(IInStream * This)
{
This->nRefCount--;
if (This->nRefCount == 0) {
CloseHandle(This->hFile);
This->hFile = (void*)-1;
}
return This->nRefCount;
}
HRESULT WINAPI IInStream_Read(ISequentialInStream *This, void *data, UInt32 size, UInt32 *processedSize)
{
ReadFile(This->hFile, data, size, processedSize, NULL);
return 0;
}
HRESULT WINAPI IInStream_Seek(IInStream *This, Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{// STREAM_SEEK_SET = 0,STREAM_SEEK_CUR = 1,STREAM_SEEK_END = 2
if(seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
return !SetFilePointerEx(This->hFile, *(LARGE_INTEGER*)&offset, (LARGE_INTEGER*)newPosition, seekOrigin);
}
const IInStreamVtbl IInStreamTable = {
IInStream_QueryInterface,
IInStream_AddRef,
IInStream_Release,
IInStream_Read,
IInStream_Seek,
};
IInStream InStream = { &IInStreamTable, 0, (void*)-1 };
HRESULT WINAPI IOutStream_QueryInterface(IOutStream * This, REFIID riid, void **ppvObject)
{
return E_NOINTERFACE;
}
ULONG WINAPI IOutStream_AddRef(IOutStream * This)
{
This->nRefCount++;
return This->nRefCount;
}
ULONG WINAPI IOutStream_Release(IOutStream * This)
{
This->nRefCount--;
if (This->nRefCount == 0) {
CloseHandle(This->hFile);
This->hFile = (void*)-1;
}
return This->nRefCount;
}
HRESULT WINAPI IOutStream_Write(ISequentialOutStream *This, const void *data, UInt32 size, UInt32 *processedSize)
{
WriteFile(This->hFile, data, size, processedSize, NULL);
return 0;
}
HRESULT WINAPI IOutStream_Seek(IOutStream *This, Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{// STREAM_SEEK_SET = 0, STREAM_SEEK_CUR = 1, STREAM_SEEK_END = 2
if(seekOrigin >= 3)
return STG_E_INVALIDFUNCTION;
return !SetFilePointerEx(This->hFile, *(LARGE_INTEGER*)&offset, (LARGE_INTEGER*)newPosition, seekOrigin);
}
HRESULT WINAPI IOutStream_SetSize(IOutStream *This, UInt64 newSize)
{
return E_NOTIMPL;
}
const IOutStreamVtbl IOutStreamTable = {
IOutStream_QueryInterface,
IOutStream_AddRef,
IOutStream_Release,
IOutStream_Write,
IOutStream_Seek,
IOutStream_SetSize
};
IOutStream OutStream = { &IOutStreamTable, 0, (void*)-1 };
/// IArchiveOpenCallback
HRESULT WINAPI IArchiveOpenCallback_QueryInterface(IArchiveOpenCallback * This, REFIID riid, void **ppvObject)
{
*ppvObject = This;
return 0;
}
ULONG WINAPI IArchiveOpenCallback_AddRef(IArchiveOpenCallback * This)
{
This->nRefCount++;
//return InterlockedIncrement(This->nRefCount);
return This->nRefCount;
}
ULONG WINAPI IArchiveOpenCallback_Release(IArchiveOpenCallback * This)
{
This->nRefCount--;
//return InterlockedDecrement(This->nRefCount);
return This->nRefCount;
}
HRESULT WINAPI IArchiveOpenCallback_SetTotal(IArchiveOpenCallback *This, const UInt64 * files, const UInt64 * bytes)
{
return 0;
}
HRESULT WINAPI IArchiveOpenCallback_SetCompleted(IArchiveOpenCallback *This, const UInt64 * files, const UInt64 * bytes)
{
return E_NOTIMPL;
}
const IArchiveOpenCallbackVtbl IArchiveOpenCallbackTable = {
IArchiveOpenCallback_QueryInterface,
IArchiveOpenCallback_AddRef,
IArchiveOpenCallback_Release,
IArchiveOpenCallback_SetTotal,
IArchiveOpenCallback_SetCompleted
};
IArchiveOpenCallback ArchiveOpenCallback = { &IArchiveOpenCallbackTable, 0};
ULONG WINAPI IArchiveExtractCallback_AddRef(IArchiveExtractCallback *This);
/// IArchiveExtractCallback
HRESULT WINAPI IArchiveExtractCallback_QueryInterface(IArchiveExtractCallback *This, REFIID riid, void **ppvObject)
{
if (!memcmp(riid, &IID_IArchiveExtractCallback, sizeof(GUID))) {
IArchiveExtractCallback_AddRef(This);
*ppvObject = This;
return 0;
}
/* if (!memcmp(riid, &IID_CompressProgressInfo, sizeof(GUID))) {
*ppvObject = &CompressProgressInfo;
return 0;
}
if (!memcmp(riid, &IID_IArchiveExtractCallbackMessage, sizeof(GUID))) {
*ppvObject = &ArchiveExtractCallbackMessage;
return 0;
}*/
*ppvObject = 0;
return E_NOINTERFACE;
}
ULONG WINAPI IArchiveExtractCallback_AddRef(IArchiveExtractCallback *This)
{
This->nRefCount++;
return This->nRefCount;
}
ULONG WINAPI IArchiveExtractCallback_Release(IArchiveExtractCallback *This)
{
This->nRefCount--;
return This->nRefCount;
}
HRESULT WINAPI IArchiveExtractCallback_SetTotal(IArchiveExtractCallback *This, UInt64 total)
{
return 0;
}
HRESULT WINAPI IArchiveExtractCallback_SetCompleted(IArchiveExtractCallback *This, const UInt64 * completeValue)
{
return 0;
}
HRESULT WINAPI IArchiveExtractCallback_GetStream(IArchiveExtractCallback *This, UInt32 index, ISequentialOutStream ** outStream, Int32 askExtractMode)
{
if (askExtractMode)
return 0;
PROPVARIANT pv;
HRESULT hr;
IInArchive *pIInArchive = This->pIInArchive;
// hr = This->pIInArchive->lpVtbl->GetProperty(This->pIInArchive, index, 3, &pv); // kpidPath = 3
hr = pIInArchive->lpVtbl->GetProperty(pIInArchive, index, 3, &pv); // kpidPath = 3
OutStream.hFile = CreateFileW(pv.bstrVal, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
*outStream = (ISequentialOutStream*)&OutStream;
IOutStream_AddRef(&OutStream);
return 0;
}
HRESULT WINAPI IArchiveExtractCallback_PrepareOperation(IArchiveExtractCallback *This, Int32 askExtractMode)
{
return 0;
}
HRESULT WINAPI IArchiveExtractCallback_SetOperationResult(IArchiveExtractCallback *This, Int32 opRes)
{
return 0;
}
const IArchiveExtractCallbackVtbl IArchiveExtractCallbackTable = {
IArchiveExtractCallback_QueryInterface,
IArchiveExtractCallback_AddRef,
IArchiveExtractCallback_Release,
IArchiveExtractCallback_SetTotal,
IArchiveExtractCallback_SetCompleted,
IArchiveExtractCallback_GetStream,
IArchiveExtractCallback_PrepareOperation,
IArchiveExtractCallback_SetOperationResult
};
IArchiveExtractCallback ArchiveExtractCallback = { &IArchiveExtractCallbackTable, 0, 0};