#include "nssm.h"\r
\r
-static enum { NSSM_TAB_APPLICATION, NSSM_TAB_DETAILS, NSSM_TAB_LOGON, NSSM_TAB_DEPENDENCIES, NSSM_TAB_PROCESS, NSSM_TAB_SHUTDOWN, NSSM_TAB_EXIT, NSSM_TAB_IO, NSSM_TAB_ROTATION, NSSM_TAB_ENVIRONMENT, NSSM_NUM_TABS };\r
+static enum { NSSM_TAB_APPLICATION, NSSM_TAB_DETAILS, NSSM_TAB_LOGON, NSSM_TAB_DEPENDENCIES, NSSM_TAB_PROCESS, NSSM_TAB_SHUTDOWN, NSSM_TAB_EXIT, NSSM_TAB_IO, NSSM_TAB_ROTATION, NSSM_TAB_ENVIRONMENT, NSSM_TAB_HOOKS, NSSM_NUM_TABS } nssm_tabs;\r
static HWND tablist[NSSM_NUM_TABS];\r
+static const TCHAR *hook_event_strings[] = { NSSM_HOOK_EVENT_START, NSSM_HOOK_EVENT_STOP, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_EVENT_ROTATE, NULL };\r
+static const TCHAR *hook_action_strings[] = { NSSM_HOOK_ACTION_PRE, NSSM_HOOK_ACTION_POST, NSSM_HOOK_ACTION_CHANGE, NSSM_HOOK_ACTION_RESUME, NULL };\r
static int selected_tab;\r
\r
static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function, LPARAM l) {\r
if (! (service->stop_method & NSSM_STOP_METHOD_TERMINATE)) {\r
SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_UNCHECKED, 0);\r
}\r
+ if (! service->kill_process_tree) {\r
+ SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_UNCHECKED, 0);\r
+ }\r
\r
/* Restart tab. */\r
SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, service->throttle_delay, 0);\r
SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);\r
if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);\r
\r
+ /* Hooks tab. */\r
+ if (service->hook_share_output_handles) SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_CHECKED, 0);\r
+\r
/* Check if advanced settings are in use. */\r
if (service->stdout_disposition != service->stderr_disposition || (service->stdout_disposition && service->stdout_disposition != NSSM_STDOUT_DISPOSITION && service->stdout_disposition != CREATE_ALWAYS) || (service->stderr_disposition && service->stderr_disposition != NSSM_STDERR_DISPOSITION && service->stderr_disposition != CREATE_ALWAYS)) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_STDIO);\r
if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);\r
EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);\r
}\r
\r
+static inline int hook_env(const TCHAR *hook_event, const TCHAR *hook_action, TCHAR *buffer, unsigned long buflen) {\r
+ return _sntprintf_s(buffer, buflen, _TRUNCATE, _T("NSSM_HOOK_%s_%s"), hook_event, hook_action);\r
+}\r
+\r
+static inline void set_hook_tab(int event_index, int action_index, bool changed) {\r
+ int first_event = NSSM_GUI_HOOK_EVENT_START;\r
+ HWND combo;\r
+ combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);\r
+ SendMessage(combo, CB_SETCURSEL, event_index, 0);\r
+ combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_ACTION);\r
+ SendMessage(combo, CB_RESETCONTENT, 0, 0);\r
+\r
+ const TCHAR *hook_event = hook_event_strings[event_index];\r
+ TCHAR *hook_action;\r
+ int i;\r
+ switch (event_index + first_event) {\r
+ case NSSM_GUI_HOOK_EVENT_ROTATE:\r
+ i = 0;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_PRE));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_POST));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;\r
+ break;\r
+\r
+ case NSSM_GUI_HOOK_EVENT_START:\r
+ i = 0;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_PRE));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_POST));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;\r
+ break;\r
+\r
+ case NSSM_GUI_HOOK_EVENT_STOP:\r
+ i = 0;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_STOP_PRE));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;\r
+ break;\r
+\r
+ case NSSM_GUI_HOOK_EVENT_EXIT:\r
+ i = 0;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_EXIT_POST));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;\r
+ break;\r
+\r
+ case NSSM_GUI_HOOK_EVENT_POWER:\r
+ i = 0;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_CHANGE));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_CHANGE;\r
+ SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_RESUME));\r
+ if (action_index == i++) hook_action = NSSM_HOOK_ACTION_RESUME;\r
+ break;\r
+ }\r
+\r
+ SendMessage(combo, CB_SETCURSEL, action_index, 0);\r
+\r
+ TCHAR hook_name[HOOK_NAME_LENGTH];\r
+ hook_env(hook_event, hook_action, hook_name, _countof(hook_name));\r
+\r
+ if (! *hook_name) return;\r
+\r
+ TCHAR cmd[CMD_LENGTH];\r
+ if (changed) {\r
+ GetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd, _countof(cmd));\r
+ SetEnvironmentVariable(hook_name, cmd);\r
+ }\r
+ else {\r
+ GetEnvironmentVariable(hook_name, cmd, _countof(cmd));\r
+ SetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd);\r
+ }\r
+}\r
+\r
+static inline int update_hook(TCHAR *service_name, const TCHAR *hook_event, const TCHAR *hook_action) {\r
+ TCHAR hook_name[HOOK_NAME_LENGTH];\r
+ if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) return 1;\r
+ TCHAR cmd[CMD_LENGTH];\r
+ ZeroMemory(cmd, sizeof(cmd));\r
+ GetEnvironmentVariable(hook_name, cmd, _countof(cmd));\r
+ if (set_hook(service_name, hook_event, hook_action, cmd)) return 2;\r
+ return 0;\r
+}\r
+\r
+static inline int update_hooks(TCHAR *service_name) {\r
+ int ret = 0;\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE);\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_POST);\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_STOP, NSSM_HOOK_ACTION_PRE);\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_ACTION_POST);\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_CHANGE);\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_RESUME);\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_PRE);\r
+ ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_POST);\r
+ return ret;\r
+}\r
+\r
static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {\r
if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;\r
if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;\r
service->username = 0;\r
service->usernamelen = 0;\r
if (service->password) {\r
- SecureZeroMemory(service->password, service->passwordlen);\r
+ SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));\r
HeapFree(GetProcessHeap(), 0, service->password);\r
}\r
service->password = 0;\r
/* Get first password. */\r
if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {\r
HeapFree(GetProcessHeap(), 0, password);\r
- SecureZeroMemory(service->password, service->passwordlen);\r
+ SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));\r
HeapFree(GetProcessHeap(), 0, service->password);\r
service->password = 0;\r
service->passwordlen = 0;\r
\r
/* Get confirmation. */\r
if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {\r
- SecureZeroMemory(password, service->passwordlen);\r
+ SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));\r
HeapFree(GetProcessHeap(), 0, password);\r
- SecureZeroMemory(service->password, service->passwordlen);\r
+ SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));\r
HeapFree(GetProcessHeap(), 0, service->password);\r
service->password = 0;\r
service->passwordlen = 0;\r
/* Compare. */\r
if (_tcsncmp(password, service->password, service->passwordlen)) {\r
popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);\r
- SecureZeroMemory(password, service->passwordlen);\r
+ SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));\r
HeapFree(GetProcessHeap(), 0, password);\r
- SecureZeroMemory(service->password, service->passwordlen);\r
+ SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));\r
HeapFree(GetProcessHeap(), 0, service->password);\r
service->password = 0;\r
service->passwordlen = 0;\r
check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);\r
check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);\r
check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);\r
+ if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->kill_process_tree = 1;\r
+ else service->kill_process_tree = 0;\r
\r
/* Get exit action stuff. */\r
check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);\r
check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);\r
}\r
\r
+ /* Get hook stuff. */\r
+ if (SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_GETCHECK, 0, 0) & BST_CHECKED) service->hook_share_output_handles = true;\r
+\r
/* Get environment. */\r
unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);\r
if (envlen) {\r
return 6;\r
}\r
\r
+ update_hooks(service->name);\r
+\r
popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);\r
cleanup_nssm_service(service);\r
return 0;\r
\r
case 3:\r
popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);\r
- return 3;\r
cleanup_nssm_service(service);\r
+ return 3;\r
\r
case 4:\r
popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);\r
return 6;\r
}\r
\r
+ update_hooks(service->name);\r
+\r
popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);\r
cleanup_nssm_service(service);\r
return 0;\r
else enabled = 0;\r
set_rotation_enabled(enabled);\r
break;\r
+\r
+ /* Hook event. */\r
+ case IDC_HOOK_EVENT:\r
+ if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), 0, false);\r
+ break;\r
+\r
+ /* Hook action. */\r
+ case IDC_HOOK_ACTION:\r
+ if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), (int) SendMessage(GetDlgItem(tab, IDC_HOOK_ACTION), CB_GETCURSEL, 0, 0), false);\r
+ break;\r
+\r
+ /* Browse for hook. */\r
+ case IDC_BROWSE_HOOK:\r
+ dlg = GetDlgItem(tab, IDC_HOOK);\r
+ GetDlgItemText(tab, IDC_HOOK, buffer, _countof(buffer));\r
+ browse(dlg, _T(""), OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);\r
+ break;\r
+\r
+ /* Hook. */\r
+ case IDC_HOOK:\r
+ set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), (int) SendMessage(GetDlgItem(tab, IDC_HOOK_ACTION), CB_GETCURSEL, 0, 0), true);\r
+ break;\r
}\r
return 1;\r
}\r
SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);\r
SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);\r
SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);\r
+ SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_CHECKED, 1);\r
\r
/* Restart tab. */\r
tab.pszText = message_string(NSSM_GUI_TAB_EXIT);\r
tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);\r
ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);\r
\r
+ /* Hooks tab. */\r
+ tab.pszText = message_string(NSSM_GUI_TAB_HOOKS);\r
+ tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;\r
+ SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_HOOKS, (LPARAM) &tab);\r
+ tablist[NSSM_TAB_HOOKS] = dialog(MAKEINTRESOURCE(IDD_HOOKS), window, tab_dlg);\r
+ ShowWindow(tablist[NSSM_TAB_HOOKS], SW_HIDE);\r
+\r
+ /* Set defaults. */\r
+ combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);\r
+ SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_START));\r
+ SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_STOP));\r
+ SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_EXIT));\r
+ SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_POWER));\r
+ SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_ROTATE));\r
+ SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_UNCHECKED, 0);\r
+ if (_tcslen(service->name)) {\r
+ TCHAR hook_name[HOOK_NAME_LENGTH];\r
+ TCHAR cmd[CMD_LENGTH];\r
+ for (i = 0; hook_event_strings[i]; i++) {\r
+ const TCHAR *hook_event = hook_event_strings[i];\r
+ int j;\r
+ for (j = 0; hook_action_strings[j]; j++) {\r
+ const TCHAR *hook_action = hook_action_strings[j];\r
+ if (! valid_hook_name(hook_event, hook_action, true)) continue;\r
+ if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) continue;\r
+ if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) continue;\r
+ SetEnvironmentVariable(hook_name, cmd);\r
+ }\r
+ }\r
+ }\r
+ set_hook_tab(0, 0, false);\r
+\r
return 1;\r
\r
/* Tab change. */\r