对于非 ascii 用户名,登录失败



我有C++代码试图向Windows验证本地用户:

BOOL result = ::LogonUserW(localAdminUserName_.c_str(), L".", localAdminPassword_.c_str(), 
    LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT);

这适用于基于 ASCII 字符集的用户名。

但不适用于名为userああ

的用户

如果我在日志中打印变量localAdminUserName_,它可以很好地打印用户名。

.c_str()以某种方式搞砸了吗?

在进行此 API 调用之前,我是否应该以某种方式对用户名/密码进行编码?

我为测试此方案而制作的以下控制台应用程序工作正常!

_declspec(dllimport)
BOOL
__stdcall
LogonUserW(
    __in        LPCWSTR lpszUsername,
    __in_opt    LPCWSTR lpszDomain,
    __in        LPCWSTR lpszPassword,
    __in        DWORD dwLogonType,
    __in        DWORD dwLogonProvider,
    __deref_out PHANDLE phToken
    );
int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hToken = NULL;
    BOOL returnValue = LogonUserW(
                            L"userああ",
                            L".",
                            L"pa$$w0rd",
                            LOGON32_LOGON_NETWORK,
                            LOGON32_PROVIDER_DEFAULT,
                            &hToken); 
    if (returnValue == false) {
        std::cout<<"Error!";
    } else {
        std::cout<<"Success!";
    }
    return 0;
}

将原始字符串转换为多字节字符串后,问题得到解决,然后在 windows.h 中使用 MultiByteToWideChar 方法将其转换为宽字符:

//convert the credentials to a multi-byte string first
std::string MbLocalAdminUserName = MbString(localAdminUserName_.c_str());
std::string MbLocalAdminPassowrd = MbString(localAdminPassowrd_.c_str());
//convert this multi-byte format to wide char that windows is expecting
//username
int len_MbLocalAdminUserName = MultiByteToWideChar(CP_UTF8, 0, MbLocalAdminUserName.c_str() , -1, NULL, 0);
wchar_t* WcLocalAdminUserName = new wchar_t[len_MbLocalAdminUserName + 1];
MultiByteToWideChar(CP_UTF8, 0, MbLocalAdminUserName.c_str(), -1, WcLocalAdminUserName, len_MbLocalAdminUserName + 1);
//password
int len_MbLocalAdminPassowrd = MultiByteToWideChar(CP_UTF8, 0, MbLocalAdminPassowrd.c_str() , -1, NULL, 0);
wchar_t* WcLocalAdminPassowrd = new wchar_t[len_MbLocalAdminPassowrd + 1];
MultiByteToWideChar(CP_UTF8, 0, MbLocalAdminPassowrd.c_str(), -1, WcLocalAdminPassowrd, len_MbLocalAdminPassowrd + 1);
BOOL result = ::LogonUser(WcLocalAdminUserName, L".", WcLocalAdminPassowrd, 
    LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken);
delete[] WcLocalAdminUserName;
delete[] WcLocalAdminPassowrd;

其中 MbString 是 :

MbString::MbString(const wchar_t* src)
: buf_(0) {
const size_t count = 1 + sizeof(wchar_t) * wcslen(src);
buf_ = new char[count];
// The 3rd parameter specifies the size of multi-bytes string buffer.
wcstombs(buf_, src, count);
}

最新更新