mirror of
https://github.com/quelsolaar/MergeSource
synced 2025-02-01 09:58:42 -05:00
219 lines
6.0 KiB
C
219 lines
6.0 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "hxa_upi.h"
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#include <winreg.h>
|
|
#include <mmsystem.h>
|
|
#include <tchar.h>
|
|
#include <wchar.h>
|
|
|
|
#define HXA_UPI_WINDOWS_PATH_LENGHT_MAX (256 * 128 - 1)
|
|
|
|
#undef UNICODE
|
|
|
|
#ifdef UNICODE
|
|
#define hxa_upi_internal_lib_load LoadLibraryW
|
|
#else
|
|
#define hxa_upi_internal_lib_load LoadLibraryA
|
|
#endif
|
|
#define hxa_upi_internal_lib_get_address GetProcAddress
|
|
#define hxa_upi_internal_lib_unload FreeLibrary
|
|
#else
|
|
#include <dlfcn.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <sys/dir.h>
|
|
#include <dirent.h>
|
|
#define hxa_upi_internal_lib_load(a) dlopen(a, RTLD_LAZY);
|
|
#define hxa_upi_internal_lib_get_address dlsym
|
|
#define hxa_upi_internal_lib_unload dlclose
|
|
#endif
|
|
typedef unsigned int uint;
|
|
|
|
HxAUPIPlugin *hxa_upi_host_temp_loaded_plugins = NULL;
|
|
unsigned int hxa_upi_host_temp_loaded_plugin_count = 0;
|
|
void *hxa_upi_host_temp_loaded_library = NULL;
|
|
|
|
void hxa_upi_host_register_func(HxAUPIPlugin *plugin)
|
|
{
|
|
if(hxa_upi_host_temp_loaded_plugin_count % 16 == 0)
|
|
hxa_upi_host_temp_loaded_plugins = realloc(hxa_upi_host_temp_loaded_plugins, (sizeof *hxa_upi_host_temp_loaded_plugins) * (hxa_upi_host_temp_loaded_plugin_count + 16));
|
|
hxa_upi_host_temp_loaded_plugins[hxa_upi_host_temp_loaded_plugin_count] = *plugin;
|
|
hxa_upi_host_temp_loaded_plugins[hxa_upi_host_temp_loaded_plugin_count].params = malloc((sizeof *plugin->params) * plugin->param_count);
|
|
memcpy(hxa_upi_host_temp_loaded_plugins[hxa_upi_host_temp_loaded_plugin_count].params, plugin->params, (sizeof *plugin->params) * plugin->param_count);
|
|
hxa_upi_host_temp_loaded_plugins[hxa_upi_host_temp_loaded_plugin_count].library = hxa_upi_host_temp_loaded_library;
|
|
hxa_upi_host_temp_loaded_plugin_count++;
|
|
}
|
|
|
|
void hxa_upi_host_load_library_internal(char *path)
|
|
{
|
|
void (*hxa_upi_plugin_library_initialize)(void (*register_func)(HxAUPIPlugin *plugin));
|
|
char *name;
|
|
unsigned int i, pre_count;
|
|
#ifdef UNICODE
|
|
short u_path[1025];
|
|
for(i = 0; i < 1024 && path[i] !=0 ; i++)
|
|
u_path[i] = (char)path[i];
|
|
u_path[i] = 0;
|
|
hxa_temp_loaded_library = hxa_upi_internal_lib_load(u_path);
|
|
#else
|
|
hxa_upi_host_temp_loaded_library = hxa_upi_internal_lib_load(path);
|
|
#endif
|
|
if(hxa_upi_host_temp_loaded_library == NULL)
|
|
{
|
|
#ifdef _WIN32
|
|
printf("HxA UPI ERROR: library %s not found. Windows error code: %u\n", path, GetLastError());
|
|
#else
|
|
printf("HxA UPI ERROR: library %s not found.\n", path);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
#ifdef WIN32
|
|
hxa_upi_plugin_library_initialize = (char *(*)(void))GetProcAddress(hxa_upi_host_temp_loaded_library, "hxa_upi_plugin_library_initialize");
|
|
#else
|
|
hxa_upi_plugin_library_initialize = dlsym(hxa_upi_host_temp_loaded_library, "hxa_upi_plugin_library_initialize");
|
|
#endif
|
|
if(hxa_upi_plugin_library_initialize == NULL)
|
|
{
|
|
printf("HxA UPI ERROR: imagine_lib_main not found in %s.\n", path);
|
|
hxa_upi_internal_lib_unload(hxa_upi_host_temp_loaded_library);
|
|
return NULL;
|
|
}
|
|
pre_count = hxa_upi_host_temp_loaded_plugin_count;
|
|
hxa_upi_plugin_library_initialize(hxa_upi_host_register_func);
|
|
if(pre_count == hxa_upi_host_temp_loaded_plugin_count)
|
|
hxa_upi_internal_lib_unload(hxa_upi_host_temp_loaded_library);
|
|
}
|
|
|
|
|
|
|
|
void hxa_upi_host_unload_library(char *path, HxAUPIPlugin *plugins, unsigned int plugin_count)
|
|
{
|
|
uint i, j;
|
|
for(i = 0; i < plugin_count; i++)
|
|
{
|
|
free(plugins[i].params);
|
|
if(i == 0 || plugins[i].library != plugins[i - 1].library)
|
|
hxa_upi_internal_lib_unload(plugins[i - 1].library);
|
|
}
|
|
free(plugins);
|
|
}
|
|
|
|
HxAUPIPlugin *hxa_upi_host_load_library(char *path, unsigned int *plugin_count)
|
|
{
|
|
hxa_upi_host_temp_loaded_plugins = NULL;
|
|
hxa_upi_host_temp_loaded_plugin_count = 0;
|
|
hxa_upi_host_load_library_internal(path);
|
|
*plugin_count = hxa_upi_host_temp_loaded_plugin_count;
|
|
return hxa_upi_host_temp_loaded_plugins;
|
|
}
|
|
|
|
|
|
#ifdef _WIN32
|
|
/* implement path searching for windows */
|
|
typedef struct{
|
|
char d_name[HXA_UPI_WINDOWS_PATH_LENGHT_MAX];
|
|
}idirent;
|
|
|
|
typedef struct{
|
|
WIN32_FIND_DATAW data;
|
|
HANDLE handle;
|
|
idirent ent;
|
|
}DIR;
|
|
|
|
DIR *hxa_upi_opendir(char *path)
|
|
{
|
|
DIR *dir;
|
|
unsigned int pos, i;
|
|
WIN32_FIND_DATAW data;
|
|
HANDLE handle;
|
|
wchar_t unicode_path[HXA_UPI_WINDOWS_PATH_LENGHT_MAX];
|
|
char *post_fix = "\\*.*";
|
|
if(path == NULL)
|
|
{
|
|
unicode_path[0] = ".";
|
|
unicode_path[1] = 0;
|
|
}else
|
|
{
|
|
for(i = pos = 0; i < HXA_UPI_WINDOWS_PATH_LENGHT_MAX - 5 && path[pos] != 0; i++)
|
|
unicode_path[i] = f_utf8_to_uint32(path, &pos);
|
|
}
|
|
for(pos = 0; post_fix[pos] != 0; i++)
|
|
unicode_path[i] = (wchar_t)post_fix[pos++];
|
|
unicode_path[i] = 0;
|
|
if((handle = FindFirstFileW(unicode_path, &data)) != INVALID_HANDLE_VALUE)
|
|
{
|
|
dir = malloc(sizeof *dir);
|
|
dir->handle = handle;
|
|
dir->data = data;
|
|
dir->ent.d_name[0] = 0;
|
|
return dir;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void hxa_upi_closedir(DIR *dir)
|
|
{
|
|
FindClose(dir->handle);
|
|
free(dir);
|
|
}
|
|
|
|
idirent *hxa_upi_readdir(DIR *dir)
|
|
{
|
|
uint i, pos;
|
|
if(FindNextFileW(dir->handle, &dir->data) != TRUE)
|
|
return NULL;
|
|
for(i = pos = 0; dir->data.cFileName[i] != 0 && pos < HXA_UPI_WINDOWS_PATH_LENGHT_MAX - 6; i++)
|
|
pos += f_uint32_to_utf8(dir->data.cFileName[i], &dir->ent.d_name[pos]);
|
|
dir->ent.d_name[pos] = 0;
|
|
return &dir->ent;
|
|
|
|
}
|
|
|
|
#else
|
|
/* use unix APIs */
|
|
#define idirent struct dirent
|
|
#define hxa_upi_opendir opendir;
|
|
#define hxa_upi_closedir closedir
|
|
#define hxa_upi_readdir readdir
|
|
#endif
|
|
|
|
HxAUPIPlugin *hxa_upi_host_load_directory(char *path, unsigned int *plugin_count)
|
|
{
|
|
DIR *d;
|
|
idirent *ent;
|
|
char p[1024];
|
|
unsigned int i, start;
|
|
hxa_upi_host_temp_loaded_plugins = NULL;
|
|
hxa_upi_host_temp_loaded_plugin_count = 0;
|
|
for(start = 0; start < 1024 - 1 && path[start] != 0; start)
|
|
p[start] = path[start];
|
|
d = opendir(path);
|
|
if(d != NULL)
|
|
{
|
|
ent = readdir(d);
|
|
if(ent != NULL)
|
|
{
|
|
while(TRUE)
|
|
{
|
|
for(i = 0; i + start < 1024 - 1 && ent->d_name[i] != 0; i++)
|
|
p[start + i] = ent->d_name[i];
|
|
if(i + start < 1024 - 1)
|
|
{
|
|
p[start + i] = 0;
|
|
hxa_upi_host_load_library_internal(p);
|
|
}
|
|
ent = readdir(d);
|
|
if(ent == NULL)
|
|
break;
|
|
}
|
|
}
|
|
closedir(d);
|
|
}
|
|
*plugin_count = hxa_upi_host_temp_loaded_plugin_count;
|
|
return hxa_upi_host_temp_loaded_plugins;
|
|
}
|