benners Posted March 10, 2008 Share Posted March 10, 2008 I am trying to write a small program so I can hide user selected drives in an unattended Windows setup. What I am trying to do is read the hex value from the registry, add the value that hides the drive and re write the key to the registry. I have monitored the registry changes made with TweakUI when I hide the individual drives and everything is fine until 100 is reached and then due to the Hex system the values change so 100 = a0, 101 = a1 and sometimes ff which should be 165 but I can't work out how knowing nothing about the hex system and can't understand what I am reading when I find something after searching what I need is a way to convert the numbers > 100 to an integer to add a new value then convert back to hex, is there a UDF or math function already in AutoIt that I could use or do I have to try and create one?. My script is below with the commented lines at the end of the WriteKey function being where the conversion code should go. Thanks CODE#include <Array.au3> #NoTrayIcon Dim $Key = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer' Dim $val = 'NoDrives' ; Arrays for drive letters Dim $Hex1[8] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] Dim $Hex2[8] = ['i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'] Dim $Hex3[8] = ['q', 'r', 's', 't', 'u', 'v', 'w', 'x'] Dim $Hex4[2] = ['y', 'z'] ; Array for value to add for tweak. Dim $HexInt[8] = ['1', '2', '4', '8', '10', '20', '40', '80'] Dim $HexVal[4] If $cmdline[0] = 0 Then Exit ; Exit if no parameters. Switch $cmdline[1] ; Get the drive letter from command line params. Case 'a' To 'h' WriteKey($Hex1, 0) Case 'i' To 'p' WriteKey($Hex2, 1) Case 'q' To 'x' WriteKey($Hex3, 2) Case 'y' To 'z' WriteKey($Hex4, 3) EndSwitch #cs Function to write the registry key to hide the specified drive. Read current 'NoDrives' value from registry, add the appropriate value and re write the value to hide the drive in Windows Explorer. $ATS = Array to search (Based on drive letter) $AB = Array block ('NoDrives' Reg binary value split into 4 pairs) #ce Func WriteKey($ATS, $AB) ; Try to read the value, if nothing is returned assume key not found and write one. If RegRead($key, $val) = '' Then RegWrite($key, $val, 'REG_BINARY', '00000000') For $i = 1 To 8 Step 2 ; Read the 'NoDrives' value into the array in pairs.(givex 4 x 2 Hex pairs, i.e 00 00 00 00) _ArrayPush($HexVal, StringMid(RegRead($Key, $val), $i, 2)) Next ; Find the drive letters position in the array.(Used to get the value to add to the Hex) $pos = _ArraySearch($ATS, $cmdline[1]) ; Convert the Hex value to an integer. ; requires code ; Add the value to hide the drive to the correct ; requires code ; Convert to hex and write the new value to the registry. ; requires code EndFunc ;==>ReadKey Link to comment Share on other sites More sharing options...
rudi Posted March 11, 2008 Share Posted March 11, 2008 Hi. This should give you a start: expandcollapse popup#include <array.au3> Dim $HideValue = 0 $Paramstr1 = "AbFrUx" ; some drive letters, mixed UPPER and lower $Paramstr1 = StringUpper($Paramstr1) $HideArray = StringSplit($Paramstr1, "") ; "" will split the string into singletons For $i = 1 To $HideArray[0] $Value = Asc($HideArray[$i]) - 65 ; ASC(A) = 65, this has to be reduced to 0 (zero), as 2^0=1, see table below. $HideValue += Exp(Log(2) * $Value) ; x ^ y = exp(log(x)*y) MsgBox(0, "Letter: " & $HideArray[$i], "Value: " & $Value & @LF & _ "2^" & $Value & "=" & Exp(Log(2) * $Value) & @LF & _ "HideValue=" & $HideValue) Next MsgBox(0, "Value in Dec and Hex:", $HideValue & @LF & Hex($HideValue)) #cs A: 1 B: 2 C: 4 D: 8 E: 16 F: 32 G: 64 H: 128 I: 256 J: 512 K: 1024 L: 2048 M: 4096 N: 8192 O: 16384 P: 32768 Q: 65536 R: 131072 S: 262144 T: 524288 U: 1048576 V: 2097152 W: 4194304 X: 8388608 Y: 16777216 Z: 33554432 All: 67108863 #ce Regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE! Link to comment Share on other sites More sharing options...
benners Posted March 14, 2008 Author Share Posted March 14, 2008 Hi. This should give you a start: expandcollapse popup#include <array.au3> Dim $HideValue = 0 $Paramstr1 = "AbFrUx" ; some drive letters, mixed UPPER and lower $Paramstr1 = StringUpper($Paramstr1) $HideArray = StringSplit($Paramstr1, "") ; "" will split the string into singletons For $i = 1 To $HideArray[0] $Value = Asc($HideArray[$i]) - 65 ; ASC(A) = 65, this has to be reduced to 0 (zero), as 2^0=1, see table below. $HideValue += Exp(Log(2) * $Value) ; x ^ y = exp(log(x)*y) MsgBox(0, "Letter: " & $HideArray[$i], "Value: " & $Value & @LF & _ "2^" & $Value & "=" & Exp(Log(2) * $Value) & @LF & _ "HideValue=" & $HideValue) Next MsgBox(0, "Value in Dec and Hex:", $HideValue & @LF & Hex($HideValue)) #cs A: 1 B: 2 C: 4 D: 8 E: 16 F: 32 G: 64 H: 128 I: 256 J: 512 K: 1024 L: 2048 M: 4096 N: 8192 O: 16384 P: 32768 Q: 65536 R: 131072 S: 262144 T: 524288 U: 1048576 V: 2097152 W: 4194304 X: 8388608 Y: 16777216 Z: 33554432 All: 67108863 #ce Regards, Rudi.Hi Rudi Thanks for the reply. I have done some more testing and although the tweaks use the Hex format they do not seem to conform when calculating the result. In Hex FF = 255 which is F (15) * 16 + F (15) * 1 but with these tweaks the number should be 165. For this tweak the first value is multiplied by 10 i.e FF = 165 which is F (15) * 10 + F (15) * 1, I made progress on the script and found a way to convert the Hex values to a number that could be added to but then found that the values also changed depending on which drives where previously hidden. An example of this is hiding drives C, D and E gives a value of 22 which shouldn't need converting but with TweakUI the reg value is 1c which also works out to 22, so I found that when converting a new tweak value back to the Hex (type) format I would not know which variation would be the correct one. Their is obviously some pattern but I cannot see it so job stopped Link to comment Share on other sites More sharing options...
Siao Posted March 14, 2008 Share Posted March 14, 2008 (edited) Func _DriveHide($sDriveLetter, $fHide = True) Local $sKey = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', $sVal = 'NoDrives', $sOld, $iData, $iRet, $aDrives $sOld = RegRead($sKey, $sVal) If $sOld = "" Then $sOld = "00000000" $iData = Dec(Hex(Binary(BitOr('0x' & $sOld, 0)))) $aDrives = StringSplit(StringUpper($sDriveLetter), "") For $i = 1 To $aDrives[0] If $fHide Then $iData = BitOr($iData, 2^(Asc($aDrives[$i])-65)) Else $iData = BitAnd($iData, BitNOT(2^(Asc($aDrives[$i])-65))) EndIf Next $iRet = RegWrite($sKey, $sVal, "REG_BINARY", Hex(Binary($iData))) Return SetError(@error, 0, $iRet) EndFunc ;Examples: ;hide B drive _DriveHide("b") MsgBox(0,'Test 1', RegRead('HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', 'NoDrives')) ;hide K and Z drives _DriveHide("kz") MsgBox(0,'Test 2', RegRead('HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', 'NoDrives')) ;show B, K and Z drives _DriveHide("bkz", 0) MsgBox(0,'Test 3', RegRead('HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', 'NoDrives')) Edited March 14, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
benners Posted March 14, 2008 Author Share Posted March 14, 2008 Func _DriveHide($sDriveLetter, $fHide = True) Local $sKey = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', $sVal = 'NoDrives', $sOld, $iData, $iRet, $aDrives $sOld = RegRead($sKey, $sVal) If $sOld = "" Then $sOld = "00000000" $iData = Dec(Hex(Binary(BitOr('0x' & $sOld, 0)))) $aDrives = StringSplit(StringUpper($sDriveLetter), "") For $i = 1 To $aDrives[0] If $fHide Then $iData = BitOr($iData, 2^(Asc($aDrives[$i])-65)) Else $iData = BitAnd($iData, BitNOT(2^(Asc($aDrives[$i])-65))) EndIf Next $iRet = RegWrite($sKey, $sVal, "REG_BINARY", Hex(Binary($iData))) Return SetError(@error, 0, $iRet) EndFunc ;Examples: ;hide B drive _DriveHide("b") MsgBox(0,'Test 1', RegRead('HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', 'NoDrives')) ;hide K and Z drives _DriveHide("kz") MsgBox(0,'Test 2', RegRead('HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', 'NoDrives')) ;show B, K and Z drives _DriveHide("bkz", 0) MsgBox(0,'Test 3', RegRead('HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer', 'NoDrives'))WOW!, thanks Siao How do you even think of scripts like that, I don't think it would enter my head no matter how many times I read the manual, it makes mine laughable . I like the multiple drives on the command line and the option to show them, I feel lazy now you have done all the work and cheated from all the sleep I have lost trying to get my script to do it. Was it obvious to you how the tweaks were applied?. Link to comment Share on other sites More sharing options...
Siao Posted March 14, 2008 Share Posted March 14, 2008 Was it obvious to you how the tweaks were applied?.Bitflag method is a pretty common practice to combine multiple options, it is used in some of the AutoIt functions too (see FileOpenDialog, FileOpen, etc.).If you see that possible values are powers of 2, it's a safe bet.If you're curious why it works the way it works, play with this little app. "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Bilgus Posted February 25, 2017 Share Posted February 25, 2017 Updated: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #RequireAdmin #include <GuiListView.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <String.au3> Opt("GUIOnEventMode", 1) Global $sKey = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer' Global $sVal = 'NoDrives' MainGUI() Func MainGUI() Global $listGUI = GUICreate("NoDrives", 280, 230, -1) Global $idListview = GUICtrlCreateListView("", 1, 1, 300, 200, $LVS_LIST, $LVS_EX_CHECKBOXES) Global $BtnId = 0 local $drive_mask = RegRead($sKey, $sVal) If @error And @error <> -1 Then MsgBox($MB_SYSTEMMODAL, "Error " & @error, "Unable to read registry key" & @CRLF & $sKey & "\" & $sVal) EndIf ConsoleWrite($drive_mask & @CRLF) GUISetOnEvent($GUI_EVENT_CLOSE, "On_Close_Main") GUICtrlCreateLabel("Unchecked drives will be hidden", 5, 208) $BtnId = GUICtrlCreateButton("Save", 180, 205, 80, 20) GUICtrlSetOnEvent($BtnId, "_BtnSave") For $i = 0 To 25 ;A-Z local $lv_Cid = GUICtrlCreateListViewItem(Chr($i + 65) & ":\", $idListview) GUICtrlSetOnEvent($lv_Cid, "_LvClick") If(Not BitAnd($drive_mask, 2 ^ ($i))) Then _GUICtrlListView_SetItemChecked($idListview, $i, True) EndIf Next GUISetState() While 1 Sleep(10) WEnd EndFunc ;==>MainGUI Func _BtnSave() local $aItem local $bState = false local $sDrives = "" For $i = 0 To 25 $aItem = _GUICtrlListView_GetItem($idListview, $i) $bState = _GUICtrlListView_GetItemChecked($idListview, $i) If(Not $bState) Then $sDrives &= StringLeft ($aItem[3],1) EndIf ConsoleWrite($aItem[3] & "Hide: " & NOT $bState & @CRLF) Next _DriveHide($sDrives, True) If @error Then MsgBox($MB_SYSTEMMODAL, "Error " & @error, "Unable to write registry key" & @CRLF & $sKey & "\" & $sVal) EndIf ;Reload regkey local $drive_mask = RegRead($sKey, $sVal) For $i = 0 To 25 ;A-Z If(Not BitAnd($drive_mask, 2 ^ ($i))) Then _GUICtrlListView_SetItemChecked($idListview, $i, True) EndIf Next ;Disable save button GUICtrlSetState(@GUI_CtrlId, $GUI_DISABLE) EndFunc ;==>_BtnSave Func _LvClick() ;Enable save button GUICtrlSetState($BtnId, $GUI_ENABLE) EndFunc ;==>_LvClick Func _DriveHide($sDriveLetter, $fHide = True) ;Siao local $iData, $iRet, $aDrives local $iData = RegRead($sKey, $sVal) local $aDrives = StringSplit(StringUpper($sDriveLetter), "") ConsoleWrite("0x" & Hex($iData) & @CRLF) For $i = 1 To $aDrives[0] ConsoleWrite($aDrives[$i] & ":\ 2^" & Asc($aDrives[$i]) - 65 & " => ") If $fHide Then $iData = BitOr($iData, 2 ^ (Asc($aDrives[$i]) - 65)) Else $iData = BitAnd($iData, BitNOT(2 ^ (Asc($aDrives[$i]) - 65))) EndIf ConsoleWrite("0x" & Hex($iData) & "< " & @CRLF) Next $iRet = RegWrite($sKey, $sVal, "REG_DWORD", "0x" & Hex($iData)) Return SetError(@error, 0, $iRet) EndFunc ;==>_DriveHide Func On_Close_Main() Exit EndFunc ;==>On_Close_Main Link to comment Share on other sites More sharing options...
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