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 = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, PATH_LENGTH * sizeof(TCHAR));
\r
751 if (flags & OFN_NOVALIDATE) {
\r
752 /* Directory hack. */
\r
753 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
754 ofn.nMaxFile = DIR_LENGTH;
\r
757 _sntprintf_s(ofn.lpstrFile, PATH_LENGTH, _TRUNCATE, _T("%s"), current);
\r
758 ofn.nMaxFile = PATH_LENGTH;
\r
761 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
762 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
764 if (GetOpenFileName(&ofn)) {
\r
765 /* Directory hack. */
\r
766 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
767 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
769 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
770 if (ofn.lpstrFile) HeapFree(GetProcessHeap(), 0, ofn.lpstrFile);
773 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
775 case WM_INITDIALOG:
\r
778 /* Button was pressed or control was controlled. */
\r
781 TCHAR buffer[PATH_LENGTH];
\r
782 unsigned char enabled;
\r
784 switch (LOWORD(w)) {
\r
785 /* Browse for application. */
\r
787 dlg = GetDlgItem(tab, IDC_PATH);
\r
788 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
789 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
790 /* Fill in startup directory if it wasn't already specified. */
\r
791 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
793 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
794 strip_basename(buffer);
\r
795 SetDlgItemText(tab, IDC_DIR, buffer);
\r
799 /* Browse for startup directory. */
\r
800 case IDC_BROWSE_DIR:
\r
801 dlg = GetDlgItem(tab, IDC_DIR);
\r
802 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
803 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
807 case IDC_LOCALSYSTEM:
\r
808 set_logon_enabled(0);
\r
812 set_logon_enabled(1);
\r
816 case IDC_AFFINITY_ALL:
\r
817 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
819 set_affinity_enabled(enabled);
\r
822 /* Shutdown methods. */
\r
823 case IDC_METHOD_CONSOLE:
\r
824 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
827 case IDC_METHOD_WINDOW:
\r
828 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
831 case IDC_METHOD_THREADS:
\r
832 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
835 /* Browse for stdin. */
\r
836 case IDC_BROWSE_STDIN:
\r
837 dlg = GetDlgItem(tab, IDC_STDIN);
\r
838 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
839 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
842 /* Browse for stdout. */
\r
843 case IDC_BROWSE_STDOUT:
\r
844 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
845 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
846 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
847 /* Fill in stderr if it wasn't already specified. */
\r
848 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
850 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
851 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
855 /* Browse for stderr. */
\r
856 case IDC_BROWSE_STDERR:
\r
857 dlg = GetDlgItem(tab, IDC_STDERR);
\r
858 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
859 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
864 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
866 set_rotation_enabled(enabled);
\r
875 /* Install/remove dialogue callback */
\r
876 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
877 nssm_service_t *service;
\r
880 /* Creating the dialogue */
\r
881 case WM_INITDIALOG:
\r
882 service = (nssm_service_t *) l;
\r
884 SetFocus(GetDlgItem(window, IDC_NAME));
\r
890 tabs = GetDlgItem(window, IDC_TAB1);
\r
891 if (! tabs) return 0;
\r
895 ZeroMemory(&tab, sizeof(tab));
\r
896 tab.mask = TCIF_TEXT;
\r
900 /* Application tab. */
\r
901 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
902 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
903 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
904 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
905 if (service->native) {
\r
906 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
907 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
908 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
910 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
911 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
914 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
915 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
916 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
917 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
918 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
920 /* Set defaults. */
\r
921 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
922 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
923 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
924 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
925 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
926 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
929 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
930 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
931 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
932 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
933 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
935 /* Set defaults. */
\r
936 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
937 set_logon_enabled(0);
\r
939 /* Remaining tabs are only for services we manage. */
\r
940 if (service->native) return 1;
\r
943 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
944 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
945 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
946 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
947 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
949 /* Set defaults. */
\r
950 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
951 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
952 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
953 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
954 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
955 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
956 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
957 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
959 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
961 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
962 for (i = 0; i < n; i++) {
\r
964 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
965 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
970 The box is high enough for four rows. It is wide enough for eight
\r
971 columns without scrolling. With scrollbars it shrinks to two rows.
\r
972 Note that the above only holds if we set the column width BEFORE
976 int columns = (n - 1) / 4;
\r
978 GetWindowRect(list, &rect);
\r
979 int width = rect.right - rect.left;
980 width -= (7 - columns) * 16;
\r
981 int height = rect.bottom - rect.top;
\r
982 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
983 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
985 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
987 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
988 set_affinity_enabled(0);
\r
990 /* Shutdown tab. */
\r
991 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
992 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
993 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
994 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
995 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
997 /* Set defaults. */
\r
998 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
999 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
1000 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
1001 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
1002 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
1003 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
1004 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
1006 /* Restart tab. */
\r
1007 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1008 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1009 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1010 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1011 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1013 /* Set defaults. */
\r
1014 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1015 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1016 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1017 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1018 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1019 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1020 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1021 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1024 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1025 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1026 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1027 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1028 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1030 /* Rotation tab. */
\r
1031 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1032 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1033 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1034 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1035 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1037 /* Set defaults. */
\r
1038 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_ONLINE, BM_SETCHECK, BST_UNCHECKED, 0);
\r
1039 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1040 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1041 set_rotation_enabled(0);
\r
1043 /* Environment tab. */
\r
1044 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1045 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1046 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1047 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1048 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1054 NMHDR *notification;
\r
1056 notification = (NMHDR *) l;
\r
1057 switch (notification->code) {
\r
1058 case TCN_SELCHANGE:
\r
1062 tabs = GetDlgItem(window, IDC_TAB1);
\r
1063 if (! tabs) return 0;
\r
1065 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1066 if (selection != selected_tab) {
\r
1067 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1068 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1069 SetFocus(GetDlgItem(window, IDOK));
\r
1070 selected_tab = selection;
\r
1077 /* Button was pressed or control was controlled */
\r
1079 switch (LOWORD(w)) {
\r
1082 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1083 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1085 else if (! install(window)) PostQuitMessage(0);
\r
1088 /* Cancel button */
\r
1090 DestroyWindow(window);
\r
1093 /* Remove button */
\r
1095 if (! remove(window)) PostQuitMessage(0);
\r
1100 /* Window closing */
\r
1102 DestroyWindow(window);
\r
1105 PostQuitMessage(0);
\r