AutoHotkey Community

It is currently May 26th, 2012, 7:30 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: May 3rd, 2009, 3:12 pm 
Offline

Joined: February 7th, 2009, 11:28 pm
Posts: 384
I think AHK would benefit from an expanded SplitPath function or a separate SplitValue function that could automatically split a registry path into: root key, sub key, value name and value.

Also, I hope RegRead can be improved to 1) keep spaces in REG_BINARY values, and 2) retrieve REG_DWORD values in hexadecimal format (with all zeroes included).

Note: Using "SetFormat, IntegerFast, H" is not enough for 2) because it drops some of the zeroes. For example, 0x00000000 would be read as 0x0, which throws off any comparison checks, etc.

I wrote the following function to convert AHK regread output, into the format that I see when look at values with regedit or another registry editor. I'm sure the function is not efficient, in fact, I only used a reg loop to be able to get A_LoopRegType for a specific value per loop, but I'm attaching to clarify what I mean.

Code:
RegValConvert(root="",sub="",vname="")
{
  Loop, %root%, %sub%
  {
    If A_LoopRegName = %vname%
    {
      If A_LoopRegType = REG_DWORD
      {
        SetFormat, IntegerFast, H
        RegRead, valNow2, %root%, %sub%, %vname%
        If SubStr(valNow2,1,2) = "0x"
        {
          If StrLen(valNow2) != 10
          {
            SetFormat, IntegerFast, D
            valNow:= "0x"
            loop, % 10-StrLen(valNow2)
            {
              valNow.= "0"
            }
            valNow.= SubStr(valNow2, 3)
            valNow2=
          }
        }
      }
      Else If A_LoopRegType = REG_BINARY
      {
        RegRead, valNow, %root%, %sub%, %vname%
        loop, parse, valNow  ;  correct how RegRead gets the data
        {
          If (A_Index = 1)
            valNow =
          valNow .= A_LoopField
          If !Mod(A_Index,2)
            valNow .=  " "
        }
        If SubStr(valNow,0,1) = " "
          StringLeft,valNow,valNow,% StrLen(valNow)-1
      }
      Else
        RegRead, valNow, %root%, %sub%, %vname%
      Break
    }
  }
  Return valNow
}


p.s. kudos to jenn for the mod2 piece of code.

_________________
Hardware: 1.8 GHz laptop with 4 GB ram, Windows XP/SP3
Software: Prevx, Privatefirewall, KeyScrambler.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 3rd, 2009, 3:40 pm 
Offline

Joined: February 7th, 2009, 11:28 pm
Posts: 384
also, fwiw, here the function i wrote to split registry value paths, though I assume it's not very well written:

Code:
RegEntrySplit(RegString="")
{
  bslash:= InStr(RegString, "\" )
  global root:= SubStr(RegString, 1, bslash-1), sub:= SubStr(RegString, bslash+1)
  If colon:= InStr(sub, ":" )
  {
    global val:= SubStr(sub, colon+2),valNow:=""
    If SubStr(val,1,1) = """" && SubStr(val, 0,1) = """"
      StringMid,val,val,2,% StrLen(val)-2  ;remove excess "
       
    sub:= SubStr(sub, 1, colon-1)
    bslash:= InStr(sub,"\",false,0)
       
    global vname:= SubStr(sub, bslash+1)
    sub:= SubStr(sub, 1, bslash-1)
       
    RegRead, valNow, %root%, %sub%, %vname%
    If !valNow
      Return 0
    Else
      Return root "\" sub "\" vname ": " val "`n" valNow
  }
  Else
  {
    Loop %root%, %sub%, 1, 1  ; checks if key exists
      keycount++
    If (keycount > 0)
      Return root "`n" sub
    Else
      Return 0
  }
}


p.s. do all REG_DWORD hex values start with 0x?

_________________
Hardware: 1.8 GHz laptop with 4 GB ram, Windows XP/SP3
Software: Prevx, Privatefirewall, KeyScrambler.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: May 4th, 2009, 11:28 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
pajenn wrote:
Also, I hope RegRead can be improved to 1) keep spaces in REG_BINARY values, and 2) retrieve REG_DWORD values in hexadecimal format (with all zeroes included).
AutoHotkey represents binary values as strings of hexadecimal digits. The spaces shown in regedit are purely for display purposes and are not stored in the registry, so they cannot be "kept". Similarly, REG_DWORD values are 32-bit unsigned integers (i.e. double-words), which are purely numbers with no formatting information.
Quote:
Note: Using "SetFormat, IntegerFast, H" is not enough for 2) because it drops some of the zeroes. For example, 0x00000000 would be read as 0x0, which throws off any comparison checks, etc.
What sort of comparison checks? Format is not relevant for numerical comparisons such as regvalue != 0x1 or regvalue > 123. The expression (0 = 0x0000) is always true.

