17 DriverIface
*DriverList
= NULL
;
18 int DriverListSize
= 0;
19 static int DriverListSizeMax
= 0;
21 altss_t ThreadCtxDriver
;
23 enum LogLevel LogLevel
= LogLevel_Error
;
26 static void LoadDriverList(void);
29 BOOL APIENTRY
DllMain(HINSTANCE
UNUSED(module
), DWORD reason
, void* UNUSED(reserved
))
36 case DLL_PROCESS_ATTACH
:
38 str
= getenv("ALROUTER_LOGFILE");
39 if(str
&& *str
!= '\0')
41 FILE *f
= fopen(str
, "w");
43 ERR("Could not open log file: %s\n", str
);
47 str
= getenv("ALROUTER_LOGLEVEL");
48 if(str
&& *str
!= '\0')
51 long l
= strtol(str
, &end
, 0);
52 if(!end
|| *end
!= '\0')
53 ERR("Invalid log level value: %s\n", str
);
54 else if(l
< LogLevel_None
|| l
> LogLevel_Trace
)
55 ERR("Log level out of range: %s\n", str
);
59 TRACE("Initializing router v0.1-%s %s\n", ALSOFT_GIT_COMMIT_HASH
, ALSOFT_GIT_BRANCH
);
62 altss_create(&ThreadCtxDriver
, NULL
);
66 case DLL_THREAD_ATTACH
:
68 case DLL_THREAD_DETACH
:
69 althrd_thread_detach();
72 case DLL_PROCESS_DETACH
:
74 altss_delete(ThreadCtxDriver
);
76 for(i
= 0;i
< DriverListSize
;i
++)
78 if(DriverList
[i
].Module
)
79 FreeLibrary(DriverList
[i
].Module
);
84 DriverListSizeMax
= 0;
86 if(LogFile
&& LogFile
!= stderr
)
98 #define CAST_FUNC(x) (__typeof(x))
100 #define CAST_FUNC(x) (void*)
103 static void AddModule(HMODULE module
, const WCHAR
*name
)
109 for(i
= 0;i
< DriverListSize
;i
++)
111 if(DriverList
[i
].Module
== module
)
113 TRACE("Skipping already-loaded module %p\n", module
);
117 if(wcscmp(DriverList
[i
].Name
, name
) == 0)
119 TRACE("Skipping similarly-named module %ls\n", name
);
125 if(DriverListSize
== DriverListSizeMax
)
127 int newmax
= DriverListSizeMax
? DriverListSizeMax
<<1 : 4;
128 void *newlist
= al_calloc(DEF_ALIGN
, sizeof(DriverList
[0])*newmax
);
131 memcpy(newlist
, DriverList
, DriverListSize
*sizeof(DriverList
[0]));
133 DriverList
= newlist
;
134 DriverListSizeMax
= newmax
;
137 memset(&newdrv
, 0, sizeof(newdrv
));
138 /* Load required functions. */
139 #define LOAD_PROC(x) do { \
140 newdrv.x = CAST_FUNC(newdrv.x) GetProcAddress(module, #x); \
143 ERR("Failed to find entry point for %s in %ls\n", #x, name); \
147 LOAD_PROC(alcCreateContext
);
148 LOAD_PROC(alcMakeContextCurrent
);
149 LOAD_PROC(alcProcessContext
);
150 LOAD_PROC(alcSuspendContext
);
151 LOAD_PROC(alcDestroyContext
);
152 LOAD_PROC(alcGetCurrentContext
);
153 LOAD_PROC(alcGetContextsDevice
);
154 LOAD_PROC(alcOpenDevice
);
155 LOAD_PROC(alcCloseDevice
);
156 LOAD_PROC(alcGetError
);
157 LOAD_PROC(alcIsExtensionPresent
);
158 LOAD_PROC(alcGetProcAddress
);
159 LOAD_PROC(alcGetEnumValue
);
160 LOAD_PROC(alcGetString
);
161 LOAD_PROC(alcGetIntegerv
);
162 LOAD_PROC(alcCaptureOpenDevice
);
163 LOAD_PROC(alcCaptureCloseDevice
);
164 LOAD_PROC(alcCaptureStart
);
165 LOAD_PROC(alcCaptureStop
);
166 LOAD_PROC(alcCaptureSamples
);
169 LOAD_PROC(alDisable
);
170 LOAD_PROC(alIsEnabled
);
171 LOAD_PROC(alGetString
);
172 LOAD_PROC(alGetBooleanv
);
173 LOAD_PROC(alGetIntegerv
);
174 LOAD_PROC(alGetFloatv
);
175 LOAD_PROC(alGetDoublev
);
176 LOAD_PROC(alGetBoolean
);
177 LOAD_PROC(alGetInteger
);
178 LOAD_PROC(alGetFloat
);
179 LOAD_PROC(alGetDouble
);
180 LOAD_PROC(alGetError
);
181 LOAD_PROC(alIsExtensionPresent
);
182 LOAD_PROC(alGetProcAddress
);
183 LOAD_PROC(alGetEnumValue
);
184 LOAD_PROC(alListenerf
);
185 LOAD_PROC(alListener3f
);
186 LOAD_PROC(alListenerfv
);
187 LOAD_PROC(alListeneri
);
188 LOAD_PROC(alListener3i
);
189 LOAD_PROC(alListeneriv
);
190 LOAD_PROC(alGetListenerf
);
191 LOAD_PROC(alGetListener3f
);
192 LOAD_PROC(alGetListenerfv
);
193 LOAD_PROC(alGetListeneri
);
194 LOAD_PROC(alGetListener3i
);
195 LOAD_PROC(alGetListeneriv
);
196 LOAD_PROC(alGenSources
);
197 LOAD_PROC(alDeleteSources
);
198 LOAD_PROC(alIsSource
);
199 LOAD_PROC(alSourcef
);
200 LOAD_PROC(alSource3f
);
201 LOAD_PROC(alSourcefv
);
202 LOAD_PROC(alSourcei
);
203 LOAD_PROC(alSource3i
);
204 LOAD_PROC(alSourceiv
);
205 LOAD_PROC(alGetSourcef
);
206 LOAD_PROC(alGetSource3f
);
207 LOAD_PROC(alGetSourcefv
);
208 LOAD_PROC(alGetSourcei
);
209 LOAD_PROC(alGetSource3i
);
210 LOAD_PROC(alGetSourceiv
);
211 LOAD_PROC(alSourcePlayv
);
212 LOAD_PROC(alSourceStopv
);
213 LOAD_PROC(alSourceRewindv
);
214 LOAD_PROC(alSourcePausev
);
215 LOAD_PROC(alSourcePlay
);
216 LOAD_PROC(alSourceStop
);
217 LOAD_PROC(alSourceRewind
);
218 LOAD_PROC(alSourcePause
);
219 LOAD_PROC(alSourceQueueBuffers
);
220 LOAD_PROC(alSourceUnqueueBuffers
);
221 LOAD_PROC(alGenBuffers
);
222 LOAD_PROC(alDeleteBuffers
);
223 LOAD_PROC(alIsBuffer
);
224 LOAD_PROC(alBufferf
);
225 LOAD_PROC(alBuffer3f
);
226 LOAD_PROC(alBufferfv
);
227 LOAD_PROC(alBufferi
);
228 LOAD_PROC(alBuffer3i
);
229 LOAD_PROC(alBufferiv
);
230 LOAD_PROC(alGetBufferf
);
231 LOAD_PROC(alGetBuffer3f
);
232 LOAD_PROC(alGetBufferfv
);
233 LOAD_PROC(alGetBufferi
);
234 LOAD_PROC(alGetBuffer3i
);
235 LOAD_PROC(alGetBufferiv
);
236 LOAD_PROC(alBufferData
);
237 LOAD_PROC(alDopplerFactor
);
238 LOAD_PROC(alDopplerVelocity
);
239 LOAD_PROC(alSpeedOfSound
);
240 LOAD_PROC(alDistanceModel
);
243 ALCint alc_ver
[2] = { 0, 0 };
244 wcsncpy(newdrv
.Name
, name
, 32);
245 newdrv
.Module
= module
;
246 newdrv
.alcGetIntegerv(NULL
, ALC_MAJOR_VERSION
, 1, &alc_ver
[0]);
247 newdrv
.alcGetIntegerv(NULL
, ALC_MINOR_VERSION
, 1, &alc_ver
[1]);
248 if(newdrv
.alcGetError(NULL
) == ALC_NO_ERROR
)
249 newdrv
.ALCVer
= MAKE_ALC_VER(alc_ver
[0], alc_ver
[1]);
251 newdrv
.ALCVer
= MAKE_ALC_VER(1, 0);
254 #define LOAD_PROC(x) do { \
255 newdrv.x = CAST_FUNC(newdrv.x) newdrv.alcGetProcAddress(NULL, #x); \
258 ERR("Failed to find entry point for %s in %ls\n", #x, name); \
262 if(newdrv
.alcIsExtensionPresent(NULL
, "ALC_EXT_thread_local_context"))
264 LOAD_PROC(alcSetThreadContext
);
265 LOAD_PROC(alcGetThreadContext
);
271 TRACE("Loaded module %p, %ls, ALC %d.%d\n", module
, name
,
272 newdrv
.ALCVer
>>8, newdrv
.ALCVer
&255);
273 DriverList
[DriverListSize
++] = newdrv
;
278 static void SearchDrivers(WCHAR
*path
)
280 WCHAR srchPath
[MAX_PATH
+1] = L
"";
281 WIN32_FIND_DATAW fdata
;
284 TRACE("Searching for drivers in %ls...\n", path
);
285 wcsncpy(srchPath
, path
, MAX_PATH
);
286 wcsncat(srchPath
, L
"\\*oal.dll", MAX_PATH
- lstrlenW(srchPath
));
287 srchHdl
= FindFirstFileW(srchPath
, &fdata
);
288 if(srchHdl
!= INVALID_HANDLE_VALUE
)
293 wcsncpy(srchPath
, path
, MAX_PATH
);
294 wcsncat(srchPath
, L
"\\", MAX_PATH
- lstrlenW(srchPath
));
295 wcsncat(srchPath
, fdata
.cFileName
, MAX_PATH
- lstrlenW(srchPath
));
296 TRACE("Found %ls\n", srchPath
);
298 mod
= LoadLibraryW(srchPath
);
300 WARN("Could not load %ls\n", srchPath
);
302 AddModule(mod
, fdata
.cFileName
);
303 } while(FindNextFileW(srchHdl
, &fdata
));
308 static WCHAR
*strrchrW(WCHAR
*str
, WCHAR ch
)
311 while(str
&& *str
!= '\0')
320 static int GetLoadedModuleDirectory(const WCHAR
*name
, WCHAR
*moddir
, DWORD length
)
322 HMODULE module
= NULL
;
327 module
= GetModuleHandleW(name
);
328 if(!module
) return 0;
331 if(GetModuleFileNameW(module
, moddir
, length
) == 0)
334 sep0
= strrchrW(moddir
, '/');
335 if(sep0
) sep1
= strrchrW(sep0
+1, '\\');
336 else sep1
= strrchrW(moddir
, '\\');
338 if(sep1
) *sep1
= '\0';
339 else if(sep0
) *sep0
= '\0';
345 void LoadDriverList(void)
347 WCHAR dll_path
[MAX_PATH
+1] = L
"";
348 WCHAR cwd_path
[MAX_PATH
+1] = L
"";
349 WCHAR proc_path
[MAX_PATH
+1] = L
"";
350 WCHAR sys_path
[MAX_PATH
+1] = L
"";
353 if(GetLoadedModuleDirectory(L
"OpenAL32.dll", dll_path
, MAX_PATH
))
354 TRACE("Got DLL path %ls\n", dll_path
);
356 GetCurrentDirectoryW(MAX_PATH
, cwd_path
);
357 len
= lstrlenW(cwd_path
);
358 if(len
> 0 && (cwd_path
[len
-1] == '\\' || cwd_path
[len
-1] == '/'))
359 cwd_path
[len
-1] = '\0';
360 TRACE("Got current working directory %ls\n", cwd_path
);
362 if(GetLoadedModuleDirectory(NULL
, proc_path
, MAX_PATH
))
363 TRACE("Got proc path %ls\n", proc_path
);
365 GetSystemDirectoryW(sys_path
, MAX_PATH
);
366 len
= lstrlenW(sys_path
);
367 if(len
> 0 && (sys_path
[len
-1] == '\\' || sys_path
[len
-1] == '/'))
368 sys_path
[len
-1] = '\0';
369 TRACE("Got system path %ls\n", sys_path
);
371 /* Don't search the DLL's path if it is the same as the current working
372 * directory, app's path, or system path (don't want to do duplicate
373 * searches, or increase the priority of the app or system path).
376 (!cwd_path
[0] || wcscmp(dll_path
, cwd_path
) != 0) &&
377 (!proc_path
[0] || wcscmp(dll_path
, proc_path
) != 0) &&
378 (!sys_path
[0] || wcscmp(dll_path
, sys_path
) != 0))
379 SearchDrivers(dll_path
);
381 (!proc_path
[0] || wcscmp(cwd_path
, proc_path
) != 0) &&
382 (!sys_path
[0] || wcscmp(cwd_path
, sys_path
) != 0))
383 SearchDrivers(cwd_path
);
384 if(proc_path
[0] && (!sys_path
[0] || wcscmp(proc_path
, sys_path
) != 0))
385 SearchDrivers(proc_path
);
387 SearchDrivers(sys_path
);
391 void InitPtrIntMap(PtrIntMap
*map
)
397 RWLockInit(&map
->lock
);
400 void ResetPtrIntMap(PtrIntMap
*map
)
402 WriteLock(&map
->lock
);
408 WriteUnlock(&map
->lock
);
411 ALenum
InsertPtrIntMapEntry(PtrIntMap
*map
, ALvoid
*key
, ALint value
)
415 WriteLock(&map
->lock
);
418 ALsizei count
= map
->size
;
420 ALsizei step
= count
>>1;
421 ALsizei i
= pos
+step
;
422 if(!(map
->keys
[i
] < key
))
432 if(pos
== map
->size
|| map
->keys
[pos
] != key
)
434 if(map
->size
== map
->capacity
)
436 ALvoid
**keys
= NULL
;
440 newcap
= (map
->capacity
? (map
->capacity
<<1) : 4);
441 if(newcap
> map
->capacity
)
442 keys
= al_calloc(16, (sizeof(map
->keys
[0])+sizeof(map
->values
[0]))*newcap
);
445 WriteUnlock(&map
->lock
);
446 return AL_OUT_OF_MEMORY
;
448 values
= (ALint
*)&keys
[newcap
];
452 memcpy(keys
, map
->keys
, map
->size
*sizeof(map
->keys
[0]));
453 memcpy(values
, map
->values
, map
->size
*sizeof(map
->values
[0]));
457 map
->values
= values
;
458 map
->capacity
= newcap
;
463 memmove(&map
->keys
[pos
+1], &map
->keys
[pos
],
464 (map
->size
-pos
)*sizeof(map
->keys
[0]));
465 memmove(&map
->values
[pos
+1], &map
->values
[pos
],
466 (map
->size
-pos
)*sizeof(map
->values
[0]));
470 map
->keys
[pos
] = key
;
471 map
->values
[pos
] = value
;
472 WriteUnlock(&map
->lock
);
477 ALint
RemovePtrIntMapKey(PtrIntMap
*map
, ALvoid
*key
)
480 WriteLock(&map
->lock
);
484 ALsizei count
= map
->size
;
486 ALsizei step
= count
>>1;
487 ALsizei i
= pos
+step
;
488 if(!(map
->keys
[i
] < key
))
496 if(pos
< map
->size
&& map
->keys
[pos
] == key
)
498 ret
= map
->values
[pos
];
499 if(pos
< map
->size
-1)
501 memmove(&map
->keys
[pos
], &map
->keys
[pos
+1],
502 (map
->size
-1-pos
)*sizeof(map
->keys
[0]));
503 memmove(&map
->values
[pos
], &map
->values
[pos
+1],
504 (map
->size
-1-pos
)*sizeof(map
->values
[0]));
509 WriteUnlock(&map
->lock
);
513 ALint
LookupPtrIntMapKey(PtrIntMap
*map
, ALvoid
*key
)
516 ReadLock(&map
->lock
);
520 ALsizei count
= map
->size
;
522 ALsizei step
= count
>>1;
523 ALsizei i
= pos
+step
;
524 if(!(map
->keys
[i
] < key
))
532 if(pos
< map
->size
&& map
->keys
[pos
] == key
)
533 ret
= map
->values
[pos
];
535 ReadUnlock(&map
->lock
);