Pass parameters around in a data structure.
[nssm.git] / gui.cpp
diff --git a/gui.cpp b/gui.cpp
index 83f2165..7773a18 100644 (file)
--- a/gui.cpp
+++ b/gui.cpp
@@ -1,13 +1,19 @@
 #include "nssm.h"\r
 \r
-int nssm_gui(int resource, char *name) {\r
-  char blurb[256];\r
+static void strip_basename(char *buffer) {\r
+  size_t len = strlen(buffer);\r
+  size_t i;\r
+  for (i = len; i && buffer[i] != '\\' && buffer[i] != '/'; i--);\r
+  /* X:\ is OK. */\r
+  if (i && buffer[i-1] == ':') i++;\r
+  buffer[i] = '\0';\r
+}\r
 \r
+int nssm_gui(int resource, char *name) {\r
   /* Create window */\r
   HWND dlg = CreateDialog(0, MAKEINTRESOURCE(resource), 0, install_dlg);\r
   if (! dlg) {\r
-    _snprintf(blurb, sizeof(blurb), "CreateDialog() failed with error code %d", GetLastError());\r
-    MessageBox(0, blurb, NSSM, MB_OK);\r
+    popup_message(MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));\r
     return 1;\r
   }\r
 \r
@@ -31,6 +37,7 @@ int nssm_gui(int resource, char *name) {
   /* Go! */\r
   MSG message;\r
   while (GetMessage(&message, 0, 0, 0)) {\r
+    if (IsDialogMessage(dlg, &message)) continue;\r
     TranslateMessage(&message);\r
     DispatchMessage(&message);\r
   }\r
@@ -65,56 +72,68 @@ void centre_window(HWND window) {
 int install(HWND window) {\r
   if (! window) return 1;\r
 \r
-  /* Check parameters in the window */\r
-  char name[STRING_SIZE];\r
-  char exe[EXE_LENGTH];\r
-  char flags[STRING_SIZE];\r
+  nssm_service_t *service = alloc_nssm_service();\r
+  if (service) {\r
+    /* Get service name. */\r
+    if (! GetDlgItemText(window, IDC_NAME, service->name, sizeof(service->name))) {\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);\r
+      cleanup_nssm_service(service);\r
+      return 2;\r
+    }\r
 \r
-  /* Get service name */\r
-  if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {\r
-    MessageBox(0, "No valid service name was specified!", NSSM, MB_OK);\r
-    return 2;\r
-  }\r
+    /* Get executable name */\r
+    if (! GetDlgItemText(window, IDC_PATH, service->exe, sizeof(service->exe))) {\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);\r
+      return 3;\r
+    }\r
+  \r
+    /* Get flags */\r
+    if (SendMessage(GetDlgItem(window, IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {\r
+      if (! GetDlgItemText(window, IDC_FLAGS, service->flags, sizeof(service->flags))) {\r
+        popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);\r
+        return 4;\r
+      }
+    }\r
 \r
-  /* Get executable name */\r
-  if (! GetDlgItemText(window, IDC_PATH, exe, sizeof(exe))) {\r
-    MessageBox(0, "No valid executable path was specified!", NSSM, MB_OK);\r
-    return 3;\r
+    memmove(service->dir, service->exe, strlen(service->exe));\r
+    strip_basename(service->dir);\r
   }\r
 \r
-  /* Get flags */\r
-  if (SendMessage(GetDlgItem(window, IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {\r
-    if (! GetDlgItemText(window, IDC_FLAGS, flags, sizeof(flags))) {\r
-      MessageBox(0, "No valid options were specified!", NSSM, MB_OK);\r
-      return 4;\r
-    }\r
-  }\r
-  else ZeroMemory(&flags, sizeof(flags));\r
+  /* See if it works. */\r
+  switch (install_service(service)) {\r
+    case 1:\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, "service", "install()");\r
+      cleanup_nssm_service(service);\r
+      return 1;\r
 \r
-  /* See if it works */\r
-  switch (install_service(name, exe, flags)) {\r
     case 2:\r
-      MessageBox(0, "Can't open service manager!\nPerhaps you need to be an administrator...", NSSM, MB_OK);\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);\r
+      cleanup_nssm_service(service);\r
       return 2;\r
 \r
     case 3:\r
-      MessageBox(0, "Path too long!\nThe full path to " NSSM " is too long.\nPlease install " NSSM " somewhere else...\n", NSSM, MB_OK);\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);\r
+      cleanup_nssm_service(service);\r
       return 3;\r
 \r
     case 4:\r
-      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
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);\r
+      cleanup_nssm_service(service);\r
       return 4;\r
 \r
     case 5:\r
-      MessageBox(0, "Couldn't create service!\nPerhaps it is already installed...", NSSM, MB_OK);\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);\r
+      cleanup_nssm_service(service);\r
       return 5;\r
 \r
     case 6:\r
-      MessageBox(0, "Couldn't set startup parameters for the service!\nDeleting the service...", NSSM, MB_OK);\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);\r
+      cleanup_nssm_service(service);\r
       return 6;\r
   }\r
 \r
-  MessageBox(0, "Service successfully installed!", NSSM, MB_OK);\r
+  popup_message(MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, service->name);\r
+  cleanup_nssm_service(service);\r
   return 0;\r
 }\r
 \r
@@ -122,58 +141,88 @@ int install(HWND window) {
 int remove(HWND window) {\r
   if (! window) return 1;\r
 \r
-  /* Check parameters in the window */\r
-  char name[STRING_SIZE];\r
+  /* See if it works */\r
+  nssm_service_t *service = alloc_nssm_service();\r
+  if (service) {\r
+    /* Get service name */\r
+    if (! GetDlgItemText(window, IDC_NAME, service->name, sizeof(service->name))) {\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);\r
+      cleanup_nssm_service(service);\r
+      return 2;\r
+    }\r
 \r
-  /* Get service name */\r
-  if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {\r
-    MessageBox(0, "No valid service name was specified!", NSSM, MB_OK);\r
-    return 2;\r
+    /* Confirm */\r
+    if (popup_message(MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, service->name) != IDYES) {\r
+      cleanup_nssm_service(service);\r
+      return 0;\r
+    }\r
   }\r
 \r
-  /* Confirm */\r
-  char blurb[MAX_PATH];\r
-  if (_snprintf(blurb, sizeof(blurb), "Remove the \"%s\" service?", name) < 0) {\r
-    if (MessageBox(0, "Remove the service?", NSSM, MB_YESNO) != IDYES) return 0;\r
-  }\r
-  else if (MessageBox(0, blurb, NSSM, MB_YESNO) != IDYES) return 0;\r
+  switch (remove_service(service)) {\r
+    case 1:\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_EVENT_OUT_OF_MEMORY, "service", "remove()");\r
+      cleanup_nssm_service(service);\r
+      return 1;\r
 \r
-  /* See if it works */\r
-  switch (remove_service(name)) {\r
     case 2:\r
-      MessageBox(0, "Can't open service manager!\nPerhaps you need to be an administrator...", NSSM, MB_OK);\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);\r
+      cleanup_nssm_service(service);\r
       return 2;\r
 \r
     case 3:\r
-      MessageBox(0, "Can't open service!\nPerhaps it isn't installed...", NSSM, MB_OK);\r
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);\r
       return 3;\r
+      cleanup_nssm_service(service);\r
 \r
     case 4:\r
-      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
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);\r
+      cleanup_nssm_service(service);\r
       return 4;\r
   }\r
 \r
-  MessageBox(0, "Service successfully removed!", NSSM, MB_OK);\r
+  popup_message(MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, service->name);\r
+  cleanup_nssm_service(service);\r
   return 0;\r
 }\r
 \r
