I'm new to this Credential Provider stuff. And I decided to start with Microsoft's V2 Credential Provider Sample.
The sample only adds the custom Credential Provider for the local administrator account. But I'd like to have it for every other local account.
I have looked into these questions:
- Credential provider not displayed for all users (Other user included)
- Credential Providers V2 Active for All users(Tiles)
- How to show ICredentialProviderCredentialv2 on more than one User tile on the other user tile
And I also make the following changes to my code in reference to this GitHub repo.
In CSampleProvider.h
:
// CSampleCredential *_pCredential; -> From this
std::vector<CSampleCredential*> _pCredential; -> To this
In CSampleProvider.cpp
:
CSampleProvider::~CSampleProvider()
{
// if (_pCredential != nullptr)
// {
// _pCredential->Release();
// _pCredential = nullptr;
// }
_ReleaseEnumerateCredentials();
...
}
HRESULT CSampleProvider::GetCredentialCount(...)
{
...
// *pdwCount = 1;
DWORD dwUserCount;
_pCredProviderUserArray->GetCount(&dwUserCount);
*pdwCount = dwUserCount;
...
}
HRESULT CSampleProvider::GetCredentialAt(...) {
...
// if ((dwIndex == 0) && ppcpc)
// {
// hr = _pCredential->QueryInterface(IID_PPV_ARGS(ppcpc));
// }
if ((dwIndex == 0) && ppcpc)
{
hr = _pCredential[dwIndex]->QueryInterface(IID_PPV_ARGS(ppcpc));
}
...
}
void CSampleProvider::_ReleaseEnumeratedCredentials()
{
DWORD dwUserCount;
_pCredProviderUserArray->GetCount(&dwUserCount);
if (!_pCredential.empty())
{
for (DWORD i = 0; i < dwUserCount; i++)
{
_pCredential[0]->Release();
_pCredential.erase(_pCredential.begin());
}
}
}
HRESULT CSampleProvider::_EnumerateCredentials()
{
HRESULT hr = E_UNEXPECTED;
if (_pCredProviderUserArray != nullptr)
{
DWORD dwUserCount;
_pCredProviderUserArray->GetCount(&dwUserCount);
if (dwUserCount > 0)
{
for (DWORD i = 0; i < dwUserCount; i++) {
ICredentialProviderUser *pCredUser;
hr = _pCredProviderUserArray->GetAt(0, &pCredUser);
if (SUCCEEDED(hr))
{
_pCredential.push_back(new(std::nothrow) CSampleCredential());
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();
}
}
}
}
return hr;
}
I saw that I must return different SID in response to getUserSID()
but I can't figure out how can I do it properly.
I've crashed some of my environment (fortunately I'm using VMs). And can't really figure out how to do it for multiple local user.
By the way, is there any way to debug the program?