Analysis::Result::Ptr Detect(const Parameters::Accessor& params, DataLocation::Ptr input, const Module::DetectCallback& callback) const override { const Binary::Container::Ptr rawData = input->GetData(); const std::size_t size = rawData->Size(); Statistic::Self().Enqueue(size); if (size < MIN_MINIMAL_RAW_SIZE) { Dbg("Size is too small (%1%)", size); return Analysis::CreateUnmatchedResult(size); } const RawPluginParameters scanParams(params); const std::size_t minRawSize = scanParams.GetMinimalSize(); const String currentPath = input->GetPath()->AsString(); Dbg("Detecting modules in raw data at '%1%'", currentPath); const Log::ProgressCallback::Ptr progress = MakePtr<RawProgressCallback>(callback, static_cast<uint_t>(size), currentPath); const Module::DetectCallback& noProgressCallback = Module::CustomProgressDetectCallbackAdapter(callback); const ArchivePlugin::Iterator::Ptr availableArchives = ArchivePluginsEnumerator::Create()->Enumerate(); const ArchivePlugin::Iterator::Ptr usedArchives = scanParams.GetDoubleAnalysis() ? MakePtr<DoubleAnalysisArchivePlugins>(availableArchives) : availableArchives; RawDetectionPlugins usedPlugins(params, PlayerPluginsEnumerator::Create()->Enumerate(), usedArchives, *this); ScanDataLocation::Ptr subLocation = MakePtr<ScanDataLocation>(input, Description->Id(), 0); while (subLocation->HasToScan(minRawSize)) { const std::size_t offset = subLocation->GetOffset(); progress->OnProgress(static_cast<uint_t>(offset)); usedPlugins.SetOffset(offset); const Module::DetectCallback& curCallback = offset ? noProgressCallback : callback; const std::size_t bytesToSkip = usedPlugins.Detect(subLocation, curCallback); if (!subLocation.unique()) { Dbg("Sublocation is captured. Duplicate."); subLocation = MakePtr<ScanDataLocation>(input, Description->Id(), offset); } subLocation->Move(std::max(bytesToSkip, SCAN_STEP)); } return Analysis::CreateMatchedResult(size); }
DataLocation::Ptr Open(const Parameters::Accessor& /*params*/, DataLocation::Ptr location, const Analysis::Path& inPath) const override { const String& pathComp = inPath.GetIterator()->Get(); std::size_t offset = 0; if (RawPath.GetIndex(pathComp, offset)) { const Binary::Container::Ptr inData = location->GetData(); const Binary::Container::Ptr subData = inData->GetSubcontainer(offset, inData->Size() - offset); return CreateNestedLocation(location, subData, Description->Id(), pathComp); } return DataLocation::Ptr(); }
Analysis::Result::Ptr DetectIn(LookaheadPluginsStorage<T>& container, DataLocation::Ptr input, const Module::DetectCallback& callback) const { const bool firstScan = 0 == Offset; const std::size_t maxSize = input->GetData()->Size(); for (typename T::Iterator::Ptr iter = container.Enumerate(); iter->IsValid(); iter->Next()) { Time::Timer timer; const typename T::Ptr plugin = iter->Get(); const Analysis::Result::Ptr result = plugin->Detect(Params, input, callback); const String id = plugin->GetDescription()->Id(); if (const std::size_t usedSize = result->GetMatchedDataSize()) { Statistic::Self().AddAimed(*plugin, timer); Dbg("Detected %1% in %2% bytes at %3%.", id, usedSize, input->GetPath()->AsString()); return result; } else { if (!firstScan) { Statistic::Self().AddMissed(*plugin, timer); timer = Time::Timer(); } const std::size_t lookahead = result->GetLookaheadOffset(); container.SetPluginLookahead(*plugin, id, lookahead); if (lookahead == maxSize) { Statistic::Self().AddAimed(*plugin, timer); } else { Statistic::Self().AddScanned(*plugin, timer); } } } const std::size_t minLookahead = container.GetMinimalPluginLookahead(); return Analysis::CreateUnmatchedResult(minLookahead); }
virtual Analysis::Result::Ptr Detect(DataLocation::Ptr input, const Module::DetectCallback& callback) const { const Binary::Container::Ptr rawData = input->GetData(); if (const Formats::Archived::Container::Ptr archive = Decoder->Decode(*rawData)) { if (const uint_t count = archive->CountFiles()) { ContainerDetectCallback detect(~std::size_t(0), Description->Id(), input, count, callback); archive->ExploreFiles(detect); } return Analysis::CreateMatchedResult(archive->Size()); } return Analysis::CreateUnmatchedResult(Decoder->GetFormat(), rawData); }
virtual DataLocation::Ptr Open(const Parameters::Accessor& /*commonParams*/, DataLocation::Ptr location, const Analysis::Path& inPath) const { const Binary::Container::Ptr rawData = location->GetData(); if (const Formats::Archived::Container::Ptr archive = Decoder->Decode(*rawData)) { if (const Formats::Archived::File::Ptr fileToOpen = FindFile(*archive, inPath)) { if (const Binary::Container::Ptr subData = fileToOpen->GetData()) { return CreateNestedLocation(location, subData, Description->Id(), fileToOpen->GetName()); } } } return DataLocation::Ptr(); }
Analysis::Result::Ptr DetectModulesInArchive(const Parameters::Accessor& params, Plugin::Ptr plugin, const Formats::Packed::Decoder& decoder, DataLocation::Ptr inputData, const Module::DetectCallback& callback) { const Binary::Container::Ptr rawData = inputData->GetData(); if (Formats::Packed::Container::Ptr subData = decoder.Decode(*rawData)) { const Module::CustomProgressDetectCallbackAdapter noProgressCallback(callback); const String subPlugin = plugin->Id(); const String subPath = EncodeArchivePluginToPath(subPlugin); const DataLocation::Ptr subLocation = CreateNestedLocation(inputData, subData, subPlugin, subPath); Module::Detect(params, subLocation, noProgressCallback); return Analysis::CreateMatchedResult(subData->PackedSize()); } const Binary::Format::Ptr format = decoder.GetFormat(); return Analysis::CreateUnmatchedResult(format, rawData); }
DataLocation::Ptr OpenLocation(Parameters::Accessor::Ptr coreParams, Binary::Container::Ptr data, const String& subpath) { const ArchivePluginsEnumerator::Ptr usedPlugins = ArchivePluginsEnumerator::Create(); DataLocation::Ptr resolvedLocation = boost::make_shared<UnresolvedLocation>(data); const Analysis::Path::Ptr sourcePath = Analysis::ParsePath(subpath, Text::MODULE_SUBPATH_DELIMITER[0]); for (Analysis::Path::Ptr unresolved = sourcePath; !unresolved->Empty(); unresolved = sourcePath->Extract(resolvedLocation->GetPath()->AsString())) { const String toResolve = unresolved->AsString(); Dbg("Resolving '%1%'", toResolve); if (!(resolvedLocation = TryToOpenLocation(*usedPlugins, *coreParams, resolvedLocation, *unresolved))) { throw MakeFormattedError(THIS_LINE, translate("Failed to resolve subpath '%1%'."), subpath); } } Dbg("Resolved '%1%'", subpath); return resolvedLocation; }
DataLocation::Ptr OpenDataFromArchive(Plugin::Ptr plugin, const Formats::Packed::Decoder& decoder, DataLocation::Ptr inputData, const Analysis::Path& pathToOpen) { const String pathComponent = pathToOpen.GetIterator()->Get(); if (!IsArchivePluginPathComponent(pathComponent)) { return DataLocation::Ptr(); } const String pluginId = DecodeArchivePluginFromPathComponent(pathComponent); if (pluginId != plugin->Id()) { return DataLocation::Ptr(); } const Binary::Container::Ptr rawData = inputData->GetData(); if (Formats::Packed::Container::Ptr subData = decoder.Decode(*rawData)) { return CreateNestedLocation(inputData, subData, pluginId, pathComponent); } return DataLocation::Ptr(); }