NetUserSetInfo:“无法找到用户名”

时间:2016-07-12 14:14:20

标签: c++ winapi

我正在编写一个可以更改已登录用户密码的c ++程序(该计算机上只有一个用户),并且该程序将在该计算机上作为服务运行,我找到了一个方法NetUserSetInfo做这项工作和我选择NetUserSetInfo的原因是我不想提供旧密码,找到我的代码

void chpwd::initialize() // function that initialize params of NetUserSetInfo
{
    cout<<"initializing"<<endl;
    string un=getenv("USERDOMAIN");
    un+="\\";
    un+=getenv("USERNAME"); //"USERDOMAIN\USERNAME", I gave name also,since the target machine won't be in domain
    wstring uname=wstring(un.begin(),un.end());
    wUserName=(wchar_t*)uname.c_str();
    wcout<<wUserName<<endl;
    wComputerName=_wgetenv (L"COMPUTERNAME");
    wcout<<wComputerName<<endl;
    string pw(p.genpassword());
    cout<<"pw "<<pw<<endl;
    wstring pwd=wstring(pw.begin(),pw.end());
    wcout.flush();
    wNewPassword=const_cast<LPWSTR>(pwd.c_str());
    wcout<<wNewPassword<<endl;

}

bool chpwd::chngpwd() //funtion that changes password
{
     initialize();
    do
    {
    pi1003.usri1003_password = wNewPassword;
          wcout.flush();
          wcout<<wNewPassword<<endl;
           nas = NetUserSetInfo(
                   wComputerName,  // computer name
                   wUserName,      // username
                   1003,           // info level
                   (LPBYTE)&pi1003,     // new info
                   NULL
                   );
        if(nas != NERR_Success)
        {
             DisplayErrorText(nas);
             l.logic_log(l.time(),"Error occured while reseting password \n old password \""+p.prevp+"\" retains");
        }
        Sleep(1000);
    }while(nas != NERR_Success);
    return 1;

}

当我运行代码时,params被正确初始化,但是我在更改密码时遇到The username could not be found.错误,我没有真正得到这个错误,我给出的用户名是正确的,我也执行了某个机器中的代码不在任何域下并具有管理员权限,但仍然相同,任何人都可以指出我出了什么问题。

bool chpwd::chngpwd()
{
    wstring uname = _wgetenv(L"USERDNSDOMAIN");
    uname += L"@";
    uname += _wgetenv(L"USERNAME"); 
    wcout << L"un " << uname << endl;//OP-Rixxxx.com@Richy_G

    wstring cname = _wgetenv (L"COMPUTERNAME");
    wcout << L"cn " << cname << endl;//TExxxxM

    wstring pwd;
    string pw = p.genpassword();//eadjbic3
    int len = MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), NULL, 0);
    if (len > 0)
    {
        pwd.resize(len);
        MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), &pwd[0], len);
    }
    wcout << L"pw " << pwd << endl;
    do
    {
    pi1003.usri1003_password = const_cast<LPWSTR>(pwd.c_str());;
          //wcout.flush();
          //wcout<<wNewPassword<<endl;
           nas = NetUserSetInfo(
                   cname.c_str(),  // computer name
                   uname.c_str(),      // username
                   1003,           // info level
                   (LPBYTE)&pi1003,     // new info
                   NULL
                   );
        if(nas != NERR_Success)
        {
             DisplayErrorText(nas);
             l.logic_log(l.time(),"Error occured while reseting password \n old password \""+p.prevp+"\" retains");
        }
        Sleep(1000);
    }while(nas != NERR_Success);
    return 1;

}
  

同样,变量是用适当的值获得的,但仍然如此   说

user name couldn't be found

1 个答案:

答案 0 :(得分:1)

使用wstring(iterator,iterator)不是将Ansi编码的std::string转换为Unicode std::wstring的正确方法。这只适用于ASCII字符,其他字符将无法正确转换。请改用MultiByteToWideChar()或等效词,或使用_wgetenv()代替getenv()

但更重要的是,您应该将所有initialize()代码直接移动到chngpwd()并删除所有中间变量。当wUserName退出时,您正在使用局部变量中超出范围的数据初始化wNewPasswordinitialize()。因此,当它们传递给NetUserSetInfo()时,它们会指向无效的内存。

尝试更像这样的事情:

bool chpwd::chngpwd()
{
    wstring uname = _wgetenv(L"USERDOMAIN");
    uname += L"\\";
    uname += _wgetenv(L"USERNAME");
    wcout << L"un " << uname << endl;

    wstring cname = _wgetenv (L"COMPUTERNAME");
    wcout << L"cn " << cname << endl;

    wstring pwd;
    string pw = p.genpassword();
    int len = MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), NULL, 0);
    if (len > 0)
    {
        pwd.resize(len);
        MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), &pwd[0], len);
    }
    wcout << L"pw " << pwd << endl;

    USER_INFO_1003 pi1003;
    pi1003.usri1003_password = const_cast<LPWSTR>(pwd.c_str());

    NET_API_STATUS nas;
    do
    {
        nas = NetUserSetInfoW(
                   cname.c_str(),  // computer name
                   uname.c_str(),      // username
                   1003,           // info level
                   (LPBYTE)&pi1003,     // new info
                   NULL
        );
        if (nas == NERR_Success) break;
        DisplayErrorText(nas);
        l.logic_log(l.time(), "Error occured while reseting password \n old password \"" + p.prevp + "\" retains");
        Sleep(1000);
    }
    while (true);
    return 1;
}