Announcement

Collapse
No announcement yet.

Registry Read/Write, %REG_BINARY Confusion

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

  • Registry Read/Write, %REG_BINARY Confusion

    I am having a problem with writing and reading binary data from the registry. The code below works to a point but not completely. It is suppose to write 15 bytes to a binary value and read it back. Instead it writes the first 7 bytes after a 8 byte filler of some kind.

    Code:
    Expected: 41 42 43 44 45 31 32 33 34 35 56 57 58 59 5A
      Actual: 9C FD 19 00 0F 00 00 00 41 42 43 44 45 31 32
    Be warned that this code writes to your registry at %HKCU\Software\TestInc\Testing\BinaryData

    Frank

    Code:
    #COMPILER PBWIN
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE "Win32Api.Inc"
    
    TYPE MyRec
      Field1 AS STRING * 5
      Field2 AS STRING * 5
      Field3 AS STRING * 5
    END TYPE
    
    FUNCTION PBMAIN () AS LONG
      LOCAL sSubKey AS STRINGZ * 100: sSubKey = "Software\TestInc\Testing"
      LOCAL sResult AS STRING
      LOCAL dwResult AS DWORD
      LOCAL R AS MyRec
    
      R.Field1 = "ABCDE"
      R.Field2 = "12345"
      R.Field3 = "VWXYZ"
    
      IF SetRegistryBinary(%HKCU, sSubKey, "BinaryData", VARPTR(R), SIZEOF(R)) THEN
        ? "SetRegistryBinary Success!"
      ELSE
        ? "SetRegistryBinary Fail"
      END IF
    
      RESET R
    
      IF GetRegistryBinary(%HKCU, sSubKey, "BinaryData", VARPTR(R), SIZEOF(R)) THEN
        ? "GetRegistryBinary Success=" & R.Field1 & R.Field2 & R.Field3
      ELSE
        ? "GetRegistryBinary Fail"
      END IF
    END FUNCTION
    
    FUNCTION SetRegistryBinary(BYVAL hKey       AS DWORD, _
                               BYVAL sSubKey    AS STRING, _
                               BYVAL sValueName AS STRING, _
                               BYVAL lpData     AS ASCIIZ PTR, _
                               BYVAL cbData     AS LONG) AS LONG
    
      LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = sSubKey
      LOCAL lpValueName AS ASCIIZ * 1024: lpValueName = sValueName
    
      IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
      IF RegCreateKeyEx(hKey, lpSubKey, 0, "", 0, %KEY_WRITE, BYVAL %Null, hKey, BYVAL %Null) = %ERROR_SUCCESS THEN
        IF RegSetValueEx(hKey, lpValueName, 0, %REG_BINARY, lpData, cbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
        RegCloseKey hKey
      END IF
    END FUNCTION
    
    FUNCTION GetRegistryBinary(BYVAL hKey AS DWORD, _
                               BYVAL sSubKey AS STRING, _
                               BYVAL sValue AS STRING, _
                               BYVAL pvData AS ASCIIZ PTR, _
                               BYVAL pcbData AS LONG) AS LONG
    
      LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = sSubKey
      LOCAL lpValue AS ASCIIZ * 1024: lpValue = sValue
    
      IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
      IF RegGetValue(hKey, lpSubKey, lpValue, %RRF_RT_REG_BINARY, BYVAL %Null, pvData, pcbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
      RegCloseKey hKey
    
    ? "RegGetValue pvData=" & @pvData & ", pcbData=" & DEC$(pcbData)
    END FUNCTION

  • #2
    Found it. Searched for hours and only took a few minutes after I post for the light to go on... forgot a couple of @ symbols
    Code:
    #COMPILER PBWIN
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE "Win32Api.Inc"
    
    TYPE MyRec
      Field1 AS STRING * 5
      Field2 AS STRING * 5
      Field3 AS STRING * 5
    END TYPE
    
    FUNCTION PBMAIN () AS LONG
      LOCAL sSubKey AS STRINGZ * 100: sSubKey = "Software\TestInc\Testing"
      LOCAL sResult AS STRING
      LOCAL dwResult AS DWORD
      LOCAL R AS MyRec
    
      R.Field1 = "ABCDE"
      R.Field2 = "12345"
      R.Field3 = "VWXYZ"
    
      IF SetRegistryBinary(%HKCU, sSubKey, "BinaryData", VARPTR(R), SIZEOF(R)) THEN
        ? "SetRegistryBinary Success!"
      ELSE
        ? "SetRegistryBinary Fail"
      END IF
    
      RESET R
    
      IF GetRegistryBinary(%HKCU, sSubKey, "BinaryData", VARPTR(R), SIZEOF(R)) THEN
        ? "GetRegistryBinary Success=" & R.Field1 & "," & R.Field2 & "," & R.Field3
      ELSE
        ? "GetRegistryBinary Fail"
      END IF
    END FUNCTION
    
    FUNCTION SetRegistryBinary(BYVAL hKey       AS DWORD, _
                               BYVAL sSubKey    AS STRING, _
                               BYVAL sValueName AS STRING, _
                               BYVAL lpData     AS ASCIIZ PTR, _
                               BYVAL cbData     AS LONG) AS LONG
    
      LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = sSubKey
      LOCAL lpValueName AS ASCIIZ * 1024: lpValueName = sValueName
    
      IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
      IF RegCreateKeyEx(hKey, lpSubKey, 0, "", 0, %KEY_WRITE, BYVAL %Null, hKey, BYVAL %Null) = %ERROR_SUCCESS THEN
        IF RegSetValueEx(hKey, lpValueName, 0, %REG_BINARY, @lpData, cbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
        RegCloseKey hKey
      END IF
    END FUNCTION
    
    FUNCTION GetRegistryBinary(BYVAL hKey    AS DWORD, _
                               BYVAL sSubKey AS STRING, _
                               BYVAL sValue  AS STRING, _
                               BYVAL pvData  AS ASCIIZ PTR, _
                               BYVAL pcbData AS LONG) AS LONG
    
      LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = sSubKey
      LOCAL lpValue AS ASCIIZ * 1024: lpValue = sValue
    
      IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
      IF RegGetValue(hKey, lpSubKey, lpValue, %RRF_RT_REG_BINARY, BYVAL %Null, @pvData, pcbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
      RegCloseKey hKey
    END FUNCTION

    Comment


    • #3
      Just as a caution...

      I would warn you that using ASCIIZ or WSTRINGZ variables for "binary" data will cause the complier to truncate the data at the first NULL character when reading or writing, making these datatypes unsuitable when the binary data contains a null.
      Michael Mattias
      Tal Systems Inc. (retired)
      Racine WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        Thanks Michael. I have been burnt by that before. In fact this code snippet fails when "Field2="12345" is commented out.

        But the important thing is the registry contains the correct
        Code:
        41 42 43 44 45 00 00 00 00 00 56 57 58 59 5A

        Comment


        • #5
          Did some more playing and added DWORD Read/Write, STRING Read/Write and Key/Value Deletion. Someone as new as me might find it useful.
          Code:
          #COMPILER PBWIN
          #COMPILE EXE
          #DIM ALL
          
          #INCLUDE "Win32Api.Inc"
          
          $Software = "Software"
          $Company = "TestInc"
          $Product = "Testing"
          
          TYPE MyRec
            Field1 AS STRING * 5
            Field2 AS STRING * 5
            Field3 AS STRING * 5
          END TYPE
          
          FUNCTION PBMAIN () AS LONG
            LOCAL sSubKey AS STRING
            LOCAL sResult AS STRING
            LOCAL dwResult AS DWORD
            LOCAL R AS MyRec
          
            R.Field1 = "ABCDE"
            R.Field2 = "12345"
            R.Field3 = "VWXYZ"
            sSubKey = $Software & "\" & $Company & "\" & $Product
          
            IF SetRegistryBinary(%HKCU, sSubKey, "BinaryData", VARPTR(R), SIZEOF(R)) THEN
              RESET R
              IF GetRegistryBinary(%HKCU, sSubKey, "BinaryData", VARPTR(R), SIZEOF(R)) THEN
                ? "Binary=" & R.Field1 & "," & R.Field2 & "," & R.Field3
              ELSE
                ? "Failed reading Binary"
              END IF
            ELSE
              ? "Failed writing Binary"
            END IF
          
            IF SetRegistryDWord(%HKCU, sSubKey, "Count", 1234) THEN
              dwResult = GetRegistryDWord(%HKCU, sSubKey, "Count", 999)
              ? "Count=" & DEC$(dwResult)
            ELSE
              ? "Count Fail"
            END IF
          
            IF SetRegistryString(%HKCU, sSubKey, "WindowPosition", "300" & "," & "300") THEN
              sResult = GetRegistryString(%HKCU, sSubKey, "WindowPosition", "100" & "," & "100")
              ? "WindowPosition=" & sResult
            ELSE
              ? "WindowPosition Fail"
            END IF
          
            IF DeleteRegistryKey(%HKCU, sSubKey, "BinaryData") THEN
              ? "Delete BinaryData success!"
            ELSE
              ? "Delete BinaryData failed!"
            END IF
          
            IF DeleteRegistryKey(%HKCU, sSubKey, "Count") THEN
              ? "Delete Count success!"
            ELSE
              ? "Delete Count failed!"
            END IF
          
            IF DeleteRegistryKey(%HKCU, sSubKey, "WindowPosition") THEN
              ? "Delete WindowPosition success!"
            ELSE
              ? "Delete WindowPosition failed!"
            END IF
          
            IF DeleteRegistryKey(%HKCU, sSubKey, "") THEN
              ? "Delete " & sSubKey & " success!"
            ELSE
              ? "Delete " & sSubKey & " failed!"
            END IF
          
            sSubKey = $Software & "\" & $Company
            IF DeleteRegistryKey(%HKCU, sSubKey, "") THEN
              ? "Delete " & sSubKey & " success!"
            ELSE
              ? "Delete " & sSubKey & " failed!"
            END IF
          END FUNCTION
          
          FUNCTION SetRegistryBinary(BYVAL hKey       AS DWORD, _
                                     BYVAL sSubKey    AS STRING, _
                                     BYVAL sValueName AS STRING, _
                                     BYVAL lpData     AS ASCIIZ PTR, _
                                     BYVAL cbData     AS LONG) AS LONG
          
            LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = TRIM$(sSubKey, "\")
            LOCAL lpValueName AS ASCIIZ * 1024: lpValueName = sValueName
          
            IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
            IF RegCreateKeyEx(hKey, lpSubKey, 0, "", 0, %KEY_WRITE, BYVAL %Null, hKey, BYVAL %Null) = %ERROR_SUCCESS THEN
              IF RegSetValueEx(hKey, lpValueName, 0, %REG_BINARY, @lpData, cbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
              RegCloseKey hKey
            END IF
          END FUNCTION
          
          FUNCTION GetRegistryBinary(BYVAL hKey    AS DWORD, _
                                     BYVAL sSubKey AS STRING, _
                                     BYVAL sValue  AS STRING, _
                                     BYVAL pvData  AS ASCIIZ PTR, _
                                     BYVAL pcbData AS LONG) AS LONG
          
            LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = TRIM$(sSubKey, "\")
            LOCAL lpValue AS ASCIIZ * 1024: lpValue = sValue
          
            IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
            IF RegGetValue(hKey, lpSubKey, lpValue, %RRF_RT_REG_BINARY, BYVAL %Null, @pvData, pcbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
            RegCloseKey hKey
          END FUNCTION
          
          FUNCTION SetRegistryString(BYVAL hKey       AS DWORD, _
                                     BYVAL sSubKey    AS STRING, _
                                     BYVAL sValueName AS STRING, _
                                     BYVAL sData      AS STRING) AS LONG
          
            LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = TRIM$(sSubKey, "\")
            LOCAL lpValueName AS ASCIIZ * 1024: lpValueName = sValueName
            LOCAL lpData AS ASCIIZ * 1024: lpData = sData
            LOCAL cbData AS DWORD: cbData = LEN(lpData)
          
            IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
            IF RegCreateKeyEx(hKey, lpSubKey, 0, "", 0, %KEY_WRITE, BYVAL %Null, hKey, BYVAL %Null) = %ERROR_SUCCESS THEN
              IF RegSetValueEx(hKey, lpValueName, 0, %REG_SZ, lpData, cbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
              RegCloseKey hKey
            END IF
          END FUNCTION
          
          FUNCTION GetRegistryString(BYVAL hKey     AS DWORD, _
                                     BYVAL sSubKey  AS STRING, _
                                     BYVAL sValue   AS STRING, _
                                     BYVAL sDefault AS STRING) AS STRING
          
            LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = TRIM$(sSubKey, "\")
            LOCAL lpValue AS ASCIIZ * 1024: lpValue = sValue
            LOCAL pvData AS ASCIIZ * 1024: pvData = sDefault
            LOCAL pcbData AS DWORD: pcbData = SIZEOF(pvData)
            LOCAL sData AS STRING
          
            IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
            IF RegGetValue(hKey, lpSubKey, lpValue, %RRF_RT_REG_SZ, BYVAL %Null, pvData, pcbData) = %ERROR_SUCCESS THEN
              sData = pvData
              FUNCTION = sData
            END IF
            RegCloseKey hKey
          END FUNCTION
          
          FUNCTION SetRegistryDWord(BYVAL hKey       AS DWORD, _
                                    BYVAL sSubKey    AS STRING, _
                                    BYVAL sValueName AS STRING, _
                                    BYVAL lpData     AS DWORD) AS LONG
          
            LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = TRIM$(sSubKey, "\")
            LOCAL lpValueName AS ASCIIZ * 1024: lpValueName = sValueName
            LOCAL cbData AS DWORD: cbData = SIZEOF(lpData)
          
            IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
            IF RegCreateKeyEx(hKey, lpSubKey, 0, "", 0, %KEY_WRITE, BYVAL %Null, hKey, BYVAL %Null) = %ERROR_SUCCESS THEN
              IF RegSetValueEx(hKey, lpValueName, 0, %REG_DWORD, lpData, cbData) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
              RegCloseKey hKey
            END IF
          END FUNCTION
          
          FUNCTION GetRegistryDWord(BYVAL hKey      AS DWORD, _
                                    BYVAL sSubKey   AS STRING, _
                                    BYVAL sValue    AS STRING, _
                                    BYVAL dwDefault AS DWORD) AS DWORD
          
            LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = TRIM$(sSubKey, "\")
            LOCAL lpValue AS ASCIIZ * 1024: lpValue = sValue
            LOCAL pvData AS DWORD: pvData = dwDefault
            LOCAL pcbData AS DWORD: pcbData = SIZEOF(pvData)
          
            IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
            IF RegGetValue(hKey, lpSubKey, lpValue, %RRF_RT_REG_DWORD, BYVAL %Null, pvData, pcbData) = %ERROR_SUCCESS THEN
              FUNCTION = pvData
            END IF
            RegCloseKey hKey
          END FUNCTION
          
          FUNCTION DeleteRegistryKey(BYVAL hKey       AS DWORD, _
                                     BYVAL sSubKey    AS STRING, _
                                     BYVAL sValueName AS STRING) AS LONG
          
            LOCAL lpSubKey AS ASCIIZ * 1024: lpSubKey = TRIM$(sSubKey, "\")
            LOCAL lpValueName AS ASCIIZ * 1024: lpValueName = sValueName
          
            IF hKey = 0 THEN hKey = %HKEY_CURRENT_USER
            IF lpSubKey <> "" THEN
              IF sValueName <> "" THEN
                IF RegOpenKeyEx(hKey, lpSubKey, 0, %KEY_SET_VALUE, hKey) = %ERROR_SUCCESS THEN
                  IF RegDeleteValue(hKey, lpValueName) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
                  RegCloseKey hKey
                END IF
              ELSE
                IF RegDeleteKeyEx(hKey, lpSubKey, %KEY_WOW64_64KEY, 0) = %ERROR_SUCCESS THEN FUNCTION = %TRUE
              END IF
            END IF
          END FUNCTION

          Comment


          • #6
            Someone as new as me might find it usefull
            I think there are also multiple "personal favorite registry access functions" posted in the source code forum.
            Michael Mattias
            Tal Systems Inc. (retired)
            Racine WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Now there is one more. You never know what future searchers might need.

              Comment


              • #8
                Originally posted by Frank Rogers View Post
                Now there is one more. You never know what future searchers might need.
                And one more in the Print PDF thread now.
                https://forum.powerbasic.com/forum/u...386#post797386

                Comment


                • #9
                  Yep, I haven't needed to get the default program for a given extension yet, but I know where to look.

                  Comment


                  • #10
                    Originally posted by Frank Rogers View Post
                    Yep, I haven't needed to get the default program for a given extension yet, but I know where to look.
                    I knocked that one up quickly last night based on a function I wrote years ago. To open/view a document, just change "
                    "\SHELL\PRINT\command" to " "\SHELL\OPEN\command"

                    I use the "opener" function quite often in document management systems to check that the user has a default application configured for a selected file type.
                    It's better than ShellExecute("Open"...) failing because they don't have something configured for a file they select.

                    It also lets you play tricks with the the operating system like opening ".dat" or .csv files with the default ".txt" application to get round MS's horrible habit of configuring Excel as the default application for .csv files.

                    It also identifies the default browser for .html etc files.

                    .

                    Comment

                    Working...
                    X