From 046572c44d388c80a03dddaf6438d2baa04fcb65 Mon Sep 17 00:00:00 2001 From: jagt Date: Sun, 15 Dec 2013 01:29:52 +0800 Subject: [PATCH] accept command line lauching options. example: --filter "outbund" --lag on --lag-time 5000; no docs yet. --- src/common.h | 17 ++++++++++++--- src/drop.c | 8 +++++++ src/duplicate.c | 9 ++++++++ src/elevate.c | 18 ++++++++++------ src/lag.c | 8 +++++++ src/main.c | 33 ++++++++++++++++++++++++---- src/ood.c | 8 +++++++ src/tamper.c | 9 ++++++++ src/throttle.c | 9 ++++++++ src/utils.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 161 insertions(+), 15 deletions(-) diff --git a/src/common.h b/src/common.h index a219d8e..37f0945 100644 --- a/src/common.h +++ b/src/common.h @@ -16,6 +16,10 @@ #define INTEGER_MAX "__INTEGER_MAX" #define INTEGER_MIN "__INTEGER_MIN" +// workaround stupid vs2012 runtime check. +// it would show even when seeing explicit "(short)(i);" +#define I2S(x) ((short)((x) & 0xFFFF)) + #ifdef __MINGW32__ #define INLINE_FUNCTION __inline__ @@ -87,7 +91,8 @@ typedef struct { /* * Static module data */ - const char *name; // name of the module + const char *displayName; // display name shown in ui + const char *shortName; // single word name short *enabledFlag; // volatile short flag to determine enabled or not Ihandle* (*setupUIFunc)(); // return hbox as controls group void (*startUp)(); // called when starting up the module @@ -150,7 +155,13 @@ void endTimePeriod(); // elevate BOOL IsElevated(); BOOL IsRunAsAdmin(); -BOOL tryElevate(HWND hWnd); +BOOL tryElevate(HWND hWnd, BOOL silent); // icons -extern const unsigned char icon8x8[8*8]; \ No newline at end of file +extern const unsigned char icon8x8[8*8]; + +// parameterized +extern BOOL parameterized; +void setFromParameter(Ihandle *ih, const char *field, const char *key); +BOOL parseArgs(int argc, char* argv[]); + diff --git a/src/drop.c b/src/drop.c index d5e5fec..1900be4 100644 --- a/src/drop.c +++ b/src/drop.c @@ -3,6 +3,7 @@ #include #include "iup.h" #include "common.h" +#define NAME "drop" static Ihandle *inboundCheckbox, *outboundCheckbox, *chanceInput; @@ -33,6 +34,12 @@ static Ihandle* dropSetupUI() { IupSetAttribute(inboundCheckbox, "VALUE", "ON"); IupSetAttribute(outboundCheckbox, "VALUE", "ON"); + if (parameterized) { + setFromParameter(inboundCheckbox, "VALUE", NAME"-inbound"); + setFromParameter(outboundCheckbox, "VALUE", NAME"-outbound"); + setFromParameter(chanceInput, "VALUE", NAME"-chance"); + } + return dropControlsBox; } @@ -68,6 +75,7 @@ static short dropProcess(PacketNode *head, PacketNode* tail) { Module dropModule = { "Drop", + NAME, (short*)&dropEnabled, dropSetupUI, dropStartUp, diff --git a/src/duplicate.c b/src/duplicate.c index 27b1bf3..a2da38c 100644 --- a/src/duplicate.c +++ b/src/duplicate.c @@ -2,6 +2,7 @@ #include #include "iup.h" #include "common.h" +#define NAME "duplicate" #define COPIES_MIN "2" #define COPIES_MAX "50" #define COPIES_COUNT 2 @@ -44,6 +45,13 @@ static Ihandle* dupSetupUI() { IupSetAttribute(inboundCheckbox, "VALUE", "ON"); IupSetAttribute(outboundCheckbox, "VALUE", "ON"); + if (parameterized) { + setFromParameter(inboundCheckbox, "VALUE", NAME"-inbound"); + setFromParameter(outboundCheckbox, "VALUE", NAME"-outbound"); + setFromParameter(chanceInput, "VALUE", NAME"-chance"); + setFromParameter(countInput, "VALUE", NAME"-count"); + } + return dupControlsBox; } @@ -78,6 +86,7 @@ static short dupProcess(PacketNode *head, PacketNode *tail) { Module dupModule = { "Duplicate", + NAME, (short*)&dupEnabled, dupSetupUI, dupStartup, diff --git a/src/elevate.c b/src/elevate.c index de562ad..3698c14 100644 --- a/src/elevate.c +++ b/src/elevate.c @@ -98,17 +98,18 @@ BOOL IsElevated( ) { } // try elevate and error out when can't happen +// is silent then no message boxes are shown // return whether to close the program -BOOL tryElevate(HWND hWnd) { +BOOL tryElevate(HWND hWnd, BOOL silent) { // Check the current process's "run as administrator" status. BOOL fIsRunAsAdmin; OSVERSIONINFO osver = {sizeof(osver)}; // MUST initialize with the size or GetVersionEx fails if (!GetVersionEx(&osver)) { - MessageBox(hWnd, (LPCSTR)"Failed to get os version. clumsy only supports Windows Vista or above.", + if (!silent) MessageBox(hWnd, (LPCSTR)"Failed to get os version. clumsy only supports Windows Vista or above.", (LPCSTR)"Aborting", MB_OK); return TRUE; } else if (osver.dwMajorVersion < 6) { - MessageBox(hWnd, (LPCSTR)"Unsupported Windows version. clumsy only supports Windows Vista or above.", + if (!silent) MessageBox(hWnd, (LPCSTR)"Unsupported Windows version. clumsy only supports Windows Vista or above.", (LPCSTR)"Aborting", MB_OK); return TRUE; } @@ -116,7 +117,10 @@ BOOL tryElevate(HWND hWnd) { fIsRunAsAdmin = IsRunAsAdmin(); if (fIsRunAsAdmin) { return FALSE; - } else { + } + + // when not silent then trying to reinvoke to elevate + if (!silent) { wchar_t szPath[MAX_PATH]; if (GetModuleFileName(NULL, (LPSTR)szPath, ARRAYSIZE(szPath))) { @@ -145,8 +149,8 @@ BOOL tryElevate(HWND hWnd) { MessageBox(hWnd, (LPCSTR)"Failed to get clumsy path. Please place the executable in a normal directory.", (LPCSTR)"Aborting", MB_OK); } - - // exit when not run as admin - return TRUE; } + + // exit when not run as admin + return TRUE; } \ No newline at end of file diff --git a/src/lag.c b/src/lag.c index 687602c..e4239f2 100644 --- a/src/lag.c +++ b/src/lag.c @@ -1,6 +1,7 @@ // lagging packets #include "iup.h" #include "common.h" +#define NAME "lag" #define LAG_MIN "0" #define LAG_MAX "3000" #define KEEP_AT_MOST 2000 @@ -50,6 +51,12 @@ static Ihandle *lagSetupUI() { IupSetAttribute(inboundCheckbox, "VALUE", "ON"); IupSetAttribute(outboundCheckbox, "VALUE", "ON"); + if (parameterized) { + setFromParameter(inboundCheckbox, "VALUE", NAME"-inbound"); + setFromParameter(outboundCheckbox, "VALUE", NAME"-outbound"); + setFromParameter(timeInput, "VALUE", NAME"-time"); + } + return lagControlsBox; } @@ -117,6 +124,7 @@ static short lagProcess(PacketNode *head, PacketNode *tail) { Module lagModule = { "Lag", + NAME, (short*)&lagEnabled, lagSetupUI, lagStartUp, diff --git a/src/main.c b/src/main.c index 3f8d0fa..31d845b 100644 --- a/src/main.c +++ b/src/main.c @@ -48,6 +48,7 @@ typedef struct { UINT filtersSize; filterRecord filters[CONFIG_MAX_RECORDS] = {0}; char configBuf[CONFIG_BUF_SIZE+2]; // add some padding to write \n +BOOL parameterized = 0; // parameterized flag, means reading args from command line // loading up filters and fill in void loadConfig() { @@ -147,6 +148,18 @@ void init(int argc, char* argv[]) { ) ); + // parse arguments and set globals *before* setting up UI. + // arguments can be read and set after callbacks are setup + // FIXME as Release is built as WindowedApp, stdout/stderr won't show + LOG("argc: %d", argc); + if (argc > 1) { + if (!parseArgs(argc, argv)) { + fprintf(stderr, "invalid argument count. ensure you're using options as \"--drop on\""); + exit(-1); // fail fast. + } + parameterized = 1; + } + IupSetAttribute(topFrame, "TITLE", "Filtering"); IupSetAttribute(topFrame, "EXPAND", "HORIZONTAL"); IupSetAttribute(filterText, "EXPAND", "HORIZONTAL"); @@ -228,6 +241,7 @@ void init(int argc, char* argv[]) { timer = IupTimer(); IupSetAttribute(timer, "TIME", STR(ICON_UPDATE_MS)); IupSetCallback(timer, "ACTION_CB", uiTimerCb); + } void startup() { @@ -267,7 +281,13 @@ static int uiOnDialogShow(Ihandle *ih, int state) { SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)icon); // try elevate and decides whether to exit - exit = tryElevate(hWnd); + exit = tryElevate(hWnd, parameterized); + if (!exit && parameterized) { + setFromParameter(filterText, "VALUE", "filter"); + LOG("is parameterized, start filtering upon execution."); + uiStartCb(filterButton); + } + return exit ? IUP_CLOSE : IUP_DEFAULT; } @@ -322,10 +342,10 @@ static int uiToggleControls(Ihandle *ih, int state) { int controlsActive = IupGetInt(controls, "ACTIVE"); if (controlsActive && !state) { IupSetAttribute(controls, "ACTIVE", "NO"); - InterlockedExchange16(target, (short)state); + InterlockedExchange16(target, I2S(state)); } else if (!controlsActive && state) { IupSetAttribute(controls, "ACTIVE", "YES"); - InterlockedExchange16(target, (short)state); + InterlockedExchange16(target, I2S(state)); } return IUP_DEFAULT; @@ -382,7 +402,7 @@ static void uiSetupModule(Module *module, Ihandle *parent) { Ihandle *groupBox, *toggle, *controls, *icon; groupBox = IupHbox( icon = IupLabel(NULL), - toggle = IupToggle(module->name, NULL), + toggle = IupToggle(module->displayName, NULL), IupFill(), controls = module->setupUIFunc(), NULL @@ -403,6 +423,11 @@ static void uiSetupModule(Module *module, Ihandle *parent) { IupSetAttribute(icon, "IMAGE", "none_icon"); IupSetAttribute(icon, "PADDING", "4x"); module->iconHandle = icon; + + // parameterize toggle + if (parameterized) { + setFromParameter(toggle, "VALUE", module->shortName); + } } int main(int argc, char* argv[]) { diff --git a/src/ood.c b/src/ood.c index cdbbe1a..8b616ca 100644 --- a/src/ood.c +++ b/src/ood.c @@ -1,6 +1,7 @@ // out of order arrange packets module #include "iup.h" #include "common.h" +#define NAME "ood" // keep a picked packet at most for KEEP_TURNS_MAX steps, or if there's no following // one it would just to be sended #define KEEP_TURNS_MAX 10 @@ -35,6 +36,12 @@ static Ihandle *oodSetupUI() { IupSetAttribute(inboundCheckbox, "VALUE", "ON"); IupSetAttribute(outboundCheckbox, "VALUE", "ON"); + if (parameterized) { + setFromParameter(inboundCheckbox, "VALUE", NAME"-inbound"); + setFromParameter(outboundCheckbox, "VALUE", NAME"-outbound"); + setFromParameter(chanceInput, "VALUE", NAME"-chance"); + } + return oodControlsBox; } @@ -134,6 +141,7 @@ static short oodProcess(PacketNode *head, PacketNode *tail) { Module oodModule = { "Out of order", + NAME, (short*)&oodEnabled, oodSetupUI, oodStartUp, diff --git a/src/tamper.c b/src/tamper.c index ae9e2d6..e36d9c4 100644 --- a/src/tamper.c +++ b/src/tamper.c @@ -2,6 +2,7 @@ #include "iup.h" #include "windivert.h" #include "common.h" +#define NAME "tamper" static Ihandle *inboundCheckbox, *outboundCheckbox, *chanceInput, *checksumCheckbox; @@ -38,6 +39,13 @@ static Ihandle* tamperSetupUI() { IupSetAttribute(outboundCheckbox, "VALUE", "ON"); IupSetAttribute(checksumCheckbox, "VALUE", "ON"); + if (parameterized) { + setFromParameter(inboundCheckbox, "VALUE", NAME"-inbound"); + setFromParameter(outboundCheckbox, "VALUE", NAME"-outbound"); + setFromParameter(chanceInput, "VALUE", NAME"-chance"); + setFromParameter(checksumCheckbox, "VALUE", NAME"-checksum"); + } + return dupControlsBox; } @@ -114,6 +122,7 @@ static short tamperProcess(PacketNode *head, PacketNode *tail) { Module tamperModule = { "Tamper", + NAME, (short*)&tamperEnabled, tamperSetupUI, tamperStartup, diff --git a/src/throttle.c b/src/throttle.c index ab5cac7..9c3c9ef 100644 --- a/src/throttle.c +++ b/src/throttle.c @@ -1,6 +1,7 @@ // throttling packets #include "iup.h" #include "common.h" +#define NAME "throttle" #define TIME_MIN "0" #define TIME_MAX "1000" #define TIME_DEFAULT 30 @@ -58,6 +59,13 @@ static Ihandle *throttleSetupUI() { IupSetAttribute(inboundCheckbox, "VALUE", "ON"); IupSetAttribute(outboundCheckbox, "VALUE", "ON"); + if (parameterized) { + setFromParameter(inboundCheckbox, "VALUE", NAME"-inbound"); + setFromParameter(outboundCheckbox, "VALUE", NAME"-outbound"); + setFromParameter(chanceInput, "VALUE", NAME"-chance"); + setFromParameter(frameInput, "VALUE", NAME"-frame"); + } + return throttleControlsBox; } @@ -129,6 +137,7 @@ static short throttleProcess(PacketNode *head, PacketNode *tail) { Module throttleModule = { "Throttle", + NAME, (short*)&throttleEnabled, throttleSetupUI, throttleStartUp, diff --git a/src/utils.c b/src/utils.c index c905d77..9682f33 100644 --- a/src/utils.c +++ b/src/utils.c @@ -49,7 +49,7 @@ int uiSyncChance(Ihandle *ih) { int uiSyncToggle(Ihandle *ih, int state) { short *togglePtr = (short*)IupGetAttribute(ih, SYNCED_VALUE); - InterlockedExchange16(togglePtr, (short)state); + InterlockedExchange16(togglePtr, I2S(state)); return IUP_DEFAULT; } @@ -88,3 +88,58 @@ const unsigned char icon8x8[8*8] = { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, }; + +typedef int (*IstateCallback)(Ihandle *ih, int state); +// parameterized setter +void setFromParameter(Ihandle *ih, const char *field, const char *key) { + char* val = IupGetGlobal(key); + Icallback cb; + IstateCallback scb; + // FIXME there should be a way to trigger handler + // manually trigger the callback, as iup won't call it + // Notice that currently only works on IupToggle, IupText + // and Iup lacks a way to get widget's type, so can't do much about this + if (val) { + IupSetAttribute(ih, field, val); + cb = IupGetCallback(ih, "VALUECHANGED_CB"); + if (cb) { + LOG("triggered VALUECHANGED_CB on key: %s", key); + cb(ih); + return; + } + // cb's argument type IS NOT ONLY Ihandle, receives a extra "state" int + scb = (IstateCallback)IupGetCallback(ih, "ACTION"); + if (scb) { + LOG("triggered ACTION on key: %s", key); + // IupGetInt handles yes/no on/off upper lower case things. + scb(ih, IupGetInt(ih, "VALUE")); + return; + } + } +} + +// parse arguments and set globals +// only checks for argument style, no extra validation is done +BOOL parseArgs(int argc, char* argv[]) { + int ix = 0; + char *key, *value; + // begin parsing "--key value" args. + // notice that quoted arg with spaces in between is already handled by shell + if (argc == 1) return 0; + for (;;) { + if (++ix >= argc) break; + key = argv[ix]; + if (key[0] != '-' || key[1] != '-' || key[2] == '\0') { + return 0; + } + key = &(key[2]); // skip "--" + if (++ix >= argc) { + return 0; + } + value = argv[ix]; + IupStoreGlobal(key, value); + LOG("option: %s : %s", key, value); + } + + return 1; +} \ No newline at end of file