mirror of
https://github.com/EnderIce2/rpc-bridge.git
synced 2025-07-01 10:29:14 +00:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
08feef776b | |||
8545467a85
|
|||
20728818d2
|
|||
751d9ab3b7
|
|||
b906c009f4
|
|||
38e620836e
|
|||
a640dd5af1
|
|||
8fbe00b555
|
|||
bf98b8784c
|
|||
3021f8e4ad
|
|||
655caa2934
|
|||
da2a006ffb | |||
e61fbf556e | |||
2dce976038 | |||
2fe1dd5ece | |||
c23af8300c
|
|||
14226489d7 | |||
66f3bc53f1 | |||
dcd9cf520e | |||
8dd5952a64 | |||
81aa5d8d18
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
*.o
|
*.o
|
||||||
*.exe
|
*.exe
|
||||||
*.res
|
*.res
|
||||||
|
*.elf
|
||||||
|
14
README.md
14
README.md
@ -25,6 +25,8 @@ Logs are stored in `C:\windows\logs\bridge.log`.
|
|||||||
- 
|
- 
|
||||||
- To remove, the same process can be followed, but click `Remove` instead.
|
- To remove, the same process can be followed, but click `Remove` instead.
|
||||||
|
|
||||||
|
*Note, an [extra step](https://github.com/EnderIce2/rpc-bridge?tab=readme-ov-file#macos) is needed on MacOS*
|
||||||
|
|
||||||
##### Lutris
|
##### Lutris
|
||||||
|
|
||||||
- Click on a game and select `Run EXE inside Wine prefix`.
|
- Click on a game and select `Run EXE inside Wine prefix`.
|
||||||
@ -50,9 +52,17 @@ Logs are stored in `C:\windows\logs\bridge.log`.
|
|||||||
- Globally
|
- Globally
|
||||||
- `flatpak override --user --filesystem=xdg-run/discord-ipc-0`
|
- `flatpak override --user --filesystem=xdg-run/discord-ipc-0`
|
||||||
|
|
||||||
## macOS
|
##### MacOS
|
||||||
|
|
||||||
On macOS, follow [these instructions](https://enderice2.github.io/rpc-bridge/installation.html#macos).
|
The steps for MacOS are almost the same, but due to the way `$TMPDIR` works, you will have to install a **LaunchAgent**.
|
||||||
|
|
||||||
|
- Download the latest build from the [releases](https://github.com/EnderIce2/rpc-bridge/releases)
|
||||||
|
- Open the archive and make the `launchd.sh` script executable by doing: `chmod +x launchd.sh`
|
||||||
|
- To **install** the LaunchAgent, run `./launchd install` and to **remove** it simply run `./launchd remove`.
|
||||||
|
|
||||||
|
The script will add a LaunchAgent to your user, that will symlink the `$TMPDIR` directory to `/tmp/rpc-bridge/tmpdir`.
|
||||||
|
|
||||||
|
*Note: You will need to launch the `bridge.exe` file manually in Wine at least once for it to register and launch automatically the next time.*
|
||||||
|
|
||||||
## Compiling from source
|
## Compiling from source
|
||||||
|
|
||||||
|
38
bridge.c
38
bridge.c
@ -43,6 +43,8 @@
|
|||||||
__attribute__((__always_inline__, __gnu_inline__))
|
__attribute__((__always_inline__, __gnu_inline__))
|
||||||
#define naked __attribute__((naked))
|
#define naked __attribute__((naked))
|
||||||
|
|
||||||
|
#define BUFFER_LENGTH 2048
|
||||||
|
|
||||||
typedef unsigned short sa_family_t;
|
typedef unsigned short sa_family_t;
|
||||||
typedef char *caddr_t;
|
typedef char *caddr_t;
|
||||||
typedef unsigned socklen_t;
|
typedef unsigned socklen_t;
|
||||||
@ -252,15 +254,29 @@ void ConnectToSocket(int fd)
|
|||||||
if (IsLinux)
|
if (IsLinux)
|
||||||
runtime = native_getenv("XDG_RUNTIME_DIR");
|
runtime = native_getenv("XDG_RUNTIME_DIR");
|
||||||
else
|
else
|
||||||
runtime = native_getenv("TMPDIR");
|
|
||||||
if (runtime == NULL)
|
|
||||||
{
|
{
|
||||||
print("IPC directory not set\n");
|
runtime = native_getenv("TMPDIR");
|
||||||
if (!RunningAsService)
|
if (runtime == NULL)
|
||||||
MessageBox(NULL, "IPC directory not set",
|
{
|
||||||
"Environment variable not set",
|
runtime = "/tmp/rpc-bridge/tmpdir";
|
||||||
MB_OK | MB_ICONSTOP);
|
print("IPC directory not set, fallback to /tmp/rpc-bridge/tmpdir\n");
|
||||||
ExitProcess(1);
|
|
||||||
|
// Check if the directory exists
|
||||||
|
DWORD dwAttrib = GetFileAttributes(runtime);
|
||||||
|
if (dwAttrib == INVALID_FILE_ATTRIBUTES || !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
{
|
||||||
|
print("IPC directory does not exist: %s. If you're on MacOS, see the github guide on how to install the launchd service.\n", runtime);
|
||||||
|
// Handle the case where the directory doesn't exist
|
||||||
|
// For example, create the directory
|
||||||
|
|
||||||
|
int result = MessageBox(NULL, "IPC directory does not exist\nDo you want to open the installation guide?",
|
||||||
|
"Directory not found",
|
||||||
|
MB_YESNO | MB_ICONSTOP);
|
||||||
|
if (result == IDYES)
|
||||||
|
ShellExecute(NULL, "open", "https://enderice2.github.io/rpc-bridge/installation.html#macos", NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
ExitProcess(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print("IPC directory: %s\n", runtime);
|
print("IPC directory: %s\n", runtime);
|
||||||
@ -322,7 +338,7 @@ void PipeBufferInThread(LPVOID lpParam)
|
|||||||
int EOFCount = 0;
|
int EOFCount = 0;
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[BUFFER_LENGTH];
|
||||||
int read = sys_read(bt->fd, buffer, sizeof(buffer));
|
int read = sys_read(bt->fd, buffer, sizeof(buffer));
|
||||||
|
|
||||||
if (unlikely(read < 0))
|
if (unlikely(read < 0))
|
||||||
@ -417,7 +433,7 @@ void PipeBufferOutThread(LPVOID lpParam)
|
|||||||
bt->fd, bt->hPipe);
|
bt->fd, bt->hPipe);
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
char buffer[1024];
|
char buffer[BUFFER_LENGTH];
|
||||||
DWORD dwRead;
|
DWORD dwRead;
|
||||||
|
|
||||||
if (unlikely(!ReadFile(bt->hPipe, buffer, sizeof(buffer),
|
if (unlikely(!ReadFile(bt->hPipe, buffer, sizeof(buffer),
|
||||||
@ -488,7 +504,7 @@ NewConnection:
|
|||||||
CreateNamedPipe("\\\\.\\pipe\\discord-ipc-0",
|
CreateNamedPipe("\\\\.\\pipe\\discord-ipc-0",
|
||||||
PIPE_ACCESS_DUPLEX,
|
PIPE_ACCESS_DUPLEX,
|
||||||
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
|
||||||
1, 1024, 1024, 0, NULL);
|
PIPE_UNLIMITED_INSTANCES, BUFFER_LENGTH, BUFFER_LENGTH, 0, NULL);
|
||||||
|
|
||||||
if (hPipe == INVALID_HANDLE_VALUE)
|
if (hPipe == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
|
25
bridge.rc
25
bridge.rc
@ -2,14 +2,7 @@
|
|||||||
#include <winuser.h>
|
#include <winuser.h>
|
||||||
#include <winresrc.h>
|
#include <winresrc.h>
|
||||||
|
|
||||||
#define VER_VERSION 1,1,0,0
|
#include "resource.h"
|
||||||
#define VER_VERSION_STR "1.1\0"
|
|
||||||
|
|
||||||
#ifndef DEBUG
|
|
||||||
#define VER_DEBUG 0
|
|
||||||
#else
|
|
||||||
#define VER_DEBUG VS_FF_DEBUG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION VER_VERSION
|
FILEVERSION VER_VERSION
|
||||||
@ -39,6 +32,22 @@ BEGIN
|
|||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDR_MAINMENU MENU
|
||||||
|
BEGIN
|
||||||
|
POPUP "&View"
|
||||||
|
BEGIN
|
||||||
|
MENUITEM "&Log", IDM_VIEW_LOG
|
||||||
|
END
|
||||||
|
POPUP "&Help"
|
||||||
|
BEGIN
|
||||||
|
MENUITEM "&Documentation", IDM_HELP_DOCUMENTATION
|
||||||
|
MENUITEM "&License", IDM_HELP_LICENSE
|
||||||
|
MENUITEM "&About", IDM_HELP_ABOUT
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
IDR_LICENSE_TXT RCDATA "LICENSE"
|
||||||
|
|
||||||
IDI_ICON_128 ICON "bridge.ico"
|
IDI_ICON_128 ICON "bridge.ico"
|
||||||
|
|
||||||
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST bridge.manifest
|
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST bridge.manifest
|
||||||
|
83
build/launchd.sh
Executable file
83
build/launchd.sh
Executable file
@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This script is used to create a LaunchAgent on MacOS, to support the service functionality.
|
||||||
|
# Usage: ./launchd.sh (install|remove)
|
||||||
|
|
||||||
|
SYMLINK=/tmp/rpc-bridge/tmpdir
|
||||||
|
LOCATION=~/Library/Application\ Support/rpc-bridge
|
||||||
|
SCRIPT=$LOCATION/rpc-bridge
|
||||||
|
AGENT=~/Library/LaunchAgents/com.enderice2.rpc-bridge.plist
|
||||||
|
|
||||||
|
function install() {
|
||||||
|
# Directories
|
||||||
|
if [ ! -d "$SYMLINK" ]; then
|
||||||
|
mkdir -p "$SYMLINK"
|
||||||
|
fi
|
||||||
|
if [ ! -d "$LOCATION" ]; then
|
||||||
|
mkdir -p "$LOCATION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Link script
|
||||||
|
if [ -f "$SCRIPT" ]; then
|
||||||
|
rm -f "$SCRIPT"
|
||||||
|
fi
|
||||||
|
echo "#!/bin/bash
|
||||||
|
TARGET_DIR=/tmp/rpc-bridge/tmpdir
|
||||||
|
if [ ! -d "\$TARGET_DIR" ]; then
|
||||||
|
mkdir -p "\$TARGET_DIR"
|
||||||
|
fi
|
||||||
|
rm -rf "\$TARGET_DIR"
|
||||||
|
ln -s "\$TMPDIR" "\$TARGET_DIR"" > "$SCRIPT"
|
||||||
|
chmod +x "$SCRIPT"
|
||||||
|
|
||||||
|
# LaunchAgent
|
||||||
|
if [ -f "$AGENT" ]; then
|
||||||
|
rm -f "$AGENT"
|
||||||
|
fi
|
||||||
|
echo "<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST File Format//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>com.enderice2.rpc-bridge</string>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>$SCRIPT</string>
|
||||||
|
</array>
|
||||||
|
<key>RunAtLoad</key>
|
||||||
|
<true />
|
||||||
|
</dict>
|
||||||
|
</plist>" > "$AGENT"
|
||||||
|
launchctl load "$AGENT"
|
||||||
|
echo "LaunchAgent has been installed."
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove() {
|
||||||
|
rm -f "$SYMLINK"
|
||||||
|
rm -f "$SCRIPT"
|
||||||
|
rmdir "$LOCATION"
|
||||||
|
if [ -f "$AGENT" ]; then
|
||||||
|
launchctl unload "$AGENT"
|
||||||
|
fi
|
||||||
|
rm -f "$AGENT"
|
||||||
|
echo "LaunchAgent has been removed."
|
||||||
|
}
|
||||||
|
|
||||||
|
# CLI
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "Usage: $0 (install|remove)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
install)
|
||||||
|
install
|
||||||
|
;;
|
||||||
|
remove)
|
||||||
|
remove
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Invalid argument. Please use 'install' or 'remove'."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
@ -64,14 +64,16 @@ This method is recommended because it's easier to manage.
|
|||||||
|
|
||||||
## macOS
|
## macOS
|
||||||
|
|
||||||
If using the default Wine prefix (`~/.wine`), you can follow the same steps as in Wine.
|
The steps for MacOS are almost the same, but due to the way `$TMPDIR` works, you will have to install a **LaunchAgent**.
|
||||||
|
|
||||||
Registering as a service [is not supported](https://github.com/EnderIce2/rpc-bridge/issues/1#issuecomment-2103423242 "Bridge can't get $TMPDIR unless is set with --rpc. See note below").
|
- Download the latest build from the [releases](https://github.com/EnderIce2/rpc-bridge/releases)
|
||||||
|
- Open the archive and make the `launchd.sh` script executable by doing: `chmod +x launchd.sh`
|
||||||
|
- To **install** the LaunchAgent, run `./launchd install` and to **remove** it simply run `./launchd remove`.
|
||||||
|
|
||||||
|
The script will add a LaunchAgent to your user, that will symlink the `$TMPDIR` directory to `/tmp/rpc-bridge/tmpdir`.
|
||||||
|
|
||||||
!!! info "Note"
|
!!! info "Note"
|
||||||
|
You will need to launch the `bridge.exe` file manually in Wine at least once for it to register and launch automatically the next time.
|
||||||
Since macOS doesn't have `/proc/self/environ` and `$TMPDIR` is neither always set nor the same after reboots, so you will need to [add `--rpc "$TMPDIR"` to the `bridge.exe` arguments](https://github.com/EnderIce2/rpc-bridge/issues/1#issuecomment-2104797235).
|
|
||||||
If you don't encounter any issues, you can ignore this step.
|
|
||||||
|
|
||||||
## Run without installing the service
|
## Run without installing the service
|
||||||
|
|
||||||
|
@ -11,7 +11,10 @@
|
|||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
- `--help` Show help message
|
- `--help` Show help message
|
||||||
- This will show the help message
|
- This will show the help message
|
||||||
|
|
||||||
|
- `--version` Show version
|
||||||
|
- This will show the version of the program
|
||||||
|
|
||||||
- `--install` Install the service
|
- `--install` Install the service
|
||||||
- This will copy the binary to `C:\windows\bridge.exe` and register it as a service
|
- This will copy the binary to `C:\windows\bridge.exe` and register it as a service
|
||||||
|
115
gui.c
115
gui.c
@ -4,6 +4,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The entire code could be better written, but at least it works.
|
* The entire code could be better written, but at least it works.
|
||||||
*
|
*
|
||||||
@ -31,7 +33,7 @@ VOID HandleStartButton(BOOL Silent)
|
|||||||
SetWindowText(item, "Do you want to start, install or remove the bridge?");
|
SetWindowText(item, "Do you want to start, install or remove the bridge?");
|
||||||
RedrawWindow(item, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
|
RedrawWindow(item, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
|
||||||
item = GetDlgItem(hwnd, /* Start Button */ 1);
|
item = GetDlgItem(hwnd, /* Start Button */ 1);
|
||||||
Button_SetText(item, "Start");
|
Button_SetText(item, "&Start");
|
||||||
EnableWindow(item, FALSE);
|
EnableWindow(item, FALSE);
|
||||||
RedrawWindow(item, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
|
RedrawWindow(item, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
|
||||||
|
|
||||||
@ -47,20 +49,6 @@ VOID HandleStartButton(BOOL Silent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsLinux)
|
|
||||||
{
|
|
||||||
hBridge = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateBridge,
|
|
||||||
NULL, 0, NULL);
|
|
||||||
|
|
||||||
HWND item = GetDlgItem(hwnd, /* Start Button */ 1);
|
|
||||||
Button_SetText(item, "Stop");
|
|
||||||
item = GetDlgItem(hwnd, 4);
|
|
||||||
SetWindowText(item, "Bridge is running...");
|
|
||||||
IsAlreadyRunning = TRUE;
|
|
||||||
ShowWindow(hwnd, SW_MINIMIZE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||||
if (hSCManager == NULL)
|
if (hSCManager == NULL)
|
||||||
{
|
{
|
||||||
@ -72,7 +60,7 @@ VOID HandleStartButton(BOOL Silent)
|
|||||||
SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_START);
|
SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_START);
|
||||||
if (schService == NULL)
|
if (schService == NULL)
|
||||||
{
|
{
|
||||||
// print("OpenService failed: %s\n", GetErrorMessage());
|
print("Service doesn't exist: %s\n", GetErrorMessage());
|
||||||
|
|
||||||
/* Service doesn't exist; running without any service */
|
/* Service doesn't exist; running without any service */
|
||||||
|
|
||||||
@ -80,7 +68,7 @@ VOID HandleStartButton(BOOL Silent)
|
|||||||
NULL, 0, NULL);
|
NULL, 0, NULL);
|
||||||
|
|
||||||
HWND item = GetDlgItem(hwnd, /* Start Button */ 1);
|
HWND item = GetDlgItem(hwnd, /* Start Button */ 1);
|
||||||
Button_SetText(item, "Stop");
|
Button_SetText(item, "&Stop");
|
||||||
item = GetDlgItem(hwnd, 4);
|
item = GetDlgItem(hwnd, 4);
|
||||||
SetWindowText(item, "Bridge is running...");
|
SetWindowText(item, "Bridge is running...");
|
||||||
IsAlreadyRunning = TRUE;
|
IsAlreadyRunning = TRUE;
|
||||||
@ -115,6 +103,7 @@ VOID HandleStartButton(BOOL Silent)
|
|||||||
CloseServiceHandle(hSCManager);
|
CloseServiceHandle(hSCManager);
|
||||||
if (Silent == FALSE)
|
if (Silent == FALSE)
|
||||||
MessageBox(NULL, "Bridge service started successfully", "Info", MB_OK);
|
MessageBox(NULL, "Bridge service started successfully", "Info", MB_OK);
|
||||||
|
print("Bridge service started successfully\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID HandleInstallButton()
|
VOID HandleInstallButton()
|
||||||
@ -135,6 +124,44 @@ VOID HandleRemoveButton()
|
|||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShowLicenseDialog()
|
||||||
|
{
|
||||||
|
HMODULE hModule = GetModuleHandle(NULL);
|
||||||
|
HRSRC hRes = FindResource(hModule, MAKEINTRESOURCE(IDR_LICENSE_TXT), RT_RCDATA);
|
||||||
|
if (!hRes)
|
||||||
|
{
|
||||||
|
MessageBox(NULL, "Resource not found", "Error", MB_OK | MB_ICONERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HGLOBAL hResData = LoadResource(NULL, hRes);
|
||||||
|
if (!hResData)
|
||||||
|
{
|
||||||
|
MessageBox(NULL, "Resource failed to load", "Error", MB_OK | MB_ICONERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD resSize = SizeofResource(NULL, hRes);
|
||||||
|
void *pRes = LockResource(hResData);
|
||||||
|
if (!pRes)
|
||||||
|
{
|
||||||
|
MessageBox(NULL, "Resource failed to lock", "Error", MB_OK | MB_ICONERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *licenseText = (char *)malloc(resSize + 1);
|
||||||
|
if (!licenseText)
|
||||||
|
{
|
||||||
|
MessageBox(NULL, "Memory allocation failed", "Error", MB_OK | MB_ICONERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(licenseText, pRes, resSize);
|
||||||
|
licenseText[resSize] = '\0';
|
||||||
|
MessageBoxA(hwnd, licenseText, "About", MB_OK);
|
||||||
|
free(licenseText);
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch (msg)
|
switch (msg)
|
||||||
@ -152,6 +179,26 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
case 3:
|
case 3:
|
||||||
HandleRemoveButton();
|
HandleRemoveButton();
|
||||||
break;
|
break;
|
||||||
|
case IDM_VIEW_LOG:
|
||||||
|
ShellExecute(NULL, "open", "C:\\windows\\notepad.exe", "C:\\windows\\logs\\bridge.log", NULL, SW_SHOW);
|
||||||
|
break;
|
||||||
|
case IDM_HELP_DOCUMENTATION:
|
||||||
|
ShellExecute(NULL, "open", "https://enderice2.github.io/rpc-bridge/index.html", NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
break;
|
||||||
|
case IDM_HELP_LICENSE:
|
||||||
|
ShowLicenseDialog();
|
||||||
|
break;
|
||||||
|
case IDM_HELP_ABOUT:
|
||||||
|
{
|
||||||
|
char msg[256];
|
||||||
|
sprintf(msg, "rpc-bridge v%s\n\n"
|
||||||
|
"Simple bridge that allows you to use Discord Rich Presence with Wine games/software.\n\n"
|
||||||
|
"Created by EnderIce2\n\n"
|
||||||
|
"Licensed under the MIT License",
|
||||||
|
VER_VERSION_STR);
|
||||||
|
MessageBox(NULL, msg, "About", MB_OK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -178,16 +225,16 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
VOID SetButtonStyles(INT *btnStartStyle, INT *btnRemoveStyle, INT *btnInstallStyle)
|
VOID SetButtonStyles(INT *btnStartStyle, INT *btnRemoveStyle, INT *btnInstallStyle)
|
||||||
{
|
{
|
||||||
*btnStartStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
|
*btnStartStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP;
|
||||||
*btnRemoveStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
|
*btnRemoveStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP;
|
||||||
*btnInstallStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
|
*btnInstallStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP;
|
||||||
|
|
||||||
if (!IsLinux)
|
// if (!IsLinux)
|
||||||
{
|
// {
|
||||||
*btnInstallStyle |= WS_DISABLED;
|
// *btnInstallStyle |= WS_DISABLED;
|
||||||
*btnRemoveStyle |= WS_DISABLED;
|
// *btnRemoveStyle |= WS_DISABLED;
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||||
SC_HANDLE schService = OpenService(hSCManager, "rpc-bridge", SERVICE_START | SERVICE_QUERY_STATUS);
|
SC_HANDLE schService = OpenService(hSCManager, "rpc-bridge", SERVICE_START | SERVICE_QUERY_STATUS);
|
||||||
@ -254,21 +301,24 @@ int WINAPI __WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
0, 15, 400, 25,
|
0, 15, 400, 25,
|
||||||
hwnd, (HMENU)4, hInstance, NULL);
|
hwnd, (HMENU)4, hInstance, NULL);
|
||||||
|
|
||||||
HWND hbtn1 = CreateWindow("BUTTON", "Start",
|
HWND hbtn1 = CreateWindow("BUTTON", "&Start",
|
||||||
btnStartStyle,
|
btnStartStyle,
|
||||||
40, 60, 100, 30,
|
40, 60, 100, 30,
|
||||||
hwnd, (HMENU)1, hInstance, NULL);
|
hwnd, (HMENU)1, hInstance, NULL);
|
||||||
|
|
||||||
HWND hbtn2 = CreateWindow("BUTTON", "Install",
|
HWND hbtn2 = CreateWindow("BUTTON", "&Install",
|
||||||
btnInstallStyle,
|
btnInstallStyle,
|
||||||
150, 60, 100, 30,
|
150, 60, 100, 30,
|
||||||
hwnd, (HMENU)2, hInstance, NULL);
|
hwnd, (HMENU)2, hInstance, NULL);
|
||||||
|
|
||||||
HWND hbtn3 = CreateWindow("BUTTON", "Remove",
|
HWND hbtn3 = CreateWindow("BUTTON", "&Remove",
|
||||||
btnRemoveStyle,
|
btnRemoveStyle,
|
||||||
260, 60, 100, 30,
|
260, 60, 100, 30,
|
||||||
hwnd, (HMENU)3, hInstance, NULL);
|
hwnd, (HMENU)3, hInstance, NULL);
|
||||||
|
|
||||||
|
HMENU hMenu = LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MAINMENU));
|
||||||
|
SetMenu(hwnd, hMenu);
|
||||||
|
|
||||||
HDC hDC = GetDC(hwnd);
|
HDC hDC = GetDC(hwnd);
|
||||||
int nHeight = -MulDiv(11, GetDeviceCaps(hDC, LOGPIXELSY), 72);
|
int nHeight = -MulDiv(11, GetDeviceCaps(hDC, LOGPIXELSY), 72);
|
||||||
|
|
||||||
@ -289,8 +339,11 @@ int WINAPI __WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
MSG msg;
|
MSG msg;
|
||||||
while (GetMessage(&msg, NULL, 0, 0) > 0)
|
while (GetMessage(&msg, NULL, 0, 0) > 0)
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
if (!IsDialogMessage(hwnd, &msg))
|
||||||
DispatchMessage(&msg);
|
{
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return msg.wParam;
|
return msg.wParam;
|
||||||
}
|
}
|
||||||
|
63
main.c
63
main.c
@ -3,6 +3,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
FILE *g_logFile = NULL;
|
FILE *g_logFile = NULL;
|
||||||
BOOL RunningAsService = FALSE;
|
BOOL RunningAsService = FALSE;
|
||||||
|
|
||||||
@ -72,14 +74,11 @@ void DetectWine()
|
|||||||
{
|
{
|
||||||
int result = MessageBox(NULL, "This program is designed for Linux and macOS only!\nDo you want to proceed?",
|
int result = MessageBox(NULL, "This program is designed for Linux and macOS only!\nDo you want to proceed?",
|
||||||
NULL, MB_YESNO | MB_ICONQUESTION);
|
NULL, MB_YESNO | MB_ICONQUESTION);
|
||||||
if (result == IDYES)
|
if (result == IDNO)
|
||||||
return;
|
|
||||||
else if (result == IDNO)
|
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsLinux = strcmp(__sysname, "Linux") == 0;
|
IsLinux = strcmp(__sysname, "Linux") == 0;
|
||||||
printf("Running on %s\n", __sysname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(char const *fmt, ...)
|
void print(char const *fmt, ...)
|
||||||
@ -272,32 +271,40 @@ void HandleArguments(int argc, char *argv[])
|
|||||||
CreateBridge();
|
CreateBridge();
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[1], "--version") == 0)
|
||||||
|
{
|
||||||
|
printf("%s\n", VER_VERSION_STR);
|
||||||
|
ExitProcess(0);
|
||||||
|
}
|
||||||
else if (strcmp(argv[1], "--help") == 0)
|
else if (strcmp(argv[1], "--help") == 0)
|
||||||
{
|
{
|
||||||
printf("Usage:\n");
|
printf("Usage:\n"
|
||||||
printf(" %s [args]\n\n", argv[0]);
|
" %s [args]\n"
|
||||||
|
"\n"
|
||||||
printf("Arguments:\n");
|
"Arguments:\n"
|
||||||
printf(" --help Show this help\n\n");
|
" --help Show this help\n"
|
||||||
|
"\n"
|
||||||
printf(" --install Install service\n");
|
" --version Show version\n"
|
||||||
printf(" This will copy the binary to C:\\windows\\bridge.exe and register it as a service\n\n");
|
"\n"
|
||||||
|
" --install Install service\n"
|
||||||
printf(" --uninstall Uninstall service\n");
|
" This will copy the binary to C:\\windows\\bridge.exe and register it as a service\n"
|
||||||
printf(" This will remove the service and delete C:\\windows\\bridge.exe\n\n");
|
"\n"
|
||||||
|
" --uninstall Uninstall service\n"
|
||||||
printf(" --steam Reserved for Steam\n");
|
" This will remove the service and delete C:\\windows\\bridge.exe\n"
|
||||||
printf(" This will start the service and exit (used with bridge.sh)\n\n");
|
"\n"
|
||||||
|
" --steam Reserved for Steam\n"
|
||||||
printf(" --no-service Do not run as service\n");
|
" This will start the service and exit (used with bridge.sh)\n"
|
||||||
printf(" (only for --steam)\n\n");
|
"\n"
|
||||||
|
" --no-service Do not run as service\n"
|
||||||
printf(" --service Reserved for service\n\n");
|
" (only for --steam)\n"
|
||||||
|
"\n"
|
||||||
printf(" --rpc <dir> Set RPC_PATH environment variable\n");
|
" --service Reserved for service\n"
|
||||||
printf(" This is used to specify the directory where 'discord-ipc-0' is located\n\n");
|
"\n"
|
||||||
|
" --rpc <dir> Set RPC_PATH environment variable\n"
|
||||||
printf("Note: If no arguments are provided, the GUI will be shown instead\n");
|
" This is used to specify the directory where 'discord-ipc-0' is located\n"
|
||||||
|
"\n"
|
||||||
|
"Note: If no arguments are provided, the GUI will be shown instead\n",
|
||||||
|
argv[0]);
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
9
resource.h
Normal file
9
resource.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#define IDR_MAINMENU 101
|
||||||
|
#define IDR_LICENSE_TXT 102
|
||||||
|
#define IDM_HELP_DOCUMENTATION 40001
|
||||||
|
#define IDM_HELP_LICENSE 40002
|
||||||
|
#define IDM_HELP_ABOUT 40003
|
||||||
|
#define IDM_VIEW_LOG 40004
|
||||||
|
|
||||||
|
#define VER_VERSION 1, 2, 0, 0
|
||||||
|
#define VER_VERSION_STR "1.2\0"
|
14
service.c
14
service.c
@ -88,13 +88,13 @@ void InstallService(int ServiceStartType, LPCSTR Path)
|
|||||||
{
|
{
|
||||||
print("Registering service\n");
|
print("Registering service\n");
|
||||||
|
|
||||||
if (IsLinux == FALSE)
|
// if (IsLinux == FALSE)
|
||||||
{
|
// {
|
||||||
/* FIXME: I don't know how to get the TMPDIR without getenv */
|
// /* FIXME: I don't know how to get the TMPDIR without getenv */
|
||||||
MessageBox(NULL, "Registering as a service is not supported on macOS at the moment.",
|
// MessageBox(NULL, "Registering as a service is not supported on macOS at the moment.",
|
||||||
"Unsupported", MB_OK | MB_ICONINFORMATION);
|
// "Unsupported", MB_OK | MB_ICONINFORMATION);
|
||||||
ExitProcess(1);
|
// ExitProcess(1);
|
||||||
}
|
// }
|
||||||
|
|
||||||
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
SC_HANDLE schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
||||||
if (schSCManager == NULL)
|
if (schSCManager == NULL)
|
||||||
|
Reference in New Issue
Block a user