adding registration keys

BlitzMax Forums/BlitzMax Programming/adding registration keys

I have a way to generate my serial keys but how/whats the best way to check the machine the software is on to make sure its the correct machine?

You want to make sure your softwere licence is machine specific?
The same way that Microsoft want to with Vista? Ie the thing we slagged off no end?

yes but I dont want to discuss why I want to or why its frowned about I just would like help.

Well, ok, you make them connect to your central server, with firewall turned off, and ask the computer for all its details. Probably as well you would ask for ramdom sector information that you have made unmoveable from their Hard drive, and compare it with the last time they were online

For sure very few people will actualy use your software if you asked them to do this. In fact you could probably only get away with it, if you were a semi monopoly operating system publisher

It kind of depends on how strictly you want to lock it down...

You can obtain a lot of info about a computer through the windows API:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/computer_system_hardware_classes.asp

Of course, locking any program to the hardware comes with some technical problems, in that it is very common for people to upgrade one or more of their hardware components. Additional memory, bigger harddrive, faster video card, etc.
Windows XP addresses this by determining the info on a lot of different components, and allowing you to make a certain number of changes over a certain time frame. Too many changes in too short a time, and it will want to be re-activated. If you do decide to tie your program to the hardware, that is pretty much a must, or you'll end up with a lot of legitimate users that will be legitimately pissed off that your program stops working. (Especially since they most likely paid for it, or why bother locking it to a computer in the first place?)

I've also seen some software that does a lot more basic test, simply by looking to the name of the computer. That does not actually tie it to specific hardware, but it will limit it to a single computer by that name on your local network -- more than one and you'll get problems thanks to the duplicate name, especially in larger networks that use a domain controller. It's not as 'secure' as looking at the actual hardware, but it's a lot more user friendly to the end user, and allows them limited portability -- as long as their new computer has the same name as the old, they can simply reinstall it regardless of the actual hardware.

ok that sounds a little better, what about getting the registration key for windows and checking that with the key? not the serial key for windows but the reg key is there a simple way of doing that ?

You could always invest in "armadillo - Software passport" which would take care of this for you. It generates reg keys, locks to hardware if specified etc..

It may take you some time to implement a system like that but above all implement one that works properly.

Sorry I couldn't be of help.

Incase you want to check out Software Passport: http://siliconrealms.com/index.shtml

Well, I apologise Ckob, it seems a lot easyer to do than I had thought.

ok that sounds a little better, what about getting the registration key for windows and checking that with the key? not the serial key for windows but the reg key is there a simple way of doing that ?


It's in the registry:

windows 95: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion and look for an entry in the right pane called "ProductId"

Windows 98 and ME:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion and look for an entry called "ProductKey"

Windows 2000 and XP: two locations: "ProductKey", one under
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion and another in
HKEY_LOCAL_MACHINE\Software\Microsoft\WinNT\CurrentVersion.

However, this probably isn't going to help you much, since it not as unique as you might think. In large companies, almost all machines are imaged from a single source, meaning they have the same serial/productkey in the registry.

That also includes pretty much any assembly-line computer: If you buy a Dell for example, you'll find a sticker on the case with a product key. However, the installed version on the PC itself got put there from an image in the factory, and there will be tens or hundreds of thousands of other people with the identical code on theirs. The windows key listed on the sticker on the case doesn't come into play until you actually re-install the operating system and it asks you for the key.

armadillo looks nice but i dont have that kinda cash to throw around :/

I'll have to make my own system im sure, I already have it working with a key but I want to make it more secure so people can't just share their key with someone else.

ckob,

google hardware serial number set by the manufacturer or PC MAC Address.

both are unique to the owners pc.

kev

Use Armadillo, a wrapper available here.

Hardware serial numbers can be a) blocked or b) changed. As can the NIC's MAC Address (assuming the user has a network interface card).

In short, there is no way to lock software to a particular machine. At least not until "trusted computing" takes off, and in that case, it's gonna cost you way more than an armadillo license to get on the list of trusted companies.

I'll probebly end up using a system which just connects to my database and make sure the key and email address match. This isn't as secure as I would like but armadillo is to expensive and locking it to one machine isn't sounding as good as I thought it would.

FD: How do you change the HD serial?

Thats what I actually would lock it too, to the harddisk and to the windows serial (or a similar non hardware thing). The serial is only to prevent users from installing it on a USB or similar and take it with them.

The HD serial actually contains the date and time of its initial format, and can be changed either by doing a low-level format, or IIRC there are tools out there that can modify the information as well. It's written somewhere on the disk itself.

FD: How do you change the HD serial?
Reformat it.

