You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by jf...@apache.org on 2003/06/17 18:46:24 UTC

cvs commit: jakarta-commons-sandbox/daemon/src/native/nt/procrun procrun.c

jfclere     2003/06/17 09:46:24

  Modified:    daemon/src/native/nt/procrun procrun.c
  Log:
  Arrange the win9x support.
  
  Revision  Changes    Path
  1.24      +150 -8    jakarta-commons-sandbox/daemon/src/native/nt/procrun/procrun.c
  
  Index: procrun.c
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/daemon/src/native/nt/procrun/procrun.c,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- procrun.c	16 Jun 2003 17:05:13 -0000	1.23
  +++ procrun.c	17 Jun 2003 16:46:24 -0000	1.24
  @@ -2278,11 +2278,145 @@
           DBPRINTF0( "Could not delete the Services registry key.\r\n");
           return -1;
       }
  -    DBPRINTF0("service deleted succesfull\n"
  +    DBPRINTF0("service deleted succesfull\n");
       SetEvent(proc->events[0]);
       return 0;
   }
   
  +/* This is the WndProc procedure for our invisible window.
  + * When our subclasssed tty window receives the WM_CLOSE, WM_ENDSESSION,
  + * or WM_QUERYENDSESSION messages, the message is dispatched to our hidden
  + * window (this message process), and we call the installed HandlerRoutine
  + * that was registered by the app.
  + */
  +#ifndef ENDSESSION_LOGOFF
  +#define ENDSESSION_LOGOFF    0x80000000
  +#endif
  +static LRESULT CALLBACK ttyConsoleCtrlWndProc(HWND hwnd, UINT msg,
  +                                              WPARAM wParam, LPARAM lParam)
  +{
  +    int   qreturn;
  +    if (msg == WM_CREATE) {
  +        DBPRINTF0("ttyConsoleCtrlWndProc WM_CREATE");
  +        return 0;
  +    } else if (msg == WM_DESTROY) {
  +        DBPRINTF0("ttyConsoleCtrlWndProc WM_DESTROY");
  +        return 0;
  +    } else if (msg == WM_CLOSE) {
  +        /* Call StopService?. */
  +        DBPRINTF0("ttyConsoleCtrlWndProc WM_CLOSE");
  +        return 0; /* May return 1 if StopService failed. */
  +    } else if ((msg == WM_QUERYENDSESSION) || (msg == WM_ENDSESSION)) {
  +        if (lParam & ENDSESSION_LOGOFF) {
  +            /* Here we have nothing to our hidden windows should stay. */
  +            DBPRINTF0(TEXT("ttyConsoleCtrlWndProc LOGOFF"));
  +            return(1); /* Otherwise it cancels the logoff */
  +        } else {
  +            /* Stop Service. */
  +            DBPRINTF0("ttyConsoleCtrlWndProc SHUTDOWN");
  +            SetEvent(g_env->m->events[0]);
  +
  +            return(1); /* Otherwise it cancels the shutdown. */
  +        }
  +    }
  +    return (DefWindowProc(hwnd, msg, wParam, lParam));
  +}                                                                               
  +/* ttyConsoleCreateThread is the process that runs within the user app's
  + * context.  It creates and pumps the messages of a hidden monitor window,
  + * watching for messages from the system, or the associated subclassed tty
  + * window.  Things can happen in our context that can't be done from the
  + * tty's context, and visa versa, so the subclass procedure and this hidden
  + * window work together to make it all happen.
  + */
  +static DWORD WINAPI ttyConsoleCtrlThread()
  +{
  +    HWND monitor_hwnd;
  +    WNDCLASS wc;
  +    MSG msg;
  +    wc.style         = CS_GLOBALCLASS;
  +    wc.lpfnWndProc   = ttyConsoleCtrlWndProc;
  +    wc.cbClsExtra    = 0;
  +    wc.cbWndExtra    = 8;
  +    wc.hInstance     = NULL;
  +    wc.hIcon         = NULL;
  +    wc.hCursor       = NULL;
  +    wc.hbrBackground = NULL;
  +    wc.lpszMenuName  = NULL;
  +    wc.lpszClassName = "ApacheJakartaService";
  + 
  +    if (!RegisterClass(&wc)) {
  +        DBPRINTF0("RegisterClass failed");
  +        return 0;
  +    }
  + 
  +    /* Create an invisible window */
  +    monitor_hwnd = CreateWindow(wc.lpszClassName, 
  +                                "ApacheJakartaService",
  +                                WS_OVERLAPPED & ~WS_VISIBLE,
  +                                CW_USEDEFAULT, CW_USEDEFAULT,
  +                                CW_USEDEFAULT, CW_USEDEFAULT,
  +                                NULL, NULL,
  +                                GetModuleHandle(NULL), NULL);
  + 
  +    if (!monitor_hwnd) {
  +        DBPRINTF0("RegisterClass failed");
  +        return 0;
  +    }
  + 
  +    while (GetMessage(&msg, NULL, 0, 0))
  +    {
  +        TranslateMessage(&msg);
  +        DispatchMessage(&msg);
  +    }
  + 
  +    return 0;
  +}
  +/*
  + * Register the process to resist logoff and start the thread that will receive
  + * the shutdown via a hidden window.
  + */
  +BOOL Windows9xServiceCtrlHandler()
  +{
  +    HANDLE hThread;
  +    DWORD tid;
  +    HINSTANCE hkernel;
  +    DWORD (WINAPI *register_service_process)(DWORD, DWORD) = NULL;
  +
  +    /* If we have not yet done so */
  +    FreeConsole();
  +
  +    /* Make sure the process will resist logoff */
  +    hkernel = LoadLibrary("KERNEL32.DLL");
  +    if (!hkernel) {
  +        DBPRINTF0("LoadLibrary KERNEL32.DLL failed");
  +        return 0;
  +    }
  +    register_service_process = (DWORD (WINAPI *)(DWORD, DWORD)) 
  +        GetProcAddress(hkernel, "RegisterServiceProcess");
  +    if (register_service_process == NULL) {
  +        DBPRINTF0("dlsym RegisterServiceProcess failed");
  +        return 0;
  +    }
  +    if (!register_service_process(0,TRUE)) {
  +        FreeLibrary(hkernel);
  +        DBPRINTF0("register_service_process failed");
  +        return 0;
  +    }
  +    DBPRINTF0("procrun registered as a service");
  +
  +    /*
  +     * To be handle notice the shutdown, we need a thread and window.
  +     */
  +     hThread = CreateThread(NULL, 0, ttyConsoleCtrlThread,
  +                               (LPVOID)NULL, 0, &tid);
  +     if (hThread) {
  +        CloseHandle(hThread);
  +        return TRUE;
  +     }
  +    DBPRINTF0("jsvc shutdown listener start failed");
  +    return TRUE;
  +}
  +
   int report_service_status(DWORD dwCurrentState,
                             DWORD dwWin32ExitCode,
                             DWORD dwWaitHint,
  @@ -2306,8 +2440,9 @@
            proc->service.status.dwCheckPoint = 0;
         else
           proc->service.status.dwCheckPoint = dwCheckPoint++;
  -      if (!(fResult = SetServiceStatus(
  -                        proc->service.h_status, &proc->service.status))) {
  +      if (g_is_windows_nt)
  +         fResult = SetServiceStatus(proc->service.h_status, &proc->service.status);
  +      if (!fResult) {
            DBPRINTF0("SetServiceStatus\tFailed\n");
            DBPRINTF0(NULL);
         }
  @@ -2388,12 +2523,14 @@
       g_env->m->service.status.dwWaitHint         = 0; 
   
       g_env->m->service.status.dwServiceSpecificExitCode = 0;
  -    if (g_env->m->service.mode) {
  +    if (g_env->m->service.mode && g_is_windows_nt) {
           g_env->m->service.h_status = RegisterServiceCtrlHandler(g_env->m->service.name,
                                                                        service_ctrl);
           if (!g_env->m->service.h_status)
               goto cleanup;
  -    }
  +    } else
  +        g_env->m->service.h_status = 0;
  +
       report_service_status(SERVICE_START_PENDING, NO_ERROR, 3000,
                             g_env->m);
       if (g_env->m->java.dll) {
  @@ -2580,9 +2717,14 @@
               }
               debug_process(argc, argv, env->m);
               env->m->service.mode = 1;
  -            dispatch_table[0].lpServiceName = env->m->service.name;
  -            dispatch_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
  -            rv = (StartServiceCtrlDispatcher(dispatch_table) == FALSE);
  +            if (g_is_windows_nt) {
  +                dispatch_table[0].lpServiceName = env->m->service.name;
  +                dispatch_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)service_main;
  +                rv = (StartServiceCtrlDispatcher(dispatch_table) == FALSE);
  +            } else {
  +                Windows9xServiceCtrlHandler();
  +                service_main(argc,argv);
  +            }
               break;
   #ifdef PROCRUN_WINAPP
           case PROCRUN_CMD_GUID_PROCESS:
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org