-1

I have to extract hive from registry key and registry name so that I can open the key in regopen

Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\Firefox

I have to extract HKEY_LOCAL_MACHINE and Software\Mozilla\Firefox

Is there any API to extract them as wstring?

wstring keyname = L"HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\Firefox";
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
cc125
  • 13
  • 1
  • 5
  • With winapi registry I/O, things are more involved than just a simple call to an appropriate function. I suggest exploring the relevant [MSDN articles](https://learn.microsoft.com/en-us/windows/win32/sysinfo/registry). – Ron Jun 11 '20 at 14:08
  • Does this answer your question? [Determine path to registry key from HKEY handle in C++](https://stackoverflow.com/questions/937044/determine-path-to-registry-key-from-hkey-handle-in-c) – Simon Mourier Jun 11 '20 at 14:42
  • @SimonMourier Unfortunately no,I want to extract HKLM and key name to use it in regsavekey – cc125 Jun 11 '20 at 14:44
  • What you you have exactly, eg: what do you mean by "registry key"? (handle? path?) and what do you want exactly? – Simon Mourier Jun 11 '20 at 14:47
  • wstring keyname=L"HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\Firefox" I have this,I have to extract HKEY_LOCAL_MACHINE as hive and Software\Mozilla\Firefox asa wstring – cc125 Jun 11 '20 at 14:52
  • @cc125 "*I have to extract HKEY_LOCAL_MACHINE as hive*" - what does that mean to you exactly? Please clarify. "*and Software\Mozilla\Firefox as a wstring*" - ??? You are not making any sense. What EXACTLY are you trying to accomplish? What is the goal? – Remy Lebeau Jun 11 '20 at 16:19
  • @RemyLebeau I have a function which takes hive as parameter ,registry name as parameter, so before giving to the function I need to extract hive string (in this case HKLM) and key name – cc125 Jun 11 '20 at 16:21
  • @cc125 that doesn't answer my question at all. What does a "hive string" refer to? Please show the actual code you are having trouble with, and explain what you are trying to accomplish with that code. – Remy Lebeau Jun 11 '20 at 16:22
  • @RemyLebeau Hive I meant HKLM or HKCU to extract from complete key name for ex:I need to split HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\Firefox into HKEY_LOCAL_MACHINE and SOFTWARE\Mozilla\Firefox – cc125 Jun 11 '20 at 16:24
  • @cc125 so, your question is just about how to parse **a string** into constituent **substrings**? That has *nothing* to do with the Registry API. Simply find the 1st ```\``` character and split the string on that. Tons of functions available to do that. Even `wstring` has its own methods for that (`find()` and `substr()`) – Remy Lebeau Jun 11 '20 at 16:27
  • @RemyLebeau I know about find and substr,I was looking for any windows api if any – cc125 Jun 11 '20 at 16:28
  • @cc125 "*I was looking for any windows api if any*" - there are no Win32 API functions for the particular purpose you are asking for. But the C and C++ runtimes have such functions, like `strtok()` and `std::getline()` and equivilents. This task is too trivial for Microsoft to waste making a dedicated API for when the work is already done by the core languages. – Remy Lebeau Jun 11 '20 at 18:20

1 Answers1

0

If I understand you correctly, you just want to split the string "HKEY_LOCAL_MACHINE\SOFTWARE\Mozilla\Firefox" into substrings "HKEY_LOCAL_MACHINE" and "SOFTWARE\Mozilla\Firefox". There are no Win32 API functions for that exact purpose, but you can use the find() and substr() methods of C++'s std::wstring class, eg:

#include <string>

std::wstring keyname = ...; // "HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Firefox"

std::wstring::size_type pos = keyname.find(L'\\');
if (pos != std::wstring::npos)
{
    std::wstring root = keyname.substr(0, pos);
    std::wstring key = keyname.substr(pos+1);
    // use root and key as needed...
}

Alternative, you can use std::wistringstream and std::getline():

#include <string>
#include <sstream>

std::wstring keyname = ...; // "HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Firefox"
std::wstring root, key;

std::wistringstream iss(keyname);
if (std::getline(iss, root, L'\\') && std::getline(iss, key))
{
    // use root and key as needed...
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • You seem to the expert in registry,I have one question in continutation of this can RegSaveKey be used other than administrators.When using for a current user Error code: 1314 Description: A required privilege is not held by the client. – cc125 Jun 12 '20 at 14:58
  • Thanks for looking into.I checked the question and I am actually using this logic https://www.codeproject.com/Articles/7874/How-to-Save-and-Restore-Registry-Keys It works for administrators but does not work for users even to save his own HKCU registries – cc125 Jun 12 '20 at 17:32
  • @cc125 As that article and MSDN documentation both state, the caller needs the `SE_BACKUP_NAME` privilege to use `RegSaveKey()`, and `SE_RESTORE_NAME` and `SE_BACKUP_NAME` to use `RegRestoreKey()`. Non-admins simply do not have that privilege available to them by default. So you MUST run your backup code under a user account that does. Whether that be an admin, or a non-admin whose security rights have been tweaked, that is up to you to decide. That is just how the API works. Otherwise, you will have to save+restore your desired Registry keys manually, then you will have fewer restrictions. – Remy Lebeau Jun 12 '20 at 17:58
  • ANy other alternative apart from reg export and import ,RegSaveKey and RegRestoreKey to preserve registries and restore – cc125 Jun 12 '20 at 18:34
  • @cc125 you mean, other than simply reading the keys yourself and writing your own file? And then reading your file and writing to the keys? Not really. – Remy Lebeau Jun 12 '20 at 19:13
  • The issue is registry tools are disabled in the machine,so no option to use reg.exe,also regsavekey will not work for other users than administrator,is there any other option? I searched and seached,didn't find solution yet – cc125 Jun 13 '20 at 16:51
  • @cc125 I already told you what you need to do. I'm not going to repeat myself. – Remy Lebeau Jun 13 '20 at 18:20
  • I am trying to use RegCopyTree to backup,however I see subkeys not getting copied,any idea whats going wrong ``` if (RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\S\\r"), 0, NULL, 0, KEY_ALL_ACCESS, 0, &deletekey,NULL) == ERROR_SUCCESS) { } if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\S\\r"), 0, NULL, 0, KEY_ALL_ACCESS, 0, &deletekey1, NULL) == ERROR_SUCCESS) { } long copykey=RegCopyTree(deletekey, TEXT("HKEY_CURRENT_USER\\SOFTWARE\\S\\r"), deletekey1); – cc125 Jun 22 '20 at 19:51
  • I had manually created subkey under r,but that didn't get copied – cc125 Jun 22 '20 at 19:52
  • @cc125 You are leaking `HKEY`s from `RegCreateKeyEx()`, and not handling failures to open the keys. More importantly, the string value you are passing to `RegCopyTree()` is completely wrong. Read the [documentation](https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regcopytreea) more carefully: "*This key must be **a subkey of the key identified by the `hKeySrc` parameter**. This parameter can also be NULL.*" `"HKEY_CURRENT_USER\\SOFTWARE\\S\\r"` does not identify a subkey underneath `HKEY_CURRENT_USER\SOFTWARE\S\r`. Since you opened `r` directly, pass `NULL` instead. – Remy Lebeau Jun 22 '20 at 20:01
  • @cc125 Or better, get rid of the 1st `RegCreateKeyEx()` altogether: `if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\S\\r"), 0, NULL, 0, KEY_ALL_ACCESS, 0, &destKey, NULL) == ERROR_SUCCESS) { long copykey = RegCopyTree(HKEY_CURRENT_USER, TEXT("SOFTWARE\\S\\r"), destKey); RegCloseKey(destKey); }` – Remy Lebeau Jun 22 '20 at 20:04
  • For my same initial question,instead of wstring I have to save root as Hkey,wcsstr(szKey.c_str(), L"HKEY_CURRENT_USER")) HKEY hkey=HKEY_CURRENT_USER,is there a better method to get root as hkey? – cc125 Jun 26 '20 at 14:58
  • @cc125 there is no API to convert a string representation of a predefined key into its corresponding `HKEY` handle. You have to do that manually. – Remy Lebeau Jun 26 '20 at 17:18
  • Thanks,so is this method ok?wcsstr(szKey.c_str(), L"HKEY_CURRENT_USER")) HKEY hkey=HKEY_CURRENT_USER, – cc125 Jun 26 '20 at 18:30
  • @cc125 I would use `if (szKey == L"HKEY_CURRENT_USER")` instead. – Remy Lebeau Jun 26 '20 at 21:26
  • szkey contains complete key name HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Firefox – cc125 Jun 27 '20 at 04:40
  • @cc125 you should split it first, like I showed you in reply to your original question. Registry functions need a root `HKEY`and a relative `subkey` string. – Remy Lebeau Jun 27 '20 at 10:46
  • I followed yours suggestion to split into wstring,as I wanted hive as hkey and wstring both – cc125 Jun 27 '20 at 11:14