Sample Code

windows driver samples/ Native Wifi IHV Service/ C++/ ihvsample/ ihvsample.cpp/

/*++

Copyright (c) 2005 Microsoft Corporation

Abstract:

   Sample IHV Extensibility DLL to extend
   802.11 LWF driver for third party protocols.


--*/

#include "precomp.h"



//
// Get Version info.
//
DWORD
WINAPI
Dot11ExtIhvGetVersionInfo
(
   OUT   PDOT11_IHV_VERSION_INFO    pDot11IHVVersionInfo
)
{
   if ( pDot11IHVVersionInfo )
   {
      pDot11IHVVersionInfo->dwVerMin = 0;
      pDot11IHVVersionInfo->dwVerMax = 0;
   }
    return ERROR_SUCCESS;
}


//
// Initialize service.
//

DWORD
WINAPI
Dot11ExtIhvInitService
(
   IN    DWORD                      dwVerNumUsed,
   IN    PDOT11EXT_APIS             pDot11ExtAPI,
   IN    LPVOID                     pvReserved,
   OUT   PDOT11EXT_IHV_HANDLERS     pDot11IHVHandlers
)
{
    DWORD   dwResult    =   ERROR_SUCCESS;
    BOOL    bLocked     =   FALSE;

    UNREFERENCED_PARAMETER( pvReserved );

    if
    (
        ( 0 != dwVerNumUsed )      ||
        ( !pDot11ExtAPI )          ||
        ( !pDot11IHVHandlers )
    )
    {
        dwResult = ERROR_INVALID_PARAMETER;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    InitAdapterDetailsList( );

    g_pDot11ExtApi = (PDOT11EXT_APIS) PrivateMemoryAlloc( sizeof( DOT11EXT_APIS ) );
    if ( !g_pDot11ExtApi )
    {
        dwResult = ERROR_OUTOFMEMORY;
        BAIL_ON_WIN32_ERROR( dwResult );
    }
    (*g_pDot11ExtApi)    =  (*pDot11ExtAPI);

    HandlerInit( pDot11IHVHandlers );


error:
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}





//
// Deinitialize service.
//
VOID
WINAPI
IhvDeinitService
(
   VOID
)
{

    EnterCriticalSection( &g_csSynch );

    // disable starting new threads or adding new adapters.
    StartShutdown( );

    LeaveCriticalSection( &g_csSynch );


    WaitOnZeroThreads( );
    DeinitAdapterDetailsList( );

    if ( g_pDot11ExtApi )
    {
        PrivateMemoryFree( g_pDot11ExtApi );
        g_pDot11ExtApi = NULL;
    }

    return;
}



//
// Initialize adapter
//
DWORD
WINAPI
IhvInitAdapter
(
   IN    PDOT11_ADAPTER    pDot11Adapter,
   IN    HANDLE            hDot11SvcHandle,
   OUT   PHANDLE           phIhvExtAdapter
)
{
    DWORD       dwResult            =   ERROR_SUCCESS;
    BOOL        bLocked             =   FALSE;
    HANDLE      hIhvExtAdapter      =   NULL;
    USHORT      usEtherTypeReg[]    =   { 0x888e, 0x8333 };

    if (( !pDot11Adapter ) || (!hDot11SvcHandle) || (!phIhvExtAdapter) )
    {
        dwResult = ERROR_INVALID_PARAMETER;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    dwResult =
    InitAdapterDetails
    (
        hDot11SvcHandle,
        &hIhvExtAdapter
    );
    BAIL_ON_WIN32_ERROR( dwResult );

    dwResult =
    (g_pDot11ExtApi->Dot11ExtSetEtherTypeHandling)
    (
        hDot11SvcHandle,
        3,
        0,
        NULL,
        2,
        usEtherTypeReg
    );
    BAIL_ON_WIN32_ERROR( dwResult );

    (*phIhvExtAdapter)  =   hIhvExtAdapter;
    hIhvExtAdapter      =   NULL;

error:

    if ( hIhvExtAdapter )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }

    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}



//
// Deinit adapter.
//
VOID
WINAPI
IhvDeinitAdapter
(
   IN    HANDLE   hIhvExtAdapter
)
{
    DerefenceAdapterDetails( hIhvExtAdapter );

    return;
}





//
// Handle session change notification.
//
DWORD
WINAPI
IhvProcessSessionChange
(
   IN    ULONG                         uEventType,
   IN    PWTSSESSION_NOTIFICATION      pSessionNotification
)
{
   UNREFERENCED_PARAMETER( pSessionNotification );

   if ( WTS_CONSOLE_CONNECT == uEventType )
   {
      // The sample does not use this session ID
      // anywhere. In an actual application, IHV
      // developers may want to use this session ID to
      // get/set the user data.
      g_dwSessionID = WTSGetActiveConsoleSessionId( );
   }
   return ERROR_SUCCESS;
}





//
// Checks if UI request is pending.
//
DWORD
WINAPI
IhvIsUIRequestPending
(
   IN    GUID     guidUIRequest,
   OUT   PBOOL    pbIsRequestPending
)
{
    DWORD                   dwResult        =   ERROR_SUCCESS;
    BOOL                    bLocked         =   FALSE;
    PADAPTER_DETAILS        pAdapterDetails =   NULL;
    HANDLE                  hIhvExtAdapter  =   NULL;


    ASSERT( pbIsRequestPending );

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    // obtain reference to the adapter using
    // UI request GUID.
    dwResult =
    ReferenceAdapterDetailsByUIRequestGuid
    (
        &guidUIRequest,
        &pAdapterDetails,
        &hIhvExtAdapter
    );
    if ( ERROR_NOT_FOUND == dwResult )
    {
        dwResult = ERROR_SUCCESS;
        (*pbIsRequestPending) = FALSE;
        BAIL( );
    }
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );


    (*pbIsRequestPending) = TRUE;

error:
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}




