tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hgo...@apache.org
Subject cvs commit: jakarta-tomcat/proposals/web-connector/native/nt_service jk_nt_service.c nt_service.dsp
Date Thu, 03 May 2001 14:47:24 GMT
hgomez      01/05/03 07:47:24

  Added:       proposals/web-connector/native/nt_service jk_nt_service.c
                        nt_service.dsp
  Log:
  nt_service stuff
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat/proposals/web-connector/native/nt_service/jk_nt_service.c
  
  Index: jk_nt_service.c
  ===================================================================
  /*
   * Copyright (c) 1997-1999 The Java Apache Project.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. All advertising materials mentioning features or use of this
   *    software must display the following acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *
   * 4. The names "Apache JServ", "Apache JServ Servlet Engine" and 
   *    "Java Apache Project" must not be used to endorse or promote products 
   *    derived from this software without prior written permission.
   *
   * 5. Products derived from this software may not be called "Apache JServ"
   *    nor may "Apache" nor "Apache JServ" appear in their names without 
   *    prior written permission of the Java Apache Project.
   *
   * 6. Redistributions of any form whatsoever must retain the following
   *    acknowledgment:
   *    "This product includes software developed by the Java Apache 
   *    Project for use in the Apache JServ servlet engine project
   *    <http://java.apache.org/>."
   *    
   * THIS SOFTWARE IS PROVIDED BY THE JAVA APACHE PROJECT "AS IS" AND ANY
   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE JAVA APACHE PROJECT OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   * OF THE POSSIBILITY OF SUCH DAMAGE.
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Java Apache Group. For more information
   * on the Java Apache Project and the Apache JServ Servlet Engine project,
   * please see <http://java.apache.org/>.
   *
   */
  
  /***************************************************************************
   * Description: NT System service for Jakarta/Tomcat                       *
   * Author:      Gal Shachor <shachor@il.ibm.com>                           *
   * Version:     $Revision: 1.1 $                                           *
   ***************************************************************************/
  
  #include "jk_global.h"
  #include "jk_util.h"
  #include "jk_ajp13.h"
  #include "jk_connect.h"
  
  #include <windows.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <process.h>
  
  #define AJP12_TAG              ("ajp12")
  #define AJP13_TAG              ("ajp13")
  #define BASE_REGISTRY_LOCATION ("SYSTEM\\CurrentControlSet\\Services\\")
  #define IMAGE_NAME             ("ImagePath")
  #define PARAMS_LOCATION        ("Parameters")
  #define PRP_LOCATION           ("PropertyFile")
  
  // internal variables
  static SERVICE_STATUS          ssStatus;       // current status of the service
  static SERVICE_STATUS_HANDLE   sshStatusHandle;
  static DWORD                   dwErr = 0;
  static char                    szErr[1024] = "";
  static HANDLE                  hServerStopEvent = NULL;
  static int                     shutdown_port;
  static char                    *shutdown_protocol = AJP12_TAG;
  
  struct jk_tomcat_startup_data {
      char *classpath;
      char *tomcat_home;
      char *stdout_file;
      char *stderr_file;
      char *java_bin;
      char *tomcat_class;
      char *server_file;
      char *cmd_line;
      int  shutdown_port;
      char *shutdown_protocol;
  
      char *extra_path;
  };
  typedef struct jk_tomcat_startup_data jk_tomcat_startup_data_t;
  
  // internal function prototypes
  static void WINAPI service_ctrl(DWORD dwCtrlCode);
  static void WINAPI service_main(DWORD dwArgc, 
                                  char **lpszArgv);
  static void install_service(char *name, 
                              char *prp_file);
  static void remove_service(char *name);
  static char *GetLastErrorText(char *lpszBuf, DWORD dwSize);
  static void AddToMessageLog(char *lpszMsg);
  static BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
                                  DWORD dwWin32ExitCode,
                                  DWORD dwWaitHint);
  static void start_jk_service(char *name);
  static void stop_jk_service(void);
  static int set_registry_values(char *name, 
                                 char *prp_file);
  static int create_registry_key(const char *tag, 
                                 HKEY *key);
  static int set_registry_config_parameter(HKEY hkey, 
                                           const char *tag, 
                                           char *value);
  static int get_registry_config_parameter(HKEY hkey, 
                                           const char *tag,  
                                           char *b, DWORD sz);
  static int start_tomcat(const char *name, 
                          HANDLE *hTomcat);
  static void stop_tomcat(short port, 
                          const char *protocol,
                          HANDLE hTomcat);
  static int read_startup_data(jk_map_t *init_map, 
                               jk_tomcat_startup_data_t *data, 
                               jk_pool_t *p);
  
  
  static void usage_message(const char *name)
  {
      printf("%s - Usage:\n", name);
      printf("%s -i <service name> <configuration properties file>\n", name);
      printf("\tto install the service\n");
      printf("%s -r <service name>\n", name);    
      printf("\tto remove the service\n");
  }
  
  void main(int argc, char **argv)
  {
      WORD wVersionRequested;
      WSADATA wsaData;
      int err; 
          
      wVersionRequested = MAKEWORD(1, 1); 
      err = WSAStartup(wVersionRequested, &wsaData);
      if(0 != err) {
          fprintf(stderr, "Error connecting to winosck");
          return;
      } 
  
      if(LOBYTE( wsaData.wVersion ) != 1 || 
         HIBYTE( wsaData.wVersion ) != 1)  {
          fprintf(stderr, 
                  "Error winsock version is %d %d \n", 
                  LOBYTE( wsaData.wVersion ),HIBYTE( wsaData.wVersion ));
          WSACleanup();
          return; 
      } 
  
      fprintf(stderr, "Asked (and given) winsock %d.%d \n", 
                      LOBYTE(wsaData.wVersion),
                      HIBYTE(wsaData.wVersion));
  
  
      __try {
          if((argc > 2) && ((*argv[1] == '-') || (*argv[1] == '/'))) {
              char *cmd = argv[1];
              cmd++;
              if(0 == stricmp("i", cmd) && (4 == argc)) {
                  install_service(argv[2], argv[3]);
                  return;
              } else if(0 == stricmp("r", cmd) && (3 == argc)) {
                  remove_service(argv[2]);
                  return;
              } else if(0 == stricmp("s", cmd) && (3 == argc)) {
                  HANDLE hTomcat;
                  start_tomcat(argv[2], &hTomcat);
                  return;
              }
          } else if(2  == argc) {
  
              SERVICE_TABLE_ENTRY dispatchTable[] =
              {
                  { argv[1], (LPSERVICE_MAIN_FUNCTION)service_main },
                  { NULL, NULL }
              };
  
              if(!StartServiceCtrlDispatcher(dispatchTable)) {
                  AddToMessageLog("StartServiceCtrlDispatcher failed.");
              }
              return;
          } 
  
          usage_message(argv[0]);
          exit(-1);
      } __finally {
          WSACleanup();
      }
  }
  
  void WINAPI service_main(DWORD dwArgc, char **lpszArgv)
  {
      // register our service control handler:
      //
      //
      sshStatusHandle = RegisterServiceCtrlHandler(lpszArgv[0], service_ctrl);
  
      if(sshStatusHandle) {
  
          ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
          ssStatus.dwServiceSpecificExitCode = 0;
  
          // report the status to the service control manager.
          //
          if(ReportStatusToSCMgr(SERVICE_START_PENDING, // service state
                                  NO_ERROR,              // exit code
                                  3000)) {                 // wait hint    
              start_jk_service(lpszArgv[0]);
          }
      }
  
      // try to report the stopped status to the service control manager.
      //
      if(sshStatusHandle) {
          ReportStatusToSCMgr(SERVICE_STOPPED,
                              dwErr,
                              0);
      }
  }
  
  
  void WINAPI service_ctrl(DWORD dwCtrlCode)
  {
      /*
       * Handle the requested control code.
       */
      switch(dwCtrlCode)
      {
          /*
           * Stop the service.
           */
          case SERVICE_CONTROL_SHUTDOWN:
          case SERVICE_CONTROL_STOP:
              ssStatus.dwCurrentState = SERVICE_STOP_PENDING;
              stop_jk_service();
              break;
  
          /*
           * Update the service status.
           */
          case SERVICE_CONTROL_INTERROGATE:
              break;
  
          /*
           * Invalid control code, nothing to do.
           */
          default:
              break;
  
      }
  
      ReportStatusToSCMgr(ssStatus.dwCurrentState, NO_ERROR, 0);
  
  }
  
  BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
                           DWORD dwWin32ExitCode,
                           DWORD dwWaitHint)
  {
      static DWORD dwCheckPoint = 1;
      BOOL fResult = TRUE;
  
      if(dwCurrentState == SERVICE_START_PENDING) {
          ssStatus.dwControlsAccepted = 0;
      } else {
          ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
      }
  
      ssStatus.dwCurrentState = dwCurrentState;
      ssStatus.dwWin32ExitCode = dwWin32ExitCode;
      ssStatus.dwWaitHint = dwWaitHint;
  
      if((dwCurrentState == SERVICE_RUNNING) ||
         (dwCurrentState == SERVICE_STOPPED)) {
          ssStatus.dwCheckPoint = 0;
      } else {
          ssStatus.dwCheckPoint = dwCheckPoint++;
      }
  
      if(!(fResult = SetServiceStatus(sshStatusHandle, &ssStatus))) {
          AddToMessageLog(TEXT("SetServiceStatus"));
      }
  
      return fResult;
  }
  
  void install_service(char *name, 
                       char *rel_prp_file)
  {
      SC_HANDLE   schService;
      SC_HANDLE   schSCManager;
      char        szExecPath[2048];
      char        szPropPath[2048];
      char        *dummy;
  
      if(!GetFullPathName(rel_prp_file, sizeof(szPropPath) - 1, szPropPath, &dummy)) {
          printf("Unable to install %s - %s\n", 
                 name, 
                 GetLastErrorText(szErr, sizeof(szErr)));
          return;
      }
  
      if(!jk_file_exists(szPropPath)) {
          printf("Unable to install %s - File [%s] does not exists\n", 
                 name, 
                 szPropPath);
          return;
      }
  
      if(GetModuleFileName( NULL, szExecPath, sizeof(szExecPath) - 1) == 0) {
          printf("Unable to install %s - %s\n", 
                 name, 
                 GetLastErrorText(szErr, sizeof(szErr)));
          return;
      }
  
      schSCManager = OpenSCManager(NULL,  // machine (NULL == local)
                                   NULL,  // database (NULL == default)
                                   SC_MANAGER_ALL_ACCESS);   // access required          
            
      if(schSCManager) {
          schService = CreateService(schSCManager, // SCManager database
                                     name,         // name of service
                                     name,         // name to display
                                     SERVICE_ALL_ACCESS, // desired access
                                     SERVICE_WIN32_OWN_PROCESS,  // service type
                                     SERVICE_DEMAND_START,       // start type
                                     SERVICE_ERROR_NORMAL,       // error control type
                                     szExecPath,                 // service's binary
                                     NULL,                       // no load ordering group
                                     NULL,                       // no tag identifier
                                     NULL,                       // dependencies
                                     NULL,                       // LocalSystem account
                                     NULL);                      // no password
  
          if(schService) {
              printf("The service named %s was created. Now adding registry entries\n", name);
              
              if(set_registry_values(name, szPropPath)) {
                  CloseServiceHandle(schService);
              } else {
                  printf("CreateService failed setting the private registry - %s\n", GetLastErrorText(szErr,
sizeof(szErr)));
                  DeleteService(schService);
                  CloseServiceHandle(schService);
              }
          } else {
              printf("CreateService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
          }
  
          CloseServiceHandle(schSCManager);
      } else { 
          printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
      }
  }
  
  void remove_service(char *name)
  {
      SC_HANDLE   schService;
      SC_HANDLE   schSCManager;
  
      schSCManager = OpenSCManager(NULL,          // machine (NULL == local)
                                   NULL,          // database (NULL == default)
                                   SC_MANAGER_ALL_ACCESS );  // access required
                          
      if(schSCManager) {
          schService = OpenService(schSCManager, name, SERVICE_ALL_ACCESS);
  
          if(schService) {
              // try to stop the service
              if(ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus )) {
                  printf("Stopping %s.", name);
                  Sleep(1000);
  
                  while(QueryServiceStatus(schService, &ssStatus )) {
                      if(ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
                          printf(".");
                          Sleep(1000);
                      } else {
                          break;
                      }
                  }
  
                  if(ssStatus.dwCurrentState == SERVICE_STOPPED) {
                      printf("\n%s stopped.\n", name);
                  } else {
                      printf("\n%s failed to stop.\n", name);
                  }
              }
  
              // now remove the service
              if(DeleteService(schService)) {
                  printf("%s removed.\n", name);
              } else {
                  printf("DeleteService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
              }
  
              CloseServiceHandle(schService);
          } else {
              printf("OpenService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
          }
  
          CloseServiceHandle(schSCManager);
      } else {
          printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
      }
  }
  
  static int set_registry_values(char *name, 
                                 char *prp_file)
  {
      char  tag[1024];
      HKEY  hk;
      int rc;
  
      strcpy(tag, BASE_REGISTRY_LOCATION);
      strcat(tag, name);
      strcat(tag, "\\");
      strcat(tag, PARAMS_LOCATION);
  
      rc = create_registry_key(tag, &hk);
  
      if(rc) {
          rc = set_registry_config_parameter(hk, PRP_LOCATION, prp_file);
          if(!rc) {
              printf("Error: Can not create value [%s] - %s\n", 
                      PRP_LOCATION, 
                      GetLastErrorText(szErr, sizeof(szErr)));                
          }
          RegCloseKey(hk);
      } else {
          printf("Error: Can not create key [%s] - %s\n", 
                  tag, 
                  GetLastErrorText(szErr, sizeof(szErr)));                
      }
  
      if(rc) {
          char value[2024];
  
          rc = JK_FALSE;
  
          strcpy(tag, BASE_REGISTRY_LOCATION);
          strcat(tag, name);
          
          if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                           tag,
                                           (DWORD)0,         
                                           KEY_WRITE | KEY_READ,
                                           &hk)) {
              rc = get_registry_config_parameter(hk,
                                                 IMAGE_NAME, 
                                                 value,
                                                 sizeof(value));
              if(rc) {
                  strcat(value, " ");
                  strcat(value, name);
                  rc = set_registry_config_parameter(hk,
                                                     IMAGE_NAME, 
                                                     value);
                  if(rc) {
                      printf("Registry values were added\n");
                      printf("If you have already updated wrapper.properties you may start
the %s service by executing \"net start %s\" from the command prompt\n",
                             name,
                             name);                    
                  }
              }
              RegCloseKey(hk);
          }
          if(!rc) {
              printf("Error: Failed to update the service command line - %s\n", 
                      GetLastErrorText(szErr, sizeof(szErr)));                
          }
      }
  
      return rc;
  }
  
  static void start_jk_service(char *name)
  {
      /*
       * report the status to the service control manager.
       */
      if(ReportStatusToSCMgr(SERVICE_START_PENDING, // service state
                             NO_ERROR,              // exit code
                             3000)) {               // wait hint
          
          /* 
           * create the event object. The control handler function signals
           * this event when it receives the "stop" control code.
           */
          hServerStopEvent = CreateEvent(NULL,    // no security attributes
                                         TRUE,    // manual reset event
                                         FALSE,   // not-signalled
                                         NULL);   // no name
  
          if(hServerStopEvent) {
              if(ReportStatusToSCMgr(SERVICE_START_PENDING, // service state
                                     NO_ERROR,              // exit code
                                     20000)) {              // wait hint
                  HANDLE hTomcat = NULL;
                  int rc = start_tomcat(name, &hTomcat);
  
                  if(rc && ReportStatusToSCMgr(SERVICE_RUNNING, // service state
                                               NO_ERROR,        // exit code
                                               0)) {            // wait hint       
                      HANDLE waitfor[] = { hServerStopEvent, hTomcat};
                      DWORD dwIndex = WaitForMultipleObjects(2, waitfor, FALSE, INFINITE);
  
                      switch(dwIndex) {
                      case WAIT_OBJECT_0:
                          /* 
                           * Stop order arrived 
                           */ 
                          ResetEvent(hServerStopEvent);
                          stop_tomcat((short)shutdown_port, shutdown_protocol, hTomcat);
                          break;
                      case (WAIT_OBJECT_0 + 1):
                          /* 
                           * Tomcat died !!!
                           */ 
                          break;
                      default:
                          /* 
                           * some error... 
                           * close the servlet container and exit 
                           */ 
                          stop_tomcat((short)shutdown_port, shutdown_protocol, hTomcat);
                      }
                      CloseHandle(hServerStopEvent);
                      CloseHandle(hTomcat);
                  }                
              }
          }
      }
  
      if(hServerStopEvent) {
          CloseHandle(hServerStopEvent);
      }
  }
  
  
  static void stop_jk_service(void)
  {
      if(hServerStopEvent) {
          SetEvent(hServerStopEvent);
      }
  }
  
  static void AddToMessageLog(char *lpszMsg)
  {   
      char    szMsg[2048];
      HANDLE  hEventSource;
      char *  lpszStrings[2];
  
      printf("Error: %s\n", lpszMsg);
  
      dwErr = GetLastError();
  
      hEventSource = RegisterEventSource(NULL, "Jakrta - Tomcat");
  
      sprintf(szMsg, "%s error: %d", "Jakrta - Tomcat", dwErr);
      lpszStrings[0] = szMsg;
      lpszStrings[1] = lpszMsg;
  
      if(hEventSource != NULL) {
          ReportEvent(hEventSource, // handle of event source
              EVENTLOG_ERROR_TYPE,  // event type
              0,                    // event category
              0,                    // event ID
              NULL,                 // current user's SID
              2,                    // strings in lpszStrings
              0,                    // no bytes of raw data
              lpszStrings,          // array of error strings
              NULL);                // no raw data
  
          DeregisterEventSource(hEventSource);
      }
      
  }
  
  //
  //  FUNCTION: GetLastErrorText
  //
  //  PURPOSE: copies error message text to string
  //
  //  PARAMETERS:
  //    lpszBuf - destination buffer
  //    dwSize - size of buffer
  //
  //  RETURN VALUE:
  //    destination buffer
  //
  //  COMMENTS:
  //
  char *GetLastErrorText( char *lpszBuf, DWORD dwSize )
  {
      DWORD dwRet;
      char *lpszTemp = NULL;
  
      dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |FORMAT_MESSAGE_ARGUMENT_ARRAY,
                            NULL,
                            GetLastError(),
                            LANG_NEUTRAL,
                            (char *)&lpszTemp,
                            0,
                            NULL);
  
      // supplied buffer is not long enough
      if(!dwRet || ((long)dwSize < (long)dwRet+14)) {
          lpszBuf[0] = '\0';
      } else {
          lpszTemp[lstrlen(lpszTemp)-2] = '\0';  //remove cr and newline character
          sprintf(lpszBuf, "%s (0x%x)", lpszTemp, GetLastError());
      }
  
      if(lpszTemp) {
          LocalFree((HLOCAL) lpszTemp );
      }
  
      return lpszBuf;
  }
  
  static void stop_tomcat(short port, 
                          const char *protocol,
                          HANDLE hTomcat)
  {
      struct sockaddr_in in;
      
      if(jk_resolve("localhost", port, &in)) {
          int sd = jk_open_socket(&in, JK_TRUE, NULL);
          if(sd >0) {
              int rc = JK_FALSE;
              if(!strcasecmp(protocol, "ajp13")) {
                  jk_pool_t pool;
                  jk_msg_buf_t *msg = NULL;
                  jk_pool_atom_t buf[TINY_POOL_SIZE];
  
                  jk_open_pool(&pool, buf, sizeof(buf));
  
                  msg = jk_b_new(&pool);
                  jk_b_set_buffer_size(msg, 512); 
  
                  rc = ajp13_marshal_shutdown_into_msgb(msg, 
                                                        &pool,
                                                        NULL);
                  if(rc) {
                      jk_b_end(msg);
      
                      if(0 > jk_tcp_socket_sendfull(sd, 
                                                    jk_b_get_buff(msg),
                                                    jk_b_get_len(msg))) {
                          rc = JK_FALSE;
                      }
                  }                                                    
              } else {
                  char b[] = {(char)254, (char)15};
                  rc = send(sd, b, 2, 0);
                  if(2 == rc) {
                      rc = JK_TRUE;
                  }
              }
              jk_close_socket(sd);
              if(JK_TRUE == rc) {
                  if(WAIT_OBJECT_0 == WaitForSingleObject(hTomcat, 30*1000)) {
                      return;
                  }
              }            
          }
      }
  
      TerminateProcess(hTomcat, 0);    
  }
  
  static int start_tomcat(const char *name, HANDLE *hTomcat)
  {
      char  tag[1024];
      HKEY  hk;
  
      strcpy(tag, BASE_REGISTRY_LOCATION);
      strcat(tag, name);
      strcat(tag, "\\");
      strcat(tag, PARAMS_LOCATION);
  
      if(ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                                       tag,
                                       (DWORD)0,         
                                       KEY_READ,
                                       &hk)) {
          char prp_file[2048];
          if(get_registry_config_parameter(hk,
                                           PRP_LOCATION, 
                                           prp_file,
                                           sizeof(prp_file))) {
              jk_map_t *init_map;
              
              if(map_alloc(&init_map)) {
                  if(map_read_properties(init_map, prp_file)) {
                      jk_tomcat_startup_data_t data;
                      jk_pool_t p;
                      jk_pool_atom_t buf[HUGE_POOL_SIZE];
                      jk_open_pool(&p, buf, sizeof(buf));
              
                      if(read_startup_data(init_map, &data, &p)) {
                          STARTUPINFO startupInfo;
                          PROCESS_INFORMATION processInformation;
                          SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE
};
  
                          if(data.extra_path) {
                              jk_append_libpath(&p, data.extra_path);
                          }
  
                          memset(&startupInfo, 0, sizeof(startupInfo));
                          startupInfo.cb = sizeof(startupInfo);
                          startupInfo.lpTitle = "Jakarta Tomcat";
                          startupInfo.dwFlags = STARTF_USESTDHANDLES;
                          startupInfo.hStdInput = NULL;
                          startupInfo.hStdOutput = CreateFile(data.stdout_file,
                                                              GENERIC_WRITE,
                                                              FILE_SHARE_READ,
                                                              &sa,
                                                              OPEN_ALWAYS,
                                                              FILE_ATTRIBUTE_NORMAL,
                                                              NULL);
                          SetFilePointer(startupInfo.hStdOutput,
                                         0,
                                         NULL,
                                         FILE_END);
                          startupInfo.hStdError = CreateFile(data.stderr_file,
                                                             GENERIC_WRITE,
                                                             FILE_SHARE_READ,
                                                             &sa,
                                                             OPEN_ALWAYS,
                                                             FILE_ATTRIBUTE_NORMAL,
                                                             NULL);
                          SetFilePointer(startupInfo.hStdError,
                                         0,
                                         NULL,
                                         FILE_END);
  
                          memset(&processInformation, 0, sizeof(processInformation));
                          
                          printf(data.cmd_line);
                          if(CreateProcess(data.java_bin,
                                          data.cmd_line,
                                          NULL,
                                          NULL,
                                          TRUE,
                                          CREATE_NEW_CONSOLE,
                                          NULL,
                                          data.tomcat_home,
                                          &startupInfo,
                                          &processInformation)){
  
                              *hTomcat = processInformation.hProcess;
                              CloseHandle(processInformation.hThread);
                              CloseHandle(startupInfo.hStdOutput);
                              CloseHandle(startupInfo.hStdError);
                              shutdown_port = data.shutdown_port;
                              shutdown_protocol = strdup(data.shutdown_protocol);
  
                              return JK_TRUE;
                          } else {
                              printf("Error: Can not create new process - %s\n", 
                                      GetLastErrorText(szErr, sizeof(szErr)));           
    
                          }
  
                      }                    
                  }
              }
              map_free(&init_map);
          }
          RegCloseKey(hk);
      } 
  
      return JK_FALSE;
  }
  
  static int create_registry_key(const char *tag,
                                 HKEY *key)
  {
      LONG  lrc = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                                 tag,
  			                   0,
  			                   NULL,
  			                   REG_OPTION_NON_VOLATILE,
  			                   KEY_WRITE,
  			                   NULL,
  			                   key,
  			                   NULL);
      if(ERROR_SUCCESS != lrc) {
          return JK_FALSE;        
      }
  
      return JK_TRUE;
  }
  
  static int set_registry_config_parameter(HKEY hkey,
                                           const char *tag, 
                                           char *value)
  {       
      LONG  lrc;
  
      lrc = RegSetValueEx(hkey, 
                          tag,            
  			            0,              
  			            REG_SZ,  
      			        value, 
                          strlen(value));
  
      if(ERROR_SUCCESS != lrc) {
          return JK_FALSE;        
      }
  
      return JK_TRUE;     
  }
  
  
  
  static int get_registry_config_parameter(HKEY hkey,
                                           const char *tag, 
                                           char *b,
                                           DWORD sz)
  {   
      DWORD type = 0;
      LONG  lrc;
  
      lrc = RegQueryValueEx(hkey,     
                            tag,      
                            (LPDWORD)0,
                            &type,    
                            (LPBYTE)b,
                            &sz); 
      if(ERROR_SUCCESS != lrc) {
          return JK_FALSE;        
      }
      
      b[sz] = '\0';
  
      return JK_TRUE;     
  }
  
  static int read_startup_data(jk_map_t *init_map, 
                               jk_tomcat_startup_data_t *data, 
                               jk_pool_t *p)
  {
      
      data->classpath = NULL;
      data->tomcat_home = NULL;
      data->stdout_file = NULL;
      data->stderr_file = NULL;
      data->java_bin = NULL;
      data->extra_path = NULL;
      data->tomcat_class = NULL;
      data->server_file = NULL;
  
      data->server_file = map_get_string(init_map, 
                                         "wrapper.server_xml", 
                                         NULL);
      if(!data->server_file) {
          return JK_FALSE;
      }
  
      data->classpath = map_get_string(init_map, 
                                       "wrapper.class_path", 
                                         NULL);
      if(!data->classpath) {
          return JK_FALSE;
      }
  
      data->tomcat_home = map_get_string(init_map, 
                                         "wrapper.tomcat_home", 
                                         NULL);
      if(!data->tomcat_home) {
          return JK_FALSE;
      }
  
      data->java_bin = map_get_string(init_map, 
                                      "wrapper.javabin", 
                                      NULL);
      if(!data->java_bin) {
          return JK_FALSE;
      }
  
      data->tomcat_class = map_get_string(init_map,
                                          "wrapper.startup_class",
                                          "org.apache.tomcat.startup.Tomcat");
  
      if(NULL == data->tomcat_class) {
          return JK_FALSE;
      }
  
      data->cmd_line = map_get_string(init_map,
                                      "wrapper.cmd_line",
                                      NULL);
      if(NULL == data->cmd_line) {
          data->cmd_line = (char *)jk_pool_alloc(p, (20 + 
                                                     strlen(data->java_bin) +
                                                     strlen(" -classpath ") +
                                                     strlen(data->classpath) +
                                                     strlen(data->tomcat_class) +
                                                     strlen(" -home ") +
                                                     strlen(data->tomcat_home) +
                                                     strlen(" -config ") +
                                                     strlen(data->server_file)
                                                     ) * sizeof(char));
          if(NULL == data->cmd_line) {
              return JK_FALSE;
          }
  
          strcpy(data->cmd_line, data->java_bin);
          strcat(data->cmd_line, " -classpath ");
          strcat(data->cmd_line, data->classpath);
          strcat(data->cmd_line, " ");
          strcat(data->cmd_line, data->tomcat_class);
          strcat(data->cmd_line, " -home ");
          strcat(data->cmd_line, data->tomcat_home);
          strcat(data->cmd_line, " -config ");
          strcat(data->cmd_line, data->server_file);
      }
  
      data->shutdown_port = map_get_int(init_map,
                                        "wrapper.shutdown_port",
                                        8007);
  
      data->shutdown_protocol = map_get_string(init_map,
                                               "wrapper.shutdown_protocol",
                                               AJP12_TAG);
  
      data->extra_path = map_get_string(init_map,
                                        "wrapper.ld_path",
                                        NULL);
  
      data->stdout_file = map_get_string(init_map,
                                         "wrapper.stdout",
                                         NULL);
  
      if(NULL == data->stdout_file) {
          data->stdout_file = jk_pool_alloc(p, strlen(data->tomcat_home) + 2 + strlen("\\stdout.log"));
          strcpy(data->stdout_file, data->tomcat_home);
          strcat(data->stdout_file, "\\stdout.log");        
      }
  
      data->stderr_file = map_get_string(init_map,
                                         "wrapper.stderr",
                                         NULL);
  
      if(NULL == data->stderr_file) {
          data->stderr_file = jk_pool_alloc(p, strlen(data->tomcat_home) + 2 + strlen("\\stderr.log"));
          strcpy(data->stderr_file, data->tomcat_home);
          strcat(data->stderr_file, "\\stderr.log");        
      }
  
      return JK_TRUE;
  }
  
  
  
  
  1.1                  jakarta-tomcat/proposals/web-connector/native/nt_service/nt_service.dsp
  
  Index: nt_service.dsp
  ===================================================================
  # Microsoft Developer Studio Project File - Name="nt_service" - Package Owner=<4>
  # Microsoft Developer Studio Generated Build File, Format Version 6.00
  # ** DO NOT EDIT **
  
  # TARGTYPE "Win32 (x86) Console Application" 0x0103
  
  CFG=nt_service - Win32 Debug
  !MESSAGE This is not a valid makefile. To build this project using NMAKE,
  !MESSAGE use the Export Makefile command and run
  !MESSAGE 
  !MESSAGE NMAKE /f "nt_service.mak".
  !MESSAGE 
  !MESSAGE You can specify a configuration when running NMAKE
  !MESSAGE by defining the macro CFG on the command line. For example:
  !MESSAGE 
  !MESSAGE NMAKE /f "nt_service.mak" CFG="nt_service - Win32 Debug"
  !MESSAGE 
  !MESSAGE Possible choices for configuration are:
  !MESSAGE 
  !MESSAGE "nt_service - Win32 Release" (based on "Win32 (x86) Console Application")
  !MESSAGE "nt_service - Win32 Debug" (based on "Win32 (x86) Console Application")
  !MESSAGE 
  
  # Begin Project
  # PROP AllowPerConfigDependencies 0
  # PROP Scc_ProjName ""
  # PROP Scc_LocalPath ""
  CPP=cl.exe
  RSC=rc.exe
  
  !IF  "$(CFG)" == "nt_service - Win32 Release"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 0
  # PROP BASE Output_Dir "Release"
  # PROP BASE Intermediate_Dir "Release"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 0
  # PROP Output_Dir "Release"
  # PROP Intermediate_Dir "Release"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD
/c
  # ADD CPP /nologo /W3 /GX /O2 /I "../common" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS"
/YX /FD /c
  # ADD BASE RSC /l 0x409 /d "NDEBUG"
  # ADD RSC /l 0x409 /d "NDEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib
gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
  # ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console
/machine:I386 /out:"Release/jk_nt_service.exe"
  
  !ELSEIF  "$(CFG)" == "nt_service - Win32 Debug"
  
  # PROP BASE Use_MFC 0
  # PROP BASE Use_Debug_Libraries 1
  # PROP BASE Output_Dir "Debug"
  # PROP BASE Intermediate_Dir "Debug"
  # PROP BASE Target_Dir ""
  # PROP Use_MFC 0
  # PROP Use_Debug_Libraries 1
  # PROP Output_Dir "Debug"
  # PROP Intermediate_Dir "Debug"
  # PROP Ignore_Export_Lib 0
  # PROP Target_Dir ""
  # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS"
/YX /FD /GZ /c
  # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../common" /D "WIN32" /D "_DEBUG" /D "_CONSOLE"
/D "_MBCS" /YX /FD /GZ /c
  # ADD BASE RSC /l 0x409 /d "_DEBUG"
  # ADD RSC /l 0x409 /d "_DEBUG"
  BSC32=bscmake.exe
  # ADD BASE BSC32 /nologo
  # ADD BSC32 /nologo
  LINK32=link.exe
  # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib
gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
  # ADD LINK32 wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console
/debug /machine:I386 /out:"Debug/jk_nt_service.exe" /pdbtype:sept
  
  !ENDIF 
  
  # Begin Target
  
  # Name "nt_service - Win32 Release"
  # Name "nt_service - Win32 Debug"
  # Begin Group "Source Files"
  
  # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
  # Begin Source File
  
  SOURCE=..\common\jk_ajp13.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_connect.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_map.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_msg_buff.c
  # End Source File
  # Begin Source File
  
  SOURCE=.\jk_nt_service.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_pool.c
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_util.c
  # End Source File
  # End Group
  # Begin Group "Header Files"
  
  # PROP Default_Filter "h;hpp;hxx;hm;inl"
  # Begin Source File
  
  SOURCE=..\common\jk_ajp12_worker.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_connect.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_global.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_logger.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_map.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_pool.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_service.h
  # End Source File
  # Begin Source File
  
  SOURCE=..\common\jk_util.h
  # End Source File
  # End Group
  # Begin Group "Resource Files"
  
  # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
  # End Group
  # End Target
  # End Project
  
  
  

Mime
View raw message