#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include <glibmm/pattern.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
#include "pbd/whitespace.h"
#include "pbd/file_utils.h"
char* s;
string lrdf_path;
- string scan_p = Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst");
- if (!PBD::find_file_in_search_path ( PBD::Searchpath(scan_p), "ardour-vst-scanner", scanner_bin_path)) {
- PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << scan_p << endmsg;
+#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
+ // source-tree (ardev, etc)
+ PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
+
+#ifdef PLATFORM_WINDOWS
+ // on windows the .exe needs to be in the same folder with libardour.dll
+ vstsp += Glib::build_filename(g_win32_get_package_installation_directory_of_module (0), "bin");
+#else
+ // on Unices additional internal-use binaries are deployed to $libdir
+ vstsp += ARDOUR::ardour_dll_directory();
+#endif
+
+ if (!PBD::find_file (vstsp,
+#ifdef PLATFORM_WINDOWS
+ #ifdef DEBUGGABLE_SCANNER_APP
+ #if defined(DEBUG) || defined(_DEBUG)
+ "ardour-vst-scannerD.exe"
+ #else
+ "ardour-vst-scannerRDC.exe"
+ #endif
+ #else
+ "ardour-vst-scanner.exe"
+ #endif
+#else
+ "ardour-vst-scanner"
+#endif
+ , scanner_bin_path)) {
+ PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << vstsp.to_string() << endmsg;
}
+#endif
load_statuses ();
PluginManager::~PluginManager()
{
+ if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
+ // don't bother, just exit quickly.
+ delete _windows_vst_plugin_info;
+ delete _lxvst_plugin_info;
+ delete _ladspa_plugin_info;
+ delete _lv2_plugin_info;
+ delete _au_plugin_info;
+ }
}
void
#ifdef AUDIOUNIT_SUPPORT
BootMessage (_("Scanning AU Plugins"));
- au_refresh ();
+ au_refresh (cache_only);
#endif
BootMessage (_("Plugin Scan Complete..."));
#ifdef WINDOWS_VST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#ifdef LXVST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
{
string personal = get_personal_vst_info_cache_dir();
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, personal, "\\.fsi$");
+ find_files_matching_regex (fsi_files, personal, "\\.fsi$", /* user cache is flat, no recursion */ false);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#ifdef WINDOWS_VST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsb$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsb$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#ifdef LXVST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsb$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsb$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
string personal = get_personal_vst_blacklist_dir();
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, personal, "\\.fsb$");
+ find_files_matching_regex (fsi_files, personal, "\\.fsb$", /* flat user cache */ false);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#endif
}
+void
+PluginManager::clear_au_cache ()
+{
+#ifdef AUDIOUNIT_SUPPORT
+ // AUPluginInfo::au_cache_path ()
+ string fn = Glib::build_filename (ARDOUR::user_config_directory(), "au_cache");
+ if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
+ ::g_unlink(fn.c_str());
+ }
+#endif
+}
+
+void
+PluginManager::clear_au_blacklist ()
+{
+#ifdef AUDIOUNIT_SUPPORT
+ string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_blacklist.txt");
+ if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
+ ::g_unlink(fn.c_str());
+ }
+#endif
+}
+
void
PluginManager::ladspa_refresh ()
{
}
}
+#ifdef HAVE_LRDF
static bool rdf_filter (const string &str, void* /*arg*/)
{
return str[0] != '.' &&
(str.find(".n3") == (str.length() - 3)) ||
(str.find(".ttl") == (str.length() - 4)));
}
+#endif
void
PluginManager::add_ladspa_presets()
#ifdef AUDIOUNIT_SUPPORT
void
-PluginManager::au_refresh ()
+PluginManager::au_refresh (bool cache_only)
{
DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
+ if (cache_only && !Config->get_discover_audio_units ()) {
+ return;
+ }
delete _au_plugin_info;
_au_plugin_info = AUPluginInfo::discover();
+
+ // disable automatic scan in case we crash
+ Config->set_discover_audio_units (false);
+ Config->save_state();
+
+ /* note: AU require a CAComponentDescription pointer provided by the OS.
+ * Ardour only caches port and i/o config. It can't just 'scan' without
+ * 'discovering' (like we do for VST).
+ *
+ * So in case discovery fails, we assume the worst: the Description
+ * is broken (malicious plugins) and even a simple 'scan' would always
+ * crash ardour on startup. Hence we disable Auto-Scan on start.
+ *
+ * If the crash happens at any later time (description is available),
+ * Ardour will blacklist the plugin in question -- unless
+ * the crash happens during realtime-run.
+ */
+
+ // successful scan re-enabled automatic discovery
+ Config->set_discover_audio_units (true);
+ Config->save_state();
}
#endif
static bool windows_vst_filter (const string& str, void * /*arg*/)
{
/* Not a dotfile, has a prefix before a period, suffix is "dll" */
-
- return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
+ return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
}
int
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
- find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
+ find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
- find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
+ find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
PluginManager::au_plugin_info ()
{
#ifdef AUDIOUNIT_SUPPORT
- assert(_au_plugin_info);
- return *_au_plugin_info;
-#else
- return _empty_plugin_info;
+ if (_au_plugin_info) {
+ return *_au_plugin_info;
+ }
#endif
+ return _empty_plugin_info;
}