adding registration keys

BlitzMax Forums/BlitzMax Programming/adding registration keys

The Forum Archive is locked. These are the original blitzbasic.com forums, kept so their posts can still be read and searched. No new topics, replies or edits can be made here. To join the conversation, head over to the Blitz3D+ forums.

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