2011-11-24 71 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然後'錯誤 –

相關問題