[WDMAUD.DRV]
[reactos.git] / reactos / dll / win32 / wdmaud.drv / wdmaud.c
1 /*
2 * PROJECT: ReactOS Sound System
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/wdmaud.drv/wdmaud.c
5 *
6 * PURPOSE: WDM Audio Driver (User-mode part)
7 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
8 *
9 * NOTES: Looking for wodMessage & co? You won't find them here. Try
10 * the MME Buddy library, which is where these routines are
11 * actually implemented.
12 *
13 */
14
15 #include <windows.h>
16 #include <ntddsnd.h>
17 #include <sndtypes.h>
18 #include <mmddk.h>
19 #include <mmebuddy.h>
20
21 #include <ks.h>
22 #include <ksmedia.h>
23 #include "interface.h"
24
25 #define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
26
27 PWSTR UnknownWaveIn = L"Wave Input";
28 PWSTR UnknownWaveOut = L"Wave Output";
29 PWSTR UnknownMidiIn = L"Midi Input";
30 PWSTR UnknownMidiOut = L"Midi Output";
31
32 HANDLE KernelHandle = INVALID_HANDLE_VALUE;
33 DWORD OpenCount = 0;
34
35 MMRESULT
36 WriteFileEx_Remixer(
37 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
38 IN PVOID OffsetPtr,
39 IN DWORD Length,
40 IN PSOUND_OVERLAPPED Overlap,
41 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine);
42
43
44
45 MMRESULT
46 GetNumWdmDevs(
47 IN HANDLE Handle,
48 IN MMDEVICE_TYPE DeviceType,
49 OUT DWORD* DeviceCount)
50 {
51 MMRESULT Result;
52 WDMAUD_DEVICE_INFO DeviceInfo;
53
54 VALIDATE_MMSYS_PARAMETER( Handle != INVALID_HANDLE_VALUE );
55 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
56 VALIDATE_MMSYS_PARAMETER( DeviceCount );
57
58 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
59 DeviceInfo.DeviceType = DeviceType;
60
61 Result = SyncOverlappedDeviceIoControl(Handle,
62 IOCTL_GETNUMDEVS_TYPE,
63 (LPVOID) &DeviceInfo,
64 sizeof(WDMAUD_DEVICE_INFO),
65 (LPVOID) &DeviceInfo,
66 sizeof(WDMAUD_DEVICE_INFO),
67 NULL);
68
69 if ( ! MMSUCCESS( Result ) )
70 {
71 SND_ERR(L"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
72 *DeviceCount = 0;
73 return TranslateInternalMmResult(Result);
74 }
75
76 *DeviceCount = DeviceInfo.DeviceCount;
77
78 return MMSYSERR_NOERROR;
79 }
80
81 MMRESULT
82 GetWdmDeviceCapabilities(
83 IN PSOUND_DEVICE SoundDevice,
84 IN DWORD DeviceId,
85 OUT PVOID Capabilities,
86 IN DWORD CapabilitiesSize)
87 {
88 /* NOTE - At this time, WDMAUD does not support this properly */
89
90 MMRESULT Result;
91 MMDEVICE_TYPE DeviceType;
92 WDMAUD_DEVICE_INFO DeviceInfo;
93
94 SND_ASSERT( SoundDevice );
95 SND_ASSERT( Capabilities );
96
97 SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities\n");
98
99 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
100 SND_ASSERT( Result == MMSYSERR_NOERROR );
101
102 if ( ! MMSUCCESS(Result) )
103 return Result;
104
105
106 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
107 DeviceInfo.DeviceType = DeviceType;
108 DeviceInfo.DeviceIndex = DeviceId;
109
110 Result = SyncOverlappedDeviceIoControl(KernelHandle,
111 IOCTL_GETCAPABILITIES,
112 (LPVOID) &DeviceInfo,
113 sizeof(WDMAUD_DEVICE_INFO),
114 (LPVOID) &DeviceInfo,
115 sizeof(WDMAUD_DEVICE_INFO),
116 NULL);
117
118 if ( ! MMSUCCESS(Result) )
119 {
120 return TranslateInternalMmResult(Result);
121 }
122
123 SND_TRACE(L"WDMAUD Name %S\n", DeviceInfo.u.WaveOutCaps.szPname);
124
125 /* This is pretty much a big hack right now */
126 switch ( DeviceType )
127 {
128 case WAVE_OUT_DEVICE_TYPE :
129 {
130 LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
131 WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
132 WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
133
134 WaveOutCaps->vDriverVersion = 0x0001;
135 CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
136
137 WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
138 WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
139 WaveOutCaps->dwSupport = DeviceInfo.u.WaveOutCaps.dwSupport;
140 break;
141 }
142 case WAVE_IN_DEVICE_TYPE :
143 {
144 LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
145 CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
146 /* TODO... other fields */
147 break;
148 }
149 }
150
151 return MMSYSERR_NOERROR;
152 }
153
154
155 MMRESULT
156 OpenWdmSoundDevice(
157 IN struct _SOUND_DEVICE* SoundDevice, /* NOT USED */
158 OUT PVOID* Handle)
159 {
160 /* Only open this if it's not already open */
161 if ( KernelHandle == INVALID_HANDLE_VALUE )
162 {
163 SND_TRACE(L"Opening wdmaud device\n");
164 KernelHandle = CreateFileW(KERNEL_DEVICE_NAME,
165 GENERIC_READ | GENERIC_WRITE,
166 0,
167 NULL,
168 OPEN_EXISTING,
169 FILE_FLAG_OVERLAPPED,
170 NULL);
171 }
172
173 if ( KernelHandle == INVALID_HANDLE_VALUE )
174 return MMSYSERR_ERROR;
175
176 SND_ASSERT( Handle );
177
178 *Handle = KernelHandle;
179 ++ OpenCount;
180
181 return MMSYSERR_NOERROR;
182 }
183
184 MMRESULT
185 CloseWdmSoundDevice(
186 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
187 IN PVOID Handle)
188 {
189 WDMAUD_DEVICE_INFO DeviceInfo;
190 MMRESULT Result;
191 MMDEVICE_TYPE DeviceType;
192 PSOUND_DEVICE SoundDevice;
193
194 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
195
196 if ( ! MMSUCCESS(Result) )
197 {
198 return TranslateInternalMmResult(Result);
199 }
200
201 if ( OpenCount == 0 )
202 {
203 return MMSYSERR_NOERROR;
204 }
205
206 SND_ASSERT( KernelHandle != INVALID_HANDLE_VALUE );
207
208 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
209 SND_ASSERT( Result == MMSYSERR_NOERROR );
210
211 if (SoundDeviceInstance->Handle != (PVOID)KernelHandle)
212 {
213 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
214
215 DeviceInfo.DeviceType = DeviceType;
216 DeviceInfo.hDevice = SoundDeviceInstance->Handle;
217
218 /* First stop the stream */
219 if (DeviceType != MIXER_DEVICE_TYPE)
220 {
221 DeviceInfo.u.State = KSSTATE_STOP;
222 SyncOverlappedDeviceIoControl(KernelHandle,
223 IOCTL_SETDEVICE_STATE,
224 (LPVOID) &DeviceInfo,
225 sizeof(WDMAUD_DEVICE_INFO),
226 (LPVOID) &DeviceInfo,
227 sizeof(WDMAUD_DEVICE_INFO),
228 NULL);
229 }
230
231 SyncOverlappedDeviceIoControl(KernelHandle,
232 IOCTL_CLOSE_WDMAUD,
233 (LPVOID) &DeviceInfo,
234 sizeof(WDMAUD_DEVICE_INFO),
235 (LPVOID) &DeviceInfo,
236 sizeof(WDMAUD_DEVICE_INFO),
237 NULL);
238 }
239
240 --OpenCount;
241
242 if ( OpenCount < 1 )
243 {
244 CloseHandle(KernelHandle);
245 KernelHandle = INVALID_HANDLE_VALUE;
246 }
247
248 return MMSYSERR_NOERROR;
249 }
250
251
252 MMRESULT
253 QueryWdmWaveDeviceFormatSupport(
254 IN PSOUND_DEVICE Device,
255 IN PWAVEFORMATEX WaveFormat,
256 IN DWORD WaveFormatSize)
257 {
258 /* Whatever... */
259 return MMSYSERR_NOERROR;
260 }
261
262
263 MMRESULT
264 SetWdmMixerDeviceFormat(
265 IN PSOUND_DEVICE_INSTANCE Instance,
266 IN DWORD DeviceId,
267 IN PWAVEFORMATEX WaveFormat,
268 IN DWORD WaveFormatSize)
269 {
270 MMRESULT Result;
271 PSOUND_DEVICE SoundDevice;
272 PVOID Identifier;
273 WDMAUD_DEVICE_INFO DeviceInfo;
274 MMDEVICE_TYPE DeviceType;
275
276 Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
277
278 if ( ! MMSUCCESS(Result) )
279 {
280 return TranslateInternalMmResult(Result);
281 }
282
283 Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
284
285 if ( ! MMSUCCESS(Result) )
286 {
287 return TranslateInternalMmResult(Result);
288 }
289
290 if (Instance->Handle != KernelHandle)
291 {
292 /* device is already open */
293 return MMSYSERR_NOERROR;
294 }
295
296
297 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
298 SND_ASSERT( Result == MMSYSERR_NOERROR );
299
300 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
301 DeviceInfo.DeviceType = DeviceType;
302 DeviceInfo.DeviceIndex = DeviceId;
303
304 Result = SyncOverlappedDeviceIoControl(KernelHandle,
305 IOCTL_OPEN_WDMAUD,
306 (LPVOID) &DeviceInfo,
307 sizeof(WDMAUD_DEVICE_INFO),
308 (LPVOID) &DeviceInfo,
309 sizeof(WDMAUD_DEVICE_INFO),
310 NULL);
311
312 if ( ! MMSUCCESS(Result) )
313 {
314 return TranslateInternalMmResult(Result);
315 }
316
317 /* Store sound device handle instance handle */
318 Instance->Handle = (PVOID)DeviceInfo.hDevice;
319
320 return MMSYSERR_NOERROR;
321 }
322
323 MMRESULT
324 SetWdmWaveDeviceFormat(
325 IN PSOUND_DEVICE_INSTANCE Instance,
326 IN DWORD DeviceId,
327 IN PWAVEFORMATEX WaveFormat,
328 IN DWORD WaveFormatSize)
329 {
330 MMRESULT Result;
331 PSOUND_DEVICE SoundDevice;
332 PVOID Identifier;
333 WDMAUD_DEVICE_INFO DeviceInfo;
334 MMDEVICE_TYPE DeviceType;
335
336 Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
337
338 if ( ! MMSUCCESS(Result) )
339 {
340 return TranslateInternalMmResult(Result);
341 }
342
343 Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
344
345 if ( ! MMSUCCESS(Result) )
346 {
347 return TranslateInternalMmResult(Result);
348 }
349
350 if (Instance->Handle != KernelHandle)
351 {
352 /* device is already open */
353 return MMSYSERR_NOERROR;
354 }
355
356
357 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
358 SND_ASSERT( Result == MMSYSERR_NOERROR );
359
360 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
361 DeviceInfo.DeviceType = DeviceType;
362 DeviceInfo.DeviceIndex = DeviceId;
363 DeviceInfo.u.WaveFormatEx.cbSize = WaveFormat->cbSize;
364 DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
365 #ifdef USERMODE_MIXER
366 DeviceInfo.u.WaveFormatEx.nChannels = 2;
367 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100;
368 DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
369 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400;
370 DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
371 #else
372 DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels;
373 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
374 DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
375 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
376 DeviceInfo.u.WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
377 #endif
378
379 Result = SyncOverlappedDeviceIoControl(KernelHandle,
380 IOCTL_OPEN_WDMAUD,
381 (LPVOID) &DeviceInfo,
382 sizeof(WDMAUD_DEVICE_INFO),
383 (LPVOID) &DeviceInfo,
384 sizeof(WDMAUD_DEVICE_INFO),
385 NULL);
386
387 if ( ! MMSUCCESS(Result) )
388 {
389 return TranslateInternalMmResult(Result);
390 }
391
392 /* Store format */
393 Instance->WaveFormatEx.cbSize = WaveFormat->cbSize;
394 Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
395 Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
396 Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
397 Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
398 Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
399 Instance->WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
400
401 /* Store sound device handle instance handle */
402 Instance->Handle = (PVOID)DeviceInfo.hDevice;
403
404 /* Now determine framing requirements */
405 Result = SyncOverlappedDeviceIoControl(KernelHandle,
406 IOCTL_GETFRAMESIZE,
407 (LPVOID) &DeviceInfo,
408 sizeof(WDMAUD_DEVICE_INFO),
409 (LPVOID) &DeviceInfo,
410 sizeof(WDMAUD_DEVICE_INFO),
411 NULL);
412
413 if ( MMSUCCESS(Result) )
414 {
415 if (DeviceInfo.u.FrameSize)
416 {
417 //Instance->FrameSize = DeviceInfo.u.FrameSize;
418 Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
419 SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
420 }
421 }
422
423 /* Now start the stream */
424 DeviceInfo.u.State = KSSTATE_RUN;
425 SyncOverlappedDeviceIoControl(KernelHandle,
426 IOCTL_SETDEVICE_STATE,
427 (LPVOID) &DeviceInfo,
428 sizeof(WDMAUD_DEVICE_INFO),
429 (LPVOID) &DeviceInfo,
430 sizeof(WDMAUD_DEVICE_INFO),
431 NULL);
432
433 return MMSYSERR_NOERROR;
434 }
435
436 MMRESULT
437 WriteFileEx_Committer2(
438 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
439 IN PVOID OffsetPtr,
440 IN DWORD Length,
441 IN PSOUND_OVERLAPPED Overlap,
442 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
443 {
444 HANDLE Handle;
445 WDMAUD_DEVICE_INFO DeviceInfo;
446
447
448 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
449 VALIDATE_MMSYS_PARAMETER( OffsetPtr );
450 VALIDATE_MMSYS_PARAMETER( Overlap );
451 VALIDATE_MMSYS_PARAMETER( CompletionRoutine );
452
453 GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
454
455 SND_ASSERT(Handle);
456
457 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
458 DeviceInfo.Header.FrameExtent = Length;
459 DeviceInfo.Header.DataUsed = Length;
460 DeviceInfo.Header.Data = OffsetPtr;
461 DeviceInfo.Header.Size = sizeof(KSSTREAM_HEADER);
462 DeviceInfo.Header.PresentationTime.Numerator = 1;
463 DeviceInfo.Header.PresentationTime.Denominator = 1;
464 DeviceInfo.hDevice = Handle;
465 DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME
466
467 Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
468
469 if ( ! WriteFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine))
470 {
471 SND_TRACE(L"WriteFileEx failed with %x\n", GetLastError());
472 }
473 else
474 {
475 WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
476
477 }
478
479 return MMSYSERR_NOERROR;
480 }
481
482 MMRESULT
483 GetWdmPosition(
484 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
485 IN MMTIME* Time)
486 {
487 MMRESULT Result;
488 PSOUND_DEVICE SoundDevice;
489 WDMAUD_DEVICE_INFO DeviceInfo;
490 MMDEVICE_TYPE DeviceType;
491 HANDLE Handle;
492
493 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
494
495 if ( ! MMSUCCESS(Result) )
496 {
497 return TranslateInternalMmResult(Result);
498 }
499
500 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
501 SND_ASSERT( Result == MMSYSERR_NOERROR );
502
503 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
504 SND_ASSERT( Result == MMSYSERR_NOERROR );
505
506 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
507 DeviceInfo.hDevice = Handle;
508 DeviceInfo.DeviceType = DeviceType;
509
510 Result = SyncOverlappedDeviceIoControl(KernelHandle,
511 IOCTL_OPEN_WDMAUD,
512 (LPVOID) &DeviceInfo,
513 sizeof(WDMAUD_DEVICE_INFO),
514 (LPVOID) &DeviceInfo,
515 sizeof(WDMAUD_DEVICE_INFO),
516 NULL);
517
518 if ( ! MMSUCCESS(Result) )
519 {
520 return TranslateInternalMmResult(Result);
521 }
522
523 Time->wType = TIME_BYTES;
524 Time->u.cb = (DWORD)DeviceInfo.u.Position;
525
526 return MMSYSERR_NOERROR;
527 }
528
529
530 MMRESULT
531 PopulateWdmDeviceList(
532 HANDLE Handle,
533 MMDEVICE_TYPE DeviceType)
534 {
535 MMRESULT Result;
536 DWORD DeviceCount = 0;
537 PSOUND_DEVICE SoundDevice = NULL;
538 MMFUNCTION_TABLE FuncTable;
539 DWORD i;
540
541 VALIDATE_MMSYS_PARAMETER( Handle != INVALID_HANDLE_VALUE );
542 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
543
544 Result = GetNumWdmDevs(Handle, DeviceType, &DeviceCount);
545
546 if ( ! MMSUCCESS(Result) )
547 {
548 SND_ERR(L"Error %d while obtaining number of devices\n", Result);
549 return TranslateInternalMmResult(Result);
550 }
551
552 SND_TRACE(L"%d devices of type %d found\n", DeviceCount, DeviceType);
553
554
555 for ( i = 0; i < DeviceCount; ++ i )
556 {
557 Result = ListSoundDevice(DeviceType, (PVOID) i, &SoundDevice);
558
559 if ( ! MMSUCCESS(Result) )
560 {
561 SND_ERR(L"Failed to list sound device - error %d\n", Result);
562 return TranslateInternalMmResult(Result);
563 }
564
565 /* Set up our function table */
566 ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
567 FuncTable.GetCapabilities = GetWdmDeviceCapabilities;
568 FuncTable.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport;
569 if (DeviceType == MIXER_DEVICE_TYPE)
570 {
571 FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat;
572 }
573 else
574 {
575 FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
576 }
577
578 FuncTable.Open = OpenWdmSoundDevice;
579 FuncTable.Close = CloseWdmSoundDevice;
580 #ifndef USERMODE_MIXER
581 FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
582 #else
583 FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
584 #endif
585 FuncTable.GetPos = GetWdmPosition;
586
587 SetSoundDeviceFunctionTable(SoundDevice, &FuncTable);
588 }
589
590 return MMSYSERR_NOERROR;
591 }
592
593
594
595 LONG
596 APIENTRY
597 DriverProc(
598 DWORD DriverId,
599 HANDLE DriverHandle,
600 UINT Message,
601 LONG Parameter1,
602 LONG Parameter2)
603 {
604 MMRESULT Result;
605
606 switch ( Message )
607 {
608 case DRV_LOAD :
609 {
610 HANDLE Handle;
611 SND_TRACE(L"DRV_LOAD\n");
612
613 Result = InitEntrypointMutexes();
614
615 if ( ! MMSUCCESS(Result) )
616 return 0L;
617
618 OpenWdmSoundDevice(NULL, &Handle);
619
620 if ( Handle == INVALID_HANDLE_VALUE )
621 {
622 SND_ERR(L"Failed to open %s\n", KERNEL_DEVICE_NAME);
623 CleanupEntrypointMutexes();
624
625 //UnlistAllSoundDevices();
626
627 return 0L;
628 }
629
630 /* Populate the device lists */
631 SND_TRACE(L"Populating device lists\n");
632 PopulateWdmDeviceList(KernelHandle, WAVE_OUT_DEVICE_TYPE);
633 PopulateWdmDeviceList(KernelHandle, WAVE_IN_DEVICE_TYPE);
634 PopulateWdmDeviceList(KernelHandle, MIDI_OUT_DEVICE_TYPE);
635 PopulateWdmDeviceList(KernelHandle, MIDI_IN_DEVICE_TYPE);
636 PopulateWdmDeviceList(KernelHandle, AUX_DEVICE_TYPE);
637 PopulateWdmDeviceList(KernelHandle, MIXER_DEVICE_TYPE);
638
639 SND_TRACE(L"Initialisation complete\n");
640
641 return 1L;
642 }
643
644 case DRV_FREE :
645 {
646 SND_TRACE(L"DRV_FREE\n");
647
648 if ( KernelHandle != INVALID_HANDLE_VALUE )
649 {
650 CloseHandle(KernelHandle);
651 KernelHandle = INVALID_HANDLE_VALUE;
652 }
653
654 /* TODO: Clean up the path names! */
655 UnlistAllSoundDevices();
656
657 CleanupEntrypointMutexes();
658
659 SND_TRACE(L"Unfreed memory blocks: %d\n",
660 GetMemoryAllocationCount());
661
662 return 1L;
663 }
664
665 case DRV_ENABLE :
666 case DRV_DISABLE :
667 {
668 SND_TRACE(L"DRV_ENABLE / DRV_DISABLE\n");
669 return 1L;
670 }
671
672 case DRV_OPEN :
673 case DRV_CLOSE :
674 {
675 SND_TRACE(L"DRV_OPEN / DRV_CLOSE\n");
676 return 1L;
677 }
678
679 case DRV_QUERYCONFIGURE :
680 {
681 SND_TRACE(L"DRV_QUERYCONFIGURE\n");
682 return 0L;
683 }
684 case DRV_CONFIGURE :
685 return DRVCNF_OK;
686
687 default :
688 SND_TRACE(L"Unhandled message %d\n", Message);
689 return DefDriverProc(DriverId,
690 DriverHandle,
691 Message,
692 Parameter1,
693 Parameter2);
694 }
695 }
696
697
698 BOOL WINAPI DllMain(
699 HINSTANCE hinstDLL,
700 DWORD fdwReason,
701 LPVOID lpvReserved)
702 {
703 switch ( fdwReason )
704 {
705 case DLL_PROCESS_ATTACH :
706 SND_TRACE(L"WDMAUD.DRV - Process attached\n");
707 break;
708 case DLL_PROCESS_DETACH :
709 SND_TRACE(L"WDMAUD.DRV - Process detached\n");
710 break;
711 case DLL_THREAD_ATTACH :
712 SND_TRACE(L"WDMAUD.DRV - Thread attached\n");
713 break;
714 case DLL_THREAD_DETACH :
715 SND_TRACE(L"WDMAUD.DRV - Thread detached\n");
716 break;
717 }
718
719 return TRUE;
720 }