MSN Messenger 7 Current Playing Song
#1
Posted 13 February 2005 - 02:36 PM
The toaster plugin shown on mess.be does it.
I think it has something to do with psmsong.dll in your Msn Messenger directory,
but I can't add a reference to it with Visual Basic 6
#2
Posted 13 February 2005 - 02:58 PM
http://msdn.microsof...wm_copydata.asp
#3
Posted 13 February 2005 - 07:16 PM
Can't figure out what text I should send to the MsnMsgrUIManager window
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal Hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Const WM_COPYDATA = &H4A
Private Sub Form_Load()
'Change the song
ChangeSong "textgoeshere"
End Sub
Private Sub ChangeSong(Song As String)
' Declarations
Dim sString As String
Dim lHwnd As Long
Dim cds As COPYDATASTRUCT
Dim buf(1 To 255) As Byte
' Check string
sString = Trim$(Song)
If sString = "" Then Exit Sub
' Get the handle of the target application.
lHwnd = FindWindow("MsnMsgrUIManager", vbNullString)
' Copy the string into a byte array,
' converting it to ASCII. Assign lpData
' the address of the byte array.
Call CopyMemory(buf(1), ByVal sString, Len(sString))
With cds
.dwData = 3
.cbData = Len(sString) + 1
.lpData = VarPtr(buf(1))
End With
' Send the string.
Call SendMessage(lHwnd, WM_COPYDATA, Me.Hwnd, cds)
End Sub
#4
Posted 14 February 2005 - 01:15 AM
#define MAGIC_NUMBER 0x547
COPYDATASTRUCT msndata;
struct msnmsgstruct
{
int msncommand;
WCHAR title[100];
WCHAR artist[100];
WCHAR album[100];
WCHAR wmcontentid[40];
};
msnmsgstruct msnpush;
ZeroMemory(&msnpush, sizeof(msnpush));
msnpush.msncommand = 1;
lstrcpyW(msnpush.title, L"Title");
lstrcpyW(msnpush.artist, L"Artist");
lstrcpyW(msnpush.album, L"Album");
lstrcpyW(msnpush.wmcontentid, L"WMContentID");
HWND msnui = FindWindow("MsnMsgrUIManager", NULL);
msndata.dwData = MAGIC_NUMBER;
msndata.lpData = &msnpush;
msndata.cbData = sizeof(msnpush);
SendMessage(msnui, WM_COPYDATA, (WPARAM)plugin.hwndParent, (LPARAM)&msndata);Send msnpush.msncommand = 0 to clear the song.
Apparently the new plugin on mess.be is "a complete port of the Windows Media Player plug-in, so it should also send extra data about the song you are playing.". Which I can tell you now is complete garbage.
I am not sur what "extra" information they are talking about, but dissambling that binary shows they are doing the exact above code, except not filling in the wmcontent id field. Which is exactly what Toaster does, except it also works with http streams and lets you customize what is displayed using ATF etc.
This post has been edited by Daniel: 14 February 2005 - 08:21 AM
#5
Posted 14 February 2005 - 07:12 AM
.text:00580877 mov ecx, [ebp+8] ; ECX = msgid .text:0058087A mov [ebp-14h], eax .text:0058087D push edi .text:0058087E xor edi, edi .text:00580880 mov eax, PSM_REBOOTSYSTEM .text:00580885 cmp ecx, eax .text:00580887 mov [ebp-10h], esp .text:0058088A mov [ebp-30Ch], ebx .text:00580890 mov [ebp-318h], edi .text:00580896 ja morethan46a ; WM messages greater than 0x46a .text:0058089C jz equalto46a ; Equal to 0x46a (PS_REBOOTSYSTEM) .text:005808A2 add eax, 0FFFFFFC7h; EAX = 0x431 .text:005808A5 cmp ecx, eax .text:005808A7 ja between431and46a; More than 0x431 (1073) & less than 0x46a .text:005808AD jz equalto431 ; Equal to 0x431 .text:005808B3 mov eax, WM_TIMER .text:005808B8 cmp ecx, eax .text:005808BA ja morethan113 ; Greater than 0x113 (275) (WM_TIMER) .text:005808C0 jz equaltowmtimer .text:005808C6 cmp ecx, WM_QUERYENDSESSION .text:005808C9 jz loc_580990 .text:005808CF cmp ecx, WM_SYSCOLORCHANGE .text:005808D2 jz loc_580986 .text:005808D8 cmp ecx, WM_SETTINGCHANGE .text:005808DB jz loc_580974 .text:005808E1 cmp ecx, WM_COPYDATA .text:005808E4 jnz abortwndproc .text:005808EA mov ecx, [ebp+10h] ; ECX = COPYDATASTRUCT .text:005808ED cmp ecx, edi ; EDI = 0 .text:005808EF jz abortwndproc .text:005808F5 cmp dword ptr [ecx], 547h; Magic number .text:005808FB jnz abortwndproc .text:00580901 mov eax, 2ACh ; Expected cbData size .text:00580906 cmp [ecx+4], eax ; +4 = cbData .text:00580909 jnz short wrongdatasize .text:0058090B mov ecx, [ecx+8] ; +8 = lpData .text:0058090E cmp ecx, edi .text:00580910 jz short nulllpdata .text:00580912 and [ebp-4], edi .text:00580915 push eax ; ucb .text:00580916 push ecx ; lp .text:00580917 call ds:IsBadReadPtr .text:0058091D test eax, eax .text:0058091F jnz short nulllpdata
What it does show though, is there are a lot of WM_USER+ messages (msgids over 0x400) which are reserved for custom messages. Exactly what these do is yet to be dermined :)
#6
Posted 14 February 2005 - 07:53 AM
Could you explain what taht msnpush is?
You are using it like a msnmsgsstruct here:
lstrcpyW(msnpush.title, L"Title"); lstrcpyW(msnpush.artist, L"Artist"); lstrcpyW(msnpush.album, L"Album"); lstrcpyW(msnpush.wmcontentid, L"WMContentID");
But you are using it like a long (not sure) here:
msndata.lpData = &msnpush; msndata.cbData = sizeof(msnpush);
I was trying to translate that code to VB, but i can't have that working :(
#7
Posted 14 February 2005 - 08:20 AM
Option Explicit
Private Type msnmsgstruct
msncommand As Integer
title As String
artist As String
album As String
wmcontentid As String
End Type
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_COPYDATA = &H4A
Private Sub Form_Load()
Dim msndata As COPYDATASTRUCT
Dim msnpush As msnmsgstruct
Dim msnui As Long
msnpush.msncommand = 1
msnpush.title = "Title"
msnpush.artist = "Artist"
msnpush.album = "Album"
msnpush.wmcontentid = "WMContentID"
msnui = FindWindow("MsnMsgrUIManager", vbNullString)
msndata.dwData = &H2AC
msndata.lpData = VarPtr(msnpush)
msndata.cbData = Len(msnpush)
Call SendMessage(msnui, WM_COPYDATA, Me.hwnd, msndata)
End SubI think this bit is wrong:
msndata.lpData = VarPtr(msnpush) msndata.cbData = Len(msnpush)
So it doesn't work... I can't remember how you're meant to do it but I'll look around.
#8
Posted 14 February 2005 - 08:43 AM
Also note the strings are in *unicode*.
with regards to the msnpush, it is just a variable of type msnmsgstruct. msndata is a variable of type COPYDATASTRUCT. I am not using it like a long, in C the use of & means the address of/pointer to the variable
I have reverse engineered all the window messages possible to send to the MsnMsgrUIManager window class. They are as follows:
0x42c - quit msngr
0x42d - Nothing (make ui visible?)
0x42e - Nothing (make ui visible?)
0x431 - allow mobile contacts msgbox
0x433 - nothing
0x43c - nothing
0x446 - crash
0x465 - crash
0x466 - preferences dialog
0x467 - crash with wparam/lparam
0x469 - sign out
0x46a - audiotuning wizard
0x464 - minimize window
0x52c - crash with wparam
0x5f5 - nothing
0x5f6 - nothing
0xd01 - nothing
0x9d0f - nothing
WM_QUERYENDSESSION
WM_SYSCOLORCHANGE
WM_SETTINGCHANGE
WM_TIMER
WM_COPYDATA - update song title information
Note that most of these are designed to be called from with msn's process space, hence the crashes or 'nothing' behaviour.
This post has been edited by shaneh: 14 February 2005 - 08:47 AM
#10
Posted 14 February 2005 - 08:59 AM
You need an array of 100 wide characters, not a pointer to a string. The pointers are taking up just 4 bytes, you need 200 (100 wide characters = 200 bytes) per title/artist/album.
Im not even sure whether its possible to do it in VB (ugh).
@5XC: reverse engineering - http://en.wikipedia....rse_engineering
This post has been edited by shaneh: 14 February 2005 - 09:01 AM
#12
Posted 14 February 2005 - 09:07 AM
This post has been edited by shaneh: 14 February 2005 - 09:08 AM
#14
Posted 14 February 2005 - 01:59 PM
MSNData.lpData = VarPtr(MSNPush) MSNData.cbData = &H2ACHowever, it does not show the song, only some squares (I already tried to convert it to unicode, but it won't work)..
I guess it's because of how VB uses string (like shaneh said)... Is there any way to use that WCHAR in vb?
This post has been edited by opperator: 14 February 2005 - 01:59 PM
#15
Posted 14 February 2005 - 02:29 PM
Type msnstruct intMsnCommand As Integer szTitle (0 To 200) As Byte szArtist (0 To 200) As Byte szTitle (0 To 200) As Byte szWmCommand (0 To 80) As Byte End Type
This is necessary because the strings cannot be of variable length, the buffers need to start at the 1/201/401/601 boundries.
you might be able to just do, szTitle = "title" & vbNullChar
or you may need to use CopyMemory or strconv converstion. I have little experience with VB (nor do I want to), so Im not sure. Personnally, I'd use a different language than VB.
This post has been edited by shaneh: 14 February 2005 - 02:46 PM
#19
Posted 14 February 2005 - 10:04 PM
Option Explicit
Private Type msnmsgstruct
msncommand As Integer
Title(0 To 200) As Byte
Artist(0 To 200) As Byte
Album(0 To 200) As Byte
WmCommand(0 To 80) As Byte
End Type
Private Type COPYDATASTRUCT
dwData As Long
cbData As Long
lpData As Long
End Type
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const WM_COPYDATA = &H4A
Private Sub Form_Load()
'Change the Msn song info
Call ChangeSong("This is the title", "This is the artist", "This is the album")
End Sub
Private Sub Form_Unload(Cancel As Integer)
'Song stops playing
Call StopSong
End Sub
Public Sub ChangeSong(sTitle As String, sArtist As String, sAlbum As String)
Dim msndata As COPYDATASTRUCT
Dim msnpush As msnmsgstruct
Dim msnui As Long
Dim i As Integer
msnpush.msncommand = 1
'change title
sTitle = Chr(0) & sTitle
For i = 0 To Len(sTitle) - 1
msnpush.Title(i * 2) = Asc(Mid(sTitle, i + 1, 1))
Next
'change artist
sArtist = Chr(0) & sArtist
For i = 1 To Len(sArtist) - 1
msnpush.Artist((i * 2) - 1) = Asc(Mid(sArtist, i + 1, 1))
Next
'change album
For i = 0 To Len(sAlbum) - 1
msnpush.Album(i * 2) = Asc(Mid(sAlbum, i + 1, 1))
Next
'Find window & Send message
msnui = FindWindow("MsnMsgrUIManager", vbNullString)
msndata.dwData = &H547
msndata.lpData = VarPtr(msnpush)
msndata.cbData = &H2AC
Call SendMessage(msnui, WM_COPYDATA, Me.hwnd, msndata)
End Sub
Public Sub StopSong()
Dim msndata As COPYDATASTRUCT
Dim msnpush As msnmsgstruct
Dim msnui As Long
'Find window & Send message
msnui = FindWindow("MsnMsgrUIManager", vbNullString)
msndata.dwData = &H547
msndata.lpData = VarPtr(msnpush)
msndata.cbData = &H2AC
Call SendMessage(msnui, WM_COPYDATA, Me.hwnd, msndata)
End Subworks great :)
This post has been edited by silverspeed: 14 February 2005 - 10:12 PM

Sign In
Register
Help


MultiQuote