DemonAngel Posted January 12, 2010 Posted January 12, 2010 Hi guys, I was wondering if you could help me with a registry key rename problem I have. I have been looking through the help file, but all I could find was read and delete functions. I want to rename the following. From: "HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet Explorer\Control Panel" To: "HKEY_CURRENT_USER\Software\Policies\Microsoft\Internet ExplorerOLD\Control Panel" Once the rename is complete, I need to make a manual IE change and then rename the key back. There are numerous keys and values contained under the Internet Explorer key that I dont want to loose. I am also an administrator on the PC and will thus not have any permission problems accessing the registry. Cheers, DMN
martin Posted January 12, 2010 Posted January 12, 2010 I think you need to export the key to a file, copy the file to another, rename the keys in the copy. Then delete the reg key, import from the modified copy. Then later, delete the new key and import from the first export. Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
DemonAngel Posted January 12, 2010 Author Posted January 12, 2010 Thanx for the reply Martin. Do know perhaps know of a UDF or an easy way to export and import registry keys?
zorphnog Posted January 12, 2010 Posted January 12, 2010 (edited) Well this turned out to be a little bit more complicated than I thought, but here's a UDF to rename a key. expandcollapse popupGlobal Const _ ; Predefined Keys $HKEY_CLASSES_ROOT = 0x80000000, _ $HKEY_CURRENT_USER = 0x80000001, _ $HKEY_LOCAL_MACHINE = 0x80000002, _ $HKEY_USERS = 0x80000003 Global Const _ ; Registry Key Security and Access Rights $KEY_ALL_ACCESS = 0xF003F, _ $KEY_CREATE_LINK = 0x0020, _ $KEY_CREATE_SUB_KEY = 0x0004, _ $KEY_ENUMERATE_SUB_KEYS = 0x0008, _ $KEY_EXECUTE = 0x20019, _ $KEY_NOTIFY = 0x0010, _ $KEY_QUERY_VALUE = 0x0001, _ $KEY_READ = 0x20019, _ $KEY_SET_VALUE = 0x0002, _ $KEY_WOW64_32KEY = 0x0200, _ $KEY_WOW64_64KEY = 0x0100, _ $KEY_WRITE = 0x20006 Global Const _ ; Registry creation options $REG_OPTION_NON_VOLATILE = 0x00000000, _ $REG_OPTION_VOLATILE = 0x00000001, _ $REG_OPTION_CREATE_LINK = 0x00000002, _ $REG_OPTION_BACKUP_RESTORE = 0x00000004 _RegRenameKey("HKLM\SOFTWARE", "TestKey", "TestKey1") Func _RegRenameKey($sKey, $sSubKeyOld, $sSubKeyNew) Local $sMainKey, $sMainSubKey, $hKeySrc, $hKeyDest ; Check for subkey existance RegRead($sKey & "\" & $sSubKeyOld, "") If @error = 1 Then ConsoleWrite(StringFormat("-> ERROR key does not exist [%s\\%s]\r\n", $sKey, $sSubKeyOld)) Return SetError(-1, 0, -1) EndIf ; Parse key for system key and subkey $aResult = StringRegExp($sKey, "(?iU)(.+)(?:\\(.*\Z)|\Z)", 3) If Not @error Then Switch UBound($aResult) Case 1 $sMainKey = $aResult[0] $sMainSubKey = "" Case 2 $sMainKey = $aResult[0] $sMainSubKey = $aResult[1] EndSwitch Else Return SetError(1, 0, -1) EndIf ; Open main subkey $hKeySrc = __RegOpenKeyEx($sMainKey, $sMainSubKey) If @error Then ConsoleWrite(StringFormat("-> ERROR opening key [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sMainKey, $sMainSubKey, @error, @extended)) Return SetError(2, 0, -1) EndIf ; Create new subkey $hKeyDest = __RegCreateKeyEx($hKeySrc, $sSubKeyNew) If @error Then ConsoleWrite(StringFormat("-> ERROR creating key [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sKey, $sSubKeyNew, @error, @extended)) __RegCloseKey($hKeySrc) Return SetError(3, 0, -1) EndIf ; Copy tree from old subkey to new __RegCopyTree($hKeySrc, $sSubKeyOld, $hKeyDest) If @error Then ConsoleWrite(StringFormat("-> ERROR copying tree [%s\\%s] to [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sKey, $sSubKeyOld, $sKey, $sSubKeyNew, @error, @extended)) __RegCloseKey($hKeySrc) __RegCloseKey($hKeyDest) Return SetError(4, 0, -1) EndIf __RegCloseKey($hKeyDest) ; Delete old subkey __RegDeleteTree($hKeySrc, $sSubKeyOld) If @error Then ConsoleWrite(StringFormat("-> ERROR deleting tree [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sKey, $sSubKeyOld, @error, @extended)) __RegCloseKey($hKeySrc) Return SetError(5, 0, -1) EndIf __RegCloseKey($hKeySrc) EndFunc ;==>_RegRenameKey Func __RegCloseKey($hKey) Local $aResult = DllCall("advapi32.dll", "int", "RegCloseKey", "int", $hKey) If @error Then Return SetError(1, @error, -1) If $aResult[0] <> 0 Then Return SetError(2, $aResult[0], -1) EndFunc ;==>__RegCloseKey Func __RegCopyTree($hKeySrc, $sSubKey, $hKeyDest) Local $tDATA, $aResult $tDATA = DllStructCreate("wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("advapi32.dll", "int", "RegCopyTreeW", _ "int", $hKeySrc, _ "ptr", DllStructGetPtr($tDATA, "SubKey"), _ "int", $hKeyDest) If @error Then $tDATA = 0 Return SetError(1, @error, -1) ; Error using DllCall EndIf $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(2, $aResult[0], -1) ; Error using RegCopyTree EndFunc ;==>__RegCopyTree Func __RegCreateKeyEx($hKey, $sSubKey, $b64 = False) Local $tDATA, $iSAM, $aResult, $hkResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid Key $iSAM = $KEY_WOW64_32KEY If $b64 Then $iSAM = $KEY_WOW64_64KEY $tDATA = DllStructCreate("int Result;dword Disposition;wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("advapi32.dll", "int", "RegCreateKeyExW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey"), _ "dword", 0, _ "ptr", 0, _ "dword", $REG_OPTION_NON_VOLATILE, _ "int", BitOR($KEY_ALL_ACCESS, $iSAM), _ "ptr", 0, _ "ptr", DllStructGetPtr($tDATA, "Result"), _ "ptr", DllStructGetPtr($tDATA, "Disposition")) If @error Then $tDATA = 0 Return SetError(2, @error, -1) ; Error using DllCall EndIf $hkResult = DllStructGetData($tDATA, "Result") $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], $hkResult) ; Error using RegCreateKeyEx Return $hkResult EndFunc ;==>__RegCreateKeyEx Func __RegDeleteKeyEx($hKey, $sSubKey, $b64 = False) Local $tDATA, $iSAM, $aResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid Key $iSAM = $KEY_WOW64_32KEY If $b64 Then $iSAM = $KEY_WOW64_64KEY $tDATA = DllStructCreate("wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("advapi32.dll", "int", "RegDeleteKeyExW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey"), _ "int", $iSAM, _ "dword", 0) If @error Then $tDATA = 0 Return SetError(2, @error, -1) ; Error using DllCall EndIf $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], -1) ; Error using RegDeleteKeyEx EndFunc ;__RegDeleteKeyEx Func __RegDeleteTree($hKey, $sSubKey = "") Local $tDATA, $aResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid Key $tDATA = DllStructCreate("wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("advapi32.dll", "int", "RegDeleteTreeW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey")) If @error Then $tDATA = 0 Return SetError(2, @error, -1) ; Error using DllCall EndIf $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], -1) ; Error using RegDeleteTree EndFunc ;==>__RegDeleteTree Func __RegOpenKeyEx($hKey, $sSubKey = "", $b64 = False) Local $tDATA, $aResult, $hkResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid Key $iSAM = $KEY_WOW64_32KEY If $b64 Then $iSAM = $KEY_WOW64_64KEY $tDATA = DllStructCreate("int Result;wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("advapi32.dll", "int", "RegOpenKeyExW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey"), _ "dword", 0, _ "int", BitOR($KEY_ALL_ACCESS, $iSAM), _ "ptr", DllStructGetPtr($tDATA, "Result")) If @error Then $tDATA = 0 Return SetError(2, @error, -1) ; Error using DllCall EndIf $hkResult = DllStructGetData($tDATA, "Result") $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], $hkResult) ; Error using RegOpenKeyEx Return $hkResult EndFunc ;==>__RegOpenKeyEx Func __GetHKey($hKey) If IsString($hKey) Then Switch StringUpper($hKey) Case "HKCR", "HKEY_CLASSES_ROOT" Return $HKEY_CLASSES_ROOT Case "HKCU", "HKEY_CURRENT_USER" Return $HKEY_CURRENT_USER Case "HKLM", "HKEY_LOCAL_MACHINE" Return $HKEY_LOCAL_MACHINE Case "HKU", "HKEY_USERS" Return $HKEY_USERS Case Else Return SetError(1, 0, -1) EndSwitch EndIf Return $hKey EndFunc ;==>__GetHKey Edit: Corrected deletion of old key. __RegDeleteTree must be used instead of __RegDeleteEx to recursively delete the subkey. Edited January 12, 2010 by zorphnog
martin Posted January 12, 2010 Posted January 12, 2010 (edited) Well this turned out to be a little bit more complicated than I thought, but here's a UDF to rename a key. Wow, that's a lot of work. I haven't tried it but I'm very impressed. This is what I was trying to describe. expandcollapse popup_RenameRegKey("HKEY_CURRENT_USER\Software\SomeKey", "HKEY_CURRENT_USER\Software\ABCNew") ;Function _RenameRegKey ;returns 1 on success ; -1 if oldkey not found ; -2 if no change to make ; -3 if failed to create new key ; -4 failed to delete old key ;a backup of the old key is in the file $savereg ;a backup of new key is in $newreg Func _RenameRegKey($oldkey, $newkey,$savereg= default, $newreg= default) If $savereg = default then $savereg = @ScriptDir & '\back01.reg' if $newreg = default then $newreg = @ScriptDir & '\back02.reg' RegRead($oldkey, "") If @error = 1 Then Return -1;no such key If $oldkey == $newkey Then Return -2 Local $header, $all, $all1, $hf2 FileDelete($savereg) $proc = RunWait('regedit /e "' & $savereg & '" "' & $oldkey & '"'); /e to export $all = FileRead($savereg) If $all = "" Then Return -1;no data $all1 = StringReplace($all, $oldkey, $newkey) If @extended = 0 Then Return -2; no changes $hf2 = FileOpen($newreg, 2) FileWrite($hf2, $all1) FileClose($hf2) RunWait('regedit /s "' & $newreg & '"'); /s means silent, ie no prompt to write to the registry RegRead($newkey, "") If @error = 1 Then Return -3;failed EndIf if RegDelete($oldkey) = 2 then return -4 Return 1; ok EndFunc ;==>_RenameRegKey EDIT: Converted to a function. Tested on XP only. Edited January 14, 2010 by martin Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
ProgAndy Posted January 12, 2010 Posted January 12, 2010 This is only for Vista and newer. For XP, ypu have to modify it to use SHCopyKey *GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes
zorphnog Posted January 12, 2010 Posted January 12, 2010 Good catch @ProgAndy. I sometimes forget about preVista. Here's the correction. expandcollapse popupGlobal Const _ ; Predefined Keys $HKEY_CLASSES_ROOT = 0x80000000, _ $HKEY_CURRENT_USER = 0x80000001, _ $HKEY_LOCAL_MACHINE = 0x80000002, _ $HKEY_USERS = 0x80000003 Global Const _ ; Registry Key Security and Access Rights $KEY_ALL_ACCESS = 0xF003F, _ $KEY_CREATE_LINK = 0x0020, _ $KEY_CREATE_SUB_KEY = 0x0004, _ $KEY_ENUMERATE_SUB_KEYS = 0x0008, _ $KEY_EXECUTE = 0x20019, _ $KEY_NOTIFY = 0x0010, _ $KEY_QUERY_VALUE = 0x0001, _ $KEY_READ = 0x20019, _ $KEY_SET_VALUE = 0x0002, _ $KEY_WOW64_32KEY = 0x0200, _ $KEY_WOW64_64KEY = 0x0100, _ $KEY_WRITE = 0x20006 Global Const _ ; Registry creation options $REG_OPTION_NON_VOLATILE = 0x00000000, _ $REG_OPTION_VOLATILE = 0x00000001, _ $REG_OPTION_CREATE_LINK = 0x00000002, _ $REG_OPTION_BACKUP_RESTORE = 0x00000004 _RegRenameKey("HKLM\SOFTWARE", "TortoiseOverlays1", "TortoiseOverlays") Func _RegRenameKey($sKey, $sSubKeyOld, $sSubKeyNew) Local $sMainKey, $sMainSubKey, $hKeySrc, $hKeyDest ; Check for subkey existance RegRead($sKey & "\" & $sSubKeyOld, "") If @error = 1 Then ConsoleWrite(StringFormat("-> ERROR key does not exist [%s\\%s]\r\n", $sKey, $sSubKeyOld)) Return SetError(-1, 0, -1) EndIf ; Parse key for system key and subkey $aResult = StringRegExp($sKey, "(?iU)(.+)(?:\\(.*\Z)|\Z)", 3) If Not @error Then Switch UBound($aResult) Case 1 $sMainKey = $aResult[0] $sMainSubKey = "" Case 2 $sMainKey = $aResult[0] $sMainSubKey = $aResult[1] EndSwitch Else Return SetError(1, 0, -1) EndIf ; Open main subkey $hKeySrc = __RegOpenKeyEx($sMainKey, $sMainSubKey) If @error Then ConsoleWrite(StringFormat("-> ERROR opening key [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sMainKey, $sMainSubKey, @error, @extended)) Return SetError(2, 0, -1) EndIf ; Create new subkey $hKeyDest = __RegCreateKeyEx($hKeySrc, $sSubKeyNew) If @error Then ConsoleWrite(StringFormat("-> ERROR creating key [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sKey, $sSubKeyNew, @error, @extended)) __RegCloseKey($hKeySrc) Return SetError(3, 0, -1) EndIf ; Copy tree from old subkey to new __SHCopyKey($hKeySrc, $sSubKeyOld, $hKeyDest) If @error Then ConsoleWrite(StringFormat("-> ERROR copying tree [%s\\%s] to [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sKey, $sSubKeyOld, $sKey, $sSubKeyNew, @error, @extended)) __RegCloseKey($hKeySrc) __RegCloseKey($hKeyDest) Return SetError(4, 0, -1) EndIf __RegCloseKey($hKeyDest) ; Delete old subkey __SHDeleteKey($hKeySrc, $sSubKeyOld) If @error Then ConsoleWrite(StringFormat("-> ERROR deleting tree [%s\\%s]\r\nError: %d\tExtended: %d\r\n", $sKey, $sSubKeyOld, @error, @extended)) __RegCloseKey($hKeySrc) Return SetError(5, 0, -1) EndIf __RegCloseKey($hKeySrc) EndFunc ;==>_RegRenameKey Func __GetHKey($hKey) If IsString($hKey) Then Switch StringUpper($hKey) Case "HKCR", "HKEY_CLASSES_ROOT" Return $HKEY_CLASSES_ROOT Case "HKCU", "HKEY_CURRENT_USER" Return $HKEY_CURRENT_USER Case "HKLM", "HKEY_LOCAL_MACHINE" Return $HKEY_LOCAL_MACHINE Case "HKU", "HKEY_USERS" Return $HKEY_USERS Case Else Return SetError(1, 0, -1) EndSwitch EndIf Return $hKey EndFunc ;==>__GetHKey Func __RegCloseKey($hKey) Local $aResult = DllCall("advapi32.dll", "int", "RegCloseKey", "int", $hKey) If @error Then Return SetError(1, @error, -1) If $aResult[0] <> 0 Then Return SetError(2, $aResult[0], -1) EndFunc ;==>__RegCloseKey Func __RegCreateKeyEx($hKey, $sSubKey, $b64 = False) Local $tDATA, $iSAM, $aResult, $hkResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid Key $iSAM = $KEY_WOW64_32KEY If $b64 Then $iSAM = $KEY_WOW64_64KEY $tDATA = DllStructCreate("int Result;dword Disposition;wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("advapi32.dll", "int", "RegCreateKeyExW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey"), _ "dword", 0, _ "ptr", 0, _ "dword", $REG_OPTION_NON_VOLATILE, _ "int", BitOR($KEY_ALL_ACCESS, $iSAM), _ "ptr", 0, _ "ptr", DllStructGetPtr($tDATA, "Result"), _ "ptr", DllStructGetPtr($tDATA, "Disposition")) If @error Then $tDATA = 0 Return SetError(2, @error, -1) ; Error using DllCall EndIf $hkResult = DllStructGetData($tDATA, "Result") $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], $hkResult) ; Error using RegCreateKeyEx Return $hkResult EndFunc ;==>__RegCreateKeyEx Func __RegOpenKeyEx($hKey, $sSubKey = "", $b64 = False) Local $tDATA, $aResult, $hkResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid Key $iSAM = $KEY_WOW64_32KEY If $b64 Then $iSAM = $KEY_WOW64_64KEY $tDATA = DllStructCreate("int Result;wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("advapi32.dll", "int", "RegOpenKeyExW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey"), _ "dword", 0, _ "int", BitOR($KEY_ALL_ACCESS, $iSAM), _ "ptr", DllStructGetPtr($tDATA, "Result")) If @error Then $tDATA = 0 Return SetError(2, @error, -1) ; Error using DllCall EndIf $hkResult = DllStructGetData($tDATA, "Result") $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], $hkResult) ; Error using RegOpenKeyEx Return $hkResult EndFunc ;==>__RegOpenKeyEx Func __SHCopyKey($hKey, $sSubKey, $hKeyNew) Local $tDATA, $aResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid source key $hKeyNew = __GetHKey($hKeyNew) If @error Then Return SetError(2, 0, -1) ; Invalid destination key $tDATA = DllStructCreate("wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("shlwapi.dll", "int", "SHCopyKeyW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey"), _ "int", $hKeyNew, _ "dword", 0) If @error Then $tDATA = 0 Return SetError(3, @error, -1) ; Error using DllCall EndIf $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(4, $aResult[0], -1) ; Error using SHCopyKey EndFunc ;==>__SHCopyKey Func __SHDeleteKey($hKey, $sSubKey) Local $tDATA, $aResult $hKey = __GetHKey($hKey) If @error Then Return SetError(1, 0, -1) ; Invalid source key $tDATA = DllStructCreate("wchar SubKey[255]") DllStructSetData($tDATA, "SubKey", $sSubKey) $aResult = DllCall("shlwapi.dll", "int", "SHDeleteKeyW", _ "int", $hKey, _ "ptr", DllStructGetPtr($tDATA, "SubKey")) If @error Then $tDATA = 0 Return SetError(2, @error, -1) ; Error using DllCall EndIf $tDATA = 0 If $aResult[0] <> 0 Then Return SetError(3, $aResult[0], -1) ; Error using SHDeleteKey EndFunc ;==>__SHDeleteKey
DemonAngel Posted January 15, 2010 Author Posted January 15, 2010 @Zorphnog - Thanx a lot mate , this looks like it took you some time to do Would this UDF allow you to rename a key over a UNC path as well? Example if the key that needs renaming is : \\PCname\HKEY_USERS\S-1-5-21-2025429265-606747145-1417001333-1003\Software\Policies\Microsoft\Internet Explorer? I will go run a few tests now
zorphnog Posted January 19, 2010 Posted January 19, 2010 @DemonAngel - Connecting to remote registries requires a few more functions. You have to create an impersonated logon and use the RegConnectRegistry function RegConnectRegistry Function (Windows). All the information you need is in that link. Note that you will only be able to access the HKEY_LOCAL_MACHINE, HKEY_PERFORMANCE_DATA, HKEY_USERS hives when connecting to remote registries.I can take a look at it later when I have some time, but I can't do it right now.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now