为什么LogonUserW失败,错误代码为183(ERROR_ALREADY_EXISTS)

use*_*890 1 c++ windows security authentication winapi

我在LogonUserW失败后立即通过调用GetLastError()来检查错误代码,它总是183,但我不知道为什么LogonUserW会失败并带有这样的值.搜索了msdn,发现183(ERROR_ALREADY_EXISTS)的意思是"当该文件已经存在时无法创建文件",那么LogonUserW会创建什么文件?

有人可以在这里说清楚吗?

if (LogonUserW(uniUserName, uniDomainName, uniPassword, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token))
{
//do something when success
}
else
{
    STI_LOG(LOG_AUTH_DETAILS, ("Login fail\n"), true);
    DWORD ec = GetLastError();
    String message;
    switch (ec)
    {
        case ERROR_PRIVILEGE_NOT_HELD:
            message = "Error Privilege not held\n";
            break;
        case ERROR_LOGON_FAILURE:
            message = "Error Logon Failure\n";
            break;
        //...
        default:
            message = "Other errors\n";
    }
    STI_LOG(LOG_ERROR, ("Fail to log in user: %d-%s\n", ec, message.getCString()), true);
}
Run Code Online (Sandbox Code Playgroud)

Rog*_*and 5

在调用之前GetLastError,您正在此宏中执行一些日志记录代码:

STI_LOG(LOG_AUTH_DETAILS, ("Login fail\n"), true);
Run Code Online (Sandbox Code Playgroud)

这个日志记录功能中的一个API调用很可能也设置了最后一个错误标志.当然,像"文件已经存在"这样的错误与日志记录功能比登录更加一致.

所以,首先你应该在失败的函数调用后GetLastError 立即调用:

if (LogonUserW(uniUserName, uniDomainName, 
        uniPassword, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &token))
{
    //do something when success
}
else
{
    DWORD ec = GetLastError();

    STI_LOG(LOG_AUTH_DETAILS, ("Login fail\n"), true);

    // ... etc. ...
}
Run Code Online (Sandbox Code Playgroud)

正如它在MSDN上所说:

MSDN

进行此更改后,查看返回代码GetLastError是否更符合您的预期.