| | |
| | | * |
| | | * |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011 ForgeRock AS |
| | | * Portions Copyright 2011-2013 ForgeRock AS |
| | | */ |
| | | |
| | | #include "service.h" |
| | |
| | | |
| | | if (strlen(relativePath)+strlen(_instanceDir)+1 < COMMAND_SIZE) |
| | | { |
| | | sprintf(command, "\"%s%s\" --windowsNetStart", _instanceDir, relativePath); |
| | | sprintf(command, "\"%s%s\" --windowsNetStart", _instanceDir, relativePath); |
| | | debug("doStartApplication: Launching batch file: %s", command); |
| | | createOk = createBatchFileChildProcess(command, FALSE, &procInfo); |
| | | |
| | |
| | | debug("The batch file process could not be created property"); |
| | | } |
| | | |
| | | if (createOk && waitOk) |
| | | if (createOk && waitOk) |
| | | { |
| | | BOOL running; |
| | | BOOL running; |
| | | // Just check once if the server is running or not: since the wait |
| | | // wait was successful, if the server is getting the lock, it already |
| | | // got it. |
| | | isServerRunning(&running, TRUE); |
| | | if (running) |
| | | isServerRunning(&running, TRUE); |
| | | if (running) |
| | | { |
| | | returnValue = SERVICE_RETURN_OK; |
| | | debug("doStartApplication: server running."); |
| | |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | debug("doStartApplication: server not running."); |
| | | } |
| | | } |
| | | } |
| | | else if (createOk) |
| | | { |
| | | // Try to see if server is really running |
| | |
| | | else |
| | | { |
| | | debug("OPENDJ_WINDOWS_SERVICE_START_NTRIES is not set. Using default %d tries.", nTries); |
| | | } |
| | | } |
| | | |
| | | debug( |
| | | "doStartApplication: the spawn of the batch command worked. Command: '%s'", |
| | |
| | | |
| | | |
| | | // ---------------------------------------------------- |
| | | // Start the application using stop-ds.bat |
| | | // Stop the application using stop-ds.bat |
| | | // The functions returns SERVICE_RETURN_OK if we could stop the server |
| | | // and SERVICE_RETURN_ERROR otherwise. |
| | | // ---------------------------------------------------- |
| | |
| | | { |
| | | // failed to get the path of the executable file |
| | | returnValue = SERVICE_RETURN_ERROR; |
| | | debug("Could not get the path of the executable file."); |
| | | debug("Could not get the path of the executable file."); |
| | | } |
| | | else |
| | | { |
| | |
| | | } // updateServiceStatus |
| | | |
| | | // ---------------------------------------------------- |
| | | // Query the current status of the service serviceName into returnedStatus |
| | | // return true if it was successful, false otherwise |
| | | // ---------------------------------------------------- |
| | | BOOL getServiceStatus(char *serviceName, LPDWORD returnedState) |
| | | { |
| | | SC_HANDLE hScm; |
| | | SC_HANDLE hService; |
| | | BOOL ret = FALSE; |
| | | |
| | | if (openScm(SC_MANAGER_ALL_ACCESS, &hScm) != SERVICE_RETURN_OK) |
| | | { |
| | | debugError("getServiceStatus: openScm did not work. Last error = %d", |
| | | GetLastError()); |
| | | return FALSE; |
| | | } |
| | | |
| | | |
| | | hService = OpenService(hScm, serviceName, SERVICE_QUERY_STATUS); |
| | | if(hService == NULL) |
| | | { |
| | | debugError("getServiceStatus: openService did not work. Last error = %d", |
| | | GetLastError()); |
| | | } |
| | | else |
| | | { |
| | | SERVICE_STATUS ss; |
| | | memset(&ss, 0, sizeof(ss)); |
| | | if (QueryServiceStatus(hService, &ss)) |
| | | { |
| | | *returnedState = ss.dwCurrentState; |
| | | ret = TRUE; |
| | | } |
| | | else |
| | | { |
| | | debugError("getServiceStatus: Failed to query the service status. Last error = %d", |
| | | GetLastError()); |
| | | } |
| | | // close the service handle |
| | | CloseServiceHandle(hService); |
| | | } |
| | | // close the service control manager handle |
| | | CloseServiceHandle(hScm); |
| | | |
| | | return ret; |
| | | } |
| | | |
| | | // ---------------------------------------------------- |
| | | // This function is the "main" of the service. It has been registered |
| | | // to the SCM by the main right after the service has been started through |
| | | // NET START command. |
| | |
| | | if (code == SERVICE_RETURN_OK) |
| | | { |
| | | BOOL updatedRunningStatus = FALSE; |
| | | DWORD returnValue; |
| | | DWORD returnValue; |
| | | int refreshPeriodSeconds = 10; |
| | | char *refreshPeriodEnv = getenv("OPENDJ_WINDOWS_SERVICE_REFRESH_PERIOD"); |
| | | if (refreshPeriodEnv != NULL) |
| | |
| | | { |
| | | returnValue = WaitForSingleObject (_terminationEvent, INFINITE); |
| | | break; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | running = FALSE; |
| | |
| | | if (returnValue == WAIT_OBJECT_0) |
| | | { |
| | | debug("The application has exited."); |
| | | break; |
| | | break; |
| | | } |
| | | } |
| | | code = isServerRunning(&running, FALSE); |
| | |
| | | else if (running) |
| | | { |
| | | _serviceCurStatus = SERVICE_RUNNING; |
| | | if (!updatedRunningStatus) |
| | | { |
| | | WORD argCount = 1; |
| | | if (!updatedRunningStatus) |
| | | { |
| | | WORD argCount = 1; |
| | | const char *argc[] = {_instanceDir}; |
| | | updateServiceStatus ( |
| | | _serviceCurStatus, |
| | | NO_ERROR, |
| | | 0, |
| | | checkPoint ++, |
| | | TIMEOUT_NONE, |
| | | TIMEOUT_NONE, |
| | | _serviceStatusHandle |
| | | ); |
| | | reportLogEvent( |
| | |
| | | WIN_EVENT_ID_SERVER_STARTED, |
| | | argCount, argc |
| | | ); |
| | | updatedRunningStatus = TRUE; |
| | | } |
| | | updatedRunningStatus = TRUE; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | WORD argCount = 1; |
| | | const char *argc[] = {_instanceDir}; |
| | | _serviceCurStatus = SERVICE_STOPPED; |
| | | debug("checking in serviceMain serviceHandler: service stopped."); |
| | | // Check current Status |
| | | DWORD state; |
| | | BOOL success = getServiceStatus(serviceName, &state); |
| | | if (!(success && |
| | | ((state == SERVICE_STOPPED) || |
| | | (state == SERVICE_STOP_PENDING)))) |
| | | { |
| | | WORD argCount = 1; |
| | | const char *argc[] = {_instanceDir}; |
| | | _serviceCurStatus = SERVICE_STOPPED; |
| | | debug("checking in serviceMain serviceHandler: service stopped with error."); |
| | | |
| | | updateServiceStatus ( |
| | | updateServiceStatus ( |
| | | _serviceCurStatus, |
| | | ERROR_SERVICE_SPECIFIC_ERROR, |
| | | -1, |
| | | CHECKPOINT_NO_ONGOING_OPERATION, |
| | | TIMEOUT_NONE, |
| | | _serviceStatusHandle); |
| | | reportLogEvent( |
| | | reportLogEvent( |
| | | EVENTLOG_ERROR_TYPE, |
| | | WIN_EVENT_ID_SERVER_STOPPED_OUTSIDE_SCM, |
| | | argCount, argc); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | |
| | | { |
| | | WORD argCount = 1; |
| | | const char *argc[] = {_instanceDir}; |
| | | debug("serviceHandler: The server could not be stopped."); |
| | | debug("serviceHandler: The server could not be stopped."); |
| | | // We could not stop the server |
| | | reportLogEvent( |
| | | EVENTLOG_ERROR_TYPE, |
| | |
| | | |
| | | if (myService == NULL) |
| | | { |
| | | debugError("getBinaryPathName: Failed to open the service '%s'.", serviceName); |
| | | debugError("getBinaryPathName: Failed to open the service '%s'.", serviceName); |
| | | } |
| | | else |
| | | { |
| | |
| | | } |
| | | if (!CloseServiceHandle(myService)) |
| | | { |
| | | debug("getBinaryPathName: error closing handle of service. Code [%d]", |
| | | GetLastError()); |
| | | debug("getBinaryPathName: error closing handle of service. Code [%d]", |
| | | GetLastError()); |
| | | } |
| | | } |
| | | |
| | |
| | | WIN_EVENT_ID_SERVER_START_FAILED, |
| | | argCount, argc |
| | | ); |
| | | debugError("startService: For instance dir '%s', %s", argc[0], argc[1]); |
| | | debugError("startService: For instance dir '%s', %s", argc[0], argc[1]); |
| | | } |
| | | deregisterEventLog(); |
| | | } |