summaryrefslogtreecommitdiff
path: root/network/wlan/ihvsample/ihvsample.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'network/wlan/ihvsample/ihvsample.cpp')
-rw-r--r--network/wlan/ihvsample/ihvsample.cpp1554
1 files changed, 1554 insertions, 0 deletions
diff --git a/network/wlan/ihvsample/ihvsample.cpp b/network/wlan/ihvsample/ihvsample.cpp
new file mode 100644
index 00000000..2b73a7ed
--- /dev/null
+++ b/network/wlan/ihvsample/ihvsample.cpp
@@ -0,0 +1,1554 @@
+/*++
+
+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;
+}
+
+