[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 MIXER_DEVICE_TYPE:
129 {
130 LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
131
132 CopyWideString(MixerCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
133
134 MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations;
135 MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport;
136 MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
137 MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
138 MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
139 break;
140 }
141 case WAVE_OUT_DEVICE_TYPE :
142 {
143 LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
144 WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
145 WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
146
147 WaveOutCaps->vDriverVersion = 0x0001;
148 CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
149
150 WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
151 WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
152 WaveOutCaps->dwSupport = DeviceInfo.u.WaveOutCaps.dwSupport;
153 break;
154 }
155 case WAVE_IN_DEVICE_TYPE :
156 {
157 LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
158 CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
159 /* TODO... other fields */
160 break;
161 }
162 }
163
164 return MMSYSERR_NOERROR;
165 }
166
167
168 MMRESULT
169 OpenWdmSoundDevice(
170 IN struct _SOUND_DEVICE* SoundDevice, /* NOT USED */
171 OUT PVOID* Handle)
172 {
173 /* Only open this if it's not already open */
174 if ( KernelHandle == INVALID_HANDLE_VALUE )
175 {
176 SND_TRACE(L"Opening wdmaud device\n");
177 KernelHandle = CreateFileW(KERNEL_DEVICE_NAME,
178 GENERIC_READ | GENERIC_WRITE,
179 0,
180 NULL,
181 OPEN_EXISTING,
182 FILE_FLAG_OVERLAPPED,
183 NULL);
184 }
185
186 if ( KernelHandle == INVALID_HANDLE_VALUE )
187 return MMSYSERR_ERROR;
188
189 SND_ASSERT( Handle );
190
191 *Handle = KernelHandle;
192 ++ OpenCount;
193
194 return MMSYSERR_NOERROR;
195 }
196
197 MMRESULT
198 CloseWdmSoundDevice(
199 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
200 IN PVOID Handle)
201 {
202 WDMAUD_DEVICE_INFO DeviceInfo;
203 MMRESULT Result;
204 MMDEVICE_TYPE DeviceType;
205 PSOUND_DEVICE SoundDevice;
206
207 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
208
209 if ( ! MMSUCCESS(Result) )
210 {
211 return TranslateInternalMmResult(Result);
212 }
213
214 if ( OpenCount == 0 )
215 {
216 return MMSYSERR_NOERROR;
217 }
218
219 SND_ASSERT( KernelHandle != INVALID_HANDLE_VALUE );
220
221 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
222 SND_ASSERT( Result == MMSYSERR_NOERROR );
223
224 if (SoundDeviceInstance->Handle != (PVOID)KernelHandle)
225 {
226 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
227
228 DeviceInfo.DeviceType = DeviceType;
229 DeviceInfo.hDevice = SoundDeviceInstance->Handle;
230
231 /* First stop the stream */
232 if (DeviceType != MIXER_DEVICE_TYPE)
233 {
234 DeviceInfo.u.State = KSSTATE_STOP;
235 SyncOverlappedDeviceIoControl(KernelHandle,
236 IOCTL_SETDEVICE_STATE,
237 (LPVOID) &DeviceInfo,
238 sizeof(WDMAUD_DEVICE_INFO),
239 (LPVOID) &DeviceInfo,
240 sizeof(WDMAUD_DEVICE_INFO),
241 NULL);
242 }
243
244 SyncOverlappedDeviceIoControl(KernelHandle,
245 IOCTL_CLOSE_WDMAUD,
246 (LPVOID) &DeviceInfo,
247 sizeof(WDMAUD_DEVICE_INFO),
248 (LPVOID) &DeviceInfo,
249 sizeof(WDMAUD_DEVICE_INFO),
250 NULL);
251 }
252
253 --OpenCount;
254
255 if ( OpenCount < 1 )
256 {
257 CloseHandle(KernelHandle);
258 KernelHandle = INVALID_HANDLE_VALUE;
259 }
260
261 return MMSYSERR_NOERROR;
262 }
263
264
265 MMRESULT
266 QueryWdmWaveDeviceFormatSupport(
267 IN PSOUND_DEVICE Device,
268 IN PWAVEFORMATEX WaveFormat,
269 IN DWORD WaveFormatSize)
270 {
271 /* Whatever... */
272 return MMSYSERR_NOERROR;
273 }
274
275
276 MMRESULT
277 SetWdmMixerDeviceFormat(
278 IN PSOUND_DEVICE_INSTANCE Instance,
279 IN DWORD DeviceId,
280 IN PWAVEFORMATEX WaveFormat,
281 IN DWORD WaveFormatSize)
282 {
283 MMRESULT Result;
284 PSOUND_DEVICE SoundDevice;
285 PVOID Identifier;
286 WDMAUD_DEVICE_INFO DeviceInfo;
287 MMDEVICE_TYPE DeviceType;
288
289 Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
290
291 if ( ! MMSUCCESS(Result) )
292 {
293 return TranslateInternalMmResult(Result);
294 }
295
296 Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
297
298 if ( ! MMSUCCESS(Result) )
299 {
300 return TranslateInternalMmResult(Result);
301 }
302
303 if (Instance->Handle != KernelHandle)
304 {
305 /* device is already open */
306 return MMSYSERR_NOERROR;
307 }
308
309
310 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
311 SND_ASSERT( Result == MMSYSERR_NOERROR );
312
313 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
314 DeviceInfo.DeviceType = DeviceType;
315 DeviceInfo.DeviceIndex = DeviceId;
316
317 Result = SyncOverlappedDeviceIoControl(KernelHandle,
318 IOCTL_OPEN_WDMAUD,
319 (LPVOID) &DeviceInfo,
320 sizeof(WDMAUD_DEVICE_INFO),
321 (LPVOID) &DeviceInfo,
322 sizeof(WDMAUD_DEVICE_INFO),
323 NULL);
324
325 if ( ! MMSUCCESS(Result) )
326 {
327 return TranslateInternalMmResult(Result);
328 }
329
330 /* Store sound device handle instance handle */
331 Instance->Handle = (PVOID)DeviceInfo.hDevice;
332
333 return MMSYSERR_NOERROR;
334 }
335
336 MMRESULT
337 SetWdmWaveDeviceFormat(
338 IN PSOUND_DEVICE_INSTANCE Instance,
339 IN DWORD DeviceId,
340 IN PWAVEFORMATEX WaveFormat,
341 IN DWORD WaveFormatSize)
342 {
343 MMRESULT Result;
344 PSOUND_DEVICE SoundDevice;
345 PVOID Identifier;
346 WDMAUD_DEVICE_INFO DeviceInfo;
347 MMDEVICE_TYPE DeviceType;
348
349 Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
350
351 if ( ! MMSUCCESS(Result) )
352 {
353 return TranslateInternalMmResult(Result);
354 }
355
356 Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
357
358 if ( ! MMSUCCESS(Result) )
359 {
360 return TranslateInternalMmResult(Result);
361 }
362
363 if (Instance->Handle != KernelHandle)
364 {
365 /* device is already open */
366 return MMSYSERR_NOERROR;
367 }
368
369
370 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
371 SND_ASSERT( Result == MMSYSERR_NOERROR );
372
373 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
374 DeviceInfo.DeviceType = DeviceType;
375 DeviceInfo.DeviceIndex = DeviceId;
376 DeviceInfo.u.WaveFormatEx.cbSize = WaveFormat->cbSize;
377 DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
378 #ifdef USERMODE_MIXER
379 DeviceInfo.u.WaveFormatEx.nChannels = 2;
380 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100;
381 DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
382 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400;
383 DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
384 #else
385 DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels;
386 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
387 DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
388 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
389 DeviceInfo.u.WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
390 #endif
391
392 Result = SyncOverlappedDeviceIoControl(KernelHandle,
393 IOCTL_OPEN_WDMAUD,
394 (LPVOID) &DeviceInfo,
395 sizeof(WDMAUD_DEVICE_INFO),
396 (LPVOID) &DeviceInfo,
397 sizeof(WDMAUD_DEVICE_INFO),
398 NULL);
399
400 if ( ! MMSUCCESS(Result) )
401 {
402 return TranslateInternalMmResult(Result);
403 }
404
405 /* Store format */
406 Instance->WaveFormatEx.cbSize = WaveFormat->cbSize;
407 Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
408 Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
409 Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
410 Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
411 Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
412 Instance->WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
413
414 /* Store sound device handle instance handle */
415 Instance->Handle = (PVOID)DeviceInfo.hDevice;
416
417 /* Now determine framing requirements */
418 Result = SyncOverlappedDeviceIoControl(KernelHandle,
419 IOCTL_GETFRAMESIZE,
420 (LPVOID) &DeviceInfo,
421 sizeof(WDMAUD_DEVICE_INFO),
422 (LPVOID) &DeviceInfo,
423 sizeof(WDMAUD_DEVICE_INFO),
424 NULL);
425
426 if ( MMSUCCESS(Result) )
427 {
428 if (DeviceInfo.u.FrameSize)
429 {
430 //Instance->FrameSize = DeviceInfo.u.FrameSize;
431 Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
432 SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
433 }
434 }
435
436 /* Now start the stream */
437 DeviceInfo.u.State = KSSTATE_RUN;
438 SyncOverlappedDeviceIoControl(KernelHandle,
439 IOCTL_SETDEVICE_STATE,
440 (LPVOID) &DeviceInfo,
441 sizeof(WDMAUD_DEVICE_INFO),
442 (LPVOID) &DeviceInfo,
443 sizeof(WDMAUD_DEVICE_INFO),
444 NULL);
445
446 return MMSYSERR_NOERROR;
447 }
448
449 MMRESULT
450 WriteFileEx_Committer2(
451 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
452 IN PVOID OffsetPtr,
453 IN DWORD Length,
454 IN PSOUND_OVERLAPPED Overlap,
455 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
456 {
457 HANDLE Handle;
458 WDMAUD_DEVICE_INFO DeviceInfo;
459
460
461 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
462 VALIDATE_MMSYS_PARAMETER( OffsetPtr );
463 VALIDATE_MMSYS_PARAMETER( Overlap );
464 VALIDATE_MMSYS_PARAMETER( CompletionRoutine );
465
466 GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
467
468 SND_ASSERT(Handle);
469
470 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
471 DeviceInfo.Header.FrameExtent = Length;
472 DeviceInfo.Header.DataUsed = Length;
473 DeviceInfo.Header.Data = OffsetPtr;
474 DeviceInfo.Header.Size = sizeof(KSSTREAM_HEADER);
475 DeviceInfo.Header.PresentationTime.Numerator = 1;
476 DeviceInfo.Header.PresentationTime.Denominator = 1;
477 DeviceInfo.hDevice = Handle;
478 DeviceInfo.DeviceType = WAVE_OUT_DEVICE_TYPE; //FIXME
479
480 Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
481
482 if ( ! WriteFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine))
483 {
484 SND_TRACE(L"WriteFileEx failed with %x\n", GetLastError());
485 }
486 else
487 {
488 WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
489
490 }
491
492 return MMSYSERR_NOERROR;
493 }
494
495 MMRESULT
496 GetWdmPosition(
497 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
498 IN MMTIME* Time)
499 {
500 MMRESULT Result;
501 PSOUND_DEVICE SoundDevice;
502 WDMAUD_DEVICE_INFO DeviceInfo;
503 MMDEVICE_TYPE DeviceType;
504 HANDLE Handle;
505
506 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
507
508 if ( ! MMSUCCESS(Result) )
509 {
510 return TranslateInternalMmResult(Result);
511 }
512
513 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
514 SND_ASSERT( Result == MMSYSERR_NOERROR );
515
516 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
517 SND_ASSERT( Result == MMSYSERR_NOERROR );
518
519 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
520 DeviceInfo.hDevice = Handle;
521 DeviceInfo.DeviceType = DeviceType;
522
523 Result = SyncOverlappedDeviceIoControl(KernelHandle,
524 IOCTL_OPEN_WDMAUD,
525 (LPVOID) &DeviceInfo,
526 sizeof(WDMAUD_DEVICE_INFO),
527 (LPVOID) &DeviceInfo,
528 sizeof(WDMAUD_DEVICE_INFO),
529 NULL);
530
531 if ( ! MMSUCCESS(Result) )
532 {
533 return TranslateInternalMmResult(Result);
534 }
535
536 Time->wType = TIME_BYTES;
537 Time->u.cb = (DWORD)DeviceInfo.u.Position;
538
539 return MMSYSERR_NOERROR;
540 }
541
542
543 MMRESULT
544 PopulateWdmDeviceList(
545 HANDLE Handle,
546 MMDEVICE_TYPE DeviceType)
547 {
548 MMRESULT Result;
549 DWORD DeviceCount = 0;
550 PSOUND_DEVICE SoundDevice = NULL;
551 MMFUNCTION_TABLE FuncTable;
552 DWORD i;
553
554 VALIDATE_MMSYS_PARAMETER( Handle != INVALID_HANDLE_VALUE );
555 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
556
557 Result = GetNumWdmDevs(Handle, DeviceType, &DeviceCount);
558
559 if ( ! MMSUCCESS(Result) )
560 {
561 SND_ERR(L"Error %d while obtaining number of devices\n", Result);
562 return TranslateInternalMmResult(Result);
563 }
564
565 SND_TRACE(L"%d devices of type %d found\n", DeviceCount, DeviceType);
566
567
568 for ( i = 0; i < DeviceCount; ++ i )
569 {
570 Result = ListSoundDevice(DeviceType, (PVOID) i, &SoundDevice);
571
572 if ( ! MMSUCCESS(Result) )
573 {
574 SND_ERR(L"Failed to list sound device - error %d\n", Result);
575 return TranslateInternalMmResult(Result);
576 }
577
578 /* Set up our function table */
579 ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
580 FuncTable.GetCapabilities = GetWdmDeviceCapabilities;
581 FuncTable.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport;
582 if (DeviceType == MIXER_DEVICE_TYPE)
583 {
584 FuncTable.SetWaveFormat = SetWdmMixerDeviceFormat;
585 }
586 else
587 {
588 FuncTable.SetWaveFormat = SetWdmWaveDeviceFormat;
589 }
590
591 FuncTable.Open = OpenWdmSoundDevice;
592 FuncTable.Close = CloseWdmSoundDevice;
593 #ifndef USERMODE_MIXER
594 FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
595 #else
596 FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
597 #endif
598 FuncTable.GetPos = GetWdmPosition;
599
600 SetSoundDeviceFunctionTable(SoundDevice, &FuncTable);
601 }
602
603 return MMSYSERR_NOERROR;
604 }
605
606
607
608 LONG
609 APIENTRY
610 DriverProc(
611 DWORD DriverId,
612 HANDLE DriverHandle,
613 UINT Message,
614 LONG Parameter1,
615 LONG Parameter2)
616 {
617 MMRESULT Result;
618
619 switch ( Message )
620 {
621 case DRV_LOAD :
622 {
623 HANDLE Handle;
624 SND_TRACE(L"DRV_LOAD\n");
625
626 Result = InitEntrypointMutexes();
627
628 if ( ! MMSUCCESS(Result) )
629 return 0L;
630
631 OpenWdmSoundDevice(NULL, &Handle);
632
633 if ( Handle == INVALID_HANDLE_VALUE )
634 {
635 SND_ERR(L"Failed to open %s\n", KERNEL_DEVICE_NAME);
636 CleanupEntrypointMutexes();
637
638 //UnlistAllSoundDevices();
639
640 return 0L;
641 }
642
643 /* Populate the device lists */
644 SND_TRACE(L"Populating device lists\n");
645 PopulateWdmDeviceList(KernelHandle, WAVE_OUT_DEVICE_TYPE);
646 PopulateWdmDeviceList(KernelHandle, WAVE_IN_DEVICE_TYPE);
647 PopulateWdmDeviceList(KernelHandle, MIDI_OUT_DEVICE_TYPE);
648 PopulateWdmDeviceList(KernelHandle, MIDI_IN_DEVICE_TYPE);
649 PopulateWdmDeviceList(KernelHandle, AUX_DEVICE_TYPE);
650 PopulateWdmDeviceList(KernelHandle, MIXER_DEVICE_TYPE);
651
652 SND_TRACE(L"Initialisation complete\n");
653
654 return 1L;
655 }
656
657 case DRV_FREE :
658 {
659 SND_TRACE(L"DRV_FREE\n");
660
661 if ( KernelHandle != INVALID_HANDLE_VALUE )
662 {
663 CloseHandle(KernelHandle);
664 KernelHandle = INVALID_HANDLE_VALUE;
665 }
666
667 /* TODO: Clean up the path names! */
668 UnlistAllSoundDevices();
669
670 CleanupEntrypointMutexes();
671
672 SND_TRACE(L"Unfreed memory blocks: %d\n",
673 GetMemoryAllocationCount());
674
675 return 1L;
676 }
677
678 case DRV_ENABLE :
679 case DRV_DISABLE :
680 {
681 SND_TRACE(L"DRV_ENABLE / DRV_DISABLE\n");
682 return 1L;
683 }
684
685 case DRV_OPEN :
686 case DRV_CLOSE :
687 {
688 SND_TRACE(L"DRV_OPEN / DRV_CLOSE\n");
689 return 1L;
690 }
691
692 case DRV_QUERYCONFIGURE :
693 {
694 SND_TRACE(L"DRV_QUERYCONFIGURE\n");
695 return 0L;
696 }
697 case DRV_CONFIGURE :
698 return DRVCNF_OK;
699
700 default :
701 SND_TRACE(L"Unhandled message %d\n", Message);
702 return DefDriverProc(DriverId,
703 DriverHandle,
704 Message,
705 Parameter1,
706 Parameter2);
707 }
708 }
709
710
711 BOOL WINAPI DllMain(
712 HINSTANCE hinstDLL,
713 DWORD fdwReason,
714 LPVOID lpvReserved)
715 {
716 switch ( fdwReason )
717 {
718 case DLL_PROCESS_ATTACH :
719 SND_TRACE(L"WDMAUD.DRV - Process attached\n");
720 break;
721 case DLL_PROCESS_DETACH :
722 SND_TRACE(L"WDMAUD.DRV - Process detached\n");
723 break;
724 case DLL_THREAD_ATTACH :
725 SND_TRACE(L"WDMAUD.DRV - Thread attached\n");
726 break;
727 case DLL_THREAD_DETACH :
728 SND_TRACE(L"WDMAUD.DRV - Thread detached\n");
729 break;
730 }
731
732 return TRUE;
733 }