Trust and liberal licenses are the best ways to loyal and satisfied customers. Per-device licenses are not very user friendly; if you want to make your customers happy, allow them to install the software on more than one computer. Nobodoy wants to pay twice just because they also want to install the software on a notebook. The reasoning is simple: Nobody usually uses the same program twice at the same time, so why the heck would you need two licenses? Right: To satisfy the vendor's greed, that's the only reason.

In my opinion, selling a license key is okay, but product activation, transmitting of individual hard- and software information and dongling are not.

If you want your customers to trust you, you first have to trust them.

Armadillo isn't that expensive for commercial products, actually is a very cheap solution.

Otherwise, make your own algo is easy too.

Here's an example to get and set regkeys:
Import leadwerks.lwbank
Import "-ladvapi32"

Extern "win32"
   Function RegOpenKey:Int(hKeyParent:Int,SubKey$z,phkResult:Byte Ptr)="RegOpenKeyA@12"
   Function RegCloseKey:Int(hKey:Int)="RegCloseKey@4"
   Function RegCreateKey:Int(hKeyParent:Int,SubKey$z,phkResult:Byte Ptr)="RegCreateKeyA@12"
   Function RegDeleteKey:Int(hKeyParent:Int,SubKey$z)="RegDeleteKeyA@8"
   Function RegSetValueEx:Int(hKey:Int,ValueName$z,Reserved:Int,nType:Int,Bytes:Byte Ptr,size:Int)="RegSetValueExA@24"
   Function RegDeleteValue:Int(hKey:Int,ValueName$z)="RegDeleteValueA@8"
   Function RegEnumKey:Int(hKey:Int,idx:Int,Key:Byte Ptr,size:Int)="RegEnumKeyA@16"
   Function RegEnumValue:Int(hKey:Int,idx:Int,ValueName:Byte Ptr,NameSize:Byte Ptr,Reserved:Int,nType:Byte Ptr,ValueBytes:Byte Ptr,ValueSize:Byte Ptr)="RegEnumValueA@32"
   Function RegQueryValueEx:Int(hKey:Int,ValueName$z,Reserved:Int,nType:Byte Ptr,ValueBytes:Byte Ptr,ValueSize:Byte Ptr)="RegQueryValueExA@24"
EndExtern

Const HKEY_CLASSES_ROOT = $80000000
Const HKEY_CURRENT_USER = $80000001
Const HKEY_LOCAL_MACHINE = $80000002
Const HKEY_USERS = $80000003

Const KEY_QUERY_VALUE = $1
Const KEY_SET_VALUE = $2
Const KEY_CREATE_SUB_KEY = $4
Const KEY_ENUMERATE_SUB_KEYS = $8
Const KEY_NOTIFY = $10
Const KEY_CREATE_LINK = $20
Const SYNCHRONIZE = $100000

Const REG_NONE                            =0
Const REG_SZ                              =1
Const REG_EXPAND_SZ                       =2
Const REG_BINARY                          =3
Const REG_DWORD                           =4
Const REG_DWORD_BIG_ENDIAN                =5
Const REG_LINK                            =6
Const REG_MULTI_SZ                        =7
Const REG_RESOURCE_LIST                   =8
Const REG_FULL_RESOURCE_DESCRIPTOR        =9
Const REG_RESOURCE_REQUIREMENTS_LIST      =10
Const REG_QWORD                           =11

Const KEY_ACCESS_ALL = KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY

Local hkey:Int

If RegOpenKey(HKEY_LOCAL_MACHINE,"SOFTWARE\3DWorldStudio",Varptr hkey)<>0
	End
EndIf

Local data1:Int=69
Local data2$="Hello"

RegSetValueEx:Int(hKey,"integer",0,REG_DWORD,Varptr data1,4)
RegSetValueEx:Int(hKey,"string",0,REG_SZ,data2.ToCString(),data2.length)

Local nType:Int
Local size:Int

RegQueryValueEx:Int(hKey,"integer",0,Varptr nType,Null,Varptr size)
bank:TBank=CreateBank(size)
RegQueryValueEx:Int(hKey,"integer",0,Null,bank.buf(),Varptr size)
Notify PeekInt(bank,0)

RegQueryValueEx:Int(hKey,"string",0,Varptr nType,Null,Varptr size)
bank:TBank=CreateBank(size)
RegQueryValueEx:Int(hKey,"string",0,Null,bank.buf(),Varptr size)
Notify PeekString(bank,0)


Can you use their MAC address and just lock it to their ethernet card?

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




Filax, any chance to get this source code without HTML tags?

Maybe by email ? :) Check you mail box