diff options
author | cbdev <cb@cbcdn.com> | 2019-12-07 20:22:03 +0100 |
---|---|---|
committer | cbdev <cb@cbcdn.com> | 2019-12-07 20:22:03 +0100 |
commit | f95dae04478b32fccaf7c6ebe1ecfd4e2fef1358 (patch) | |
tree | 6f545dc81166ee1a0f1b21b5245a70bcbf05751d /plugin.c | |
parent | 534207d16314a4f6a69d36cf2305a3fe435a769b (diff) | |
parent | 1bb3b9a3eaf94af045c39a1ff1ee8bf9b8e5b8ec (diff) | |
download | midimonster-f95dae04478b32fccaf7c6ebe1ecfd4e2fef1358.tar.gz midimonster-f95dae04478b32fccaf7c6ebe1ecfd4e2fef1358.tar.bz2 midimonster-f95dae04478b32fccaf7c6ebe1ecfd4e2fef1358.zip |
Merge current master
Diffstat (limited to 'plugin.c')
-rw-r--r-- | plugin.c | 88 |
1 files changed, 77 insertions, 11 deletions
@@ -1,31 +1,56 @@ #include <stdio.h> #include <string.h> -#include <dlfcn.h> #include <stdlib.h> #include <errno.h> #include <sys/stat.h> #include <sys/types.h> #include <dirent.h> +#include "portability.h" +#ifdef _WIN32 +#define dlclose FreeLibrary +#define dlsym GetProcAddress +#define dlerror() "Failed" +#define dlopen(lib,ig) LoadLibrary(lib) +#else +#include <dlfcn.h> +#endif + #include "plugin.h" -size_t plugins = 0; -void** plugin_handle = NULL; +static size_t plugins = 0; +static void** plugin_handle = NULL; static int plugin_attach(char* path, char* file){ plugin_init init = NULL; void* handle = NULL; - - char* lib = calloc(strlen(path) + strlen(file) + 1, sizeof(char)); + char* lib = NULL; + #ifdef _WIN32 + char* path_separator = "\\"; + #else + char* path_separator = "/"; + #endif + + lib = calloc(strlen(path) + strlen(file) + 2, sizeof(char)); if(!lib){ fprintf(stderr, "Failed to allocate memory\n"); return 1; } - - snprintf(lib, strlen(path) + strlen(file) + 1, "%s%s", path, file); + snprintf(lib, strlen(path) + strlen(file) + 2, "%s%s%s", + path, + (path[strlen(path)] == path_separator[0]) ? "" : path_separator, + file); handle = dlopen(lib, RTLD_NOW); if(!handle){ + #ifdef _WIN32 + char* error = NULL; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &error, 0, NULL); + fprintf(stderr, "Failed to load plugin %s: %s\n", lib, error); + LocalFree(error); + #else fprintf(stderr, "Failed to load plugin %s: %s\n", lib, dlerror()); + #endif free(lib); return 0; } @@ -62,6 +87,38 @@ static int plugin_attach(char* path, char* file){ int plugins_load(char* path){ int rv = -1; +#ifdef _WIN32 + char* search_expression = calloc(strlen(path) + strlen("*.dll") + 1, sizeof(char)); + if(!search_expression){ + fprintf(stderr, "Failed to allocate memory\n"); + return -1; + } + snprintf(search_expression, strlen(path) + strlen("*.dll"), "%s*.dll", path); + + WIN32_FIND_DATA result; + HANDLE hSearch = FindFirstFile(search_expression, &result); + + if(hSearch == INVALID_HANDLE_VALUE){ + LPVOID lpMsgBuf = NULL; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); + fprintf(stderr, "Failed to search for backend plugin files in %s: %s\n", path, lpMsgBuf); + LocalFree(lpMsgBuf); + return -1; + } + + do { + if(plugin_attach(path, result.cFileName)){ + goto load_done; + } + } while(FindNextFile(hSearch, &result)); + + rv = 0; +load_done: + free(search_expression); + FindClose(hSearch); + return rv; +#else struct dirent* entry; struct stat file_stat; DIR* directory = opendir(path); @@ -84,10 +141,6 @@ int plugins_load(char* path){ continue; } - if(!(file_stat.st_mode & S_IXUSR)){ - continue; - } - if(plugin_attach(path, entry->d_name)){ goto load_done; } @@ -100,14 +153,27 @@ load_done: return -1; } return rv; +#endif } int plugins_close(){ size_t u; + for(u = 0; u < plugins; u++){ +#ifdef _WIN32 + char* error = NULL; + //FreeLibrary returns the inverse of dlclose + if(!FreeLibrary(plugin_handle[u])){ + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &error, 0, NULL); + fprintf(stderr, "Failed to unload plugin: %s\n", error); + LocalFree(error); + } +#else if(dlclose(plugin_handle[u])){ fprintf(stderr, "Failed to unload plugin: %s\n", dlerror()); } +#endif } free(plugin_handle); |