Add new comment
Programmatically instantiate the password login dialog
In Windows CE there is built in functionality that allows a user to lock and login the system, just like you are used to on "big" desktop systems. To activate this functionality you simply set the system password in Windows CE through the control panel applet. You can also do this programmatically using the SetPassword() and SetPasswordStatus() API's.
When the password is set at boot the system will show the standard Windows CE login screen:

Recently I got a question whether it is possible to programmatically bring up the password dialog. After some analysis the answer was yes. I found out that the Power Manager instantiates the password dialog when the system returns from showing a screensaver. The password dialog is instantiated by calling ShowStartupWindow(). Here's the code used by the Power Manager (from "<WINCEROOT>\PUBLIC\COMMON\OAK\DRIVERS\PM"):
gpfnShowStartupWindow = (PFN_ShowStartupWindow) GetProcAddress(hmCoreDll, _T("ShowStartupWindow"));
The example below shows you how to use the exact same technique inside your applications to instantiate the password dialog:
// We need to declare these functions here because they are defined
// in pwinbase.h (contrary to what MSDN help for "SetPassword" tells
// us!) and pwinbase.h is not included as an SDK header file.
// Therefore to use these functions without needing access to all
// Platform Builder include files, we have to define them ourselves.
extern "C"
{
BOOL SetPassword (LPWSTR lpszOldpassword, LPWSTR lspzNewPassword);
BOOL SetPasswordStatus(DWORD dwStatus, LPWSTR lpszPassword);
}
// Forward declarations
bool InitPassword(LPWSTR pszOldPassword, LPWSTR pszNewPassword);
// Defines
#define PASSWORD_STATUS_ACTIVE 1
#define PASSWORD_STATUS_SCREENSAVERPROTECT 2
// Typedef'ed functions
typedef BOOL (WINAPI *PFN_ShowStartupWindow)(void);
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bRet = false;
HMODULE hCoreDll = NULL;
PFN_ShowStartupWindow pfnShowStartupWindow = NULL;
// Create and activate password
// (you can supply the current ("old") password on the command line)
LPWSTR pszOldPassword = (argc > 1) ? argv[1] : NULL;
if (InitPassword(pszOldPassword, L"password"))
{
hCoreDll = (HMODULE) LoadLibrary(L"coredll.dll");
if (hCoreDll)
{
pfnShowStartupWindow = (PFN_ShowStartupWindow)GetProcAddress(hCoreDll, L"ShowStartupWindow");
if (pfnShowStartupWindow)
bRet = pfnShowStartupWindow();
else
RETAILMSG(1, (L"Failed to get address of \"ShowStartupWindow\" in coredll.dll, error %d\r\n", GetLastError()));
FreeLibrary(hCoreDll);
}
else
RETAILMSG(1, (L"Failed to load coredll.dll, error %d\r\n", GetLastError()));
}
return (int)bRet;
}
bool InitPassword(LPWSTR pszOldPassword, LPWSTR pszNewPassword)
{
bool bRet = false;
// Please note that the password must be lower case when you set it!
// The password dialog box (code in startui.cpp) always converts the
// user entered password to lower case before the compare!
if (!SetPassword(pszOldPassword, pszNewPassword))
RETAILMSG(1, (L"Failed to set the password, error %d\r\n", GetLastError()));
//Set the password status
else if (!SetPasswordStatus(PASSWORD_STATUS_ACTIVE | PASSWORD_STATUS_SCREENSAVERPROTECT, pszNewPassword))
RETAILMSG(1, (L"Failed to set the password status, error %d\r\n", GetLastError()));
else
bRet = true;
return bRet;
}
Of course you can always create your own password dialog (because let's be honest; it's not the most beautiful dialog you've ever seen, right?!), but if you don't mind the ugly box the technique above just uses the existing functionality of CE and will save you a bit of time developing a password dialog yourself.
From the comments in the code above you can see I found a rather interesting little fact: Windows CE passwords are CASE INSENSITIVE! That's old-school, isn't it?!
The code that handles the GUI portion of the password handling code is in startui.cpp (here "<WINCEROOT>\PUBLIC\COMMON\OAK\DRIVERS\STARTUI"):
SendMessage(hwndPass, WM_GETTEXT, PASSWORD_LENGTH + 1, (LPARAM)szText);
_wcslwr(szText);
isAuthValid = (CheckPassword(szText) != FALSE);
The _wcslwr function converts the password string to lowercase before checking it, but SetPassword allows you to set a password using mixed case! Keep that in mind next time you locked yourself out of your Windows CE device... ;o)
| Attachment | Size |
|---|---|
| 11.4 KB |


