我正在尝试显示Windows默认凭证提示,并将用户名、密码和域检索为字符串。
我正在使用这些文档:
CredUIPromptForWindowsCredentialsW
CredUnPackAuthenticationBufferW
当提示符显示时,我输入随机用户名和密码(例如,用户名: test,密码: test123),点击enter和函数CredUnPackAuthenticationBuffer()失败。
代码:
#include <Windows.h>
#include <wincred.h> //Link library Credui.lib for CredUIPromptForWindowsCredentials() to work
#include <iostream>
#include <string>
//Display error in console and close application
void DisplayConsoleError(const WCHAR* errorMessage, const WCHAR* fName);
int wmain(int argc, WCHAR* argv[])
{
CREDUI_INFO cuiInfo;
cuiInfo.cbSize = sizeof(CREDUI_INFO);
cuiInfo.hbmBanner = nullptr;
cuiInfo.hwndParent = nullptr;
cuiInfo.pszCaptionText = L"CaptionText";
cuiInfo.pszMessageText = L"MessageText";
DWORD dwAuthError = 0;
ULONG dwAuthPackage = 0;
LPVOID outCredBuffer = nullptr;
ULONG outCredBufferSize = 0;
BOOL credSaveCheckbox = false;
DWORD dwError = 0;
DWORD lastError = 0;
dwError = CredUIPromptForWindowsCredentials(
&cuiInfo,
dwAuthError,
&dwAuthPackage,
nullptr,
NULL,
&outCredBuffer,
&outCredBufferSize,
&credSaveCheckbox,
CREDUIWIN_CHECKBOX | CREDUIWIN_GENERIC);
if (dwError == ERROR_SUCCESS)
{
DWORD maxUserNameSize = CREDUI_MAX_USERNAME_LENGTH;
DWORD maxDomainNameSize = CREDUI_MAX_DOMAIN_TARGET_LENGTH;
DWORD maxPasswordLength = CREDUI_MAX_PASSWORD_LENGTH;
LPWSTR szUserName = new WCHAR[maxUserNameSize];
LPWSTR szDomain = new WCHAR[maxDomainNameSize];
LPWSTR szPassword = new WCHAR[maxPasswordLength];
DWORD dwCredBufferSize = outCredBufferSize; //ULONG to DWORD
DWORD lastError = 0;
dwError = CredUnPackAuthenticationBuffer(
CRED_PACK_GENERIC_CREDENTIALS,
&outCredBuffer,
dwCredBufferSize,
szUserName,
&maxUserNameSize,
szDomain,
&maxDomainNameSize,
szPassword,
&maxPasswordLength
);
lastError = GetLastError();
//Check for error
if (dwError == FALSE)
{
DisplayConsoleError(L"Blah", L"CredUnPackAuthenticationBuffer", lastError);
}
else
{
std::wcout << L"username " << szUserName << std::endl;
std::wcout << L"domain " << szDomain << std::endl;
std::wcout << L"password " << szPassword << std::endl;
}
}
else
{
lastError = dwError;
}
SecureZeroMemory(outCredBuffer, outCredBufferSize);
CoTaskMemFree(outCredBuffer);
return lastError;
} 此外,在CredUIPromptForWindowsCredentials()中调试VS2019失败(加载符号问题?),但编译的.exe工作正常。作为解决办法,我附加调试器来处理。
我是winapi的初学者,所以如果有人能解释为什么会出现这个错误,我做错了什么,以及如何修复这段代码,我将不胜感激。
编辑将错误检查移至SecureZeroMemory()和CoTaskMemFree()函数之上,以避免在检查错误消息之前调用其他API函数,但错误保持不变。
DisplayConsoleError:
void DisplayConsoleError(const WCHAR* errorMessage, const WCHAR* fName, DWORD lastError)
{
std::cout << std::endl;
std::cout << "Error\t" << std::endl;
std::wcout << L"In function:\t" << fName << std::endl;
std::cout << "Code:\t" << lastError << std::endl;
std::cout << std::endl;
}考虑@RemyLebeau反馈对代码的编辑2更改
发布于 2019-09-24 07:27:21
在代码中查看此函数:
CredUnPackAuthenticationBuffer(
CRED_PACK_GENERIC_CREDENTIALS,
&outCredBuffer,
dwCredBufferSize,
szUserName,
&maxUserNameSize,
szDomain,
&maxDomainNameSize,
szPassword,
&maxPasswordLength
);您需要将&outCredBuffer 更改为 outCredBuffer**.**
#include <Windows.h>
#include <wincred.h> //Link library Credui.lib for CredUIPromptForWindowsCredentials() to work
#include <iostream>
#include <string>
//Display error in console and close application
void DisplayConsoleError(const WCHAR* errorMessage, const WCHAR* fName, DWORD lastError)
{
std::cout << std::endl;
std::cout << "Error\t" << std::endl;
std::wcout << L"In function:\t" << fName << std::endl;
std::cout << "Code:\t" << lastError << std::endl;
std::cout << std::endl;
}
int wmain(int argc, WCHAR* argv[])
{
CREDUI_INFO cuiInfo;
cuiInfo.cbSize = sizeof(CREDUI_INFO);
cuiInfo.hbmBanner = nullptr;
cuiInfo.hwndParent = nullptr;
cuiInfo.pszCaptionText = L"CaptionText";
cuiInfo.pszMessageText = L"MessageText";
DWORD dwAuthError = 0;
ULONG dwAuthPackage = 0;
LPVOID outCredBuffer = nullptr;
ULONG outCredBufferSize = 0;
BOOL credSaveCheckbox = false;
DWORD dwError = 0;
DWORD lastError = 0;
dwError = CredUIPromptForWindowsCredentials(
&cuiInfo,
dwAuthError,
&dwAuthPackage,
nullptr,
NULL,
&outCredBuffer,
&outCredBufferSize,
&credSaveCheckbox,
CREDUIWIN_CHECKBOX | CREDUIWIN_GENERIC);
if (dwError == ERROR_SUCCESS)
{
DWORD maxUserNameSize = CREDUI_MAX_USERNAME_LENGTH;
DWORD maxDomainNameSize = CREDUI_MAX_DOMAIN_TARGET_LENGTH;
DWORD maxPasswordLength = CREDUI_MAX_PASSWORD_LENGTH;
LPWSTR szUserName = new WCHAR[maxUserNameSize];
LPWSTR szDomain = new WCHAR[maxDomainNameSize];
LPWSTR szPassword = new WCHAR[maxPasswordLength];
DWORD dwCredBufferSize = outCredBufferSize; //ULONG to DWORD
DWORD lastError = 0;
dwError = CredUnPackAuthenticationBuffer(
CRED_PACK_GENERIC_CREDENTIALS,
outCredBuffer,
dwCredBufferSize,
szUserName,
&maxUserNameSize,
szDomain,
&maxDomainNameSize,
szPassword,
&maxPasswordLength
);
lastError = GetLastError();
//Check for error
if (dwError == FALSE)
{
DisplayConsoleError(L"Blah", L"CredUnPackAuthenticationBuffer", lastError);
}
else
{
std::wcout << L"username " << szUserName << std::endl;
std::wcout << L"domain " << szDomain << std::endl;
std::wcout << L"password " << szPassword << std::endl;
}
}
else
{
lastError = dwError;
}
SecureZeroMemory(outCredBuffer, outCredBufferSize);
CoTaskMemFree(outCredBuffer);
return lastError;
}https://stackoverflow.com/questions/57945493
复制相似问题