diff options
author | Chris Robinson <[email protected]> | 2017-06-28 16:41:38 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-06-28 16:41:38 -0700 |
commit | cfec20830bca1bdb1bdef5d7429c946fde881d77 (patch) | |
tree | 714b918e5d84e88f8947137c0be1ea7ab7d02d89 | |
parent | ebee8da05cc02fa8da0cbdc47dd9f379e20b962a (diff) |
Load driver dlls in the router
-rw-r--r-- | router/al.c | 1 | ||||
-rw-r--r-- | router/alc.c | 1 | ||||
-rw-r--r-- | router/router.c | 264 | ||||
-rw-r--r-- | router/router.h | 115 |
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 */ |