Author: janderwald
Date: Sun Nov 29 19:56:56 2009
New Revision: 44323
URL:
http://svn.reactos.org/svn/reactos?rev=44323&view=rev
Log:
[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
Modified:
trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
trunk/reactos/drivers/wdm/audio/legacy/wdmaud/mixer.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1]
(original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp [iso-8859-1] Sun
Nov 29 19:56:56 2009
@@ -1243,8 +1243,8 @@
m_Port = Port;
m_Filter = Filter;
- //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 acquire %x\n",
m_Stream->SetState(KSSTATE_ACQUIRE));
+ DPRINT("Setting state to pause %x\n",
m_Stream->SetState(KSSTATE_PAUSE));
return STATUS_SUCCESS;
}
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/…
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp [iso-8859-1] Sun Nov 29
19:56:56 2009
@@ -86,6 +86,269 @@
return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK,
(PVOID)Descriptor->EventListLock);
}
+NTSTATUS
+PcHandleGuidNullRequest(
+ IN OUT PIRP Irp,
+ IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
+{
+ PPCNODE_DESCRIPTOR Node;
+ PPCPROPERTY_ITEM PropertyItem;
+ PIO_STACK_LOCATION IoStack;
+ PKSP_NODE Property;
+ LPGUID Buffer;
+ ULONG Count = 0, SubIndex, Index;
+
+ // get current irp stack location
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+
+ // access property
+ Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+ if (Property->NodeId >=
SubDeviceDescriptor->DeviceDescriptor->NodeCount)
+ {
+ // request is out of bounds
+ Irp->IoStatus.Information = 0;
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Node =
(PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes +
(Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
+
+ if (!Node->AutomationTable)
+ {
+ // request is out of bounds
+ Irp->IoStatus.Information = 0;
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ PC_ASSERT(Node->AutomationTable);
+ PC_ASSERT(Node->AutomationTable->PropertyCount);
+ PC_ASSERT(Node->AutomationTable->PropertyItemSize);
+
+ Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) *
Node->AutomationTable->PropertyCount, TAG_PORTCLASS);
+ if (!Buffer)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
+ for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++)
+ {
+ BOOL Found = FALSE;
+ for (SubIndex = 0; SubIndex < Count; Index++)
+ {
+ if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set))
+ {
+ Found = TRUE;
+ break;
+ }
+ }
+ if (!Found)
+ {
+ RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID));
+ Count++;
+ }
+ PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem +
Node->AutomationTable->PropertyItemSize);
+ }
+
+ // store result length
+ Irp->IoStatus.Information = sizeof (GUID) * Count;
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) *
Count)
+ {
+ // buffer too small
+ FreeItem(Buffer, TAG_PORTCLASS);
+ return STATUS_MORE_ENTRIES;
+ }
+
+ RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count);
+ FreeItem(Buffer, TAG_PORTCLASS);
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+PcFindNodePropertyHandler(
+ PIRP Irp,
+ 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)
+ {
+ // request is out of bounds
+ DPRINT("InvalidIndex %u %u\n", Property->NodeId,
SubDeviceDescriptor->DeviceDescriptor->NodeCount);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ Node =
(PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes +
(Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
+
+ if (!Node->AutomationTable)
+ {
+ // request is out of bounds
+ Irp->IoStatus.Information = 0;
+ return STATUS_NOT_FOUND;
+ }
+
+ // sanity checks
+ PC_ASSERT(Node->AutomationTable);
+ PC_ASSERT(Node->AutomationTable->PropertyCount);
+ PC_ASSERT(Node->AutomationTable->PropertyItemSize);
+
+ 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++)
+ {
+ if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set)
&& PropertyItem->Id == Property->Property.Id)
+ {
+ //found property handler
+ *OutPropertyItem = PropertyItem;
+ return STATUS_SUCCESS;
+ }
+ PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem +
Node->AutomationTable->PropertyItemSize);
+ }
+
+ // 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;
+
+ if (PropertyItem->Flags & KSPROPERTY_TYPE_SET)
+ *Flags |= KSPROPERTY_TYPE_SET;
+
+ if (PropertyItem->Flags & KSPROPERTY_TYPE_GET)
+ *Flags |= KSPROPERTY_TYPE_GET;
+
+ // store result length
+ Irp->IoStatus.Information = sizeof(ULONG);
+
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >=
sizeof(KSPROPERTY_DESCRIPTION))
+ {
+ // get output buffer
+ Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer;
+
+ // store result
+ Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION);
+ Description->PropTypeSet.Set = KSPROPTYPESETID_General;
+ Description->PropTypeSet.Id = 0;
+ Description->PropTypeSet.Flags = 0;
+ Description->MembersListCount = 0;
+ Description->Reserved = 0;
+
+ Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION);
+ }
+ 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);
+ if (!PropertyRequest)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport;
+ PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream;
+ PropertyRequest->Irp = Irp;
+ PropertyRequest->Node = Property->NodeId;
+ PropertyRequest->PropertyItem = PropertyItem;
+ PropertyRequest->Verb = Property->Property.Flags;
+ PropertyRequest->InstanceSize =
IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY);
+ PropertyRequest->Instance =
(PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer +
sizeof(KSNODEPROPERTY));
+ PropertyRequest->ValueSize =
IoStack->Parameters.DeviceIoControl.OutputBufferLength;
+ PropertyRequest->Value = Irp->UserBuffer;
+
+ Status = PropertyItem->Handler(PropertyRequest);
+
+ if (Status != STATUS_PENDING)
+ {
+ //request completed
+ Irp->IoStatus.Information = PropertyRequest->ValueSize;
+ ExFreePool(PropertyRequest);
+ }
+
+ // done
+ DPRINT("Status %x\n", Status);
+ return Status;
+}
NTSTATUS
NTAPI
@@ -96,207 +359,19 @@
IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
{
NTSTATUS Status;
- PIO_STACK_LOCATION IoStack;
- PKSP_NODE Property;
- PPCNODE_DESCRIPTOR Node;
- PPCPROPERTY_ITEM PropertyItem;
- ULONG Index;
- LPGUID Buffer;
- //PULONG Flags;
- 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
- IoStack = IoGetCurrentIrpStackLocation(Irp);
-
- // access property
- Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
-
- // check if this a GUID_NULL request
+
+ // try handle it as node property request
+ Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor);
+
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)
- {
- // request is out of bounds
- Irp->IoStatus.Information = 0;
- return STATUS_INVALID_PARAMETER;
- }
-
- Node =
(PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes +
(Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
-
- if (!Node->AutomationTable)
- {
- // request is out of bounds
- Irp->IoStatus.Information = 0;
- return STATUS_INVALID_PARAMETER;
- }
-
- PC_ASSERT(Node->AutomationTable);
- PC_ASSERT(Node->AutomationTable->PropertyCount);
- PC_ASSERT(Node->AutomationTable->PropertyItemSize);
-
- Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) *
Node->AutomationTable->PropertyCount, TAG_PORTCLASS);
- if (!Buffer)
- return STATUS_INSUFFICIENT_RESOURCES;
-
-
- ULONG Count = 0, SubIndex;
- PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
- for (Index = 0; Index < Node->AutomationTable->PropertyCount;
Index++)
- {
- BOOL Found = FALSE;
- for (SubIndex = 0; SubIndex < Count; Index++)
- {
- if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set))
- {
- Found = TRUE;
- break;
- }
- }
- if (!Found)
- {
- RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof
(GUID));
- Count++;
- }
- PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem +
Node->AutomationTable->PropertyItemSize);
- }
-
- Irp->IoStatus.Information = sizeof (GUID) * Count;
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof
(GUID) * Count)
- {
- // buffer too small
- FreeItem(Buffer, TAG_PORTCLASS);
- return STATUS_MORE_ENTRIES;
- }
-
- RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count);
- FreeItem(Buffer, TAG_PORTCLASS);
- return STATUS_SUCCESS;
- }
- else /*if (Property->Property.Flags == (KSPROPERTY_TYPE_BASICSUPPORT |
KSPROPERTY_TYPE_TOPOLOGY) ||
- Property->Property.Flags == (KSPROPERTY_TYPE_GET |
KSPROPERTY_TYPE_TOPOLOGY) ||
- Property->Property.Flags == (KSPROPERTY_TYPE_SET |
KSPROPERTY_TYPE_TOPOLOGY)) */
- {
- //UNICODE_STRING GuidString;
-
- if (Property->NodeId >=
SubDeviceDescriptor->DeviceDescriptor->NodeCount)
- {
- // request is out of bounds
- Irp->IoStatus.Information = 0;
- return STATUS_INVALID_PARAMETER;
- }
-
- Node =
(PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes +
(Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
-
- if (!Node->AutomationTable)
- {
- // request is out of bounds
- Irp->IoStatus.Information = 0;
- return STATUS_NOT_FOUND;
- }
-
- PC_ASSERT(Node->AutomationTable);
- PC_ASSERT(Node->AutomationTable->PropertyCount);
- PC_ASSERT(Node->AutomationTable->PropertyItemSize);
-
- PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties;
-
- for(Index = 0; Index < Node->AutomationTable->PropertyCount;
Index++)
- {
- if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set)
&& PropertyItem->Id == Property->Property.Id)
- {
- if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT)
- {
- if (!(PropertyItem->Flags &
KSPROPERTY_TYPE_BASICSUPPORT))
- {
-
PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG));
- PULONG Flags = (PULONG)Irp->UserBuffer;
-
- /* reset flags */
- *Flags = 0;
-
- if (PropertyItem->Flags & KSPROPERTY_TYPE_SET)
- *Flags |= KSPROPERTY_TYPE_SET;
-
- if (PropertyItem->Flags & KSPROPERTY_TYPE_GET)
- *Flags |= KSPROPERTY_TYPE_GET;
-
- Irp->IoStatus.Information = sizeof(ULONG);
-
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength
>= sizeof(KSPROPERTY_DESCRIPTION))
- {
- /* get output buffer */
- PKSPROPERTY_DESCRIPTION Description =
(PKSPROPERTY_DESCRIPTION)Irp->UserBuffer;
-
- /* store result */
- Description->DescriptionSize =
sizeof(KSPROPERTY_DESCRIPTION);
- Description->PropTypeSet.Set =
KSPROPTYPESETID_General;
- Description->PropTypeSet.Id = 0;
- Description->PropTypeSet.Flags = 0;
- Description->MembersListCount = 0;
- Description->Reserved = 0;
-
- Irp->IoStatus.Information =
sizeof(KSPROPERTY_DESCRIPTION);
- }
- return STATUS_SUCCESS;
- }
- }
-
-
- PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool,
sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
- if (!PropertyRequest)
- return STATUS_INSUFFICIENT_RESOURCES;
-
- PC_ASSERT(SubDeviceDescriptor->UnknownMiniport);
- PropertyRequest->MajorTarget =
SubDeviceDescriptor->UnknownMiniport;
- PropertyRequest->MinorTarget =
SubDeviceDescriptor->UnknownStream;
- PropertyRequest->Irp = Irp;
- PropertyRequest->Node = Property->NodeId;
- PropertyRequest->PropertyItem = PropertyItem;
- PropertyRequest->Verb = Property->Property.Flags;
- PropertyRequest->InstanceSize =
IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY);
- PropertyRequest->Instance =
(PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer +
sizeof(KSNODEPROPERTY));
- PropertyRequest->ValueSize =
IoStack->Parameters.DeviceIoControl.OutputBufferLength;
- PropertyRequest->Value = Irp->UserBuffer;
-
- Status = PropertyItem->Handler(PropertyRequest);
-
- if (Status != STATUS_PENDING)
- {
- //DPRINT("Status %x ValueSize %u
-
- Irp->IoStatus.Information = PropertyRequest->ValueSize;
- ExFreePool(PropertyRequest);
- }
-#if 0
- RtlStringFromGUID(Property->Property.Set, &GuidString);
- DPRINT("Id %u Flags %x Set %S FlagsItem %x Status %x\n",
Property->Property.Id, Property->Property.Flags, GuidString.Buffer,
PropertyItem->Flags, Status);
- RtlFreeUnicodeString(&GuidString);
-#endif
- return Status;
- }
- 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
- }
- }
+ // store device descriptor
+ KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
+
+ /* then try KsPropertyHandler */
+ Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet);
+ }
+
return Status;
}
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] Sun Nov 29 19:56:56
2009
@@ -2162,7 +2162,7 @@
Value = Input->fValue;
/* 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))
return Status;