Hi Moonliver
Hope I'm not too late. I had the same problem some month ago, and after some
week of lonely desperation I got the right suggestion. Unfortunately, I'm
working with eVC++ 4.0 (that is, in the unmanaged world), then I can only
provide a snippet of C++ code. This is a function to set the preferred
connection with WPA-PSK. It is not real working code (it has been extracted
from a very complex class), but at least it compiles. Hope you can map WZC
calls it into OpenNETCF environment. If so, take care of the call to
WZCPassword2Key, required to translate the ASCII passphrase into a valid
network key (this was the right suggestion).
Best regards.
Marco
#include <eapol.h>
#include <wzcsapi.h>
#define MAXNETKEYCHARS 27
#define MAXSSIDCHARS 33
BOOL SetPreferredConnection (// Your adapter (e.g. CISCO1)
LPCTSTR pszAdapter,
// Your SSID (network name)
LPCTSTR pszSSID,
// Your WPA passphrase
LPCTSTR pszNetKey)
{
BOOL fOk = FALSE;
// Get current settings for this adapter.
wchar_t wszAdapter[64];
ZeroMemory (wszAdapter, sizeof(wszAdapter));
#ifdef _UNICODE
wcsncpy (wszAdapter, pszAdapter, SIZEOF(wszAdapter)-1);
#else
if (! MultiByteToWideChar (CP_ACP, 0, pszAdapter, -1,
wszAdapter, SIZEOF(wszAdapter)-1))
return fOk;
#endif
INTF_ENTRY intfEntry;
intfEntry.wszGuid = wszAdapter;
DWORD dwOutFlags;
DWORD dwStatus =
WZCQueryInterface (NULL, INTF_ALL, &intfEntry, &dwOutFlags);
if (dwStatus != ERROR_SUCCESS) return fOk;
if (intfEntry.nAuthMode < 0) intfEntry.nAuthMode = 0;
if (intfEntry.nInfraMode < 0) intfEntry.nInfraMode = 0;
// Allocate a new configuration list with a single entry.
WZC_802_11_CONFIG_LIST configList;
ZeroMemory (&configList, sizeof(configList));
configList.NumberOfItems = 1;
configList.Index = 0;
PWZC_WLAN_CONFIG pConfig = configList.Config;
pConfig->Length = sizeof(WZC_WLAN_CONFIG);
// Setup SSID.
char szSSID[MAXSSIDCHARS+1];
ZeroMemory (szSSID, sizeof(szSSID));
#ifdef UNICODE
if (! WideCharToMultiByte (CP_ACP, 0, pszSSID, -1,
szSSID, MAXSSIDCHARS, NULL, NULL))
return fOk;
#else
strncpy (szSSID, pszSSID, MAXSSIDCHARS);
#endif
pConfig->Ssid.SsidLength = strlen (szSSID);
memcpy (pConfig->Ssid.Ssid, szSSID, strlen (szSSID));
// Setup authentication mode and encryption type.
pConfig->AuthenticationMode = Ndis802_11AuthModeWPAPSK;
pConfig->Privacy = Ndis802_11Encryption2Enabled;
pConfig->EapolParams.bEnable8021x = TRUE;
pConfig->EapolParams.dwEapFlags = DEFAULT_EAPOL_STATE;
pConfig->EapolParams.dwEapType = DEFAULT_EAP_TYPE;
// Setup infrastructure mode.
pConfig->InfrastructureMode = Ndis802_11Infrastructure;
// Setup network key.
size_t ccNetKey = _tcslen (pszNetKey);
if (ccNetKey > MAXNETKEYCHARS) return fOk;
char szNetKey[MAXNETKEYCHARS+1];
ZeroMemory (szNetKey, sizeof(szNetKey));
#ifdef UNICODE
if (! WideCharToMultiByte (CP_ACP, 0, pszNetKey, -1,
szNetKey, MAXNETKEYCHARS, NULL, NULL))
return fOk;
#else
strncpy (szNetKey, pszNetKey, MAXNETKEYCHARS);
#endif
// TKIP pre-shared keys take 256 bit key (everything else is incorrect
// formatting).
// User can only enter either 64 HEX entries, or 8 to 63 ASCII entries
// (always converted to HEX format).
if (ccNetKey >= 8 && ccNetKey <= 63) {
WZCPassword2Key (pConfig, szNetKey);
ccNetKey = WZCCTL_MAX_WEPK_MATERIAL;
} else if (ccNetKey != 64) {
return fOk;
}
pConfig->KeyLength = ccNetKey;
pConfig->dwCtlFlags |= (WZCCTL_WEPK_PRESENT | WZCCTL_WEPK_XFORMAT);
if (pConfig->EapolParams.bEnable8021x)
pConfig->dwCtlFlags |= WZCCTL_ONEX_ENABLED;
BYTE chFakeKeyMaterial[] =
{0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03,
0x01, 0x67, 0x66};
for (size_t ccIndex = 0; ccIndex < WZCCTL_MAX_WEPK_MATERIAL; ccIndex++) {
pConfig->KeyMaterial[ccIndex] ^=
chFakeKeyMaterial[(7*ccIndex)%13];
}
// Apply new settings.
// The preferred configuration list will contain only the new entry.
intfEntry.rdStSSIDList.dwDataLen = sizeof(WZC_802_11_CONFIG_LIST);
intfEntry.rdStSSIDList.pData = (LPBYTE) &configList;
dwStatus = WZCSetInterface (NULL, INTF_PREFLIST, &intfEntry, NULL);
if (dwStatus == ERROR_SUCCESS) fOk = TRUE;
return fOk;
}