[wdmaudiodev] Re: USB midi driver?

  • From: Waldemar Haszlakiewicz <waldemar.haszlakiewicz@xxxxxxxx>
  • To: Jeff Pages <wdmaudiodev@xxxxxxxxxxxxx>
  • Date: Wed, 24 Nov 2004 11:32:34 +0100

JP> I have a similar problem with multiple PCI wave input devices. Each device 
is identical,
JP> but they are physically connected to different audio sources and it is 
important for the
JP> application to be able to distinguish them reliably and consistently across 
reboots. I still
JP> don't have a really satisfactory solution to this.
This should solve your problem(AVStream driver type):



NTSTATUS card_c::RegisterChannelsToSystem_Wave
(
)
{
#ifdef DBG_AND_LOGGER
        Procedure_Start_Local( "card_c::RegisterChannelsToSystem_Wave" );
#endif

        NTSTATUS                                Status = STATUS_UNSUCCESSFUL;

        WCHAR                                   buffer_friendlyName[64];
        WCHAR                                   buffer_interfaceName[32];
        unsigned long                   cardType;
        unsigned long                   i;
        unsigned long                   j;
        KSFILTER_DESCRIPTOR*    pFilterDescriptor;
        unsigned long                   serialNumber;


//Define card type.
        if ( type == CARD_TYPE_424 )
        {
                cardType = 424;
                pFilterDescriptor = (KSFILTER_DESCRIPTOR*) 
&FilterDescriptor_Wave96;
        }
        else if ( type == CARD_TYPE_496 )
        {
                cardType = 496;
                pFilterDescriptor = (KSFILTER_DESCRIPTOR*) 
&FilterDescriptor_Wave96;
        }
        else
        {
                cardType = 824;
                pFilterDescriptor = (KSFILTER_DESCRIPTOR*) 
&FilterDescriptor_Wave48;
        }

//Get card serial number.
        for ( serialNumber = 0; serialNumber < WAVE8_MAX_CARDS; serialNumber++ )
        {
        //Check for empty space.
                if ( glClass.cards[serialNumber] == NULL )
                {
                //We found an empty space.
                        Status = STATUS_SUCCESS;
                        break;
                }
        }

//Define filters.
        if ( SUCCESS( Status ) )
        {
        //Convert serialNumber to 1 based number.
                ++serialNumber;

        //Register channels.
                for ( i = 0; i < numberOfStereoChannels; i++ )
                {
                //Convert stereo to mono (channel numbers) and convert
                //to 1 based number.
                        j = i*2 + 1;

                //Create strings.
                        swprintf(
                          buffer_friendlyName,
                          L"WavePro%d(%d) ch. %d-%d",
                          cardType,
                          serialNumber,
                          j,
                          j+1
                        );

                        swprintf(
                          buffer_interfaceName,
                          L"GLI%d(%d) %d-%d",
                          cardType,
                          serialNumber,
                          j,
                          j+1
                        );

                //Register filter interface.
                        Status = RegisterFilterInterface(
                          buffer_interfaceName,
                          buffer_friendlyName
                        );

                //Register filter to system.
                        if ( SUCCESS( Status ) )
                        {
                                Status = KsCreateFilterFactory(
                                  cardDeviceObject->FunctionalDeviceObject,
                                  pFilterDescriptor,
                                  buffer_interfaceName,
                                  NULL,
                                  0,
                                  NULL,
                                  NULL,
                                  &pFilterFactories[i]
                                );
                        }

                        if ( Status != STATUS_SUCCESS )
                        {
                                break;
                        }
                }
        }

#ifdef DBG_AND_LOGGER
        Procedure_Exit( "card_c::RegisterChannelsToSystem_Wave", Status );
#endif
        return Status;
}

