[WDMAUD_KERNEL]

- Always set Mute control on first channel
[PORTCLS]
- Rewrite node property handling. Fixes lots of bugs and fixes all winmm_winetest mixer failures

svn path=/trunk/; revision=44323
This commit is contained in:
Johannes Anderwald 2009-11-29 18:56:56 +00:00
parent eeba3408b2
commit f21af7347f
3 changed files with 273 additions and 198 deletions

View file

@ -1243,8 +1243,8 @@ CPortPinWaveCyclic::Init(
m_Port = Port; m_Port = Port;
m_Filter = Filter; m_Filter = Filter;
//DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE));
//DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE));
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -86,48 +86,25 @@ PcHandleDisableEventWithTable(
return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock); return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock);
} }
NTSTATUS NTSTATUS
NTAPI PcHandleGuidNullRequest(
PcHandlePropertyWithTable( IN OUT PIRP Irp,
IN PIRP Irp,
IN ULONG PropertySetCount,
IN PKSPROPERTY_SET PropertySet,
IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
{ {
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
PKSP_NODE Property;
PPCNODE_DESCRIPTOR Node; PPCNODE_DESCRIPTOR Node;
PPCPROPERTY_ITEM PropertyItem; PPCPROPERTY_ITEM PropertyItem;
ULONG Index; PIO_STACK_LOCATION IoStack;
PKSP_NODE Property;
LPGUID Buffer; LPGUID Buffer;
//PULONG Flags; ULONG Count = 0, SubIndex, Index;
PPCPROPERTY_REQUEST PropertyRequest;
KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
/* try first KsPropertyHandler */
Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
if (Status != STATUS_NOT_FOUND)
return Status;
// get current irp stack location // get current irp stack location
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
// access property // access property
Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
// check if this a GUID_NULL request
if (Status == STATUS_NOT_FOUND)
{
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE))
return Status;
// check if its a request for a topology node
if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY))
{
if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
{ {
// request is out of bounds // request is out of bounds
@ -152,8 +129,6 @@ PcHandlePropertyWithTable(
if (!Buffer) if (!Buffer)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
ULONG Count = 0, SubIndex;
PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
{ {
@ -174,6 +149,7 @@ PcHandlePropertyWithTable(
PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
} }
// store result length
Irp->IoStatus.Information = sizeof (GUID) * Count; Irp->IoStatus.Information = sizeof (GUID) * Count;
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count)
{ {
@ -185,17 +161,30 @@ PcHandlePropertyWithTable(
RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count);
FreeItem(Buffer, TAG_PORTCLASS); FreeItem(Buffer, TAG_PORTCLASS);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT | KSPROPERTY_TYPE_TOPOLOGY) ||
Property->Property.Flags == (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_TOPOLOGY) || NTSTATUS
Property->Property.Flags == (KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_TOPOLOGY)) */ PcFindNodePropertyHandler(
{ PIRP Irp,
//UNICODE_STRING GuidString; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor,
OUT PPCPROPERTY_ITEM * OutPropertyItem)
{
PPCNODE_DESCRIPTOR Node;
PPCPROPERTY_ITEM PropertyItem;
PIO_STACK_LOCATION IoStack;
PKSP_NODE Property;
ULONG Index;
// get current irp stack location
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access property
Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount)
{ {
// request is out of bounds // request is out of bounds
Irp->IoStatus.Information = 0; DPRINT("InvalidIndex %u %u\n", Property->NodeId, SubDeviceDescriptor->DeviceDescriptor->NodeCount);
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
@ -208,24 +197,50 @@ PcHandlePropertyWithTable(
return STATUS_NOT_FOUND; return STATUS_NOT_FOUND;
} }
// sanity checks
PC_ASSERT(Node->AutomationTable); PC_ASSERT(Node->AutomationTable);
PC_ASSERT(Node->AutomationTable->PropertyCount); PC_ASSERT(Node->AutomationTable->PropertyCount);
PC_ASSERT(Node->AutomationTable->PropertyItemSize); PC_ASSERT(Node->AutomationTable->PropertyItemSize);
PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
DPRINT("NodeId %u PropertyCount %u\n", Property->NodeId, Node->AutomationTable->PropertyCount);
for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
{ {
if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id)
{ {
if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) //found property handler
{ *OutPropertyItem = PropertyItem;
if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) return STATUS_SUCCESS;
{ }
PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
PULONG Flags = (PULONG)Irp->UserBuffer; }
/* reset flags */ // no handler yet found
DPRINT("NotFound\n");
return STATUS_NOT_FOUND;
}
NTSTATUS
PcNodeBasicSupportHandler(
PIRP Irp,
PPCPROPERTY_ITEM PropertyItem)
{
PULONG Flags;
PIO_STACK_LOCATION IoStack;
PKSPROPERTY_DESCRIPTION Description;
PKSP_NODE Property;
// get current irp stack location
IoStack = IoGetCurrentIrpStackLocation(Irp);
// access property
Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG));
Flags= (PULONG)Irp->UserBuffer;
// reset flags
*Flags = 0; *Flags = 0;
if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) if (PropertyItem->Flags & KSPROPERTY_TYPE_SET)
@ -234,14 +249,15 @@ PcHandlePropertyWithTable(
if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) if (PropertyItem->Flags & KSPROPERTY_TYPE_GET)
*Flags |= KSPROPERTY_TYPE_GET; *Flags |= KSPROPERTY_TYPE_GET;
// store result length
Irp->IoStatus.Information = sizeof(ULONG); Irp->IoStatus.Information = sizeof(ULONG);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION))
{ {
/* get output buffer */ // get output buffer
PKSPROPERTY_DESCRIPTION Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer;
/* store result */ // store result
Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION);
Description->PropTypeSet.Set = KSPROPTYPESETID_General; Description->PropTypeSet.Set = KSPROPTYPESETID_General;
Description->PropTypeSet.Id = 0; Description->PropTypeSet.Id = 0;
@ -252,15 +268,63 @@ PcHandlePropertyWithTable(
Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION);
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
}
NTSTATUS
PcHandleNodePropertyRequest(
PIRP Irp,
IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
{
PIO_STACK_LOCATION IoStack;
PPCPROPERTY_ITEM PropertyItem;
PPCPROPERTY_REQUEST PropertyRequest;
PKSP_NODE Property;
NTSTATUS Status;
// get current irp stack location
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE))
{
// certainly not a node property request
return STATUS_NOT_FOUND;
}
// access property
Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY))
{
return PcHandleGuidNullRequest(Irp, SubDeviceDescriptor);
}
// find property handler
Status = PcFindNodePropertyHandler(Irp, SubDeviceDescriptor, &PropertyItem);
// check for success
if (!NT_SUCCESS(Status))
{
// might not be a node property request
DPRINT("NotFound\n");
return STATUS_NOT_FOUND;
}
if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT)
{
// caller issued a basic property request
if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT))
{
// driver does not have a basic support handler
return PcNodeBasicSupportHandler(Irp, PropertyItem);
} }
} }
// allocate a property request
PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
if (!PropertyRequest) if (!PropertyRequest)
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
PC_ASSERT(SubDeviceDescriptor->UnknownMiniport);
PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport;
PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream;
PropertyRequest->Irp = Irp; PropertyRequest->Irp = Irp;
@ -276,27 +340,38 @@ PcHandlePropertyWithTable(
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
{ {
//DPRINT("Status %x ValueSize %u //request completed
Irp->IoStatus.Information = PropertyRequest->ValueSize; Irp->IoStatus.Information = PropertyRequest->ValueSize;
ExFreePool(PropertyRequest); ExFreePool(PropertyRequest);
} }
#if 0
RtlStringFromGUID(Property->Property.Set, &GuidString); // done
DPRINT("Id %u Flags %x Set %S FlagsItem %x Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, PropertyItem->Flags, Status); DPRINT("Status %x\n", Status);
RtlFreeUnicodeString(&GuidString);
#endif
return Status; return Status;
}
NTSTATUS
NTAPI
PcHandlePropertyWithTable(
IN PIRP Irp,
IN ULONG PropertySetCount,
IN PKSPROPERTY_SET PropertySet,
IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
{
NTSTATUS Status;
// try handle it as node property request
Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor);
if (Status == STATUS_NOT_FOUND)
{
// store device descriptor
KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
/* then try KsPropertyHandler */
Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
} }
PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize);
}
#if 0
RtlStringFromGUID(Property->Property.Set, &GuidString);
DPRINT("Id %u Flags %x Set %S Status %x\n", Property->Property.Id, Property->Property.Flags, GuidString.Buffer, Status);
RtlFreeUnicodeString(&GuidString);
#endif
}
}
return Status; return Status;
} }

View file

@ -2162,7 +2162,7 @@ SetGetMuteControlDetails(
Value = Input->fValue; Value = Input->fValue;
/* set control details */ /* set control details */
Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, MAXULONG, &Value); Status = SetGetControlDetails(DeviceObject, DeviceId, NodeId, DeviceInfo, bSet, KSPROPERTY_AUDIO_MUTE, 0, &Value);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return Status;