From 08d62ab30082bc0feb209c8de443b8ec9a419dd6 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Wed, 18 Jul 2007 21:28:42 +0000
Subject: [PATCH] Fix for issue 1603 (quickInstall fails to register service on vista)

---
 opendj-sdk/opends/resource/uninstall.bat                                          |    2 
 opendj-sdk/opends/src/build-tools/windows/common.c                                |   12 
 opendj-sdk/opends/src/build-tools/windows/launcher_administrator.exe.manifest     |   16 +
 opendj-sdk/opends/resource/bin/start-ds.bat                                       |    4 
 opendj-sdk/opends/resource/bin/status-panel.bat                                   |    2 
 opendj-sdk/opends/src/build-tools/windows/Makefile                                |   20 +
 opendj-sdk/opends/lib/launcher_administrator.exe                                  |    0 
 opendj-sdk/opends/src/build-tools/windows/README                                  |   12 +
 opendj-sdk/opends/resource/setup.bat                                              |    2 
 opendj-sdk/opends/src/server/org/opends/server/tools/StartWindowsService.java     |   27 ++
 opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java |  153 +++++++++++++-
 opendj-sdk/opends/src/build-tools/windows/winlauncher.c                           |  130 +++++++++----
 opendj-sdk/opends/resource/bin/_client-script.bat                                 |    2 
 opendj-sdk/opends/src/build-tools/windows/opends_service.exe.manifest             |   16 +
 opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java               |   20 ++
 opendj-sdk/opends/lib/opends_service.exe                                          |    0 
 opendj-sdk/opends/src/build-tools/windows/service.c                               |  135 ++++++++-----
 opendj-sdk/opends/lib/winlauncher.exe                                             |    0 
 opendj-sdk/opends/src/server/org/opends/server/tools/StopWindowsService.java      |   27 ++
 19 files changed, 444 insertions(+), 136 deletions(-)

diff --git a/opendj-sdk/opends/lib/launcher_administrator.exe b/opendj-sdk/opends/lib/launcher_administrator.exe
new file mode 100644
index 0000000..7b1ba12
--- /dev/null
+++ b/opendj-sdk/opends/lib/launcher_administrator.exe
Binary files differ
diff --git a/opendj-sdk/opends/lib/opends_service.exe b/opendj-sdk/opends/lib/opends_service.exe
index 63cccd9..546161b 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/lib/winlauncher.exe b/opendj-sdk/opends/lib/winlauncher.exe
index 7e0fd52..5c836f0 100755
--- a/opendj-sdk/opends/lib/winlauncher.exe
+++ b/opendj-sdk/opends/lib/winlauncher.exe
Binary files differ
diff --git a/opendj-sdk/opends/resource/bin/_client-script.bat b/opendj-sdk/opends/resource/bin/_client-script.bat
index 88fe198..343eaeb 100644
--- a/opendj-sdk/opends/resource/bin/_client-script.bat
+++ b/opendj-sdk/opends/resource/bin/_client-script.bat
@@ -25,7 +25,7 @@
 rem
 rem      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 
-rem This script is used to invoke various server-side processes.  It should not
+rem This script is used to invoke various client-side processes.  It should not
 rem be invoked directly by end users.
 
 setlocal
diff --git a/opendj-sdk/opends/resource/bin/start-ds.bat b/opendj-sdk/opends/resource/bin/start-ds.bat
index cf2becc..c4e2efb 100644
--- a/opendj-sdk/opends/resource/bin/start-ds.bat
+++ b/opendj-sdk/opends/resource/bin/start-ds.bat
@@ -111,7 +111,7 @@
 goto end
 
 :runDetachCalledByWinService
-rem We write the output of the start command to the winwervice.out file.
+rem We write the output of the start command to the winservice.out file.
 echo %SCRIPT%: Run detach called by windows service  >> %LOG%
 if not exist "%DIR_HOME%\logs\server.out" echo. > "%DIR_HOME%\logs\server.out"
 if not exist "%DIR_HOME%\logs\server.starting" echo. > "%DIR_HOME%\logs\server.starting"
@@ -133,4 +133,4 @@
 if exist "%DIR_HOME%\logs\winservice.out" erase "%DIR_HOME%\logs\winservice.out"
 :end
 
-echo %SCRIPT%: finished >> %LOG%
\ No newline at end of file
+echo %SCRIPT%: finished >> %LOG%
diff --git a/opendj-sdk/opends/resource/bin/status-panel.bat b/opendj-sdk/opends/resource/bin/status-panel.bat
index a82ba38..952481d 100644
--- a/opendj-sdk/opends/resource/bin/status-panel.bat
+++ b/opendj-sdk/opends/resource/bin/status-panel.bat
@@ -57,7 +57,7 @@
 
 set PATH=%SystemRoot%
 
-"%DIR_HOME%\lib\winlauncher.exe" launch "%DIR_HOME%" "%JAVA_BIN%" %JAVA_ARGS%  org.opends.statuspanel.StatusPanelLauncher %*
+"%DIR_HOME%\lib\winlauncher.exe" launch "%JAVA_BIN%" %JAVA_ARGS%  org.opends.statuspanel.StatusPanelLauncher %*
 goto end
 
 
diff --git a/opendj-sdk/opends/resource/setup.bat b/opendj-sdk/opends/resource/setup.bat
index b5f48c9..1dec017 100644
--- a/opendj-sdk/opends/resource/setup.bat
+++ b/opendj-sdk/opends/resource/setup.bat
@@ -72,7 +72,7 @@
 goto callJava
 
 :callLaunch
-"%DIR_HOME%\lib\winlauncher.exe" launch "%DIR_HOME%" "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.InstallLauncher -P setup.bat
+"%DIR_HOME%\lib\winlauncher.exe" launch "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.InstallLauncher -P setup.bat
 goto end
 
 :callJava
diff --git a/opendj-sdk/opends/resource/uninstall.bat b/opendj-sdk/opends/resource/uninstall.bat
index 3429073..f7b2991 100644
--- a/opendj-sdk/opends/resource/uninstall.bat
+++ b/opendj-sdk/opends/resource/uninstall.bat
@@ -72,7 +72,7 @@
 goto callJava
 
 :callLaunch
