From 322b2fe97d86334f18d80609f7958a23b976f854 Mon Sep 17 00:00:00 2001 From: Daniel Collins Date: Sun, 18 Sep 2011 14:36:24 +0000 Subject: [PATCH] Added tray icon and menu with exit option to ipxrouter. Added filename argument to log_open. --- Makefile | 4 +- src/common.h | 4 + src/directplay.c | 2 +- src/ipxwrapper.c | 2 +- src/ipxwrapper.h | 3 - src/log.c | 4 +- src/router-exe.c | 213 ++++++++++++++++++++++++++++++++++++++++++----- src/stubdll.c | 6 +- 8 files changed, 202 insertions(+), 36 deletions(-) diff --git a/Makefile b/Makefile index 5554f6a..4581022 100644 --- a/Makefile +++ b/Makefile @@ -64,8 +64,8 @@ ipxconfig.exe: src/ipxconfig.cpp dpwsockx.dll: src/directplay.o src/log.o src/dpwsockx_stubs.o src/common.o $(CC) $(CFLAGS) -Wl,--enable-stdcall-fixup -shared -o dpwsockx.dll src/directplay.o src/log.o src/common.o src/dpwsockx_stubs.o src/dpwsockx.def -lwsock32 -ipxrouter.exe: src/router-exe.o src/router.o src/interface.o src/common.o - $(CC) $(CFLAGS) -static-libgcc -o ipxrouter.exe $^ -lws2_32 -liphlpapi +ipxrouter.exe: src/router-exe.o src/router.o src/interface.o src/common.o src/log.o + $(CC) $(CFLAGS) -static-libgcc -mwindows -o ipxrouter.exe $^ -lws2_32 -liphlpapi src/ipxwrapper_stubs.s: src/ipxwrapper_stubs.txt perl mkstubs.pl src/ipxwrapper_stubs.txt src/ipxwrapper_stubs.s 0 diff --git a/src/common.h b/src/common.h index d0113e2..345dce2 100644 --- a/src/common.h +++ b/src/common.h @@ -61,4 +61,8 @@ void unload_dlls(void); void __stdcall *find_sym(unsigned int dllnum, const char *symbol); void __stdcall log_call(unsigned int dllnum, const char *symbol); +void log_open(const char *file); +void log_close(); +void log_printf(const char *fmt, ...); + #endif /* !IPXWRAPPER_COMMON_H */ diff --git a/src/directplay.c b/src/directplay.c index 8f15a56..d3e22f1 100644 --- a/src/directplay.c +++ b/src/directplay.c @@ -561,7 +561,7 @@ HRESULT WINAPI SPInit(LPSPINITDATA data) { BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { if(why == DLL_PROCESS_ATTACH) { - log_open(); + log_open("ipxwrapper.log"); reg_open(KEY_QUERY_VALUE); diff --git a/src/ipxwrapper.c b/src/ipxwrapper.c index 2398422..faa5242 100644 --- a/src/ipxwrapper.c +++ b/src/ipxwrapper.c @@ -63,7 +63,7 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { static int initialised_cs = 0; if(why == DLL_PROCESS_ATTACH) { - log_open(); + log_open("ipxwrapper.log"); if(!rclient_init(&g_rclient)) { return FALSE; diff --git a/src/ipxwrapper.h b/src/ipxwrapper.h index 3a01f76..7ad0a48 100644 --- a/src/ipxwrapper.h +++ b/src/ipxwrapper.h @@ -111,9 +111,6 @@ void unlock_sockets(void); ipx_host *find_host(const unsigned char *net, const unsigned char *node); void add_host(const unsigned char *net, const unsigned char *node, uint32_t ipaddr); -void log_open(); -void log_close(); - INT APIENTRY r_EnumProtocolsA(LPINT,LPVOID,LPDWORD); INT APIENTRY r_EnumProtocolsW(LPINT,LPVOID,LPDWORD); int PASCAL FAR r_WSARecvEx(SOCKET,char*,int,int*); diff --git a/src/log.c b/src/log.c index 121d096..aac9485 100644 --- a/src/log.c +++ b/src/log.c @@ -25,13 +25,13 @@ static HANDLE log_fh = NULL; static HANDLE log_mutex = NULL; -void log_open() { +void log_open(const char *file) { if(!(log_mutex = CreateMutex(NULL, FALSE, NULL))) { abort(); } log_fh = CreateFile( - "ipxwrapper.log", + file, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, diff --git a/src/router-exe.c b/src/router-exe.c index e33ba27..897cada 100644 --- a/src/router-exe.c +++ b/src/router-exe.c @@ -15,6 +15,7 @@ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include #include #include @@ -24,9 +25,18 @@ struct reg_global global_conf; +static HMODULE netshell_dll = NULL; + +#define APPWM_TRAY (WM_APP+1) +#define MNU_EXIT 101 + +static void die(const char *fmt, ...); +static void init_ui(); +static LRESULT CALLBACK tray_wproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); +static void show_menu(HWND hwnd); + int main(int argc, char **argv) { - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); + log_open("ipxrouter.log"); reg_open(KEY_QUERY_VALUE); @@ -39,37 +49,196 @@ int main(int argc, char **argv) { WSADATA wsdata; int err = WSAStartup(MAKEWORD(2,0), &wsdata); - if(err) { - log_printf("Failed to initialize winsock: %s", w32_error(err)); - }else{ - struct router_vars *router = router_init(TRUE); - - if(router) { - //FreeConsole(); - router_main(router); - router_destroy(router); - } - - WSACleanup(); + die("Failed to initialize winsock: %s", w32_error(err)); } + struct router_vars *router = router_init(TRUE); + if(!router) { + die("Error while initializing router, check ipxrouter.log"); + } + + HANDLE worker = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&router_main, router, 0, NULL); + if(!worker) { + die("Failed to create router thread: %s", w32_error(GetLastError())); + } + + init_ui(); + + MSG msg; + + while(GetMessage(&msg, NULL, 0, 0) > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + EnterCriticalSection(&(router->crit_sec)); + + router->running = FALSE; + WSASetEvent(router->wsa_event); + + LeaveCriticalSection(&(router->crit_sec)); + + if(WaitForSingleObject(worker, 3000) == WAIT_TIMEOUT) { + log_printf("Router thread didn't exit in 3 seconds, terminating"); + TerminateThread(worker, 0); + } + + CloseHandle(worker); + router_destroy(router); + + WSACleanup(); + reg_close(); - system("pause"); + log_close(); return 0; } -void log_printf(const char *fmt, ...) { +static void die(const char *fmt, ...) { va_list argv; + char msg[512]; va_start(argv, fmt); - - //AllocConsole(); - - vfprintf(stderr, fmt, argv); - fputc('\n', stderr); - + vsnprintf(msg, sizeof(msg), fmt, argv); va_end(argv); + + MessageBox(NULL, msg, "Fatal error", MB_OK | MB_TASKMODAL); + exit(1); +} + +static void init_ui() { + WNDCLASS wclass; + + wclass.style = 0; + wclass.lpfnWndProc = &tray_wproc; + wclass.cbClsExtra = 0; + wclass.cbWndExtra = 0; + wclass.hInstance = GetModuleHandle(NULL); + wclass.hIcon = NULL; + wclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wclass.hbrBackground = NULL; + wclass.lpszMenuName = NULL; + wclass.lpszClassName = "ipxrouter_tray"; + + if(!RegisterClass(&wclass)) { + die("RegisterClass: %s", w32_error(GetLastError())); + } + + HWND window = CreateWindow( + "ipxrouter_tray", + "IPX Router", + 0, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + NULL, + NULL, + GetModuleHandle(NULL), + NULL + ); + + if(!window) { + die("CreateWindow: ", w32_error(GetLastError())); + } + + if(!(netshell_dll = LoadLibrary("netshell.dll"))) { + die("Error loading netshell.dll: ", w32_error(GetLastError())); + } + + HICON icon = LoadIcon(netshell_dll, MAKEINTRESOURCE(162)); + if(!icon) { + die("Error loading icon: ", w32_error(GetLastError())); + } + + NOTIFYICONDATA tray; + + tray.cbSize = sizeof(tray); + tray.hWnd = window; + tray.uID = 1; + tray.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + tray.uCallbackMessage = APPWM_TRAY; + tray.hIcon = icon; + strcpy(tray.szTip, "IPXWrapper Router"); + + if(!Shell_NotifyIcon(NIM_ADD, &tray)) { + die("Shell_NotifyIcon failed"); + } +} + +static LRESULT CALLBACK tray_wproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { + switch(msg) { + case WM_CLOSE: { + DestroyWindow(hwnd); + break; + } + + case WM_DESTROY: { + PostQuitMessage(0); + break; + } + + case APPWM_TRAY: { + if(lp == WM_LBUTTONUP || lp == WM_RBUTTONUP) { + show_menu(hwnd); + } + + break; + } + + case WM_COMMAND: { + if(wp == MNU_EXIT) { + if(MessageBox(NULL, "If the router is stopped any existing sockets will become invalid.\nAre you sure you want to exit?", "IPXWrapper", MB_YESNO) == IDNO) { + return 0; + } + + NOTIFYICONDATA tray; + tray.cbSize = sizeof(tray); + tray.hWnd = hwnd; + tray.uID = 1; + tray.uFlags = 0; + + Shell_NotifyIcon(NIM_DELETE, &tray); + DestroyWindow(hwnd); + } + + break; + } + + default: { + return DefWindowProc(hwnd, msg, wp, lp); + } + } + + return 0; +} + +static void show_menu(HWND hwnd) { + POINT cursor_pos; + + GetCursorPos(&cursor_pos); + + SetForegroundWindow(hwnd); + + HMENU menu = CreatePopupMenu(); + if(!menu) { + die("CreatePopupMenu: %s", w32_error(GetLastError())); + } + + InsertMenu(menu, -1, MF_BYPOSITION | MF_STRING, MNU_EXIT, "Exit"); + + SetMenuDefaultItem(menu, MNU_EXIT, FALSE); + + SetFocus(hwnd); + + TrackPopupMenu( + menu, + TPM_LEFTALIGN | TPM_BOTTOMALIGN, + cursor_pos.x, cursor_pos.y, + 0, + hwnd, + NULL + ); + + DestroyMenu(menu); } diff --git a/src/stubdll.c b/src/stubdll.c index ddc3145..2c88d93 100644 --- a/src/stubdll.c +++ b/src/stubdll.c @@ -21,13 +21,9 @@ #include "common.h" -void log_open(); -void log_close(); -void log_printf(const char *fmt, ...); - BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res) { if(why == DLL_PROCESS_ATTACH) { - log_open(); + log_open("ipxwrapper.log"); reg_open(KEY_QUERY_VALUE);