//
// Handle NIC specific notifications.
//
DWORD
WINAPI
IhvReceiveIndication
(
    IN  HANDLE                          hIhvExtAdapter,
    IN  DOT11EXT_IHV_INDICATION_TYPE    indicationType,
    IN  ULONG                           uBufferLength,
    IN  LPVOID                          pvBuffer
)
{
    DWORD                                   dwResult                    =   ERROR_SUCCESS;
    PDOT11_PMKID_CANDIDATE_LIST_PARAMETERS  pPMKCandidateListParams     =   NULL;
    PDOT11_TKIPMIC_FAILURE_PARAMETERS       pTkipMicFailureParams       =   NULL;
    PDOT11_PHY_STATE_PARAMETERS             pPHYStateChange             =   NULL;
    PDOT11_LINK_QUALITY_PARAMETERS          pDot11LinkQualityParams     =   NULL;

    ASSERT( pvBuffer );

    // Note that sample does not really use the buffer.
    UNREFERENCED_PARAMETER( hIhvExtAdapter );
    UNREFERENCED_PARAMETER( uBufferLength );

    switch ( indicationType )
    {
        case IndicationTypeNicSpecificNotification:
            // The pointer pvBuffer can be interpreted by IHV appropriately. Format
            // is a contract between the miniport driver and the IHV extensibility module.
            break;

        case IndicationTypePmkidCandidateList:
            pPMKCandidateListParams = (PDOT11_PMKID_CANDIDATE_LIST_PARAMETERS) pvBuffer;
            // Ihv extensibility module may choose to use this data appropriately.
            break;

        case IndicationTypeTkipMicFailure:
            pTkipMicFailureParams = (PDOT11_TKIPMIC_FAILURE_PARAMETERS) pvBuffer;
            // Ihv extensibility module may choose to use this data appropriately.
            break;

        case IndicationTypePhyStateChange:
            pPHYStateChange = (PDOT11_PHY_STATE_PARAMETERS) pvBuffer;
            // Ihv extensibility module may choose to use this data appropriately.
            break;

        case IndicationTypeLinkQuality:
            pDot11LinkQualityParams = (PDOT11_LINK_QUALITY_PARAMETERS) pvBuffer;
            // Ihv extensibility module may choose to use this data appropriately.
            break;

        default:
            ASSERTFAILURE();
            dwResult = ERROR_INVALID_PARAMETER;
            BAIL_ON_WIN32_ERROR( dwResult );
            break;
    }

error:
    return dwResult;
}






