/* * @(#)service.c 1.0 4th March 1997 Hitesh Kr. Seth * * Note: This program is a tailored version of MSVC (Visual C++) Sample Source * Code. * * @requires JDK1.1Final. * This program implements the NT service. * function service_impl_main uses the Invocation API. * For more details see the JNI Guide from http://www.javasoft.com * */ /******************************************************************************\ * This is a part of the Microsoft Source Code Samples. * Copyright (C) 1993 Microsoft Corporation. * All rights reserved. * This source code is only intended as a supplement to * Microsoft Development Tools and/or WinHelp documentation. * See these sources for detailed information regarding the * Microsoft samples programs. \******************************************************************************/ #include #include #include #include #include #include HANDLE hServDoneEvent = NULL; SERVICE_STATUS_HANDLE sshStatusHandle; SERVICE_STATUS ssStatus; HANDLE threadHandle = NULL; VOID service_main(DWORD dwArgc, LPTSTR *lpszArgv); VOID service_ctrl(DWORD dwCtrlCode); BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint, DWORD dwWaitHint); VOID StopSampleService(LPTSTR lpszMsg); void service_impl_main( void); VOID StopSimpleService(LPTSTR lpszMsg); DWORD dwGlobalErr; VOID main() { SERVICE_TABLE_ENTRY dispatchTable[] = { { TEXT("SimpleJavaNTService"), (LPSERVICE_MAIN_FUNCTION)service_main }, { NULL, NULL } }; if (!StartServiceCtrlDispatcher(dispatchTable)) { StopSimpleService("StartServiceCtrlDispatcher failed."); } } VOID service_main(DWORD dwArgc, LPTSTR *lpszArgv) { DWORD dwWait; PSECURITY_DESCRIPTOR pSD; SECURITY_ATTRIBUTES sa; sshStatusHandle = RegisterServiceCtrlHandler( TEXT("SimpleJavaNTService"), (LPHANDLER_FUNCTION)service_ctrl); if (!sshStatusHandle) goto cleanup; ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ssStatus.dwServiceSpecificExitCode = 0; if (!ReportStatusToSCMgr( SERVICE_START_PENDING, NO_ERROR, 1, 3000)) goto cleanup; hServDoneEvent = CreateEvent( NULL, TRUE, FALSE, NULL); if (hServDoneEvent == (HANDLE)NULL) goto cleanup; threadHandle = (HANDLE)_beginthread( service_impl_main, 4096, // stack size NULL); // argument to thread if (!threadHandle) goto cleanup; if (!ReportStatusToSCMgr( SERVICE_RUNNING, // service state NO_ERROR, // exit code 0, // checkpoint 0)) // wait hint goto cleanup; dwWait = WaitForSingleObject( hServDoneEvent, // event object INFINITE); // wait indefinitely cleanup: if (hServDoneEvent != NULL) CloseHandle(hServDoneEvent); if (sshStatusHandle != 0) (VOID)ReportStatusToSCMgr( SERVICE_STOPPED, dwGlobalErr, 0, 0); return; } VOID service_ctrl(DWORD dwCtrlCode) { DWORD dwState = SERVICE_RUNNING; switch(dwCtrlCode) { case SERVICE_CONTROL_PAUSE: if (ssStatus.dwCurrentState == SERVICE_RUNNING) { SuspendThread(threadHandle); dwState = SERVICE_PAUSED; } break; case SERVICE_CONTROL_CONTINUE: if (ssStatus.dwCurrentState == SERVICE_PAUSED) { ResumeThread(threadHandle); dwState = SERVICE_RUNNING; } break; case SERVICE_CONTROL_STOP: dwState = SERVICE_STOP_PENDING; ReportStatusToSCMgr( SERVICE_STOP_PENDING, // current state NO_ERROR, // exit code 1, // checkpoint 3000); // waithint SetEvent(hServDoneEvent); return; case SERVICE_CONTROL_INTERROGATE: break; default: break; } ReportStatusToSCMgr(dwState, NO_ERROR, 0, 0); } BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwCheckPoint, DWORD dwWaitHint) { BOOL fResult; if (dwCurrentState == SERVICE_START_PENDING) ssStatus.dwControlsAccepted = 0; else ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; ssStatus.dwCurrentState = dwCurrentState; ssStatus.dwWin32ExitCode = dwWin32ExitCode; ssStatus.dwCheckPoint = dwCheckPoint; ssStatus.dwWaitHint = dwWaitHint; if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus))) { StopSimpleService("SetServiceStatus"); } return fResult; } VOID StopSimpleService(LPTSTR lpszMsg) { CHAR chMsg[256]; HANDLE hEventSource; LPTSTR lpszStrings[2]; dwGlobalErr = GetLastError(); hEventSource = RegisterEventSource(NULL, TEXT("SimpleJavaNTService")); sprintf(chMsg, "SimpleJavaNTService error: %d", dwGlobalErr); lpszStrings[0] = chMsg; lpszStrings[1] = lpszMsg; if (hEventSource != NULL) { ReportEvent(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 2, 0, lpszStrings, NULL); (VOID) DeregisterEventSource(hEventSource); } SetEvent(hServDoneEvent); } VOID service_impl_main() { JNIEnv *env; JavaVM *jvm; JDK1_1InitArgs vm_args; char *main_class_name="Server"; // The main class of the server jclass c; jarray ja; int i; jmethodID mid; jstring str; /* * Get the default initialization arguments and set the class * path */ JNI_GetDefaultJavaVMInitArgs(&vm_args); vm_args.classpath="C:\\jdk1.1\\lib\\classes.zip;C:\\users\\hks"; /* * load and initialize a Java VM, return a JNI interface * pointer in env */ JNI_CreateJavaVM(&jvm,&env,&vm_args); /* * Create an empty String[] to be passed to the class Server * while calling its static main(String[]) method */ c=(*env)->FindClass(env,"java/lang/String"); ja = (*env)->NewObjectArray(env,0,c,NULL); c = (*env)->FindClass(env,main_class_name); mid = (*env)->GetStaticMethodID(env,c,"main","([Ljava/lang/String;)V"); /* * Invoke Server.main(String[]) method */ (*env)->CallStaticVoidMethod(env,c,mid,ja); }