.NET CF 2.0 has a built-in Registry namespace for dealing with the registry.
The CF applications that I write usually talk to a web service running under IIS on a server. If the application needs a file from the server, the web service returns it as a byte array. RAPI can be a royal pain, and I've managed to avoid it successfully so far.
After some more investigation I eventually gave up with the registry settings. It seems that the key to a successful connection is the Password value in HKCU\Comm\EAP\Config[SSID]. But because CryptProtectData uses an undocumented entropy value (for obvious security reasons) to encrypt the password, it seems impossible to recreate a valid entry in the registry programmatically.
I then went with the second best solution, catching the User Logon dialog after calling WZCSetInterface
and enter the required fields in there:
bool enteredPeapCred = false;
DateTime timePeapCredStarted = DateTime.Now.AddSeconds(10);
// wait for PEAP credentials window to appear (max. wait for 10 seconds)
while (!enteredPeapCred && timePeapCredStarted >= DateTime.Now)
{
IntPtr hwndLogon = Win32.FindWindow(null, "User Logon");
if (hwndLogon != IntPtr.Zero)
{
// move User Logon window offscreen to prevent screen flicker in app
Win32.MoveWindow(hwndLogon, -600, 0, 320, 480, true);
// "Network Log On" label
IntPtr hwndCtrl1 = Win32.GetWindow(hwndLogon, Win32.GW_CHILD);
// "Enter network info..." label
IntPtr hwndCtrl2 = Win32.GetWindow(hwndCtrl1, Win32.GW_HWNDNEXT);
// "User name:" label
IntPtr hwndCtrl3 = Win32.GetWindow(hwndCtrl2, Win32.GW_HWNDNEXT);
// username textbox
IntPtr hwndCtrl4 = Win32.GetWindow(hwndCtrl3, Win32.GW_HWNDNEXT);
// "Password:" label
IntPtr hwndCtrl5 = Win32.GetWindow(hwndCtrl4, Win32.GW_HWNDNEXT);
// password textbox
IntPtr hwndCtrl6 = Win32.GetWindow(hwndCtrl5, Win32.GW_HWNDNEXT);
// enter password into textbox
StringBuilder sbPassword = new StringBuilder();
sbPassword.Append(eapPassword);
Win32.SetWindowText(hwndCtrl6, sbPassword);
// "Domain:" label
IntPtr hwndCtrl7 = Win32.GetWindow(hwndCtrl6, Win32.GW_HWNDNEXT);
// domain textbox
IntPtr hwndCtrl8 = Win32.GetWindow(hwndCtrl7, Win32.GW_HWNDNEXT);
// "Save password" checkbox
IntPtr hwndCtrl9 = Win32.GetWindow(hwndCtrl8, Win32.GW_HWNDNEXT);
// send BST_CHECKED message to set checkbox
Win32.SendMessage(hwndCtrl9, Win32.BM_SETCHECK, Win32.BST_CHECKED, 0);
// send WM_COMMAND with left softkey to submit user dialog
IntPtr hwndMenu = Win32.SHFindMenuBar(hwndLogon);
Win32.SendMessage(hwndLogon, Win32.WM_COMMAND, 0x2F87, hwndMenu.ToInt32());
enteredPeapCred = true;
}
}
Note that I'm only setting the password field, because the username and domain fields are pre-populated with the information already stored in the registry (the Identity value mentioned in my original question).
This works well enough, as it creates the WLAN connection using the PEAP credentials. And by moving User Logon dialog offscreen as soon as it's found, this all happens invisibly to our application's user (our app runs in kiosk mode).
Best Answer
You can periodically check when those message boxes appear and close/destroy them using WM_CLOSE/DestroyWindow respectively.
Besides you can try SureLock Studio which handles these messages and many other situations to simulate kiosk mode.