Hello,
I know how to enumerate keys and values, but i want to load the whole registry into an array.
Is there any source code out there? Or can someone give me some advice on how I can do this?
Thanks
Simon Canning
Printable View
Hello,
I know how to enumerate keys and values, but i want to load the whole registry into an array.
Is there any source code out there? Or can someone give me some advice on how I can do this?
Thanks
Simon Canning
By using the RegEnumKey() api call, you can do a complete walk-thru on the whole registry database, by enumerating each subkeys in all depth. But this may takes for a pretty long time (for an older than 1 year windows installation, it may take for 10-20 minutes).
To make a smart application, you can get the Regedit.exe design, where it is enumerates a subkey only, when the user opens the actual subkey.
Another way would be to shellexecute the regedit.exe passing the proper switches to export thte entire regiustry to a text file. Then read the file in and plit it to an array. Just food for thought ;)
'By using the RegEnumKey() api call, you can do a complete walk-thru on the whole registry database'
By this, do you mean a recursive search with a do loop? If so, can you give me some advice on how to declare/load the array?
By this, do you mean you can enumerate subkeys, or you just meant you can read out a specific key you know its path and key name? :)Quote:
I know how to enumerate keys and values
Put this into a module.
vb Code:
Option Explicit Private Declare Function RegEnumKey Lib "advapi32.DLL" Alias "RegEnumKeyA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpName As String, ByVal cbName As Long) As Long Private Declare Function RegOpenKey Lib "advapi32.DLL" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long Private Declare Function RegCloseKey Lib "advapi32.DLL" (ByVal hKey As Long) As Long Public Enum regPredefinedKey HKEY_CLASSES_ROOT = &H80000000 HKEY_CURRENT_USER = &H80000001 HKEY_LOCAL_MACHINE = &H80000002 HKEY_USERS = &H80000003 End Enum Function CollectSubKeys(RegPos As regPredefinedKey, sRegPos As String, ByRef Ary) As Boolean Dim Res As String Dim i As Long Res = ReadRegistryGetSubkey(RegPos, sRegPos, i) ReDim Ary(0) Do Until Res = "Not Found" ReDim Preserve Ary(UBound(Ary) + 1) Ary(UBound(Ary)) = Res CollectSubKeys = True i = i + 1 Res = ReadRegistryGetSubkey(RegPos, sRegPos, i) Loop End Function Public Function ReadRegistryGetSubkey(ByVal Group As Long, ByVal Section As String, Idx As Long) As String Dim lResult As Long, lKeyValue As Long, lDataTypeValue As Long, lValueLength As Long, sValue As String, td As Double On Error Resume Next lResult = RegOpenKey(Group, Section, lKeyValue) sValue = Space$(2048) lValueLength = Len(sValue) lResult = RegEnumKey(lKeyValue, Idx, sValue, lValueLength) If (lResult = 0) And (Err.Number = 0) Then sValue = Left$(sValue, InStr(sValue, Chr(0)) - 1) Else sValue = "Not Found" End If lResult = RegCloseKey(lKeyValue) ReadRegistryGetSubkey = sValue End Function
You can call it by this way:
This will do the job for you!Code:Dim sValues() As String, I As Long
Module1.CollectSubKeys HKEY_LOCAL_MACHINE, "Software", sValues
For I = LBound(sValues) To UBound(sValues)
Debug.Print sValues(I)
Next Z
OK, this lists all the sub keys under 'Software.' I want to list all these values as well as all the sub keys under the 'Software' sub key. (All values basically)
Does this make sense...? not sure how to word it.
You have to recursive call this function. Replace all occurences of "Not Found" to chr$(0), in the registry functions (CollectSubKeys,ReadRegistryGetSubkey) , that will help you to NOT display the "Not Found" text, in case a key have no more subkeys.
This is a recursive call will walk thru for the latest depth, in all subkeys. You can see that the GetVals sub will call itself as long as the results are valid.Code:Sub GetVals(MasterKey As regPredefinedKey, KeyName As String)
Dim sValues() As String, I As Long
CollectSubKeys MasterKey, KeyName, sValues
For I = LBound(sValues) To UBound(sValues)
If Not sValues(i) = Chr$(0) Then Call GetVals(MasterKey, KeyName & "\" & sValues(i))
'Avoid to calling illegal string.
Next Z
End Sub
Edit:
Oops, a small fix, i included the KeyName, that is was missing.
I doubt that loading the registry into arrays is going to be as easy as you think. For instance, how would you store the values in the arrays? In their intended format of Longs, Binary byte arrays, Strings etc, bearing in mind that you would have to create and re-dimension multi-dimensional arrays on the fly?, as byte arrays? as comma or space delimited byte strings? How would you even know where the values were without an index?
Also bear in mind that any copy of the registry loaded into memory is liable to be made obsolete almost immediately as other programs access the hard disk registry files.
If you let us know what you are trying to acheive, we may be able to point out alternatives.
EDIT: Also, what about the hives of users that are not currently logged on ?
@schoolbusdriver is right. In my previos post i mentioned to get the desing of Regedit.exe that is using some ListView control, to displaying the Registry tree. But, it only displaying the part of the tree the user opening, so, the user is opens a node, the program will load the subkeys of one level that are belongs to that node, but nothing else. You can also check the displayed results, to have any subkeys or not, but you dont have to roll down all their subkeys, but only the first occurence, that is fairly enough to display the (+) node next to the subkey entry.
Edit: i made a small fix on my previos post, i have included the KeyName that was missing. Now you can follow the indexing, since KeyName will always stands for the Path for each subkeys.
Schoolbusdriver: I am wanting to make an application that detects changes made to the registry and filesystem.
Basically, I will create an listing of the registry, get the user to install the test application, create another listing of the registry and compare the two listings and display the changes.
Jim Davis: I get an error on the line of code:
If Not sValues(i) = Chr$(0) Then GetVals(MasterKey, KeyName & "\" & sValues(i))
I think the syntax is wrong.. but cant find out how to fix it... pls help.
Also, can you give me an example on how to use the sub 'GetVals'. eg What do i set the values MasterKey and KeyName to when I load the sub.
Just wondering, how does regedit do its export?
Done a little bit of research. Is it true that many registry keys will constantly be updated while windows is running... making this application of mine useless\unreasonable?
Registry keys get constantly updated. Even clicking on a start menu item will add it to a "recent" list somewhere. There are also sections in the registry that are hidden even from admins - your program would have to run under the "System" account to access these.
Most freeware/shareware registry comparison tools don't work by loading the registry into memory. They take 2 snapshots of the registry and save them to HDD, then compare the 2 files. You can do this with regedit.
My own experience with registry comparators is that you have to sort the wheat from the chaff during analysis. It definitely needs the human touch.
EDIT: Just a note to point out that regedit exports REG_MULTI_SZ strings in REG_NONE or REG_BINARY format.
You may also like to take a look at the Registry API functions, in particular the RegNotifyChangeKeyValue API (http://msdn.microsoft.com/en-us/libr...92(VS.85).aspx)
... Then Call GetVals(MasterKey, KeyName & "\" & sValues(I))
Simon, that is @schoolbusdriver says is absolutely true, it makes no sense to constantly reading the registry thru api calls, that will does a huge amount of continous processing, will makes the system to slowing down.
There is a process called 'System' (ctrl+shift+esc), in the processes tab, that is have exclusive file lock on each registry file. I'm not sure how you can open up this lock to access the files, you cant copy, or open them, thru simple file operations via administrator privileges.
i'm affraid that it is a quite advanced api knowledge will needed, to monitor the registry.
@Doogle: wow nice catch, i dont ever saw this api call. :) However monitoring each registry entry seems almost impossible to setting up.
Notwithstanding Jim's and the other comments, the 'advantage' of using the Notify function is that it can run asynchronously and raise an event when a monitored key / sub key is changed, which minimises the overhead. However, bearing in mind the limitations of VB and multi-threading, the implementation can be quite problematic.
I developed an application using the API and solved the problem by having two programs; one was waiting for a Key change to happen and when it did it communicated (I used Winsock) to another application with the details. It worked quite well. I was specifically looking at the Run and RunOnce keys to monitor if anything was attempting to alter the start up processes.
@Doogle: the LocalMachine/.../CurrentVersion/RunServices also a startup point, just like the explorer extensions (that i'm not sure where it is contained), but some trojans will startup from the C:\documents and settings\All user\Startmenu\Startup.
Yes, I never completed the project because I didn't understand enough about the Registry to monitor all the correct keys. However, it was a useful academic exercise.
EDIT: .... and, of course, by the time you've received the notification, it's too late - the change has happened. I wanted to trap an attempt to change and then allow / deny and, I guess, some quite low level code would be required for that !
Perhaps I shouldn't mention it - I'll delete this comment if anyone thinks it unwise - but it's possible to create hidden values in the "run" etc subkeys that windows executes without quibbling. A monitor shows nothing.Quote:
Originally Posted by Doogle
RegNotifyChangeKeyValue returns a blizzard of subkey change notifications when watching a value in the root of HKCU, just by scrolling through "Start" menu submenus. It's good for watching a single item, but I think the OP wanted to compare the entire registry.
schoolbusdriver: - it's possible to create hidden values in the "run" etc subkeys that windows executes without quibbling. A monitor shows nothing.
This is quite interesting. I would like to test this out if possible... can you give me a tutorial or some sample code to look at this? If you are worried out hackers/virus creators viewing this post, could you maybe email me the info?
thanks
OK, rather than showing me how to do it... is there an application out there to detect these hidden values?
Also, another question. Is this a flaw in Vista as well as XP?
As you can imagine, I don't want the code public. I initially found this by way of a completely unrelated mistake and tested it elsewhere out of curiosity. Luckily, AFAIK, no software (except a test app on my PC), legit or otherwise, is built to use or detect this. It's best kept that way. I recall testing this on Vista last winter with the same results. The jury's still out on Windows 7.
A saving grace about this is that the values don't get exported by regedit, so subkeys can be exported to a .reg file, deleted (in regedit) and reimported to remove them.
I have a question similar to this: How do I build an array with ALL the keys in the registry and then search through all these keys for a specific value? Does anyone have a code sample? Thank you.