Skip to content

Commit

Permalink
[AUDIO] Device management code refactoring
Browse files Browse the repository at this point in the history
[WDMAUD.DRV]
Completely rewrite Legacy and MMixer routines, to make them more compatible with Windows.
- Make it independent from MMEBuddy library and make it using its own MME routines instead of MMEBuddy's.
- Get rid from SOUND_DEVICE_INSTANCE structure usage, use WDMAUD_DEVICE_INFO instead. SOUND_DEVICE_INSTANCE has the same purpose as WDMAUD_DEVICE_INFO, and Windows does not use multiple structures, so we also don't need that, to be more compatible with MS. Separate all device state related stuff into WDMAUD_DEVICE_STATE structure. Rework them t the look similar to Windows's (based on analysis). Set alignment 1 for both of them, to make it of the same size as in Windows XP/2003. This gets us better compatibility (and therefore ability to work together) between our/MS wdmaud.drv/sys ring. Although it still doesn't work, but the major steps are done.
- Rewrite all Legacy rotines to make them more similar to MS. Add their own WdmAudIoControl, and don't use SyncOverlappedDeviceIoControl from MMEBuddy.
- Don't use separate members for each data buffer in WDMAUD_DEVICE_INFO structure, declare one buffer member, which can store several types of data passed by the caller (as in Windows). Add a second member which indicates the size of passed data.
- Adapt all MMixer routines to other changes. Use WDMAUD_DEVICE_INFO structure for all of them too, instead of SOUND_DEVICE_INSTANCE.
- Implement proper resampling support. Rename WriteFileEx_Remixer to WdmAudResampleStream, and rewrite it to only do the resampling, remove all streaming code from it, which is buggy anyway. Call it in WdmAudSubmitWaveHeader (reworked from WdmAudCommitWaveBuffer), to properly resample wave header data before sending it. Add RESAMPLING_ENABLED define which allows to enable/disable resampling support.
- Don't use MMFUNCTION_TABLE structure from MMEBuddy, extend usage of FUNC_NAME macro instead, which redirects to Legacy or MMixer API appropriatedly, depending on USE_MMIXER_LIB define.
- Remove WdmAudQueryDeviceInterfaceString, since it does not exist in Windows. The device interface string is already received by calling SetupApi routines and is stored in WDMAUD_DEVICE_INFO structure.
- Refactor opening audio device mechanism. Add WdmAudOpenKernelSoundDevice (previously WdmAudOpenSoundDevice), which does the initial initialization of Wdm Audio driver mapper, and WdmAudOpenSoundDevice, which opens the device itself (previously SetWaveDeviceFormat). This is more similar to Windows.
- Completely rewrite Wave Header extension management. In Windows, header extension has two members: streaming device info pointer (aka sound private handle), allocated and used by SubmitWaveHeader for I/O operations, and a pointer to OVERLAPPED structure which contains steaming event handle. There is no committed and completed bytes counts.

[WDMAUD]
Fix all kernel-mode routines, whose are used by Legacy APIs. Adapt them to current changes also.
- Fix all IOCTL declarations. Add new/update existing IOCTLs to Windows-compatible state. I investigated them by the following way: 1. Analyze them via debugger, when they are passed to DeviceIoControl. 2. Copy their handle and paste it to any IOCTL decoder (I used OSR online IOCTL Decoder for example). 3. Decode them ang get their actual declarations, those can be used by us.
- Use Buffer member of WDMAUD_DEVICE_INFO when possible for storing user data received from/passed to the caller.
- Implement some more IOCTLs whose exist in Windows. Add initialization code, and rewrite streaming routine. Use KsStreamIo for that, instead of dumb calling the driver via IoCallDriver. That KS routine is buggy, so it also needs a fix, which I will send in a a separate PR.
- Extend usage of MMixer library. Implement MMixerGetWavePosition, and use it for both Legacy and MMixer routines (in wdmaud.sys and wdmaud.drv appropriately).

[MMIXER]
- Add support for WAVE_FORMAT_EXTENSIBLE audio format. Don't fail when it is requested. Initialize required structure fields for it. It already is supported properly by us, since it is just and extended representation of WAVE_FORMAT_PCM.
- Handle some more Mixer control types, to fix sndvol32.exe Mixer open failures after my changes. Remove unneeded duplicating of MIXERCONTROL_CONTROLTYPE_MUX handling.
- Implement MMixerGetWavePosition.

