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

  • From: DJ Sisolak <dsisolak@xxxxxxxxxxxxxxxxxxxxxx>
  • To: "wdmaudiodev@xxxxxxxxxxxxx" <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Mon, 11 May 2009 14:53:52 -0700

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_BASICSUPPORT_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: