I’ve found that
NetUserChangePassword(0, 0, L"ab", L"cd");
changes the user password from ab to cd. However,
NetUserChangePassword(0, 0, (LPCWSTR) "ab", (LPCWSTR) "cd");
doesn’t work. The returned value indicates invalid password.
I need to pass const char* as last two parameters for this function call. How can I do that? For example,
NetUserChangePassword(0, 0, (LPCWSTR) vs[0].c_str(), (LPCWSTR) vs[1].c_str());
Where vs is std::vector<std::string>.
Those are two totally different L‘s. The first is a part of the C++ language syntax. Prefix a string literal with
Land it becomes a wide string literal; instead of an array ofchar, you get an array ofwchar_t.The
LinLPCWSTRdoesn’t describe the width of the characters, though. Instead, it describes the size of the pointer. Or, at least, it used to. TheLabbreviation on type names is a relic of 16-bit Windows, when there were two kinds of pointers. There were near pointers, where the address was somewhere within the current 64 KB segment, and there were far, or long pointers, which could point beyond the current segment. The OS required callers to provide the latter to its APIs, so all the pointer-type names useLP. Nowadays, there’s only one type of pointer; Microsoft keeps the same type names so that old code continues to compile.The part of
LPCWSTRthat specifies wide characters is theW. But merely type-casting acharstring literal toLPCWSTRis not sufficient to transform those characters into wide characters. Instead, what happens is the type-cast tells the compiler that what you wrote really is a pointer to a wide string, even though it really isn’t. The compiler trusts you. Don’t type-cast unless you really know better than the compiler what the real types are.If you really need to pass a
const char*, then you don’t need to type-cast anything, and you don’t need anyLprefix. A plain old string literal is sufficient. (If you really want to cast to a Windows type, useLPCSTR— noW.) But it looks like what you really need to pass in is aconst wchar_t*. As we learned above, you can get that with theLprefix on the string literal.In a real program, you probably don’t have a string literal. The user will provide a password, or you’ll read a password from some other external source. Ideally, you would store that password in a
std::wstring, which is likestd::stringbut forwchar_tinstead ofchar. Thec_str()method of that type returns aconst wchar_t*. If you don’t have awstring, a plain array ofwchar_tmight be sufficient.But if you’re storing the password in a
std::string, then you’ll need to convert it into wide characters some other way. To do a conversion, you need to know what code page thestd::stringcharacters use. The “current ANSI code page” is usually a safe bet; it’s represented by the constantCP_ACP. You’ll use that when callingMultiByteToWideStringto have the OS convert from the password’s code page into Unicode.Now, when you need a
wchar_t*, just use a pointer to the first element of that vector:&wv[0]. If you need it in awstring, you can construct it from the vector in a few ways: