Code archives/Miscellaneous/Registry Module

This code has been declared by its author to be Public Domain code.

Download source code

Registry Module by skn32007
Example1:
Adding some stuff
Local temp:tregkey = OpenRegKey("HKEY_CLASSES_ROOT\hello\there\how\are\you")
If temp
	temp.setint("time",MilliSecs())
	temp.setlong("somevalue",12345678910111213)
	temp.setstring("name","peter griffin")
	temp.close()'will automatically close with garbage collector but do this anyway
End If


Example2:
deleting a key recursively
Local temp:tregkey = OpenRegKey("HKEY_CLASSES_ROOT\hello\there\how\are\you")
If temp
	'delete recursively (all sub values and keys get removed)
	temp.remove(true)
End If
Strict

Import "-ladvapi32"

Extern "win32"
	Function _RegCreateKeyEx:Int(key:Int,subkey$z,reserved:Int,class$z,options:Int,desired:Int,securityattributes:Byte Ptr,result:Byte Ptr,disposition:Byte Ptr)="RegCreateKeyExA@36"
	Function _RegOpenKeyEx:Int(key:Int,subkey$z,options:Int,desired:Int,result:Byte Ptr) = "RegOpenKeyExA@20"
	Function _RegCloseKey:Int(key:Int) = "RegCloseKey@4"
	Function _RegSetValueEx:Int(key:Int,valuename$z,reserved:Int,dwtype:Int,data:Byte Ptr,datasize:Int) = "RegSetValueExA@24"
	Function _RegQueryValueEx:Int(key:Int,valuename$z,reserved:Int,lptype:Byte Ptr,data:Byte Ptr,datasize:Byte Ptr) = "RegQueryValueExA@24"
	Function _RegDeleteValue:Int(key:Int,valuename$z) = "RegDeleteValueA@8"
	Function _RegDeleteKey:Int(key:Int,subkey$z) = "RegDeleteKeyA@8"
	Function _RegEnumKeyEx:Int(key:Int,index:Int,name:Byte Ptr,namesize:Byte Ptr,reserved:Int,class$z,classsize:Byte Ptr,lastwritetime:Byte Ptr) = "RegEnumKeyExA@32"
EndExtern

'win32 constants
Const HKEY_CLASSES_ROOT:Int = 2147483648
Const HKEY_CURRENT_USER:Int = 2147483649
Const HKEY_LOCAL_MACHINE:Int = 2147483650
Const HKEY_USERS:Int = 2147483651

Const REG_OPTION_NON_VOLATILE:Int = 0

Const ERROR_NO_MORE_ITEMS:Int = 259

Const KEY_QUERY_VALUE:Int = 1
Const KEY_SET_VALUE:Int = 2
Const KEY_CREATE_SUB_KEY:Int = 4
Const KEY_ENUMERATE_SUB_KEYS:Int = 8

Const REG_CREATED_NEW_KEY:Int = 1
Const REG_OPENED_EXISTING_KEY:Int = 2

Const REG_SZ:Int = 1
Const REG_DWORD:Int = 4
Const REG_QWORD:Int = 11

