Skip to content

Commit

Permalink
Allow user to use their chosen WINEPREFIX for each bridge
Browse files Browse the repository at this point in the history
Additionally, I cleaned up and secured templating a bit.
  • Loading branch information
michalrus committed Sep 19, 2014
1 parent b6ac33b commit 2a85415
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 23 deletions.
2 changes: 2 additions & 0 deletions README
Expand Up @@ -12,6 +12,8 @@ First you have to create a directory for your bridges:
Then you can create your first bridge:
$ ~/local/bin/vst-bridge-maker ~/.wine/drive_c/VST/Synth1/Synth1.dll ~/.vst-bridges/Synth1.so

Optionally, you can add a third argument — a path to a WINEPREFIX you want the plugin to use.

Now edit ~/.bashrc and add $HOME/.vst-bridges/ to VST_PATH. Mine looks like:
export VST_PATH=/usr/lib/vst/:$HOME/.vst-bridges/

Expand Down
4 changes: 3 additions & 1 deletion common/common.h
Expand Up @@ -14,7 +14,9 @@
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

# define VST_BRIDGE_TPL_MAGIC "VST-BRIDGE-TPL-PATH"
# define VST_BRIDGE_TPL_DLL "VST-BRIDGE-TPL-DLL"
# define VST_BRIDGE_TPL_HOST "VST-BRIDGE-TPL-HOST"
# define VST_BRIDGE_TPL_WINEPREFIX "VST-BRIDGE-TPL-WINEPREFIX"
# define VST_BRIDGE_TPL_PATH INSTALL_PREFIX "/lib/vst-bridge/vst-bridge-plugin-tpl.so"
# define VST_BRIDGE_HOST32_PATH INSTALL_PREFIX "/lib/vst-bridge/vst-bridge-host-32.exe"
# define VST_BRIDGE_HOST64_PATH INSTALL_PREFIX "/lib/vst-bridge/vst-bridge-host-64.exe"
Expand Down
70 changes: 50 additions & 20 deletions maker/maker.c
Expand Up @@ -8,23 +8,30 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

#include <magic.h>

#include "../config.h"
#include "../common/common.h"

void replace_magic(void *mem_so, size_t mem_sz,
const char *magic, const char *replacement);

int main(int argc, char **argv)
{
int arch = 32;
magic_t magic;
char dll_real_path[PATH_MAX];
char wineprefix_real_path[PATH_MAX];

if (argc != 3) {
fprintf(stderr, "usage: %s <vst.dll> <vst.so>\n", argv[0]);
if (argc != 3 && argc != 4) {
fprintf(stderr, "usage: %s <vst.dll> <vst.so> [<wine-prefix>]\n", argv[0]);
return 2;
}

int has_wineprefix = argc == 4;

struct stat st_dll;
if (stat(argv[1], &st_dll) ||
!realpath(argv[1], dll_real_path)) {
Expand All @@ -38,6 +45,21 @@ int main(int argc, char **argv)
return 1;
}

if (has_wineprefix) {
struct stat st_wineprefix;

if (stat(argv[3], &st_wineprefix) ||
!realpath(argv[3], wineprefix_real_path)) {
fprintf(stderr, "%s: %m\n", argv[3]);
return 1;
}

if (!S_ISDIR(st_wineprefix.st_mode)) {
fprintf(stderr, "%s: %s\n", argv[3], strerror(ENOTDIR));
return 1;
}
}

magic = magic_open(MAGIC_NONE);
if (!magic)
fprintf(stderr, "failed to initialize magic\n");
Expand Down Expand Up @@ -81,28 +103,36 @@ int main(int argc, char **argv)
return 1;
}

void *dll_path = memmem(mem_so, st_tpl.st_size, VST_BRIDGE_TPL_MAGIC,
sizeof (VST_BRIDGE_TPL_MAGIC));
if (!dll_path) {
fprintf(stderr, "template magic not found in plugin\n");
return 1;
}
strncpy(dll_path, dll_real_path, PATH_MAX);
replace_magic(mem_so, st_tpl.st_size, VST_BRIDGE_TPL_DLL, dll_real_path);
replace_magic(mem_so, st_tpl.st_size, VST_BRIDGE_TPL_HOST, arch == 32 ? VST_BRIDGE_HOST32_PATH : VST_BRIDGE_HOST64_PATH);
if (has_wineprefix)
replace_magic(mem_so, st_tpl.st_size, VST_BRIDGE_TPL_WINEPREFIX, wineprefix_real_path);

void *host_path = memmem(mem_so, st_tpl.st_size, VST_BRIDGE_HOST32_PATH,
sizeof (VST_BRIDGE_HOST32_PATH));
if (!host_path) {
fprintf(stderr, "host path not found in plugin\n");
return 1;
}

if (arch == 32)
memcpy(host_path, VST_BRIDGE_HOST32_PATH, sizeof (VST_BRIDGE_HOST32_PATH));
else
memcpy(host_path, VST_BRIDGE_HOST64_PATH, sizeof (VST_BRIDGE_HOST64_PATH));
munmap(mem_so, st_tpl.st_size);

close(fd_so);

return 0;
}

void replace_magic(void *mem_so, size_t mem_sz,
const char *magic, const char *replacement)
{
char pattern[PATH_MAX];

// Just to make sure we replace only values of PATH_MAX length.
memset(pattern, 0, sizeof(pattern));
strcpy(pattern, magic);

void *pos = memmem(mem_so, mem_sz, pattern, sizeof(pattern));
if (!pos) {
fprintf(stderr, "`%s' magic not found in plugin\n", magic);
exit(1);
}

// Remove all the rubbish. Probably will never matter.
memset(pattern, 0, sizeof(pattern));
strcpy(pattern, replacement);

memcpy(pos, pattern, sizeof(pattern));
}
15 changes: 13 additions & 2 deletions plugin/plugin.cc
Expand Up @@ -19,8 +19,9 @@
#include "../config.h"
#include "../common/common.h"

const char g_plugin_path[PATH_MAX] = VST_BRIDGE_TPL_MAGIC;
const char g_host_path[PATH_MAX] = VST_BRIDGE_HOST32_PATH;
const char g_plugin_path[PATH_MAX] = VST_BRIDGE_TPL_DLL;
const char g_host_path[PATH_MAX] = VST_BRIDGE_TPL_HOST;
const char g_plugin_wineprefix[PATH_MAX] = VST_BRIDGE_TPL_WINEPREFIX;

#ifdef DEBUG

Expand Down Expand Up @@ -798,6 +799,16 @@ AEffect* VSTPluginMain(audioMasterCallback audio_master)

if (!vbe->child) {
// in the child

// A hack to cheat GCC optimisation. If we'd simply compare
// g_plugin_wineprefix to VST_BRIDGE_TPL_WINEPREFIX, the
// whole if(strcmp(...)) {} will disappear in the assembly.

char *local_plugin_wineprefix = strdup(g_plugin_wineprefix);
if (strcmp(local_plugin_wineprefix, VST_BRIDGE_TPL_WINEPREFIX) != 0)
setenv("WINEPREFIX", local_plugin_wineprefix, 1); // Should we really override an existing var?
free(local_plugin_wineprefix);

char buff[8];
close(fds[0]);
snprintf(buff, sizeof (buff), "%d", fds[1]);
Expand Down

0 comments on commit 2a85415

Please sign in to comment.