[WDMAUD.DRV][WDMAUD_KERNEL][MMEBUDDY]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 26 Oct 2009 23:10:05 +0000 (23:10 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Mon, 26 Oct 2009 23:10:05 +0000 (23:10 +0000)
- Implement support for DRV_QUERYDEVICEINTERFACESIZE, DRV_QUERYDEVICEINTERFACE
- Required for DSound support

svn path=/trunk/; revision=43788

reactos/dll/win32/wdmaud.drv/wdmaud.c
reactos/drivers/wdm/audio/legacy/wdmaud/control.c
reactos/drivers/wdm/audio/legacy/wdmaud/interface.h
reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
reactos/include/reactos/libs/sound/mmebuddy.h
reactos/lib/drivers/sound/mmebuddy/mmewrap.c
reactos/lib/drivers/sound/mmebuddy/wave/wodMessage.c

index 27c38a5..3378be6 100644 (file)
@@ -554,6 +554,64 @@ SetWdmWaveState(
     return Result;
 }
 
+MMRESULT
+GetDeviceInterfaceString(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  DWORD DeviceId,
+    IN  LPWSTR Interface,
+    IN  DWORD  InterfaceLength,
+    OUT  DWORD * InterfaceSize)
+{
+    WDMAUD_DEVICE_INFO DeviceInfo;
+    MMRESULT Result;
+
+    ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+    DeviceInfo.DeviceType = DeviceType;
+    DeviceInfo.DeviceIndex = DeviceId;
+
+
+    Result = SyncOverlappedDeviceIoControl(KernelHandle,
+                                           IOCTL_QUERYDEVICEINTERFACESTRING,
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           NULL);
+
+
+    if ( ! MMSUCCESS(Result) )
+    {
+        return TranslateInternalMmResult(Result);
+    }
+
+
+    if (!Interface)
+    {
+        SND_ASSERT(InterfaceSize);
+
+        *InterfaceSize = DeviceInfo.u.Interface.DeviceInterfaceStringSize;
+        return MMSYSERR_NOERROR;
+    }
+
+    if (InterfaceLength < DeviceInfo.u.Interface.DeviceInterfaceStringSize)
+    {
+        /* buffer is too small */
+        return MMSYSERR_MOREDATA;
+    }
+
+    DeviceInfo.u.Interface.DeviceInterfaceStringSize = InterfaceLength;
+    DeviceInfo.u.Interface.DeviceInterfaceString = Interface;
+
+    Result = SyncOverlappedDeviceIoControl(KernelHandle,
+                                           IOCTL_QUERYDEVICEINTERFACESTRING,
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           NULL);
+    return Result;
+}
+
 MMRESULT
 GetWdmPosition(
     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
@@ -734,6 +792,7 @@ PopulateWdmDeviceList(
 
         FuncTable.Open = OpenWdmSoundDevice;
         FuncTable.Close = CloseWdmSoundDevice;
+        FuncTable.GetDeviceInterfaceString = GetDeviceInterfaceString;
 #ifndef USERMODE_MIXER
         FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
 #else
index 73b4b70..2bac810 100644 (file)
@@ -203,6 +203,110 @@ WdmAudFrameSize(
 
 }
 
+NTSTATUS
+NTAPI
+WdmAudGetDeviceInterface(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo)
+{
+    PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+    NTSTATUS Status;
+    LPWSTR Device;
+    LPWAVE_INFO WaveInfo;
+    ULONG Size, Length;
+
+    /* get device extension */
+    DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+    /* get device interface string input length */
+    Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
+
+    if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+    {
+        /* get wave info */
+        Status = GetWaveInfoByIndexAndType(DeviceObject, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &WaveInfo);
+
+        /* check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        }
+
+        Status = GetSysAudioDevicePnpName(DeviceObject, WaveInfo->FilterId, &Device);
+        /* check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        }
+
+        /* calculate length */
+        Length = (wcslen(Device)+1) * sizeof(WCHAR);
+
+        if (!Size)
+        {
+            /* store device interface size */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+        }
+        else if (Size < Length)
+        {
+            /* buffer too small */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+            return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+        }
+        else
+        {
+            //FIXME SEH
+            RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
+        }
+
+        ExFreePool(Device);
+        return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+    }
+    else if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+    {
+        if (DeviceInfo->DeviceIndex >= DeviceExtension->MixerInfoCount)
+        {
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+        }
+
+        Status = GetSysAudioDevicePnpName(DeviceObject, DeviceExtension->MixerInfo[DeviceInfo->DeviceIndex].DeviceIndex, &Device);
+        /* check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* invalid device id */
+            return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+        }
+
+        /* calculate length */
+        Length = (wcslen(Device)+1) * sizeof(WCHAR);
+
+        if (!Size)
+        {
+            /* store device interface size */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+        }
+        else if (Size < Length)
+        {
+            /* buffer too small */
+            DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
+            return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
+        }
+        else
+        {
+            //FIXME SEH
+            RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
+        }
+
+        ExFreePool(Device);
+        return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+    }
+
+    return SetIrpIoStatus(Irp, STATUS_INVALID_DEVICE_REQUEST, sizeof(WDMAUD_DEVICE_INFO));
+}
 
 NTSTATUS
 NTAPI
@@ -266,6 +370,8 @@ WdmAudDeviceControl(
             return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
         case IOCTL_GETCONTROLDETAILS:
             return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
+        case IOCTL_QUERYDEVICEINTERFACESTRING:
+            return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
         case IOCTL_GETPOS:
         case IOCTL_GETDEVID:
         case IOCTL_GETVOLUME:
index fa7e416..44eef61 100644 (file)
@@ -44,6 +44,11 @@ typedef struct
         AUXCAPSW     AuxCaps;
         WAVEINCAPSW  WaveInCaps;
         ULONGLONG    Position;
+        struct
+        {
+            LPWSTR DeviceInterfaceString;
+            ULONG DeviceInterfaceStringSize;
+        }Interface;
         KSSTATE State;
         ULONG Volume;
         ULONG FrameSize;
@@ -313,4 +318,22 @@ typedef struct
              METHOD_BUFFERED, \
              FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
 
+
+/// IOCTL_QUERYDEVICEINTERFACESTRING
+///
+/// Description: This IOCTL queries the mixer / playback / recording device for its device interface string
+///
+/// Arguments:  InputBuffer is a pointer to a WDMAUD_DEVICE_INFO structure,
+///             InputBufferSize is size of WDMAUD_DEVICE_INFO structure
+/// Note:       The DeviceType, DeviceIndex must be set
+/// Result:     The size is returned in Interface.DeviceInterfaceStringSize and if a buffer is supplied in Interface.DeviceInterfaceString
+///             the device interface string is stored
+/// ReturnCode:  STATUS_SUCCESS indicates success
+
+#define IOCTL_QUERYDEVICEINTERFACESTRING \
+    CTL_CODE(FILE_DEVICE_SOUND, \
+             15, \
+             METHOD_BUFFERED, \
+             FILE_CREATE_TREE_CONNECTION | FILE_ANY_ACCESS)
+
 #endif
index db59c0b..4229290 100644 (file)
@@ -1536,6 +1536,7 @@ InitializeMixer(
     MixerInfo->MixCaps.vDriverVersion = 1; //FIXME
     MixerInfo->MixCaps.fdwSupport = 0;
     MixerInfo->MixCaps.cDestinations = 1;
+    MixerInfo->DeviceIndex = DeviceIndex;
 
     /* get target pnp name */
     Status = GetSysAudioDevicePnpName(DeviceObject, DeviceIndex, &Device);
index 16f8599..598d374 100644 (file)
@@ -67,7 +67,7 @@ typedef struct
 typedef struct
 {
     MIXERCAPSW    MixCaps;
-
+    ULONG DeviceIndex;
     LIST_ENTRY    LineList;
     ULONG ControlId;
 }MIXER_INFO, *LPMIXER_INFO;
@@ -277,4 +277,17 @@ InsertPinHandle(
     IN  ULONG FreeIndex);
 
 
+NTSTATUS
+GetWaveInfoByIndexAndType(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  ULONG DeviceIndex,
+    IN  SOUND_DEVICE_TYPE DeviceType,
+    OUT LPWAVE_INFO *OutWaveInfo);
+
+NTSTATUS
+GetSysAudioDevicePnpName(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  ULONG DeviceIndex,
+    OUT LPWSTR * Device);
+
 #endif
index b815800..b145c16 100644 (file)
@@ -242,6 +242,14 @@ typedef MMRESULT(*MMSETSTATE_FUNC)(
     IN  BOOL bStart);
 
 
+typedef MMRESULT(*MMQUERYDEVICEINTERFACESTRING_FUNC)(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  DWORD DeviceId,
+    IN  LPWSTR Interface,
+    IN  DWORD  InterfaceLength,
+    OUT  DWORD * InterfaceSize);
+
+
 typedef struct _MMFUNCTION_TABLE
 {
     union
@@ -265,6 +273,7 @@ typedef struct _MMFUNCTION_TABLE
 
     MMGETPOS_FUNC                   GetPos;
     MMSETSTATE_FUNC                 SetState;
+    MMQUERYDEVICEINTERFACESTRING_FUNC     GetDeviceInterfaceString;
 
     // Redundant
     //MMWAVEHEADER_FUNC               PrepareWaveHeader;
@@ -414,6 +423,15 @@ MmeGetPosition(
     IN  MMTIME* Time,
     IN  DWORD Size);
 
+MMRESULT
+MmeGetDeviceInterfaceString(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  DWORD DeviceId,
+    IN  LPWSTR Interface,
+    IN  DWORD  InterfaceLength,
+    OUT  DWORD * InterfaceSize);
+
+
 MMRESULT
 MmeSetState(
     IN  DWORD PrivateHandle,
index f63e55a..63f3e6f 100644 (file)
@@ -247,6 +247,39 @@ MmeResetWavePlayback(
     return StopStreaming(SoundDeviceInstance);
 }
 
+MMRESULT
+MmeGetDeviceInterfaceString(
+    IN  MMDEVICE_TYPE DeviceType,
+    IN  DWORD DeviceId,
+    IN  LPWSTR Interface,
+    IN  DWORD  InterfaceLength,
+    OUT  DWORD * InterfaceSize)
+{
+    MMRESULT Result;
+    PSOUND_DEVICE SoundDevice;
+    PMMFUNCTION_TABLE FunctionTable;
+
+    Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice);
+    if ( ! MMSUCCESS(Result) )
+        return TranslateInternalMmResult(Result);
+
+    Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
+    if ( ! MMSUCCESS(Result) )
+        return TranslateInternalMmResult(Result);
+
+    if ( FunctionTable->GetDeviceInterfaceString == NULL )
+    {
+        /* querying device interface string / size not supported */
+        return MMSYSERR_NOTSUPPORTED;
+    }
+
+    /* Call the driver */
+    Result = FunctionTable->GetDeviceInterfaceString(DeviceType, DeviceId, Interface, InterfaceLength, InterfaceSize);
+
+    return Result;
+}
+
+
 MMRESULT
 MmeGetPosition(
     IN  MMDEVICE_TYPE DeviceType,
index 108941e..de579f3 100644 (file)
@@ -117,6 +117,18 @@ wodMessage(
             Result = MmeGetPosition(WAVE_OUT_DEVICE_TYPE, DeviceId, PrivateHandle, (MMTIME*)Parameter1, Parameter2);
             break;
         }
+
+        case DRV_QUERYDEVICEINTERFACESIZE :
+        {
+            Result = MmeGetDeviceInterfaceString(WAVE_OUT_DEVICE_TYPE, DeviceId, NULL, 0, (DWORD*)Parameter1); //FIXME DWORD_PTR
+            break;
+        }
+
+        case DRV_QUERYDEVICEINTERFACE :
+        {
+            Result = MmeGetDeviceInterfaceString(WAVE_OUT_DEVICE_TYPE, DeviceId, (LPWSTR)Parameter1, Parameter2, NULL); //FIXME DWORD_PTR
+            break;
+        }
     }
 
     SND_TRACE(L"wodMessage returning MMRESULT %d\n", Result);