mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[WDMAUD.DRV]
- Disable traces - Use device name from IOCTL [WDMAUD_KERNEL] - Implement retrieving devicename by looking up in the registry [SYSAUDIO] - Implement KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME - Audio CPL should now show correct audio device name svn path=/trunk/; revision=42759
This commit is contained in:
parent
e453915908
commit
bc5b55fb73
5 changed files with 270 additions and 8 deletions
|
@ -43,7 +43,7 @@ PerformSampleRateConversion(
|
||||||
ULONG NumSamples;
|
ULONG NumSamples;
|
||||||
ULONG NewSamples;
|
ULONG NewSamples;
|
||||||
|
|
||||||
SND_TRACE(L"PerformSampleRateConversion OldRate %u NewRate %u BytesPerSample %u NumChannels %u\n", OldRate, NewRate, BytesPerSample, NumChannels);
|
//SND_TRACE(L"PerformSampleRateConversion OldRate %u NewRate %u BytesPerSample %u NumChannels %u\n", OldRate, NewRate, BytesPerSample, NumChannels);
|
||||||
|
|
||||||
ASSERT(BytesPerSample == 1 || BytesPerSample == 2 || BytesPerSample == 4);
|
ASSERT(BytesPerSample == 1 || BytesPerSample == 2 || BytesPerSample == 4);
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ PerformQualityConversion(
|
||||||
Samples = BufferLength / (OldWidth / 8);
|
Samples = BufferLength / (OldWidth / 8);
|
||||||
//DPRINT("Samples %u BufferLength %u\n", Samples, BufferLength);
|
//DPRINT("Samples %u BufferLength %u\n", Samples, BufferLength);
|
||||||
|
|
||||||
SND_TRACE(L"PerformQualityConversion OldWidth %u NewWidth %u\n", OldWidth, NewWidth);
|
//SND_TRACE(L"PerformQualityConversion OldWidth %u NewWidth %u\n", OldWidth, NewWidth);
|
||||||
|
|
||||||
if (OldWidth == 8 && NewWidth == 16)
|
if (OldWidth == 8 && NewWidth == 16)
|
||||||
{
|
{
|
||||||
|
@ -292,7 +292,7 @@ PerformQualityConversion(
|
||||||
|
|
||||||
for(Index = 0; Index < Samples; Index++)
|
for(Index = 0; Index < Samples; Index++)
|
||||||
{
|
{
|
||||||
Sample = Buffer[Index];
|
Sample = Buffer[Index];// & 0xFF);
|
||||||
Sample *= 2;
|
Sample *= 2;
|
||||||
#ifdef _X86_
|
#ifdef _X86_
|
||||||
Sample = _byteswap_ushort(Sample);
|
Sample = _byteswap_ushort(Sample);
|
||||||
|
|
|
@ -120,6 +120,7 @@ GetWdmDeviceCapabilities(
|
||||||
return TranslateInternalMmResult(Result);
|
return TranslateInternalMmResult(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SND_TRACE(L"WDMAUD Name %S\n", DeviceInfo.u.WaveOutCaps.szPname);
|
||||||
|
|
||||||
/* This is pretty much a big hack right now */
|
/* This is pretty much a big hack right now */
|
||||||
switch ( DeviceType )
|
switch ( DeviceType )
|
||||||
|
@ -131,7 +132,7 @@ GetWdmDeviceCapabilities(
|
||||||
WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
|
WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
|
||||||
|
|
||||||
WaveOutCaps->vDriverVersion = 0x0001;
|
WaveOutCaps->vDriverVersion = 0x0001;
|
||||||
CopyWideString(WaveOutCaps->szPname, UnknownWaveOut);
|
CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
|
||||||
|
|
||||||
WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
|
WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
|
||||||
WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
|
WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
|
||||||
|
@ -141,7 +142,7 @@ GetWdmDeviceCapabilities(
|
||||||
case WAVE_IN_DEVICE_TYPE :
|
case WAVE_IN_DEVICE_TYPE :
|
||||||
{
|
{
|
||||||
LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
|
LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
|
||||||
CopyWideString(WaveInCaps->szPname, UnknownWaveIn);
|
CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
|
||||||
/* TODO... other fields */
|
/* TODO... other fields */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -468,6 +468,212 @@ CheckFormatSupport(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* 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
|
NTSTATUS
|
||||||
WdmAudCapabilities(
|
WdmAudCapabilities(
|
||||||
IN PDEVICE_OBJECT DeviceObject,
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -489,6 +695,7 @@ WdmAudCapabilities(
|
||||||
ULONG dwSupport = 0;
|
ULONG dwSupport = 0;
|
||||||
ULONG FilterId;
|
ULONG FilterId;
|
||||||
ULONG PinId;
|
ULONG PinId;
|
||||||
|
WCHAR DeviceName[MAX_PATH];
|
||||||
|
|
||||||
DPRINT("WdmAudCapabilities entered\n");
|
DPRINT("WdmAudCapabilities entered\n");
|
||||||
|
|
||||||
|
@ -514,6 +721,25 @@ WdmAudCapabilities(
|
||||||
DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision);
|
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.Reserved = DeviceInfo->DeviceIndex;
|
||||||
PinProperty.PinId = PinId;
|
PinProperty.PinId = PinId;
|
||||||
PinProperty.Property.Set = KSPROPSETID_Pin;
|
PinProperty.Property.Set = KSPROPSETID_Pin;
|
||||||
|
@ -575,10 +801,9 @@ WdmAudCapabilities(
|
||||||
DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats;
|
DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats;
|
||||||
DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport;
|
DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport;
|
||||||
DeviceInfo->u.WaveOutCaps.wChannels = wChannels;
|
DeviceInfo->u.WaveOutCaps.wChannels = wChannels;
|
||||||
DeviceInfo->u.WaveOutCaps.szPname[0] = L'\0';
|
|
||||||
|
|
||||||
|
|
||||||
ExFreePool(MultipleItem);
|
ExFreePool(MultipleItem);
|
||||||
|
|
||||||
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
|
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <ksmedia.h>
|
#include <ksmedia.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
|
|
||||||
|
|
|
@ -351,7 +351,7 @@ SysAudioHandleProperty(
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
UNICODE_STRING GuidString;
|
UNICODE_STRING GuidString;
|
||||||
PKSP_PIN Pin;
|
PKSP_PIN Pin;
|
||||||
|
LPWSTR DeviceName;
|
||||||
|
|
||||||
/* access the create item */
|
/* access the create item */
|
||||||
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
|
||||||
|
@ -394,6 +394,39 @@ SysAudioHandleProperty(
|
||||||
}
|
}
|
||||||
else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
|
else if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Sysaudio))
|
||||||
{
|
{
|
||||||
|
if (Property->Id == KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME)
|
||||||
|
{
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))
|
||||||
|
{
|
||||||
|
/* invalid request */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(KSPROPERTY) + sizeof(ULONG));
|
||||||
|
}
|
||||||
|
Index = (PULONG)(Property + 1);
|
||||||
|
|
||||||
|
if (DeviceExtension->NumberOfKsAudioDevices <= *Index)
|
||||||
|
{
|
||||||
|
/* invalid index */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, *Index);
|
||||||
|
ASSERT(Entry != NULL);
|
||||||
|
|
||||||
|
BytesReturned = Entry->DeviceName.Length + sizeof(WCHAR);
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < BytesReturned)
|
||||||
|
{
|
||||||
|
/* too small buffer */
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, BytesReturned);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy device name */
|
||||||
|
DeviceName = (LPWSTR)Irp->UserBuffer;
|
||||||
|
|
||||||
|
RtlMoveMemory(DeviceName, Entry->DeviceName.Buffer, Entry->DeviceName.Length);
|
||||||
|
DeviceName[Entry->DeviceName.Length / sizeof(WCHAR)] = L'\0';
|
||||||
|
return SetIrpIoStatus(Irp, STATUS_SUCCESS, BytesReturned);
|
||||||
|
}
|
||||||
|
|
||||||
if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)
|
if (Property->Id == KSPROPERTY_SYSAUDIO_COMPONENT_ID)
|
||||||
{
|
{
|
||||||
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))
|
||||||
|
|
Loading…
Reference in a new issue