Generic Music Player

Posts 115 of 16 · Page 1 of 2
Generic Music Player
I saw @Shadow` 's hack and saw that it had the ability to be able to play music. The only downside was that it only worked with WAV files and had to be in a specific folder so I decided to tackle this problem myself and write a small class for it. With this class, you will be able to play MP3 files and other formats supported by the computer as long as you have the codecs available for it. I've also tested it with FLAC and WAV, they work fine. This class is mainly powered by the MCI API from Microsoft. You can enter in relative/partial paths, like "Music" and it will find all files in the "Music" folder next to the injected DLL. You can also put in absolute paths like "C:\Music Stuff" and it will search that directory.

Also if you noticed that I used, TCHAR, LPTSTR and _T alot, well that's because I wanted to add support for both ANSI and Unicode depeding on the Character Set that's been used on the current project. Also note that the class is static, meaning you can only have 1 instance of it in every application or DLL.

I should also mention that SetVolume uses a value between 0 and 1000, eg. 0 = 0% and 1000 = 100%. The same thing applies to the Volume variable which tells the current volume level. GetCurrentPosition and SetCurrentPosition use millisecond values for their positions.

player.h
Code:
#include <Windows.h>
#include <Shlwapi.h>
#include <vector>
#include <tchar.h>
#pragma comment(lib, "Winmm.lib")
#pragma comment(lib, "Shlwapi.lib")

struct MusicPlayerEntry
{
	LPTSTR SongName;
	LPTSTR Path;
};

class MusicPlayer
{
public:
	static std::vector<MusicPlayerEntry*> Entries;

	static void PopulateMusic(LPTSTR directory, LPTSTR extension);
	static void Cleanup();

	static bool IsPlaying();
	static bool IsPaused();
	
	static void PlayMusic(MusicPlayerEntry* entry);
	static void PauseMusic();
	static void ResumeMusic();
	static void StopMusic();

	static void SetVolume(int value);
	static int GetCurrentPosition();
	static void SetCurrentPosition(int position);

	static void FormatMilliseconds(int milliseconds, LPTSTR output, size_t bufferSize);

	static int LengthMilliseconds, Volume;

private:
	static bool AliasDefined;

	static void AddEntry(LPTSTR filePath, LPTSTR songName);
	static HMODULE GetCurrentModuleHandle();
	static BOOL DirectoryExists(LPTSTR directory);
};
player.cpp
Code:
#include "player.h"

std::vector<MusicPlayerEntry*> MusicPlayer::Entries;
int MusicPlayer::LengthMilliseconds = 0;
int MusicPlayer::Volume = 1000;
bool MusicPlayer::AliasDefined = false;

void MusicPlayer::PopulateMusic(LPTSTR directory, LPTSTR extension)
{
	if(PathIsRelative(directory))
	{
		TCHAR buffer[MAX_PATH];
		GetModuleFileName(GetCurrentModuleHandle(), buffer, MAX_PATH);
		PathRemoveFileSpec(buffer);
		PathCombine(buffer, buffer, directory);
		directory = buffer;
	}

	if(!DirectoryExists(directory))
		return;

	TCHAR wildcardPath[MAX_PATH];
	PathCombine(wildcardPath, directory, _T("*"));
	WIN32_FIND_DATA findData;
	HANDLE findHandle = FindFirstFile(wildcardPath, &findData);

	do 
	{
		LPTSTR currentExtension = PathFindExtension(findData.cFileName);
		if(!lstrcmp(currentExtension, extension))
		{
			LPTSTR path = new TCHAR[MAX_PATH];
			PathCombine(path, directory, findData.cFileName);
			
			LPTSTR songName = new TCHAR[MAX_PATH];
			lstrcpy(songName, findData.cFileName);
			PathStripPath(songName);
			PathRemoveExtension(songName);
			AddEntry(path, songName);
		}
	} while (FindNextFile(findHandle, &findData) != 0);
}

void MusicPlayer::Cleanup()
{
	StopMusic();
	for(unsigned int i = 0; i < Entries.size(); i++)
	{
		delete Entries[i]->SongName;
		delete Entries[i]->Path;
	}
	Entries.clear();
}

HMODULE MusicPlayer::GetCurrentModuleHandle()
{
	static int var = 0;
	MEMORY_BASIC_INFORMATION mbi;
	if(!VirtualQuery(&var, &mbi, sizeof(mbi)))
		return NULL;
	return static_cast<HMODULE>(mbi.AllocationBase);
}

void MusicPlayer::FormatMilliseconds(int milliseconds, LPTSTR output, size_t bufferSize)
{
	_stprintf_s(output, bufferSize, _T("%d:%02d"), milliseconds / 1000 / 60, milliseconds / 1000 % 60);
}

bool MusicPlayer::IsPlaying()
{
	TCHAR buffer[20];
	mciSendString(_T("status currentSong mode"), buffer, 20, NULL);
	return !lstrcmp(buffer, _T("playing"));
}

bool MusicPlayer::IsPaused()
{
	TCHAR buffer[20];
	mciSendString(_T("status currentSong mode"), buffer, 20, NULL);
	return !lstrcmp(buffer, _T("paused"));
}

void MusicPlayer::PlayMusic(MusicPlayerEntry* entry)
{
	StopMusic();
	TCHAR buffer[MAX_PATH + 40];
	_stprintf_s(buffer, _T("open \"%s\" type mpegvideo alias currentSong"), entry->Path);
	mciSendString(buffer, NULL, 0, NULL);
	mciSendString(_T("play currentSong"), NULL, 0, NULL);
	TCHAR length[128];
	mciSendString(_T("status currentSong length"), length, 128, NULL);
	LengthMilliseconds = _ttoi(length);
	AliasDefined = true;
}

void MusicPlayer::PauseMusic()
{
	if(IsPlaying())
		mciSendString(_T("pause currentSong"), NULL, 0, NULL);
}

void MusicPlayer::ResumeMusic()
{
	if(IsPaused())
		mciSendString(_T("resume currentSong"), NULL, 0, NULL);
}

void MusicPlayer::StopMusic()
{
	if(AliasDefined)
		mciSendString(_T("close currentSong"), NULL, 0, NULL);
}

int MusicPlayer::GetCurrentPosition()
{
	if(IsPlaying())
	{
		TCHAR length[128];
		mciSendString(_T("status currentSong position"), length, 128, NULL);
		return _ttoi(length);
	}
	return 0;
}

void MusicPlayer::SetCurrentPosition(int position)
{
	if(IsPlaying())
	{
		TCHAR buffer[60];
		_stprintf_s(buffer, _T("play currentSong from %d"), position);
		mciSendString(buffer, NULL, 0, NULL);
	}
}

void MusicPlayer::SetVolume(int value)
{
	if(IsPlaying() && value >= 0 && value <= 1000)
	{
		TCHAR buffer[40];
		_stprintf_s(buffer, _T("setaudio currentSong volume to %i"), value);
		mciSendString(buffer, NULL, 0, NULL);
		Volume = value;
	}
}

BOOL MusicPlayer::DirectoryExists(LPTSTR dirName) 
{
	DWORD attribs = GetFileAttributes(dirName);
	if (attribs == INVALID_FILE_ATTRIBUTES) 
		return false;
	return (attribs & FILE_ATTRIBUTE_DIRECTORY);
}

void MusicPlayer::AddEntry(LPTSTR filePath, LPTSTR songName)
{
	MusicPlayerEntry* entry = new MusicPlayerEntry();
	entry->SongName = songName;
	entry->Path = filePath;
	Entries.push_back(entry);
}
Here's a little "Demo DLL" source that you can try out to test some of the class' features.

Code:
#include <Windows.h>
#include "player.h"

DWORD WINAPI Main(LPVOID)
{
	unsigned int currentEntryIndex = 0;

	// Find all .mp3 files inside the Music folder next to the DLL.
	MusicPlayer::PopulateMusic(_T("Music"), _T(".mp3"));

	// Check if there were any .mp3 files found.
	if(!MusicPlayer::Entries.size()) return 0;

	while(true)
	{
		// If no song is playing, play one.
		if(!MusicPlayer::IsPlaying())
		{
			// Check that we've played all songs.
			if(currentEntryIndex < MusicPlayer::Entries.size())
			{
				// Play the next song available.
				MusicPlayerEntry* entry = MusicPlayer::Entries[currentEntryIndex++];
				MusicPlayer::PlayMusic(entry);

				// Display song information.
				TCHAR buffer[255];
				TCHAR formattedTime[20];
				// Convert the milliseconds to minutes and seconds.
				MusicPlayer::FormatMilliseconds(MusicPlayer::LengthMilliseconds, formattedTime, 20);
				_stprintf_s(buffer, _T("Current song is: %s\nLength: %s"), entry->SongName, formattedTime);
				MessageBox(NULL, buffer, _T("Information"), MB_OK);
			}
			else
			{
				// Exit.
				MessageBox(NULL, _T("All songs have been played!"), _T("Done"), MB_OK);
				break;
			}
		}
		Sleep(1000);
	}

	return 0;
}

BOOL APIENTRY DllMain(HMODULE hDll, DWORD dwReason, LPVOID lpReserved)
{
	switch(dwReason)
	{
	case DLL_PROCESS_ATTACH:
		DisableThreadLibraryCalls(hDll);
		CreateThread(NULL, NULL, Main, NULL, NULL, NULL);
		break;
	case DLL_PROCESS_DETACH:
                // Cleanup stuff here, only do it when the player is no longer needed.
		MusicPlayer::Cleanup();
	}

	return TRUE;
}
I've attached the built Demo DLL which you can inject into any process and mess around with.

Virus Scans:
https://www.virustotal.com/file/b467...is/1348830741/
BasicMusicPlayerDemo.rar - Jotti's malware scan
BasicMusicPlayerDemo_mpgh.net.rar25 KB · 26 downloads Scanning…
Great job bro.
This is great work. I was personally trying to get WinAMP integration working since I couldn't find any info on iTunes.

This is a good thing to settle to if everything fails. Either way, its good work
Well Done , thanks

Meennn!!!
Cool post.

Well, Hybrid GUI released by EvilNess back in June 2010 has more control features.

Code:
//control functions
    void        Play( void ){ Send_Command( WINAMP_BUTTON2 ); }
    void        Pause( void ){ Send_Command( WINAMP_BUTTON3 ); }
    void        Stop( void ){ Send_Command( WINAMP_BUTTON4 ); }
    void        Next_Track( void ){ Send_Command( WINAMP_BUTTON5 ); }
    void        Previous_Track( void ){ Send_Command( WINAMP_BUTTON1 ); }
    void        Repeat_Toggle( void ){ Send_Command( WINAMP_BUTTON_REPEAT ); }
    void        Shuffle_Toggle( void ){ Send_Command( WINAMP_BUTTON_SHUFFLE ); }
    void        Seek_Track_Position( int m_iPosition ){ Request_Command( m_iPosition, IPC_JUMPTOTIME ); }
    void        SetVolume( int m_iVolume ){ Request_Command( m_iVolume, IPC_SETVOLUME ); }
    void        IncreaseVolume( void ){ Send_Command( WINAMP_VOLUMEUP ); }
    void        DecreaseVolume( void ){ Send_Command( WINAMP_VOLUMEDOWN ); }
    void        Goto_Track_Begin( void ){ Send_Command( WINAMP_BUTTON1_CTRL ); }
    void        Goto_Track_End( void ){ Send_Command( WINAMP_BUTTON5_CTRL ); }
    void        Goto_TrackByIndex( int index ){ Request_Command( index - 1,IPC_SETPLAYLISTPOS ); }
    void        FastForward( void ){ Send_Command( WINAMP_FFWD5S ); }
    void        FastRewind( void ){ Send_Command( WINAMP_REW5S ); }
    void        LoadPlaylist( char *m_szDirectory, char *m_szFile );
Quote Originally Posted by P0w3r View Post
Cool post.

Well, Hybrid GUI released by EvilNess back in June 2010 has more control features.

Code:
//control functions
    void        Play( void ){ Send_Command( WINAMP_BUTTON2 ); }
    void        Pause( void ){ Send_Command( WINAMP_BUTTON3 ); }
    void        Stop( void ){ Send_Command( WINAMP_BUTTON4 ); }
    void        Next_Track( void ){ Send_Command( WINAMP_BUTTON5 ); }
    void        Previous_Track( void ){ Send_Command( WINAMP_BUTTON1 ); }
    void        Repeat_Toggle( void ){ Send_Command( WINAMP_BUTTON_REPEAT ); }
    void        Shuffle_Toggle( void ){ Send_Command( WINAMP_BUTTON_SHUFFLE ); }
    void        Seek_Track_Position( int m_iPosition ){ Request_Command( m_iPosition, IPC_JUMPTOTIME ); }
    void        SetVolume( int m_iVolume ){ Request_Command( m_iVolume, IPC_SETVOLUME ); }
    void        IncreaseVolume( void ){ Send_Command( WINAMP_VOLUMEUP ); }
    void        DecreaseVolume( void ){ Send_Command( WINAMP_VOLUMEDOWN ); }
    void        Goto_Track_Begin( void ){ Send_Command( WINAMP_BUTTON1_CTRL ); }
    void        Goto_Track_End( void ){ Send_Command( WINAMP_BUTTON5_CTRL ); }
    void        Goto_TrackByIndex( int index ){ Request_Command( index - 1,IPC_SETPLAYLISTPOS ); }
    void        FastForward( void ){ Send_Command( WINAMP_FFWD5S ); }
    void        FastRewind( void ){ Send_Command( WINAMP_REW5S ); }
    void        LoadPlaylist( char *m_szDirectory, char *m_szFile );
Hybrid GUI. Still the sexiest GUI 2 years running
Quote Originally Posted by Shizuo Heiwajima View Post
Hybrid GUI. Still the sexiest GUI 2 years running
Lol I beg to differ, there have been extremely sexy menus in the past 2 years.
Quote Originally Posted by P0w3r View Post
Cool post.

Well, Hybrid GUI released by EvilNess back in June 2010 has more control features.

Code:
//control functions
    void        Play( void ){ Send_Command( WINAMP_BUTTON2 ); }
    void        Pause( void ){ Send_Command( WINAMP_BUTTON3 ); }
    void        Stop( void ){ Send_Command( WINAMP_BUTTON4 ); }
    void        Next_Track( void ){ Send_Command( WINAMP_BUTTON5 ); }
    void        Previous_Track( void ){ Send_Command( WINAMP_BUTTON1 ); }
    void        Repeat_Toggle( void ){ Send_Command( WINAMP_BUTTON_REPEAT ); }
    void        Shuffle_Toggle( void ){ Send_Command( WINAMP_BUTTON_SHUFFLE ); }
    void        Seek_Track_Position( int m_iPosition ){ Request_Command( m_iPosition, IPC_JUMPTOTIME ); }
    void        SetVolume( int m_iVolume ){ Request_Command( m_iVolume, IPC_SETVOLUME ); }
    void        IncreaseVolume( void ){ Send_Command( WINAMP_VOLUMEUP ); }
    void        DecreaseVolume( void ){ Send_Command( WINAMP_VOLUMEDOWN ); }
    void        Goto_Track_Begin( void ){ Send_Command( WINAMP_BUTTON1_CTRL ); }
    void        Goto_Track_End( void ){ Send_Command( WINAMP_BUTTON5_CTRL ); }
    void        Goto_TrackByIndex( int index ){ Request_Command( index - 1,IPC_SETPLAYLISTPOS ); }
    void        FastForward( void ){ Send_Command( WINAMP_FFWD5S ); }
    void        FastRewind( void ){ Send_Command( WINAMP_REW5S ); }
    void        LoadPlaylist( char *m_szDirectory, char *m_szFile );
Hybrid GUI is only for Winamp though, master131's class lets you listen to music from any folder on your computer.
Woah fck yeah !!! Thanks for sharing this code brah! of course if it works you get da credits :P
you guys need to check out the BASS library, why better sound and support multiple codec straight out the box without using windows media player control.
Quote Originally Posted by Departure View Post
you guys need to check out the BASS library, why better sound and support multiple codec straight out the box without using windows media player control.
I've also heard FMOD is pretty nice.
Quote Originally Posted by Departure View Post
you guys need to check out the BASS library, why better sound and support multiple codec straight out the box without using windows media player control.
Windows Media Player Control? What? MCI != WMP It's not even a control. I'm well aware of the BASS library, I've used it in a .NET application to play XM files. Anyway, adding alot of extra DLLs just to play music is going to be a hassle for people if it's used in a hack.
FMOD is for playing .mod files not mp3/mp4/ogg/ect..
THanks Master!
Posts 115 of 16 · Page 1 of 2
This thread is closed for replies.

Similar Threads

Tags for this Thread

None

Need help?