[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 375
  • Last Modified:

Formatting the values returned from RegEnumValue

I've been putting together a nice little class for reading and writing to the registry, copying or deleteing registry keys and all of their sub keys and/or values.  


My problem is that after running RegEnumValue, I'm displaying the contents of the values in a grid. This works fine for values of type string, but I'm not formatting the DWORD or BINARY return values correctly for display.  

What I'd like to do, is translate DWORD values so that they display exactly as they do in RegEdit.  So, a DWORD with a hex value of 20000, decimal value of 131072 will display as:

0x00020000 (131072)

and a BINARY value will display as:
9A 01 00 00 34 00 00 00
84 00 00 00 FC 02 00 00

and so on ....

(extra points if you can display it as:)
9A 01 00 00 34 00 00 00  ....4...
84 00 00 00 FC 02 00 00  .....u..

with the character representation on the right.

These are the two main types I need help displaying, but extra points for a more complete answer that formats all of the possible Registry value types.

Here is the kind of function I was trying to write:
(but it's not working properly)

Public Function FormatValue(vValue As Variant, nType As Long) As String
Dim Temp As String
Dim J As Long

 Select Case nType
     Case REG_DWORD
         For J = 1 To Len(vValue)
             Temp = Temp & CStr(CDec(Asc(Mid(vValue, J, 1))))
         Next J
         Temp = "0x0" & Temp & IIf(7 - Len(Temp) > 0, String(7 - Len(Temp), "0"), "")
         FormatValue = Temp
     Case REG_BINARY
         For J = 1 To Len(vValue)
             Temp = Temp & IIf(Len(CStr(Hex(Asc(Mid(vValue, J, 1))))) > 1, "", "0") & CStr(CDec(Asc(Mid(vValue, J, 1)))) & IIf(J Mod 8 = 0, vbCrLf, Space(1))
         Next J
         FormatValue = Temp
     Case Else
         FormatValue = vValue
End Select

End Function
0
mdougan
Asked:
mdougan
  • 5
  • 3
1 Solution
 
GordonpCommented:
Public Function FormatValue(byData() As Byte, nType As Integer) As String

    Select Case nType
        Case REG_DWORD
            Dim dwValue As Long
            CopyMemory dwValue, byData(0), LenB(dwValue)
            FormatValue = Format(dwValue, "0x00000000") & " (" & dwValue & ")"
                       
        Case REG_SZ
            FormatValue = byData

        Case REG_BINARY
            'Coming Soon

    End Select
       
End Function

Heres the DWORD part of your question.

this assumes you copied the data into a byte array from the pointer returned by RegEnumValue.

I'll have the bit for the REG_BINARY just shortly

Gordon
0
 
GordonpCommented:
       Case REG_BINARY
            Dim sLine As String
            Dim sLine2 As String
       
            Dim I As Integer
            For I = 0 To UBound(byData)
                sLine = sLine & Format(byData(I), "00") & " "
                sLine2 = sLine2 & Chr(byData(I))
                               
                If (I Mod 8) = 0 Then
                    FormatValue = FormatValue & vbCrLf & sLine & vbTab & sLine2
                    sLine = ""
                    sLine2 = ""
                End If
            Next

Here the bit for the Binary formatting

Hope this helps

Gordon
0
 
mdouganAuthor Commented:
So far, this looks great, but I hadn't been copying the data to a byte array.  When I tried to do it in your routine I got a type missmatch, so, I'm not sure how to load the byte array.  

Here is the code I use in the enum function, which puts the value into a variant/string.  This type of variable works fine for the routine that copies one tree to another, but if you can suggest how to put the value into a byte array instead of a string/variant then the points are yours:

            nRet = RegEnumValue(hKey, nIndex, ValueName, nValueNameLen, ByVal 0&, nType, ByVal Value, nValueLen)
            If nRet = ERROR_SUCCESS Then
                ReDim Preserve Values(0 To 2, 0 To nStrings) As Variant
                Values(0, nStrings) = Left$(ValueName, nValueNameLen)
                Values(1, nStrings) = Left$(Value, nValueLen - 1)
                Values(2, nStrings) = nType


Or, if you can modify your routine to use a variant/string is the input parm, and then copy to a byte array in the routine, even better.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
mdouganAuthor Commented:
GordonP's answer looks good, but it only takes me half way.  I'm currently getting the value out of RegEnumValue as a variant/string.  To use GordonP's function, I'd need it to be in a byte array.  

So, I'd either need a way to put the value in a Byte Array from RegEnumValue or, better for me, to have GordonP's function accept a variant/string and then do whatever it has to do to format it for display.

I'm opening this back up since GordonP hasn't replied in a couple of days.
0
 
GordonpCommented:
Ok, I'm back.

I was on holiday.

Have you tried passing a byte array to RegEnumValue instead of a string

Other option is to convert your string

Dim byData() as byte
byData = strconv(Value,vbFromUnicode)

Hope these help

Gordon
0
 
mdouganAuthor Commented:
Adjusted points from 150 to 200
0
 
mdouganAuthor Commented:
Thanks!  I was finally able to get it to display as I wanted it to.  I did have to make a few adjustments to your original routine, so I'll post the final version below for the benefit of others that might buy this question.  

Putting the values returned from RegEnumValue into a variant/string type variable worked for me, as I created a two dimensional variant array that would hold the name of the key, the value, and the type of the key.  In all of the code for copying the values or otherwise manipulating the registry, I didn't have to do anything to the value, it was only in displaying it that I had to muck around with it.  So, I was happy to convert it to the byte array in the display routine.  Thanks for the strconv using vbFromUnicode, I don't think I ever would have figured that out on my own.

Some of the things that I had to change to get it to display the binary like RegEdit, I had to pad a line that was less than 8 characters, so that the last line's char rep would line up with the others.  I also changed certain ascii codes to "." in the char rep to match what RegEdit displays.  Also, I added the HEX function to get the hex rep of the decimal values.  This was necessary for both the DWORD and BINARY displays.  I also put in code to keep the very first line of the binary display from being prefaced by a tab.

Thanks again!

Public Function FormatValues(vValue As Variant, nType As Integer) As String
Dim sLine As String
Dim sLine2 As String
Dim i As Integer
Dim byData() As Byte
Dim sTemp As String
   
    byData = StrConv(vValue, vbFromUnicode)
                       
    Select Case nType
        Case REG_DWORD
            Dim dwValue As Long
            CopyMemory dwValue, byData(0), LenB(dwValue)
            sTemp = Hex(dwValue)
            FormatValues = "0x" & IIf(Len(sTemp) < 8, String(8 - Len(sTemp), "0"), "") & sTemp & " (" & dwValue & ")"
                         
        Case REG_SZ
            FormatValues = vValue

        Case REG_BINARY
        For i = 0 To UBound(byData)
            sTemp = Trim(Format(Hex(byData(i)), "@@"))
            sLine = sLine & IIf(Len(sTemp) < 2, "0", "") & sTemp & " "
            sLine2 = sLine2 & IIf((byData(i) < 32 Or _
                                  byData(i) = 127 Or _
                                 (byData(i) >= 129 And byData(i) <= 144) Or _
                                 (byData(i) >= 147 And byData(i) <= 159)), _
                                 ".", Chr(byData(i)))
            If ((i + 1) Mod 8) = 0 Then
                FormatValues = FormatValues & IIf(Len(FormatValues) > 0, vbCrLf, "") & sLine & vbTab & sLine2
                sLine = ""
                sLine2 = ""
            End If
        Next
        FormatValues = FormatValues & IIf(Len(FormatValues) > 0, vbCrLf, "") & sLine & IIf(Len(sLine) < 24, Space(24 - Len(sLine)), "") & vbTab & sLine2
    End Select
         
End Function
0
 
mdouganAuthor Commented:
Thanks again.
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now