3 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
4 static HWND tablist[NSSM_NUM_TABS];
\r
5 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
6 static const TCHAR *hook_action_strings[] = { NSSM_HOOK_ACTION_PRE, NSSM_HOOK_ACTION_POST, NSSM_HOOK_ACTION_CHANGE, NSSM_HOOK_ACTION_RESUME, NULL };
\r
7 static int selected_tab;
\r
9 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function, LPARAM l) {
\r
10 /* The caller will deal with GetLastError()... */
\r
11 HRSRC resource = FindResourceEx(0, RT_DIALOG, templ, GetUserDefaultLangID());
\r
13 if (GetLastError() != ERROR_RESOURCE_LANG_NOT_FOUND) return 0;
\r
14 resource = FindResourceEx(0, RT_DIALOG, templ, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
\r
15 if (! resource) return 0;
\r
18 HGLOBAL ret = LoadResource(0, resource);
\r
19 if (! ret) return 0;
\r
21 return CreateDialogIndirectParam(0, (DLGTEMPLATE *) ret, parent, function, l);
\r
24 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function) {
\r
25 return dialog(templ, parent, function, 0);
\r
28 int nssm_gui(int resource, nssm_service_t *service) {
\r
30 HWND dlg = dialog(MAKEINTRESOURCE(resource), 0, nssm_dlg, (LPARAM) service);
\r
32 popup_message(0, MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));
\r
36 /* Load the icon. */
\r
37 HANDLE icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
\r
38 if (icon) SendMessage(dlg, WM_SETICON, ICON_SMALL, (LPARAM) icon);
\r
39 icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
\r
40 if (icon) SendMessage(dlg, WM_SETICON, ICON_BIG, (LPARAM) icon);
\r
42 /* Remember what the window is for. */
\r
43 SetWindowLongPtr(dlg, GWLP_USERDATA, (LONG_PTR) resource);
\r
45 /* Display the window */
\r
47 ShowWindow(dlg, SW_SHOW);
\r
49 /* Set service name if given */
\r
50 if (service->name[0]) {
\r
51 SetDlgItemText(dlg, IDC_NAME, service->name);
\r
52 /* No point making user click remove if the name is already entered */
\r
53 if (resource == IDD_REMOVE) {
\r
54 HWND button = GetDlgItem(dlg, IDC_REMOVE);
\r
56 SendMessage(button, WM_LBUTTONDOWN, 0, 0);
\r
57 SendMessage(button, WM_LBUTTONUP, 0, 0);
\r
62 if (resource == IDD_EDIT) {
\r
63 /* We'll need the service handle later. */
\r
64 SetWindowLongPtr(dlg, DWLP_USER, (LONG_PTR) service);
\r
66 /* Service name can't be edited. */
\r
67 EnableWindow(GetDlgItem(dlg, IDC_NAME), 0);
\r
68 SetFocus(GetDlgItem(dlg, IDOK));
\r
70 /* Set existing details. */
\r
74 /* Application tab. */
\r
75 if (service->native) SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->image);
\r
76 else SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe);
\r
77 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir);
\r
78 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags);
\r
81 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname);
\r
82 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description);
\r
83 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
84 SendMessage(combo, CB_SETCURSEL, service->startup, 0);
\r
87 if (service->username) {
\r
88 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_ACCOUNT);
\r
89 SetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username);
\r
90 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), 0);
\r
91 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), 1);
\r
92 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), 1);
\r
93 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), 1);
\r
96 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
97 if (service->type & SERVICE_INTERACTIVE_PROCESS) SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_SETCHECK, BST_CHECKED, 0);
\r
100 /* Dependencies tab. */
\r
101 if (service->dependencieslen) {
\r
103 unsigned long newlen;
\r
104 if (format_double_null(service->dependencies, service->dependencieslen, &formatted, &newlen)) {
\r
105 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("nssm_dlg()"));
\r
108 SetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, formatted);
\r
109 HeapFree(GetProcessHeap(), 0, formatted);
\r
114 if (service->priority) {
\r
115 int priority = priority_constant_to_index(service->priority);
\r
116 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
117 SendMessage(combo, CB_SETCURSEL, priority, 0);
\r
120 if (service->affinity) {
\r
121 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
122 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
\r
123 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), 1);
\r
125 DWORD_PTR affinity, system_affinity;
\r
126 if (GetProcessAffinityMask(GetCurrentProcess(), &affinity, &system_affinity)) {
\r
127 if ((service->affinity & (__int64) system_affinity) != service->affinity) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_AFFINITY);
\r
130 for (int i = 0; i < num_cpus(); i++) {
\r
131 if (! (service->affinity & (1LL << (__int64) i))) SendMessage(list, LB_SETSEL, 0, i);
\r
135 if (service->no_console) {
\r
136 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
139 /* Shutdown tab. */
\r
140 if (! (service->stop_method & NSSM_STOP_METHOD_CONSOLE)) {
\r
141 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
142 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE), 0);
\r
144 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, service->kill_console_delay, 0);
\r
145 if (! (service->stop_method & NSSM_STOP_METHOD_WINDOW)) {
\r
146 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_UNCHECKED, 0);
\r
147 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW), 0);
\r
149 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, service->kill_window_delay, 0);
\r
150 if (! (service->stop_method & NSSM_STOP_METHOD_THREADS)) {
\r
151 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_UNCHECKED, 0);
\r
152 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS), 0);
\r
154 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, service->kill_threads_delay, 0);
\r
155 if (! (service->stop_method & NSSM_STOP_METHOD_TERMINATE)) {
\r
156 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
158 if (! service->kill_process_tree) {
\r
159 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
163 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, service->throttle_delay, 0);
\r
164 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
165 SendMessage(combo, CB_SETCURSEL, service->default_exit_action, 0);
\r
166 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, service->restart_delay, 0);
\r
169 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDIN, service->stdin_path);
\r
170 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDOUT, service->stdout_path);
\r
171 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDERR, service->stderr_path);
\r
173 /* Rotation tab. */
\r
174 if (service->stdout_disposition == CREATE_ALWAYS) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_SETCHECK, BST_CHECKED, 0);
\r
175 if (service->rotate_files) {
\r
176 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_SETCHECK, BST_CHECKED, 0);
\r
177 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), 1);
\r
178 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), 1);
\r
179 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), 1);
\r
181 if (service->rotate_stdout_online || service->rotate_stderr_online) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_CHECKED, 0);
\r
182 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);
\r
183 if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);
\r
186 if (service->hook_share_output_handles) SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_CHECKED, 0);
\r
188 /* Check if advanced settings are in use. */
\r
189 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
190 if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);
\r
192 /* Environment tab. */
\r
194 unsigned long envlen;
\r
195 if (service->env_extralen) {
\r
196 env = service->env_extra;
\r
197 envlen = service->env_extralen;
\r
200 env = service->env;
\r
201 envlen = service->envlen;
\r
202 if (envlen) SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_SETCHECK, BST_CHECKED, 0);
\r
207 unsigned long newlen;
\r
208 if (format_double_null(env, envlen, &formatted, &newlen)) {
\r
209 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()"));
\r
212 SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted);
\r
213 HeapFree(GetProcessHeap(), 0, formatted);
\r
216 if (service->envlen && service->env_extralen) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT);
\r
221 while (GetMessage(&message, 0, 0, 0)) {
\r
222 if (IsDialogMessage(dlg, &message)) continue;
\r
223 TranslateMessage(&message);
\r
224 DispatchMessage(&message);
\r
227 return (int) message.wParam;
\r
230 void centre_window(HWND window) {
\r
232 RECT size, desktop_size;
\r
233 unsigned long x, y;
\r
235 if (! window) return;
\r
237 /* Find window size */
\r
238 if (! GetWindowRect(window, &size)) return;
\r
240 /* Find desktop window */
\r
241 desktop = GetDesktopWindow();
\r
242 if (! desktop) return;
\r
244 /* Find desktop window size */
\r
245 if (! GetWindowRect(desktop, &desktop_size)) return;
\r
247 /* Centre window */
\r
248 x = (desktop_size.right - size.right) / 2;
\r
249 y = (desktop_size.bottom - size.bottom) / 2;
\r
250 MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);
\r
253 static inline void check_stop_method(nssm_service_t *service, unsigned long method, unsigned long control) {
\r
254 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) return;
\r
255 service->stop_method &= ~method;
\r
258 static inline void check_number(HWND tab, unsigned long control, unsigned long *timeout) {
\r
260 unsigned long configured = GetDlgItemInt(tab, control, &translated, 0);
\r
261 if (translated) *timeout = configured;
\r
264 static inline void set_timeout_enabled(unsigned long control, unsigned long dependent) {
\r
265 unsigned char enabled = 0;
\r
266 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
267 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], dependent), enabled);
\r
270 static inline void set_logon_enabled(unsigned char enabled) {
\r
271 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), ! enabled);
\r
272 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), enabled);
\r
273 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), enabled);
\r
274 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), enabled);
\r
277 static inline void set_affinity_enabled(unsigned char enabled) {
\r
278 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), enabled);
\r
281 static inline void set_rotation_enabled(unsigned char enabled) {
\r
282 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), enabled);
\r
283 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), enabled);
\r
284 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);
\r
287 static inline int hook_env(const TCHAR *hook_event, const TCHAR *hook_action, TCHAR *buffer, unsigned long buflen) {
\r
288 return _sntprintf_s(buffer, buflen, _TRUNCATE, _T("NSSM_HOOK_%s_%s"), hook_event, hook_action);
\r
291 static inline void set_hook_tab(int event_index, int action_index, bool changed) {
\r
292 int first_event = NSSM_GUI_HOOK_EVENT_START;
\r
294 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
295 SendMessage(combo, CB_SETCURSEL, event_index, 0);
\r
296 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_ACTION);
\r
297 SendMessage(combo, CB_RESETCONTENT, 0, 0);
\r
299 const TCHAR *hook_event = hook_event_strings[event_index];
\r
300 TCHAR *hook_action;
\r
302 switch (event_index + first_event) {
\r
303 case NSSM_GUI_HOOK_EVENT_ROTATE:
\r
305 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_PRE));
\r
306 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
307 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_POST));
\r
308 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
311 case NSSM_GUI_HOOK_EVENT_START:
\r
313 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_PRE));
\r
314 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
315 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_POST));
\r
316 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
319 case NSSM_GUI_HOOK_EVENT_STOP:
\r
321 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_STOP_PRE));
\r
322 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
325 case NSSM_GUI_HOOK_EVENT_EXIT:
\r
327 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_EXIT_POST));
\r
328 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
331 case NSSM_GUI_HOOK_EVENT_POWER:
\r
333 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_CHANGE));
\r
334 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_CHANGE;
\r
335 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_RESUME));
\r
336 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_RESUME;
\r
340 SendMessage(combo, CB_SETCURSEL, action_index, 0);
\r
342 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
343 hook_env(hook_event, hook_action, hook_name, _countof(hook_name));
\r
345 if (! *hook_name) return;
\r
347 TCHAR cmd[CMD_LENGTH];
\r
349 GetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd, _countof(cmd));
\r
350 SetEnvironmentVariable(hook_name, cmd);
\r
353 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
354 SetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd);
\r
358 static inline int update_hook(TCHAR *service_name, const TCHAR *hook_event, const TCHAR *hook_action) {
\r
359 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
360 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) return 1;
\r
361 TCHAR cmd[CMD_LENGTH];
\r
362 ZeroMemory(cmd, sizeof(cmd));
\r
363 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
364 if (set_hook(service_name, hook_event, hook_action, cmd)) return 2;
\r
368 static inline int update_hooks(TCHAR *service_name) {
\r
370 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE);
\r
371 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_POST);
\r
372 ret += update_hook(service_name, NSSM_HOOK_EVENT_STOP, NSSM_HOOK_ACTION_PRE);
\r
373 ret += update_hook(service_name, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_ACTION_POST);
\r
374 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_CHANGE);
\r
375 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_RESUME);
\r
376 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_PRE);
\r
377 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_POST);
\r
381 static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {
\r
382 if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;
\r
383 if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;
\r
384 popup_message(owner, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, name);
\r
385 ZeroMemory(buffer, len * sizeof(TCHAR));
\r
388 /* Set service parameters. */
\r
389 int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service) {
\r
390 if (! service) return 1;
\r
392 set_nssm_service_defaults(service);
\r
394 if (orig_service) {
\r
395 service->native = orig_service->native;
\r
396 service->handle = orig_service->handle;
\r
399 /* Get service name. */
\r
400 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
401 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
402 cleanup_nssm_service(service);
\r
406 /* Get executable name */
\r
407 if (! service->native) {
\r
408 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe, _countof(service->exe))) {
\r
409 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
\r
413 /* Get startup directory. */
\r
414 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir, _countof(service->dir))) {
\r
415 _sntprintf_s(service->dir, _countof(service->dir), _TRUNCATE, _T("%s"), service->exe);
\r
416 strip_basename(service->dir);
\r
420 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
\r
421 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags, _countof(service->flags))) {
\r
422 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
\r
429 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME), WM_GETTEXTLENGTH, 0, 0)) {
\r
430 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname, _countof(service->displayname))) {
\r
431 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DISPLAYNAME);
\r
436 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION), WM_GETTEXTLENGTH, 0, 0)) {
\r
437 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description, _countof(service->description))) {
\r
438 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DESCRIPTION);
\r
443 HWND combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
444 service->startup = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
445 if (service->startup == CB_ERR) service->startup = 0;
\r
447 /* Get logon stuff. */
\r
448 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
449 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
450 service->type |= SERVICE_INTERACTIVE_PROCESS;
\r
452 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
453 service->username = 0;
\r
454 service->usernamelen = 0;
\r
455 if (service->password) {
\r
456 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
457 HeapFree(GetProcessHeap(), 0, service->password);
\r
459 service->password = 0;
\r
460 service->passwordlen = 0;
\r
464 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
465 if (! service->usernamelen) {
\r
466 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
469 service->usernamelen++;
\r
471 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
472 if (! service->username) {
\r
473 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
476 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
477 HeapFree(GetProcessHeap(), 0, service->username);
\r
478 service->username = 0;
\r
479 service->usernamelen = 0;
\r
480 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
485 Special case for well-known accounts.
\r
486 Ignore the password if we're editing and the username hasn't changed.
\r
488 const TCHAR *well_known = well_known_username(service->username);
\r
490 if (str_equiv(well_known, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
491 HeapFree(GetProcessHeap(), 0, service->username);
\r
492 service->username = 0;
\r
493 service->usernamelen = 0;
\r
496 service->usernamelen = _tcslen(well_known) + 1;
\r
497 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
498 if (! service->username) {
\r
499 print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("install()"));
\r
502 memmove(service->username, well_known, service->usernamelen * sizeof(TCHAR));
\r
507 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
508 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
510 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
511 if (! service->passwordlen) {
\r
512 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
515 if (passwordlen != service->passwordlen) {
\r
516 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
519 service->passwordlen++;
\r
521 /* Temporary buffer for password validation. */
\r
522 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
524 HeapFree(GetProcessHeap(), 0, service->username);
\r
525 service->username = 0;
\r
526 service->usernamelen = 0;
\r
527 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
531 /* Actual password buffer. */
\r
532 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
533 if (! service->password) {
\r
534 HeapFree(GetProcessHeap(), 0, password);
\r
535 HeapFree(GetProcessHeap(), 0, service->username);
\r
536 service->username = 0;
\r
537 service->usernamelen = 0;
\r
538 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
542 /* Get first password. */
\r
543 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
544 HeapFree(GetProcessHeap(), 0, password);
\r
545 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
546 HeapFree(GetProcessHeap(), 0, service->password);
\r
547 service->password = 0;
\r
548 service->passwordlen = 0;
\r
549 HeapFree(GetProcessHeap(), 0, service->username);
\r
550 service->username = 0;
\r
551 service->usernamelen = 0;
\r
552 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
556 /* Get confirmation. */
\r
557 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
558 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
559 HeapFree(GetProcessHeap(), 0, password);
\r
560 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
561 HeapFree(GetProcessHeap(), 0, service->password);
\r
562 service->password = 0;
\r
563 service->passwordlen = 0;
\r
564 HeapFree(GetProcessHeap(), 0, service->username);
\r
565 service->username = 0;
\r
566 service->usernamelen = 0;
\r
567 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
572 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
573 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
574 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
575 HeapFree(GetProcessHeap(), 0, password);
\r
576 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
577 HeapFree(GetProcessHeap(), 0, service->password);
\r
578 service->password = 0;
\r
579 service->passwordlen = 0;
\r
580 HeapFree(GetProcessHeap(), 0, service->username);
\r
581 service->username = 0;
\r
582 service->usernamelen = 0;
\r
589 /* Get dependencies. */
\r
590 unsigned long dependencieslen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES), WM_GETTEXTLENGTH, 0, 0);
\r
591 if (dependencieslen) {
\r
592 TCHAR *dependencies = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (dependencieslen + 2) * sizeof(TCHAR));
\r
593 if (! dependencies) {
\r
594 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
595 cleanup_nssm_service(service);
\r
599 if (! GetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, dependencies, dependencieslen + 1)) {
\r
600 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DEPENDENCIES);
\r
601 HeapFree(GetProcessHeap(), 0, dependencies);
\r
602 cleanup_nssm_service(service);
\r
606 if (unformat_double_null(dependencies, dependencieslen, &service->dependencies, &service->dependencieslen)) {
\r
607 HeapFree(GetProcessHeap(), 0, dependencies);
\r
608 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
609 cleanup_nssm_service(service);
\r
613 HeapFree(GetProcessHeap(), 0, dependencies);
\r
616 /* Remaining tabs are only for services we manage. */
\r
617 if (service->native) return 0;
\r
619 /* Get process stuff. */
\r
620 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
621 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
623 service->affinity = 0LL;
\r
624 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
625 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
626 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
627 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
629 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
632 else if (selected < count) {
\r
633 for (int i = 0; i < count; i++) {
\r
634 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
639 if (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->no_console = 0;
\r
640 else service->no_console = 1;
\r
642 /* Get stop method stuff. */
\r
643 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
644 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
645 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
646 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
647 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
648 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
649 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
650 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->kill_process_tree = 1;
\r
651 else service->kill_process_tree = 0;
\r
653 /* Get exit action stuff. */
\r
654 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
655 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
656 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
657 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
658 check_number(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, &service->restart_delay);
\r
660 /* Get I/O stuff. */
\r
661 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
662 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
663 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
665 /* Override stdout and/or stderr. */
\r
666 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
667 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
668 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
671 /* Get rotation stuff. */
\r
672 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
673 service->rotate_files = true;
\r
674 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->rotate_stdout_online = service->rotate_stderr_online = NSSM_ROTATE_ONLINE;
\r
675 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
676 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
679 /* Get hook stuff. */
\r
680 if (SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_GETCHECK, 0, 0) & BST_CHECKED) service->hook_share_output_handles = true;
\r
682 /* Get environment. */
\r
683 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
685 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
687 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
688 cleanup_nssm_service(service);
\r
692 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
693 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
694 HeapFree(GetProcessHeap(), 0, env);
\r
695 cleanup_nssm_service(service);
\r
700 unsigned long newlen;
\r
701 if (unformat_double_null(env, envlen, &newenv, &newlen)) {
\r
702 HeapFree(GetProcessHeap(), 0, env);
\r
703 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
704 cleanup_nssm_service(service);
\r
708 HeapFree(GetProcessHeap(), 0, env);
\r
712 /* Test the environment is valid. */
\r
713 if (test_environment(env)) {
\r
714 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
715 HeapFree(GetProcessHeap(), 0, env);
\r
716 cleanup_nssm_service(service);
\r
720 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
721 service->env = env;
\r
722 service->envlen = envlen;
\r
725 service->env_extra = env;
\r
726 service->env_extralen = envlen;
\r
733 /* Install the service. */
\r
734 int install(HWND window) {
\r
735 if (! window) return 1;
\r
737 nssm_service_t *service = alloc_nssm_service();
\r
739 int ret = configure(window, service, 0);
\r
740 if (ret) return ret;
\r
743 /* See if it works. */
\r
744 switch (install_service(service)) {
\r
746 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
747 cleanup_nssm_service(service);
\r
751 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
752 cleanup_nssm_service(service);
\r
756 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
757 cleanup_nssm_service(service);
\r
761 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
762 cleanup_nssm_service(service);
\r
766 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
767 cleanup_nssm_service(service);
\r
771 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
772 cleanup_nssm_service(service);
\r
776 update_hooks(service->name);
\r
778 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
779 cleanup_nssm_service(service);
\r
783 /* Remove the service */
\r
784 int remove(HWND window) {
\r
785 if (! window) return 1;
\r
787 /* See if it works */
\r
788 nssm_service_t *service = alloc_nssm_service();
\r
790 /* Get service name */
\r
791 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
792 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
793 cleanup_nssm_service(service);
\r
798 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
799 cleanup_nssm_service(service);
\r
804 switch (remove_service(service)) {
\r
806 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
807 cleanup_nssm_service(service);
\r
811 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
812 cleanup_nssm_service(service);
\r
816 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
817 cleanup_nssm_service(service);
\r
821 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
822 cleanup_nssm_service(service);
\r
826 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
827 cleanup_nssm_service(service);
\r
831 int edit(HWND window, nssm_service_t *orig_service) {
\r
832 if (! window) return 1;
\r
834 nssm_service_t *service = alloc_nssm_service();
\r
836 int ret = configure(window, service, orig_service);
\r
837 if (ret) return ret;
\r
840 switch (edit_service(service, true)) {
\r
842 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
843 cleanup_nssm_service(service);
\r
847 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
848 cleanup_nssm_service(service);
\r
852 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
853 cleanup_nssm_service(service);
\r
858 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
859 cleanup_nssm_service(service);
\r
863 update_hooks(service->name);
\r
865 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
866 cleanup_nssm_service(service);
\r
870 static TCHAR *browse_filter(int message) {
\r
872 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
873 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
874 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
875 default: return _T("*.*");
\r
879 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
881 case WM_INITDIALOG:
\r
888 /* Browse for application */
\r
889 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
890 if (! window) return;
\r
893 size_t bufsize = 256;
\r
894 size_t len = bufsize;
\r
898 ZeroMemory(&ofn, sizeof(ofn));
\r
899 ofn.lStructSize = sizeof(ofn);
\r
900 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
901 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
902 if (ofn.lpstrFilter) {
\r
903 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
905 /* "Applications" + NULL + "*.exe" + NULL */
\r
906 va_start(arg, flags);
\r
907 while (i = va_arg(arg, int)) {
\r
908 TCHAR *localised = message_string(i);
\r
909 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
910 len += _tcslen(localised) + 1;
\r
911 LocalFree(localised);
\r
912 TCHAR *filter = browse_filter(i);
\r
913 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
914 len += _tcslen(filter) + 1;
\r
917 /* Remainder of the buffer is already zeroed */
\r
919 ofn.lpstrFile = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, PATH_LENGTH * sizeof(TCHAR));
\r
920 if (ofn.lpstrFile) {
\r
921 if (flags & OFN_NOVALIDATE) {
\r
922 /* Directory hack. */
\r
923 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
924 ofn.nMaxFile = DIR_LENGTH;
\r
927 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T("%s"), current);
\r
928 ofn.nMaxFile = PATH_LENGTH;
\r
931 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
932 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
934 if (GetOpenFileName(&ofn)) {
\r
935 /* Directory hack. */
\r
936 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
937 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
939 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
940 if (ofn.lpstrFile) HeapFree(GetProcessHeap(), 0, ofn.lpstrFile);
\r
943 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
945 case WM_INITDIALOG:
\r
948 /* Button was pressed or control was controlled. */
\r
951 TCHAR buffer[PATH_LENGTH];
\r
952 unsigned char enabled;
\r
954 switch (LOWORD(w)) {
\r
955 /* Browse for application. */
\r
957 dlg = GetDlgItem(tab, IDC_PATH);
\r
958 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
959 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
960 /* Fill in startup directory if it wasn't already specified. */
\r
961 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
963 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
964 strip_basename(buffer);
\r
965 SetDlgItemText(tab, IDC_DIR, buffer);
\r
969 /* Browse for startup directory. */
\r
970 case IDC_BROWSE_DIR:
\r
971 dlg = GetDlgItem(tab, IDC_DIR);
\r
972 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
973 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
977 case IDC_LOCALSYSTEM:
\r
978 set_logon_enabled(0);
\r
982 set_logon_enabled(1);
\r
986 case IDC_AFFINITY_ALL:
\r
987 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
989 set_affinity_enabled(enabled);
\r
992 /* Shutdown methods. */
\r
993 case IDC_METHOD_CONSOLE:
\r
994 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
997 case IDC_METHOD_WINDOW:
\r
998 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
1001 case IDC_METHOD_THREADS:
\r
1002 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
1005 /* Browse for stdin. */
\r
1006 case IDC_BROWSE_STDIN:
\r
1007 dlg = GetDlgItem(tab, IDC_STDIN);
\r
1008 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
1009 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1012 /* Browse for stdout. */
\r
1013 case IDC_BROWSE_STDOUT:
\r
1014 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
1015 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1016 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1017 /* Fill in stderr if it wasn't already specified. */
\r
1018 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1019 if (! buffer[0]) {
\r
1020 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1021 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
1025 /* Browse for stderr. */
\r
1026 case IDC_BROWSE_STDERR:
\r
1027 dlg = GetDlgItem(tab, IDC_STDERR);
\r
1028 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1029 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1034 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
1036 set_rotation_enabled(enabled);
\r
1040 case IDC_HOOK_EVENT:
\r
1041 if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), 0, false);
\r
1044 /* Hook action. */
\r
1045 case IDC_HOOK_ACTION:
\r
1046 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
1049 /* Browse for hook. */
\r
1050 case IDC_BROWSE_HOOK:
\r
1051 dlg = GetDlgItem(tab, IDC_HOOK);
\r
1052 GetDlgItemText(tab, IDC_HOOK, buffer, _countof(buffer));
\r
1053 browse(dlg, _T(""), OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1058 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
1067 /* Install/remove dialogue callback */
\r
1068 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
1069 nssm_service_t *service;
\r
1071 switch (message) {
\r
1072 /* Creating the dialogue */
\r
1073 case WM_INITDIALOG:
\r
1074 service = (nssm_service_t *) l;
\r
1076 SetFocus(GetDlgItem(window, IDC_NAME));
\r
1082 tabs = GetDlgItem(window, IDC_TAB1);
\r
1083 if (! tabs) return 0;
\r
1085 /* Set up tabs. */
\r
1087 ZeroMemory(&tab, sizeof(tab));
\r
1088 tab.mask = TCIF_TEXT;
\r
1092 /* Application tab. */
\r
1093 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
1094 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
1095 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1096 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
1097 if (service->native) {
\r
1098 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
1099 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
1100 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
1102 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
1103 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
1105 /* Details tab. */
\r
1106 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
1107 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1108 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
1109 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
1110 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
1112 /* Set defaults. */
\r
1113 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
1114 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
1115 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
1116 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
1117 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
1118 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
1121 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
1122 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1123 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
1124 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
1125 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
1127 /* Set defaults. */
\r
1128 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
1129 set_logon_enabled(0);
\r
1131 /* Dependencies tab. */
\r
1132 tab.pszText = message_string(NSSM_GUI_TAB_DEPENDENCIES);
\r
1133 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1134 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DEPENDENCIES, (LPARAM) &tab);
\r
1135 tablist[NSSM_TAB_DEPENDENCIES] = dialog(MAKEINTRESOURCE(IDD_DEPENDENCIES), window, tab_dlg);
\r
1136 ShowWindow(tablist[NSSM_TAB_DEPENDENCIES], SW_HIDE);
\r
1138 /* Remaining tabs are only for services we manage. */
\r
1139 if (service->native) return 1;
\r
1141 /* Process tab. */
\r
1142 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
1143 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1144 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
1145 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
1146 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
1148 /* Set defaults. */
\r
1149 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
1150 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
1151 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
1152 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
1153 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
1154 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
1155 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
1156 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
1158 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1160 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
1162 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
1163 for (i = 0; i < n; i++) {
\r
1165 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
1166 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
1171 The box is high enough for four rows. It is wide enough for eight
\r
1172 columns without scrolling. With scrollbars it shrinks to two rows.
\r
1173 Note that the above only holds if we set the column width BEFORE
\r
1174 adding the strings.
\r
1177 int columns = (n - 1) / 4;
\r
1179 GetWindowRect(list, &rect);
\r
1180 int width = rect.right - rect.left;
\r
1181 width -= (7 - columns) * 16;
\r
1182 int height = rect.bottom - rect.top;
\r
1183 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
\r
1184 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
1186 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
1188 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
1189 set_affinity_enabled(0);
\r
1191 /* Shutdown tab. */
\r
1192 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
1193 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1194 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
1195 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
1196 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
1198 /* Set defaults. */
\r
1199 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1200 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
1201 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
1202 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
1203 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
1204 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1205 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1206 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_CHECKED, 1);
\r
1208 /* Restart tab. */
\r
1209 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1210 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1211 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1212 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1213 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1215 /* Set defaults. */
\r
1216 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1217 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1218 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1219 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1220 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1221 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1222 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1223 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1226 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1227 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1228 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1229 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1230 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1232 /* Rotation tab. */
\r
1233 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1234 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1235 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1236 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1237 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1239 /* Set defaults. */
\r
1240 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1241 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1242 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1243 set_rotation_enabled(0);
\r
1245 /* Environment tab. */
\r
1246 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1247 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1248 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1249 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1250 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1253 tab.pszText = message_string(NSSM_GUI_TAB_HOOKS);
\r
1254 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1255 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_HOOKS, (LPARAM) &tab);
\r
1256 tablist[NSSM_TAB_HOOKS] = dialog(MAKEINTRESOURCE(IDD_HOOKS), window, tab_dlg);
\r
1257 ShowWindow(tablist[NSSM_TAB_HOOKS], SW_HIDE);
\r
1259 /* Set defaults. */
\r
1260 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
1261 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_START));
\r
1262 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_STOP));
\r
1263 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_EXIT));
\r
1264 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_POWER));
\r
1265 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_ROTATE));
\r
1266 SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1267 if (_tcslen(service->name)) {
\r
1268 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
1269 TCHAR cmd[CMD_LENGTH];
\r
1270 for (i = 0; hook_event_strings[i]; i++) {
\r
1271 const TCHAR *hook_event = hook_event_strings[i];
\r
1273 for (j = 0; hook_action_strings[j]; j++) {
\r
1274 const TCHAR *hook_action = hook_action_strings[j];
\r
1275 if (! valid_hook_name(hook_event, hook_action, true)) continue;
\r
1276 if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) continue;
\r
1277 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) continue;
\r
1278 SetEnvironmentVariable(hook_name, cmd);
\r
1282 set_hook_tab(0, 0, false);
\r
1288 NMHDR *notification;
\r
1290 notification = (NMHDR *) l;
\r
1291 switch (notification->code) {
\r
1292 case TCN_SELCHANGE:
\r
1296 tabs = GetDlgItem(window, IDC_TAB1);
\r
1297 if (! tabs) return 0;
\r
1299 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1300 if (selection != selected_tab) {
\r
1301 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1302 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1303 SetFocus(GetDlgItem(window, IDOK));
\r
1304 selected_tab = selection;
\r
1311 /* Button was pressed or control was controlled */
\r
1313 switch (LOWORD(w)) {
\r
1316 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1317 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1319 else if (! install(window)) PostQuitMessage(0);
\r
1322 /* Cancel button */
\r
1324 DestroyWindow(window);
\r
1327 /* Remove button */
\r
1329 if (! remove(window)) PostQuitMessage(0);
\r
1334 /* Window closing */
\r
1336 DestroyWindow(window);
\r
1339 PostQuitMessage(0);
\r