2011-11-24 88 views
3

我使用下面的代码试图读取或写入受保护的内存。这通常是指示其他内存已损坏

出现此错误:

试图读取或写入保护内存。这通常表明其他内存已损坏。 试图读取或写入受保护的内存。这通常表明其他内存已损坏。

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 

请告诉我正确的方式

回答

4

这通常是由不正确的Private Declare Function语句引起的。 Windows API中列出的类型与VB或C#代码中使用的类型不同。这是Windows API和.Net之间数据类型转换的很好列表:Win32 API C++ to .NET

PInvoke网站通常会列出正确的VB代码。

对于RegEnumValue,固定的数据类型,和lpcValueName是一个为ByRef,而不是一个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 

对于RegCloseKey,只是固定的数据类型:

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

对于RegOpenKey,修复数据类型并将phkResult更改为ByRef:

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

所以你的功能应该看起来更像这样。不幸的是,我不确定要写什么strDataRetvalData。我加入了一个Try/Finally块,即使发生错误,也会确保调用RegCloseKey。你想确保你总是关闭事情,特别是如果出现问题。

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 
+0

如何使用RegEnumValue函数? –

+0

增加用法来回答。 –

1

使用包含在内置Microsoft.Win32.Registry命名空间,而不是功能。

你可以在MSDN找到参考和大量的例子。

更新

如果你需要使用的API,然后RegEnumValue签名已改为类似:

Declare Function RegEnumValue Lib "advapi32.dll" Alias "RegEnumValueA"(ByVal hKey As Integer, ByVal dwIndex As Integer, ByVal lpValueName As String, ByRef lpcbValueName As Integer, ByVal lpReserved As Integer, ByRef lpType As Integer, ByRef lpData As StringBuilder, ByRef lpcbData As Integer) As Integer 

然后,strData是的类型更改为StringBuilder的创造一个StringBuilder的新实例,你正在用空格填充strData:

strData = New StringBuilder(buffer) 

可能需要t o其他变化也是如此,但这是目前最大的变化。

更新2

其他声明需要有自己的长值改为整数和RegOpenKey结果参数为ByRef:

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

更新3

审查后我的旧API代码,我发现你需要做相当多的额外工作才能处理结果:

一旦您确定RegEnumValue成功(返回值为0),您需要根据结束时的3参数(lpType)处理结果,这会告诉您数据的类型。

然后,根据类型(即REG_SZ,REG_DWORD,等等),你将需要调用的函数RegQueryValueExA API方法之一:

Declare Function RegQueryValueExString Lib "advapi32.dll" Alias "RegQueryValueExA"(ByVal hKey As Integer, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As Integer, ByVal lpData As String, ByRef lpcbData As Integer) As Integer 

Declare Function RegQueryValueExLong Lib "advapi32.dll" Alias "RegQueryValueExA"(ByVal hKey As Integer, ByVal lpValueName As String, ByVal lpReserved As Integer, ByRef lpType As Integer, ByRef lpData As Integer, ByRef lpcbData As Integer) As Integer 

等,以便于检索值注册表项。

+0

我想使用API​​ –

+0

@jack rasha:用RegEnumValueA和附加信息的正确签名更新了答案。 –

+0

错误:如果RegOpenKey(HKEY_CURRENT_USER,“控制面板\桌面”,hKey)= 0然后'错误 –

相关问题