Chinese translations of NTVDM by Samuel Lee. Bug #5087.
[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 DWORD OpenCount = 0;
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 MMRESULT
565 WdmAudSetWaveStateByLegacy(
566 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
567 IN BOOL bStart)
568 {
569 MMRESULT Result;
570 PSOUND_DEVICE SoundDevice;
571 WDMAUD_DEVICE_INFO DeviceInfo;
572 MMDEVICE_TYPE DeviceType;
573 HANDLE Handle;
574
575 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
576
577 if ( ! MMSUCCESS(Result) )
578 {
579 return TranslateInternalMmResult(Result);
580 }
581
582 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
583 SND_ASSERT( Result == MMSYSERR_NOERROR );
584
585 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
586 SND_ASSERT( Result == MMSYSERR_NOERROR );
587
588 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
589 DeviceInfo.hDevice = Handle;
590 DeviceInfo.DeviceType = DeviceType;
591
592 if (bStart)
593 DeviceInfo.u.State = KSSTATE_RUN;
594 else
595 DeviceInfo.u.State = KSSTATE_PAUSE;
596 Result = SyncOverlappedDeviceIoControl(KernelHandle,
597 IOCTL_SETDEVICE_STATE,
598 (LPVOID) &DeviceInfo,
599 sizeof(WDMAUD_DEVICE_INFO),
600 (LPVOID) &DeviceInfo,
601 sizeof(WDMAUD_DEVICE_INFO),
602 NULL);
603
604 return Result;
605 }
606
607 MMRESULT
608 WdmAudGetDeviceInterfaceStringByLegacy(
609 IN MMDEVICE_TYPE DeviceType,
610 IN DWORD DeviceId,
611 IN LPWSTR Interface,
612 IN DWORD InterfaceLength,
613 OUT DWORD * InterfaceSize)
614 {
615 WDMAUD_DEVICE_INFO DeviceInfo;
616 MMRESULT Result;
617
618 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
619 DeviceInfo.DeviceType = DeviceType;
620 DeviceInfo.DeviceIndex = DeviceId;
621
622
623 Result = SyncOverlappedDeviceIoControl(KernelHandle,
624 IOCTL_QUERYDEVICEINTERFACESTRING,
625 (LPVOID) &DeviceInfo,
626 sizeof(WDMAUD_DEVICE_INFO),
627 (LPVOID) &DeviceInfo,
628 sizeof(WDMAUD_DEVICE_INFO),
629 NULL);
630
631
632 if ( ! MMSUCCESS(Result) )
633 {
634 return TranslateInternalMmResult(Result);
635 }
636
637
638 if (!Interface)
639 {
640 SND_ASSERT(InterfaceSize);
641
642 *InterfaceSize = DeviceInfo.u.Interface.DeviceInterfaceStringSize;
643 return MMSYSERR_NOERROR;
644 }
645
646 if (InterfaceLength < DeviceInfo.u.Interface.DeviceInterfaceStringSize)
647 {
648 /* buffer is too small */
649 return MMSYSERR_MOREDATA;
650 }
651
652 DeviceInfo.u.Interface.DeviceInterfaceStringSize = InterfaceLength;
653 DeviceInfo.u.Interface.DeviceInterfaceString = Interface;
654
655 Result = SyncOverlappedDeviceIoControl(KernelHandle,
656 IOCTL_QUERYDEVICEINTERFACESTRING,
657 (LPVOID) &DeviceInfo,
658 sizeof(WDMAUD_DEVICE_INFO),
659 (LPVOID) &DeviceInfo,
660 sizeof(WDMAUD_DEVICE_INFO),
661 NULL);
662
663 if ( MMSUCCESS(Result) && InterfaceLength > 2)
664 {
665 Interface[1] = L'\\';
666 Interface[InterfaceLength-1] = L'\0';
667 }
668
669 return Result;
670 }
671
672 MMRESULT
673 WdmAudGetWavePositionByLegacy(
674 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
675 IN MMTIME* Time)
676 {
677 MMRESULT Result;
678 PSOUND_DEVICE SoundDevice;
679 WDMAUD_DEVICE_INFO DeviceInfo;
680 MMDEVICE_TYPE DeviceType;
681 HANDLE Handle;
682
683 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
684
685 if ( ! MMSUCCESS(Result) )
686 {
687 return TranslateInternalMmResult(Result);
688 }
689
690 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
691 SND_ASSERT( Result == MMSYSERR_NOERROR );
692
693 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
694 SND_ASSERT( Result == MMSYSERR_NOERROR );
695
696 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
697 DeviceInfo.hDevice = Handle;
698 DeviceInfo.DeviceType = DeviceType;
699
700 Result = SyncOverlappedDeviceIoControl(KernelHandle,
701 IOCTL_OPEN_WDMAUD,
702 (LPVOID) &DeviceInfo,
703 sizeof(WDMAUD_DEVICE_INFO),
704 (LPVOID) &DeviceInfo,
705 sizeof(WDMAUD_DEVICE_INFO),
706 NULL);
707
708 if ( ! MMSUCCESS(Result) )
709 {
710 return TranslateInternalMmResult(Result);
711 }
712
713 Time->wType = TIME_BYTES;
714 Time->u.cb = (DWORD)DeviceInfo.u.Position;
715
716 return MMSYSERR_NOERROR;
717 }
718
719
720 MMRESULT
721 WdmAudResetStreamByLegacy(
722 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
723 IN MMDEVICE_TYPE DeviceType,
724 IN BOOLEAN bStartReset)
725 {
726 MMRESULT Result;
727 HANDLE Handle;
728 WDMAUD_DEVICE_INFO DeviceInfo;
729
730 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
731 SND_ASSERT( Result == MMSYSERR_NOERROR );
732
733 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
734 DeviceInfo.hDevice = Handle;
735 DeviceInfo.DeviceType = DeviceType;
736 DeviceInfo.u.ResetStream = (bStartReset ? KSRESET_BEGIN : KSRESET_END);
737
738 Result = SyncOverlappedDeviceIoControl(KernelHandle,
739 IOCTL_RESET_STREAM,
740 (LPVOID) &DeviceInfo,
741 sizeof(WDMAUD_DEVICE_INFO),
742 (LPVOID) &DeviceInfo,
743 sizeof(WDMAUD_DEVICE_INFO),
744 NULL);
745 return Result;
746 }
747
748 MMRESULT
749 WdmAudQueryMixerInfoByLegacy(
750 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
751 IN UINT uMsg,
752 IN LPVOID Parameter,
753 IN DWORD Flags)
754 {
755 MMRESULT Result;
756 WDMAUD_DEVICE_INFO DeviceInfo;
757 HANDLE Handle;
758 DWORD IoControlCode;
759 LPMIXERLINEW MixLine;
760 LPMIXERLINECONTROLSW MixControls;
761 LPMIXERCONTROLDETAILS MixDetails;
762
763 SND_TRACE(L"uMsg %x Flags %x\n", uMsg, Flags);
764
765 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
766 SND_ASSERT( Result == MMSYSERR_NOERROR );
767
768 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
769 DeviceInfo.hDevice = Handle;
770 DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
771 DeviceInfo.Flags = Flags;
772
773 MixLine = (LPMIXERLINEW)Parameter;
774 MixControls = (LPMIXERLINECONTROLSW)Parameter;
775 MixDetails = (LPMIXERCONTROLDETAILS)Parameter;
776
777 switch(uMsg)
778 {
779 case MXDM_GETLINEINFO:
780 RtlCopyMemory(&DeviceInfo.u.MixLine, MixLine, sizeof(MIXERLINEW));
781 IoControlCode = IOCTL_GETLINEINFO;
782 break;
783 case MXDM_GETLINECONTROLS:
784 RtlCopyMemory(&DeviceInfo.u.MixControls, MixControls, sizeof(MIXERLINECONTROLSW));
785 IoControlCode = IOCTL_GETLINECONTROLS;
786 break;
787 case MXDM_SETCONTROLDETAILS:
788 RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
789 IoControlCode = IOCTL_SETCONTROLDETAILS;
790 break;
791 case MXDM_GETCONTROLDETAILS:
792 RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS));
793 IoControlCode = IOCTL_GETCONTROLDETAILS;
794 break;
795 default:
796 SND_ASSERT(0);
797 return MMSYSERR_NOTSUPPORTED;
798 }
799
800 Result = SyncOverlappedDeviceIoControl(KernelHandle,
801 IoControlCode,
802 (LPVOID) &DeviceInfo,
803 sizeof(WDMAUD_DEVICE_INFO),
804 (LPVOID) &DeviceInfo,
805 sizeof(WDMAUD_DEVICE_INFO),
806 NULL);
807
808 if ( ! MMSUCCESS(Result) )
809 {
810 return Result;
811 }
812
813 switch(uMsg)
814 {
815 case MXDM_GETLINEINFO:
816 {
817 RtlCopyMemory(MixLine, &DeviceInfo.u.MixLine, sizeof(MIXERLINEW));
818 break;
819 }
820 }
821
822 return Result;
823 }