首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >windows凭据提示出现问题,CredUnPackAuthenticationBuffer错误50

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

Stack Overflow用户
提问于 2019-09-15 15:20:05
回答 1查看 653关注 0票数 0

我正在尝试显示Windows默认凭证提示,并将用户名、密码和域检索为字符串。

我正在使用这些文档:

CredUIPromptForWindowsCredentialsW

CredUnPackAuthenticationBufferW

当提示符显示时,我输入随机用户名和密码(例如,用户名: test,密码: test123),点击enter和函数CredUnPackAuthenticationBuffer()失败。

代码:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
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更改

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-24 07:27:21

在代码中查看此函数:

代码语言:javascript
复制
CredUnPackAuthenticationBuffer(
            CRED_PACK_GENERIC_CREDENTIALS,
            &outCredBuffer,
            dwCredBufferSize,
            szUserName,
            &maxUserNameSize,
            szDomain,
            &maxDomainNameSize,
            szPassword,
            &maxPasswordLength
        );

您需要将&outCredBuffer 更改为 outCredBuffer**.**

代码语言:javascript
复制
#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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57945493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档