Old 20th April 2002, 20:21   #1
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
Solution: Get FileName from external app/dll

It IS possible!
Some guy wrote the pointers aren´t valid, because every process has its own 32bit memory address block.
Thats True, but there are some nice functions which let you access the memory space of another process...

I wrote an example how to get the FileName....in Delphi, but the functions should be the same in C or whatever:

code:

function GetWinampFilename: String;
var Text, tempStr: String;
hwndWinamp, TempHandle : THandle;
dat2: array[0..500] of Char;
TrackPos: Integer;
temp, MPointer: Cardinal;
begin
hwndWinamp:= FindWindow('Winamp v1.x',nil);
TrackPos:= SendMessage(hwndWinamp,WM_USER,0 , 125);
MPointer:= SendMessage(hwndWinamp,WM_USER,TrackPos , 211);
GetWindowThreadProcessId(hwndWinamp,TempHandle);
hwndWinamp:= OpenProcess(PROCESS_ALL_ACCESS,False,TempHandle);
ReadProcessMemory(hwndWinamp, Pointer(MPointer), @dat2,500,temp);
CloseHandle(hwndWinamp);
tempStr:= dat2; // ;-)
Result:= tempStr;
end;



First we get the Winamp handle, as usual.
Then we get the actual played track, as usual.
Then the Pointer to the Filename (MPointer).

This Pointer is not valid in our dll´s process memory.
So we need to Read in Winamp´s process memory.
ReadProcessMemory(); does this.
OpenProcess gives us a new handle, on which we have Read/Write Access.
Otherwise we get an EAccessViolation.
the filename is stored in dat2.

With C there may be some string copy actions necessary.
But this should be no problem...


I hope i helped some of you "I don´t like a winamp plugin" guys
Heiko S.

PS: I wrote a simple example dll for mIRC which puts out the usual stuff on command. (trackname, time, kbps etc..)
Any questions about that are welcome.
And Sorry for neglecting any existing name conventions
HeikoSS is offline   Reply With Quote
Old 20th April 2002, 20:29   #2
peter
ist death
 
peter's Avatar
 
Join Date: May 2000
Posts: 3,704
yeah, nice. which windows OS did you test that in ?
peter is offline   Reply With Quote
Old 20th April 2002, 20:31   #3
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
Windows 2000

So i think for Win95/98/ME/ NT it should work surely.

Windows XP...idk (but i may look...tomorrow..)

Heiko S.
HeikoSS is offline   Reply With Quote
Old 20th April 2002, 20:41   #4
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
-deleted
HeikoSS is offline   Reply With Quote
Old 20th April 2002, 21:17   #5
peter
ist death
 
peter's Avatar
 
Join Date: May 2000
Posts: 3,704
i was only afraid about win2k and similar, but if it works then it's OK.
peter is offline   Reply With Quote
Old 22nd April 2002, 01:38   #6
Gourou
Senior Member
 
Gourou's Avatar
 
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
the probable conversion to vb..... but it doesnt work

Dim hwndWinamp As Long
Dim TempHandle As Long
Dim dat2 As String * 256
Dim TrackPos As Long
Dim temp As Long
Dim MPointer As Long
Public Const WM_USER = &H400
Public Const PROCESS_VM_READ = &H10
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
Dim pTemp As Long
Dim nTemp As Long

Public Function ShowTitle() As String

hwndWinamp = FindWindow("Winamp v1.x", vbNullString)
TrackPos = SendMessage(hwndWinamp, &H400, 0, 125)
MPointer = SendMessage(hwndWinamp, &H400, TrackPos, 211)
temp = GetWindowThreadProcessId(hwndWinamp, TempHandle)
hwndWinamp = OpenProcess(PROCESS_VM_READ, False, TempHandle)
pTemp = lstrcpy(dat2, dat2)
nTemp = ReadProcessMemory(hwndWinamp, MPointer, pTemp, 256, temp)
temp = CloseHandle(hwndWinamp)
ShowTitle = dat2

End Function


it shows that the read process memory works, that it copies 256, but all that's in my string is null characters, it doesnt change anything, nothing at all. changing anything around gives me some lovely access violations, the worst being where visual studio disappears without a trace..now if only my frozen programs could do that, anyway, that's where I'm at, any help would be most appreciated, thnx in advance.
Gourou is offline   Reply With Quote
Old 22nd April 2002, 06:59   #7
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
Hi again,
I don´t know much about VB...
But here are some things i found:

First I changed my code to equal your VB Code.
Old:
var dat2: array[0..500] of Char;

New:
var dat2: PChar; //Pointer to char


Now I initialized dat2 in two different way´s.

dat2:= PChar('Just a 256 byte long String to hold the Filename..........');

PChar() returns a Pointer to a String;
If it´s intialized this way, ReadProcessMemory fails. The output is the original "Just a long enough......"


Now I used AllocMem(X: Cardinal), which returns a pointer to X Bytes of Memory.

dat:=AllocMem(256);

If its done this way, ReadProcessMemory succeeds.

Maybe there´s a function like AllocMem in VB?

Heiko S.
HeikoSS is offline   Reply With Quote
Old 23rd April 2002, 00:34   #8
Gourou
Senior Member
 
Gourou's Avatar
 
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
Bows down to Heiko

Dim hwndWinamp As Long
Dim TempHandle As Long
Dim dat2 As String
Dim TrackPos As Long
Dim temp As Long
Dim MPointer As Long
Public Const WM_USER = &H400
Public Const PROCESS_VM_READ = &H10
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Public Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
Dim pTemp As Long
Dim nTemp As Long

Public Function ShowTitle() As String

hwndWinamp = FindWindow("Winamp v1.x", vbNullString)
TrackPos = SendMessage(hwndWinamp, &H400, 0, 125)
MPointer = SendMessage(hwndWinamp, &H400, TrackPos, 211)
temp = GetWindowThreadProcessId(hwndWinamp, TempHandle)
hwndWinamp = OpenProcess(PROCESS_VM_READ, False, TempHandle)
For xn = 1 To 256
dat2 = dat2 & " "
Next xn
nTemp = ReadProcessMemory(hwndWinamp, MPointer, dat2, 256, temp)
temp = CloseHandle(hwndWinamp)
ShowTitle = dat2

I was on the right track, I just didnt know it, you see, I was filling it with null characters by making it fixes length, so it would get to the first null and think that was the end of the string, go figure, so I filled it with spaces, the code works, works like a charm, thank you again Heiko. *bows down to you*
If anyone remembers the vb command to fill a string with a character, then use that instead of my loop.
Gourou is offline   Reply With Quote
Old 23rd April 2002, 08:39   #9
bananskib
Junior Member
 
Join Date: Apr 2002
Posts: 8
The answer is no - documented in frontend.h :

#define IPC_GETPLAYLISTFILE 211

/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
**
** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
** returns a pointer to it. returns NULL on error.
*/

notice "not external apps" - sorry

bananskib
bananskib is offline   Reply With Quote
Old 23rd April 2002, 09:56   #10
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
LOL?

Did you actually read the post´s above?

Quote:
It IS possible!
^^ This is no question

These Functions ARE the solution, they work...
Ok, I write one for C...
*sighs*

Perhaps someone updates the frontend.h?
Or the FAQ Page?
I´m sure the other "only usable from within winamp´plugin´s" API SendMessages are also usable from external app´s since we are able to freely read/write in winamp´s process memory from an external app too.

Anyone who got how OpenProcess, ReadProcessMemory and WriteProcessMemory work, should be able to port it to the
other IPC_´s .


Heiko S.
HeikoSS is offline   Reply With Quote
Old 23rd April 2002, 12:45   #11
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
I´m not very used to C too, but this Code works.

code:

char *GetWinampFilename()
{
HWND hwndWinamp = FindWindowA("Winamp v1.x",NULL);
LPDWORD TempHandle, temp;
TempHandle = new(DWORD);
temp = new(DWORD);
int index = SendMessage(hwndWinamp, WM_USER, 0, 125); //returns the playlist position
LPCVOID lpFileName=(LPCVOID)SendMessage(hwndWinamp, WM_USER, index, 211);
GetWindowThreadProcessId(hwndWinamp, TempHandle);
HANDLE hWinamp = OpenProcess(PROCESS_ALL_ACCESS,false,*TempHandle);
char *dat = (char*) malloc(256);
ReadProcessMemory(hWinamp, lpFileName, dat,256,temp);
CloseHandle(hWinamp);
free(TempHandle);
free(temp);
return dat;
}



Maybe someone wants to rewrite it, to make it look nicer


Heiko S.
HeikoSS is offline   Reply With Quote
Old 27th April 2002, 09:22   #12
salva
Junior Member
 
