Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ windows凭据提示出现问题,CredUnPackAuthenticationBuffer错误50_C++_Winapi_Credentials - Fatal编程技术网

C++ windows凭据提示出现问题,CredUnPackAuthenticationBuffer错误50

C++ windows凭据提示出现问题,CredUnPackAuthenticationBuffer错误50,c++,winapi,credentials,C++,Winapi,Credentials,我正在尝试显示Windows默认凭据提示,并以字符串形式检索用户名、密码和域 我正在使用以下文档: 当提示显示时,我输入随机用户名和密码(如用户名:test,密码:test123),点击回车,函数CredUnPackAuthenticationBuffer()失败,出现错误\u不受支持 代码: #包括 #包括//链接库Credui.lib,以便CredUIPromptForWindowsCredentials()正常工作 #包括 #包括 //在控制台中显示错误并关闭应用程序 void Dis

我正在尝试显示Windows默认凭据提示,并以字符串形式检索用户名、密码和域

我正在使用以下文档:

当提示显示时,我输入随机用户名和密码(如用户名:test,密码:test123),点击回车,函数
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;
}