mirror of
https://github.com/solemnwarning/ipxwrapper
synced 2024-12-30 16:45:37 +01:00
Refactored ipxconfig, allow enabling Ethernet encapsulation.
This commit is contained in:
parent
35d853ae54
commit
4fd24354a5
2
Makefile
2
Makefile
@ -23,7 +23,7 @@ endif
|
|||||||
INCLUDE := -I./include/
|
INCLUDE := -I./include/
|
||||||
|
|
||||||
CFLAGS := -std=c99 -Wall -D_WIN32_WINNT=0x0500 -DHAVE_REMOTE $(DBG_OPT) $(INCLUDE)
|
CFLAGS := -std=c99 -Wall -D_WIN32_WINNT=0x0500 -DHAVE_REMOTE $(DBG_OPT) $(INCLUDE)
|
||||||
CXXFLAGS := -Wall -DHAVE_REMOTE $(DBG_OPT) $(INCLUDE)
|
CXXFLAGS := -std=c++0x -Wall -DHAVE_REMOTE $(DBG_OPT) $(INCLUDE)
|
||||||
|
|
||||||
# Used by mkdeps.pl
|
# Used by mkdeps.pl
|
||||||
#
|
#
|
||||||
|
@ -30,6 +30,7 @@ main_config_t get_main_config(void)
|
|||||||
config.udp_port = DEFAULT_PORT;
|
config.udp_port = DEFAULT_PORT;
|
||||||
config.w95_bug = true;
|
config.w95_bug = true;
|
||||||
config.fw_except = false;
|
config.fw_except = false;
|
||||||
|
config.use_pcap = false;
|
||||||
config.log_level = LOG_INFO;
|
config.log_level = LOG_INFO;
|
||||||
|
|
||||||
HKEY reg = reg_open_main(false);
|
HKEY reg = reg_open_main(false);
|
||||||
@ -51,6 +52,7 @@ main_config_t get_main_config(void)
|
|||||||
config.udp_port = reg_get_dword(reg, "port", config.udp_port);
|
config.udp_port = reg_get_dword(reg, "port", config.udp_port);
|
||||||
config.w95_bug = reg_get_dword(reg, "w95_bug", config.w95_bug);
|
config.w95_bug = reg_get_dword(reg, "w95_bug", config.w95_bug);
|
||||||
config.fw_except = reg_get_dword(reg, "fw_except", config.fw_except);
|
config.fw_except = reg_get_dword(reg, "fw_except", config.fw_except);
|
||||||
|
config.use_pcap = reg_get_dword(reg, "use_pcap", config.use_pcap);
|
||||||
config.log_level = reg_get_dword(reg, "log_level", config.log_level);
|
config.log_level = reg_get_dword(reg, "log_level", config.log_level);
|
||||||
|
|
||||||
reg_close(reg);
|
reg_close(reg);
|
||||||
@ -65,6 +67,7 @@ bool set_main_config(const main_config_t *config)
|
|||||||
bool ok = reg_set_dword(reg, "port", config->udp_port)
|
bool ok = reg_set_dword(reg, "port", config->udp_port)
|
||||||
&& reg_set_dword(reg, "w95_bug", config->w95_bug)
|
&& reg_set_dword(reg, "w95_bug", config->w95_bug)
|
||||||
&& reg_set_dword(reg, "fw_except", config->fw_except)
|
&& reg_set_dword(reg, "fw_except", config->fw_except)
|
||||||
|
&& reg_set_dword(reg, "use_pcap", config->use_pcap)
|
||||||
&& reg_set_dword(reg, "log_level", config->log_level);
|
&& reg_set_dword(reg, "log_level", config->log_level);
|
||||||
|
|
||||||
reg_close(reg);
|
reg_close(reg);
|
||||||
|
@ -31,6 +31,7 @@ typedef struct main_config {
|
|||||||
|
|
||||||
bool w95_bug;
|
bool w95_bug;
|
||||||
bool fw_except;
|
bool fw_except;
|
||||||
|
bool use_pcap;
|
||||||
|
|
||||||
enum ipx_log_level log_level;
|
enum ipx_log_level log_level;
|
||||||
} main_config_t;
|
} main_config_t;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* IPXWrapper - Configuration tool
|
/* IPXWrapper - Configuration tool
|
||||||
* Copyright (C) 2011-2013 Daniel Collins <solemnwarning@solemnwarning.net>
|
* Copyright (C) 2011-2014 Daniel Collins <solemnwarning@solemnwarning.net>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 as published by
|
* under the terms of the GNU General Public License version 2 as published by
|
||||||
@ -29,22 +29,25 @@
|
|||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "addr.h"
|
#include "addr.h"
|
||||||
|
|
||||||
#define ID_PRI_LIST 1
|
const char *IPXCONFIG_WINDOW_CLASS = "ipxconfig_class";
|
||||||
|
|
||||||
#define ID_NIC_LIST 11
|
enum {
|
||||||
#define ID_NIC_ENABLED 12
|
ID_NIC_LIST = 11,
|
||||||
#define ID_NIC_NET 13
|
ID_NIC_ENABLED = 12,
|
||||||
#define ID_NIC_NODE 14
|
ID_NIC_NET = 13,
|
||||||
|
ID_NIC_NODE = 14,
|
||||||
|
|
||||||
#define ID_OPT_PORT 21
|
ID_OPT_PORT = 21,
|
||||||
#define ID_OPT_W95 22
|
ID_OPT_W95 = 22,
|
||||||
#define ID_OPT_LOG_DEBUG 25
|
ID_OPT_LOG_DEBUG = 25,
|
||||||
#define ID_OPT_LOG_TRACE 26
|
ID_OPT_LOG_TRACE = 26,
|
||||||
#define ID_OPT_FW_EXCEPT 27
|
ID_OPT_FW_EXCEPT = 27,
|
||||||
|
ID_OPT_USE_PCAP = 28,
|
||||||
|
|
||||||
#define ID_OK 31
|
ID_OK = 31,
|
||||||
#define ID_CANCEL 32
|
ID_CANCEL = 32,
|
||||||
#define ID_APPLY 33
|
ID_APPLY = 33,
|
||||||
|
};
|
||||||
|
|
||||||
struct iface {
|
struct iface {
|
||||||
/* C style string so it can be passed directly to the listview */
|
/* C style string so it can be passed directly to the listview */
|
||||||
@ -55,23 +58,31 @@ struct iface {
|
|||||||
iface_config_t config;
|
iface_config_t config;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<iface> iface_list;
|
static void reload_nics();
|
||||||
|
static void reload_primary_nics();
|
||||||
|
static bool stash_nic_config();
|
||||||
|
|
||||||
static void get_nics();
|
|
||||||
static bool save_config();
|
static bool save_config();
|
||||||
static bool store_nic();
|
static void main_window_init();
|
||||||
static void init_windows();
|
static void main_window_update();
|
||||||
static void update_nic_conf();
|
static void main_window_resize(int width, int height);
|
||||||
static void init_pri_list();
|
|
||||||
static HWND create_child(HWND parent, int x, int y, int w, int h, LPCTSTR class_name, LPCTSTR title, DWORD style = 0, DWORD ex_style = 0, unsigned int id = 0);
|
static HWND create_child(HWND parent, LPCTSTR class_name, LPCTSTR title, DWORD style = 0, DWORD ex_style = 0, unsigned int id = 0);
|
||||||
static HWND create_group(HWND parent, int x, int y, int w, int h, LPCTSTR title);
|
static HWND create_GroupBox(HWND parent, LPCTSTR title);
|
||||||
|
static HWND create_STATIC(HWND parent, LPCTSTR text);
|
||||||
|
static HWND create_checkbox(HWND parent, LPCTSTR label, int id);
|
||||||
|
static bool get_checkbox(HWND checkbox);
|
||||||
|
static void set_checkbox(HWND checkbox, bool state);
|
||||||
static int get_text_width(HWND hwnd, const char *txt);
|
static int get_text_width(HWND hwnd, const char *txt);
|
||||||
static int get_text_height(HWND hwnd);
|
static int get_text_height(HWND hwnd);
|
||||||
static RECT get_window_rect(HWND hwnd);
|
|
||||||
static std::string w32_errmsg(DWORD errnum);
|
static std::string w32_errmsg(DWORD errnum);
|
||||||
static void die(std::string msg);
|
static void die(std::string msg);
|
||||||
|
static bool _pcap_installed();
|
||||||
|
|
||||||
static iface_list nics;
|
static const bool PCAP_INSTALLED = _pcap_installed();
|
||||||
|
|
||||||
|
static std::vector<iface> nics;
|
||||||
|
|
||||||
static main_config_t main_config = get_main_config();
|
static main_config_t main_config = get_main_config();
|
||||||
static addr48_t primary_iface = get_primary_iface();
|
static addr48_t primary_iface = get_primary_iface();
|
||||||
@ -85,10 +96,10 @@ static wproc_fptr default_groupbox_wproc = NULL;
|
|||||||
static struct {
|
static struct {
|
||||||
HWND main;
|
HWND main;
|
||||||
|
|
||||||
HWND primary_group;
|
HWND box_primary;
|
||||||
HWND primary;
|
HWND primary;
|
||||||
|
|
||||||
HWND nic_group;
|
HWND box_nic;
|
||||||
HWND nic_list;
|
HWND nic_list;
|
||||||
HWND nic_enabled;
|
HWND nic_enabled;
|
||||||
HWND nic_net_lbl;
|
HWND nic_net_lbl;
|
||||||
@ -96,7 +107,7 @@ static struct {
|
|||||||
HWND nic_node_lbl;
|
HWND nic_node_lbl;
|
||||||
HWND nic_node;
|
HWND nic_node;
|
||||||
|
|
||||||
HWND opt_group;
|
HWND box_options;
|
||||||
|
|
||||||
HWND opt_port_lbl;
|
HWND opt_port_lbl;
|
||||||
HWND opt_port;
|
HWND opt_port;
|
||||||
@ -105,11 +116,12 @@ static struct {
|
|||||||
HWND opt_log_debug;
|
HWND opt_log_debug;
|
||||||
HWND opt_log_trace;
|
HWND opt_log_trace;
|
||||||
HWND opt_fw_except;
|
HWND opt_fw_except;
|
||||||
|
HWND opt_use_pcap;
|
||||||
|
|
||||||
HWND ok_btn;
|
HWND ok_btn;
|
||||||
HWND can_btn;
|
HWND can_btn;
|
||||||
HWND app_btn;
|
HWND app_btn;
|
||||||
} windows;
|
} wh;
|
||||||
|
|
||||||
/* Callback for the main window */
|
/* Callback for the main window */
|
||||||
static LRESULT CALLBACK main_wproc(HWND window, UINT msg, WPARAM wp, LPARAM lp) {
|
static LRESULT CALLBACK main_wproc(HWND window, UINT msg, WPARAM wp, LPARAM lp) {
|
||||||
@ -132,13 +144,13 @@ static LRESULT CALLBACK main_wproc(HWND window, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
NMLISTVIEW *lv = (NMLISTVIEW*)lp;
|
NMLISTVIEW *lv = (NMLISTVIEW*)lp;
|
||||||
|
|
||||||
if(lv->uNewState & LVIS_FOCUSED) {
|
if(lv->uNewState & LVIS_FOCUSED) {
|
||||||
update_nic_conf();
|
main_window_update();
|
||||||
}
|
}
|
||||||
}else if(nhdr->code == LVN_ITEMCHANGING) {
|
}else if(nhdr->code == LVN_ITEMCHANGING) {
|
||||||
NMLISTVIEW *lv = (NMLISTVIEW*)lp;
|
NMLISTVIEW *lv = (NMLISTVIEW*)lp;
|
||||||
|
|
||||||
if((lv->uOldState & LVIS_FOCUSED && !(lv->uNewState & LVIS_FOCUSED)) || (lv->uOldState & LVIS_SELECTED && !(lv->uNewState & LVIS_SELECTED))) {
|
if((lv->uOldState & LVIS_FOCUSED && !(lv->uNewState & LVIS_FOCUSED)) || (lv->uOldState & LVIS_SELECTED && !(lv->uNewState & LVIS_SELECTED))) {
|
||||||
if(!store_nic()) {
|
if(!stash_nic_config()) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,30 +164,38 @@ static LRESULT CALLBACK main_wproc(HWND window, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
if(HIWORD(wp) == BN_CLICKED) {
|
if(HIWORD(wp) == BN_CLICKED) {
|
||||||
switch(LOWORD(wp)) {
|
switch(LOWORD(wp)) {
|
||||||
case ID_NIC_ENABLED: {
|
case ID_NIC_ENABLED: {
|
||||||
int nic = ListView_GetNextItem(windows.nic_list, (LPARAM)-1, LVNI_FOCUSED);
|
int nic = ListView_GetNextItem(wh.nic_list, (LPARAM)(-1), LVNI_FOCUSED);
|
||||||
nics[nic].config.enabled = Button_GetCheck(windows.nic_enabled) == BST_CHECKED;
|
nics[nic].config.enabled = get_checkbox(wh.nic_enabled);
|
||||||
|
|
||||||
init_pri_list();
|
reload_primary_nics();
|
||||||
update_nic_conf();
|
main_window_update();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ID_OPT_LOG_DEBUG: {
|
case ID_OPT_LOG_DEBUG: {
|
||||||
EnableWindow(windows.opt_log_trace, Button_GetCheck(windows.opt_log_debug) == BST_CHECKED);
|
main_window_update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ID_OPT_USE_PCAP: {
|
||||||
|
main_config.use_pcap = get_checkbox(wh.opt_use_pcap);
|
||||||
|
|
||||||
|
reload_nics();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ID_OK: {
|
case ID_OK: {
|
||||||
if(save_config()) {
|
if(save_config()) {
|
||||||
PostMessage(windows.main, WM_CLOSE, 0, 0);
|
PostMessage(wh.main, WM_CLOSE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ID_CANCEL: {
|
case ID_CANCEL: {
|
||||||
PostMessage(windows.main, WM_CLOSE, 0, 0);
|
PostMessage(wh.main, WM_CLOSE, 0, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,72 +213,7 @@ static LRESULT CALLBACK main_wproc(HWND window, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case WM_SIZE: {
|
case WM_SIZE: {
|
||||||
int width = LOWORD(lp), height = HIWORD(lp);
|
main_window_resize(LOWORD(lp), HIWORD(lp));
|
||||||
|
|
||||||
int edge = GetSystemMetrics(SM_CYEDGE);
|
|
||||||
int text_h = get_text_height(windows.primary_group);
|
|
||||||
int edit_h = text_h + 2 * edge;
|
|
||||||
int pri_h = edit_h + text_h + 10;
|
|
||||||
|
|
||||||
MoveWindow(windows.primary_group, 0, 0, width, pri_h, TRUE);
|
|
||||||
MoveWindow(windows.primary, 10, text_h, width - 20, edit_h, TRUE);
|
|
||||||
|
|
||||||
/* Buttons */
|
|
||||||
|
|
||||||
RECT btn_rect = get_window_rect(windows.ok_btn);
|
|
||||||
int btn_w = btn_rect.right - btn_rect.left;
|
|
||||||
int btn_h = btn_rect.bottom - btn_rect.top;
|
|
||||||
|
|
||||||
MoveWindow(windows.app_btn, width - btn_w - 6, height - btn_h - 6, btn_w, btn_h, TRUE);
|
|
||||||
MoveWindow(windows.can_btn, width - btn_w * 2 - 12, height - btn_h - 6, btn_w, btn_h, TRUE);
|
|
||||||
MoveWindow(windows.ok_btn, width - btn_w * 3 - 18, height - btn_h - 6, btn_w, btn_h, TRUE);
|
|
||||||
|
|
||||||
/* Options groupbox */
|
|
||||||
|
|
||||||
int lbl_w = get_text_width(windows.nic_net_lbl, "Network number");
|
|
||||||
int edit_w = get_text_width(windows.nic_node, "000000");
|
|
||||||
|
|
||||||
int opt_h = 5 * text_h + edit_h + 18;
|
|
||||||
|
|
||||||
MoveWindow(windows.opt_group, 0, height - opt_h - btn_h - 12, width, opt_h, TRUE);
|
|
||||||
|
|
||||||
int y = text_h;
|
|
||||||
|
|
||||||
MoveWindow(windows.opt_port_lbl, 10, y + edge, lbl_w, text_h, TRUE);
|
|
||||||
MoveWindow(windows.opt_port, 15 + lbl_w, y, edit_w, edit_h, TRUE);
|
|
||||||
|
|
||||||
MoveWindow(windows.opt_w95, 10, y += edit_h + 4, width - 20, text_h, TRUE);
|
|
||||||
MoveWindow(windows.opt_log_debug, 10, y += text_h + 2, width - 20, text_h, TRUE);
|
|
||||||
MoveWindow(windows.opt_log_trace, 10, y += text_h + 2, width - 20, text_h, TRUE);
|
|
||||||
MoveWindow(windows.opt_fw_except, 10, y += text_h + 2, width - 20, text_h, TRUE);
|
|
||||||
|
|
||||||
/* NIC groupbox */
|
|
||||||
|
|
||||||
// lbl_w = get_text_width(windows.nic_net_lbl, "Network number");
|
|
||||||
edit_w = get_text_width(windows.nic_node, "00:00:00:00:00:00");
|
|
||||||
|
|
||||||
int net_h = height - pri_h - opt_h - btn_h - 12;
|
|
||||||
|
|
||||||
MoveWindow(windows.nic_group, 0, pri_h, width, net_h, TRUE);
|
|
||||||
|
|
||||||
y = net_h - (6 + edit_h);
|
|
||||||
|
|
||||||
MoveWindow(windows.nic_node_lbl, 10, y + edge, lbl_w, text_h, TRUE);
|
|
||||||
MoveWindow(windows.nic_node, 15 + lbl_w, y, edit_w, edit_h, TRUE);
|
|
||||||
|
|
||||||
y -= 2 + edit_h;
|
|
||||||
|
|
||||||
MoveWindow(windows.nic_net_lbl, 10, y + edge, lbl_w, text_h, TRUE);
|
|
||||||
MoveWindow(windows.nic_net, 15 + lbl_w, y, edit_w, edit_h, TRUE);
|
|
||||||
|
|
||||||
y -= 2 + edit_h;
|
|
||||||
|
|
||||||
MoveWindow(windows.nic_enabled, 10, y, width - 20, text_h, TRUE);
|
|
||||||
|
|
||||||
y -= 6;
|
|
||||||
|
|
||||||
MoveWindow(windows.nic_list, 10, text_h, width - 20, y - text_h, TRUE);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +229,7 @@ static LRESULT CALLBACK groupbox_wproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp
|
|||||||
switch(msg) {
|
switch(msg) {
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
case WM_NOTIFY:
|
case WM_NOTIFY:
|
||||||
return main_wproc(windows.main, msg, wp, lp);
|
return main_wproc(wh.main, msg, wp, lp);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return default_groupbox_wproc(hwnd, msg, wp, lp);
|
return default_groupbox_wproc(hwnd, msg, wp, lp);
|
||||||
@ -283,9 +238,42 @@ static LRESULT CALLBACK groupbox_wproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
get_nics();
|
INITCOMMONCONTROLSEX common_controls;
|
||||||
|
common_controls.dwSize = sizeof(common_controls);
|
||||||
|
common_controls.dwICC = ICC_LISTVIEW_CLASSES;
|
||||||
|
|
||||||
init_windows();
|
if(!InitCommonControlsEx(&common_controls))
|
||||||
|
{
|
||||||
|
die("Could not initialise common controls");
|
||||||
|
}
|
||||||
|
|
||||||
|
WNDCLASSEX wclass;
|
||||||
|
wclass.cbSize = sizeof(wclass);
|
||||||
|
wclass.style = CS_HREDRAW | CS_VREDRAW;
|
||||||
|
wclass.lpfnWndProc = &main_wproc;
|
||||||
|
wclass.cbClsExtra = 0;
|
||||||
|
wclass.cbWndExtra = 0;
|
||||||
|
wclass.hInstance = GetModuleHandle(NULL);
|
||||||
|
wclass.hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(50), IMAGE_ICON, 32, 32, LR_SHARED);
|
||||||
|
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
|
||||||
|
wclass.lpszMenuName = NULL;
|
||||||
|
wclass.lpszClassName = IPXCONFIG_WINDOW_CLASS;
|
||||||
|
wclass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(50), IMAGE_ICON, 16, 16, LR_SHARED);
|
||||||
|
|
||||||
|
if(!RegisterClassEx(&wclass))
|
||||||
|
{
|
||||||
|
die("Could not register window class: " + w32_errmsg(GetLastError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!PCAP_INSTALLED && main_config.use_pcap)
|
||||||
|
{
|
||||||
|
MessageBox(NULL, "IPXWrapper is currently configured to use WinPcap, but it doesn't seem to be installed.\n"
|
||||||
|
"Configuration has been reset to use IP encapsulation.", "WinPcap not found", MB_OK | MB_TASKMODAL | MB_ICONWARNING);
|
||||||
|
main_config.use_pcap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
main_window_init();
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
BOOL mret;
|
BOOL mret;
|
||||||
@ -299,7 +287,7 @@ int main()
|
|||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
|
|
||||||
if(inv_window && !PeekMessage(&msg, NULL, 0, 0, 0)) {
|
if(inv_window && !PeekMessage(&msg, NULL, 0, 0, 0)) {
|
||||||
MessageBox(windows.main, inv_error.c_str(), "Error", MB_OK);
|
MessageBox(wh.main, inv_error.c_str(), "Error", MB_OK);
|
||||||
|
|
||||||
SetFocus(inv_window);
|
SetFocus(inv_window);
|
||||||
Edit_SetSel(inv_window, 0, Edit_GetTextLength(inv_window));
|
Edit_SetSel(inv_window, 0, Edit_GetTextLength(inv_window));
|
||||||
@ -323,8 +311,35 @@ static void _add_nic(addr48_t hwaddr, const char *name)
|
|||||||
nics.push_back(iface);
|
nics.push_back(iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_nics()
|
/* Repopulate the list of network interfaces.
|
||||||
|
*
|
||||||
|
* This is called during main window initialisation and when switching between
|
||||||
|
* IP/Ethernet encapsulation.
|
||||||
|
*/
|
||||||
|
static void reload_nics()
|
||||||
{
|
{
|
||||||
|
nics.clear();
|
||||||
|
|
||||||
|
if(main_config.use_pcap)
|
||||||
|
{
|
||||||
|
/* Ethernet encapsulation is selected, so we base the NIC list
|
||||||
|
* on the list of usable WinPcap interfaces.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ipx_pcap_interface_t *pcap_interfaces = ipx_get_pcap_interfaces(), *i;
|
||||||
|
|
||||||
|
DL_FOREACH(pcap_interfaces, i)
|
||||||
|
{
|
||||||
|
_add_nic(i->mac_addr, i->desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipx_free_pcap_interfaces(&pcap_interfaces);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/* IP encapsulation is selected, so we base the NIC list on the
|
||||||
|
* list of IP interfaces.
|
||||||
|
*/
|
||||||
|
|
||||||
_add_nic(WILDCARD_IFACE_HWADDR, "Wildcard interface");
|
_add_nic(WILDCARD_IFACE_HWADDR, "Wildcard interface");
|
||||||
|
|
||||||
IP_ADAPTER_INFO *ifroot = load_sys_interfaces(), *ifptr;
|
IP_ADAPTER_INFO *ifroot = load_sys_interfaces(), *ifptr;
|
||||||
@ -342,25 +357,124 @@ static void get_nics()
|
|||||||
free(ifroot);
|
free(ifroot);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListView_DeleteAllItems(wh.nic_list);
|
||||||
|
|
||||||
|
LVITEM lvi;
|
||||||
|
lvi.mask = LVIF_TEXT | LVIF_STATE;
|
||||||
|
lvi.iItem = 0;
|
||||||
|
lvi.iSubItem = 0;
|
||||||
|
lvi.state = 0;
|
||||||
|
lvi.stateMask = 0;
|
||||||
|
|
||||||
|
for(auto i = nics.begin(); i != nics.end(); ++i)
|
||||||
|
{
|
||||||
|
lvi.pszText = i->name;
|
||||||
|
|
||||||
|
ListView_InsertItem(wh.nic_list, &lvi);
|
||||||
|
++(lvi.iItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView_SetColumnWidth(wh.nic_list, 0, LVSCW_AUTOSIZE);
|
||||||
|
|
||||||
|
reload_primary_nics();
|
||||||
|
main_window_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Repopulate the list of interfaces available to be used as the primary.
|
||||||
|
*
|
||||||
|
* This is called after reloading the list of NICs or when toggling the enabled
|
||||||
|
* state of an interface.
|
||||||
|
*/
|
||||||
|
static void reload_primary_nics()
|
||||||
|
{
|
||||||
|
ComboBox_ResetContent(wh.primary);
|
||||||
|
|
||||||
|
ComboBox_AddString(wh.primary, "Default");
|
||||||
|
ComboBox_SetCurSel(wh.primary, 0);
|
||||||
|
|
||||||
|
for(auto i = nics.begin(); i != nics.end(); i++)
|
||||||
|
{
|
||||||
|
if(i->config.enabled)
|
||||||
|
{
|
||||||
|
int index = ComboBox_AddString(wh.primary, i->name);
|
||||||
|
|
||||||
|
if(i->hwaddr == primary_iface)
|
||||||
|
{
|
||||||
|
ComboBox_SetCurSel(wh.primary, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fetch NIC settings from UI and stash them in the NIC list.
|
||||||
|
*
|
||||||
|
* Returns false if an address or other text value could not be parsed, true
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
static bool stash_nic_config()
|
||||||
|
{
|
||||||
|
int selected_nic = ListView_GetNextItem(wh.nic_list, (LPARAM)-1, LVNI_FOCUSED);
|
||||||
|
|
||||||
|
if(selected_nic == -1) {
|
||||||
|
/* Return success if no NIC is selected */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
char net[32], node[32];
|
||||||
|
|
||||||
|
GetWindowText(wh.nic_net, net, 32);
|
||||||
|
GetWindowText(wh.nic_node, node, 32);
|
||||||
|
|
||||||
|
if(!addr32_from_string(&(nics[selected_nic].config.netnum), net))
|
||||||
|
{
|
||||||
|
inv_error = "Network number is invalid.\n"
|
||||||
|
"Valid network numbers are in the format XX:XX:XX:XX";
|
||||||
|
inv_window = wh.nic_net;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!main_config.use_pcap)
|
||||||
|
{
|
||||||
|
if(!addr48_from_string(&(nics[selected_nic].config.nodenum), node))
|
||||||
|
{
|
||||||
|
inv_error = "Node number is invalid.\n"
|
||||||
|
"Valid numbers are in the format XX:XX:XX:XX:XX:XX";
|
||||||
|
inv_window = wh.nic_node;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool save_config()
|
static bool save_config()
|
||||||
{
|
{
|
||||||
if(!store_nic())
|
if(!stash_nic_config())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pri_index = ComboBox_GetCurSel(windows.primary);
|
int pri_index = ComboBox_GetCurSel(wh.primary);
|
||||||
|
|
||||||
if(pri_index == 0)
|
if(pri_index == 0)
|
||||||
{
|
{
|
||||||
primary_iface = addr48_in((unsigned char[]){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF});
|
primary_iface = addr48_in((unsigned char[]){0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF});
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
int this_nic = 1;
|
/* Iterate over the NIC list to find the selected primary
|
||||||
|
* interface.
|
||||||
|
*
|
||||||
|
* Can't just deref by index here as disabled interfaces don't
|
||||||
|
* increment the index.
|
||||||
|
*/
|
||||||
|
|
||||||
for(iface_list::iterator i = nics.begin(); i != nics.end(); i++)
|
int this_nic = 0;
|
||||||
|
|
||||||
|
for(auto i = nics.begin(); i != nics.end(); i++)
|
||||||
{
|
{
|
||||||
if(i->config.enabled && this_nic++ == pri_index)
|
if(i->config.enabled && ++this_nic == pri_index)
|
||||||
{
|
{
|
||||||
primary_iface = i->hwaddr;
|
primary_iface = i->hwaddr;
|
||||||
break;
|
break;
|
||||||
@ -368,36 +482,41 @@ static bool save_config()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!main_config.use_pcap)
|
||||||
|
{
|
||||||
char port_s[32], *endptr;
|
char port_s[32], *endptr;
|
||||||
|
|
||||||
GetWindowText(windows.opt_port, port_s, 32);
|
GetWindowText(wh.opt_port, port_s, 32);
|
||||||
int port = strtol(port_s, &endptr, 10);
|
int port = strtol(port_s, &endptr, 10);
|
||||||
|
|
||||||
if(port < 1 || port > 65535 || *endptr) {
|
if(port < 1 || port > 65535 || *endptr) {
|
||||||
MessageBox(windows.main, "Invalid port number.\nPort number must be an integer in the range 1 - 65535", "Error", MB_OK);
|
MessageBox(wh.main, "Invalid port number.\n"
|
||||||
|
"Port number must be an integer in the range 1 - 65535", "Error", MB_OK);
|
||||||
|
|
||||||
SetFocus(windows.opt_port);
|
SetFocus(wh.opt_port);
|
||||||
Edit_SetSel(windows.opt_port, 0, Edit_GetTextLength(windows.opt_port));
|
Edit_SetSel(wh.opt_port, 0, Edit_GetTextLength(wh.opt_port));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
main_config.udp_port = port;
|
main_config.udp_port = port;
|
||||||
main_config.w95_bug = Button_GetCheck(windows.opt_w95) == BST_CHECKED;
|
}
|
||||||
main_config.fw_except = Button_GetCheck(windows.opt_fw_except) == BST_CHECKED;
|
|
||||||
|
main_config.w95_bug = get_checkbox(wh.opt_w95);
|
||||||
|
main_config.fw_except = get_checkbox(wh.opt_fw_except);
|
||||||
main_config.log_level = LOG_INFO;
|
main_config.log_level = LOG_INFO;
|
||||||
|
|
||||||
if(Button_GetCheck(windows.opt_log_debug) == BST_CHECKED)
|
if(get_checkbox(wh.opt_log_debug))
|
||||||
{
|
{
|
||||||
main_config.log_level = LOG_DEBUG;
|
main_config.log_level = LOG_DEBUG;
|
||||||
|
|
||||||
if(Button_GetCheck(windows.opt_log_trace) == BST_CHECKED)
|
if(get_checkbox(wh.opt_log_trace))
|
||||||
{
|
{
|
||||||
main_config.log_level = LOG_CALL;
|
main_config.log_level = LOG_CALL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(iface_list::iterator i = nics.begin(); i != nics.end(); i++)
|
for(auto i = nics.begin(); i != nics.end(); i++)
|
||||||
{
|
{
|
||||||
if(!set_iface_config(i->hwaddr, &(i->config)))
|
if(!set_iface_config(i->hwaddr, &(i->config)))
|
||||||
{
|
{
|
||||||
@ -408,68 +527,13 @@ static bool save_config()
|
|||||||
return set_main_config(&main_config) && set_primary_iface(primary_iface);
|
return set_main_config(&main_config) && set_primary_iface(primary_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch NIC settings from UI and store in NIC list */
|
/* Create the main window and all the child windows, populate them with the
|
||||||
static bool store_nic() {
|
* current configuration and then display them.
|
||||||
int selected_nic = ListView_GetNextItem(windows.nic_list, (LPARAM)-1, LVNI_FOCUSED);
|
*/
|
||||||
|
static void main_window_init()
|
||||||
if(selected_nic == -1) {
|
|
||||||
/* Return success if no NIC is selected */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
char net[32], node[32];
|
|
||||||
|
|
||||||
GetWindowText(windows.nic_net, net, 32);
|
|
||||||
GetWindowText(windows.nic_node, node, 32);
|
|
||||||
|
|
||||||
if(!addr32_from_string(&(nics[selected_nic].config.netnum), net))
|
|
||||||
{
|
{
|
||||||
inv_error = "Network number is invalid.\nValid numbers are in the format XX:XX:XX:XX";
|
wh.main = CreateWindow(
|
||||||
inv_window = windows.nic_net;
|
IPXCONFIG_WINDOW_CLASS,
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!addr48_from_string(&(nics[selected_nic].config.nodenum), node))
|
|
||||||
{
|
|
||||||
inv_error = "Node number is invalid.\nValid numbers are in the format XX:XX:XX:XX:XX:XX";
|
|
||||||
inv_window = windows.nic_node;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void init_windows() {
|
|
||||||
INITCOMMONCONTROLSEX common_controls;
|
|
||||||
common_controls.dwSize = sizeof(common_controls);
|
|
||||||
common_controls.dwICC = ICC_LISTVIEW_CLASSES;
|
|
||||||
|
|
||||||
if(!InitCommonControlsEx(&common_controls)) {
|
|
||||||
die("Failed to initialise common controls");
|
|
||||||
}
|
|
||||||
|
|
||||||
WNDCLASSEX wclass;
|
|
||||||
wclass.cbSize = sizeof(wclass);
|
|
||||||
wclass.style = 0;
|
|
||||||
wclass.lpfnWndProc = &main_wproc;
|
|
||||||
wclass.cbClsExtra = 0;
|
|
||||||
wclass.cbWndExtra = 0;
|
|
||||||
wclass.hInstance = GetModuleHandle(NULL);
|
|
||||||
wclass.hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(50), IMAGE_ICON, 32, 32, LR_SHARED);
|
|
||||||
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
||||||
wclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
|
|
||||||
wclass.lpszMenuName = NULL;
|
|
||||||
wclass.lpszClassName = "ipxconfig_class";
|
|
||||||
wclass.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(50), IMAGE_ICON, 16, 16, LR_SHARED);
|
|
||||||
|
|
||||||
if(!RegisterClassEx(&wclass)) {
|
|
||||||
die("Failed to register ipxconfig_class: " + w32_errmsg(GetLastError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
windows.main = CreateWindow(
|
|
||||||
"ipxconfig_class",
|
|
||||||
"IPXWrapper configuration",
|
"IPXWrapper configuration",
|
||||||
WS_TILEDWINDOW,
|
WS_TILEDWINDOW,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||||
@ -480,137 +544,225 @@ static void init_windows() {
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!windows.main) {
|
if(!wh.main)
|
||||||
die("Failed to create main window: " + w32_errmsg(GetLastError()));
|
{
|
||||||
|
die("Could not create main window: " + w32_errmsg(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
windows.primary_group = create_group(windows.main, 0, 0, 400, 50, "Primary interface");
|
/* +- Primary interface -------------------------------------+
|
||||||
|
* | | Default |▼| |
|
||||||
|
* +---------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
int text_h = get_text_height(windows.primary_group);
|
wh.box_primary = create_GroupBox(wh.main, "Primary interface");
|
||||||
|
|
||||||
windows.primary = create_child(windows.primary_group, 10, text_h, 380, 300, WC_COMBOBOX, NULL, CBS_DROPDOWNLIST | CBS_HASSTRINGS, 0, ID_PRI_LIST);
|
wh.primary = create_child(wh.box_primary, WC_COMBOBOX, NULL, CBS_DROPDOWNLIST | CBS_HASSTRINGS, 0);
|
||||||
init_pri_list();
|
|
||||||
|
/* +- Network adapters --------------------------------------+
|
||||||
|
* | +-----------------------------------------------------+ |
|
||||||
|
* | | ... | |
|
||||||
|
* | | ... | |
|
||||||
|
* | | ... | |
|
||||||
|
* | +-----------------------------------------------------+ |
|
||||||
|
* | □ Enable interface |
|
||||||
|
* | Network number | AA:BB:CC:DD | |
|
||||||
|
* | Node number | AA:BB:CC:DD:EE:FF | |
|
||||||
|
* +---------------------------------------------------------+
|
||||||
|
*/
|
||||||
|
|
||||||
{
|
{
|
||||||
windows.nic_group = create_group(windows.main, 0, 0, 0, 0, "Network adapters");
|
wh.box_nic = create_GroupBox(wh.main, "Network adapters");
|
||||||
|
|
||||||
windows.nic_list = create_child(windows.nic_group, 0, 0, 0, 0, WC_LISTVIEW, NULL, LVS_SINGLESEL | LVS_REPORT | WS_TABSTOP | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE, ID_NIC_LIST);
|
wh.nic_list = create_child(wh.box_nic, WC_LISTVIEW, NULL, LVS_SINGLESEL | LVS_REPORT | WS_TABSTOP | LVS_NOCOLUMNHEADER | LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE, ID_NIC_LIST);
|
||||||
//ListView_SetExtendedListViewStyle(windows.nic_list, LVS_EX_FULLROWSELECT);
|
|
||||||
|
|
||||||
LVCOLUMN lvc;
|
LVCOLUMN lvc;
|
||||||
lvc.mask = LVCF_FMT;
|
lvc.mask = LVCF_FMT;
|
||||||
lvc.fmt = LVCFMT_LEFT;
|
lvc.fmt = LVCFMT_LEFT;
|
||||||
|
|
||||||
ListView_InsertColumn(windows.nic_list, 0, &lvc);
|
ListView_InsertColumn(wh.nic_list, 0, &lvc);
|
||||||
|
|
||||||
LVITEM lvi;
|
wh.nic_enabled = create_checkbox(wh.box_nic, "Enable interface", ID_NIC_ENABLED);
|
||||||
|
|
||||||
lvi.mask = LVIF_TEXT | LVIF_STATE;
|
wh.nic_net_lbl = create_STATIC(wh.box_nic, "Network number");
|
||||||
lvi.iItem = 0;
|
wh.nic_net = create_child(wh.box_nic, "EDIT", "", WS_TABSTOP, WS_EX_CLIENTEDGE, ID_NIC_NET);
|
||||||
lvi.iSubItem = 0;
|
|
||||||
lvi.state = 0;
|
|
||||||
lvi.stateMask = 0;
|
|
||||||
|
|
||||||
for(iface_list::iterator i = nics.begin(); i != nics.end(); i++) {
|
wh.nic_node_lbl = create_STATIC(wh.box_nic, "Node number");
|
||||||
lvi.pszText = i->name;
|
wh.nic_node = create_child(wh.box_nic, "EDIT", "", WS_TABSTOP, WS_EX_CLIENTEDGE, ID_NIC_NODE);
|
||||||
|
|
||||||
ListView_InsertItem(windows.nic_list, &lvi);
|
|
||||||
lvi.iItem++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView_SetColumnWidth(windows.nic_list, 0, LVSCW_AUTOSIZE);
|
/* +- Options -----------------------------------------------+
|
||||||
|
* | Broadcast port | 54792 | |
|
||||||
windows.nic_enabled = create_child(windows.nic_group, 0, 0, 0, 0, "BUTTON", "Enable interface", BS_AUTOCHECKBOX | WS_TABSTOP, 0, ID_NIC_ENABLED);
|
* | □ Enable Windows 95 SO_BROADCAST bug |
|
||||||
|
* | □ Log debugging messages |
|
||||||
windows.nic_net_lbl = create_child(windows.nic_group, 0, 0, 0, 0, "STATIC", "Network number", SS_RIGHT);
|
* | □ Log WinSock API calls |
|
||||||
windows.nic_net = create_child(windows.nic_group, 0, 0, 0, 0, "EDIT", "", WS_TABSTOP, WS_EX_CLIENTEDGE, ID_NIC_NET);
|
* | □ Automatically create Windows Firewall exceptions |
|
||||||
|
* | □ Send and receive real IPX packets |
|
||||||
windows.nic_node_lbl = create_child(windows.nic_group, 0, 0, 0, 0, "STATIC", "Node number", SS_RIGHT);
|
* +---------------------------------------------------------+
|
||||||
windows.nic_node = create_child(windows.nic_group, 0, 0, 0, 0, "EDIT", "", WS_TABSTOP, WS_EX_CLIENTEDGE, ID_NIC_NODE);
|
*/
|
||||||
|
|
||||||
update_nic_conf();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
windows.opt_group = create_group(windows.main, 0, 0, 0, 0, "Options");
|
wh.box_options = create_GroupBox(wh.main, "Options");
|
||||||
|
|
||||||
windows.opt_port_lbl = create_child(windows.opt_group, 0, 0, 0, 0, "STATIC", "Broadcast port", SS_RIGHT);
|
wh.opt_port_lbl = create_STATIC(wh.box_options, "Broadcast port");
|
||||||
windows.opt_port = create_child(windows.opt_group, 0, 0, 0, 0, "EDIT", "", WS_TABSTOP, WS_EX_CLIENTEDGE, ID_OPT_PORT);
|
wh.opt_port = create_child(wh.box_options, "EDIT", "", WS_TABSTOP, WS_EX_CLIENTEDGE, ID_OPT_PORT);
|
||||||
|
|
||||||
char port_s[8];
|
char port_s[8];
|
||||||
|
|
||||||
sprintf(port_s, "%hu", main_config.udp_port);
|
sprintf(port_s, "%hu", main_config.udp_port);
|
||||||
SetWindowText(windows.opt_port, port_s);
|
SetWindowText(wh.opt_port, port_s);
|
||||||
|
|
||||||
windows.opt_w95 = create_child(windows.opt_group, 0, 0, 0, 0, "BUTTON", "Enable Windows 95 SO_BROADCAST bug", BS_AUTOCHECKBOX | WS_TABSTOP, 0, ID_OPT_W95);
|
wh.opt_w95 = create_checkbox(wh.box_options, "Enable Windows 95 SO_BROADCAST bug", ID_OPT_W95);
|
||||||
windows.opt_log_debug = create_child(windows.opt_group, 0, 0, 0, 0, "BUTTON", "Log debugging messages", BS_AUTOCHECKBOX | WS_TABSTOP, 0, ID_OPT_LOG_DEBUG);
|
wh.opt_log_debug = create_checkbox(wh.box_options, "Log debugging messages", ID_OPT_LOG_DEBUG);
|
||||||
windows.opt_log_trace = create_child(windows.opt_group, 0, 0, 0, 0, "BUTTON", "Log WinSock API calls", BS_AUTOCHECKBOX | WS_TABSTOP, 0, ID_OPT_LOG_TRACE);
|
wh.opt_log_trace = create_checkbox(wh.box_options, "Log WinSock API calls", ID_OPT_LOG_TRACE);
|
||||||
windows.opt_fw_except = create_child(windows.opt_group, 0, 0, 0, 0, "BUTTON", "Automatically create Windows Firewall exceptions", BS_AUTOCHECKBOX | WS_TABSTOP, 0, ID_OPT_FW_EXCEPT);
|
wh.opt_fw_except = create_checkbox(wh.box_options, "Automatically create Windows Firewall exceptions", ID_OPT_FW_EXCEPT);
|
||||||
|
wh.opt_use_pcap = create_checkbox(wh.box_options, "Send and receive real IPX packets", ID_OPT_USE_PCAP);
|
||||||
|
|
||||||
Button_SetCheck(windows.opt_w95, main_config.w95_bug ? BST_CHECKED : BST_UNCHECKED);
|
set_checkbox(wh.opt_w95, main_config.w95_bug);
|
||||||
Button_SetCheck(windows.opt_log_debug, main_config.log_level <= LOG_DEBUG ? BST_CHECKED : BST_UNCHECKED);
|
set_checkbox(wh.opt_log_debug, main_config.log_level <= LOG_DEBUG);
|
||||||
Button_SetCheck(windows.opt_log_trace, main_config.log_level <= LOG_CALL ? BST_CHECKED : BST_UNCHECKED);
|
set_checkbox(wh.opt_log_trace, main_config.log_level <= LOG_CALL);
|
||||||
Button_SetCheck(windows.opt_fw_except, main_config.fw_except ? BST_CHECKED : BST_UNCHECKED);
|
set_checkbox(wh.opt_fw_except, main_config.fw_except);
|
||||||
|
set_checkbox(wh.opt_use_pcap, main_config.use_pcap);
|
||||||
|
|
||||||
EnableWindow(windows.opt_log_trace, Button_GetCheck(windows.opt_log_debug) == BST_CHECKED);
|
EnableWindow(wh.opt_use_pcap, PCAP_INSTALLED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Size buttons dynamically */
|
wh.ok_btn = create_child(wh.main, "BUTTON", "OK", BS_PUSHBUTTON | WS_TABSTOP, 0, ID_OK);
|
||||||
int btn_w = 75;
|
wh.can_btn = create_child(wh.main, "BUTTON", "Cancel", BS_PUSHBUTTON | WS_TABSTOP, 0, ID_CANCEL);
|
||||||
int btn_h = 23;
|
wh.app_btn = create_child(wh.main, "BUTTON", "Apply", BS_PUSHBUTTON | WS_TABSTOP, 0, ID_APPLY);
|
||||||
|
|
||||||
windows.ok_btn = create_child(windows.main, 0, 0, btn_w, btn_h, "BUTTON", "OK", BS_PUSHBUTTON | WS_TABSTOP, 0, ID_OK);
|
reload_nics();
|
||||||
windows.can_btn = create_child(windows.main, 0, 0, btn_w, btn_h, "BUTTON", "Cancel", BS_PUSHBUTTON | WS_TABSTOP, 0, ID_CANCEL);
|
|
||||||
windows.app_btn = create_child(windows.main, 0, 0, btn_w, btn_h, "BUTTON", "Apply", BS_PUSHBUTTON | WS_TABSTOP, 0, ID_APPLY);
|
|
||||||
|
|
||||||
ShowWindow(windows.main, SW_SHOW);
|
ShowWindow(wh.main, SW_SHOW);
|
||||||
UpdateWindow(windows.main);
|
UpdateWindow(wh.main);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_nic_conf() {
|
/* Reset the NIC network/node numbers and toggle the enabled state of controls
|
||||||
int selected_nic = ListView_GetNextItem(windows.nic_list, (LPARAM)-1, LVNI_FOCUSED);
|
* on the UI. Called when the selected NIC changes and when some options are
|
||||||
bool enabled = selected_nic >= 0 ? nics[selected_nic].config.enabled : false;
|
* toggled.
|
||||||
|
*/
|
||||||
|
static void main_window_update()
|
||||||
|
{
|
||||||
|
int selected_nic = ListView_GetNextItem(wh.nic_list, (LPARAM)(-1), LVNI_FOCUSED);
|
||||||
|
|
||||||
EnableWindow(windows.nic_net, enabled);
|
bool nic_enabled = selected_nic >= 0
|
||||||
EnableWindow(windows.nic_node, enabled);
|
? nics[selected_nic].config.enabled
|
||||||
EnableWindow(windows.nic_enabled, selected_nic >= 0);
|
: false;
|
||||||
|
|
||||||
|
EnableWindow(wh.nic_enabled, selected_nic >= 0);
|
||||||
|
EnableWindow(wh.nic_net, nic_enabled);
|
||||||
|
EnableWindow(wh.nic_node, nic_enabled && !main_config.use_pcap);
|
||||||
|
|
||||||
if(selected_nic >= 0)
|
if(selected_nic >= 0)
|
||||||
{
|
{
|
||||||
Button_SetCheck(windows.nic_enabled, enabled ? BST_CHECKED : BST_UNCHECKED);
|
set_checkbox(wh.nic_enabled, nic_enabled);
|
||||||
|
|
||||||
char net_s[ADDR32_STRING_SIZE];
|
char net_s[ADDR32_STRING_SIZE];
|
||||||
addr32_string(net_s, nics[selected_nic].config.netnum);
|
addr32_string(net_s, nics[selected_nic].config.netnum);
|
||||||
|
|
||||||
char node_s[ADDR48_STRING_SIZE];
|
char node_s[ADDR48_STRING_SIZE];
|
||||||
addr48_string(node_s, nics[selected_nic].config.nodenum);
|
addr48_string(node_s, (main_config.use_pcap
|
||||||
|
? nics[selected_nic].hwaddr
|
||||||
|
: nics[selected_nic].config.nodenum));
|
||||||
|
|
||||||
SetWindowText(windows.nic_net, net_s);
|
SetWindowText(wh.nic_net, net_s);
|
||||||
SetWindowText(windows.nic_node, node_s);
|
SetWindowText(wh.nic_node, node_s);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_pri_list() {
|
EnableWindow(wh.opt_port, !main_config.use_pcap);
|
||||||
ComboBox_ResetContent(windows.primary);
|
EnableWindow(wh.opt_log_trace, get_checkbox(wh.opt_log_debug));
|
||||||
|
}
|
||||||
|
|
||||||
ComboBox_AddString(windows.primary, "Default");
|
/* Update the size and position of everything within the window. */
|
||||||
ComboBox_SetCurSel(windows.primary, 0);
|
static void main_window_resize(int width, int height)
|
||||||
|
|
||||||
for(iface_list::iterator i = nics.begin(); i != nics.end(); i++)
|
|
||||||
{
|
{
|
||||||
if(i->config.enabled)
|
int edge = GetSystemMetrics(SM_CYEDGE);
|
||||||
{
|
int text_h = get_text_height(wh.box_primary);
|
||||||
int index = ComboBox_AddString(windows.primary, i->name);
|
int edit_h = text_h + 2 * edge;
|
||||||
|
int lbl_w = get_text_width(wh.nic_net_lbl, "Network number");
|
||||||
|
|
||||||
if(i->hwaddr == primary_iface)
|
/* Primary interface
|
||||||
{
|
* Height is constant. Vertical position is at the very top.
|
||||||
ComboBox_SetCurSel(windows.primary, index);
|
*/
|
||||||
}
|
|
||||||
}
|
int pri_h = edit_h + text_h + 10;
|
||||||
}
|
|
||||||
|
MoveWindow(wh.box_primary, 0, 0, width, pri_h, TRUE);
|
||||||
|
MoveWindow(wh.primary, 10, text_h, width - 20, height, TRUE);
|
||||||
|
|
||||||
|
/* Buttons
|
||||||
|
* Height is constant. Vertical position is at the very bottom.
|
||||||
|
*
|
||||||
|
* TODO: Dynamic button sizing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int btn_w = 75;
|
||||||
|
int btn_h = 23;
|
||||||
|
|
||||||
|
MoveWindow(wh.app_btn, width - btn_w - 6, height - btn_h - 6, btn_w, btn_h, TRUE);
|
||||||
|
MoveWindow(wh.can_btn, width - btn_w * 2 - 12, height - btn_h - 6, btn_w, btn_h, TRUE);
|
||||||
|
MoveWindow(wh.ok_btn, width - btn_w * 3 - 18, height - btn_h - 6, btn_w, btn_h, TRUE);
|
||||||
|
|
||||||
|
/* Options
|
||||||
|
* Height is constant. Vertical position is above buttons.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int box_options_y = text_h;
|
||||||
|
|
||||||
|
int port_w = get_text_width(wh.nic_node, "000000");
|
||||||
|
|
||||||
|
MoveWindow(wh.opt_port_lbl, 10, box_options_y + edge, lbl_w, text_h, TRUE);
|
||||||
|
MoveWindow(wh.opt_port, 15 + lbl_w, box_options_y, port_w, edit_h, TRUE);
|
||||||
|
box_options_y += edit_h + 4;
|
||||||
|
|
||||||
|
MoveWindow(wh.opt_w95, 10, box_options_y, width - 20, text_h, TRUE);
|
||||||
|
box_options_y += text_h + 2;
|
||||||
|
|
||||||
|
MoveWindow(wh.opt_log_debug, 10, box_options_y, width - 20, text_h, TRUE);
|
||||||
|
box_options_y += text_h + 2;
|
||||||
|
|
||||||
|
MoveWindow(wh.opt_log_trace, 10, box_options_y, width - 20, text_h, TRUE);
|
||||||
|
box_options_y += text_h + 2;
|
||||||
|
|
||||||
|
MoveWindow(wh.opt_fw_except, 10, box_options_y, width - 20, text_h, TRUE);
|
||||||
|
box_options_y += text_h + 2;
|
||||||
|
|
||||||
|
MoveWindow(wh.opt_use_pcap, 10, box_options_y, width - 20, text_h, TRUE);
|
||||||
|
box_options_y += text_h + 2;
|
||||||
|
|
||||||
|
int box_options_h = box_options_y + 2;
|
||||||
|
|
||||||
|
MoveWindow(wh.box_options, 0, height - box_options_y - btn_h - 12, width, box_options_h, TRUE);
|
||||||
|
|
||||||
|
/* NICs
|
||||||
|
* Fills available space between primary interface and options.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int node_w = get_text_width(wh.nic_node, "00:00:00:00:00:00");
|
||||||
|
int box_nic_h = height - pri_h - box_options_h - btn_h - 12;
|
||||||
|
|
||||||
|
MoveWindow(wh.box_nic, 0, pri_h, width, box_nic_h, TRUE);
|
||||||
|
|
||||||
|
int box_nic_y = box_nic_h - 4;
|
||||||
|
|
||||||
|
box_nic_y -= edit_h + 2;
|
||||||
|
MoveWindow(wh.nic_node_lbl, 10, box_nic_y + edge, lbl_w, text_h, TRUE);
|
||||||
|
MoveWindow(wh.nic_node, 15 + lbl_w, box_nic_y, node_w, edit_h, TRUE);
|
||||||
|
|
||||||
|
box_nic_y -= edit_h + 2;
|
||||||
|
MoveWindow(wh.nic_net_lbl, 10, box_nic_y + edge, lbl_w, text_h, TRUE);
|
||||||
|
MoveWindow(wh.nic_net, 15 + lbl_w, box_nic_y, node_w, edit_h, TRUE);
|
||||||
|
|
||||||
|
box_nic_y -= edit_h + 2;
|
||||||
|
MoveWindow(wh.nic_enabled, 10, box_nic_y, width - 20, text_h, TRUE);
|
||||||
|
|
||||||
|
box_nic_y -= 6;
|
||||||
|
MoveWindow(wh.nic_list, 10, text_h, width - 20, box_nic_y - text_h, TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
UpdateWindow(wh.main);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HWND create_child(HWND parent, int x, int y, int w, int h, LPCTSTR class_name, LPCTSTR title, DWORD style, DWORD ex_style, unsigned int id) {
|
static HWND create_child(HWND parent, LPCTSTR class_name, LPCTSTR title, DWORD style, DWORD ex_style, unsigned int id) {
|
||||||
static unsigned int idnum = 100;
|
static unsigned int idnum = 100;
|
||||||
|
|
||||||
HWND hwnd = CreateWindowEx(
|
HWND hwnd = CreateWindowEx(
|
||||||
@ -618,15 +770,16 @@ static HWND create_child(HWND parent, int x, int y, int w, int h, LPCTSTR class_
|
|||||||
class_name,
|
class_name,
|
||||||
title,
|
title,
|
||||||
WS_CHILD | WS_VISIBLE | style,
|
WS_CHILD | WS_VISIBLE | style,
|
||||||
x, y, w, h,
|
0, 0, 0, 0,
|
||||||
parent,
|
parent,
|
||||||
(HMENU)(id ? id : idnum++),
|
(HMENU)(id ? id : idnum++),
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!hwnd) {
|
if(!hwnd)
|
||||||
die(std::string("Failed to create child window (") + class_name + "): " + w32_errmsg(GetLastError()));
|
{
|
||||||
|
die(std::string("Could not create ") + class_name + " window: " + w32_errmsg(GetLastError()));
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
|
SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
|
||||||
@ -634,13 +787,34 @@ static HWND create_child(HWND parent, int x, int y, int w, int h, LPCTSTR class_
|
|||||||
return hwnd;
|
return hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HWND create_group(HWND parent, int x, int y, int w, int h, LPCTSTR title) {
|
static HWND create_GroupBox(HWND parent, LPCTSTR title)
|
||||||
HWND groupbox = create_child(parent, x, y, w, h, "BUTTON", title, BS_GROUPBOX);
|
{
|
||||||
|
HWND groupbox = create_child(parent, "BUTTON", title, BS_GROUPBOX);
|
||||||
default_groupbox_wproc = (wproc_fptr)SetWindowLongPtr(groupbox, GWLP_WNDPROC, (LONG_PTR)&groupbox_wproc);
|
default_groupbox_wproc = (wproc_fptr)SetWindowLongPtr(groupbox, GWLP_WNDPROC, (LONG_PTR)&groupbox_wproc);
|
||||||
|
|
||||||
return groupbox;
|
return groupbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HWND create_STATIC(HWND parent, LPCTSTR text)
|
||||||
|
{
|
||||||
|
return create_child(parent, "STATIC", text, SS_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HWND create_checkbox(HWND parent, LPCTSTR label, int id)
|
||||||
|
{
|
||||||
|
return create_child(parent, "BUTTON", label, BS_AUTOCHECKBOX | WS_TABSTOP, 0, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool get_checkbox(HWND checkbox)
|
||||||
|
{
|
||||||
|
return Button_GetCheck(checkbox) == BST_CHECKED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_checkbox(HWND checkbox, bool state)
|
||||||
|
{
|
||||||
|
Button_SetCheck(checkbox, (state ? BST_CHECKED : BST_UNCHECKED));
|
||||||
|
}
|
||||||
|
|
||||||
static int get_text_width(HWND hwnd, const char *txt) {
|
static int get_text_width(HWND hwnd, const char *txt) {
|
||||||
HDC dc = GetDC(hwnd);
|
HDC dc = GetDC(hwnd);
|
||||||
if(!dc) {
|
if(!dc) {
|
||||||
@ -673,16 +847,6 @@ static int get_text_height(HWND hwnd) {
|
|||||||
return tm.tmHeight;
|
return tm.tmHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RECT get_window_rect(HWND hwnd) {
|
|
||||||
RECT rect;
|
|
||||||
|
|
||||||
if(!GetWindowRect(hwnd, &rect)) {
|
|
||||||
die("GetWindowRect failed: " + w32_errmsg(GetLastError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert a win32 error number to a message */
|
/* Convert a win32 error number to a message */
|
||||||
static std::string w32_errmsg(DWORD errnum) {
|
static std::string w32_errmsg(DWORD errnum) {
|
||||||
char buf[256] = {'\0'};
|
char buf[256] = {'\0'};
|
||||||
@ -697,6 +861,21 @@ static void die(std::string msg) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if WinPcap is installed.
|
||||||
|
* Returns true if wpcap.dll can be loaded.
|
||||||
|
*/
|
||||||
|
static bool _pcap_installed()
|
||||||
|
{
|
||||||
|
HMODULE wpcap = LoadLibrary("wpcap.dll");
|
||||||
|
if(wpcap)
|
||||||
|
{
|
||||||
|
FreeLibrary(wpcap);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Used to display errors from shared functions. */
|
/* Used to display errors from shared functions. */
|
||||||
extern "C" void log_printf(enum ipx_log_level level, const char *fmt, ...)
|
extern "C" void log_printf(enum ipx_log_level level, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
@ -82,6 +82,7 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res)
|
|||||||
|
|
||||||
main_config = get_main_config();
|
main_config = get_main_config();
|
||||||
min_log_level = main_config.log_level;
|
min_log_level = main_config.log_level;
|
||||||
|
ipx_use_pcap = main_config.use_pcap;
|
||||||
|
|
||||||
if(main_config.fw_except)
|
if(main_config.fw_except)
|
||||||
{
|
{
|
||||||
@ -89,7 +90,6 @@ BOOL WINAPI DllMain(HINSTANCE me, DWORD why, LPVOID res)
|
|||||||
add_self_to_firewall();
|
add_self_to_firewall();
|
||||||
}
|
}
|
||||||
|
|
||||||
ipx_use_pcap = FALSE;
|
|
||||||
addr_cache_init();
|
addr_cache_init();
|
||||||
|
|
||||||
ipx_interfaces_init();
|
ipx_interfaces_init();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user