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[MAX_PATH];
\r
750 if (flags & OFN_NOVALIDATE) {
\r
751 /* Directory hack. */
\r
752 _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
754 else _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T("%s"), current);
\r
755 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
756 ofn.nMaxFile = MAX_PATH;
\r
757 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
759 if (GetOpenFileName(&ofn)) {
\r
760 /* Directory hack. */
\r
761 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
762 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
764 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
766 delete[] ofn.lpstrFile;
\r
769 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
771 case WM_INITDIALOG:
\r
774 /* Button was pressed or control was controlled. */
\r
777 TCHAR buffer[MAX_PATH];
\r
778 unsigned char enabled;
\r
780 switch (LOWORD(w)) {
\r
781 /* Browse for application. */
\r
783 dlg = GetDlgItem(tab, IDC_PATH);
\r
784 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
785 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
786 /* Fill in startup directory if it wasn't already specified. */
\r
787 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
789 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
790 strip_basename(buffer);
\r
791 SetDlgItemText(tab, IDC_DIR, buffer);
\r
795 /* Browse for startup directory. */
\r
796 case IDC_BROWSE_DIR:
\r
797 dlg = GetDlgItem(tab, IDC_DIR);
\r
798 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
799 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
803 case IDC_LOCALSYSTEM:
\r
804 set_logon_enabled(0);
\r
808 set_logon_enabled(1);
\r
812 case IDC_AFFINITY_ALL:
\r
813 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
815 set_affinity_enabled(enabled);
\r
818 /* Shutdown methods. */
\r
819 case IDC_METHOD_CONSOLE:
\r
820 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
823 case IDC_METHOD_WINDOW:
\r
824 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
827 case IDC_METHOD_THREADS:
\r
828 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
831 /* Browse for stdin. */
\r
832 case IDC_BROWSE_STDIN:
\r
833 dlg = GetDlgItem(tab, IDC_STDIN);
\r
834 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
835 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
838 /* Browse for stdout. */
\r
839 case IDC_BROWSE_STDOUT:
\r
840 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
841 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
842 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
843 /* Fill in stderr if it wasn't already specified. */
\r
844 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
846 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
847 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
851 /* Browse for stderr. */
\r
852 case IDC_BROWSE_STDERR:
\r
853 dlg = GetDlgItem(tab, IDC_STDERR);
\r
854 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
855 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
860 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
862 set_rotation_enabled(enabled);
\r
871 /* Install/remove dialogue callback */
\r
872 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
873 nssm_service_t *service;
\r
876 /* Creating the dialogue */
\r
877 case WM_INITDIALOG:
\r
878 service = (nssm_service_t *) l;
\r
880 SetFocus(GetDlgItem(window, IDC_NAME));
\r
886 tabs = GetDlgItem(window, IDC_TAB1);
\r
887 if (! tabs) return 0;
\r
891 ZeroMemory(&tab, sizeof(tab));
\r
892 tab.mask = TCIF_TEXT;
\r
896 /* Application tab. */
\r
897 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
898 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
899 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
900 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
901 if (service->native) {
\r
902 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
903 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
904 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
906 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
907 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
910 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
911 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
912 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
913 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
914 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
916 /* Set defaults. */
\r
917 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
918 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
919 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
920 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
921 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
922 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
925 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
926 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
927 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
928 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
929 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
931 /* Set defaults. */
\r
932 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
933 set_logon_enabled(0);
\r
935 /* Remaining tabs are only for services we manage. */
\r
936 if (service->native) return 1;
\r
939 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
940 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
941 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
942 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
943 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
945 /* Set defaults. */
\r
946 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
947 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
948 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
949 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
950 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
951 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
952 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
953 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
955 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
957 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
958 for (i = 0; i < n; i++) {
\r
960 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
961 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
966 The box is high enough for four rows. It is wide enough for eight
\r
967 columns without scrolling. With scrollbars it shrinks to two rows.
\r
968 Note that the above only holds if we set the column width BEFORE
972 int columns = (n - 1) / 4;
\r
974 GetWindowRect(list, &rect);
\r
975 int width = rect.right - rect.left;
976 width -= (7 - columns) * 16;
\r
977 int height = rect.bottom - rect.top;
\r
978 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
979 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
981 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
983 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
984 set_affinity_enabled(0);
\r
986 /* Shutdown tab. */
\r
987 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
988 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
989 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
990 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
991 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
993 /* Set defaults. */
\r
994 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
995 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
996 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
997 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
998 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
999 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1000 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1002 /* Restart tab. */
\r
1003 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1004 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1005 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1006 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1007 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1009 /* Set defaults. */
\r
1010 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1011 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1012 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1013 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1014 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1015 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1016 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1017 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1020 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1021 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1022 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1023 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1024 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1026 /* Rotation tab. */
\r
1027 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1028 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1029 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1030 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1031 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1033 /* Set defaults. */
\r
1034 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1035 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1036 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1037 set_rotation_enabled(0);
\r
1039 /* Environment tab. */
\r
1040 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1041 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1042 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1043 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1044 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1050 NMHDR *notification;
\r
1052 notification = (NMHDR *) l;
\r
1053 switch (notification->code) {
\r
1054 case TCN_SELCHANGE:
\r
1058 tabs = GetDlgItem(window, IDC_TAB1);
\r
1059 if (! tabs) return 0;
\r
1061 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1062 if (selection != selected_tab) {
\r
1063 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1064 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1065 SetFocus(GetDlgItem(window, IDOK));
\r
1066 selected_tab = selection;
\r
1073 /* Button was pressed or control was controlled */
\r
1075 switch (LOWORD(w)) {
\r
1078 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1079 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1081 else if (! install(window)) PostQuitMessage(0);
\r
1084 /* Cancel button */
\r
1086 DestroyWindow(window);
\r
1089 /* Remove button */
\r
1091 if (! remove(window)) PostQuitMessage(0);
\r
1096 /* Window closing */
\r
1098 DestroyWindow(window);
\r
1101 PostQuitMessage(0);
\r