[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:
Johannes Anderwald 2009-08-17 17:23:35 +00:00
parent e453915908
commit bc5b55fb73
5 changed files with 270 additions and 8 deletions

View file

@ -43,7 +43,7 @@ PerformSampleRateConversion(
ULONG NumSamples;
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);
@ -281,7 +281,7 @@ PerformQualityConversion(
Samples = BufferLength / (OldWidth / 8);
//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)
{
@ -292,7 +292,7 @@ PerformQualityConversion(
for(Index = 0; Index < Samples; Index++)
{
Sample = Buffer[Index];
Sample = Buffer[Index];// & 0xFF);
Sample *= 2;
#ifdef _X86_
Sample = _byteswap_ushort(Sample);

View file

@ -120,6 +120,7 @@ GetWdmDeviceCapabilities(
return TranslateInternalMmResult(Result);
}
SND_TRACE(L"WDMAUD Name %S\n", DeviceInfo.u.WaveOutCaps.szPname);
/* This is pretty much a big hack right now */
switch ( DeviceType )
@ -131,7 +132,7 @@ GetWdmDeviceCapabilities(
WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
WaveOutCaps->vDriverVersion = 0x0001;
CopyWideString(WaveOutCaps->szPname, UnknownWaveOut);
CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels;
@ -141,7 +142,7 @@ GetWdmDeviceCapabilities(
case WAVE_IN_DEVICE_TYPE :
{
LPWAVEINCAPS WaveInCaps = (LPWAVEINCAPS) Capabilities;
CopyWideString(WaveInCaps->szPname, UnknownWaveIn);
CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
/* TODO... other fields */
break;
}

View file

@ -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
WdmAudCapabilities(
IN PDEVICE_OBJECT DeviceObject,
@ -489,6 +695,7 @@ WdmAudCapabilities(
ULONG dwSupport = 0;
ULONG FilterId;
ULONG PinId;
WCHAR DeviceName[MAX_PATH];
DPRINT("WdmAudCapabilities entered\n");
@ -514,6 +721,25 @@ WdmAudCapabilities(
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;
@ -575,10 +801,9 @@ WdmAudCapabilities(
DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats;
DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport;
DeviceInfo->u.WaveOutCaps.wChannels = wChannels;
DeviceInfo->u.WaveOutCaps.szPname[0] = L'\0';
ExFreePool(MultipleItem);
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}

View file

@ -9,6 +9,9 @@
#include <debug.h>
#include <ksmedia.h>
#include <mmsystem.h>
#include <stdlib.h>
#include <stdio.h>
#include <wchar.h>
#include "interface.h"

View file

@ -351,7 +351,7 @@ SysAudioHandleProperty(
PKSOBJECT_CREATE_ITEM CreateItem;
UNICODE_STRING GuidString;
PKSP_PIN Pin;
LPWSTR DeviceName;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
@ -394,6 +394,39 @@ SysAudioHandleProperty(
}
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 (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY) + sizeof(ULONG))