Not able to delete the registry entry - winapi

I created a new registry entries. I am not able to delete parent node. The structure of registry is as below:
HKEY_CURRENT_USER\Software\IE_BACKUP\Internet Settings
Below is the code I am using for deleting the registry entries. It deletes the content of the node InternetSettings but not able to delete IE_BACKUP.
void main()
{ //some other stuffs of code are here for creating new registry.
bool ret = DeleteValueKey(HKEY_CURRENT_USER, L"Software\\IE_BACKUP",L"Internet Settings");
}
bool DeleteValueKey(HKEY hKeyRoot, LPCWSTR Subkey, LPCWSTR ValueKey)
{
HKEY hKey = NULL;
bool bReturn = false;
if (RegDeleteKey(hKey, Subkey ) == ERROR_SUCCESS)
{
bReturn = true;
}
if (RegOpenKeyEx(hKeyRoot, Subkey, 0, KEY_SET_VALUE , &hKey) == ERROR_SUCCESS)
{
if (RegDeleteKey(hKey, ValueKey ) == ERROR_SUCCESS)
{
bReturn = true;
}
}
if(hKey != NULL){RegCloseKey(hKey);}
return bReturn;
}

Related

images not working properly if I open it from my shell namespace extension folder

I have my custom shell namespace extension. Just want to have a virtual folder mapped to some folder on disk C:/ with the same functionality.
using namespace ATL;
class ATL_NO_VTABLE CMyShellFolder :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CMyShellFolder, &CLSID_CMyShellFolder>,
public IPersistFolder2,
public IShellFolder2,
public IExplorerPaneVisibility
{
CComHeapPtr<ITEMIDLIST_ABSOLUTE> m_pidl;
CComPtr<IShellFolder2> m_folder;
CComPtr<IThumbnailHandlerFactory> m_thFactory;
CComPtr<IUnknown> m_site;
public:
CMyShellFolder()
{
}
static HRESULT WINAPI UpdateRegistry(BOOL reg) throw();
BEGIN_COM_MAP(CMyShellFolder)
COM_INTERFACE_ENTRY(IShellFolder)
COM_INTERFACE_ENTRY(IShellFolder2)
COM_INTERFACE_ENTRY2(IPersist, IPersistFolder)
COM_INTERFACE_ENTRY(IPersistFolder)
COM_INTERFACE_ENTRY(IPersistFolder2)
COM_INTERFACE_ENTRY(IExplorerPaneVisibility)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
---------------------------------
HRESULT CMyShellFolder::BindToObject(PCUIDLIST_RELATIVE pidl, IBindCtx* pbc, REFIID riid, LPVOID* ppv)
{
if (riid == __uuidof(IShellFolder3))
return E_NOINTERFACE;
HR;
CComObject<CMyShellFolder>* folder = nullptr;
CHECKARG(pidl);
hr = E_NOINTERFACE;
if (riid == IID_IShellFolder ||
riid == IID_IShellFolder2)
{
// check it's a folder
SFGAOF atts = SFGAO_FOLDER;
auto hr2 = GetAttributesOf(1, (PCUITEMID_CHILD_ARRAY)&pidl, &atts);
if (FAILED(hr2) || !(atts & SFGAO_FOLDER))
goto cleanup; // nope, get out
CHECKHR(CreateInstanceAddRef(&folder));
CHECKHR(folder->_Initialize(this, pidl));
CHECKHR(folder->QueryInterface(riid, ppv));
}
RELEASE(folder);
HRONFAIL(L"CMyShellFolder::BindToObject"); }
HRESULT CMyShellFolder::CreateViewObject(HWND hwnd, REFIID riid, LPVOID* ppv)
{
HR;
SFV_CREATE sfvc = { 0 };
DEFCONTEXTMENU dcm = { 0 };
CHECKITEM;
CHECKARG(ppv);
hr = E_NOINTERFACE;
if (riid == IID_IShellView)
{
sfvc.cbSize = sizeof(SFV_CREATE);
CHECKHR(QueryInterface(IID_PPV_ARGS(&sfvc.pshf)));
QueryInterface(IID_PPV_ARGS(&sfvc.psfvcb));
CHECKHR(SHCreateShellFolderView(&sfvc, (IShellView**)ppv));
goto cleanup;
}
if (riid == IID_IContextMenu)
{
dcm.hwnd = hwnd;
//dcm.pidlFolder = (PCIDLIST_ABSOLUTE)m_pidl.m_pData;
QueryInterface(IID_PPV_ARGS(&dcm.pcmcb));
CHECKHR(QueryInterface(IID_PPV_ARGS(&dcm.psf)));
CHECKHR(SHCreateDefaultContextMenu(&dcm, riid, ppv));
goto cleanup;
}
if (riid == IID_ITransferSource || // for delete & file operations
riid == IID_IDropTarget) // for copy paste & dd
{
CHECKHR(m_folder->CreateViewObject(hwnd, riid, ppv));
goto cleanup;
}
CHECKHR(m_folder->CreateViewObject(hwnd, riid, ppv));
cleanup:
RELEASE(dcm.pcmcb);
RELEASE(dcm.psf);
RELEASE(sfvc.psfvcb);
RELEASE(sfvc.pshf);
HRONFAIL(L"CMyShellFolder::CreateViewObject"); }
But opening images from my custom folders don't work.
image image2
Actually it displays an image for about a second and then error message appears.
Nevertheless it could be opened normally via Paint
Your nse need handle IID_Istream to open file with UWP program
// Pseudo code
STDMETHODIMP NSEShellFolder::BindToObject (LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, void** ppvOut)
{
HRESULT hr = E NOTIMPL;
//.....//
if (riid == IID IStream) {
DWORD grfMode = 0;
if (pbcReserved) { //IBindCtx
BIND OPTS opts;
ZeroMemory (&opts, sizeof (BIND OPTS));
opts.cbStruct = sizeof (opts);
pbc->GetBindOptions (&opts);
grfMode = opts.grfMode;
}
//If your nse Has FileSystemPath, Win32 API ¹SHCreateStreamOnFile Ex' is useful.
//or you can implement own IStream interface.
LPWSTR pPath = CNSEData::GetPath (m_pidl);
BOOL bCreate = grfMode & STGM CREATE? TRUE : FALSE;
hr = SHCreateStreamOnFileEx (pPath,grfMode, FILE_ATTRIBUTE_NORMAL,bCreate,NULL, (IStream**)ppvOut);
}
//.....//
return hr;
}
Before
After

Credential provider not displayed for all users (Other user included)

I am trying to show credential provider for all local and for other user(Domain users) in signing options but I am not able to. I developed this credential provider taking reference from here. I made following changes in _EnumerateCredentials and GetCredentialCount functions of CSampleprovider.cpp file.
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;
}
}
And I have changed a private header of type CSampleCredential to
std::vector<CSampleCredential> _pCredentialVector;
// SampleV2CredentialCSampleProvider.h
in CSampleProvider.h file.
When I tested this Credential provider of mine it is working fine i.e it is displaying for all local users in sign in options when no domain is added (No other user) but when domain is added(other user enabled) then I am being stuck at the welcome wallpaper and screen keeps on flickering.
So, How do I display my Credential provider for all local and domain users (Other user) in sign in options and over come that flickering of screen. I am new to this VC++ please help me out.
While I was trying to enable the custom credential provider to all the tiles including the other user tile I made few changes in GetCredentialCount() method and _EnumerateCredentials() method in SampleProvider.cpp file in Credential provider Sample given by Microsoft. The changes I made are:
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;
}
Now as you see we are sending nullptr as one of the argument while calling Initialize() method after checking if system is connected to domain, we need to handle that nullptr in Initialize() method by checking with if condition in SampleCredential.cpp file.
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;}
Using above code you can solve flickering (which is crashing of CP) as well as enable Credential provider for all user tiles.

Structure of the certificate pointed to by NCRYPT_KEY_HANDLE

I've written a credential provider and a key storage provider to logon to windows via certificate. As the documentation in this points is quite vague I used different samples from Microsoft to get things working.
I think I'm nearly there, but the logon behaves unpredictably. Sometimes I get through to the kerberos server (which complains about the certificate), sometimes the process fails with 0x80090029 without any information and sometimes windows crashes. As these crashes all have to do with access violations or null pointers and happen to occur in various places (kerberos.dll, Windows.UI.Logon.dll, ...) I think it has something to do with my key structure that i point the given NCRYT_KEY_HANDLE to in my OpenKey-implementation.
The KeyStorageProviderSample in the CNG-Kit has an example, but relies on a RSA-key stored in %AppData%. I don't have the private key available as it is stored in secure hardware, I just have the public part (i.e. the public certificate), that I read from another device and import via the following code:
SECURITY_STATUS WINAPI KeyHandler::ReadPemCert(__inout KSP_KEY *keyHandle)
{
LOG_FUNCTION;
CERT_CONTEXT certContext = {};
DWORD readLength = 0;
LOG("Fetch certificate");
const int maxSizeInBytes = 4096;
char pemCertificateAsBytes[maxSizeInBytes];
BluetoothClient bluetoothClient = BluetoothClient();
bluetoothClient.getCertificate((PBYTE)pemCertificateAsBytes, readLength);
DWORD certAsDerLen = readLength;
BYTE* certAsDer = new BYTE[certAsDerLen];
LOG("convert PEM to DER");
if (!CryptStringToBinaryA(pemCertificateAsBytes, 0, CRYPT_STRING_BASE64, certAsDer, &certAsDerLen, NULL, NULL))
{
LOG_LAST_ERROR("CryptStringToBinary failed. Err:");
}
LOG_BYTES_AS_HEX("DER-Zertifikat", certAsDer, certAsDerLen);
PCCERT_CONTEXT pcCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, certAsDer, certAsDerLen);
certContext->pCertInfo = pcCertContext->pCertInfo;
certContext->cbCertEncoded = pcCertContext->cbCertEncoded;
certContext->pbCertEncoded = pcCertContext->pbCertEncoded;
certContext->dwCertEncodingType = pcCertContext->dwCertEncodingType;
CERT_INFO *certInfo;
certInfo = certContext.pCertInfo;
CERT_PUBLIC_KEY_INFO pubKeyInfo = certInfo->SubjectPublicKeyInfo;
LOG("Aquire cryptocontext");
HCRYPTPROV hProv = 0;
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
{
LOG_LAST_ERROR("CryptAcquireContext failed. Err:");
return -1;
}
}
LOG("Importing public key");
NCRYPT_KEY_HANDLE publicKeyHandle = NULL;
if (!CryptImportPublicKeyInfo(hProv, X509_ASN_ENCODING, &pubKeyInfo, &publicKeyHandle))
{
LOG_LAST_ERROR("CryptImportPublicKeyInfo failed. Err:");
return -1;
}
keyHandle->fFinished = TRUE;
keyHandle->hPublicKey = (BCRYPT_KEY_HANDLE)publicKeyHandle;
keyHandle->pszKeyBlobType = BCRYPT_RSAPUBLIC_BLOB;
LocalFree(certInfo);
return ERROR_SUCCESS;
}
The key structure is initialized this way:
SECURITY_STATUS
WINAPI
KeyHandler::CreateNewKeyObject(
__in_opt LPCWSTR pszKeyName,
__deref_out KSP_KEY **ppKey)
{
LOG_FUNCTION;
KSP_KEY *pKey = NULL;
DWORD cbKeyName = 0;
SECURITY_STATUS Status = NTE_INTERNAL_ERROR;
NTSTATUS ntStatus = STATUS_INTERNAL_ERROR;
pKey = (KSP_KEY *)HeapAlloc(GetProcessHeap(), 0, sizeof(KSP_KEY));
if (pKey == NULL)
{
return NTE_NO_MEMORY;
}
pKey->cbLength = sizeof(KSP_KEY);
pKey->dwMagic = KSP_KEY_MAGIC;
pKey->dwAlgID = KSP_RSA_ALGID;
pKey->pszKeyFilePath = NULL;
pKey->pszKeyBlobType = NULL;
pKey->dwKeyBitLength = 0;
pKey->fFinished = FALSE;
//Copy the keyname into the key struct.
if (pszKeyName != NULL)
{
cbKeyName = (DWORD)(wcslen(pszKeyName) + 1) * sizeof(WCHAR);
pKey->pszKeyName = (LPWSTR)HeapAlloc(
GetProcessHeap(),
0,
cbKeyName + sizeof(WCHAR));
if (pKey->pszKeyName == NULL)
{
return NTE_NO_MEMORY;
}
CopyMemory(pKey->pszKeyName, pszKeyName, cbKeyName);
pKey->pszKeyName[cbKeyName / sizeof(WCHAR)] = L'\0';
}
else
{
pKey->pszKeyName = NULL;
}
if (globalRSAProviderHandle == NULL)
{
ntStatus = BCryptOpenAlgorithmProvider(
&globalRSAProviderHandle,
BCRYPT_RSA_ALGORITHM,
NULL,
0);
if (!NT_SUCCESS(ntStatus))
{
return NormalizeNteStatus(ntStatus);
}
}
pKey->hProvider = globalRSAProviderHandle;
pKey->pbKeyFile = NULL;
pKey->cbKeyFile = 0;
pKey->pbPrivateKey = NULL;
pKey->cbPrivateKey = 0;
pKey->hPublicKey = NULL;
pKey->hPrivateKey = NULL;
pKey->dwExportPolicy = NCRYPT_ALLOW_EXPORT_FLAG | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
pKey->dwKeyUsagePolicy = NCRYPT_ALLOW_DECRYPT_FLAG | NCRYPT_ALLOW_SIGNING_FLAG;
pKey->pbSecurityDescr = NULL;
pKey->cbSecurityDescr = 0;
InitializeListHead(&pKey->PropertyList);
*ppKey = pKey;
pKey = NULL;
return ERROR_SUCCESS;
}
Somewhere in there must be the mistake leading to the various memory errors. But as I'm quite new to windows programming and c/c++ I just can't spot the point and can't find any documentation about the datastructure that windows expects for the NCRYTP_KEY_HANDLE.
Does anybody know more about this structure?
NCRYPT_KEY_HANDLE is just a pointer to a structure that you defined.
Windows itself doesn't care about this structure and expect that your provider knows how to work with it.
In KeyHandler::ReadPemCert you mixed legacy CryptoAPI and CNG API. Since you are implementing KSP you should use only CNG API (CryptImportPublicKeyInfoEx2).
DWORD error = NTE_FAIL;
BCRYPT_KEY_HANDLE hKey = NULL;
...
PCCERT_CONTEXT pcCertContext = CertCreateCertificateContext(X509_ASN_ENCODING, certAsDer, certAsDerLen);
if(!pcCertContext)
{
goto Exit;
}
if (!CryptImportPublicKeyInfoEx2(X509_ASN_ENCODING, &pcCertContext->pCertInfo->SubjectPublicKeyInfo, 0, nullptr, &hKey))
{
goto Exit;
}
/* Also you can export key and print out the result to make sure everything works
DWORD temp = 0;
status = BCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, nullptr, 0, &temp, 0);
if (status != ERROR_SUCCESS)
{
goto Exit;
}
std::vector<BYTE> key(temp);
status = BCryptExportKey(hKey, 0, BCRYPT_RSAPUBLIC_BLOB, key.data(), key.size(), &temp, 0);
if (status != ERROR_SUCCESS)
{
goto Exit;
}
for (auto const& i : key)
{
std::cout << std::hex << (int)i;
}
}
*/
keyHandle->fFinished = TRUE;
keyHandle->hPublicKey = hKey;
keyHandle->pszKeyBlobType = BCRYPT_RSAPUBLIC_BLOB;
erro = ERROR_SUCCESS;
Exit:
if(pcCertContext)
{
CertFreeCertificateContext(pcCertContext);
}
return error;

