variable plugin port config.
[ardour.git] / libs / ardour / plugin_manager.cc
index 11b34de209f6f93627ffce7eb8af1cf5a534f28e..89ddc5ff19f303fb204bd979f96be89e362a3426 100644 (file)
 #include <sys/types.h>
 #include <cstdio>
 #include <cstdlib>
-#include <fstream>
 
 #include <glib.h>
-#include <pbd/gstdio_compat.h>
+#include "pbd/gstdio_compat.h"
 
 #ifdef HAVE_LRDF
 #include <lrdf.h>
 #include "fst.h"
 #include "pbd/basename.h"
 #include <cstring>
+
+// dll-info
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdint.h>
+
 #endif // WINDOWS_VST_SUPPORT
 
 #ifdef LXVST_SUPPORT
@@ -49,7 +55,6 @@
 #include <cstring>
 #endif //LXVST_SUPPORT
 
-#include <pbd/gstdio_compat.h>
 #include <glibmm/miscutils.h>
 #include <glibmm/pattern.h>
 #include <glibmm/fileutils.h>
@@ -270,8 +275,12 @@ PluginManager::refresh (bool cache_only)
                        string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
                        if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
                                gchar *bl = NULL;
-                               if (g_file_get_contents(fn.c_str (), contents, NULL, NULL)) {
-                                       PBD::info << _("VST Blacklist:") << "\n" << bl << "-----" << endmsg;
+                               if (g_file_get_contents(fn.c_str (), &bl, NULL, NULL)) {
+                                       if (Config->get_verbose_plugin_scan()) {
+                                               PBD::info << _("VST Blacklist: ") << fn << "\n" << bl << "-----" << endmsg;
+                                       } else {
+                                               PBD::info << _("VST Blacklist:") << "\n" << bl << "-----" << endmsg;
+                                       }
                                        g_free (bl);
                                }
                        }
@@ -783,13 +792,77 @@ PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
        return ret;
 }
 
+static std::string dll_info (std::string path) {
+       std::string rv;
+       uint8_t buf[68];
+       uint16_t type = 0;
+       off_t pe_hdr_off = 0;
+
+       int fd = g_open(path.c_str(), O_RDONLY, 0444);
+
+       if (fd < 0) {
+               return _("cannot open dll"); // TODO strerror()
+       }
+
+       if (68 != read (fd, buf, 68)) {
+               rv = _("invalid dll, file too small");
+               goto errorout;
+       }
+       if (buf[0] != 'M' && buf[1] != 'Z') {
+               rv = _("not a dll");
+               goto errorout;
+       }
+
+       pe_hdr_off = *((int32_t*) &buf[60]);
+       if (pe_hdr_off !=lseek (fd, pe_hdr_off, SEEK_SET)) {
+               rv = _("cannot determine dll type");
+               goto errorout;
+       }
+       if (6 != read (fd, buf, 6)) {
+               rv = _("cannot read dll PE header");
+               goto errorout;
+       }
+
+       if (buf[0] != 'P' && buf[1] != 'E') {
+               rv = _("invalid dll PE header");
+               goto errorout;
+       }
+
+       type = *((uint16_t*) &buf[4]);
+       switch (type) {
+               case 0x014c:
+                       rv = _("i386 (32-bit)");
+                       break;
+               case  0x0200:
+                       rv = _("Itanium");
+                       break;
+               case 0x8664:
+                       rv = _("x64 (64-bit)");
+                       break;
+               case 0:
+                       rv = _("Native Architecture");
+                       break;
+               default:
+                       rv = _("Unknown Architecture");
+                       break;
+       }
+errorout:
+       assert (rv.length() > 0);
+       close (fd);
+       return rv;
+}
+
 int
 PluginManager::windows_vst_discover (string path, bool cache_only)
 {
        DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
 
        if (Config->get_verbose_plugin_scan()) {
-               info << string_compose (_(" *  %1 %2"), path, (cache_only ? _(" (cache only)") : "")) << endmsg;
+               if (cache_only) {
+                       info << string_compose (_(" *  %1 (cache only)"), path) << endmsg;
+               } else {
+                       info << string_compose (_(" *  %1 - %2"), path, dll_info (path)) << endmsg;
+               }
        }
 
        _cancel_timeout = false;
@@ -1029,6 +1102,10 @@ PluginManager::save_statuses ()
                case LXVST:
                        ofs << "LXVST";
                        break;
+               case Lua:
+                       assert (0);
+                       continue;
+                       break;
                }
 
                ofs << ' ';
@@ -1050,6 +1127,7 @@ PluginManager::save_statuses ()
                ofs << endl;
        }
        g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL);
+       PluginStatusesChanged (); /* EMIT SIGNAL */
 }
 
 void