1 /*
2  * PROJECT:     ReactOS Sound System "MME Buddy" Library
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        include/reactos/libs/sound/mmebuddy.h
5  *
6  * PURPOSE:     Header for the "MME Buddy" helper library (located in
7  *              lib/drivers/sound/mmebuddy)
8  *
9  * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
10  *
11  * HISTORY:     4 July 2008 - Created
12  *              31 Dec 2008 - Split off NT4-specific code into a separate library
13  *
14  * NOTES:       MME Buddy was the best name I could come up with...
15  *              The structures etc. here should be treated as internal to the
16  *              library so should not be directly accessed elsewhere. Perhaps they
17  *              can be moved to an internal header?
18 */
19 
20 #ifndef ROS_AUDIO_MMEBUDDY_H
21 #define ROS_AUDIO_MMEBUDDY_H
22 
23 /*
24     Some memory allocation helper macros
25 */
26 
27 #define AllocateStruct(thing) \
28     (thing*) AllocateMemory(sizeof(thing))
29 
30 #define StringLengthToBytes(chartype, string_length) \
31     ( ( string_length + 1 ) * sizeof(chartype) )
32 
33 #define AllocateWideString(string_length) \
34     (PWSTR) AllocateMemory(StringLengthToBytes(WCHAR, string_length))
35 
36 #define ZeroWideString(string) \
37     ZeroMemory(string, StringLengthToBytes(WCHAR, wcslen(string)))
38 
39 #define CopyWideString(dest, source) \
40     CopyMemory(dest, source, StringLengthToBytes(WCHAR, wcslen(source)))
41 
42 
43 /*
44     Helps find the minimum/maximum of two values
45 */
46 
47 #define MinimumOf(value_a, value_b) \
48     ( value_a < value_b ? value_a : value_b )
49 
50 #define MaximumOf(value_a, value_b) \
51     ( value_a > value_b ? value_a : value_b )
52 
53 
54 /*
55     Convert a device type into a zero-based array index
56 */
57 
58 #define SOUND_DEVICE_TYPE_TO_INDEX(x) \
59     ( x - MIN_SOUND_DEVICE_TYPE )
60 
61 #define INDEX_TO_SOUND_DEVICE_TYPE(x) \
62     ( x + MIN_SOUND_DEVICE_TYPE )
63 
64 
65 /*
66     Validation
67 */
68 
69 #define IsValidSoundDeviceType IS_VALID_SOUND_DEVICE_TYPE
70 
71 #define VALIDATE_MMSYS_PARAMETER(parameter_condition) \
72     { \
73         if ( ! (parameter_condition) ) \
74         { \
75             SND_ERR(L"FAILED parameter check: %hS at File %S Line %lu\n", #parameter_condition, __FILE__, __LINE__); \
76             return MMSYSERR_INVALPARAM; \
77         } \
78     }
79 
80 #define MMSUCCESS(result) \
81     ( result == MMSYSERR_NOERROR )
82 
83 
84 /*
85     Types and Structures
86 */
87 
88 typedef UCHAR MMDEVICE_TYPE, *PMMDEVICE_TYPE;
89 struct _SOUND_DEVICE;
90 struct _SOUND_DEVICE_INSTANCE;
91 
92 
93 #define DEFINE_GETCAPS_FUNCTYPE(func_typename, caps_type) \
94     typedef MMRESULT (*func_typename)( \
95         IN  struct _SOUND_DEVICE* SoundDevice, \
96         IN  DWORD DeviceId, \
97         OUT caps_type Capabilities, \
98         IN  DWORD CapabilitiesSize);
99 
100 /* This one is for those of us who don't care */
101 DEFINE_GETCAPS_FUNCTYPE(MMGETCAPS_FUNC, PVOID);
102 
103 /* These are for those of us that do */
104 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEOUTCAPS_FUNC, LPWAVEOUTCAPS);
105 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEINCAPS_FUNC,  LPWAVEINCAPS );
106 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIOUTCAPS_FUNC, LPMIDIOUTCAPS);
107 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIINCAPS_FUNC,  LPMIDIINCAPS );
108 
109 struct _SOUND_DEVICE;
110 struct _SOUND_DEVICE_INSTANCE;
111 
112 
113 /*
114     By extending the OVERLAPPED structure, it becomes possible to provide the
115     I/O completion routines with additional information.
116 */
117 
118 typedef struct _SOUND_OVERLAPPED
119 {
120     OVERLAPPED Standard;
121     struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
122     PWAVEHDR Header;
123 
124     LPOVERLAPPED_COMPLETION_ROUTINE OriginalCompletionRoutine;
125     PVOID CompletionContext;
126 
127 } SOUND_OVERLAPPED, *PSOUND_OVERLAPPED;
128 
129 typedef MMRESULT (*WAVE_COMMIT_FUNC)(
130     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
131     IN  PVOID OffsetPtr,
132     IN  DWORD Bytes,
133     IN  PSOUND_OVERLAPPED Overlap,
134     IN  LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine);
135 
136 typedef MMRESULT (*MMMIXERQUERY_FUNC) (
137     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
138     IN DWORD DeviceId,
139     IN UINT uMsg,
140     IN LPVOID Parameter,
141     IN DWORD Flags);
142 
143 typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC)(
144     IN  struct _SOUND_DEVICE* Device,
145     IN  PWAVEFORMATEX WaveFormat,
146     IN  DWORD WaveFormatSize);
147 
148 typedef MMRESULT (*MMWAVESETFORMAT_FUNC)(
149     IN  struct _SOUND_DEVICE_INSTANCE* Instance,
150     IN  DWORD DeviceId,
151     IN  PWAVEFORMATEX WaveFormat,
152     IN  DWORD WaveFormatSize);
153 
154 typedef MMRESULT (*MMOPEN_FUNC)(
155     IN  struct _SOUND_DEVICE* SoundDevice,
156     OUT PVOID* Handle);
157 
158 typedef MMRESULT (*MMCLOSE_FUNC)(
159     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
160     IN  PVOID Handle);  /* not sure about this */
161 
162 typedef MMRESULT (*MMWAVEHEADER_FUNC)(
163     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
164     IN  PWAVEHDR WaveHeader);
165 
166 typedef MMRESULT (*MMBUFFER_FUNC)(
167     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
168     IN  PVOID Buffer,
169     IN  DWORD Length);
170 
171 typedef MMRESULT(*MMGETPOS_FUNC)(
172     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
173     IN  MMTIME* Time);
174 
175 
176 typedef MMRESULT(*MMSETSTATE_FUNC)(
177     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
178     IN  BOOL bStart);
179 
180 
181 typedef MMRESULT(*MMQUERYDEVICEINTERFACESTRING_FUNC)(
182     IN  MMDEVICE_TYPE DeviceType,
183     IN  DWORD DeviceId,
184     IN  LPWSTR Interface,
185     IN  DWORD  InterfaceLength,
186     OUT  DWORD * InterfaceSize);
187 
188 typedef MMRESULT(*MMRESETSTREAM_FUNC)(
189     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
190     IN  MMDEVICE_TYPE DeviceType,
191     IN  BOOLEAN bStartReset);
192 
193 typedef MMRESULT(*MMGETVOLUME_FUNC)(
194     _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
195     _In_ DWORD DeviceId,
196     _Out_ PDWORD pdwVolume);
197 
198 typedef MMRESULT(*MMSETVOLUME_FUNC)(
199     _In_ struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
200     _In_ DWORD DeviceId,
201     _In_ DWORD dwVolume);
202 
203 typedef struct _MMFUNCTION_TABLE
204 {
205     union
206     {
207         MMGETCAPS_FUNC              GetCapabilities;
208         MMGETWAVEOUTCAPS_FUNC       GetWaveOutCapabilities;
209         MMGETWAVEINCAPS_FUNC        GetWaveInCapabilities;
210         MMGETMIDIOUTCAPS_FUNC       GetMidiOutCapabilities;
211         MMGETMIDIINCAPS_FUNC        GetMidiInCapabilities;
212     };
213 
214     MMOPEN_FUNC                     Open;
215     MMCLOSE_FUNC                    Close;
216 
217     MMWAVEQUERYFORMATSUPPORT_FUNC   QueryWaveFormatSupport;
218     MMWAVESETFORMAT_FUNC            SetWaveFormat;
219 
220     MMMIXERQUERY_FUNC               QueryMixerInfo;
221 
222     WAVE_COMMIT_FUNC                CommitWaveBuffer;
223 
224     MMGETPOS_FUNC                   GetPos;
225     MMSETSTATE_FUNC                 SetState;
226     MMQUERYDEVICEINTERFACESTRING_FUNC     GetDeviceInterfaceString;
227     MMRESETSTREAM_FUNC               ResetStream;
228 
229     MMGETVOLUME_FUNC                GetVolume;
230     MMSETVOLUME_FUNC                SetVolume;
231 
232     // Redundant
233     //MMWAVEHEADER_FUNC               PrepareWaveHeader;
234     //MMWAVEHEADER_FUNC               UnprepareWaveHeader;
235     //MMWAVEHEADER_FUNC               WriteWaveHeader;
236 
237     //MMWAVEHEADER_FUNC               SubmitWaveHeaderToDevice;
238     //MMBUFFER_FUNC                   CompleteBuffer;
239 } MMFUNCTION_TABLE, *PMMFUNCTION_TABLE;
240 
241 
242 
243 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER)(
244     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
245     IN  PVOID Parameter);
246 
247 typedef struct _SOUND_THREAD
248 {
249     HANDLE Handle;
250     BOOL Running;
251 
252     struct
253     {
254         HANDLE Ready;
255         HANDLE Request;
256         HANDLE Done;
257     } Events;
258 
259     struct
260     {
261         SOUND_THREAD_REQUEST_HANDLER Handler;
262         struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
263         PVOID Parameter;
264         MMRESULT Result;
265     } Request;
266 } SOUND_THREAD, *PSOUND_THREAD;
267 
268 typedef struct _SOUND_DEVICE
269 {
270     struct _SOUND_DEVICE* Next;
271     struct _SOUND_DEVICE_INSTANCE* HeadInstance;
272     struct _SOUND_DEVICE_INSTANCE* TailInstance;
273     MMDEVICE_TYPE Type;
274     PVOID Identifier;       /* Path for NT4 drivers */
275     /*PWSTR Path;*/
276     MMFUNCTION_TABLE FunctionTable;
277 } SOUND_DEVICE, *PSOUND_DEVICE;
278 
279 typedef struct _SOUND_DEVICE_INSTANCE
280 {
281     struct _SOUND_DEVICE_INSTANCE* Next;
282     struct _SOUND_DEVICE* Device;
283     PVOID Handle;
284     struct _SOUND_THREAD* Thread;
285 
286     /* Stuff generously donated to us from WinMM */
287     struct
288     {
289         HDRVR Handle;
290         DWORD Flags;
291         DWORD_PTR ClientCallback;
292         DWORD_PTR ClientCallbackInstanceData;
293     } WinMM;
294 
295     /* DO NOT TOUCH THESE OUTSIDE OF THE SOUND THREAD */
296 
297     union
298     {
299         PWAVEHDR HeadWaveHeader;
300     };
301 
302     union
303     {
304         PWAVEHDR TailWaveHeader;
305     };
306 
307     PWAVEHDR WaveLoopStart;
308     //PWAVEHDR CurrentWaveHeader;
309     DWORD OutstandingBuffers;
310     DWORD LoopsRemaining;
311     DWORD FrameSize;
312     DWORD BufferCount;
313     WAVEFORMATEX WaveFormatEx;
314     HANDLE hNotifyEvent;
315     HANDLE hStopEvent;
316     HANDLE hResetEvent;
317     BOOL ResetInProgress;
318     BOOL bPaused;
319 } SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE;
320 
321 /* This lives in WAVEHDR.reserved */
322 typedef struct _WAVEHDR_EXTENSION
323 {
324     DWORD BytesCommitted;
325     DWORD BytesCompleted;
326 } WAVEHDR_EXTENSION, *PWAVEHDR_EXTENSION;
327 
328 
329 /*
330     reentrancy.c
331 */
332 
333 MMRESULT
334 InitEntrypointMutexes(VOID);
335 
336 VOID
337 CleanupEntrypointMutexes(VOID);
338 
339 VOID
340 AcquireEntrypointMutex(
341     IN  MMDEVICE_TYPE DeviceType);
342 
343 VOID
344 ReleaseEntrypointMutex(
345     IN  MMDEVICE_TYPE DeviceType);
346 
347 
348 /*
349     mme.c
350 */
351 
352 VOID
353 NotifyMmeClient(
354     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
355     IN  UINT Message,
356     IN  DWORD_PTR Parameter);
357 
358 MMRESULT
359 MmeGetSoundDeviceCapabilities(
360     IN  MMDEVICE_TYPE DeviceType,
361     IN  DWORD DeviceId,
362     IN  PVOID Capabilities,
363     IN  DWORD CapabilitiesSize);
364 
365 MMRESULT
366 MmeOpenDevice(
367     IN  MMDEVICE_TYPE DeviceType,
368     IN  UINT DeviceId,
369     IN  LPWAVEOPENDESC OpenParameters,
370     IN  DWORD Flags,
371     OUT DWORD_PTR* PrivateHandle);
372 
373 MMRESULT
374 MmeCloseDevice(
375     IN  DWORD_PTR PrivateHandle);
376 
377 MMRESULT
378 MmeGetPosition(
379     IN  MMDEVICE_TYPE DeviceType,
380     IN  DWORD DeviceId,
381     IN  DWORD_PTR PrivateHandle,
382     IN  MMTIME* Time,
383     IN  DWORD Size);
384 
385 MMRESULT
386 MmeGetVolume(
387     _In_ MMDEVICE_TYPE DeviceType,
388     _In_ DWORD DeviceId,
389     _In_ DWORD_PTR PrivateHandle,
390     _Out_ DWORD_PTR pdwVolume);
391 
392 MMRESULT
393 MmeSetVolume(
394     _In_ MMDEVICE_TYPE DeviceType,
395     _In_ DWORD DeviceId,
396     _In_ DWORD_PTR PrivateHandle,
397     _In_ DWORD_PTR dwVolume);
398 
399 MMRESULT
400 MmeGetDeviceInterfaceString(
401     IN  MMDEVICE_TYPE DeviceType,
402     IN  DWORD DeviceId,
403     IN  LPWSTR Interface,
404     IN  DWORD  InterfaceLength,
405     OUT  DWORD * InterfaceSize);
406 
407 
408 MMRESULT
409 MmeSetState(
410     IN  DWORD_PTR PrivateHandle,
411     IN  BOOL bStart);
412 
413 
414 #define MmePrepareWaveHeader(private_handle, header) \
415     PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
416 
417 #define MmeUnprepareWaveHeader(private_handle, header) \
418     UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
419 
420 #define MmeWriteWaveHeader(private_handle, header) \
421     WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
422 
423 MMRESULT
424 MmeResetWavePlayback(
425     IN  DWORD_PTR PrivateHandle);
426 
427 
428 /*
429     capabilities.c
430 */
431 
432 MMRESULT
433 GetSoundDeviceCapabilities(
434     IN  PSOUND_DEVICE SoundDevice,
435     IN  DWORD DeviceId,
436     OUT PVOID Capabilities,
437     IN  DWORD CapabilitiesSize);
438 
439 
440 /*
441     devicelist.c
442 */
443 
444 ULONG
445 GetSoundDeviceCount(
446     IN  MMDEVICE_TYPE DeviceType);
447 
448 BOOLEAN
449 IsValidSoundDevice(
450     IN  PSOUND_DEVICE SoundDevice);
451 
452 MMRESULT
453 ListSoundDevice(
454     IN  MMDEVICE_TYPE DeviceType,
455     IN  PVOID Identifier OPTIONAL,
456     OUT PSOUND_DEVICE* SoundDevice OPTIONAL);
457 
458 MMRESULT
459 UnlistSoundDevice(
460     IN  MMDEVICE_TYPE DeviceType,
461     IN  PSOUND_DEVICE SoundDevice);
462 
463 MMRESULT
464 UnlistSoundDevices(
465     IN  MMDEVICE_TYPE DeviceType);
466 
467 VOID
468 UnlistAllSoundDevices(VOID);
469 
470 MMRESULT
471 GetSoundDevice(
472     IN  MMDEVICE_TYPE DeviceType,
473     IN  DWORD DeviceIndex,
474     OUT PSOUND_DEVICE* Device);
475 
476 MMRESULT
477 GetSoundDeviceIdentifier(
478     IN  PSOUND_DEVICE SoundDevice,
479     OUT PVOID* Identifier);
480 
481 MMRESULT
482 GetSoundDeviceType(
483     IN  PSOUND_DEVICE SoundDevice,
484     OUT PMMDEVICE_TYPE DeviceType);
485 
486 
487 /*
488     functiontable.c
489 */
490 
491 MMRESULT
492 SetSoundDeviceFunctionTable(
493     IN  PSOUND_DEVICE SoundDevice,
494     IN  PMMFUNCTION_TABLE FunctionTable);
495 
496 MMRESULT
497 GetSoundDeviceFunctionTable(
498     IN  PSOUND_DEVICE SoundDevice,
499     OUT PMMFUNCTION_TABLE* FunctionTable);
500 
501 
502 /*
503     deviceinstance.c
504 */
505 
506 BOOLEAN
507 IsValidSoundDeviceInstance(
508     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
509 
510 MMRESULT
511 CreateSoundDeviceInstance(
512     IN  PSOUND_DEVICE SoundDevice,
513     OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance);
514 
515 MMRESULT
516 DestroySoundDeviceInstance(
517     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
518 
519 MMRESULT
520 DestroyAllSoundDeviceInstances(
521     IN  PSOUND_DEVICE SoundDevice);
522 
523 MMRESULT
524 GetSoundDeviceFromInstance(
525     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
526     OUT PSOUND_DEVICE* SoundDevice);
527 
528 MMRESULT
529 GetSoundDeviceInstanceHandle(
530     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
531     OUT PVOID* Handle);
532 
533 MMRESULT
534 SetSoundDeviceInstanceMmeData(
535     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
536     IN  HDRVR MmeHandle,
537     IN  DWORD_PTR ClientCallback,
538     IN  DWORD_PTR ClientCallbackData,
539     IN  DWORD Flags);
540 
541 
542 /*
543     thread.c
544 */
545 
546 MMRESULT
547 CreateSoundThread(
548     OUT PSOUND_THREAD* Thread);
549 
550 MMRESULT
551 DestroySoundThread(
552     IN  PSOUND_THREAD Thread);
553 
554 MMRESULT
555 CallSoundThread(
556     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
557     IN  SOUND_THREAD_REQUEST_HANDLER RequestHandler,
558     IN  PVOID Parameter OPTIONAL);
559 
560 
561 /*
562     utility.c
563 */
564 
565 PVOID
566 AllocateMemory(
567     IN  UINT Size);
568 
569 VOID
570 FreeMemory(
571     IN  PVOID Pointer);
572 
573 UINT
574 GetMemoryAllocationCount(VOID);
575 
576 UINT
577 GetDigitCount(
578     IN  UINT Number);
579 
580 MMRESULT
581 Win32ErrorToMmResult(
582     IN  UINT ErrorCode);
583 
584 MMRESULT
585 TranslateInternalMmResult(
586     IN  MMRESULT Result);
587 
588 
589 /*
590     wave/format.c
591 */
592 
593 MMRESULT
594 QueryWaveDeviceFormatSupport(
595     IN  PSOUND_DEVICE SoundDevice,
596     IN  LPWAVEFORMATEX Format,
597     IN  DWORD FormatSize);
598 
599 MMRESULT
600 SetWaveDeviceFormat(
601     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
602     IN  DWORD DeviceId,
603     IN  LPWAVEFORMATEX Format,
604     IN  DWORD FormatSize);
605 
606 
607 /*
608     wave/header.c
609 */
610 
611 MMRESULT
612 EnqueueWaveHeader(
613     PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
614     IN  PVOID Parameter);
615 
616 VOID
617 CompleteWaveHeader(
618     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
619     IN  PWAVEHDR Header);
620 
621 MMRESULT
622 PrepareWaveHeader(
623     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
624     IN  PWAVEHDR Header);
625 
626 MMRESULT
627 UnprepareWaveHeader(
628     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
629     IN  PWAVEHDR Header);
630 
631 MMRESULT
632 WriteWaveHeader(
633     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
634     IN  PWAVEHDR Header);
635 
636 
637 /*
638     wave/streaming.c
639 */
640 
641 VOID
642 DoWaveStreaming(
643     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
644 
645 VOID CALLBACK
646 CompleteIO(
647     IN  DWORD dwErrorCode,
648     IN  DWORD dwNumberOfBytesTransferred,
649     IN  LPOVERLAPPED lpOverlapped);
650 
651 MMRESULT
652 CommitWaveHeaderToKernelDevice(
653     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
654     IN  PWAVEHDR Header,
655     IN  WAVE_COMMIT_FUNC CommitFunction);
656 
657 MMRESULT
658 WriteFileEx_Committer(
659     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
660     IN  PVOID OffsetPtr,
661     IN  DWORD Length,
662     IN  PSOUND_OVERLAPPED Overlap,
663     IN  LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine);
664 
665 MMRESULT
666 StopStreaming(
667     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
668 
669 VOID
670 InitiateSoundStreaming(
671     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
672 
673 /*
674     kernel.c
675 */
676 
677 MMRESULT
678 OpenKernelSoundDeviceByName(
679     IN  PWSTR DevicePath,
680     IN  BOOLEAN ReadOnly,
681     OUT PHANDLE Handle);
682 
683 MMRESULT
684 OpenKernelSoundDevice(
685     IN  PSOUND_DEVICE SoundDevice,
686     IN  BOOLEAN ReadOnly,
687     OUT PHANDLE Handle);
688 
689 MMRESULT
690 CloseKernelSoundDevice(
691     IN  HANDLE Handle);
692 
693 MMRESULT
694 SyncOverlappedDeviceIoControl(
695     IN  HANDLE SoundDeviceInstance,
696     IN  DWORD IoControlCode,
697     IN  LPVOID InBuffer,
698     IN  DWORD InBufferSize,
699     OUT LPVOID OutBuffer,
700     IN  DWORD OutBufferSize,
701     OUT LPDWORD BytesTransferred OPTIONAL);
702 
703 
704 #endif
705