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"):

hmCoreDll = (HMODULE) LoadLibrary(_T("coredll.dll"));
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:

#include <windows.h>

// 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"):

//      Get text from password window.
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)

AttachmentSize
Image icon ShowStartup.jpg11.4 KB

Comments

Hi,
very interesting work. I was wondering if your program might help me with my problem. I have activated the password protection on my PNA but the screen resolution is to small so that the text field is not visible. Now I can't log in, although the password is known. Do you know any possibility to get rid of this screen?
Thanks
Nathon

You should still be able to enter your password, even if you can't see the text box. The text box should have focus, so just enter the password and press ENTER. Then go into control panel and set the password to nothing and don't set it again! ;) Bad OEM for not changing the password dialog to match the screen!

When I boot my UMPC it comes to the login screen that asks for a password. The problem is the touch screen keyboard does not come up so I can't type my password. I have tried connecting a USB external keyboard but it does not work. Any suggestions?

Hi,

very nice article,

I am facing the problem entering the password as my device don't have keyboard support.For other operation I have used SIP for Input. but for login dialog it does't show SIP(Software Input Panel). is there any solution available for this issue.

Thanks,
Anant

Not that I know of, except creating your own password dialog and calling SipShowIM when the textbox gets the focus. If you've set the password and are now unable to unlock the device you could try to attach a USB keyboard but if that doesn't work you only way out is a hard reset I'm afraid...

Hi,
Nice artical. I am lookign for login dialog box in my Win CE5 handheld.
I am using C3 code. I wna t to validate the user against domain (wireless connectivity) crediantial.

Can you please help. Is there is a wsy to do it programmitically.