At this point you should run the HLK tests, which will find the problem with
your response and give you a (hopefully) helpful error message.
From: Yudi Cao<mailto:yudi.cao@xxxxxxxxx>
Sent: Monday, May 8, 2017 9:01 PM
To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx>
Subject: [wdmaudiodev] Re: How to implement KSPROPSETID_AudioSignalProcessing
Property Set in AVstream mini-driver
Thank you for your help.
When I return the status as STATUS_BUFFER_OVERFLOW instead of
STATUS_BUFFER_TOO_SMALL when pData is NULL,
the host will call the get handler with specific size to get the property value.
But system will get an exception in
MMDevAPI!CAudioSignalProcessingModes::GetModes. And the device won't be listed
in the Sound device list.
Below are what I have done for the property get.
1. There are 4 pins for my AVstream mini-driver filter.
typedef enum _KSPIN_ID
{
KSPIN_SINK_RENDER = 0, //For playback.
KSPIN_SOURCE_CAPTURE, //For capture
KSPIN_SINK_BRIDGE_MIC,
// Bridge Microphone
KSPIN_SOURCE_BRIDGE_SPEAKER //Bridge Speaker
}KSPIN_ID, *PKSPIN_ID;
2. Get and set the property value size with the IRP/IrpStack fields.
3. Implement the KSPROPERTY_AUDIOSIGNALPROCESSING_MODES as this link:
https://msdn.microsoft.com/en-us/library/windows/hardware/dn457708(v=vs.85).aspx<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmsdn.microsoft.com%2Fen-us%2Flibrary%2Fwindows%2Fhardware%2Fdn457708(v%3Dvs.85).aspx&data=02%7C01%7CMatthew.van.Eerde%40microsoft.com%7C569c36861ca44765312a08d496902188%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636298993176644660&sdata=ptLm0Xy3baRFW4w9XJ4Li1Bsp948LTqTSUBVF8ZNEfo%3D&reserved=0>
3.1 Report the RAW+DEFAULT modes for the the playback and capture pins.
3.2 Report KSMULTIPLE_ITEM structure with its Count parameter set to zero (0)
for the bridge pins.
The codes are below:
#define SINGNAL_PROCESSINGMODE_NUMBER 2
typedef struct _KSMULTIPLE_ITEM_CLSID {
KSMULTIPLE_ITEM KsMultiple_Item;
GUID
clsid[SINGNAL_PROCESSINGMODE_NUMBER];
} KSMULTIPLE_ITEM_CLSID, *PKSMULTIPLE_ITEM_CLSID;
GUID gProcessinModesTable[2] =
{
STATIC_AUDIO_SIGNALPROCESSINGMODE_RAW,
STATIC_AUDIO_SIGNALPROCESSINGMODE_DEFAULT
};
NTSTATUS CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessing(IN PIRP
pIrp, IN PKSP_PIN pKSP_Pin, IN OUT PKSMULTIPLE_ITEM pData)
{
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
ULONG ulOutputBufferLength =
pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch (pKSP_Pin->PinId)
{
case KSPIN_SINK_RENDER:
case KSPIN_SOURCE_CAPTURE:
{
if (ulOutputBufferLength < sizeof(KSMULTIPLE_ITEM_CLSID))
{
pIrp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM_CLSID);
return STATUS_BUFFER_OVERFLOW;
}else
{
KSMULTIPLE_ITEM_CLSID Ks_Item;
Ks_Item.KsMultiple_Item.Count = SINGNAL_PROCESSINGMODE_NUMBER;
Ks_Item.KsMultiple_Item.Size = sizeof(KSMULTIPLE_ITEM_CLSID);
RtlCopyMemory(Ks_Item.clsid, gProcessinModesTable,
SINGNAL_PROCESSINGMODE_NUMBER * sizeof(GUID));
if (pData)
{
*((PKSMULTIPLE_ITEM_CLSID)pData) = Ks_Item;
}
}
}
break;
case KSPIN_SINK_BRIDGE_MIC:
case KSPIN_SOURCE_BRIDGE_SPEAKER:
{
if (ulOutputBufferLength < sizeof(KSMULTIPLE_ITEM))
{
pIrp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM);
return STATUS_BUFFER_OVERFLOW;
}
else
{
if (pData)
{
pData->Count = 0;
pData->Size = sizeof(KSMULTIPLE_ITEM);
}
}
}
break;
The exception contents are below:
*** An Access Violation occurred in c:\windows\system32\svchost.exe -k
localsystemnetworkrestricted -s AudioEndpointBuilder:
The instruction at 00007FFC59521EA2 tried to read from an invalid address,
0000000000000004
EXCEPTION_RECORD: 000000b03ea7ee30 -- (.exr 0xb03ea7ee30)
ExceptionAddress: 00007ffc59521ea2
(MMDevAPI!CAudioSignalProcessingModes::GetModes+0x0000000000000022)
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 0000000000000000
Parameter[1]: 0000000000000004
Attempt to read from address 0000000000000004
CONTEXT: 000000b03ea7e940 -- (.cxr 0xb03ea7e940)
rax=0000000000000000 rbx=ffffffffffffffff rcx=00000236dd83deb0
rdx=000000b03ea7f0d8 rsi=0000000000000000 rdi=000000b03ea7f0d8
rip=00007ffc59521ea2 rsp=000000b03ea7f060 rbp=000000b03ea7f1a0
r8=000000b03ea7f0d0 r9=00000236dd83de90 r10=00000fff8b2a43d0
r11=0000100000010100 r12=00000236dd81de50 r13=00000236dd87ac70
r14=000000b03ea7f0d0 r15=ffffffffffffffff
iopl=0 nv up ei pl nz na po nc
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206
MMDevAPI!CAudioSignalProcessingModes::GetModes+0x22:
0033:00007ffc`59521ea2 8b6804 mov ebp,dword ptr [rax+4]
ds:002b:00000000`00000004=????????
Resetting default scope
FOLLOWUP_IP:
MMDevAPI!CAudioSignalProcessingModes::GetModes+22
0033:00007ffc`59521ea2 8b6804 mov ebp,dword ptr [rax+4]
READ_ADDRESS: 0000000000000004
BUGCHECK_STR: STATUS_BREAKPOINT
What's wrong in my implementation?
Thank you for your help,
Hunter
On Mon, May 8, 2017 at 10:55 PM, Matthew van Eerde
<dmarc-noreply@xxxxxxxxxxxxx<mailto:dmarc-noreply@xxxxxxxxxxxxx>> wrote:
Windows is not giving you a buffer because it doesn’t know how big of a buffer
to give you.
For documentation on writing kernel streaming property handlers directly, see
https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/audio-property-handlers<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fwindows-hardware%2Fdrivers%2Faudio%2Faudio-property-handlers&data=02%7C01%7CMatthew.van.Eerde%40microsoft.com%7C569c36861ca44765312a08d496902188%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636298993176644660&sdata=fxBv1F%2B5Gfu84kzw0E1yRTSlbMhLjEO17E0jxqPNWaM%3D&reserved=0>
- in particular
Before submitting a get-property request to retrieve a property value, the
client should allocate an output buffer into which the miniport driver's
property handler can write the property value. For some properties, the size of
the output buffer is device-dependent and the client must query the property
handler for the required buffer size. In these cases, the client submits an
initial property request with a zero-length output buffer. The handler responds
by returning the required buffer size along with the status code
STATUS_BUFFER_OVERFLOW. (The handler writes the required size into the
ValueSize member of the PCPROPERTY_REQUEST structure.) The client then
retrieves the property value by allocating an output buffer of the specified
size and sending this buffer in a second get-property request.
From: Yudi Cao<mailto:yudi.cao@xxxxxxxxx>
Sent: Monday, May 8, 2017 1:40 AM
To: wdmaudiodev@xxxxxxxxxxxxx<mailto:wdmaudiodev@xxxxxxxxxxxxx>
Subject: [wdmaudiodev] How to implement KSPROPSETID_AudioSignalProcessing
Property Set in AVstream mini-driver
Hello,
I'm working on an AVstream audio driver for USB Headset (add some extra formats
comparing to inbox usbaudio.sys).
To integrate APO DLL to my driver package, I need implement the
KSPROPSETID_AudioSignalProcessing property set.
The property set AutomationTable definitions are below:
DEFINE_KSPROPERTY_TABLE(AudioFilterPropertySetTable)
{
DEFINE_KSPROPERTY_ITEM
(
KSPROPERTY_AUDIOSIGNALPROCESSING_MODES, // property item
defined in ksmedia.h
CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessing,
sizeof(KSP_PIN), // minimum buffer length for
property
0, // minimum buffer length for returned data
NULL,
NULL, // default values
0, // related properties
NULL,
CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessingBasicSupport,
0 // don't serialize
)
};
DEFINE_KSPROPERTY_SET_TABLE(AudioFilterProperties)
{
DEFINE_KSPROPERTY_SET
(
&KSPROPSETID_AudioSignalProcessing, //
property set defined in ksmedia.h
SIZEOF_ARRAY(AudioFilterPropertySetTable), // the properties
supported
AudioFilterPropertySetTable,
0, // reserved
NULL // reserved
)
};
DEFINE_KSAUTOMATION_TABLE(AudioFilterAutomationTable) {
DEFINE_KSAUTOMATION_PROPERTIES(AudioFilterProperties),
DEFINE_KSAUTOMATION_METHODS_NULL,
DEFINE_KSAUTOMATION_EVENTS_NULL
};
m_KSFilterDesc.AutomationTable = &AudioFilterAutomationTable;
The function declared as below:
NTSTATUS CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessing(IN PIRP
pIrp, IN PKSP_PIN pKSP_Pin, IN OUT PKSMULTIPLE_ITEM pData)
NTSTATUS
CCaptureRenderFilter::FILTERPROP_PropertyAudioSignalProcessingBasicSupport(IN
PIRP pIrp, IN PKSP_PIN Request, IN OUT PVOID Data)
The problem is:
The system will call FILTERPROP_PropertyAudioSignalProcessing() for several
times with the pData==NULL. Why the pData is always null?
What's wrong with my code? Is there anywhere to get some sample code for
AVStream mini-driver to support KSPROPSETID_AudioSignalProcessing?
Thank you for your help,
Hunter