Windows Custom Credential Provider is not displaying tile on logon for all users in a pc

17 Views Asked by At

I am unable to implement Windows Custom Credential Provider to all the users in a pc during logon when they click sign-in option. Tile is getting displayed for only my main user.

I modified Initialize function in CSampleCredential.cpp file to:

HRESULT CSampleCredential::Initialize(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
                                      _In_ CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR const *rgcpfd,
                                      _In_ FIELD_STATE_PAIR const *rgfsp,
                                      _In_ ICredentialProviderUser *pcpUser)
{
    HRESULT hr = S_OK;
    _cpus = cpus;
    GUID guidProvider;
    pcpUser->GetProviderID(&guidProvider);
    _fIsLocalUser = (guidProvider == Identity_LocalUserProvider);
    
    // Copy the field descriptors for each field. This is useful if you want to vary the field
    // descriptors based on what Usage scenario the credential was created for.
    for (DWORD i = 0; SUCCEEDED(hr) && i < ARRAYSIZE(_rgCredProvFieldDescriptors); i++)
    {
        _rgFieldStatePairs[i] = rgfsp[i];
        hr = FieldDescriptorCopy(rgcpfd[i], &_rgCredProvFieldDescriptors[i]);
    }

    // Initialize the String value of all the fields.
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Sample Credential", &_rgFieldStrings[SFI_LABEL]);
    }
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Zaperon Credential Provider", &_rgFieldStrings[SFI_LARGE_TEXT]);
    }
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Edit Text", &_rgFieldStrings[SFI_EDIT_TEXT]);
    }
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"", &_rgFieldStrings[SFI_PASSWORD]);
    }
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Submit Test", &_rgFieldStrings[SFI_SUBMIT_BUTTON]);
    }
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Checkbox Test", &_rgFieldStrings[SFI_CHECKBOX]);
    }
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Combobox", &_rgFieldStrings[SFI_COMBOBOX]);
    }
    /*if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Launch helper window", &_rgFieldStrings[SFI_LAUNCHWINDOW_LINK]);
    }*/
    if (SUCCEEDED(hr))
    {
        hr = SHStrDupW(L"Hide additional controls", &_rgFieldStrings[SFI_HIDECONTROLS_LINK]);
    }
    if (SUCCEEDED(hr))
    {
        hr = pcpUser->GetStringValue(PKEY_Identity_QualifiedUserName, &_pszQualifiedUserName);
    }
    if (SUCCEEDED(hr))
    {
            PWSTR pszUserName;
            pcpUser->GetStringValue(PKEY_Identity_UserName, &pszUserName);
            if (pszUserName != nullptr)
            {
                wchar_t szString[256];
                StringCchPrintf(szString, ARRAYSIZE(szString), L"User Name: %s", pszUserName);
                hr = SHStrDupW(szString, &_rgFieldStrings[SFI_FULLNAME_TEXT]);
                CoTaskMemFree(pszUserName);
            }
            else
            {
                hr = SHStrDupW(L"User Name is NULL", &_rgFieldStrings[SFI_FULLNAME_TEXT]);
            }
    }
    if (SUCCEEDED(hr))
    {
            PWSTR pszDisplayName;
            pcpUser->GetStringValue(PKEY_Identity_DisplayName, &pszDisplayName);
            if (pszDisplayName != nullptr)
            {
                wchar_t szString[256];
                StringCchPrintf(szString, ARRAYSIZE(szString), L"Display Name: %s", pszDisplayName);
                hr = SHStrDupW(szString, &_rgFieldStrings[SFI_DISPLAYNAME_TEXT]);
                CoTaskMemFree(pszDisplayName);
            }
            else
            {
                hr = SHStrDupW(L"Display Name is NULL", &_rgFieldStrings[SFI_DISPLAYNAME_TEXT]);
            }
    }
    if (SUCCEEDED(hr))
    {
            PWSTR pszLogonStatus;
            pcpUser->GetStringValue(PKEY_Identity_LogonStatusString, &pszLogonStatus);
            if (pszLogonStatus != nullptr)
            {
                wchar_t szString[256];
                StringCchPrintf(szString, ARRAYSIZE(szString), L"Logon Status: %s", pszLogonStatus);
                hr = SHStrDupW(szString, &_rgFieldStrings[SFI_LOGONSTATUS_TEXT]);
                CoTaskMemFree(pszLogonStatus);
            }
            else
            {
                hr = SHStrDupW(L"Logon Status is NULL", &_rgFieldStrings[SFI_LOGONSTATUS_TEXT]);
            }
    }

    if (SUCCEEDED(hr))
    {
            hr = pcpUser->GetSid(&_pszUserSid);
    }

    return hr;
}

I am using microsoft sample credential provider repo here

I have also made following changes in _EnumerateCredentials and GetCredentialCount functions of CSampleprovider.cpp file.

_EnumerateCredentials():

HRESULT CSampleProvider::_EnumerateCredentials()
{
    //_pCredential = new(std::nothrow) CSampleCredential();
    HRESULT hr = E_UNEXPECTED;
    DWORD dwUserCount;
    if (_pCredProviderUserArray != nullptr)
    {
        
        _pCredProviderUserArray->GetCount(&dwUserCount);
        if (dwUserCount > 0)
        {
            for (DWORD i = 0; i < dwUserCount; i++) {
                ICredentialProviderUser* pCredUser;
                hr = _pCredProviderUserArray->GetAt(i, &pCredUser);
                if (SUCCEEDED(hr))
                {
                    //_pCredential = new(std::nothrow) CSampleCredential();
                    _pCredentialVector.push_back(new(std::nothrow) CSampleCredential());
                    if (_pCredentialVector[i] != nullptr)
                    {
                        hr = _pCredentialVector[i]->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, pCredUser);
                        if (FAILED(hr))
                        {
                            _pCredentialVector[i]->Release();
                            _pCredentialVector[i] = nullptr;
                        }
                    }
                    else
                    {
                        hr = E_OUTOFMEMORY;
                    }
                    pCredUser->Release();
                }
            }
        }
        if ((dwUserCount == 0) || (IsOS(OS_DOMAINMEMBER) == 1)) {
            _pCredentialVector.push_back(new(std::nothrow) CSampleCredential());
            if (_pCredentialVector[_pCredentialVector.size() - 1] != nullptr) {
                hr = _pCredentialVector[_pCredentialVector.size() - 1]->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, nullptr);
            }
        }
        return hr;
    }
    return hr;
}

GetCredentialCount():

HRESULT CSampleProvider::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;
}

I am still unable to get CP tile to all my users with above provided code. So, How do I display my Credential provider for all users in a pc in sign-in options?

0

There are 0 best solutions below