-"%DIR_HOME%\lib\winlauncher.exe" launch "%DIR_HOME%" "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.uninstaller.UninstallLauncher
+"%DIR_HOME%\lib\winlauncher.exe" launch "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.uninstaller.UninstallLauncher
 goto end
 
 :callJava
diff --git a/opendj-sdk/opends/src/build-tools/windows/Makefile b/opendj-sdk/opends/src/build-tools/windows/Makefile
index 93fd9fa..caa92e1 100644
--- a/opendj-sdk/opends/src/build-tools/windows/Makefile
+++ b/opendj-sdk/opends/src/build-tools/windows/Makefile
@@ -44,13 +44,15 @@
 
 CC=cl
 SERVICE_PROGNAME=opends_service.exe
+LAUNCHER_ADMINISTRATOR_PROGNAME=launcher_administrator.exe
 WINLAUNCHER_PROGNAME=winlauncher.exe
-LINKER=link -nologo
+LINKER=link -nologo /machine:x86
 LIBS=advapi32.lib
 
-CFLAGS= -D_WINDOWS  -nologo -MD  -W3 -O2 -G6
+CFLAGS= -D_WINDOWS  -nologo  -W3 -O2
 RC=rc
 MC=mc
+MT=mt
 
 SRCS = common.c winlauncher.c service.c 
 
@@ -65,6 +67,9 @@
 
 RES_FILE = EventLogMsg.res
 
+SERVICE_MANIFEST_FILE = opends_service.exe.manifest
+LAUNCHER_ADMINISTRATOR_MANIFEST_FILE = launcher_administrator.exe.manifest
+
 .c.obj:
   $(CC) $(CFLAGS) -c $< -Fo$@
   
@@ -73,14 +78,19 @@
   $(RC) /fo $(RES_FILE) $(RC_FILE)
 
 
-all: $(SERVICE_PROGNAME) $(WINLAUNCHER_PROGNAME)
+all: $(SERVICE_PROGNAME) $(WINLAUNCHER_PROGNAME) $(LAUNCHER_ADMINISTRATOR_PROGNAME) 
 
 $(SERVICE_PROGNAME) : $(RES_FILE) $(SERVICE_OBJS)
   $(LINKER) /OUT:$(SERVICE_PROGNAME) $(RES_FILE) $(SERVICE_OBJS) $(LIBS)
-
+  $(MT) -manifest "$(SERVICE_MANIFEST_FILE)" -outputresource:"$(SERVICE_PROGNAME)";#1
+  
 $(WINLAUNCHER_PROGNAME) : $(WINLAUNCHER_OBJS)
   $(LINKER) $(WINLAUNCHER_OBJS) /OUT:$(WINLAUNCHER_PROGNAME)
 
+$(LAUNCHER_ADMINISTRATOR_PROGNAME) : $(WINLAUNCHER_OBJS)
+  $(LINKER) $(WINLAUNCHER_OBJS) /OUT:$(LAUNCHER_ADMINISTRATOR_PROGNAME)
+  $(MT) -manifest "$(LAUNCHER_ADMINISTRATOR_MANIFEST_FILE)" -outputresource:"$(LAUNCHER_ADMINISTRATOR_PROGNAME)";#1
+  
 clean:
-  del $(SERVICE_OBJS) $(EVENTLOG_H) $(WINLAUNCHER_OBJS) $(RC_FILE) $(RES_FILE) $(SERVICE_PROGNAME) $(WINLAUNCHER_PROGNAME) core
+  del $(SERVICE_OBJS) $(EVENTLOG_H) $(WINLAUNCHER_OBJS) $(RC_FILE) $(RES_FILE) $(SERVICE_PROGNAME) $(WINLAUNCHER_PROGNAME) $(LAUNCHER_ADMINISTRATOR_PROGNAME) core
 
diff --git a/opendj-sdk/opends/src/build-tools/windows/README b/opendj-sdk/opends/src/build-tools/windows/README
index 6a19ec2..e90f3a4 100644
--- a/opendj-sdk/opends/src/build-tools/windows/README
+++ b/opendj-sdk/opends/src/build-tools/windows/README
@@ -44,6 +44,16 @@
 
 See the comments in service.c file and common.c for more information.
 
+ WHAT is launcher_administrator.exe
+ ========================
+launcher_administrator.exe is a small windows executable that is intended to
+be used by the command line files to launch operations that require
+administrator privileges on Vista.  Basically is a wrapper containing a
+manifest that specifies to require administrator privileges to be run.  This
+is required if UAC is enabled on Vista so that we have a prompt for the user
+asking for confirmation.
+
+See the comments in winlauncher.c file and common.c for more information.
 
  INSTRUCTIONS TO COMPILE winlauncher.exe
  ========================
@@ -90,7 +100,7 @@
 This will generate the binary winlauncher.exe.
 
 
- INSTRUCTIONS TO COMPILE opends_service.exe
+ INSTRUCTIONS TO COMPILE opends_service.exe and administrator_launcher.exe
  ========================
 service.c (the main code file for opends_service.exe) uses windows resources and
 so 
diff --git a/opendj-sdk/opends/src/build-tools/windows/common.c b/opendj-sdk/opends/src/build-tools/windows/common.c
index daabef4..088360e 100644
--- a/opendj-sdk/opends/src/build-tools/windows/common.c
+++ b/opendj-sdk/opends/src/build-tools/windows/common.c
@@ -53,7 +53,8 @@
   STARTUPINFO startInfo; // info to pass to the new process
   DWORD processFlag; // background process flag
 
-  debug("Attempting to create child process '%s' background=%d.", command, background);
+  debug("Attempting to create child process '%s' background=%d.", command,
+      background);
 
   // reset process info first
   ZeroMemory(procInfo, sizeof(PROCESS_INFORMATION));
@@ -84,7 +85,8 @@
   }
   else
   {
-    debugError("Failed to create child process '%s'.  Last error = %d.", command, GetLastError());
+    debugError("Failed to create child process '%s'.  Last error = %d.",
+        command, GetLastError());
   }
   
   return createOk;
@@ -156,7 +158,8 @@
   {
     currentProcessPid = GetCurrentProcessId();
     noMessageLogged = FALSE;
-    debug("--------------- FIRST LOG MESSAGE FROM '%s' ---------------", _pgmptr);
+    debug("--------------- FIRST LOG MESSAGE FROM '%s' ---------------",
+        _pgmptr);
   }
 
   // Time-stamp
@@ -211,7 +214,8 @@
     MAX_PATH
     ); 
 
-  // Cut everything after the last slash, twice.  This will take us back to the instance root.
+  // Cut everything after the last slash, twice.  This will take us back to the
+  // instance root.
   // This logic assumes that we are in a directory above the instance root.
   lastSlash = strrchr(execName, '\\');
   lastSlash[0] = '\0';
diff --git a/opendj-sdk/opends/src/build-tools/windows/launcher_administrator.exe.manifest b/opendj-sdk/opends/src/build-tools/windows/launcher_administrator.exe.manifest
new file mode 100644
index 0000000..f0c7d11
--- /dev/null
+++ b/opendj-sdk/opends/src/build-tools/windows/launcher_administrator.exe.manifest
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
+  <assemblyIdentity version="1.0.0.0"
+     processorArchitecture="X86" name="launcher_administrator" type="win32"/> 
+  <description>Executable used to run code that requires administrator privileges</description> 
+  <!-- Identify the application security requirements. -->
+  <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
+    <ms_asmv2:security>
+      <ms_asmv2:requestedPrivileges>
+        <ms_asmv2:requestedExecutionLevel
+          level="requireAdministrator"
+          uiAccess="false"/>
+        </ms_asmv2:requestedPrivileges>
+       </ms_asmv2:security>
+  </ms_asmv2:trustInfo>
+</assembly>
diff --git a/opendj-sdk/opends/src/build-tools/windows/opends_service.exe.manifest b/opendj-sdk/opends/src/build-tools/windows/opends_service.exe.manifest
new file mode 100644
index 0000000..7db0633
--- /dev/null
+++ b/opendj-sdk/opends/src/build-tools/windows/opends_service.exe.manifest
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
+  <assemblyIdentity version="1.0.0.0"
+     processorArchitecture="X86" name="opends_service" type="win32"/> 
+  <description>Executable used to run OpenDS as a Windows Service</description> 
+  <!-- Identify the application security requirements. -->
+  <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
+    <ms_asmv2:security>
+      <ms_asmv2:requestedPrivileges>
+        <ms_asmv2:requestedExecutionLevel
+          level="asInvoker"
+          uiAccess="false"/>
+        </ms_asmv2:requestedPrivileges>
+       </ms_asmv2:security>
+  </ms_asmv2:trustInfo>
+</assembly>
\ No newline at end of file
diff --git a/opendj-sdk/opends/src/build-tools/windows/service.c b/opendj-sdk/opends/src/build-tools/windows/service.c
index 5152900..1e70851 100644
--- a/opendj-sdk/opends/src/build-tools/windows/service.c
+++ b/opendj-sdk/opends/src/build-tools/windows/service.c
@@ -72,7 +72,7 @@
   }
 
   debug("registerServiceHandler returning '%d'", returnValue);
-  
+
   return returnValue;
 }  // registerServiceHandler
 
@@ -147,7 +147,8 @@
   );
   if (scm == NULL)
   {
-    debugError("Failed to open the Service Control Manager.  Last error = %d", GetLastError());
+    debugError("Failed to open the Service Control Manager.  Last error = %d",
+        GetLastError());
     returnValue = SERVICE_RETURN_ERROR;
   }
   else
@@ -247,7 +248,8 @@
     );
     if (result != ERROR_SUCCESS)
     {
-      debugError("RegSetValueEx('EventMessageFile') failed, result=%d.", result);
+      debugError("RegSetValueEx('EventMessageFile') failed, result=%d.",
+          result);
       success = FALSE;
     }
   }
@@ -290,7 +292,8 @@
     );
     if (result != ERROR_SUCCESS)
     {
-      debugError("RegSetValueEx('CategoryMessageFile') failed, result=%d.", result);
+      debugError("RegSetValueEx('CategoryMessageFile') failed, result=%d.",
+          result);
       success = FALSE;
     }
   }
@@ -362,7 +365,8 @@
   );
   if (result != ERROR_SUCCESS)
   {
-    debug("The registry key for service '%s' does not exist, so we do not need to remove it.", serviceName);
+    debug("The registry key for service '%s' does not exist, so we do not need to remove it.",
+        serviceName);
     // Assume that the registry key does not exist.
     returnValue = TRUE;
   }
@@ -429,14 +433,15 @@
   char* relativePath = "\\locks\\server.lock";
   char lockFile[MAX_PATH];
   debug("Determining if the server is running.");
-  
+
   if (strlen(relativePath)+strlen(_instanceDir)+1 < MAX_PATH)
   {
     int fd;
 
     sprintf(lockFile, "%s%s", _instanceDir, relativePath);
-    debug("When determining whether the server is running, the lock file name is '%s'.", lockFile);
-  
+    debug("When determining whether the server is running, the lock file name is '%s'.",
+        lockFile);
+
     fd = _open(lockFile, _O_RDWR);
 
     if (fd != -1)
@@ -469,7 +474,8 @@
     }
     else
     {
-      debug("Could not open lock file '%s', which means the server is not running.", lockFile);
+      debug("Could not open lock file '%s', which means the server is not running.",
+          lockFile);
       *running = FALSE;
       returnValue = SERVICE_RETURN_ERROR;
     }
@@ -499,7 +505,7 @@
 
   debug("doStartApplication called.");
 
-  
+
   if (strlen(relativePath)+strlen(_instanceDir)+1 < COMMAND_SIZE)
   {
     sprintf(command, "\"%s%s\" --windowsNetStart", _instanceDir, relativePath);
@@ -511,8 +517,10 @@
       // Try to see if server is really running
       int nTries = 10;
       BOOL running = FALSE;
-      
-      debug("doStartApplication: the spawn of the process worked.  Command: '%s'", command);
+
+      debug(
+          "doStartApplication: the spawn of the process worked.  Command: '%s'",
+          command);
       // Wait to be able to launch the java process in order it to free the lock
       // on the file.
       debug("Sleeping for 3 seconds to allow the process to free the lock.");
@@ -526,7 +534,8 @@
         }
         if (!running)
         {
-          debug("Sleeping for 2 seconds to allow the process to free the lock.  %d tries remaining.", nTries);
+          debug("Sleeping for 2 seconds to allow the process to free the lock.  %d tries remaining.",
+              nTries);
           Sleep(2000);
         }
       }
@@ -543,7 +552,7 @@
     }
     else
     {
-      
+
       returnValue = SERVICE_RETURN_ERROR;
       debug("doStartApplication: spawn failed.  Sent command: '%s'", command);
     }
@@ -577,9 +586,9 @@
       // Try to see if server is really stopped
       int nTries = 10;
       BOOL running = TRUE;
-      
+
       debug("doStopApplication: the spawn of the process worked.");
-      
+
       // Wait to be able to launch the java process in order it to free the lock
       // on the file.
       Sleep(3000);
@@ -625,7 +634,7 @@
 // serviceBinPath  the path to the service binary.
 // instanceDir the instanceDirectory.
 // The string stored in serviceBinPath looks like
-// <SERVER_ROOT>/lib/service.exe start <_instanceDir>
+// <SERVER_ROOT>/lib/opends_service.exe start <_instanceDir>
 // It is up to the caller of the function to allocate
 // at least COMMAND_SIZE bytes in serviceBinPath.
 // The function returns SERVICE_RETURN_OK if we could create the binary
@@ -652,7 +661,9 @@
   }
   else
   {
-    debug("When determining the service bin path, the module file name is '%s'.", fileName);
+    debug(
+        "When determining the service bin path, the module file name is '%s'.",
+        fileName);
 
     if (result == MAX_PATH)
     {
@@ -662,15 +673,16 @@
     }
     else
     {
-      if ((strlen(fileName) + strlen(" start ") + strlen(_instanceDir) + 2 * strlen("\"\""))
-        < COMMAND_SIZE)
+      if ((strlen(fileName) + strlen(" start ") + strlen(_instanceDir) +
+          2 * strlen("\"\"")) < COMMAND_SIZE)
       {
         sprintf(serviceBinPath, "\"%s\" start \"%s\"", fileName,
         _instanceDir);
       }
       else
       {
-        char * msg = "The name of the resulting windows service command is too long.\n";
+        char * msg =
+          "The name of the resulting windows service command is too long.\n";
         debug(msg);
         // buffer was too small, executable name is probably not valid
         returnValue = SERVICE_RETURN_ERROR;
@@ -704,7 +716,8 @@
 
   strcpy(serviceName, "");
 
-  debug("Attempting to get the service name assuming command to run is '%s'.", cmdToRun);
+  debug("Attempting to get the service name assuming command to run is '%s'.",
+      cmdToRun);
 
   returnValue = getServiceList(&serviceList, &nbServices);
 
@@ -733,7 +746,8 @@
             }
             else
             {
-              debug("The service name found is too long: '%s'", curService.serviceName);
+              debug("The service name found is too long: '%s'",
+                  curService.serviceName);
             }
             break;
           }
@@ -748,7 +762,7 @@
   }
 
   debug("The service name was found to be '%s'.", serviceName);
-  
+
   return returnValue;
 
 }  // getServiceName
@@ -801,7 +815,7 @@
   debug("Updating the service status.  statusToSet=%d win32ExitCode=%d serviceExitCode=%d checkPoint=%d waitHint=%d",
         statusToSet, win32ExitCode, serviceExitCode,
         checkPoint, waitHint);
-  
+
   if (statusToSet == SERVICE_START_PENDING)
   {
     debug("Service start pending.");
@@ -835,7 +849,8 @@
 
   if (!success)
   {
-    debugError("Failed to set the service status.  Last error = %d.", GetLastError());
+    debugError("Failed to set the service status.  Last error = %d.",
+        GetLastError());
     returnValue = SERVICE_RETURN_ERROR;
   }
   else
@@ -872,7 +887,7 @@
   // __debugbreak();
 
   debug("serviceMain called.");
-  
+
   code = createServiceBinPath(cmdToRun);
 
   if (code == SERVICE_RETURN_OK)
@@ -1170,8 +1185,8 @@
 //
 // scm is the SCM handler (must not be NULL)
 // serviceName  the name of the service.
-// It is up to the caller of the function to allocate at least COMMAND_SIZE bytes
-// in binPathName.
+// It is up to the caller of the function to allocate at least COMMAND_SIZE
+// bytes in binPathName.
 // The function returns SERVICE_RETURN_OK if we could create the binary
 // path name and SERVICE_RETURN_ERROR otherwise.
 // ---------------------------------------------------------------
@@ -1232,7 +1247,8 @@
         }
         else
         {
-          debug("getBinaryPath: error calling QueryServiceConfig. Code [%d]", errCode);
+          debug("getBinaryPath: error calling QueryServiceConfig. Code [%d]",
+              errCode);
           break;
         }
       }
@@ -1245,7 +1261,8 @@
         }
         else
         {
-          debug("getBinaryPath: the length of the binary path name is too big. serviceName='%s', binaryPath='%s'", serviceName, serviceConfig->lpBinaryPathName);
+          debug("getBinaryPath: the length of the binary path name is too big. serviceName='%s', binaryPath='%s'",
+              serviceName, serviceConfig->lpBinaryPathName);
         }
       }
     }
@@ -1330,7 +1347,8 @@
           if (lastError != ERROR_MORE_DATA)
           {
             returnValue = SERVICE_RETURN_ERROR;
-            debug("getServiceList: second try generic error. Code [%d]", lastError);
+            debug("getServiceList: second try generic error. Code [%d]",
+                lastError);
           }
           else
           {
@@ -1384,7 +1402,8 @@
         }
         else
         {
-          debug("Error getting binary path name of service: %s", l[i].serviceName);
+          debug("Error getting binary path name of service: %s",
+              l[i].serviceName);
         }
         curService++;
       }
@@ -1425,7 +1444,7 @@
   int i;
 
   debug("Determining if service name '%s' is in use.", serviceName);
-  
+
   // go through the list of services and search for the service name
   if (getServiceList(&serviceList, &nbServices) == SERVICE_RETURN_OK)
   {
@@ -1456,7 +1475,8 @@
   }
   else
   {
-    debugError("Could not determine if the service name '%s' is in use because listing the services failed.", serviceName);
+    debugError("Could not determine if the service name '%s' is in use because listing the services failed.",
+        serviceName);
     returnValue = SERVICE_RETURN_ERROR;
   }
   return returnValue;
@@ -1513,7 +1533,7 @@
   }
 
   debug("createServiceName returning serviceName='%s' and returnValue=%d",
-        serviceName, returnValue);  
+        serviceName, returnValue);
 
   return returnValue;
 } // createServiceName
@@ -1547,7 +1567,7 @@
   // create the service
   if (returnValue == SERVICE_RETURN_OK)
   {
-    if (openScm(GENERIC_WRITE, &scm) != SERVICE_RETURN_OK)
+    if (openScm(SC_MANAGER_ALL_ACCESS, &scm) != SERVICE_RETURN_OK)
     {
       returnValue = SERVICE_RETURN_ERROR;
       debug("createServiceInScm: openScm did not work.");
@@ -1583,7 +1603,8 @@
   if ((returnValue == SERVICE_RETURN_OK) && (myService == NULL))
   {
     DWORD errCode = GetLastError();
-    debugError("Failed to create the service '%s'.  Last error = %d.", serviceName, errCode);
+    debugError("Failed to create the service '%s'.  Last error = %d.",
+        serviceName, errCode);
     if (errCode == ERROR_DUPLICATE_SERVICE_NAME)
     {
       returnValue = DUPLICATED_SERVICE_NAME;
@@ -1594,6 +1615,10 @@
     }
     else
     {
+      if (errCode == ERROR_INVALID_HANDLE)
+      {
+        debugError("The handle seems to be invalid.");
+      }
       returnValue = SERVICE_RETURN_ERROR;
     }
   }
@@ -1612,7 +1637,9 @@
 
     if (!success)
     {
-      debugError("Failed to add a description to the service '%s'.  Last error = %d.", serviceName, GetLastError());
+      debugError(
+          "Failed to add a description to the service '%s'.  Last error = %d.",
+          serviceName, GetLastError());
       returnValue = SERVICE_RETURN_ERROR;
     }
   }
@@ -1635,7 +1662,7 @@
   }
 
   debug("createServiceInScm returning %d.", returnValue);
-        
+
   return returnValue;
 } // createServiceInScm
 
@@ -1656,7 +1683,7 @@
   SERVICE_STATUS serviceStatus;
 
   debug("Removing service '%s' from the Service Control Manager.", serviceName);
-  
+
   returnValue = openScm(GENERIC_WRITE, &scm);
 
   // open the service
@@ -1671,7 +1698,8 @@
     debug("After opening service myService=%d.", myService);
     if (myService == NULL)
     {
-      debugError("Failed to open the service '%s'. Last error = %d", serviceName, GetLastError());
+      debugError("Failed to open the service '%s'. Last error = %d",
+          serviceName, GetLastError());
       returnValue = SERVICE_RETURN_ERROR;
     }
   }
@@ -1686,7 +1714,8 @@
     );
     if (!success)
     {
-      debugError("Failed to query the status for service '%s'. Last error = %d", serviceName, GetLastError());
+      debugError("Failed to query the status for service '%s'. Last error = %d",
+          serviceName, GetLastError());
       returnValue = SERVICE_RETURN_ERROR;
     }
   }
@@ -1707,7 +1736,8 @@
       if (!success)
       {
         DWORD errCode = GetLastError();
-        debugError("Failed to stop the service '%s'.  Last error = %d.", serviceName, errCode);
+        debugError("Failed to stop the service '%s'.  Last error = %d.",
+            serviceName, errCode);
         if (errCode == ERROR_SERVICE_MARKED_FOR_DELETE)
         {
           returnValue = SERVICE_MARKED_FOR_DELETION;
@@ -1733,7 +1763,8 @@
     if (!success)
     {
       DWORD errCode = GetLastError();
-      debugError("Failed to delete the service '%s'.  Last error = %d.", serviceName, errCode);
+      debugError("Failed to delete the service '%s'.  Last error = %d.",
+          serviceName, errCode);
       if (errCode == ERROR_SERVICE_MARKED_FOR_DELETE)
       {
         returnValue = SERVICE_MARKED_FOR_DELETION;
@@ -1778,7 +1809,8 @@
   char cmdToRun[COMMAND_SIZE];
   ServiceReturnCode code;
 
-  debug("Creating service displayName='%s' description='%s'.", displayName, description);
+  debug("Creating service displayName='%s' description='%s'.", displayName,
+      description);
   code = createServiceBinPath(cmdToRun);
 
   if (code == SERVICE_RETURN_OK)
@@ -1858,12 +1890,13 @@
   strcpy(serviceName, "");
   debug("Getting service state.");
   code = createServiceBinPath(cmdToRun);
-  debug("Created the service bin path. code=%d.  cmdToRun='%s'.", code, cmdToRun);
+  debug("Created the service bin path. code=%d.  cmdToRun='%s'.", code,
+      cmdToRun);
 
   if (code == SERVICE_RETURN_OK)
   {
     code = getServiceName(cmdToRun, serviceName);
-    
+
     if (code == SERVICE_RETURN_OK)
     {
       // There is a valid serviceName for the command to run, so
@@ -1875,7 +1908,7 @@
     else
     {
       returnCode = 1;
-      debug("Service '%s' is disabled enabled.", serviceName);
+      debug("Service '%s' is disabled.", serviceName);
     }
   }
   else
@@ -2072,7 +2105,7 @@
   char* subcommand;
   int returnCode = 0;
   int i;
-  
+
   updateDebugFlag(argv, argc);
 
   debug("main called.");
@@ -2201,7 +2234,7 @@
   }
 
   debug("main returning %d.", returnCode);
-    
+
   return returnCode;
 } // main
 
diff --git a/opendj-sdk/opends/src/build-tools/windows/winlauncher.c b/opendj-sdk/opends/src/build-tools/windows/winlauncher.c
index 2f446e7..2fb58a8 100644
--- a/opendj-sdk/opends/src/build-tools/windows/winlauncher.c
+++ b/opendj-sdk/opends/src/build-tools/windows/winlauncher.c
@@ -63,7 +63,7 @@
 {
   struct stat finfo;
   BOOL returnValue = FALSE;
-  
+
   if(stat(fileName, &finfo) < 0)
   {
     returnValue = FALSE;
@@ -89,7 +89,7 @@
   BOOL returnValue = FALSE;
   char pidFile[PATH_SIZE];
   int nTries = 10;
-  
+
   debug("Attempting to delete the PID file from instanceDir='%s'.", instanceDir);
   // Sometimes the lock on the system in windows takes time to be released.
   if (getPidFile(instanceDir, pidFile, PATH_SIZE))
@@ -110,7 +110,7 @@
       }
     }
   }
-  
+
   debug("deletePidFile('%s') returning %d.", instanceDir, returnValue);
   return returnValue;
 }  // deletePidFile
@@ -128,7 +128,7 @@
   FILE *f;
   char buf[BUF_SIZE];
   int read;
-  
+
   debug("Attempting to get the PID for the server rooted at '%s'.", instanceDir);
   if (getPidFile(instanceDir, pidFile, PATH_SIZE))
   {
@@ -137,7 +137,7 @@
       read = fread(buf, 1, sizeof(buf),f);
       debug("Read '%s' from the PID file '%s'.", buf, pidFile);
     }
-    
+
     if (f != NULL)
     {
       fclose(f);
@@ -179,7 +179,7 @@
   FALSE,                          // handle is not inheritable
   pid
   );
-  
+
   if (procHandle == NULL)
   {
     debug("The process with pid=%d has already terminated.", pid);
@@ -201,7 +201,7 @@
 
       debug("Successfully began termination process for (pid=%d).", pid);
       // wait for the process to end.
-      
+
       processDead = FALSE;
       while ((nTries > 0) && !processDead)
       {
@@ -234,11 +234,11 @@
 // otherwise.
 // ----------------------------------------------------
 BOOL createPidFile(const char* instanceDir, int pid)
-{ 
+{
   BOOL returnValue = FALSE;
   char pidFile[PATH_SIZE];
   FILE *f;
-  
+
   debug("createPidFile(instanceDir='%s',pid=%d)", instanceDir, pid);
 
   if (getPidFile(instanceDir, pidFile, PATH_SIZE))
@@ -261,7 +261,7 @@
     debugError("Couldn't create the pid file because the pid file name could not be constructed.");
     returnValue = FALSE;
   }
-  
+
   return returnValue;
 }  // createPidFile
 
@@ -281,11 +281,11 @@
   BOOL overflow = FALSE;
 
   debug("Constructing full command line from arguments:");
-  for (i = 0; (argv[i] != NULL); i++) 
+  for (i = 0; (argv[i] != NULL); i++)
   {
     debug(" argv[%d]: %s", i, argv[i]);
   }
-  
+
   i = 0;
   while ((argv[i] != NULL) && !overflow)
   {
@@ -302,11 +302,11 @@
         overflow = TRUE;
       }
     }
-    
+
     if (curarg[0] != '\0')
     {
       int argInd = 0;
-      
+
       if (curarg[0] == '"')
       {
         // there is a quote: no need to add extra quotes
@@ -346,7 +346,7 @@
           overflow = TRUE;
         }
       }
-      
+
     } else {
       if (curCmdInd + strlen("\"\"") < maxSize)
       {
@@ -360,15 +360,15 @@
     }
   }
 
-  if (overflow) 
+  if (overflow)
   {
     debugError("Failed to construct the full commandline because the buffer wasn't big enough.");
-  } 
-  else 
+  }
+  else
   {
     debug("The full commandline is '%s'.", command);
   }
-  
+
   return !overflow;
 } // getCommandLine
 
@@ -397,13 +397,13 @@
 {
   int returnValue;
   int childPid;
-  
+
   char command[COMMAND_SIZE];
 
   if (getCommandLine(argv, command, COMMAND_SIZE))
   {
     childPid = spawn(command, TRUE);
-    
+
     if (childPid > 0)
     {
       createPidFile(instanceDir, childPid);
@@ -420,7 +420,7 @@
     debugError("Couldn't start the child process because the full command line could not be constructed.");
     returnValue = -1;
   }
-  
+
   return returnValue;
 } // start
 
@@ -449,13 +449,13 @@
 int stop(const char* instanceDir)
 {
   int returnCode = -1;
-  
+
   int childPid;
-  
+
   debug("Attempting to stop the server running at root '%s'.", instanceDir);
 
   childPid = getPid(instanceDir);
-  
+
   if (childPid != 0)
   {
     if (killProcess(childPid))
@@ -464,7 +464,7 @@
       deletePidFile(instanceDir);
     }
   }
-  else 
+  else
   {
     debug("Could not stop the server running at root '%s' because the pid could not be located.", instanceDir);
   }
@@ -485,7 +485,7 @@
 // prompt-window associated with it.
 // Launch batch files from the prompt that generate a java process that does not
 // block the prompt and that keeps running even if the prompt window is closed.
-// 
+//
 // This function expects the following parameter to be passed:
 // the directory of the server we want to start and the
 // command line that we want to execute (basically the java
@@ -495,19 +495,19 @@
 // 2. Allow the administrator some flexibility in the way the
 // server is started by leaving most of the logic in the command-line.
 //
-// Returns the pid of the process associated with the command if it could be 
+// Returns the pid of the process associated with the command if it could be
 // launched and -1 otherwise.
 // ----------------------------------------------------
 int launch(char* argv[])
 {
   int returnValue;
-  
+
   char command[COMMAND_SIZE];
-  
+
   if (getCommandLine(argv, command, COMMAND_SIZE))
   {
     returnValue = spawn(command, TRUE);
-    if (returnValue <= 0) 
+    if (returnValue <= 0)
     {
       debugError("Failed to launch the child process '%s'.", command);
     }
@@ -521,18 +521,60 @@
     debugError("Couldn't launch the child process because the full command line could not be constructed.");
     returnValue = -1;
   }
-  
+
   return returnValue;
 } // launch
 
+//----------------------------------------------------
+// Function called when we want to launch a process and it to be run as
+// administrator on Vista (the binary containing this function must have
+// a manifest specifying that).
+// Returns the exit code of the process associated with the command if it
+// could be launched and -1 otherwise.
+//----------------------------------------------------
+int run(char* argv[])
+{
+  PROCESS_INFORMATION procInfo; // info on the new process
+  BOOL createOk;
+  DWORD exitCode;
+  int returnValue = -1;
+  int millisToWait = 30000;
+  int waitedMillis = 0;
+
+  char command[COMMAND_SIZE];
+
+  if (getCommandLine(argv, command, COMMAND_SIZE))
+  {
+    createOk = createChildProcess((char*)command, TRUE, &procInfo);
+
+    if(createOk)
+    {
+      GetExitCodeProcess(procInfo.hProcess, &exitCode);
+      while (exitCode == STILL_ACTIVE)
+      {
+        GetExitCodeProcess(procInfo.hProcess, &exitCode);
+        Sleep(500);
+        waitedMillis += 500;
+        if (waitedMillis > millisToWait)
+        {
+          break;
+        }
+      }
+      returnValue = exitCode;
+    }
+  }
+  return returnValue;
+} // run
+
 // ----------------------------------------------------
 // main function called by the executable.  This code is
 // called by the start-ds.bat, stop-ds.bat and statuspanel.bat batch files.
 //
 // The code assumes that the first passed argument is the subcommand to be
-// executed and the second argument the directory of the server.  The rest
-// of the arguments are the arguments specific to each subcommand (see the
-// comments for the functions start, stop and launch).
+// executed and for start and stop the second argument the directory of the
+// server.
+// The rest of the arguments are the arguments specific to each subcommand (see
+// the comments for the functions start, stop and launch).
 // ----------------------------------------------------
 int main(int argc, char* argv[])
 {
@@ -540,36 +582,44 @@
   char* subcommand = NULL;
   char* instanceDir = NULL;
   int i;
-  
+
   debug("main called.");
   for (i = 0; i < argc; i++) {
     debug("  argv[%d] = '%s'", i, argv[i]);
   }
 
   if (argc < 3) {
-    char * msg = "Expected command line args of [subcommand] [server directory], but got %d arguments.\n";
+    char * msg =
+      "Expected command line args of [subcommand], but got %d arguments.\n";
     debugError(msg, argc - 1);
     fprintf(stderr, msg, argc - 1);
 	  return -1;
   }
 
   subcommand = argv[1];
-  instanceDir = argv[2];
 
-  argv += 3;
-  
   if (strcmp(subcommand, "start") == 0)
   {
+    instanceDir = argv[2];
+    argv += 3;
     returnCode = start(instanceDir, argv);
   }
   else if (strcmp(subcommand, "stop") == 0)
   {
+    instanceDir = argv[2];
+    argv += 3;
     returnCode = stop(instanceDir);
   }
   else if (strcmp(subcommand, "launch") == 0)
   {
+    argv += 2;
     returnCode = launch(argv);
   }
+  else if (strcmp(subcommand, "run") == 0)
+  {
+    argv += 2;
+    returnCode = run(argv);
+  }
   else
   {
     char * msg = "Unknown subcommand: [%s]\n";
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 b77c1d5..ef389f6 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
@@ -36,6 +36,7 @@
 
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.NullOutputStream;
+import org.opends.server.util.SetupUtils;
 import org.opends.server.util.args.ArgumentException;
 import org.opends.server.util.args.ArgumentParser;
 import org.opends.server.util.args.BooleanArgument;
@@ -52,6 +53,22 @@
   * 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.
+  *
+  * Some comments about Vista:
+  * In Vista, when we launch the subcommands that require administrator
+  * privileges (enable, disable and cleanup) we cannot use the administrator
+  * launcher binary directly from Java (see
+  * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6410605) so we use
+  * winlauncher.exe.
+  * When we launch subcommands that required administrator privileges
+  * we must launch a binary containing the manifest that specifies that we
+  * require administrator privileges (requireAdministrator value): if UAC is
+  * enabled, the user will be asked for confirmation.
+  * To minimize the number of confirmation that the user must provide when
+  * launching the state subcommand we will use a binary whose manifest does
+  * not contain the requireAdministrator value.
+  *
+  * See the files under src/build-tools/windows for more details.
   */
 public class ConfigureWindowsService
 {
@@ -62,6 +79,10 @@
     "org.opends.server.tools.ConfigureWindowsService";
 
   private static final String DEBUG_OPTION = "--debug";
+  /**
+   * Option to be used when calling the launchers.
+   */
+  public static final String LAUNCHER_OPTION = "run";
 
   private static int ERROR = 1;
 
@@ -333,7 +354,7 @@
         getBinaryFullPath(),
         "state",
         serverRoot
-        };
+    };
     try
     {
       Process p = Runtime.getRuntime().exec(cmd);
@@ -385,14 +406,35 @@
     String msg;
     String serverRoot = getServerRoot();
 
-    String[] cmd = {
-        getBinaryFullPath(),
-        "create",
-        serverRoot,
-        getMessage(MSGID_WINDOWS_SERVICE_NAME, (Object[]) null),
-        getMessage(MSGID_WINDOWS_SERVICE_DESCRIPTION, serverRoot),
-        DEBUG_OPTION
-        };
+    String[] cmd;
+
+    if (isVista())
+    {
+      cmd = new String[] {
+          getLauncherBinaryFullPath(),
+          LAUNCHER_OPTION,
+          getLauncherAdministratorBinaryFullPath(),
+          LAUNCHER_OPTION,
+          getBinaryFullPath(),
+          "create",
+          serverRoot,
+          getMessage(MSGID_WINDOWS_SERVICE_NAME, (Object[]) null),
+          getMessage(MSGID_WINDOWS_SERVICE_DESCRIPTION, serverRoot),
+          DEBUG_OPTION
+      };
+    }
+    else
+    {
+      cmd = new String[] {
+          getBinaryFullPath(),
+          "create",
+          serverRoot,
+          getMessage(MSGID_WINDOWS_SERVICE_NAME, (Object[]) null),
+          getMessage(MSGID_WINDOWS_SERVICE_DESCRIPTION, serverRoot),
+          DEBUG_OPTION
+      };
+    }
+
     try
     {
       int resultCode = Runtime.getRuntime().exec(cmd).waitFor();
@@ -456,12 +498,29 @@
     int returnValue;
     String msg;
     String serverRoot = getServerRoot();
-    String[] cmd = {
+    String[] cmd;
+    if (isVista())
+    {
+      cmd = new String[] {
+          getLauncherBinaryFullPath(),
+          LAUNCHER_OPTION,
+          getLauncherAdministratorBinaryFullPath(),
+          LAUNCHER_OPTION,
+          getBinaryFullPath(),
+          "remove",
+          serverRoot,
+          DEBUG_OPTION
+      };
+    }
+    else
+    {
+      cmd = new String[] {
         getBinaryFullPath(),
         "remove",
         serverRoot,
         DEBUG_OPTION
         };
+    }
     try
     {
       int resultCode = Runtime.getRuntime().exec(cmd).waitFor();
@@ -525,12 +584,29 @@
   {
     int returnValue;
     String msg;
-    String[] cmd = {
-        getBinaryFullPath(),
-        "cleanup",
-        serviceName,
-        DEBUG_OPTION
-        };
+    String[] cmd;
+    if (isVista())
+    {
+      cmd = new String[] {
+          getLauncherBinaryFullPath(),
+          LAUNCHER_OPTION,
+          getLauncherAdministratorBinaryFullPath(),
+          LAUNCHER_OPTION,
+          getBinaryFullPath(),
+          "cleanup",
+          serviceName,
+          DEBUG_OPTION
+      };
+    }
+    else
+    {
+      cmd = new String[] {
+          getBinaryFullPath(),
+          "cleanup",
+          serviceName,
+          DEBUG_OPTION
+      };
+    }
     try
     {
       int resultCode = Runtime.getRuntime().exec(cmd).waitFor();
@@ -588,12 +664,13 @@
     String serviceName = null;
 
     String serverRoot = getServerRoot();
-    String[] cmd = {
+    String[] cmd = new String[] {
         getBinaryFullPath(),
         "state",
         serverRoot,
         DEBUG_OPTION
-        };
+    };
+
     try
     {
       int resultCode = -1;
@@ -711,7 +788,8 @@
 
   /**
    * Returns the full path of the executable used by this class to perform
-   * operations related to the service.
+   * operations related to the service.  This binaries file has the asInvoker
+   * value in its manifest.
    * @return the full path of the executable used by this class to perform
    * operations related to the service.
    */
@@ -719,4 +797,41 @@
   {
     return getServerRoot()+"\\lib\\opends_service.exe";
   }
+
+  /**
+   * Returns the full path of the executable that has a manifest requiring
+   * administrator privileges used by this class to perform
+   * operations related to the service.
+   * @return the full path of the executable that has a manifest requiring
+   * administrator privileges used by this class to perform
+   * operations related to the service.
+   */
+  public static String getLauncherAdministratorBinaryFullPath()
+  {
+    return getServerRoot()+"\\lib\\launcher_administrator.exe";
+  }
+
+  /**
+   * Returns the full path of the executable that has a manifest requiring
+   * administrator privileges used by this class to perform
+   * operations related to the service.
+   * @return the full path of the executable that has a manifest requiring
+   * administrator privileges used by this class to perform
+   * operations related to the service.
+   */
+  public static String getLauncherBinaryFullPath()
+  {
+    return getServerRoot()+"\\lib\\winlauncher.exe";
+  }
+
+  /**
+   * Indicates whether the underlying operating system is Windows Vista.
+   *
+   * @return  {@code true} if the underlying operating system is Windows
+   *          Vista, or {@code false} if not.
+   */
+  private static boolean isVista()
+  {
+    return SetupUtils.isVista();
+  }
 }
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/StartWindowsService.java b/opendj-sdk/opends/src/server/org/opends/server/tools/StartWindowsService.java
index 1c3d340..cb005eb 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/StartWindowsService.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/StartWindowsService.java
@@ -31,6 +31,7 @@
 import java.io.PrintStream;
 
 import org.opends.server.types.NullOutputStream;
+import org.opends.server.util.SetupUtils;
 
 import static org.opends.server.messages.MessageHandler.getMessage;
 import static org.opends.server.messages.ToolMessages.*;
@@ -113,11 +114,27 @@
     }
     else
     {
-      String[] cmd = {
-          "net",
-          "start",
-          serviceName
-          };
+      String[] cmd;
+      if (SetupUtils.isVista())
+      {
+        cmd= new String[] {
+            ConfigureWindowsService.getLauncherBinaryFullPath(),
+            ConfigureWindowsService.LAUNCHER_OPTION,
+            ConfigureWindowsService.getLauncherAdministratorBinaryFullPath(),
+            ConfigureWindowsService.LAUNCHER_OPTION,
+            "net",
+            "start",
+            serviceName
+        };
+      }
+      else
+      {
+        cmd= new String[] {
+            "net",
+            "start",
+            serviceName
+        };
+      }
       /* Check if is a running service */
       try
       {
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/StopWindowsService.java b/opendj-sdk/opends/src/server/org/opends/server/tools/StopWindowsService.java
index 9a57f90..257722f 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/StopWindowsService.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/StopWindowsService.java
@@ -31,6 +31,7 @@
 import java.io.PrintStream;
 
 import org.opends.server.types.NullOutputStream;
+import org.opends.server.util.SetupUtils;
 
 import static org.opends.server.messages.MessageHandler.getMessage;
 import static org.opends.server.messages.ToolMessages.*;
@@ -117,11 +118,27 @@
     }
     else
     {
-      String[] cmd = {
-          "net",
-          "stop",
-          serviceName
-          };
+      String[] cmd;
+      if (SetupUtils.isVista())
+      {
+        cmd= new String[] {
+            ConfigureWindowsService.getLauncherBinaryFullPath(),
+            ConfigureWindowsService.LAUNCHER_OPTION,
+            ConfigureWindowsService.getLauncherAdministratorBinaryFullPath(),
+            ConfigureWindowsService.LAUNCHER_OPTION,
+            "net",
+            "stop",
+            serviceName
+        };
+      }
+      else
+      {
+        cmd= new String[] {
+            "net",
+            "stop",
+            serviceName
+        };
+      }
       /* Check if is a running service */
       try
       {
diff --git a/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java b/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java
index 20e779e..544d922 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/util/SetupUtils.java
@@ -154,6 +154,26 @@
   }
 
   /**
+   * Indicates whether the underlying operating system is Windows Vista.
+   *
+   * @return  {@code true} if the underlying operating system is Windows
+   *          Vista, or {@code false} if not.
+   */
+  public static boolean isVista()
+  {
+    boolean isVista;
+    String os = System.getProperty("os.name");
+    if (os != null)
+    {
+     isVista = isWindows() && (os.toLowerCase().indexOf("vista") != -1);
+    }
+    else
+    {
+      isVista = false;
+    }
+    return isVista;
+  }
+  /**
    * Returns a String representation of the OS we are running.
    * @return a String representation of the OS we are running.
    */

--
Gitblit v1.10.0