mirror of
https://github.com/EnderIce2/rpc-bridge.git
synced 2025-07-07 13:29:14 +00:00
Compare commits
8 Commits
kvm
...
9f1a9de3d7
Author | SHA1 | Date | |
---|---|---|---|
9f1a9de3d7
|
|||
ccf09806c9
|
|||
7363ee64d5
|
|||
a3023e349e
|
|||
39966d7149
|
|||
a8904bf3f1
|
|||
08feef776b | |||
8545467a85
|
4
.github/workflows/build-deploy.yml
vendored
4
.github/workflows/build-deploy.yml
vendored
@ -13,13 +13,13 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: dependencies
|
- name: dependencies
|
||||||
run: sudo apt-get update && sudo apt-get install gcc-mingw-w64 make
|
run: sudo apt-get update && sudo apt-get install gcc-mingw-w64 make
|
||||||
- name: make
|
- name: make
|
||||||
run: make
|
run: make
|
||||||
- name: artifact
|
- name: artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: bridge
|
name: bridge
|
||||||
path: build
|
path: build
|
||||||
|
16
.vscode/c_cpp_properties.json
vendored
16
.vscode/c_cpp_properties.json
vendored
@ -5,21 +5,13 @@
|
|||||||
"includePath": [
|
"includePath": [
|
||||||
"${workspaceFolder}/**"
|
"${workspaceFolder}/**"
|
||||||
],
|
],
|
||||||
"defines": [],
|
"defines": [
|
||||||
|
"GIT_COMMIT",
|
||||||
|
"GIT_BRANCH"
|
||||||
|
],
|
||||||
"cStandard": "c17",
|
"cStandard": "c17",
|
||||||
"cppStandard": "gnu++17",
|
"cppStandard": "gnu++17",
|
||||||
"intelliSenseMode": "windows-gcc-x64"
|
"intelliSenseMode": "windows-gcc-x64"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Linux",
|
|
||||||
"includePath": [
|
|
||||||
"${workspaceFolder}/**"
|
|
||||||
],
|
|
||||||
"defines": [],
|
|
||||||
"cStandard": "c17",
|
|
||||||
"cppStandard": "gnu++17",
|
|
||||||
"intelliSenseMode": "linux-gcc-x64",
|
|
||||||
"compilerPath": "/usr/bin/gcc"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": 4
|
"version": 4
|
||||||
|
6
Makefile
6
Makefile
@ -1,7 +1,10 @@
|
|||||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||||
C_OBJECTS = $(C_SOURCES:.c=.o)
|
C_OBJECTS = $(C_SOURCES:.c=.o)
|
||||||
|
|
||||||
CFLAGS = -std=c17 -Wno-int-conversion
|
GIT_COMMIT = $(shell git rev-parse --short HEAD)
|
||||||
|
GIT_BRANCH = $(shell git rev-parse --abbrev-ref HEAD)
|
||||||
|
|
||||||
|
CFLAGS = -std=c17 -Wno-int-conversion -DGIT_COMMIT='"$(GIT_COMMIT)"' -DGIT_BRANCH='"$(GIT_BRANCH)"'
|
||||||
LFLAGS = -lgdi32
|
LFLAGS = -lgdi32
|
||||||
|
|
||||||
# DBGFLAGS = -Wl,--export-all-symbols -g -O0 -ggdb3 -Wall
|
# DBGFLAGS = -Wl,--export-all-symbols -g -O0 -ggdb3 -Wall
|
||||||
@ -12,7 +15,6 @@ build: $(C_OBJECTS)
|
|||||||
$(info Linking)
|
$(info Linking)
|
||||||
x86_64-w64-mingw32-windres bridge.rc -O coff -o bridge.res
|
x86_64-w64-mingw32-windres bridge.rc -O coff -o bridge.res
|
||||||
x86_64-w64-mingw32-gcc $(C_OBJECTS) bridge.res $(LFLAGS) $(DBGFLAGS) -o build/bridge.exe
|
x86_64-w64-mingw32-gcc $(C_OBJECTS) bridge.res $(LFLAGS) $(DBGFLAGS) -o build/bridge.exe
|
||||||
gcc kvm.c -o build/rpc-bridge.elf
|
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(info Compiling $<)
|
$(info Compiling $<)
|
||||||
|
278
bridge.c
278
bridge.c
@ -4,8 +4,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "bridge.h"
|
|
||||||
|
|
||||||
#define __linux_read 3
|
#define __linux_read 3
|
||||||
#define __linux_write 4
|
#define __linux_write 4
|
||||||
#define __linux_open 5
|
#define __linux_open 5
|
||||||
@ -66,7 +64,7 @@ void print(char const *fmt, ...);
|
|||||||
LPTSTR GetErrorMessage();
|
LPTSTR GetErrorMessage();
|
||||||
extern BOOL RunningAsService;
|
extern BOOL RunningAsService;
|
||||||
BOOL RetryNewConnection;
|
BOOL RetryNewConnection;
|
||||||
OS_INFO OSInfo = {0};
|
BOOL IsLinux;
|
||||||
HANDLE hOut = NULL;
|
HANDLE hOut = NULL;
|
||||||
HANDLE hIn = NULL;
|
HANDLE hIn = NULL;
|
||||||
|
|
||||||
@ -104,7 +102,7 @@ static naked int darwin_syscall(int num,
|
|||||||
|
|
||||||
static inline int sys_read(int fd, void *buf, size_t count)
|
static inline int sys_read(int fd, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
if (OSInfo.IsLinux)
|
if (IsLinux)
|
||||||
return linux_syscall(__linux_read, fd, buf, count, 0, 0, 0);
|
return linux_syscall(__linux_read, fd, buf, count, 0, 0, 0);
|
||||||
else
|
else
|
||||||
return darwin_syscall(__darwin_read, fd, buf, count, 0, 0, 0);
|
return darwin_syscall(__darwin_read, fd, buf, count, 0, 0, 0);
|
||||||
@ -112,7 +110,7 @@ static inline int sys_read(int fd, void *buf, size_t count)
|
|||||||
|
|
||||||
static inline int sys_write(int fd, const void *buf, size_t count)
|
static inline int sys_write(int fd, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
if (OSInfo.IsLinux)
|
if (IsLinux)
|
||||||
return linux_syscall(__linux_write, fd, buf, count, 0, 0, 0);
|
return linux_syscall(__linux_write, fd, buf, count, 0, 0, 0);
|
||||||
else
|
else
|
||||||
return darwin_syscall(__darwin_write, fd, buf, count, 0, 0, 0);
|
return darwin_syscall(__darwin_write, fd, buf, count, 0, 0, 0);
|
||||||
@ -120,7 +118,7 @@ static inline int sys_write(int fd, const void *buf, size_t count)
|
|||||||
|
|
||||||
static inline int sys_open(const char *pathname, int flags, int mode)
|
static inline int sys_open(const char *pathname, int flags, int mode)
|
||||||
{
|
{
|
||||||
if (OSInfo.IsLinux)
|
if (IsLinux)
|
||||||
return linux_syscall(__linux_open, pathname, flags, mode, 0, 0, 0);
|
return linux_syscall(__linux_open, pathname, flags, mode, 0, 0, 0);
|
||||||
else
|
else
|
||||||
return darwin_syscall(__darwin_open, pathname, flags, mode, 0, 0, 0);
|
return darwin_syscall(__darwin_open, pathname, flags, mode, 0, 0, 0);
|
||||||
@ -128,7 +126,7 @@ static inline int sys_open(const char *pathname, int flags, int mode)
|
|||||||
|
|
||||||
static inline int sys_close(int fd)
|
static inline int sys_close(int fd)
|
||||||
{
|
{
|
||||||
if (OSInfo.IsLinux)
|
if (IsLinux)
|
||||||
return linux_syscall(__linux_close, fd, 0, 0, 0, 0, 0);
|
return linux_syscall(__linux_close, fd, 0, 0, 0, 0, 0);
|
||||||
else
|
else
|
||||||
return darwin_syscall(__darwin_close, fd, 0, 0, 0, 0, 0);
|
return darwin_syscall(__darwin_close, fd, 0, 0, 0, 0, 0);
|
||||||
@ -136,25 +134,25 @@ static inline int sys_close(int fd)
|
|||||||
|
|
||||||
static inline unsigned int *sys_mmap(unsigned int *addr, size_t length, int prot, int flags, int fd, off_t offset)
|
static inline unsigned int *sys_mmap(unsigned int *addr, size_t length, int prot, int flags, int fd, off_t offset)
|
||||||
{
|
{
|
||||||
assert(OSInfo.IsLinux);
|
assert(IsLinux);
|
||||||
return linux_syscall(__linux_mmap2, addr, length, prot, flags, fd, offset);
|
return linux_syscall(__linux_mmap2, addr, length, prot, flags, fd, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sys_munmap(unsigned int *addr, size_t length)
|
static inline int sys_munmap(unsigned int *addr, size_t length)
|
||||||
{
|
{
|
||||||
assert(OSInfo.IsLinux);
|
assert(IsLinux);
|
||||||
return linux_syscall(__linux_munmap, addr, length, 0, 0, 0, 0);
|
return linux_syscall(__linux_munmap, addr, length, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sys_socketcall(int call, unsigned long *args)
|
static inline int sys_socketcall(int call, unsigned long *args)
|
||||||
{
|
{
|
||||||
assert(OSInfo.IsLinux);
|
assert(IsLinux);
|
||||||
return linux_syscall(__linux_socketcall, call, args, 0, 0, 0, 0);
|
return linux_syscall(__linux_socketcall, call, args, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sys_socket(int domain, int type, int protocol)
|
static inline int sys_socket(int domain, int type, int protocol)
|
||||||
{
|
{
|
||||||
if (OSInfo.IsLinux)
|
if (IsLinux)
|
||||||
return linux_syscall(__linux_socket, domain, type, protocol, 0, 0, 0);
|
return linux_syscall(__linux_socket, domain, type, protocol, 0, 0, 0);
|
||||||
else
|
else
|
||||||
return darwin_syscall(__darwin_socket, domain, type, protocol, 0, 0, 0);
|
return darwin_syscall(__darwin_socket, domain, type, protocol, 0, 0, 0);
|
||||||
@ -162,7 +160,7 @@ static inline int sys_socket(int domain, int type, int protocol)
|
|||||||
|
|
||||||
static inline int sys_connect(int s, caddr_t name, socklen_t namelen)
|
static inline int sys_connect(int s, caddr_t name, socklen_t namelen)
|
||||||
{
|
{
|
||||||
if (OSInfo.IsLinux)
|
if (IsLinux)
|
||||||
return linux_syscall(__linux_connect, s, name, namelen, 0, 0, 0);
|
return linux_syscall(__linux_connect, s, name, namelen, 0, 0, 0);
|
||||||
else
|
else
|
||||||
return darwin_syscall(__darwin_connect, s, name, namelen, 0, 0, 0);
|
return darwin_syscall(__darwin_connect, s, name, namelen, 0, 0, 0);
|
||||||
@ -176,7 +174,7 @@ char *native_getenv(const char *name)
|
|||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return lpBuffer;
|
return lpBuffer;
|
||||||
|
|
||||||
if (!OSInfo.IsLinux)
|
if (!IsLinux)
|
||||||
{
|
{
|
||||||
char *value = getenv(name);
|
char *value = getenv(name);
|
||||||
if (value == NULL)
|
if (value == NULL)
|
||||||
@ -253,9 +251,9 @@ void ConnectToSocket(int fd)
|
|||||||
{
|
{
|
||||||
print("Connecting to socket\n");
|
print("Connecting to socket\n");
|
||||||
const char *runtime;
|
const char *runtime;
|
||||||
if (OSInfo.IsLinux)
|
if (IsLinux)
|
||||||
runtime = native_getenv("XDG_RUNTIME_DIR");
|
runtime = native_getenv("XDG_RUNTIME_DIR");
|
||||||
else if (OSInfo.IsDarwin)
|
else
|
||||||
{
|
{
|
||||||
runtime = native_getenv("TMPDIR");
|
runtime = native_getenv("TMPDIR");
|
||||||
if (runtime == NULL)
|
if (runtime == NULL)
|
||||||
@ -280,36 +278,34 @@ void ConnectToSocket(int fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
print("Unsupported OS\n");
|
|
||||||
ExitProcess(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
print("IPC directory: %s\n", runtime);
|
print("IPC directory: %s\n", runtime);
|
||||||
|
|
||||||
/* TODO: check for multiple discord instances and create a pipe for each */
|
/* TODO: check for multiple discord instances and create a pipe for each */
|
||||||
const char *discordUnixPipes[] = {
|
const char *discordUnixSockets[] = {
|
||||||
"/discord-ipc-0",
|
"%s/discord-ipc-%d",
|
||||||
"/snap.discord/discord-ipc-0",
|
"%s/app/com.discordapp.Discord/discord-ipc-%d",
|
||||||
"/app/com.discordapp.Discord/discord-ipc-0",
|
"%s/.flatpak/dev.vencord.Vesktop/xdg-run/discord-ipc-%d",
|
||||||
|
"%s/snap.discord/discord-ipc-%d",
|
||||||
|
"%s/snap.discord-canary/discord-ipc-%d",
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sockaddr_un socketAddr;
|
struct sockaddr_un socketAddr;
|
||||||
socketAddr.sun_family = AF_UNIX;
|
socketAddr.sun_family = AF_UNIX;
|
||||||
char *pipePath = NULL;
|
|
||||||
int sockRet = -1;
|
|
||||||
|
|
||||||
for (int i = 0; i < sizeof(discordUnixPipes) / sizeof(discordUnixPipes[0]); i++)
|
int sockRet = 0;
|
||||||
|
for (int i = 0; i < sizeof(discordUnixSockets) / sizeof(discordUnixSockets[0]); i++)
|
||||||
{
|
{
|
||||||
pipePath = malloc(strlen(runtime) + strlen(discordUnixPipes[i]) + 1);
|
size_t pipePathLen = strlen(runtime) + strlen(discordUnixSockets[i]) + 1;
|
||||||
strcpy(pipePath, runtime);
|
char *pipePath = malloc(pipePathLen);
|
||||||
strcat(pipePath, discordUnixPipes[i]);
|
|
||||||
|
for (int j = 0; j < 16; j++)
|
||||||
|
{
|
||||||
|
snprintf(pipePath, pipePathLen, discordUnixSockets[i], runtime, j);
|
||||||
strcpy_s(socketAddr.sun_path, sizeof(socketAddr.sun_path), pipePath);
|
strcpy_s(socketAddr.sun_path, sizeof(socketAddr.sun_path), pipePath);
|
||||||
|
print("Probing %s\n", pipePath);
|
||||||
|
|
||||||
print("Connecting to %s\n", pipePath);
|
if (IsLinux)
|
||||||
|
|
||||||
if (OSInfo.IsLinux)
|
|
||||||
{
|
{
|
||||||
unsigned long socketArgs[] = {
|
unsigned long socketArgs[] = {
|
||||||
(unsigned long)fd,
|
(unsigned long)fd,
|
||||||
@ -321,11 +317,20 @@ void ConnectToSocket(int fd)
|
|||||||
else
|
else
|
||||||
sockRet = sys_connect(fd, (caddr_t)&socketAddr, sizeof(socketAddr));
|
sockRet = sys_connect(fd, (caddr_t)&socketAddr, sizeof(socketAddr));
|
||||||
|
|
||||||
free(pipePath);
|
print(" error: %d\n", sockRet);
|
||||||
if (sockRet >= 0)
|
if (sockRet >= 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sockRet >= 0)
|
||||||
|
{
|
||||||
|
print("Connecting to %s\n", pipePath);
|
||||||
|
free(pipePath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(pipePath);
|
||||||
|
}
|
||||||
|
|
||||||
if (sockRet < 0)
|
if (sockRet < 0)
|
||||||
{
|
{
|
||||||
print("socketcall failed for: %d\n", sockRet);
|
print("socketcall failed for: %d\n", sockRet);
|
||||||
@ -487,162 +492,6 @@ void PipeBufferOutThread(LPVOID lpParam)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void COMPipeBufferInThread(LPVOID lpParam)
|
|
||||||
{
|
|
||||||
bridge_thread *bt = (bridge_thread *)lpParam;
|
|
||||||
print("COM In thread started using COM port and pipe %#x\n", bt->hPipe);
|
|
||||||
|
|
||||||
HANDLE hComPort = CreateFile("\\\\.\\COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (hComPort == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
print("Failed to open COM2 port: %s\n", GetErrorMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EOFCount = 0;
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
char buffer[BUFFER_LENGTH];
|
|
||||||
DWORD bytesRead;
|
|
||||||
|
|
||||||
if (!ReadFile(hComPort, buffer, sizeof(buffer), &bytesRead, NULL))
|
|
||||||
{
|
|
||||||
print("Failed to read from COM2 port: %s\n", GetErrorMessage());
|
|
||||||
Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EOFCount > 4)
|
|
||||||
{
|
|
||||||
print("EOF count exceeded\n");
|
|
||||||
RetryNewConnection = TRUE;
|
|
||||||
TerminateThread(hOut, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bytesRead == 0)
|
|
||||||
{
|
|
||||||
print("EOF\n");
|
|
||||||
Sleep(1000);
|
|
||||||
EOFCount++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
EOFCount = 0;
|
|
||||||
|
|
||||||
print("Reading %d bytes from COM2 port: \"", bytesRead);
|
|
||||||
for (DWORD i = 0; i < bytesRead; i++)
|
|
||||||
print("%c", buffer[i]);
|
|
||||||
print("\"\n");
|
|
||||||
|
|
||||||
DWORD dwWritten;
|
|
||||||
if (!WriteFile(bt->hPipe, buffer, bytesRead, &dwWritten, NULL))
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_BROKEN_PIPE)
|
|
||||||
{
|
|
||||||
RetryNewConnection = TRUE;
|
|
||||||
print("In Broken pipe\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Failed to write to pipe: %s\n", GetErrorMessage());
|
|
||||||
Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (dwWritten < bytesRead)
|
|
||||||
{
|
|
||||||
int last_written = dwWritten;
|
|
||||||
if (!WriteFile(bt->hPipe, buffer + dwWritten, bytesRead - dwWritten, &dwWritten, NULL))
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_BROKEN_PIPE)
|
|
||||||
{
|
|
||||||
RetryNewConnection = TRUE;
|
|
||||||
print("In Broken pipe\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Failed to write to pipe: %s\n", GetErrorMessage());
|
|
||||||
Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_written == dwWritten)
|
|
||||||
{
|
|
||||||
print("Failed to write to pipe: %s\n", GetErrorMessage());
|
|
||||||
Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hComPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
void COMPipeBufferOutThread(LPVOID lpParam)
|
|
||||||
{
|
|
||||||
bridge_thread *bt = (bridge_thread *)lpParam;
|
|
||||||
print("COM Out thread started using COM port and pipe %#x\n", bt->hPipe);
|
|
||||||
|
|
||||||
HANDLE hComPort = CreateFile("\\\\.\\COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
if (hComPort == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
print("Failed to open COM2 port: %s\n", GetErrorMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
char buffer[BUFFER_LENGTH];
|
|
||||||
DWORD dwRead;
|
|
||||||
|
|
||||||
if (!ReadFile(bt->hPipe, buffer, sizeof(buffer), &dwRead, NULL))
|
|
||||||
{
|
|
||||||
if (GetLastError() == ERROR_BROKEN_PIPE)
|
|
||||||
{
|
|
||||||
RetryNewConnection = TRUE;
|
|
||||||
print("Out Broken pipe\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Failed to read from pipe: %s\n", GetErrorMessage());
|
|
||||||
Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
print("Writing %d bytes to COM2 port: \"", dwRead);
|
|
||||||
for (DWORD i = 0; i < dwRead; i++)
|
|
||||||
print("%c", buffer[i]);
|
|
||||||
print("\"\n");
|
|
||||||
|
|
||||||
DWORD bytesWritten;
|
|
||||||
if (!WriteFile(hComPort, buffer, dwRead, &bytesWritten, NULL))
|
|
||||||
{
|
|
||||||
print("Failed to write to COM2 port: %s\n", GetErrorMessage());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bytesWritten < dwRead)
|
|
||||||
{
|
|
||||||
int last_written = bytesWritten;
|
|
||||||
if (!WriteFile(hComPort, buffer + bytesWritten, dwRead - bytesWritten, &bytesWritten, NULL))
|
|
||||||
{
|
|
||||||
print("Failed to write to COM2 port: %s\n", GetErrorMessage());
|
|
||||||
Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_written == bytesWritten)
|
|
||||||
{
|
|
||||||
print("Failed to write to COM2 port: %s\n", GetErrorMessage());
|
|
||||||
Sleep(1000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hComPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CreateBridge()
|
void CreateBridge()
|
||||||
{
|
{
|
||||||
LPCTSTR lpszPipename = TEXT("\\\\.\\pipe\\discord-ipc-0");
|
LPCTSTR lpszPipename = TEXT("\\\\.\\pipe\\discord-ipc-0");
|
||||||
@ -696,49 +545,7 @@ NewConnection:
|
|||||||
print("Pipe connected\n");
|
print("Pipe connected\n");
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
if (!OSInfo.IsWine)
|
if (IsLinux)
|
||||||
{
|
|
||||||
print("Running on Windows\n");
|
|
||||||
/* KVM, send 0xBB1569 and wait with timeout (TODO) for response 0xB41D6E */
|
|
||||||
|
|
||||||
print("Trying \\\\.\\COM2\n");
|
|
||||||
HANDLE hComPort = CreateFile("\\\\.\\COM2", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
|
||||||
assert(hComPort != INVALID_HANDLE_VALUE);
|
|
||||||
DWORD dwWritten;
|
|
||||||
print("Writing to COM port\n");
|
|
||||||
char buffer[4] = "\x69\x15\xBB";
|
|
||||||
assert(WriteFile(hComPort, buffer, sizeof(buffer), &dwWritten, NULL));
|
|
||||||
print("Wrote %d bytes to COM port\n", dwWritten);
|
|
||||||
DWORD dwRead;
|
|
||||||
print("Reading from COM port\n");
|
|
||||||
assert(ReadFile(hComPort, buffer, sizeof(buffer), &dwRead, NULL));
|
|
||||||
print("Read %d bytes from COM port\n", dwRead);
|
|
||||||
|
|
||||||
if (dwRead != 4 || memcmp(buffer, "\x6E\x1D\xB4", 4) != 0)
|
|
||||||
{
|
|
||||||
CloseHandle(hComPort);
|
|
||||||
print("Failed to connect to COM2\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hComPort);
|
|
||||||
print("Connected to COM2\n");
|
|
||||||
|
|
||||||
bridge_thread bt = {0, hPipe};
|
|
||||||
|
|
||||||
hIn = CreateThread(NULL, 0,
|
|
||||||
(LPTHREAD_START_ROUTINE)COMPipeBufferInThread,
|
|
||||||
(LPVOID)&bt,
|
|
||||||
0, NULL);
|
|
||||||
|
|
||||||
hOut = CreateThread(NULL, 0,
|
|
||||||
(LPTHREAD_START_ROUTINE)COMPipeBufferOutThread,
|
|
||||||
(LPVOID)&bt,
|
|
||||||
0, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (OSInfo.IsLinux)
|
|
||||||
{
|
{
|
||||||
unsigned long socketArgs[] = {
|
unsigned long socketArgs[] = {
|
||||||
(unsigned long)AF_UNIX,
|
(unsigned long)AF_UNIX,
|
||||||
@ -769,14 +576,12 @@ NewConnection:
|
|||||||
(LPTHREAD_START_ROUTINE)PipeBufferInThread,
|
(LPTHREAD_START_ROUTINE)PipeBufferInThread,
|
||||||
(LPVOID)&bt,
|
(LPVOID)&bt,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
|
print("Created in thread %#lx\n", hIn);
|
||||||
|
|
||||||
hOut = CreateThread(NULL, 0,
|
hOut = CreateThread(NULL, 0,
|
||||||
(LPTHREAD_START_ROUTINE)PipeBufferOutThread,
|
(LPTHREAD_START_ROUTINE)PipeBufferOutThread,
|
||||||
(LPVOID)&bt,
|
(LPVOID)&bt,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
}
|
|
||||||
|
|
||||||
print("Created in thread %#lx\n", hIn);
|
|
||||||
print("Created out thread %#lx\n", hOut);
|
print("Created out thread %#lx\n", hOut);
|
||||||
|
|
||||||
if (hIn == NULL || hOut == NULL)
|
if (hIn == NULL || hOut == NULL)
|
||||||
@ -807,7 +612,6 @@ NewConnection:
|
|||||||
print("Failed to terminate thread: %s\n",
|
print("Failed to terminate thread: %s\n",
|
||||||
GetErrorMessage());
|
GetErrorMessage());
|
||||||
|
|
||||||
if (OSInfo.IsWine)
|
|
||||||
sys_close(fd);
|
sys_close(fd);
|
||||||
CloseHandle(hOut);
|
CloseHandle(hOut);
|
||||||
CloseHandle(hIn);
|
CloseHandle(hIn);
|
||||||
|
13
bridge.h
13
bridge.h
@ -1,13 +0,0 @@
|
|||||||
#ifndef _BRIDGE_H
|
|
||||||
#define _BRIDGE_H
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
typedef struct _OS_INFO
|
|
||||||
{
|
|
||||||
BOOL IsLinux;
|
|
||||||
BOOL IsDarwin;
|
|
||||||
BOOL IsWine;
|
|
||||||
} OS_INFO;
|
|
||||||
|
|
||||||
#endif // _BRIDGE_H
|
|
@ -3,7 +3,7 @@
|
|||||||
<assemblyIdentity
|
<assemblyIdentity
|
||||||
version="1.0.0.0"
|
version="1.0.0.0"
|
||||||
processorArchitecture="amd64"
|
processorArchitecture="amd64"
|
||||||
name="EnderIce2.rpc-bridge"
|
name="com.enderice2.rpc-bridge"
|
||||||
type="win32"
|
type="win32"
|
||||||
/>
|
/>
|
||||||
<description>Simple bridge that allows you to use Discord Rich Presence with Wine games/software.</description>
|
<description>Simple bridge that allows you to use Discord Rich Presence with Wine games/software.</description>
|
||||||
|
@ -21,10 +21,10 @@ TEMP_PATH="$XDG_RUNTIME_DIR"
|
|||||||
TEMP_PATH=${TEMP_PATH:-"$TMPDIR"}
|
TEMP_PATH=${TEMP_PATH:-"$TMPDIR"}
|
||||||
|
|
||||||
VESSEL_PATH="$BRIDGE_PATH"
|
VESSEL_PATH="$BRIDGE_PATH"
|
||||||
IPC_PATHS="$TEMP_PATH /run/user/$UID $TEMP_PATH/snap.discord $TEMP_PATH/app/com.discordapp.Discord"
|
IPC_PATHS="$TEMP_PATH /run/user/$UID $TEMP_PATH/app/com.discordapp.Discord $TEMP_PATH/.flatpak/dev.vencord.Vesktop/xdg-run $TEMP_PATH/snap.discord $TEMP_PATH/snap.discord-canary"
|
||||||
for discord_ipc in $IPC_PATHS; do
|
for discord_ipc in $IPC_PATHS; do
|
||||||
if [ -S "$discord_ipc"/discord-ipc-0 ]; then
|
if [ -S "$discord_ipc"/discord-ipc-? ]; then
|
||||||
VESSEL_PATH="$BRIDGE_PATH:$(echo "$discord_ipc"/discord-ipc-0)"
|
VESSEL_PATH="$BRIDGE_PATH:$(echo "$discord_ipc"/discord-ipc-?)"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
22
gui.c
22
gui.c
@ -4,7 +4,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "bridge.h"
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -18,8 +17,7 @@ void print(char const *fmt, ...);
|
|||||||
void InstallService(int ServiceStartType, LPCSTR Path);
|
void InstallService(int ServiceStartType, LPCSTR Path);
|
||||||
void RemoveService();
|
void RemoveService();
|
||||||
void CreateBridge();
|
void CreateBridge();
|
||||||
extern OS_INFO OSInfo;
|
extern BOOL IsLinux;
|
||||||
extern char *logFilePath;
|
|
||||||
|
|
||||||
HWND hwnd = NULL;
|
HWND hwnd = NULL;
|
||||||
HANDLE hBridge = NULL;
|
HANDLE hBridge = NULL;
|
||||||
@ -51,7 +49,7 @@ VOID HandleStartButton(BOOL Silent)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
||||||
if (hSCManager == NULL)
|
if (hSCManager == NULL)
|
||||||
{
|
{
|
||||||
print("OpenSCManager failed: %s\n", GetErrorMessage());
|
print("OpenSCManager failed: %s\n", GetErrorMessage());
|
||||||
@ -182,7 +180,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
HandleRemoveButton();
|
HandleRemoveButton();
|
||||||
break;
|
break;
|
||||||
case IDM_VIEW_LOG:
|
case IDM_VIEW_LOG:
|
||||||
ShellExecute(NULL, "open", "C:\\windows\\notepad.exe", logFilePath, NULL, SW_SHOW);
|
ShellExecute(NULL, "open", "C:\\windows\\notepad.exe", "C:\\windows\\logs\\bridge.log", NULL, SW_SHOW);
|
||||||
break;
|
break;
|
||||||
case IDM_HELP_DOCUMENTATION:
|
case IDM_HELP_DOCUMENTATION:
|
||||||
ShellExecute(NULL, "open", "https://enderice2.github.io/rpc-bridge/index.html", NULL, NULL, SW_SHOWNORMAL);
|
ShellExecute(NULL, "open", "https://enderice2.github.io/rpc-bridge/index.html", NULL, NULL, SW_SHOWNORMAL);
|
||||||
@ -193,11 +191,14 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
case IDM_HELP_ABOUT:
|
case IDM_HELP_ABOUT:
|
||||||
{
|
{
|
||||||
char msg[256];
|
char msg[256];
|
||||||
sprintf(msg, "rpc-bridge v%s\n\n"
|
snprintf(msg, sizeof(msg),
|
||||||
|
"rpc-bridge v%s\n"
|
||||||
|
" branch: %s\n"
|
||||||
|
" commit: %s\n\n"
|
||||||
"Simple bridge that allows you to use Discord Rich Presence with Wine games/software.\n\n"
|
"Simple bridge that allows you to use Discord Rich Presence with Wine games/software.\n\n"
|
||||||
"Created by EnderIce2\n\n"
|
"Created by EnderIce2\n\n"
|
||||||
"Licensed under the MIT License",
|
"Licensed under the MIT License",
|
||||||
VER_VERSION_STR);
|
VER_VERSION_STR, GIT_BRANCH, GIT_COMMIT);
|
||||||
MessageBox(NULL, msg, "About", MB_OK);
|
MessageBox(NULL, msg, "About", MB_OK);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -231,6 +232,13 @@ VOID SetButtonStyles(INT *btnStartStyle, INT *btnRemoveStyle, INT *btnInstallSty
|
|||||||
*btnRemoveStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP;
|
*btnRemoveStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP;
|
||||||
*btnInstallStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP;
|
*btnInstallStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP;
|
||||||
|
|
||||||
|
// if (!IsLinux)
|
||||||
|
// {
|
||||||
|
// *btnInstallStyle |= WS_DISABLED;
|
||||||
|
// *btnRemoveStyle |= WS_DISABLED;
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
100
kvm.c
100
kvm.c
@ -1,100 +0,0 @@
|
|||||||
#if defined(__linux__)
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/un.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
void transferData(int fromSock, int toSock)
|
|
||||||
{
|
|
||||||
char buffer[256];
|
|
||||||
ssize_t bytesRead;
|
|
||||||
while ((bytesRead = read(fromSock, buffer, sizeof(buffer))) > 0)
|
|
||||||
{
|
|
||||||
write(toSock, buffer, bytesRead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int connectToSocket(const char *socketPath)
|
|
||||||
{
|
|
||||||
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
||||||
assert(sock >= 0);
|
|
||||||
|
|
||||||
struct sockaddr_un addr;
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
|
||||||
addr.sun_family = AF_UNIX;
|
|
||||||
strncpy(addr.sun_path, socketPath, sizeof(addr.sun_path) - 1);
|
|
||||||
|
|
||||||
int result = connect(sock, (struct sockaddr *)&addr, sizeof(addr));
|
|
||||||
assert(result == 0);
|
|
||||||
|
|
||||||
return sock;
|
|
||||||
}
|
|
||||||
|
|
||||||
int kvmSock;
|
|
||||||
int discordSock;
|
|
||||||
void sigintHandler(int sig)
|
|
||||||
{
|
|
||||||
close(kvmSock);
|
|
||||||
close(discordSock);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
signal(SIGINT, sigintHandler);
|
|
||||||
|
|
||||||
const char *kvmSocketPath = "/tmp/kvm-rpc-bridge";
|
|
||||||
const char *discordSocketPath = getenv("XDG_RUNTIME_DIR");
|
|
||||||
if (discordSocketPath == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "XDG_RUNTIME_DIR environment variable not set\n");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
char discordSocketFullPath[256];
|
|
||||||
snprintf(discordSocketFullPath, sizeof(discordSocketFullPath), "%s/discord-ipc-0", discordSocketPath);
|
|
||||||
|
|
||||||
printf("Trying Discord socket at %s\n", discordSocketFullPath);
|
|
||||||
discordSock = connectToSocket(discordSocketFullPath);
|
|
||||||
printf("Connected to Discord socket successfully\n");
|
|
||||||
|
|
||||||
// Connect to KVM socket
|
|
||||||
printf("Trying KVM socket at %s\n", kvmSocketPath);
|
|
||||||
kvmSock = connectToSocket(kvmSocketPath);
|
|
||||||
|
|
||||||
// Read specific message from KVM and send confirmation
|
|
||||||
const char kvmExpectedMsg[] = {0x69, 0x15, 0xBB};
|
|
||||||
const char kvmResponseMsg[] = {0x6E, 0x1D, 0xB4};
|
|
||||||
|
|
||||||
char buffer[3];
|
|
||||||
ssize_t bytesRead = read(kvmSock, buffer, sizeof(buffer));
|
|
||||||
printf("Read %ld bytes from KVM (%x %x %x)\n", bytesRead, buffer[0], buffer[1], buffer[2]);
|
|
||||||
assert(bytesRead == sizeof(kvmExpectedMsg));
|
|
||||||
assert(memcmp(buffer, kvmExpectedMsg, sizeof(kvmExpectedMsg)) == 0);
|
|
||||||
|
|
||||||
ssize_t bytesSent = write(kvmSock, kvmResponseMsg, sizeof(kvmResponseMsg));
|
|
||||||
assert(bytesSent == sizeof(kvmResponseMsg));
|
|
||||||
printf("Connected to KVM socket successfully\n");
|
|
||||||
|
|
||||||
// Transfer data between KVM and Discord sockets
|
|
||||||
if (fork() == 0)
|
|
||||||
{
|
|
||||||
// Child process: transfer data from KVM to Discord
|
|
||||||
transferData(kvmSock, discordSock);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Parent process: transfer data from Discord to KVM
|
|
||||||
transferData(discordSock, kvmSock);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(kvmSock);
|
|
||||||
close(discordSock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __linux__
|
|
37
main.c
37
main.c
@ -3,12 +3,10 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "bridge.h"
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
FILE *g_logFile = NULL;
|
FILE *g_logFile = NULL;
|
||||||
BOOL RunningAsService = FALSE;
|
BOOL RunningAsService = FALSE;
|
||||||
char *logFilePath = NULL;
|
|
||||||
|
|
||||||
void CreateGUI();
|
void CreateGUI();
|
||||||
void CreateBridge();
|
void CreateBridge();
|
||||||
@ -17,7 +15,7 @@ void ServiceMain(int argc, char *argv[]);
|
|||||||
void InstallService(int ServiceStartType, LPCSTR Path);
|
void InstallService(int ServiceStartType, LPCSTR Path);
|
||||||
char *native_getenv(const char *name);
|
char *native_getenv(const char *name);
|
||||||
void RemoveService();
|
void RemoveService();
|
||||||
extern OS_INFO OSInfo;
|
extern BOOL IsLinux;
|
||||||
|
|
||||||
LPTSTR GetErrorMessage()
|
LPTSTR GetErrorMessage()
|
||||||
{
|
{
|
||||||
@ -59,8 +57,11 @@ void DetectWine()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!GetProcAddress(hNTdll, "wine_get_version"))
|
if (!GetProcAddress(hNTdll, "wine_get_version"))
|
||||||
return;
|
{
|
||||||
OSInfo.IsWine = TRUE;
|
MessageBox(NULL, "This program is only intended to run under Wine.",
|
||||||
|
GetErrorMessage(), MB_OK | MB_ICONINFORMATION);
|
||||||
|
ExitProcess(1);
|
||||||
|
}
|
||||||
|
|
||||||
static void(CDECL * wine_get_host_version)(const char **sysname, const char **release);
|
static void(CDECL * wine_get_host_version)(const char **sysname, const char **release);
|
||||||
wine_get_host_version = (void *)GetProcAddress(hNTdll, "wine_get_host_version");
|
wine_get_host_version = (void *)GetProcAddress(hNTdll, "wine_get_host_version");
|
||||||
@ -77,8 +78,7 @@ void DetectWine()
|
|||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
OSInfo.IsLinux = strcmp(__sysname, "Linux") == 0;
|
IsLinux = strcmp(__sysname, "Linux") == 0;
|
||||||
OSInfo.IsDarwin = strcmp(__sysname, "Darwin") == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(char const *fmt, ...)
|
void print(char const *fmt, ...)
|
||||||
@ -113,13 +113,14 @@ void HandleArguments(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else if (strcmp(argv[1], "--steam") == 0)
|
else if (strcmp(argv[1], "--steam") == 0)
|
||||||
{
|
{
|
||||||
assert(OSInfo.IsWine == TRUE);
|
|
||||||
|
|
||||||
/* All this mess just so when you close the game,
|
/* All this mess just so when you close the game,
|
||||||
it automatically closes the bridge and Steam
|
it automatically closes the bridge and Steam
|
||||||
will not say that the game is still running. */
|
will not say that the game is still running. */
|
||||||
|
|
||||||
print("Running as Steam\n");
|
print("Running as Steam\n");
|
||||||
|
if (IsLinux == FALSE)
|
||||||
|
CreateBridge();
|
||||||
|
|
||||||
if (argc > 2)
|
if (argc > 2)
|
||||||
{
|
{
|
||||||
if (strcmp(argv[2], "--no-service") == 0)
|
if (strcmp(argv[2], "--no-service") == 0)
|
||||||
@ -272,12 +273,12 @@ void HandleArguments(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else if (strcmp(argv[1], "--version") == 0)
|
else if (strcmp(argv[1], "--version") == 0)
|
||||||
{
|
{
|
||||||
printf("%s\n", VER_VERSION_STR);
|
/* Already shows the version */
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[1], "--help") == 0)
|
else if (strcmp(argv[1], "--help") == 0)
|
||||||
{
|
{
|
||||||
printf("Usage:\n"
|
print("Usage:\n"
|
||||||
" %s [args]\n"
|
" %s [args]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Arguments:\n"
|
"Arguments:\n"
|
||||||
@ -311,22 +312,16 @@ void HandleArguments(int argc, char *argv[])
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
DetectWine();
|
DetectWine();
|
||||||
if (OSInfo.IsWine)
|
char *logFilePath = "C:\\windows\\logs\\bridge.log";
|
||||||
logFilePath = "C:\\windows\\logs\\bridge.log";
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logFilePath = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH);
|
|
||||||
GetTempPath(MAX_PATH, logFilePath);
|
|
||||||
strcat_s(logFilePath, MAX_PATH, "bridge.log");
|
|
||||||
}
|
|
||||||
g_logFile = fopen(logFilePath, "w");
|
g_logFile = fopen(logFilePath, "w");
|
||||||
if (g_logFile == NULL)
|
if (g_logFile == NULL)
|
||||||
{
|
{
|
||||||
printf("Failed to open logs file: %ld\n",
|
MessageBox(NULL, "Failed to open logs file", "Error", MB_OK | MB_ICONERROR);
|
||||||
GetLastError());
|
printf("Failed to open logs file: %ld\n", GetLastError());
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("rpc-bridge v%s %s-%s\n", VER_VERSION_STR, GIT_BRANCH, GIT_COMMIT);
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
HandleArguments(argc, argv);
|
HandleArguments(argc, argv);
|
||||||
else
|
else
|
||||||
|
@ -5,5 +5,5 @@
|
|||||||
#define IDM_HELP_ABOUT 40003
|
#define IDM_HELP_ABOUT 40003
|
||||||
#define IDM_VIEW_LOG 40004
|
#define IDM_VIEW_LOG 40004
|
||||||
|
|
||||||
#define VER_VERSION 1, 1, 0, 0
|
#define VER_VERSION 1, 3, 0, 0
|
||||||
#define VER_VERSION_STR "1.1\0"
|
#define VER_VERSION_STR "1.3\0"
|
||||||
|
@ -8,6 +8,7 @@ SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
|
|||||||
void print(char const *fmt, ...);
|
void print(char const *fmt, ...);
|
||||||
void CreateBridge();
|
void CreateBridge();
|
||||||
LPTSTR GetErrorMessage();
|
LPTSTR GetErrorMessage();
|
||||||
|
extern BOOL IsLinux;
|
||||||
|
|
||||||
void WINAPI ServiceCtrlHandler(DWORD CtrlCode)
|
void WINAPI ServiceCtrlHandler(DWORD CtrlCode)
|
||||||
{
|
{
|
||||||
@ -87,6 +88,14 @@ void InstallService(int ServiceStartType, LPCSTR Path)
|
|||||||
{
|
{
|
||||||
print("Registering service\n");
|
print("Registering service\n");
|
||||||
|
|
||||||
|
// if (IsLinux == FALSE)
|
||||||
|
// {
|
||||||
|
// /* 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.",
|
||||||
|
// "Unsupported", MB_OK | MB_ICONINFORMATION);
|
||||||
|
// 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