P
pangel83
I've been trying for days to write a piece of VB.NET code that will
read from winamp's memory space the paths of the files from the current
winamp playlist.
The GETPLAYLISTFILE command of the winamp API will only return a
pointer to the position of the asked path. An article available on
http://msmvps.com/ch21st/archive/2004/02/26.aspx provides a VB6
implementation of this, using the ReadProcessMemory Windows API
command. Through digging and asking around, I managed to read the
memory contents that winamp points to, but I can't seem to be able to
decode them!
In the attached code below that contains all you need to recreate my
problem. The function always returns the following giberish:
"UVßwXjÝw
======================================================================
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
MsgBox(Me.GetPlaylistFile(0))
End Sub
Private Const PROCESS_VM_READ As Long = &H10
Private Const IPC_GETPLAYLISTFILE = 211
Private Declare Auto Function FindWindow Lib "user32" (ByVal
lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As
IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As
Integer) As IntPtr
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal
hwnd As IntPtr, ByRef lpdwProcessId As IntPtr) As IntPtr
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Integer, _
ByVal bIneritHandle As Boolean, _
ByVal dwProcessId As IntPtr) As IntPtr
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal
hProcess As IntPtr, ByRef lpBase As IntPtr, ByVal lpBuffer() As Byte,
ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As
Boolean
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
IntPtr) As Boolean
Private Function FindWinamp() As IntPtr
Return FindWindow("Winamp v1.x", vbNullString)
End Function
Public Function GetPlaylistFile(ByVal TrackNo As Integer) As String
Dim winampWindow As IntPtr = FindWinamp()
Dim fileName As String = String.Empty
If Not IsNullPtr(winampWindow) Then
Dim lp As IntPtr = SendMessage(winampWindow, &H400, TrackNo,
IPC_GETPLAYLISTFILE)
If Not IsNullPtr(lp) Then
Dim pid As IntPtr
Call GetWindowThreadProcessId(winampWindow, pid)
If Not IsNullPtr(pid) Then
Dim hWinampProcess As IntPtr = OpenProcess(PROCESS_VM_READ, False, pid)
If Not IsNullPtr(hWinampProcess) Then
Dim buffer(1000) As Byte
Dim bytesWritten As Integer
If ReadProcessMemory(hWinampProcess, lp, buffer, buffer.Length,
bytesWritten) Then
fileName = System.Text.Encoding.Default.GetString(buffer)
End If
CloseHandle(hWinampProcess)
End If
End If
End If
End If
Return fileName
End Function
Private Function IsNullPtr(ByVal ptr As IntPtr) As Boolean
Return ptr.Equals(IntPtr.Zero)
End Function
read from winamp's memory space the paths of the files from the current
winamp playlist.
The GETPLAYLISTFILE command of the winamp API will only return a
pointer to the position of the asked path. An article available on
http://msmvps.com/ch21st/archive/2004/02/26.aspx provides a VB6
implementation of this, using the ReadProcessMemory Windows API
command. Through digging and asking around, I managed to read the
memory contents that winamp points to, but I can't seem to be able to
decode them!
In the attached code below that contains all you need to recreate my
problem. The function always returns the following giberish:
"UVßwXjÝw
======================================================================
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
MsgBox(Me.GetPlaylistFile(0))
End Sub
Private Const PROCESS_VM_READ As Long = &H10
Private Const IPC_GETPLAYLISTFILE = 211
Private Declare Auto Function FindWindow Lib "user32" (ByVal
lpClassName As String, ByVal lpWindowName As String) As IntPtr
Private Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As
IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As
Integer) As IntPtr
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal
hwnd As IntPtr, ByRef lpdwProcessId As IntPtr) As IntPtr
Private Declare Function OpenProcess Lib "kernel32" _
(ByVal dwDesiredAccess As Integer, _
ByVal bIneritHandle As Boolean, _
ByVal dwProcessId As IntPtr) As IntPtr
Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal
hProcess As IntPtr, ByRef lpBase As IntPtr, ByVal lpBuffer() As Byte,
ByVal nSize As Integer, ByRef lpNumberOfBytesWritten As Integer) As
Boolean
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
IntPtr) As Boolean
Private Function FindWinamp() As IntPtr
Return FindWindow("Winamp v1.x", vbNullString)
End Function
Public Function GetPlaylistFile(ByVal TrackNo As Integer) As String
Dim winampWindow As IntPtr = FindWinamp()
Dim fileName As String = String.Empty
If Not IsNullPtr(winampWindow) Then
Dim lp As IntPtr = SendMessage(winampWindow, &H400, TrackNo,
IPC_GETPLAYLISTFILE)
If Not IsNullPtr(lp) Then
Dim pid As IntPtr
Call GetWindowThreadProcessId(winampWindow, pid)
If Not IsNullPtr(pid) Then
Dim hWinampProcess As IntPtr = OpenProcess(PROCESS_VM_READ, False, pid)
If Not IsNullPtr(hWinampProcess) Then
Dim buffer(1000) As Byte
Dim bytesWritten As Integer
If ReadProcessMemory(hWinampProcess, lp, buffer, buffer.Length,
bytesWritten) Then
fileName = System.Text.Encoding.Default.GetString(buffer)
End If
CloseHandle(hWinampProcess)
End If
End If
End If
End If
Return fileName
End Function
Private Function IsNullPtr(ByVal ptr As IntPtr) As Boolean
Return ptr.Equals(IntPtr.Zero)
End Function