3 extern const TCHAR *hook_event_strings[];
\r
4 extern const TCHAR *hook_action_strings[];
\r
6 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
7 static HWND tablist[NSSM_NUM_TABS];
\r
8 static int selected_tab;
\r
10 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function, LPARAM l) {
\r
11 /* The caller will deal with GetLastError()... */
\r
12 HRSRC resource = FindResourceEx(0, RT_DIALOG, templ, GetUserDefaultLangID());
\r
14 if (GetLastError() != ERROR_RESOURCE_LANG_NOT_FOUND) return 0;
\r
15 resource = FindResourceEx(0, RT_DIALOG, templ, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
\r
16 if (! resource) return 0;
\r
19 HGLOBAL ret = LoadResource(0, resource);
\r
20 if (! ret) return 0;
\r
22 return CreateDialogIndirectParam(0, (DLGTEMPLATE *) ret, parent, function, l);
\r
25 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function) {
\r
26 return dialog(templ, parent, function, 0);
\r
29 int nssm_gui(int resource, nssm_service_t *service) {
\r
31 HWND dlg = dialog(MAKEINTRESOURCE(resource), 0, nssm_dlg, (LPARAM) service);
\r
33 popup_message(0, MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));
\r
37 /* Load the icon. */
\r
38 HANDLE icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
\r
39 if (icon) SendMessage(dlg, WM_SETICON, ICON_SMALL, (LPARAM) icon);
\r
40 icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
\r
41 if (icon) SendMessage(dlg, WM_SETICON, ICON_BIG, (LPARAM) icon);
\r
43 /* Remember what the window is for. */
\r
44 SetWindowLongPtr(dlg, GWLP_USERDATA, (LONG_PTR) resource);
\r
46 /* Display the window */
\r
48 ShowWindow(dlg, SW_SHOW);
\r
50 /* Set service name if given */
\r
51 if (service->name[0]) {
\r
52 SetDlgItemText(dlg, IDC_NAME, service->name);
\r
53 /* No point making user click remove if the name is already entered */
\r
54 if (resource == IDD_REMOVE) {
\r
55 HWND button = GetDlgItem(dlg, IDC_REMOVE);
\r
57 SendMessage(button, WM_LBUTTONDOWN, 0, 0);
\r
58 SendMessage(button, WM_LBUTTONUP, 0, 0);
\r
63 if (resource == IDD_EDIT) {
\r
64 /* We'll need the service handle later. */
\r
65 SetWindowLongPtr(dlg, DWLP_USER, (LONG_PTR) service);
\r
67 /* Service name can't be edited. */
\r
68 EnableWindow(GetDlgItem(dlg, IDC_NAME), 0);
\r
69 SetFocus(GetDlgItem(dlg, IDOK));
\r
71 /* Set existing details. */
\r
75 /* Application tab. */
\r
76 if (service->native) SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->image);
\r
77 else SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe);
\r
78 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir);
\r
79 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags);
\r
82 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname);
\r
83 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description);
\r
84 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
85 SendMessage(combo, CB_SETCURSEL, service->startup, 0);
\r
88 if (service->username) {
\r
89 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_ACCOUNT);
\r
90 SetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username);
\r
91 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), 0);
\r
92 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), 1);
\r
93 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), 1);
\r
94 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), 1);
\r
97 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
98 if (service->type & SERVICE_INTERACTIVE_PROCESS) SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_SETCHECK, BST_CHECKED, 0);
\r
101 /* Dependencies tab. */
\r
102 if (service->dependencieslen) {
\r
104 unsigned long newlen;
\r
105 if (format_double_null(service->dependencies, service->dependencieslen, &formatted, &newlen)) {
\r
106 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("nssm_dlg()"));
\r
109 SetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, formatted);
\r
110 HeapFree(GetProcessHeap(), 0, formatted);
\r
115 if (service->priority) {
\r
116 int priority = priority_constant_to_index(service->priority);
\r
117 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
118 SendMessage(combo, CB_SETCURSEL, priority, 0);
\r
121 if (service->affinity) {
\r
122 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
123 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
\r
124 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), 1);
\r
126 DWORD_PTR affinity, system_affinity;
\r
127 if (GetProcessAffinityMask(GetCurrentProcess(), &affinity, &system_affinity)) {
\r
128 if ((service->affinity & (__int64) system_affinity) != service->affinity) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_AFFINITY);
\r
131 for (int i = 0; i < num_cpus(); i++) {
\r
132 if (! (service->affinity & (1LL << (__int64) i))) SendMessage(list, LB_SETSEL, 0, i);
\r
136 if (service->no_console) {
\r
137 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
140 /* Shutdown tab. */
\r
141 if (! (service->stop_method & NSSM_STOP_METHOD_CONSOLE)) {
\r
142 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
143 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE), 0);
\r
145 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, service->kill_console_delay, 0);
\r
146 if (! (service->stop_method & NSSM_STOP_METHOD_WINDOW)) {
\r
147 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_UNCHECKED, 0);
\r
148 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW), 0);
\r
150 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, service->kill_window_delay, 0);
\r
151 if (! (service->stop_method & NSSM_STOP_METHOD_THREADS)) {
\r
152 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_UNCHECKED, 0);
\r
153 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS), 0);
\r
155 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, service->kill_threads_delay, 0);
\r
156 if (! (service->stop_method & NSSM_STOP_METHOD_TERMINATE)) {
\r
157 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
159 if (! service->kill_process_tree) {
\r
160 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
164 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, service->throttle_delay, 0);
\r
165 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
166 SendMessage(combo, CB_SETCURSEL, service->default_exit_action, 0);
\r
167 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, service->restart_delay, 0);
\r
170 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDIN, service->stdin_path);
\r
171 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDOUT, service->stdout_path);
\r
172 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDERR, service->stderr_path);
\r
174 /* Rotation tab. */
\r
175 if (service->stdout_disposition == CREATE_ALWAYS) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_SETCHECK, BST_CHECKED, 0);
\r
176 if (service->rotate_files) {
\r
177 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_SETCHECK, BST_CHECKED, 0);
\r
178 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), 1);
\r
179 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), 1);
\r
180 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), 1);
\r
182 if (service->rotate_stdout_online || service->rotate_stderr_online) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_CHECKED, 0);
\r
183 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);
\r
184 if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);
\r
187 if (service->hook_share_output_handles) SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_CHECKED, 0);
\r
189 /* Check if advanced settings are in use. */
\r
190 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
191 if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);
\r
193 /* Environment tab. */
\r
195 unsigned long envlen;
\r
196 if (service->env_extralen) {
\r
197 env = service->env_extra;
\r
198 envlen = service->env_extralen;
\r
201 env = service->env;
\r
202 envlen = service->envlen;
\r
203 if (envlen) SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_SETCHECK, BST_CHECKED, 0);
\r
208 unsigned long newlen;
\r
209 if (format_double_null(env, envlen, &formatted, &newlen)) {
\r
210 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()"));
\r
213 SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted);
\r
214 HeapFree(GetProcessHeap(), 0, formatted);
\r
217 if (service->envlen && service->env_extralen) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT);
\r
222 while (GetMessage(&message, 0, 0, 0)) {
\r
223 if (IsDialogMessage(dlg, &message)) continue;
\r
224 TranslateMessage(&message);
\r
225 DispatchMessage(&message);
\r
228 return (int) message.wParam;
\r
231 void centre_window(HWND window) {
\r
233 RECT size, desktop_size;
\r
234 unsigned long x, y;
\r
236 if (! window) return;
\r
238 /* Find window size */
\r
239 if (! GetWindowRect(window, &size)) return;
\r
241 /* Find desktop window */
\r
242 desktop = GetDesktopWindow();
\r
243 if (! desktop) return;
\r
245 /* Find desktop window size */
\r
246 if (! GetWindowRect(desktop, &desktop_size)) return;
\r
248 /* Centre window */
\r
249 x = (desktop_size.right - size.right) / 2;
\r
250 y = (desktop_size.bottom - size.bottom) / 2;
\r
251 MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);
\r
254 static inline void check_stop_method(nssm_service_t *service, unsigned long method, unsigned long control) {
\r
255 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) return;
\r
256 service->stop_method &= ~method;
\r
259 static inline void check_number(HWND tab, unsigned long control, unsigned long *timeout) {
\r
261 unsigned long configured = GetDlgItemInt(tab, control, &translated, 0);
\r
262 if (translated) *timeout = configured;
\r
265 static inline void set_timeout_enabled(unsigned long control, unsigned long dependent) {
\r
266 unsigned char enabled = 0;
\r
267 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
268 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], dependent), enabled);
\r
271 static inline void set_logon_enabled(unsigned char enabled) {
\r
272 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), ! enabled);
\r
273 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), enabled);
\r
274 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), enabled);
\r
275 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), enabled);
\r
278 static inline void set_affinity_enabled(unsigned char enabled) {
\r
279 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), enabled);
\r
282 static inline void set_rotation_enabled(unsigned char enabled) {
\r
283 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), enabled);
\r
284 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), enabled);
\r
285 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);
\r
288 static inline int hook_env(const TCHAR *hook_event, const TCHAR *hook_action, TCHAR *buffer, unsigned long buflen) {
\r
289 return _sntprintf_s(buffer, buflen, _TRUNCATE, _T("NSSM_HOOK_%s_%s"), hook_event, hook_action);
\r
292 static inline void set_hook_tab(int event_index, int action_index, bool changed) {
\r
293 int first_event = NSSM_GUI_HOOK_EVENT_START;
\r
295 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
296 SendMessage(combo, CB_SETCURSEL, event_index, 0);
\r
297 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_ACTION);
\r
298 SendMessage(combo, CB_RESETCONTENT, 0, 0);
\r
300 const TCHAR *hook_event = hook_event_strings[event_index];
\r
301 TCHAR *hook_action;
\r
303 switch (event_index + first_event) {
\r
304 case NSSM_GUI_HOOK_EVENT_ROTATE:
\r
306 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_PRE));
\r
307 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
308 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_ROTATE_POST));
\r
309 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
312 case NSSM_GUI_HOOK_EVENT_START:
\r
314 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_PRE));
\r
315 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
316 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_START_POST));
\r
317 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
320 case NSSM_GUI_HOOK_EVENT_STOP:
\r
322 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_STOP_PRE));
\r
323 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_PRE;
\r
326 case NSSM_GUI_HOOK_EVENT_EXIT:
\r
328 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_EXIT_POST));
\r
329 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_POST;
\r
332 case NSSM_GUI_HOOK_EVENT_POWER:
\r
334 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_CHANGE));
\r
335 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_CHANGE;
\r
336 SendMessage(combo, CB_INSERTSTRING, i, (LPARAM) message_string(NSSM_GUI_HOOK_ACTION_POWER_RESUME));
\r
337 if (action_index == i++) hook_action = NSSM_HOOK_ACTION_RESUME;
\r
341 SendMessage(combo, CB_SETCURSEL, action_index, 0);
\r
343 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
344 hook_env(hook_event, hook_action, hook_name, _countof(hook_name));
\r
346 if (! *hook_name) return;
\r
348 TCHAR cmd[CMD_LENGTH];
\r
350 GetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd, _countof(cmd));
\r
351 SetEnvironmentVariable(hook_name, cmd);
\r
354 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
355 SetDlgItemText(tablist[NSSM_TAB_HOOKS], IDC_HOOK, cmd);
\r
359 static inline int update_hook(TCHAR *service_name, const TCHAR *hook_event, const TCHAR *hook_action) {
\r
360 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
361 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) return 1;
\r
362 TCHAR cmd[CMD_LENGTH];
\r
363 ZeroMemory(cmd, sizeof(cmd));
\r
364 GetEnvironmentVariable(hook_name, cmd, _countof(cmd));
\r
365 if (set_hook(service_name, hook_event, hook_action, cmd)) return 2;
\r
369 static inline int update_hooks(TCHAR *service_name) {
\r
371 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_PRE);
\r
372 ret += update_hook(service_name, NSSM_HOOK_EVENT_START, NSSM_HOOK_ACTION_POST);
\r
373 ret += update_hook(service_name, NSSM_HOOK_EVENT_STOP, NSSM_HOOK_ACTION_PRE);
\r
374 ret += update_hook(service_name, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_ACTION_POST);
\r
375 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_CHANGE);
\r
376 ret += update_hook(service_name, NSSM_HOOK_EVENT_POWER, NSSM_HOOK_ACTION_RESUME);
\r
377 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_PRE);
\r
378 ret += update_hook(service_name, NSSM_HOOK_EVENT_ROTATE, NSSM_HOOK_ACTION_POST);
\r
382 static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {
\r
383 if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;
\r
384 if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;
\r
385 popup_message(owner, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, name);
\r
386 ZeroMemory(buffer, len * sizeof(TCHAR));
\r
389 /* Set service parameters. */
\r
390 int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service) {
\r
391 if (! service) return 1;
\r
393 set_nssm_service_defaults(service);
\r
395 if (orig_service) {
\r
396 service->native = orig_service->native;
\r
397 service->handle = orig_service->handle;
\r
400 /* Get service name. */
\r
401 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
402 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
403 cleanup_nssm_service(service);
\r
407 /* Get executable name */
\r
408 if (! service->native) {
\r
409 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe, _countof(service->exe))) {
\r
410 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
\r
414 /* Get startup directory. */
\r
415 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir, _countof(service->dir))) {
\r
416 _sntprintf_s(service->dir, _countof(service->dir), _TRUNCATE, _T("%s"), service->exe);
\r
417 strip_basename(service->dir);
\r
421 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
\r
422 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags, _countof(service->flags))) {
\r
423 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
\r
430 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME), WM_GETTEXTLENGTH, 0, 0)) {
\r
431 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname, _countof(service->displayname))) {
\r
432 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DISPLAYNAME);
\r
437 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION), WM_GETTEXTLENGTH, 0, 0)) {
\r
438 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description, _countof(service->description))) {
\r
439 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DESCRIPTION);
\r
444 HWND combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
445 service->startup = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
446 if (service->startup == CB_ERR) service->startup = 0;
\r
448 /* Get logon stuff. */
\r
449 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
450 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
451 service->type |= SERVICE_INTERACTIVE_PROCESS;
\r
453 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
454 service->username = 0;
\r
455 service->usernamelen = 0;
\r
456 if (service->password) {
\r
457 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
458 HeapFree(GetProcessHeap(), 0, service->password);
\r
460 service->password = 0;
\r
461 service->passwordlen = 0;
\r
465 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
466 if (! service->usernamelen) {
\r
467 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
470 service->usernamelen++;
\r
472 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
473 if (! service->username) {
\r
474 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
477 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
478 HeapFree(GetProcessHeap(), 0, service->username);
\r
479 service->username = 0;
\r
480 service->usernamelen = 0;
\r
481 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
486 Special case for well-known accounts.
\r
487 Ignore the password if we're editing and the username hasn't changed.
\r
489 const TCHAR *well_known = well_known_username(service->username);
\r
491 if (str_equiv(well_known, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
492 HeapFree(GetProcessHeap(), 0, service->username);
\r
493 service->username = 0;
\r
494 service->usernamelen = 0;
\r
497 service->usernamelen = _tcslen(well_known) + 1;
\r
498 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
499 if (! service->username) {
\r
500 print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY, _T("canon"), _T("install()"));
\r
503 memmove(service->username, well_known, service->usernamelen * sizeof(TCHAR));
\r
508 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
509 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
511 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
512 if (! service->passwordlen) {
\r
513 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
516 if (passwordlen != service->passwordlen) {
\r
517 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
520 service->passwordlen++;
\r
522 /* Temporary buffer for password validation. */
\r
523 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
525 HeapFree(GetProcessHeap(), 0, service->username);
\r
526 service->username = 0;
\r
527 service->usernamelen = 0;
\r
528 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
532 /* Actual password buffer. */
\r
533 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
534 if (! service->password) {
\r
535 HeapFree(GetProcessHeap(), 0, password);
\r
536 HeapFree(GetProcessHeap(), 0, service->username);
\r
537 service->username = 0;
\r
538 service->usernamelen = 0;
\r
539 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
543 /* Get first password. */
\r
544 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
545 HeapFree(GetProcessHeap(), 0, password);
\r
546 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
547 HeapFree(GetProcessHeap(), 0, service->password);
\r
548 service->password = 0;
\r
549 service->passwordlen = 0;
\r
550 HeapFree(GetProcessHeap(), 0, service->username);
\r
551 service->username = 0;
\r
552 service->usernamelen = 0;
\r
553 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
557 /* Get confirmation. */
\r
558 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
559 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
560 HeapFree(GetProcessHeap(), 0, password);
\r
561 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
562 HeapFree(GetProcessHeap(), 0, service->password);
\r
563 service->password = 0;
\r
564 service->passwordlen = 0;
\r
565 HeapFree(GetProcessHeap(), 0, service->username);
\r
566 service->username = 0;
\r
567 service->usernamelen = 0;
\r
568 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
573 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
574 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
575 SecureZeroMemory(password, service->passwordlen * sizeof(TCHAR));
\r
576 HeapFree(GetProcessHeap(), 0, password);
\r
577 SecureZeroMemory(service->password, service->passwordlen * sizeof(TCHAR));
\r
578 HeapFree(GetProcessHeap(), 0, service->password);
\r
579 service->password = 0;
\r
580 service->passwordlen = 0;
\r
581 HeapFree(GetProcessHeap(), 0, service->username);
\r
582 service->username = 0;
\r
583 service->usernamelen = 0;
\r
590 /* Get dependencies. */
\r
591 unsigned long dependencieslen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES), WM_GETTEXTLENGTH, 0, 0);
\r
592 if (dependencieslen) {
\r
593 TCHAR *dependencies = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (dependencieslen + 2) * sizeof(TCHAR));
\r
594 if (! dependencies) {
\r
595 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
596 cleanup_nssm_service(service);
\r
600 if (! GetDlgItemText(tablist[NSSM_TAB_DEPENDENCIES], IDC_DEPENDENCIES, dependencies, dependencieslen + 1)) {
\r
601 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DEPENDENCIES);
\r
602 HeapFree(GetProcessHeap(), 0, dependencies);
\r
603 cleanup_nssm_service(service);
\r
607 if (unformat_double_null(dependencies, dependencieslen, &service->dependencies, &service->dependencieslen)) {
\r
608 HeapFree(GetProcessHeap(), 0, dependencies);
\r
609 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("dependencies"), _T("install()"));
\r
610 cleanup_nssm_service(service);
\r
614 HeapFree(GetProcessHeap(), 0, dependencies);
\r
617 /* Remaining tabs are only for services we manage. */
\r
618 if (service->native) return 0;
\r
620 /* Get process stuff. */
\r
621 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
622 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
624 service->affinity = 0LL;
\r
625 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
626 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
627 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
628 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
630 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
633 else if (selected < count) {
\r
634 for (int i = 0; i < count; i++) {
\r
635 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
640 if (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->no_console = 0;
\r
641 else service->no_console = 1;
\r
643 /* Get stop method stuff. */
\r
644 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
645 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
646 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
647 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
648 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
649 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
650 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
651 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_GETCHECK, 0, 0) & BST_CHECKED) service->kill_process_tree = 1;
\r
652 else service->kill_process_tree = 0;
\r
654 /* Get exit action stuff. */
\r
655 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
656 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
657 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
658 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
659 check_number(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, &service->restart_delay);
\r
661 /* Get I/O stuff. */
\r
662 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
663 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
664 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
666 /* Override stdout and/or stderr. */
\r
667 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
668 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
669 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
672 /* Get rotation stuff. */
\r
673 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
674 service->rotate_files = true;
\r
675 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
676 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
677 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
680 /* Get hook stuff. */
\r
681 if (SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_GETCHECK, 0, 0) & BST_CHECKED) service->hook_share_output_handles = true;
\r
683 /* Get environment. */
\r
684 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
686 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
688 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
689 cleanup_nssm_service(service);
\r
693 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
694 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
695 HeapFree(GetProcessHeap(), 0, env);
\r
696 cleanup_nssm_service(service);
\r
701 unsigned long newlen;
\r
702 if (unformat_double_null(env, envlen, &newenv, &newlen)) {
\r
703 HeapFree(GetProcessHeap(), 0, env);
\r
704 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
705 cleanup_nssm_service(service);
\r
709 HeapFree(GetProcessHeap(), 0, env);
\r
713 /* Test the environment is valid. */
\r
714 if (test_environment(env)) {
\r
715 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
716 HeapFree(GetProcessHeap(), 0, env);
\r
717 cleanup_nssm_service(service);
\r
721 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
722 service->env = env;
\r
723 service->envlen = envlen;
\r
726 service->env_extra = env;
\r
727 service->env_extralen = envlen;
\r
734 /* Install the service. */
\r
735 int install(HWND window) {
\r
736 if (! window) return 1;
\r
738 nssm_service_t *service = alloc_nssm_service();
\r
740 int ret = configure(window, service, 0);
\r
741 if (ret) return ret;
\r
744 /* See if it works. */
\r
745 switch (install_service(service)) {
\r
747 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
748 cleanup_nssm_service(service);
\r
752 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
753 cleanup_nssm_service(service);
\r
757 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
758 cleanup_nssm_service(service);
\r
762 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
763 cleanup_nssm_service(service);
\r
767 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
768 cleanup_nssm_service(service);
\r
772 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
773 cleanup_nssm_service(service);
\r
777 update_hooks(service->name);
\r
779 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
780 cleanup_nssm_service(service);
\r
784 /* Remove the service */
\r
785 int remove(HWND window) {
\r
786 if (! window) return 1;
\r
788 /* See if it works */
\r
789 nssm_service_t *service = alloc_nssm_service();
\r
791 /* Get service name */
\r
792 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
793 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
794 cleanup_nssm_service(service);
\r
799 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
800 cleanup_nssm_service(service);
\r
805 switch (remove_service(service)) {
\r
807 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
808 cleanup_nssm_service(service);
\r
812 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
813 cleanup_nssm_service(service);
\r
817 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
818 cleanup_nssm_service(service);
\r
822 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
823 cleanup_nssm_service(service);
\r
827 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
828 cleanup_nssm_service(service);
\r
832 int edit(HWND window, nssm_service_t *orig_service) {
\r
833 if (! window) return 1;
\r
835 nssm_service_t *service = alloc_nssm_service();
\r
837 int ret = configure(window, service, orig_service);
\r
838 if (ret) return ret;
\r
841 switch (edit_service(service, true)) {
\r
843 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
844 cleanup_nssm_service(service);
\r
848 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
849 cleanup_nssm_service(service);
\r
853 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
854 cleanup_nssm_service(service);
\r
859 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
860 cleanup_nssm_service(service);
\r
864 update_hooks(service->name);
\r
866 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
867 cleanup_nssm_service(service);
\r
871 static TCHAR *browse_filter(int message) {
\r
873 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
874 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
875 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
876 default: return _T("*.*");
\r
880 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
882 case WM_INITDIALOG:
\r
889 /* Browse for application */
\r
890 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
891 if (! window) return;
\r
894 size_t bufsize = 256;
\r
895 size_t len = bufsize;
\r
899 ZeroMemory(&ofn, sizeof(ofn));
\r
900 ofn.lStructSize = sizeof(ofn);
\r
901 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
902 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
903 if (ofn.lpstrFilter) {
\r
904 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
906 /* "Applications" + NULL + "*.exe" + NULL */
\r
907 va_start(arg, flags);
\r
908 while (i = va_arg(arg, int)) {
\r
909 TCHAR *localised = message_string(i);
\r
910 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
911 len += _tcslen(localised) + 1;
\r
912 LocalFree(localised);
\r
913 TCHAR *filter = browse_filter(i);
\r
914 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
915 len += _tcslen(filter) + 1;
\r
918 /* Remainder of the buffer is already zeroed */
\r
920 ofn.lpstrFile = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, PATH_LENGTH * sizeof(TCHAR));
\r
921 if (ofn.lpstrFile) {
\r
922 if (flags & OFN_NOVALIDATE) {
\r
923 /* Directory hack. */
\r
924 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
925 ofn.nMaxFile = DIR_LENGTH;
\r
928 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T("%s"), current);
\r
929 ofn.nMaxFile = PATH_LENGTH;
\r
932 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
933 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
935 if (GetOpenFileName(&ofn)) {
\r
936 /* Directory hack. */
\r
937 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
938 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
940 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
941 if (ofn.lpstrFile) HeapFree(GetProcessHeap(), 0, ofn.lpstrFile);
\r
944 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
946 case WM_INITDIALOG:
\r
949 /* Button was pressed or control was controlled. */
\r
952 TCHAR buffer[PATH_LENGTH];
\r
953 unsigned char enabled;
\r
955 switch (LOWORD(w)) {
\r
956 /* Browse for application. */
\r
958 dlg = GetDlgItem(tab, IDC_PATH);
\r
959 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
960 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
961 /* Fill in startup directory if it wasn't already specified. */
\r
962 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
964 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
965 strip_basename(buffer);
\r
966 SetDlgItemText(tab, IDC_DIR, buffer);
\r
970 /* Browse for startup directory. */
\r
971 case IDC_BROWSE_DIR:
\r
972 dlg = GetDlgItem(tab, IDC_DIR);
\r
973 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
974 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
978 case IDC_LOCALSYSTEM:
\r
979 set_logon_enabled(0);
\r
983 set_logon_enabled(1);
\r
987 case IDC_AFFINITY_ALL:
\r
988 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
990 set_affinity_enabled(enabled);
\r
993 /* Shutdown methods. */
\r
994 case IDC_METHOD_CONSOLE:
\r
995 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
998 case IDC_METHOD_WINDOW:
\r
999 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
1002 case IDC_METHOD_THREADS:
\r
1003 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
1006 /* Browse for stdin. */
\r
1007 case IDC_BROWSE_STDIN:
\r
1008 dlg = GetDlgItem(tab, IDC_STDIN);
\r
1009 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
1010 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1013 /* Browse for stdout. */
\r
1014 case IDC_BROWSE_STDOUT:
\r
1015 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
1016 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1017 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1018 /* Fill in stderr if it wasn't already specified. */
\r
1019 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1020 if (! buffer[0]) {
\r
1021 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
1022 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
1026 /* Browse for stderr. */
\r
1027 case IDC_BROWSE_STDERR:
\r
1028 dlg = GetDlgItem(tab, IDC_STDERR);
\r
1029 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
1030 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1035 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
1037 set_rotation_enabled(enabled);
\r
1041 case IDC_HOOK_EVENT:
\r
1042 if (HIWORD(w) == CBN_SELCHANGE) set_hook_tab((int) SendMessage(GetDlgItem(tab, IDC_HOOK_EVENT), CB_GETCURSEL, 0, 0), 0, false);
\r
1045 /* Hook action. */
\r
1046 case IDC_HOOK_ACTION:
\r
1047 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
1050 /* Browse for hook. */
\r
1051 case IDC_BROWSE_HOOK:
\r
1052 dlg = GetDlgItem(tab, IDC_HOOK);
\r
1053 GetDlgItemText(tab, IDC_HOOK, buffer, _countof(buffer));
\r
1054 browse(dlg, _T(""), OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
1059 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
1068 /* Install/remove dialogue callback */
\r
1069 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
1070 nssm_service_t *service;
\r
1072 switch (message) {
\r
1073 /* Creating the dialogue */
\r
1074 case WM_INITDIALOG:
\r
1075 service = (nssm_service_t *) l;
\r
1077 SetFocus(GetDlgItem(window, IDC_NAME));
\r
1083 tabs = GetDlgItem(window, IDC_TAB1);
\r
1084 if (! tabs) return 0;
\r
1086 /* Set up tabs. */
\r
1088 ZeroMemory(&tab, sizeof(tab));
\r
1089 tab.mask = TCIF_TEXT;
\r
1093 /* Application tab. */
\r
1094 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
1095 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
1096 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1097 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
1098 if (service->native) {
\r
1099 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
1100 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
1101 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
1103 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
1104 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
1106 /* Details tab. */
\r
1107 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
1108 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1109 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
1110 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
1111 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
1113 /* Set defaults. */
\r
1114 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
1115 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
1116 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
1117 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
1118 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
1119 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
1122 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
1123 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1124 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
1125 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
1126 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
1128 /* Set defaults. */
\r
1129 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
1130 set_logon_enabled(0);
\r
1132 /* Dependencies tab. */
\r
1133 tab.pszText = message_string(NSSM_GUI_TAB_DEPENDENCIES);
\r
1134 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1135 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DEPENDENCIES, (LPARAM) &tab);
\r
1136 tablist[NSSM_TAB_DEPENDENCIES] = dialog(MAKEINTRESOURCE(IDD_DEPENDENCIES), window, tab_dlg);
\r
1137 ShowWindow(tablist[NSSM_TAB_DEPENDENCIES], SW_HIDE);
\r
1139 /* Remaining tabs are only for services we manage. */
\r
1140 if (service->native) return 1;
\r
1142 /* Process tab. */
\r
1143 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
1144 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1145 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
1146 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
1147 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
1149 /* Set defaults. */
\r
1150 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
1151 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
1152 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
1153 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
1154 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
1155 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
1156 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
1157 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
1159 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1161 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
1163 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
1164 for (i = 0; i < n; i++) {
\r
1166 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
1167 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
1172 The box is high enough for four rows. It is wide enough for eight
\r
1173 columns without scrolling. With scrollbars it shrinks to two rows.
\r
1174 Note that the above only holds if we set the column width BEFORE
\r
1175 adding the strings.
\r
1178 int columns = (n - 1) / 4;
\r
1180 GetWindowRect(list, &rect);
\r
1181 int width = rect.right - rect.left;
\r
1182 width -= (7 - columns) * 16;
\r
1183 int height = rect.bottom - rect.top;
\r
1184 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
\r
1185 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
1187 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
1189 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
1190 set_affinity_enabled(0);
\r
1192 /* Shutdown tab. */
\r
1193 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
1194 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1195 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
1196 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
1197 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
1199 /* Set defaults. */
\r
1200 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
1201 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
1202 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
1203 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
1204 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
1205 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1206 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1207 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_PROCESS_TREE, BM_SETCHECK, BST_CHECKED, 1);
\r
1209 /* Restart tab. */
\r
1210 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1211 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1212 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1213 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1214 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1216 /* Set defaults. */
\r
1217 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1218 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1219 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1220 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1221 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1222 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1223 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1224 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1227 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1228 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1229 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1230 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1231 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1233 /* Rotation tab. */
\r
1234 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1235 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1236 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1237 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1238 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1240 /* Set defaults. */
\r
1241 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1242 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1243 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1244 set_rotation_enabled(0);
\r
1246 /* Environment tab. */
\r
1247 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1248 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1249 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1250 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1251 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1254 tab.pszText = message_string(NSSM_GUI_TAB_HOOKS);
\r
1255 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1256 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_HOOKS, (LPARAM) &tab);
\r
1257 tablist[NSSM_TAB_HOOKS] = dialog(MAKEINTRESOURCE(IDD_HOOKS), window, tab_dlg);
\r
1258 ShowWindow(tablist[NSSM_TAB_HOOKS], SW_HIDE);
\r
1260 /* Set defaults. */
\r
1261 combo = GetDlgItem(tablist[NSSM_TAB_HOOKS], IDC_HOOK_EVENT);
\r
1262 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_START));
\r
1263 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_STOP));
\r
1264 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_EXIT));
\r
1265 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_POWER));
\r
1266 SendMessage(combo, CB_INSERTSTRING, -1, (LPARAM) message_string(NSSM_GUI_HOOK_EVENT_ROTATE));
\r
1267 SendDlgItemMessage(tablist[NSSM_TAB_HOOKS], IDC_REDIRECT_HOOK, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1268 if (_tcslen(service->name)) {
\r
1269 TCHAR hook_name[HOOK_NAME_LENGTH];
\r
1270 TCHAR cmd[CMD_LENGTH];
\r
1271 for (i = 0; hook_event_strings[i]; i++) {
\r
1272 const TCHAR *hook_event = hook_event_strings[i];
\r
1274 for (j = 0; hook_action_strings[j]; j++) {
\r
1275 const TCHAR *hook_action = hook_action_strings[j];
\r
1276 if (! valid_hook_name(hook_event, hook_action, true)) continue;
\r
1277 if (get_hook(service->name, hook_event, hook_action, cmd, sizeof(cmd))) continue;
\r
1278 if (hook_env(hook_event, hook_action, hook_name, _countof(hook_name)) < 0) continue;
\r
1279 SetEnvironmentVariable(hook_name, cmd);
\r
1283 set_hook_tab(0, 0, false);
\r
1289 NMHDR *notification;
\r
1291 notification = (NMHDR *) l;
\r
1292 switch (notification->code) {
\r
1293 case TCN_SELCHANGE:
\r
1297 tabs = GetDlgItem(window, IDC_TAB1);
\r
1298 if (! tabs) return 0;
\r
1300 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1301 if (selection != selected_tab) {
\r
1302 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1303 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1304 SetFocus(GetDlgItem(window, IDOK));
\r
1305 selected_tab = selection;
\r
1312 /* Button was pressed or control was controlled */
\r
1314 switch (LOWORD(w)) {
\r
1317 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1318 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1320 else if (! install(window)) PostQuitMessage(0);
\r
1323 /* Cancel button */
\r
1325 DestroyWindow(window);
\r
1328 /* Remove button */
\r
1330 if (! remove(window)) PostQuitMessage(0);
\r
1335 /* Window closing */
\r
1337 DestroyWindow(window);
\r
1340 PostQuitMessage(0);
\r