Skip to content

Instantly share code, notes, and snippets.

@VelocityRa
Created December 26, 2016 18:44
Show Gist options
  • Save VelocityRa/79e91d1521e88fefad128a6c5498be00 to your computer and use it in GitHub Desktop.
Save VelocityRa/79e91d1521e88fefad128a6c5498be00 to your computer and use it in GitHub Desktop.
// SpotifyAdMuter.cpp : Defines the entry point for the console application.
//
#include <iostream>
#include <string>
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <stdlib.h>
#include <cassert>
#ifdef _DEBUG
static bool debug = true;
#else
static bool debug = false;
#endif
namespace std {
#if defined _UNICODE || defined UNICODE
typedef wstring tstring;
#else
typedef string tstring;
#endif
}
using namespace std;
const string APP_VERSION = "0.8";
struct handle_data {
unsigned long process_id;
HWND best_handle;
};
BOOL CALLBACK enumWindowsProc(HWND handle, LPARAM lParam)
{
handle_data& data = *reinterpret_cast<handle_data*>(lParam);
unsigned long process_id = 0;
GetWindowThreadProcessId(handle, &process_id);
if (data.process_id != process_id) {
return TRUE;
}
data.best_handle = handle; // Found a matching PID, save the handle
return FALSE; // and stop searching
}
HWND GetSpofifyWindowHandle(DWORD process_id)
{
cout << "Finding Spotify window handle...\n";
handle_data data;
data.process_id = process_id;
data.best_handle = nullptr;
if (!EnumWindows(enumWindowsProc, LPARAM(&data)))
cout << "Found Spotify window handle.\n\n";
else
{
cerr << "Couldn't find Spotify window handle\n";
getchar();
exit(EXIT_FAILURE);
}
return data.best_handle;
}
// Returns how many processes it found. Should be 3 for Spotify
int FindProcessID(const char* p_ProcessName, DWORD processes[])
{
PROCESSENTRY32 s_ProcessEntry;
s_ProcessEntry.dwSize = sizeof(PROCESSENTRY32);
HANDLE s_Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
auto processCount = 0;
if (Process32First(s_Snapshot, &s_ProcessEntry))
{
while (Process32Next(s_Snapshot, &s_ProcessEntry) && processCount < 3) // Spotify always has 3 processes running
{
if (_stricmp(s_ProcessEntry.szExeFile, p_ProcessName) == 0)
{
processes[processCount] = s_ProcessEntry.th32ProcessID;
processCount++;
}
}
}
CloseHandle(s_Snapshot);
return processCount;
}
int LocateSpotifyProcesses(DWORD processes[])
{
auto processesFound = -1;
auto waitingForSpotify = false;
cout << "Locating Spotify processes... \n";
while (processesFound != 3)
{
processesFound = FindProcessID("Spotify.exe", processes);
if (processesFound == 3)
{
cout << "Found 3 Spotify processes succesfully.\n\n";
if (debug)
{
cout << "PIDs:\n";
for (auto i = 0; i < processesFound; i++)
cout << " - " << processes[i] << endl;
cout << endl;
}
}
else
{
if (!waitingForSpotify)
{
waitingForSpotify = true;
cout << "Couldn't find 3 processes, found " << processesFound << " instead.\n\n";
cout << "Make sure Spotify is running.\n";
}
Sleep(1000);
}
}
return 0;
}
string GetWindowTitle(HWND handle)
{
auto length = ::GetWindowTextLength(handle);
TCHAR* buffer;
buffer = new TCHAR[length + 1];
memset(buffer, 0, (length + 1) * sizeof(TCHAR));
if (!GetWindowText(handle, buffer, length + 1))
{
cerr << "Title bar is empty, or window handle is invalid.\n";
getchar();
exit(EXIT_FAILURE);
}
auto windowTitle = tstring(buffer);
if(debug)
//cout << handle << TEXT(": ") << windowTitle << endl;
delete[] buffer;
return windowTitle;
}
void initApplication()
{
SetConsoleTitleA("Spotify Ad Muter - v1.0");
cout << string(35, '=');
cout << "\n|| Spotify Ad Muter v" + APP_VERSION + " ||\n";
cout << string(35, '=') << "\n\n";
}
// Returns true if currently playing, false if paused
bool ReadPlayingStatus(DWORD processID)
{
// Get a handle to the process.
HANDLE hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
processID
);
if (!hProcess)
{
cerr << "Couldn't open Spotify process.";
getchar();
}
DWORD playingStatusAdress = 0xF5DC58; // This is the address that we want to read from
unsigned char value = 0; // This will store our value. In my case, its an integer, which is the timer
ReadProcessMemory(hProcess, reinterpret_cast<void*>(playingStatusAdress), &value, sizeof(value), nullptr);
// Byte is either 3 for playing or 5 for paused
assert(value == 3 || value == 5, "Adress needs updating.");
return value == 3;
}
int main()
{
DWORD processes[3];
bool playing;
const auto filler = string(100, ' ');
initApplication();
LocateSpotifyProcesses(processes);
// Use the first found PID to find the window handle (any one of the 3 works)
auto spotifyHandle = GetSpofifyWindowHandle(processes[2]);
if(debug)
cout << "Spotify window handle: " << spotifyHandle << endl;
while(1)
{
playing = ReadPlayingStatus(processes[0]);
cout << "\rStatus: ";
if (playing)
cout << "Playing " + GetWindowTitle(spotifyHandle);
else
cout << "Paused" << filler;
Sleep(500);
}
getchar();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment