Hallo zusammen,
erst mal Danke an hobby_programmer, mm78pr und Martoeng für die Antworten.
Hilfreich war der Link zu AllAPI. Dort habe ich unter ReadProcessMemory (http://www.mentalis.org/apilist/ReadProcessMemory.shtml) nachgeschaut und ein bißchen mehr von der Problematik verstanden. (Es gibt dort auch ein Beispiel.)
Leider bin ich mit meinem eigenlichen Problem noch nicht fertig geworden.
In dem Beispiel auf AllAPI wird ein Memorybereich gelesen dessen Größe vorher bekannt ist. Ich kenne aber die Größe/Länge des Strings der dort gespeichert ist nicht. Das ist halt immer unterschiedlich. Wie kann ich denn ein ByteArray anlegen das auf jedenfall groß genug ist den String aufzunehemen und wie bekomme ich den Byte-String nachher als String heraus? Ich poste mal meinen bisherigen Code, der leider (noch) nicht läuft:
Public Function get_InternInfo(ByVal cmd As Long, Optional ByVal val As Long = _
0) As String
On Error GoTo ErrHandler
' hWndPLAYER ist ein globales Fensterhandle zum
' WinampPlayer
Dim PID As Long ' Used to hold the Process Id
Dim pHandle As Long ' Holds the Process Handle
Dim bytValue As Long ' Stores the value of a byte in the memory
Dim i As Long
Dim Address As Long ' Hält den Pointer auf den Speicherbereich dessen
' String abgefragt werden soll
Dim Bytes As Long ' Hält die Länge des zu lesenden Bereichs
' Get the ProcId of the Window
GetWindowThreadProcessId hWndPLAYER, PID
' use the PID to get a handle
pHandle = OpenProcess(PROCESS_VM_READ, False, PID)
If (pHandle = 0) Then
Exit Function
End If
' Get a pointer into Winamps MemoryMap
' Ergebnis von Sendmessage wird als StringPointer in Address gespeichert
Address = StrPtr(SendMessage(hWndPLAYER, WM_WA_IPC, val, cmd))
If Address = 0 Then
CloseHandle pHandle
Exit Function
End If
' Zu Testzwecken habe ich hier mal 2 Möglichkeiten aufgenommen
Dim AllAPI As Boolean
AllAPI = False
If AllAPI Then
' Versuch 1
' Beispiel von AllAPI
' Länge des zu lesenden Bereichs bestimmen! (Aber wie ???)
Bytes = LenB(Address)
For i = 1 To Bytes Step 2
' Read Byte to Byte
ReadProcessMemory pHandle, Address + i - 1, bytValue, 1, 0&
'value now contains the long value of the byte located in [Address
' + i - 1] pos.
'ReadMemory is a string...
get_InternInfo = get_InternInfo & Chr$(bytValue)
Next
Else
' Versuch 2
' Versuch das Beispiel aus dem Winamp-Forum für VB6 zu nutzen
Dim dwRead As Long
Dim ByteArray(0 To 2048) As Byte
If (ReadProcessMemory(pHandle, Address, ByteArray, LenB(ByteArray), _
dwRead) = 0) Then
CloseHandle pHandle
Exit Function
End If
' null-terminate the buffer, to be on the safe side
ByteArray(dwRead - 1) = CByte(0)
For i = LBound(ByteArray) To UBound(ByteArray)
get_InternInfo = get_InternInfo & Chr$(ByteArray(i))
Next
End If
'Close the Handle
CloseHandle pHandle
Escape:
Exit Function
ErrHandler:
Call ErrMsg(Err, E_Output, E_Output)
Resume Escape
End Function Also der erste Teil bis zu der Verzweigung (If AllAPI Then) läuft. Ich bekomme einen Pointer per SendMessage und StrPtr.
Was noch nicht klappt ist bei Version eins (AllAPI-Beispiel) die Länge des zu lesenden Speichers bestimmen.
Oder bei Variante 2 (die sehr wahrscheinlich eher zum Ziel führt, wenn man sie richtig anwendet) habe ich es noch nicht geschafft einen (Byte)-Buffer anzulegen, der dann die Kopie des zu lesenden Speichers aufnimmt.
Wie lege ich ein Byte-Array an?.
Bestimme ich dann mit LenB die Größe des zu lesenden Speicherbereichs?
dwRead soll dann den Wert (Anzahl) der gelesenen Bytes enthalten. Heißt das, man liest so viel wie der ByteArray-Buffer groß ist, auch wenn der String den man sucht nur z.B. 50 Byte groß ist?. Und in dwRead ist dann 50 hinterlegt?
Bin für jeden Tipp oder jede Erklärung dankbar.
Gruß,
Horst |