home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / WEBSERVE / SAMBAR / DATA.1 / NTMAIN.C < prev    next >
C/C++ Source or Header  |  1997-07-29  |  9KB  |  444 lines

  1. /*
  2. ** NTMAIN
  3. **
  4. **      This is the main driver for the Windows NT Service driver of 
  5. **        the Sambar Server. 
  6. **
  7. **        Confidential Property of Tod Sambar
  8. **        (c) Copyright Tod Sambar 1997
  9. **        All rights reserved.
  10. **
  11. **
  12. ** Syntax:
  13. **
  14. **      ntserver [-i] [-u] [-d]
  15. **
  16. **            -i        Install the Sambar Server as an NT Service
  17. **             -u        Uninstall the Sambar Server NT Service
  18. **            -d         Start the Sambar Server in debug mode
  19. **
  20. **
  21. ** History:
  22. ** Chg#    Date    Description                                                Resp
  23. ** ----    -------    -------------------------------------------------------    ----
  24. **        26JUL97    Created                                                    sambar
  25. */
  26.  
  27. #include     <windows.h>
  28. #include    <stdio.h>
  29. #include    <stdlib.h>
  30. #include     <direct.h>
  31. #include     <process.h>
  32. #include    <sambar.h>
  33.  
  34. /*
  35. ** Local Defines
  36. */
  37. #define SERVICE_NAME        "Sambar Server"
  38. #define SERVICE_TITLE        "Sambar Server"
  39. #define NTSERVER_DEBUG        (SA_INT)0x0001
  40. #define NTSERVER_INSTALL    (SA_INT)0x0002
  41. #define NTSERVER_UNINSTALL    (SA_INT)0x0004
  42.  
  43.  
  44. /*
  45. ** Local Prototypes
  46. */
  47. static SA_RETCODE     get_args(int argc, char **argv, SA_INT *flagsp);
  48. static void         syntax_error(char *name, char *argv);
  49. static SA_RETCODE    install_service(void);
  50. static SA_RETCODE    uninstall_service(void);
  51. VOID                 service_main(DWORD argc, LPTSTR *argv);
  52. VOID                  service_ctrl(DWORD dwCtrlCode);
  53. static SA_RETCODE    service_cd(void);
  54. static void         service_status(int state, int exitCode, int waitHint);
  55.  
  56.  
  57. /*
  58. ** Global Handles
  59. */
  60. static SERVICE_STATUS_HANDLE    hServiceStatus;
  61. static int                        sState;
  62.  
  63.  
  64.  
  65. int    
  66. main(int argc, char *argv[])
  67. {
  68.     SA_INT    flags;
  69.  
  70.     /*
  71.     ** Read the command line arguments.
  72.     */
  73.     if (get_args(argc, argv, &flags) != SA_SUCCEED)
  74.         return (0);
  75.  
  76.     if (flags & NTSERVER_INSTALL)
  77.     {
  78.         if (install_service() != SA_SUCCEED)
  79.             return (-1);
  80.  
  81.         fprintf(stdout, 
  82.             "The %s NT Service can be started from the Service Panel.\n", 
  83.             SERVICE_NAME);
  84.  
  85.         return (0);
  86.     }
  87.  
  88.     if (flags & NTSERVER_UNINSTALL)
  89.     {
  90.         if (uninstall_service() != SA_SUCCEED)
  91.             return (-1);
  92.  
  93.         return (0);
  94.     }
  95.  
  96.     /* Change to the appropriate working directory for execution        */ 
  97.     if (service_cd() != SA_SUCCEED)
  98.         return (-1);
  99.  
  100.     if (flags & NTSERVER_DEBUG)
  101.     {
  102.         /* Execute the Sambar Server Shell                                */
  103.         if (sa_server((SA_VOID *)NULL) != SA_SUCCEED)
  104.             return (-1);
  105.     }
  106.     else
  107.     {
  108.         SERVICE_TABLE_ENTRY        ste[] =
  109.         {
  110.             { SERVICE_NAME,        (LPSERVICE_MAIN_FUNCTION)service_main },
  111.             { NULL,                NULL }
  112.         };
  113.  
  114.         if (StartServiceCtrlDispatcher(ste) != TRUE)
  115.         {
  116.             fprintf(stderr, "Failed to start %s NT Service (%d)\n",
  117.                 SERVICE_NAME, GetLastError());
  118.             return (-1);
  119.         }
  120.     }
  121.  
  122.     return (0);
  123. }
  124.  
  125. /*
  126. **  GET_ARGS
  127. **
  128. **     This routine parses the command line arguments passed to the
  129. **     NT Server application.
  130. **
  131. */
  132. static SA_RETCODE
  133. get_args(int argc, char **argv, SA_INT *flagsp)
  134. {
  135.     int        j;
  136.     SA_INT    flags;
  137.  
  138.     /* Initialization                                                    */
  139.     flags = 0;
  140.  
  141.     /*
  142.     ** Are there any arguments to parse?
  143.     */
  144.     if (argc <= 1)
  145.     {
  146.         /*
  147.         ** We don't have any arguments.
  148.         */
  149.         *flagsp = 0;
  150.         return (SA_SUCCEED);
  151.     }
  152.  
  153.     /* Loop through the arguments                                        */
  154.     j = 1;
  155.  
  156.     while (j < argc)
  157.     {
  158.         if (strcmp(argv[j], "-i") == 0)
  159.         {
  160.             flags |= NTSERVER_INSTALL;
  161.         }
  162.         else if (strcmp(argv[j], "-u") == 0)
  163.         {
  164.             flags |= NTSERVER_UNINSTALL;
  165.         }
  166.         else if (strcmp(argv[j], "-d") == 0)
  167.         {
  168.             flags |= NTSERVER_DEBUG;
  169.         }
  170.         else
  171.         {
  172.             syntax_error(argv[0], argv[j]);
  173.             return (SA_FAIL);
  174.         }
  175.  
  176.         j++;
  177.     }
  178.  
  179.     *flagsp = flags;
  180.  
  181.     /*
  182.     ** All done.
  183.     */
  184.     return (SA_SUCCEED);
  185. }
  186.  
  187. /*
  188. ** SYNTAX_ERROR
  189. **
  190. **     This routine is used to inform the user that a command-line
  191. **     syntax error occurred.
  192. */
  193. static void
  194. syntax_error(char *name, char *argv)
  195. {
  196.     /*
  197.     ** Print the error string.
  198.     */
  199.     if (argv != NULL)
  200.         fprintf(stderr, "\nUnexpected flag: %s\n", argv);
  201.  
  202.     fprintf(stderr, "\nCorrect syntax is: %s\n", name);
  203.  
  204.     fprintf(stderr, "\t\t[-i]      # Install the NT Service\n");
  205.     fprintf(stderr, "\t\t[-u]      # Unistall the NT Service\n");
  206.     fprintf(stderr, "\t\t[-d]      # Start the Sambar Server in debug mode\n");
  207.  
  208.     return;
  209. }
  210.  
  211. static SA_RETCODE
  212. install_service(void)
  213. {
  214.     SC_HANDLE    schService;
  215.     SC_HANDLE    schSCManager;
  216.     TCHAR         szPath[512];
  217.  
  218.     if (GetModuleFileName(NULL, szPath, 512) == 0)
  219.     {
  220.         fprintf(stderr, "Failed to get exe for service %s (%d)\n", 
  221.             SERVICE_NAME, GetLastError());
  222.         return (SA_FAIL);
  223.     }
  224.  
  225.     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  226.  
  227.     if (schSCManager == NULL)
  228.     {
  229.         fprintf(stderr, "Failed to open the service manager.\n");
  230.         return (SA_FAIL);
  231.     }
  232.  
  233.     schService = CreateService(schSCManager, SERVICE_NAME, SERVICE_TITLE,
  234.                     SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
  235.                     SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
  236.                     szPath, NULL, NULL, NULL, NULL, NULL);
  237.  
  238.  
  239.     if (schService == NULL)
  240.     {
  241.         fprintf(stderr, "Failed to create service %s (%d)\n", 
  242.             SERVICE_NAME, GetLastError());
  243.         CloseServiceHandle(schSCManager);
  244.         return (SA_FAIL);
  245.     }
  246.  
  247.     fprintf(stdout, "Installed service %s.\n", SERVICE_NAME);
  248.  
  249.     CloseServiceHandle(schService);
  250.     CloseServiceHandle(schSCManager);
  251.  
  252.     return (SA_SUCCEED);
  253. }
  254.  
  255. static SA_RETCODE
  256. uninstall_service(void)
  257. {
  258.     SC_HANDLE        schService;
  259.     SC_HANDLE        schSCManager;
  260.     SERVICE_STATUS    status;
  261.  
  262.     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
  263.  
  264.     if (schSCManager == NULL)
  265.     {
  266.         fprintf(stderr, "Failed to open the service manager.\n");
  267.         return (SA_FAIL);
  268.     }
  269.  
  270.     schService = OpenService(schSCManager, SERVICE_NAME, SERVICE_ALL_ACCESS);
  271.  
  272.     if (schService == NULL)
  273.     {
  274.         fprintf(stderr, "Failed to open service %s (%d).\n", 
  275.             SERVICE_NAME, GetLastError());
  276.         CloseServiceHandle(schSCManager);
  277.         return (SA_FAIL);
  278.     }
  279.  
  280.     /* Try to stop the service                                             */
  281.     if (ControlService(schService, SERVICE_CONTROL_STOP, &status))
  282.     {
  283.         Sleep(1000);
  284.         while (QueryServiceStatus(schService, &status))
  285.         {
  286.             if (status.dwCurrentState == SERVICE_STOP_PENDING)
  287.                 Sleep(1000);
  288.             else
  289.                 break;
  290.         }
  291.     }
  292.  
  293.     /* Delete the service                                                */
  294.     if (DeleteService(schService) != TRUE)
  295.     {
  296.         fprintf(stderr, "Failed in attempt to delete service %s (%d).\n", 
  297.             SERVICE_NAME, GetLastError());
  298.         CloseServiceHandle(schService);
  299.         CloseServiceHandle(schSCManager);
  300.         return (SA_FAIL);
  301.     }
  302.  
  303.     fprintf(stdout, "Deleted service %s.\n", SERVICE_NAME);
  304.     CloseServiceHandle(schService);
  305.     CloseServiceHandle(schSCManager);
  306.  
  307.     return (SA_SUCCEED);
  308. }
  309.  
  310. VOID
  311. service_main(DWORD argc, LPTSTR *argv)
  312. {
  313.     hServiceStatus = RegisterServiceCtrlHandler(SERVICE_NAME, 
  314.                         (LPHANDLER_FUNCTION)service_ctrl);
  315.     if (!hServiceStatus)
  316.     {
  317.         fprintf(stderr, "Failed to register %s service control handler (%d).\n",
  318.             SERVICE_NAME, GetLastError());
  319.         return;
  320.     }
  321.  
  322.     service_status(SERVICE_START_PENDING, NO_ERROR, 5000);
  323.  
  324.     service_status(SERVICE_RUNNING, NO_ERROR, 0);
  325.  
  326.     /* Start the Sambar Server                                            */
  327.     sa_server((SA_VOID *)NULL);
  328.  
  329.     service_status(SERVICE_STOPPED, NO_ERROR, 0);
  330.  
  331.     return;
  332. }
  333.  
  334. VOID
  335. service_ctrl(DWORD dwCtrlCode)
  336. {
  337.     int     state;
  338.  
  339.     state = sState;
  340.  
  341.     switch(dwCtrlCode)
  342.     {
  343.         // Stop the service.
  344.         //
  345.         case SERVICE_CONTROL_STOP:
  346.         case SERVICE_CONTROL_SHUTDOWN:
  347.             service_status(SERVICE_STOP_PENDING, NO_ERROR, 8000);
  348.  
  349.             (SA_VOID)sa_shutdown();
  350.             return;
  351.  
  352.         // Update the service status.
  353.         //
  354.         case SERVICE_CONTROL_INTERROGATE:
  355.             break;
  356.  
  357.         // invalid control code
  358.         //
  359.         default:
  360.             break;
  361.     }
  362.  
  363.     service_status(state, NO_ERROR, 0);
  364. }
  365.  
  366.  
  367. static void
  368. service_status(int state, int exitCode, int waitHint)
  369. {
  370.     SERVICE_STATUS    status;
  371.     
  372.     status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  373.     status.dwServiceSpecificExitCode = 0;
  374.     status.dwCheckPoint = 0;
  375.  
  376.     if (state == SERVICE_START_PENDING)
  377.     {
  378.         status.dwControlsAccepted = 0;
  379.     }
  380.     else
  381.     {
  382.         status.dwControlsAccepted =    SERVICE_ACCEPT_STOP | 
  383.                                     SERVICE_ACCEPT_SHUTDOWN;
  384.     }
  385.  
  386.     sState = state;
  387.     status.dwCurrentState = state;
  388.     status.dwWin32ExitCode = exitCode;
  389.     status.dwWaitHint = waitHint;
  390.  
  391.     (VOID)SetServiceStatus(hServiceStatus, &status);
  392.  
  393.     return;
  394. }
  395.  
  396. static SA_RETCODE
  397. service_cd(void)
  398. {
  399.     int            count;
  400.     DWORD        len;
  401.     TCHAR         szPath[512];
  402.  
  403.     len = GetModuleFileName(NULL, szPath, 512);
  404.     if (len == 0)
  405.     {
  406.         fprintf(stderr, "Failed to get exe for service %s (%d)\n", 
  407.             SERVICE_NAME, GetLastError());
  408.         return (SA_FAIL);
  409.     }
  410.  
  411.     /* 
  412.     ** Change to the directory above the executable.                    
  413.     **
  414.     ** The working directory for the Sambar Server application must
  415.     ** be the installation directory.
  416.     */
  417.     count = 0;
  418.     while ((len > 0) && (count < 2))
  419.     {
  420.         len--;
  421.         if (szPath[len] == '\\')
  422.         {
  423.             count++;
  424.             szPath[len] = '\0';
  425.         }
  426.     }
  427.  
  428.     if (count != 2)
  429.     {
  430.         fprintf(stderr, 
  431.             "Unable to change to the Sambar Server installation.\n");
  432.         return (SA_FAIL);
  433.     }
  434.  
  435.     if (chdir(szPath) != 0)
  436.     {
  437.         fprintf(stderr, 
  438.             "Unable to change to the Sambar Server installation.\n");
  439.         return (SA_FAIL);
  440.     }
  441.  
  442.     return (SA_SUCCEED);
  443. }
  444.