From ba928b801598f6651897e07f8e4ed8a4eeea68bd Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Fri, 16 Mar 2007 14:10:42 +0000
Subject: [PATCH] Fix for issue 1382 (Provide a way to cleanup the registry/service information for Windows).
---
opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java | 100 ++++++++++++++
opendj-sdk/opends/build-tools/src/windows/service.c | 216 ++++++++----------------------
opendj-sdk/opends/build-tools/src/windows/service.h | 2
opendj-sdk/opends/lib/opends_service.exe | 0
opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java | 60 ++++++++
5 files changed, 220 insertions(+), 158 deletions(-)
diff --git a/opendj-sdk/opends/build-tools/src/windows/service.c b/opendj-sdk/opends/build-tools/src/windows/service.c
index 2442c82..a22a88c 100644
--- a/opendj-sdk/opends/build-tools/src/windows/service.c
+++ b/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);
diff --git a/opendj-sdk/opends/build-tools/src/windows/service.h b/opendj-sdk/opends/build-tools/src/windows/service.h
index cc69bee..5971df2 100644
--- a/opendj-sdk/opends/build-tools/src/windows/service.h
+++ b/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);
diff --git a/opendj-sdk/opends/lib/opends_service.exe b/opendj-sdk/opends/lib/opends_service.exe
index 7a5a5b3..c89278d 100755
--- a/opendj-sdk/opends/lib/opends_service.exe
+++ b/opendj-sdk/opends/lib/opends_service.exe
Binary files differ
diff --git a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java b/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
index de101c5..997906c 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/messages/ToolMessages.java
+++ b/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.");
}
}
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java b/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java
index fd16026..72e243b 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java
+++ b/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.
--
Gitblit v1.10.0