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