NSSM 1.0.
[nssm.git] / gui.cpp
1 #include "nssm.h"\r
2 \r
3 int nssm_gui(int resource, char *name) {\r
4   char blurb[256];\r
5 \r
6   /* Create window */\r
7   HWND dlg = CreateDialog(0, MAKEINTRESOURCE(resource), 0, install_dlg);\r
8   if (! dlg) {\r
9     snprintf(blurb, sizeof(blurb), "CreateDialog() failed with error code %d", GetLastError());\r
10     MessageBox(0, blurb, NSSM, MB_OK);\r
11     return 1;\r
12   }\r
13 \r
14   /* Display the window */\r
15   centre_window(dlg);\r
16   ShowWindow(dlg, SW_SHOW);\r
17 \r
18   /* Set service name if given */\r
19   if (name) {\r
20     SetDlgItemText(dlg, IDC_NAME, name);\r
21     /* No point making user click remove if the name is already entered */\r
22     if (resource == IDD_REMOVE) {\r
23       HWND button = GetDlgItem(dlg, IDC_REMOVE);\r
24       if (button) {\r
25         SendMessage(button, WM_LBUTTONDOWN, 0, 0);\r
26         SendMessage(button, WM_LBUTTONUP, 0, 0);\r
27       }\r
28     }\r
29   }\r
30 \r
31   /* Go! */\r
32   MSG message;\r
33   while (GetMessage(&message, 0, 0, 0)) {\r
34     TranslateMessage(&message);\r
35     DispatchMessage(&message);\r
36   }\r
37 \r
38   return message.wParam;\r
39 }\r
40 \r
41 void centre_window(HWND window) {\r
42   HWND desktop;\r
43   RECT size, desktop_size;\r
44   unsigned long x, y;\r
45 \r
46   if (! window) return;\r
47 \r
48   /* Find window size */\r
49   if (! GetWindowRect(window, &size)) return;\r
50   \r
51   /* Find desktop window */\r
52   desktop = GetDesktopWindow();\r
53   if (! desktop) return;\r
54 \r
55   /* Find desktop window size */\r
56   if (! GetWindowRect(desktop, &desktop_size)) return;\r
57 \r
58   /* Centre window */\r
59   x = (desktop_size.right - size.right) / 2;\r
60   y = (desktop_size.bottom - size.bottom) / 2;\r
61   MoveWindow(window, x, y, size.right, size.bottom, 0);\r
62 }\r
63 \r
64 /* Install the service */\r
65 int install(HWND window) {\r
66   if (! window) return 1;\r
67 \r
68   /* Check parameters in the window */\r
69   char name[STRING_SIZE];\r
70   char exe[MAX_PATH];\r
71   char flags[STRING_SIZE];\r
72   char dir[MAX_PATH];\r
73 \r
74   /* Get service name */\r
75   if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {\r
76     MessageBox(0, "No valid service name was specified!", NSSM, MB_OK);\r
77     return 2;\r
78   }\r
79 \r
80   /* Get executable name */\r
81   if (! GetDlgItemText(window, IDC_PATH, exe, sizeof(exe))) {\r
82     MessageBox(0, "No valid executable path was specified!", NSSM, MB_OK);\r
83     return 3;\r
84   }\r
85 \r
86   /* Get flags */\r
87   if (SendMessage(GetDlgItem(window, IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {\r
88     if (! GetDlgItemText(window, IDC_FLAGS, flags, sizeof(flags))) {\r
89       MessageBox(0, "No valid options were specified!", NSSM, MB_OK);\r
90       return 4;\r
91     }\r
92   }\r
93   else ZeroMemory(&flags, sizeof(flags));\r
94 \r
95   /* Work out directory name */\r
96   unsigned int len = strlen(exe);\r
97   unsigned int i;\r
98   for (i = len; i && exe[i] != '\\' && exe[i] != '/'; i--);\r
99   memmove(dir, exe, i);\r
100   dir[i] = '\0';\r
101 \r
102   /* Open service manager */\r
103   SC_HANDLE services = open_service_manager();\r
104   if (! services) {\r
105     MessageBox(0, "Can't open service manager!\nPerhaps you need to be an administrator...", NSSM, MB_OK);\r
106     return 2;\r
107   }\r
108   \r
109   /* Get path of this program */\r
110   char path[MAX_PATH];\r
111   GetModuleFileName(0, path, MAX_PATH);\r
112 \r
113   /* Construct command */\r
114   char command[MAX_PATH];\r
115   int runlen = strlen(NSSM_RUN);\r
116   int pathlen = strlen(path);\r
117   if (pathlen + runlen + 2 >= MAX_PATH) {\r
118     MessageBox(0, "Path too long!\nThe full path to " NSSM " is too long.\nPlease install " NSSM " somewhere else...\n", NSSM, MB_OK);\r
119     return 3;\r
120   }\r
121   if (snprintf(command, sizeof(command), "%s %s", path, NSSM_RUN) < 0) {\r
122      MessageBox(0, "Error constructing ImagePath!\nThis really shouldn't happen.  You could be out of memory\nor the world may be about to end or something equally bad.", NSSM, MB_OK);\r
123      return 4;\r
124   }\r
125 \r
126   /* Create the service */\r
127   SC_HANDLE service = CreateService(services, name, name, SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, command, 0, 0, 0, 0, 0);\r
128   if (! service) {\r
129     MessageBox(0, "Couldn't create service!\nPerhaps it is already installed...", NSSM, MB_OK);\r
130     CloseServiceHandle(services);\r
131     return 5;\r
132   }\r
133 \r
134   /* Now we need to put the parameters into the registry */\r
135   if (create_parameters(name, exe, flags, dir)) {\r
136     MessageBox(0, "Couldn't set startup parameters for the service!\nDeleting the service...", NSSM, MB_OK);\r
137     DeleteService(service);\r
138     CloseServiceHandle(services);\r
139     return 6;\r
140   }\r
141 \r
142   /* Cleanup */\r
143   CloseServiceHandle(service);\r
144   CloseServiceHandle(services);\r
145 \r
146   MessageBox(0, "Service successfully installed!", NSSM, MB_OK);\r
147   return 0;\r
148 }\r
149 \r
150 /* Remove the service */\r
151 int remove(HWND window) {\r
152   if (! window) return 1;\r
153 \r
154   /* Check parameters in the window */\r
155   char name[STRING_SIZE];\r
156 \r
157   /* Get service name */\r
158   if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {\r
159     MessageBox(0, "No valid service name was specified!", NSSM, MB_OK);\r
160     return 2;\r
161   }\r
162 \r
163   /* Confirm */\r
164   char blurb[MAX_PATH];\r
165   if (snprintf(blurb, sizeof(blurb), "Remove the \"%s\" service?", name) < 0) {\r
166     if (MessageBox(0, "Remove the service?", NSSM, MB_YESNO) != IDYES) return 0;\r
167   }\r
168   else if (MessageBox(0, blurb, NSSM, MB_YESNO) != IDYES) return 0;\r
169 \r
170   /* Open service manager */\r
171   SC_HANDLE services = open_service_manager();\r
172   if (! services) {\r
173     MessageBox(0, "Can't open service manager!\nPerhaps you need to be an administrator...", NSSM, MB_OK);\r
174     return 2;\r
175   }\r
176   \r
177   /* Try to open the service */\r
178   SC_HANDLE service = OpenService(services, name, SC_MANAGER_ALL_ACCESS);\r
179   if (! service) {\r
180     MessageBox(0, "Can't open service!\nPerhaps it isn't installed...", NSSM, MB_OK);\r
181     CloseServiceHandle(services);\r
182     return 3;\r
183   }\r
184 \r
185   /* Try to delete the service */\r
186   if (! DeleteService(service)) {\r
187     MessageBox(0, "Can't delete service!  Make sure the service is stopped and try again.\nIf this error persists, you may need to set the service NOT to start\nautomatically, reboot your computer and try removing it again.", NSSM, MB_OK);\r
188     CloseServiceHandle(service);\r
189     CloseServiceHandle(services);\r
190     return 4;\r
191   }\r
192 \r
193   /* Cleanup */\r
194   CloseServiceHandle(service);\r
195   CloseServiceHandle(services);\r
196 \r
197   MessageBox(0, "Service successfully removed!", NSSM, MB_OK);\r
198   return 0;\r
199 }\r
200 \r
201 /* Browse for game */\r
202 void browse(HWND window) {\r
203   if (! window) return;\r
204 \r
205   OPENFILENAME ofn;\r
206   ZeroMemory(&ofn, sizeof(ofn));\r
207   ofn.lStructSize = sizeof(ofn);\r
208   ofn.lpstrFilter = "Applications\0*.exe\0All files\0*.*\0\0";\r
209   ofn.lpstrFile = new char[MAX_PATH];\r
210   ofn.lpstrFile[0] = '\0';\r
211   ofn.lpstrTitle = "Locate application file";\r
212   ofn.nMaxFile = MAX_PATH;\r
213   ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;\r
214 \r
215   if (GetOpenFileName(&ofn)) {\r
216     SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);\r
217   }\r
218 \r
219   delete[] ofn.lpstrFile;\r
220 }\r
221 \r
222 /* Install/remove dialogue callback */\r
223 int CALLBACK install_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {\r
224   switch (message) {\r
225     /* Creating the dialogue */\r
226     case WM_INITDIALOG:\r
227       return 1;\r
228 \r
229     /* Button was pressed or control was controlled */\r
230     case WM_COMMAND:\r
231       switch (LOWORD(w)) {\r
232         /* OK button */\r
233         case IDC_OK:\r
234           PostQuitMessage(install(window));\r
235           break;\r
236 \r
237         /* Cancel button */\r
238         case IDC_CANCEL:\r
239           DestroyWindow(window);\r
240           break;\r
241 \r
242         /* Browse button */\r
243         case IDC_BROWSE:\r
244           browse(GetDlgItem(window, IDC_PATH));\r
245           break;\r
246 \r
247         /* Remove button */\r
248         case IDC_REMOVE:\r
249           PostQuitMessage(remove(window));\r
250           break;\r
251       }\r
252       return 1;\r
253 \r
254     /* Window closing */\r
255     case WM_CLOSE:\r
256       DestroyWindow(window);\r
257       return 0;\r
258     case WM_DESTROY:\r
259       PostQuitMessage(0);\r
260   }\r
261   return 0;\r
262 }\r