Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Registry enumeration

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Registry enumeration

    Registry enumeration
    (Look next post for a console version)

    Updated 2004/11/18

    Have fun...

    Pierre

    Code:
    #COMPILE EXE '#Win 8.03#
    #INCLUDE "Win32Api.Inc" '2003-03-27
     
    GLOBAL hDlg  AS DWORD
    GLOBAL hList AS DWORD
    %Listbox1 = 101
    '______________________________________________________________________________
     
     'Registry Element Size Limits
     'The following table identifies the size limits for the various registry elements.
     
     'Key name
     ' 255 characters
     
     'Value name
     ' 95/98/Me    255 characters
     ' 2000        260 characters ANSI
     ' 2000     16,383 characters Unicode
     ' other    16,383 characters
     
     'Value
     ' Available memory (latest format)
     ' 1MB (standard format)
     ' Me/98/95: 16,300 bytes.
     
     'For Windows 95, there is a 64K limit for the total size of all values of a key.
    '______________________________________________________________________________
     
     'REG_NONE                No defined value type.(0)
     'REG_SZ                  A null-terminated string. It will be a Unicode or ANSI string,
     '                        depending on whether you use the Unicode or ANSI functions.(1)
     'REG_EXPAND_SZ               A null-terminated string that contains unexpanded references to
     '                        environment variables (for example, "%PATH%").
     '                        It will be a Unicode or ANSI string depending on whether you use
     '                        the Unicode or ANSI functions.(2)
     'REG_BINARY              Binary data in any form. (3)
     'REG_DWORD               A 32-bit number.(4)
     'REG_DWORD_LITTLE_ENDIAN A 32-bit number in little-endian format (same as REG_DWORD).
     '                        In little-endian format, the most significant byte of a word
     '                        is the high-order byte. This is the most common format for
     '                        computers running Windows NT and Windows 95.(4)
     'REG_DWORD_BIG_ENDIAN    A 32-bit number in big-endian format. In big-endian format,
     '                        the most significant byte of a word is the low-order byte.(5)
     'REG_LINK                A Unicode symbolic link.(6)
     'REG_MULTI_SZ            An array of null-terminated strings, terminated by two null characters.(7)
     'REG_RESOURCE_LIST       A device-driver resource list.(8)
    '______________________________________________________________________________
     
    FUNCTION EnumValue(Key AS LONG, zStartHere AS ASCIIZ) AS LONG
     LOCAL zValueName    AS ASCIIZ * 16384
     LOCAL sData         AS STRING * 16384 'Can be bigger
     LOCAL Buffer        AS STRING
     LOCAL hKey          AS DWORD
     LOCAL dwIndex       AS DWORD
     LOCAL dwType        AS DWORD
     LOCAL ListCount     AS DWORD
     LOCAL ValueNameSize AS LONG
     LOCAL DataSize      AS LONG
     LOCAL Retval        AS LONG
     LOCAL Counter       AS LONG
     
     IF RegOpenKeyEx(Key, zStartHere, 0, %KEY_READ, hKey) = %ERROR_SUCCESS THEN
     'IF RegOpenKey(Key, zStartHere, hKey) = %ERROR_SUCCESS THEN
       dwIndex = 0
       DO
         ValueNameSize = SIZEOF(zValueName)
         DataSize = SIZEOF(sData)
         Retval = RegEnumValue(hKey, dwIndex, zValueName, ValueNameSize, _
                               BYVAL %NULL,dwType, sData, DataSize)
         IF Retval <> %ERROR_SUCCESS THEN EXIT DO
         Buffer = LEFT$(zValueName, ValueNameSize)
         IF Buffer = "" THEN Buffer = "(Default)"
         SELECT CASE dwType
     
           CASE %REG_SZ
             Buffer = Buffer & " = " & LEFT$(sData, DataSize - 1) & " (REG_SZ)"
     
           CASE %REG_EXPAND_SZ
             Buffer = Buffer & " = " & LEFT$(sData, DataSize - 1) & " (REG_EXPAND_SZ)"
     
           CASE %REG_BINARY
             Buffer = Buffer & " = "
             FOR Counter = 1 TO DataSize
               Buffer = Buffer & " " & HEX$(ASC(sData, Counter),2)
             NEXT
             Buffer = Buffer & " (REG_BINARY " & FORMAT$(DataSize) & " bytes)
     
           CASE %REG_DWORD
             Buffer = Buffer & " = " & STR$(CVDWD(sData)) & " (REG_DWORD)"
     
           CASE %REG_MULTI_SZ
             REPLACE $NUL WITH ", " IN sData
             Buffer = Buffer & " = " & LEFT$(sData, DataSize - 2) & " (REG_MULTI_SZ)"
     
           CASE ELSE
             Buffer = Buffer & " (Data type is" & STR$(dwType) & ")"
     
         END SELECT
         LISTBOX ADD hDlg, %Listbox1, "   " & Buffer
         INCR dwIndex
         ListCount = SendMessage(hList, %LB_GETCOUNT, 0, 0) - 1
         SendMessage hList, %LB_SETSEL, ListCount, 0
         SendMessage hList, %LB_SETCURSEL, ListCount, 0
         UpdateWindow hList
       LOOP
       RegCloseKey hKey
     END IF
     
    END FUNCTION
    '______________________________________________________________________________
     
    FUNCTION EnumKey(Key AS LONG, zStartHere AS ASCIIZ) AS LONG
     LOCAL zBuf          AS ASCIIZ * 256
     LOCAL zClass        AS ASCIIZ * 256
     LOCAL LastWriteTime AS FILETIME
     LOCAL ListCount     AS DWORD
     LOCAL dwIndex       AS LONG
     LOCAL BufLen        AS LONG
     LOCAL ClassLen      AS LONG
     LOCAL RetVal        AS LONG
     LOCAL hKey          AS LONG
     
     IF RegOpenKeyEx(Key, zStartHere, 0, %KEY_ENUMERATE_SUB_KEYS, hKey) = %ERROR_SUCCESS THEN
       EnumValue Key, zStartHere 'Search for ValueName and Data
       DO
         BufLen   = 256
         ClassLen = 256
         Retval = RegEnumKeyEx(hKey, dwIndex, zBuf, BufLen, 0, zClass, ClassLen, LastWriteTime)
         IF Retval <> %ERROR_SUCCESS THEN EXIT DO
         LISTBOX ADD hDlg, %Listbox1, zStartHere & "\" & zBuf
         ListCount = SendMessage(hList, %LB_GETCOUNT,  0, 0) - 1
         SendMessage hList, %LB_SETSEL, ListCount, 0
         SendMessage hList, %LB_SETCURSEL, ListCount, 0
         UpdateWindow hList
         EnumKey Key, zStartHere & "\" & zBuf 'Do a recursive search for more entry...
         INCR dwIndex
       LOOP
       RegCloseKey hKey
     END IF
     
    END FUNCTION
    '______________________________________________________________________________
     
    CALLBACK FUNCTION DlgProc
     LOCAL zStartHere AS ASCIIZ * 256
     
     SELECT CASE CBMSG
     
       CASE %WM_INITDIALOG
         CONTROL HANDLE hDlg, %ListBox1 TO hList
         PostMessage CBHNDL, %WM_USER + 401, 0, 0
     
       CASE %WM_USER + 401
         'zStartHere = "Software\Adobe"                                 'Change to your need
         'zStartHere = "Software\Microsoft\Windows\CurrentVersion"      'Change to your need
         zStartHere = "Software\Microsoft\Windows\CurrentVersion\Setup" 'Change to your need
         LISTBOX ADD hDlg, %Listbox1, zStartHere
         EnumKey %HKEY_LOCAL_MACHINE, zStartHere
         DIALOG SET TEXT CBHNDL, "Registry walk"
     
       CASE %WM_SIZE
         MoveWindow hList, 0, 0, LOWRD(CBLPARAM), HIWRD(CBLPARAM), %TRUE
         FUNCTION = 0
         EXIT FUNCTION
     
     END SELECT
     
    END FUNCTION
    '______________________________________________________________________________
     
    FUNCTION PBMAIN
     
     DIALOG NEW %HWND_DESKTOP, "Registry walk - Please wait...", , , 350, 250, _
                %WS_OVERLAPPEDWINDOW OR %DS_MODALFRAME, TO hDlg  
     
     CONTROL ADD LISTBOX, hdlg, %Listbox1 , , 5, 5, 590, 290, %WS_CHILD OR %WS_VSCROLL, %WS_EX_CLIENTEDGE
     
     DIALOG SHOW MODAL hDlg CALL DlgProc
     
    END FUNCTION
    '______________________________________________________________________________



    [This message has been edited by Pierre Bellisle (edited June 05, 2007).]

  • #2
    That is really cool. I'm very impressed. I goofed of a bit the
    last few days, and it is great to come back online and find a nice
    bit of code like this waiting for me. I hope others realize the
    benefit of it as well.

    ------------------
    Old Navy Chief, Systems Engineer, Systems Analyst, now semi-retired

    Comment


    • #3
      Thank for the kind word Donald,
      note that the code is now updated,
      had many little bugs...

      Pierre

      Added: Also, here is a console version...

      Code:
      #COMPILE EXE '#CC 4.03#
      #INCLUDE "Win32Api.Inc" '2003-03-27
       
      GLOBAL hDlg  AS DWORD
      GLOBAL hList AS DWORD
      %Listbox1 = 101
      '______________________________________________________________________________
       
       'Registry Element Size Limits
       'The following table identifies the size limits for the various registry elements.
       
       'Key name
       ' 255 characters
       
       'Value name
       ' 95/98/Me    255 characters
       ' 2000        260 characters ANSI
       ' 2000     16,383 characters Unicode
       ' other    16,383 characters
       
       'Value
       ' Available memory (latest format)
       ' 1MB (standard format)
       ' Me/98/95: 16,300 bytes.
       
       'For Windows 95, there is a 64K limit for the total size of all values of a key.
      '______________________________________________________________________________
       
       'REG_NONE                No defined value type.(0)
       'REG_SZ                  A null-terminated string. It will be a Unicode or ANSI string,
       '                        depending on whether you use the Unicode or ANSI functions.(1)
       'REG_EXPAND_SZ               A null-terminated string that contains unexpanded references to
       '                        environment variables (for example, "%PATH%").
       '                        It will be a Unicode or ANSI string depending on whether you use
       '                        the Unicode or ANSI functions.(2)
       'REG_BINARY              Binary data in any form. (3)
       'REG_DWORD               A 32-bit number.(4)
       'REG_DWORD_LITTLE_ENDIAN A 32-bit number in little-endian format (same as REG_DWORD).
       '                        In little-endian format, the most significant byte of a word
       '                        is the high-order byte. This is the most common format for
       '                        computers running Windows NT and Windows 95.(4)
       'REG_DWORD_BIG_ENDIAN    A 32-bit number in big-endian format. In big-endian format,
       '                        the most significant byte of a word is the low-order byte.(5)
       'REG_LINK                A Unicode symbolic link.(6)
       'REG_MULTI_SZ            An array of null-terminated strings, terminated by two null characters.(7)
       'REG_RESOURCE_LIST       A device-driver resource list.(8)
      '______________________________________________________________________________
       
      FUNCTION EnumValue(MainKey AS LONG, zStartHere AS ASCIIZ) AS LONG
       LOCAL zValueName    AS ASCIIZ * 16384
       LOCAL sData         AS STRING * 16384 'Can be bigger
       LOCAL Buffer        AS STRING
       LOCAL hKey          AS DWORD
       LOCAL dwIndex       AS DWORD
       LOCAL dwType        AS DWORD
       LOCAL ListCount     AS DWORD
       LOCAL ValueNameSize AS LONG
       LOCAL DataSize      AS LONG
       LOCAL Retval        AS LONG
       LOCAL Counter       AS LONG
       
       IF RegOpenKeyEx(MainKey, zStartHere, 0, %KEY_READ, hKey) = %ERROR_SUCCESS THEN
       'IF RegOpenKey(Key, zStartHere, hKey) = %ERROR_SUCCESS THEN
         dwIndex = 0
         DO
           ValueNameSize = SIZEOF(zValueName)
           DataSize = SIZEOF(sData)
           Retval = RegEnumValue(hKey, dwIndex, zValueName, ValueNameSize, _
                                 BYVAL %NULL,dwType, sData, DataSize)
           IF Retval <> %ERROR_SUCCESS THEN EXIT DO
           Buffer = LEFT$(zValueName, ValueNameSize)
           IF Buffer = "" THEN Buffer = "(Default)"
           SELECT CASE dwType
       
             CASE %REG_SZ
               Buffer = Buffer & " = " & LEFT$(sData, DataSize - 1) & " (REG_SZ)"
       
             CASE %REG_EXPAND_SZ
               Buffer = Buffer & " = " & LEFT$(sData, DataSize - 1) & " (REG_EXPAND_SZ)"
       
             CASE %REG_BINARY
               Buffer = Buffer & " = "
               FOR Counter = 1 TO DataSize
                 Buffer = Buffer & " " & HEX$(ASC(sData, Counter),2)
               NEXT
               Buffer = Buffer & " (REG_BINARY " & FORMAT$(DataSize) & " bytes)
       
             CASE %REG_DWORD
               Buffer = Buffer & " = " & STR$(CVDWD(sData)) & " (REG_DWORD)"
       
             CASE %REG_MULTI_SZ
               REPLACE $NUL WITH ", " IN sData
               Buffer = Buffer & " = " & LEFT$(sData, DataSize - 2) & " (REG_MULTI_SZ)"
       
             CASE ELSE
               Buffer = Buffer & " (Data type is" & STR$(dwType) & ")"
       
           END SELECT
           PRINT "   " & Buffer
           INCR dwIndex
         LOOP
         RegCloseKey hKey
       END IF
       
      END FUNCTION
      '______________________________________________________________________________
       
      FUNCTION EnumKey(MainKey AS LONG, zStartHere AS ASCIIZ) AS LONG
       LOCAL zBuf          AS ASCIIZ * 256
       LOCAL zClass        AS ASCIIZ * 256
       LOCAL LastWriteTime AS FILETIME
       LOCAL ListCount     AS DWORD
       LOCAL dwIndex       AS LONG
       LOCAL BufLen        AS LONG
       LOCAL ClassLen      AS LONG
       LOCAL RetVal        AS LONG
       LOCAL hKey          AS LONG
       
       IF RegOpenKeyEx(MainKey, zStartHere, 0, %KEY_ENUMERATE_SUB_KEYS, hKey) = %ERROR_SUCCESS THEN
         EnumValue MainKey, zStartHere 'Search for ValueName and Data
         DO
           BufLen   = 256
           ClassLen = 256
           Retval = RegEnumKeyEx(hKey, dwIndex, zBuf, BufLen, 0, zClass, ClassLen, LastWriteTime)
           IF Retval <> %ERROR_SUCCESS THEN EXIT DO
           PRINT zStartHere & "\" & zBuf
           EnumKey MainKey, zStartHere & "\" & zBuf 'Do a recursive search for more entry...
           INCR dwIndex
         LOOP
         RegCloseKey hKey
       END IF
       
      END FUNCTION
      '______________________________________________________________________________
       
      FUNCTION PBMAIN
       LOCAL zStartHere AS ASCIIZ * 256 
       
       CONSOLE NAME "Registry walk - Please wait..."
       
       'zStartHere = "Software\Adobe"                                 'Change to your need
       zStartHere = "Software\Microsoft\Windows\CurrentVersion\Setup" 'Change to your need
       
       PRINT "zStartHere = " & zStartHere
       PRINT STRING$(70, "-")
       
       EnumKey %HKEY_LOCAL_MACHINE, zStartHere
       
       CONSOLE NAME "Registry walk" 
       
       PRINT : PRINT "Press any key or click to continue..." : MOUSE ON : MOUSE 3, UP : WAITKEY$
       
      END FUNCTION
      '______________________________________________________________________________


      [This message has been edited by Pierre Bellisle (edited June 05, 2007).]

      Comment


      • #4
        Thank to Donald Darden who found that
        enumeration won't proceed correctly
        when EnumKey is called with an empty zStartHere
        to enumerae from the root registry.

        To avoid this situation in both Console and Windows version...
        Code:
        Replace
         EnumKey Key, zStartHere & "\" & zBuf 'Do a recursive search for more entry...
         
        With
         IF LEN(zStartHere) THEN
           EnumKey Key, zStartHere & "\" & zBuf 'Enumerating from zStartHere\zBuf
         ELSE
           EnumKey Key, zBuf                    'zStartHere is empty, enumerating fromt the root
         END IF

        Comment


        • #5
          Also, need to add ending quote to

          Buffer = Buffer & " (REG_BINARY " & FORMAT$(DataSize) & " bytes)"

          Comment

          Working...
          X