Creating new registry entries in vc++

I am trying to create new registry entries which copies the certain registry values from HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings. I am successfully able to create the new registry entries but the values and sub key are not copied.I am not able to figure out where I have done the mistake. Please help me out.below is my code:
#include<tchar.h>
#include<conio.h>
#include<Windows.h>
#include<Winreg.h>
#include<WinBase.h >
#include<TlHelp32.h>
#define MAX_PATH 1024
DWORD MigrateProxy;
DWORD ProxyEnable;
DWORD ProxyHTTP11;
LPWSTR AutoConfigURL=0;
LPWSTR ProxyServer=0;
LPWSTR ProxyOverride=0;
void CopyRegistryProxySettings(HKEY hKeyRoot, LPCWSTR Subkey, LPCWSTR ValueKey);
bool CreateNewRegistry(HKEY hKeyRoot);
void main()
{
bool bStatusFlag = false,bReadFlag=false,bWriteFlag=false;
LPCWSTR lpSubKey = L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings";
LPCWSTR lpValueName = L"AutoConfigURL";
CopyRegistryProxySettings(HKEY_CURRENT_USER, lpSubKey,lpValueName);
bStatusFlag = CreateNewRegistry(HKEY_CURRENT_USER);
//bWriteFlag = RestoreOlderRegistry()
getch();
}
void CopyRegistryProxySettings(HKEY hKeyRoot, LPCWSTR Subkey, LPCWSTR ValueKey)
{
HKEY hKey = NULL;
wchar_t buffer[MAX_PATH];
DWORD dwBufLen;
DWORD dwValue = 0;
DWORD dwDataSize = sizeof(DWORD);
memset(buffer, 0, sizeof buffer);
dwBufLen = MAX_PATH;
if ( ERROR_SUCCESS == RegOpenKeyEx(hKeyRoot, Subkey, 0, KEY_ALL_ACCESS , &hKey))
{
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"AutoConfigURL",NULL,NULL,(BYTE*)buffer,&dwBufLen))
{
AutoConfigURL = buffer;
memset(buffer, 0, sizeof buffer);
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyServer",NULL,NULL,(BYTE*)buffer,&dwBufLen))
{
ProxyServer = buffer;
memset(buffer, 0, sizeof buffer);
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyOverride",NULL,NULL,(BYTE*)buffer,&dwBufLen))
{
ProxyOverride = buffer;
memset(buffer, 0, sizeof buffer);
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"MigrateProxy",NULL,NULL,(LPBYTE)&dwValue,&dwDataSize))
{
MigrateProxy = dwValue;
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyEnable",NULL,NULL,(LPBYTE)&dwValue,&dwDataSize))
{
ProxyEnable = dwValue;
}
if(ERROR_SUCCESS == RegQueryValueEx(hKey,L"ProxyHttp1.1",NULL,NULL,(LPBYTE)&dwValue,&dwDataSize))
{
ProxyHTTP11 = dwValue;
}
}
}
bool CreateNewRegistry(HKEY hKeyRoot)
{
HKEY hKey;
if (RegCreateKeyEx(HKEY_CURRENT_USER, L"Software\\NewSettings\\Internet Settings", NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
{
RegSetValueEx(hKey, L"AutoConfigURL", NULL,REG_SZ,(BYTE*)AutoConfigURL, (DWORD)((lstrlen(AutoConfigURL)+1)*sizeof(TCHAR)));
RegSetValueEx(hKey, L"ProxyServer", NULL,REG_SZ,(BYTE*)ProxyServer, (DWORD)((lstrlen(ProxyServer)+1)*sizeof(TCHAR)));
RegSetValueEx(hKey, L"ProxyOverride", NULL,REG_SZ,(BYTE*)ProxyOverride, (DWORD)((lstrlen(ProxyOverride)+1)*sizeof(TCHAR)));
RegSetValueEx(hKey, L"MigrateProxy", NULL,REG_DWORD,(BYTE*)MigrateProxy, (DWORD)sizeof(MigrateProxy));
RegSetValueEx(hKey, L"ProxyEnable", NULL,REG_DWORD,(BYTE*)ProxyEnable, (DWORD)sizeof(ProxyEnable));
RegSetValueEx(hKey, L"ProxyHTTP1.1", NULL, REG_DWORD,(BYTE*)ProxyHTTP11, (DWORD)sizeof(ProxyHTTP11));
}
return 1;
}

c++ check installed programms

How do I list all programs installed on my computer? I've tried using the MsiEnumProducts and MsiGetProductInfo functions, but they do not return a full list of installed applications like I see in "Add/Remove Programs".
Enumerate the registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
bool EnumInstalledSoftware(void)
{
HKEY hUninstKey = NULL;
HKEY hAppKey = NULL;
WCHAR sAppKeyName[1024];
WCHAR sSubKey[1024];
WCHAR sDisplayName[1024];
WCHAR *sRoot = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
long lResult = ERROR_SUCCESS;
DWORD dwType = KEY_ALL_ACCESS;
DWORD dwBufferSize = 0;
//Open the "Uninstall" key.
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, sRoot, 0, KEY_READ, &hUninstKey) != ERROR_SUCCESS)
{
return false;
}
for(DWORD dwIndex = 0; lResult == ERROR_SUCCESS; dwIndex++)
{
//Enumerate all sub keys...
dwBufferSize = sizeof(sAppKeyName);
if((lResult = RegEnumKeyEx(hUninstKey, dwIndex, sAppKeyName,
&dwBufferSize, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
{
//Open the sub key.
wsprintf(sSubKey, L"%s\\%s", sRoot, sAppKeyName);
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, sSubKey, 0, KEY_READ, &hAppKey) != ERROR_SUCCESS)
{
RegCloseKey(hAppKey);
RegCloseKey(hUninstKey);
return false;
}
//Get the display name value from the application's sub key.
dwBufferSize = sizeof(sDisplayName);
if(RegQueryValueEx(hAppKey, L"DisplayName", NULL,
&dwType, (unsigned char*)sDisplayName, &dwBufferSize) == ERROR_SUCCESS)
{
wprintf(L"%s\n", sDisplayName);
}
else{
//Display name value doe not exist, this application was probably uninstalled.
}
RegCloseKey(hAppKey);
}
}
RegCloseKey(hUninstKey);
return true;
}

Resources