实例介绍
【实例简介】
【实例截图】
【实例截图】
【核心代码】
// Client7z.cpp
#include "StdAfx.h"
#include <stdio.h>
#include <string>
#include <shlobj.h>
#include "../../../Common/MyWindows.h"
#include "../../../Common/Defs.h"
#include "../../../Common/MyInitGuid.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/DLL.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileFind.h"
#include "../../../Windows/FileName.h"
#include "../../../Windows/NtCheck.h"
#include "../../../Windows/PropVariant.h"
#include "../../../Windows/PropVariantConv.h"
#include "../../Common/FileStreams.h"
#include "../../Archive/IArchive.h"
#include "../../IPassword.h"
#include "../../../../C/7zVersion.h"
#include "Client7z.h"
#ifdef _WIN32
HINSTANCE g_hInstance = 0;
#endif
// Tou can find the list of all GUIDs in Guid.txt file.
// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-40C1-278A-1000-000110070000}
#define CLSID_Format CLSID_CFormat7z
// #define CLSID_Format CLSID_CFormatXz
Func_CreateObject g_CreateObjectFunc = NULL;
Func_GetNumberOfFormats g_GetNumberOfFormats = NULL;
Func_GetHandlerProperty2 g_GetHandlerProperty2 = NULL;
Func_GetIsArc g_GetIsArc = NULL;
vector<CArcInfoEx> g_ArcInfo;
using namespace NWindows;
using namespace NFile;
using namespace NDir;
#define kDllName "7z.dll"
wstring g_strPsw;
static const char * const kCopyrightString =
"\n"
"7-Zip"
" (" kDllName " client)"
" " MY_VERSION
" : " MY_COPYRIGHT_DATE
"\n";
static const char * const kHelpString =
"Usage: 7zcl.exe [a | l | x] archive.7z [fileName ...]\n"
"Examples:\n"
" 7zcl.exe a archive.7z f1.txt f2.txt : compress two files to archive.7z\n"
" 7zcl.exe l archive.7z : List contents of archive.7z\n"
" 7zcl.exe x archive.7z : eXtract files from archive.7z\n";
LPREQUESTCALLBACK g_lpRequestCallback = NULL;
static void Convert_UString_to_AString(const UString &s, AString &temp)
{
int codePage = CP_OEMCP;
/*
int g_CodePage = -1;
int codePage = g_CodePage;
if (codePage == -1)
codePage = CP_OEMCP;
if (codePage == CP_UTF8)
ConvertUnicodeToUTF8(s, temp);
else
*/
UnicodeStringToMultiByte2(temp, s, (UINT)codePage);
}
static FString CmdStringToFString(const char *s)
{
return us2fs(GetUnicodeString(s));
}
static void Print(const char *s)
{
fputs(s, stdout);
}
static void Print(const AString &s)
{
Print(s.Ptr());
}
static void Print(const UString &s)
{
AString as;
Convert_UString_to_AString(s, as);
Print(as);
}
static void Print(const wchar_t *s)
{
Print(UString(s));
}
static void PrintNewLine()
{
Print("\n");
}
static void PrintStringLn(const char *s)
{
Print(s);
PrintNewLine();
}
static void PrintError(const char *message)
{
Print("Error: ");
PrintNewLine();
Print(message);
PrintNewLine();
}
static void PrintError(const char *message, const FString &name)
{
PrintError(message);
Print(name);
}
static HRESULT IsArchiveItemProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result)
{
NCOM::CPropVariant prop;
RINOK(archive->GetProperty(index, propID, &prop));
if (prop.vt == VT_BOOL)
result = VARIANT_BOOLToBool(prop.boolVal);
else if (prop.vt == VT_EMPTY)
result = false;
else
return E_FAIL;
return S_OK;
}
static HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result)
{
return IsArchiveItemProp(archive, index, kpidIsDir, result);
}
static const wchar_t * const kEmptyFileAlias = L"[Content]";
//////////////////////////////////////////////////////////////
// Archive Open callback class
class CArchiveOpenCallback:
public IArchiveOpenCallback,
public ICryptoGetTextPassword,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP1(ICryptoGetTextPassword)
STDMETHOD(SetTotal)(const UInt64 *files, const UInt64 *bytes);
STDMETHOD(SetCompleted)(const UInt64 *files, const UInt64 *bytes);
STDMETHOD(CryptoGetTextPassword)(BSTR *password);
bool PasswordIsDefined;
UString Password;
CArchiveOpenCallback() : PasswordIsDefined(false) {}
};
STDMETHODIMP CArchiveOpenCallback::SetTotal(const UInt64 * files , const UInt64 * bytes )
{
if (g_lpRequestCallback)
{
I7zOpenBack callback = { 0 };
callback.nType = 1;
memcpy(&callback.itotal, files, sizeof(unsigned long long int));
g_lpRequestCallback(1, &callback);
}
return S_OK;
}
STDMETHODIMP CArchiveOpenCallback::SetCompleted(const UInt64 * files , const UInt64 * bytes )
{
if (g_lpRequestCallback)
{
I7zOpenBack callback = { 0 };
callback.nType = 2;
memcpy(&callback.icurrent, files, sizeof(unsigned long long int));
g_lpRequestCallback(1, &callback);
}
return S_OK;
}
STDMETHODIMP CArchiveOpenCallback::CryptoGetTextPassword(BSTR *password)
{
if (!PasswordIsDefined)
{
g_strPsw.clear();
I7zOpenBack callback = { 0 };
callback.nType = 3;
callback.isPassword = true;
g_lpRequestCallback(1, &callback);
if (g_strPsw.length())
{
Password = g_strPsw.c_str();;
PasswordIsDefined = true;
return StringToBstr(Password, password);
}
else
{
PrintError("Password is not defined");
return E_ABORT;
}
}
return StringToBstr(Password, password);
}
static const char * const kIncorrectCommand = "incorrect command";
//////////////////////////////////////////////////////////////
// Archive Extracting callback class
static const char * const kTestingString = "Testing ";
static const char * const kExtractingString = "Extracting ";
static const char * const kSkippingString = "Skipping ";
static const char * const kUnsupportedMethod = "Unsupported Method";
static const char * const kCRCFailed = "CRC Failed";
static const char * const kDataError = "Data Error";
static const char * const kUnavailableData = "Unavailable data";
static const char * const kUnexpectedEnd = "Unexpected end of data";
static const char * const kDataAfterEnd = "There are some data after the end of the payload data";
static const char * const kIsNotArc = "Is not archive";
static const char * const kHeadersError = "Headers Error";
I7zExpandBack g_Expandcallback = { 0 };
void CArchiveExtractCallback::Init(IInArchive *archiveHandler, const FString &directoryPath)
{
m_Handle = NULL;
m_cancel = false;
m_stop = false;
NumErrors = 0;
_archiveHandler = archiveHandler;
_directoryPath = directoryPath;
NName::NormalizeDirPathPrefix(_directoryPath);
}
STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size )
{
if (g_lpRequestCallback)
{
I7zExpandBack Expandcallback = { 0 };
Expandcallback.nType = 1;
memcpy(&Expandcallback.itotal, &size, sizeof(unsigned long long int));
g_lpRequestCallback(2, &Expandcallback);
}
if (m_stop)
{
WaitForSingleObject(m_Handle, INFINITE);
}
if (m_cancel)
return 1;
else
return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 * completeValue)
{
if (g_lpRequestCallback)
{
I7zExpandBack Expandcallback = { 0 };
Expandcallback.nType = 2;
memcpy(&Expandcallback.icurrent, completeValue, sizeof(unsigned long long int));
g_lpRequestCallback(2, &Expandcallback);
}
if (m_stop)
{
WaitForSingleObject(m_Handle, INFINITE);
}
if (m_cancel)
return 1;
else
return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index,
ISequentialOutStream **outStream, Int32 askExtractMode)
{
*outStream = 0;
_outFileStream.Release();
{
// Get Name
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidPath, &prop));
UString fullPath;
if (prop.vt == VT_EMPTY)
fullPath = kEmptyFileAlias;
else
{
if (prop.vt != VT_BSTR)
return E_FAIL;
fullPath = prop.bstrVal;
}
_filePath = fullPath;
}
if (askExtractMode != NArchive::NExtract::NAskMode::kExtract)
return S_OK;
{
// Get Attrib
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidAttrib, &prop));
if (prop.vt == VT_EMPTY)
{
_processedFileInfo.Attrib = 0;
_processedFileInfo.AttribDefined = false;
}
else
{
if (prop.vt != VT_UI4)
return E_FAIL;
_processedFileInfo.Attrib = prop.ulVal;
_processedFileInfo.AttribDefined = true;
}
}
RINOK(IsArchiveItemFolder(_archiveHandler, index, _processedFileInfo.isDir));
{
// Get Modified Time
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidMTime, &prop));
_processedFileInfo.MTimeDefined = false;
switch (prop.vt)
{
case VT_EMPTY:
// _processedFileInfo.MTime = _utcMTimeDefault;
break;
case VT_FILETIME:
_processedFileInfo.MTime = prop.filetime;
_processedFileInfo.MTimeDefined = true;
break;
default:
return E_FAIL;
}
}
{
NCOM::CPropVariant prop;
RINOK(_archiveHandler->GetProperty(index, kpidSize, &prop));
UInt64 newFileSize;
ConvertPropVariantToUInt64(prop, newFileSize);
}
{
int slashPos = _filePath.ReverseFind_PathSepar();
if (slashPos >= 0)
CreateComplexDir(_directoryPath us2fs(_filePath.Left(slashPos)));
}
FString fullProcessedPath = _directoryPath us2fs(_filePath);
_diskFilePath = fullProcessedPath;
if (_processedFileInfo.isDir)
{
CreateComplexDir(fullProcessedPath);
}
else
{
NFind::CFileInfo fi;
if (fi.Find(fullProcessedPath))
{
if (_filePath.Len())
{
if (g_lpRequestCallback)
{
I7zExpandBack Expandcallback = { 0 };
Expandcallback.nType = 3;
Expandcallback.nIndex = index;
m_index = index;
wcscpy(Expandcallback.lpFilePath, fullProcessedPath);
g_lpRequestCallback(2, &Expandcallback);
}
}
if (2 == nFileType) //重命名
{
wstring strzipfile = fullProcessedPath;
strzipfile = TEXT(".temp");
_wrename(fullProcessedPath.GetBuf(), strzipfile.c_str());
}
}
if (fi.Find(fullProcessedPath) && 3 == nFileType)
{
}
else
{
_outFileStreamSpec = new COutFileStream;
CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec);
if (!_outFileStreamSpec->Open(fullProcessedPath, CREATE_ALWAYS))
{
PrintError("Can not open output file", fullProcessedPath);
return E_ABORT;
}
_outFileStream = outStreamLoc;
*outStream = outStreamLoc.Detach();
}
}
if (m_stop)
{
WaitForSingleObject(m_Handle, INFINITE);
}
if (m_cancel)
return 1;
else
return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
{
_extractMode = false;
switch (askExtractMode)
{
case NArchive::NExtract::NAskMode::kExtract: _extractMode = true; break;
};
switch (askExtractMode)
{
case NArchive::NExtract::NAskMode::kExtract: Print(kExtractingString); break;
case NArchive::NExtract::NAskMode::kTest: Print(kTestingString); break;
case NArchive::NExtract::NAskMode::kSkip: Print(kSkippingString); break;
};
Print(_filePath);
if (m_stop)
{
WaitForSingleObject(m_Handle, INFINITE);
}
if (m_cancel)
return 1;
else
return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
{
switch (operationResult)
{
case NArchive::NExtract::NOperationResult::kOK:
break;
default:
{
NumErrors ;
Print(" : ");
const char *s = NULL;
switch (operationResult)
{
case NArchive::NExtract::NOperationResult::kUnsupportedMethod:
s = kUnsupportedMethod;
break;
case NArchive::NExtract::NOperationResult::kCRCError:
s = kCRCFailed;
break;
case NArchive::NExtract::NOperationResult::kDataError:
s = kDataError;
break;
case NArchive::NExtract::NOperationResult::kUnavailable:
s = kUnavailableData;
break;
case NArchive::NExtract::NOperationResult::kUnexpectedEnd:
s = kUnexpectedEnd;
break;
case NArchive::NExtract::NOperationResult::kDataAfterEnd:
s = kDataAfterEnd;
break;
case NArchive::NExtract::NOperationResult::kIsNotArc:
s = kIsNotArc;
break;
case NArchive::NExtract::NOperationResult::kHeadersError:
s = kHeadersError;
break;
}
if (s)
{
Print("Error : ");
Print(s);
}
else
{
char temp[16];
ConvertUInt32ToString(operationResult, temp);
Print("Error #");
Print(temp);
}
}
}
if (_outFileStream)
{
if (_processedFileInfo.MTimeDefined)
_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
RINOK(_outFileStreamSpec->Close());
}
_outFileStream.Release();
if (_extractMode && _processedFileInfo.AttribDefined)
SetFileAttrib_PosixHighDetect(_diskFilePath, _processedFileInfo.Attrib);
PrintNewLine();
if (g_lpRequestCallback)
{
I7zExpandBack ExpandBack = { 0 };
ExpandBack.nType = 4;
ExpandBack.nSuccess = operationResult;
ExpandBack.nIndex = m_index;
wcscpy(ExpandBack.lpFilePath, _filePath);
g_lpRequestCallback(2, &ExpandBack);
}
if (m_stop)
{
WaitForSingleObject(m_Handle, INFINITE);
}
if (m_cancel)
return 1;
else
return S_OK;
}
STDMETHODIMP CArchiveExtractCallback::CryptoGetTextPassword(BSTR *password)
{
if (!PasswordIsDefined)
{
g_strPsw.clear();
I7zExpandBack ExpandBack = { 0 };
ExpandBack.nType = 5;
ExpandBack.isPassword = true;
g_lpRequestCallback(2, &ExpandBack);
if (g_strPsw.length())
{
Password = g_strPsw.c_str();;
PasswordIsDefined = true;
return StringToBstr(Password, password);
}
else
{
PrintError("Password is not defined");
return E_ABORT;
}
}
return StringToBstr(Password, password);
}
//////////////////////////////////////////////////////////////
// Archive Creating callback class
class CArchiveUpdateCallback:
public IArchiveUpdateCallback2,
public ICryptoGetTextPassword2,
public CMyUnknownImp
{
public:
MY_UNKNOWN_IMP2(IArchiveUpdateCallback2, ICryptoGetTextPassword2)
// IProgress
STDMETHOD(SetTotal)(UInt64 size);
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
// IUpdateCallback2
STDMETHOD(GetUpdateItemInfo)(UInt32 index,
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **inStream);
STDMETHOD(SetOperationResult)(Int32 operationResult);
STDMETHOD(GetVolumeSize)(UInt32 index, UInt64 *size);
STDMETHOD(GetVolumeStream)(UInt32 index, ISequentialOutStream **volumeStream);
STDMETHOD(CryptoGetTextPassword2)(Int32 *passwordIsDefined, BSTR *password);
public:
CRecordVector<UInt64> VolumesSizes;
UString VolName;
UString VolExt;
FString DirPrefix;
const CObjectVector<CDirItem> *DirItems;
bool PasswordIsDefined;
UString Password;
bool AskPassword;
bool m_NeedBeClosed;
FStringVector FailedFiles;
CRecordVector<HRESULT> FailedCodes;
CArchiveUpdateCallback(): PasswordIsDefined(false), AskPassword(false), DirItems(0) {};
~CArchiveUpdateCallback() { Finilize(); }
HRESULT Finilize();
void Init(const CObjectVector<CDirItem> *dirItems)
{
DirItems = dirItems;
m_NeedBeClosed = false;
FailedFiles.Clear();
FailedCodes.Clear();
}
};
STDMETHODIMP CArchiveUpdateCallback::SetTotal(UInt64 size )
{
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * completeValue )
{
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 index ,
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
{
if (newData)
*newData = BoolToInt(true);
if (newProperties)
*newProperties = BoolToInt(true);
if (indexInArchive)
*indexInArchive = (UInt32)(Int32)-1;
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
NCOM::CPropVariant prop;
if (propID == kpidIsAnti)
{
prop = false;
prop.Detach(value);
return S_OK;
}
{
const CDirItem &dirItem = (*DirItems)[index];
switch (propID)
{
case kpidPath: prop = dirItem.Name; break;
case kpidIsDir: prop = dirItem.isDir(); break;
case kpidSize: prop = dirItem.Size; break;
case kpidAttrib: prop = dirItem.Attrib; break;
case kpidCTime: prop = dirItem.CTime; break;
case kpidATime: prop = dirItem.ATime; break;
case kpidMTime: prop = dirItem.MTime; break;
}
}
prop.Detach(value);
return S_OK;
}
HRESULT CArchiveUpdateCallback::Finilize()
{
if (m_NeedBeClosed)
{
PrintNewLine();
m_NeedBeClosed = false;
}
return S_OK;
}
static void GetStream2(const wchar_t *name)
{
Print("Compressing ");
if (name[0] == 0)
name = kEmptyFileAlias;
Print(name);
}
STDMETHODIMP CArchiveUpdateCallback::GetStream(UInt32 index, ISequentialInStream **inStream)
{
RINOK(Finilize());
const CDirItem &dirItem = (*DirItems)[index];
GetStream2(dirItem.Name);
if (dirItem.isDir())
return S_OK;
{
CInFileStream *inStreamSpec = new CInFileStream;
CMyComPtr<ISequentialInStream> inStreamLoc(inStreamSpec);
FString path = DirPrefix dirItem.FullPath;
if (!inStreamSpec->Open(path))
{
DWORD sysError = ::GetLastError();
FailedCodes.Add(sysError);
FailedFiles.Add(path);
// if (systemError == ERROR_SHARING_VIOLATION)
{
PrintNewLine();
PrintError("WARNING: can't open file");
// Print(NError::MyFormatMessageW(systemError));
return S_FALSE;
}
// return sysError;
}
*inStream = inStreamLoc.Detach();
}
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::SetOperationResult(Int32 operationResult )
{
m_NeedBeClosed = true;
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::GetVolumeSize(UInt32 index, UInt64 *size)
{
if (VolumesSizes.Size() == 0)
return S_FALSE;
if (index >= (UInt32)VolumesSizes.Size())
index = VolumesSizes.Size() - 1;
*size = VolumesSizes[index];
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::GetVolumeStream(UInt32 index, ISequentialOutStream **volumeStream)
{
wchar_t temp[16];
ConvertUInt32ToString(index 1, temp);
UString res = temp;
while (res.Len() < 2)
res.InsertAtFront(L'0');
UString fileName = VolName;
fileName = '.';
fileName = res;
fileName = VolExt;
COutFileStream *streamSpec = new COutFileStream;
CMyComPtr<ISequentialOutStream> streamLoc(streamSpec);
if (!streamSpec->Create(us2fs(fileName), false))
return ::GetLastError();
*volumeStream = streamLoc.Detach();
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::CryptoGetTextPassword2(Int32 *passwordIsDefined, BSTR *password)
{
if (!PasswordIsDefined)
{
if (AskPassword)
{
// You can ask real password here from user
// Password = GetPassword(OutStream);
// PasswordIsDefined = true;
PrintError("Password is not defined");
return E_ABORT;
}
}
*passwordIsDefined = BoolToInt(PasswordIsDefined);
return StringToBstr(Password, password);
}
bool __stdcall I7zOutArchive::SaveToFile(LPWSTR lpOutFilePath, unsigned int nSpeed = 1, bool isSFX = false, unsigned int nCount512K = 1)
{
if (NULL == lpOutFilePath)
{
return false;
}
if (':' != lpOutFilePath[1])
{
return false;
}
SECURITY_ATTRIBUTES secattr = { 0 };
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = TRUE;
HANDLE rPipe = NULL, wPipe = NULL;
CreatePipe(&rPipe, &wPipe, &secattr, 0);
shared_ptr<HANDLE> ptrHandler(&rPipe,handlecloser);
shared_ptr<HANDLE> ptrHandlew(&wPipe, handlecloser);
STARTUPINFO sInfo = { 0 };
PROCESS_INFORMATION pInfo = { 0 };
sInfo.cb = sizeof(sInfo);
sInfo.dwFlags = STARTF_USESTDHANDLES;
sInfo.hStdInput = NULL;
sInfo.hStdOutput = wPipe;
sInfo.hStdError = wPipe;
wstring wsExecute;
wsExecute = TEXT("C:\\UTIL\\7z.exe ");
wsExecute = TEXT("A \"C:\\qt-everywhere-src-51.zip\" \"C:\\qt-everywhere-src-5.15.1.zip\" -v200m ");
if (CreateProcessW(0, (LPWSTR)wsExecute.c_str(), 0, 0, TRUE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, 0, 0, &sInfo, &pInfo) != 0)
{
string m_csOutput;
bool res = false;
do
{
DWORD reDword;
BYTE buf[100] = { 0 };
res = ::ReadFile(rPipe, buf, 100, &reDword, 0);
m_csOutput = (char *)buf;
} while (res);
return true;
}
else
{
return false;
}
}
bool __stdcall I7zOutArchive::SaveToFile(LPWSTR lpOutFilePath,LPWSTR LPFileType )
{
if (NULL == lpOutFilePath)
{
return false;
}
if (':' != lpOutFilePath[1])
{
return false;
}
_wcslwr_s(LPFileType, wcslen(LPFileType) 1);
if (!wcscmp(LPFileType, TEXT("7z"))&&
!wcscmp(LPFileType, TEXT("zip"))&&
!wcscmp(LPFileType, TEXT("bz2"))&&
!wcscmp(LPFileType, TEXT("xz"))&&
!wcscmp(LPFileType, TEXT("tar"))&&
!wcscmp(LPFileType, TEXT("gz"))&&
!wcscmp(LPFileType, TEXT("wim")) )
{
return false;
}
vector<CLSID> vtr;
for (auto itr = g_ArcInfo.begin();itr != g_ArcInfo.end();itr )
{
wstring wstr = itr->Exts[LPFileType];
if (wstr.length())
{
if (0 == itr->SignatureOffset)
{
vtr.push_back(itr->ClassID);
}
}
}
if (0 == vtr.size())
{
return false;
}
COutFileStream *outFileStreamSpec = new COutFileStream;
CMyComPtr<IOutStream> outFileStream = outFileStreamSpec;
if (!outFileStreamSpec->Create(lpOutFilePath, false))
{
PrintError("can't create archive file");
return false;
}
CMyComPtr<IOutArchive> outArchive;
if (g_CreateObjectFunc(&vtr[0], &IID_IOutArchive, (void **)&outArchive) != S_OK)
{
PrintError("Can not get class object");
return false;
}
CArchiveUpdateCallback *updateCallbackSpec = new CArchiveUpdateCallback;
CMyComPtr<IArchiveUpdateCallback2> updateCallback(updateCallbackSpec);
updateCallbackSpec->Init(&m_dirItems);
if (0 == m_wstr.length())
{
updateCallbackSpec->PasswordIsDefined = false;
}
else
{
updateCallbackSpec->PasswordIsDefined = true;
updateCallbackSpec->Password = m_wstr.c_str();
}
HRESULT result = outArchive->UpdateItems(outFileStream, m_dirItems.Size(), updateCallback);
updateCallbackSpec->Finilize();
m_dirItems.Clear();
if (result != S_OK)
{
PrintError("Update Error");
return false;
}
FOR_VECTOR(i, updateCallbackSpec->FailedFiles)
{
PrintNewLine();
PrintError("Error for file", updateCallbackSpec->FailedFiles[i]);
}
if (updateCallbackSpec->FailedFiles.Size() != 0)
return false;
else
return true;
}
bool __stdcall I7zOutArchive::AddFile(LPWSTR lpFileName, LPWSTR lpFullPath)
{
CDirItem di;
FString name = lpFullPath;
NFind::CFileInfo fi;
if (!fi.Find(lpFullPath))
{
PrintError("Can't find file", name);
return false;
}
di.Attrib = fi.Attrib;
di.Size = fi.Size;
di.CTime = fi.CTime;
di.ATime = fi.ATime;
di.MTime = fi.MTime;
di.Name = lpFileName;
di.FullPath = lpFullPath;
m_dirItems.Add(di);
return true;
}
void __stdcall I7zInArchive::ExtractCancel()
{
m_extractCallbackSpec->m_cancel = true;
}
void __stdcall I7zInArchive::ExtractPause()
{
m_extractCallbackSpec->m_stop = true;
if (NULL == m_extractCallbackSpec->m_Handle)
{
m_extractCallbackSpec->m_Handle = CreateSemaphore(NULL, 0, 1, NULL);
}
}
void __stdcall I7zInArchive::ExtractStar()
{
m_extractCallbackSpec->m_stop = false;
ReleaseSemaphore(m_extractCallbackSpec->m_Handle, 1, NULL);
}
LPWSTR __stdcall I7zInArchive::GetItemCreateTime(unsigned int index)
{
wchar_t wTemp[1024] = { 0 };
NCOM::CPropVariant prop;
m_archive->GetProperty(index, kpidCTime, &prop);
SYSTEMTIME st = {0};
FileTimeToLocalFileTime(&prop.filetime, &prop.filetime);
FileTimeToSystemTime(&prop.filetime, &st);
wsprintfW(wTemp,TEXT("%d-%d-%d %d:%d"), st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute);
return wTemp;
}
LPWSTR __stdcall I7zInArchive::GetItemModifyTime(unsigned int index)
{
wchar_t wTemp[1024] = { 0 };
NCOM::CPropVariant prop;
m_archive->GetProperty(index, kpidMTime, &prop);
SYSTEMTIME st = {0};
FileTimeToLocalFileTime(&prop.filetime, &prop.filetime);
FileTimeToSystemTime(&prop.filetime, &st);
wsprintfW(wTemp, TEXT("%d-%d-%d %d:%d"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute);
return wTemp;
}
bool __stdcall I7zInArchive::ExtractTo(LPWSTR lpOutPath,bool isTest = false)
{
if (false == isTest)
{
if (NULL == lpOutPath)
return false;
if (':' != lpOutPath[1])
return false;
SHCreateDirectoryExW(NULL, lpOutPath, NULL);
}
m_extractCallbackSpec = new CArchiveExtractCallback;
CMyComPtr<IArchiveExtractCallback> extractCallback(m_extractCallbackSpec);
if(NULL == lpOutPath)
m_extractCallbackSpec->Init(m_archive, TEXT("C:\\text"));
else
m_extractCallbackSpec->Init(m_archive, lpOutPath);
m_extractCallbackSpec->nFileType = 3;
m_extractCallbackSpec->PasswordIsDefined = false;
if (0 == m_wstr.length())
{
m_extractCallbackSpec->PasswordIsDefined = false;
}
else
{
m_extractCallbackSpec->PasswordIsDefined = true;
m_extractCallbackSpec->Password = m_wstr.c_str();
}
HRESULT result = m_archive->Extract(NULL, (UInt32)(Int32)(-1), isTest, extractCallback);
if (NULL != m_extractCallbackSpec->m_Handle)
{
CloseHandle(m_extractCallbackSpec->m_Handle);
}
if (result != S_OK)
return false;
else
return true;
}
bool __stdcall I7zInArchive::ExtractItems(unsigned int* nIndex, unsigned int nCount, LPWSTR lpOutPath)
{
if (NULL == nIndex || nCount == 0)
return false;
if (NULL == lpOutPath)
return false;
if (':' != lpOutPath[1])
return false;
SHCreateDirectoryExW(NULL, lpOutPath, NULL);
m_extractCallbackSpec = new CArchiveExtractCallback;
m_extractCallbackSpec->nFileType = 1;
CMyComPtr<IArchiveExtractCallback> extractCallback(m_extractCallbackSpec);
m_extractCallbackSpec->Init(m_archive, lpOutPath); // second parameter is output folder path
m_extractCallbackSpec->PasswordIsDefined = false;
if (0 == m_wstr.length())
{
m_extractCallbackSpec->PasswordIsDefined = false;
}
else
{
m_extractCallbackSpec->PasswordIsDefined = true;
m_extractCallbackSpec->Password = m_wstr.c_str();
}
HRESULT result = m_archive->Extract(nIndex, (UInt32)(Int32)nCount, false, extractCallback);
if (NULL != m_extractCallbackSpec->m_Handle)
{
CloseHandle(m_extractCallbackSpec->m_Handle);
}
if (result != S_OK)
return false;
else
return true;
}
void __stdcall I7zInArchive::SetFileType(int nType)
{
if (m_extractCallbackSpec)
{
m_extractCallbackSpec->nFileType = nType;
}
}
unsigned long long int I7zInArchive::GetItemPackSize(unsigned int index)
{
NCOM::CPropVariant prop;
m_archive->GetProperty(index, kpidPackSize, &prop);
return prop.uhVal.QuadPart;
}
bool I7zInArchive::GetItemIsFolder(unsigned int index)
{
NCOM::CPropVariant prop;
m_archive->GetProperty(index, kpidIsDir, &prop);
return (bool)prop.boolVal;
}
unsigned long long int I7zInArchive::GetItemSize(unsigned int index)
{
NCOM::CPropVariant prop;
m_archive->GetProperty(index, kpidSize, &prop);
return prop.uhVal.QuadPart;
}
void I7zInArchive::GetNumberOfItems(unsigned int *numItems)
{
m_archive->GetNumberOfItems(numItems);
}
LPWSTR I7zInArchive::GetItemPath(unsigned int index)
{
NCOM::CPropVariant prop;
m_archive->GetProperty(index, kpidPath, &prop);
return (LPWSTR)prop.bstrVal;
}
void I7zInArchive::SetPassword(LPWSTR lppassword)
{
m_wstr = lppassword;
g_strPsw = lppassword;
}
bool I7zInArchive::OpenFile(CLSID vtr,LPWSTR szFileName)
{
if (g_CreateObjectFunc(&vtr, &IID_IInArchive, (void **)&m_archive) != S_OK)
{
return false;
}
CInFileStream *fileSpec = new CInFileStream;
CMyComPtr<IInStream> file = fileSpec;
if (!fileSpec->Open(us2fs(szFileName)))
{
return false;
}
// UInt64 _arhiveBeginStreamPosition, _fileEndPosition;
// fileSpec->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition);
// fileSpec->Seek(0, STREAM_SEEK_END, &_fileEndPosition);
CArchiveOpenCallback *openCallbackSpec = new CArchiveOpenCallback;
CMyComPtr<IArchiveOpenCallback> openCallback(openCallbackSpec);
if (0 == m_wstr.length())
{
openCallbackSpec->PasswordIsDefined = false;
}
else
{
openCallbackSpec->PasswordIsDefined = true;
openCallbackSpec->Password = m_wstr.c_str();
}
const UInt64 scanSize = 1 << 23;
if (m_archive->Open(file, &scanSize, openCallback) == S_OK)
{
m_isOpen = true;
return true;
}
return false;
}
bool I7zInArchive::OpenFile(LPWSTR szFileName)
{
wchar_t drive[10] = { 0 };
wchar_t dir[256] = { 0 };
wchar_t fname[256] = { 0 };
wchar_t ext[256] = { 0 };
wchar_t ext1[256] = { 0 };
if (NULL == szFileName)
{
return false;
}
if (':' != szFileName[1])
{
return false;
}
::_wsplitpath_s(szFileName, drive, _MAX_DRIVE, dir, _MAX_DIR,fname, _MAX_FNAME, ext, _MAX_EXT);
if ('.' == ext[0])
{
// if ('0' == ext[1]&& '0'== ext[2])
// {
// memcpy(ext1, PathFindExtensionW(fname) 1, 4);
// }
// else
// {
// memcpy(ext1, &ext[1], 10);
// }
memcpy(ext1, &ext[1], 10);
_wcslwr_s(ext1, wcslen(ext1) 1);
}
vector<CLSID> vtr;
for (vector<CArcInfoEx>::iterator itr = g_ArcInfo.begin(); itr != g_ArcInfo.end(); itr)
{
wstring wstr = itr->Exts[ext1];
if (wstr.length())
{
if (0 == wstr.compare(ext1))
{
vtr.push_back(itr->ClassID);
}
}
}
if (vtr.size())
{
if (true == OpenFile(vtr.at(0),szFileName))
{
return true;
}
}
DWORD nSize = 0;
BYTE *buf = NULL;
DWORD dwBytes = 0;
HANDLE hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return false;
DWORD dwsizehigh_src, dwsizelow_src;
dwsizelow_src = GetFileSize(hFile, &dwsizehigh_src);
if (dwsizehigh_src > 0 || dwsizelow_src > nSize)
{
nSize = 1048576;
}
else
{
nSize = dwsizelow_src;
}
buf = new BYTE[nSize];
shared_ptr<BYTE> pbuf(buf);
shared_ptr<HANDLE> ptr(&hFile, handlecloser);
if (false == ReadFile(hFile, buf, nSize, &dwBytes, NULL))
return false;
for (vector<CArcInfoEx>::iterator itr1 = g_ArcInfo.begin(); itr1 != g_ArcInfo.end(); itr1)
{
const CObjectVector<CByteBuffer> &sigs = itr1->Signatures;
for (int n = 0; n < itr1->Signatures.Size(); n )
{
const CByteBuffer &sig = sigs[n];
if (memcmp(sig, buf itr1->SignatureOffset, sig.Size()) == 0)
if (true == OpenFile(itr1->ClassID, szFileName))
{
return true;
}
}
}
return false;
}
bool InitModule()
{
char szPath[256] = { 0 };
CS_GetApplicationPath(szPath, 256, "7z.dll");
HMODULE hlib = ::LoadLibraryA(szPath);
if (NULL == hlib)
{
return false;
}
g_CreateObjectFunc = (Func_CreateObject)GetProcAddress(hlib, "CreateObject");
if (!g_CreateObjectFunc)
return false;
g_GetNumberOfFormats = (Func_GetNumberOfFormats)GetProcAddress(hlib, "GetNumberOfFormats");
if (!g_GetNumberOfFormats)
return false;
g_GetHandlerProperty2 = (Func_GetHandlerProperty2)GetProcAddress(hlib, "GetHandlerProperty2");
if (!g_GetHandlerProperty2)
return false;
g_GetIsArc = (Func_GetIsArc)GetProcAddress(hlib, "GetIsArc");
if (!g_GetIsArc)
return false;
vector<wstring> vExe, vaddExt;
UInt32 numFormats = 0;
g_GetNumberOfFormats(&numFormats);
for (UInt32 i = 0; i < numFormats; i )
{
NCOM::CPropVariant prop;
CArcInfoEx item;
item.FormatIndex = i;
{
prop.Clear();
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kName, &prop);
if (prop.vt != VT_EMPTY)
{
item.wstrName = prop.bstrVal;
}
}
{
prop.Clear();
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kClassID, &prop);
if (::SysStringByteLen(prop.bstrVal) != sizeof(GUID))
continue;
item.ClassID = *(const GUID *)prop.bstrVal;
}
{
prop.Clear();
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kExtension, &prop);
if (prop.vt != VT_EMPTY)
{
SplitString(prop.bstrVal, vExe);
}
}
{
prop.Clear();
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kAddExtension, &prop);
if (prop.vt != VT_EMPTY)
{
SplitString(prop.bstrVal, vaddExt);
}
}
for (int n = 0; n < vExe.size(); n )
{
if (n < vaddExt.size())
{
if (L"*" != vaddExt[n])
{
item.Exts[vExe.at(n)] = vaddExt.at(n);
continue;
}
}
item.Exts[vExe.at(n)] = vExe.at(n);
}
{
prop.Clear();
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kUpdate, &prop);
item.isUpdateEnabled = prop.boolVal;
}
{
prop.Clear();
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kFlags, &prop);
item.Flags = prop.ulVal;
}
{
prop.Clear();
CByteBuffer sig;
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kSignature, &prop);
UINT len = ::SysStringByteLen(prop.bstrVal);
if (len != 0)
item.Signatures.AddNew().CopyFrom((const Byte *)prop.bstrVal, len);
else
{
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kMultiSignature, &prop);
ParseSignatures((const Byte *)prop.bstrVal, (unsigned)SysStringByteLen(prop.bstrVal), item.Signatures);
}
}
{
prop.Clear();
g_GetHandlerProperty2(i, NArchive::NHandlerPropID::kSignatureOffset, &prop);
item.SignatureOffset = prop.ulVal;
}
g_GetIsArc(i, &item.IsArcFunc);
g_ArcInfo.push_back(item);
}
return true;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
if (false == InitModule())
return false;
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void __stdcall SetCallBack(LPREQUESTCALLBACK lpCallBack)
{
g_lpRequestCallback = lpCallBack;
}
bool __stdcall GetI7zInArchiveClass(I7zInArchive*& i7z)
{
i7z = new I7zInArchive;
if (i7z)
return true;
else
return false;
}
void __stdcall FreeClass(void* i7z)
{
//全部放入vector或者只能指针释放
if (i7z)
{
delete i7z;
i7z = NULL;
}
}
bool __stdcall GetI7zOutArchiveClass(I7zOutArchive*& i7z)
{
i7z = new I7zOutArchive;
if (i7z)
return true;
else
return false;
}
//{23170F69 - 40C1 - 278A - 1000 - 000110010000}
#define NT_CHECK_FAIL_ACTION PrintError("Unsupported Windows version"); return 1;
int MY_CDECL main(int numArgs, const char *args[])
{
InitModule();
I7zInArchive* I7zIn = NULL;
I7zOutArchive* I7zout = NULL;
GetI7zInArchiveClass(I7zIn);
//I7zIn->OpenFile(TEXT("C:\\qt-everywhere-src-5.15.1.zip"));
//int i[10];
//for (int n = 0; n<10;n )
//{
// i[n] = n;
//}
//I7zIn->ExtractItems((unsigned int*)&i, 10, TEXT("D:\\2222"));
//I7zIn->OpenFile( TEXT("c:\\windows11111"));
//I7zIn->ExtractTo(NULL,true);
GetI7zOutArchiveClass(I7zout);
I7zout->AddFile(TEXT("7-ZIP\\7zFM.exe"), TEXT("C:\\Program Files\\7-ZIP\\7zFM.exe"));
I7zout->AddFile(TEXT("vscd1"), TEXT("C:\\迅雷下载\\vscd1"));
I7zout->SaveToFile(TEXT("d:\\DriverTest_1.7z"), TEXT("7z"));
// I7zout->SaveToFile(TEXT("C:\\Program Files\\7-ZIP\\7zFM.zip"), 1,false,1);
return 0;
}
;
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论