Author: janderwald
Date: Fri Oct 2 12:57:24 2009
New Revision: 43254
URL:
http://svn.reactos.org/svn/reactos?rev=43254&view=rev
Log:
- Rewrite Wave API to enumerate wave out / in devices at startup
- Improves speedup of application minus short delay in system boot
- Enumerate controls for source and destination lines
Added:
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/sup.c (with props)
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wave.c (with props)
Modified:
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Fri Oct 2
12:57:24 2009
@@ -19,378 +19,51 @@
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf,
0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5,
0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
-NTSTATUS
-SetIrpIoStatus(
- IN PIRP Irp,
- IN NTSTATUS Status,
- IN ULONG Length)
-{
- Irp->IoStatus.Information = Length;
- Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return Status;
-
-}
-
-NTSTATUS
-GetFilterIdAndPinId(
- IN PDEVICE_OBJECT DeviceObject,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo,
- IN PULONG FilterId,
- IN PULONG PinId)
-{
- KSP_PIN Pin;
- ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
+
+NTSTATUS
+WdmAudControlOpen(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo)
+{
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+ {
+ return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ }
+
+ if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType ==
WAVE_IN_DEVICE_TYPE)
+ {
+ return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
+ }
+
+ return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
+}
+
+NTSTATUS
+WdmAudControlDeviceType(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo)
+{
+ ULONG Result = 0;
NTSTATUS Status;
- KSPIN_COMMUNICATION Communication;
- KSPIN_DATAFLOW DataFlow;
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE &&
DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
- {
- DPRINT1("FIXME: Unsupported device type %x\n",
DeviceInfo->DeviceType);
- return STATUS_UNSUCCESSFUL;
- }
-
- Pin.Property.Set = KSPROPSETID_Sysaudio;
- Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG),
&BytesReturned);
- if (!NT_SUCCESS(Status))
- return STATUS_UNSUCCESSFUL;
-
- Result = 0;
- for(Index = 0; Index < Count; Index++)
- {
- /* query number of pins */
- Pin.Reserved = Index; // see sysaudio
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
- Pin.Property.Set = KSPROPSETID_Pin;
- Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
- Pin.PinId = 0;
-
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG),
&BytesReturned);
- if (NT_SUCCESS(Status))
- {
- /* enumerate now all pins */
- for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
- {
- Pin.PinId = SubIndex;
- Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
- Communication = KSPIN_COMMUNICATION_NONE;
-
- /* get pin communication type */
- KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication,
sizeof(KSPIN_COMMUNICATION), &BytesReturned);
-
- Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
- DataFlow = 0;
-
- /* get pin dataflow type */
- KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow,
sizeof(KSPIN_DATAFLOW), &BytesReturned);
-
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_IN)
- {
- if(DeviceInfo->DeviceIndex == Result)
- {
- /* found the index */
- *FilterId = Index;
- *PinId = SubIndex;
- return STATUS_SUCCESS;
- }
-
- Result++;
- }
- }
- else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_OUT)
- {
- if(DeviceInfo->DeviceIndex == Result)
- {
- /* found the index */
- *FilterId = Index;
- *PinId = SubIndex;
- return STATUS_SUCCESS;
- }
- Result++;
- }
- }
- }
- }
- }
-
- return STATUS_UNSUCCESSFUL;
-}
-
-NTSTATUS
-WdmAudControlOpen(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- SYSAUDIO_INSTANCE_INFO InstanceInfo;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
- ULONG BytesReturned;
- NTSTATUS Status;
- ACCESS_MASK DesiredAccess = 0;
- HANDLE PinHandle;
- KSPIN_CONNECT * PinConnect;
- ULONG Length, Index;
- KSDATAFORMAT_WAVEFORMATEX * DataFormat;
- ULONG FilterId;
- ULONG PinId;
- ULONG FreeIndex;
-
if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
- return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
- }
-
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE &&
DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
- {
- DPRINT1("FIXME: only waveout / wavein devices are supported\n");
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- if (DeviceInfo->u.WaveFormatEx.wFormatTag != WAVE_FORMAT_PCM)
- {
- DPRINT("FIXME: Only WAVE_FORMAT_PCM is supported RequestFormat %x\n",
DeviceInfo->u.WaveFormatEx.wFormatTag);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId,
&PinId);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid device index %u\n", DeviceInfo->DeviceIndex);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
- }
-
- /* close pin handle which uses same virtual audio device id and pin id */
- FreeIndex = MAXULONG;
- for(Index = 0; Index < ClientInfo->NumPins; Index++)
- {
- if (ClientInfo->hPins[Index].FilterId == FilterId &&
ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle
&& ClientInfo->hPins[Index].Type == DeviceInfo->DeviceType)
- {
- ZwClose(ClientInfo->hPins[Index].Handle);
- ClientInfo->hPins[Index].Handle = NULL;
- FreeIndex = Index;
- }
- }
-
-
- Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT);
- PinConnect = ExAllocatePool(NonPagedPool, Length);
- if (!PinConnect)
- {
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- DesiredAccess |= GENERIC_READ;
- }
-
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE ||
- DeviceInfo->DeviceType == AUX_DEVICE_TYPE ||
- DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- DesiredAccess |= GENERIC_WRITE;
- }
-
- PinConnect->Interface.Set = KSINTERFACESETID_Standard;
- PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
- PinConnect->Interface.Flags = 0;
- PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
- PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
- PinConnect->Medium.Flags = 0;
- PinConnect->PinToHandle = NULL;
- PinConnect->PinId = PinId;
- PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
- PinConnect->Priority.PrioritySubClass = 1;
-
-
- DataFormat = (KSDATAFORMAT_WAVEFORMATEX*) (PinConnect + 1);
- DataFormat->WaveFormatEx.wFormatTag = DeviceInfo->u.WaveFormatEx.wFormatTag;
- DataFormat->WaveFormatEx.nChannels = DeviceInfo->u.WaveFormatEx.nChannels;
- DataFormat->WaveFormatEx.nSamplesPerSec =
DeviceInfo->u.WaveFormatEx.nSamplesPerSec;
- DataFormat->WaveFormatEx.nBlockAlign = DeviceInfo->u.WaveFormatEx.nBlockAlign;
- DataFormat->WaveFormatEx.nAvgBytesPerSec =
DeviceInfo->u.WaveFormatEx.nAvgBytesPerSec;
- DataFormat->WaveFormatEx.wBitsPerSample =
DeviceInfo->u.WaveFormatEx.wBitsPerSample;
- DataFormat->WaveFormatEx.cbSize = 0;
- DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
- DataFormat->DataFormat.Flags = 0;
- DataFormat->DataFormat.Reserved = 0;
- DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
-
- DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
- DataFormat->DataFormat.SampleSize = 4;
-
- /* setup property request */
- InstanceInfo.Property.Set = KSPROPSETID_Sysaudio;
- InstanceInfo.Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO;
- InstanceInfo.Property.Flags = KSPROPERTY_TYPE_SET;
- InstanceInfo.Flags = 0;
- InstanceInfo.DeviceNumber = FilterId;
-
- /* first open the virtual device */
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0,
&BytesReturned);
-
- if (!NT_SUCCESS(Status))
- {
- /* failed */
- ExFreePool(PinConnect);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- /* now create the pin */
- Status = KsCreatePin(DeviceExtension->hSysAudio, PinConnect, DesiredAccess,
&PinHandle);
-
- /* free create info */
- ExFreePool(PinConnect);
-
- if (NT_SUCCESS(Status))
- {
- PWDMAUD_HANDLE Handels;
-
- if (FreeIndex != MAXULONG)
- {
- /* re-use a free index */
- ClientInfo->hPins[Index].Handle = PinHandle;
- ClientInfo->hPins[Index].FilterId = FilterId;
- ClientInfo->hPins[Index].PinId = PinId;
- ClientInfo->hPins[Index].Type = DeviceInfo->DeviceType;
-
- DeviceInfo->hDevice = PinHandle;
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- Handels = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_HANDLE) *
(ClientInfo->NumPins+1));
-
- if (Handels)
- {
- if (ClientInfo->NumPins)
- {
- RtlMoveMemory(Handels, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) *
ClientInfo->NumPins);
- ExFreePool(ClientInfo->hPins);
- }
-
- ClientInfo->hPins = Handels;
- ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
- ClientInfo->hPins[ClientInfo->NumPins].Type =
DeviceInfo->DeviceType;
- ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
- ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
- ClientInfo->NumPins++;
- }
- DeviceInfo->hDevice = PinHandle;
- }
- else
- {
- DeviceInfo->hDevice = NULL;
- }
-
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
-}
-
-NTSTATUS
-WdmAudControlDeviceType(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp,
- IN PWDMAUD_DEVICE_INFO DeviceInfo,
- IN PWDMAUD_CLIENT ClientInfo)
-{
- KSP_PIN Pin;
- ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
- NTSTATUS Status;
- KSPIN_COMMUNICATION Communication;
- KSPIN_DATAFLOW DataFlow;
- PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
- if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
- {
- DeviceInfo->DeviceCount = DeviceExtension->MixerInfoCount;
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE &&
DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
- {
- DPRINT("FIXME: Unsupported device type %x\n",
DeviceInfo->DeviceType);
- DeviceInfo->DeviceCount = 0;
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
- }
-
- Pin.Property.Set = KSPROPSETID_Sysaudio;
- Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
-
-
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG),
&BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
- }
- Result = 0;
- /* now enumerate all available filters */
- for(Index = 0; Index < Count; Index++)
- {
- /* query number of pins */
- Pin.Reserved = Index; // see sysaudio
- Pin.Property.Flags = KSPROPERTY_TYPE_GET;
- Pin.Property.Set = KSPROPSETID_Pin;
- Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
- Pin.PinId = 0;
-
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG),
&BytesReturned);
- if (NT_SUCCESS(Status))
- {
- /* enumerate now all pins */
- for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
- {
- Pin.PinId = SubIndex;
- Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
- Communication = KSPIN_COMMUNICATION_NONE;
-
- /* get pin communication type */
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject,
KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN),
(PVOID)&Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
- if (!NT_SUCCESS(Status))
- continue;
-
- Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
- DataFlow = 0;
-
- /* get pin dataflow type */
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject,
KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow,
sizeof(KSPIN_DATAFLOW), &BytesReturned);
- if (!NT_SUCCESS(Status))
- continue;
-
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_IN)
- Result++;
- }
- else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_OUT)
- Result++;
- }
- }
- }
+ Result = DeviceExtension->MixerInfoCount;
+ }
+ else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ Result = DeviceExtension->WaveOutDeviceCount;
+ }
+ else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+ {
+ Result = DeviceExtension->WaveInDeviceCount;
}
/* store result count */
@@ -436,253 +109,6 @@
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
-ULONG
-CheckFormatSupport(
- IN PKSDATARANGE_AUDIO DataRangeAudio,
- ULONG SampleFrequency,
- ULONG Mono8Bit,
- ULONG Stereo8Bit,
- ULONG Mono16Bit,
- ULONG Stereo16Bit)
-{
- ULONG Result = 0;
-
- if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency &&
DataRangeAudio->MaximumSampleFrequency >= SampleFrequency)
- {
- if (DataRangeAudio->MinimumBitsPerSample <= 8 &&
DataRangeAudio->MaximumBitsPerSample >= 8)
- {
- Result |= Mono8Bit;
- if (DataRangeAudio->MaximumChannels >= 2)
- {
- Result |= Stereo8Bit;
- }
- }
-
- if (DataRangeAudio->MinimumBitsPerSample <= 16 &&
DataRangeAudio->MaximumBitsPerSample >= 16)
- {
- Result |= Mono16Bit;
- if (DataRangeAudio->MaximumChannels >= 2)
- {
- Result |= Stereo8Bit;
- }
- }
- }
- return Result;
-
-}
-
-PKEY_VALUE_PARTIAL_INFORMATION
-ReadKeyValue(
- IN HANDLE hSubKey,
- IN PUNICODE_STRING KeyName)
-{
- NTSTATUS Status;
- ULONG Length;
- PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
-
- /* now query MatchingDeviceId key */
- Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0,
&Length);
-
- /* check for success */
- if (Status != STATUS_BUFFER_TOO_SMALL)
- return NULL;
-
- /* allocate a buffer for key data */
- PartialInformation = ExAllocatePool(NonPagedPool, Length);
-
- if (!PartialInformation)
- return NULL;
-
-
- /* now query MatchingDeviceId key */
- Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation,
PartialInformation, Length, &Length);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(PartialInformation);
- return NULL;
- }
-
- if (PartialInformation->Type != REG_SZ)
- {
- /* invalid key type */
- ExFreePool(PartialInformation);
- return NULL;
- }
-
- return PartialInformation;
-}
-
-
-NTSTATUS
-CompareProductName(
- IN HANDLE hSubKey,
- IN LPWSTR PnpName,
- IN ULONG ProductNameSize,
- OUT LPWSTR ProductName)
-{
- PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
- UNICODE_STRING DriverDescName = RTL_CONSTANT_STRING(L"DriverDesc");
- UNICODE_STRING MatchingDeviceIdName =
RTL_CONSTANT_STRING(L"MatchingDeviceId");
- ULONG Length;
- LPWSTR DeviceName;
-
- /* read MatchingDeviceId value */
- PartialInformation = ReadKeyValue(hSubKey, &MatchingDeviceIdName);
-
- if (!PartialInformation)
- return STATUS_UNSUCCESSFUL;
-
-
- /* extract last '&' */
- DeviceName = wcsrchr((LPWSTR)PartialInformation->Data, L'&');
- ASSERT(DeviceName);
- /* terminate it */
- DeviceName[0] = L'\0';
-
- Length = wcslen((LPWSTR)PartialInformation->Data);
-
- DPRINT("DeviceName %S PnpName %S Length %u\n",
(LPWSTR)PartialInformation->Data, PnpName, Length);
-
- if (_wcsnicmp((LPWSTR)PartialInformation->Data, &PnpName[4], Length))
- {
- ExFreePool(PartialInformation);
- return STATUS_NO_MATCH;
- }
-
- /* free buffer */
- ExFreePool(PartialInformation);
-
- /* read DriverDescName value */
- PartialInformation = ReadKeyValue(hSubKey, &DriverDescName);
-
- if (!PartialInformation)
- {
- /* failed to read driver desc key */
- return STATUS_UNSUCCESSFUL;
- }
-
- /* copy key name */
- Length = min(ProductNameSize * sizeof(WCHAR), PartialInformation->DataLength);
- RtlMoveMemory(ProductName, (PVOID)PartialInformation->Data, Length);
-
- /* zero terminate it */
- ProductName[ProductNameSize-1] = L'\0';
-
- /* free buffer */
- ExFreePool(PartialInformation);
-
- return STATUS_SUCCESS;
-}
-
-
-
-NTSTATUS
-FindProductName(
- IN LPWSTR PnpName,
- IN ULONG ProductNameSize,
- OUT LPWSTR ProductName)
-{
- UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
-
- UNICODE_STRING SubKeyName;
- WCHAR SubKey[20];
- OBJECT_ATTRIBUTES ObjectAttributes;
- HANDLE hKey, hSubKey;
- NTSTATUS Status;
- ULONG Length, Index;
- PKEY_FULL_INFORMATION KeyInformation;
-
- for(Index = 0; Index < wcslen(PnpName); Index++)
- {
- if (PnpName[Index] == '#')
- PnpName[Index] = L'\\';
- }
-
-
- /* initialize key attributes */
- InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF, NULL, NULL);
-
- /* open the key */
- Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- return Status;
-
- /* query num of subkeys */
- Status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &Length);
-
- if (Status != STATUS_BUFFER_TOO_SMALL)
- {
- DPRINT1("ZwQueryKey failed with %x\n", Status);
- /* failed */
- ZwClose(hKey);
- return Status;
- }
-
- /* allocate key information struct */
- KeyInformation = ExAllocatePool(NonPagedPool, Length);
- if (!KeyInformation)
- {
- /* no memory */
- ZwClose(hKey);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* query num of subkeys */
- Status = ZwQueryKey(hKey, KeyFullInformation, (PVOID)KeyInformation, Length,
&Length);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("ZwQueryKey failed with %x\n", Status);
- ExFreePool(KeyInformation);
- ZwClose(hKey);
- return Status;
- }
-
- /* now iterate through all subkeys */
- for(Index = 0; Index < KeyInformation->SubKeys; Index++)
- {
- /* subkeys are always in the format 0000-XXXX */
- swprintf(SubKey, L"%04u", Index);
-
- /* initialize subkey name */
- RtlInitUnicodeString(&SubKeyName, SubKey);
-
- /* initialize key attributes */
- InitializeObjectAttributes(&ObjectAttributes, &SubKeyName,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF, hKey, NULL);
-
- /* open the sub key */
- Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
-
- /* check for success */
- if (NT_SUCCESS(Status))
- {
- /* compare product name */
- Status = CompareProductName(hSubKey, PnpName, ProductNameSize, ProductName);
-
- /* close subkey */
- ZwClose(hSubKey);
-
- if (NT_SUCCESS(Status))
- break;
- }
- }
-
- /* free buffer */
- ExFreePool(KeyInformation);
-
- /* close key */
- ZwClose(hKey);
-
- /* no matching key found */
- return Status;
-}
-
-
-
NTSTATUS
WdmAudCapabilities(
IN PDEVICE_OBJECT DeviceObject,
@@ -692,19 +118,6 @@
{
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
- KSP_PIN PinProperty;
- KSCOMPONENTID ComponentId;
- KSMULTIPLE_ITEM * MultipleItem;
- ULONG BytesReturned;
- PKSDATARANGE_AUDIO DataRangeAudio;
- PKSDATARANGE DataRange;
- ULONG Index;
- ULONG wChannels = 0;
- ULONG dwFormats = 0;
- ULONG dwSupport = 0;
- ULONG FilterId;
- ULONG PinId;
- WCHAR DeviceName[MAX_PATH];
DPRINT("WdmAudCapabilities entered\n");
@@ -713,114 +126,11 @@
if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo,
DeviceExtension);
- return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
- }
-
-
- Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId,
&PinId);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Invalid device index provided %u\n",
DeviceInfo->DeviceIndex);
- return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
- }
-
- PinProperty.PinId = FilterId;
- PinProperty.Property.Set = KSPROPSETID_Sysaudio;
- PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_COMPONENT_ID;
- PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
-
- RtlZeroMemory(&ComponentId, sizeof(KSCOMPONENTID));
-
-
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId,
sizeof(KSCOMPONENTID), &BytesReturned);
- if (NT_SUCCESS(Status))
- {
- DeviceInfo->u.WaveOutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
- DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version,
ComponentId.Revision);
- }
-
- /* retrieve pnp base name */
- PinProperty.PinId = FilterId;
- PinProperty.Property.Set = KSPROPSETID_Sysaudio;
- PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME;
- PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
-
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)DeviceName,
sizeof(DeviceName), &BytesReturned);
- if (NT_SUCCESS(Status))
- {
- /* find product name */
- Status = FindProductName(DeviceName, MAXPNAMELEN,
DeviceInfo->u.WaveOutCaps.szPname);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- DeviceInfo->u.WaveOutCaps.szPname[0] = L'\0';
- }
- }
-
- PinProperty.Reserved = DeviceInfo->DeviceIndex;
- PinProperty.PinId = PinId;
- PinProperty.Property.Set = KSPROPSETID_Pin;
- PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES;
- PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
-
- BytesReturned = 0;
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0,
&BytesReturned);
- if (Status != STATUS_BUFFER_TOO_SMALL)
- {
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
- if (!MultipleItem)
- {
- /* no memory */
- return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
- }
-
- Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem,
BytesReturned, &BytesReturned);
- if (!NT_SUCCESS(Status))
- {
- ExFreePool(MultipleItem);
- return SetIrpIoStatus(Irp, Status, 0);
- }
-
- DataRange = (PKSDATARANGE) (MultipleItem + 1);
- for(Index = 0; Index < MultipleItem->Count; Index++)
- {
- if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE ||
DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
- {
- if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO))
- {
- DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange;
-
- if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat,
&KSDATAFORMAT_TYPE_AUDIO) &&
- IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat,
&KSDATAFORMAT_SUBTYPE_PCM) &&
- IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier,
&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
- {
- DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max
Channel %u\n", DataRangeAudio->MinimumSampleFrequency,
DataRangeAudio->MaximumSampleFrequency,
-
DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample,
DataRangeAudio->MaximumChannels);
-
- dwFormats |= CheckFormatSupport(DataRangeAudio, 11025,
WAVE_FORMAT_1M08, WAVE_FORMAT_1S08, WAVE_FORMAT_1M16, WAVE_FORMAT_1S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 22050,
WAVE_FORMAT_2M08, WAVE_FORMAT_2S08, WAVE_FORMAT_2M16, WAVE_FORMAT_2S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 44100,
WAVE_FORMAT_4M08, WAVE_FORMAT_4S08, WAVE_FORMAT_4M16, WAVE_FORMAT_4S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 48000,
WAVE_FORMAT_48M08, WAVE_FORMAT_48S08, WAVE_FORMAT_48M16, WAVE_FORMAT_48S16);
- dwFormats |= CheckFormatSupport(DataRangeAudio, 96000,
WAVE_FORMAT_96M08, WAVE_FORMAT_96S08, WAVE_FORMAT_96M16, WAVE_FORMAT_96S16);
-
-
- wChannels = DataRangeAudio->MaximumChannels;
- dwSupport = WAVECAPS_VOLUME; //FIXME get info from nodes
- }
- }
- }
- DataRange = (PKSDATARANGE)((PUCHAR)DataRange + DataRange->FormatSize);
- }
-
- DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats;
- DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport;
- DeviceInfo->u.WaveOutCaps.wChannels = wChannels;
-
- ExFreePool(MultipleItem);
+ }
+ else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE ||
DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo,
DeviceExtension);
+ }
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
@@ -846,6 +156,7 @@
return STATUS_SUCCESS;
}
}
+
SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
return STATUS_INVALID_PARAMETER;
}
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] Fri Oct 2 12:57:24
2009
@@ -78,6 +78,8 @@
Status = WdmAudMixerInitialize(DeviceObject);
DPRINT("WdmAudMixerInitialize Status %x\n", Status);
+ Status = WdmAudWaveInitialize(DeviceObject);
+ DPRINT("WdmAudWaveInitialize Status %x\n", Status);
DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c [iso-8859-1] Fri Oct 2 12:57:24
2009
@@ -21,6 +21,7 @@
const GUID KSNODETYPE_CHORUS = {0x20173F20L, 0xC559, 0x11D0, {0x8A, 0x2B, 0x00,
0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
const GUID KSNODETYPE_REVERB = {0xEF0328E0L, 0xC558, 0x11D0, {0x8A, 0x2B, 0x00,
0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
const GUID KSNODETYPE_SUPERMIX = {0xE573ADC0L, 0xC555, 0x11D0, {0x8A, 0x2B, 0x00,
0xA0, 0xC9, 0x25, 0x5A, 0xC1}};
+const GUID KSNODETYPE_SUM = {0xDA441A60L, 0xC556, 0x11D0, {0x8A, 0x2B, 0x00, 0xA0, 0xC9,
0x25, 0x5A, 0xC1}};
#define DESTINATION_LINE 0xFFFF0000
@@ -62,7 +63,7 @@
while(Entry != &MixerInfo->LineList)
{
MixerLineSrc = (LPMIXERLINE_EXT)CONTAINING_RECORD(Entry, MIXERLINE_EXT, Entry);
- DPRINT("dwLineID %x dwLineID %x\n", MixerLineSrc->Line.dwLineID,
dwLineID);
+ DPRINT1("dwLineID %x dwLineID %x\n", MixerLineSrc->Line.dwLineID,
dwLineID);
if (MixerLineSrc->Line.dwLineID == dwLineID)
return MixerLineSrc;
@@ -719,67 +720,369 @@
return Pins;
}
+PKSTOPOLOGY_CONNECTION
+GetConnectionByIndex(
+ IN PKSMULTIPLE_ITEM MultipleItem,
+ IN ULONG Index)
+{
+ PKSTOPOLOGY_CONNECTION Descriptor;
+
+ ASSERT(Index < MultipleItem->Count);
+
+ Descriptor = (PKSTOPOLOGY_CONNECTION)(MultipleItem + 1);
+ return &Descriptor[Index];
+}
+
+LPGUID
+GetNodeType(
+ IN PKSMULTIPLE_ITEM MultipleItem,
+ IN ULONG Index)
+{
+ LPGUID NodeType;
+
+ ASSERT(Index < MultipleItem->Count);
+
+ NodeType = (LPGUID)(MultipleItem + 1);
+ return &NodeType[Index];
+}
+
+NTSTATUS
+GetControlsFromPinByConnectionIndex(
+ IN PKSMULTIPLE_ITEM NodeConnections,
+ IN PKSMULTIPLE_ITEM NodeTypes,
+ IN ULONG bUpDirection,
+ IN ULONG NodeConnectionIndex,
+ OUT PULONG Nodes)
+{
+ PKSTOPOLOGY_CONNECTION CurConnection;
+ LPGUID NodeType;
+ ULONG NodeIndex;
+ NTSTATUS Status;
+ ULONG NodeConnectionCount, Index;
+ PULONG NodeConnection;
+
+
+ /* get current connection */
+ CurConnection = GetConnectionByIndex(NodeConnections, NodeConnectionIndex);
+
+ if (bUpDirection)
+ NodeIndex = CurConnection->FromNode;
+ else
+ NodeIndex = CurConnection->ToNode;
+
+ /* get target node type of current connection */
+ NodeType = GetNodeType(NodeTypes, NodeIndex);
+
+ if (IsEqualGUIDAligned(NodeType, &KSNODETYPE_SUM) || IsEqualGUIDAligned(NodeType,
&KSNODETYPE_MUX))
+ {
+ if (bUpDirection)
+ {
+ /* add the sum / mux node to destination line */
+ //Nodes[NodeIndex] = TRUE;
+ }
+
+ return STATUS_SUCCESS;
+ }
+
+ /* now add the node */
+ Nodes[NodeIndex] = TRUE;
+
+
+ /* get all node indexes referenced by that node */
+ if (bUpDirection)
+ {
+ Status = GetNodeIndexes(NodeConnections, NodeIndex, TRUE, FALSE,
&NodeConnectionCount, &NodeConnection);
+ }
+ else
+ {
+ Status = GetNodeIndexes(NodeConnections, NodeIndex, TRUE, TRUE,
&NodeConnectionCount, &NodeConnection);
+ }
+
+ if (NT_SUCCESS(Status))
+ {
+ for(Index = 0; Index < NodeConnectionCount; Index++)
+ {
+ /* iterate recursively into the nodes */
+ Status = GetControlsFromPinByConnectionIndex(NodeConnections, NodeTypes,
bUpDirection, NodeConnection[Index], Nodes);
+ ASSERT(Status == STATUS_SUCCESS);
+ }
+ /* free node connection indexes */
+ ExFreePool(NodeConnection);
+ }
+
+ return Status;
+}
+
+NTSTATUS
+GetControlsFromPin(
+ IN PKSMULTIPLE_ITEM NodeConnections,
+ IN PKSMULTIPLE_ITEM NodeTypes,
+ IN ULONG PinId,
+ IN ULONG bUpDirection,
+ OUT PULONG Nodes)
+{
+ ULONG NodeConnectionCount, Index;
+ NTSTATUS Status;
+ PULONG NodeConnection;
+
+ /* sanity check */
+ ASSERT(PinId != (ULONG)-1);
+
+ /* get all node indexes referenced by that pin */
+ if (bUpDirection)
+ Status = GetNodeIndexes(NodeConnections, PinId, FALSE, FALSE,
&NodeConnectionCount, &NodeConnection);
+ else
+ Status = GetNodeIndexes(NodeConnections, PinId, FALSE, TRUE,
&NodeConnectionCount, &NodeConnection);
+
+ for(Index = 0; Index < NodeConnectionCount; Index++)
+ {
+ /* get all associated controls */
+ Status = GetControlsFromPinByConnectionIndex(NodeConnections, NodeTypes,
bUpDirection, NodeConnection[Index], Nodes);
+ }
+
+ ExFreePool(NodeConnection);
+
+ return Status;
+}
+
+NTSTATUS
+AddMixerControl(
+ IN LPMIXER_INFO MixerInfo,
+ IN PFILE_OBJECT FileObject,
+ IN PKSMULTIPLE_ITEM NodeTypes,
+ IN ULONG NodeIndex,
+ OUT LPMIXERCONTROLW MixerControl)
+{
+ LPGUID NodeType;
+ KSP_NODE Node;
+ ULONG BytesReturned;
+ NTSTATUS Status;
+ LPWSTR Name;
+
+
+ /* initialize mixer control */
+ MixerControl->cbStruct = sizeof(MIXERCONTROLW);
+ MixerControl->dwControlID = MixerInfo->ControlId;
+
+ /* get node type */
+ NodeType = GetNodeType(NodeTypes, NodeIndex);
+ /* store control type */
+ MixerControl->dwControlType = GetControlTypeFromTopologyNode(NodeType);
+
+ MixerControl->fdwControl = MIXERCONTROL_CONTROLF_UNIFORM; //FIXME
+ MixerControl->cMultipleItems = 0; //FIXME
+
+ if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_MUTE)
+ {
+ MixerControl->Bounds.dwMinimum = 0;
+ MixerControl->Bounds.dwMaximum = 1;
+ }
+ else if (MixerControl->dwControlType == MIXERCONTROL_CONTROLTYPE_VOLUME)
+ {
+ MixerControl->Bounds.dwMinimum = 0;
+ MixerControl->Bounds.dwMaximum = 0xFFFF;
+ MixerControl->Metrics.cSteps = 0xC0; //FIXME
+ }
+
+ /* setup request to retrieve name */
+ Node.NodeId = NodeIndex;
+ Node.Property.Id = KSPROPERTY_TOPOLOGY_NAME;
+ Node.Property.Flags = KSPROPERTY_TYPE_GET;
+ Node.Property.Set = KSPROPSETID_Topology;
+ Node.Reserved = 0;
+
+ /* get node name size */
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
(PVOID)&Node, sizeof(KSP_NODE), NULL, 0, &BytesReturned);
+
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ ASSERT(BytesReturned != 0);
+ Name = ExAllocatePool(NonPagedPool, BytesReturned);
+ if (!Name)
+ {
+ /* not enough memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* get node name */
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
(PVOID)&Node, sizeof(KSP_NODE), (LPVOID)Name, BytesReturned, &BytesReturned);
+ if (NT_SUCCESS(Status))
+ {
+ RtlMoveMemory(MixerControl->szShortName, Name,
(min(MIXER_SHORT_NAME_CHARS, wcslen(Name)+1)) * sizeof(WCHAR));
+ MixerControl->szShortName[MIXER_SHORT_NAME_CHARS-1] = L'\0';
+
+ RtlMoveMemory(MixerControl->szName, Name, (min(MIXER_LONG_NAME_CHARS,
wcslen(Name)+1)) * sizeof(WCHAR));
+ MixerControl->szName[MIXER_LONG_NAME_CHARS-1] = L'\0';
+ }
+
+ /* free name buffer */
+ ExFreePool(Name);
+ }
+
+ MixerInfo->ControlId++;
+
+ DPRINT("Status %x Name %S\n", Status, MixerControl->szName);
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
AddMixerSourceLine(
IN OUT LPMIXER_INFO MixerInfo,
IN PFILE_OBJECT FileObject,
+ IN PKSMULTIPLE_ITEM NodeConnections,
+ IN PKSMULTIPLE_ITEM NodeTypes,
IN ULONG DeviceIndex,
- IN ULONG PinId)
+ IN ULONG PinId,
+ IN ULONG bBridgePin,
+ IN ULONG bTargetPin)
{
LPMIXERLINE_EXT SrcLine, DstLine;
NTSTATUS Status;
KSP_PIN Pin;
LPWSTR PinName;
GUID NodeType;
- ULONG BytesReturned;
-
- /* allocate src mixer line */
- SrcLine = (LPMIXERLINE_EXT)ExAllocatePool(NonPagedPool, sizeof(MIXERLINE_EXT));
- if (!SrcLine)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- /* zero struct */
- RtlZeroMemory(SrcLine, sizeof(MIXERLINE_EXT));
-
- /* initialize mixer src line */
- SrcLine->DeviceIndex = DeviceIndex;
- SrcLine->PinId = PinId;
- SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
+ ULONG BytesReturned, ControlCount, Index;
+ PULONG Nodes;
+
+ if (!bTargetPin)
+ {
+ /* allocate src mixer line */
+ SrcLine = (LPMIXERLINE_EXT)ExAllocatePool(NonPagedPool, sizeof(MIXERLINE_EXT));
+
+ if (!SrcLine)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* zero struct */
+ RtlZeroMemory(SrcLine, sizeof(MIXERLINE_EXT));
+
+ }
+ else
+ {
+ ASSERT(!IsListEmpty(&MixerInfo->LineList));
+ SrcLine = GetSourceMixerLineByLineId(MixerInfo, DESTINATION_LINE);
+ }
/* get destination line */
DstLine = GetSourceMixerLineByLineId(MixerInfo, DESTINATION_LINE);
-
- /* initialize mixer destination line */
- SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
- SrcLine->Line.dwDestination = 0;
- SrcLine->Line.dwSource = DstLine->Line.cConnections;
- SrcLine->Line.dwLineID = (DstLine->Line.cConnections * 0x10000);
- SrcLine->Line.fdwLine = MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE;
- SrcLine->Line.dwUser = 0;
- SrcLine->Line.cChannels = DstLine->Line.cChannels;
- SrcLine->Line.cConnections = 0;
- SrcLine->Line.cControls = 1; //FIXME
-
- //HACK
- SrcLine->LineControls = ExAllocatePool(NonPagedPool, SrcLine->Line.cControls *
sizeof(MIXERCONTROLW));
- if (!SrcLine->LineControls)
+ ASSERT(DstLine);
+
+
+ if (!bTargetPin)
+ {
+ /* initialize mixer src line */
+ SrcLine->DeviceIndex = DeviceIndex;
+ SrcLine->PinId = PinId;
+ SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
+
+ /* initialize mixer destination line */
+ SrcLine->Line.cbStruct = sizeof(MIXERLINEW);
+ SrcLine->Line.dwDestination = 0;
+ SrcLine->Line.dwSource = DstLine->Line.cConnections;
+ SrcLine->Line.dwLineID = (DstLine->Line.cConnections * 0x10000);
+ SrcLine->Line.fdwLine = MIXERLINE_LINEF_ACTIVE | MIXERLINE_LINEF_SOURCE;
+ SrcLine->Line.dwUser = 0;
+ SrcLine->Line.cChannels = DstLine->Line.cChannels;
+ SrcLine->Line.cConnections = 0;
+ SrcLine->Line.Target.dwType = 1;
+ SrcLine->Line.Target.dwDeviceID = DstLine->Line.Target.dwDeviceID;
+ SrcLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
+ SrcLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
+ SrcLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
+ wcscpy(SrcLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
+
+ }
+
+ /* allocate a node arrary */
+ Nodes = ExAllocatePool(NonPagedPool, sizeof(ULONG) * NodeTypes->Count);
+
+ if (!Nodes)
{
/* not enough memory */
- ExFreePool(SrcLine);
+ if (!bTargetPin)
+ {
+ ExFreePool(SrcLine);
+ }
return STATUS_INSUFFICIENT_RESOURCES;
}
- /* clear line controls */
- RtlZeroMemory(SrcLine->LineControls, sizeof(MIXERCONTROLW));
-
- /* fill in pseudo mixer control */
- SrcLine->LineControls->dwControlID = 1; //FIXME
- SrcLine->LineControls->cbStruct = sizeof(MIXERCONTROLW);
- SrcLine->LineControls->fdwControl = 0;
- SrcLine->LineControls->cMultipleItems = 0;
- wcscpy(SrcLine->LineControls->szName, L"test");
- wcscpy(SrcLine->LineControls->szShortName, L"test");
-
+ /* clear nodes array */
+ RtlZeroMemory(Nodes, sizeof(ULONG) * NodeTypes->Count);
+
+ Status = GetControlsFromPin(NodeConnections, NodeTypes, PinId, bTargetPin, Nodes);
+ if (!NT_SUCCESS(Status))
+ {
+ /* something went wrong */
+ if (!bTargetPin)
+ {
+ ExFreePool(SrcLine);
+ }
+ ExFreePool(Nodes);
+ return Status;
+ }
+
+ /* now count all nodes controlled by that pin */
+ ControlCount = 0;
+ for(Index = 0; Index < NodeTypes->Count; Index++)
+ {
+ if (Nodes[Index])
+ ControlCount++;
+ }
+
+ /* now allocate the line controls */
+ if (ControlCount)
+ {
+ SrcLine->LineControls = ExAllocatePool(NonPagedPool, sizeof(MIXERCONTROLW) *
ControlCount);
+
+ if (!SrcLine->LineControls)
+ {
+ /* no memory available */
+ if (!bTargetPin)
+ {
+ ExFreePool(SrcLine);
+ }
+ ExFreePool(Nodes);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ SrcLine->NodeIds = ExAllocatePool(NonPagedPool, sizeof(ULONG) *
ControlCount);
+ if (!SrcLine->NodeIds)
+ {
+ /* no memory available */
+ ExFreePool(SrcLine->LineControls);
+ if (!bTargetPin)
+ {
+ ExFreePool(SrcLine);
+ }
+ ExFreePool(Nodes);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* zero line controls */
+ RtlZeroMemory(SrcLine->LineControls, sizeof(MIXERCONTROLW) * ControlCount);
+ RtlZeroMemory(SrcLine->NodeIds, sizeof(ULONG) * ControlCount);
+
+ ControlCount = 0;
+ for(Index = 0; Index < NodeTypes->Count; Index++)
+ {
+ if (Nodes[Index])
+ {
+ /* store the node index for retrieving / setting details */
+ SrcLine->NodeIds[ControlCount] = Index;
+
+ Status = AddMixerControl(MixerInfo, FileObject, NodeTypes, Index,
&SrcLine->LineControls[ControlCount]);
+ if (NT_SUCCESS(Status))
+ {
+ /* increment control count on success */
+ ControlCount++;
+ }
+ }
+ }
+ /* store control count */
+ SrcLine->Line.cControls = ControlCount;
+ }
+
+ /* release nodes array */
+ ExFreePool(Nodes);
/* get pin category */
Pin.PinId = PinId;
@@ -831,17 +1134,12 @@
}
}
- SrcLine->Line.Target.dwType = 1;
- SrcLine->Line.Target.dwDeviceID = DstLine->Line.Target.dwDeviceID;
- SrcLine->Line.Target.wMid = MixerInfo->MixCaps.wMid;
- SrcLine->Line.Target.wPid = MixerInfo->MixCaps.wPid;
- SrcLine->Line.Target.vDriverVersion = MixerInfo->MixCaps.vDriverVersion;
- wcscpy(SrcLine->Line.Target.szPname, MixerInfo->MixCaps.szPname);
-
-
/* insert src line */
- InsertTailList(&MixerInfo->LineList, &SrcLine->Entry);
- DstLine->Line.cConnections++;
+ if (!bTargetPin)
+ {
+ InsertTailList(&MixerInfo->LineList, &SrcLine->Entry);
+ DstLine->Line.cConnections++;
+ }
return STATUS_SUCCESS;
}
@@ -851,8 +1149,12 @@
AddMixerSourceLines(
IN OUT LPMIXER_INFO MixerInfo,
IN PFILE_OBJECT FileObject,
+ IN PKSMULTIPLE_ITEM NodeConnections,
+ IN PKSMULTIPLE_ITEM NodeTypes,
IN ULONG DeviceIndex,
IN ULONG PinsCount,
+ IN ULONG BridgePinIndex,
+ IN ULONG TargetPinIndex,
IN PULONG Pins)
{
ULONG Index;
@@ -862,7 +1164,7 @@
{
if (Pins[Index-1])
{
- AddMixerSourceLine(MixerInfo, FileObject, DeviceIndex, Index-1);
+ AddMixerSourceLine(MixerInfo, FileObject, NodeConnections, NodeTypes,
DeviceIndex, Index-1, (Index -1 == BridgePinIndex), (Index -1 == TargetPinIndex));
}
}
return Status;
@@ -987,7 +1289,7 @@
PinsSrcRef[OutConnection->Pin] = TRUE;
}
- Status = AddMixerSourceLines(MixerInfo, FileObject, DeviceIndex,
PinsRefCount, PinsSrcRef);
+ Status = AddMixerSourceLines(MixerInfo, FileObject, NodeConnections,
NodeTypes, DeviceIndex, PinsRefCount, OutConnection->Pin, Index, PinsSrcRef);
ExFreePool(MixerControls);
ExFreePool(PinsSrcRef);
@@ -1045,10 +1347,6 @@
if (!DestinationLine)
return STATUS_INSUFFICIENT_RESOURCES;
- /* initialize mixer info */
- MixerInfo->hMixer = hDevice;
- MixerInfo->MixerFileObject = FileObject;
-
/* intialize mixer caps */
MixerInfo->MixCaps.wMid = MM_MICROSOFT; //FIXME
MixerInfo->MixCaps.wPid = MM_PID_UNMAPPED; //FIXME
@@ -1083,7 +1381,6 @@
DestinationLine->Line.dwUser = 0;
DestinationLine->Line.dwComponentType = (bInput == 0 ?
MIXERLINE_COMPONENTTYPE_DST_SPEAKERS : MIXERLINE_COMPONENTTYPE_DST_WAVEIN);
DestinationLine->Line.cChannels = 2; //FIXME
- DestinationLine->Line.cControls = 0; //FIXME
wcscpy(DestinationLine->Line.szShortName, L"Summe"); //FIXME
wcscpy(DestinationLine->Line.szName, L"Summe"); //FIXME
DestinationLine->Line.Target.dwType = (bInput == 0 ? MIXERLINE_TARGETTYPE_WAVEOUT
: MIXERLINE_TARGETTYPE_WAVEIN);
@@ -1411,6 +1708,7 @@
{
LPMIXERLINE_EXT MixerLineSrc;
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ ULONG Index;
/* get device extension */
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -1427,15 +1725,12 @@
ASSERT(MixerLineSrc);
if (MixerLineSrc)
{
- RtlMoveMemory(DeviceInfo->u.MixControls.pamxctrl,
MixerLineSrc->LineControls, min(MixerLineSrc->Line.cControls,
DeviceInfo->u.MixControls.cControls) * sizeof(MIXERLINECONTROLSW));
+ RtlMoveMemory(DeviceInfo->u.MixControls.pamxctrl,
MixerLineSrc->LineControls, min(MixerLineSrc->Line.cControls,
DeviceInfo->u.MixControls.cControls) * sizeof(MIXERCONTROLW));
}
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
}
else if (DeviceInfo->Flags == MIXER_GETLINECONTROLSF_ONEBYTYPE)
{
- DPRINT1("dwLineID %u\n",DeviceInfo->u.MixControls.dwLineID);
- UNIMPLEMENTED
- //HACK
if ((ULONG)DeviceInfo->hDevice >= DeviceExtension->MixerInfoCount)
{
/* invalid parameter */
@@ -1444,11 +1739,18 @@
MixerLineSrc =
GetSourceMixerLineByLineId(&DeviceExtension->MixerInfo[(ULONG)DeviceInfo->hDevice],
DeviceInfo->u.MixControls.dwLineID);
ASSERT(MixerLineSrc);
- if (MixerLineSrc)
- {
- RtlMoveMemory(DeviceInfo->u.MixControls.pamxctrl,
MixerLineSrc->LineControls, min(MixerLineSrc->Line.cControls,
DeviceInfo->u.MixControls.cControls) * sizeof(MIXERLINECONTROLSW));
- }
- return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+
+ Index = 0;
+ for(Index = 0; Index < MixerLineSrc->Line.cControls; Index++)
+ {
+ if (DeviceInfo->u.MixControls.dwControlType ==
MixerLineSrc->LineControls[Index].dwControlType)
+ {
+ RtlMoveMemory(DeviceInfo->u.MixControls.pamxctrl,
&MixerLineSrc->LineControls[Index], sizeof(MIXERCONTROLW));
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+ }
+ }
+ DPRINT1("DeviceInfo->u.MixControls.dwControlType %x not found in Line
%x\n", DeviceInfo->u.MixControls.dwControlType,
DeviceInfo->u.MixControls.dwLineID);
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO));
}
UNIMPLEMENTED;
Added: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/sup.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/sup.c (added)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/sup.c [iso-8859-1] Fri Oct 2 12:57:24
2009
@@ -1,0 +1,300 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/wdm/audio/legacy/wdmaud/sup.c
+ * PURPOSE: System Audio graph builder
+ * PROGRAMMER: Andrew Greenwood
+ * Johannes Anderwald
+ */
+#include "wdmaud.h"
+
+NTSTATUS
+SetIrpIoStatus(
+ IN PIRP Irp,
+ IN NTSTATUS Status,
+ IN ULONG Length)
+{
+ Irp->IoStatus.Information = Length;
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return Status;
+
+}
+
+NTSTATUS
+ClosePin(
+ IN PWDMAUD_CLIENT ClientInfo,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN SOUND_DEVICE_TYPE DeviceType)
+{
+ ULONG Index;
+
+ for(Index = 0; Index < ClientInfo->NumPins; Index++)
+ {
+ if (ClientInfo->hPins[Index].FilterId == FilterId &&
ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle
&& ClientInfo->hPins[Index].Type == DeviceType)
+ {
+ if (ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
+ {
+ ZwClose(ClientInfo->hPins[Index].Handle);
+ }
+ ClientInfo->hPins[Index].Handle = NULL;
+ return Index;
+ }
+ }
+ return MAXULONG;
+}
+
+NTSTATUS
+InsertPinHandle(
+ IN PWDMAUD_CLIENT ClientInfo,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN SOUND_DEVICE_TYPE DeviceType,
+ IN HANDLE PinHandle,
+ IN ULONG FreeIndex)
+{
+ PWDMAUD_HANDLE Handles;
+
+ if (FreeIndex != MAXULONG)
+ {
+ /* re-use a free index */
+ ClientInfo->hPins[FreeIndex].Handle = PinHandle;
+ ClientInfo->hPins[FreeIndex].FilterId = FilterId;
+ ClientInfo->hPins[FreeIndex].PinId = PinId;
+ ClientInfo->hPins[FreeIndex].Type = DeviceType;
+
+ return STATUS_SUCCESS;
+ }
+
+ Handles = ExAllocatePool(NonPagedPool, sizeof(WDMAUD_HANDLE) *
(ClientInfo->NumPins+1));
+
+ if (!Handles)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ if (ClientInfo->NumPins)
+ {
+ RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) *
ClientInfo->NumPins);
+ ExFreePool(ClientInfo->hPins);
+ }
+
+ ClientInfo->hPins = Handles;
+ ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
+ ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceType;
+ ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
+ ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
+ ClientInfo->NumPins++;
+
+ return STATUS_SUCCESS;
+}
+
+PKEY_VALUE_PARTIAL_INFORMATION
+ReadKeyValue(
+ IN HANDLE hSubKey,
+ IN PUNICODE_STRING KeyName)
+{
+ NTSTATUS Status;
+ ULONG Length;
+ PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
+
+ /* now query MatchingDeviceId key */
+ Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0,
&Length);
+
+ /* check for success */
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ return NULL;
+
+ /* allocate a buffer for key data */
+ PartialInformation = ExAllocatePool(NonPagedPool, Length);
+
+ if (!PartialInformation)
+ return NULL;
+
+
+ /* now query MatchingDeviceId key */
+ Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation,
PartialInformation, Length, &Length);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(PartialInformation);
+ return NULL;
+ }
+
+ if (PartialInformation->Type != REG_SZ)
+ {
+ /* invalid key type */
+ ExFreePool(PartialInformation);
+ return NULL;
+ }
+
+ return PartialInformation;
+}
+
+
+NTSTATUS
+CompareProductName(
+ IN HANDLE hSubKey,
+ IN LPWSTR PnpName,
+ IN ULONG ProductNameSize,
+ OUT LPWSTR ProductName)
+{
+ PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
+ UNICODE_STRING DriverDescName = RTL_CONSTANT_STRING(L"DriverDesc");
+ UNICODE_STRING MatchingDeviceIdName =
RTL_CONSTANT_STRING(L"MatchingDeviceId");
+ ULONG Length;
+ LPWSTR DeviceName;
+
+ /* read MatchingDeviceId value */
+ PartialInformation = ReadKeyValue(hSubKey, &MatchingDeviceIdName);
+
+ if (!PartialInformation)
+ return STATUS_UNSUCCESSFUL;
+
+
+ /* extract last '&' */
+ DeviceName = wcsrchr((LPWSTR)PartialInformation->Data, L'&');
+ ASSERT(DeviceName);
+ /* terminate it */
+ DeviceName[0] = L'\0';
+
+ Length = wcslen((LPWSTR)PartialInformation->Data);
+
+ DPRINT("DeviceName %S PnpName %S Length %u\n",
(LPWSTR)PartialInformation->Data, PnpName, Length);
+
+ if (_wcsnicmp((LPWSTR)PartialInformation->Data, &PnpName[4], Length))
+ {
+ ExFreePool(PartialInformation);
+ return STATUS_NO_MATCH;
+ }
+
+ /* free buffer */
+ ExFreePool(PartialInformation);
+
+ /* read DriverDescName value */
+ PartialInformation = ReadKeyValue(hSubKey, &DriverDescName);
+
+ if (!PartialInformation)
+ {
+ /* failed to read driver desc key */
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* copy key name */
+ Length = min(ProductNameSize * sizeof(WCHAR), PartialInformation->DataLength);
+ RtlMoveMemory(ProductName, (PVOID)PartialInformation->Data, Length);
+
+ /* zero terminate it */
+ ProductName[ProductNameSize-1] = L'\0';
+
+ /* free buffer */
+ ExFreePool(PartialInformation);
+
+ return STATUS_SUCCESS;
+}
+
+
+
+NTSTATUS
+FindProductName(
+ IN LPWSTR PnpName,
+ IN ULONG ProductNameSize,
+ OUT LPWSTR ProductName)
+{
+ UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
+
+ UNICODE_STRING SubKeyName;
+ WCHAR SubKey[20];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hKey, hSubKey;
+ NTSTATUS Status;
+ ULONG Length, Index;
+ PKEY_FULL_INFORMATION KeyInformation;
+
+ for(Index = 0; Index < wcslen(PnpName); Index++)
+ {
+ if (PnpName[Index] == '#')
+ PnpName[Index] = L'\\';
+ }
+
+
+ /* initialize key attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF, NULL, NULL);
+
+ /* open the key */
+ Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* query num of subkeys */
+ Status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &Length);
+
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ DPRINT1("ZwQueryKey failed with %x\n", Status);
+ /* failed */
+ ZwClose(hKey);
+ return Status;
+ }
+
+ /* allocate key information struct */
+ KeyInformation = ExAllocatePool(NonPagedPool, Length);
+ if (!KeyInformation)
+ {
+ /* no memory */
+ ZwClose(hKey);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* query num of subkeys */
+ Status = ZwQueryKey(hKey, KeyFullInformation, (PVOID)KeyInformation, Length,
&Length);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwQueryKey failed with %x\n", Status);
+ ExFreePool(KeyInformation);
+ ZwClose(hKey);
+ return Status;
+ }
+
+ /* now iterate through all subkeys */
+ for(Index = 0; Index < KeyInformation->SubKeys; Index++)
+ {
+ /* subkeys are always in the format 0000-XXXX */
+ swprintf(SubKey, L"%04u", Index);
+
+ /* initialize subkey name */
+ RtlInitUnicodeString(&SubKeyName, SubKey);
+
+ /* initialize key attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &SubKeyName,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF, hKey, NULL);
+
+ /* open the sub key */
+ Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
+
+ /* check for success */
+ if (NT_SUCCESS(Status))
+ {
+ /* compare product name */
+ Status = CompareProductName(hSubKey, PnpName, ProductNameSize, ProductName);
+
+ /* close subkey */
+ ZwClose(hSubKey);
+
+ if (NT_SUCCESS(Status))
+ break;
+ }
+ }
+
+ /* free buffer */
+ ExFreePool(KeyInformation);
+
+ /* close key */
+ ZwClose(hKey);
+
+ /* no matching key found */
+ return Status;
+}
+
Propchange: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/sup.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wave.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wave.c (added)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wave.c [iso-8859-1] Fri Oct 2 12:57:24
2009
@@ -1,0 +1,756 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/wdm/audio/legacy/wdmaud/wave.c
+ * PURPOSE: Wave Out enumeration
+ * PROGRAMMER: Andrew Greenwood
+ * Johannes Anderwald
+ */
+#include "wdmaud.h"
+
+
+typedef struct
+{
+ ULONG SampleRate;
+ ULONG Bit8Mono;
+ ULONG Bit8Stereo;
+ ULONG Bit16Mono;
+ ULONG Bit16Stereo;
+}AUDIO_RANGE;
+
+#define AUDIO_TEST_RANGE (5)
+
+static AUDIO_RANGE TestRange[AUDIO_TEST_RANGE] =
+{
+ {
+ 11025,
+ WAVE_FORMAT_1M08,
+ WAVE_FORMAT_1S08,
+ WAVE_FORMAT_1M16,
+ WAVE_FORMAT_1S16
+ },
+ {
+ 22050,
+ WAVE_FORMAT_2M08,
+ WAVE_FORMAT_2S08,
+ WAVE_FORMAT_2M16,
+ WAVE_FORMAT_2S16
+ },
+ {
+ 44100,
+ WAVE_FORMAT_4M08,
+ WAVE_FORMAT_4S08,
+ WAVE_FORMAT_4M16,
+ WAVE_FORMAT_4S16
+ },
+ {
+ 48000,
+ WAVE_FORMAT_48M08,
+ WAVE_FORMAT_48S08,
+ WAVE_FORMAT_48M16,
+ WAVE_FORMAT_48S16
+ },
+ {
+ 96000,
+ WAVE_FORMAT_96M08,
+ WAVE_FORMAT_96S08,
+ WAVE_FORMAT_96M16,
+ WAVE_FORMAT_96S16
+ }
+};
+
+LPWAVE_INFO
+AllocateWaveInfo()
+{
+ /* allocate wav info */
+ LPWAVE_INFO WaveOutInfo = ExAllocatePool(NonPagedPool, sizeof(WAVE_INFO));
+ if (!WaveOutInfo)
+ return NULL;
+
+ /* zero wave info struct */
+ RtlZeroMemory(WaveOutInfo, sizeof(WAVE_INFO));
+
+ return WaveOutInfo;
+}
+
+PKSPIN_CONNECT
+AllocatePinConnect(
+ ULONG DataFormatSize)
+{
+ PKSPIN_CONNECT Connect = ExAllocatePool(NonPagedPool, sizeof(KSPIN_CONNECT) +
DataFormatSize);
+ if (!Connect)
+ return NULL;
+
+ /* zero pin connect struct */
+ RtlZeroMemory(Connect, sizeof(KSPIN_CONNECT) + DataFormatSize);
+
+ return Connect;
+}
+
+NTSTATUS
+GetWaveInfoByIndexAndType(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG DeviceIndex,
+ IN SOUND_DEVICE_TYPE DeviceType,
+ OUT LPWAVE_INFO *OutWaveInfo)
+{
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ ULONG Index = 0;
+ PLIST_ENTRY Entry, ListHead;
+ LPWAVE_INFO WaveInfo;
+
+ /* get device extension */
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ if (DeviceType == WAVE_IN_DEVICE_TYPE)
+ ListHead = &DeviceExtension->WaveInList;
+ else
+ ListHead = &DeviceExtension->WaveOutList;
+
+ /* get first entry */
+ Entry = ListHead->Flink;
+
+ while(Entry != ListHead)
+ {
+ WaveInfo = (LPWAVE_INFO)CONTAINING_RECORD(Entry, WAVE_INFO, Entry);
+
+ if (Index == DeviceIndex)
+ {
+ *OutWaveInfo = WaveInfo;
+ return STATUS_SUCCESS;
+ }
+ Index++;
+ Entry = Entry->Flink;
+ }
+
+ return STATUS_NOT_FOUND;
+}
+
+
+VOID
+InitializePinConnect(
+ IN OUT PKSPIN_CONNECT PinConnect,
+ IN ULONG PinId)
+{
+ PinConnect->Interface.Set = KSINTERFACESETID_Standard;
+ PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
+ PinConnect->Interface.Flags = 0;
+ PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
+ PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
+ PinConnect->Medium.Flags = 0;
+ PinConnect->PinToHandle = NULL;
+ PinConnect->PinId = PinId;
+ PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
+ PinConnect->Priority.PrioritySubClass = 1;
+}
+
+VOID
+InitializeDataFormat(
+ IN PKSDATAFORMAT_WAVEFORMATEX DataFormat,
+ LPWAVEFORMATEX WaveFormatEx)
+{
+
+ DataFormat->WaveFormatEx.wFormatTag = WaveFormatEx->wFormatTag;
+ DataFormat->WaveFormatEx.nChannels = WaveFormatEx->nChannels;
+ DataFormat->WaveFormatEx.nSamplesPerSec = WaveFormatEx->nSamplesPerSec;
+ DataFormat->WaveFormatEx.nBlockAlign = WaveFormatEx->nBlockAlign;
+ DataFormat->WaveFormatEx.nAvgBytesPerSec = WaveFormatEx->nAvgBytesPerSec;
+ DataFormat->WaveFormatEx.wBitsPerSample = WaveFormatEx->wBitsPerSample;
+ DataFormat->WaveFormatEx.cbSize = 0;
+ DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
+ DataFormat->DataFormat.Flags = 0;
+ DataFormat->DataFormat.Reserved = 0;
+ DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
+
+ DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
+ DataFormat->DataFormat.SampleSize = 4;
+}
+
+
+NTSTATUS
+AttachToVirtualAudioDevice(
+ IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+ IN ULONG VirtualDeviceId)
+{
+ ULONG BytesReturned;
+ SYSAUDIO_INSTANCE_INFO InstanceInfo;
+
+ /* setup property request */
+ InstanceInfo.Property.Set = KSPROPSETID_Sysaudio;
+ InstanceInfo.Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO;
+ InstanceInfo.Property.Flags = KSPROPERTY_TYPE_SET;
+ InstanceInfo.Flags = 0;
+ InstanceInfo.DeviceNumber = VirtualDeviceId;
+
+ /* attach to virtual device */
+ return KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0,
&BytesReturned);
+
+}
+
+NTSTATUS
+GetAudioPinDataRanges(
+ IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN OUT PKSMULTIPLE_ITEM * OutMultipleItem)
+{
+ KSP_PIN PinProperty;
+ ULONG BytesReturned = 0;
+ NTSTATUS Status;
+ PKSMULTIPLE_ITEM MultipleItem;
+
+ /* retrieve size of data ranges buffer */
+ PinProperty.Reserved = FilterId;
+ PinProperty.PinId = PinId;
+ PinProperty.Property.Set = KSPROPSETID_Pin;
+ PinProperty.Property.Id = KSPROPERTY_PIN_DATARANGES;
+ PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
+
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)NULL, 0,
&BytesReturned);
+ if (Status != STATUS_MORE_ENTRIES)
+ {
+ return Status;
+ }
+
+ MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
+ if (!MultipleItem)
+ {
+ /* not enough memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)MultipleItem,
BytesReturned, &BytesReturned);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ ExFreePool(MultipleItem);
+ return Status;
+ }
+
+ /* save result */
+ *OutMultipleItem = MultipleItem;
+ return Status;
+}
+
+NTSTATUS
+FindAudioDataRange(
+ PKSMULTIPLE_ITEM MultipleItem,
+ PKSDATARANGE_AUDIO * OutDataRangeAudio)
+{
+ ULONG Index;
+ PKSDATARANGE_AUDIO DataRangeAudio;
+ PKSDATARANGE DataRange;
+
+ DataRange = (PKSDATARANGE) (MultipleItem + 1);
+ for(Index = 0; Index < MultipleItem->Count; Index++)
+ {
+ if (DataRange->FormatSize == sizeof(KSDATARANGE_AUDIO))
+ {
+ DataRangeAudio = (PKSDATARANGE_AUDIO)DataRange;
+ if (IsEqualGUIDAligned(&DataRangeAudio->DataRange.MajorFormat,
&KSDATAFORMAT_TYPE_AUDIO) &&
+ IsEqualGUIDAligned(&DataRangeAudio->DataRange.SubFormat,
&KSDATAFORMAT_SUBTYPE_PCM) &&
+ IsEqualGUIDAligned(&DataRangeAudio->DataRange.Specifier,
&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
+ {
+ DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max
Channel %u\n", DataRangeAudio->MinimumSampleFrequency,
DataRangeAudio->MaximumSampleFrequency,
+
DataRangeAudio->MinimumBitsPerSample, DataRangeAudio->MaximumBitsPerSample,
DataRangeAudio->MaximumChannels);
+ *OutDataRangeAudio = DataRangeAudio;
+ return STATUS_SUCCESS;
+ }
+ }
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+NTAPI
+OpenWavePin(
+ IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN LPWAVEFORMATEX WaveFormatEx,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE PinHandle)
+{
+ PKSPIN_CONNECT PinConnect;
+ PKSDATAFORMAT_WAVEFORMATEX DataFormat;
+ NTSTATUS Status;
+
+ /* allocate pin connect */
+ PinConnect = AllocatePinConnect(sizeof(KSDATAFORMAT_WAVEFORMATEX));
+ if (!PinConnect)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* initialize pin connect struct */
+ InitializePinConnect(PinConnect, PinId);
+
+ /* get offset to dataformat */
+ DataFormat = (PKSDATAFORMAT_WAVEFORMATEX) (PinConnect + 1);
+ /* initialize with requested wave format */
+ InitializeDataFormat(DataFormat, WaveFormatEx);
+
+ /* first attach to the virtual device */
+ Status = AttachToVirtualAudioDevice(DeviceExtension, FilterId);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ ExFreePool(PinConnect);
+ return Status;
+ }
+
+ /* now create the pin */
+ Status = KsCreatePin(DeviceExtension->hSysAudio, PinConnect, DesiredAccess,
PinHandle);
+
+ /* free create info */
+ ExFreePool(PinConnect);
+
+ return Status;
+}
+
+ULONG
+GetPinInstanceCount(
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+ ULONG FilterId,
+ ULONG PinId)
+{
+ KSP_PIN PinRequest;
+ KSPIN_CINSTANCES PinInstances;
+ ULONG BytesReturned;
+ NTSTATUS Status;
+
+ /* query the instance count */
+ PinRequest.Reserved = FilterId;
+ PinRequest.PinId = PinId;
+ PinRequest.Property.Set = KSPROPSETID_Pin;
+ PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
+ PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
+
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances,
sizeof(KSPIN_CINSTANCES), &BytesReturned);
+ ASSERT(Status == STATUS_SUCCESS);
+ return PinInstances.CurrentCount;
+}
+
+
+NTSTATUS
+CheckSampleFormat(
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+ LPWAVE_INFO WaveInfo,
+ ULONG SampleRate,
+ ULONG NumChannels,
+ ULONG BitsPerSample)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+#if 0
+
+ WAVEFORMATEX WaveFormat;
+ HANDLE PinHandle;
+
+ /* clear wave format */
+ RtlZeroMemory(&WaveFormat, sizeof(WAVEFORMATEX));
+
+ WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
+ WaveFormat.nChannels = NumChannels;
+ WaveFormat.nSamplesPerSec = SampleRate;
+ WaveFormat.nAvgBytesPerSec = SampleRate * NumChannels * (BitsPerSample/8);
+ WaveFormat.nBlockAlign = (NumChannels * BitsPerSample) / 8;
+ WaveFormat.wBitsPerSample = BitsPerSample;
+ WaveFormat.cbSize = sizeof(WAVEFORMATEX);
+
+ Status = OpenWavePin(DeviceExtension, WaveInfo->FilterId, WaveInfo->PinId,
&WaveFormat, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+
+ if (NT_SUCCESS(Status))
+ {
+ /* success */
+ ZwClose(PinHandle);
+
+ while(GetPinInstanceCount(DeviceExtension, WaveInfo->FilterId,
WaveInfo->PinId))
+ KeStallExecutionProcessor(5);
+ }
+
+ DPRINT("SampleRate %u BitsPerSample %u NumChannels %u Status %x bInput
%u\n", SampleRate, BitsPerSample, NumChannels, Status, WaveInfo->bInput);
+#endif
+
+
+ return Status;
+}
+
+
+NTSTATUS
+CheckFormat(
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+ PKSDATARANGE_AUDIO DataRangeAudio,
+ LPWAVE_INFO WaveInfo)
+{
+ ULONG Index, SampleFrequency;
+ ULONG Result = 0;
+ NTSTATUS Status;
+
+ for(Index = 0; Index < AUDIO_TEST_RANGE; Index++)
+ {
+ SampleFrequency = TestRange[Index].SampleRate;
+
+ if (DataRangeAudio->MinimumSampleFrequency <= SampleFrequency &&
DataRangeAudio->MaximumSampleFrequency >= SampleFrequency)
+ {
+ /* the audio adapter supports the sample frequency */
+ if (DataRangeAudio->MinimumBitsPerSample <= 8 &&
DataRangeAudio->MaximumBitsPerSample >= 8)
+ {
+ /* check if pin supports the sample rate in 8-Bit Mono */
+ Status = CheckSampleFormat(DeviceExtension, WaveInfo, SampleFrequency, 1,
8);
+ if (NT_SUCCESS(Status))
+ {
+ Result |= TestRange[Index].Bit8Mono;
+ }
+
+ if (DataRangeAudio->MaximumChannels > 1)
+ {
+ /* check if pin supports the sample rate in 8-Bit Stereo */
+ Status = CheckSampleFormat(DeviceExtension, WaveInfo,
SampleFrequency, 2, 8);
+ if (NT_SUCCESS(Status))
+ {
+ Result |= TestRange[Index].Bit8Stereo;
+ }
+ }
+ }
+
+ if (DataRangeAudio->MinimumBitsPerSample <= 16 &&
DataRangeAudio->MaximumBitsPerSample >= 16)
+ {
+ /* check if pin supports the sample rate in 16-Bit Mono */
+ Status = CheckSampleFormat(DeviceExtension, WaveInfo, SampleFrequency, 1,
16);
+ if (NT_SUCCESS(Status))
+ {
+ Result |= TestRange[Index].Bit16Mono;
+ }
+
+ if (DataRangeAudio->MaximumChannels > 1)
+ {
+ /* check if pin supports the sample rate in 16-Bit Stereo */
+ Status = CheckSampleFormat(DeviceExtension, WaveInfo,
SampleFrequency, 2, 16);
+ if (NT_SUCCESS(Status))
+ {
+ Result |= TestRange[Index].Bit16Stereo;
+ }
+ }
+ }
+ }
+ }
+
+
+ if (WaveInfo->bInput)
+ WaveInfo->u.InCaps.dwFormats = Result;
+ else
+ WaveInfo->u.OutCaps.dwFormats = Result;
+
+ DPRINT("Format %x bInput %u\n", Result, WaveInfo->bInput);
+
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+InitializeWaveInfo(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN ULONG bInput)
+{
+ KSP_PIN PinProperty;
+ KSCOMPONENTID ComponentId;
+ NTSTATUS Status;
+ ULONG BytesReturned;
+ WCHAR DeviceName[MAX_PATH];
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ PKSMULTIPLE_ITEM MultipleItem;
+ PKSDATARANGE_AUDIO DataRangeAudio;
+ LPWAVE_INFO WaveInfo = AllocateWaveInfo();
+
+
+ if (!WaveInfo)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* initialize wave info */
+ WaveInfo->bInput = bInput;
+ WaveInfo->FilterId = FilterId;
+ WaveInfo->PinId = PinId;
+
+ /* setup request to return component id */
+ PinProperty.PinId = FilterId;
+ PinProperty.Property.Set = KSPROPSETID_Sysaudio;
+ PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_COMPONENT_ID;
+ PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
+
+ /* get device extension */
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* query sysaudio for component id */
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)&ComponentId,
sizeof(KSCOMPONENTID), &BytesReturned);
+ if (NT_SUCCESS(Status))
+ {
+ if (bInput)
+ {
+ WaveInfo->u.InCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
+ WaveInfo->u.InCaps.vDriverVersion = MAKELONG(ComponentId.Version,
ComponentId.Revision);
+ }
+ else
+ {
+ WaveInfo->u.OutCaps.wMid = ComponentId.Manufacturer.Data1 - 0xd5a47fa7;
+ WaveInfo->u.OutCaps.vDriverVersion = MAKELONG(ComponentId.Version,
ComponentId.Revision);
+ }
+ }
+ else
+ {
+ /* set up something useful */
+ if (bInput)
+ {
+ WaveInfo->u.InCaps.wMid = MM_MICROSOFT;
+ WaveInfo->u.InCaps.wPid = MM_PID_UNMAPPED;
+ WaveInfo->u.InCaps.vDriverVersion = 1;
+ }
+ else
+ {
+ WaveInfo->u.OutCaps.wMid = MM_MICROSOFT;
+ WaveInfo->u.OutCaps.wPid = MM_PID_UNMAPPED;
+ WaveInfo->u.OutCaps.vDriverVersion = 1;
+ }
+ }
+
+ /* retrieve pnp base name */
+ PinProperty.PinId = FilterId;
+ PinProperty.Property.Set = KSPROPSETID_Sysaudio;
+ PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME;
+ PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
+
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)DeviceName,
sizeof(DeviceName), &BytesReturned);
+ if (NT_SUCCESS(Status))
+ {
+ /* find product name */
+ if (bInput)
+ Status = FindProductName(DeviceName, MAXPNAMELEN,
WaveInfo->u.OutCaps.szPname);
+ else
+ Status = FindProductName(DeviceName, MAXPNAMELEN,
WaveInfo->u.InCaps.szPname);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ if (bInput)
+ WaveInfo->u.OutCaps.szPname[0] = L'\0';
+ else
+ WaveInfo->u.InCaps.szPname[0] = L'\0';
+ }
+ }
+
+ Status = GetAudioPinDataRanges(DeviceExtension, FilterId, PinId, &MultipleItem);
+ if (NT_SUCCESS(Status))
+ {
+ /* find a audio data range */
+ Status = FindAudioDataRange(MultipleItem, &DataRangeAudio);
+
+ if (NT_SUCCESS(Status))
+ {
+ if (bInput)
+ {
+ WaveInfo->u.InCaps.wChannels = DataRangeAudio->MaximumChannels;
+ }
+ else
+ {
+ WaveInfo->u.OutCaps.wChannels = DataRangeAudio->MaximumChannels;
+ }
+ CheckFormat(DeviceExtension, DataRangeAudio, WaveInfo);
+ }
+ ExFreePool(MultipleItem);
+ }
+
+ if (bInput)
+ {
+ InsertTailList(&DeviceExtension->WaveInList, &WaveInfo->Entry);
+ DeviceExtension->WaveInDeviceCount++;
+ }
+ else
+ {
+ InsertTailList(&DeviceExtension->WaveOutList, &WaveInfo->Entry);
+ DeviceExtension->WaveOutDeviceCount++;
+ }
+
+
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+NTAPI
+WdmAudWaveInitialize(
+ IN PDEVICE_OBJECT DeviceObject)
+{
+ KSP_PIN Pin;
+ ULONG Count, BytesReturned, Index, SubIndex, Result, NumPins;
+ NTSTATUS Status;
+ KSPIN_COMMUNICATION Communication;
+ KSPIN_DATAFLOW DataFlow;
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+
+ Pin.Property.Set = KSPROPSETID_Sysaudio;
+ Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT;
+ Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* set wave count to zero */
+ DeviceExtension->WaveInDeviceCount = 0;
+ DeviceExtension->WaveOutDeviceCount = 0;
+
+ /* intialize list head */
+ InitializeListHead(&DeviceExtension->WaveInList);
+ InitializeListHead(&DeviceExtension->WaveOutList);
+
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG),
&BytesReturned);
+ if (!NT_SUCCESS(Status))
+ return STATUS_UNSUCCESSFUL;
+
+ Result = 0;
+ for(Index = 0; Index < Count; Index++)
+ {
+ /* query number of pins */
+ Pin.Reserved = Index; // see sysaudio
+ Pin.Property.Flags = KSPROPERTY_TYPE_GET;
+ Pin.Property.Set = KSPROPSETID_Pin;
+ Pin.Property.Id = KSPROPERTY_PIN_CTYPES;
+ Pin.PinId = 0;
+
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&NumPins, sizeof(ULONG),
&BytesReturned);
+ if (NT_SUCCESS(Status))
+ {
+ /* enumerate now all pins */
+ for(SubIndex = 0; SubIndex < NumPins; SubIndex++)
+ {
+ Pin.PinId = SubIndex;
+ Pin.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
+ Communication = KSPIN_COMMUNICATION_NONE;
+
+ /* get pin communication type */
+ KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&Communication,
sizeof(KSPIN_COMMUNICATION), &BytesReturned);
+
+ Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
+ DataFlow = 0;
+
+ /* get pin dataflow type */
+ KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode,
IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)&DataFlow,
sizeof(KSPIN_DATAFLOW), &BytesReturned);
+
+ if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_IN)
+ {
+ /* found a wave out device */
+ InitializeWaveInfo(DeviceObject, Index, SubIndex, FALSE);
+ }
+ else if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow ==
KSPIN_DATAFLOW_OUT)
+ {
+ /* found a wave in device */
+ InitializeWaveInfo(DeviceObject, Index, SubIndex, TRUE);
+ }
+ }
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+WdmAudControlOpenWave(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo)
+{
+ PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ LPWAVE_INFO WaveInfo;
+ NTSTATUS Status;
+ ACCESS_MASK DesiredAccess = 0;
+ HANDLE PinHandle;
+ ULONG FreeIndex;
+
+ if (DeviceInfo->u.WaveFormatEx.wFormatTag != WAVE_FORMAT_PCM)
+ {
+ DPRINT("FIXME: Only WAVE_FORMAT_PCM is supported RequestFormat %x\n",
DeviceInfo->u.WaveFormatEx.wFormatTag);
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+
+ /* get device extension */
+ DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* find destination wave */
+ Status = GetWaveInfoByIndexAndType(DeviceObject, DeviceInfo->DeviceIndex,
DeviceInfo->DeviceType, &WaveInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to find wave info */
+ DbgBreakPoint();
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+
+ /* close pin handle which uses same virtual audio device id and pin id */
+ FreeIndex = ClosePin(ClientInfo, WaveInfo->FilterId, WaveInfo->PinId,
DeviceInfo->DeviceType);
+
+ /* get desired access */
+ if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+ {
+ DesiredAccess |= GENERIC_READ;
+ }
+ else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+ DesiredAccess |= GENERIC_WRITE;
+ }
+
+ /* now try open the pin */
+ Status = OpenWavePin(DeviceExtension, WaveInfo->FilterId, WaveInfo->PinId,
&DeviceInfo->u.WaveFormatEx, DesiredAccess, &PinHandle);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to open the pin */
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+
+ /* store the handle */
+ Status = InsertPinHandle(ClientInfo, WaveInfo->FilterId, WaveInfo->PinId,
DeviceInfo->DeviceType, PinHandle, FreeIndex);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to insert handle */
+ ZwClose(PinHandle);
+ return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ }
+
+ /* store pin handle */
+ DeviceInfo->hDevice = PinHandle;
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+}
+
+NTSTATUS
+WdmAudWaveCapabilities(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo,
+ IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
+{
+ LPWAVE_INFO WaveInfo;
+ NTSTATUS Status;
+
+ /* find destination wave */
+ Status = GetWaveInfoByIndexAndType(DeviceObject, DeviceInfo->DeviceIndex,
DeviceInfo->DeviceType, &WaveInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to find wave info */
+ DbgBreakPoint();
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
+ {
+ RtlMoveMemory(&DeviceInfo->u.WaveInCaps, &WaveInfo->u.InCaps,
sizeof(WAVEINCAPSW));
+ }
+ else
+ {
+ RtlMoveMemory(&DeviceInfo->u.WaveOutCaps, &WaveInfo->u.OutCaps,
sizeof(WAVEOUTCAPSW));
+ }
+
+ return STATUS_SUCCESS;
+}
+
Propchange: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wave.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Fri Oct 2
12:57:24 2009
@@ -40,19 +40,31 @@
ULONG DeviceIndex;
MIXERLINEW Line;
LPMIXERCONTROLW LineControls;
+ PULONG NodeIds;
}MIXERLINE_EXT, *LPMIXERLINE_EXT;
typedef struct
{
- HANDLE hMixer;
- PFILE_OBJECT MixerFileObject;
-
MIXERCAPSW MixCaps;
LIST_ENTRY LineList;
-
+ ULONG ControlId;
}MIXER_INFO, *LPMIXER_INFO;
+
+
+typedef struct
+{
+ LIST_ENTRY Entry;
+ ULONG FilterId;
+ ULONG PinId;
+ ULONG bInput;
+ union
+ {
+ WAVEOUTCAPSW OutCaps;
+ WAVEINCAPSW InCaps;
+ }u;
+}WAVE_INFO, *LPWAVE_INFO;
typedef struct
@@ -77,6 +89,12 @@
ULONG MixerInfoCount;
LPMIXER_INFO MixerInfo;
+ ULONG WaveInDeviceCount;
+ LIST_ENTRY WaveInList;
+
+ ULONG WaveOutDeviceCount;
+ LIST_ENTRY WaveOutList;
+
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
@@ -87,6 +105,16 @@
}CONTEXT_WRITE, *PCONTEXT_WRITE;
NTSTATUS
+NTAPI
+OpenWavePin(
+ IN PWDMAUD_DEVICE_EXTENSION DeviceExtension,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN LPWAVEFORMATEX WaveFormatEx,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE PinHandle);
+
+NTSTATUS
WdmAudRegisterDeviceInterface(
IN PDEVICE_OBJECT PhysicalDeviceObject,
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
@@ -119,6 +147,14 @@
IN PIRP Irp,
IN PWDMAUD_DEVICE_INFO DeviceInfo,
IN PWDMAUD_CLIENT ClientInfo);
+
+NTSTATUS
+WdmAudControlOpenWave(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo);
+
ULONG
GetNumOfMixerDevices(
@@ -149,6 +185,13 @@
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
NTSTATUS
+WdmAudWaveCapabilities(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PWDMAUD_DEVICE_INFO DeviceInfo,
+ IN PWDMAUD_CLIENT ClientInfo,
+ IN PWDMAUD_DEVICE_EXTENSION DeviceExtension);
+
+NTSTATUS
NTAPI
WdmAudFrameSize(
IN PDEVICE_OBJECT DeviceObject,
@@ -192,5 +235,26 @@
WdmAudMixerInitialize(
IN PDEVICE_OBJECT DeviceObject);
+NTSTATUS
+NTAPI
+WdmAudWaveInitialize(
+ IN PDEVICE_OBJECT DeviceObject);
+
+NTSTATUS
+ClosePin(
+ IN PWDMAUD_CLIENT ClientInfo,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN SOUND_DEVICE_TYPE DeviceType);
+
+NTSTATUS
+InsertPinHandle(
+ IN PWDMAUD_CLIENT ClientInfo,
+ IN ULONG FilterId,
+ IN ULONG PinId,
+ IN SOUND_DEVICE_TYPE DeviceType,
+ IN HANDLE PinHandle,
+ IN ULONG FreeIndex);
+
#endif
Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/w…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.rbuild [iso-8859-1] Fri Oct 2
12:57:24 2009
@@ -7,9 +7,12 @@
<library>ntoskrnl</library>
<library>ks</library>
<library>pseh</library>
+ <library>hal</library>
<file>control.c</file>
<file>deviface.c</file>
<file>entry.c</file>
<file>mixer.c</file>
+ <file>wave.c</file>
+ <file>sup.c</file>
<file>wdmaud.rc</file>
</module>