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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]