Solved

Formatting the values returned from RegEnumValue

Posted on 2000-03-30
8
330 Views
Last Modified: 2008-03-10
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
Comment
Question by:mdougan
  • 5
  • 3
8 Comments
 
LVL 3

Accepted Solution

by:
Gordonp earned 200 total points
Comment Utility
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
 
LVL 3

Expert Comment

by:Gordonp
Comment Utility
       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
 
LVL 18

Author Comment

by:mdougan
Comment Utility
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
 
LVL 18

Author Comment

by:mdougan
Comment Utility
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 3

Expert Comment

by:Gordonp
Comment Utility
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
 
LVL 18

Author Comment

by:mdougan
Comment Utility
Adjusted points from 150 to 200
0
 
LVL 18

Author Comment

by:mdougan
Comment Utility
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
 
LVL 18

Author Comment

by:mdougan
Comment Utility
Thanks again.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

I’ve seen a number of people looking for examples of how to access web services from VB6.  I’ve been using a test harness I built in VB6 (using many resources I found online) that I use for small projects to work out how to communicate with web serv…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now