[wdmaudiodev] Re: How to implement the SupportHandler for KSPROPERTY_AUDIO_VOLUMELEVEL?

  • From: "Ydcao" <ydcao@xxxxxxxxxxx>
  • To: <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Fri, 15 May 2009 12:37:26 +0800

Hi DJ,

 

You are right, something wrong in my code. I do not initialize the
Reserved  of KSPROPERTY_DESCRIPTION to zero. After I add
"PropDesc.Reserved = 0; " in my code, the system will call my handler
twice with the right buffer size.

 

Thank you,

Hunter

 

 

From: DJ Sisolak [mailto:dsisolak@xxxxxxxxxxxxxxxxxxxxxx] 
Sent: Friday, May 15, 2009 8:28 AM
To: Ydcao
Subject: RE: [wdmaudiodev] Re: How to implement the SupportHandler for
KSPROPERTY_AUDIO_VOLUMELEVEL?

 

Hi Hunter,

 

Not sure why you are seeing a problem then. This generally indicates
that it is not getting the proper response in the returned
KSPROPERTY_DESCRIPTION structure, in particular the DescriptionSize
field. Have you verified that the structure is successfully transferred
to the data pointer? Verify return status? Verify return size in the
Irp's Information field? I know this is obvious but I cannot think of
any other good reason for this to fail.

 

Thx,

DJ

 

From: wdmaudiodev-bounce@xxxxxxxxxxxxx
[mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Ydcao
Sent: Monday, May 11, 2009 8:27 PM
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Re: How to implement the SupportHandler for
KSPROPERTY_AUDIO_VOLUMELEVEL?

 

Hi DJ,

 

With the code you give, system still just call the handler with buffer
size 0x28 (sizeof(KSPROPERTY_DESCRIPTION )) but not with the full size
of Basic Support information 0x48. 

 

The range -32k ~+ 32K with steps of 1 is not the real range of my
device.  My device range information is: RES = 0x0100, MIN=0xE500,
MAX=0x1500. I have specify the range data  by take reference to usbaudio
as below.  But system do not provide a chance for me to return the range
data.

//-----

Range.SteppingDelta = 0x10000;

        Range.Bounds.UnsignedMinimum = 0xffe50000; 

        Range.Bounds.UnsignedMaximum = 0x150000;

//-----

 

Thank you,

Hunter

 

 

 

 

 

From: wdmaudiodev-bounce@xxxxxxxxxxxxx
[mailto:wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of DJ Sisolak
Sent: Tuesday, May 12, 2009 5:54 AM
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] Re: How to implement the SupportHandler for
KSPROPERTY_AUDIO_VOLUMELEVEL?

 

In an AVStream driver the size of the request's output buffer can be
determined as:

 

    PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation( pIrp );
    ULONG ulOutputBufferLength =
pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

As to the remainder of the routine below you want to have several levels
of response based on the size of the output buffer (and assuming you
really want a range of -32K to +32K with steps of 1...which I doubt but
its your device :-)):

 

        NTSTATUS ntStatus = STATUS_INVALID_PARAMETER;

 

        if ( sizeof(ULONG) > ulOutputBufferLength ) {

            // No useful buffer. Return info about the requested size
and an error.
            pIrp->IoStatus.Information = cbFullProperty;
            ntStatus = STATUS_BUFFER_TOO_SMALL;
        }

        else {

            ntStatus = STATUS_SUCCESS;

 

            if  ( sizeof(ULONG)  <= ulOutputBufferLength ) {

                // Should only be Access flags

                pIrp->IoStatus.Information = sizeof(ULONG);

 

                if ( sizeof( KSPROPERTY_DESCRIPTION )  <=
ulOutputBufferLength  ) {

                    // Just the PropDesc at this level.

                    *((PKSPROPERTY_DESCRIPTION )Data) = PropDesc;

                    pIrp->IoStatus.Information =
sizeof(KSPROPERTY_DESCRIPTION );

                    

                    if  ( cbFullProperty  <= ulOutputBufferLength  ) {

                         // All of it.

                        *((PVOLUMESUPPORTLEVEL)Data) = VolumeSupport;

                        pIrp->IoStatus.Information = cbFullProperty ;

                    }

                }

            }

        }
        return ntStatus;

 

NOTE: There are no guarantees as to the functionality of the code
snippit!!!! It is merely a guideline based on the information below.

 

Hope this helps,

DJ

 

________________________________

From: wdmaudiodev-bounce@xxxxxxxxxxxxx
[wdmaudiodev-bounce@xxxxxxxxxxxxx] On Behalf Of Ydcao
[ydcao@xxxxxxxxxxx]
Sent: Monday, May 11, 2009 4:21 AM
To: wdmaudiodev@xxxxxxxxxxxxx
Subject: [wdmaudiodev] How to implement the SupportHandler for
KSPROPERTY_AUDIO_VOLUMELEVEL?

Hi,

 

I failed to implement Volume Control for my USB Microphone driver under
Windows Vista. 

 

