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