//
// Perform the capabiity match.
//
DWORD
WINAPI
IhvPerformCapabilityMatch
(
    IN  HANDLE                              hIhvExtAdapter,
    IN  PDOT11EXT_IHV_PROFILE_PARAMS        pIhvProfileParams,
    IN  PDOT11EXT_IHV_CONNECTIVITY_PROFILE  pIhvConnProfile,
    IN  PDOT11EXT_IHV_SECURITY_PROFILE      pIhvSecProfile,
    IN  PDOT11_BSS_LIST                     pConnectableBssid,
    OUT PDWORD                              pdwReasonCode
)
{
    DWORD                       dwResult                =   ERROR_SUCCESS;
    BOOL                        bLocked                 =   FALSE;
    PBYTE                       pbCurrPos               =   NULL;
    ULONG                       uRemainBytes            =   0;
    ULONG                       uBssEntryBytes          =   0;
    PULDOT11_BSS_ENTRY          pBssEntry               =   NULL;
    PADAPTER_DETAILS            pAdapterDetails         =   NULL;
    PIHV_CONNECTIVITY_PROFILE   pConnectivityProfile    =   NULL;
    PIHV_SECURITY_PROFILE       pSecurityProfile        =   NULL;

    ASSERT( hIhvExtAdapter );
    ASSERT( pdwReasonCode );

    (*pdwReasonCode) = L2_REASON_CODE_UNKNOWN;

    if ( !pConnectableBssid )
    {
        dwResult =
        IhvValidateProfile
        (
            hIhvExtAdapter,
            pIhvProfileParams,
            pIhvConnProfile,
            pIhvSecProfile,
            pdwReasonCode
        );
        BAIL_ON_WIN32_ERROR( dwResult );

        // Only validate profile if
        // pConnectableBssid is NULL.
        BAIL( );
    }

    // Validating data in pConnectableBssid
    if (( 0 == pConnectableBssid->uNumOfBytes ) || ( NULL == pConnectableBssid->pucBuffer ))
    {
        dwResult = ERROR_NO_MATCH;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    (*pdwReasonCode) = L2_REASON_CODE_IHV_BAD_PROFILE;

    // parse the connectivity profile.
    dwResult =
    GetIhvConnectivityProfile
    (
        pIhvConnProfile,
        &pConnectivityProfile
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pConnectivityProfile );

    // parse the security profile.
    dwResult =
    GetIhvSecurityProfile
    (
        pIhvSecProfile,
        &pSecurityProfile
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pSecurityProfile );

    (*pdwReasonCode) = L2_REASON_CODE_UNKNOWN;

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    // reference the adapter.
    dwResult =
    ReferenceAdapterDetails
    (
        hIhvExtAdapter,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );


    // try matching each BSS description field with the profile
    // and see if there is a match.
    uRemainBytes   =  pConnectableBssid->uNumOfBytes;
    pbCurrPos      =  pConnectableBssid->pucBuffer;

    // BSS Description might not contain any buffer!
    while (uRemainBytes >= FIELD_OFFSET(DOT11_BSS_ENTRY, ucBuffer))
    {
        pBssEntry = (PULDOT11_BSS_ENTRY)pbCurrPos;
        uBssEntryBytes = pBssEntry->uBufferLength + FIELD_OFFSET(DOT11_BSS_ENTRY, ucBuffer);

        ASSERT (uRemainBytes >= uBssEntryBytes);
        uRemainBytes -= uBssEntryBytes;
        pbCurrPos += uBssEntryBytes;

        if
        (
            MatchBssDescription
            (
                pIhvProfileParams,
                pConnectivityProfile,
                pSecurityProfile,
                pBssEntry
            )
        )
        {
            (*pdwReasonCode) = L2_REASON_CODE_SUCCESS;
            dwResult = ERROR_SUCCESS;
            BAIL( );
        }
    }

    // Since none of the BSS entries matched.
    dwResult = ERROR_NO_MATCH;

error:
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    FreeIhvConnectivityProfile( &pConnectivityProfile );
    FreeIhvSecurityProfile( &pSecurityProfile );
    return dwResult;
}





//
// Function to validate profile.
//
DWORD
WINAPI
IhvValidateProfile
(
    IN  HANDLE                              hIhvExtAdapter,
    IN  PDOT11EXT_IHV_PROFILE_PARAMS        pIhvProfileParams,
    IN  PDOT11EXT_IHV_CONNECTIVITY_PROFILE  pIhvConnProfile,
    IN  PDOT11EXT_IHV_SECURITY_PROFILE      pIhvSecProfile,
    OUT PDWORD                              pdwReasonCode
)
{
    DWORD                       dwResult                =   ERROR_SUCCESS;
    PIHV_CONNECTIVITY_PROFILE   pConnectivityProfile    =   NULL;
    PIHV_SECURITY_PROFILE       pSecurityProfile        =   NULL;


    ASSERT( hIhvExtAdapter );
    ASSERT( pdwReasonCode );

    UNREFERENCED_PARAMETER( hIhvExtAdapter );
    UNREFERENCED_PARAMETER( pIhvProfileParams );

    (*pdwReasonCode) = L2_REASON_CODE_IHV_BAD_PROFILE;

    // parse ihv connectivity profile.
    dwResult =
    GetIhvConnectivityProfile
    (
        pIhvConnProfile,
        &pConnectivityProfile
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pConnectivityProfile );

    // parse ihv security profile.
    dwResult =
    GetIhvSecurityProfile
    (
        pIhvSecProfile,
        &pSecurityProfile
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pSecurityProfile );

    (*pdwReasonCode) = L2_REASON_CODE_SUCCESS;

error:
    FreeIhvConnectivityProfile( &pConnectivityProfile );
    FreeIhvSecurityProfile( &pSecurityProfile );
    return dwResult;
}


//
// This function does the actual preassociation work.
//
DWORD
WINAPI
DoPreAssociate
(
    LPVOID  pvPreAssociate
)
{
    DWORD                       dwResult            =   ERROR_SUCCESS;
    DWORD                       dwStatus            =   ERROR_SUCCESS;
    PADAPTER_DETAILS            pAdapterDetails     =   NULL;
    PRE_ASSOCIATE_FUNCTION      lpfnPreAssociate    =   NULL;
    BOOL                        bLocked             =   FALSE;
    DWORD                       dwReasonCode        =   L2_REASON_CODE_UNKNOWN;


    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    dwResult =
    ReferenceAdapterDetails
    (
        (HANDLE) pvPreAssociate,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );


    dwReasonCode = L2_REASON_CODE_IHV_BAD_PROFILE;

    if ( !(pAdapterDetails->pConnectivityProfile && pAdapterDetails->pSecurityProfile) )
    {
        dwResult = ERROR_INVALID_PARAMETER;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    // choose pre-association function based on profile content.
    if
    (
        ( pAdapterDetails->pSecurityProfile->bUseFullSecurity ) ||
        ( pAdapterDetails->pSecurityProfile->bUseIhvConnectivityOnly )
    )
    {
        if ( pAdapterDetails->pSecurityProfile->bUseIhvConnectivityOnly )
        {
            lpfnPreAssociate = DoIhvConnPreAssociate;
        }
        else if ( NULL == pAdapterDetails->pConnectivityProfile->pszParam2 )
        {
            lpfnPreAssociate = DoMissingKeyWepPreAssociate;
        }
        else if ( 0 == pAdapterDetails->pConnectivityProfile->pszParam2[0] )
        {
            lpfnPreAssociate = DoMissingKeyWepPreAssociate;
        }
        else
        {
            lpfnPreAssociate = DoWepPreAssociate;
        }
    }
    else if
    (
        ( !(pAdapterDetails->pSecurityProfile->bUseFullSecurity) )     &&
        ( IHVAuthV1 == pAdapterDetails->pSecurityProfile->AuthType )
    )
    {
            lpfnPreAssociate = Do1xPreAssociate;
    }
    else
    {
        dwResult = ERROR_INVALID_PARAMETER;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    dwReasonCode = L2_REASON_CODE_UNKNOWN;

    LeaveCriticalSection( &g_csSynch );
    bLocked = FALSE;

    ASSERT( lpfnPreAssociate );
    ASSERT( !bLocked );

    dwResult =
    (lpfnPreAssociate)
    (
        pAdapterDetails,
        &dwReasonCode
    );
    BAIL_ON_WIN32_ERROR( dwResult );

error:
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( (HANDLE) &(pAdapterDetails->Link) );
    }
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    if ( pAdapterDetails )
    {
        // call the completion function directly in this thread.
        dwStatus =
        (g_pDot11ExtApi->Dot11ExtPreAssociateCompletion)
        (
            pAdapterDetails->hDot11SvcHandle,
            pAdapterDetails->hConnectSession,
            dwReasonCode,
            dwResult
        );
    }
    if ( ERROR_SUCCESS != dwStatus )
    {
        // IHV specific logging can happen here.
    }
    return dwResult;
}



//
// Function to start the preassociation thread.
//
DWORD
WINAPI
IhvPerformPreAssociate
(
   IN    HANDLE                                 hIhvExtAdapter,
   IN    HANDLE                                 hConnectSession,
   IN    PDOT11EXT_IHV_PROFILE_PARAMS           pIhvProfileParams,
   IN    PDOT11EXT_IHV_CONNECTIVITY_PROFILE     pIhvConnProfile,
   IN    PDOT11EXT_IHV_SECURITY_PROFILE         pIhvSecProfile,
   IN    PDOT11_BSS_LIST                        pConnectableBssid,
   OUT   PDWORD                                 pdwReasonCode
)
{
    DWORD               dwResult        =   ERROR_SUCCESS;
    DWORD               dwStatus        =   ERROR_SUCCESS;
    BOOL                bLocked         =   FALSE;
    PADAPTER_DETAILS    pAdapterDetails =   NULL;


    ASSERT ( pIhvProfileParams );
    ASSERT ( pdwReasonCode );

    UNREFERENCED_PARAMETER( pIhvProfileParams );
    UNREFERENCED_PARAMETER( pConnectableBssid );

    (*pdwReasonCode) = L2_REASON_CODE_UNKNOWN;

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    dwResult =
    ReferenceAdapterDetails
    (
        hIhvExtAdapter,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );

    if ( nic_state_initialized != pAdapterDetails->NicState )
    {
        dwResult = ERROR_INVALID_STATE;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    // Connection specific parameters should be properly initialized.
    if
    (
        ( pAdapterDetails->pOnexData )                              ||
        ( pAdapterDetails->hConnectSession )                        ||
        ( pAdapterDetails->pPerformPostAssociateCompletionRoutine ) ||
        ( pAdapterDetails->pPerformPostAssociateRoutine )           ||
        ( pAdapterDetails->pStopPostAssociateRoutine )
    )
    {
        dwResult = ERROR_INVALID_STATE;
        BAIL_ON_WIN32_ERROR( dwResult );
    }



    (*pdwReasonCode) = L2_REASON_CODE_IHV_BAD_PROFILE;

    // parse connectivity profile
    dwResult =
    GetIhvConnectivityProfile
    (
        pIhvConnProfile,
        &(pAdapterDetails->pConnectivityProfile)
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails->pConnectivityProfile );

    // parse security profile.
    dwResult =
    GetIhvSecurityProfile
    (
        pIhvSecProfile,
        &(pAdapterDetails->pSecurityProfile)
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails->pSecurityProfile );

    (*pdwReasonCode) = L2_REASON_CODE_UNKNOWN;

    pAdapterDetails->NicState = nic_state_pre_assoc_started;

    pAdapterDetails->hConnectSession        =   hConnectSession;
    pAdapterDetails->bModifyCurrentProfile  =   FALSE;


    // post a new thread to do the pre-association work.
    dwResult =
    StartNewProtectedThread
    (
        hIhvExtAdapter,
        DoPreAssociate,
        (LPVOID) hIhvExtAdapter
    );
    BAIL_ON_WIN32_ERROR( dwResult );


    (*pdwReasonCode) = L2_REASON_CODE_SUCCESS;


error:
    if ( ERROR_SUCCESS != dwResult )
    {
        dwStatus =
        IhvAdapterReset
        (
            hIhvExtAdapter
        );
        ASSERT( ERROR_SUCCESS == dwStatus );
    }
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}





//
// This function starts post associate routine
// in a separate thread and returns.
//
DWORD
WINAPI
IhvPerformPostAssociate
(
   IN    HANDLE                                       hIhvExtAdapter,
   IN    HANDLE                                       hSecuritySessionID,
   IN    PDOT11_PORT_STATE                            pPortState,
   IN    ULONG                                        uDot11AssocParamsBytes,
   IN    PDOT11_ASSOCIATION_COMPLETION_PARAMETERS     pDot11AssocParams
)
{
    DWORD               dwResult        =   ERROR_SUCCESS;
    BOOL                bLocked         =   FALSE;
    PPOST_ASSOC_DATA    ppostAssocData  =   NULL;
    PADAPTER_DETAILS    pAdapterDetails =   NULL;


    ASSERT ( pDot11AssocParams );

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    dwResult =
    ReferenceAdapterDetails
    (
        hIhvExtAdapter,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );


    if ( nic_state_pre_assoc_ended != pAdapterDetails->NicState )
    {
        dwResult = ERROR_INVALID_STATE;
        BAIL_ON_WIN32_ERROR( dwResult );
    }
    pAdapterDetails->NicState = nic_state_post_assoc_started;

    // is any post-association work required ??
    if ( pAdapterDetails->pPerformPostAssociateRoutine )
    {
        dwResult =
        ( pAdapterDetails->pPerformPostAssociateRoutine )
        (
            pAdapterDetails,
            hSecuritySessionID,
            pPortState,
            uDot11AssocParamsBytes,
            pDot11AssocParams
        );
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    // The post association completion thread may have been
    // started by the perform post association routine for
    // the current profile. Check if the completion thread
    // needs to be started and start the routine.
    if ( pAdapterDetails->pPerformPostAssociateCompletionRoutine )
    {
        ppostAssocData = (PPOST_ASSOC_DATA) PrivateMemoryAlloc( sizeof( POST_ASSOC_DATA ) );
        if ( !ppostAssocData )
        {
            dwResult = ERROR_OUTOFMEMORY;
            BAIL_ON_WIN32_ERROR( dwResult );
        }

        ppostAssocData->hIhvExtAdapter      =  hIhvExtAdapter;
        ppostAssocData->hDot11SvcHandle     =  pAdapterDetails->hDot11SvcHandle;
        ppostAssocData->hSecuritySessionId  =  hSecuritySessionID;


        dwResult =
        StartNewProtectedThread
        (
            hIhvExtAdapter,
            pAdapterDetails->pPerformPostAssociateCompletionRoutine,
            ppostAssocData
        );
        BAIL_ON_WIN32_ERROR( dwResult );


        ppostAssocData = NULL;
    }



error:
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    PrivateMemoryFree( ppostAssocData );
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}



//
// Reset the adapter to initialized state.
//
DWORD
WINAPI
IhvAdapterReset
(
   IN    HANDLE   hIhvExtAdapter
)
{
    DWORD               dwResult        =   ERROR_SUCCESS;
    PADAPTER_DETAILS    pAdapterDetails =   NULL;
    DWORD               dwRefCount      =   0;
    BOOL                bOk             =   FALSE;
    BOOL                bLocked         =   FALSE;


    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    dwResult =
    ReferenceAdapterDetails
    (
        hIhvExtAdapter,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );


    for ( ;; )
    {
        ASSERT( bLocked );

        dwRefCount = pAdapterDetails->dwRefCount;

        if ( 2 == dwRefCount ) // For adapter init and self call.
        {
            break;
        }

        if ( nic_state_pre_assoc_started == pAdapterDetails->NicState )
        {
            pAdapterDetails->NicState = nic_state_pre_assoc_ended;
            bOk = SetEvent( pAdapterDetails->hUIResponse );
            ASSERT( bOk );
        }

        LeaveCriticalSection( &g_csSynch );
        bLocked = FALSE;

        Sleep( 100 );

        EnterCriticalSection( &g_csSynch );
        bLocked = TRUE;
    }

    ASSERT( bLocked );

    // Resetting adapter.

    pAdapterDetails->NicState                                   =   nic_state_initialized;
    pAdapterDetails->hConnectSession                            =   NULL;
    pAdapterDetails->bModifyCurrentProfile                      =   FALSE;
    pAdapterDetails->pPerformPostAssociateCompletionRoutine     =   NULL;
    pAdapterDetails->pPerformPostAssociateRoutine               =   NULL;
    pAdapterDetails->pStopPostAssociateRoutine                  =   NULL;

    // freeing UI response data.
    pAdapterDetails->dwResponseLen                              =   0;

    PrivateMemoryFree( pAdapterDetails->pbResponse );
    pAdapterDetails->pbResponse                                 =   NULL;

    ZeroMemory( &(pAdapterDetails->currentGuidUIRequest), sizeof( GUID ) );

    // freeing profile and onex data
    FreeOnexData( &(pAdapterDetails->pOnexData) );
    FreeIhvConnectivityProfile( &(pAdapterDetails->pConnectivityProfile) );
    FreeIhvSecurityProfile( &(pAdapterDetails->pSecurityProfile) );

    // unblocking UI thread.
    bOk = ResetEvent( pAdapterDetails->hUIResponse );
    if ( !bOk )
    {
        dwResult = GetLastError( );
        BAIL_ON_WIN32_ERROR( dwResult );
    }

error:
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    return dwResult;
}




//
// Stop post association. Get back
// to the state before post association started.
//
DWORD
WINAPI
IhvStopPostAssociate
(
   IN    HANDLE               hIhvExtAdapter,
   IN    PDOT11_MAC_ADDRESS   pPeer,
   IN    DOT11_ASSOC_STATUS   dot11AssocStatus
)
{
    DWORD               dwResult        =   ERROR_SUCCESS;
    PADAPTER_DETAILS    pAdapterDetails =   NULL;
    DWORD               dwRefCount      =   0;
    BOOL                bLocked         =   FALSE;

    // The dot11AssocStatus parameter can be compared with
    // values DOT11_ASSOC_STATUS_* defined in the public
    // headers.

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    dwResult =
    ReferenceAdapterDetails
    (
        hIhvExtAdapter,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );

    for ( ;; )
    {
        ASSERT( bLocked );

        dwRefCount = pAdapterDetails->dwRefCount;

        if ( 2 == dwRefCount ) // For adapter init and self call.
        {
            break;
        }

        LeaveCriticalSection( &g_csSynch );
        bLocked = FALSE;

        Sleep( 100 );

        EnterCriticalSection( &g_csSynch );
        bLocked = TRUE;
    }

    ASSERT( bLocked );

    if ( nic_state_initialized == pAdapterDetails->NicState )
    {
        // NO OP
        // To handle the case when stop post associate
        // call comes after adapter reset.
        BAIL( );
    }

    // Call the post association routine - if there is any.
    if ( pAdapterDetails->pStopPostAssociateRoutine )
    {
        dwResult =
        (pAdapterDetails->pStopPostAssociateRoutine)
        (
            pAdapterDetails,
            pPeer,
            dot11AssocStatus
        );
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    pAdapterDetails->NicState = nic_state_pre_assoc_ended;

error:
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    return dwResult;
}


//
// Process received packets.
//
DWORD
WINAPI
IhvReceivePacket
(
   IN    HANDLE   hIhvExtAdapter,
   IN    DWORD    dwInBufferSize,
   IN    LPVOID   pvInBuffer
)
{
    DWORD                       dwResult            =   ERROR_SUCCESS;
    BOOL                        bLocked             =   FALSE;
    PADAPTER_DETAILS            pAdapterDetails     =   NULL;
    IHV_RECEIVE_PACKET_HANDLER  lpfnReceivePacket   =   NULL;


    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;


    dwResult =
    ReferenceAdapterDetails
    (
        hIhvExtAdapter,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );


    if ( pAdapterDetails->pOnexData && pAdapterDetails->pOnexData->lpfnReceivePacket )
    {
        lpfnReceivePacket = pAdapterDetails->pOnexData->lpfnReceivePacket;
    }
    else
    {
        dwResult = ERROR_INVALID_STATE;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    LeaveCriticalSection( &g_csSynch );
    bLocked = FALSE;

    ASSERT( lpfnReceivePacket );

    // Call the receive packet routine.
    dwResult =
    (lpfnReceivePacket)
    (
        pAdapterDetails,
        dwInBufferSize,
        pvInBuffer
    );
    BAIL_ON_WIN32_ERROR( dwResult );


error:
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}




//
// Local copy of possible discovery profiles.
//
DOT11EXT_IHV_DISCOVERY_PROFILE
g_IhvDiscoveryProfiles[] =
{
    // discovery profile 1.
    {
        {
            L"<IhvConnectivity xmlns=\"http://www.someihv.com/nwifi/profile\">"
            L"<IHVConnectivityParam1>0</IHVConnectivityParam1>"
            L"<IHVConnectivityParam2></IHVConnectivityParam2>"
            L"</IhvConnectivity>"
        },

        // Use MS Onex.
        {
            L"<IhvSecurity xmlns=\"http://www.someihv.com/nwifi/profile\">"
            L"<IHVUsesFullSecurity>FALSE</IHVUsesFullSecurity>"
            L"<IHVAuthentication>IHVAuthV1</IHVAuthentication>"
            L"<IHVEncryption>IHVCipher1</IHVEncryption>"
            L"<IHVSecurityParam1>0</IHVSecurityParam1>"
            L"<IHVSecurityParam2></IHVSecurityParam2>"
            L"</IhvSecurity>",

            TRUE
        }
    },

    // discovery profile 2
    {
        // Open Wep
        {
            L"<IhvConnectivity xmlns=\"http://www.someihv.com/nwifi/profile\">"
            L"<IHVConnectivityParam1>0</IHVConnectivityParam1>"
            L"<IHVConnectivityParam2></IHVConnectivityParam2>"
            L"</IhvConnectivity>"
        },

        // Full IHV Security
        {
            L"<IhvSecurity xmlns=\"http://www.someihv.com/nwifi/profile\">"
            L"<IHVUsesFullSecurity>TRUE</IHVUsesFullSecurity>"
            L"<IHVAuthentication>IHVAuthV1</IHVAuthentication>"
            L"<IHVEncryption>IHVCipher1</IHVEncryption>"
            L"<IHVSecurityParam1>0</IHVSecurityParam1>"
            L"<IHVSecurityParam2></IHVSecurityParam2>"
            L"</IhvSecurity>",

            FALSE
        }
    }
};







//
// Create discovery profiles.
//
DWORD
WINAPI
IhvCreateDiscoveryProfiles
(
    IN  HANDLE                                      hIhvExtAdapter,
    IN  BOOL                                        bInsecure,
    IN  PDOT11EXT_IHV_PROFILE_PARAMS                pIhvProfileParams,
    IN  PDOT11_BSS_LIST                             pConnectableBssid,
    OUT PDOT11EXT_IHV_DISCOVERY_PROFILE_LIST        pIhvDiscoveryProfileList,
    OUT PDWORD                                      pdwReasonCode
)
{
    DWORD   dwResult            =   ERROR_SUCCESS;
    DWORD   dwIndex             =   0;
    DWORD   dwIHVNumProfiles    =   ARRAY_LENGTH( g_IhvDiscoveryProfiles );

    ASSERT( pIhvDiscoveryProfileList );
    ASSERT( pdwReasonCode );

    UNREFERENCED_PARAMETER( hIhvExtAdapter );
    UNREFERENCED_PARAMETER( bInsecure );
    UNREFERENCED_PARAMETER( pIhvProfileParams );
    UNREFERENCED_PARAMETER( pConnectableBssid );

    (*pdwReasonCode) = L2_REASON_CODE_IHV_OUTOFMEMORY;

    // allocate buffer for the array.
    dwResult =
    (g_pDot11ExtApi->Dot11ExtAllocateBuffer)
    (
        dwIHVNumProfiles * sizeof( DOT11EXT_IHV_DISCOVERY_PROFILE ),
        (LPVOID*) &(pIhvDiscoveryProfileList->pIhvDiscoveryProfiles)
    );
    BAIL_ON_WIN32_ERROR( dwResult );

    ASSERT( pIhvDiscoveryProfileList->pIhvDiscoveryProfiles );
    ZeroMemory
    (
        pIhvDiscoveryProfileList->pIhvDiscoveryProfiles,
        dwIHVNumProfiles * sizeof( DOT11EXT_IHV_DISCOVERY_PROFILE )
    );



    // prepare each discovery profile.
    for ( dwIndex = 0; dwIndex < dwIHVNumProfiles; dwIndex++ )
    {
        dwResult =
        CopyDiscoveryProfile
        (
            g_IhvDiscoveryProfiles + dwIndex,
            pIhvDiscoveryProfileList->pIhvDiscoveryProfiles + dwIndex
        );
        BAIL_ON_WIN32_ERROR( dwResult );

    }

    pIhvDiscoveryProfileList->dwCount = dwIHVNumProfiles;
    (*pdwReasonCode) = L2_REASON_CODE_SUCCESS;

error:
    if ( ERROR_SUCCESS != dwResult )
    {
        if ( pIhvDiscoveryProfileList->pIhvDiscoveryProfiles )
        {
            for ( dwIndex = 0; dwIndex < dwIHVNumProfiles; dwIndex++ )
            {
                FreeDiscoveryProfile( pIhvDiscoveryProfileList->pIhvDiscoveryProfiles + dwIndex );
            }
            (g_pDot11ExtApi->Dot11ExtFreeBuffer)( pIhvDiscoveryProfileList->pIhvDiscoveryProfiles );
        }
        pIhvDiscoveryProfileList->dwCount = 0;
    }
    return dwResult;
}



//
// Process UI Response function.
//
DWORD
WINAPI
IhvProcessUIResponse
(
   IN    GUID        guidUIRequest,
   IN    DWORD       dwByteCount,
   IN    LPVOID      pvResponseBuffer
)
{
    DWORD                   dwResult        =   ERROR_SUCCESS;
    BOOL                    bLocked         =   FALSE;
    PADAPTER_DETAILS        pAdapterDetails =   NULL;
    HANDLE                  hIhvExtAdapter  =   NULL;

    if ( !( dwByteCount && pvResponseBuffer ) )
    {
        dwResult = ERROR_INVALID_PARAMETER;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;

    // find the adapter from the UI response guid.
    dwResult =
    ReferenceAdapterDetailsByUIRequestGuid
    (
        &guidUIRequest,
        &pAdapterDetails,
        &hIhvExtAdapter
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );

    ZeroMemory( &(pAdapterDetails->currentGuidUIRequest), sizeof( GUID ) );

    // Copy the UI response to the adapter data structure.
    PrivateMemoryFree( pAdapterDetails->pbResponse );

    pAdapterDetails->pbResponse = (BYTE*) PrivateMemoryAlloc( dwByteCount );
    if ( !(pAdapterDetails->pbResponse) )
    {
        dwResult = ERROR_OUTOFMEMORY;
        BAIL_ON_WIN32_ERROR(dwResult);
    }
    CopyMemory( pAdapterDetails->pbResponse, pvResponseBuffer, dwByteCount );

    (pAdapterDetails->dwResponseLen) = dwByteCount;

    // Waiting thread can pick up the response now.
    SetEvent( pAdapterDetails->hUIResponse );

error:
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}




//
// Handler to clear memory after sending packet.
//
DWORD
WINAPI
IhvSendPacketCompletion
(
   IN    HANDLE   hSendCompletion
)
{
    // The sample is not sending any packets.
    // So send packet completion should
    // not be called.
    ASSERTFAILURE();

    // The freeing function used here
    // should be the reverse of the function
    // used to allocate memory before calling
    // Send Packet.
    PrivateMemoryFree( (LPVOID) hSendCompletion );
    return ERROR_SUCCESS;
}




//
// Function to return UI Request on OS query.
//
DWORD
WINAPI
IhvQueryUIRequest
(
   IN    HANDLE                        hIhvExtAdapter,
   IN    DOT11EXT_IHV_CONNECTION_PHASE connectionPhase,
   OUT   PDOT11EXT_IHV_UI_REQUEST*     ppIhvUIRequest
)
{
    // This IHV handler is a post Vista extensibility point.
    // It is currently unused.
    ASSERTFAILURE();

    UNREFERENCED_PARAMETER( hIhvExtAdapter );
    UNREFERENCED_PARAMETER( connectionPhase );
    UNREFERENCED_PARAMETER( ppIhvUIRequest );

    return ERROR_CALL_NOT_IMPLEMENTED;
}




//
// Handler to receive the Onex Result.
//
DWORD
WINAPI
IhvOnexIndicateResult
(
   IN    HANDLE                           hIhvExtAdapter,
   IN    DOT11_MSONEX_RESULT              msOneXResult,
   IN    PDOT11_MSONEX_RESULT_PARAMS      pDot11MsOneXResultParams
)
{
    DWORD               dwResult        =   ERROR_SUCCESS;
    BOOL                bLocked         =   FALSE;
    PADAPTER_DETAILS    pAdapterDetails =   NULL;


    EnterCriticalSection( &g_csSynch );
    bLocked = TRUE;


    dwResult =
    ReferenceAdapterDetails
    (
        hIhvExtAdapter,
        &pAdapterDetails
    );
    BAIL_ON_WIN32_ERROR( dwResult );
    ASSERT( pAdapterDetails );


    // If indication of result is required.
    if ( pAdapterDetails->pOnexData && pAdapterDetails->pOnexData->lpfnIndicateResult )
    {
        dwResult =
        (pAdapterDetails->pOnexData->lpfnIndicateResult)
        (
            pAdapterDetails,
            msOneXResult,
            pDot11MsOneXResultParams
        );
        BAIL_ON_WIN32_ERROR( dwResult );

    }
    else
    {
        dwResult = ERROR_INVALID_STATE;
        BAIL_ON_WIN32_ERROR( dwResult );
    }

error:
    if ( pAdapterDetails )
    {
        DerefenceAdapterDetails( hIhvExtAdapter );
    }
    if ( bLocked )
    {
        LeaveCriticalSection( &g_csSynch );
    }
    return dwResult;
}





//
// Handler to receive Control.
//
DWORD
WINAPI
IhvControl
(
   IN    HANDLE    hIhvExtAdapter,
   IN    DWORD     dwInBufferSize,
   IN    PBYTE     pInBuffer,
   IN    DWORD     dwOutBufferSize,
   OUT   PBYTE     pOutBuffer,
   OUT   PDWORD    pdwBytesReturned
)
{
    // Sample does not demonstrate use of IHV control.

    UNREFERENCED_PARAMETER( hIhvExtAdapter );
    UNREFERENCED_PARAMETER( dwInBufferSize );
    UNREFERENCED_PARAMETER( pInBuffer );
    UNREFERENCED_PARAMETER( dwOutBufferSize );
    UNREFERENCED_PARAMETER( pOutBuffer );
    UNREFERENCED_PARAMETER( pdwBytesReturned );

    return ERROR_SUCCESS;
}


Our Services

  • What our customers say about us?

© 2011-2025 All Rights Reserved. Joya Systems. 4425 South Mopac Building II Suite 101 Austin, TX 78735 Tel: 800-DEV-KERNEL

Privacy Policy. Terms of use. Valid XHTML & CSS