-/* Browse for game */\r
+/* Browse for application */\r
 void browse(HWND window) {\r
   if (! window) return;\r
 \r
+  size_t bufsize = 256;\r
+  size_t len = bufsize;\r
   OPENFILENAME ofn;\r
   ZeroMemory(&ofn, sizeof(ofn));\r
   ofn.lStructSize = sizeof(ofn);\r
-  ofn.lpstrFilter = "Applications\0*.exe\0All files\0*.*\0\0";\r
+  ofn.lpstrFilter = (char *) HeapAlloc(GetProcessHeap(), 0, bufsize);\r
+  /* XXX: Escaping nulls with FormatMessage is tricky */\r
+  if (ofn.lpstrFilter) {\r
+    ZeroMemory((void *) ofn.lpstrFilter, bufsize);\r
+    char *localised = message_string(NSSM_GUI_BROWSE_FILTER_APPLICATIONS);\r
+    _snprintf_s((char *) ofn.lpstrFilter, bufsize, _TRUNCATE, localised);\r
+    /* "Applications" + NULL + "*.exe" + NULL */\r
+    len = strlen(localised) + 1;\r
+    LocalFree(localised);\r
+    _snprintf_s((char *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, "*.exe");\r
+    /* "All files" + NULL + "*.*" + NULL */\r
+    len += 6;\r
+    localised = message_string(NSSM_GUI_BROWSE_FILTER_ALL_FILES);\r
+    _snprintf_s((char *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, localised);\r
+    len += strlen(localised) + 1;\r
+    LocalFree(localised);\r
+    _snprintf_s((char *) ofn.lpstrFilter + len, bufsize - len, _TRUNCATE, "*.*");\r
+    /* Remainder of the buffer is already zeroed */\r
+  }\r
   ofn.lpstrFile = new char[MAX_PATH];\r
   ofn.lpstrFile[0] = '\0';\r
-  ofn.lpstrTitle = "Locate application file";\r
+  ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);\r
   ofn.nMaxFile = MAX_PATH;\r
   ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;\r
 \r
   if (GetOpenFileName(&ofn)) {\r
     SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);\r
   }\r
+  if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);\r
 \r
   delete[] ofn.lpstrFile;\r
 }\r
@@ -190,11 +239,11 @@ INT_PTR CALLBACK install_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
       switch (LOWORD(w)) {\r
         /* OK button */\r
         case IDC_OK:\r
-          PostQuitMessage(install(window));\r
+          if (! install(window)) PostQuitMessage(0);\r
           break;\r
 \r
         /* Cancel button */\r
-        case IDC_CANCEL:\r
+        case IDCANCEL:\r
           DestroyWindow(window);\r
           break;\r
 \r
@@ -205,7 +254,7 @@ INT_PTR CALLBACK install_dlg(HWND window, UINT message, WPARAM w, LPARAM l) {
 \r
         /* Remove button */\r
         case IDC_REMOVE:\r
-          PostQuitMessage(remove(window));\r
+          if (! remove(window)) PostQuitMessage(0);\r
           break;\r
       }\r
       return 1;\r