aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/soyuz/library.hh4
-rw-r--r--include/soyuz/resource.hh17
-rw-r--r--include/soyuz/soyuz.hh1
-rw-r--r--include/soyuz/tray.hh26
-rw-r--r--include/soyuz/windows.hh3
-rw-r--r--resource/resource.rc44
-rw-r--r--resource/soyuz.icobin0 -> 14982 bytes
-rw-r--r--soyuz/CMakeLists.txt4
-rw-r--r--soyuz/library.cc23
-rw-r--r--soyuz/soyuz.cc84
-rw-r--r--soyuz/tray.cc135
-rw-r--r--soyuz/windows.cc3
12 files changed, 324 insertions, 20 deletions
diff --git a/include/soyuz/library.hh b/include/soyuz/library.hh
index 41668a7..ae7ce13 100644
--- a/include/soyuz/library.hh
+++ b/include/soyuz/library.hh
@@ -11,8 +11,12 @@
#define NT_SUCCESS(status) (status >= 0)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
+namespace soyuz {
+
static auto enum_windows_proc(HWND hwnd, LPARAM lparam) -> BOOL;
auto find_lunar() -> DWORD;
auto delete_handle(DWORD pid) -> int;
+}
+
#endif //SOYUZ_LIBRARY_HH
diff --git a/include/soyuz/resource.hh b/include/soyuz/resource.hh
new file mode 100644
index 0000000..89c1242
--- /dev/null
+++ b/include/soyuz/resource.hh
@@ -0,0 +1,17 @@
+// Copyright (C) 2021-2021 Fuwn
+// SPDX-License-Identifier: GPL-3.0-only
+
+#ifndef SOYUZ_RESOURCE_HH
+#define SOYUZ_RESOURCE_HH
+
+#pragma once
+
+#include <shellapi.h>
+#include <Windows.h>
+
+#define ICO1 101
+#define ID_TRAY_APP_ICON 1001
+#define ID_TRAY_EXIT 1002
+#define WM_SYSICON (WM_USER + 1)
+
+#endif //SOYUZ_RESOURCE_HH
diff --git a/include/soyuz/soyuz.hh b/include/soyuz/soyuz.hh
index 20cf432..99ffaa4 100644
--- a/include/soyuz/soyuz.hh
+++ b/include/soyuz/soyuz.hh
@@ -8,5 +8,6 @@
#define LUNAR_WINDOW_NAME_BASE "Lunar Client ("
#define DISCORD_IPC_NAMED_PIPE_NAME L"\\Device\\NamedPipe\\discord-ipc-0"
+#define WINDOW_TRAY_NAME "Soyuz - 1.1.0 | Copyright (C) 2021-2021 Fuwn"
#endif //SOYUZ_SOYUZ_HH
diff --git a/include/soyuz/tray.hh b/include/soyuz/tray.hh
new file mode 100644
index 0000000..27c3214
--- /dev/null
+++ b/include/soyuz/tray.hh
@@ -0,0 +1,26 @@
+// Copyright (C) 2021-2021 Fuwn
+// SPDX-License-Identifier: GPL-3.0-only
+
+#ifndef SOYUZ_TRAY_HH
+#define SOYUZ_TRAY_HH
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <Windows.h>
+
+#define LOG(message) logs.push_back(message);
+
+auto WindowProcedure(HWND, UINT, WPARAM, LPARAM) -> LRESULT; // CALLBACK
+auto minimize() -> void;
+auto restore() -> void;
+auto InitNotifyIconData() -> void;
+
+namespace soyuz {
+
+auto log(const std::string &message) -> void;
+
+}
+
+#endif //SOYUZ_TRAY_HH
diff --git a/include/soyuz/windows.hh b/include/soyuz/windows.hh
index dd145ac..f709444 100644
--- a/include/soyuz/windows.hh
+++ b/include/soyuz/windows.hh
@@ -1,3 +1,6 @@
+// Copyright (C) 2021-2021 Fuwn
+// SPDX-License-Identifier: GPL-3.0-only
+
#ifndef SOYUZ_WINDOWS_HH
#define SOYUZ_WINDOWS_HH
diff --git a/resource/resource.rc b/resource/resource.rc
new file mode 100644
index 0000000..32cf3e6
--- /dev/null
+++ b/resource/resource.rc
@@ -0,0 +1,44 @@
+// Copyright (C) 2021-2021 Fuwn
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include "soyuz/resource.hh"
+
+ICO1 ICON DISCARDABLE "soyuz.ico"
+
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION 1,0,0,0
+PRODUCTVERSION 1.1.0 // 1,0,0,0
+FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+FILEFLAGS 0x9L
+#else
+FILEFLAGS 0x8L
+#endif
+FILEOS 0x40004L
+FILETYPE 0x2L
+FILESUBTYPE 0x0L
+BEGIN
+BLOCK "StringFileInfo"
+BEGIN
+BLOCK "040904b0"
+BEGIN
+VALUE "Comments", "\0"
+VALUE "CompanyName", "Fuwn Technologies\0"
+VALUE "FileDescription", "Discord RPC Blocker for Lunar Client\0"
+VALUE "FileVersion", "1,0,0,0\0"
+VALUE "InternalName", "Soyuz\0"
+VALUE "LegalCopyright", "Copyright (C) 2021-2021 Fuwn\0"
+VALUE "LegalTrademarks", "\0"
+VALUE "OriginalFilename", "soyuz.exe\0"
+VALUE "PrivateBuild", "1\0"
+VALUE "ProductName", "Soyuz\0"
+VALUE "ProductVersion", "1.1.0\0" // 10, 0, 0, 0
+VALUE "SpecialBuild", "\0"
+END
+END
+BLOCK "VarFileInfo"
+BEGIN
+VALUE "Translation", 0x409, 1200
+END
+END
diff --git a/resource/soyuz.ico b/resource/soyuz.ico
new file mode 100644
index 0000000..3b2f9cc
--- /dev/null
+++ b/resource/soyuz.ico
Binary files differ
diff --git a/soyuz/CMakeLists.txt b/soyuz/CMakeLists.txt
index 01eddb7..fdf5897 100644
--- a/soyuz/CMakeLists.txt
+++ b/soyuz/CMakeLists.txt
@@ -1,5 +1,7 @@
-add_executable(${PROJECT_NAME}
+add_executable(${PROJECT_NAME} WIN32
+ tray.cc
library.cc
+ ../resource/resource.rc
soyuz.cc
windows.cc
)
diff --git a/soyuz/library.cc b/soyuz/library.cc
index 5356bcd..bf2b451 100644
--- a/soyuz/library.cc
+++ b/soyuz/library.cc
@@ -3,20 +3,24 @@
#include <cstdio>
#include <memory>
+#include <sstream>
#include <string>
#include <Windows.h>
#include "soyuz/library.hh"
#include "soyuz/soyuz.hh"
+#include "soyuz/tray.hh"
#include "soyuz/windows.hh"
+namespace soyuz {
+
static auto enum_windows_proc(HWND hwnd, LPARAM lparam) -> BOOL {
int length = GetWindowTextLength(hwnd);
auto title = new CHAR[length + 1];
GetWindowText(hwnd, title, length);
if (strstr(title, LUNAR_WINDOW_NAME_BASE)) {
- *((HWND*)lparam) = hwnd;
+ *((HWND *)lparam) = hwnd;
delete[] title;
@@ -48,7 +52,9 @@ auto delete_handle(DWORD pid) -> int {
pid
);
if (!lunar) {
- printf("could not open handle to lunar client: %lu\n", GetLastError());
+ std::stringstream ss;
+ ss << "could not open handle to lunar client: " << GetLastError();
+ soyuz::log(ss.str());
return 1;
}
@@ -69,12 +75,12 @@ auto delete_handle(DWORD pid) -> int {
if (NT_SUCCESS(status)) { break; }
if (status == STATUS_INFO_LENGTH_MISMATCH) { size += 1 << 10; continue; }
- printf("could not enumerate handle\n");
+ soyuz::log("could not enumerate handle, skipping");
return 1;
}
- auto *info = reinterpret_cast<PROCESS_HANDLE_SNAPSHOT_INFORMATION*>(buffer.get());
+ auto *info = reinterpret_cast<PROCESS_HANDLE_SNAPSHOT_INFORMATION *>(buffer.get());
for (ULONG i = 0; i < info->NumberOfHandles; ++i) {
HANDLE h = info->Handles[i].HandleValue;
HANDLE target;
@@ -105,23 +111,22 @@ auto delete_handle(DWORD pid) -> int {
swprintf_s(target_name, DISCORD_IPC_NAMED_PIPE_NAME);
size_t length = wcslen(target_name);
- auto *name = reinterpret_cast<UNICODE_STRING*>(name_buffer);
+ auto *name = reinterpret_cast<UNICODE_STRING *>(name_buffer);
if (name->Buffer && _wcsnicmp(name->Buffer, target_name, length) == 0) {
- printf("found lunar client's discord ipc named pipe\n");
+ soyuz::log("found lunar client's discord ipc named pipe");
DuplicateHandle(
lunar,
h,
GetCurrentProcess(),
&target,
-
0,
FALSE,
DUPLICATE_CLOSE_SOURCE
);
CloseHandle(target);
- printf("closed lunar client's discord ipc named pipe\n");
+ soyuz::log("closed lunar client's discord ipc named pipe");
return 0;
}
@@ -129,3 +134,5 @@ auto delete_handle(DWORD pid) -> int {
return 0;
}
+
+}
diff --git a/soyuz/soyuz.cc b/soyuz/soyuz.cc
index f6be4e2..b030bd5 100644
--- a/soyuz/soyuz.cc
+++ b/soyuz/soyuz.cc
@@ -3,25 +3,87 @@
#pragma comment(lib, "ntdll.lib")
-#include <cstdio>
+#include <thread>
#include <Windows.h>
#include "soyuz/library.hh"
+#include "soyuz/resource.hh"
+#include "soyuz/tray.hh"
-auto main() -> int {
- DWORD pid = find_lunar();
- if (pid == 0 || pid == 3435973836) {
- printf("could not locate lunar client\n");
+extern UINT WM_TASKBAR;
+extern HWND window;
+extern HMENU menu;
+extern NOTIFYICONDATA data;
+extern TCHAR tip[64];
+extern char class_name[];
+extern std::vector<std::string> logs;
- return 1;
+auto WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR argument, int show) -> int { // WINAPI
+ MSG messages;
+ WNDCLASSEX wincl;
+ WM_TASKBAR = RegisterWindowMessageA("TaskbarCreated");
+
+ wincl.hInstance = instance;
+ wincl.lpszClassName = class_name;
+ wincl.lpfnWndProc = WindowProcedure;
+ wincl.style = CS_DBLCLKS;
+ wincl.cbSize = sizeof(WNDCLASSEX);
+
+ wincl.hIcon = LoadIcon (GetModuleHandle(nullptr), MAKEINTRESOURCE(ICO1));
+ wincl.hIconSm = LoadIcon (GetModuleHandle(nullptr), MAKEINTRESOURCE(ICO1));
+ wincl.hCursor = LoadCursor (nullptr, IDC_ARROW);
+ wincl.lpszMenuName = nullptr;
+ wincl.cbClsExtra = 0;
+ wincl.cbWndExtra = 0;
+ wincl.hbrBackground = (HBRUSH)(CreateSolidBrush(RGB(255, 255, 255)));
+ if (!RegisterClassEx (&wincl)) {
+ return 0;
}
- printf("located lunar client: %lu\n\n", pid);
- for (;;) {
- if (delete_handle(pid) == 1) {
- printf("unable to close lunar client's discord ipc named pipe\n");
+ window = CreateWindowEx(
+ 0,
+ class_name,
+ class_name,
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ 544,
+ 375,
+ HWND_DESKTOP,
+ nullptr,
+ instance,
+ nullptr
+ );
+ InitNotifyIconData();
+ ShowWindow(window, show);
+
+ // https://medium.com/@vgasparyan1995/a-new-thread-in-c-20-jthread-ebd121ae8906
+ std::jthread soyuz {[](const std::stop_token& stop) -> void {
+ DWORD pid = soyuz::find_lunar();
+ if (pid == 0 || pid == 3435973836) {
+ soyuz::log("could not locate lunar client");
+
+ exit(1);
}
+ std::stringstream ss;
+ ss << "located lunar client: pid " << pid;
+ soyuz::log(ss.str());
+
+ while (!stop.stop_requested()) {
+ if (soyuz::delete_handle(pid) == 1) {
+ soyuz::log("unable to close lunar client's discord ipc named pipe");
+ }
+ }
+ }};
+
+ while (GetMessage(&messages, nullptr, 0, 0)) {
+ TranslateMessage(&messages);
+ DispatchMessage(&messages);
}
- return 0;
+ soyuz::log("requesting exit");
+ soyuz.request_stop(); soyuz.join();
+
+ soyuz::log("exiting");
+ return (int)messages.wParam;
}
diff --git a/soyuz/tray.cc b/soyuz/tray.cc
new file mode 100644
index 0000000..1796bf0
--- /dev/null
+++ b/soyuz/tray.cc
@@ -0,0 +1,135 @@
+// Copyright (C) 2021-2021 Fuwn
+// SPDX-License-Identifier: GPL-3.0-only
+
+#include "soyuz/tray.hh"
+#include "soyuz/resource.hh"
+#include "soyuz/soyuz.hh"
+
+UINT WM_TASKBAR = 0;
+HWND window;
+HMENU menu;
+NOTIFYICONDATA data;
+TCHAR tip[64] = TEXT(WINDOW_TRAY_NAME);
+char class_name[] = WINDOW_TRAY_NAME;
+std::vector<std::string> logs = {
+ "lunar client has been hooked, you may now close this window",
+};
+
+auto WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -> LRESULT { // CALLBACK
+ if (message == WM_TASKBAR && !IsWindowVisible(window)) {
+ minimize(); return 0;
+ }
+
+ switch (message) {
+ case WM_ACTIVATE:
+ Shell_NotifyIcon(NIM_ADD, &data);
+ break;
+
+ case WM_PAINT: {
+ PAINTSTRUCT ps;
+ RECT rect;
+ HDC hdc = BeginPaint(window, &ps);
+
+ GetClientRect(hwnd, &rect);
+
+ int height = 5;
+ for (const auto &i : logs) {
+ TextOut(hdc, 5, height, i.c_str(), (int)strlen(i.c_str()));
+ height += 20;
+ }
+
+ EndPaint(window, &ps);
+ } break;
+
+ case WM_CREATE:
+ ShowWindow(window, SW_HIDE);
+ menu = CreatePopupMenu();
+ AppendMenu(menu, MF_STRING, ID_TRAY_EXIT, TEXT("Exit Soyuz"));
+
+ break;
+
+ case WM_SYSCOMMAND:
+ switch(wParam & 0xFFF0) {
+ case SC_MINIMIZE:
+ case SC_CLOSE:
+ minimize(); return 0; // break;
+ } break;
+
+ case WM_SYSICON: {
+ switch (wParam) {
+ case ID_TRAY_APP_ICON:
+ SetForegroundWindow(window);
+ break;
+
+ default: ;
+ }
+
+ if (lParam == WM_LBUTTONUP) {
+ restore();
+ } else if (lParam == WM_RBUTTONDOWN) {
+ POINT curPoint;
+ GetCursorPos(&curPoint);
+ SetForegroundWindow(window);
+
+ UINT clicked = TrackPopupMenu(
+ menu,
+ TPM_RETURNCMD | TPM_NONOTIFY,
+ curPoint.x,
+ curPoint.y,
+ 0,
+ hwnd,
+ nullptr
+ );
+
+ SendMessage(hwnd, WM_NULL, 0, 0);
+ if (clicked == ID_TRAY_EXIT) {
+ Shell_NotifyIcon(NIM_DELETE, &data);
+ PostQuitMessage(0);
+ }
+ }
+ } break;
+
+ case WM_NCHITTEST: {
+ LRESULT uHitTest = DefWindowProc(hwnd, WM_NCHITTEST, wParam, lParam);
+ if (uHitTest == HTCLIENT) {
+ return HTCAPTION;
+ } else {
+ return uHitTest;
+ }
+ }
+
+ case WM_CLOSE:
+ minimize(); return 0; // break;
+
+ case WM_DESTROY:
+ PostQuitMessage (0); break;
+
+ default: ;
+ }
+
+ return DefWindowProc(hwnd, message, wParam, lParam);
+}
+
+void minimize() { ShowWindow(window, SW_HIDE); }
+void restore() { ShowWindow(window, SW_SHOW); }
+
+void InitNotifyIconData() {
+ memset(&data, 0, sizeof(NOTIFYICONDATA));
+
+ data.cbSize = sizeof(NOTIFYICONDATA);
+ data.hWnd = window;
+ data.uID = ID_TRAY_APP_ICON;
+ data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+ data.uCallbackMessage = WM_SYSICON;
+ data.hIcon = (HICON)LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(ICO1));
+ strncpy_s(data.szTip, tip, sizeof(tip));
+}
+
+namespace soyuz {
+
+auto log(const std::string &message) -> void {
+ LOG(message)
+ RedrawWindow(window, nullptr, nullptr, RDW_INVALIDATE | RDW_UPDATENOW);
+}
+
+}
diff --git a/soyuz/windows.cc b/soyuz/windows.cc
index df1d08f..4cc84fc 100644
--- a/soyuz/windows.cc
+++ b/soyuz/windows.cc
@@ -1 +1,4 @@
+// Copyright (C) 2021-2021 Fuwn
+// SPDX-License-Identifier: GPL-3.0-only
+
#include "soyuz/windows.hh"