实例介绍
【实例简介】
【实例截图】
【实例截图】
【核心代码】
// 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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论