📄 wifisetup.c
字号:
pwzcConfig1->dwCtlFlags |= WZCCTL_WEPK_PRESENT;
}
}
else if(pwzcConfig1->Privacy == Ndis802_11Encryption2Enabled || pwzcConfig1->Privacy == Ndis802_11Encryption3Enabled)
{
// TKIP key
// -key 12345678 [8-char]
// -key HelloWorld [10-char]
// -key abcdefghij1234567890abcdefghij1234567890abcdefghij1234567890abc [63-char]
// -key auto [key comes from successful EAP]
if(!_wcsicmp(szEncryptionKey, L"auto"))
*pfNeed8021X = TRUE;
else
{
pwzcConfig1->KeyLength = wcslen(szEncryptionKey);
if((pwzcConfig1->KeyLength<8) || (pwzcConfig1->KeyLength>63))
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: InterpretEncryptionKeyValue: WPA-PSK/TKIP key should be 8-63 char long string\n")));
return;
}
// WPA/TKIP pre-shared key takes 256 bit key.
// Everything else is incorrect format.
// Translates a user password (8 to 63 ascii chars) into a 256 bit network key.
// We do this for WPA-PSK and WPA-None.
memset(szEncryptionKeyValue8, 0, sizeof(szEncryptionKeyValue8));
WideCharToMultiByte(CP_ACP,
0,
szEncryptionKey,
pwzcConfig1->KeyLength+1,
szEncryptionKeyValue8,
pwzcConfig1->KeyLength+1,
NULL,
NULL);
WZCPassword2Key(pwzcConfig1, szEncryptionKeyValue8);
EncryptWepKMaterial(pwzcConfig1);
pwzcConfig1->dwCtlFlags |= WZCCTL_WEPK_XFORMAT
| WZCCTL_WEPK_PRESENT
| WZCCTL_ONEX_ENABLED;
}
pwzcConfig1->EapolParams.dwEapFlags = EAPOL_ENABLED;
pwzcConfig1->EapolParams.dwEapType = DEFAULT_EAP_TYPE;
pwzcConfig1->EapolParams.bEnable8021x = TRUE;
pwzcConfig1->WPAMCastCipher = Ndis802_11Encryption2Enabled;
}
}
// adding to the [Preferred Networks]
// [Preferred Networks] is a list of SSIDs in preference order.
// WZC continuously scans available SSIDs and attempt to connect to the most preferable SSID.
void AddToPreferredNetworkList(LPTSTR pszWiFiCard,
PWZC_WLAN_CONFIG pwzcConfig,
LPTSTR pszSSID)
{
DWORD dwOutFlags = 0;
INTF_ENTRY_EX Intf;
DWORD dwStatus;
WZC_802_11_CONFIG_LIST *pConfigList;
WZC_802_11_CONFIG_LIST *pNewConfigList;
DWORD dwDataLen;
ULONG uiNumberOfItems;
UINT i;
memset(&Intf, 0x00, sizeof(INTF_ENTRY_EX));
Intf.wszGuid = pszWiFiCard;
dwStatus = WZCQueryInterfaceEx(
NULL,
INTF_ALL,
&Intf,
&dwOutFlags);
if(dwStatus)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: AddToPreferredNetworkList: WZCQueryInterfaceEx() error dwStatus=0x%0X, dwOutFlags=0x%0X\r\n"), dwStatus, dwOutFlags));
WZCDeleteIntfObjEx(&Intf);
return;
}
pConfigList = (PWZC_802_11_CONFIG_LIST)Intf.rdStSSIDList.pData;
if(!pConfigList) // empty [Preferred Networks] list case
{
dwDataLen = sizeof(WZC_802_11_CONFIG_LIST);
pNewConfigList = (WZC_802_11_CONFIG_LIST *)LocalAlloc(LPTR, dwDataLen);
pNewConfigList->NumberOfItems = 1;
pNewConfigList->Index = 0;
memcpy(pNewConfigList->Config, pwzcConfig, sizeof(WZC_WLAN_CONFIG));
Intf.rdStSSIDList.pData = (BYTE*)pNewConfigList;
Intf.rdStSSIDList.dwDataLen = dwDataLen;
}
else
{
uiNumberOfItems = pConfigList->NumberOfItems;
for(i=0; i<uiNumberOfItems; i++)
{
if(memcmp(&(pwzcConfig->Ssid), &pConfigList->Config[i].Ssid, sizeof(NDIS_802_11_SSID)) == 0)
{
DEBUGMSG(ZONE_VERBOSE, (TEXT("Ethman: AddToPreferredNetworkList: The SSID [%s] in registry is already in the [Preferred Networks] list.\r\n"), pszSSID));
WZCDeleteIntfObjEx(&Intf);
return;
}
}
DEBUGMSG(ZONE_VERBOSE, (TEXT("Ethman: AddToPreferredNetworkList: SSID List has [%d] entries.\r\n"), uiNumberOfItems));
DEBUGMSG(ZONE_VERBOSE, (TEXT("Ethman: AddToPreferredNetworkList: Adding %s to the top of [Preferred Networks]\r\n"), pszSSID)); // this will be the most preferable SSID
dwDataLen = sizeof(WZC_802_11_CONFIG_LIST) + (uiNumberOfItems+1)*sizeof(WZC_WLAN_CONFIG);
pNewConfigList = (WZC_802_11_CONFIG_LIST *)LocalAlloc(LPTR, dwDataLen);
pNewConfigList->NumberOfItems = uiNumberOfItems + 1;
pNewConfigList->Index = 0;
memcpy(pNewConfigList->Config, pwzcConfig, sizeof(WZC_WLAN_CONFIG));
if(pConfigList->NumberOfItems)
{
pNewConfigList->Index = pConfigList->Index;
memcpy(pNewConfigList->Config+1, pConfigList->Config, (uiNumberOfItems)*sizeof(WZC_WLAN_CONFIG));
LocalFree(pConfigList);
pConfigList = NULL;
}
Intf.rdStSSIDList.pData = (BYTE*)pNewConfigList;
Intf.rdStSSIDList.dwDataLen = dwDataLen;
}
dwStatus = WZCSetInterfaceEx(NULL, INTF_PREFLIST, &Intf, &dwOutFlags);
if(dwStatus)
DEBUGMSG(ZONE_VERBOSE, (TEXT("Ethman: AddToPreferredNetworkList: WZCSetInterfaceEx() error dwStatus=0x%0X, dwOutFlags=0x%0X\r\n"), dwStatus, dwOutFlags));
WZCDeleteIntfObjEx(&Intf);
} // AddToPreferredNetworkList()
// configure WZC data as the registry setting
// sample:
// [HKEY_CURRENT_USER\Software\Microsoft\Plato\Ethman]
// "SSID" = "CE8021X",
// "authentication" = dword:0 ; open (Ndis802_11AuthModeOpen)
// "encryption" = dword:0 ; WEP (Ndis802_11WEPEnabled)
// "key" = "auto" ; key generated automatically by EAP
// "eap" = "tls" ; EAP type is TLS (certificate based authentication)
// "adhoc" = dword:0 ; CE8021X is an infrastructure network
DWORD ConfigureWLANFromRegistry(LPTSTR pszWifiCard)
{
HKEY hKey1 = NULL;
WZC_WLAN_CONFIG wzcConfig1;
BYTE ucbData[MAX_PATH];
DWORD *pdwData = (DWORD *)ucbData;
DWORD dwDataSize = sizeof(ucbData);
DWORD dwType;
LONG rc;
UINT i;
WCHAR *szSsidToConnect;
WCHAR *szEncryptionKey;
BOOL fNeed8021X = FALSE;
WCHAR *szEapType;
rc = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Microsoft\\Plato\\Ethman", 0, 0, &hKey1);
if (rc != ERROR_SUCCESS)
return rc;
memset(&wzcConfig1, 0, sizeof(wzcConfig1));
wzcConfig1.Length = sizeof(wzcConfig1);
wzcConfig1.dwCtlFlags = 0;
// SSID
if((ERROR_SUCCESS != RegQueryValueEx(hKey1, L"SSID", NULL, &dwType, ucbData, &dwDataSize)) ||
(dwType != REG_SZ) )
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: ConfigureWLANFromRegistry:: error no SSID is given. Check usage.\r\n")));
RegCloseKey(hKey1);
return rc;
}
szSsidToConnect = (WCHAR *)ucbData;
wzcConfig1.Ssid.SsidLength = wcslen(szSsidToConnect);
if(wzcConfig1.Ssid.SsidLength >= 32)
{
DEBUGMSG(ZONE_WARNING, (TEXT("Ethman: ConfigureWLANFromRegistry:: SSID is too long, truncating to max-32-chars\r\n")));
wzcConfig1.Ssid.SsidLength = 32;
}
for(i=0; i<wzcConfig1.Ssid.SsidLength; i++)
wzcConfig1.Ssid.Ssid[i] = (char)szSsidToConnect[i];
wzcConfig1.Ssid.Ssid[i] = 0;
// adhoc? or infrastructure net?
wzcConfig1.InfrastructureMode = Ndis802_11Infrastructure;
dwDataSize = sizeof(ucbData);
if((ERROR_SUCCESS == RegQueryValueEx(hKey1, L"adhoc", NULL, &dwType, ucbData, &dwDataSize)) &&
(dwType == REG_DWORD) &&
(*pdwData) )
{
wzcConfig1.InfrastructureMode = Ndis802_11IBSS;
}
// Authentication
wzcConfig1.AuthenticationMode = Ndis802_11AuthModeOpen;
dwDataSize = sizeof(ucbData);
if((ERROR_SUCCESS == RegQueryValueEx(hKey1, L"authentication", NULL, &dwType, ucbData, &dwDataSize)) &&
(dwType == REG_DWORD) )
{
wzcConfig1.AuthenticationMode = (NDIS_802_11_AUTHENTICATION_MODE)(*pdwData);
}
// Encryption
wzcConfig1.Privacy = Ndis802_11WEPDisabled;
dwDataSize = sizeof(ucbData);
if((ERROR_SUCCESS == RegQueryValueEx(hKey1, L"encryption", NULL, &dwType, ucbData, &dwDataSize)) &&
(dwType == REG_DWORD) )
{
wzcConfig1.Privacy = *pdwData;
}
// Key
szEncryptionKey = (WCHAR *)ucbData;
dwDataSize = sizeof(ucbData);
if((ERROR_SUCCESS == RegQueryValueEx(hKey1, L"key", NULL, &dwType, ucbData, &dwDataSize)) &&
(dwType == REG_SZ) )
{
InterpretEncryptionKeyValue(&wzcConfig1, szEncryptionKey, &fNeed8021X);
}
if(fNeed8021X)
{
szEapType = (WCHAR *)ucbData;
dwDataSize = sizeof(ucbData);
if((ERROR_SUCCESS == RegQueryValueEx(hKey1, L"eap", NULL, &dwType, ucbData, &dwDataSize)) &&
(dwType == REG_SZ) )
{
if(!_wcsicmp(szEapType, L"tls"))
wzcConfig1.EapolParams.dwEapType = EAP_TYPE_TLS;
else if(!_wcsicmp(szEapType, L"peap"))
wzcConfig1.EapolParams.dwEapType = EAP_TYPE_PEAP;
else
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: ConfigureWLANFromRegistry:: invalid eap type\r\n")));
return ERROR_INVALID_PARAMETER;
}
//
// Check if there are any User certificates in the Cert Store. This is required
// if the connection specified is a 802.1x connection. If there are no certificates
// in the user store, the connection attemption will fail without a useful error
// message and in order to prevent that, we detect the presence of certificates
// before the connection attempt and notify the user using a MessageBox if
// no certs are present.
//
if (!UserCertificatePresent())
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: ConfigureWLANFromRegistry:: no user certificate present\r\n")));
return ERROR_NOT_AUTHENTICATED;
}
wzcConfig1.EapolParams.dwEapFlags = EAPOL_ENABLED;
wzcConfig1.EapolParams.bEnable8021x = TRUE;
wzcConfig1.EapolParams.dwAuthDataLen = 0;
wzcConfig1.EapolParams.pbAuthData = 0;
}
else
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: ConfigureWLANFromRegistry:: need eap-type for this option\r\n")));
return ERROR_INVALID_PARAMETER;
}
}
RegCloseKey(hKey1);
AddToPreferredNetworkList(pszWifiCard, &wzcConfig1, szSsidToConnect);
return NO_ERROR;
}
DWORD WaitForIPNotification(LPTSTR pszDeviceName, BOOL *pfConnected, LPTSTR* ppszIPAddress, DWORD* pdwIpAddress)
{
HANDLE hEvent = NULL;
DWORD dwRetVal = NO_ERROR;
WORD wVersionRequested;
WSADATA wsadata;
int Status;
BOOL fConnected = FALSE;
SOCKET AddrChangeSock = INVALID_SOCKET;
WSAOVERLAPPED WSAOverlapped;
DEBUGMSG(ZONE_FUNCTION, (TEXT("Ethman::WaitForIPNotification: Starting...\r\n")));
wVersionRequested = MAKEWORD(2,2);
Status = WSAStartup (wVersionRequested, &wsadata);
if (Status != 0)
{
DEBUGMSG (ZONE_ERROR, (TEXT("Ethman: WSAStartup() call failed. Err:[0x%x]\r\n"), WSAGetLastError()));
goto exit;
}
AddrChangeSock = socket(AF_INET, SOCK_STREAM, 0);
if (AddrChangeSock == INVALID_SOCKET)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman:: Failed socket() call.\r\n")));
AddrChangeSock = INVALID_SOCKET;
WSACleanup();
goto exit;
}
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (hEvent == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman:: Failed CreateEvent() in StartAddressChangeNotification().\r\n")));
goto exit;
}
//
// Now request for the notification..
//
memset (&WSAOverlapped, 0x00, sizeof(WSAOVERLAPPED));
WSAOverlapped.hEvent = hEvent;
Status = WSAIoctl(
AddrChangeSock,
SIO_ADDRESS_LIST_CHANGE,
NULL,
0,
NULL,
0,
NULL,
&WSAOverlapped,
NULL);
if (Status != ERROR_SUCCESS && GetLastError() != ERROR_IO_PENDING)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman:: Failed WSAIoctl() for SIO_ADDRESS_LIST_CHANGE.\r\n")));
goto exit;
}
// We should update connection status once since IP could have already been bound
dwRetVal = CheckConnectionStatus(pszDeviceName, &fConnected, NULL, NULL);
if (NO_ERROR != dwRetVal)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman:: CheckConnectionStatus Failed. Err = %d.\r\n"), dwRetVal));
goto exit;
}
while(!fConnected)
{
// Wait for quit event or IP change
dwRetVal = WaitForSingleObject(hEvent, 60000);
//
// Immediately tells winsock to listen for the next one..
//
Status = WSAIoctl(
AddrChangeSock,
SIO_ADDRESS_LIST_CHANGE,
NULL,
0,
NULL,
0,
NULL,
&WSAOverlapped,
NULL);
if (Status != ERROR_SUCCESS && GetLastError() != ERROR_IO_PENDING)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman:: IPNotificationThread: Failed WSAIoctl() for SIO_ADDRESS_LIST_CHANGE.\r\n")));
goto exit;
}
if (dwRetVal == WAIT_TIMEOUT)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman: IPNotificationThread: Exiting IPNotificationThread due to timeout\r\n")));
break;
}
// Create a thread to update the connection status and get back to notify
// call immediately.
dwRetVal = CheckConnectionStatus(pszDeviceName, &fConnected, NULL, NULL);
if (NO_ERROR != dwRetVal)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman:: IPNotificationThread: CheckConnectionStatus Failed. Err = %d.\r\n"), dwRetVal));
goto exit;
}
}
dwRetVal = CheckConnectionStatus(pszDeviceName, &fConnected, ppszIPAddress, pdwIpAddress);
if (NO_ERROR != dwRetVal)
{
DEBUGMSG(ZONE_ERROR, (TEXT("Ethman:: IPNotificationThread: CheckConnectionStatus Failed. Err = %d.\r\n"), dwRetVal));
goto exit;
}
if (NULL != pfConnected)
{
*pfConnected = fConnected;
}
exit:
DEBUGMSG(ZONE_FUNCTION, (TEXT("Ethman: IPNotificationThread: Exiting IPNotificationThread\r\n")));
if (AddrChangeSock != INVALID_SOCKET)
{
closesocket(AddrChangeSock);
WSACleanup();
}
if (hEvent)
CloseHandle(hEvent);
return dwRetVal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -