237 lines
6 KiB
C++
237 lines
6 KiB
C++
|
|
// tray agent functions for butt
|
|
//
|
|
// Copyright 2007-2021 by Daniel Noethen.
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2, or (at your option)
|
|
// any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
|
|
#ifdef WIN32
|
|
#include <windows.h>
|
|
#include <string>
|
|
#include <FL/x.H>
|
|
|
|
#include "flgui.h"
|
|
#include "cfg.h"
|
|
#include "config.h"
|
|
#include "butt.h"
|
|
#include "sha256.h"
|
|
#include "tray_agent.h"
|
|
|
|
#define AGENT_CLASS "AutoHotkeyGUI"
|
|
#define AGENT_TITLE "buttTrayAgent11-03-2021"
|
|
#define AGENT_SHA256 "80015491aabc0b6a3470cd375d8304a5b4446b2ee88929e552c03676ca877f53"
|
|
#define AGENT_EXECUTABLE "butt_agent.exe"
|
|
|
|
static char song_buf[512];
|
|
|
|
static int check_hash(void)
|
|
{
|
|
char agent_sha256[65];
|
|
const int salt = 0xA50D;
|
|
|
|
if (sha256_file((char *)AGENT_EXECUTABLE, agent_sha256, salt) == 0) {
|
|
// #warning "REMOVE THIS RETURN FOR PRODUCTION"
|
|
// printf("agent hash: %s\n", agent_sha256);
|
|
// return 0;
|
|
// #warning "REMOVE THIS RETURN FOR PRODUCTION"
|
|
|
|
if (strncmp(agent_sha256, AGENT_SHA256, 64) == 0) {
|
|
return 0; // correct hash found
|
|
}
|
|
}
|
|
|
|
return 1; // error
|
|
}
|
|
|
|
static int send_msg(char *cmsg)
|
|
{
|
|
COPYDATASTRUCT MyCDS;
|
|
wchar_t wmsg[512];
|
|
|
|
// Convert normal char array to wide char array
|
|
mbstowcs(wmsg, cmsg, 512);
|
|
|
|
MyCDS.dwData = 0;
|
|
MyCDS.cbData = sizeof(wmsg);
|
|
MyCDS.lpData = &wmsg;
|
|
|
|
// Get handle of butt main window
|
|
HWND hwButt = fl_xid(fl_g->window_main);
|
|
HWND hwAgent;
|
|
|
|
if (tray_agent_is_running(&hwAgent) == 1) {
|
|
SendMessage(hwAgent, WM_COPYDATA, (WPARAM)(HWND)hwButt, (LPARAM)(LPVOID)&MyCDS);
|
|
return 0;
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int tray_agent_start(void)
|
|
{
|
|
char command[32];
|
|
STARTUPINFOA si;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
// Do not start if it is already running
|
|
if (tray_agent_is_running(NULL) == 1) {
|
|
return 1;
|
|
}
|
|
|
|
if (check_hash() != 0) {
|
|
return 1; // agent has wrong hash. Do not execute it!
|
|
}
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cb = sizeof(si);
|
|
ZeroMemory(&pi, sizeof(pi));
|
|
|
|
snprintf(command, sizeof(command), "%s -s", AGENT_EXECUTABLE);
|
|
|
|
if (CreateProcessA(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) != 0) {
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
|
|
struct timespec wait_50ms;
|
|
wait_50ms.tv_sec = 0;
|
|
wait_50ms.tv_nsec = (50 * 1000 * 1000);
|
|
|
|
// Wait max 40*50 ms = 2 seconds until agent has been started
|
|
int timed_out = 1;
|
|
for (int i = 0; i < 40; i++) {
|
|
if (tray_agent_is_running(NULL) == 1) {
|
|
timed_out = 0;
|
|
break;
|
|
}
|
|
nanosleep(&wait_50ms, NULL);
|
|
}
|
|
if (timed_out == 1) {
|
|
return 1; // error: tray agent still not running
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
else {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int tray_agent_is_running(HWND *hwAgent)
|
|
{
|
|
HWND hwWindow = FindWindow(AGENT_CLASS, AGENT_TITLE);
|
|
|
|
if (hwWindow != NULL) {
|
|
if (hwAgent != NULL) {
|
|
*hwAgent = hwWindow;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void tray_agent_set_song(char *song)
|
|
{
|
|
snprintf(song_buf, sizeof(song_buf), "%s", song);
|
|
}
|
|
|
|
int tray_agent_send_cmd(int cmd)
|
|
{
|
|
char msg[512];
|
|
char tray_title[128];
|
|
char custom_window_title[128];
|
|
int minimize;
|
|
|
|
int pid = GetCurrentProcessId();
|
|
|
|
if (cfg.gui.window_title[0] != '\0') {
|
|
snprintf(custom_window_title, sizeof(custom_window_title), "%s", cfg.gui.window_title);
|
|
}
|
|
else {
|
|
snprintf(custom_window_title, sizeof(custom_window_title), "dummy");
|
|
}
|
|
|
|
if (cfg.main.num_of_srv > 0) {
|
|
snprintf(tray_title, sizeof(tray_title), "%s", cfg.srv[cfg.selected_srv]->name);
|
|
}
|
|
else {
|
|
snprintf(tray_title, sizeof(tray_title), "%s", "no server");
|
|
}
|
|
|
|
switch (cmd) {
|
|
case TA_MINIMIZE:
|
|
// Start agent when minimizing and agent is not running yet
|
|
if (tray_agent_is_running(NULL) == 0) {
|
|
if (tray_agent_start() != 0) {
|
|
return 1; // Tray agent could not be started
|
|
}
|
|
}
|
|
minimize = 1;
|
|
snprintf(msg, sizeof(msg), "%s\t%d\t%d\t%s\t%d\t%s", VERSION, minimize, pid, tray_title, connected, custom_window_title);
|
|
break;
|
|
case TA_START:
|
|
case TA_SERVER_NAME:
|
|
case TA_CONNECT_STATE:
|
|
minimize = 0;
|
|
snprintf(msg, sizeof(msg), "%s\t%d\t%d\t%s\t%d\t%s", VERSION, minimize, pid, tray_title, connected, custom_window_title);
|
|
break;
|
|
case TA_SONG_UPDATE:
|
|
minimize = 0;
|
|
snprintf(msg, sizeof(msg), "%s\t%d\t%d\t%s\t%d\t%s\t%s", VERSION, minimize, pid, tray_title, connected, custom_window_title, song_buf);
|
|
break;
|
|
default:
|
|
return 1;
|
|
}
|
|
|
|
int ret = send_msg(msg);
|
|
if ((ret == 0) && (minimize == 1)) {
|
|
if (fl_g->window_cfg->shown()) // Close settings window when minimizing to tray
|
|
{
|
|
fl_g->window_cfg->hide();
|
|
Fl::remove_timeout(&cfg_win_pos_timer);
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int tray_agent_stop(void)
|
|
{
|
|
char command[32];
|
|
STARTUPINFOA si;
|
|
PROCESS_INFORMATION pi;
|
|
|
|
if (check_hash() != 0) {
|
|
return 1; // Agent has wrong hash. Do not execute it!
|
|
}
|
|
|
|
ZeroMemory(&si, sizeof(si));
|
|
si.cb = sizeof(si);
|
|
ZeroMemory(&pi, sizeof(pi));
|
|
|
|
snprintf(command, sizeof(command), "%s -q", AGENT_EXECUTABLE);
|
|
|
|
if (CreateProcessA(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) != 0) {
|
|
CloseHandle(pi.hProcess);
|
|
CloseHandle(pi.hThread);
|
|
return 0;
|
|
}
|
|
else {
|
|
return 1; // CreateProcessA failed
|
|
}
|
|
}
|
|
|
|
#endif // ifdef WIN32
|