aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2017-06-28 16:41:38 -0700
committerChris Robinson <[email protected]>2017-06-28 16:41:38 -0700
commitcfec20830bca1bdb1bdef5d7429c946fde881d77 (patch)
tree714b918e5d84e88f8947137c0be1ea7ab7d02d89
parentebee8da05cc02fa8da0cbdc47dd9f379e20b962a (diff)
Load driver dlls in the router
-rw-r--r--router/al.c1
-rw-r--r--router/alc.c1
-rw-r--r--router/router.c264
-rw-r--r--router/router.h115
4 files changed, 378 insertions, 3 deletions
diff --git a/router/al.c b/router/al.c
index ec17226b..8e179c82 100644
--- a/router/al.c
+++ b/router/al.c
@@ -4,6 +4,7 @@
#include <stddef.h>
#include "AL/al.h"
+#include "router.h"
#define DECL_THUNK0(R, n) AL_API R AL_APIENTRY n(void) { return (R)0; }
diff --git a/router/alc.c b/router/alc.c
index 45cacabe..35572b65 100644
--- a/router/alc.c
+++ b/router/alc.c
@@ -4,6 +4,7 @@
#include <stddef.h>
#include "AL/alc.h"
+#include "router.h"
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename)
diff --git a/router/router.c b/router/router.c
index cb1bf763..21ab8a6a 100644
--- a/router/router.c
+++ b/router/router.c
@@ -1,19 +1,277 @@
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+#include "config.h"
-BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
+#include "router.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "AL/alc.h"
+#include "AL/al.h"
+
+
+DriverIface *DriverList = NULL;
+int DriverListSize = 0;
+static int DriverListSizeMax = 0;
+
+static void LoadDriverList(void);
+
+
+BOOL APIENTRY DllMain(HINSTANCE module, DWORD reason, void *reserved)
{
+ int i;
+
switch(reason)
{
case DLL_PROCESS_ATTACH:
+ LoadDriverList();
break;
+ case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
+ for(i = 0;i < DriverListSize;i++)
+ {
+ if(DriverList[i].Module)
+ FreeLibrary(DriverList[i].Module);
+ }
+ free(DriverList);
+ DriverList = NULL;
+ DriverListSize = 0;
+ DriverListSizeMax = 0;
break;
}
return TRUE;
}
+
+
+#ifdef __GNUC__
+#define CAST_FUNC(x) (__typeof(x))
+#else
+#define CAST_FUNC(x) (void*)
+#endif
+
+static void AddModule(HMODULE module, const WCHAR *name)
+{
+ int err = 0;
+ int i;
+
+ for(i = 0;i < DriverListSize;i++)
+ {
+ if(DriverList[i].Module == module || wcscmp(DriverList[i].Name, name) == 0)
+ {
+ FreeLibrary(module);
+ return;
+ }
+ }
+
+ if(DriverListSize == DriverListSizeMax)
+ {
+ int newmax = DriverListSizeMax ? DriverListSizeMax<<1 : 4;
+ void *newlist = calloc(sizeof(DriverList[0]), newmax);
+ if(!newlist) return;
+
+ memcpy(newlist, DriverList, DriverListSize*sizeof(DriverList[0]));
+ free(DriverList);
+ DriverList = newlist;
+ DriverListSizeMax = newmax;
+ }
+
+#define LOAD_PROC(x) do { \
+ DriverList[DriverListSize].x = CAST_FUNC(DriverList[DriverListSize].x) \
+ GetProcAddress(module, #x); \
+ if(!DriverList[DriverListSize].x) \
+ { \
+ fprintf(stderr, "Failed to find entry point for %s in %ls\n", \
+ #x, name); \
+ err = 1; \
+ } \
+} while(0)
+ LOAD_PROC(alcCreateContext);
+ LOAD_PROC(alcMakeContextCurrent);
+ LOAD_PROC(alcProcessContext);
+ LOAD_PROC(alcSuspendContext);
+ LOAD_PROC(alcDestroyContext);
+ LOAD_PROC(alcGetCurrentContext);
+ LOAD_PROC(alcGetContextsDevice);
+ LOAD_PROC(alcOpenDevice);
+ LOAD_PROC(alcCloseDevice);
+ LOAD_PROC(alcGetError);
+ LOAD_PROC(alcIsExtensionPresent);
+ LOAD_PROC(alcGetProcAddress);
+ LOAD_PROC(alcGetEnumValue);
+ LOAD_PROC(alcGetString);
+ LOAD_PROC(alcGetIntegerv);
+ LOAD_PROC(alcCaptureOpenDevice);
+ LOAD_PROC(alcCaptureCloseDevice);
+ LOAD_PROC(alcCaptureStart);
+ LOAD_PROC(alcCaptureStop);
+ LOAD_PROC(alcCaptureSamples);
+
+ LOAD_PROC(alEnable);
+ LOAD_PROC(alDisable);
+ LOAD_PROC(alIsEnabled);
+ LOAD_PROC(alGetString);
+ LOAD_PROC(alGetBooleanv);
+ LOAD_PROC(alGetIntegerv);
+ LOAD_PROC(alGetFloatv);
+ LOAD_PROC(alGetDoublev);
+ LOAD_PROC(alGetBoolean);
+ LOAD_PROC(alGetInteger);
+ LOAD_PROC(alGetFloat);
+ LOAD_PROC(alGetDouble);
+ LOAD_PROC(alGetError);
+ LOAD_PROC(alIsExtensionPresent);
+ LOAD_PROC(alGetProcAddress);
+ LOAD_PROC(alGetEnumValue);
+ LOAD_PROC(alListenerf);
+ LOAD_PROC(alListener3f);
+ LOAD_PROC(alListenerfv);
+ LOAD_PROC(alListeneri);
+ LOAD_PROC(alListener3i);
+ LOAD_PROC(alListeneriv);
+ LOAD_PROC(alGetListenerf);
+ LOAD_PROC(alGetListener3f);
+ LOAD_PROC(alGetListenerfv);
+ LOAD_PROC(alGetListeneri);
+ LOAD_PROC(alGetListener3i);
+ LOAD_PROC(alGetListeneriv);
+ LOAD_PROC(alGenSources);
+ LOAD_PROC(alDeleteSources);
+ LOAD_PROC(alIsSource);
+ LOAD_PROC(alSourcef);
+ LOAD_PROC(alSource3f);
+ LOAD_PROC(alSourcefv);
+ LOAD_PROC(alSourcei);
+ LOAD_PROC(alSource3i);
+ LOAD_PROC(alSourceiv);
+ LOAD_PROC(alGetSourcef);
+ LOAD_PROC(alGetSource3f);
+ LOAD_PROC(alGetSourcefv);
+ LOAD_PROC(alGetSourcei);
+ LOAD_PROC(alGetSource3i);
+ LOAD_PROC(alGetSourceiv);
+ LOAD_PROC(alSourcePlayv);
+ LOAD_PROC(alSourceStopv);
+ LOAD_PROC(alSourceRewindv);
+ LOAD_PROC(alSourcePausev);
+ LOAD_PROC(alSourcePlay);
+ LOAD_PROC(alSourceStop);
+ LOAD_PROC(alSourceRewind);
+ LOAD_PROC(alSourcePause);
+ LOAD_PROC(alSourceQueueBuffers);
+ LOAD_PROC(alSourceUnqueueBuffers);
+ LOAD_PROC(alGenBuffers);
+ LOAD_PROC(alDeleteBuffers);
+ LOAD_PROC(alIsBuffer);
+ LOAD_PROC(alBufferf);
+ LOAD_PROC(alBuffer3f);
+ LOAD_PROC(alBufferfv);
+ LOAD_PROC(alBufferi);
+ LOAD_PROC(alBuffer3i);
+ LOAD_PROC(alBufferiv);
+ LOAD_PROC(alGetBufferf);
+ LOAD_PROC(alGetBuffer3f);
+ LOAD_PROC(alGetBufferfv);
+ LOAD_PROC(alGetBufferi);
+ LOAD_PROC(alGetBuffer3i);
+ LOAD_PROC(alGetBufferiv);
+ LOAD_PROC(alBufferData);
+ LOAD_PROC(alDopplerFactor);
+ LOAD_PROC(alDopplerVelocity);
+ LOAD_PROC(alSpeedOfSound);
+ LOAD_PROC(alDistanceModel);
+ if(!err)
+ {
+ wcsncpy(DriverList[DriverListSize].Name, name, 32);
+ DriverList[DriverListSize++].Module = module;
+ }
+}
+
+static void SearchDrivers(WCHAR *path)
+{
+ WCHAR srchPath[MAX_PATH+1] = L"";
+ WIN32_FIND_DATAW fdata;
+ HANDLE srchHdl;
+
+ wcsncpy(srchPath, path, MAX_PATH);
+ wcsncat(srchPath, L"\\*oal.dll", MAX_PATH - lstrlenW(srchPath));
+ srchHdl = FindFirstFileW(srchPath, &fdata);
+ if(srchHdl != INVALID_HANDLE_VALUE)
+ {
+ do {
+ HMODULE mod;
+
+ wcsncpy(srchPath, path, MAX_PATH);
+ wcsncat(srchPath, L"\\", MAX_PATH - lstrlenW(srchPath));
+ wcsncat(srchPath, fdata.cFileName, MAX_PATH - lstrlenW(srchPath));
+
+ mod = LoadLibraryW(srchPath);
+ if(mod) AddModule(mod, fdata.cFileName);
+ } while(FindNextFileW(srchHdl, &fdata));
+ FindClose(srchHdl);
+ }
+}
+
+static WCHAR *strrchrW(WCHAR *str, WCHAR ch)
+{
+ WCHAR *res = NULL;
+ while(str && *str != '\0')
+ {
+ if(*str == ch)
+ res = str;
+ ++str;
+ }
+ return res;
+}
+
+static int GetLoadedModuleDirectory(const WCHAR *name, WCHAR *moddir, DWORD length)
+{
+ HMODULE module = NULL;
+ WCHAR *sep0, *sep1;
+
+ if(name)
+ {
+ module = GetModuleHandleW(name);
+ if(!module) return 0;
+ }
+
+ if(GetModuleFileNameW(module, moddir, length) == 0)
+ return 0;
+
+ sep0 = strrchrW(moddir, '/');
+ if(sep0) sep1 = strrchrW(sep0+1, '\\');
+ else sep1 = strrchrW(moddir, '\\');
+
+ if(sep1) *sep1 = '\0';
+ else if(sep0) *sep0 = '\0';
+ else *moddir = '\0';
+
+ return 1;
+}
+
+void LoadDriverList(void)
+{
+ WCHAR path[MAX_PATH+1] = L"";
+ int len;
+
+ if(GetLoadedModuleDirectory(L"OpenAL32.dll", path, MAX_PATH))
+ SearchDrivers(path);
+
+ GetCurrentDirectoryW(MAX_PATH, path);
+ len = lstrlenW(path);
+ if(len > 0 && (path[len-1] == '\\' || path[len-1] == '/'))
+ path[len-1] = '\0';
+ SearchDrivers(path);
+
+ if(GetLoadedModuleDirectory(NULL, path, MAX_PATH))
+ SearchDrivers(path);
+
+ GetSystemDirectoryW(path, MAX_PATH);
+ len = lstrlenW(path);
+ if(len > 0 && (path[len-1] == '\\' || path[len-1] == '/'))
+ path[len-1] = '\0';
+ SearchDrivers(path);
+}
diff --git a/router/router.h b/router/router.h
new file mode 100644
index 00000000..ee20bc17
--- /dev/null
+++ b/router/router.h
@@ -0,0 +1,115 @@
+#ifndef ROUTER_ROUTER_H
+#define ROUTER_ROUTER_H
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winnt.h>
+
+#include "AL/alc.h"
+#include "AL/al.h"
+
+
+typedef struct DriverIface {
+ WCHAR Name[32];
+ HMODULE Module;
+
+ LPALCCREATECONTEXT alcCreateContext;
+ LPALCMAKECONTEXTCURRENT alcMakeContextCurrent;
+ LPALCPROCESSCONTEXT alcProcessContext;
+ LPALCSUSPENDCONTEXT alcSuspendContext;
+ LPALCDESTROYCONTEXT alcDestroyContext;
+ LPALCGETCURRENTCONTEXT alcGetCurrentContext;
+ LPALCGETCONTEXTSDEVICE alcGetContextsDevice;
+ LPALCOPENDEVICE alcOpenDevice;
+ LPALCCLOSEDEVICE alcCloseDevice;
+ LPALCGETERROR alcGetError;
+ LPALCISEXTENSIONPRESENT alcIsExtensionPresent;
+ LPALCGETPROCADDRESS alcGetProcAddress;
+ LPALCGETENUMVALUE alcGetEnumValue;
+ LPALCGETSTRING alcGetString;
+ LPALCGETINTEGERV alcGetIntegerv;
+ LPALCCAPTUREOPENDEVICE alcCaptureOpenDevice;
+ LPALCCAPTURECLOSEDEVICE alcCaptureCloseDevice;
+ LPALCCAPTURESTART alcCaptureStart;
+ LPALCCAPTURESTOP alcCaptureStop;
+ LPALCCAPTURESAMPLES alcCaptureSamples;
+
+ LPALENABLE alEnable;
+ LPALDISABLE alDisable;
+ LPALISENABLED alIsEnabled;
+ LPALGETSTRING alGetString;
+ LPALGETBOOLEANV alGetBooleanv;
+ LPALGETINTEGERV alGetIntegerv;
+ LPALGETFLOATV alGetFloatv;
+ LPALGETDOUBLEV alGetDoublev;
+ LPALGETBOOLEAN alGetBoolean;
+ LPALGETINTEGER alGetInteger;
+ LPALGETFLOAT alGetFloat;
+ LPALGETDOUBLE alGetDouble;
+ LPALGETERROR alGetError;
+ LPALISEXTENSIONPRESENT alIsExtensionPresent;
+ LPALGETPROCADDRESS alGetProcAddress;
+ LPALGETENUMVALUE alGetEnumValue;
+ LPALLISTENERF alListenerf;
+ LPALLISTENER3F alListener3f;
+ LPALLISTENERFV alListenerfv;
+ LPALLISTENERI alListeneri;
+ LPALLISTENER3I alListener3i;
+ LPALLISTENERIV alListeneriv;
+ LPALGETLISTENERF alGetListenerf;
+ LPALGETLISTENER3F alGetListener3f;
+ LPALGETLISTENERFV alGetListenerfv;
+ LPALGETLISTENERI alGetListeneri;
+ LPALGETLISTENER3I alGetListener3i;
+ LPALGETLISTENERIV alGetListeneriv;
+ LPALGENSOURCES alGenSources;
+ LPALDELETESOURCES alDeleteSources;
+ LPALISSOURCE alIsSource;
+ LPALSOURCEF alSourcef;
+ LPALSOURCE3F alSource3f;
+ LPALSOURCEFV alSourcefv;
+ LPALSOURCEI alSourcei;
+ LPALSOURCE3I alSource3i;
+ LPALSOURCEIV alSourceiv;
+ LPALGETSOURCEF alGetSourcef;
+ LPALGETSOURCE3F alGetSource3f;
+ LPALGETSOURCEFV alGetSourcefv;
+ LPALGETSOURCEI alGetSourcei;
+ LPALGETSOURCE3I alGetSource3i;
+ LPALGETSOURCEIV alGetSourceiv;
+ LPALSOURCEPLAYV alSourcePlayv;
+ LPALSOURCESTOPV alSourceStopv;
+ LPALSOURCEREWINDV alSourceRewindv;
+ LPALSOURCEPAUSEV alSourcePausev;
+ LPALSOURCEPLAY alSourcePlay;
+ LPALSOURCESTOP alSourceStop;
+ LPALSOURCEREWIND alSourceRewind;
+ LPALSOURCEPAUSE alSourcePause;
+ LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers;
+ LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers;
+ LPALGENBUFFERS alGenBuffers;
+ LPALDELETEBUFFERS alDeleteBuffers;
+ LPALISBUFFER alIsBuffer;
+ LPALBUFFERF alBufferf;
+ LPALBUFFER3F alBuffer3f;
+ LPALBUFFERFV alBufferfv;
+ LPALBUFFERI alBufferi;
+ LPALBUFFER3I alBuffer3i;
+ LPALBUFFERIV alBufferiv;
+ LPALGETBUFFERF alGetBufferf;
+ LPALGETBUFFER3F alGetBuffer3f;
+ LPALGETBUFFERFV alGetBufferfv;
+ LPALGETBUFFERI alGetBufferi;
+ LPALGETBUFFER3I alGetBuffer3i;
+ LPALGETBUFFERIV alGetBufferiv;
+ LPALBUFFERDATA alBufferData;
+ LPALDOPPLERFACTOR alDopplerFactor;
+ LPALDOPPLERVELOCITY alDopplerVelocity;
+ LPALSPEEDOFSOUND alSpeedOfSound;
+ LPALDISTANCEMODEL alDistanceModel;
+} DriverIface;
+
+extern DriverIface *DriverList;
+extern int DriverListSize;
+
+#endif /* ROUTER_ROUTER_H */