[FREELDR]
[reactos.git] / dll / win32 / wdmaud.drv / legacy.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 Johannes Anderwald
9 *
10 * NOTES: Looking for wodMessage & co? You won't find them here. Try
11 * the MME Buddy library, which is where these routines are
12 * actually implemented.
13 *
14 */
15
16 #include "wdmaud.h"
17
18 #include <stdio.h>
19
20 #define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud"
21
22 HANDLE KernelHandle = INVALID_HANDLE_VALUE;
23 DWORD OpenCount = 0;
24
25 DWORD
26 WINAPI
27 MixerEventThreadRoutine(
28 LPVOID Parameter)
29 {
30 HANDLE WaitObjects[2];
31 DWORD dwResult;
32 MMRESULT Result;
33 WDMAUD_DEVICE_INFO DeviceInfo;
34 PSOUND_DEVICE_INSTANCE Instance = (PSOUND_DEVICE_INSTANCE)Parameter;
35
36 /* setup wait objects */
37 WaitObjects[0] = Instance->hNotifyEvent;
38 WaitObjects[1] = Instance->hStopEvent;
39
40 /* zero device info */
41 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
42
43 DeviceInfo.hDevice = Instance->Handle;
44 DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
45
46 do
47 {
48 dwResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE);
49
50 if (dwResult == WAIT_OBJECT_0 + 1)
51 {
52 /* stop event was signalled */
53 break;
54 }
55
56 do
57 {
58 Result = SyncOverlappedDeviceIoControl(KernelHandle,
59 IOCTL_GET_MIXER_EVENT,
60 (LPVOID) &DeviceInfo,
61 sizeof(WDMAUD_DEVICE_INFO),
62 (LPVOID) &DeviceInfo,
63 sizeof(WDMAUD_DEVICE_INFO),
64 NULL);
65
66 if (Result == MMSYSERR_NOERROR)
67 {
68 DriverCallback(Instance->WinMM.ClientCallback,
69 HIWORD(Instance->WinMM.Flags),
70 Instance->WinMM.Handle,
71 DeviceInfo.u.MixerEvent.NotificationType,
72 Instance->WinMM.ClientCallbackInstanceData,
73 (DWORD_PTR)DeviceInfo.u.MixerEvent.Value,
74 0);
75 }
76 }while(Result == MMSYSERR_NOERROR);
77 }while(TRUE);
78
79 /* done */
80 return 0;
81 }
82
83 MMRESULT
84 WdmAudCleanupByLegacy()
85 {
86 if (KernelHandle != INVALID_HANDLE_VALUE)
87 {
88 CloseHandle(KernelHandle);
89 KernelHandle = INVALID_HANDLE_VALUE;
90 }
91
92 return MMSYSERR_NOERROR;
93 }
94
95 MMRESULT
96 WdmAudGetNumWdmDevsByLegacy(
97 IN MMDEVICE_TYPE DeviceType,
98 OUT DWORD* DeviceCount)
99 {
100 MMRESULT Result;
101 WDMAUD_DEVICE_INFO DeviceInfo;
102
103 VALIDATE_MMSYS_PARAMETER( KernelHandle != INVALID_HANDLE_VALUE );
104 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
105 VALIDATE_MMSYS_PARAMETER( DeviceCount );
106
107 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
108 DeviceInfo.DeviceType = DeviceType;
109
110 Result = SyncOverlappedDeviceIoControl(KernelHandle,
111 IOCTL_GETNUMDEVS_TYPE,
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 SND_ERR(L"Call to IOCTL_GETNUMDEVS_TYPE failed\n");
121 *DeviceCount = 0;
122 return TranslateInternalMmResult(Result);
123 }
124
125 *DeviceCount = DeviceInfo.DeviceCount;
126
127 return MMSYSERR_NOERROR;
128 }
129
130 MMRESULT
131 WdmAudGetCapabilitiesByLegacy(
132 IN PSOUND_DEVICE SoundDevice,
133 IN DWORD DeviceId,
134 OUT PVOID Capabilities,
135 IN DWORD CapabilitiesSize)
136 {
137 MMRESULT Result;
138 MMDEVICE_TYPE DeviceType;
139 WDMAUD_DEVICE_INFO DeviceInfo;
140
141 SND_ASSERT( SoundDevice );
142 SND_ASSERT( Capabilities );
143
144 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
145 SND_ASSERT( Result == MMSYSERR_NOERROR );
146
147 if ( ! MMSUCCESS(Result) )
148 return Result;
149
150 SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType, DeviceId);
151
152 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
153 DeviceInfo.DeviceType = DeviceType;
154 DeviceInfo.DeviceIndex = DeviceId;
155
156 Result = SyncOverlappedDeviceIoControl(KernelHandle,
157 IOCTL_GETCAPABILITIES,
158 (LPVOID) &DeviceInfo,
159 sizeof(WDMAUD_DEVICE_INFO),
160 (LPVOID) &DeviceInfo,
161 sizeof(WDMAUD_DEVICE_INFO),
162 NULL);
163
164 if ( ! MMSUCCESS(Result) )
165 {
166 return TranslateInternalMmResult(Result);
167 }
168
169 /* This is pretty much a big hack right now */
170 switch ( DeviceType )
171 {
172 case MIXER_DEVICE_TYPE:
173 {
174 LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
175
176 DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
177 CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname);
178
179 MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations;
180 MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport;
181 MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion;
182 MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid;
183 MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid;
184 break;
185 }
186 case WAVE_OUT_DEVICE_TYPE :
187 {
188 LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
189
190 DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
191 WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
192 WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
193
194 WaveOutCaps->vDriverVersion = 0x0001;
195 CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
196
197 WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
198 WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
199 WaveOutCaps->dwSupport = DeviceInfo.u.WaveOutCaps.dwSupport;
200 break;
201 }
202 case WAVE_IN_DEVICE_TYPE :
203 {
204 LPWAVEINCAPSW WaveInCaps = (LPWAVEINCAPSW) Capabilities;
205
206 DeviceInfo.u.WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0';
207
208 WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid;
209 WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid;
210
211 WaveInCaps->vDriverVersion = 0x0001;
212 CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname);
213
214 WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats;
215 WaveInCaps->wChannels = DeviceInfo.u.WaveInCaps.wChannels;
216 WaveInCaps->wReserved1 = 0;
217 break;
218 }
219 }
220
221 return MMSYSERR_NOERROR;
222 }
223
224 MMRESULT
225 WdmAudOpenSoundDeviceByLegacy()
226 {
227 /* Only open this if it's not already open */
228 if ( KernelHandle == INVALID_HANDLE_VALUE )
229 {
230 SND_TRACE(L"Opening wdmaud device\n");
231 KernelHandle = CreateFileW(KERNEL_DEVICE_NAME,
232 GENERIC_READ | GENERIC_WRITE,
233 0,
234 NULL,
235 OPEN_EXISTING,
236 FILE_FLAG_OVERLAPPED,
237 NULL);
238 }
239
240 if ( KernelHandle == INVALID_HANDLE_VALUE )
241 return MMSYSERR_ERROR;
242
243 ++ OpenCount;
244
245 return MMSYSERR_NOERROR;
246 }
247
248 MMRESULT
249 WdmAudCloseSoundDeviceByLegacy(
250 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
251 IN PVOID Handle)
252 {
253 WDMAUD_DEVICE_INFO DeviceInfo;
254 MMRESULT Result;
255 MMDEVICE_TYPE DeviceType;
256 PSOUND_DEVICE SoundDevice;
257
258 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
259
260 if ( ! MMSUCCESS(Result) )
261 {
262 return TranslateInternalMmResult(Result);
263 }
264
265 if ( OpenCount == 0 )
266 {
267 return MMSYSERR_NOERROR;
268 }
269
270 SND_ASSERT( KernelHandle != INVALID_HANDLE_VALUE );
271
272 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
273 SND_ASSERT( Result == MMSYSERR_NOERROR );
274
275 if (SoundDeviceInstance->Handle != (PVOID)KernelHandle)
276 {
277 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
278
279 DeviceInfo.DeviceType = DeviceType;
280 DeviceInfo.hDevice = SoundDeviceInstance->Handle;
281
282 /* First stop the stream */
283 if (DeviceType != MIXER_DEVICE_TYPE)
284 {
285 DeviceInfo.u.State = KSSTATE_PAUSE;
286 SyncOverlappedDeviceIoControl(KernelHandle,
287 IOCTL_SETDEVICE_STATE,
288 (LPVOID) &DeviceInfo,
289 sizeof(WDMAUD_DEVICE_INFO),
290 (LPVOID) &DeviceInfo,
291 sizeof(WDMAUD_DEVICE_INFO),
292 NULL);
293
294 DeviceInfo.u.State = KSSTATE_ACQUIRE;
295 SyncOverlappedDeviceIoControl(KernelHandle,
296 IOCTL_SETDEVICE_STATE,
297 (LPVOID) &DeviceInfo,
298 sizeof(WDMAUD_DEVICE_INFO),
299 (LPVOID) &DeviceInfo,
300 sizeof(WDMAUD_DEVICE_INFO),
301 NULL);
302
303
304 DeviceInfo.u.State = KSSTATE_STOP;
305 SyncOverlappedDeviceIoControl(KernelHandle,
306 IOCTL_SETDEVICE_STATE,
307 (LPVOID) &DeviceInfo,
308 sizeof(WDMAUD_DEVICE_INFO),
309 (LPVOID) &DeviceInfo,
310 sizeof(WDMAUD_DEVICE_INFO),
311 NULL);
312 }
313
314 SyncOverlappedDeviceIoControl(KernelHandle,
315 IOCTL_CLOSE_WDMAUD,
316 (LPVOID) &DeviceInfo,
317 sizeof(WDMAUD_DEVICE_INFO),
318 (LPVOID) &DeviceInfo,
319 sizeof(WDMAUD_DEVICE_INFO),
320 NULL);
321 }
322
323 if (DeviceType == MIXER_DEVICE_TYPE)
324 {
325 SetEvent(SoundDeviceInstance->hStopEvent);
326 CloseHandle(SoundDeviceInstance->hStopEvent);
327 CloseHandle(SoundDeviceInstance->hNotifyEvent);
328 }
329
330 --OpenCount;
331
332 if ( OpenCount < 1 )
333 {
334 CloseHandle(KernelHandle);
335 KernelHandle = INVALID_HANDLE_VALUE;
336 }
337
338 return MMSYSERR_NOERROR;
339 }
340
341 MMRESULT
342 WdmAudSetMixerDeviceFormatByLegacy(
343 IN PSOUND_DEVICE_INSTANCE Instance,
344 IN DWORD DeviceId,
345 IN PWAVEFORMATEX WaveFormat,
346 IN DWORD WaveFormatSize)
347 {
348 MMRESULT Result;
349 WDMAUD_DEVICE_INFO DeviceInfo;
350 HANDLE hThread;
351
352 Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
353 if ( ! Instance->hNotifyEvent )
354 return MMSYSERR_NOMEM;
355
356 if (Instance->Handle != NULL)
357 {
358 /* device is already open */
359 return MMSYSERR_NOERROR;
360 }
361
362 Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
363 if ( ! Instance->hStopEvent )
364 return MMSYSERR_NOMEM;
365
366 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
367 DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
368 DeviceInfo.DeviceIndex = DeviceId;
369 DeviceInfo.u.hNotifyEvent = Instance->hNotifyEvent;
370
371 Result = SyncOverlappedDeviceIoControl(KernelHandle,
372 IOCTL_OPEN_WDMAUD,
373 (LPVOID) &DeviceInfo,
374 sizeof(WDMAUD_DEVICE_INFO),
375 (LPVOID) &DeviceInfo,
376 sizeof(WDMAUD_DEVICE_INFO),
377 NULL);
378
379 if ( ! MMSUCCESS(Result) )
380 {
381 CloseHandle(Instance->hNotifyEvent);
382 CloseHandle(Instance->hStopEvent);
383 return TranslateInternalMmResult(Result);
384 }
385
386 hThread = CreateThread(NULL, 0, MixerEventThreadRoutine, (LPVOID)Instance, 0, NULL);
387 if ( hThread )
388 {
389 CloseHandle(hThread);
390 }
391
392 /* Store sound device handle instance handle */
393 Instance->Handle = (PVOID)DeviceInfo.hDevice;
394
395 return MMSYSERR_NOERROR;
396 }
397
398 MMRESULT
399 WdmAudSetWaveDeviceFormatByLegacy(
400 IN PSOUND_DEVICE_INSTANCE Instance,
401 IN DWORD DeviceId,
402 IN PWAVEFORMATEX WaveFormat,
403 IN DWORD WaveFormatSize)
404 {
405 MMRESULT Result;
406 PSOUND_DEVICE SoundDevice;
407 PVOID Identifier;
408 WDMAUD_DEVICE_INFO DeviceInfo;
409 MMDEVICE_TYPE DeviceType;
410
411 Result = GetSoundDeviceFromInstance(Instance, &SoundDevice);
412
413 if ( ! MMSUCCESS(Result) )
414 {
415 return TranslateInternalMmResult(Result);
416 }
417
418 Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier);
419
420 if ( ! MMSUCCESS(Result) )
421 {
422 return TranslateInternalMmResult(Result);
423 }
424
425 if (Instance->Handle != NULL)
426 {
427 /* device is already open */
428 return MMSYSERR_NOERROR;
429 }
430
431 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
432
433 SND_ASSERT( Result == MMSYSERR_NOERROR );
434
435 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
436 DeviceInfo.DeviceType = DeviceType;
437 DeviceInfo.DeviceIndex = DeviceId;
438 DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize;
439 DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
440 #ifdef USERMODE_MIXER
441 DeviceInfo.u.WaveFormatEx.nChannels = 2;
442 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100;
443 DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
444 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400;
445 DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
446 #else
447 DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels;
448 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
449 DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
450 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
451 DeviceInfo.u.WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
452 #endif
453
454 Result = SyncOverlappedDeviceIoControl(KernelHandle,
455 IOCTL_OPEN_WDMAUD,
456 (LPVOID) &DeviceInfo,
457 sizeof(WDMAUD_DEVICE_INFO),
458 (LPVOID) &DeviceInfo,
459 sizeof(WDMAUD_DEVICE_INFO),
460 NULL);
461
462 if ( ! MMSUCCESS(Result) )
463 {
464 return TranslateInternalMmResult(Result);
465 }
466
467 /* Store format */
468 Instance->WaveFormatEx.cbSize = WaveFormat->cbSize;
469 Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
470 Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
471 Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
472 Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
473 Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
474 Instance->WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
475
476 /* Store sound device handle instance handle */
477 Instance->Handle = (PVOID)DeviceInfo.hDevice;
478
479 /* Now determine framing requirements */
480 Result = SyncOverlappedDeviceIoControl(KernelHandle,
481 IOCTL_GETFRAMESIZE,
482 (LPVOID) &DeviceInfo,
483 sizeof(WDMAUD_DEVICE_INFO),
484 (LPVOID) &DeviceInfo,
485 sizeof(WDMAUD_DEVICE_INFO),
486 NULL);
487
488 if ( MMSUCCESS(Result) )
489 {
490 if (DeviceInfo.u.FrameSize)
491 {
492 Instance->FrameSize = DeviceInfo.u.FrameSize * 2;
493 Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize;
494 SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount);
495 }
496 }
497 else
498 {
499 // use a default of 100 buffers
500 Instance->BufferCount = 100;
501 }
502
503 if (DeviceType == WAVE_OUT_DEVICE_TYPE)
504 {
505 /* Now start the stream */
506 DeviceInfo.u.State = KSSTATE_RUN;
507 SyncOverlappedDeviceIoControl(KernelHandle,
508 IOCTL_SETDEVICE_STATE,
509 (LPVOID) &DeviceInfo,
510 sizeof(WDMAUD_DEVICE_INFO),
511 (LPVOID) &DeviceInfo,
512 sizeof(WDMAUD_DEVICE_INFO),
513 NULL);
514 }
515
516 return MMSYSERR_NOERROR;
517 }
518
519 MMRESULT
520 WdmAudCommitWaveBufferByLegacy(
521 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
522 IN PVOID OffsetPtr,
523 IN DWORD Length,
524 IN PSOUND_OVERLAPPED Overlap,
525 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
526 {
527 HANDLE Handle;
528 MMRESULT Result;
529 WDMAUD_DEVICE_INFO DeviceInfo;
530 PSOUND_DEVICE SoundDevice;
531 MMDEVICE_TYPE DeviceType;
532 BOOL Ret;
533
534 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
535 VALIDATE_MMSYS_PARAMETER( OffsetPtr );
536 VALIDATE_MMSYS_PARAMETER( Overlap );
537 VALIDATE_MMSYS_PARAMETER( CompletionRoutine );
538
539 GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
540 SND_ASSERT(Handle);
541
542 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
543
544 if ( ! MMSUCCESS(Result) )
545 {
546 return TranslateInternalMmResult(Result);
547 }
548
549 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
550 SND_ASSERT( Result == MMSYSERR_NOERROR );
551
552 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
553
554 DeviceInfo.Header.FrameExtent = Length;
555 if (DeviceType == WAVE_OUT_DEVICE_TYPE)
556 {
557 DeviceInfo.Header.DataUsed = Length;
558 }
559 DeviceInfo.Header.Data = OffsetPtr;
560 DeviceInfo.Header.Size = sizeof(WDMAUD_DEVICE_INFO);
561 DeviceInfo.Header.PresentationTime.Numerator = 1;
562 DeviceInfo.Header.PresentationTime.Denominator = 1;
563 DeviceInfo.hDevice = Handle;
564 DeviceInfo.DeviceType = DeviceType;
565
566
567
568 Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
569
570 if (DeviceType == WAVE_OUT_DEVICE_TYPE)
571 {
572 Ret = WriteFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
573 if (Ret)
574 WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
575 }
576 else if (DeviceType == WAVE_IN_DEVICE_TYPE)
577 {
578 Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
579 //if (Ret)
580 // WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
581 }
582
583 return MMSYSERR_NOERROR;
584 }
585
586
587
588 MMRESULT
589 WdmAudSetWaveStateByLegacy(
590 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
591 IN BOOL bStart)
592 {
593 MMRESULT Result;
594 PSOUND_DEVICE SoundDevice;
595 WDMAUD_DEVICE_INFO DeviceInfo;
596 MMDEVICE_TYPE DeviceType;
597 HANDLE Handle;
598
599 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
600
601 if ( ! MMSUCCESS(Result) )
602 {
603 return TranslateInternalMmResult(Result);
604 }
605
606 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
607 SND_ASSERT( Result == MMSYSERR_NOERROR );
608
609 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
610 SND_ASSERT( Result == MMSYSERR_NOERROR );
611
612 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
613 DeviceInfo.hDevice = Handle;
614 DeviceInfo.DeviceType = DeviceType;
615
616 if (bStart)
617 DeviceInfo.u.State = KSSTATE_RUN;
618 else
619 DeviceInfo.u.State = KSSTATE_PAUSE;
620 Result = SyncOverlappedDeviceIoControl(KernelHandle,
621 IOCTL_SETDEVICE_STATE,
622 (LPVOID) &DeviceInfo,
623 sizeof(WDMAUD_DEVICE_INFO),
624 (LPVOID) &DeviceInfo,
625 sizeof(WDMAUD_DEVICE_INFO),
626 NULL);
627
628 return Result;
629 }
630
631 MMRESULT
632 WdmAudGetDeviceInterfaceStringByLegacy(
633 IN MMDEVICE_TYPE DeviceType,
634 IN DWORD DeviceId,
635 IN LPWSTR Interface,
636 IN DWORD InterfaceLength,
637 OUT DWORD * InterfaceSize)
638 {
639 WDMAUD_DEVICE_INFO DeviceInfo;
640 MMRESULT Result;
641
642 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
643 DeviceInfo.DeviceType = DeviceType;
644 DeviceInfo.DeviceIndex = DeviceId;
645
646
647 Result = SyncOverlappedDeviceIoControl(KernelHandle,
648 IOCTL_QUERYDEVICEINTERFACESTRING,
649 (LPVOID) &DeviceInfo,
650 sizeof(WDMAUD_DEVICE_INFO),
651 (LPVOID) &DeviceInfo,
652 sizeof(WDMAUD_DEVICE_INFO),
653 NULL);
654
655
656 if ( ! MMSUCCESS(Result) )
657 {
658 return TranslateInternalMmResult(Result);
659 }
660
661
662 if (!Interface)
663 {
664 SND_ASSERT(InterfaceSize);
665
666 *InterfaceSize = DeviceInfo.u.Interface.DeviceInterfaceStringSize;
667 return MMSYSERR_NOERROR;
668 }
669
670 if (InterfaceLength < DeviceInfo.u.Interface.DeviceInterfaceStringSize)
671 {
672 /* buffer is too small */
673 return MMSYSERR_MOREDATA;
674 }
675
676 DeviceInfo.u.Interface.DeviceInterfaceStringSize = InterfaceLength;
677 DeviceInfo.u.Interface.DeviceInterfaceString = Interface;
678
679 Result = SyncOverlappedDeviceIoControl(KernelHandle,
680 IOCTL_QUERYDEVICEINTERFACESTRING,
681 (LPVOID) &DeviceInfo,
682 sizeof(WDMAUD_DEVICE_INFO),
683 (LPVOID) &DeviceInfo,
684 sizeof(WDMAUD_DEVICE_INFO),
685 NULL);
686
687 if ( MMSUCCESS(Result) && InterfaceLength > 2)
688 {
689 Interface[1] = L'\\';
690 Interface[InterfaceLength-1] = L'\0';
691 }
692
693 return Result;
694 }
695
696 MMRESULT
697 WdmAudGetWavePositionByLegacy(
698 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
699 IN MMTIME* Time)
700 {
701 MMRESULT Result;
702 PSOUND_DEVICE SoundDevice;
703 WDMAUD_DEVICE_INFO DeviceInfo;
704 MMDEVICE_TYPE DeviceType;
705 HANDLE Handle;
706
707 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
708
709 if ( ! MMSUCCESS(Result) )
710 {
711 return TranslateInternalMmResult(Result);
712 }
713
714 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
715 SND_ASSERT( Result == MMSYSERR_NOERROR );
716
717 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
718 SND_ASSERT( Result == MMSYSERR_NOERROR );
719
720 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
721 DeviceInfo.hDevice = Handle;
722 DeviceInfo.DeviceType = DeviceType;
723
724 Result = SyncOverlappedDeviceIoControl(KernelHandle,
725 IOCTL_OPEN_WDMAUD,
726 (LPVOID) &DeviceInfo,
727 sizeof(WDMAUD_DEVICE_INFO),
728 (LPVOID) &DeviceInfo,
729 sizeof(WDMAUD_DEVICE_INFO),
730 NULL);
731
732 if ( ! MMSUCCESS(Result) )
733 {
734 return TranslateInternalMmResult(Result);
735 }
736
737 Time->wType = TIME_BYTES;
738 Time->u.cb = (DWORD)DeviceInfo.u.Position;
739
740 return MMSYSERR_NOERROR;
741 }
742
743
744 MMRESULT
745 WdmAudResetStreamByLegacy(
746 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
747 IN MMDEVICE_TYPE DeviceType,
748 IN BOOLEAN bStartReset)
749 {
750 MMRESULT Result;
751 HANDLE Handle;
752 WDMAUD_DEVICE_INFO DeviceInfo;
753
754 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
755 SND_ASSERT( Result == MMSYSERR_NOERROR );
756
757 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
758 DeviceInfo.hDevice = Handle;
759 DeviceInfo.DeviceType = DeviceType;
760 DeviceInfo.u.ResetStream = (bStartReset ? KSRESET_BEGIN : KSRESET_END);
761
762 Result = SyncOverlappedDeviceIoControl(KernelHandle,
763 IOCTL_RESET_STREAM,
764 (LPVOID) &DeviceInfo,
765 sizeof(WDMAUD_DEVICE_INFO),
766 (LPVOID) &DeviceInfo,
767 sizeof(WDMAUD_DEVICE_INFO),
768 NULL);
769 return Result;
770 }
771
772 MMRESULT
773 WdmAudQueryMixerInfoByLegacy(
774 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
775 IN UINT uMsg,
776 IN LPVOID Parameter,
777 IN DWORD Flags)
778 {
779 MMRESULT Result;
780 WDMAUD_DEVICE_INFO DeviceInfo;
781 HANDLE Handle;
782 DWORD IoControlCode;
783 LPMIXERLINEW MixLine;
784 LPMIXERLINECONTROLSW MixControls;
785 LPMIXERCONTROLDETAILS MixDetails;
786
787 SND_TRACE(L"uMsg %x Flags %x\n", uMsg, Flags);
788
789 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
790 SND_ASSERT( Result == MMSYSERR_NOERROR );
791
792 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
793 DeviceInfo.hDevice = Handle;
794 DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
795 DeviceInfo.Flags = Flags;
796
797 MixLine = (LPMIXERLINEW)Parameter;
798 MixControls = (LPMIXERLINECONTROLSW)Parameter;
799 MixDetails = (LPMIXERCONTROLDETAILS)Parameter;
800
801 switch(uMsg)
802 {
803 case MXDM_GETLINEINFO:
804 RtlCopyMemory(&DeviceInfo.u.MixLine, MixLine, sizeof(MIXERLINEW));
805 IoControlCode = IOCTL_GETLINEINFO;
806 break;
807 case MXDM_GETLINECONTROLS:
808 RtlCopyMemory(&DeviceInfo.u.MixControls, MixControls, sizeof(MIXERLINECONTROLSW));
809 IoControlCode = IOCTL_GETLINECONTROLS;
810 break;
811 case MXDM_SETCONTROLDETAILS:
812 RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
813 IoControlCode = IOCTL_SETCONTROLDETAILS;
814 break;
815 case MXDM_GETCONTROLDETAILS:
816 RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
817 IoControlCode = IOCTL_GETCONTROLDETAILS;
818 break;
819 default:
820 SND_ASSERT(0);
821 return MMSYSERR_NOTSUPPORTED;
822 }
823
824 Result = SyncOverlappedDeviceIoControl(KernelHandle,
825 IoControlCode,
826 (LPVOID) &DeviceInfo,
827 sizeof(WDMAUD_DEVICE_INFO),
828 (LPVOID) &DeviceInfo,
829 sizeof(WDMAUD_DEVICE_INFO),
830 NULL);
831
832 if ( ! MMSUCCESS(Result) )
833 {
834 return Result;
835 }
836
837 switch(uMsg)
838 {
839 case MXDM_GETLINEINFO:
840 {
841 RtlCopyMemory(MixLine, &DeviceInfo.u.MixLine, sizeof(MIXERLINEW));
842 break;
843 }
844 }
845
846 return Result;
847 }