Attempted to read or write protected memory. This is often an indication that other memory is corrupt

jack rasha picture jack rasha · Nov 24, 2011 · Viewed 17.2k times · Source

I am using the following code

This error occurs :

Attempted to read or write protected memory. This is often an indication that other memory is corrupt. Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Public Class FormRegEnumValue

Private Const ERROR_SUCCESS = 0&
Private Const ERROR_NO_MORE_ITEMS = 259&
Private Const HKEY_CURRENT_USER = &H80000001

Private Const REG_BINARY = 3
Private Const REG_DWORD = 4
Private Const REG_EXPAND_SZ = 2
Private Const REG_SZ = 1

Private Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, ByVal lpcbValueName As Long, ByVal lpReserved As Long, ByVal lpType As Long, ByVal lpData As Object, ByVal lpcbData As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal phkResult As Long) As Long


Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim hKey As Long, num As Long, strName As String
    Dim strData As String, Retval As Long, RetvalData As Long

    Const Buffer As Long = 255
    num = 0
    strName = Space(Buffer)
    strData = Space(Buffer)
    Retval = Buffer
    RetvalData = Buffer
    If RegOpenKey(HKEY_CURRENT_USER, "Control Panel\Desktop", hKey) = 0 Then 'error
        While RegEnumValue(hKey, num, strName, Retval, 0, 0&, strData, RetvalData) <> ERROR_NO_MORE_ITEMS
            If RetvalData > 0 Then
                ListBox1.Items.Add(strName + Retval + "  =  " + strData + RetvalData - 1)
            End If
            num = num + 1
            strName = Space(Buffer)
            strData = Space(Buffer)
            Retval = Buffer
            RetvalData = Buffer
        End While
        RegCloseKey(hKey)
    Else
        ListBox1.Items.Add("Error")
    End If
End Sub
End Class

Please show me the right way

Answer

Hand-E-Food picture Hand-E-Food · Nov 24, 2011

This is usually caused by an incorrect Private Declare Function statement. The types listed in the Windows API are different to those used in VB or C# code. This is a great list of data type conversions between the Windows API and .Net: Win32 API C++ to .NET

The PInvoke site often has the correct VB code listed.

For RegEnumValue, fix the data types, and lpcValueName is a ByRef, not a ByVal:

Declare Auto Function RegEnumValue Lib "Advapi32" ( _
    ByVal hKey As IntPtr, _
    ByVal dwIndex As Integer, _
    ByVal lpValueName As StringBuilder, _
    ByRef lpcValueName As Integer, _
    ByVal lpReserved As IntPtr, _
    ByVal lpType As IntPtr, _
    ByVal lpData As IntPtr, _
    ByVal lpcbData As IntPtr _
) As Integer

For RegCloseKey, just fix the data types:

Declare Function RegCloseKey Lib "advapi32.dll" ( _
    ByVal hKey As UIntPtr _
) As Integer

For RegOpenKey, fix the data types and change phkResult to a ByRef:

Private Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" ( _
    ByVal hKey As Integer, _
    ByVal lpSubKey As String, _
    ByRef phkResult As IntPtr _
) As Integer

So your function should look more like this. Unfortunately, I'm not sure what to write for strData or RetvalData. I added in a Try/Finally block which will make sure RegCloseKey is called even if an error occurs. You want to make sure you always close things, especially if something goes wrong.

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Const Buffer As Long = 255
    Dim hKey As IntPtr = IntPtr.Zero
    Dim num As Integer = 0
    Dim strName As New StringBuilder
    Dim strData As IntPtr = ' I'm not surte what goes here.
    Dim Retval As Integer = Buffer
    Dim RetvalData As IntPtr = ' I'm not surte what goes here.
    If RegOpenKey(HKEY_CURRENT_USER, "Control Panel\Desktop", hKey) = 0 Then 'error
        Try
            While RegEnumValue(hKey, num, strName, Retval, IntPtr.Zero, IntPtr.Zero, strData, RetvalData) <> ERROR_NO_MORE_ITEMS
                If RetvalData > 0 Then
                    ListBox1.Items.Add(strName.ToString + Retval + "  =  " + strData + RetvalData - 1)
                End If
                num = num + 1
                strName = New StringBuilder(Buffer)
                strData = ' I'm not sure what goes here.
                Retval = Buffer
                RetvalData = ' I'm not surte what goes here.
            End While
        Finally
            RegCloseKey(hKey)
        End Try
    Else
        ListBox1.Items.Add("Error")
    End If
End Sub