Join Date: Oct 2001
Posts: 6
Hello Gourou, will you post some project sample with your code ?

Tks
salva is offline   Reply With Quote
Old 27th April 2002, 14:11   #13
Gourou
Senior Member
 
Gourou's Avatar
 
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
sure, hell, why not, gimme a min to get a sample cobbled together..
Gourou is offline   Reply With Quote
Old 27th April 2002, 14:19   #14
Gourou
Senior Member
 
Gourou's Avatar
 
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
here, it works fine for me, if it doesnt work correctly for you, then message me
Attached Files
File Type: zip songtitles + filenames.zip (2.1 KB, 808 views)
Gourou is offline   Reply With Quote
Old 28th April 2002, 12:10   #15
Gourou
Senior Member
 
Gourou's Avatar
 
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
bloody hell, cant edit my own upload, that sux, so here's an update, I fixed a bug, it wasnt noticeable, but it was an error, and I dont like errors, even if they get passed by ok. BTW, this is just source code, I didnt bother to compile it
Attached Files
File Type: zip songtitles + filenames.zip (2.2 KB, 1334 views)
Gourou is offline   Reply With Quote
Old 2nd July 2002, 23:58   #16
deep_burn
Junior Member
 
Join Date: Jul 2001
Posts: 17
Send a message via ICQ to deep_burn Send a message via AIM to deep_burn
Excellent code!

I know I shouldn't be replying to a post that's 3 months old, but I can't help it. This is an excellent example of being able to pull the current song title/filename from WinAmp, which is exactly what I wanted to do. Even better, it's native VB.
*praise to the NSDN*
deep_burn is offline   Reply With Quote
Old 3rd July 2002, 14:27   #17
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
/me wonders how many vb coders are out there =)

np
HeikoSS is offline   Reply With Quote
Old 4th July 2002, 02:32   #18
Gourou
Senior Member
 
Gourou's Avatar
 
Join Date: Feb 2002
Location: The backside of the universe on the trailing edge of eternity
Posts: 238
more than you think...
Gourou is offline   Reply With Quote
Old 10th July 2002, 07:55   #19
NegativeFactor
Junior Member
 
Join Date: Jul 2002
Posts: 5
This thread has made my life 100% better, since now i can get the song names!! No more sleepless nights, yeah!!

I'm a VB coder 2!

NegativeFactor is offline   Reply With Quote
Old 12th January 2003, 20:00   #20
quentin
Junior Member
 
Join Date: Aug 2001
Location: austria
Posts: 43
vbcoder
i'm going to reactivate this post since i have a problem

i surely get the right title returned but when i want to return some more text afterwards it doesn't work. i guess that's because of the Space(256)

does anyone have a clue how to just return a normal string instead of this special string? or how to terminate the string so that i can add normal text after it?

heres my code:
[quote]Public Function ShowFile() As String
On Error Resume Next
hWndWinamp = FindWindow("Winamp v1.x", vbNullString)
TrackPos = SendMessage(hWndWinamp, WM_USER, 0, 125)
MPointer = SendMessage(hWndWinamp, WM_USER, TrackPos, 211) '212 is Title
temp = GetWindowThreadProcessId(hWndWinamp, TempHandle)
hwndWinampP = OpenProcess(PROCESS_VM_READ, False, TempHandle)
Data = Space(256)
nTemp = ReadProcessMemory(hwndWinampP, MPointer, Data, 256, temp)
pTemp = CloseHandle(hwndWinampP)
ShowFile = Trim(Data)
End Function[/code]

thanks!
quentin is offline   Reply With Quote
Old 12th January 2003, 22:17   #21
HeikoSS
Junior Member
 
Join Date: Apr 2002
Location: Germany
Posts: 8
Send a message via ICQ to HeikoSS Send a message via AIM to HeikoSS
Sorry, other question:

Is there any WinampAPI in Winamp3 ?

I wanted to port this to 3...but didn´t find anything...

Heiko S.
HeikoSS is offline   Reply With Quote
Old 14th January 2003, 07:33   #22
Lion King
Major Dude
 
Join Date: Jan 2001
Posts: 1,670
http://forums.winamp.com/showthread.php?threadid=106344
Lion King is offline   Reply With Quote
Old 18th February 2003, 16:38   #23
daydee
Junior Member
 
Join Date: Oct 2002
Location: Montreal ,Canada
Posts: 11
[QUOTE]Originally posted by quentin
vbcoder
i'm going to reactivate this post since i have a problem

i surely get the right title returned but when i want to return some more text afterwards it doesn't work. i guess that's because of the Space(256)

does anyone have a clue how to just return a normal string instead of this special string? or how to terminate the string so that i can add normal text after it?

heres my code:
Quote:
Public Function ShowFile() As String
On Error Resume Next
hWndWinamp = FindWindow("Winamp v1.x", vbNullString)
TrackPos = SendMessage(hWndWinamp, WM_USER, 0, 125)
MPointer = SendMessage(hWndWinamp, WM_USER, TrackPos, 211) '212 is Title
temp = GetWindowThreadProcessId(hWndWinamp, TempHandle)
hwndWinampP = OpenProcess(PROCESS_VM_READ, False, TempHandle)
Data = Space(256)
nTemp = ReadProcessMemory(hwndWinampP, MPointer, Data, 256, temp)
pTemp = CloseHandle(hwndWinampP)
ShowFile = Trim(Data)
End Function[/code]

thanks!
Add the TrimNulls function below and give it a try. Hope this helps...
code:

Public Function ShowFile() As String
On Error Resume Next
hWndWinamp = FindWindow("Winamp v1.x", vbNullString)
TrackPos = SendMessage(hWndWinamp, WM_USER, 0, 125)
MPointer = SendMessage(hWndWinamp, WM_USER, TrackPos, 211) '212 is Title
temp = GetWindowThreadProcessId(hWndWinamp, TempHandle)
hwndWinampP = OpenProcess(PROCESS_VM_READ, False, TempHandle)
Data = Space(256)
nTemp = ReadProcessMemory(hwndWinampP, MPointer, Data, 256, temp)
pTemp = CloseHandle(hwndWinampP)
ShowFile = TrimNulls(Data)
End Function

Private Function TrimNulls(strString As String) As String
Dim l As Long
l = InStr(1, strString, Chr(0))
TrimNulls = Left$(strString, l - 1)
strString = TrimNulls
End Function

daydee is offline   Reply With Quote
Old 18th February 2003, 19:22   #24
quentin
Junior Member
 
Join Date: Aug 2001
Location: austria
Posts: 43
Quote:
Add the TrimNulls function below and give it a try. Hope this helps...
code:

Private Function TrimNulls(strString As String) As String
Dim l As Long
l = InStr(1, strString, Chr(0))
TrimNulls = Left$(strString, l - 1)
strString = TrimNulls
End Function

i love you

yeah that worked fine

thanks for your help!
quentin is offline   Reply With Quote
Old 20th February 2003, 03:07   #25
daydee
Junior Member
 
Join Date: Oct 2002
Location: Montreal ,Canada
Posts: 11
your welcome!
You could also use it if your populating a listbox...
This was originally a function which I grabbed from Gourou's project but I made it into a sub with a variable for a Listbox.
I'm using this in my latest app which works great. My thanks to Gourou for coming up with this neat stuff.
I was able to reduce my initial code considerably because of it.
Happy coding!
code:

Public Sub ShowFileList(ByVal LstBox As ListBox)
Dim tempStr As String
On Error Resume Next
LstBox.Clear
hwndWinamp = FindWindow("Winamp v1.x", vbNullString)
pLength = SendMessage(hwndWinamp, WM_USER, 0, 124)

For xn = 1 To pLength
MPointer = SendMessage(hwndWinamp, WM_USER, xn - 1, 211) '212 is Title
temp = GetWindowThreadProcessId(hwndWinamp, TempHandle)
hwndWinampP = OpenProcess(PROCESS_VM_READ, False, TempHandle)
Data = Space(256)
nTemp = ReadProcessMemory(hwndWinampP, MPointer, Data, 256, temp)
pTemp = CloseHandle(hwndWinampP)
tempStr = TrimNulls(Data)
'do your string manipulation here,
'like remove file extension etc...
LstBox.AddItem tempStr
Next xn

End Sub

daydee is offline   Reply With Quote
Old 21st February 2003, 17:23   #26
deep_burn
Junior Member
 
Join Date: Jul 2001
Posts: 17
Send a message via ICQ to deep_burn Send a message via AIM to deep_burn
You people are beautiful. The DAY I come back to working with the API for VB, you resurrect this post.

Currently, I'm working on a special project that I'll talk about when it's done. It's a stand-alone VB app that communicates with WinAMP (of course)... but it takes a whole new twist. I hope it's well received.
deep_burn is offline   Reply With Quote
Old 22nd February 2003, 06:14   #27
daydee
Junior Member
 
Join Date: Oct 2002
Location: Montreal ,Canada
Posts: 11
Quote:
Originally posted by deep_burn
You people are beautiful. The DAY I come back to working with the API for VB, you resurrect this post.

Currently, I'm working on a special project that I'll talk about when it's done. It's a stand-alone VB app that communicates with WinAMP (of course)... but it takes a whole new twist. I hope it's well received.
Hi there deep_burn, wonder if that new twist your mentioning is something simmilar to what I've done? I don't want to turn this into a chit chat but I got so p..... o.. at trying to find a decent visual front end for winamp 2 that I decided to learn VB 2 years ago and make it myself. I think I've maxed out just about every functions you can get out of winamp on this one. Well maybe not but pretty close...
My web counter is surely proof that that there was a need for such a thing.
Funny but of all people I would have thought Nullsoft would have come out with something like this long ago. I mean a front end that you could easily use with your full album folders. Sure there are a few plugins out there that'll let you see the album covers while listening to your tunes but I think most people want a little more interaction than this no? I did... Anyway I'm sure with the huge hard drives coming out on the market nowadays a whole bunch of people are going to start realizing that it's wwwwway more efficient to keep your music collection on your pc than all over the place.

I've got over 550 CD'S neatly stored on two separate HD and would never ever go back to listening to my cd's the old way.
I don't really feel comfortable about mentioning this here but anyway if you want to try it out here's the link. It's free btw... unless you use it commercially of course
http://pages.globetrotter.net/bakery...me_jukebox.htm

If you wanta share ideas you can write me at bakerywizard@globetrotter.net

Cheers and thanks again to all the forum gurus for not abandoning us... Winamp 2 lovers that is!
daydee is offline   Reply With Quote
Old 23rd February 2003, 16:12   #28
deep_burn
Junior Member
 
Join Date: Jul 2001
Posts: 17
Send a message via ICQ to deep_burn Send a message via AIM to deep_burn
That's an excellent idea. Although, it's nowhere close to what I'm doing.

I've decided not to release my app. I would, but I've gotten a second wind on things I can do with it, and unfortunatly, it's becomming more multi-purpose than just WinAMP.

When I reach version 2.0, that's when I'll release it as a plugin.

Yeah, WinAMP 2 still rocks! I'll never replace it. It'll be one of those things that you've had on your computer for like 11 years... like Temple of Abshai.
deep_burn is offline   Reply With Quote
Old 16th July 2003, 16:52   #29
syph424
Junior Member
 
Join Date: Jul 2003
Location: Louisville, KY
Posts: 2
Send a message via AIM to syph424
Back from the dead....

Looks like it's been a few months since anyone's dug this one up from the dead... it's about time to do it again, eh?

I'm working on a class to interact with WinAmp 2.x in VB.NET. I haven't run into any problems so far, so I figured it was about time to tackle the current file issue.

Using Gourou's code, I can get the title in VB6 without any issues. However, I'm having a hell of a time rolling it up to .NET. The current issue (I'm sure there's more to follow) is with the OpenProcess API call. Up until that call, I've got VB6 and VB.NET on the same page. However, I can't get the .NET code to return the same value as the VB6 code.

I've got the API registered as "Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Integer, ByVal bInheritHandle As Integer, ByVal dwProcessId As Integer) As Integer". I attempted using GetProcessById in the System.Diagnostics.Process class too, no dice.

Any ideas? Anyone tried this yet?

Thanks for any assistance...

syph
syph424 is offline   Reply With Quote
Old 27th November 2003, 21:43   #30
orlandocurioso
Junior Member
 
Join Date: Oct 2003
Posts: 9
Big Thank You for HeikoSS & Gourou!
A nice VB wrapper for using your methods & a hack to use restricted
stringbuffers,can be found at
http://forums.winamp.com/showthread....hreadid=157836
orlandocurioso is offline   Reply With Quote
Old 18th March 2004, 12:31   #31
ScoBra7
Junior Member
 
Join Date: Mar 2004
Location: Pretoria
Posts: 4
Quote:
...frontend.h
In SDK v 5.02 (I think it is in wa_icp.h)

Here is my C code, using MFC, I used a dialog box just to test:
code:

void CWinampTestDlg::OnOK()
{
CString Text, tempStr;
HWND hwndWinamp;
HANDLE hWinamp;
unsigned long TempHandle;
char * dat2 = new char[500];
memset(dat2,0,500);
int TrackPos;
int * MPointer;
unsigned long temp;

hwndWinamp = ::FindWindow("Winamp v1.x",0);
if(hwndWinamp == NULL)
{
AfxMessageBox("Please be so kind as to start Winamp.");
return;
}
TrackPos = ::SendMessage(hwndWinamp,WM_USER,0 , 125);
MPointer = (int*)::SendMessage(hwndWinamp,WM_USER,TrackPos , 211);
GetWindowThreadProcessId(hwndWinamp,&TempHandle);
hWinamp = ::OpenProcess(PROCESS_ALL_ACCESS,FALSE,TempHandle);
ReadProcessMemory(hWinamp, MPointer, dat2,500,&temp);
CloseHandle(hWinamp);
tempStr = dat2; // ;-)
CString str;
str.Format("Now playing\n%d\t%s",TrackPos,tempStr);
AfxMessageBox(str);
delete dat2;
}

ScoBra7 is offline   Reply With Quote
Old 31st March 2004, 08:24   #32
cutter2004
Junior Member
 
Join Date: Mar 2004
Posts: 2
Urgent!!! How to get filename in fullpath

Urgent!!! How to get filename in fullpath.
Thank.
cutter2004 is offline   Reply With Quote
Old 1st April 2004, 06:41   #33
ScoBra7
Junior Member
 
Join Date: Mar 2004
Location: Pretoria
Posts: 4
In wa_ipc.h you'll find
code:
#define IPC_GETPLAYLISTFILE 211
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTFILE);
** IPC_GETPLAYLISTFILE gets the filename of the playlist entry [index].
** returns a pointer to it. returns NULL on error.
*/


#define IPC_GETPLAYLISTTITLE 212
/* (requires Winamp 2.04+, only usable from plug-ins (not external apps))
** char *name=SendMessage(hwnd_winamp,WM_WA_IPC,index,IPC_GETPLAYLISTTITLE);
**
** IPC_GETPLAYLISTTITLE gets the title of the playlist entry [index].
** returns a pointer to it. returns NULL on error.
*/


But "(not external apps)" is not true my app can get it.

Thus for the fullpath use
code:
MPointer = (int*)::SendMessage(hwndWinamp,WM_USER,TrackPos , IPC_GETPLAYLISTFILE);


in the above code.
ScoBra7 is offline   Reply With Quote
Old 4th April 2004, 22:24   #34
Davman99
Junior Member
 
Join Date: Mar 2004
Posts: 9
Ok, now im gonna have to reveal my n00bness here, and while i doubt i will get an answer, im gonna ask anyway...

Im looking for a DLL for use with mIRC (must follow this format)

code:
int __stdcall procname(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)


that will allow me to control winamp's volume, along with play and stop.

I take it this is possible (everything is), but not being a C coder, im not sure how.

If anyone has any ideas, or can point me in the direction of code samples that i may understand (are nicely commented), it would be great....
Davman99 is offline   Reply With Quote
Old 5th April 2004, 05:26   #35
ScoBra7
Junior Member
 
Join Date: Mar 2004
Location: Pretoria
Posts: 4
If I understand you correctly, the DLL "plugs-in" to mIRC?

If so, you use the same code listed above in your DLL.

If you want a DLL that already does this, I think you have to write one. Which doesn't answer your question

Search this forum, you'll find clues on how to do it.
ScoBra7 is offline   Reply With Quote
Old 16th January 2007, 19:47   #36
fdeshayes
Junior Member
 
Join Date: Jan 2007
Location: Caen, France
Posts: 4
hi!

i'm trying to get the filename of the current playing song in winamp from an external application written in C# (.NET 2.0)

I'm doing the same things that are your C or Vb code but it doesn't work. The openProcess method alway return me zero, so i can't read in winamp memory.

Anybody have a sample code in C# ? i can post my code here if somebody can help...
fdeshayes is offline   Reply With Quote
Old 17th January 2007, 11:27   #37
Tardymo
Member
 
Join Date: Sep 2006
Posts: 89
Can you post a DllImport you are using for openProcess?
Tardymo is offline   Reply With Quote
Old 17th January 2007, 18:13   #38
fdeshayes
Junior Member
 
Join Date: Jan 2007
Location: Caen, France
Posts: 4
i've seen your WACC lib and download it. It work fine :-)
but why use a bind method with path of winamp ?
can we get this path from registry ?
is bind necessary for all winamp interaction or only for some (which used command line to control winamp?) ?

by the way, when i get songpath from your WACC lib, i use it with taglib dll (http://developer.novell.com/wiki/index.php/TagLib_Sharp) to read all ID3 stuff (and other tag format for vorbis / ape...)

If i put the songpath in hard code (like String songPath ="c:\\mp3\\toto.mp3" all is ok, i can read the id3 tags. But if i use your WACC lib to get the current winamp song played (the same toto.mp3), the taglib constructor return null. I've compared the two string (the hard coded and the one return from your lib), all is the same (after a substring to kill \0 at end of string return by WACC). So what's wrong with String return by your WACC?

here is my getCurrentSongPath method
code:
public String getCurrentSongPath() {
String songPath = "";
findAndSetHandle();

if (handle != IntPtr.Zero) {
clsWACC cWinamp = new clsWACC();
bool bind = cWinamp.Bind("c:\\Program Files\\Winamp\\Winamp.exe");
if (bind) {
int currPos = cWinamp.Playlist.Position;
songPath = cWinamp.Playlist.GetItemPath(currPos);
songPath = songPath.Substring(0, songPath.IndexOf('\0'));
songPath = songPath.Trim();
}
}
return songPath;
}



here is how i get tag with taglib
code:

String musicPath = sensorWinamp.multimediaPlayer.getCurrentSongPath();
String musicPath2 = "E:\\MP3\\Albums\\Thunderstone\\2004 - The Burning\\06. Sea of Sorrow.mp3";
Console.WriteLine(musicPath.CompareTo(musicPath2)); // return zero
currentSong = TagLib.File.Create(musicPath); // return null !?!?
currentSong = TagLib.File.Create(musicPath2); // all is ok


Last edited by fdeshayes; 17th January 2007 at 20:26.
fdeshayes is offline   Reply With Quote
Old 18th January 2007, 20:37   #39
Tardymo
Member
 
Join Date: Sep 2006
Posts: 89
Quote:
but why use a bind method with path of winamp ?
can we get this path from registry ?
Sure we can. In fact, I will add this functionality in the next release.

Quote:
is bind necessary for all winamp interaction or only for some (which used command line to control winamp?) ?
It is needed for all interactions. Bind method gets a handle to winamp's main window to which most of the commands are sent. This handle is a global instance member of a class.

Quote:
If i put the songpath in hard code (like String songPath ="c:\\mp3\\toto.mp3" all is ok, i can read the id3 tags. But if i use your WACC lib to get the current winamp song played (the same toto.mp3), the taglib constructor return null. I've compared the two string (the hard coded and the one return from your lib), all is the same (after a substring to kill \0 at end of string return by WACC). So what's wrong with String return by your WACC?
A bug actually
A string returned by GetItemPath (and all other strings that are read from the winamp's memory space) is not terminated properly. I have fixed the problem so you have to wait for the next release planned in this weekend. You will not have to use the following line anymore and taglib will work as expected.
code:

songPath = songPath.Substring(0, songPath.IndexOf('\0'));



If you don't want to wait, you can fix the library yourself. Just replace this line:
Dim RetStr As String = Marshal.PtrToStringAnsi(returnVal, MaxStrLen)
with this one:
Dim RetStr As String = Marshal.PtrToStringAnsi(returnVal)
It's in clsWacc.vb in ReadRemoteString function.

By the way. Next version will be able to read information from tags, so stay tuned.
Tardymo is offline   Reply With Quote
Old 19th January 2007, 18:00   #40
fdeshayes
Junior Member
 
Join Date: Jan 2007
Location: Caen, France
Posts: 4
thanks for this explication.

For your bind, maybe you can use system method FindWindow with the classname of winamp : "Winamp v1.x". This classname doesn't change, contrary to the path of winamp.exe

here is an exemple in C#. I've not VB.

code:
// find a process windows by classname or windows name
[System.Runtime.InteropServices.DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

// call like this
IntPtr winampHandle = FindWindow("Winamp v1.x", null);



i've not VB so i must wait until next released. Can you said approximatly when will be the next released or maybe can you send me only the fresh .dll (even in beta, i only use cWinamp.Playlist.Position and cWinamp.Playlist.GetItemPath()) ?

thanks for your work!
fdeshayes is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > Winamp Development

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump