VOID PkUpdateArchiveExtractCallback::Run() { HRESULT result; IInArchive *currentArchive; PhAcquireQueuedLockExclusive(&Lock); while (!ThreadStopping) { if (!InArchive) { PhWaitForCondition(&Condition, &Lock, NULL); continue; } currentArchive = InArchive; currentArchive->AddRef(); result = currentArchive->Extract(NULL, -1, FALSE, this); currentArchive->Release(); if (result != E_ABORT && !SUCCEEDED(result)) Result = result; } PhReleaseQueuedLockExclusive(&Lock); }
int ArchiveFile::ExtractItem(int index, const char* outFilename) const { assert(!s_formatInfos.empty()); //assert(index >= 0 && index < m_numItems); if(!(index >= 0 && index < m_numItems)) return 0; ArchiveItem& item = m_items[index]; int rv = item.size; #ifndef ANDROID DWORD outAttributes = GetFileAttributes(outFilename); if(outAttributes & FILE_ATTRIBUTE_READONLY) SetFileAttributes(outFilename, outAttributes & ~FILE_ATTRIBUTE_READONLY); // temporarily remove read-only attribute so we can decompress to there #endif if(m_typeIndex < 0) { #ifndef ANDROID //I don't *think* we care about this // uncompressed if(!CopyFile(m_filename, outFilename, false)) #endif rv = 0; } else { IInArchive* object = NULL; HRESULT hr = E_FAIL; if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object))) { InFileStream* ifs = new InFileStream(m_filename); if(SUCCEEDED(object->Open(ifs,0,0))) { gameInfo.resize(rv); OutStream* os = new OutStream(index, outFilename); const UInt32 indices [1] = {index}; hr = object->Extract(indices, 1, 0, os); object->Close(); } object->Release(); } if(FAILED(hr)) rv = 0; } #ifndef ANDROID if(outAttributes & FILE_ATTRIBUTE_READONLY) SetFileAttributes(outFilename, outAttributes); // restore read-only attribute #endif return rv; }
int ArchiveFile::ExtractItem(int index, unsigned char* outBuffer, int bufSize) const { assert(!s_formatInfos.empty()); //assert(index >= 0 && index < m_numItems); if(!(index >= 0 && index < m_numItems)) return 0; ArchiveItem& item = m_items[index]; if(bufSize < item.size) return 0; if(m_typeIndex < 0) { // uncompressed FILE* file = fopen(m_filename, "rb"); fread(outBuffer, 1, item.size, file); fclose(file); } else { IInArchive* object = NULL; HRESULT hr = E_FAIL; if(SUCCEEDED(CreateObject(&s_formatInfos[m_typeIndex].guid, &IID_IInArchive, (void**)&object))) { InFileStream* ifs = new InFileStream(m_filename); if(SUCCEEDED(object->Open(ifs,0,0))) { OutStream* os = new OutStream(index, outBuffer, item.size); const UInt32 indices [1] = {index}; hr = object->Extract(indices, 1, 0, os); object->Close(); } object->Release(); } if(FAILED(hr)) return 0; } return item.size; }
HRESULT PkExtractPackage( __in PPK_PACKAGE Package, __in_opt PPK_ACTION_LIST ActionList, __in PPK_PACKAGE_CALLBACK Callback, __in_opt PVOID Context ) { HRESULT result; IInArchive *inArchive; PkArchiveExtractCallback *extractCallback; PULONG items; ULONG numberOfItems; PPK_ACTION_SEGMENT segment; ULONG i; result = S_OK; inArchive = (IInArchive *)Package; extractCallback = new PkArchiveExtractCallback; extractCallback->ReferenceCount = 1; extractCallback->ActionList = ActionList; extractCallback->Callback = Callback; extractCallback->Context = Context; extractCallback->InArchive = inArchive; if (ActionList) { items = (PULONG)PhAllocate(sizeof(ULONG) * ActionList->NumberOfActions); segment = ActionList->FirstSegment; numberOfItems = 0; while (segment) { for (i = 0; i < segment->Count; i++) { if (numberOfItems >= ActionList->NumberOfActions) { result = E_INVALIDARG; break; } if (segment->Actions[i].Type == PkUpdateType) { items[numberOfItems] = segment->Actions[i].u.Update.Index; numberOfItems++; } } segment = segment->Next; } extractCallback->CreateActionMap(); } else { items = NULL; numberOfItems = -1; } if (!SUCCEEDED(result)) return result; result = inArchive->Extract((UInt32 *)items, numberOfItems, FALSE, extractCallback); if (items) PhFree(items); extractCallback->Release(); return result; }
static HRESULT DecompressArchive( const CArc &arc, UInt64 packSize, const NWildcard::CCensorNode &wildcardCensor, const CExtractOptions &options, IExtractCallbackUI *callback, CArchiveExtractCallback *extractCallbackSpec, UString &errorMessage, UInt64 &stdInProcessed) { stdInProcessed = 0; IInArchive *archive = arc.Archive; CRecordVector<UInt32> realIndices; if (!options.StdInMode) { UInt32 numItems; RINOK(archive->GetNumberOfItems(&numItems)); for (UInt32 i = 0; i < numItems; i++) { UString filePath; RINOK(arc.GetItemPath(i, filePath)); bool isFolder; RINOK(IsArchiveItemFolder(archive, i, isFolder)); if (!wildcardCensor.CheckPath(filePath, !isFolder)) continue; realIndices.Add(i); } if (realIndices.Size() == 0) { callback->ThereAreNoFiles(); return S_OK; } } UStringVector removePathParts; UString outDir = options.OutputDir; outDir.Replace(L"*", GetCorrectFsPath(arc.DefaultName)); #ifdef _WIN32 // GetCorrectFullFsPath doesn't like "..". // outDir.TrimRight(); // outDir = GetCorrectFullFsPath(outDir); #endif if (!outDir.IsEmpty()) if (!NFile::NDirectory::CreateComplexDirectory(outDir)) { HRESULT res = ::GetLastError(); if (res == S_OK) res = E_FAIL; errorMessage = ((UString)L"Can not create output directory ") + outDir; return res; } extractCallbackSpec->Init( options.StdInMode ? &wildcardCensor : NULL, &arc, callback, options.StdOutMode, options.TestMode, options.CalcCrc, outDir, removePathParts, packSize); #if !defined(_7ZIP_ST) && !defined(_SFX) RINOK(SetProperties(archive, options.Properties)); #endif HRESULT result; Int32 testMode = (options.TestMode && !options.CalcCrc) ? 1: 0; if (options.StdInMode) { result = archive->Extract(NULL, (UInt32)(Int32)-1, testMode, extractCallbackSpec); NCOM::CPropVariant prop; if (archive->GetArchiveProperty(kpidPhySize, &prop) == S_OK) if (prop.vt == VT_UI8 || prop.vt == VT_UI4) stdInProcessed = ConvertPropVariantToUInt64(prop); } else result = archive->Extract(&realIndices.Front(), realIndices.Size(), testMode, extractCallbackSpec); return callback->ExtractResult(result); }