3 static enum { NSSM_TAB_APPLICATION, NSSM_TAB_DETAILS, NSSM_TAB_LOGON, NSSM_TAB_PROCESS, NSSM_TAB_SHUTDOWN, NSSM_TAB_EXIT, NSSM_TAB_IO, NSSM_TAB_ROTATION, NSSM_TAB_ENVIRONMENT, NSSM_NUM_TABS };
\r
4 static HWND tablist[NSSM_NUM_TABS];
\r
5 static int selected_tab;
\r
7 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function, LPARAM l) {
\r
8 /* The caller will deal with GetLastError()... */
\r
9 HRSRC resource = FindResourceEx(0, RT_DIALOG, templ, GetUserDefaultLangID());
\r
11 if (GetLastError() != ERROR_RESOURCE_LANG_NOT_FOUND) return 0;
\r
12 resource = FindResourceEx(0, RT_DIALOG, templ, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
\r
13 if (! resource) return 0;
\r
16 HGLOBAL ret = LoadResource(0, resource);
\r
17 if (! ret) return 0;
\r
19 return CreateDialogIndirectParam(0, (DLGTEMPLATE *) ret, parent, function, l);
\r
22 static HWND dialog(const TCHAR *templ, HWND parent, DLGPROC function) {
\r
23 return dialog(templ, parent, function, 0);
\r
26 int nssm_gui(int resource, nssm_service_t *service) {
\r
28 HWND dlg = dialog(MAKEINTRESOURCE(resource), 0, nssm_dlg, (LPARAM) service);
\r
30 popup_message(0, MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));
\r
34 /* Load the icon. */
\r
35 HANDLE icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), 0);
\r
36 if (icon) SendMessage(dlg, WM_SETICON, ICON_SMALL, (LPARAM) icon);
\r
37 icon = LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_NSSM), IMAGE_ICON, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), 0);
\r
38 if (icon) SendMessage(dlg, WM_SETICON, ICON_BIG, (LPARAM) icon);
\r
40 /* Remember what the window is for. */
\r
41 SetWindowLongPtr(dlg, GWLP_USERDATA, (LONG_PTR) resource);
\r
43 /* Display the window */
\r
45 ShowWindow(dlg, SW_SHOW);
\r
47 /* Set service name if given */
\r
48 if (service->name[0]) {
\r
49 SetDlgItemText(dlg, IDC_NAME, service->name);
\r
50 /* No point making user click remove if the name is already entered */
\r
51 if (resource == IDD_REMOVE) {
\r
52 HWND button = GetDlgItem(dlg, IDC_REMOVE);
\r
54 SendMessage(button, WM_LBUTTONDOWN, 0, 0);
\r
55 SendMessage(button, WM_LBUTTONUP, 0, 0);
\r
60 if (resource == IDD_EDIT) {
\r
61 /* We'll need the service handle later. */
\r
62 SetWindowLongPtr(dlg, DWLP_USER, (LONG_PTR) service);
\r
64 /* Service name can't be edited. */
\r
65 EnableWindow(GetDlgItem(dlg, IDC_NAME), 0);
\r
66 SetFocus(GetDlgItem(dlg, IDOK));
\r
68 /* Set existing details. */
\r
72 /* Application tab. */
\r
73 if (service->native) SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->image);
\r
74 else SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe);
\r
75 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir);
\r
76 SetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags);
\r
79 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname);
\r
80 SetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description);
\r
81 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
82 SendMessage(combo, CB_SETCURSEL, service->startup, 0);
\r
85 if (service->username) {
\r
86 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_ACCOUNT);
\r
87 SetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username);
\r
88 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), 0);
\r
89 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), 1);
\r
90 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), 1);
\r
91 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), 1);
\r
94 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
95 if (service->type & SERVICE_INTERACTIVE_PROCESS) SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_SETCHECK, BST_CHECKED, 0);
\r
99 if (service->priority) {
\r
100 int priority = priority_constant_to_index(service->priority);
\r
101 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
102 SendMessage(combo, CB_SETCURSEL, priority, 0);
\r
105 if (service->affinity) {
\r
106 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
107 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_UNCHECKED, 0);
\r
108 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), 1);
\r
110 DWORD_PTR affinity, system_affinity;
\r
111 if (GetProcessAffinityMask(GetCurrentProcess(), &affinity, &system_affinity)) {
\r
112 if ((service->affinity & (__int64) system_affinity) != service->affinity) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_AFFINITY);
\r
115 for (int i = 0; i < num_cpus(); i++) {
\r
116 if (! (service->affinity & (1LL << (__int64) i))) SendMessage(list, LB_SETSEL, 0, i);
\r
120 /* Shutdown tab. */
\r
121 if (! (service->stop_method & NSSM_STOP_METHOD_CONSOLE)) {
\r
122 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
123 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE), 0);
\r
125 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, service->kill_console_delay, 0);
\r
126 if (! (service->stop_method & NSSM_STOP_METHOD_WINDOW)) {
\r
127 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_UNCHECKED, 0);
\r
128 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW), 0);
\r
130 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, service->kill_window_delay, 0);
\r
131 if (! (service->stop_method & NSSM_STOP_METHOD_THREADS)) {
\r
132 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_UNCHECKED, 0);
\r
133 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS), 0);
\r
135 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, service->kill_threads_delay, 0);
\r
136 if (! (service->stop_method & NSSM_STOP_METHOD_TERMINATE)) {
\r
137 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
141 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, service->throttle_delay, 0);
\r
142 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
143 SendMessage(combo, CB_SETCURSEL, service->default_exit_action, 0);
\r
144 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, service->restart_delay, 0);
\r
147 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDIN, service->stdin_path);
\r
148 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDOUT, service->stdout_path);
\r
149 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDERR, service->stderr_path);
\r
151 /* Rotation tab. */
\r
152 if (service->stdout_disposition == CREATE_ALWAYS) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_SETCHECK, BST_CHECKED, 0);
\r
153 if (service->rotate_files) {
\r
154 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_SETCHECK, BST_CHECKED, 0);
\r
155 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), 1);
\r
156 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), 1);
\r
157 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), 1);
\r
159 if (service->rotate_stdout_online || service->rotate_stderr_online) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_CHECKED, 0);
\r
160 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);
\r
161 if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);
\r
163 /* Check if advanced settings are in use. */
\r
164 if (service->stdout_disposition ^ service->stderr_disposition || service->stdout_disposition & ~CREATE_ALWAYS || service->stderr_disposition & ~CREATE_ALWAYS) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_STDIO);
\r
165 if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);
\r
167 /* Environment tab. */
\r
169 unsigned long envlen;
\r
170 if (service->env_extralen) {
\r
171 env = service->env_extra;
\r
172 envlen = service->env_extralen;
\r
175 env = service->env;
\r
176 envlen = service->envlen;
\r
177 if (envlen) SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_SETCHECK, BST_CHECKED, 0);
\r
182 unsigned long newlen;
\r
183 if (format_environment(env, envlen, &formatted, &newlen)) {
\r
184 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()"));
\r
187 SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted);
\r
188 HeapFree(GetProcessHeap(), 0, formatted);
\r
191 if (service->envlen && service->env_extralen) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT);
\r
196 while (GetMessage(&message, 0, 0, 0)) {
\r
197 if (IsDialogMessage(dlg, &message)) continue;
\r
198 TranslateMessage(&message);
\r
199 DispatchMessage(&message);
\r
202 return (int) message.wParam;
\r
205 void centre_window(HWND window) {
\r
207 RECT size, desktop_size;
\r
208 unsigned long x, y;
\r
210 if (! window) return;
\r
212 /* Find window size */
\r
213 if (! GetWindowRect(window, &size)) return;
\r
215 /* Find desktop window */
\r
216 desktop = GetDesktopWindow();
\r
217 if (! desktop) return;
\r
219 /* Find desktop window size */
\r
220 if (! GetWindowRect(desktop, &desktop_size)) return;
\r
222 /* Centre window */
\r
223 x = (desktop_size.right - size.right) / 2;
\r
224 y = (desktop_size.bottom - size.bottom) / 2;
\r
225 MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);
\r
228 static inline void check_stop_method(nssm_service_t *service, unsigned long method, unsigned long control) {
\r
229 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) return;
\r
230 service->stop_method &= ~method;
\r
233 static inline void check_number(HWND tab, unsigned long control, unsigned long *timeout) {
\r
235 unsigned long configured = GetDlgItemInt(tab, control, &translated, 0);
\r
236 if (translated) *timeout = configured;
\r
239 static inline void set_timeout_enabled(unsigned long control, unsigned long dependent) {
\r
240 unsigned char enabled = 0;
\r
241 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
242 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], dependent), enabled);
\r
245 static inline void set_logon_enabled(unsigned char enabled) {
\r
246 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), ! enabled);
\r
247 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), enabled);
\r
248 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), enabled);
\r
249 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), enabled);
\r
252 static inline void set_affinity_enabled(unsigned char enabled) {
\r
253 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), enabled);
\r
256 static inline void set_rotation_enabled(unsigned char enabled) {
\r
257 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE), enabled);
\r
258 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), enabled);
\r
259 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);
\r
262 static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {
\r
263 if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;
\r
264 if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;
\r
265 popup_message(owner, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, name);
\r
266 ZeroMemory(buffer, len * sizeof(TCHAR));
\r
269 /* Set service parameters. */
\r
270 int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service) {
\r
271 if (! service) return 1;
\r
273 set_nssm_service_defaults(service);
\r
275 if (orig_service) {
\r
276 service->native = orig_service->native;
\r
277 service->handle = orig_service->handle;
\r
280 /* Get service name. */
\r
281 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
282 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
283 cleanup_nssm_service(service);
\r
287 /* Get executable name */
\r
288 if (! service->native) {
\r
289 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe, _countof(service->exe))) {
\r
290 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
\r
294 /* Get startup directory. */
\r
295 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir, _countof(service->dir))) {
\r
296 _sntprintf_s(service->dir, _countof(service->dir), _TRUNCATE, _T("%s"), service->exe);
\r
297 strip_basename(service->dir);
\r
301 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
\r
302 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags, _countof(service->flags))) {
\r
303 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
\r
310 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME), WM_GETTEXTLENGTH, 0, 0)) {
\r
311 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname, _countof(service->displayname))) {
\r
312 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DISPLAYNAME);
\r
317 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION), WM_GETTEXTLENGTH, 0, 0)) {
\r
318 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description, _countof(service->description))) {
\r
319 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DESCRIPTION);
\r
324 HWND combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
325 service->startup = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
326 if (service->startup == CB_ERR) service->startup = 0;
\r
328 /* Get logon stuff. */
\r
329 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
330 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
331 service->type |= SERVICE_INTERACTIVE_PROCESS;
\r
333 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
334 service->username = 0;
\r
335 service->usernamelen = 0;
\r
336 if (service->password) {
\r
337 SecureZeroMemory(service->password, service->passwordlen);
\r
338 HeapFree(GetProcessHeap(), 0, service->password);
\r
340 service->password = 0;
\r
341 service->passwordlen = 0;
\r
345 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
346 if (! service->usernamelen) {
\r
347 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
350 service->usernamelen++;
\r
352 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
353 if (! service->username) {
\r
354 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
357 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
358 HeapFree(GetProcessHeap(), 0, service->username);
\r
359 service->username = 0;
\r
360 service->usernamelen = 0;
\r
361 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
366 Special case LOCALSYSTEM.
\r
367 Ignore the password if we're editing and the username hasn't changed.
\r
369 if (str_equiv(service->username, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
370 HeapFree(GetProcessHeap(), 0, service->username);
\r
371 service->username = 0;
\r
372 service->usernamelen = 0;
\r
376 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
377 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
379 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
380 if (! service->passwordlen) {
\r
381 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
384 if (passwordlen != service->passwordlen) {
\r
385 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
388 service->passwordlen++;
\r
390 /* Temporary buffer for password validation. */
\r
391 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
393 HeapFree(GetProcessHeap(), 0, service->username);
\r
394 service->username = 0;
\r
395 service->usernamelen = 0;
\r
396 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
400 /* Actual password buffer. */
\r
401 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
402 if (! service->password) {
\r
403 HeapFree(GetProcessHeap(), 0, password);
\r
404 HeapFree(GetProcessHeap(), 0, service->username);
\r
405 service->username = 0;
\r
406 service->usernamelen = 0;
\r
407 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
411 /* Get first password. */
\r
412 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
413 HeapFree(GetProcessHeap(), 0, password);
\r
414 SecureZeroMemory(service->password, service->passwordlen);
\r
415 HeapFree(GetProcessHeap(), 0, service->password);
\r
416 service->password = 0;
\r
417 service->passwordlen = 0;
\r
418 HeapFree(GetProcessHeap(), 0, service->username);
\r
419 service->username = 0;
\r
420 service->usernamelen = 0;
\r
421 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
425 /* Get confirmation. */
\r
426 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
427 SecureZeroMemory(password, service->passwordlen);
\r
428 HeapFree(GetProcessHeap(), 0, password);
\r
429 SecureZeroMemory(service->password, service->passwordlen);
\r
430 HeapFree(GetProcessHeap(), 0, service->password);
\r
431 service->password = 0;
\r
432 service->passwordlen = 0;
\r
433 HeapFree(GetProcessHeap(), 0, service->username);
\r
434 service->username = 0;
\r
435 service->usernamelen = 0;
\r
436 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
441 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
442 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
443 SecureZeroMemory(password, service->passwordlen);
\r
444 HeapFree(GetProcessHeap(), 0, password);
\r
445 SecureZeroMemory(service->password, service->passwordlen);
\r
446 HeapFree(GetProcessHeap(), 0, service->password);
\r
447 service->password = 0;
\r
448 service->passwordlen = 0;
\r
449 HeapFree(GetProcessHeap(), 0, service->username);
\r
450 service->username = 0;
\r
451 service->usernamelen = 0;
\r
458 /* Remaining tabs are only for services we manage. */
\r
459 if (service->native) return 0;
\r
461 /* Get process stuff. */
\r
462 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
463 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
465 service->affinity = 0LL;
\r
466 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
467 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
468 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
469 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
471 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
474 else if (selected < count) {
\r
475 for (int i = 0; i < count; i++) {
\r
476 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
481 /* Get stop method stuff. */
\r
482 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
483 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
484 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
485 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
486 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
487 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
488 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
490 /* Get exit action stuff. */
\r
491 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
492 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
493 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
494 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
495 check_number(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, &service->restart_delay);
\r
497 /* Get I/O stuff. */
\r
498 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
499 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
500 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
502 /* Override stdout and/or stderr. */
\r
503 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
504 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
505 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
508 /* Get rotation stuff. */
\r
509 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
510 service->rotate_files = true;
\r
511 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;
512 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
513 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
516 /* Get environment. */
\r
517 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
519 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
521 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
522 cleanup_nssm_service(service);
\r
526 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
527 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
528 HeapFree(GetProcessHeap(), 0, env);
\r
529 cleanup_nssm_service(service);
\r
534 unsigned long newlen;
\r
535 if (unformat_environment(env, envlen, &newenv, &newlen)) {
\r
536 HeapFree(GetProcessHeap(), 0, env);
\r
537 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
538 cleanup_nssm_service(service);
\r
542 HeapFree(GetProcessHeap(), 0, env);
\r
546 /* Test the environment is valid. */
\r
547 if (test_environment(env)) {
\r
548 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
549 HeapFree(GetProcessHeap(), 0, env);
\r
550 cleanup_nssm_service(service);
\r
554 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
555 service->env = env;
\r
556 service->envlen = envlen;
\r
559 service->env_extra = env;
\r
560 service->env_extralen = envlen;
\r
567 /* Install the service. */
\r
568 int install(HWND window) {
\r
569 if (! window) return 1;
\r
571 nssm_service_t *service = alloc_nssm_service();
\r
573 int ret = configure(window, service, 0);
\r
574 if (ret) return ret;
\r
577 /* See if it works. */
\r
578 switch (install_service(service)) {
\r
580 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
581 cleanup_nssm_service(service);
\r
585 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
586 cleanup_nssm_service(service);
\r
590 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
591 cleanup_nssm_service(service);
\r
595 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
596 cleanup_nssm_service(service);
\r
600 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
601 cleanup_nssm_service(service);
\r
605 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
606 cleanup_nssm_service(service);
\r
610 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
611 cleanup_nssm_service(service);
\r
615 /* Remove the service */
\r
616 int remove(HWND window) {
\r
617 if (! window) return 1;
\r
619 /* See if it works */
\r
620 nssm_service_t *service = alloc_nssm_service();
\r
622 /* Get service name */
\r
623 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
624 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
625 cleanup_nssm_service(service);
\r
630 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
631 cleanup_nssm_service(service);
\r
636 switch (remove_service(service)) {
\r
638 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
639 cleanup_nssm_service(service);
\r
643 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
644 cleanup_nssm_service(service);
\r
648 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
650 cleanup_nssm_service(service);
\r
653 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
654 cleanup_nssm_service(service);
\r
658 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
659 cleanup_nssm_service(service);
\r
663 int edit(HWND window, nssm_service_t *orig_service) {
\r
664 if (! window) return 1;
\r
666 nssm_service_t *service = alloc_nssm_service();
\r
668 int ret = configure(window, service, orig_service);
\r
669 if (ret) return ret;
\r
672 switch (edit_service(service, true)) {
\r
674 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
675 cleanup_nssm_service(service);
\r
679 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
680 cleanup_nssm_service(service);
\r
684 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
685 cleanup_nssm_service(service);
\r
690 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
691 cleanup_nssm_service(service);
\r
695 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
696 cleanup_nssm_service(service);
\r
700 static TCHAR *browse_filter(int message) {
\r
702 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
703 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
704 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
705 default: return _T("*.*");
\r
709 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
711 case WM_INITDIALOG:
\r
718 /* Browse for application */
\r
719 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
720 if (! window) return;
\r
723 size_t bufsize = 256;
\r
724 size_t len = bufsize;
\r
728 ZeroMemory(&ofn, sizeof(ofn));
\r
729 ofn.lStructSize = sizeof(ofn);
\r
730 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
731 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
732 if (ofn.lpstrFilter) {
\r
733 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
735 /* "Applications" + NULL + "*.exe" + NULL */
\r
736 va_start(arg, flags);
\r
737 while (i = va_arg(arg, int)) {
\r
738 TCHAR *localised = message_string(i);
\r
739 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
740 len += _tcslen(localised) + 1;
\r
741 LocalFree(localised);
\r
742 TCHAR *filter = browse_filter(i);
\r
743 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
744 len += _tcslen(filter) + 1;
\r
747 /* Remainder of the buffer is already zeroed */
\r
749 ofn.lpstrFile = new TCHAR[PATH_LENGTH];
\r
750 if (flags & OFN_NOVALIDATE) {
\r
751 /* Directory hack. */
\r
752 _sntprintf_s(ofn.lpstrFile, _countof(ofn.lpstrFile), _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
753 ofn.nMaxFile = DIR_LENGTH;
\r
756 _sntprintf_s(ofn.lpstrFile, _countof(ofn.lpstrFile), _TRUNCATE, _T("%s"), current);
\r
757 ofn.nMaxFile = PATH_LENGTH;
\r
759 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
760 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
762 if (GetOpenFileName(&ofn)) {
\r
763 /* Directory hack. */
\r
764 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
765 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
767 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
769 delete[] ofn.lpstrFile;
\r
772 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
774 case WM_INITDIALOG:
\r
777 /* Button was pressed or control was controlled. */
\r
780 TCHAR buffer[PATH_LENGTH];
\r
781 unsigned char enabled;
\r
783 switch (LOWORD(w)) {
\r
784 /* Browse for application. */
\r
786 dlg = GetDlgItem(tab, IDC_PATH);
\r
787 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
788 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
789 /* Fill in startup directory if it wasn't already specified. */
\r
790 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
792 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
793 strip_basename(buffer);
\r
794 SetDlgItemText(tab, IDC_DIR, buffer);
\r
798 /* Browse for startup directory. */
\r
799 case IDC_BROWSE_DIR:
\r
800 dlg = GetDlgItem(tab, IDC_DIR);
\r
801 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
802 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
806 case IDC_LOCALSYSTEM:
\r
807 set_logon_enabled(0);
\r
811 set_logon_enabled(1);
\r
815 case IDC_AFFINITY_ALL:
\r
816 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
818 set_affinity_enabled(enabled);
\r
821 /* Shutdown methods. */
\r
822 case IDC_METHOD_CONSOLE:
\r
823 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
826 case IDC_METHOD_WINDOW:
\r
827 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
830 case IDC_METHOD_THREADS:
\r
831 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
834 /* Browse for stdin. */
\r
835 case IDC_BROWSE_STDIN:
\r
836 dlg = GetDlgItem(tab, IDC_STDIN);
\r
837 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
838 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
841 /* Browse for stdout. */
\r
842 case IDC_BROWSE_STDOUT:
\r
843 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
844 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
845 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
846 /* Fill in stderr if it wasn't already specified. */
\r
847 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
849 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
850 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
854 /* Browse for stderr. */
\r
855 case IDC_BROWSE_STDERR:
\r
856 dlg = GetDlgItem(tab, IDC_STDERR);
\r
857 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
858 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
863 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
865 set_rotation_enabled(enabled);
\r
874 /* Install/remove dialogue callback */
\r
875 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
876 nssm_service_t *service;
\r
879 /* Creating the dialogue */
\r
880 case WM_INITDIALOG:
\r
881 service = (nssm_service_t *) l;
\r
883 SetFocus(GetDlgItem(window, IDC_NAME));
\r
889 tabs = GetDlgItem(window, IDC_TAB1);
\r
890 if (! tabs) return 0;
\r
894 ZeroMemory(&tab, sizeof(tab));
\r
895 tab.mask = TCIF_TEXT;
\r
899 /* Application tab. */
\r
900 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
901 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
902 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
903 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
904 if (service->native) {
\r
905 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
906 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
907 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
909 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
910 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
913 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
914 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
915 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
916 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
917 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
919 /* Set defaults. */
\r
920 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
921 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
922 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
923 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
924 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
925 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
928 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
929 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
930 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
931 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
932 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
934 /* Set defaults. */
\r
935 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
936 set_logon_enabled(0);
\r
938 /* Remaining tabs are only for services we manage. */
\r
939 if (service->native) return 1;
\r
942 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
943 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
944 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
945 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
946 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
948 /* Set defaults. */
\r
949 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
950 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
951 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
952 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
953 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
954 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
955 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
956 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
958 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
960 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
961 for (i = 0; i < n; i++) {
\r
963 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
964 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
969 The box is high enough for four rows. It is wide enough for eight
\r
970 columns without scrolling. With scrollbars it shrinks to two rows.
\r
971 Note that the above only holds if we set the column width BEFORE
975 int columns = (n - 1) / 4;
\r
977 GetWindowRect(list, &rect);
\r
978 int width = rect.right - rect.left;
979 width -= (7 - columns) * 16;
\r
980 int height = rect.bottom - rect.top;
\r
981 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
982 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
984 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
986 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
987 set_affinity_enabled(0);
\r
989 /* Shutdown tab. */
\r
990 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
991 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
992 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
993 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
994 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
996 /* Set defaults. */
\r
997 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
998 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
999 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
1000 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
1001 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
1002 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1003 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1005 /* Restart tab. */
\r
1006 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1007 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1008 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1009 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1010 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1012 /* Set defaults. */
\r
1013 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1014 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1015 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1016 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1017 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1018 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1019 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1020 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1023 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1024 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1025 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1026 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1027 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1029 /* Rotation tab. */
\r
1030 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1031 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1032 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1033 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1034 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1036 /* Set defaults. */
\r
1037 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1038 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1039 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1040 set_rotation_enabled(0);
\r
1042 /* Environment tab. */
\r
1043 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1044 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1045 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1046 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1047 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1053 NMHDR *notification;
\r
1055 notification = (NMHDR *) l;
\r
1056 switch (notification->code) {
\r
1057 case TCN_SELCHANGE:
\r
1061 tabs = GetDlgItem(window, IDC_TAB1);
\r
1062 if (! tabs) return 0;
\r
1064 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1065 if (selection != selected_tab) {
\r
1066 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1067 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1068 SetFocus(GetDlgItem(window, IDOK));
\r
1069 selected_tab = selection;
\r
1076 /* Button was pressed or control was controlled */
\r
1078 switch (LOWORD(w)) {
\r
1081 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1082 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1084 else if (! install(window)) PostQuitMessage(0);
\r
1087 /* Cancel button */
\r
1089 DestroyWindow(window);
\r
1092 /* Remove button */
\r
1094 if (! remove(window)) PostQuitMessage(0);
\r
1099 /* Window closing */
\r
1101 DestroyWindow(window);
\r
1104 PostQuitMessage(0);
\r