diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /network/wlan/ihvsample | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'network/wlan/ihvsample')
27 files changed, 7743 insertions, 0 deletions
diff --git a/network/wlan/ihvsample/adapters.cpp b/network/wlan/ihvsample/adapters.cpp new file mode 100644 index 00000000..919e47a6 --- /dev/null +++ b/network/wlan/ihvsample/adapters.cpp @@ -0,0 +1,439 @@ +/*++ + +Copyright (c) 2005 Microsoft Corporation + +Abstract: + + Sample IHV Extensibility DLL to extend + 802.11 LWF driver for third party protocols. + + +--*/ + +#include "precomp.h" + +LIST_ENTRY g_AdaptersList = {0}; + + + +// +// Copied Macros from wdm.h +// + +#define CONTAINING_RECORD(address, type, field) ((type *)( \ + (PCHAR)(address) - \ + (ULONG_PTR)(&((type *)0)->field))) + + +#define InitializeListHead(ListHead) (\ + (ListHead)->Flink = (ListHead)->Blink = (ListHead)) + + + +#define RemoveEntryList(Entry) {\ + PLIST_ENTRY _EX_Blink;\ + PLIST_ENTRY _EX_Flink;\ + _EX_Flink = (Entry)->Flink;\ + _EX_Blink = (Entry)->Blink;\ + _EX_Blink->Flink = _EX_Flink;\ + _EX_Flink->Blink = _EX_Blink;\ + } + + +#define InsertTailList(ListHead,Entry) {\ + PLIST_ENTRY _EX_Blink;\ + PLIST_ENTRY _EX_ListHead;\ + _EX_ListHead = (ListHead);\ + _EX_Blink = _EX_ListHead->Blink;\ + (Entry)->Flink = _EX_ListHead;\ + (Entry)->Blink = _EX_Blink;\ + _EX_Blink->Flink = (Entry);\ + _EX_ListHead->Blink = (Entry);\ + } + + + + +// +// Initialize the AdapterList data structure. +// +VOID +InitAdapterDetailsList +( + VOID +) +{ + EnterCriticalSection( &g_csSynch ); + + // Assuming that memory in g_AdaptersList + // could be garbage - just initialize the + // fields appropriately. + + InitializeListHead( &g_AdaptersList ); + + LeaveCriticalSection( &g_csSynch ); + + return; +} + + + + +// +// Free the AdapterList data structure - contention is not supported. +// +VOID +DeinitAdapterDetailsList +( + VOID +) +{ + EnterCriticalSection( &g_csSynch ); + + // ASSERT that the list is empty. The call + // to InitializeListHead is not really required + // if the following conditions are true. + ASSERT(g_AdaptersList.Flink == &g_AdaptersList ); + ASSERT(g_AdaptersList.Blink == &g_AdaptersList ); + + // clear the memory any way. + InitializeListHead( &g_AdaptersList ); + + LeaveCriticalSection( &g_csSynch ); + + return; +} + + + + + +// +// Add a single adapter to the list. Starting refcount is one. +// +DWORD +InitAdapterDetails +( + HANDLE hDot11SvcHandle, + PHANDLE phIhvExtAdapter +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + PADAPTER_DETAILS pAdapterDetails = NULL; + HANDLE hIhvExtAdapter = NULL; + + + // acquire global lock. + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // verify state. this check prevents new adapters from + // being added when service is being deinited. + if (!g_bAllowInit) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // allocate memory. + pAdapterDetails = (PADAPTER_DETAILS) PrivateMemoryAlloc( sizeof( ADAPTER_DETAILS ) ); + if ( !pAdapterDetails ) + { + dwResult = ERROR_OUTOFMEMORY; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // add the new object to the list. if anything fails + // in this function the object would be automatically + // dereferenced and removed from the list. + InsertTailList( &g_AdaptersList, &(pAdapterDetails->Link) ); + + // initialize fields that are used by object lifetime management. + hIhvExtAdapter = (HANDLE) &(pAdapterDetails->Link); + pAdapterDetails->dwRefCount = 1; + pAdapterDetails->hDot11SvcHandle = hDot11SvcHandle; + pAdapterDetails->NicState = nic_state_initialized; + + + // Event that gets triggered + // once UI response is received. + pAdapterDetails->hUIResponse = + CreateEvent + ( + NULL, + FALSE, // Auto Reset + FALSE, // Start in non-signaled state. + NULL + ); + if ( !(pAdapterDetails->hUIResponse) ) + { + dwResult = GetLastError( ); + BAIL_ON_WIN32_ERROR( dwResult ); + } + + + // fill out-params. release responsibility to + // for deiniting object to caller. + (*phIhvExtAdapter) = hIhvExtAdapter; + hIhvExtAdapter = NULL; + +error: + if ( hIhvExtAdapter ) + { + // something failed after adding the object to + // the global list. so it needs to be removed. + DerefenceAdapterDetails( hIhvExtAdapter ); + } + if ( bLocked ) + { + // leave global lock. + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + + + + + +// +// Add a reference to a particular adapter and find the pointer to the context. +// +DWORD +ReferenceAdapterDetails +( + HANDLE hIhvExtAdapter, + PADAPTER_DETAILS* ppAdapterDetails +) +{ + DWORD dwResult = ERROR_NOT_FOUND; + BOOL bLocked = FALSE; + PLIST_ENTRY pEntry = NULL; + PADAPTER_DETAILS pAdapterDetails = NULL; + + ASSERT( ppAdapterDetails ); + + // acquire global lock. + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + + // search the global list of adapters for a match. + for + ( + pEntry = g_AdaptersList.Flink; + pEntry != &g_AdaptersList; + pEntry = pEntry->Flink + ) + { + // Get the adapter data structure for current entry. + pAdapterDetails = CONTAINING_RECORD( pEntry, ADAPTER_DETAILS, Link ); + ASSERT( pAdapterDetails ); + + // conditions could be converted to an ASSERT. + if + ( + ( pAdapterDetails->NicState == nic_state_uninitialized ) || + ( pAdapterDetails->NicState >= nic_state_max ) + ) + { + ASSERTFAILURE(); + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // if match found - bail with success. + if ( hIhvExtAdapter == ((HANDLE) pEntry) ) + { + (pAdapterDetails->dwRefCount)++; + (*ppAdapterDetails) = pAdapterDetails; + + dwResult = ERROR_SUCCESS; + BAIL( ); + } + } + +error: + if ( bLocked ) + { + // release global lock. + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + + + + +// +// Find adapter context pointer using UI request GUID. +// +DWORD +ReferenceAdapterDetailsByUIRequestGuid +( + GUID* pguidUIRequest, + PADAPTER_DETAILS* ppAdapterDetails, + HANDLE* phIhvExtAdapter +) +{ + DWORD dwResult = ERROR_NOT_FOUND; + BOOL bLocked = FALSE; + PLIST_ENTRY pEntry = NULL; + PADAPTER_DETAILS pAdapterDetails = NULL; + + ASSERT( ppAdapterDetails ); + ASSERT( phIhvExtAdapter ); + + // acquire global lock. + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // look for adapter with matching ui request guid in the global list. + for + ( + pEntry = g_AdaptersList.Flink; + pEntry != &g_AdaptersList; + pEntry = pEntry->Flink + ) + { + // get the current adapter's context info. + pAdapterDetails = CONTAINING_RECORD( pEntry, ADAPTER_DETAILS, Link ); + ASSERT( pAdapterDetails ); + + // could be an ASSERT. + if + ( + ( pAdapterDetails->NicState == nic_state_uninitialized ) || + ( pAdapterDetails->NicState >= nic_state_max ) + ) + { + ASSERTFAILURE(); + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // if match found, bail with success. + if ( pAdapterDetails->currentGuidUIRequest == (*pguidUIRequest) ) + { + (pAdapterDetails->dwRefCount)++; + (*ppAdapterDetails) = pAdapterDetails; + (*phIhvExtAdapter) = (HANDLE) pEntry; + + dwResult = ERROR_SUCCESS; + BAIL( ); + } + } + +error: + if ( bLocked ) + { + // leave global lock. + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + + + + + +// +// Dereference an adapter - resources will be freed when the refcount +// goes to zero. +// +VOID +DerefenceAdapterDetails +( + HANDLE hIhvExtAdapter +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + PADAPTER_DETAILS pAdapterDetails = NULL; + BOOL bOk = TRUE; + + + // acquire global lock. + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // trying to reference the adapter. the part of the + // code that increments the refcount is not useful + // here, we are only using the algorithm to find + // the context pointer. the refcount would be decremented + // after the function call if the call succeeds. + dwResult = + ReferenceAdapterDetails + ( + hIhvExtAdapter, + &pAdapterDetails + ); + BAIL_ON_WIN32_ERROR( dwResult ); + + ASSERT( pAdapterDetails ); + + // Undoing the refcount increment in the previous call. + (pAdapterDetails->dwRefCount)--; + + // could be an ASSERT - the adapter + // context should not be in this state. + if ( 0 == pAdapterDetails->dwRefCount ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // performing the intended dereferencing. + (pAdapterDetails->dwRefCount)--; + + // checking if the adapter entry can go. + if ( pAdapterDetails->dwRefCount ) + { + BAIL( ); + } + + // Since this was the last reference, + // it is time to deinitialize the memory. + + // remove the adapter from the global list. + RemoveEntryList( &(pAdapterDetails->Link) ); + + // Close handle to the UI response event. + if ( pAdapterDetails->hUIResponse ) + { + bOk = CloseHandle( pAdapterDetails->hUIResponse ); + ASSERT( bOk ); + } + + // free the UI response memory. + if ( pAdapterDetails->pbResponse ) + { + PrivateMemoryFree( pAdapterDetails->pbResponse ); + pAdapterDetails->pbResponse = NULL; + } + + // frees the connection specific data in the adapter data structure. + FreeOnexData( &(pAdapterDetails->pOnexData) ); + + // frees the profiles. + FreeIhvConnectivityProfile( &(pAdapterDetails->pConnectivityProfile) ); + FreeIhvSecurityProfile( &(pAdapterDetails->pSecurityProfile) ); + + // frees the context. + SecureZeroMemory( pAdapterDetails, sizeof( ADAPTER_DETAILS ) ); + PrivateMemoryFree( pAdapterDetails ); + +error: + if ( bLocked ) + { + // release global lock. + LeaveCriticalSection( &g_csSynch ); + } + ASSERT( ERROR_SUCCESS == dwResult ); + return; +} + diff --git a/network/wlan/ihvsample/adapters.h b/network/wlan/ihvsample/adapters.h new file mode 100644 index 00000000..ad0f9779 --- /dev/null +++ b/network/wlan/ihvsample/adapters.h @@ -0,0 +1,125 @@ + + + +// +// Different states of current NIC. +// +typedef +enum _NIC_STATE +{ + nic_state_uninitialized, + nic_state_initialized, + nic_state_pre_assoc_started, + nic_state_pre_assoc_ended, + nic_state_post_assoc_started, + nic_state_onex_in_progress, + nic_state_post_assoc_ended, + + nic_state_max // should be the last one. +} +NIC_STATE, *PNIC_STATE; + + +////////////////////////////////// +// Adapter lifetime management // +////////////////////////////////// + +// +// Adapter Data Structure +// + +struct _ADAPTER_DETAILS +{ + // Adapter list and lifetime management. + LIST_ENTRY Link; + DWORD dwRefCount; + NIC_STATE NicState; + + + // Framework reference. + HANDLE hDot11SvcHandle; + + // Handler functions for different stages of connection. + LPTHREAD_START_ROUTINE pPerformPostAssociateCompletionRoutine; + POST_ASSOCIATE_FUNCTION pPerformPostAssociateRoutine; + STOP_POST_ASSOCIATE_FUNCTION pStopPostAssociateRoutine; + + + // Data for current connection. + HANDLE hConnectSession; + BOOL bModifyCurrentProfile; + PONEX_DATA pOnexData; + GUID currentGuidUIRequest; + DWORD dwResponseLen; + _Field_size_bytes_(dwResponseLen) BYTE* pbResponse; + HANDLE hUIResponse; + PIHV_CONNECTIVITY_PROFILE pConnectivityProfile; + PIHV_SECURITY_PROFILE pSecurityProfile; +}; + + + +// +// Initialize the AdapterList data structure. +// +VOID +InitAdapterDetailsList +( + VOID +); + + +// +// Free the AdapterList data structure - contention is not supported. +// +VOID +DeinitAdapterDetailsList +( + VOID +); + +// +// Add a single adapter to the list. Starting refcount is one. +// +DWORD +InitAdapterDetails +( + HANDLE hDot11SvcHandle, + PHANDLE phIhvExtAdapter +); + + +// +// Add a reference to a particular adapter and find the pointer to the context. +// +DWORD +ReferenceAdapterDetails +( + HANDLE hIhvExtAdapter, + PADAPTER_DETAILS* ppAdapterDetails +); + + +// +// Find adapter context pointer using UI request GUID. +// +DWORD +ReferenceAdapterDetailsByUIRequestGuid +( + GUID* pguidUIRequest, + PADAPTER_DETAILS* ppAdapterDetails, + HANDLE* phIhvExtAdapter +); + + + +// +// Dereference an adapter - resources will be freed when the refcount +// goes to zero. +// +VOID +DerefenceAdapterDetails +( + HANDLE hIhvExtAdapter +); + diff --git a/network/wlan/ihvsample/ihv1xext.xml b/network/wlan/ihvsample/ihv1xext.xml new file mode 100644 index 00000000..77ae471f --- /dev/null +++ b/network/wlan/ihvsample/ihv1xext.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" ?> +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihv1xext</name> + <SSIDConfig> + <SSID> + <name>_1x_SSID_</name> + </SSID> + <nonBroadcast>false</nonBroadcast> + </SSIDConfig> + <connectionType>ESS</connectionType> + <connectionMode>manual</connectionMode> + <autoSwitch>false</autoSwitch> + <MSM> + <security> + <OneX xmlns="http://www.microsoft.com/networking/OneX/v1"> + <EAPConfig> + <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> + <EapMethod> + <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type> + <VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId> + <VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType> + <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId> + </EapMethod> + <ConfigBlob></ConfigBlob> + </EapHostConfig> + </EAPConfig> + </OneX> + </security> + </MSM> + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVConnectivityParam1>0</IHVConnectivityParam1> + <IHVConnectivityParam2></IHVConnectivityParam2> + </IhvConnectivity> + </connectivity> + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVUsesFullSecurity>FALSE</IHVUsesFullSecurity> + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + <IHVEncryption>IHVCipher1</IHVEncryption> + <IHVSecurityParam1>0</IHVSecurityParam1> + <IHVSecurityParam2></IHVSecurityParam2> + </IhvSecurity> + </security> + <useMSOneX>true</useMSOneX> + </IHV> +</WLANProfile> diff --git a/network/wlan/ihvsample/ihvconn.xml b/network/wlan/ihvsample/ihvconn.xml new file mode 100644 index 00000000..0bb09694 --- /dev/null +++ b/network/wlan/ihvsample/ihvconn.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvconn</name> + + <SSIDConfig> + <SSID> + <name>_SSID_</name> + </SSID> + </SSIDConfig> + + <connectionType>ESS</connectionType> + <connectionMode>manual</connectionMode> + + <MSM> + <connectivity> + + </connectivity> + <security> + <authEncryption> + <authentication>open</authentication> + <encryption>WEP</encryption> + </authEncryption> + </security> + + + </MSM> + + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + + <IHVConnectivityParam1>0</IHVConnectivityParam1> + + <IHVConnectivityParam2>wrongkey</IHVConnectivityParam2> + + </IhvConnectivity> + </connectivity> + + </IHV> + +</WLANProfile> + diff --git a/network/wlan/ihvsample/ihvmachine.xml b/network/wlan/ihvsample/ihvmachine.xml new file mode 100644 index 00000000..04b7ba21 --- /dev/null +++ b/network/wlan/ihvsample/ihvmachine.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" ?> +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvmachine</name> + <SSIDConfig> + <SSID> + <name>_1x_SSID_</name> + </SSID> + <nonBroadcast>false</nonBroadcast> + </SSIDConfig> + <connectionType>ESS</connectionType> + <connectionMode>manual</connectionMode> + <autoSwitch>false</autoSwitch> + <MSM> + <security> + <authEncryption> + <authentication>open</authentication> + <encryption>WEP</encryption> + <useOneX>true</useOneX> + </authEncryption> + <OneX xmlns="http://www.microsoft.com/networking/OneX/v1"> + <maxAuthFailures>3</maxAuthFailures> + + <!-- This would not work if any UI prompt is required by the backend. --> + <authMode>machine</authMode> + + <EAPConfig> + <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> + <EapMethod> + <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type> + <VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId> + <VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType> + <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId> + </EapMethod> + <ConfigBlob></ConfigBlob> + </EapHostConfig> + </EAPConfig> + </OneX> + </security> + </MSM> + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVConnectivityParam1>0</IHVConnectivityParam1> + <IHVConnectivityParam2></IHVConnectivityParam2> + </IhvConnectivity> + </connectivity> + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVUsesFullSecurity>FALSE</IHVUsesFullSecurity> + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + <IHVEncryption>IHVCipher1</IHVEncryption> + <IHVSecurityParam1>0</IHVSecurityParam1> + <IHVSecurityParam2></IHVSecurityParam2> + </IhvSecurity> + </security> + <useMSOneX>true</useMSOneX> + </IHV> +</WLANProfile> diff --git a/network/wlan/ihvsample/ihvonexext.cpp b/network/wlan/ihvsample/ihvonexext.cpp new file mode 100644 index 00000000..8e80ab8a --- /dev/null +++ b/network/wlan/ihvsample/ihvonexext.cpp @@ -0,0 +1,1113 @@ + +/*++ + +Copyright (c) 2005 Microsoft Corporation + +Abstract: + + Sample IHV Extensibility DLL to extend + 802.11 LWF driver for third party protocols. + + +--*/ + +#include "precomp.h" + + + + + +#define MAX_BACKLOG 32 +#define MAX_EXEMPTIONS 1 +#define MAX_REGISTRATIONS 2 +#define ETHTYPE_EAPOL 0x888e +#define EapolTypeEapolKey 0x03 + + +DWORD +PlumbWEPKey +( + HANDLE hDot11SvcHandle, + ULONG uKeyIndex, + DOT11_DIRECTION direction, + LPBYTE pbKey, + ULONG uKeyLen +); + + +DWORD +ProcessRC4Key +( + HANDLE hIhvExtAdapter, + PDOT11_MSONEX_RESULT_PARAMS pOneXResultParams, + HANDLE hDot11SvcHandle, + HANDLE hSecuritySessionID, + ULONG uPktLen, + PBYTE pbEapolPkt +); + + + +// initialize onex data structure. +DWORD +GetNewOnexData +( + PONEX_DATA* ppOnexData +) +{ + DWORD dwResult = ERROR_SUCCESS; + PONEX_DATA pOnexData = NULL; + + ASSERT( ppOnexData ); + + if (*ppOnexData) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // allocate memory. + pOnexData = (PONEX_DATA) PrivateMemoryAlloc( sizeof( ONEX_DATA ) ); + if (!pOnexData) + { + dwResult = ERROR_OUTOFMEMORY; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // init fields here. + pOnexData->lpfnReceivePacket = Do1xReceivePacket; + pOnexData->lpfnIndicateResult = Do1xIndicateResult; + + // transfer data to caller. + (*ppOnexData) = pOnexData; + pOnexData = NULL; + +error: + if ( pOnexData ) + { + FreeOnexData( &pOnexData ); + } + return dwResult; +} + + + + +// free onex data structure. +VOID +FreeOnexData +( + PONEX_DATA* ppOnexData +) +{ + PONEX_DATA pOnexData = NULL; + + if ( ppOnexData && (*ppOnexData) ) + { + // Freeing caller's variable. + pOnexData = (*ppOnexData); + (*ppOnexData) = NULL; + + RC4UtilsFreeResultParams( &(pOnexData->pOnexResultParams) ); + ZeroMemory( pOnexData , sizeof( ONEX_DATA ) ); + PrivateMemoryFree( pOnexData ); + } +} + + +// verify if result params are available and valid. +BOOL +IsOneXResultParamsAvailable +( + PDOT11_MSONEX_RESULT_PARAMS pOneXResultParams +) +{ + BOOL bResult = FALSE; + + + bResult = + ( + pOneXResultParams && + pOneXResultParams->pbMPPERecvKey && + pOneXResultParams->dwMPPERecvKeyLen && + pOneXResultParams->pbMPPESendKey && + pOneXResultParams->dwMPPESendKeyLen + ); + + TRACE_MESSAGE_VAL( "Onex Result Params Available = ", bResult ); + + return bResult; +} + + +// free rc4 packet. +VOID +FreeRC4Pkt +( + PCACHED_PKT pPkt +) +{ + if ( pPkt ) + { + PrivateMemoryFree( pPkt->pbPkt ); + pPkt->pbPkt = NULL; + pPkt->uPktLen = 0; + } +} + +// flush rc4 packet cache. +VOID +FlushRC4PktCache +( + PONEX_DATA pOnexData +) +{ + ULONG i = 0; + + ASSERT( pOnexData ); + + for (i = 0; i< RC4_CACHE_SIZE; i++) + { + FreeRC4Pkt( &(pOnexData->RC4Cache[i]) ); + } +} + + +// cache rc4 packet +DWORD +CacheRC4Pkt +( + PONEX_DATA pOnexData, + ULONG uPktLen, + PBYTE pbEapolPkt +) +{ + DWORD dwResult = ERROR_SUCCESS; + PBYTE pbPktCopy = NULL; + + if ( !(pOnexData && uPktLen && pbEapolPkt) ) + { + dwResult = ERROR_INVALID_PARAMETER; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // copy the packet. + pbPktCopy = (PBYTE) PrivateMemoryAlloc(uPktLen); + if (!pbPktCopy) + { + dwResult = ERROR_OUTOFMEMORY; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + CopyMemory + ( + pbPktCopy, + pbEapolPkt, + uPktLen + ); + + // free packet destination. + FreeRC4Pkt( &(pOnexData->RC4Cache[pOnexData->uCacheFreeIdx]) ); + + // move packet copy to cache. + pOnexData->RC4Cache[ pOnexData->uCacheFreeIdx ].pbPkt = pbPktCopy; + pOnexData->RC4Cache[ pOnexData->uCacheFreeIdx ].uPktLen = uPktLen; + + + TRACE_MESSAGE_VAL( "RC4 Packet cached, Index = ", pOnexData->uCacheFreeIdx ); + + // increment index. + pOnexData->uCacheFreeIdx = (pOnexData->uCacheFreeIdx + 1 ) % RC4_CACHE_SIZE; + +error: + return dwResult; +} + +// process cached rc4 packets. +DWORD +ProcessCachedRC4Packets +( + PADAPTER_DETAILS pAdapterDetails +) +{ + DWORD dwResult = ERROR_SUCCESS; + ULONG ulIndex = 0; + ULONG uProcessIndex = 0; + PONEX_DATA pOnexData = NULL; + + ASSERT( pAdapterDetails ); + ASSERT( pAdapterDetails->pOnexData ); + + pOnexData = pAdapterDetails->pOnexData; + + // If no 1x result available, bail + if (!IsOneXResultParamsAvailable( pOnexData->pOnexResultParams )) + { + dwResult = ERROR_SUCCESS; + BAIL( ); + } + + TRACE_MESSAGE( "Processing cached RC4 packets." ); + + // We process last 2 received frames + + for ( ulIndex = 1; ulIndex <= RC4_CACHE_SIZE; ulIndex++ ) + { + uProcessIndex = ( pOnexData->uCacheFreeIdx - ulIndex) % RC4_CACHE_SIZE; + + if + ( + ( pOnexData->RC4Cache[uProcessIndex].pbPkt ) && + ( pOnexData->RC4Cache[uProcessIndex].uPktLen ) + ) + { + dwResult = + ProcessRC4Key + ( + (HANDLE) &(pAdapterDetails->Link), + pOnexData->pOnexResultParams, + pAdapterDetails->hDot11SvcHandle, + pOnexData->hSecuritySessionID, + pOnexData->RC4Cache[uProcessIndex].uPktLen, + pOnexData->RC4Cache[uProcessIndex].pbPkt + ); + BAIL_ON_WIN32_ERROR(dwResult); + + FreeRC4Pkt( &(pOnexData->RC4Cache[uProcessIndex]) ); + + } + } + +error: + return dwResult; +} + + + + + +// pre-associate function for onex profile. +DWORD +WINAPI +Do1xPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + ULONG uNumExemptions = 0; + ULONG uNumRegistrations = 0; + DOT11_PRIVACY_EXEMPTION PrivacyExemption[MAX_EXEMPTIONS] = {0}; + USHORT usRegistration[MAX_REGISTRATIONS] = {0}; + + ASSERT( pAdapterDetails ); + ASSERT( pdwReasonCode ); + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_INVALID_STATE; + + if ( nic_state_pre_assoc_started != pAdapterDetails->NicState ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_OUTOFMEMORY; + + dwResult = + GetNewOnexData + ( + &(pAdapterDetails->pOnexData) + ); + BAIL_ON_WIN32_ERROR(dwResult); + + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_HARDWARE_FAILURE; + + + TRACE_MESSAGE( "Setting Auth Algorithm." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetAuthAlgorithm) + ( + pAdapterDetails->hDot11SvcHandle, + DOT11_AUTH_ALGO_80211_OPEN + ); + BAIL_ON_WIN32_ERROR(dwResult); + + TRACE_MESSAGE( "Setting Unicast cipher algorithm." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetUnicastCipherAlgorithm) + ( + pAdapterDetails->hDot11SvcHandle, + DOT11_CIPHER_ALGO_WEP + ); + BAIL_ON_WIN32_ERROR(dwResult); + + TRACE_MESSAGE( "Setting Multicast cipher algorithm." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetMulticastCipherAlgorithm) + ( + pAdapterDetails->hDot11SvcHandle, + DOT11_CIPHER_ALGO_WEP + ); + BAIL_ON_WIN32_ERROR(dwResult); + + TRACE_MESSAGE( "Setting exclude unencrypted flag." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetExcludeUnencrypted) + ( + pAdapterDetails->hDot11SvcHandle, + TRUE + ); + BAIL_ON_WIN32_ERROR(dwResult); + + // set the exemption handler + + // In vanilla 1x, 802.1x packets are never encrypted + PrivacyExemption[uNumExemptions].usExemptionActionType = DOT11_EXEMPT_ALWAYS; + PrivacyExemption[uNumExemptions].usEtherType = htons(ETHTYPE_EAPOL); + PrivacyExemption[uNumExemptions].usExemptionPacketType = DOT11_EXEMPT_UNICAST; + uNumExemptions++; + ASSERT(uNumExemptions <= MAX_EXEMPTIONS); + + usRegistration[uNumRegistrations] = htons(ETHTYPE_EAPOL); + uNumRegistrations++; + ASSERT(uNumRegistrations <= MAX_REGISTRATIONS); + + TRACE_MESSAGE( "Setting ethertype handling." ); + dwResult = + g_pDot11ExtApi->Dot11ExtSetEtherTypeHandling + ( + pAdapterDetails->hDot11SvcHandle, + MAX_BACKLOG, + uNumExemptions, + PrivacyExemption, + uNumRegistrations, + usRegistration + ); + BAIL_ON_WIN32_ERROR(dwResult); + + + // Verified before, just after acquiring lock. + ASSERT( nic_state_pre_assoc_started == pAdapterDetails->NicState ); + + pAdapterDetails->NicState = nic_state_pre_assoc_ended; + + // Reason code is set to SUCCESS. + (*pdwReasonCode) = L2_REASON_CODE_SUCCESS; + + // populate post associate handler functions. + pAdapterDetails->pPerformPostAssociateCompletionRoutine = NULL; + pAdapterDetails->pPerformPostAssociateRoutine = Do1xPostAssociate; + pAdapterDetails->pStopPostAssociateRoutine = Do1xStopPostAssociate; + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + + + +// post-associate function for onex profile. +DWORD +WINAPI +Do1xPostAssociate +( + IN PADAPTER_DETAILS pAdapterDetails, + IN HANDLE hSecuritySessionID, + IN PDOT11_PORT_STATE pPortState, + IN ULONG uDot11AssocParamsBytes, + IN PDOT11_ASSOCIATION_COMPLETION_PARAMETERS pDot11AssocParams +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + + ASSERT( pAdapterDetails ); + + UNREFERENCED_PARAMETER( pPortState ); + UNREFERENCED_PARAMETER( uDot11AssocParamsBytes ); + UNREFERENCED_PARAMETER( pDot11AssocParams ); + + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // verify and change state. + if + ( + ( nic_state_post_assoc_started != pAdapterDetails->NicState && + nic_state_post_assoc_ended != pAdapterDetails->NicState + ) || + ( !(pAdapterDetails->pOnexData) ) + ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + pAdapterDetails->NicState = nic_state_onex_in_progress; + + // no need to free old id handle. + pAdapterDetails->pOnexData->hSecuritySessionID = hSecuritySessionID; + + TRACE_MESSAGE( "Starting OneX." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtStartOneX) + ( + pAdapterDetails->hDot11SvcHandle, + NULL // EAP attributes + ); + BAIL_ON_WIN32_ERROR( dwResult ); + pAdapterDetails->pOnexData->fMSOneXStarted = TRUE; + + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + + + + +// receive rc4 key. +DWORD +ReceiveRC4Key +( + PADAPTER_DETAILS pAdapterDetails, + ULONG uPktLen, + PEAPOL_PACKET pEapolPkt +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + + ASSERT( pAdapterDetails ); + ASSERT( uPktLen ); + ASSERT( pEapolPkt ); + + EnterCriticalSection(&g_csSynch); + bLocked = TRUE; + + ASSERT( pAdapterDetails->pOnexData ); + + TRACE_MESSAGE( "Received RC4 Key packet." ); + + if ( IsOneXResultParamsAvailable( pAdapterDetails->pOnexData->pOnexResultParams ) ) + { + // 1x params are available + dwResult = + ProcessRC4Key + ( + (HANDLE) &(pAdapterDetails->Link), + pAdapterDetails->pOnexData->pOnexResultParams, + pAdapterDetails->hDot11SvcHandle, + pAdapterDetails->pOnexData->hSecuritySessionID, + uPktLen, + (PBYTE)pEapolPkt + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + else + { + dwResult = + CacheRC4Pkt + ( + pAdapterDetails->pOnexData, + uPktLen, + (PBYTE) pEapolPkt + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + +error: + if (bLocked) + { + LeaveCriticalSection(&g_csSynch); + } + return dwResult; +} + + + + +// receive packet function for onex profile. +DWORD +WINAPI +Do1xReceivePacket +( + PADAPTER_DETAILS pAdapterDetails, + DWORD dwInBufferSize, + LPVOID pvInBuffer +) +{ + DWORD dwResult = ERROR_SUCCESS; + HANDLE hDot11SvcHandle = NULL; + BOOL bLocked = FALSE; + PDOT11_SECURITY_PACKET_HEADER pSecurityPkt = NULL; + PEAPOL_PACKET pEapolPkt = NULL; + DWORD uReqdPktLen = 0; + + ASSERT( pAdapterDetails ); + + // Must include at least one byte of data + uReqdPktLen = FIELD_OFFSET(DOT11_SECURITY_PACKET_HEADER, Data) + 1; + + if ( dwInBufferSize < uReqdPktLen ) + { + dwResult = ERROR_INVALID_PARAMETER; + BAIL_ON_WIN32_ERROR(dwResult); + } + + if ( !pvInBuffer ) + { + dwResult = ERROR_INVALID_PARAMETER; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + pSecurityPkt = (PDOT11_SECURITY_PACKET_HEADER) pvInBuffer; + pEapolPkt = (PEAPOL_PACKET) pSecurityPkt->Data; + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // validate state. + if + ( + (!(pAdapterDetails->pOnexData)) || + ( + ( nic_state_onex_in_progress != pAdapterDetails->NicState ) && + ( nic_state_post_assoc_ended != pAdapterDetails->NicState ) + ) + ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + hDot11SvcHandle = pAdapterDetails->hDot11SvcHandle; + + TRACE_MESSAGE( "Received security packet." ); + + // Ignoring version + if ( EapolTypeEapolKey == pEapolPkt->PacketType ) + { + dwResult = + ReceiveRC4Key + ( + pAdapterDetails, + dwInBufferSize - FIELD_OFFSET(DOT11_SECURITY_PACKET_HEADER, Data), + pEapolPkt + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + else + { + // leave lock before sending security packet to AC. + LeaveCriticalSection( &g_csSynch ); + bLocked = FALSE; + + dwResult = + (g_pDot11ExtApi->Dot11ExtProcessSecurityPacket) + ( + hDot11SvcHandle, + dwInBufferSize - FIELD_OFFSET(DOT11_SECURITY_PACKET_HEADER, Data), + pSecurityPkt->Data + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + +// parameters for calling AC with post assoc completion. +typedef +struct _POST_ASSOC_COMPL_DATA +{ + HANDLE hIhvExtAdapter; + HANDLE hDot11SvcHandle; + HANDLE hSecuritySessionID; + DOT11_MAC_ADDRESS PeerMacAddress; + DWORD dwSecurityReasonCode; + DWORD dwSecurityWin32Error; +} +POST_ASSOC_COMPL_DATA, *PPOST_ASSOC_COMPL_DATA; + + +// function to make the actual post assoc completion call. +// this function is started in a separate thread. +DWORD +WINAPI +PostAssocComplWorker +( + LPVOID pvCtxt +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + PPOST_ASSOC_COMPL_DATA pCtxt = (PPOST_ASSOC_COMPL_DATA) pvCtxt; + PADAPTER_DETAILS pAdapterDetails = NULL; + + ASSERT( pCtxt ); + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + dwResult = + ReferenceAdapterDetails + ( + pCtxt->hIhvExtAdapter, + &pAdapterDetails + ); + BAIL_ON_WIN32_ERROR( dwResult ); + ASSERT( pAdapterDetails ); + + if ( nic_state_onex_in_progress != pAdapterDetails->NicState && + nic_state_post_assoc_ended != pAdapterDetails->NicState ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + pAdapterDetails->NicState = nic_state_post_assoc_ended; + + LeaveCriticalSection( &g_csSynch ); + bLocked = FALSE; + + TRACE_MESSAGE_VAL( "Calling PostAssocCompletion, Status = ", pCtxt->dwSecurityWin32Error ); + + dwResult = + (g_pDot11ExtApi->Dot11ExtPostAssociateCompletion) + ( + pCtxt->hDot11SvcHandle, + pCtxt->hSecuritySessionID, + &(pCtxt->PeerMacAddress), + pCtxt->dwSecurityReasonCode, + pCtxt->dwSecurityWin32Error + ); + BAIL_ON_WIN32_ERROR( dwResult ); + +error: + if ( pAdapterDetails ) + { + DerefenceAdapterDetails( pCtxt->hIhvExtAdapter ); + } + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + PrivateMemoryFree( pvCtxt ); + return dwResult; +} + + +// starts a worker thread for the post association completion. +DWORD +Do1xPostAssocCompletion +( + HANDLE hIhvExtAdapter, + HANDLE hDot11SvcHandle, + HANDLE hSecuritySessionID, + PDOT11_MAC_ADDRESS pPeer, + DWORD dwSecurityReasonCode, + DWORD dwSecurityWin32Error +) +{ + DWORD dwResult = ERROR_SUCCESS; + PPOST_ASSOC_COMPL_DATA pCtxt = NULL; + + // allocate memory and copy parameters. + pCtxt = (PPOST_ASSOC_COMPL_DATA) PrivateMemoryAlloc(sizeof(POST_ASSOC_COMPL_DATA)); + if (!pCtxt) + { + dwResult = ERROR_OUTOFMEMORY; + BAIL_ON_WIN32_ERROR(dwResult); + } + + pCtxt->hIhvExtAdapter = hIhvExtAdapter; + pCtxt->hDot11SvcHandle = hDot11SvcHandle; + pCtxt->hSecuritySessionID = hSecuritySessionID; + + if (pPeer) + { + CopyMemory + ( + &(pCtxt->PeerMacAddress), + pPeer, + sizeof(DOT11_MAC_ADDRESS) + ); + } + + pCtxt->dwSecurityReasonCode = dwSecurityReasonCode; + pCtxt->dwSecurityWin32Error = dwSecurityWin32Error; + + // start the new thread. + dwResult = + StartNewProtectedThread + ( + hIhvExtAdapter, + PostAssocComplWorker, + pCtxt + ); + BAIL_ON_WIN32_ERROR(dwResult); + + pCtxt = NULL; + +error: + PrivateMemoryFree( pCtxt ); + return dwResult; +} + + +// indicate result function for onex profile. +DWORD +WINAPI +Do1xIndicateResult +( + PADAPTER_DETAILS pAdapterDetails, + DOT11_MSONEX_RESULT msOneXResult, + PDOT11_MSONEX_RESULT_PARAMS pDot11MsOneXResultParams +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + ASSERT( pAdapterDetails ); + ASSERT( pAdapterDetails->pOnexData ); + + // validate state. + if ( nic_state_onex_in_progress != pAdapterDetails->NicState && + nic_state_post_assoc_ended != pAdapterDetails->NicState + ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + if ( msOneXResult == DOT11_MSONEX_IN_PROGRESS ) + { + // free the onex params if they exist + RC4UtilsFreeResultParams( &( pAdapterDetails->pOnexData->pOnexResultParams) ); + FlushRC4PktCache( pAdapterDetails->pOnexData ); + TRACE_MESSAGE( "Received DOT11_MSONEX_IN_PROGRESS." ); + } + else if ( msOneXResult == DOT11_MSONEX_FAILURE ) + { + TRACE_MESSAGE( "Received DOT11_MSONEX_FAILURE." ); + + // If failure, indicate right away + dwResult = + Do1xPostAssocCompletion + ( + (HANDLE) &(pAdapterDetails->Link), + pAdapterDetails->hDot11SvcHandle, + pAdapterDetails->pOnexData->hSecuritySessionID, + NULL, + (pDot11MsOneXResultParams && + pDot11MsOneXResultParams->Dot11OneXReasonCode != ONEX_REASON_CODE_SUCCESS)? + pDot11MsOneXResultParams->Dot11OneXReasonCode: + L2_REASON_CODE_IHV_ONEX_FAILURE, + msOneXResult + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + else if ( msOneXResult == DOT11_MSONEX_SUCCESS ) + { + // success case. + TRACE_MESSAGE( "Received DOT11_MSONEX_SUCCESS." ); + + // free result params and get new result params. + RC4UtilsFreeResultParams( &(pAdapterDetails->pOnexData->pOnexResultParams) ); + + dwResult = + RC4UtilsDecryptResultParams + ( + pDot11MsOneXResultParams, + &(pAdapterDetails->pOnexData->pOnexResultParams) + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + + // Process cached RC4 packets if any + dwResult = + ProcessCachedRC4Packets + ( + pAdapterDetails + ); + BAIL_ON_WIN32_ERROR(dwResult); + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + +// stop-post-associate function for onex profile. +DWORD +WINAPI +Do1xStopPostAssociate +( + PADAPTER_DETAILS pAdapterDetails, + PDOT11_MAC_ADDRESS pPeer, + DOT11_ASSOC_STATUS dot11AssocStatus +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + + UNREFERENCED_PARAMETER( pPeer ); + UNREFERENCED_PARAMETER( dot11AssocStatus ); + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + TRACE_MESSAGE( "Performing StopPostAssociate." ); + + if + ( + ( nic_state_post_assoc_ended != pAdapterDetails->NicState ) && + ( nic_state_onex_in_progress != pAdapterDetails->NicState ) && + ( nic_state_post_assoc_started != pAdapterDetails->NicState ) + ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // Reset the port specific variables. + + if ( pAdapterDetails->pOnexData ) + { + if(pAdapterDetails->pOnexData->fMSOneXStarted) + { + // NOTE THAT THE OS WILL STOP THE AUTH EVEN IF THIS CALL IS NOT MADE. + // The sample should keep track of port downs and call start auth + // once a port up is received. + dwResult = + (g_pDot11ExtApi->Dot11ExtStopOneX) + ( + pAdapterDetails->hDot11SvcHandle + ); + if(dwResult != ERROR_SUCCESS) + { + // log error + dwResult = ERROR_SUCCESS; + } + else + { + pAdapterDetails->pOnexData->fMSOneXStarted = FALSE; + } + } + + // flush the rc4 packet cache. + FlushRC4PktCache( pAdapterDetails->pOnexData ); + + // free the result params. + RC4UtilsFreeResultParams( &(pAdapterDetails->pOnexData->pOnexResultParams) ); + } + + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + + + + + +DWORD +PlumbWEPKey +( + HANDLE hDot11SvcHandle, + ULONG uKeyIndex, + DOT11_DIRECTION direction, + LPBYTE pbKey, + ULONG uKeyLen +) +{ + DWORD dwResult = ERROR_SUCCESS; + PDOT11_CIPHER_DEFAULT_KEY_VALUE pDefaultKey = NULL; + ULONG uAllocLen = 0; + BOOL bLocked = FALSE; + + uAllocLen = FIELD_OFFSET(DOT11_CIPHER_DEFAULT_KEY_VALUE, ucKey) + uKeyLen; + + if (uAllocLen < uKeyLen) + { + dwResult = ERROR_ARITHMETIC_OVERFLOW; + BAIL_ON_WIN32_ERROR(dwResult); + } + + pDefaultKey = (PDOT11_CIPHER_DEFAULT_KEY_VALUE) PrivateMemoryAlloc(uAllocLen); + if (!pDefaultKey) + { + dwResult = ERROR_NOT_ENOUGH_MEMORY; + BAIL_ON_WIN32_ERROR(dwResult); + } + + pDefaultKey->AlgorithmId = DOT11_CIPHER_ALGO_WEP; + pDefaultKey->uKeyIndex = uKeyIndex; + pDefaultKey->bDelete = FALSE; + pDefaultKey->bStatic = FALSE; + pDefaultKey->usKeyLength = (USHORT) uKeyLen; + + ZeroMemory(&(pDefaultKey->MacAddr), sizeof(DOT11_MAC_ADDRESS)); + + CopyMemory + ( + pDefaultKey->ucKey, + pbKey, + uKeyLen + ); + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + TRACE_MESSAGE( "Setting default key." ); + TRACE_MESSAGE_VAL( " Key Index = ", uKeyIndex ); + TRACE_MESSAGE_VAL( " Key Length = ", uKeyLen ); + TRACE_MESSAGE_VAL( " Direction = ", direction ); + + dwResult = + (g_pDot11ExtApi->Dot11ExtSetDefaultKey) + ( + hDot11SvcHandle, + pDefaultKey, + direction + ); + BAIL_ON_WIN32_ERROR(dwResult); + + +error: + if (pDefaultKey) + { + SecureZeroMemory( pDefaultKey, uAllocLen ); + PrivateMemoryFree( pDefaultKey ); + } + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + +DWORD +ProcessRC4Key +( + HANDLE hIhvExtAdapter, + PDOT11_MSONEX_RESULT_PARAMS pOneXResultParams, + HANDLE hDot11SvcHandle, + HANDLE hSecuritySessionID, + ULONG uPktLen, + PBYTE pbEapolPkt +) +{ + DWORD dwResult = ERROR_SUCCESS; + PEAPOL_PACKET pEapolPkt = NULL; + DWORD dwKeyLen = 0; + DWORD dwKeyIndex = 0; + LPBYTE pbDecryptedKey = NULL; + BOOL bUCast = FALSE; + BOOL bLocked = FALSE; + + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + ASSERT( IsOneXResultParamsAvailable ( pOneXResultParams ) ); + + TRACE_MESSAGE( "Processing RC4 key." ); + + pEapolPkt = (PEAPOL_PACKET) pbEapolPkt; + + dwResult = + RC4UtilsParseKeyPacket + ( + pEapolPkt, + uPktLen, + pOneXResultParams, + &bUCast, + &pbDecryptedKey, + &dwKeyLen, + &dwKeyIndex + ); + BAIL_ON_WIN32_ERROR( dwResult ); + + dwResult = + PlumbWEPKey + ( + hDot11SvcHandle, + dwKeyIndex, + bUCast ? DOT11_DIR_BOTH : DOT11_DIR_INBOUND, + pbDecryptedKey, + dwKeyLen + ); + BAIL_ON_WIN32_ERROR(dwResult); + + if ( bUCast ) + { + TRACE_MESSAGE_VAL( "Setting default key ID, Key Index = ", dwKeyIndex ); + + dwResult = + (g_pDot11ExtApi->Dot11ExtSetDefaultKeyId) + ( + hDot11SvcHandle, + dwKeyIndex + ); + BAIL_ON_WIN32_ERROR(dwResult); + + dwResult = + Do1xPostAssocCompletion + ( + hIhvExtAdapter, + hDot11SvcHandle, + hSecuritySessionID, + NULL, + L2_REASON_CODE_SUCCESS, + ERROR_SUCCESS + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + +error: + RC4UtilsFreeKeyMaterial( pbDecryptedKey, dwKeyLen ); + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} diff --git a/network/wlan/ihvsample/ihvonexext.h b/network/wlan/ihvsample/ihvonexext.h new file mode 100644 index 00000000..574bbdfa --- /dev/null +++ b/network/wlan/ihvsample/ihvonexext.h @@ -0,0 +1,108 @@ + + + +// cache size. +#define RC4_CACHE_SIZE 2 + + +// cached packet. +typedef +struct _CACHED_PKT +{ + ULONG uPktLen; + PBYTE pbPkt; +} +CACHED_PKT, *PCACHED_PKT; + + +// connection specific data for onex profiles. +typedef +struct _ONEX_DATA +{ + HANDLE hSecuritySessionID; + BOOL fMSOneXStarted; + CACHED_PKT RC4Cache[RC4_CACHE_SIZE]; + ULONG uCacheFreeIdx; + PDOT11_MSONEX_RESULT_PARAMS pOnexResultParams; + IHV_RECEIVE_PACKET_HANDLER lpfnReceivePacket; + IHV_INDICATE_RESULT_HANDLER lpfnIndicateResult; +} +ONEX_DATA, *PONEX_DATA; + + +// initialize onex data structure. +DWORD +GetNewOnexData +( + PONEX_DATA* ppOnexData +); + +// free onex data structure. +VOID +FreeOnexData +( + PONEX_DATA* ppOnexData +); + + + + +// pre-associate function for onex profile. +DWORD +WINAPI +Do1xPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +); + + + +// post-associate function for onex profile. +DWORD +WINAPI +Do1xPostAssociate +( + IN PADAPTER_DETAILS pAdapterDetails, + IN HANDLE hSecuritySessionID, + IN PDOT11_PORT_STATE pPortState, + IN ULONG uDot11AssocParamsBytes, + IN PDOT11_ASSOCIATION_COMPLETION_PARAMETERS pDot11AssocParams +); + + +// stop-post-associate function for onex profile. +DWORD +WINAPI +Do1xStopPostAssociate +( + PADAPTER_DETAILS pAdapterDetails, + PDOT11_MAC_ADDRESS pPeer, + DOT11_ASSOC_STATUS dot11AssocStatus +); + + + +// receive packet function for onex profile. +DWORD +WINAPI +Do1xReceivePacket +( + PADAPTER_DETAILS pAdapterDetails, + DWORD dwInBufferSize, + LPVOID pvInBuffer +); + + + +// indicate result function for onex profile. +DWORD +WINAPI +Do1xIndicateResult +( + PADAPTER_DETAILS pAdapterDetails, + DOT11_MSONEX_RESULT msOneXResult, + PDOT11_MSONEX_RESULT_PARAMS pDot11MsOneXResultParams +); + + diff --git a/network/wlan/ihvsample/ihvplapmachineoruser.xml b/network/wlan/ihvsample/ihvplapmachineoruser.xml new file mode 100644 index 00000000..cd86060e --- /dev/null +++ b/network/wlan/ihvsample/ihvplapmachineoruser.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" ?> +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvplapmachineoruser</name> + <SSIDConfig> + <SSID> + <name>_1x_SSID_</name> + </SSID> + <nonBroadcast>false</nonBroadcast> + </SSIDConfig> + <connectionType>ESS</connectionType> + <connectionMode>auto</connectionMode> + <autoSwitch>false</autoSwitch> + <MSM> + <security> + <authEncryption> + <authentication>open</authentication> + <encryption>WEP</encryption> + <useOneX>true</useOneX> + </authEncryption> + <OneX xmlns="http://www.microsoft.com/networking/OneX/v1"> + <maxAuthFailures>3</maxAuthFailures> + <authMode>machineOrUser</authMode> + + <singleSignOn> + <type>preLogon</type> + <maxDelay>50</maxDelay> + </singleSignOn> + <EAPConfig> + <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> + <EapMethod> + <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type> + <VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId> + <VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType> + <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId> + </EapMethod> + <ConfigBlob></ConfigBlob> + </EapHostConfig> + </EAPConfig> + </OneX> + </security> + </MSM> + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVConnectivityParam1>0</IHVConnectivityParam1> + <IHVConnectivityParam2></IHVConnectivityParam2> + </IhvConnectivity> + </connectivity> + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVUsesFullSecurity>FALSE</IHVUsesFullSecurity> + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + <IHVEncryption>IHVCipher1</IHVEncryption> + <IHVSecurityParam1>0</IHVSecurityParam1> + <IHVSecurityParam2></IHVSecurityParam2> + </IhvSecurity> + </security> + <useMSOneX>true</useMSOneX> + </IHV> +</WLANProfile> diff --git a/network/wlan/ihvsample/ihvplapuser.xml b/network/wlan/ihvsample/ihvplapuser.xml new file mode 100644 index 00000000..37334800 --- /dev/null +++ b/network/wlan/ihvsample/ihvplapuser.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" ?> +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvplapuser</name> + <SSIDConfig> + <SSID> + <name>_1x_SSID_</name> + </SSID> + <nonBroadcast>false</nonBroadcast> + </SSIDConfig> + <connectionType>ESS</connectionType> + <connectionMode>auto</connectionMode> + <autoSwitch>false</autoSwitch> + <MSM> + <security> + <authEncryption> + <authentication>open</authentication> + <encryption>WEP</encryption> + <useOneX>true</useOneX> + </authEncryption> + <OneX xmlns="http://www.microsoft.com/networking/OneX/v1"> + <maxAuthFailures>3</maxAuthFailures> + <authMode>user</authMode> + + <singleSignOn> + <type>preLogon</type> + <maxDelay>50</maxDelay> + </singleSignOn> + <EAPConfig> + <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> + <EapMethod> + <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type> + <VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId> + <VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType> + <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId> + </EapMethod> + <ConfigBlob></ConfigBlob> + </EapHostConfig> + </EAPConfig> + </OneX> + </security> + </MSM> + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVConnectivityParam1>0</IHVConnectivityParam1> + <IHVConnectivityParam2></IHVConnectivityParam2> + </IhvConnectivity> + </connectivity> + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVUsesFullSecurity>FALSE</IHVUsesFullSecurity> + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + <IHVEncryption>IHVCipher1</IHVEncryption> + <IHVSecurityParam1>0</IHVSecurityParam1> + <IHVSecurityParam2></IHVSecurityParam2> + </IhvSecurity> + </security> + <useMSOneX>true</useMSOneX> + </IHV> +</WLANProfile> 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; +} + + diff --git a/network/wlan/ihvsample/ihvsample.def b/network/wlan/ihvsample/ihvsample.def new file mode 100644 index 00000000..dbbfe637 --- /dev/null +++ b/network/wlan/ihvsample/ihvsample.def @@ -0,0 +1,8 @@ +; Test Ihv Extensibility DLL + +LIBRARY IhvSample.dll + +EXPORTS + DllMain + Dot11ExtIhvGetVersionInfo + Dot11ExtIhvInitService diff --git a/network/wlan/ihvsample/ihvsample.h b/network/wlan/ihvsample/ihvsample.h new file mode 100644 index 00000000..0b0484bd --- /dev/null +++ b/network/wlan/ihvsample/ihvsample.h @@ -0,0 +1,261 @@ + + + + +// +// IHV can start defining reason codes in the IHV range. +// +enum +{ + L2_REASON_CODE_IHV_BAD_USER_KEY = L2_REASON_CODE_IHV_BASE, + L2_REASON_CODE_IHV_OUTOFMEMORY, + L2_REASON_CODE_IHV_BAD_PROFILE, + L2_REASON_CODE_IHV_HARDWARE_FAILURE, + L2_REASON_CODE_IHV_ONEX_FAILURE, + L2_REASON_CODE_IHV_INVALID_STATE +}; + + + + + + +//////////////////////////////////// +// IHV provided Handler functions // +//////////////////////////////////// + + + +VOID +WINAPI +IhvDeinitService +( + VOID +); + + + + +DWORD +WINAPI +IhvInitAdapter +( + IN PDOT11_ADAPTER pDot11Adapter, + IN HANDLE hDot11SvcHandle, + OUT PHANDLE phIhvExtAdapter +); + + + + +VOID +WINAPI +IhvDeinitAdapter +( + IN HANDLE hIhvExtAdapter +); + + + + +DWORD +WINAPI +IhvProcessSessionChange +( + IN ULONG uEventType, + IN PWTSSESSION_NOTIFICATION pSessionNotification +); + + + + +DWORD +WINAPI +IhvIsUIRequestPending +( + IN GUID guidUIRequest, + OUT PBOOL pbIsRequestPending +); + + + + +DWORD +WINAPI +IhvReceiveIndication +( + IN HANDLE hIhvExtAdapter, + IN DOT11EXT_IHV_INDICATION_TYPE indicationType, + IN ULONG uBufferLength, + IN LPVOID pvBuffer +); + + + + +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 +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 +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 +WINAPI +IhvPerformPostAssociate +( + IN HANDLE hIhvExtAdapter, + IN HANDLE hSecuritySessionID, + IN PDOT11_PORT_STATE pPortState, + IN ULONG uDot11AssocParamsBytes, + IN PDOT11_ASSOCIATION_COMPLETION_PARAMETERS pDot11AssocParams +); + + + + +DWORD +WINAPI +IhvAdapterReset +( + IN HANDLE hIhvExtAdapter +); + + + + +DWORD +WINAPI +IhvStopPostAssociate +( + IN HANDLE hIhvExtAdapter, + IN PDOT11_MAC_ADDRESS pPeer, + IN DOT11_ASSOC_STATUS dot11AssocStatus +); + + + + + +DWORD +WINAPI +IhvReceivePacket +( + IN HANDLE hIhvExtAdapter, + IN DWORD dwInBufferSize, + IN LPVOID pvInBuffer +); + + + + +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 +WINAPI +IhvProcessUIResponse +( + IN GUID guidUIRequest, + IN DWORD dwByteCount, + IN LPVOID pvResponseBuffer +); + + + + +DWORD +WINAPI +IhvSendPacketCompletion +( + IN HANDLE hSendCompletion +); + + + + +DWORD +WINAPI +IhvQueryUIRequest +( + IN HANDLE hIhvExtAdapter, + IN DOT11EXT_IHV_CONNECTION_PHASE connectionPhase, + OUT PDOT11EXT_IHV_UI_REQUEST* ppIhvUIRequest +); + + + + +DWORD +WINAPI +IhvOnexIndicateResult +( + IN HANDLE hIhvExtAdapter, + IN DOT11_MSONEX_RESULT msOneXResult, + IN PDOT11_MSONEX_RESULT_PARAMS pDot11MsOneXResultParams +); + + + + +DWORD +WINAPI +IhvControl +( + IN HANDLE hIhvExtAdapter, + IN DWORD dwInBufferSize, + IN PBYTE pInBuffer, + IN DWORD dwOutBufferSize, + OUT PBYTE pOutBuffer, + OUT PDWORD pdwBytesReturned +); diff --git a/network/wlan/ihvsample/ihvsample.vcxproj b/network/wlan/ihvsample/ihvsample.vcxproj new file mode 100644 index 00000000..8b0dde8a --- /dev/null +++ b/network/wlan/ihvsample/ihvsample.vcxproj @@ -0,0 +1,254 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C2DB15CB-342E-4E84-BFD0-5E839DE380DE}</ProjectGuid> + <RootNamespace>$(MSBuildProjectName)</RootNamespace> + <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration> + <Platform Condition="'$(Platform)' == ''">Win32</Platform> + <SampleGuid>{D58AEDC0-211B-4E2E-B92B-D297D272865F}</SampleGuid> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>False</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetVersion>Windows10</TargetVersion> + <UseDebugLibraries>True</UseDebugLibraries> + <DriverTargetPlatform>Desktop</DriverTargetPlatform> + <DriverType /> + <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <PropertyGroup> + <OutDir>$(IntDir)</OutDir> + </PropertyGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" /> + </ImportGroup> + <ItemGroup Label="WrappedTaskItems" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <TargetName>ihvsample</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <TargetName>ihvsample</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <TargetName>ihvsample</TargetName> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <TargetName>ihvsample</TargetName> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Link> + <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol> + <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ClCompile> + <Midl> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </Midl> + <ResourceCompile> + <PreprocessorDefinitions>%(PreprocessorDefinitions);RPC_NO_WINDOWS_H;UNICODE;_UNICODE;NO_STRICT;WIN32</PreprocessorDefinitions> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);kernel32.lib;ntdll.lib;advapi32.lib;rpcrt4.lib;uuid.lib;user32.lib;wmip.lib;ole32.lib;oleaut32.lib;ws2_32.lib;..\ihvfrm\$(DDKPlatform)\rc4utils.lib</AdditionalDependencies> + <ModuleDefinitionFile>ihvsample.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);kernel32.lib;ntdll.lib;advapi32.lib;rpcrt4.lib;uuid.lib;user32.lib;wmip.lib;ole32.lib;oleaut32.lib;ws2_32.lib;..\ihvfrm\$(DDKPlatform)\rc4utils.lib</AdditionalDependencies> + <ModuleDefinitionFile>ihvsample.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);kernel32.lib;ntdll.lib;advapi32.lib;rpcrt4.lib;uuid.lib;user32.lib;wmip.lib;ole32.lib;oleaut32.lib;ws2_32.lib;..\ihvfrm\$(DDKPlatform)\rc4utils.lib</AdditionalDependencies> + <ModuleDefinitionFile>ihvsample.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Link> + <AdditionalDependencies>%(AdditionalDependencies);kernel32.lib;ntdll.lib;advapi32.lib;rpcrt4.lib;uuid.lib;user32.lib;wmip.lib;ole32.lib;oleaut32.lib;ws2_32.lib;..\ihvfrm\$(DDKPlatform)\rc4utils.lib</AdditionalDependencies> + <ModuleDefinitionFile>ihvsample.def</ModuleDefinitionFile> + </Link> + <ResourceCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </ResourceCompile> + <ClCompile> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + <ExceptionHandling> + </ExceptionHandling> + </ClCompile> + <Midl> + <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(WDKContentRoot)\net\wlan\ihvfrm\test\rc4utils</AdditionalIncludeDirectories> + </Midl> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="adapters.cpp" /> + <ClCompile Include="ihvonexext.cpp" /> + <ClCompile Include="ihvsample.cpp" /> + <ClCompile Include="ihvwep.cpp" /> + <ClCompile Include="precompsrc.c"> + <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile> + <PreCompiledHeader>Create</PreCompiledHeader> + <PreCompiledHeaderOutputFile>$(IntDir)\precomp.h.pch</PreCompiledHeaderOutputFile> + </ClCompile> + <ClCompile Include="profile.cpp" /> + <ClCompile Include="utils.cpp" /> + </ItemGroup> + <ItemGroup> + <Inf Exclude="@(Inf)" Include="*.inf" /> + <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" /> + <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" /> + </ItemGroup> + <ItemGroup> + <None Exclude="@(None)" Include="*.txt;*.htm;*.html" /> + <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" /> + <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" /> + </ItemGroup> + <ItemGroup> + <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project>
\ No newline at end of file diff --git a/network/wlan/ihvsample/ihvsample.vcxproj.Filters b/network/wlan/ihvsample/ihvsample.vcxproj.Filters new file mode 100644 index 00000000..7a93e51c --- /dev/null +++ b/network/wlan/ihvsample/ihvsample.vcxproj.Filters @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions> + <UniqueIdentifier>{C3AD44B7-58F4-43D6-8928-4E57B6E0C023}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files"> + <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions> + <UniqueIdentifier>{76ABC86D-F7B4-4BB5-8600-84AEDE01171B}</UniqueIdentifier> + </Filter> + <Filter Include="Resource Files"> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions> + <UniqueIdentifier>{25477ACB-EF62-4C7A-9AAC-8DF8119A6070}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="adapters.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ihvonexext.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ihvsample.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="ihvwep.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="precompsrc.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="profile.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="utils.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <None Include="ihvsample.def"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/network/wlan/ihvsample/ihvtimelymachineoruser.xml b/network/wlan/ihvsample/ihvtimelymachineoruser.xml new file mode 100644 index 00000000..d115ee11 --- /dev/null +++ b/network/wlan/ihvsample/ihvtimelymachineoruser.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" ?> +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvtimelymachineoruser</name> + <SSIDConfig> + <SSID> + <name>_1x_SSID_</name> + </SSID> + <nonBroadcast>false</nonBroadcast> + </SSIDConfig> + <connectionType>ESS</connectionType> + <connectionMode>auto</connectionMode> + <autoSwitch>false</autoSwitch> + <MSM> + <security> + <authEncryption> + <authentication>open</authentication> + <encryption>WEP</encryption> + <useOneX>true</useOneX> + </authEncryption> + <OneX xmlns="http://www.microsoft.com/networking/OneX/v1"> + <maxAuthFailures>3</maxAuthFailures> + <authMode>machineOrUser</authMode> + + <singleSignOn> + <type>postLogon</type> + <maxDelay>50</maxDelay> + </singleSignOn> + <EAPConfig> + <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> + <EapMethod> + <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type> + <VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId> + <VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType> + <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId> + </EapMethod> + <ConfigBlob></ConfigBlob> + </EapHostConfig> + </EAPConfig> + </OneX> + </security> + </MSM> + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVConnectivityParam1>0</IHVConnectivityParam1> + <IHVConnectivityParam2></IHVConnectivityParam2> + </IhvConnectivity> + </connectivity> + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVUsesFullSecurity>FALSE</IHVUsesFullSecurity> + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + <IHVEncryption>IHVCipher1</IHVEncryption> + <IHVSecurityParam1>0</IHVSecurityParam1> + <IHVSecurityParam2></IHVSecurityParam2> + </IhvSecurity> + </security> + <useMSOneX>true</useMSOneX> + </IHV> +</WLANProfile> diff --git a/network/wlan/ihvsample/ihvtimelyuser.xml b/network/wlan/ihvsample/ihvtimelyuser.xml new file mode 100644 index 00000000..83af761f --- /dev/null +++ b/network/wlan/ihvsample/ihvtimelyuser.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" ?> +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvtimelyuser</name> + <SSIDConfig> + <SSID> + <name>_1x_SSID_</name> + </SSID> + <nonBroadcast>false</nonBroadcast> + </SSIDConfig> + <connectionType>ESS</connectionType> + <connectionMode>auto</connectionMode> + <autoSwitch>false</autoSwitch> + <MSM> + <security> + <authEncryption> + <authentication>open</authentication> + <encryption>WEP</encryption> + <useOneX>true</useOneX> + </authEncryption> + <OneX xmlns="http://www.microsoft.com/networking/OneX/v1"> + <maxAuthFailures>3</maxAuthFailures> + <authMode>user</authMode> + <singleSignOn> + <type>postLogon</type> + <maxDelay>50</maxDelay> + </singleSignOn> + <EAPConfig> + <EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"> + <EapMethod> + <Type xmlns="http://www.microsoft.com/provisioning/EapCommon">25</Type> + <VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId> + <VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType> + <AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</AuthorId> + </EapMethod> + <ConfigBlob></ConfigBlob> + </EapHostConfig> + </EAPConfig> + </OneX> + </security> + </MSM> + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVConnectivityParam1>0</IHVConnectivityParam1> + <IHVConnectivityParam2></IHVConnectivityParam2> + </IhvConnectivity> + </connectivity> + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + <IHVUsesFullSecurity>FALSE</IHVUsesFullSecurity> + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + <IHVEncryption>IHVCipher1</IHVEncryption> + <IHVSecurityParam1>0</IHVSecurityParam1> + <IHVSecurityParam2></IHVSecurityParam2> + </IhvSecurity> + </security> + <useMSOneX>true</useMSOneX> + </IHV> +</WLANProfile> diff --git a/network/wlan/ihvsample/ihvwep.cpp b/network/wlan/ihvsample/ihvwep.cpp new file mode 100644 index 00000000..3f4b1c6d --- /dev/null +++ b/network/wlan/ihvsample/ihvwep.cpp @@ -0,0 +1,837 @@ +/*++ + +Copyright (c) 2005 Microsoft Corporation + +Abstract: + + Sample IHV Extensibility DLL to extend + 802.11 LWF driver for third party protocols. + + +--*/ + +#include "precomp.h" + + + +// +// UI Request structure to +// be parsed by IHV UI DLL. +// +typedef struct _IHV_UI_REQUEST +{ + CHAR szTitle [80]; + CHAR szHelp [80]; +} +IHV_UI_REQUEST, *PIHV_UI_REQUEST; + + +DWORD +ConvertHexCharToNibble +( + CHAR chData, + BOOL bUpper, + PBYTE pbtData +) +{ + DWORD dwResult = ERROR_SUCCESS; + BYTE btNibble = 0xF0; + + ASSERT( pbtData ); + + if ( (chData >= '0') && (chData <= '9') ) + { + btNibble = (BYTE) (chData - '0'); + } + else if ( (chData >= 'a') && (chData <= 'f') ) + { + btNibble = (BYTE) (chData - 'a') + 0xA; + } + else if ( (chData >= 'A') && (chData <= 'F') ) + { + btNibble = (BYTE) (chData - 'A') + 0xA; + } + else + { + // Wrong type input + dwResult = ERROR_BAD_FORMAT; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + ASSERT( btNibble < 0xF0 ); + + if ( bUpper ) + { + (*pbtData) = (*pbtData) & 0x0F; + (*pbtData) = (*pbtData) | (btNibble << 4); + } + else + { + (*pbtData) = (*pbtData) & 0xF0; + (*pbtData) = (*pbtData) | btNibble; + } + +error: + return dwResult; +} + + +// For a 13 byte key, user can choose to input upto 26 hex digits + +#define MAX_KEY_STRING_LENGTH 26 + +#define MAX_RESPONSE_SIZE (( MAX_KEY_STRING_LENGTH + 1 ) * sizeof( WCHAR ) ) + +// +// The UI Response is a UNICODE string since +// the UI module has just passed a BSTR to this +// module. This UNICODE string needs to converted +// to a key. Any IHV specific algorithm can be +// used here. +// + +DWORD +ConvertStringToKey +( + BYTE* pbKeyData, + DWORD* pdwKeyLen +) +{ + DWORD dwResult = ERROR_SUCCESS; + HRESULT hr = S_OK; + CHAR szKey[ MAX_KEY_STRING_LENGTH + 2 ] = {0}; + DWORD dwKeyStringLen = 0; + DWORD dwIndex = 0; + + + if + ( + (!pbKeyData) || + (!pdwKeyLen) || + ( 0 == (*pdwKeyLen) ) || + ( (*pdwKeyLen) % sizeof( WCHAR ) ) + ) + { + dwResult = ERROR_INVALID_PARAMETER; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + dwKeyStringLen = (DWORD) wcslen( (LPWSTR) pbKeyData ); + if ( MAX_KEY_STRING_LENGTH < dwKeyStringLen ) + { + dwResult = ERROR_BAD_FORMAT; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // Converting the UNICODE string to + // ANSI string in scratch pad. + hr = + StringCchPrintfA + ( + szKey, + MAX_KEY_STRING_LENGTH + 1, + "%S", + (WCHAR*) pbKeyData + ); + BAIL_ON_FAILURE( hr ); + + ASSERT( dwKeyStringLen == (DWORD) strlen( szKey )); + + + if ( ( 5 == dwKeyStringLen ) || ( 13 == dwKeyStringLen ) ) + { + // Copying the ANSI string back to original buffer. + hr = + StringCchPrintfA + ( + (CHAR*) pbKeyData, + (*pdwKeyLen), + "%s", + szKey + ); + BAIL_ON_FAILURE( hr ); + + // The strings are direct representations + // of the Wep Key and can be directly returned. + (*pdwKeyLen) = dwKeyStringLen; + + TRACE_MESSAGE_VAL( "Received WEP key of length = ", (*pdwKeyLen) ); + + BAIL( ); + } + + if (( 10 != dwKeyStringLen ) && ( 26 != dwKeyStringLen )) + { + // Wrong length input + dwResult = ERROR_BAD_FORMAT; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + for( dwIndex = 0; dwIndex < (dwKeyStringLen / 2); dwIndex++ ) + { + dwResult = + ConvertHexCharToNibble + ( + szKey[ 2 * dwIndex ], + TRUE, + &(pbKeyData[ dwIndex ]) + ); + BAIL_ON_WIN32_ERROR( dwResult ); + + dwResult = + ConvertHexCharToNibble + ( + szKey[ 1 + (2 * dwIndex) ], + FALSE, + &(pbKeyData[ dwIndex ]) + ); + BAIL_ON_WIN32_ERROR( dwResult ); + + } + + (*pdwKeyLen) = dwKeyStringLen / 2; + + TRACE_MESSAGE_VAL( "Received WEP key of length = ", (*pdwKeyLen) ); + +error: + return WIN32_COMBINED_ERROR( dwResult, hr ); +} + + + + + +// +// Defining UI help strings. In a realistic +// implementation these values would be numbers +// to be interpreted the IHV UI DLL that could +// be converted to strings using resource files. +// +#define UI_TITLE_STRING "Title" +#define UI_HELP_STRING "Help" + + + + +// Send the UI request and wait for the UI response. +DWORD +SendUIRequestToReceiveKey +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwKeyLen, + BYTE** ppbKeyData +) +{ + DWORD dwResult = ERROR_SUCCESS; + DOT11EXT_IHV_UI_REQUEST uiRequest = {0}; + PIHV_UI_REQUEST pIHVRequest = NULL; + CHAR szTitle[] = UI_TITLE_STRING; + CHAR szHelp[] = UI_HELP_STRING; + BOOL bLocked = FALSE; + HANDLE hUIResponse = NULL; + + + + // CLSID of COM class that implements the UI page. In a real + // implementation this GUID could be dynamically obtained. + CLSID uiPageClsid = + { + /* 4A01F9F9-6012-4343-A8C4-10B5DF32672A */ + 0x4A01F9F9, + 0x6012, + 0x4343, + {0xA8, 0xC4, 0x10, 0xB5, 0xDF, 0x32, 0x67, 0x2A} + }; + + ASSERT( pAdapterDetails ); + + // prepare the IHV request. + uiRequest.dwByteCount = sizeof(IHV_UI_REQUEST); + uiRequest.pvUIRequest = (BYTE*) PrivateMemoryAlloc( sizeof(IHV_UI_REQUEST) ); + if ( !(uiRequest.pvUIRequest) ) + { + dwResult = ERROR_OUTOFMEMORY; + BAIL( ); + } + + pIHVRequest = (IHV_UI_REQUEST*)uiRequest.pvUIRequest; + + + memcpy( pIHVRequest->szTitle , szTitle , sizeof(szTitle) ); + memcpy( pIHVRequest->szHelp , szHelp , sizeof(szHelp) ); + + uiRequest.dwSessionId = WTSGetActiveConsoleSessionId( ); + uiRequest.UIPageClsid = uiPageClsid; + + // acquire the lock to register the request. + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // create new request guid. + dwResult = UuidCreate( &(uiRequest.guidUIRequest) ); + BAIL_ON_WIN32_ERROR(dwResult); + + // free the existing response. + PrivateMemoryFree( pAdapterDetails->pbResponse ); + pAdapterDetails->pbResponse = NULL; + + // register the guid. + pAdapterDetails->currentGuidUIRequest = uiRequest.guidUIRequest; + + // Initializing the event this thread + // would be waiting on later. + ResetEvent( pAdapterDetails->hUIResponse ); + + hUIResponse = pAdapterDetails->hUIResponse; + + // leave the lock since this thread needs + // to wait for the response. + LeaveCriticalSection( &g_csSynch ); + bLocked = FALSE; + + + // send the request. + dwResult = + (g_pDot11ExtApi->Dot11ExtSendUIRequest) + ( + pAdapterDetails->hDot11SvcHandle, + &uiRequest + ); + BAIL_ON_WIN32_ERROR(dwResult); + + TRACE_MESSAGE( "Sent UI request to receive key." ); + + // Waiting for UI response. + // This would be triggered + // off if no UI response + // is received. + dwResult = + WaitForSingleObject + ( + hUIResponse, + 1000 * 60 * 5 // 5 minutes + ); + + // acquire the lock - required for both success and failure. + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + ZeroMemory( &(pAdapterDetails->currentGuidUIRequest), sizeof( GUID ) ); + + if ( WAIT_OBJECT_0 == dwResult ) + { + dwResult = ERROR_SUCCESS; + } + BAIL_ON_WIN32_ERROR(dwResult); + + if ( NULL == pAdapterDetails->pbResponse ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR(dwResult); + } + + + // At this point in the code a response + // has been received, and the thread + // has not been aborted. + + (*ppbKeyData) = pAdapterDetails->pbResponse; + pAdapterDetails->pbResponse = NULL; + + (*pdwKeyLen) = pAdapterDetails->dwResponseLen; + + + // Convert the Unicode string to ASCII. + dwResult = + ConvertStringToKey + ( + *ppbKeyData, + pdwKeyLen + ); + BAIL_ON_WIN32_ERROR(dwResult); + + pAdapterDetails->bModifyCurrentProfile = TRUE; + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + PrivateMemoryFree( uiRequest.pvUIRequest ); + return dwResult; +} + + +// +// Key index limits. +// +#define MIN_KEY_INDEX 0 +#define MAX_KEY_INDEX 3 + + +// +// Perform Wep based pre-association once the key is known. +// +DWORD +WINAPI +DoWepPreAssociateCommon +( + PADAPTER_DETAILS pAdapterDetails, + DWORD dwKeyLen, + BYTE* pbKeyData, + DWORD* pdwReasonCode +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + LONG lIndex = 0; + PDOT11_CIPHER_DEFAULT_KEY_VALUE pKey = 0; + ULONG uLen = 0; + + ASSERT( pAdapterDetails ); + ASSERT( dwKeyLen ); + ASSERT( pbKeyData ); + ASSERT( pdwReasonCode ); + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_OUTOFMEMORY; + + uLen = FIELD_OFFSET(DOT11_CIPHER_DEFAULT_KEY_VALUE, ucKey) + dwKeyLen * sizeof(UCHAR); + pKey = (PDOT11_CIPHER_DEFAULT_KEY_VALUE) PrivateMemoryAlloc(uLen); + if (!pKey) + { + dwResult = ERROR_OUTOFMEMORY; + BAIL_ON_WIN32_ERROR(dwResult); + } + CopyMemory( &(pKey->ucKey), pbKeyData, dwKeyLen ); + + // Prepare the key. + pKey->AlgorithmId = DOT11_CIPHER_ALGO_WEP; + pKey->usKeyLength = (USHORT) dwKeyLen; + pKey->bStatic = TRUE; + pKey->Header.Type = NDIS_OBJECT_TYPE_DEFAULT; + pKey->Header.Revision = DOT11_CIPHER_DEFAULT_KEY_VALUE_REVISION_1; + pKey->Header.Size = sizeof(DOT11_CIPHER_DEFAULT_KEY_VALUE); + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_INVALID_STATE; + + if ( nic_state_pre_assoc_started != pAdapterDetails->NicState ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_HARDWARE_FAILURE; + + // plumb the settings and keys down. + + TRACE_MESSAGE( "Setting Auth Algorithm." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetAuthAlgorithm) + ( + pAdapterDetails->hDot11SvcHandle, + DOT11_AUTH_ALGO_80211_OPEN + ); + BAIL_ON_WIN32_ERROR(dwResult); + + TRACE_MESSAGE( "Setting Unicast cipher algorithm." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetUnicastCipherAlgorithm) + ( + pAdapterDetails->hDot11SvcHandle, + DOT11_CIPHER_ALGO_WEP + ); + BAIL_ON_WIN32_ERROR(dwResult); + + TRACE_MESSAGE( "Setting exclude unencrypted flag." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetExcludeUnencrypted) + ( + pAdapterDetails->hDot11SvcHandle, + TRUE + ); + BAIL_ON_WIN32_ERROR(dwResult); + + for ( lIndex = MAX_KEY_INDEX; lIndex >= MIN_KEY_INDEX; lIndex-- ) + { + pKey->uKeyIndex = lIndex; + + TRACE_MESSAGE( "Setting default key." ); + + dwResult = + (g_pDot11ExtApi->Dot11ExtSetDefaultKey) + ( + pAdapterDetails->hDot11SvcHandle, + pKey, + DOT11_DIR_BOTH + ); + BAIL_ON_WIN32_ERROR(dwResult); + } + + TRACE_MESSAGE( "Setting default key ID." ); + dwResult = + (g_pDot11ExtApi->Dot11ExtSetDefaultKeyId) + ( + pAdapterDetails->hDot11SvcHandle, + 0 + ); + BAIL_ON_WIN32_ERROR(dwResult); + + + // Verified before, just after acquiring lock. + ASSERT( nic_state_pre_assoc_started == pAdapterDetails->NicState ); + + pAdapterDetails->NicState = nic_state_pre_assoc_ended; + + // Reason code is set to SUCCESS. + (*pdwReasonCode) = L2_REASON_CODE_SUCCESS; + + // register the post-association handlers with the adapter. + + pAdapterDetails->pPerformPostAssociateCompletionRoutine = DoWepPostAssociate; + pAdapterDetails->pPerformPostAssociateRoutine = NULL; + pAdapterDetails->pStopPostAssociateRoutine = NULL; + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + PrivateMemoryFree( pKey ); + return dwResult; +} + + +// Pre-association when the profile does not have the key. +DWORD +WINAPI +DoMissingKeyWepPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +) +{ + DWORD dwResult = ERROR_SUCCESS; + DWORD dwKeyLen = ERROR_SUCCESS; + BYTE* pbKeyData = NULL; + + ASSERT( pAdapterDetails ); + ASSERT( pdwReasonCode ); + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_BAD_USER_KEY; + + // Possible enhancement - try to call Dot11ExtGetProfileCustomUserData + // function in IHV Framework to see if the key is + // available there. Else, send UI Request. + + + // try to obtain the key through an UI request. + dwResult = + SendUIRequestToReceiveKey + ( + pAdapterDetails, + &dwKeyLen, + &pbKeyData + ); + BAIL_ON_WIN32_ERROR(dwResult); + + ASSERT ( pbKeyData ); + ASSERT ( dwKeyLen ); + + // use the key for connection. + dwResult = + DoWepPreAssociateCommon + ( + pAdapterDetails, + dwKeyLen, + pbKeyData, + pdwReasonCode + ); + BAIL_ON_WIN32_ERROR(dwResult); + + + // Possible enhancement - try to call Dot11ExtSetProfileCustomUserData + // to store the key if the key was obtained by a UI request. + +error: + PrivateMemoryFree( pbKeyData ); + return dwResult; +} + + + + + + + +// Pre-association when the profile does have the key. +DWORD +WINAPI +DoWepPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +) +{ + DWORD dwResult = ERROR_SUCCESS; + BOOL bLocked = FALSE; + DWORD dwKeyLen = ERROR_SUCCESS; + CHAR szKey[MAX_RESPONSE_SIZE+1] = {0}; + + ASSERT( pAdapterDetails ); + ASSERT( pdwReasonCode ); + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_BAD_USER_KEY; + + if + ( + (!( pAdapterDetails->pConnectivityProfile )) || + (!( pAdapterDetails->pConnectivityProfile->pszParam2 )) || + ( 0 == pAdapterDetails->pConnectivityProfile->pszParam2[0] ) + ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR(dwResult); + } + + // Convert the profile string to a usable key. + dwKeyLen = (DWORD)wcslen( pAdapterDetails->pConnectivityProfile->pszParam2 ); + dwKeyLen = sizeof(WCHAR) * ( 1 + dwKeyLen ); + + if ( dwKeyLen > sizeof( szKey ) ) + { + dwResult = ERROR_BAD_PROFILE; + BAIL_ON_WIN32_ERROR(dwResult); + } + + + // Copy string. + CopyMemory + ( + (BYTE*) szKey, + pAdapterDetails->pConnectivityProfile->pszParam2, + dwKeyLen + ); + + // Convert UNICODE to ASCII. + dwResult = + ConvertStringToKey + ( + (BYTE*) szKey, + &dwKeyLen + ); + BAIL_ON_WIN32_ERROR(dwResult); + ASSERT ( dwKeyLen ); + + + // Do pre-association with the key in the profile. + dwResult = + DoWepPreAssociateCommon + ( + pAdapterDetails, + dwKeyLen, + (BYTE*) szKey, + pdwReasonCode + ); + BAIL_ON_WIN32_ERROR(dwResult); + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + + + +extern +DOT11EXT_IHV_DISCOVERY_PROFILE +g_IhvDiscoveryProfiles[]; + + +// +// This function is responsible for the post association +// operations and completing the post association call +// for WEP scenario. +// +DWORD +WINAPI +DoWepPostAssociate +( + LPVOID pvPostAssociate +) +{ + DWORD dwResult = ERROR_SUCCESS; + DWORD dwStatus = ERROR_SUCCESS; + DWORD dwReasonCode = L2_REASON_CODE_IHV_INVALID_STATE; + BOOL bLocked = FALSE; + PPOST_ASSOC_DATA ppostAssocData = (PPOST_ASSOC_DATA) pvPostAssociate; + PADAPTER_DETAILS pAdapterDetails = NULL; + + + ASSERT( ppostAssocData ); + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + dwResult = + ReferenceAdapterDetails + ( + ppostAssocData->hIhvExtAdapter, + &pAdapterDetails + ); + BAIL_ON_WIN32_ERROR( dwResult ); + ASSERT( pAdapterDetails ); + + + if ( nic_state_post_assoc_started != pAdapterDetails->NicState ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + // This could be an appropriate place to modify the current profile + + if ( pAdapterDetails->bModifyCurrentProfile ) + { + pAdapterDetails->bModifyCurrentProfile = FALSE; + + dwResult = + (g_pDot11ExtApi->Dot11ExtSetCurrentProfile) + ( + pAdapterDetails->hDot11SvcHandle, + pAdapterDetails->hConnectSession, + &(g_IhvDiscoveryProfiles[1].IhvConnectivityProfile), + &(g_IhvDiscoveryProfiles[1].IhvSecurityProfile) + ); + BAIL_ON_WIN32_ERROR( dwResult ); + } + + + // In wep connection case, function only changes the adapter state. + pAdapterDetails->NicState = nic_state_post_assoc_ended; + + + // Reason Code is set to success. + dwReasonCode = L2_REASON_CODE_SUCCESS; + +error: + if ( pAdapterDetails ) + { + DerefenceAdapterDetails( ppostAssocData->hIhvExtAdapter ); + } + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + + // call completion function. + dwStatus = + (g_pDot11ExtApi->Dot11ExtPostAssociateCompletion) + ( + ppostAssocData->hDot11SvcHandle, + ppostAssocData->hSecuritySessionId, + NULL, + dwReasonCode, + dwResult + ); + if ( ERROR_SUCCESS != dwStatus ) + { + // IHV specific logging can happen here. + } + PrivateMemoryFree( ppostAssocData ); + return dwResult; +} + + +// no op function for preassociation when +// ihv is used only for connectivity. in a +// realistic implementation there would probably +// be calls to Dot11ExtNicSpecificExtension +// in this function to prepare the driver for +// additional connectivity settings. +DWORD +WINAPI +DoIhvConnPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +) +{ + DWORD dwResult = ERROR_SUCCESS; + DWORD dwKeyLen = 0; + PBYTE pbKeyData = NULL; + BOOL bLocked = FALSE; + + ASSERT( pAdapterDetails ); + ASSERT( pdwReasonCode ); + + // try to send UI request to obtain some data that could be useful here. + // the sample does not really use the data. + dwResult = + SendUIRequestToReceiveKey + ( + pAdapterDetails, + &dwKeyLen, + &pbKeyData + ); + BAIL_ON_WIN32_ERROR(dwResult); + ASSERT ( pbKeyData ); + + PrivateMemoryFree( pbKeyData ); + pbKeyData = NULL; + + // try to send UI request to obtain some data that could be useful here. + // the sample does not really use the data. + dwResult = + SendUIRequestToReceiveKey + ( + pAdapterDetails, + &dwKeyLen, + &pbKeyData + ); + BAIL_ON_WIN32_ERROR(dwResult); + ASSERT ( pbKeyData ); + + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + // Reason code is set before making calls that could fail. + (*pdwReasonCode) = L2_REASON_CODE_IHV_INVALID_STATE; + + if ( nic_state_pre_assoc_started != pAdapterDetails->NicState ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + pAdapterDetails->NicState = nic_state_pre_assoc_ended; + + // Reason code is set to SUCCESS. + (*pdwReasonCode) = L2_REASON_CODE_SUCCESS; + + pAdapterDetails->pPerformPostAssociateCompletionRoutine = NULL; + pAdapterDetails->pPerformPostAssociateRoutine = NULL; + pAdapterDetails->pStopPostAssociateRoutine = NULL; + +error: + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + PrivateMemoryFree( pbKeyData ); + return dwResult; +} diff --git a/network/wlan/ihvsample/ihvwep.h b/network/wlan/ihvsample/ihvwep.h new file mode 100644 index 00000000..d8aabe71 --- /dev/null +++ b/network/wlan/ihvsample/ihvwep.h @@ -0,0 +1,62 @@ + +// +// Structure to marshal information for +// postassociation thread. +// +typedef +struct _POST_ASSOC_DATA +{ + HANDLE hIhvExtAdapter; + HANDLE hDot11SvcHandle; + HANDLE hSecuritySessionId; +} +POST_ASSOC_DATA, *PPOST_ASSOC_DATA; + + +// Pre-association when the profile does have the key. +DWORD +WINAPI +DoWepPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +); + + +// Pre-association when the profile does not have the key. +DWORD +WINAPI +DoMissingKeyWepPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +); + + +// no op function for preassociation when +// ihv is used only for connectivity. in a +// realistic implementation there would probably +// be calls to Dot11ExtNicSpecificExtension +// in this function to prepare the driver for +// additional connectivity settings. +DWORD +WINAPI +DoIhvConnPreAssociate +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +); + + +// This function is responsible for the post association +// operations and completing the post association call +// for WEP scenario. +DWORD +WINAPI +DoWepPostAssociate +( + LPVOID pvPostAssociate +); + + + diff --git a/network/wlan/ihvsample/ihvwep1.xml b/network/wlan/ihvsample/ihvwep1.xml new file mode 100644 index 00000000..2e4403f9 --- /dev/null +++ b/network/wlan/ihvsample/ihvwep1.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvwep1</name> + + <SSIDConfig> + <SSID> + <name>_SSID_</name> + </SSID> + </SSIDConfig> + + <connectionType>ESS</connectionType> + <connectionMode>manual</connectionMode> + + <MSM> + <connectivity> + </connectivity> + + </MSM> + + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + + <IHVConnectivityParam1>0</IHVConnectivityParam1> + + <IHVConnectivityParam2></IHVConnectivityParam2> + + </IhvConnectivity> + </connectivity> + + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + + <IHVUsesFullSecurity>TRUE</IHVUsesFullSecurity> + + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + + <IHVEncryption>IHVCipher1</IHVEncryption> + + <IHVSecurityParam1>0</IHVSecurityParam1> + + <IHVSecurityParam2></IHVSecurityParam2> + + </IhvSecurity> + </security> + </IHV> + +</WLANProfile> diff --git a/network/wlan/ihvsample/ihvwep2.xml b/network/wlan/ihvsample/ihvwep2.xml new file mode 100644 index 00000000..32b538ba --- /dev/null +++ b/network/wlan/ihvsample/ihvwep2.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> + <name>ihvwep2</name> + + <SSIDConfig> + <SSID> + <name>_SSID_</name> + </SSID> + </SSIDConfig> + + <connectionType>ESS</connectionType> + <connectionMode>manual</connectionMode> + + <MSM> + <connectivity> + </connectivity> + + </MSM> + + <IHV> + <OUIHeader> + <OUI>123456</OUI> + <type>01</type> + </OUIHeader> + + <connectivity> + <IhvConnectivity xmlns="http://www.someihv.com/nwifi/profile"> + + <IHVConnectivityParam1>0</IHVConnectivityParam1> + + <IHVConnectivityParam2>_KEY_</IHVConnectivityParam2> + + </IhvConnectivity> + </connectivity> + + <security> + <IhvSecurity xmlns="http://www.someihv.com/nwifi/profile"> + + <IHVUsesFullSecurity>TRUE</IHVUsesFullSecurity> + + <IHVAuthentication>IHVAuthV1</IHVAuthentication> + + <IHVEncryption>IHVCipher1</IHVEncryption> + + <IHVSecurityParam1>0</IHVSecurityParam1> + + <IHVSecurityParam2></IHVSecurityParam2> + + </IhvSecurity> + </security> + </IHV> + +</WLANProfile> diff --git a/network/wlan/ihvsample/precomp.h b/network/wlan/ihvsample/precomp.h new file mode 100644 index 00000000..244ad664 --- /dev/null +++ b/network/wlan/ihvsample/precomp.h @@ -0,0 +1,36 @@ + +#ifndef __WLAN_IHV_SAMPLE_PRECOMP_H__ +#define __WLAN_IHV_SAMPLE_PRECOMP_H__ + + +#pragma once + +#include <driverspecs.h> +_Analysis_mode_(_Analysis_code_type_user_code_) + + +#include <windows.h> +#include <stdlib.h> +#include <wchar.h> +#include <strsafe.h> +#include <rpc.h> +#include <Winsock2.h> +#include <wlanihv.h> +#include <objbase.h> + +#include "profile.h" +#include "utils.h" +#include "ihvwep.h" +#include "ihvonexext.h" +#include "adapters.h" +#include "rc4utils.h" +#include "ihvsample.h" + +#ifdef __cplusplus +#include <new> +#endif + + + +#endif // __WLAN_IHV_SAMPLE_PRECOMP_H__ + diff --git a/network/wlan/ihvsample/precompsrc.c b/network/wlan/ihvsample/precompsrc.c new file mode 100644 index 00000000..5944cf51 --- /dev/null +++ b/network/wlan/ihvsample/precompsrc.c @@ -0,0 +1 @@ +#include "precomp.h"
\ No newline at end of file diff --git a/network/wlan/ihvsample/profile.cpp b/network/wlan/ihvsample/profile.cpp new file mode 100644 index 00000000..c6988990 --- /dev/null +++ b/network/wlan/ihvsample/profile.cpp @@ -0,0 +1,1222 @@ +// +// Copyright (C) Microsoft Corporation 2005 +// IHV UI Extension sample +// + +#include "precomp.h" + + + + +// +// Free BSTR +// +#define SYS_FREE_STRING( _s ) \ + if ( _s ) \ + { \ + SysFreeString( _s ); \ + (_s) = NULL; \ + } \ + + +// +// Release interface. +// +#define RELEASE_INTERFACE( _p ) \ + if ( _p ) \ + { \ + (_p)->Release( ); \ + (_p) = NULL; \ + } \ + + +// XPath strings for parsing xml blobs, + +#define CON_PARAM1_XPATH L"/IhvConnectivity/IHVConnectivityParam1" +#define CON_PARAM2_XPATH L"/IhvConnectivity/IHVConnectivityParam2" + + +#define SEC_FSFLAG_XPATH L"/IhvSecurity/IHVUsesFullSecurity" +#define SEC_ATYPE_XPATH L"/IhvSecurity/IHVAuthentication" +#define SEC_ETYPE_XPATH L"/IhvSecurity/IHVEncryption" +#define SEC_PARAM1_XPATH L"/IhvSecurity/IHVSecurityParam1" +#define SEC_PARAM2_XPATH L"/IhvSecurity/IHVSecurityParam2" + + +// Strings to match the profile with internal data types. +LPCWSTR +gppszIhvAuthTypes[] = +{ + L"IHVAuthV1", + L"IHVAuthV2", + L"IHVAuthV3" +}; + + +LPCWSTR +gppszIhvCipherTypes[] = +{ + L"None", + L"IHVCipher1", + L"IHVCipher2", + L"IHVCipher3" +}; + + +// +// Base class for profile APIs. +// +class CIhvProfileBase +{ +public: + + // Constructor + CIhvProfileBase( ) + { + m_pRootNode = NULL; + } + + // Destructor + ~CIhvProfileBase( ) + { + RELEASE_INTERFACE( m_pRootNode ); + } + + HRESULT + LoadXml + ( + IN BSTR bstrIhvProfile + ); + + + // Caller needs to know what type to + // cast the pointer to depending upon + // the type of the derived class. + // Caller needs to free memory recursively + // by using the free( ) function. + virtual + HRESULT + GetNativeData + ( + LPVOID* ppvData + ) + = 0; + +protected: + + HRESULT + GetTextFromNode + ( + IN LPCWSTR pszQuery, + OUT BSTR* pbstrText + ); + + + IXMLDOMElement* m_pRootNode; + +}; + + + + + +// +// Derived class for connectivity profiles. +// +class CIhvConnectivityProfile : public CIhvProfileBase +{ + +public: + + // Constructor Destructor + CIhvConnectivityProfile( ) { } + ~CIhvConnectivityProfile( ) { } + + // Caller needs to know what type to + // cast the pointer to depending upon + // the type of the derived class. + // Caller needs to free memory recursively + // by using the PrivateMemoryFree( ) function. + HRESULT + GetNativeData + ( + LPVOID* ppvData + ); + + + // Accessor dwParam1 + HRESULT + GetParam1 + ( + DWORD* pdwParam1 + ); + + + // Accessor for pszParam2 + HRESULT + GetParam2 + ( + BSTR* pbstrValue + ); + + +}; + + + + + + +// +// Derived class for security profiles. +// + +class CIhvSecurityProfile + : public CIhvProfileBase +{ + +public: + + // Constructor Destructor + CIhvSecurityProfile( ) { } + ~CIhvSecurityProfile( ) { } + + // Caller needs to know what type to + // cast the pointer to depending upon + // the type of the derived class. + // Caller needs to free memory recursively + // by using the PrivateMemoryFree( ) function. + HRESULT + GetNativeData + ( + LPVOID* ppvData + ); + + + // Accessor and Modifier for bUseFullSecurity + HRESULT + GetFullSecurityFlag + ( + BOOL* pbUseFullSecurity + ); + + + // Accessor for AuthType + HRESULT + GetAuthType + ( + PIHV_AUTH_TYPE pAuthType + ); + + // Accessor for CipherType + HRESULT + GetCipherType + ( + PIHV_CIPHER_TYPE pCipherType + ); + + // Accessor for dwParam1 + HRESULT + GetParam1 + ( + DWORD* pdwParam1 + ); + + // Accessor for pszParam2 + HRESULT + GetParam2 + ( + BSTR* pbstrValue + ); + +}; + + +// Convert unicode string to BSTR. NULL safe. +HRESULT +Wstr2Bstr +( + _In_ LPCWSTR pszSrc, + _Outptr_ BSTR* pbstrDest +) +{ + HRESULT hr = S_OK; + + if ( !pbstrDest ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + (*pbstrDest) = NULL; + if ( !pszSrc ) + { + BAIL( ); + } + + (*pbstrDest) = SysAllocString( pszSrc ); + if ( !(*pbstrDest) ) + { + hr = E_OUTOFMEMORY; + BAIL_ON_FAILURE( hr ); + } + +error: + return hr; +} + + + + +// Convert unicode string to unicode string. NULL safe. +// string allocated by malloc and freed by free. +HRESULT +Wstr2Wstr +( + _In_ LPCWSTR pszSrc, + _Outptr_ LPWSTR* ppszDest +) +{ + HRESULT hr = S_OK; + size_t len = 0; + + if ( !ppszDest ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + (*ppszDest) = NULL; + if ( !pszSrc ) + { + BAIL( ); + } + + len = 1 + wcslen( pszSrc ); + len *= sizeof( WCHAR ); + + (*ppszDest) = (LPWSTR) PrivateMemoryAlloc( len ); + if ( !(*ppszDest) ) + { + hr = E_OUTOFMEMORY; + BAIL_ON_FAILURE( hr ); + } + + CopyMemory( (*ppszDest), pszSrc, len ); + +error: + return hr; +} + + + +// +// convert unicode string to DWORD +// +HRESULT +Wstr2Dword +( + _In_ LPCWSTR pszSrc, + _Out_ DWORD* pdwDest +) +{ + HRESULT hr = S_OK; + + if ( (!pdwDest) || (!pszSrc) ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + (*pdwDest) = (DWORD) _wtol( pszSrc ); + +error: + return hr; +} + + + + +// +// convert unicode string to BOOL +// +HRESULT +Wstr2Bool +( + _In_ LPCWSTR pszSrc, + _Out_ BOOL* pbDest +) +{ + HRESULT hr = S_OK; + + if ( (!pbDest) || (!pszSrc) ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + if ( 0 == wcscmp( L"TRUE", pszSrc ) ) + { + (*pbDest) = TRUE; + } + else if ( 0 == wcscmp( L"FALSE", pszSrc ) ) + { + (*pbDest) = FALSE; + } + else + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + +error: + return hr; +} + + + + + + + +// +// convert unicode string to auth type +// +HRESULT +Wstr2AuthType +( + _In_ LPCWSTR pszSrc, + _Out_ PIHV_AUTH_TYPE pAuthType +) +{ + HRESULT hr = S_OK; + DWORD dwIndex = 0; + + if ( (!pAuthType) || (!pszSrc) ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + for ( dwIndex = 0; dwIndex < MAX_AUTH_TYPES; dwIndex++ ) + { + if ( 0 == wcscmp( gppszIhvAuthTypes[dwIndex], pszSrc ) ) + { + (*pAuthType) = (IHV_AUTH_TYPE) dwIndex; + BAIL( ); + } + } + + // String not found. + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + + +error: + return hr; +} + + + + + + + +// +// convert unicode string to cipher type +// +HRESULT +Wstr2CipherType +( + _In_ LPCWSTR pszSrc, + _Out_ PIHV_CIPHER_TYPE pCipherType +) +{ + HRESULT hr = S_OK; + DWORD dwIndex = 0; + + if ( (!pCipherType) || (!pszSrc) ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + for ( dwIndex = 0; dwIndex < MAX_CIPHER_TYPES; dwIndex++ ) + { + if ( 0 == wcscmp( gppszIhvCipherTypes[dwIndex], pszSrc ) ) + { + (*pCipherType) = (IHV_CIPHER_TYPE) dwIndex; + BAIL( ); + } + } + + // String not found. + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + + +error: + return hr; +} + + + + +// base function to obtain text from +// node described by XPATH. +HRESULT +CIhvProfileBase::GetTextFromNode +( + IN LPCWSTR pszQuery, + OUT BSTR* pbstrText +) +{ + HRESULT hr = S_OK; + BSTR bstrQuery = NULL; + IXMLDOMNode* pQueryNode = NULL; + + ASSERT( pszQuery ); + ASSERT( pbstrText ); + + // if node is NULL, return empty string. + if ( !m_pRootNode ) + { + hr = + Wstr2Bstr + ( + L"", + pbstrText + ); + BAIL( ); + } + + hr = + Wstr2Bstr + ( + pszQuery, + &bstrQuery + ); + BAIL_ON_FAILURE( hr ); + + hr = m_pRootNode->selectSingleNode( bstrQuery, &pQueryNode ); + BAIL_ON_FAILURE( hr ); + + if (!pQueryNode) + { + hr = E_UNEXPECTED; + BAIL_ON_FAILURE( hr ); + } + + hr = pQueryNode->get_text( pbstrText ); + BAIL_ON_FAILURE( hr ); + + if ( !(*pbstrText) ) + { + hr = E_UNEXPECTED; + BAIL_ON_FAILURE( hr ); + } + +error: + RELEASE_INTERFACE( pQueryNode ); + SYS_FREE_STRING( bstrQuery ); + return hr; +} + + + +// Load node from xml string. If xml string is null this +// function is a NO_OP. +HRESULT +CIhvProfileBase::LoadXml +( + IN BSTR bstrIhvProfile +) +{ + HRESULT hr = S_OK; + IXMLDOMDocument* pDOMDoc = NULL; + IXMLDOMElement* pDocElem = NULL; + VARIANT_BOOL vfSuccess; + + if ( m_pRootNode ) + { + hr = E_UNEXPECTED; + BAIL_ON_FAILURE( hr ); + } + + if ( !bstrIhvProfile ) + { + BAIL( ); + } + + hr = + CoCreateInstance + ( + CLSID_DOMDocument, + NULL, + CLSCTX_ALL, + IID_IXMLDOMDocument, + (LPVOID *) &pDOMDoc + ); + BAIL_ON_FAILURE( hr ); + + hr = + pDOMDoc->loadXML + ( + bstrIhvProfile, + &vfSuccess + ); + BAIL_ON_FAILURE( hr ); + + if ( VARIANT_TRUE != vfSuccess ) + { + hr = E_UNEXPECTED; + BAIL_ON_FAILURE( hr ); + } + + hr = + pDOMDoc->get_documentElement + ( + &pDocElem + ); + BAIL_ON_FAILURE( hr ); + + // Caching the pointer to the document element + // in a member variable. + m_pRootNode = pDocElem; + pDocElem = NULL; + + +error: + RELEASE_INTERFACE( pDOMDoc ); + RELEASE_INTERFACE( pDocElem ); + return hr; +} + + + + + +// Accessor. +HRESULT +CIhvConnectivityProfile::GetParam1 +( + DWORD* pdwParam1 +) +{ + HRESULT hr = S_OK; + BSTR bstrData = NULL; + + hr = + GetTextFromNode + ( + CON_PARAM1_XPATH, + &bstrData + ); + BAIL_ON_FAILURE( hr ); + + if ( NULL == bstrData ) + { + hr = E_POINTER; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2Dword + ( + bstrData, + pdwParam1 + ); + BAIL_ON_FAILURE( hr ); + +error: + SYS_FREE_STRING( bstrData ); + return hr; +} + + + +// Accessor. +HRESULT +CIhvConnectivityProfile::GetParam2 +( + BSTR* pbstrValue +) +{ + HRESULT hr = S_OK; + + hr = + GetTextFromNode + ( + CON_PARAM2_XPATH, + pbstrValue + ); + BAIL_ON_FAILURE( hr ); + + +error: + return hr; +} + + + + +// +// Calls the accessors to build native data. +// +HRESULT +CIhvConnectivityProfile::GetNativeData +( + LPVOID* ppvData +) +{ + HRESULT hr = S_OK; + PIHV_CONNECTIVITY_PROFILE pIhvProfile = NULL; + BSTR bstrParam2 = NULL; + + if ( !ppvData ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + pIhvProfile = (PIHV_CONNECTIVITY_PROFILE) PrivateMemoryAlloc( sizeof( IHV_CONNECTIVITY_PROFILE ) ); + if ( !pIhvProfile ) + { + hr = E_OUTOFMEMORY; + BAIL_ON_FAILURE( hr ); + } + + // Ignoring errors since structure is already + // populated with defaults. + + hr = + GetParam2 + ( + &bstrParam2 + ); + BAIL_ON_FAILURE( hr ); + + if ( NULL == bstrParam2 ) + { + hr = E_POINTER; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2Wstr + ( + bstrParam2, + &(pIhvProfile->pszParam2) + ); + BAIL_ON_FAILURE( hr ); + + hr = + GetParam1 + ( + &(pIhvProfile->dwParam1) + ); + + // Consuming earlier failures. + hr = S_OK; + + // Transfering local cache to OUT parameter. + (*ppvData) = pIhvProfile; + pIhvProfile = NULL; + +error: + if ( pIhvProfile ) + { + PrivateMemoryFree( pIhvProfile->pszParam2 ); // NULL Safe. + PrivateMemoryFree( pIhvProfile ); + } + SYS_FREE_STRING( bstrParam2 ); + return hr; +} + + + + + +// Accessor. +HRESULT +CIhvSecurityProfile::GetFullSecurityFlag +( + BOOL* pbUseFullSecurity +) +{ + HRESULT hr = S_OK; + BSTR bstrData = NULL; + + hr = + GetTextFromNode + ( + SEC_FSFLAG_XPATH, + &bstrData + ); + BAIL_ON_FAILURE( hr ); + + if ( NULL == bstrData ) + { + hr = E_POINTER; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2Bool + ( + bstrData, + pbUseFullSecurity + ); + BAIL_ON_FAILURE( hr ); + +error: + SYS_FREE_STRING( bstrData ); + return hr; +} + + + + + +// Accessor. +HRESULT +CIhvSecurityProfile::GetAuthType +( + PIHV_AUTH_TYPE pAuthType +) +{ + HRESULT hr = S_OK; + BSTR bstrData = NULL; + + hr = + GetTextFromNode + ( + SEC_ATYPE_XPATH, + &bstrData + ); + BAIL_ON_FAILURE( hr ); + + if ( NULL == bstrData ) + { + hr = E_POINTER; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2AuthType + ( + bstrData, + pAuthType + ); + BAIL_ON_FAILURE( hr ); + +error: + SYS_FREE_STRING( bstrData ); + return hr; +} + + + + +// Accessor. +HRESULT +CIhvSecurityProfile::GetCipherType +( + PIHV_CIPHER_TYPE pCipherType +) +{ + HRESULT hr = S_OK; + BSTR bstrData = NULL; + + hr = + GetTextFromNode + ( + SEC_ETYPE_XPATH, + &bstrData + ); + BAIL_ON_FAILURE( hr ); + + if ( NULL == bstrData ) + { + hr = E_POINTER; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2CipherType + ( + bstrData, + pCipherType + ); + BAIL_ON_FAILURE( hr ); + +error: + SYS_FREE_STRING( bstrData ); + return hr; +} + + + + + +// Accessor. +HRESULT +CIhvSecurityProfile::GetParam1 +( + DWORD* pdwParam1 +) +{ + HRESULT hr = S_OK; + BSTR bstrData = NULL; + + hr = + GetTextFromNode + ( + SEC_PARAM1_XPATH, + &bstrData + ); + BAIL_ON_FAILURE( hr ); + + if ( NULL == bstrData ) + { + hr = E_POINTER; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2Dword + ( + bstrData, + pdwParam1 + ); + BAIL_ON_FAILURE( hr ); + +error: + SYS_FREE_STRING( bstrData ); + return hr; +} + + + + + + +// Accessor. +HRESULT +CIhvSecurityProfile::GetParam2 +( + BSTR* pbstrValue +) +{ + HRESULT hr = S_OK; + + hr = + GetTextFromNode + ( + SEC_PARAM2_XPATH, + pbstrValue + ); + BAIL_ON_FAILURE( hr ); + + +error: + return hr; +} + + +// +// Calls the accessors to build native data. +// +HRESULT +CIhvSecurityProfile::GetNativeData +( + LPVOID* ppvData +) +{ + HRESULT hr = S_OK; + PIHV_SECURITY_PROFILE pIhvProfile = NULL; + BSTR bstrParam2 = NULL; + + if ( !ppvData ) + { + hr = E_INVALIDARG; + BAIL_ON_FAILURE( hr ); + } + + pIhvProfile = (PIHV_SECURITY_PROFILE) PrivateMemoryAlloc( sizeof( IHV_SECURITY_PROFILE ) ); + if ( !pIhvProfile ) + { + hr = E_OUTOFMEMORY; + BAIL_ON_FAILURE( hr ); + } + + pIhvProfile->bUseIhvConnectivityOnly = ( m_pRootNode == NULL ); + + // Ignoring errors since structure is already + // populated with defaults. + hr = + GetFullSecurityFlag + ( + &(pIhvProfile->bUseFullSecurity) + ); + + hr = + GetAuthType + ( + &(pIhvProfile->AuthType) + ); + + hr = + GetCipherType + ( + &(pIhvProfile->CipherType) + ); + + hr = + GetParam1 + ( + &(pIhvProfile->dwParam1) + ); + + hr = + GetParam2 + ( + &bstrParam2 + ); + BAIL_ON_FAILURE( hr ); + + if ( NULL == bstrParam2 ) + { + hr = E_POINTER; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2Wstr + ( + bstrParam2, + &(pIhvProfile->pszParam2) + ); + + // Consuming earlier failures. + hr = S_OK; + + // Transfering local cache to OUT parameter. + (*ppvData) = pIhvProfile; + pIhvProfile = NULL; + +error: + if ( pIhvProfile ) + { + PrivateMemoryFree( pIhvProfile->pszParam2 ); // NULL Safe. + PrivateMemoryFree( pIhvProfile ); + } + SYS_FREE_STRING( bstrParam2 ); + return hr; +} + + +// Converts string to connectivity profile. +DWORD +GetIhvConnectivityProfile +( + PDOT11EXT_IHV_CONNECTIVITY_PROFILE pDot11ExtIhvConnProfile, + PIHV_CONNECTIVITY_PROFILE* ppConnectivityProfile +) +{ + HRESULT hr = S_OK; + BOOL bComInitialized = FALSE; + BSTR bstrIhvProfile = NULL; + PIHV_CONNECTIVITY_PROFILE pConnectivityProfile = NULL; + + CIhvConnectivityProfile* pIhvProfile = NULL; + + ASSERT( pDot11ExtIhvConnProfile ); + ASSERT( ppConnectivityProfile ); + + + // Data structure is multi-thread safe because + // it is both allocated and freed by current + // function. + hr = + CoInitializeEx + ( + NULL, + COINIT_MULTITHREADED + ); + BAIL_ON_FAILURE( hr ); + bComInitialized = TRUE; + + + pIhvProfile = new(std::nothrow) CIhvConnectivityProfile; + if (!pIhvProfile) + { + hr = E_OUTOFMEMORY; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2Bstr + ( + pDot11ExtIhvConnProfile->pszXmlFragmentIhvConnectivity, + &bstrIhvProfile + ); + BAIL_ON_FAILURE( hr ); + + hr = + pIhvProfile->LoadXml + ( + bstrIhvProfile + ); + BAIL_ON_FAILURE( hr ); + + hr = + pIhvProfile->GetNativeData + ( + (LPVOID*) &pConnectivityProfile + ); + BAIL_ON_FAILURE( hr ); + + + (*ppConnectivityProfile) = pConnectivityProfile; + pConnectivityProfile = NULL; + + +error: + SYS_FREE_STRING( bstrIhvProfile ); + + FreeIhvConnectivityProfile ( &pConnectivityProfile ); + + delete pIhvProfile; + + if ( bComInitialized ) + { + CoUninitialize( ); + } + return WIN32_FROM_HRESULT( hr ); +} + + + + +// free connectivity profile. + +VOID +FreeIhvConnectivityProfile +( + PIHV_CONNECTIVITY_PROFILE* ppConnectivityProfile +) +{ + if ( ppConnectivityProfile && (*ppConnectivityProfile) ) + { + PrivateMemoryFree( (*ppConnectivityProfile)->pszParam2 ); + PrivateMemoryFree( (*ppConnectivityProfile) ); + (*ppConnectivityProfile) = NULL; + } +} + + +// Converts string to security profile. +DWORD +GetIhvSecurityProfile +( + PDOT11EXT_IHV_SECURITY_PROFILE pDot11ExtIhvSecProfile, + PIHV_SECURITY_PROFILE* ppSecurityProfile +) +{ + HRESULT hr = S_OK; + BOOL bComInitialized = FALSE; + BSTR bstrIhvProfile = NULL; + PIHV_SECURITY_PROFILE pSecurityProfile = NULL; + + CIhvSecurityProfile* pIhvProfile = NULL; + + ASSERT( pDot11ExtIhvSecProfile ); + ASSERT( ppSecurityProfile ); + + + // Data structure is multi-thread safe because + // it is both allocated and freed by current + // function. + hr = + CoInitializeEx + ( + NULL, + COINIT_MULTITHREADED + ); + BAIL_ON_FAILURE( hr ); + bComInitialized = TRUE; + + + + pIhvProfile = new(std::nothrow) CIhvSecurityProfile; + if (!pIhvProfile) + { + hr = E_OUTOFMEMORY; + BAIL_ON_FAILURE( hr ); + } + + hr = + Wstr2Bstr + ( + pDot11ExtIhvSecProfile->pszXmlFragmentIhvSecurity, + &bstrIhvProfile + ); + BAIL_ON_FAILURE( hr ); + + hr = + pIhvProfile->LoadXml + ( + bstrIhvProfile + ); + BAIL_ON_FAILURE( hr ); + + hr = + pIhvProfile->GetNativeData + ( + (LPVOID*) &pSecurityProfile + ); + BAIL_ON_FAILURE( hr ); + + if ( pDot11ExtIhvSecProfile->bUseMSOnex && pSecurityProfile->bUseFullSecurity ) + { + hr = E_UNEXPECTED; + BAIL_ON_FAILURE( hr ); + } + + (*ppSecurityProfile) = pSecurityProfile; + pSecurityProfile = NULL; + + +error: + SYS_FREE_STRING( bstrIhvProfile ); + + FreeIhvSecurityProfile ( &pSecurityProfile ); + + delete pIhvProfile; + + if ( bComInitialized ) + { + CoUninitialize( ); + } + return WIN32_FROM_HRESULT( hr ); +} + + + + + +// free security profile. +VOID +FreeIhvSecurityProfile +( + PIHV_SECURITY_PROFILE* ppSecurityProfile +) +{ + if ( ppSecurityProfile && (*ppSecurityProfile) ) + { + PrivateMemoryFree( (*ppSecurityProfile)->pszParam2 ); + PrivateMemoryFree( (*ppSecurityProfile) ); + (*ppSecurityProfile) = NULL; + } +} diff --git a/network/wlan/ihvsample/profile.h b/network/wlan/ihvsample/profile.h new file mode 100644 index 00000000..cf676908 --- /dev/null +++ b/network/wlan/ihvsample/profile.h @@ -0,0 +1,108 @@ +// +// Copyright (C) Microsoft Corporation 2005 +// IHV UI Extension sample +// + +#pragma once + +#ifndef _IHVSAMPLEPROFILE_H +#define _IHVSAMPLEPROFILE_H + + + +#define MAX_AUTH_TYPES 3 + + +// IHV Auth types +typedef enum _IHV_AUTH_TYPE +{ + IHVAuthV1, + IHVAuthV2, + IHVAuthV3, + IHVAuthInvalid +} +IHV_AUTH_TYPE, *PIHV_AUTH_TYPE; + + +#define MAX_CIPHER_TYPES 4 + + +// IHV cipher types +typedef enum _IHV_CIPHER_TYPE +{ + None, + IHVCipher1, + IHVCipher2, + IHVCipher3, + IHVCipherInvalid +} +IHV_CIPHER_TYPE, *PIHV_CIPHER_TYPE; + + + + + +// Ihv connectivity profile data type. +typedef +struct _IHV_CONNECTIVITY_PROFILE +{ + DWORD dwParam1; + LPWSTR pszParam2; +} +IHV_CONNECTIVITY_PROFILE, *PIHV_CONNECTIVITY_PROFILE; + + + + + + +// Ihv security profile data type. +typedef struct _IHV_SECURITY_PROFILE +{ + BOOL bUseIhvConnectivityOnly; + BOOL bUseFullSecurity; + IHV_AUTH_TYPE AuthType; + IHV_CIPHER_TYPE CipherType; + DWORD dwParam1; + LPWSTR pszParam2; +} +IHV_SECURITY_PROFILE, *PIHV_SECURITY_PROFILE; + + + +// Converts string to connectivity profile. +DWORD +GetIhvConnectivityProfile +( + PDOT11EXT_IHV_CONNECTIVITY_PROFILE pDot11ExtIhvConnProfile, + PIHV_CONNECTIVITY_PROFILE* ppConnectivityProfile +); + + +// free connectivity profile. +VOID +FreeIhvConnectivityProfile +( + PIHV_CONNECTIVITY_PROFILE* ppConnectivityProfile +); + + +// Converts string to security profile. +DWORD +GetIhvSecurityProfile +( + PDOT11EXT_IHV_SECURITY_PROFILE pDot11ExtIhvSecProfile, + PIHV_SECURITY_PROFILE* ppSecurityProfile +); + + +// free security profile. +VOID +FreeIhvSecurityProfile +( + PIHV_SECURITY_PROFILE* ppSecurityProfile +); + + +#endif _IHVSAMPLEPROFILE_H + diff --git a/network/wlan/ihvsample/rc4utils.h b/network/wlan/ihvsample/rc4utils.h new file mode 100644 index 00000000..41ff9936 --- /dev/null +++ b/network/wlan/ihvsample/rc4utils.h @@ -0,0 +1,67 @@ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + + + +#include <packon.h> + +typedef struct EAPOL_PACKET +{ + BYTE ProtocolVersion; + BYTE PacketType; + BYTE PacketBodyLength[2]; + BYTE PacketBody[1]; +} EAPOL_PACKET, *UNALIGNED PEAPOL_PACKET; + +#include <packoff.h> + + +VOID +WINAPI +RC4UtilsFreeKeyMaterial +( + PBYTE pbDecryptedKey, + DWORD dwKeyLen +); + + +DWORD +WINAPI +RC4UtilsParseKeyPacket +( + PEAPOL_PACKET pEapolPkt, + ULONG uPktLen, + PDOT11_MSONEX_RESULT_PARAMS pOneXResultParams, + BOOL* pbUCast, + PBYTE* ppbDecryptedKey, + DWORD* pdwKeyLen, + DWORD* pdwKeyIndex +); + + + +DWORD +WINAPI +RC4UtilsDecryptResultParams +( + PDOT11_MSONEX_RESULT_PARAMS pResultParamsOrig, + PDOT11_MSONEX_RESULT_PARAMS* ppResultParamsCopy +); + + +VOID +WINAPI +RC4UtilsFreeResultParams +( + PDOT11_MSONEX_RESULT_PARAMS* ppResultParams +); + + +#ifdef __cplusplus +} +#endif + diff --git a/network/wlan/ihvsample/utils.cpp b/network/wlan/ihvsample/utils.cpp new file mode 100644 index 00000000..f7dae91e --- /dev/null +++ b/network/wlan/ihvsample/utils.cpp @@ -0,0 +1,662 @@ +/*++ + +Copyright (c) 2005 Microsoft Corporation + +Abstract: + + Sample IHV Extensibility DLL to extend + 802.11 LWF driver for third party protocols. + + +--*/ + +#include "precomp.h" + +// +// Service specific global Variables +// +PDOT11EXT_APIS g_pDot11ExtApi = NULL; + +CRITICAL_SECTION g_csSynch = {0}; +DWORD g_dwThreadCount = 0; +DWORD g_dwSessionID = 0; +BOOL g_bAllowInit = TRUE; + + + + +// +// Structure to store data +// required to start a new +// thread. The thread count +// needs to be protected. +// +typedef +struct _THREAD_PROTECTOR +{ + LPTHREAD_START_ROUTINE pStartRoutine; + LPVOID pvParams; + HANDLE hIhvExtAdapter; +} +THREAD_PROTECTOR, *PTHREAD_PROTECTOR; + + + +// +// Logical copy function macro. +// +#define COPY_FUNCTION( _p, _FuncName, _Preface ) \ + (_p)->Dot11ExtIhv##_FuncName = \ + _Preface##_FuncName; \ + + + +// +// Trace utility function +// +VOID +SampleTraceFn +( + LPCSTR pszFormat, + LPCSTR pszVal1, + DWORD dwVal1 +) +{ + CHAR szMsgString[ 512 ] = {0}; + HRESULT hr = S_OK; + + hr = + StringCchPrintfA + ( + szMsgString, + sizeof( szMsgString ) - 1, + pszFormat, + pszVal1, + dwVal1 + ); + + if ( S_OK == hr ) + { + OutputDebugStringA( szMsgString ); + } + else + { + OutputDebugStringA( "ERROR: Trace message generation failed.\n" ); + } + + return; +} + +// Private Memory alloc function +LPVOID +PrivateMemoryAlloc +( + size_t MemSize +) +{ + LPVOID pvBuffer = NULL; + + if (!MemSize) + { + BAIL( ); + } + + pvBuffer = malloc( MemSize ); + if ( pvBuffer ) + { + ZeroMemory( pvBuffer, MemSize ); + } + +error: + return pvBuffer; +} + +// Private Memory free function +VOID +PrivateMemoryFree +( + LPVOID pvBuffer +) +{ + if ( pvBuffer ) + { + free( pvBuffer ); + } +} + + + +// +// Initialize the handler functions +// +VOID +HandlerInit +( + OUT PDOT11EXT_IHV_HANDLERS pDot11IHVHandlers +) +{ + + COPY_FUNCTION( pDot11IHVHandlers, DeinitService , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, InitAdapter , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, DeinitAdapter , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, ProcessSessionChange , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, IsUIRequestPending , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, ReceiveIndication , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, PerformCapabilityMatch , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, ValidateProfile , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, PerformPreAssociate , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, PerformPostAssociate , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, AdapterReset , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, StopPostAssociate , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, ReceivePacket , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, CreateDiscoveryProfiles , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, ProcessUIResponse , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, SendPacketCompletion , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, QueryUIRequest , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, OnexIndicateResult , Ihv ); + COPY_FUNCTION( pDot11IHVHandlers, Control , Ihv ); + +} + +#define ASSERT_MSG_LEN 768 + +// +// Calling DebugBreak indirectly +// to facilitate frame stepping +// in a debugger. +// +VOID +AssertFunc +( + _In_ LPCSTR pszFile, + int nLine +) +{ + HRESULT hr = S_OK; + CHAR Message[ ASSERT_MSG_LEN ] = {0}; + + hr = + StringCchPrintfA + ( + Message, + ASSERT_MSG_LEN-1, + "\n\nAssertion failed in File %s, Line %d\n\n", + pszFile, + nLine + ); + if ( S_OK == hr ) + { + OutputDebugStringA( Message ); + } + else + { + OutputDebugStringA( "Assertion Failed\n" ); + } + + DebugBreak( ); +} + +// +// Initialize global synchronization structure. +// +DWORD +InitCritSect +( + CRITICAL_SECTION* pCritSect +) +{ + DWORD dwResult = ERROR_SUCCESS; + + __try + { + InitializeCriticalSection( pCritSect ); + } + __except (EXCEPTION_EXECUTE_HANDLER) + { + dwResult = GetExceptionCode( ); + BAIL_ON_WIN32_ERROR( dwResult ); + } + +error: + return dwResult; +} + + + + + +// +// Dll Main function. +// +BOOL +WINAPI +DllMain +( + IN HINSTANCE Dll, + IN DWORD Reason, + IN PVOID Reserved +) +{ + DWORD dwResult = ERROR_SUCCESS; + + UNREFERENCED_PARAMETER( Dll ); + UNREFERENCED_PARAMETER( Reserved ); + + switch (Reason) + { + case DLL_PROCESS_ATTACH: + + dwResult = InitCritSect( &g_csSynch ); + BAIL_ON_WIN32_ERROR( dwResult ); + + g_dwThreadCount = 0; + g_dwSessionID = 0; + g_bAllowInit = TRUE; + + break; + + case DLL_PROCESS_DETACH: + DeleteCriticalSection( &g_csSynch ); + break; + + default: + break; + } + +error: + return ( ERROR_SUCCESS == dwResult ); +} + + + + +// +// Disable starting new threads or adding new adapters.. +// +VOID +StartShutdown +( + VOID +) +{ + g_bAllowInit = FALSE; +} + + + +// +// Wait for spawned threadcount +// to come down to zero. +// +VOID +WaitOnZeroThreads +( + VOID +) +{ + BOOL bZeroThreads = FALSE; + + for ( ;; ) + { + EnterCriticalSection( &g_csSynch ); + bZeroThreads = ( 0 == g_dwThreadCount ); + LeaveCriticalSection( &g_csSynch ); + + if ( bZeroThreads ) + { + break; + } + + Sleep( 100 ); + } +} + + + + + + +// +// Function uses pThreadProtector structure +// to start a new thread. Decrements the +// global thread count after this thread has +// returned. +// +DWORD +WINAPI +ProtectedThreadEntry +( + LPVOID pvThreadProtector +) +{ + DWORD dwResult = ERROR_SUCCESS; + PTHREAD_PROTECTOR pThreadProtector = NULL; + LPTHREAD_START_ROUTINE pStartRoutine = NULL; + LPVOID pvParams = NULL; + HANDLE hIhvExtAdapter = NULL; + + pThreadProtector = (PTHREAD_PROTECTOR) pvThreadProtector; + ASSERT ( pThreadProtector ) + + pStartRoutine = pThreadProtector->pStartRoutine; + pvParams = pThreadProtector->pvParams; + hIhvExtAdapter = pThreadProtector->hIhvExtAdapter; + + PrivateMemoryFree( pThreadProtector ); + pThreadProtector = NULL; + + + if ( pStartRoutine ) + { + dwResult = pStartRoutine( pvParams ); + BAIL_ON_WIN32_ERROR( dwResult ); + } + +error: + EnterCriticalSection( &g_csSynch ); + + // decrement thread count. + g_dwThreadCount--; + + // decrement adapter reference. + DerefenceAdapterDetails( hIhvExtAdapter ); + + LeaveCriticalSection( &g_csSynch ); + + return dwResult; +} + + +// +// Start a new thread. +// +DWORD +StartNewProtectedThread +( + HANDLE hIhvExtAdapter, + LPTHREAD_START_ROUTINE pStartRoutine, + LPVOID pvParams +) +{ + DWORD dwResult = ERROR_SUCCESS; + HANDLE hThread = NULL; + PTHREAD_PROTECTOR pThreadProtector = NULL; + BOOL bLocked = FALSE; + PADAPTER_DETAILS pAdapterDetails = NULL; + BOOL bCloseHandle = FALSE; + BOOL bOk = TRUE; + + + EnterCriticalSection( &g_csSynch ); + bLocked = TRUE; + + if (( !g_bAllowInit ) || (g_dwThreadCount >= MAX_THREAD_COUNT) ) + { + dwResult = ERROR_INVALID_STATE; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + dwResult = + ReferenceAdapterDetails + ( + hIhvExtAdapter, + &pAdapterDetails + ); + BAIL_ON_WIN32_ERROR( dwResult ); + ASSERT( pAdapterDetails ); + + + // This memory is initialized, used and freed entirely by the Extensibility + // DLL. Hence this memory can be allocated and freed using any method. + pThreadProtector = (PTHREAD_PROTECTOR) PrivateMemoryAlloc( sizeof( THREAD_PROTECTOR ) ); + if ( !pThreadProtector ) + { + dwResult = ERROR_OUTOFMEMORY; + BAIL_ON_WIN32_ERROR( dwResult ); + } + + pThreadProtector->pStartRoutine = pStartRoutine; + pThreadProtector->pvParams = pvParams; + pThreadProtector->hIhvExtAdapter = hIhvExtAdapter; + + hThread = + CreateThread + ( + NULL, // security attributes + 0, // default stack size + ProtectedThreadEntry, // pointer to function to run + pThreadProtector, // parameter + 0, // run thread immediately + NULL // Thread ID receiver + ); + if ( !hThread ) + { + dwResult = GetLastError( ); + BAIL_ON_WIN32_ERROR( dwResult ); + } + bCloseHandle = TRUE; + + // Thread successfully started, memory + // would be freed by ProtectedThreadEntry + pThreadProtector = NULL; + + // Transfering dereference duty to ProtectedThreadEntry function. + pAdapterDetails = NULL; + + g_dwThreadCount++; + +error: + if ( bCloseHandle ) + { + bOk = CloseHandle( hThread ); + ASSERT( bOk ); + } + + PrivateMemoryFree( pThreadProtector ); + + if ( pAdapterDetails ) + { + DerefenceAdapterDetails( hIhvExtAdapter ); + } + + if ( bLocked ) + { + LeaveCriticalSection( &g_csSynch ); + } + return dwResult; +} + + +// +// Function to match beacon and profile. +// +BOOL +WINAPI +MatchBssDescription +( + PDOT11EXT_IHV_PROFILE_PARAMS pIhvProfileParams, + PIHV_CONNECTIVITY_PROFILE pConnectivityProfile, + PIHV_SECURITY_PROFILE pSecurityProfile, + PULDOT11_BSS_ENTRY pBssEntry +) +{ + UNREFERENCED_PARAMETER( pIhvProfileParams ); + UNREFERENCED_PARAMETER( pConnectivityProfile ); + UNREFERENCED_PARAMETER( pSecurityProfile ); + UNREFERENCED_PARAMETER( pBssEntry ); + + // Try to match the current profile with the beacon. + return TRUE; +} + + + +DWORD +CopyConnectivityProfile +( + IN PDOT11EXT_IHV_CONNECTIVITY_PROFILE pSrc, + OUT PDOT11EXT_IHV_CONNECTIVITY_PROFILE pDst +) +{ + DWORD dwResult = ERROR_SUCCESS; + DWORD dwLen = 0; + + ASSERT( pSrc ); + ASSERT( pDst ); + + ZeroMemory( pDst, sizeof( DOT11EXT_IHV_CONNECTIVITY_PROFILE ) ); + + if ( pSrc->pszXmlFragmentIhvConnectivity ) + { + dwLen = (DWORD) wcslen( pSrc->pszXmlFragmentIhvConnectivity ); + + dwResult = + (g_pDot11ExtApi->Dot11ExtAllocateBuffer) + ( + (dwLen+1) * sizeof( WCHAR ), + (LPVOID*) &(pDst->pszXmlFragmentIhvConnectivity) + ); + BAIL_ON_WIN32_ERROR( dwResult ); + ASSERT( pDst->pszXmlFragmentIhvConnectivity ); + + CopyMemory + ( + (LPVOID) pDst->pszXmlFragmentIhvConnectivity, + (LPVOID) pSrc->pszXmlFragmentIhvConnectivity, + (dwLen+1) * sizeof( WCHAR ) + ); + } + +error: + return dwResult; +} + + +VOID +FreeConnectivityProfile +( + IN PDOT11EXT_IHV_CONNECTIVITY_PROFILE pSrc +) +{ + if ( pSrc && pSrc->pszXmlFragmentIhvConnectivity ) + { + (g_pDot11ExtApi->Dot11ExtFreeBuffer)( (LPVOID) pSrc->pszXmlFragmentIhvConnectivity ); + pSrc->pszXmlFragmentIhvConnectivity = NULL; + } +} + + + +DWORD +CopySecurityProfile +( + IN PDOT11EXT_IHV_SECURITY_PROFILE pSrc, + OUT PDOT11EXT_IHV_SECURITY_PROFILE pDst +) +{ + DWORD dwResult = ERROR_SUCCESS; + DWORD dwLen = 0; + + ASSERT( pSrc ); + ASSERT( pDst ); + + ZeroMemory( pDst, sizeof( DOT11EXT_IHV_SECURITY_PROFILE ) ); + + pDst->bUseMSOnex = pSrc->bUseMSOnex; + + if ( pSrc->pszXmlFragmentIhvSecurity ) + { + dwLen = (DWORD) wcslen( pSrc->pszXmlFragmentIhvSecurity ); + + dwResult = + (g_pDot11ExtApi->Dot11ExtAllocateBuffer) + ( + (dwLen+1) * sizeof( WCHAR ), + (LPVOID*) &(pDst->pszXmlFragmentIhvSecurity) + ); + BAIL_ON_WIN32_ERROR( dwResult ); + ASSERT( pDst->pszXmlFragmentIhvSecurity ); + + CopyMemory + ( + (LPVOID) pDst->pszXmlFragmentIhvSecurity, + (LPVOID) pSrc->pszXmlFragmentIhvSecurity, + (dwLen+1) * sizeof( WCHAR ) + ); + } + + +error: + return dwResult; +} + + +VOID +FreeSecurityProfile +( + IN PDOT11EXT_IHV_SECURITY_PROFILE pSrc +) +{ + if ( pSrc && pSrc->pszXmlFragmentIhvSecurity ) + { + (g_pDot11ExtApi->Dot11ExtFreeBuffer)( (LPVOID) pSrc->pszXmlFragmentIhvSecurity ); + pSrc->pszXmlFragmentIhvSecurity = NULL; + } +} + + + + +DWORD +CopyDiscoveryProfile +( + IN PDOT11EXT_IHV_DISCOVERY_PROFILE pSrc, + OUT PDOT11EXT_IHV_DISCOVERY_PROFILE pDst +) +{ + DWORD dwResult = ERROR_SUCCESS; + + ASSERT( pSrc ); + ASSERT( pDst ); + + dwResult = + CopyConnectivityProfile + ( + &(pSrc->IhvConnectivityProfile), + &(pDst->IhvConnectivityProfile) + ); + BAIL_ON_WIN32_ERROR( dwResult ); + + + dwResult = + CopySecurityProfile + ( + &(pSrc->IhvSecurityProfile), + &(pDst->IhvSecurityProfile) + ); + BAIL_ON_WIN32_ERROR( dwResult ); + +error: + if ( ERROR_SUCCESS != dwResult ) + { + FreeDiscoveryProfile( pDst ); + } + return dwResult; +} + + +VOID +FreeDiscoveryProfile +( + IN PDOT11EXT_IHV_DISCOVERY_PROFILE pSrc +) +{ + if ( pSrc ) + { + FreeConnectivityProfile( &(pSrc->IhvConnectivityProfile) ); + FreeSecurityProfile( &(pSrc->IhvSecurityProfile) ); + } +} + + + diff --git a/network/wlan/ihvsample/utils.h b/network/wlan/ihvsample/utils.h new file mode 100644 index 00000000..d2d4a80c --- /dev/null +++ b/network/wlan/ihvsample/utils.h @@ -0,0 +1,318 @@ + + +////////////////// +// Macros // +////////////////// + + +// Trace Macros + + +VOID +SampleTraceFn +( + LPCSTR pszFormat, + LPCSTR pszVal1, + DWORD dwVal1 +); + +#define TRACE_MESSAGE( _x ) SampleTraceFn( "INFO: %s\n",_x, 0 ); +#define TRACE_MESSAGE_VAL( _x, _y ) SampleTraceFn( "INFO: %s %lu\n", _x, _y ); + + +// +// Error Handling +// +#define BAIL_ON_WIN32_ERROR( __x ) \ + if ( ERROR_SUCCESS != (__x) ) \ + { \ + goto error; \ + } \ + + +// +// COM failure +// +#define BAIL_ON_FAILURE( __hr ) \ + if ( FAILED( __hr ) ) \ + { \ + goto error; \ + } \ + +// +// combine win32 and com error codes. +// +#define WIN32_FROM_HRESULT(hr) \ + (SUCCEEDED(hr) ? ERROR_SUCCESS : \ + (HRESULT_FACILITY(hr) == FACILITY_WIN32 ? HRESULT_CODE(hr) : (hr))) + + +// Combined Error Macro +#define WIN32_COMBINED_ERROR( _dwError, _hr ) ( (_dwError)?(_dwError):WIN32_FROM_HRESULT((_hr))) + +// +// Unconditional bail +// +#define BAIL( ) goto error; + + +// +// Maximum number of new threads +// to spawn at any given time. +// +#define MAX_THREAD_COUNT 100 + + + +// +// Debug Macro. +// +#ifdef DBG +#define ASSERT(exp) \ + if (!(exp)) \ + { \ + AssertFunc( __FILE__, __LINE__ ); \ + } + +#define ASSERTFAILURE() \ + AssertFunc( __FILE__, __LINE__ ); +#else +#define ASSERT(exp) +#define ASSERTFAILURE() +#endif // DBG + + + +// Private Memory alloc function +LPVOID +PrivateMemoryAlloc +( + size_t MemSize +); + +// Private Memory free function +VOID +PrivateMemoryFree +( + LPVOID pvBuffer +); + + +// +// Array length. +// +#define ARRAY_LENGTH( _x ) (sizeof( (_x) ) / sizeof( (_x)[0] )) + +// +// Declarations for service specific global Variables +// +extern PDOT11EXT_APIS g_pDot11ExtApi; +extern CRITICAL_SECTION g_csSynch; +extern DWORD g_dwThreadCount; +extern DWORD g_dwSessionID; +extern BOOL g_bAllowInit; + + + + + + + + +// Pre-declaration for the ADAPTER_DETAILS structure. +typedef +struct _ADAPTER_DETAILS +ADAPTER_DETAILS, *PADAPTER_DETAILS; + + + + +// +// Handler type for pre-association. +// +typedef +DWORD +(WINAPI *PRE_ASSOCIATE_FUNCTION) +( + PADAPTER_DETAILS pAdapterDetails, + DWORD* pdwReasonCode +); + + +// +// Handler type for post-association. +// +typedef +DWORD +(WINAPI *POST_ASSOCIATE_FUNCTION) +( + PADAPTER_DETAILS pAdapterDetails, + HANDLE hSecuritySessionID, + PDOT11_PORT_STATE pPortState, + ULONG uDot11AssocParamsBytes, + PDOT11_ASSOCIATION_COMPLETION_PARAMETERS pDot11AssocParams +); + + + +// +// Handler type for stop-post-association. +// +typedef +DWORD +(WINAPI *STOP_POST_ASSOCIATE_FUNCTION) +( + PADAPTER_DETAILS pAdapterDetails, + PDOT11_MAC_ADDRESS pPeer, + DOT11_ASSOC_STATUS dot11AssocStatus +); + + + +// +// Handler type for receive packet. +// +typedef +DWORD +(WINAPI *IHV_RECEIVE_PACKET_HANDLER) +( + PADAPTER_DETAILS pAdapterDetails, + DWORD dwInBufferSize, + LPVOID pvInBuffer +); + + + +// +// Handler type for IHV result indication. +// +typedef +DWORD +(WINAPI *IHV_INDICATE_RESULT_HANDLER) +( + PADAPTER_DETAILS pAdapterDetails, + DOT11_MSONEX_RESULT msOneXResult, + PDOT11_MSONEX_RESULT_PARAMS pDot11MsOneXResultParams +); + + + +// Assert function in debug builds. +VOID +AssertFunc +( + _In_ LPCSTR pszFile, + int nLine +); + + +// +// Register intention to start shut down. +// +VOID +StartShutdown +( + VOID +); + + +// +// Wait for posted thread count to go down to zero. +// +VOID +WaitOnZeroThreads +( + VOID +); + + +// +// Populate IHV handler function pointers to IHV Framework. +// +VOID +HandlerInit +( + OUT PDOT11EXT_IHV_HANDLERS pDot11IHVHandlers +); + + +// +// Call createthread to start a new thread and ensure +// the adapter stays active till the thread finishes +// by putting a refcount increment/decrement around +// the lifetime of the thread. +// +DWORD +StartNewProtectedThread +( + HANDLE hIhvExtAdapter, + LPTHREAD_START_ROUTINE pStartRoutine, + LPVOID pvParams +); + + +// Typedef for unaligned BSS Entry to process beacons. +typedef UNALIGNED DOT11_BSS_ENTRY* PULDOT11_BSS_ENTRY; + +// +// Function to match beacon and profile. +// +BOOL +WINAPI +MatchBssDescription +( + PDOT11EXT_IHV_PROFILE_PARAMS pIhvProfileParams, + PIHV_CONNECTIVITY_PROFILE pConnectivityProfile, + PIHV_SECURITY_PROFILE pSecurityProfile, + PULDOT11_BSS_ENTRY pBssEntry +); + + +// +// Functions to copy and free discovery profiles. +// + +DWORD +CopyConnectivityProfile +( + IN PDOT11EXT_IHV_CONNECTIVITY_PROFILE pSrc, + OUT PDOT11EXT_IHV_CONNECTIVITY_PROFILE pDst +); + + +VOID +FreeConnectivityProfile +( + IN PDOT11EXT_IHV_CONNECTIVITY_PROFILE pSrc +); + + +DWORD +CopySecurityProfile +( + IN PDOT11EXT_IHV_SECURITY_PROFILE pSrc, + OUT PDOT11EXT_IHV_SECURITY_PROFILE pDst +); + +VOID +FreeSecurityProfile +( + IN PDOT11EXT_IHV_SECURITY_PROFILE pSrc +); + + + +VOID +FreeDiscoveryProfile +( + IN PDOT11EXT_IHV_DISCOVERY_PROFILE pSrc +); + + + +DWORD +CopyDiscoveryProfile +( + IN PDOT11EXT_IHV_DISCOVERY_PROFILE pSrc, + OUT PDOT11EXT_IHV_DISCOVERY_PROFILE pDst +); |
