nssm.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #include "nssm.h"
  2. extern unsigned long tls_index;
  3. extern bool is_admin;
  4. /* String function */
  5. int str_equiv(const char *a, const char *b) {
  6. int i;
  7. for (i = 0; ; i++) {
  8. if (tolower(b[i]) != tolower(a[i])) return 0;
  9. if (! a[i]) return 1;
  10. }
  11. }
  12. /* How to use me correctly */
  13. int usage(int ret) {
  14. print_message(stderr, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_DATE);
  15. return(ret);
  16. }
  17. void check_admin() {
  18. is_admin = false;
  19. /* Lifted from MSDN examples */
  20. PSID AdministratorsGroup;
  21. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  22. if (! AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &AdministratorsGroup)) return;
  23. CheckTokenMembership(0, AdministratorsGroup, /*XXX*/(PBOOL) &is_admin);
  24. FreeSid(AdministratorsGroup);
  25. }
  26. int main(int argc, char **argv) {
  27. /* Remember if we are admin */
  28. check_admin();
  29. /* Elevate */
  30. if (argc > 1) {
  31. /* Valid commands are install or remove */
  32. if (str_equiv(argv[1], "install")) {
  33. if (! is_admin) {
  34. print_message(stderr, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_INSTALL);
  35. exit(100);
  36. }
  37. exit(pre_install_service(argc - 2, argv + 2));
  38. }
  39. if (str_equiv(argv[1], "remove")) {
  40. if (! is_admin) {
  41. print_message(stderr, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_REMOVE);
  42. exit(100);
  43. }
  44. exit(pre_remove_service(argc - 2, argv + 2));
  45. }
  46. }
  47. /* Thread local storage for error message buffer */
  48. tls_index = TlsAlloc();
  49. /* Register messages */
  50. if (is_admin) create_messages();
  51. /* Start service magic */
  52. SERVICE_TABLE_ENTRY table[] = { { NSSM, service_main }, { 0, 0 } };
  53. if (! StartServiceCtrlDispatcher(table)) {
  54. unsigned long error = GetLastError();
  55. /* User probably ran nssm with no argument */
  56. if (error == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) exit(usage(1));
  57. log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_DISPATCHER_FAILED, error_string(error), 0);
  58. exit(100);
  59. }
  60. /* And nothing more to do */
  61. exit(0);
  62. }