'types
Type tregkey
	'fields
	Field root:Int
	Field handle:Int = 0
	Field path:String

	'methods
	Method Delete:Int()
		'close the reg key
		close()
	End Method
		
	Method removevalue:Int(nname:String)
		'delete a value regardless of type
		If handle And _RegDeleteValue(handle,nname) = 0
			'return value deleted
			Return True
		End If
		
		'return value not deleted
		Return False
	End Method
	
	Method remove:Int(nrecurse:Int = False)
		'removes itself from the registry
		If nrecurse
			'recurse key and delete all sub keys and values
			If handle And tregkey.Remove_Recurse(root,path)
				close()
				'return key deleted
				Return True
			End If
		Else
			'delete key
			If handle And _RegDeleteKey(handle,path) = 0
				close()
				'return key deleted
				Return True
			End If
		End If
		
		'return key not deleted
		Return False
	End Method
	
	Method getint:Int(nname:String)
		'get an int
		Local temp_type:Int
		Local temp_size:Int = 4
		Local temp_value:Int
		
		If handle And _RegQueryValueEx(handle,nname,0,Varptr(temp_type),Null,Null) = 0 And temp_type = REG_DWORD And _RegQueryValueEx(handle,nname,0,Null,Varptr(temp_value),Varptr(temp_size)) = 0
			'return value
			Return temp_value
		End If
		
		'return false if no value (can be decieving though as false is also 0)
		Return False
	End Method
	
	Method getlong:Int(nname:String)
		'get an int
		Local temp_type:Int
		Local temp_size:Int = 8
		Local temp_value:Long
		
		If handle And _RegQueryValueEx(handle,nname,0,Varptr(temp_type),Null,Null) = 0 And temp_type = REG_QWORD And _RegQueryValueEx(handle,nname,0,Null,Varptr(temp_value),Varptr(temp_size)) = 0
			'return value
			Return temp_value
		End If
		
		'return false if no value (can be decieving though as false is also 0)
		Return False
	End Method
	
	Method getstring:String(nname:String)
		'get an int
		Local temp_type:Int
		Local temp_size:Int
		Local temp_value:String
		Local temp_cstring:Byte Ptr
		
		If handle And _RegQueryValueEx(handle,nname,0,Varptr(temp_type),Null,Varptr(temp_size)) = 0 And temp_type = REG_SZ
			'create a buffer to recieve the string
			temp_cstring = MemAlloc(temp_size)
			'retrieve the string
			If _RegQueryValueEx(handle,nname,0,Null,temp_cstring,Varptr(temp_size))
				'free created c string
				MemFree(temp_cstring)
				Return ""
			End If
			
			'convert c string to string
			temp_value = String.FromCString(temp_cstring)
			
			'free created c string
			MemFree(temp_cstring)
			
			'return value
			Return temp_value
		End If
		
		'return false if no value (can be decieving though as false is also "")
		Return ""
	End Method

	Method setint:Int(nname:String,nvalue:Int)
		'set an int
		If handle And _RegSetValueEx(handle,nname,0,REG_DWORD,Varptr(nvalue),4) = 0
			'return int set
			Return True
		End If
		
		'return int not set
		Return False
	End Method
	
	Method setlong:Int(nname:String,nvalue:Long)
		'set a long
		If handle And _RegSetValueEx(handle,nname,0,REG_QWORD,Varptr(nvalue),8) = 0
			'return long set
			Return True
		End If
		
		'return long not set
		Return False
	End Method
	
	Method setstring:Int(nname:String,nvalue:String)
		'set a string
		Local temp_cstring:Byte Ptr = nvalue.tocstring()
		If handle And _RegSetValueEx(handle,nname,0,REG_SZ,temp_cstring,nvalue.length) = 0
			'free teh created c string
			MemFree(temp_cstring)
			'return string set
			Return True
		End If
		
		'return string not set
		'free the created c string
		MemFree(temp_cstring)
		Return False
	End Method
	
	Method close:Int()
		'close the reg key
		If handle And handle <> HKEY_CLASSES_ROOT And handle <> HKEY_CURRENT_USER And handle <> HKEY_LOCAL_MACHINE And handle <> HKEY_USERS
			_RegCloseKey(handle)
		End If
		handle = 0
	End Method
	
	
	'functions
	Function Remove_Recurse:Int(nroot:Int,npath:String)
		Local temp_result:Int
		Local temp_index:Int = 0
		Local temp_cstring:Byte Ptr
		Local temp_cstringsize:Int = 255
		Local temp_path:String
	
		'try to delete the key without recursing
		If _RegDeleteKey(nroot,npath) = 0
			Return True
		End If
		
		'open the key for recursing
		If _RegOpenKeyEx(nroot,npath,0,KEY_QUERY_VALUE | KEY_CREATE_SUB_KEY | KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS,Varptr(temp_result)) = 0
			'create c string
			temp_cstring = MemAlloc(temp_cstringsize)
			'recurse the keys keys
			While _RegEnumKeyEx(temp_result,temp_index,temp_cstring,Varptr(temp_cstringsize),Null,Null,Null,Null) = 0
				temp_path = npath
				If temp_path.length temp_path :+ "\"
				temp_path :+ String.FromCString(temp_cstring)
				tregkey.Remove_Recurse(nroot,temp_path)
				temp_index :+ 1
				temp_cstringsize = 255
			Wend
			'close the key
			_RegCloseKey(temp_result)
			'free the cstring
			MemFree(temp_cstring)
		End If
		
		'try to delete key again
		If _RegDeleteKey(nroot,npath) = 0
			Return True
		End If
		
		Return False
	End Function
	
	Function PredefinedKey:Int(nroot:String)
		Select nroot
			Case "HKEY_CLASSES_ROOT"
				Return HKEY_CLASSES_ROOT
			Case "HKEY_CURRENT_USER"
				Return HKEY_CURRENT_USER
			Case "HKEY_LOCAL_MACHINE"
				Return HKEY_LOCAL_MACHINE
			Case "HKEY_USERS"
				Return HKEY_USERS
		End Select
		Return 0
	End Function
	
	Function ExtractSegments:String[](npath:String)
		Local temp_segments:String[]
		Local temp_count:Int
		Local temp_pos:Int
		Local temp_segment:String
		Local temp_subpos:Int
		Local temp_subsegment1:String
		Local temp_subsegment2:String
		
		'fix forward slashes
		npath = npath.replace("/","\")
		
		temp_pos = npath.find("\")
		While temp_pos <> -1
			'extract the segment
			temp_segment = npath[..temp_pos]
			If temp_segment.length
				'resize segment array
				temp_segments = temp_segments[..temp_count+1]
				
				'set segment
				temp_segments[temp_count] = temp_segment
				
				'increase segment count
				temp_count :+ 1
			End If
			
			npath = npath[temp_pos+1..]
			temp_pos = npath.find("\")
		Wend
		'add last
		temp_segment = npath
		If temp_segment.length
			'resize segment array
			temp_segments = temp_segments[..temp_count+1]
			
			'set segment
			temp_segments[temp_count] = temp_segment
			
			'increase segment count
			temp_count :+ 1
		End If
		
		Return temp_segments
	End Function
End Type

Function CreateRegKey:tregkey(npath:String)
	Local temp_regkey:tregkey
	Local temp_segments:String[] = tregkey.ExtractSegments(npath)
	Local temp_root:Int
	Local temp_path:String
	Local temp_key:String
	Local temp_index:Int
	Local temp_result:Int
	Local temp_disposition:Int
	
	If temp_segments.length > 1
		'get root
		temp_root = tregkey.PredefinedKey(temp_segments[0])
		
		'get path
		If temp_segments.length > 2
			For temp_index = 1 Until temp_segments.length-1
				If temp_path.length temp_path :+ "\"
				temp_path :+ temp_segments[temp_index]
			Next
		End If
		
		'get key
		temp_key = temp_segments[temp_segments.length-1]
		
		'create the key
		If _RegCreateKeyEx(temp_root,temp_path+"\"+temp_key,0,"",REG_OPTION_NON_VOLATILE,KEY_QUERY_VALUE | KEY_CREATE_SUB_KEY | KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS,Null,Varptr(temp_result),Varptr(temp_disposition)) = 0
			'create the reg key
			temp_regkey = New tregkey
			temp_regkey.root = temp_root
			temp_regkey.handle = temp_result
			temp_regkey.path = temp_path+"\"+temp_key
		End If
		
		'return the reg key
		Return temp_regkey
	End If
	
	Return Null
End Function

Function OpenRegKey:tregkey(npath:String)
	Local temp_regkey:tregkey
	Local temp_segments:String[] = tregkey.ExtractSegments(npath)
	Local temp_root:Int
	Local temp_path:String
	Local temp_key:String
	Local temp_index:Int
	Local temp_result:Int
	
	If temp_segments.length > 1
		'get root
		temp_root = tregkey.PredefinedKey(temp_segments[0])
		
		'get path
		If temp_segments.length > 2
			For temp_index = 1 Until temp_segments.length-1
				If temp_path.length temp_path :+ "\"
				temp_path :+ temp_segments[temp_index]
			Next
		End If
		
		'get key
		temp_key = temp_segments[temp_segments.length-1]
		
		If _RegOpenKeyEx(temp_root,temp_path+"\"+temp_key,0,KEY_QUERY_VALUE | KEY_CREATE_SUB_KEY | KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS,Varptr(temp_result)) = 0
			'create regkey instance
			temp_regkey = New tregkey
			temp_regkey.root = temp_root
			temp_regkey.handle = temp_result
			temp_regkey.path = temp_path+"\"+temp_key
			
			Return temp_regkey
		End If
	End If
End Function

Comments

CASO2007
AWESOME!

I actually didn't expect it to work because things of these sorts have been floating around for some time, but YOU DID IT. I am actually still learning the language, but this was SO SIMPLE. Open...Create...Set...Get... it don't get any simpler.


skn32007
:) I know what you mean. This should kinda be native in the language...


Filax2007
Here is an example of filetype creation, very usefull
module, many thanks to share !




Sub_Zero2010
I've added a "Enumerate" function to the module, so you can parse subkeys from the registry...




ImaginaryHuman2010
Great work, this really helps me out a lot, thank you!


ImaginaryHuman2010
Does anyone know if accessing the registry is going to throw up lots of security warnings, virus checkers
complaining etc?

After testing this it is working great for me. Just a note for others, if there is a folder that you want to put values into, like you want to put something in HKEY_CURRENT_USER\Software\MySoftwareName and if that folder doesn't exist already, trying to ADD keys to it will do nothing. You have to create the MySoftwareName folder first (and any others) before you add keys. I kept wondering why my keys weren't showing up with `add` and then I realized it's because the folder wasn't getting created by `open`. Gotta `create` instead.

I did not see any complaint from Kaspersky antivirus so far.... it has a registry monitor but it only looks at special parts of the registry like internet and security stuff, etc... so hopefully should be fine.


ImaginaryHuman2010
Just a note... in the `GetLong()` method, you have the function defined as returning an int but really it should be returning a Long? I changed it to :Long for me. Looks like the number of bytes in there is 8 so it seems to make sense. Let me know if it's not.

Also in your method `GetString()`, it looks fine but your initial comment is `get an int` but it really should say `get a string`. :-)


BODYPRINT2014
Awesome module.
Thanks for this :)


Fielder2015
anyone can make a 64bit capable version?


Code Archives Forum