mturk       2004/12/22 02:18:48

  Added:       daemon/src/native/nt/procrun/apps/srvbatch MSG00001.bin
                        srvbatch.c srvbatch.rc srvbatch.sln srvbatch.vcproj
               daemon/src/native/nt/procrun/apps/srvbatch/example example.c
                        example.vcproj exservice.bat
  Log:
  Add new component to procrun.
  It behaves like standard unix rc.d conerting batch script to
  a service management script. It allows to run any program like
  service, but the focus is on running batch files as services.
  
  Revision  Changes    Path
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/MSG00001.bin
  
        <<Binary file>>
  
  
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.c
  
  Index: srvbatch.c
  ===================================================================
  /* Copyright 2000-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  
  
  #include <windows.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <process.h>
  
  /* Custom return error values */
  #define ERR_RET_USAGE           1
  #define ERR_RET_VERSION         2
  #define ERR_RET_INSTALL         3
  #define ERR_RET_REMOVE          4
  #define ERR_RET_PARAMS          5
  #define ERR_RET_MODE            6
  
  #define MSG_ERROR               0xC0000001L
  #define MSG_INFO                0x40000002L
  
  
  
  #define MAX_CMDLINE   8192
  /* Extensions On, Old quote style */
  static LPCSTR CMD_DEFAULT     = "/E:ON /S /C \"SET SERVICE_PPID=%d && SET 
SERVICE_NAME=%s && CALL %s %s";
  static LPCSTR REGSERVICE_ROOT = "SYSTEM\\CurrentControlSet\\Services\\"; 
  static LPCSTR REGSERVICE_LOG  = 
"SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
  
  static LPCSTR REGPARAMS       = "\\Parameters";
  static LPCSTR REGDESCRIPTION  = "Description"; 
  static LPCSTR REG_SERVFILE    = "ServiceFile";
  static LPCSTR REG_LOGFILE     = "LogFile";
  static LPCSTR REG_WPATH       = "WorkingPath";
  
  
  /* Main servic table entry
   * filled at run-time
   */
  static SERVICE_TABLE_ENTRY  _service_table[] = {
          {NULL, NULL},
          {NULL, NULL}
  };
   
  static SERVICE_STATUS        _service_status; 
  static SERVICE_STATUS_HANDLE _service_status_handle = NULL; 
  static char                  _service_name[MAX_PATH + 1];
  static char                  _service_disp[MAX_PATH + 1];
  static char                  _service_desc[MAX_PATH * 2 + 1];
  static char                  _working_path[MAX_PATH + 1];
  static char                  _service_image[MAX_PATH + 1];
  static char                  _service_bat[MAX_PATH + 1];
  static char                  _cmd_exe[MAX_PATH + 1];
  static BOOL                  _service_log = FALSE;
  
  enum _service_mode_e {
      mode_none,
      mode_install,
      mode_uninstall,
      mode_debug,
      mode_run
  };
  
  static enum _service_mode_e   _service_mode = mode_none;
  
  static BOOL IsWindowsNT()
  {
      BOOL rv = FALSE;
      OSVERSIONINFO osvi;
  
      ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
      osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  
      if (!GetVersionEx(&osvi))
          return FALSE;
  
      switch (osvi.dwPlatformId) {
          case VER_PLATFORM_WIN32_NT:
              rv = TRUE;
          break;
          default:
              rv = FALSE;
          break;
      }
      return rv;
  }
  
  
  static BOOL IsServiceRunning(LPCSTR szServiceName)
  {
      DWORD rc = 0;
      SC_HANDLE schService;
      SC_HANDLE schSCManager;
      SERVICE_STATUS schSStatus;
  
      schSCManager = OpenSCManager(NULL, NULL,
                                   SC_MANAGER_CONNECT);
      if (!schSCManager)
          return FALSE;
  
      schService = OpenService(schSCManager, szServiceName, 
                               SERVICE_QUERY_STATUS);
      if (schService != NULL) {
          if (QueryServiceStatus(schService, &schSStatus))
              rc = schSStatus.dwCurrentState;
          CloseServiceHandle(schService);
          CloseServiceHandle(schSCManager);
          return rc == SERVICE_RUNNING ? TRUE : FALSE;
      }
      CloseServiceHandle(schSCManager);
      return FALSE;
  
  }
  
  static void AddToMessageLog(BOOL isError, LPSTR szFormat, ...)
  {
      char szMsg [MAX_PATH];
      LPSTR   lpszStrings[2];
      LPVOID  lpMsgBuf = NULL;
      HANDLE  hEventSource;
      DWORD dwErr = GetLastError();
      WORD  wErrType;
      DWORD dwErrId;
      WORD  nStr;
      va_list args;
  
      if (!_service_log && !isError) {
          /* Nothing to log */
          return;
      }
  
      va_start(args, szFormat);
      vsprintf(szMsg, szFormat, args);
      va_end(args); 
  
      if (isError) {
          nStr = 2;
          wErrType = EVENTLOG_ERROR_TYPE;
          dwErrId = MSG_ERROR;
          FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                          FORMAT_MESSAGE_FROM_SYSTEM |
                          FORMAT_MESSAGE_IGNORE_INSERTS,
                          NULL, GetLastError(),
                          MAKELANGID(LANG_NEUTRAL, LANG_NEUTRAL),
                          (LPSTR) &lpMsgBuf, 0, NULL);
          lpszStrings[0] = lpMsgBuf;
          lpszStrings[1] = szMsg;
      }
      else {
          wErrType = EVENTLOG_INFORMATION_TYPE;
          dwErrId = MSG_INFO;
          nStr = 1;
          lpszStrings[0] = szMsg;
      }
      /* Use event logging to log the error.
      */
      hEventSource = RegisterEventSource(NULL, _service_name);
  
      if (hEventSource != NULL) {
          ReportEvent(hEventSource, // handle of event source
              wErrType,             // event type
              0,                    // event category
              dwErrId,              // event ID
              NULL,                 // current user's SID
              nStr,                 // strings in lpszStrings
              0,                    // no bytes of raw data
              lpszStrings,          // array of error strings
              NULL);                // no raw data
          DeregisterEventSource(hEventSource);
      }
      if (lpMsgBuf)
          LocalFree(lpMsgBuf);
  }
  
  static void ErrorUsage()
  {
      if (_service_mode == mode_run)
          return;
  
      fprintf(stderr, "srvbatch -- program for running batch files as 
services.\n\n");
      fprintf(stderr, "Usage: srvbatch -i        service service.bat\n");
      fprintf(stderr, "                -i[wdcl]  service workingpath 
description comment\n"
                      "                          service.bat\n");
      fprintf(stderr, "                -u        service\n");
      fprintf(stderr, "                -t        service\n");
      fprintf(stderr, "Options:\n");
      fprintf(stderr, "   -d   Service display name\n");
      fprintf(stderr, "   -c   Service description\n");
      fprintf(stderr, "   -w   Service working path\n");
      fprintf(stderr, "   -l   Turn info logging On\n");
  
      ExitProcess(ERR_RET_USAGE);
  }
  
  static void DumpParams()
  {
      if (_service_mode == mode_run)
          return;
  
      fprintf(stdout, "Name           %s\n", _service_name);
      fprintf(stdout, "Display        %s\n", _service_disp);
      fprintf(stdout, "Description    %s\n", _service_desc);
      fprintf(stdout, "ImagePath      %s\n", _service_image);
      fprintf(stdout, "Shell          %s\n", _cmd_exe);
      fprintf(stdout, "WorkingPath    %s\n", _working_path);
      fprintf(stdout, "Service Script %s\n", _service_bat);
  
  }
  
  static void BuildCommandLine(char *buf, const char *action)
  {
  
      ZeroMemory(buf, MAX_CMDLINE);
      lstrcpy(buf, _cmd_exe);
      lstrcat(buf, " ");
      buf += lstrlen(buf);
  
      sprintf(buf, CMD_DEFAULT, getpid(), _service_name, _service_bat, action);
      lstrcat(buf, "\"");
      fprintf(stdout, "Service Cmd    %s\n", buf);
  }
  
  /* We could use the ChangeServiceConfig2 on WIN2K+ 
   * For now use the registry.
   */
  static BOOL SetServiceDescription(LPCSTR szServiceName,
                                    LPCSTR szDescription)
  {
      HKEY  hKey;
      CHAR  szName[MAX_PATH + 1];
      DWORD rc;
  
      if (lstrlen(szServiceName) > MAX_PATH)
          return FALSE;
      lstrcpy(szName, REGSERVICE_ROOT);
      lstrcat(szName, szServiceName);
  
      rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szName, 0, KEY_WRITE, &hKey);
      if (rc != ERROR_SUCCESS) {
          return FALSE;
      }
  
      rc = RegSetValueEx(hKey, REGDESCRIPTION, 0, REG_SZ,
                         (CONST BYTE *)szDescription,
                         lstrlen(szDescription) + 1);
      CloseHandle(hKey);
  
      return rc == ERROR_SUCCESS;
  }
  
  /* We could use the ChangeServiceConfig2 on WIN2K+ 
   * For now use the registry.
   */
  static BOOL SetServiceEventLog(LPCSTR szServiceName)
  {
      HKEY  hKey;
      CHAR  szName[MAX_PATH + 1];
      DWORD dwData;
  
      if (lstrlen(szServiceName) > MAX_PATH)
          return FALSE;
      lstrcpy(szName, REGSERVICE_LOG);
      lstrcat(szName, szServiceName);
  
      RegCreateKey(HKEY_LOCAL_MACHINE, szName, &hKey);
  
      if (!GetModuleFileName(NULL, szName, MAX_PATH)) {
          RegCloseKey(hKey);
          return FALSE;
      }
  
      RegSetValueEx(hKey, "EventMessageFile", 0, REG_SZ, (LPBYTE)szName,
                    lstrlen(szName) + 1);
      dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
               EVENTLOG_INFORMATION_TYPE;
  
      RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (LPBYTE)&dwData,
                    sizeof(DWORD));
   
      RegFlushKey(hKey);
      RegCloseKey(hKey);
  
      return TRUE;
  }
  
  BOOL SetServiceParameters(LPCSTR szServiceName)
  {
      HKEY  hKey;
      CHAR  szName[MAX_PATH + 1];
      DWORD rc;
      BOOL  rv = TRUE;
  
      if (lstrlen(szServiceName) > MAX_PATH)
          return FALSE;
  
      lstrcpy(szName, REGSERVICE_ROOT);
      lstrcat(szName, szServiceName);
      lstrcat(szName, REGPARAMS);
  
      rc = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                          szName,
                          0,
                          NULL,
                          0,
                          KEY_WRITE,
                          NULL,
                          &hKey,
                          NULL);
      if (rc != ERROR_SUCCESS) {
          rv = FALSE;
          goto cleanup;
      }
      rc = RegSetValueEx(hKey, REG_SERVFILE, 0, REG_SZ,
                         (CONST BYTE *)_service_bat,
                         lstrlen(_service_bat) + 1);
      if (rc != ERROR_SUCCESS) {
          rv = FALSE;
          goto cleanup;
      }
      if (_service_log) {
          rc = RegSetValueEx(hKey, REG_LOGFILE, 0, REG_DWORD,
              (CONST BYTE *)&_service_log,
              sizeof(DWORD));
          if (rc != ERROR_SUCCESS) {
              rv = FALSE;
              goto cleanup;
          }
      }
      if (lstrlen(_working_path)) {
          rc = RegSetValueEx(hKey, REG_WPATH, 0, REG_SZ,
              (CONST BYTE *)_working_path,
              lstrlen(_working_path) + 1);
          if (rc != ERROR_SUCCESS) {
              rv = FALSE;
              goto cleanup;
          }
      }
  
  cleanup:
      CloseHandle(hKey);
      return rv;
  }
  
  BOOL GetServiceParameters(LPCSTR szServiceName)
  {
      HKEY  hKey;
      CHAR  szName[MAX_PATH + 1];
      DWORD rc;
      BOOL  rv = TRUE;
      DWORD dwType;
      DWORD dwSize;
  
      if (lstrlen(szServiceName) > MAX_PATH)
          return FALSE;
      lstrcpy(szName, REGSERVICE_ROOT);
      lstrcat(szName, szServiceName);
      lstrcat(szName, REGPARAMS);
      rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey);
      if (rc != ERROR_SUCCESS) {
          return FALSE;
      }
      dwSize = MAX_PATH + 1;
      rc = RegQueryValueEx(hKey, REG_SERVFILE, NULL, &dwType,
                           (LPBYTE)_service_bat, &dwSize);
      if (rc != ERROR_SUCCESS || dwType != REG_SZ) {
          rv = FALSE;
          goto cleanup;
      }
      dwSize = sizeof(DWORD);
      rc = RegQueryValueEx(hKey, REG_LOGFILE, NULL, &dwType,
                           (LPBYTE)&_service_log, &dwSize);
      if (rc != ERROR_SUCCESS || dwType != REG_DWORD) {
          _service_log = FALSE;
      }
      dwSize = MAX_PATH + 1;
      rc = RegQueryValueEx(hKey, REG_WPATH, NULL, &dwType,
                           (LPBYTE)_working_path, &dwSize);
      if (rc != ERROR_SUCCESS || dwType != REG_SZ) {
          _working_path[0] = '\0';
      }
  
      if (GetSystemDirectory(szName, MAX_PATH + 1)) {
          lstrcat(szName, "\\cmd.exe");
          if (strchr(_cmd_exe, ' ')) {
              _cmd_exe[0] = '"';
              lstrcpy(&_cmd_exe[1], szName);
              lstrcat(_cmd_exe, "\"");
          }
          else
              lstrcpy(_cmd_exe, szName);
      }
  
  cleanup:
      CloseHandle(hKey);
      return rv;
  }
  
  BOOL InstallService(LPCSTR szServiceName)
  {
      char szImage[MAX_PATH + 1];
      char szPath[MAX_PATH + 1];
      char *p;
      BOOL rv = TRUE;
      SC_HANDLE hManager; 
      SC_HANDLE hService;
  
      if (!(hManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE))) {
          return FALSE;
      }
  
      p = &szImage[1];
      if (!GetModuleFileName(NULL, p, MAX_PATH)) {
          rv = FALSE;
          goto cleanup;
      }
      lstrcpy(szPath, p);
      
      if ((p = strrchr(szPath, '\\'))) {
          *p = '\0';
      }
      szImage[0] = '"';
      lstrcat(szImage, "\" -r ");
      lstrcat(szImage, szServiceName);
      if (!_working_path[0])
          lstrcpy(_working_path, szPath);
  
      hService = CreateService(hManager,                  // SCManager database
                               _service_name,             // name of service
                               _service_disp,             // name to display
                               SERVICE_ALL_ACCESS,        // access required
                               SERVICE_WIN32_OWN_PROCESS, // service type
                               SERVICE_AUTO_START,        // start type
                               SERVICE_ERROR_NORMAL,      // error control type
                               szImage,                   // service's binary
                               NULL,                      // no load svc group
                               NULL,                      // no tag identifier
                               "Tcpip\0Afd\0",            // dependencies
                               NULL,                      // use SYSTEM account
                               NULL);                     // no password
      if (!hService) {
          rv = FALSE;
          goto cleanup;
      }
  cleanup:
      if (hService)
          CloseServiceHandle(hService);
      CloseServiceHandle(hManager);
  
      return rv;
  }
  
  BOOL RemoveService(LPCSTR szServiceName)
  {
      BOOL rv = TRUE;
      SC_HANDLE hManager; 
      SC_HANDLE hService;
  
      if (!(hManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) {
          return FALSE;
      }
      hService = OpenService(hManager, _service_name, DELETE);
      if (!hService) {
          rv = FALSE;
          goto cleanup;
      }
  
      rv = DeleteService(hService);
  
  cleanup:
      if (hService)
          CloseServiceHandle(hService);
      CloseServiceHandle(hManager);
      return rv;
  
  }
  
  /* Report the service status to the SCM
   */
  BOOL ReportServiceStatus(DWORD dwCurrentState,
                           DWORD dwWin32ExitCode,
                           DWORD dwWaitHint)
  {
     static DWORD dwCheckPoint = 1;
     BOOL fResult = TRUE;
  
     if (_service_mode == mode_run && _service_status_handle) {      
         if (dwCurrentState == SERVICE_START_PENDING)
              _service_status.dwControlsAccepted = 0;
          else
              _service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
  
         _service_status.dwCurrentState  = dwCurrentState;
         _service_status.dwWin32ExitCode = dwWin32ExitCode;
         _service_status.dwWaitHint      = dwWaitHint;
  
         if ((dwCurrentState == SERVICE_RUNNING) ||
             (dwCurrentState == SERVICE_STOPPED))
             _service_status.dwCheckPoint = 0;
         else
             _service_status.dwCheckPoint = dwCheckPoint++;
         fResult = SetServiceStatus(_service_status_handle, &_service_status);
         if (!fResult) {
             /* TODO: Deal with error */
         }
     }
     return fResult;
  }
  
  static BOOL RunChildProcess(LPCSTR szApplication, LPSTR szCmdLine,
                              LPPROCESS_INFORMATION lpprInfo)
  {
      STARTUPINFO stInfo;
      BOOL bResult;
  
      ZeroMemory(&stInfo, sizeof(stInfo));
      stInfo.cb = sizeof(stInfo);
      stInfo.dwFlags = STARTF_USESHOWWINDOW;
      stInfo.wShowWindow = SW_HIDE;
  
      bResult = CreateProcess(szApplication,
                              szCmdLine,
                              NULL,
                              NULL,
                              TRUE,
                              CREATE_NEW_PROCESS_GROUP,
                              NULL,
                              _working_path,
                              &stInfo,
                              lpprInfo);
  
      return bResult;
  }
  
  
  /* Executed when the service receives stop event */
  static DWORD ServiceStop()
  { 
      DWORD rv;
      PROCESS_INFORMATION prInfo;
      char cmd[MAX_CMDLINE + 1];
      
      if (!IsServiceRunning(_service_name)) {
          AddToMessageLog(FALSE, "Service %s is already stopped", 
_service_name);
          return 0;
      }
      BuildCommandLine(cmd, "stop");
      AddToMessageLog(FALSE, "Stopping service %s", _service_name);
      if (RunChildProcess(_cmd_exe, cmd, &prInfo)) {
          ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
          rv = WaitForSingleObject(prInfo.hProcess, INFINITE);
          AddToMessageLog(FALSE, "Stopped service %s", _service_name);
          CloseHandle(prInfo.hProcess);
          CloseHandle(prInfo.hThread);
          return 0;
      }
      else {
          AddToMessageLog(TRUE, "Stopping service %s", _service_name);
          return 1;
      }
  }
  
  /* Executed when the service receives restart event */
  static DWORD ServiceRestart()
  { 
      DWORD rv;
      PROCESS_INFORMATION prInfo;
      char cmd[MAX_CMDLINE + 1];    
  
      BuildCommandLine(cmd, "restart");
      ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
      if (RunChildProcess(_cmd_exe, cmd, &prInfo)) {
          ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0);
          rv = WaitForSingleObject(prInfo.hProcess, INFINITE);
          printf("Restart Wait %d %d\n", rv, WAIT_OBJECT_0);
          CloseHandle(prInfo.hProcess);
          CloseHandle(prInfo.hThread);
          rv = 0;
      }
      else {
          AddToMessageLog(TRUE, "Restarting service %s", _service_name);
          rv = 1;
      }
      ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
      ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
  
      return rv;
  }
  
  /* Service controll handler
   */
  void WINAPI ServiceCtrlHandler(DWORD dwCtrlCode)
  {
  
      switch (dwCtrlCode) {
          case SERVICE_CONTROL_STOP:
              ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
              /* Call the stop handler that will actualy stop the service */
              ServiceStop();
              return;
          case SERVICE_CONTROL_INTERROGATE:
          break;
          default:
          break;
     }
     ReportServiceStatus(_service_status.dwCurrentState, NO_ERROR, 0);
  }
  
  /* Console control handler
   * 
   */
  BOOL WINAPI ConsoleHandler(DWORD dwCtrlType)
  {
  
      switch (dwCtrlType) {
          case CTRL_BREAK_EVENT:
              if (_service_mode == mode_run) {
                  ServiceStop();
                  return TRUE;
              }
              else
                  return FALSE;
          case CTRL_C_EVENT:
          case CTRL_CLOSE_EVENT:
          case CTRL_SHUTDOWN_EVENT:
              ServiceStop();
              return TRUE;
          break;
      }
  
      return FALSE;
  } 
  
  /* Executed when the service receives start event */
  static DWORD ServiceStart()
  { 
      DWORD rv;
      PROCESS_INFORMATION prInfo;
      char cmd[MAX_CMDLINE + 1];    
  
      BuildCommandLine(cmd, "start");
  
      DumpParams();
  
      AddToMessageLog(FALSE, "Starting service %s", _service_name);
      if (RunChildProcess(_cmd_exe, cmd, &prInfo)) {
          AddToMessageLog(FALSE, "Started service %s", _service_name);
          ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0);
          SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE);
  
          rv = WaitForSingleObject(prInfo.hProcess, INFINITE);
          AddToMessageLog(FALSE, "Finished service %s", _service_name);
          ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);
          ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0);
   
          CloseHandle(prInfo.hProcess);
          CloseHandle(prInfo.hThread);
          return 0;
      }
      else {
          AddToMessageLog(TRUE, "Starting service %s", _service_name);
          return 1;
      }
  }
  
  /* Main service execution loop */
  void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
  {
      DWORD rc;
      _service_status.dwServiceType      = SERVICE_WIN32_OWN_PROCESS;
      _service_status.dwCurrentState     = SERVICE_START_PENDING; 
      _service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP |
                                           SERVICE_ACCEPT_PAUSE_CONTINUE; 
      _service_status.dwWin32ExitCode    = 0; 
      _service_status.dwCheckPoint       = 0; 
      _service_status.dwWaitHint         = 0; 
      _service_status.dwServiceSpecificExitCode = 0; 
   
      if (_service_mode == mode_run) {
          /* Register Service Control handler */
          _service_status_handle = RegisterServiceCtrlHandler(_service_name,
                                                              
ServiceCtrlHandler); 
          if (!_service_status_handle) {
              AddToMessageLog(TRUE, "RegisterServiceCtrlHandler failed for %s",
                              _service_name);
              goto cleanup;
          }
      } 
      ReportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000);
      if ((rc = ServiceStart()) == 0) {
          AddToMessageLog(FALSE, "Service %s Main finished", _service_name);
      } 
  
      return;
  cleanup:
      /* Cleanup */
      ReportServiceStatus(SERVICE_STOPPED, ERROR_SERVICE_SPECIFIC_ERROR, 0);
      return; 
  }
  
  
  void __cdecl main(int argc, char **argv)
  {
      UINT rv = 0;
      char *arg;
      int i;
      int args_left = 1;
      int need_desc = 0;
      int need_disp = 0;
      int need_path = 0;
  
      if (argc < 3) {
          ErrorUsage();
      }
  
      if (!IsWindowsNT()) {
          fprintf(stderr, "This program will run only on Windows NT or 
higher\n");
          ExitProcess(ERR_RET_VERSION);
      }
  
      for (i = 1; i < argc; i++) {
          arg = argv[i];
          if (*arg != '-')
              break;
  
          while (*++arg != '\0') {
              switch (*arg) {
                  case 'i':
                      _service_mode = mode_install;
                      args_left++;
                  break;
                  case 'u':
                      _service_mode = mode_uninstall;
                  break;
                  case 't':
                      _service_mode = mode_debug;
                  break;
                  case 'r':
                      _service_mode = mode_run;
                  break;
                  case 'd':
                      need_disp = 1;
                      args_left++;
                  break;
                  case 'c':
                      need_desc = 1;
                      args_left++;
                  break;
                  case 'w':
                      need_path = 1;
                      args_left++;
                  break;
                  case 'l':
                      _service_log = TRUE;
                  break;
                  default:
                      ErrorUsage();
                  break;
              }
          }
      }
      if ((argc - i) < args_left)
          ErrorUsage();
      lstrcpy(_service_name, argv[i++]);
      if (need_path)
          lstrcpy(_working_path, argv[i++]);
      if (need_disp)
          lstrcpy(_service_disp, argv[i++]);
      if (need_desc)
          lstrcpy(_service_desc, argv[i++]);
  
      SetServiceEventLog(_service_name);
      if (_service_mode == mode_install) {
          lstrcpy(_service_bat, argv[i++]);
          if (!InstallService(_service_name)) {
              rv = ERR_RET_INSTALL;
              AddToMessageLog(TRUE, "Failed installing %s", _service_name);
              goto cleanup;
          }
          SetServiceParameters(_service_name);
          if (need_desc)
              SetServiceDescription(_service_name, _service_desc);
          AddToMessageLog(FALSE, "Installed %s", _service_name);
      }
      else if (_service_mode == mode_uninstall) {
          GetServiceParameters(_service_name);
          AddToMessageLog(FALSE, "Uninstalling %s", _service_name);
          ServiceStop();
          if (!RemoveService(_service_name)) {
              AddToMessageLog(TRUE, "Failed removing %s", _service_name);
              rv = ERR_RET_REMOVE;
          }
      }
      else if (_service_mode == mode_run) {
          GetServiceParameters(_service_name);
          AddToMessageLog(FALSE, "Initialized %s", _service_name);
          _service_table[0].lpServiceName = _service_name;
          _service_table[0].lpServiceProc = 
(LPSERVICE_MAIN_FUNCTION)ServiceMain; 
          StartServiceCtrlDispatcher(_service_table);
      }
      else if (_service_mode == mode_debug) {
          GetServiceParameters(_service_name);
          AddToMessageLog(FALSE, "Debugging %s", _service_name);
          ServiceMain(argc, argv);
      }
      else {
          AddToMessageLog(TRUE, "Unknown service mode for %s", _service_name);
          rv = ERR_RET_MODE;
      }
  
  
  cleanup:
      AddToMessageLog(FALSE, "SrvBatch finished");
      ExitProcess(rv);
  }
  
  
  
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.rc
  
  Index: srvbatch.rc
  ===================================================================
  /* Copyright 2000-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
   
   #include <windows.h>
   
   #define PRODUCT_VER_STRING "1.0.0.0\0"
   #define PRODUCT_VER_NAME   "ServBatch\0"
   
   IDI_MAINICON         ICON                   "../../resources/procrunw.ico"
  
  LANGUAGE 0x9,0x1
  1 11 MSG00001.bin
   
   1 VERSIONINFO
   FILEVERSION 1,0,0,0
   PRODUCTVERSION 1,0,0,0
   FILEFLAGSMASK 0x3fL
  #if defined(_DEBUG)
   FILEFLAGS 0x03L
  #else
   FILEFLAGS 0x02L
  #endif
   FILEOS 0x40004L
   FILETYPE 0x1L
   FILESUBTYPE 0x0L
  BEGIN
    BLOCK "StringFileInfo"
    BEGIN
      BLOCK "040904b0"
      BEGIN
        VALUE "Comments", "\0"
        VALUE "CompanyName", "Apache Software Foundation\0"
        VALUE "FileDescription", "Application for running batch files as 
services\0"
        VALUE "FileVersion", PRODUCT_VER_STRING
        VALUE "InternalName", PRODUCT_VER_NAME
        VALUE "LegalCopyright", "Copyright © 2000-2004 The Apache Software 
Foundation.\0"
        VALUE "OriginalFilename", "srvbatch.exe\0"
        VALUE "ProductVersion", PRODUCT_VER_STRING
        VALUE "ProductName", PRODUCT_VER_NAME
      END
    END
    BLOCK "VarFileInfo"
    BEGIN
      VALUE "Translation", 0x409, 1200
    END
  END
  
  
  
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.sln
  
  Index: srvbatch.sln
  ===================================================================
  Microsoft Visual Studio Solution File, Format Version 8.00

  Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srvbatch", 
"srvbatch.vcproj", "{6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}"

        ProjectSection(ProjectDependencies) = postProject

        EndProjectSection

  EndProject

  Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", 
"example\example.vcproj", "{1C38835C-714F-49F3-85FC-9E6372149DF3}"

        ProjectSection(ProjectDependencies) = postProject

                {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB} = 
{6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}

        EndProjectSection

  EndProject

  Global

        GlobalSection(SolutionConfiguration) = preSolution

                Debug = Debug

                Release = Release

        EndGlobalSection

        GlobalSection(ProjectConfiguration) = postSolution

                {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Debug.ActiveCfg = 
Debug|Win32

                {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Debug.Build.0 = 
Debug|Win32

                {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Release.ActiveCfg = 
Release|Win32

                {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Release.Build.0 = 
Release|Win32

                {1C38835C-714F-49F3-85FC-9E6372149DF3}.Debug.ActiveCfg = 
Debug|Win32

                {1C38835C-714F-49F3-85FC-9E6372149DF3}.Debug.Build.0 = 
Debug|Win32

                {1C38835C-714F-49F3-85FC-9E6372149DF3}.Release.ActiveCfg = 
Release|Win32

                {1C38835C-714F-49F3-85FC-9E6372149DF3}.Release.Build.0 = 
Release|Win32

        EndGlobalSection

        GlobalSection(ExtensibilityGlobals) = postSolution

        EndGlobalSection

        GlobalSection(ExtensibilityAddIns) = postSolution

        EndGlobalSection

  EndGlobal

  
  
  
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.vcproj
  
  Index: srvbatch.vcproj
  ===================================================================
  <?xml version="1.0" encoding="Windows-1252"?>

  <VisualStudioProject

        ProjectType="Visual C++"

        Version="7.10"

        Name="srvbatch"

        ProjectGUID="{6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}"

        Keyword="Win32Proj">

        <Platforms>

                <Platform

                        Name="Win32"/>

        </Platforms>

        <Configurations>

                <Configuration

                        Name="Debug|Win32"

                        OutputDirectory="Debug"

                        IntermediateDirectory="Debug"

                        ConfigurationType="1"

                        CharacterSet="2">

                        <Tool

                                Name="VCCLCompilerTool"

                                Optimization="0"

                                PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"

                                MinimalRebuild="TRUE"

                                BasicRuntimeChecks="3"

                                RuntimeLibrary="1"

                                UsePrecompiledHeader="0"

                                WarningLevel="3"

                                Detect64BitPortabilityProblems="TRUE"

                                DebugInformationFormat="4"/>

                        <Tool

                                Name="VCCustomBuildTool"/>

                        <Tool

                                Name="VCLinkerTool"

                                OutputFile="$(OutDir)/srvbatch.exe"

                                LinkIncremental="2"

                                GenerateDebugInformation="TRUE"

                                ProgramDatabaseFile="$(OutDir)/srvbatch.pdb"

                                SubSystem="1"

                                TargetMachine="1"/>

                        <Tool

                                Name="VCMIDLTool"/>

                        <Tool

                                Name="VCPostBuildEventTool"/>

                        <Tool

                                Name="VCPreBuildEventTool"/>

                        <Tool

                                Name="VCPreLinkEventTool"/>

                        <Tool

                                Name="VCResourceCompilerTool"/>

                        <Tool

                                Name="VCWebServiceProxyGeneratorTool"/>

                        <Tool

                                Name="VCXMLDataGeneratorTool"/>

                        <Tool

                                Name="VCWebDeploymentTool"/>

                        <Tool

                                Name="VCManagedWrapperGeneratorTool"/>

                        <Tool

                                Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

                </Configuration>

                <Configuration

                        Name="Release|Win32"

                        OutputDirectory="Release"

                        IntermediateDirectory="Release"

                        ConfigurationType="1"

                        CharacterSet="2">

                        <Tool

                                Name="VCCLCompilerTool"

                                PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

                                RuntimeLibrary="0"

                                UsePrecompiledHeader="0"

                                WarningLevel="3"

                                Detect64BitPortabilityProblems="TRUE"

                                DebugInformationFormat="3"/>

                        <Tool

                                Name="VCCustomBuildTool"/>

                        <Tool

                                Name="VCLinkerTool"

                                OutputFile="$(OutDir)/srvbatch.exe"

                                LinkIncremental="1"

                                GenerateDebugInformation="TRUE"

                                SubSystem="1"

                                OptimizeReferences="2"

                                EnableCOMDATFolding="2"

                                TargetMachine="1"/>

                        <Tool

                                Name="VCMIDLTool"/>

                        <Tool

                                Name="VCPostBuildEventTool"/>

                        <Tool

                                Name="VCPreBuildEventTool"/>

                        <Tool

                                Name="VCPreLinkEventTool"/>

                        <Tool

                                Name="VCResourceCompilerTool"/>

                        <Tool

                                Name="VCWebServiceProxyGeneratorTool"/>

                        <Tool

                                Name="VCXMLDataGeneratorTool"/>

                        <Tool

                                Name="VCWebDeploymentTool"/>

                        <Tool

                                Name="VCManagedWrapperGeneratorTool"/>

                        <Tool

                                Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

                </Configuration>

        </Configurations>

        <References>

        </References>

        <Files>

                <Filter

                        Name="Source Files"

                        Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

                        
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

                        <File

                                RelativePath=".\srvbatch.c">

                        </File>

                </Filter>

                <Filter

                        Name="Header Files"

                        Filter="h;hpp;hxx;hm;inl;inc;xsd"

                        
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

                </Filter>

                <Filter

                        Name="Resource Files"

                        
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

                        
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">

                        <File

                                RelativePath=".\srvbatch.rc">

                        </File>

                </Filter>

        </Files>

        <Globals>

        </Globals>

  </VisualStudioProject>

  
  
  
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/example/example.c
  
  Index: example.c
  ===================================================================
  /* Copyright 2000-2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  
  
  #include <windows.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <process.h>
  
  HANDLE hGlobalEvent; 
  #define EVENT_NAME "ServBatchExampleEvent"
  
  
  int main(int argc, char **argv)
  {
      int mode = 0;
      int i;
  
      for (i = 0; i < argc; i++)
          fprintf(stdout, "Command line param [%d] = %s\n", i, argv[i]);
  
      if (argc > 1 && stricmp(argv[1], "stop") == 0)
          mode = 1;
      
      if (mode) {
          fprintf(stdout, "Stopping service\n");
          hGlobalEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, EVENT_NAME);
          if (!hGlobalEvent)
              fprintf(stderr, "Unable to upen the Global Event\n");
          else {
              fprintf(stdout, "Signaling service event\n");
              SetEvent(hGlobalEvent);
          }
  
      }
      else {
          fprintf(stdout, "Starting service\n");
          hGlobalEvent = CreateEvent(NULL, FALSE, FALSE, EVENT_NAME);
          WaitForSingleObject(hGlobalEvent, INFINITE);
          fprintf(stdout, "Event Signaled\n");
      }
   
      fprintf(stdout, "Service mode %d finished\n", mode);
      return 0;
  }
  
  
  
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/example/example.vcproj
  
  Index: example.vcproj
  ===================================================================
  <?xml version="1.0" encoding="Windows-1252"?>

  <VisualStudioProject

        ProjectType="Visual C++"

        Version="7.10"

        Name="example"

        ProjectGUID="{1C38835C-714F-49F3-85FC-9E6372149DF3}"

        Keyword="Win32Proj">

        <Platforms>

                <Platform

                        Name="Win32"/>

        </Platforms>

        <Configurations>

                <Configuration

                        Name="Debug|Win32"

                        OutputDirectory="Debug"

                        IntermediateDirectory="Debug"

                        ConfigurationType="1"

                        CharacterSet="2">

                        <Tool

                                Name="VCCLCompilerTool"

                                Optimization="0"

                                PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"

                                MinimalRebuild="TRUE"

                                BasicRuntimeChecks="3"

                                RuntimeLibrary="1"

                                UsePrecompiledHeader="0"

                                WarningLevel="3"

                                Detect64BitPortabilityProblems="TRUE"

                                DebugInformationFormat="4"/>

                        <Tool

                                Name="VCCustomBuildTool"/>

                        <Tool

                                Name="VCLinkerTool"

                                OutputFile="example.exe"

                                LinkIncremental="2"

                                GenerateDebugInformation="TRUE"

                                ProgramDatabaseFile="$(OutDir)/example.pdb"

                                SubSystem="1"

                                TargetMachine="1"/>

                        <Tool

                                Name="VCMIDLTool"/>

                        <Tool

                                Name="VCPostBuildEventTool"/>

                        <Tool

                                Name="VCPreBuildEventTool"/>

                        <Tool

                                Name="VCPreLinkEventTool"/>

                        <Tool

                                Name="VCResourceCompilerTool"/>

                        <Tool

                                Name="VCWebServiceProxyGeneratorTool"/>

                        <Tool

                                Name="VCXMLDataGeneratorTool"/>

                        <Tool

                                Name="VCWebDeploymentTool"/>

                        <Tool

                                Name="VCManagedWrapperGeneratorTool"/>

                        <Tool

                                Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

                </Configuration>

                <Configuration

                        Name="Release|Win32"

                        OutputDirectory="Release"

                        IntermediateDirectory="Release"

                        ConfigurationType="1"

                        CharacterSet="2">

                        <Tool

                                Name="VCCLCompilerTool"

                                PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"

                                RuntimeLibrary="0"

                                UsePrecompiledHeader="0"

                                WarningLevel="3"

                                Detect64BitPortabilityProblems="TRUE"

                                DebugInformationFormat="3"/>

                        <Tool

                                Name="VCCustomBuildTool"/>

                        <Tool

                                Name="VCLinkerTool"

                                OutputFile="$(OutDir)/example.exe"

                                LinkIncremental="1"

                                GenerateDebugInformation="TRUE"

                                SubSystem="1"

                                OptimizeReferences="2"

                                EnableCOMDATFolding="2"

                                TargetMachine="1"/>

                        <Tool

                                Name="VCMIDLTool"/>

                        <Tool

                                Name="VCPostBuildEventTool"/>

                        <Tool

                                Name="VCPreBuildEventTool"/>

                        <Tool

                                Name="VCPreLinkEventTool"/>

                        <Tool

                                Name="VCResourceCompilerTool"/>

                        <Tool

                                Name="VCWebServiceProxyGeneratorTool"/>

                        <Tool

                                Name="VCXMLDataGeneratorTool"/>

                        <Tool

                                Name="VCWebDeploymentTool"/>

                        <Tool

                                Name="VCManagedWrapperGeneratorTool"/>

                        <Tool

                                Name="VCAuxiliaryManagedWrapperGeneratorTool"/>

                </Configuration>

        </Configurations>

        <References>

        </References>

        <Files>

                <Filter

                        Name="Source Files"

                        Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"

                        
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">

                        <File

                                RelativePath=".\example.c">

                        </File>

                </Filter>

                <Filter

                        Name="Header Files"

                        Filter="h;hpp;hxx;hm;inl;inc;xsd"

                        
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">

                </Filter>

                <Filter

                        Name="Resource Files"

                        
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"

                        
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">

                </Filter>

        </Files>

        <Globals>

        </Globals>

  </VisualStudioProject>

  
  
  
  1.1                  
jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/example/exservice.bat
  
  Index: exservice.bat
  ===================================================================
  @echo off

  REM Copyright 2000-2004 The Apache Software Foundation

  REM

  REM Licensed under the Apache License, Version 2.0 (the "License");

  REM you may not use this file except in compliance with the License.

  REM You may obtain a copy of the License at

  REM

  REM     http://www.apache.org/licenses/LICENSE-2.0

  REM

  REM Unless required by applicable law or agreed to in writing, software

  REM distributed under the License is distributed on an "AS IS" BASIS,

  REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

  REM See the License for the specific language governing permissions and

  REM limitations under the License.

  REM

  

  @if not "%ECHO%" == ""  echo %ECHO%

  @if "%OS%" == "Windows_NT"  setlocal

  

  set SERVICE_EXECUTABLE=example.exe

  

  REM Figure out the running mode

  

  @if "%1" == "install"   goto cmdInstall

  @if "%1" == "uninstall" goto cmdUninstall

  @if "%1" == "start"     goto cmdStart

  @if "%1" == "stop"      goto cmdStop

  @if "%1" == "restart"   goto cmdRestart

  echo Usage

  goto cmdEnd

  

  :cmdInstall

  ..\Debug\srvbatch.exe -iwdcl SrvbatchExample "%CD%" "Srvbatch Example 
Service" "This is an Example service" exservice.bat 

  goto cmdEnd

  

  :cmdUninstall

  ..\Debug\srvbatch.exe -u SrvbatchExample

  goto cmdEnd

  

  :cmdStart

  %SERVICE_EXECUTABLE% start

  goto cmdEnd

  

  :cmdStop

  %SERVICE_EXECUTABLE% stop

  goto cmdEnd

  

  :cmdRestart

  %SERVICE_EXECUTABLE% stop

  %SERVICE_EXECUTABLE% start

  goto cmdEnd

  

  :cmdEnd

  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to