并非为所有用户(包括其他用户)显示凭据提供者

时间:2019-05-03 10:01:26

标签: windows visual-c++ credential-providers

我正在尝试在签名选项中显示所有本地用户和其他用户(域用户)的凭据提供程序,但我不能。我参考here开发了此凭据提供程序。我对CSampleprovider.cpp文件的_EnumerateCredentials和GetCredentialCount函数进行了以下更改。

GetCredentialCount()

HRESULT GetCredentialCount([out] DWORD* pdwCount,
                           [out] DWORD* pdwDefault,
                           [out] BOOL* pbAutoLogonWithDefault)
{
    *pdwDefault = CREDENTIAL_PROVIDER_NO_DEFAULT;
    *pbAutoLogonWithDefault = FALSE;

    if (_fRecreateEnumeratedCredentials)
    {
        _fRecreateEnumeratedCredentials = false;
        _ReleaseEnumeratedCredentials();
        _CreateEnumeratedCredentials();
    }
    DWORD dwUserCount;
    HRESULT hr;

    if (_pCredProviderUserArray != nullptr) {
        hr = _pCredProviderUserArray->GetCount(&dwUserCount);
    }

    if ((dwUserCount == 0) || (IsOS(OS_DOMAINMEMBER) == 1)) {
        dwUserCount += 1;//display additional empty tile
    }
    *pdwCount = dwUserCount;
    return S_OK;
}

_EnumerateCredentials()

HRESULT CSampleProvider::_EnumerateCredentials()
{
    HRESULT hr = E_UNEXPECTED;


    DWORD dwUserCount;
    if (_pCredProviderUserArray != nullptr)
    {
        //DWORD dwUserCount = 0;
        _pCredProviderUserArray->GetCount(&dwUserCount);
        if (dwUserCount > 0)
        {
            //_pCredential = new CSampleCredential*[dwUserCount];
            for (DWORD i = 0; i < dwUserCount; i++) {
                ICredentialProviderUser* pCredUser;
                hr = _pCredProviderUserArray->GetAt(i, &pCredUser);
                if (SUCCEEDED(hr))
                {
                    //_pCredential[i] = new(std::nothrow) CSampleCredential();
                    _pCredential.push_back(new(std::nothrow) CSampleCredential());
                    if (_pCredential[i] != nullptr)
                    {
                        //logfile << "new CSampleCredential()\n";

                        hr = _pCredential[i]->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, pCredUser);

                        if (FAILED(hr))
                        {
                            _pCredential[i]->Release();
                            _pCredential[i] = nullptr;

                        }
                    }
                    else
                    {
                        hr = E_OUTOFMEMORY;
                    }
                    pCredUser->Release();
                }
            }
        }
        //if you are in a domain or have no users on the list you have to show "Other user tile"
        if (DEVELOPING) PrintLn(L"IsOS(OS_DOMAINMEMBER): %d", IsOS(OS_DOMAINMEMBER));
        if ((dwUserCount == 0) || (IsOS(OS_DOMAINMEMBER) == 1)) {
            if (DEVELOPING) PrintLn(L"Adding empty user tile");
            _pCredential.push_back(new(std::nothrow) CSampleCredential());
            if (_pCredential[_pCredential.size() - 1] != nullptr) {
                hr = _pCredential[_pCredential.size() - 1]->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, nullptr);
            }
            else {
                if (DEVELOPING) PrintLn(L"Error adding user: %d", _pCredential.size());
            }
        }

        return hr;
    }
}

并且我将类型CSampleCredential的专用标头更改为

std::vector<CSampleCredential> _pCredentialVector; 
// SampleV2CredentialCSampleProvider.h

在CSampleProvider.h文件中。

当我测试了我的此凭据提供程序时,它工作正常,即当未添加域(没有其他用户)但添加域(启用了其他用户)时,它在登录选项中为所有本地用户显示卡在受欢迎的墙纸上,屏幕不断闪烁。

因此,如何在登录选项中为所有本地和域用户(其他用户)显示我的凭据提供程序,以解决屏幕闪烁的问题。我是这个VC ++的新手,请帮助我。

1 个答案:

答案 0 :(得分:1)

当我尝试为所有图块(包括其他用户图块)启用自定义凭据提供程序时,我在给定凭据提供程序Sample的SampleProvider.cpp文件中的GetCredentialCount()方法和_EnumerateCredentials()方法中进行了一些更改由Microsoft。我所做的更改是:

HRESULT CServiceProvider::GetCredentialCount(
_Out_ DWORD *pdwCount,
_Out_ DWORD *pdwDefault,
_Out_ BOOL *pbAutoLogonWithDefault){

*pdwDefault = CREDENTIAL_PROVIDER_NO_DEFAULT;
*pbAutoLogonWithDefault = FALSE;

if (_fRecreateEnumeratedCredentials)
{
    _fRecreateEnumeratedCredentials = false;
    _ReleaseEnumeratedCredentials();
    _CreateEnumeratedCredentials();
}
DWORD dwUserCount;
HRESULT hr;

if (_pCredProviderUserArray != nullptr) {
    hr = _pCredProviderUserArray->GetCount(&dwUserCount);
}

if ((dwUserCount == 0) || (IsOS(OS_DOMAINMEMBER) == 1)) {
    dwUserCount += 1;//display additional empty tile
}
*pdwCount = dwUserCount;
return S_OK;}



HRESULT CServiceProvider::_EnumerateCredentials(){
HRESULT hr = E_UNEXPECTED;
DWORD dwUserCount;
if (_pCredProviderUserArray != nullptr)
{
    _pCredProviderUserArray->GetCount(&dwUserCount);
    if (dwUserCount > 0)
    {   
        //You need to initialize all the fields in LogonUI for each and every user 
        for (DWORD i = 0; i < dwUserCount; i++) {
            ICredentialProviderUser* pCredUser;
            hr = _pCredProviderUserArray->GetAt(i, &pCredUser);
            if (SUCCEEDED(hr))
            {
                _pCredential.push_back(new(std::nothrow) CUserCredential());
                if (_pCredential[i] != nullptr)
                {
                    hr = _pCredential[i]->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, pCredUser);

                    if (FAILED(hr))
                    {
                        _pCredential[i]->Release();
                        _pCredential[i] = nullptr;
                    }
                }
                else
                {
                    hr = E_OUTOFMEMORY;
                }
                pCredUser->Release();
            }
        }
    }
    //if you are in a domain or have no users on the list you have to show "Other user tile"
    if ((dwUserCount == 0) || (IsOS(OS_DOMAINMEMBER) == 1)) {
        _pCredential.push_back(new(std::nothrow) CUserCredential());
        if (_pCredential[_pCredential.size() - 1] != nullptr) {
            hr = _pCredential[_pCredential.size() - 1]->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, nullptr);
        }
    }
    return hr;
}
return hr;

}

现在,如您所见,在检查系统是否连接到域后,在调用nullptr方法时将Initialize()作为参数之一发送,我们需要处理{{ 1}}方法,检查SampleCredential.cpp文件中的条件是否存在。

nullptr

使用上述代码,您可以解决闪烁(CP崩溃)的问题,并为所有用户图块启用凭据提供程序。