adding registration keys

BlitzMax Forums/BlitzMax Programming/adding registration keys

A new version with filetype creation and deletion

Note : Any ideas to set and get binary data ?

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

' -------------
' Registry Type
' -------------
Type Tregkey
	Field root:Int
	Field handle:Int = 0
	Field path:String

	Method Delete:Int()
		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 the 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()
		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 to create registry key
' -------------------------------
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 to open reg key
' ------------------------
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

' -----------------------------
' Function to create a filetype
' -----------------------------
Function CreateFileType(Filext:String,Path:String)
	Local Temp:Tregkey
	
	' --------------
	' Key number one
	' --------------
	Temp= CreateRegKey("HKEY_CLASSES_ROOT\."+Filext)

	If Temp
		Temp.setstring("",Filext+"_auto_file")
	End If	

	' --------------
	' Key number two
	' --------------	
	Temp= CreateRegKey("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\."+Filext)
	
	If Temp Then
		Temp.setstring("","") 
	EndIf
	
	' ----------------
	' Key number three
	' ----------------
	Temp= CreateRegKey("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\."+Filext+"\OpenWithList")
	
	If Temp Then
		Temp.setstring("a",Path) 
	EndIf

	' ---------------
	' Key number four
	' ---------------
	Temp= CreateRegKey("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\."+Filext+"\OpenWithProgids")
	
	If Temp Then
		Temp.setint(Filext+"_auto_file",0) 
	EndIf
	
	' ---------------
	' Key number five
	' ---------------
	Temp = CreateRegKey("HKEY_LOCAL_MACHINE\SOFTWARE\Classes\."+Filext)
	
	If Temp
		Temp.setstring("",Filext+"_auto_file")
	End If	
	
	Temp.close()	
End Function

' -----------------------------
' Function to delete a filetype
' -----------------------------
Function DeleteFileType(Filext:String)
	Local Temp:Tregkey

	' --------------
	' Key number one
	' --------------
	Temp= OpenRegKey("HKEY_CLASSES_ROOT\."+Filext)

	If Temp
		Temp.remove(True) ; Print "Registry debug : Key 1 removed..."
	End If
	
	' --------------
	' Key number two
	' --------------	
	Temp= OpenRegKey("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\."+Filext)
	
	If Temp Then
		Temp.remove(True) ; Print "Registry debug : Key 2 removed..."
	EndIf

	' ----------------
	' Key number three
	' ----------------
	Temp= OpenRegKey("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\."+Filext)
	
	If Temp Then
		Temp.remove(True)  ; Print "Registry debug : Key 3 removed..."
	EndIf

	' ---------------
	' Key number four
	' ---------------
	Temp = OpenRegKey("HKEY_LOCAL_MACHINE\SOFTWARE\Classes"+Filext+"_auto_file")
	
	If Temp
		Temp.remove(True)  ; Print "Registry debug : Key 4 removed..."
	End If		
	
End Function

CreateFileType("kmp","L:\BlitzMax\sources\Keep my password\Kmp.exe")
Local A:String=Input("Press a key to continue...")
DeleteFileType("kmp")

End




'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