gpt4 book ai didi

windows - 未为所有用户显示凭据提供程序(包括其他用户)

转载 作者:行者123 更新时间:2023-12-03 11:08:41 34 4
gpt4 key购买 nike

我正在尝试在签名选项中为所有本地和其他用户(域用户)显示凭据提供程序,但我不能。我开发了这个凭证提供程序,引用了 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 类型的私有(private) header 到
std::vector<CSampleCredential> _pCredentialVector; 
// SampleV2CredentialCSampleProvider.h

在 CSampleProvider.h 文件中。

当我测试我的这个凭据提供程序时,它工作正常,即当没有添加域(没有其他用户)但添加域(启用其他用户)时,它会在登录选项中显示所有本地用户,然后我被困在欢迎壁纸和屏幕不断闪烁。

那么,如何在登录选项中为所有本地和域用户(其他用户)显示我的凭据提供程序并克服屏幕闪烁。我是这个 VC++ 的新手,请帮帮我。

最佳答案

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

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() 时的参数之一检查系统是否连接到域后的方法,我们需要处理 nullptrInitialize()通过检查 SampleCredential.cpp 文件中的 if 条件的方法。
HRESULT CUserCredential::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;
_nNextScreenID = e_ARSNone;

GUID guidProvider;
LPOLESTR clsid;

if (pcpUser != nullptr) {
pcpUser->GetProviderID(&guidProvider);
StringFromCLSID(guidProvider, &clsid);
CoTaskMemFree(clsid);
_fIsLocalUser = (guidProvider == Identity_LocalUserProvider);
}
else {
_fIsLocalUser = true;//CP V1 or Domain
}

// 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"SomeLable1", &_rgFieldStrings[SFI_LABEL]);
}

if (SUCCEEDED(hr))
{
hr = SHStrDupW(L"SomeLable2", &_rgFieldStrings[SFI_LARGE_TEXT]);
}


if (SUCCEEDED(hr))
{
hr = SHStrDupW(L"", &_rgFieldStrings[SFI_PASSWORD]);
}

if (SUCCEEDED(hr))
{
hr = SHStrDupW(L"Somelabel4", &_rgFieldStrings[SFI_SUBMIT_BUTTON]);
}


hr = S_OK;
if (SUCCEEDED(hr))
{
if (pcpUser != nullptr) {
hr = pcpUser->GetStringValue(PKEY_Identity_QualifiedUserName, &_pszQualifiedUserName);//get username from the LogonUI user object
PWSTR pszUserName1;
pcpUser->GetStringValue(PKEY_Identity_UserName, &pszUserName1);
if (_fIsLocalUser) {
PWSTR pszUserName;
pcpUser->GetStringValue(PKEY_Identity_UserName, &pszUserName);
if (pszUserName != nullptr)
{
wchar_t szString[256];
StringCchPrintf(szString, ARRAYSIZE(szString), L"User Name: %s", pszUserName);
if (DEVELOPING) PrintLn(szString);
hr = SHStrDupW(pszUserName, &_rgFieldStrings[SFI_LARGE_TEXT]);
CoTaskMemFree(pszUserName);
}
else
{
hr = SHStrDupW(L"User Name is NULL", &_rgFieldStrings[SFI_LARGE_TEXT]);
}
}
else {
if (DEVELOPING) PrintLn(L"Domain user, skip SFI_LARGE_TEXT");
}
}
else {
PWSTR connectedDomainName = getNetworkName();
wchar_t szString[256];
StringCchPrintf(szString, ARRAYSIZE(szString), L"Sign in to: %s", connectedDomainName);
hr = SHStrDupW(szString, &_rgFieldStrings[SFI_DOMAIN_NAME_TEXT]);

if (DEVELOPING) PrintLn("Unknown user -> display LoginName");
hr = SHStrDupW(L"", &_pszQualifiedUserName);
_fUserNameVisible = true;
_rgFieldStatePairs[SFI_LOGIN_NAME].cpfs = CPFS_DISPLAY_IN_SELECTED_TILE;//unhide login name
//switch focus to login
_rgFieldStatePairs[SFI_LOGIN_NAME].cpfis = CPFIS_FOCUSED;
_rgFieldStatePairs[SFI_PASSWORD].cpfis = CPFIS_NONE;
//Don't panic!!!
}
}
if (pcpUser != nullptr)
{
hr = pcpUser->GetSid(&_pszUserSid);
}
return hr;}

使用上面的代码,您可以解决闪烁(即 CP 崩溃)以及为所有用户磁贴启用凭据提供程序。

关于windows - 未为所有用户显示凭据提供程序(包括其他用户),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55967533/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com