LogonUser:程序意外完成

时间:2014-11-19 19:39:04

标签: c++ winapi

以下LogonUser的使用会导致我的应用程序崩溃。

inline std::string w_to_string(std::wstring wstr) {
    typedef std::codecvt_utf8<wchar_t> convert_type;
    std::wstring_convert<convert_type, wchar_t> converter;
    return converter.to_bytes(wstr);
}

inline const std::wstring to_wstring(const std::string& str) {
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    return converter.from_bytes(str);
}

inline bool verify(const std::string username,
        const std::string password, const std::string domain) {
    auto user = to_wstring(username);
    auto pass = to_wstring(password);
    auto dom  = to_wstring(domain);
    PHANDLE hToken;
    //UNICODE is set
    return LogonUser(user.c_str(), dom.c_str(), pass.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, hToken);
}

但是,如果我将auto pass = to_wstring(password);替换为auto pass = to_wstring("test");,一切正常。

有人可以解释为什么会这样,以及如何避免它?

1 个答案:

答案 0 :(得分:2)

问题不在于您的字符串,而在于您的hToken变量。您正在将未初始化的指针传递给LogonUser(),因此它将用户的令牌写入随机内存,这是未定义的行为,因此任何事情都可能发生。

您需要将指针传递给有效的HANDLE变量,然后在完成使用后调用CloseHandle(),例如:

inline bool verify(const std::string username, const std::string password, const std::string domain)
{
    auto user = to_wstring(username);
    auto pass = to_wstring(password);
    auto dom  = to_wstring(domain);
    HANDLE hToken;
    bool success = LogonUserW(user.c_str(), dom.c_str(), pass.c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken);
    if (success)
        CloseHandle(hToken);
    return success;
}

可以简化为:

inline bool verify(const std::string username, const std::string password, const std::string domain)
{
    HANDLE hToken;
    bool success = LogonUserW(to_wstring(username).c_str(), to_wstring(domain).c_str(), to_wstring(password).c_str(), LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken);
    if (success)
        CloseHandle(hToken);
    return success;
}