There are ways to do what you want without looping:
Code:
regvalue := "0x0123"

; Format integer as hexadecimal, padding with 0 up to 8 digits.
VarSetCapacity(display,20)
DllCall("msvcrt\sprintf", "str", display, "str", "0x%08x", "uint", regvalue)
MsgBox % display

; Alternate method.
SetFormat, IntegerFast, H
MsgBox % "0x" SubStr("00000000" SubStr(regvalue+0, 3), -7)
Code:
regvalue := "ABCDEF"
; Insert a space every two characters (except at the end).
MsgBox % RegExReplace(regvalue, "..(?=.)", "$0 ")


Report this post
Top
 Profile  
Reply with quote  
PostPosted: May 4th, 2009, 1:57 pm 
Offline

Joined: February 7th, 2009, 11:28 pm
Posts: 384
Lexikos wrote:
What sort of comparison checks? Format is not relevant for numerical comparisons such as regvalue != 0x1 or regvalue > 123. The expression (0 = 0x0000) is always true.


I take a pre- and post-installation snapshot with RegShot, and after uninstalling a program I go over the log using AHK. My script checks if the log entries (files or registry values) still exist, and if so whether they are the same as in the log. The log shows these values the way they appear in regedit, so comparisons for REG_BINARIES and REG_DWORD entries fail unless I first adjust RegRead (or RegShot) output.

Quote:
There are ways to do what you want without looping:


The loop is to get the type (a_LoopRegType) for the value. That's how AHK's help file example (for RegRead) suggests to determine the type for a registry entry.

edit1: sorry, the 'redundant' loop i referred to in my original post was the reg loop that loops through a key to get type for one value, but i realized the loop you referred to was different, and your method's definately better - thanks for the improvement.

From help file:

Code:
RegKeyType(RootKey, SubKey, ValueName)  ; This function returns the type of the specified value.
{
    Loop, %RootKey%, %SubKey%
        if (A_LoopRegName = ValueName)
            return A_LoopRegType
    return "Error"
}


Thank you for the code. The alternate method was three times faster (in a single benchmark I ran), so I replaced my original code with it:

Code:
regvalue := "0x0123"

; Format integer as hexadecimal, padding with 0 up to 8 digits.
VarSetCapacity(display,20)
DllCall("msvcrt\sprintf", "str", display, "str", "0x%08x", "uint", regvalue)
MsgBox % display

; Alternate method.
SetFormat, IntegerFast, H
MsgBox % "0x" SubStr("00000000" SubStr(regvalue+0, 3), -7)


This method doesn't appear to work for longer strings.<snip>

edit2: works great, sorry, my bad applying the code initially. Thanks again.

Code:
;regvalue := "ABCDEF"
; Insert a space every two characters (except at the end).
MsgBox % RegExReplace(regvalue, "..(?=.)", "$0 ")


To your overall point though: I suppose I was too quick to judge AHK's RegRead format. I thought RegShot logs were more correct because that's how the registry values appear (visually) in regedit, but I suppose I need to change my If-statements to compare the underlying values of each representation rather than their forms.

_________________
Hardware: 1.8 GHz laptop with 4 GB ram, Windows XP/SP3
Software: Prevx, Privatefirewall, KeyScrambler.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group