NTSTATUS card_c::UnregisterChannelsFromSystem_Wave
(
)
{
#ifdef DBG_AND_LOGGER
        Procedure_Start_Local( "card_c::UnregisterChannelsFromSystem_Wave" );
#endif

        NTSTATUS                                Status = STATUS_UNSUCCESSFUL;

        WCHAR                                   buffer_interfaceName[32];
        unsigned long                   cardType;
        unsigned long                   i;
        unsigned long                   j;
        unsigned long                   serialNumber;

//Define card type.
        if ( type == CARD_TYPE_424 )
        {
                cardType = 424;
        }
        else if ( type == CARD_TYPE_496 )
        {
                cardType = 496;
        }
        else
        {
                cardType = 824;
        }

//Get serialNumber.
//Be carefull as this procedure can be called even if card failed to install.
        for ( serialNumber = 0; serialNumber < WAVE8_MAX_CARDS; serialNumber++ )
        {
        //Check if the card was installed.
                if ( glClass.cards[serialNumber] == this )
                {
                //We found it.
                        Status = STATUS_SUCCESS;
                        break;
                }
        }
        if ( Status != STATUS_SUCCESS )
        {
        //Card wasn't installed -> find first empty space.
                for ( serialNumber = 0; serialNumber < WAVE8_MAX_CARDS; 
serialNumber++ )
                {
                        if ( glClass.cards[serialNumber] == NULL )
                        {
                        //We found it.
                                Status = STATUS_SUCCESS;
                                break;
                        }
                }
        }

//Define filters.
        if ( SUCCESS( Status ) )
        {
        //Convert serialNumber to 1 based number.
                ++serialNumber;

        //Unregister.
                for ( i = 0; i < numberOfStereoChannels; i++ )
                {
                        if ( pFilterFactories[i] == NULL )
                        {
                        //There are no more pFilterFactories after 1st NULL.
                                break;
                        }

                //Convert stereo to mono (channel numbers) and convert
                //to 1 based number.
                        j = i*2 + 1;

                //Create strings.
                        swprintf(
                          buffer_interfaceName,
                          L"GLI%d(%d) %d-%d",
                          cardType,
                          serialNumber,
                          j,
                          j+1
                        );

                //Disable filter factory.
                        DisableFilterInterface( buffer_interfaceName );

                //Release filter factories
                        KsDeleteFilterFactory( pFilterFactories[i] );
                        pFilterFactories[i] = NULL;
                }
        }

#ifdef DBG_AND_LOGGER
        Procedure_Exit( "card_c::UnregisterChannelsFromSystem_Wave", Status );
#endif
        return Status;
}

UNICODE_STRING  FriendlyName_USTR =
{
        sizeof( FRIENDLY_NAME ),
        sizeof( FRIENDLY_NAME ),
        &FRIENDLY_NAME
};
UNICODE_STRING  CLSID_USTR =
{
        sizeof( sCLSID ),
        sizeof( sCLSID ),
        &sCLSID
};

