Search code examples
c++winapicredui

How to use CredUICmdLinePromptForCredentials?


I was tried for writing a application that use a function that nobody uses(CredUICmdLinePromptForCredentials). But the result is wrong, the user and pass variable is output as hex values.

This is my code:

#include <windows.h>
#include <wincred.h>
#include <iostream>
#pragma comment(lib,"Credui.lib")
int main()
{
    DWORD dwErr;
    WCHAR szUserName[CREDUI_MAX_USERNAME_LENGTH] = {NULL};
    WCHAR szPassword[CREDUI_MAX_PASSWORD_LENGTH] = {NULL};
    BOOL fSave;
    DWORD dwAuthError=1223;

    dwErr = CredUICmdLinePromptForCredentials(
        L".",
        NULL,
        dwAuthError,
        (PWSTR)&szUserName,
        CREDUI_MAX_USERNAME_LENGTH + 1,
        (PWSTR)&szPassword,
        CREDUI_MAX_PASSWORD_LENGTH + 1,
        &fSave,
        CREDUI_FLAGS_DO_NOT_PERSIST|CREDUI_FLAGS_EXCLUDE_CERTIFICATES
    );

    if (dwErr == ERROR_SUCCESS)
    {
        std::cout << "User Name: " << szUserName << std::endl;
        std::cout << "Password : " << szPassword << std::endl;
    }
    else if (dwErr == ERROR_CANCELLED)
    {
        std::cout << "User cancelled the operation." << std::endl;
    }
    else
    {
        std::cout << "Error occurred: " << dwErr << std::endl;
    }

    return 0;
}

This is the result:

User Name: 000000C5402FED80

Password : 000000C5402FF1B0

If I change the trigger code of ERROR_SUCCESS to:

        std::cout << "User Name: " << char(szUserName[0]) << std::endl;
        std::cout << "Password : " << char(szPassword[0]) << std::endl;

all working successfully, with the chars display correctly.


Solution

  • Please take a look at the szPassword and szUserName. That has the following definition:

        WCHAR szUserName[CREDUI_MAX_USERNAME_LENGTH] = {NULL};
        WCHAR szPassword[CREDUI_MAX_PASSWORD_LENGTH] = {NULL};
    

    while, we are printing strings as std::cout, which is taking only ASCII strings, or char, const char, char*, const char*, std::string.

    This should being this:

            std::wcout << L"User Name: " << szUserName << std::endl;
            std::wcout << L"Password : " << szPassword << std::endl;
    

    (because std::wcout is designed for Unicode strings, and std::cout isn't.)