I implemented the Volume Control Support following the post "
//www.freelists.org/post/wdmaudiodev/AVStream-Mixer-Problems,15 "  

 

It is not work. Under KSStudio, the Nodes/KSNODETYPE_VOLUME/Description
will be empty.

 

Take reference the USBAUDIO behavior and WDK. I have changed the code
compare to John's.

1.      Add buffer size detection by compare the address of Request and
Data. ---- I do not know if it is right or not. 

2.      Set the pIrp->IoStatus.Information. In WDK, the Information
field should return the size of the buffer.

 

Compare with my driver with usbaudio.sys that loaded for UAC compatible
devices, here is the difference.

1.      The system will call the handler
(usbaudio!PropertyGetOldDbBasicSupport) twice.  

a.      The first time, set pIrp->IoStatus.Information = 0x28; //
sizeof(KSPROPERTY_DESCRIPTION)

b.      The second time, set the pIrp->IoStatus.Information = 0x28;//
sizeof(VOLUMELEVELSUPPORT) ;

2.      For my driver, system only call my handle once. And the buffer
for me is sizeof (KSPROPERTY_DESCRIPTION).

 

I don't know what I can do now. Any help is appreciated. 

 

Here is the code:

 

//--------Code here----------------------------------

typedef struct _VOLUME_LEVEL_SUPPORT {

         KSPROPERTY_DESCRIPTION               PropDesc;

         KSPROPERTY_MEMBERSHEADER     Members;

         KSPROPERTY_STEPPING_LONG     Range;

} VOLUMELEVELSUPPORT, *PVOLUMELEVELSUPPORT;

 

NTSTATUS SupportVolumeLevel(IN PIRP pIrp, IN PKSIDENTIFIER  Request, IN
OUT PVOID  Data)

{

        LONG cbFullProperty = sizeof(KSPROPERTY_DESCRIPTION) +

 
sizeof(KSPROPERTY_MEMBERSHEADER) +

 
sizeof(KSPROPERTY_STEPPING_LONG);

 

        if(!(Request->Flags&KSPROPERTY_TYPE_BASICSUPPORT))

               return STATUS_INVALID_PARAMETER;

 

 

        KSPROPERTY_DESCRIPTION PropDesc;

 

        PropDesc.AccessFlags = KSPROPERTY_TYPE_BASICSUPPORT |

 
KSPROPERTY_TYPE_GET | 

 
KSPROPERTY_TYPE_SET;

    PropDesc.DescriptionSize   = sizeof(KSPROPERTY_DESCRIPTION) +

 
sizeof(KSPROPERTY_MEMBERSHEADER) + 

 
sizeof(KSPROPERTY_STEPPING_LONG);

    PropDesc.PropTypeSet.Set = KSPROPTYPESETID_General;

    PropDesc.PropTypeSet.Id  = VT_I4;

    PropDesc.PropTypeSet.Flags = 0;

    PropDesc.MembersListCount = 1;

 

    KSPROPERTY_MEMBERSHEADER Members;

 

    Members.MembersFlags = KSPROPERTY_MEMBER_STEPPEDRANGES;

    Members.MembersSize  = sizeof(KSPROPERTY_STEPPING_LONG);

    Members.MembersCount = 1;

    Members.Flags =
KSPROPERTY_MEMBER_FLAG_BASICSUPPORT_UNIFORM;//KSPROPERTY_MEMBER_FLAG_BAS
ICSUPPORT_MULTICHANNEL;  //

 

    KSPROPERTY_STEPPING_LONG Range;

    

        Range.SteppingDelta = 1;

        Range.Bounds.SignedMinimum = -32767; 

        Range.Bounds.SignedMaximum = 32767;

 

  

    VolumeSupport.PropDesc = PropDesc;

    VolumeSupport.Members = Members;

    VolumeSupport.Range = Range;

 

        LONG ltemp0 = 0, ltemp1 = 0, lBufLength = 0;

        ltemp0 = (LONG) Request;

        ltemp1 = (LONG) Data;

        lBufLength = ltemp0-ltemp1;

 

        if( lBufLength < cbFullProperty)  //Detect the buffer length.

        {

               pIrp->IoStatus.Information = 0;

 

               if(lBufLength >= sizeof(KSPROPERTY_DESCRIPTION))

               { //System always call this.

 

                       *((PKSPROPERTY_DESCRIPTION) Data) = PropDesc;

                       

                       pIrp->IoStatus.Information =
sizeof(KSPROPERTY_DESCRIPTION);

 

                       return STATUS_SUCCESS;

               }

 

               return STATUS_BUFFER_TOO_SMALL;

        }   

        else

        {  //Never get called.

               

 

               *((PVOLUMELEVELSUPPORT) Data) = VolumeSupport;

 

               pIrp->IoStatus.Information = cbFullProperty;

               return STATUS_SUCCESS;

        }

 

}

//--------End of code--------------------------------

 

Thank you

Hunter

Other related posts: