By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
464,712 Members | 1,362 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 464,712 IT Pros & Developers. It's quick & easy.

Help! - Reading playlist files from winamp through Windows & Winamp APIs & .NET - Decoding memory contents

P: n/a
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:
"UVwXjw

================================================== ====================

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

Nov 21 '05 #1
Share this Question
Share on Google+
1 Reply

P: n/a
The error lies in the fact that the lpBase argument of the ReadProcessMemory
declaration should be declared ByVal, not ByRef.

Hope this helps,
Stefan
<pa******@gmail.com> wrote in message
news:11**********************@g43g2000cwa.googlegr oups.com...
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:
"UVwXjw

================================================== ====================

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
Nov 21 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.