opendj-sdk/opends/build-tools/src/windows/service.c
@@ -1373,8 +1373,8 @@ // --------------------------------------------------------------- // Build a service name for OpenDS and make sure // the service name is unique on the system. To achieve this requirement // the service name looks like OpenDS for the first OpenDS and // OpenDS-n if there are more than one. // the service name looks like <baseName> for the first OpenDS and // <baseName>-n if there are more than one. // // The functions returns SERVICE_RETURN_OK if we could create a service // name and SERVICE_RETURN_ERROR otherwise. @@ -1382,7 +1382,7 @@ // minimum size must be of 256 (the maximum string length of a Service Name). // --------------------------------------------------------------- ServiceReturnCode createServiceName(char* serviceName) ServiceReturnCode createServiceName(char* serviceName, char* baseName) { ServiceReturnCode returnValue = SERVICE_RETURN_OK; int i = 1; @@ -1392,11 +1392,11 @@ { if (i == 1) { sprintf(serviceName, "OpenDS"); sprintf(serviceName, baseName); } else { sprintf(serviceName, "OpenDS-%d", i); sprintf(serviceName, "%s-%d", baseName, i); } nameInUseResult = serviceNameInUse(serviceName); @@ -1445,8 +1445,8 @@ // - serviceName is the service name char* serviceName = (char*) calloc(1, MAX_SERVICE_NAME); // elaborate the service name returnValue = createServiceName(serviceName); // elaborate the service name based on the displayName provided returnValue = createServiceName(serviceName, displayName); // create the service if (returnValue == SERVICE_RETURN_OK) @@ -1468,7 +1468,7 @@ myService = CreateService( scm, serviceName, // name of service displayName, // service name to display serviceName, // service name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start service during @@ -1753,7 +1753,45 @@ return returnCode; } // serviceState // --------------------------------------------------------------- // Function called to remove the service associated with a given // service name. // Returns 0 if the service was successfully removed. // Returns 1 if the service does not exist. // Returns 2 if the service was marked for deletion but is still in // use. // Returns 3 if an error occurred. // --------------------------------------------------------------- int removeServiceWithServiceName(char *serviceName) { int returnCode = 0; ServiceReturnCode code = serviceNameInUse(serviceName); if (code != SERVICE_IN_USE) { returnCode = 1; } else { code = removeServiceFromScm(serviceName); switch (code) { case SERVICE_RETURN_OK: removeRegistryKey(serviceName); returnCode = 0; break; case SERVICE_MARKED_FOR_DELETION: removeRegistryKey(serviceName); returnCode = 2; break; default: returnCode = 3; } } return returnCode; } // removeServiceWithServiceName // --------------------------------------------------------------- // Function called to remove the service for the OpenDS instance @@ -1778,21 +1816,7 @@ code = getServiceName(cmdToRun, serviceName); if (code == SERVICE_RETURN_OK) { code = removeServiceFromScm(serviceName); switch (code) { case SERVICE_RETURN_OK: removeRegistryKey(serviceName); returnCode = 0; break; case SERVICE_MARKED_FOR_DELETION: removeRegistryKey(serviceName); returnCode = 2; break; default: returnCode = 3; } returnCode = removeServiceWithServiceName(serviceName); } else { @@ -1808,6 +1832,7 @@ } // removeService // --------------------------------------------------------------- // Function called to start the service where this executable is installed. // Returns 0 if the service runs. @@ -1916,105 +1941,6 @@ } } void formatMessage(DWORD msgId, int count, ...) { char buf[2048]; int result; va_list args; char execName [MAX_PATH]; GetModuleFileName ( NULL, execName, MAX_PATH ); if (count > 0) { va_start(args, count); // Retrieve the English message string. result = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE, (LPBYTE)execName, WIN_EVENT_ID_SERVER_STARTED, //msgId, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buf, 2048, &args); } else { result = FormatMessage( FORMAT_MESSAGE_FROM_HMODULE, (LPBYTE)execName, msgId, LANG_NEUTRAL, (LPTSTR) &buf, 2048, NULL); } if (execName != NULL) { fprintf(stderr, "The module is [%s]\n", execName); } else { fprintf(stderr, "The module is NULL\n"); } if (result > 0) { fprintf(stderr, "formatMessage worked: [%s]\n", buf); } else { fprintf(stderr, "formatMessage failed, error is: %d\n", GetLastError()); } } void logMsgTest(char *serviceName) { DWORD ids[] = {WIN_EVENT_ID_SERVER_STARTED, WIN_EVENT_ID_SERVER_STOP, WIN_EVENT_ID_SERVER_START_FAILED, WIN_EVENT_ID_SERVER_STOP_FAILED, WIN_EVENT_ID_DEBUG}; const char* args[] = {"c:\\temp\\OpenDS tarara"}; int evCount = 5; int i; _eventLog = registerEventLog(serviceName); for (i = 0; i<evCount; i++) { if (i != 5) { formatMessage(ids[i], 1, args[0]); if(reportLogEvent(EVENTLOG_SUCCESS, ids[i], 1, args)) { fprintf(stderr, "reportLogEvent successful.\n"); } else { fprintf(stderr, "reportLogEvent failed: %d.\n", GetLastError()); } } else { formatMessage(ids[i], 0); if (reportLogEvent(EVENTLOG_SUCCESS, ids[i], 1, args)) { fprintf(stderr, "reportLogEvent successful.\n"); } else { fprintf(stderr, "reportLogEvent failed: %d.\n", GetLastError()); } } } deregisterEventLog(); } int main(int argc, char* argv[]) { char* subcommand; @@ -2022,7 +1948,8 @@ if (argc <= 1) { fprintf(stderr, "Subcommand required: create, state, remove or start\n"); fprintf(stderr, "Subcommand required: create, state, remove, start or cleanup.\n"); returnCode = -1; } else @@ -2033,7 +1960,7 @@ if (argc <= 4) { fprintf(stderr, "Subcommand create requires instance dir, service name and description.\n"); "Subcommand create requires instance dir, service name and description.\n"); returnCode = -1; } else @@ -2049,7 +1976,7 @@ if (argc <= 2) { fprintf(stderr, "Subcommand state requires instance dir\n"); "Subcommand state requires instance dir.\n"); returnCode = -1; } else @@ -2065,7 +1992,7 @@ if (argc <= 2) { fprintf(stderr, "Subcommand remove requires instance dir\n"); "Subcommand remove requires instance dir.\n"); returnCode = -1; } else @@ -2081,7 +2008,7 @@ if (argc <= 2) { fprintf(stderr, "Subcommand start requires instancedir.\n"); "Subcommand start requires instance dir.\n"); returnCode = -1; } else @@ -2097,7 +2024,7 @@ if (argc <= 2) { fprintf(stderr, "Subcommand isrunning requires instancedir.\n"); "Subcommand isrunning requires instance dir.\n"); returnCode = -1; } else @@ -2119,42 +2046,23 @@ } } else if (strcmp(subcommand, "logevents") == 0) else if (strcmp(subcommand, "cleanup") == 0) { if (argc <= 2) { fprintf(stderr, "Subcommand logevents requires instancedir.\n"); "Subcommand cleanup requires service name.\n"); returnCode = -1; } else { ServiceReturnCode code; char cmdToRun[MAX_PATH]; char serviceName[MAX_SERVICE_NAME]; _instanceDir = strdup(argv[2]); code = createServiceBinPath(cmdToRun); if (code == SERVICE_RETURN_OK) { code = getServiceName(cmdToRun, serviceName); } if (code == SERVICE_RETURN_OK) { logMsgTest(serviceName); returnCode = 0; } else { returnCode = -1; } free(_instanceDir); char* serviceName = strdup(argv[2]); updateDebugFlag(argv, argc, 3); returnCode = removeServiceWithServiceName(serviceName); free(serviceName); } } else { fprintf(stderr, "Unknown subcommand: [%s]\n", subcommand); opendj-sdk/opends/build-tools/src/windows/service.h
@@ -92,7 +92,7 @@ ServiceReturnCode registerServiceHandler (char* serviceName, LPHANDLER_FUNCTION serviceHandler, SERVICE_STATUS_HANDLE* serviceStatusHandle); ServiceReturnCode serviceNameInUse(char* serviceName); ServiceReturnCode createServiceName(char* serviceName); ServiceReturnCode createServiceName(char* serviceName, char* baseName); ServiceReturnCode getServiceList(ServiceDescriptor** serviceList, int *nbServices); ServiceReturnCode createServiceBinPath(char* serviceBinPath); opendj-sdk/opends/lib/opends_service.exeBinary files differ
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
@@ -7940,6 +7940,43 @@ /** * The message ID for the message for the description of cleanup Windows * service. This does not take any argument. */ public static final int MSGID_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_CLEANUP = CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 844; /** * The message ID to inform that the cleanup of the Windows service was * successful. This takes the service name as argument. */ public static final int MSGID_WINDOWS_SERVICE_CLEANUP_SUCCESS = CATEGORY_MASK_TOOLS | SEVERITY_MASK_INFORMATIONAL | 845; /** * The message ID to inform that the service during the cleanup could not be * found. This takes the service name as argument. */ public static final int MSGID_WINDOWS_SERVICE_CLEANUP_NOT_FOUND = CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 846; /** * The message ID to inform that the service has been marked for deletion. * This takes the service name as argument. */ public static final int MSGID_WINDOWS_SERVICE_CLEANUP_MARKED_FOR_DELETION = CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_WARNING | 847; /** * The message ID to inform that an error occurred during the service clean * up. This takes the service name as argument. */ public static final int MSGID_WINDOWS_SERVICE_CLEANUP_ERROR = CATEGORY_MASK_TOOLS | SEVERITY_MASK_SEVERE_ERROR | 848; /** * Associates a set of generic messages with the message IDs defined in this * class. */ @@ -10354,6 +10391,11 @@ "Provides information about the state of OpenDS as a "+ "Windows service."); registerMessage(MSGID_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_CLEANUP, "Allows to disable the OpenDS service and to clean up the "+ "windows registry information associated with the "+ "provided service name."); registerMessage(MSGID_CONFIGURE_WINDOWS_SERVICE_CANNOT_INITIALIZE_ARGS, "An unexpected error occurred while attempting to " + "initialize the command-line arguments: %s."); @@ -10364,11 +10406,13 @@ registerMessage(MSGID_CONFIGURE_WINDOWS_SERVICE_TOO_MANY_ARGS, "You can only provide one of the following arguments:"+ EOL+"enableService, disableService or serviceState."); EOL+"enableService, disableService, serviceState or "+ "cleanupService."); registerMessage(MSGID_CONFIGURE_WINDOWS_SERVICE_TOO_FEW_ARGS, "You must provide at least one of the following arguments:"+ EOL+"enableService, disableService or serviceState."); EOL+"enableService, disableService or serviceState or "+ "cleanupService."); registerMessage(MSGID_WINDOWS_SERVICE_NAME, "OpenDS"); @@ -10415,6 +10459,18 @@ registerMessage(MSGID_WINDOWS_SERVICE_STATE_ERROR, "An unexpected error occurred trying to retrieve the "+ "state of OpenDS as a Windows service."); registerMessage(MSGID_WINDOWS_SERVICE_CLEANUP_SUCCESS, "Clean up of service %s was successful."); registerMessage(MSGID_WINDOWS_SERVICE_CLEANUP_NOT_FOUND, "Could not find the service with name %s."); registerMessage(MSGID_WINDOWS_SERVICE_CLEANUP_ERROR, "An unexpected error occurred cleaning up the service %s."); registerMessage(MSGID_WINDOWS_SERVICE_CLEANUP_MARKED_FOR_DELETION, "Service %s has been marked for deletion."); } } opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java
@@ -39,6 +39,7 @@ import org.opends.server.util.args.ArgumentException; import org.opends.server.util.args.ArgumentParser; import org.opends.server.util.args.BooleanArgument; import org.opends.server.util.args.StringArgument; import static org.opends.server.messages.MessageHandler.getMessage; import static org.opends.server.messages.ToolMessages.*; @@ -118,6 +119,27 @@ public static final int SERVICE_STATE_ERROR = 2; /** * Return codes for the method cleanupService. */ /** * The service cleanup worked. */ public static final int SERVICE_CLEANUP_SUCCESS = 0; /** * The service could not be found. */ public static final int SERVICE_NOT_FOUND = 1; /** * An error occurred cleaning up the service. */ public static final int SERVICE_CLEANUP_ERROR = 2; /** * The service is marked for deletion. */ public static final int SERVICE_CLEANUP_MARKED_FOR_DELETION = 3; /** * Configures the Windows service for this instance on this machine. * This tool allows to enable and disable OpenDS to run as a Windows service * and allows to know if OpenDS is running as a Windows service or not. @@ -174,6 +196,7 @@ BooleanArgument enableService = null; BooleanArgument disableService = null; BooleanArgument serviceState = null; StringArgument cleanupService = null; BooleanArgument showUsage = null; try @@ -192,6 +215,11 @@ MSGID_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_STATE); argParser.addArgument(serviceState); cleanupService = new StringArgument("cleanupservice", 'c', "cleanupService", false, false, true, "{serviceName}", null, null, MSGID_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_CLEANUP); argParser.addArgument(cleanupService); showUsage = new BooleanArgument("showusage", 'H', "help", MSGID_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_SHOWUSAGE); argParser.addArgument(showUsage); @@ -241,6 +269,10 @@ { nArgs++; } if (cleanupService.isPresent()) { nArgs++; } if (nArgs > 1) { int msgID = MSGID_CONFIGURE_WINDOWS_SERVICE_TOO_MANY_ARGS; @@ -269,10 +301,14 @@ { returnValue = disableService(out, err); } else else if (serviceState.isPresent()) { returnValue = serviceState(out, err); } else { returnValue = cleanupService(cleanupService.getValue(), out, err); } } return returnValue; @@ -464,6 +500,68 @@ } /** * Cleans up a service for a given service name. * @param serviceName the service name to be cleaned up. * @param out the stream used to write the standard output. * @param err the stream used to write the error output. * @return <CODE>SERVICE_CLEANUP_SUCCESS</CODE>, * <CODE>SERVICE_NOT_FOUND</CODE>, * <CODE>SERVICE_MARKED_FOR_DELETION</CODE> or * <CODE>SERVICE_CLEANUP_ERROR</CODE> depending on whether the service * could be found or not. */ public static int cleanupService(String serviceName, PrintStream out, PrintStream err) { int returnValue; String msg; String[] cmd = { getBinaryFullPath(), "cleanup", serviceName }; try { int resultCode = Runtime.getRuntime().exec(cmd).waitFor(); switch (resultCode) { case 0: returnValue = SERVICE_CLEANUP_SUCCESS; msg = getMessage(MSGID_WINDOWS_SERVICE_CLEANUP_SUCCESS, serviceName); out.println(msg); break; case 1: returnValue = SERVICE_NOT_FOUND; msg = getMessage(MSGID_WINDOWS_SERVICE_CLEANUP_NOT_FOUND, serviceName); err.println(msg); break; case 2: returnValue = SERVICE_CLEANUP_MARKED_FOR_DELETION; msg = getMessage(MSGID_WINDOWS_SERVICE_CLEANUP_MARKED_FOR_DELETION, serviceName); out.println(msg); break; case 3: returnValue = SERVICE_CLEANUP_ERROR; msg = getMessage(MSGID_WINDOWS_SERVICE_CLEANUP_ERROR, serviceName); err.println(msg); break; default: returnValue = SERVICE_CLEANUP_ERROR; msg = getMessage(MSGID_WINDOWS_SERVICE_CLEANUP_ERROR, serviceName); err.println(msg); } } catch (Throwable t) { returnValue = SERVICE_CLEANUP_ERROR; msg = getMessage(MSGID_WINDOWS_SERVICE_CLEANUP_ERROR, serviceName); err.println(msg); } return returnValue; } /** * Checks if OpenDS is enabled as a windows service and if it is * write the serviceName in the output stream (if it is not null). * @param out the stream used to write the standard output.