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_SECONDS), 1);
\r
156 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), 1);
\r
158 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, service->rotate_seconds, 0);
\r
159 if (! service->rotate_bytes_high) SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, service->rotate_bytes_low, 0);
\r
161 /* Check if advanced settings are in use. */
\r
162 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
163 if (service->rotate_bytes_high) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ROTATE_BYTES);
\r
165 /* Environment tab. */
\r
167 unsigned long envlen;
\r
168 if (service->env_extralen) {
\r
169 env = service->env_extra;
\r
170 envlen = service->env_extralen;
\r
173 env = service->env;
\r
174 envlen = service->envlen;
\r
175 if (envlen) SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_SETCHECK, BST_CHECKED, 0);
\r
180 unsigned long newlen;
\r
181 if (format_environment(env, envlen, &formatted, &newlen)) {
\r
182 popup_message(dlg, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("nssm_dlg()"));
\r
185 SetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, formatted);
\r
186 HeapFree(GetProcessHeap(), 0, formatted);
\r
189 if (service->envlen && service->env_extralen) popup_message(dlg, MB_OK | MB_ICONWARNING, NSSM_GUI_WARN_ENVIRONMENT);
\r
194 while (GetMessage(&message, 0, 0, 0)) {
\r
195 if (IsDialogMessage(dlg, &message)) continue;
\r
196 TranslateMessage(&message);
\r
197 DispatchMessage(&message);
\r
200 return (int) message.wParam;
\r
203 void centre_window(HWND window) {
\r
205 RECT size, desktop_size;
\r
206 unsigned long x, y;
\r
208 if (! window) return;
\r
210 /* Find window size */
\r
211 if (! GetWindowRect(window, &size)) return;
\r
213 /* Find desktop window */
\r
214 desktop = GetDesktopWindow();
\r
215 if (! desktop) return;
\r
217 /* Find desktop window size */
\r
218 if (! GetWindowRect(desktop, &desktop_size)) return;
\r
220 /* Centre window */
\r
221 x = (desktop_size.right - size.right) / 2;
\r
222 y = (desktop_size.bottom - size.bottom) / 2;
\r
223 MoveWindow(window, x, y, size.right - size.left, size.bottom - size.top, 0);
\r
226 static inline void check_stop_method(nssm_service_t *service, unsigned long method, unsigned long control) {
\r
227 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) return;
\r
228 service->stop_method &= ~method;
\r
231 static inline void check_number(HWND tab, unsigned long control, unsigned long *timeout) {
\r
233 unsigned long configured = GetDlgItemInt(tab, control, &translated, 0);
\r
234 if (translated) *timeout = configured;
\r
237 static inline void set_timeout_enabled(unsigned long control, unsigned long dependent) {
\r
238 unsigned char enabled = 0;
\r
239 if (SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], control, BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
240 EnableWindow(GetDlgItem(tablist[NSSM_TAB_SHUTDOWN], dependent), enabled);
\r
243 static inline void set_logon_enabled(unsigned char enabled) {
\r
244 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_INTERACT), ! enabled);
\r
245 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), enabled);
\r
246 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), enabled);
\r
247 EnableWindow(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), enabled);
\r
250 static inline void set_affinity_enabled(unsigned char enabled) {
\r
251 EnableWindow(GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY), enabled);
\r
254 static inline void set_rotation_enabled(unsigned char enabled) {
\r
255 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS), enabled);
\r
256 EnableWindow(GetDlgItem(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW), enabled);
\r
259 static inline void check_io(HWND owner, TCHAR *name, TCHAR *buffer, unsigned long len, unsigned long control) {
\r
260 if (! SendMessage(GetDlgItem(tablist[NSSM_TAB_IO], control), WM_GETTEXTLENGTH, 0, 0)) return;
\r
261 if (GetDlgItemText(tablist[NSSM_TAB_IO], control, buffer, (int) len)) return;
\r
262 popup_message(owner, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, name);
\r
263 ZeroMemory(buffer, len * sizeof(TCHAR));
\r
266 /* Set service parameters. */
\r
267 int configure(HWND window, nssm_service_t *service, nssm_service_t *orig_service) {
\r
268 if (! service) return 1;
\r
270 set_nssm_service_defaults(service);
\r
272 if (orig_service) {
\r
273 service->native = orig_service->native;
\r
274 service->handle = orig_service->handle;
\r
277 /* Get service name. */
\r
278 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
279 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
280 cleanup_nssm_service(service);
\r
284 /* Get executable name */
\r
285 if (! service->native) {
\r
286 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_PATH, service->exe, _countof(service->exe))) {
\r
287 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
\r
291 /* Get startup directory. */
\r
292 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_DIR, service->dir, _countof(service->dir))) {
\r
293 _sntprintf_s(service->dir, _countof(service->dir), _TRUNCATE, _T("%s"), service->exe);
\r
294 strip_basename(service->dir);
\r
298 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
\r
299 if (! GetDlgItemText(tablist[NSSM_TAB_APPLICATION], IDC_FLAGS, service->flags, _countof(service->flags))) {
\r
300 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
\r
307 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME), WM_GETTEXTLENGTH, 0, 0)) {
\r
308 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DISPLAYNAME, service->displayname, _countof(service->displayname))) {
\r
309 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DISPLAYNAME);
\r
314 if (SendMessage(GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION), WM_GETTEXTLENGTH, 0, 0)) {
\r
315 if (! GetDlgItemText(tablist[NSSM_TAB_DETAILS], IDC_DESCRIPTION, service->description, _countof(service->description))) {
\r
316 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_DESCRIPTION);
\r
321 HWND combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
322 service->startup = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
323 if (service->startup == CB_ERR) service->startup = 0;
\r
325 /* Get logon stuff. */
\r
326 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
327 if (SendDlgItemMessage(tablist[NSSM_TAB_LOGON], IDC_INTERACT, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
328 service->type |= SERVICE_INTERACTIVE_PROCESS;
\r
330 if (service->username) HeapFree(GetProcessHeap(), 0, service->username);
\r
331 service->username = 0;
\r
332 service->usernamelen = 0;
\r
333 if (service->password) {
\r
334 SecureZeroMemory(service->password, service->passwordlen);
\r
335 HeapFree(GetProcessHeap(), 0, service->password);
\r
337 service->password = 0;
\r
338 service->passwordlen = 0;
\r
342 service->usernamelen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_USERNAME), WM_GETTEXTLENGTH, 0, 0);
\r
343 if (! service->usernamelen) {
\r
344 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_USERNAME);
\r
347 service->usernamelen++;
\r
349 service->username = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->usernamelen * sizeof(TCHAR));
\r
350 if (! service->username) {
\r
351 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("account name"), _T("install()"));
\r
354 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_USERNAME, service->username, (int) service->usernamelen)) {
\r
355 HeapFree(GetProcessHeap(), 0, service->username);
\r
356 service->username = 0;
\r
357 service->usernamelen = 0;
\r
358 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_USERNAME);
\r
363 Special case LOCALSYSTEM.
\r
364 Ignore the password if we're editing and the username hasn't changed.
\r
366 if (str_equiv(service->username, NSSM_LOCALSYSTEM_ACCOUNT)) {
\r
367 HeapFree(GetProcessHeap(), 0, service->username);
\r
368 service->username = 0;
\r
369 service->usernamelen = 0;
\r
373 service->passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1), WM_GETTEXTLENGTH, 0, 0);
\r
374 size_t passwordlen = SendMessage(GetDlgItem(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2), WM_GETTEXTLENGTH, 0, 0);
\r
376 if (! orig_service || ! orig_service->username || ! str_equiv(service->username, orig_service->username) || service->passwordlen || passwordlen) {
\r
377 if (! service->passwordlen) {
\r
378 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
381 if (passwordlen != service->passwordlen) {
\r
382 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
385 service->passwordlen++;
\r
387 /* Temporary buffer for password validation. */
\r
388 TCHAR *password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
390 HeapFree(GetProcessHeap(), 0, service->username);
\r
391 service->username = 0;
\r
392 service->usernamelen = 0;
\r
393 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password confirmation"), _T("install()"));
\r
397 /* Actual password buffer. */
\r
398 service->password = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, service->passwordlen * sizeof(TCHAR));
\r
399 if (! service->password) {
\r
400 HeapFree(GetProcessHeap(), 0, password);
\r
401 HeapFree(GetProcessHeap(), 0, service->username);
\r
402 service->username = 0;
\r
403 service->usernamelen = 0;
\r
404 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("password"), _T("install()"));
\r
408 /* Get first password. */
\r
409 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD1, service->password, (int) service->passwordlen)) {
\r
410 HeapFree(GetProcessHeap(), 0, password);
\r
411 SecureZeroMemory(service->password, service->passwordlen);
\r
412 HeapFree(GetProcessHeap(), 0, service->password);
\r
413 service->password = 0;
\r
414 service->passwordlen = 0;
\r
415 HeapFree(GetProcessHeap(), 0, service->username);
\r
416 service->username = 0;
\r
417 service->usernamelen = 0;
\r
418 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
422 /* Get confirmation. */
\r
423 if (! GetDlgItemText(tablist[NSSM_TAB_LOGON], IDC_PASSWORD2, password, (int) service->passwordlen)) {
\r
424 SecureZeroMemory(password, service->passwordlen);
\r
425 HeapFree(GetProcessHeap(), 0, password);
\r
426 SecureZeroMemory(service->password, service->passwordlen);
\r
427 HeapFree(GetProcessHeap(), 0, service->password);
\r
428 service->password = 0;
\r
429 service->passwordlen = 0;
\r
430 HeapFree(GetProcessHeap(), 0, service->username);
\r
431 service->username = 0;
\r
432 service->usernamelen = 0;
\r
433 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_PASSWORD);
\r
438 if (_tcsncmp(password, service->password, service->passwordlen)) {
\r
439 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PASSWORD);
\r
440 SecureZeroMemory(password, service->passwordlen);
\r
441 HeapFree(GetProcessHeap(), 0, password);
\r
442 SecureZeroMemory(service->password, service->passwordlen);
\r
443 HeapFree(GetProcessHeap(), 0, service->password);
\r
444 service->password = 0;
\r
445 service->passwordlen = 0;
\r
446 HeapFree(GetProcessHeap(), 0, service->username);
\r
447 service->username = 0;
\r
448 service->usernamelen = 0;
\r
455 /* Remaining tabs are only for services we manage. */
\r
456 if (service->native) return 0;
\r
458 /* Get process stuff. */
\r
459 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
460 service->priority = priority_index_to_constant((unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0));
\r
462 service->affinity = 0LL;
\r
463 if (! (SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_GETCHECK, 0, 0) & BST_CHECKED)) {
\r
464 HWND list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
465 int selected = (int) SendMessage(list, LB_GETSELCOUNT, 0, 0);
\r
466 int count = (int) SendMessage(list, LB_GETCOUNT, 0, 0);
\r
468 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_WARN_AFFINITY_NONE);
\r
471 else if (selected < count) {
\r
472 for (int i = 0; i < count; i++) {
\r
473 if (SendMessage(list, LB_GETSEL, i, 0)) service->affinity |= (1LL << (__int64) i);
\r
478 /* Get stop method stuff. */
\r
479 check_stop_method(service, NSSM_STOP_METHOD_CONSOLE, IDC_METHOD_CONSOLE);
\r
480 check_stop_method(service, NSSM_STOP_METHOD_WINDOW, IDC_METHOD_WINDOW);
\r
481 check_stop_method(service, NSSM_STOP_METHOD_THREADS, IDC_METHOD_THREADS);
\r
482 check_stop_method(service, NSSM_STOP_METHOD_TERMINATE, IDC_METHOD_TERMINATE);
\r
483 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, &service->kill_console_delay);
\r
484 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, &service->kill_window_delay);
\r
485 check_number(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, &service->kill_threads_delay);
\r
487 /* Get exit action stuff. */
\r
488 check_number(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, &service->throttle_delay);
\r
489 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
490 service->default_exit_action = (unsigned long) SendMessage(combo, CB_GETCURSEL, 0, 0);
\r
491 if (service->default_exit_action == CB_ERR) service->default_exit_action = 0;
\r
492 check_number(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, &service->restart_delay);
\r
494 /* Get I/O stuff. */
\r
495 check_io(window, _T("stdin"), service->stdin_path, _countof(service->stdin_path), IDC_STDIN);
\r
496 check_io(window, _T("stdout"), service->stdout_path, _countof(service->stdout_path), IDC_STDOUT);
\r
497 check_io(window, _T("stderr"), service->stderr_path, _countof(service->stderr_path), IDC_STDERR);
\r
499 /* Override stdout and/or stderr. */
\r
500 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_TRUNCATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
501 if (service->stdout_path[0]) service->stdout_disposition = CREATE_ALWAYS;
\r
502 if (service->stderr_path[0]) service->stderr_disposition = CREATE_ALWAYS;
\r
505 /* Get rotation stuff. */
\r
506 if (SendDlgItemMessage(tablist[NSSM_TAB_ROTATION], IDC_ROTATE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
507 service->rotate_files = true;
\r
508 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, &service->rotate_seconds);
\r
509 check_number(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, &service->rotate_bytes_low);
\r
512 /* Get environment. */
\r
513 unsigned long envlen = (unsigned long) SendMessage(GetDlgItem(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT), WM_GETTEXTLENGTH, 0, 0);
\r
515 TCHAR *env = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (envlen + 2) * sizeof(TCHAR));
\r
517 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
518 cleanup_nssm_service(service);
\r
522 if (! GetDlgItemText(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT, env, envlen + 1)) {
\r
523 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
524 HeapFree(GetProcessHeap(), 0, env);
\r
525 cleanup_nssm_service(service);
\r
530 unsigned long newlen;
\r
531 if (unformat_environment(env, envlen, &newenv, &newlen)) {
\r
532 HeapFree(GetProcessHeap(), 0, env);
\r
533 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("environment"), _T("install()"));
\r
534 cleanup_nssm_service(service);
\r
538 HeapFree(GetProcessHeap(), 0, env);
\r
542 /* Test the environment is valid. */
\r
543 if (test_environment(env)) {
\r
544 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_ENVIRONMENT);
\r
545 HeapFree(GetProcessHeap(), 0, env);
\r
546 cleanup_nssm_service(service);
\r
550 if (SendDlgItemMessage(tablist[NSSM_TAB_ENVIRONMENT], IDC_ENVIRONMENT_REPLACE, BM_GETCHECK, 0, 0) & BST_CHECKED) {
\r
551 service->env = env;
\r
552 service->envlen = envlen;
\r
555 service->env_extra = env;
\r
556 service->env_extralen = envlen;
\r
563 /* Install the service. */
\r
564 int install(HWND window) {
\r
565 if (! window) return 1;
\r
567 nssm_service_t *service = alloc_nssm_service();
\r
569 int ret = configure(window, service, 0);
\r
570 if (ret) return ret;
\r
573 /* See if it works. */
\r
574 switch (install_service(service)) {
\r
576 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("install()"));
\r
577 cleanup_nssm_service(service);
\r
581 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
582 cleanup_nssm_service(service);
\r
586 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
587 cleanup_nssm_service(service);
\r
591 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
592 cleanup_nssm_service(service);
\r
596 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
\r
597 cleanup_nssm_service(service);
\r
601 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
\r
602 cleanup_nssm_service(service);
\r
606 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);
\r
607 cleanup_nssm_service(service);
\r
611 /* Remove the service */
\r
612 int remove(HWND window) {
\r
613 if (! window) return 1;
\r
615 /* See if it works */
\r
616 nssm_service_t *service = alloc_nssm_service();
\r
618 /* Get service name */
\r
619 if (! GetDlgItemText(window, IDC_NAME, service->name, _countof(service->name))) {
\r
620 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
\r
621 cleanup_nssm_service(service);
\r
626 if (popup_message(window, MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {
\r
627 cleanup_nssm_service(service);
\r
632 switch (remove_service(service)) {
\r
634 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("remove()"));
\r
635 cleanup_nssm_service(service);
\r
639 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
\r
640 cleanup_nssm_service(service);
\r
644 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
\r
646 cleanup_nssm_service(service);
\r
649 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
\r
650 cleanup_nssm_service(service);
\r
654 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);
\r
655 cleanup_nssm_service(service);
\r
659 int edit(HWND window, nssm_service_t *orig_service) {
\r
660 if (! window) return 1;
\r
662 nssm_service_t *service = alloc_nssm_service();
\r
664 int ret = configure(window, service, orig_service);
\r
665 if (ret) return ret;
\r
668 switch (edit_service(service, true)) {
\r
670 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, _T("service"), _T("edit()"));
\r
671 cleanup_nssm_service(service);
\r
675 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
\r
676 cleanup_nssm_service(service);
\r
680 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
\r
681 cleanup_nssm_service(service);
\r
686 popup_message(window, MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_EDIT_PARAMETERS_FAILED);
\r
687 cleanup_nssm_service(service);
\r
691 popup_message(window, MB_OK, NSSM_MESSAGE_SERVICE_EDITED, service->name);
\r
692 cleanup_nssm_service(service);
\r
696 static TCHAR *browse_filter(int message) {
\r
698 case NSSM_GUI_BROWSE_FILTER_APPLICATIONS: return _T("*.exe;*.bat;*.cmd");
\r
699 case NSSM_GUI_BROWSE_FILTER_DIRECTORIES: return _T(".");
\r
700 case NSSM_GUI_BROWSE_FILTER_ALL_FILES: /* Fall through. */
\r
701 default: return _T("*.*");
\r
705 UINT_PTR CALLBACK browse_hook(HWND dlg, UINT message, WPARAM w, LPARAM l) {
\r
707 case WM_INITDIALOG:
\r
714 /* Browse for application */
\r
715 void browse(HWND window, TCHAR *current, unsigned long flags, ...) {
\r
716 if (! window) return;
\r
719 size_t bufsize = 256;
\r
720 size_t len = bufsize;
\r
724 ZeroMemory(&ofn, sizeof(ofn));
\r
725 ofn.lStructSize = sizeof(ofn);
\r
726 ofn.lpstrFilter = (TCHAR *) HeapAlloc(GetProcessHeap(), 0, bufsize * sizeof(TCHAR));
\r
727 /* XXX: Escaping nulls with FormatMessage is tricky */
\r
728 if (ofn.lpstrFilter) {
\r
729 ZeroMemory((void *) ofn.lpstrFilter, bufsize);
\r
731 /* "Applications" + NULL + "*.exe" + NULL */
\r
732 va_start(arg, flags);
\r
733 while (i = va_arg(arg, int)) {
\r
734 TCHAR *localised = message_string(i);
\r
735 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize, _TRUNCATE, localised);
\r
736 len += _tcslen(localised) + 1;
\r
737 LocalFree(localised);
\r
738 TCHAR *filter = browse_filter(i);
\r
739 _sntprintf_s((TCHAR *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, _T("%s"), filter);
\r
740 len += _tcslen(filter) + 1;
\r
743 /* Remainder of the buffer is already zeroed */
\r
745 ofn.lpstrFile = new TCHAR[MAX_PATH];
\r
746 if (flags & OFN_NOVALIDATE) {
\r
747 /* Directory hack. */
\r
748 _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES));
\r
750 else _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T("%s"), current);
\r
751 ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
\r
752 ofn.nMaxFile = MAX_PATH;
\r
753 ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags;
\r
755 if (GetOpenFileName(&ofn)) {
\r
756 /* Directory hack. */
\r
757 if (flags & OFN_NOVALIDATE) strip_basename(ofn.lpstrFile);
\r
758 SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
\r
760 if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
\r
762 delete[] ofn.lpstrFile;
\r
765 INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) {
\r
767 case WM_INITDIALOG:
\r
770 /* Button was pressed or control was controlled. */
\r
773 TCHAR buffer[MAX_PATH];
\r
774 unsigned char enabled;
\r
776 switch (LOWORD(w)) {
\r
777 /* Browse for application. */
\r
779 dlg = GetDlgItem(tab, IDC_PATH);
\r
780 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
781 browse(dlg, buffer, OFN_FILEMUSTEXIST, NSSM_GUI_BROWSE_FILTER_APPLICATIONS, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
782 /* Fill in startup directory if it wasn't already specified. */
\r
783 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
785 GetDlgItemText(tab, IDC_PATH, buffer, _countof(buffer));
\r
786 strip_basename(buffer);
\r
787 SetDlgItemText(tab, IDC_DIR, buffer);
\r
791 /* Browse for startup directory. */
\r
792 case IDC_BROWSE_DIR:
\r
793 dlg = GetDlgItem(tab, IDC_DIR);
\r
794 GetDlgItemText(tab, IDC_DIR, buffer, _countof(buffer));
\r
795 browse(dlg, buffer, OFN_NOVALIDATE, NSSM_GUI_BROWSE_FILTER_DIRECTORIES, 0);
\r
799 case IDC_LOCALSYSTEM:
\r
800 set_logon_enabled(0);
\r
804 set_logon_enabled(1);
\r
808 case IDC_AFFINITY_ALL:
\r
809 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 0;
\r
811 set_affinity_enabled(enabled);
\r
814 /* Shutdown methods. */
\r
815 case IDC_METHOD_CONSOLE:
\r
816 set_timeout_enabled(LOWORD(w), IDC_KILL_CONSOLE);
\r
819 case IDC_METHOD_WINDOW:
\r
820 set_timeout_enabled(LOWORD(w), IDC_KILL_WINDOW);
\r
823 case IDC_METHOD_THREADS:
\r
824 set_timeout_enabled(LOWORD(w), IDC_KILL_THREADS);
\r
827 /* Browse for stdin. */
\r
828 case IDC_BROWSE_STDIN:
\r
829 dlg = GetDlgItem(tab, IDC_STDIN);
\r
830 GetDlgItemText(tab, IDC_STDIN, buffer, _countof(buffer));
\r
831 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
834 /* Browse for stdout. */
\r
835 case IDC_BROWSE_STDOUT:
\r
836 dlg = GetDlgItem(tab, IDC_STDOUT);
\r
837 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
838 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
839 /* Fill in stderr if it wasn't already specified. */
\r
840 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
842 GetDlgItemText(tab, IDC_STDOUT, buffer, _countof(buffer));
\r
843 SetDlgItemText(tab, IDC_STDERR, buffer);
\r
847 /* Browse for stderr. */
\r
848 case IDC_BROWSE_STDERR:
\r
849 dlg = GetDlgItem(tab, IDC_STDERR);
\r
850 GetDlgItemText(tab, IDC_STDERR, buffer, _countof(buffer));
\r
851 browse(dlg, buffer, 0, NSSM_GUI_BROWSE_FILTER_ALL_FILES, 0);
\r
856 if (SendDlgItemMessage(tab, LOWORD(w), BM_GETCHECK, 0, 0) & BST_CHECKED) enabled = 1;
\r
858 set_rotation_enabled(enabled);
\r
867 /* Install/remove dialogue callback */
\r
868 INT_PTR CALLBACK nssm_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
\r
869 nssm_service_t *service;
\r
872 /* Creating the dialogue */
\r
873 case WM_INITDIALOG:
\r
874 service = (nssm_service_t *) l;
\r
876 SetFocus(GetDlgItem(window, IDC_NAME));
\r
882 tabs = GetDlgItem(window, IDC_TAB1);
\r
883 if (! tabs) return 0;
\r
887 ZeroMemory(&tab, sizeof(tab));
\r
888 tab.mask = TCIF_TEXT;
\r
892 /* Application tab. */
\r
893 if (service->native) tab.pszText = message_string(NSSM_GUI_TAB_NATIVE);
\r
894 else tab.pszText = message_string(NSSM_GUI_TAB_APPLICATION);
\r
895 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
896 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_APPLICATION, (LPARAM) &tab);
\r
897 if (service->native) {
\r
898 tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_NATIVE), window, tab_dlg);
\r
899 EnableWindow(tablist[NSSM_TAB_APPLICATION], 0);
\r
900 EnableWindow(GetDlgItem(tablist[NSSM_TAB_APPLICATION], IDC_PATH), 0);
\r
902 else tablist[NSSM_TAB_APPLICATION] = dialog(MAKEINTRESOURCE(IDD_APPLICATION), window, tab_dlg);
\r
903 ShowWindow(tablist[NSSM_TAB_APPLICATION], SW_SHOW);
\r
906 tab.pszText = message_string(NSSM_GUI_TAB_DETAILS);
\r
907 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
908 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_DETAILS, (LPARAM) &tab);
\r
909 tablist[NSSM_TAB_DETAILS] = dialog(MAKEINTRESOURCE(IDD_DETAILS), window, tab_dlg);
\r
910 ShowWindow(tablist[NSSM_TAB_DETAILS], SW_HIDE);
\r
912 /* Set defaults. */
\r
913 combo = GetDlgItem(tablist[NSSM_TAB_DETAILS], IDC_STARTUP);
\r
914 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_AUTOMATIC, (LPARAM) message_string(NSSM_GUI_STARTUP_AUTOMATIC));
\r
915 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DELAYED, (LPARAM) message_string(NSSM_GUI_STARTUP_DELAYED));
\r
916 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_MANUAL, (LPARAM) message_string(NSSM_GUI_STARTUP_MANUAL));
\r
917 SendMessage(combo, CB_INSERTSTRING, NSSM_STARTUP_DISABLED, (LPARAM) message_string(NSSM_GUI_STARTUP_DISABLED));
\r
918 SendMessage(combo, CB_SETCURSEL, NSSM_STARTUP_AUTOMATIC, 0);
\r
921 tab.pszText = message_string(NSSM_GUI_TAB_LOGON);
\r
922 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
923 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_LOGON, (LPARAM) &tab);
\r
924 tablist[NSSM_TAB_LOGON] = dialog(MAKEINTRESOURCE(IDD_LOGON), window, tab_dlg);
\r
925 ShowWindow(tablist[NSSM_TAB_LOGON], SW_HIDE);
\r
927 /* Set defaults. */
\r
928 CheckRadioButton(tablist[NSSM_TAB_LOGON], IDC_LOCALSYSTEM, IDC_ACCOUNT, IDC_LOCALSYSTEM);
\r
929 set_logon_enabled(0);
\r
931 /* Remaining tabs are only for services we manage. */
\r
932 if (service->native) return 1;
\r
935 tab.pszText = message_string(NSSM_GUI_TAB_PROCESS);
\r
936 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
937 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_PROCESS, (LPARAM) &tab);
\r
938 tablist[NSSM_TAB_PROCESS] = dialog(MAKEINTRESOURCE(IDD_PROCESS), window, tab_dlg);
\r
939 ShowWindow(tablist[NSSM_TAB_PROCESS], SW_HIDE);
\r
941 /* Set defaults. */
\r
942 combo = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_PRIORITY);
\r
943 SendMessage(combo, CB_INSERTSTRING, NSSM_REALTIME_PRIORITY, (LPARAM) message_string(NSSM_GUI_REALTIME_PRIORITY_CLASS));
\r
944 SendMessage(combo, CB_INSERTSTRING, NSSM_HIGH_PRIORITY, (LPARAM) message_string(NSSM_GUI_HIGH_PRIORITY_CLASS));
\r
945 SendMessage(combo, CB_INSERTSTRING, NSSM_ABOVE_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_ABOVE_NORMAL_PRIORITY_CLASS));
\r
946 SendMessage(combo, CB_INSERTSTRING, NSSM_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_NORMAL_PRIORITY_CLASS));
\r
947 SendMessage(combo, CB_INSERTSTRING, NSSM_BELOW_NORMAL_PRIORITY, (LPARAM) message_string(NSSM_GUI_BELOW_NORMAL_PRIORITY_CLASS));
\r
948 SendMessage(combo, CB_INSERTSTRING, NSSM_IDLE_PRIORITY, (LPARAM) message_string(NSSM_GUI_IDLE_PRIORITY_CLASS));
\r
949 SendMessage(combo, CB_SETCURSEL, NSSM_NORMAL_PRIORITY, 0);
\r
951 list = GetDlgItem(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY);
\r
953 SendMessage(list, LB_SETCOLUMNWIDTH, 16, 0);
\r
954 for (i = 0; i < n; i++) {
\r
956 _sntprintf_s(buffer, _countof(buffer), _TRUNCATE, _T("%d"), i);
\r
957 SendMessage(list, LB_ADDSTRING, 0, (LPARAM) buffer);
\r
962 The box is high enough for four rows. It is wide enough for eight
\r
963 columns without scrolling. With scrollbars it shrinks to two rows.
\r
964 Note that the above only holds if we set the column width BEFORE
968 int columns = (n - 1) / 4;
\r
970 GetWindowRect(list, &rect);
\r
971 int width = rect.right - rect.left;
972 width -= (7 - columns) * 16;
\r
973 int height = rect.bottom - rect.top;
\r
974 if (n < 4) height -= (int) SendMessage(list, LB_GETITEMHEIGHT, 0, 0) * (4 - n);
975 SetWindowPos(list, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOOWNERZORDER);
\r
977 SendMessage(list, LB_SELITEMRANGE, 1, MAKELPARAM(0, n));
\r
979 SendDlgItemMessage(tablist[NSSM_TAB_PROCESS], IDC_AFFINITY_ALL, BM_SETCHECK, BST_CHECKED, 0);
\r
980 set_affinity_enabled(0);
\r
982 /* Shutdown tab. */
\r
983 tab.pszText = message_string(NSSM_GUI_TAB_SHUTDOWN);
\r
984 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
985 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_SHUTDOWN, (LPARAM) &tab);
\r
986 tablist[NSSM_TAB_SHUTDOWN] = dialog(MAKEINTRESOURCE(IDD_SHUTDOWN), window, tab_dlg);
\r
987 ShowWindow(tablist[NSSM_TAB_SHUTDOWN], SW_HIDE);
\r
989 /* Set defaults. */
\r
990 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_CONSOLE, BM_SETCHECK, BST_CHECKED, 0);
\r
991 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_CONSOLE, NSSM_KILL_CONSOLE_GRACE_PERIOD, 0);
\r
992 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_WINDOW, BM_SETCHECK, BST_CHECKED, 0);
\r
993 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_WINDOW, NSSM_KILL_WINDOW_GRACE_PERIOD, 0);
\r
994 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_THREADS, BM_SETCHECK, BST_CHECKED, 0);
\r
995 SetDlgItemInt(tablist[NSSM_TAB_SHUTDOWN], IDC_KILL_THREADS, NSSM_KILL_THREADS_GRACE_PERIOD, 0);
\r
996 SendDlgItemMessage(tablist[NSSM_TAB_SHUTDOWN], IDC_METHOD_TERMINATE, BM_SETCHECK, BST_CHECKED, 0);
\r
999 tab.pszText = message_string(NSSM_GUI_TAB_EXIT);
\r
1000 tab.cchTextMax = (int) _tcslen(tab.pszText);
\r
1001 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_EXIT, (LPARAM) &tab);
\r
1002 tablist[NSSM_TAB_EXIT] = dialog(MAKEINTRESOURCE(IDD_APPEXIT), window, tab_dlg);
\r
1003 ShowWindow(tablist[NSSM_TAB_EXIT], SW_HIDE);
\r
1005 /* Set defaults. */
\r
1006 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_THROTTLE, NSSM_RESET_THROTTLE_RESTART, 0);
\r
1007 combo = GetDlgItem(tablist[NSSM_TAB_EXIT], IDC_APPEXIT);
\r
1008 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_RESTART, (LPARAM) message_string(NSSM_GUI_EXIT_RESTART));
\r
1009 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_IGNORE, (LPARAM) message_string(NSSM_GUI_EXIT_IGNORE));
\r
1010 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_REALLY, (LPARAM) message_string(NSSM_GUI_EXIT_REALLY));
\r
1011 SendMessage(combo, CB_INSERTSTRING, NSSM_EXIT_UNCLEAN, (LPARAM) message_string(NSSM_GUI_EXIT_UNCLEAN));
\r
1012 SendMessage(combo, CB_SETCURSEL, NSSM_EXIT_RESTART, 0);
\r
1013 SetDlgItemInt(tablist[NSSM_TAB_EXIT], IDC_RESTART_DELAY, 0, 0);
\r
1016 tab.pszText = message_string(NSSM_GUI_TAB_IO);
\r
1017 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1018 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_IO, (LPARAM) &tab);
\r
1019 tablist[NSSM_TAB_IO] = dialog(MAKEINTRESOURCE(IDD_IO), window, tab_dlg);
\r
1020 ShowWindow(tablist[NSSM_TAB_IO], SW_HIDE);
\r
1022 /* Rotation tab. */
\r
1023 tab.pszText = message_string(NSSM_GUI_TAB_ROTATION);
\r
1024 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1025 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ROTATION, (LPARAM) &tab);
\r
1026 tablist[NSSM_TAB_ROTATION] = dialog(MAKEINTRESOURCE(IDD_ROTATION), window, tab_dlg);
\r
1027 ShowWindow(tablist[NSSM_TAB_ROTATION], SW_HIDE);
\r
1029 /* Set defaults. */
\r
1030 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_SECONDS, 0, 0);
\r
1031 SetDlgItemInt(tablist[NSSM_TAB_ROTATION], IDC_ROTATE_BYTES_LOW, 0, 0);
\r
1032 set_rotation_enabled(0);
\r
1034 /* Environment tab. */
\r
1035 tab.pszText = message_string(NSSM_GUI_TAB_ENVIRONMENT);
\r
1036 tab.cchTextMax = (int) _tcslen(tab.pszText) + 1;
\r
1037 SendMessage(tabs, TCM_INSERTITEM, NSSM_TAB_ENVIRONMENT, (LPARAM) &tab);
\r
1038 tablist[NSSM_TAB_ENVIRONMENT] = dialog(MAKEINTRESOURCE(IDD_ENVIRONMENT), window, tab_dlg);
\r
1039 ShowWindow(tablist[NSSM_TAB_ENVIRONMENT], SW_HIDE);
\r
1045 NMHDR *notification;
\r
1047 notification = (NMHDR *) l;
\r
1048 switch (notification->code) {
\r
1049 case TCN_SELCHANGE:
\r
1053 tabs = GetDlgItem(window, IDC_TAB1);
\r
1054 if (! tabs) return 0;
\r
1056 selection = (int) SendMessage(tabs, TCM_GETCURSEL, 0, 0);
\r
1057 if (selection != selected_tab) {
\r
1058 ShowWindow(tablist[selected_tab], SW_HIDE);
\r
1059 ShowWindow(tablist[selection], SW_SHOWDEFAULT);
\r
1060 SetFocus(GetDlgItem(window, IDOK));
\r
1061 selected_tab = selection;
\r
1068 /* Button was pressed or control was controlled */
\r
1070 switch (LOWORD(w)) {
\r
1073 if ((int) GetWindowLongPtr(window, GWLP_USERDATA) == IDD_EDIT) {
\r
1074 if (! edit(window, (nssm_service_t *) GetWindowLongPtr(window, DWLP_USER))) PostQuitMessage(0);
\r
1076 else if (! install(window)) PostQuitMessage(0);
\r
1079 /* Cancel button */
\r
1081 DestroyWindow(window);
\r
1084 /* Remove button */
\r
1086 if (! remove(window)) PostQuitMessage(0);
\r
1091 /* Window closing */
\r
1093 DestroyWindow(window);
\r
1096 PostQuitMessage(0);
\r