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
146 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDIN, service->stdin_path);
\r
147 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDOUT, service->stdout_path);
\r
148 SetDlgItemText(tablist[NSSM_TAB_IO], IDC_STDERR, service->stderr_path);
\r
150 /* Rotation tab. */
\r
151 if (service->stdout_disposition == CREATE_ALWAYS) SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_SETCHECK, BST_CHECKED, 0);
\r
152 if (service->rotate_files) {
\r
153 SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_SETCHECK, BST_CHECKED, 0);
\r
154 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), 1);
\r
155 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), 1);
\r
157 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);
\r
158 if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);
\r
160 /* Check if advanced settings are in use. */
\r
161 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
162 if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);
\r
164 /* Environment tab. */
\r
166 unsigned long envlen;
\r
167 if (service->env_extralen) {
\r
168 env = service->env_extra;
\r
169 envlen = service->env_extralen;
\r
172 env = service->env;
\r
173 envlen = service->envlen;
\r
174 if (envlen) SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_SETCHECK, BST_CHECKED, 0);
\r
179 unsigned long newlen;
\r
180 if (format_environment(env, envlen, &formatted, &newlen)) {
\r
181 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()"));
\r
184 SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted);
\r
185 HeapFree(GetProcessHeap(), 0, formatted);
\r
188 if (service->envlen && service->env_extralen) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT);
\r
193 while (GetMessage(&message, 0, 0, 0)) {
\r
194 if (IsDialogMessage(dlg, &message)) continue;
\r
195 TranslateMessage(&message);
\r
196 DispatchMessage(&message);
\r
199 return (int) message.wParam;
\r
202 void centre_window(HWND window) {
\r
204 RECT size, desktop_size;
\r
205 unsigned long x, y;
\r
207 if (! window) return;
\r
209 /* Find window size */
\r
210 if (! GetWindowRect(window, &size)) return;
\r
212 /* Find desktop window */
\r
213 desktop = GetDesktopWindow();
\r
214 if (! desktop) return;
\r
216 /* Find desktop window size */
\r
217 if (! GetWindowRect(desktop, &desktop_size)) return;
\r
219 /* Centre window */
\r
220 x = (desktop_size.right - size.right) / 2;
\r
221 y = (desktop_size.bottom - size.bottom) / 2;
\r
222 MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);
\r
225 static inline void check_stop_method(nssm_service_t *service, unsigned long method, unsigned long control) {
\r
226 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) return;
\r
227 service->stop_method &= ~method;
\r
230 static inline void check_number(HWND tab, unsigned long control, unsigned long *timeout) {
\r
232 unsigned long configured = GetDlgItemInt(tab, control, &translated, 0);
\r
233 if (translated) *timeout = configured;
\r
236 static inline void set_timeout_enabled(unsigned long control, unsigned long dependent) {
\r
237 unsigned char enabled = 0;
\r
238 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
239 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], dependent), enabled);
\r
242 static inline void set_logon_enabled(unsigned char enabled) {
\r
243 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), ! enabled);
\r
244 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), enabled);
\r
245 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), enabled);
\r
246 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), enabled);
\r
249 static inline void set_affinity_enabled(unsigned char enabled) {
\r
250 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), enabled);
\r
253 static inline void set_rotation_enabled(unsigned char enabled) {
\r
254 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), enabled);
\r
255 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);
\r
258 static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {
\r
259 if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;
\r
260 if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;
\r
261 popup_message(owner, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, name);
\r
262 ZeroMemory(buffer, len * sizeof(TCHAR));
\r
265 /* Set service parameters. */
\r
266 int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service) {
\r
267 if (! service) return 1;
\r
269 set_nssm_service_defaults(service);
\r
271 if (orig_service) {
\r
272 service->native = orig_service->native;
\r
273 service->handle = orig_service->handle;
\r
276 /* Get service name. */
\r
277 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
278 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
279 cleanup_nssm_service(service);
\r
283 /* Get executable name */
\r
284 if (! service->native) {
\r
285 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe, _countof(service->exe))) {
\r
286 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
\r
290 /* Get startup directory. */
\r
291 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir, _countof(service->dir))) {
\r
292 _sntprintf_s(service->dir, _countof(service->dir), _TRUNCATE, _T("%s"), service->exe);
\r
293 strip_basename(service->dir);
\r
297 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
\r
298 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags, _countof(service->flags))) {
\r
299 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
\r
306 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME), WM_GETTEXTLENGTH, 0, 0)) {
\r
307 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname, _countof(service->displayname))) {
\r
308 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DISPLAYNAME);
\r
313 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION), WM_GETTEXTLENGTH, 0, 0)) {
\r
314 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description, _countof(service->description))) {
\r
315 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DESCRIPTION);
\r
320 HWND combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
321 service->startup = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
322 if (service->startup == CB_ERR) service->startup = 0;
\r
324 /* Get logon stuff. */
\r
325 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
326 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
327 service->type |= SERVICE_INTERACTIVE_PROCESS;
\r
329 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
330 service->username = 0;
\r
331 service->usernamelen = 0;
\r
332 if (service->password) {
\r
333 SecureZeroMemory(service->password, service->passwordlen);
\r
334 HeapFree(GetProcessHeap(), 0, service->password);
\r
336 service->password = 0;
\r
337 service->passwordlen = 0;
\r
341 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
342 if (! service->usernamelen) {
\r
343 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
346 service->usernamelen++;
\r
348 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
349 if (! service->username) {
\r
350 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
353 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
354 HeapFree(GetProcessHeap(), 0, service->username);
\r
355 service->username = 0;
\r
356 service->usernamelen = 0;
\r
357 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
362 Special case LOCALSYSTEM.
\r
363 Ignore the password if we're editing and the username hasn't changed.
\r
365 if (str_equiv(service->username, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
366 HeapFree(GetProcessHeap(), 0, service->username);
\r
367 service->username = 0;
\r
368 service->usernamelen = 0;
\r
372 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
373 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
375 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
376 if (! service->passwordlen) {
\r
377 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
380 if (passwordlen != service->passwordlen) {
\r
381 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
384 service->passwordlen++;
\r
386 /* Temporary buffer for password validation. */
\r
387 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
389 HeapFree(GetProcessHeap(), 0, service->username);
\r
390 service->username = 0;
\r
391 service->usernamelen = 0;
\r
392 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
396 /* Actual password buffer. */
\r
397 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
398 if (! service->password) {
\r
399 HeapFree(GetProcessHeap(), 0, password);
\r
400 HeapFree(GetProcessHeap(), 0, service->username);
\r
401 service->username = 0;
\r
402 service->usernamelen = 0;
\r
403 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
407 /* Get first password. */
\r
408 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
409 HeapFree(GetProcessHeap(), 0, password);
\r
410 SecureZeroMemory(service->password, service->passwordlen);
\r
411 HeapFree(GetProcessHeap(), 0, service->password);
\r
412 service->password = 0;
\r
413 service->passwordlen = 0;
\r
414 HeapFree(GetProcessHeap(), 0, service->username);
\r
415 service->username = 0;
\r
416 service->usernamelen = 0;
\r
417 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
421 /* Get confirmation. */
\r
422 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
423 SecureZeroMemory(password, service->passwordlen);
\r
424 HeapFree(GetProcessHeap(), 0, password);
\r
425 SecureZeroMemory(service->password, service->passwordlen);
\r
426 HeapFree(GetProcessHeap(), 0, service->password);
\r
427 service->password = 0;
\r
428 service->passwordlen = 0;
\r
429 HeapFree(GetProcessHeap(), 0, service->username);
\r
430 service->username = 0;
\r
431 service->usernamelen = 0;
\r
432 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
437 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
438 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
439 SecureZeroMemory(password, service->passwordlen);
\r
440 HeapFree(GetProcessHeap(), 0, password);
\r
441 SecureZeroMemory(service->password, service->passwordlen);
\r
442 HeapFree(GetProcessHeap(), 0, service->password);
\r
443 service->password = 0;
\r
444 service->passwordlen = 0;
\r
445 HeapFree(GetProcessHeap(), 0, service->username);
\r
446 service->username = 0;
\r
447 service->usernamelen = 0;
\r
454 /* Remaining tabs are only for services we manage. */
\r
455 if (service->native) return 0;
\r
457 /* Get process stuff. */
\r
458 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
459 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
461 service->affinity = 0LL;
\r
462 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
463 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
464 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
465 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
467 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
470 else if (selected < count) {
\r
471 for (int i = 0; i < count; i++) {
\r
472 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
477 /* Get stop method stuff. */
\r
478 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
479 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
480 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
481 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
482 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
483 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
484 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
486 /* Get exit action stuff. */
\r
487 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
488 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
489 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
490 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
492 /* Get I/O stuff. */
\r
493 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
494 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
495 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
497 /* Override stdout and/or stderr. */
\r
498 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
499 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
500 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
503 /* Get rotation stuff. */
\r
504 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
505 service->rotate_files = true;
\r
506 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
507 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
510 /* Get environment. */
\r
511 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
513 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
515 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
516 cleanup_nssm_service(service);
\r
520 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
521 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
522 HeapFree(GetProcessHeap(), 0, env);
\r
523 cleanup_nssm_service(service);
\r
528 unsigned long newlen;
\r
529 if (unformat_environment(env, envlen, &newenv, &newlen)) {
\r
530 HeapFree(GetProcessHeap(), 0, env);
\r
531 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
532 cleanup_nssm_service(service);
\r
536 HeapFree(GetProcessHeap(), 0, env);
\r
540 /* Test the environment is valid. */
\r
541 if (test_environment(env)) {
\r
542 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
543 HeapFree(GetProcessHeap(), 0, env);
\r
544 cleanup_nssm_service(service);
\r
548 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
549 service->env = env;
\r
550 service->envlen = envlen;
\r
553 service->env_extra = env;
\r
554 service->env_extralen = envlen;
\r
561 /* Install the service. */
\r
562 int install(HWND window) {
\r
563 if (! window) return 1;
\r
565 nssm_service_t *service = alloc_nssm_service();
\r
567 int ret = configure(window, service, 0);
\r
568 if (ret) return ret;
\r
571 /* See if it works. */
\r
572 switch (install_service(service)) {
\r
574 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
575 cleanup_nssm_service(service);
\r
579 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
580 cleanup_nssm_service(service);
\r
584 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
585 cleanup_nssm_service(service);
\r
589 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
590 cleanup_nssm_service(service);
\r
594 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
595 cleanup_nssm_service(service);
\r
599 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
600 cleanup_nssm_service(service);
\r
604 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
605 cleanup_nssm_service(service);
\r
609 /* Remove the service */
\r
610 int remove(HWND window) {
\r
611 if (! window) return 1;
\r
613 /* See if it works */
\r
614 nssm_service_t *service = alloc_nssm_service();
\r
616 /* Get service name */
\r
617 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
618 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
619 cleanup_nssm_service(service);
\r
624 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
625 cleanup_nssm_service(service);
\r
630 switch (remove_service(service)) {
\r
632 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
633 cleanup_nssm_service(service);
\r
637 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
638 cleanup_nssm_service(service);
\r
642 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
644 cleanup_nssm_service(service);
\r
647 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
648 cleanup_nssm_service(service);
\r
652 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
653 cleanup_nssm_service(service);
\r
657 int edit(HWND window, nssm_service_t *orig_service) {
\r
658 if (! window) return 1;
\r
660 nssm_service_t *service = alloc_nssm_service();
\r
662 int ret = configure(window, service, orig_service);
\r
663 if (ret) return ret;
\r
666 switch (edit_service(service, true)) {
\r
668 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
669 cleanup_nssm_service(service);
\r
673 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
674 cleanup_nssm_service(service);
\r
678 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
679 cleanup_nssm_service(service);
\r
684 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
685 cleanup_nssm_service(service);
\r
689 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
690 cleanup_nssm_service(service);
\r
694 static TCHAR *browse_filter(int message) {
\r
696 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
697 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
698 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
699 default: return _T("*.*");
\r
703 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
705 case WM_INITDIALOG:
\r
712 /* Browse for application */
\r
713 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
714 if (! window) return;
\r
717 size_t bufsize = 256;
\r
718 size_t len = bufsize;
\r
722 ZeroMemory(&ofn, sizeof(ofn));
\r
723 ofn.lStructSize = sizeof(ofn);
\r
724 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
725 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
726 if (ofn.lpstrFilter) {
\r
727 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
729 /* "Applications" + NULL + "*.exe" + NULL */
\r
730 va_start(arg, flags);
\r
731 while (i = va_arg(arg, int)) {
\r
732 TCHAR *localised = message_string(i);
\r
733 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
734 len += _tcslen(localised) + 1;
\r
735 LocalFree(localised);
\r
736 TCHAR *filter = browse_filter(i);
\r
737 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
738 len += _tcslen(filter) + 1;
\r
741 /* Remainder of the buffer is already zeroed */
\r
743 ofn.lpstrFile = new TCHAR[MAX_PATH];
\r
744 if (flags & OFN_NOVALIDATE) {
\r
745 /* Directory hack. */
\r
746 _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
748 else _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T("%s"), current);
\r
749 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
750 ofn.nMaxFile = MAX_PATH;
\r
751 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
753 if (GetOpenFileName(&ofn)) {
\r
754 /* Directory hack. */
\r
755 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
756 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
758 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
760 delete[] ofn.lpstrFile;
\r
763 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
765 case WM_INITDIALOG:
\r
768 /* Button was pressed or control was controlled. */
\r
771 TCHAR buffer[MAX_PATH];
\r
772 unsigned char enabled;
\r
774 switch (LOWORD(w)) {
\r
775 /* Browse for application. */
\r
777 dlg = GetDlgItem(tab, IDC_PATH);
\r
778 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
779 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
780 /* Fill in startup directory if it wasn't already specified. */
\r
781 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
783 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
784 strip_basename(buffer);
\r
785 SetDlgItemText(tab, IDC_DIR, buffer);
\r
789 /* Browse for startup directory. */
\r
790 case IDC_BROWSE_DIR:
\r
791 dlg = GetDlgItem(tab, IDC_DIR);
\r
792 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
793 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
797 case IDC_LOCALSYSTEM:
\r
798 set_logon_enabled(0);
\r
802 set_logon_enabled(1);
\r
806 case IDC_AFFINITY_ALL:
\r
807 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
809 set_affinity_enabled(enabled);
\r
812 /* Shutdown methods. */
\r
813 case IDC_METHOD_CONSOLE:
\r
814 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
817 case IDC_METHOD_WINDOW:
\r
818 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
821 case IDC_METHOD_THREADS:
\r
822 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
825 /* Browse for stdin. */
\r
826 case IDC_BROWSE_STDIN:
\r
827 dlg = GetDlgItem(tab, IDC_STDIN);
\r
828 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
829 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
832 /* Browse for stdout. */
\r
833 case IDC_BROWSE_STDOUT:
\r
834 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
835 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
836 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
837 /* Fill in stderr if it wasn't already specified. */
\r
838 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
840 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
841 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
845 /* Browse for stderr. */
\r
846 case IDC_BROWSE_STDERR:
\r
847 dlg = GetDlgItem(tab, IDC_STDERR);
\r
848 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
849 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
854 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
856 set_rotation_enabled(enabled);
\r
865 /* Install/remove dialogue callback */
\r
866 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
867 nssm_service_t *service;
\r
870 /* Creating the dialogue */
\r
871 case WM_INITDIALOG:
\r
872 service = (nssm_service_t *) l;
\r
874 SetFocus(GetDlgItem(window, IDC_NAME));
\r
880 tabs = GetDlgItem(window, IDC_TAB1);
\r
881 if (! tabs) return 0;
\r
885 ZeroMemory(&tab, sizeof(tab));
\r
886 tab.mask = TCIF_TEXT;
\r
890 /* Application tab. */
\r
891 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
892 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
893 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
894 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
895 if (service->native) {
\r
896 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
897 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
898 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
900 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
901 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
904 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
905 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
906 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
907 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
908 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
910 /* Set defaults. */
\r
911 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
912 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
913 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
914 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
915 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
916 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
919 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
920 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
921 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
922 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
923 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
925 /* Set defaults. */
\r
926 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
927 set_logon_enabled(0);
\r
929 /* Remaining tabs are only for services we manage. */
\r
930 if (service->native) return 1;
\r
933 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
934 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
935 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
936 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
937 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
939 /* Set defaults. */
\r
940 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
941 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
942 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
943 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
944 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
945 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
946 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
947 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
949 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
951 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
952 for (i = 0; i < n; i++) {
\r
954 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
955 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
960 The box is high enough for four rows. It is wide enough for eight
\r
961 columns without scrolling. With scrollbars it shrinks to two rows.
\r
962 Note that the above only holds if we set the column width BEFORE
966 int columns = (n - 1) / 4;
\r
968 GetWindowRect(list, &rect);
\r
969 int width = rect.right - rect.left;
970 width -= (7 - columns) * 16;
\r
971 int height = rect.bottom - rect.top;
\r
972 if (n < 4) height -= SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
973 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
975 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
977 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
978 set_affinity_enabled(0);
\r
980 /* Shutdown tab. */
\r
981 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
982 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
983 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
984 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
985 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
987 /* Set defaults. */
\r
988 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
989 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
990 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
991 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
992 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
993 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
994 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
997 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
998 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
999 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1000 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1001 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1003 /* Set defaults. */
\r
1004 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1005 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1006 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1007 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1008 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1009 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1010 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1013 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1014 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1015 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1016 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1017 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1019 /* Rotation tab. */
\r
1020 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1021 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1022 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1023 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1024 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1026 /* Set defaults. */
\r
1027 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1028 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1029 set_rotation_enabled(0);
\r
1031 /* Environment tab. */
\r
1032 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1033 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1034 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1035 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1036 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1042 NMHDR *notification;
\r
1044 notification = (NMHDR *) l;
\r
1045 switch (notification->code) {
\r
1046 case TCN_SELCHANGE:
\r
1050 tabs = GetDlgItem(window, IDC_TAB1);
\r
1051 if (! tabs) return 0;
\r
1053 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1054 if (selection != selected_tab) {
\r
1055 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1056 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1057 SetFocus(GetDlgItem(window, IDOK));
\r
1058 selected_tab = selection;
\r
1065 /* Button was pressed or control was controlled */
\r
1067 switch (LOWORD(w)) {
\r
1070 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1071 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1073 else if (! install(window)) PostQuitMessage(0);
\r
1076 /* Cancel button */
\r
1078 DestroyWindow(window);
\r
1081 /* Remove button */
\r
1083 if (! remove(window)) PostQuitMessage(0);
\r
1088 /* Window closing */
\r
1090 DestroyWindow(window);
\r
1093 PostQuitMessage(0);
\r