NTSTATUS card_c::RegisterFilterInterface
(
        IN PWCHAR       interfaceName,
        IN PWCHAR       friendlyName
)
{
#ifdef DBG_AND_LOGGER
        Procedure_Start_Local( "card_c::RegisterFilterInterface" );
#endif

        NTSTATUS                        Status;

        HANDLE                          hKey_interface = 0;
        GUID*                           interfaceClassGuid;
        UNICODE_STRING          referenceName;
        UNICODE_STRING          symbolicLinkName;

//Convert PWCHAR to UNICODE_STRING.
        RtlInitUnicodeString( &referenceName, interfaceName );

//Register interface and set it's registry values.
        for ( int i = 0; i< 3; i++ )
        {
        //Get class GUID.
                switch ( i )
                {
                case 0 :
                        interfaceClassGuid = (GUID*) &KSCATEGORY_AUDIO;
                        break;

                case 1 :
                        interfaceClassGuid = (GUID*) &KSCATEGORY_RENDER;
                        break;

                case 2 :
                        interfaceClassGuid = (GUID*) &KSCATEGORY_CAPTURE;
                        break;

                default:;
                }

        //Register Interface
                Status = IoRegisterDeviceInterface(
                  cardDeviceObject->PhysicalDeviceObject,
                  interfaceClassGuid,
                  &referenceName,
                  &symbolicLinkName
                );

        //Set CLSID and FriendlyName interface values.
                if ( SUCCESS( Status ) )
                {
                //Open interface registry handle.
                        Status = IoOpenDeviceInterfaceRegistryKey(
                          &symbolicLinkName,
                          KEY_WRITE,
                          &hKey_interface
                        );

                //Set registry values.
                        if ( SUCCESS( Status ) )
                        {
                        //Set CLSID value.
                                Status = ZwSetValueKey(
                                  hKey_interface,
                                  &CLSID_USTR,
                                  0,
                                  REG_SZ,
                                  &guid_CLSID_Value_W,
                                  sizeof( guid_CLSID_Value_W ) + sizeof( WCHAR )
                                );

                        //Set FriendlyName value.
                                if ( SUCCESS( Status ) )
                                {
                                        Status = ZwSetValueKey(
                                          hKey_interface,
                                          &FriendlyName_USTR,
                                          0,
                                          REG_SZ,
                                          friendlyName,
                                          ( wcslen( friendlyName ) + 1 
)*sizeof( WCHAR )
                                        );
                                }

                        //Release resources
                                ZwClose( hKey_interface );
                        }

                        if ( SUCCESS( Status ) )
                        {
                        //Enable interface.
                                Status = IoSetDeviceInterfaceState(
                                  &symbolicLinkName,
                                  TRUE
                                );
                        }

                //Release resources
                        RtlFreeUnicodeString( &symbolicLinkName );
                }

        //Failed?
                if ( Status != STATUS_SUCCESS )
                {
                        break;
                }
        }

#ifdef DBG_AND_LOGGER
        Procedure_Exit( "card_c::RegisterFilterInterface", Status );
#endif
        return Status;
}

NTSTATUS card_c::DisableFilterInterface
(
        IN PWCHAR       interfaceName
)
{
#ifdef DBG_AND_LOGGER
        Procedure_Start_Local( "card_c::DisableFilterInterface" );
#endif

        NTSTATUS                        Status;

        HANDLE                          hKey_interface = 0;
        GUID*                           interfaceClassGuid;
        UNICODE_STRING          referenceName;
        UNICODE_STRING          symbolicLinkName;

//Convert PWCHAR to UNICODE_STRING.
        RtlInitUnicodeString( &referenceName, interfaceName );

//Register interface and set it's registry values.
        for ( int i = 0; i< 3; i++ )
        {
        //Get class GUID.
                switch ( i )
                {
                case 0 :
                        interfaceClassGuid = (GUID*) &KSCATEGORY_AUDIO;
                        break;

                case 1 :
                        interfaceClassGuid = (GUID*) &KSCATEGORY_RENDER;
                        break;

                case 2 :
                        interfaceClassGuid = (GUID*) &KSCATEGORY_CAPTURE;
                        break;

                default:;
                }

        //Get Interface
                Status = IoRegisterDeviceInterface(
                  cardDeviceObject->PhysicalDeviceObject,
                  interfaceClassGuid,
                  &referenceName,
                  &symbolicLinkName
                );

                if ( SUCCESS( Status ) )
                {
                //Disable interface->we don't want that system will link
                //the interface to our driver when is not present anymore.
                        Status = IoSetDeviceInterfaceState(
                          &symbolicLinkName,
                          FALSE
                        );

                //Release resources
                        RtlFreeUnicodeString( &symbolicLinkName );
                }
        }

#ifdef DBG_AND_LOGGER
        Procedure_Exit( "card_c::DisableFilterInterface", Status );
#endif
        return Status;
}


******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.de/

Other related posts: