void CPanel::Properties() { CMyComPtr<IGetFolderArchiveProperties> getFolderArchiveProperties; _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties); if (!getFolderArchiveProperties) { InvokeSystemCommand("properties"); return; } { UString message; CRecordVector<UInt32> operatedIndices; GetOperatedItemIndices(operatedIndices); if (operatedIndices.Size() == 1) { UInt32 index = operatedIndices[0]; // message += L"Item:\n"; UInt32 numProps; if (_folder->GetNumberOfProperties(&numProps) == S_OK) { for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE varType; if (_folder->GetPropertyInfo(i, &name, &propID, &varType) != S_OK) continue; NCOM::CPropVariant prop; if (_folder->GetProperty(index, propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } message += kSeparator; } message += LangString(IDS_PROPERTY_FILE_TYPE, 0x02000214); message += kPropValueSeparator; message += GetFolderTypeID(); message += L"\n"; { NCOM::CPropVariant prop; if (_folder->GetFolderProperty(kpidPath, &prop) == S_OK) { AddPropertyString(kpidName, L"Path", prop, message); } } CMyComPtr<IFolderProperties> folderProperties; _folder.QueryInterface(IID_IFolderProperties, &folderProperties); if (folderProperties) { UInt32 numProps; if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK) { for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (_folder->GetFolderProperty(propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } } CMyComPtr<IGetFolderArchiveProperties> getFolderArchiveProperties; _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties); if (getFolderArchiveProperties) { CMyComPtr<IFolderArchiveProperties> getProps; getFolderArchiveProperties->GetFolderArchiveProperties(&getProps); if (getProps) { UInt32 numProps; if (getProps->GetNumberOfArchiveProperties(&numProps) == S_OK) { if (numProps > 0) message += kSeparator; for (UInt32 i = 0; i < numProps; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; if (getProps->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (getProps->GetArchiveProperty(propID, &prop) != S_OK) continue; AddPropertyString(propID, name, prop, message); } } } } ::MessageBoxW(*(this), message, LangString(IDS_PROPERTIES, 0x03020900), MB_OK); } }
void CPlugin::GetOpenPluginInfo(struct OpenPluginInfo *info) { info->StructSize = sizeof(*info); info->Flags = OPIF_USEFILTER | OPIF_USESORTGROUPS| OPIF_USEHIGHLIGHTING| OPIF_ADDDOTS | OPIF_COMPAREFATTIME; UINT codePage = ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; MyStringCopy(m_FileNameBuffer, (const char *)UnicodeStringToMultiByte(m_FileName, codePage)); info->HostFile = m_FileNameBuffer; // test it it is not static MyStringCopy(m_CurrentDirBuffer, (const char *)UnicodeStringToMultiByte(m_CurrentDir, CP_OEMCP)); info->CurDir = m_CurrentDirBuffer; info->Format = kPluginFormatName; UString name; { UString fullName; int index; NFile::NDirectory::MyGetFullPathName(m_FileName, fullName, index); name = fullName.Mid(index); } m_PannelTitle = UString(L' ') + _archiveTypeName + UString(L':') + name + UString(L' '); if (!m_CurrentDir.IsEmpty()) { // m_PannelTitle += '\\'; m_PannelTitle += m_CurrentDir; } MyStringCopy(m_PannelTitleBuffer, (const char *)UnicodeStringToMultiByte(m_PannelTitle, CP_OEMCP)); info->PanelTitle = m_PannelTitleBuffer; memset(m_InfoLines, 0, sizeof(m_InfoLines)); MyStringCopy(m_InfoLines[0].Text, ""); m_InfoLines[0].Separator = TRUE; MyStringCopy(m_InfoLines[1].Text, g_StartupInfo.GetMsgString(NMessageID::kArchiveType)); MyStringCopy(m_InfoLines[1].Data, (const char *)UnicodeStringToMultiByte(_archiveTypeName, CP_OEMCP)); int numItems = 2; { CMyComPtr<IFolderProperties> folderProperties; _folder.QueryInterface(IID_IFolderProperties, &folderProperties); if (folderProperties) { UInt32 numProps; if (folderProperties->GetNumberOfFolderProperties(&numProps) == S_OK) { for (UInt32 i = 0; i < numProps && numItems < kNumInfoLinesMax; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; if (folderProperties->GetFolderPropertyInfo(i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (_folder->GetFolderProperty(propID, &prop) != S_OK || prop.vt == VT_EMPTY) continue; InfoPanelLine &item = m_InfoLines[numItems++]; MyStringCopy(item.Text, (const char *)GetNameOfProp2(propID, name)); MyStringCopy(item.Data, (const char *)PropToString2(prop, propID)); } } } } if (numItems < kNumInfoLinesMax) { InfoPanelLine &item = m_InfoLines[numItems++]; MyStringCopy(item.Text, ""); MyStringCopy(item.Data, ""); item.Separator = TRUE; } { CMyComPtr<IGetFolderArchiveProperties> getFolderArchiveProperties; _folder.QueryInterface(IID_IGetFolderArchiveProperties, &getFolderArchiveProperties); if (getFolderArchiveProperties) { CMyComPtr<IFolderArchiveProperties> getProps; getFolderArchiveProperties->GetFolderArchiveProperties(&getProps); if (getProps) { UInt32 numProps; if (getProps->GetNumberOfArchiveProperties(&numProps) == S_OK) { /* if (numProps > 0) message += kSeparator; */ for (UInt32 i = 0; i < numProps && numItems < kNumInfoLinesMax; i++) { CMyComBSTR name; PROPID propID; VARTYPE vt; if (getProps->GetArchivePropertyInfo(i, &name, &propID, &vt) != S_OK) continue; NCOM::CPropVariant prop; if (getProps->GetArchiveProperty(propID, &prop) != S_OK || prop.vt == VT_EMPTY) continue; InfoPanelLine &item = m_InfoLines[numItems++]; MyStringCopy(item.Text, (const char *)GetNameOfProp2(propID, name)); MyStringCopy(item.Data, (const char *)PropToString2(prop, propID)); } } } } } //m_InfoLines[1].Separator = 0; info->InfoLines = m_InfoLines; info->InfoLinesNumber = numItems; info->DescrFiles = NULL; info->DescrFilesNumber = 0; PanelModeColumnTypes.Empty(); PanelModeColumnWidths.Empty(); /* AddColumn(kpidName); AddColumn(kpidSize); AddColumn(kpidPackedSize); AddColumn(kpidMTime); AddColumn(kpidCTime); AddColumn(kpidATime); AddColumn(kpidAttrib); PanelMode.ColumnTypes = (char *)(const char *)PanelModeColumnTypes; PanelMode.ColumnWidths = (char *)(const char *)PanelModeColumnWidths; PanelMode.ColumnTitles = NULL; PanelMode.FullScreen = TRUE; PanelMode.DetailedStatus = FALSE; PanelMode.AlignExtensions = FALSE; PanelMode.CaseConversion = FALSE; PanelMode.StatusColumnTypes = "N"; PanelMode.StatusColumnWidths = "0"; PanelMode.Reserved[0] = 0; PanelMode.Reserved[1] = 0; info->PanelModesArray = &PanelMode; info->PanelModesNumber = 1; */ info->PanelModesArray = NULL; info->PanelModesNumber = 0; info->StartPanelMode = 0; info->StartSortMode = 0; info->KeyBar = NULL; info->ShortcutData = NULL; }
HRESULT CArc::OpenStream( CCodecs *codecs, int formatIndex, IInStream *stream, ISequentialInStream *seqStream, IArchiveOpenCallback *callback) { Archive.Release(); ErrorMessage.Empty(); const UString fileName = ExtractFileNameFromPath(Path); UString extension; { int dotPos = fileName.ReverseFind(L'.'); if (dotPos >= 0) extension = fileName.Mid(dotPos + 1); } CIntVector orderIndices; if (formatIndex >= 0) orderIndices.Add(formatIndex); else { int i; int numFinded = 0; for (i = 0; i < codecs->Formats.Size(); i++) if (codecs->Formats[i].FindExtension(extension) >= 0) orderIndices.Insert(numFinded++, i); else orderIndices.Add(i); if (!stream) { if (numFinded != 1) return E_NOTIMPL; orderIndices.DeleteFrom(1); } #ifndef _SFX if (orderIndices.Size() >= 2 && (numFinded == 0 || extension.CompareNoCase(L"exe") == 0)) { CIntVector orderIndices2; CByteBuffer byteBuffer; const size_t kBufferSize = (1 << 21); byteBuffer.SetCapacity(kBufferSize); RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); size_t processedSize = kBufferSize; RINOK(ReadStream(stream, byteBuffer, &processedSize)); if (processedSize == 0) return S_FALSE; const Byte *buf = byteBuffer; CByteBuffer hashBuffer; const UInt32 kNumVals = 1 << (kNumHashBytes * 8); hashBuffer.SetCapacity(kNumVals); Byte *hash = hashBuffer; memset(hash, 0xFF, kNumVals); Byte prevs[256]; if (orderIndices.Size() >= 256) return S_FALSE; int i; for (i = 0; i < orderIndices.Size(); i++) { const CArcInfoEx &ai = codecs->Formats[orderIndices[i]]; const CByteBuffer &sig = ai.StartSignature; if (sig.GetCapacity() < kNumHashBytes) continue; UInt32 v = HASH_VAL(sig, 0); prevs[i] = hash[v]; hash[v] = (Byte)i; } processedSize -= (kNumHashBytes - 1); for (UInt32 pos = 0; pos < processedSize; pos++) { for (; pos < processedSize && hash[HASH_VAL(buf, pos)] == 0xFF; pos++); if (pos == processedSize) break; UInt32 v = HASH_VAL(buf, pos); Byte *ptr = &hash[v]; int i = *ptr; do { int index = orderIndices[i]; const CArcInfoEx &ai = codecs->Formats[index]; const CByteBuffer &sig = ai.StartSignature; if (sig.GetCapacity() != 0 && pos + sig.GetCapacity() <= processedSize + (kNumHashBytes - 1) && TestSignature(buf + pos, sig, sig.GetCapacity())) { orderIndices2.Add(index); orderIndices[i] = 0xFF; *ptr = prevs[i]; } else ptr = &prevs[i]; i = *ptr; } while (i != 0xFF); } for (i = 0; i < orderIndices.Size(); i++) { int val = orderIndices[i]; if (val != 0xFF) orderIndices2.Add(val); } orderIndices = orderIndices2; } else if (extension == L"000" || extension == L"001") { CByteBuffer byteBuffer; const size_t kBufferSize = (1 << 10); byteBuffer.SetCapacity(kBufferSize); Byte *buffer = byteBuffer; RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); size_t processedSize = kBufferSize; RINOK(ReadStream(stream, buffer, &processedSize)); if (processedSize >= 16) { Byte kRarHeader[] = {0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00}; if (TestSignature(buffer, kRarHeader, 7) && buffer[9] == 0x73 && (buffer[10] & 1) != 0) { for (int i = 0; i < orderIndices.Size(); i++) { int index = orderIndices[i]; const CArcInfoEx &ai = codecs->Formats[index]; if (ai.Name.CompareNoCase(L"rar") != 0) continue; orderIndices.Delete(i--); orderIndices.Insert(0, index); break; } } } } if (orderIndices.Size() >= 2) { int isoIndex = codecs->FindFormatForArchiveType(L"iso"); int udfIndex = codecs->FindFormatForArchiveType(L"udf"); int iIso = -1; int iUdf = -1; for (int i = 0; i < orderIndices.Size(); i++) { if (orderIndices[i] == isoIndex) iIso = i; if (orderIndices[i] == udfIndex) iUdf = i; } if (iUdf > iIso && iIso >= 0) { orderIndices[iUdf] = isoIndex; orderIndices[iIso] = udfIndex; } } #endif } for (int i = 0; i < orderIndices.Size(); i++) { if (stream) { RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL)); } CMyComPtr<IInArchive> archive; FormatIndex = orderIndices[i]; RINOK(codecs->CreateInArchive(FormatIndex, archive)); if (!archive) continue; #ifdef EXTERNAL_CODECS { CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo; archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecs)); } } #endif // OutputDebugStringW(codecs->Formats[FormatIndex].Name); HRESULT result; if (stream) result = archive->Open(stream, &kMaxCheckStartPosition, callback); else { CMyComPtr<IArchiveOpenSeq> openSeq; archive.QueryInterface(IID_IArchiveOpenSeq, (void **)&openSeq); if (!openSeq) return E_NOTIMPL; result = openSeq->OpenSeq(seqStream); } if (result == S_FALSE) continue; RINOK(result); { NCOM::CPropVariant prop; archive->GetArchiveProperty(kpidError, &prop); if (prop.vt != VT_EMPTY) ErrorMessage = (prop.vt == VT_BSTR) ? prop.bstrVal : L"Unknown error"; } Archive = archive; const CArcInfoEx &format = codecs->Formats[FormatIndex]; if (format.Exts.Size() == 0) DefaultName = GetDefaultName2(fileName, L"", L""); else { int subExtIndex = format.FindExtension(extension); if (subExtIndex < 0) subExtIndex = 0; const CArcExtInfo &extInfo = format.Exts[subExtIndex]; DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt); } return S_OK; } return S_FALSE; }
static HRESULT InternalOpenArchive(C7ZipLibrary * pLibrary, C7ZipDllHandler * pHandler, C7ZipInStream * pInStream, C7ZipArchiveOpenCallback * pOpenCallBack, C7ZipArchive ** ppArchive, HRESULT * pResult, bool fCheckFileTypeBySignature) { CMyComPtr<IInArchive> archive = NULL; CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo = NULL; CMyComPtr<IInArchiveGetStream> getStream = NULL; wstring extension = pInStream->GetExt(); C7ZipInStreamWrapper * pArchiveStream = new C7ZipInStreamWrapper(pInStream); CMyComPtr<IInStream> inStream(pArchiveStream); CMyComPtr<IArchiveOpenCallback> openCallBack(pOpenCallBack); std::vector<IInArchive *> archives; do { if (archive != NULL) archives.push_back(archive); FAIL_RET(CreateInArchive(pHandler->GetFunctions(), pHandler->GetFormatInfoArray(), inStream, extension, archive, fCheckFileTypeBySignature), pResult); if (archive == NULL) return false; archive.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { C7ZipCompressCodecsInfo * pCompressCodecsInfo = new C7ZipCompressCodecsInfo(pLibrary); RBOOLOK(setCompressCodecsInfo->SetCompressCodecsInfo(pCompressCodecsInfo)); } FAIL_RET(archive->Open(inStream, &kMaxCheckStartPosition, openCallBack), pResult); UInt32 mainSubfile; { NCOM::CPropVariant prop; FAIL_RET(archive->GetArchiveProperty(kpidMainSubfile, &prop), pResult); if (prop.vt == VT_UI4) mainSubfile = prop.ulVal; else { break; } UInt32 numItems; FAIL_RET(archive->GetNumberOfItems(&numItems), pResult); if (mainSubfile >= numItems) break; } if (archive->QueryInterface(IID_IInArchiveGetStream, (void **)&getStream) != S_OK || !getStream) break; CMyComPtr<ISequentialInStream> subSeqStream; if (getStream->GetStream(mainSubfile, &subSeqStream) != S_OK || !subSeqStream) break; inStream = NULL; if (subSeqStream.QueryInterface(IID_IInStream, &inStream) != S_OK || !inStream) break; wstring path; FAIL_RET(GetArchiveItemPath(archive, mainSubfile, path), pResult); CMyComPtr<IArchiveOpenSetSubArchiveName> setSubArchiveName; openCallBack->QueryInterface(IID_IArchiveOpenSetSubArchiveName, (void **)&setSubArchiveName); if (setSubArchiveName) { setSubArchiveName->SetSubArchiveName(path.c_str()); } FAIL_RET(GetFilePathExt(path, extension), pResult); } while(true); if (archive == NULL) return S_FALSE; return Create7ZipArchive(pLibrary, archives, archive, ppArchive) ? S_OK : S_FALSE; }