windows 保存用户名密码的另一种方式 CREDENTIALW

        在Windows客户端开发时,如果需要用户进行登录,那么很多时候都需要对用户密码进行保存。尤其是需要自动登录的时候!

        一般来说,可能会使用ini文件进行用户名密码的保存。稍有安全意识的,会对用户名密码进行加密,再保存。下面要介绍的是另一种保存用户名密码的实现方式:windows系统上的PCREDENTIALW附赠string与wstring互转的代码)。示例代码如下:

#include 
#include 
#include 
#include 

//s2ws
std::wstring s2ws(const char* pStr, int len, unsigned int CodePage = CP_ACP)
{
	std::wstring buf;
	if(pStr == NULL || (len < 0 && len != -1))
	{
		return buf;
	}

	// figure out how many wide characters we are going to get 
	int nChars = MultiByteToWideChar( CodePage, 0, pStr, len, NULL, 0 ); 
	if ( len == -1 )
		--nChars; 
	if ( nChars == 0 )
		return L"";

	// convert the narrow string to a wide string 
	// nb: slightly naughty to write directly into the string like this
	buf.resize( nChars ); 
	MultiByteToWideChar( CodePage, 0, pStr, len, const_cast(buf.c_str()), nChars ); 

	return buf;
}

//ws2s
std::string ws2s(const wchar_t* pStr, int len, unsigned int CodePage = CP_ACP)
{
	std::string buf;
	if(pStr == NULL || (len < 0 && len != -1))
	{
		return buf;
	}

	// figure out how many narrow characters we are going to get 
	int nChars = WideCharToMultiByte( CodePage, 0, pStr, len, NULL, 0, NULL, NULL ); 
	if ( len == -1 )
		--nChars; 
	if ( nChars == 0 )
		return "";

	// convert the wide string to a narrow string
	// nb: slightly naughty to write directly into the string like this
	buf.resize( nChars );
	WideCharToMultiByte( CodePage, 0, pStr, len, const_cast(buf.c_str()), nChars, NULL, NULL ); 

	return buf;
}

bool WriteAccount(const std::string& username, const std::string& password) 
{
    char password_chars[255] = { 0 };
    wchar_t username_wstrs[255] = { 0 };
    wchar_t target_name_wstrs[1024] = { 0 };

    // password
    strcpy(password_chars, password.c_str());
    DWORD cbCreds = 1 + strlen(password_chars);

    // username
    std::wstring username_wstr = s2ws(username.c_str(), strlen(username.c_str()));
    wcscpy(username_wstrs, username_wstr.c_str());

    // target name
    std::wstring target_name_wstr = L"YourAppName";
    wcscpy(target_name_wstrs, target_name_wstr.c_str());

    CREDENTIALW cred = { 0 };
    cred.Type = CRED_TYPE_GENERIC;
    cred.TargetName = target_name_wstrs;
    cred.CredentialBlobSize = cbCreds;
    cred.CredentialBlob = (LPBYTE)password_chars;
    cred.Persist = CRED_PERSIST_LOCAL_MACHINE;
    cred.UserName = username_wstrs;

    return ::CredWriteW(&cred, 0);
}

bool ReadAccount(std::string& username, std::string& password)
{
	wchar_t username_wstrs[255] = { 0 };
	wchar_t target_name_wstrs[1024] = { 0 };

	// target name
	std::wstring target_name_wstr = L"YourAppName";

	PCREDENTIALW pcred;

	BOOL success = false;
	do {
		success = ::CredReadW(target_name_wstr.c_str(), CRED_TYPE_GENERIC, 0, &pcred);
		if (!success)
		{
			break;
		}
		std::wstring wszUserName = std::wstring(pcred->UserName);
		username = ws2s(wszUserName.c_str(), wcslen(wszUserName.c_str()));

		std::string pwd((char*)pcred->CredentialBlob, pcred->CredentialBlobSize);
		password = pwd;
		::CredFree(pcred);
		return true;
	} while (0);

	return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
	std::string szUserName = "admin";
	std::string szPassWord = "helloworld123456";
	WriteAccount(szUserName, szPassWord);

	std::string szUserNameOut;
	std::string szPassWordOut;
	ReadAccount(szUserNameOut, szPassWordOut);

	printf("username : %s, password : %s\r\n", szUserNameOut.c_str(), szPassWordOut.c_str());

	system("pause");
	return 0;
}




你可能感兴趣的:(Windows,程序设计)