2025-11-28 00:35:46 +09:00

553 lines
26 KiB
C++

#include "pch.h"
#include "PluginCredentialManager.h"
#include <CorError.h>
#include <Credential.h>
#include <wil/win32_helpers.h>
#include <wil/registry.h>
#include <wil/registry_helpers.h>
#include <wil/filesystem.h>
#include <filesystem>
#include <windows.storage.h>
namespace winrt::PasskeyManager::implementation
{
PluginCredentialManager::PluginCredentialManager() : m_webAuthnDll(LoadLibraryExW(L"webauthn.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32))
{
Initialize();
}
PluginCredentialManager::~PluginCredentialManager()
{
}
HRESULT PluginCredentialManager::AddAllPluginCredentials()
{
// Get the function pointer of WebAuthNPluginAuthenticatorAddCredentials
auto webAuthNPluginAuthenticatorAddCredentials = GetProcAddressByFunctionDeclaration(m_webAuthnDll.get(), EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentials);
RETURN_HR_IF_NULL(E_FAIL, webAuthNPluginAuthenticatorAddCredentials);
std::vector<unique_plugin_credential_details> credentialDetailList{};
for (auto& iter : m_pluginLocalCredentialMetadataMap)
{
auto& savedCred = iter.second;
unique_plugin_credential_details pluginCred (new EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS());
pluginCred->pwszRpId = _wcsdup(savedCred->pRpInformation->pwszId);
pluginCred->pwszRpName = _wcsdup(savedCred->pRpInformation->pwszName);
pluginCred->pwszUserName = _wcsdup(savedCred->pUserInformation->pwszName);
pluginCred->pwszUserDisplayName = _wcsdup(savedCred->pUserInformation->pwszDisplayName);
pluginCred->cbUserId = savedCred->pUserInformation->cbId;
pluginCred->pbUserId = wil::make_unique_nothrow<BYTE[]>(pluginCred->cbUserId).release();
memcpy_s(pluginCred->pbUserId, pluginCred->cbUserId, savedCred->pUserInformation->pbId, savedCred->pUserInformation->cbId);
pluginCred->cbCredentialId = savedCred->cbCredentialID;
pluginCred->pbCredentialId = wil::make_unique_nothrow<BYTE[]>(pluginCred->cbCredentialId).release();
memcpy_s(pluginCred->pbCredentialId, pluginCred->cbCredentialId, savedCred->pbCredentialID, savedCred->cbCredentialID);
credentialDetailList.push_back(std::move(pluginCred));
}
RETURN_HR_IF(E_FAIL, credentialDetailList.empty());
EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST pluginCredentialList;
pluginCredentialList.cCredentialDetails = static_cast<DWORD>(credentialDetailList.size());
auto credentialDetailPtrList = std::vector<EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS>{};
for (auto& credential : credentialDetailList)
{
credentialDetailPtrList.push_back(credential.get());
}
pluginCredentialList.pCredentialDetails = credentialDetailPtrList.data();
auto pluginClsId = wil::make_unique_string<wil::unique_cotaskmem_string>(c_pluginClsid);
pluginCredentialList.pwszPluginClsId = pluginClsId.get();
RETURN_IF_FAILED(webAuthNPluginAuthenticatorAddCredentials(&pluginCredentialList));
return S_OK;
}
HRESULT PluginCredentialManager::AddPluginCredentialById(const std::vector<std::vector<UINT8>>& credentialIdList)
{
RETURN_HR_IF(E_FAIL, credentialIdList.empty());
// Get the function pointer of WebAuthNPluginAuthenticatorAddCredentials
auto webAuthNPluginAuthenticatorAddCredentials = GetProcAddressByFunctionDeclaration(m_webAuthnDll.get(), EXPERIMENTAL_WebAuthNPluginAuthenticatorAddCredentials);
RETURN_HR_IF_NULL(E_FAIL, webAuthNPluginAuthenticatorAddCredentials);
std::vector<unique_plugin_credential_details> credentialDetailList{};
for (auto& credentialId : credentialIdList)
{
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
auto iter = m_pluginLocalCredentialMetadataMap.find(credentialId);
if (iter != m_pluginLocalCredentialMetadataMap.end())
{
auto& savedCred = iter->second;
unique_plugin_credential_details pluginCred (new EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS ());
pluginCred->pwszRpId = _wcsdup(savedCred->pRpInformation->pwszId);
pluginCred->pwszRpName = _wcsdup(savedCred->pRpInformation->pwszName);
pluginCred->pwszUserName = _wcsdup(savedCred->pUserInformation->pwszName);
pluginCred->pwszUserDisplayName = _wcsdup(savedCred->pUserInformation->pwszDisplayName);
pluginCred->cbUserId = savedCred->pUserInformation->cbId;
pluginCred->pbUserId = wil::make_unique_nothrow<BYTE[]>(pluginCred->cbUserId).release();
memcpy_s(pluginCred->pbUserId, pluginCred->cbUserId, savedCred->pUserInformation->pbId, savedCred->pUserInformation->cbId);
pluginCred->cbCredentialId = savedCred->cbCredentialID;
pluginCred->pbCredentialId = wil::make_unique_nothrow<BYTE[]>(pluginCred->cbCredentialId).release();
memcpy_s(pluginCred->pbCredentialId, pluginCred->cbCredentialId, savedCred->pbCredentialID, savedCred->cbCredentialID);
credentialDetailList.push_back(std::move(pluginCred));
}
}
if (!credentialDetailList.empty())
{
EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST pluginCredentialList;
pluginCredentialList.cCredentialDetails = static_cast<DWORD>(credentialDetailList.size());
std::vector<EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS> credentialDetailPtrList{};
for (auto& credential : credentialDetailList)
{
credentialDetailPtrList.push_back(credential.get());
}
pluginCredentialList.pCredentialDetails = credentialDetailPtrList.data();
auto pluginClsId = wil::make_unique_string<wil::unique_cotaskmem_string>(c_pluginClsid);
pluginCredentialList.pwszPluginClsId = pluginClsId.get();
RETURN_IF_FAILED(webAuthNPluginAuthenticatorAddCredentials(&pluginCredentialList));
}
return S_OK;
}
HRESULT PluginCredentialManager::DeleteAllPluginCredentials()
{
// Get the function pointer of WebAuthNPluginAuthenticatorAddCredentials
auto webAuthNPluginAuthenticatorRemoveAllCredentials = GetProcAddressByFunctionDeclaration(
m_webAuthnDll.get(),
EXPERIMENTAL_WebAuthNPluginAuthenticatorRemoveAllCredentials);
RETURN_HR_IF_NULL(E_FAIL, webAuthNPluginAuthenticatorRemoveAllCredentials);
RETURN_HR(webAuthNPluginAuthenticatorRemoveAllCredentials(c_pluginClsid));
}
HRESULT PluginCredentialManager::DeletePluginCredentialById(std::vector<std::vector<UINT8>> const& credentialIdList, bool deleteEverywhere)
{
RETURN_HR_IF(E_FAIL, credentialIdList.empty());
// Get the function pointer of WebAuthNPluginAddAuthenticator
auto webAuthNPluginRemoveCredential = GetProcAddressByFunctionDeclaration(
m_webAuthnDll.get(),
EXPERIMENTAL_WebAuthNPluginAuthenticatorRemoveCredentials);
RETURN_HR_IF_NULL(E_FAIL, webAuthNPluginRemoveCredential);
std::vector<unique_plugin_credential_details> credentialDetailList{};
for (auto& credentialId : credentialIdList)
{
std::lock_guard<std::mutex> lock(m_pluginCachedCredentialsOperationMutex);
auto savedCred = m_pluginCachedCredentialMetadataMap.find(credentialId);
if (savedCred != m_pluginCachedCredentialMetadataMap.end())
{
auto& credToDelete = savedCred->second;
credentialDetailList.push_back(std::move(credToDelete));
m_pluginCachedCredentialMetadataMap.erase(savedCred);
}
}
if (!credentialDetailList.empty())
{
EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST pluginCredentialList;
pluginCredentialList.cCredentialDetails = static_cast<DWORD>(credentialDetailList.size());
std::vector<EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS> credentialDetailPtrList{};
for (auto& credential : credentialDetailList)
{
credentialDetailPtrList.push_back(credential.get());
}
pluginCredentialList.pCredentialDetails = credentialDetailPtrList.data();
auto pluginClsId = wil::make_unique_string<wil::unique_cotaskmem_string>(c_pluginClsid);
pluginCredentialList.pwszPluginClsId = pluginClsId.get();
RETURN_IF_FAILED(webAuthNPluginRemoveCredential(&pluginCredentialList));
}
if (deleteEverywhere)
{
for (auto& credentialId : credentialIdList)
{
{
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
m_pluginLocalCredentialMetadataMap.erase(credentialId);
}
}
RecreateCredentialMetadataFile();
}
return S_OK;
}
HRESULT PluginCredentialManager::RefreshAutofillPluginCredentialsList()
{
std::lock_guard<std::mutex> lock(m_pluginCachedCredentialsOperationMutex);
m_cachedCredentialsLoaded = false;
m_pluginCachedCredentialMetadataMap.clear();
// Get the function pointer of EXPERIMENTAL_WebAuthNPluginAuthenticatorGetAllCredentials
auto webAuthNPluginAuthenticatorGetAllCredentials = GetProcAddressByFunctionDeclaration(m_webAuthnDll.get(),
EXPERIMENTAL_WebAuthNPluginAuthenticatorGetAllCredentials);
RETURN_HR_IF_NULL(E_FAIL, webAuthNPluginAuthenticatorGetAllCredentials);
EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS_LIST localCredentialDetailsList = nullptr;
HRESULT hr = webAuthNPluginAuthenticatorGetAllCredentials(c_pluginClsid, &localCredentialDetailsList);
RETURN_HR_IF_EXPECTED(S_OK, hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
for (DWORD i = 0; i < localCredentialDetailsList->cCredentialDetails; i++)
{
EXPERIMENTAL_PWEBAUTHN_PLUGIN_CREDENTIAL_DETAILS credentialDetailsPtr = localCredentialDetailsList->pCredentialDetails[i];
std::vector<UINT8> credentialId(credentialDetailsPtr->pbCredentialId, credentialDetailsPtr->pbCredentialId + credentialDetailsPtr->cbCredentialId);
// Create a copy of the credential details
unique_plugin_credential_details credentialDetailsCopy(new EXPERIMENTAL_WEBAUTHN_PLUGIN_CREDENTIAL_DETAILS());
credentialDetailsCopy->cbCredentialId = credentialDetailsPtr->cbCredentialId;
credentialDetailsCopy->pbCredentialId = wil::make_unique_nothrow<BYTE[]>(credentialDetailsPtr->cbCredentialId).release();
if (credentialDetailsCopy->pbCredentialId == nullptr || credentialDetailsPtr->cbCredentialId == 0 || credentialDetailsPtr->pbCredentialId == nullptr)
{
continue;
}
memcpy_s(credentialDetailsCopy->pbCredentialId,
credentialDetailsCopy->cbCredentialId,
credentialDetailsPtr->pbCredentialId,
credentialDetailsPtr->cbCredentialId);
credentialDetailsCopy->pwszRpId = _wcsdup(credentialDetailsPtr->pwszRpId);
credentialDetailsCopy->pwszRpName = _wcsdup(credentialDetailsPtr->pwszRpName);
credentialDetailsCopy->cbUserId = credentialDetailsPtr->cbUserId;
credentialDetailsCopy->pbUserId = wil::make_unique_nothrow<BYTE[]>(credentialDetailsPtr->cbUserId).release();
if (credentialDetailsCopy->pbUserId == nullptr || credentialDetailsPtr->cbUserId == 0 || credentialDetailsPtr->pbUserId == nullptr)
{
continue;
}
memcpy_s(
credentialDetailsCopy->pbUserId,
credentialDetailsCopy->cbUserId,
credentialDetailsPtr->pbUserId,
credentialDetailsPtr->cbUserId);
credentialDetailsCopy->pwszUserName = _wcsdup(credentialDetailsPtr->pwszUserName);
credentialDetailsCopy->pwszUserDisplayName = _wcsdup(credentialDetailsPtr->pwszUserDisplayName);
// Insert the copy into the map
m_pluginCachedCredentialMetadataMap.emplace(credentialId, std::move(credentialDetailsCopy));
}
m_cachedCredentialsLoaded = true;
return S_OK;
}
/*
* Helper function to prepare the DataModel to diplay the list of credentials
*/
std::vector<winrt::com_ptr<Credential>> PluginCredentialManager::GetCredentialListViewModel()
{
std::vector< winrt::com_ptr<Credential>> credentialViewList;
for (const auto& mapItem : m_pluginLocalCredentialMetadataMap)
{
auto& savedCredential = mapItem.second;
auto& savedCredentialId = mapItem.first;
auto credentialOptions = CredentialOptionFlags::MetadataValid;
if (IsPluginCredentialIdAutofillSupported(savedCredential->cbCredentialID, savedCredential->pbCredentialID))
{
credentialOptions |= CredentialOptionFlags::AutofillCapable;
}
auto writer = winrt::Windows::Storage::Streams::DataWriter();
auto credIdSpan = std::span(savedCredentialId);
writer.WriteBytes(credIdSpan);
auto credentialIdBuffer = writer.DetachBuffer();
auto credentialViewListItem = winrt::make_self<PasskeyManager::implementation::Credential>(
savedCredential->pUserInformation->pwszName, savedCredential->pRpInformation->pwszName, credentialIdBuffer, credentialOptions);
credentialViewList.emplace_back(credentialViewListItem);
}
for (const auto& mapItem : m_pluginCachedCredentialMetadataMap)
{
const auto& cachedCredential = mapItem.second;
const auto& cachedCredentialId = mapItem.first;
bool isValidCredential = m_pluginLocalCredentialMetadataMap.find(cachedCredentialId) != m_pluginLocalCredentialMetadataMap.end();
if (isValidCredential)
{
// Skip the credentials that are already in the local credential list
continue;
}
auto credentialOptions = CredentialOptionFlags::AutofillCapable;
auto buffer = winrt::Windows::Storage::Streams::DataWriter();
auto credIdSpan = std::span(cachedCredentialId);
buffer.WriteBytes(credIdSpan);
auto credentialIdBuffer = buffer.DetachBuffer();
auto credentialViewListItem = winrt::make_self<PasskeyManager::implementation::Credential>(
cachedCredential->pwszUserName, cachedCredential->pwszRpName, credentialIdBuffer, credentialOptions);
credentialViewList.emplace_back(credentialViewListItem);
}
return credentialViewList;
}
bool PluginCredentialManager::IsPluginCredentialIdAutofillSupported(DWORD cbCredentialId, PBYTE pbCredentialId) const
{
return m_pluginCachedCredentialMetadataMap.find(
std::vector<UINT8>(pbCredentialId, pbCredentialId + cbCredentialId)) !=
m_pluginCachedCredentialMetadataMap.end();
}
DWORD readBytesFromFile(std::ifstream& file, PBYTE* buffer, const DWORD maxSize)
{
DWORD bytesToRead = 0;
if (file.is_open() && buffer != nullptr)
{
while (!file.eof())
{
file.read((char*)(&bytesToRead), sizeof(DWORD));
if (maxSize && bytesToRead > maxSize)
{
return 0;
}
if (bytesToRead == 0)
{
return 0;
}
if (*buffer == nullptr)
{
// allocate memory for the buffer
*buffer = wil::make_unique_nothrow<BYTE[]>(bytesToRead).release();
memset(*buffer, 0, bytesToRead);
}
file.read((char*)*buffer, bytesToRead);
return bytesToRead;
}
}
return 0;
}
bool PluginCredentialManager::LoadSavedCredentialsFromMockDatabase()
{
std::ifstream file{};
std::wstring filePath;
if (!GetCredentialStorageFilePath(filePath))
{
return false;
}
// open file in binary mode
file.open(filePath, std::ifstream::in | std::ifstream::binary);
if (file.is_open())
{
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
m_localCredentialsLoaded = false;
m_pluginLocalCredentialMetadataMap.clear();
while (!file.eof())
{
unique_credential_details savedCredential(new WEBAUTHN_CREDENTIAL_DETAILS());
//WEBAUTHN_CREDENTIAL_DETAILS savedCredential{};
savedCredential->pUserInformation = wil::make_unique_nothrow<WEBAUTHN_USER_ENTITY_INFORMATION>().release();
savedCredential->pRpInformation = wil::make_unique_nothrow<WEBAUTHN_RP_ENTITY_INFORMATION>().release();
if (savedCredential->pUserInformation == nullptr || savedCredential->pRpInformation == nullptr)
{
break;
}
// read the user id
savedCredential->pUserInformation->pbId = nullptr;
savedCredential->pUserInformation->cbId = 0;
savedCredential->pUserInformation->cbId = readBytesFromFile(file, &savedCredential->pUserInformation->pbId, savedCredential->pUserInformation->cbId);
if (savedCredential->pUserInformation->cbId == 0)
{
break;
}
// read the username and display name
PBYTE buffer = nullptr;
buffer = wil::make_unique_nothrow<BYTE[]>(maxWebAuthnWStringSize).release();
readBytesFromFile(file, &buffer, maxWebAuthnWStringSize);
savedCredential->pUserInformation->pwszName = (WCHAR*)buffer;
buffer = wil::make_unique_nothrow<BYTE[]>(maxWebAuthnWStringSize).release();
readBytesFromFile(file, &buffer, maxWebAuthnWStringSize);
savedCredential->pUserInformation->pwszDisplayName = (WCHAR*)buffer;
buffer = nullptr;
// read credential id
savedCredential->pbCredentialID = nullptr;
savedCredential->cbCredentialID = 0;
savedCredential->cbCredentialID = readBytesFromFile(file, &savedCredential->pbCredentialID, savedCredential->cbCredentialID);
// read rp name and id
buffer = wil::make_unique_nothrow<BYTE[]>(maxWebAuthnWStringSize).release();
readBytesFromFile(file, &buffer, maxWebAuthnWStringSize);
savedCredential->pRpInformation->pwszId = (WCHAR*)buffer;
buffer = wil::make_unique_nothrow<BYTE[]>(maxWebAuthnWStringSize).release();
readBytesFromFile(file, &buffer, maxWebAuthnWStringSize);
savedCredential->pRpInformation->pwszName = (WCHAR*)buffer;
buffer = nullptr;
std::vector<UINT8> localCredId(savedCredential->pbCredentialID, savedCredential->pbCredentialID + savedCredential->cbCredentialID);
m_pluginLocalCredentialMetadataMap.emplace(localCredId, std::move(savedCredential));
}
file.close();
m_localCredentialsLoaded = true;
}
return true;
}
bool PluginCredentialManager::GetCredentialStorageFilePath(std::wstring& filePath)
{
Windows::Storage::ApplicationData appData = Windows::Storage::ApplicationData::Current();
Windows::Storage::StorageFolder localFolder = appData.LocalFolder();
std::wstring localFolderPath = localFolder.Path().c_str();
std::wstring directoryPath = localFolderPath + L"\\" + c_pluginLocalAppDataDBDir;
if (!std::filesystem::exists(directoryPath))
{
THROW_IF_WIN32_BOOL_FALSE(std::filesystem::create_directory(directoryPath) ? TRUE: FALSE);
}
filePath = directoryPath + L"\\" + c_credentialsFileName;
return true;
}
bool PluginCredentialManager::SaveCredentialMetadataToMockDB(const WEBAUTHN_CREDENTIAL_DETAILS& newCredential)
{
if (newCredential.cbCredentialID == 0 || newCredential.pbCredentialID == nullptr)
{
return true;
}
std::wstring filePath;
if (!GetCredentialStorageFilePath(filePath))
{
return false;
}
std::ofstream file{};
file.open(filePath, std::ofstream::out | std::ofstream::binary | std::ofstream::app);
if (file.is_open())
{
DWORD len = newCredential.pUserInformation->cbId;
file.write((const char*)(&len), sizeof(DWORD));
file.write((const char*)newCredential.pUserInformation->pbId, len);
len = static_cast<DWORD>(wcslen(newCredential.pUserInformation->pwszName));
len *= sizeof(WCHAR);
file.write((const char*)(&len), sizeof(DWORD));
file.write((const char*)newCredential.pUserInformation->pwszName, len);
len = static_cast<DWORD>(wcslen(newCredential.pUserInformation->pwszDisplayName));
len *= sizeof(WCHAR);
file.write((const char*)(&len), sizeof(DWORD));
file.write((const char*)newCredential.pUserInformation->pwszDisplayName, len);
len = newCredential.cbCredentialID;
file.write((const char*)(&len), sizeof(DWORD));
file.write((const char*)newCredential.pbCredentialID, len);
len = static_cast<DWORD>(wcslen(newCredential.pRpInformation->pwszId));
len *= sizeof(WCHAR);
file.write((const char*)(&len), sizeof(DWORD));
file.write((const char*)newCredential.pRpInformation->pwszId, len);
len = static_cast<DWORD>(wcslen(newCredential.pRpInformation->pwszName));
len *= sizeof(WCHAR);
file.write((const char*)(&len), sizeof(DWORD));
file.write((const char*)newCredential.pRpInformation->pwszName, len);
file.close();
}
else
{
return false;
}
return true;
}
void PluginCredentialManager::GetLocalCredsByRpIdAndAllowList(PCWSTR rpId, PWEBAUTHN_CREDENTIAL_EX* ppCredentialList, DWORD pcCredentials, std::vector<const WEBAUTHN_CREDENTIAL_DETAILS *>& matchingCredentials)
{
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
for (const auto& mapItem : m_pluginLocalCredentialMetadataMap)
{
auto& cred = mapItem.second;
if (lstrcmpW(cred->pRpInformation->pwszId, rpId) == 0)
{
if (pcCredentials > 0)
{
for (DWORD i = 0; i < pcCredentials; i++)
{
if (cred->cbCredentialID == ppCredentialList[i]->cbId &&
memcmp(cred->pbCredentialID, ppCredentialList[i]->pbId, cred->cbCredentialID) == 0)
{
matchingCredentials.push_back(cred.get());
break;
}
}
}
else
{
matchingCredentials.push_back(cred.get());
}
}
}
}
bool PluginCredentialManager::RecreateCredentialMetadataFile()
{
std::wstring filePath;
if (!GetCredentialStorageFilePath(filePath))
{
return false;
}
std::ofstream file{};
file.open(filePath, std::ofstream::out | std::ofstream::binary | std::ofstream::trunc);
if (file.is_open())
{
file.close();
}
else
{
return false;
}
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
// iterating over all the saved credentials and writing them to the file
for (const auto& credEntry : m_pluginLocalCredentialMetadataMap)
{
SaveCredentialMetadataToMockDB(*credEntry.second.get());
}
return true;
}
bool PluginCredentialManager::ResetLocalCredentialsStore()
{
{
std::lock_guard<std::mutex> lock(m_pluginLocalCredentialsOperationMutex);
m_pluginLocalCredentialMetadataMap.clear();
}
return RecreateCredentialMetadataFile();
}
HRESULT PluginCredentialManager::SetVaultLock(bool lock)
{
std::lock_guard<std::mutex> lockguard(m_pluginOperationConfigMutex);
if (m_vaultLocked != lock)
{
wil::unique_hkey hKey;
RETURN_IF_WIN32_ERROR(RegCreateKeyEx(HKEY_CURRENT_USER, c_pluginRegistryPath, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &hKey, nullptr));
RETURN_IF_WIN32_ERROR(RegSetValueEx(hKey.get(), c_windowsPluginVaultLockedRegKeyName, 0, REG_DWORD, reinterpret_cast<PBYTE>(&lock), sizeof(lock)));
m_vaultLocked = lock;
}
return S_OK;
}
bool PluginCredentialManager::GetVaultLock()
{
std::lock_guard<std::mutex> lock(m_pluginOperationConfigMutex);
return m_vaultLocked;
}
HRESULT PluginCredentialManager::SetSilentOperation(bool silent)
{
std::lock_guard<std::mutex> lock(m_pluginOperationConfigMutex);
if (m_silentOperation != silent)
{
wil::unique_hkey hKey;
RETURN_IF_WIN32_ERROR(RegCreateKeyEx(HKEY_CURRENT_USER, c_pluginRegistryPath, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &hKey, nullptr));
RETURN_IF_WIN32_ERROR(RegSetValueEx(hKey.get(), c_windowsPluginSilentOperationRegKeyName, 0, REG_DWORD, reinterpret_cast<PBYTE>(&silent), sizeof(silent)));
m_silentOperation = silent;
}
return S_OK;
}
bool PluginCredentialManager::GetSilentOperation()
{
std::lock_guard<std::mutex> lock(m_pluginOperationConfigMutex);
return m_silentOperation;
}
}