STDMETHODIMP CExtractCallbackImp::GetStream(UInt32 index, ISequentialOutStream **outStream, Int32 askExtractMode) { #ifndef _NO_PROGRESS if(ProgressDialog.ProgressSynch.GetStopped()) return E_ABORT; #endif _outFileStream.Release(); NCOM::CPropVariant propVariantName; RINOK(_archiveHandler->GetProperty(index, kpidPath, &propVariantName)); UString fullPath; if(propVariantName.vt == VT_EMPTY) fullPath = _itemDefaultName; else { if(propVariantName.vt != VT_BSTR) return E_FAIL; fullPath = propVariantName.bstrVal; } _filePath = fullPath; // m_CurrentFilePath = GetSystemString(fullPath, _codePage); if(askExtractMode == NArchive::NExtract::NAskMode::kExtract) { NCOM::CPropVariant propVariant; RINOK(_archiveHandler->GetProperty(index, kpidAttributes, &propVariant)); if (propVariant.vt == VT_EMPTY) _processedFileInfo.Attributes = _attributesDefault; else { if (propVariant.vt != VT_UI4) return E_FAIL; _processedFileInfo.Attributes = propVariant.ulVal; } RINOK(_archiveHandler->GetProperty(index, kpidIsFolder, &propVariant)); _processedFileInfo.IsDirectory = VARIANT_BOOLToBool(propVariant.boolVal); bool isAnti = false; { NCOM::CPropVariant propVariantTemp; RINOK(_archiveHandler->GetProperty(index, kpidIsAnti, &propVariantTemp)); if (propVariantTemp.vt == VT_BOOL) isAnti = VARIANT_BOOLToBool(propVariantTemp.boolVal); } RINOK(_archiveHandler->GetProperty(index, kpidLastWriteTime, &propVariant)); switch(propVariant.vt) { case VT_EMPTY: _processedFileInfo.UTCLastWriteTime = _utcLastWriteTimeDefault; break; case VT_FILETIME: _processedFileInfo.UTCLastWriteTime = propVariant.filetime; break; default: return E_FAIL; } UStringVector pathParts; SplitPathToParts(fullPath, pathParts); if(pathParts.IsEmpty()) return E_FAIL; UString processedPath = fullPath; if(!_processedFileInfo.IsDirectory) pathParts.DeleteBack(); if (!pathParts.IsEmpty()) { if (!isAnti) CreateComplexDirectory(pathParts); } UString fullProcessedPath = _directoryPath + processedPath; if(_processedFileInfo.IsDirectory) { _diskFilePath = fullProcessedPath; if (isAnti) NDirectory::MyRemoveDirectory(_diskFilePath); return S_OK; } NFind::CFileInfoW fileInfo; if(NFind::FindFile(fullProcessedPath, fileInfo)) { if (!NDirectory::DeleteFileAlways(fullProcessedPath)) { _message = kCantDeleteFile; return E_FAIL; } } if (!isAnti) { _outFileStreamSpec = new COutFileStream; CMyComPtr<ISequentialOutStream> outStreamLoc(_outFileStreamSpec); if (!_outFileStreamSpec->Create(fullProcessedPath, true)) { _message = kCantOpenFile; return E_FAIL; } _outFileStream = outStreamLoc; *outStream = outStreamLoc.Detach(); } _diskFilePath = fullProcessedPath; } else { *outStream = NULL; } return S_OK; }