rudi Posted November 19, 2008 Posted November 19, 2008 Hi. 0xFFFFFFFF = -1, and it's 4294967295 as well. So I came across this problem, when setting REG_DWORD values to 0xFFFFFFFF when I want to test the value found with the value it should be: Dim $RegArr[4][4] = [[3], _ ["HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", 4294967295], _ ["HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", 0xFFFFFFFF], _ ["HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", Dec("FFFFFFFF")]] For $i = 1 To $RegArr[0][0] $found = RegRead($RegArr[$i][0], $RegArr[$i][1]) If $found = $RegArr[$i][3] Then $Test = "The value was *ALREADY* set correctly." Else $Test = "Value was *NOT* set correctly!" EndIf RegWrite($RegArr[1][0], $RegArr[1][1], $RegArr[1][2], $RegArr[1][3]) $ChangedTo = RegRead($RegArr[$i][0], $RegArr[$i][1]) MsgBox(0, "Loop # " & $i, $Test & @LF & @LF & _ "Value to be set: " & $RegArr[$i][3] & @LF & _ "Value found: at program's start: " & $found & @LF & _ "Value set now after correction: " & $ChangedTo) Next Looks like I need to specify REG_DWORD values decimal, if I want to compare the found value and the wanted one? Regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE!
PsaltyDS Posted November 20, 2008 Posted November 20, 2008 (edited) Hi. 0xFFFFFFFF = -1, and it's 4294967295 as well.One is signed the other not. Whenever AutoIt is using the INT32 type it will be signed, so 4294967295 is out of range. AutoIt uses INT64 for that value. Numbers too large for INT64 will become FLOAT (VarGetType() says "DOUBLE"). On RegRead() the "REG_DWORD" type becomes "DOUBLE" every time. So I came across this problem, when setting REG_DWORD values to 0xFFFFFFFF when I want to test the value found with the value it should be: Dim $RegArr[4][4] = [[3], _ ["HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", 4294967295], _ ["HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", 0xFFFFFFFF], _ ["HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", Dec("FFFFFFFF")]] For $i = 1 To $RegArr[0][0] $found = RegRead($RegArr[$i][0], $RegArr[$i][1]) If $found = $RegArr[$i][3] Then $Test = "The value was *ALREADY* set correctly." Else $Test = "Value was *NOT* set correctly!" EndIf RegWrite($RegArr[1][0], $RegArr[1][1], $RegArr[1][2], $RegArr[1][3]) $ChangedTo = RegRead($RegArr[$i][0], $RegArr[$i][1]) MsgBox(0, "Loop # " & $i, $Test & @LF & @LF & _ "Value to be set: " & $RegArr[$i][3] & @LF & _ "Value found: at program's start: " & $found & @LF & _ "Value set now after correction: " & $ChangedTo) Next Looks like I need to specify REG_DWORD values decimal, if I want to compare the found value and the wanted one? Regards, Rudi. Demo: Global $sRegKey = "HKCU\SOFTWARE\Test", $sRegValue = "TestValue", $RegData Dim $avReg[4] = [-1, 4294967295, 0xFFFFFFFF, Dec("FFFFFFFF")] For $n = 0 To UBound($avReg) - 1 RegWrite($sRegKey, $sRegValue, "REG_DWORD", $avReg[$n]) $RegData = RegRead($sRegKey, $sRegValue) ConsoleWrite("Case: " & $n & ":" & @CRLF & _ @TAB & "Write value = " & $avReg[$n] & @CRLF & _ @TAB & "Write type = " & VarGetType($avReg[$n]) & @CRLF & _ @TAB & "Read data = " & $RegData & @CRLF & _ @TAB & "Read type = " & VarGetType($RegData) & @CRLF) Next Output: >Running:(3.2.12.1):C:\Program Files\AutoIt3\autoit3.exe "C:\temp\Test\Test1.au3" Case: 0: Write value = -1 Write type = Int32 Read data = 4294967295 Read type = Double Case: 1: Write value = 4294967295 Write type = Int64 Read data = 4294967295 Read type = Double Case: 2: Write value = -1 Write type = Int32 Read data = 4294967295 Read type = Double Case: 3: Write value = -1 Write type = Int32 Read data = 4294967295 Read type = Double Case: 4: Write value = 3.68934881474191e+019 Write type = Double Read data = 2147483648 Read type = Double +>09:29:47 AutoIT3.exe ended.rc:0 Output is the same with 3.2.13.11 Beta. Edited November 20, 2008 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
rudi Posted November 21, 2008 Author Posted November 21, 2008 One is signed the other not. Whenever AutoIt is using the INT32 type it will be signed, so 4294967295 is out of range. AutoIt uses INT64 for that value. Numbers too large for INT64 will become FLOAT (VarGetType() says "DOUBLE"). On RegRead() the "REG_DWORD" type becomes "DOUBLE" every time. I see. Output: >Running:(3.2.12.1):C:\Program Files\AutoIt3\autoit3.exe "C:\temp\Test\Test1.au3" [snip] Case: 4: Write value = 3.68934881474191e+019 Write type = Double Read data = 2147483648 Read type = Double +>09:29:47 AutoIT3.exe ended.rc:0 That one I can't see for a Array[4] I see, what's going on, but I'm a bit confused: REG_DWORD means the registry value is double word, that's "2x Word" = "4x Byte" = Int32, right? 0xFFFFFF *IS* a DWORD value, isn't it? So is there a way to specify the variable type when setting that value for RegWrite, so that "FFFFFFF" is *NOT* handled as "-1", so that I can compare it with the existing value in the Registry? Thanks for your answer. Regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE!
PsaltyDS Posted November 21, 2008 Posted November 21, 2008 I see. I see, what's going on, but I'm a bit confused: REG_DWORD means the registry value is double word, that's "2x Word" = "4x Byte" = Int32, right? 0xFFFFFF *IS* a DWORD value, isn't it? So is there a way to specify the variable type when setting that value for RegWrite, so that "FFFFFFF" is *NOT* handled as "-1", so that I can compare it with the existing value in the Registry? Thanks for your answer. Regards, Rudi. If you have any choice in creating the registry key, use REG_BINARY instead. Otherwise, convert with: $iData = RegRead("HKCU\MyKey", "MyRegDword") If $iData < 0 Then $iData += 2^32 Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
rudi Posted November 23, 2008 Author Posted November 23, 2008 Hi. If you have any choice in creating the registry key, use REG_BINARY instead. Otherwise, convert with: $iData = RegRead("HKCU\MyKey", "MyRegDword") If $iData < 0 Then $iData += 2^32 No, the READ Value is correct: As you pointed me to, Autoit will store in an Int64 when reading a REG_DWORD. It's the Autoit Variable, that I want to set to the positive value of 0xFFFFFFFF. So the Question is: Is there any way to tell the "DIM Process" to use a certain variable type? So that specifying 0xFFFFFFFF doesn't end up with a "-1" ? I mean: Either "tell" autoit to use a unsigned Int32 for storing 0xFFFFFFFF, or use Int64 instead? Regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE!
PsaltyDS Posted November 23, 2008 Posted November 23, 2008 Hi.No, the READ Value is correct: As you pointed me to, Autoit will store in an Int64 when reading a REG_DWORD.It's the Autoit Variable, that I want to set to the positive value of 0xFFFFFFFF.That's what "If $iData < 0 Then $iData += 2^32" does for you.So the Question is: Is there any way to tell the "DIM Process" to use a certain variable type? So that specifying 0xFFFFFFFF doesn't end up with a "-1" ? I mean: Either "tell" autoit to use a unsigned Int32 for storing 0xFFFFFFFF, or use Int64 instead?Regards, Rudi.Not exactly. All variables in AutoIt are, behind the curtain, C-type Variant, because the AutoIt executables are written in C++. The "types" like array, float, or INT32, are just added bits that tell AutoIt what do with the data. By default, you get a signed INT32 from RegRead() of a REG_DWORD, so you get the signed behavior. I already gave you a line of code to fix that, or you can use things like Number(), Binary(), or String() to assign the "type" designator for that variant.If you want a "strongly typed" language, you'll have to quit using AutoIt. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
rudi Posted November 24, 2008 Author Posted November 24, 2008 Hi Psalty, thanks again for your help. Well, I'm still stuck: I have to compare hex values to *GIVEN* REG_DWORD values in the registry, that are specified to *BE* REG_DWORD in several MS KB articles. So I would like to be able to set some Autoit variant to that hex value, then to compare it against the current value to be found in the registry. Honestly, I do not want to use strict variable types, nor to quit using Autoit: I'm just seeking for a solution to do these compares *WITH* Autoit expandcollapse popupDim $RegArr[6][2]= [[5], _ ["4294967295: Compare correct, Reg write correct.", 4294967295], _ ["0xFFFFFFFF: Compare incorrect, Reg write *IS* OK",0xFFFFFFFF], _ ["Dec(0xFFFFFFFF): Compare incorrect, Reg write *WRONG*",dec(0xFFFFFFFF)], _ ["2^32 - 1: Compare correct, Reg write *WRONG*",2^32 -1], _ ["0xFFFFFFFF + 2^32: Compare correct, Reg write *WRONG* (same as above, just specified HEX)",0xFFFFFFFF + 2^32]] For $i = 1 To $RegArr[0][0] ; set the correct value: I'm looking for some way to correctly "catch" REG_DWORD values and to compare them with a given value... RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", 4294967295) ; now read the just (correctly) initialized value back into an autoit variable: $found = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType") ; now compare the value read from registry with that one I want to compare it to: If $found = $RegArr[$i][1] Then $Test = "Values match." Else $Test = "Values do *NOT* match." EndIf ; Write the value to the registry ... RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType", "REG_DWORD", $RegArr[$i][1]) ; ... and read it back into an Autoit Variable again. $ChangedTo = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client\Default\AddIns\RDPDR", "FilterQueueType") ; display, what happend. consolewrite("Loop # " & $i & ", My Value: " & $RegArr[$i][0] & @lf & _ $Test & @LF & _ ConvertedCompare($RegArr[$i][1],$found) & @lf & _ "Data Type: " & VarGetType($found) & @TAB & "Reg-Value found: " & $found & @LF & _ "Data Type: " & VarGetType($RegArr[$i][1])& @TAB & "Value to be set: " & $RegArr[$i][1] & @LF & _ "Data Type: " & VarGetType($ChangedTo)&@TAB & "Value now : " & $ChangedTo& @lf & @LF) Next Func ConvertedCompare($MyVal,$RegFound) $match=$MyVal=$RegFound $dummy="Natively:" & @TAB &@TAB & "MyVal = " & $MyVal & ", RegFound = " & $RegFound& " Match: " & $match if $MyVal < 0 Then $MyVal += 2^32 if $RegFound < 0 Then $RegFound += 2^32 $match=$MyVal=$RegFound $dummy&=@lf & "After "".. &=2^32"": " & @TAB & "MyVal = " & $MyVal & ", RegFound = " & $RegFound& " Match: " & $match Return $dummy EndFunc This is giving these results: expandcollapse popupLoop # 1, My Value: 4294967295: Compare correct, Reg write correct. Values match. Natively: MyVal = 4294967295, RegFound = 4294967295 Match: True After ".. &=2^32": MyVal = 4294967295, RegFound = 4294967295 Match: True Data Type: Double Reg-Value found: 4294967295 Data Type: Int64 Value to be set: 4294967295 Data Type: Double Value now : 4294967295 Loop # 2, My Value: 0xFFFFFFFF: Compare incorrect, Reg write *IS* OK Values do *NOT* match. Natively: MyVal = -1, RegFound = 4294967295 Match: False After ".. &=2^32": MyVal = 4294967295, RegFound = 4294967295 Match: True Data Type: Double Reg-Value found: 4294967295 Data Type: Int32 Value to be set: -1 Data Type: Double Value now : 4294967295 Loop # 3, My Value: Dec(0xFFFFFFFF): Compare incorrect, Reg write *WRONG* Values do *NOT* match. Natively: MyVal = 0, RegFound = 4294967295 Match: False After ".. &=2^32": MyVal = 0, RegFound = 4294967295 Match: False Data Type: Double Reg-Value found: 4294967295 Data Type: Int32 Value to be set: 0 Data Type: Double Value now : 0 Loop # 4, My Value: 2^32 - 1: Compare correct, Reg write *WRONG* Values match. Natively: MyVal = 4294967295, RegFound = 4294967295 Match: True After ".. &=2^32": MyVal = 4294967295, RegFound = 4294967295 Match: True Data Type: Double Reg-Value found: 4294967295 Data Type: Double Value to be set: 4294967295 Data Type: Double Value now : 2147483648 Loop # 5, My Value: 0xFFFFFFFF + 2^32: Compare correct, Reg write *WRONG* (same as above, just specified HEX) Values match. Natively: MyVal = 4294967295, RegFound = 4294967295 Match: True After ".. &=2^32": MyVal = 4294967295, RegFound = 4294967295 Match: True Data Type: Double Reg-Value found: 4294967295 Data Type: Double Value to be set: 4294967295 Data Type: Double Value now : 2147483648 +>10:40:48 AutoIT3.exe ended.rc:0 >Exit code: 0 Time: 0.994 Helpless. Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE!
Administrators Jon Posted November 24, 2008 Administrators Posted November 24, 2008 AutoIt only has signed int32 and signed int64 types. To store a full unsigned int32 we need to use the int64. The hex notation only works for 32bits so you'll have to use decimal notation. Conversion from reg DWORDs to AutoIt int64 types should work fine, just drop the hex notation. Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/
PsaltyDS Posted November 24, 2008 Posted November 24, 2008 AutoIt only has signed int32 and signed int64 types. To store a full unsigned int32 we need to use the int64. The hex notation only works for 32bits so you'll have to use decimal notation.Conversion from reg DWORDs to AutoIt int64 types should work fine, just drop the hex notation.The problem with that is inconsistency. If you RegWrite() a -1 to a REG_DWORD, it will be assumed to be decimal and get converted to Int32 (all ones). But when you RegRead() it get converted to Int64 and becomes 4294967295. (As in my demo in post #2.) I did some Googling around MSDN and all the definitions I could find for REG_DWORD just said "32 bit number". The words "signed" or "unsigned" were frustratingly missing is all the references I found. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
rudi Posted November 24, 2008 Author Posted November 24, 2008 The problem with that is inconsistency. If you RegWrite() a -1 to a REG_DWORD, it will be assumed to be decimal and get converted to Int32 (all ones). But when you RegRead() it get converted to Int64 and becomes 4294967295. (As in my demo in post #2.) I did some Googling around MSDN and all the definitions I could find for REG_DWORD just said "32 bit number". The words "signed" or "unsigned" were frustratingly missing is all the references I found. Thanks for your reply.As you can switch in Regedit.exe between decimal and hex presentation, IMHO from the presented DEC values you can see, that it's unsigned?So it looks like it's a quite tricky task to such a basic thing like: "Check, if this *EXISTING* REG_DWORD matches <0xsomehexvalue>".I didn't expect trouble whith such a simple task. Amazing...I'll have a closer look to that trouble next week. With your replies I'll hopefully find a *comfortable* way around it.Regards, Rudi. Earth is flat, pigs can fly, and Nuclear Power is SAFE!
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