[KS]
- Fix bug in KsStreamIo
Properly set output buffer length in IO Stack Location of the current IRP, since it is passed to KsProbeStreamIrp when calling KsStreamIo, so it fails if the length isn't set properly.
Don't set an input buffer length and the buffer itself, since it isn't passed anywhere, so setting it makes no sense. Moreover, MSDN says that for IOCTL_KS_READ/WRITE_STREAM, only output buffer (and its length) is needed to be set, but not an input one. So it indeed is more correct.
It fixes buffer overflow in KsProbeStreamIrp when attempting to perform the streaming via KsStreamIo. I discovered this bug during my audio refactoring from PR reactos#4660.
- Restore old hack for MS portcls.
  • Loading branch information
oleg-dubinskiy committed Aug 18, 2023
1 parent a995d8d commit ef62d66
Show file tree
Hide file tree
Showing 43 changed files with 3,928 additions and 2,327 deletions.
19 changes: 15 additions & 4 deletions dll/win32/wdmaud.drv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,21 @@ include_directories(
spec2def(wdmaud.drv wdmaud.spec)

list(APPEND SOURCE
wdmaud.c
mixer.c
mmixer.c
legacy.c
mmewrap.c
mmixer.c
reentrancy.c
resample.c
result.c
wdmaud.c
auxiliary/auxMessage.c
midi/midMessage.c
midi/modMessage.c
mixer/mxdMessage.c
wave/header.c
wave/streaming.c
wave/widMessage.c
wave/wodMessage.c
wdmaud.h)

add_library(wdmaud.drv MODULE
Expand All @@ -21,7 +32,7 @@ add_library(wdmaud.drv MODULE

set_module_type(wdmaud.drv win32dll UNICODE)
set_target_properties(wdmaud.drv PROPERTIES SUFFIX "")
target_link_libraries(wdmaud.drv mmebuddy libsamplerate mmixer)
target_link_libraries(wdmaud.drv libsamplerate mmixer)
add_importlibs(wdmaud.drv user32 winmm advapi32 msvcrt setupapi ksuser kernel32 ntdll)
add_pch(wdmaud.drv wdmaud.h SOURCE)
add_cd_file(TARGET wdmaud.drv DESTINATION reactos/system32 FOR all)
71 changes: 71 additions & 0 deletions dll/win32/wdmaud.drv/auxiliary/auxMessage.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* PROJECT: ReactOS Sound System "MME Buddy" Library
* LICENSE: GPL - See COPYING in the top level directory
* FILE: lib/sound/mmebuddy/auxiliary/auxMessage.c
*
* PURPOSE: Provides the auxMessage exported function, as required by
* the MME API, for auxiliary device support.
*
* PROGRAMMERS: Andrew Greenwood ([email protected])
*/

#include "wdmaud.h"

#define YDEBUG
#include <debug.h>

/*
Standard MME driver entry-point for messages relating to auxiliary devices.
*/
DWORD
APIENTRY
auxMessage(
UINT DeviceId,
UINT Message,
DWORD_PTR PrivateHandle,
DWORD_PTR Parameter1,
DWORD_PTR Parameter2)
{
MMRESULT Result = MMSYSERR_NOTSUPPORTED;

AcquireEntrypointMutex(AUX_DEVICE_TYPE);

DPRINT("auxMessage - Message type %d\n", Message);

switch ( Message )
{
#ifndef USE_MMIXER_LIB
case AUXM_INIT:
{
Result = WdmAudAddRemoveDeviceNode(AUX_DEVICE_TYPE, TRUE);
break;
}

case DRVM_EXIT:
{
Result = WdmAudAddRemoveDeviceNode(AUX_DEVICE_TYPE, FALSE);
break;
}
#endif

case AUXDM_GETNUMDEVS :
{
Result = MmeGetNumDevs(AUX_DEVICE_TYPE);
break;
}

case AUXDM_GETDEVCAPS :
{
Result = MmeGetSoundDeviceCapabilities(AUX_DEVICE_TYPE,
DeviceId,
(MDEVICECAPSEX*)Parameter1);
break;
}
}

DPRINT("auxMessage returning MMRESULT %d\n", Result);

ReleaseEntrypointMutex(AUX_DEVICE_TYPE);

return Result;
}
Loading

0 comments on commit ef62d66

Please sign in to comment.