C++ windows凭据提示出现问题,CredUnPackAuthenticationBuffer错误50
我正在尝试显示Windows默认凭据提示,并以字符串形式检索用户名、密码和域 我正在使用以下文档: 当提示显示时,我输入随机用户名和密码(如用户名:test,密码:test123),点击回车,函数C++ windows凭据提示出现问题,CredUnPackAuthenticationBuffer错误50,c++,winapi,credentials,C++,Winapi,Credentials,我正在尝试显示Windows默认凭据提示,并以字符串形式检索用户名、密码和域 我正在使用以下文档: 当提示显示时,我输入随机用户名和密码(如用户名:test,密码:test123),点击回车,函数CredUnPackAuthenticationBuffer()失败,出现错误\u不受支持 代码: #包括 #包括//链接库Credui.lib,以便CredUIPromptForWindowsCredentials()正常工作 #包括 #包括 //在控制台中显示错误并关闭应用程序 void Dis
CredUnPackAuthenticationBuffer()
失败,出现错误\u不受支持
代码:
#包括
#包括//链接库Credui.lib,以便CredUIPromptForWindowsCredentials()正常工作
#包括
#包括
//在控制台中显示错误并关闭应用程序
void DisplayConsoleError(常量WCHAR*errorMessage,常量WCHAR*fName);
int wmain(int argc,WCHAR*argv[])
{
CREDUI_INFO cuinfo;
cuinfo.cbSize=sizeof(CREDUI_INFO);
cuinfo.hbmBanner=nullptr;
cuinfo.hwndpress=nullptr;
cuinfo.pszcaptitontext=L“字幕文本”;
cuinfo.pszMessageText=L“MessageText”;
DWORD dwAuthError=0;
ULONG dwAuthPackage=0;
LPVOID outterdbuffer=nullptr;
ULONG露头缓冲区大小=0;
BOOL credSaveCheckbox=false;
DWORD dwError=0;
DWORD lastError=0;
dwError=CredUIPromptForWindowsCredentials(
&cuiInfo,
dwauthorror,
&DWAUTH软件包,
nullptr,
无效的
&露头缓冲区,
&露头缓冲区大小,
&Credsaveecheckbox,
CREDUIWIN_复选框(CREDUIWIN_通用);
if(dwError==ERROR\u SUCCESS)
{
DWORD maxUserNameSize=CREDUI\u MAX\u USERNAME\u LENGTH;
DWORD maxDomainNameSize=CREDUI_MAX_DOMAIN_TARGET_LENGTH;
DWORD maxPasswordLength=CREDUI_MAX_PASSWORD_LENGTH;
LPWSTR szUserName=new WCHAR[maxusernamize];
LPWSTR szDomain=new WCHAR[maxDomainNameSize];
LPWSTR szPassword=new WCHAR[maxPasswordLength];
DWORD dwCredBufferSize=露头缓冲区大小;//ULONG到DWORD
DWORD lastError=0;
dwError=CredUnPackAuthenticationBuffer(
CRED_PACK_GENERIC_凭证,
&露头缓冲区,
dwCredBufferSize,
szUserName,
&maxUserNameSize,
szDomain,
&maxDomainNameSize,
szPassword,
&maxPasswordLength
);
lastError=GetLastError();
//检查错误
if(dwError==FALSE)
{
DisplayConsoleError(L“Blah”,L“CredUnPackAuthenticationBuffer”,lastError);
}
其他的
{
std::wcout查看代码中的此函数:
CredUnPackAuthenticationBuffer(
CRED_PACK_GENERIC_CREDENTIALS,
&outCredBuffer,
dwCredBufferSize,
szUserName,
&maxUserNameSize,
szDomain,
&maxDomainNameSize,
szPassword,
&maxPasswordLength
);
您需要将露头缓冲区
更改为露头缓冲区
#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;
}
#包括
#包括//链接库Credui.lib,以便CredUIPromptForWindowsCredentials()正常工作
#包括
#包括
//在控制台中显示错误并关闭应用程序
void DisplayConsoleError(常量WCHAR*errorMessage,常量WCHAR*fName,DWORD lastError)
{
std::即使creduipromptforwindowscdentials()
失败,您是否仍在调用CredUnPackAuthenticationBuffer()
。如果CredUnPackAuthenticationBuffer()
失败,您在显示错误之前调用了其他API函数,因此在检索错误代码之前可以清除错误代码,因此错误50可能根本不属于CredUnPackAuthenticationBuffer()
。使用GetLastError()时
若要检索错误代码,请始终在使用它的失败API之后立即调用它。@RemyLebeau感谢您的响应。我正在检查CreduipPromptForWindowsCredentials()
保存到变量dwError
的返回值。如果失败,则函数DisplayConsoleError()调用了
,它将显示错误消息并关闭应用程序。我将错误检查移到了
SecureZeroMemory(露头缓冲区,露头缓冲区大小);CoTaskMemFree(露头缓冲区);
上面,但错误号保持不变。另请参见,您的DisplayConsoleError()
仍在调用API函数(通过cout
和wcout
)在调用GetLastError()
之前,请注意,GetLastError()
是获取失败的CredUIPromptForWindowsCredentials()
的错误方法,因此如果CredUIPromptForWindowsCredentials()
失败,您将不会为此报告正确的错误代码。我将更改DisplayConsoleError()
以将错误代码作为输入参数,并让调用方决定如何获取正确的错误代码以传入。谢谢您的exit()建议。我根据您的反馈调整了代码。返回的错误代码仍然为50。
#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;
}