diff --git a/app/services/resources/classes/lib_win.php b/app/services/resources/classes/lib_win.php
new file mode 100644
index 0000000000..6368893376
--- /dev/null
+++ b/app/services/resources/classes/lib_win.php
@@ -0,0 +1,227 @@
+'CONTINUE_PENDING',
+ WIN32_SERVICE_PAUSE_PENDING =>'PAUSE_PENDING',
+ WIN32_SERVICE_PAUSED =>'PAUSED',
+ WIN32_SERVICE_RUNNING =>'RUNNING',
+ WIN32_SERVICE_START_PENDING =>'START_PENDING',
+ WIN32_SERVICE_STOP_PENDING =>'STOP_PENDING',
+ WIN32_SERVICE_STOPPED =>'STOPPED',
+ );
+
+ private static $win_error = array(
+ WIN32_NO_ERROR => 'NO_ERROR',
+ WIN32_ERROR_ACCESS_DENIED => 'ACCESS_DENIED',
+ WIN32_ERROR_CIRCULAR_DEPENDENCY => 'CIRCULAR_DEPENDENCY',
+ WIN32_ERROR_DATABASE_DOES_NOT_EXIST => 'DATABASE_DOES_NOT_EXIST',
+ WIN32_ERROR_DEPENDENT_SERVICES_RUNNING => 'DEPENDENT_SERVICES_RUNNING',
+ WIN32_ERROR_DUPLICATE_SERVICE_NAME => 'DUPLICATE_SERVICE_NAME',
+ WIN32_ERROR_FAILED_SERVICE_CONTROLLER_CONNECT => 'FAILED_SERVICE_CONTROLLER_CONNECT',
+ WIN32_ERROR_INSUFFICIENT_BUFFER => 'INSUFFICIENT_BUFFER',
+ WIN32_ERROR_INVALID_DATA => 'INVALID_DATA',
+ WIN32_ERROR_INVALID_HANDLE => 'INVALID_HANDLE',
+ WIN32_ERROR_INVALID_LEVEL => 'INVALID_LEVEL',
+ WIN32_ERROR_INVALID_NAME => 'INVALID_NAME',
+ WIN32_ERROR_INVALID_PARAMETER => 'INVALID_PARAMETER',
+ WIN32_ERROR_INVALID_SERVICE_ACCOUNT => 'INVALID_SERVICE_ACCOUNT',
+ WIN32_ERROR_INVALID_SERVICE_CONTROL => 'INVALID_SERVICE_CONTROL',
+ WIN32_ERROR_PATH_NOT_FOUND => 'PATH_NOT_FOUND',
+ WIN32_ERROR_SERVICE_ALREADY_RUNNING => 'SERVICE_ALREADY_RUNNING',
+ WIN32_ERROR_SERVICE_CANNOT_ACCEPT_CTRL => 'SERVICE_CANNOT_ACCEPT_CTRL',
+ WIN32_ERROR_SERVICE_DATABASE_LOCKED => 'SERVICE_DATABASE_LOCKED',
+ WIN32_ERROR_SERVICE_DEPENDENCY_DELETED => 'SERVICE_DEPENDENCY_DELETED',
+ WIN32_ERROR_SERVICE_DEPENDENCY_FAIL => 'SERVICE_DEPENDENCY_FAIL',
+ WIN32_ERROR_SERVICE_DISABLED => 'SERVICE_DISABLED',
+ WIN32_ERROR_SERVICE_DOES_NOT_EXIST => 'SERVICE_DOES_NOT_EXIST',
+ WIN32_ERROR_SERVICE_EXISTS => 'SERVICE_EXISTS',
+ WIN32_ERROR_SERVICE_LOGON_FAILED => 'SERVICE_LOGON_FAILED',
+ WIN32_ERROR_SERVICE_MARKED_FOR_DELETE => 'SERVICE_MARKED_FOR_DELETE',
+ WIN32_ERROR_SERVICE_NO_THREAD => 'SERVICE_NO_THREAD',
+ WIN32_ERROR_SERVICE_NOT_ACTIVE => 'SERVICE_NOT_ACTIVE',
+ WIN32_ERROR_SERVICE_REQUEST_TIMEOUT => 'SERVICE_REQUEST_TIMEOUT',
+ WIN32_ERROR_SHUTDOWN_IN_PROGRESS => 'SHUTDOWN_IN_PROGRESS'
+ );
+
+ private static function val2val($val,$map,$default){
+ if(isset($map[$val])) return $map[$val];
+ return $default;
+ }
+
+ var $status;
+ var $last_error;
+ var $name;
+ var $description;
+ var $machine;
+
+ function win_service($srvname, $machine=null){
+ $this->name = $srvname;
+ $this->machine = $machine;
+ $this->status = null;
+ $this->last_error = WIN32_NO_ERROR;
+ }
+
+ function refresh_status(){
+ $status = win32_query_service_status($this->name,$this->machine);
+ if(is_array($status)){
+ $this->status = (object)$status;
+ $this->last_error = WIN32_NO_ERROR;
+ return true;
+ }
+ $this->status = null;
+ $last_error = $status;
+ return false;
+ }
+
+ function start(){
+ $this->last_error = win32_start_service($this->name, $this->machine);
+ return ($this->last_error === WIN32_NO_ERROR) or ($this->last_error === WIN32_ERROR_SERVICE_ALREADY_RUNNING);
+ }
+
+ function stop(){
+ $this->last_error = win32_stop_service($this->name, $this->machine);
+ return $this->last_error === WIN32_NO_ERROR;
+ }
+
+ function last_error($as_string = true){
+ if($as_string){
+ return self::val2val(
+ $this->last_error, self::$win_error, $this->last_error
+ );
+ }
+ return $this->last_error;
+ }
+
+ function state($as_string = true){
+ if((!$this->status)and(!$this->refresh_status())) return false;
+ if($as_string){
+ return self::val2val(
+ $this->status->CurrentState, self::$service_state, 'UNKNOWN'
+ );
+ }
+ return $this->status->CurrentState;
+ }
+
+ function pid(){
+ if((!$this->status)and(!$this->refresh_status())) return false;
+ return $this->status->ProcessId;
+ }
+
+ }
+
+}
+
+if(function_exists('reg_open_key')){
+
+ class win_reg_key{
+
+ private static $HK = array(
+ HKEY_CLASSES_ROOT => "HKCR",
+ HKEY_CURRENT_USER => "HKCU",
+ HKEY_LOCAL_MACHINE => "HKLM",
+ HKEY_USERS => "HKU",
+ HKEY_CURRENT_CONFIG => "HKCC",
+ );
+
+ function __construct($haiv, $key){
+ $this->h = $haiv;
+ $this->k = $key;
+ $this->r = reg_open_key($this->h, $this->k);
+ $this->shell = new COM('WScript.Shell');
+ if(!$this->shell){
+ throw new Exception("Cannot create shell object.");
+ }
+ if(!$this->r){
+ throw new Exception("Cannot access registry.");
+ }
+ $this->path = self::$HK[$this->h] . '\\' . $this->k;
+ }
+
+ function __destruct(){
+ if($this->r){
+ reg_close_key($this->r);
+ $this->r = false;
+ }
+ }
+
+ function keys(){
+ return reg_enum_key($this->r);
+ }
+
+ function values($as_hash = false){
+ $values = reg_enum_value($this->r);
+ if(!$as_hash) return $values;
+ $result = Array();
+ foreach($values as $key){
+ $result[$key] = reg_get_value($this->r, $key);
+ }
+ return $result;
+ }
+
+ function value($key){
+ return reg_get_value($this->r, $key);
+ }
+
+ function exists($key){
+ $v = $this->value($key);
+ if($v === NULL) return false;
+ if($v === false) return false;
+ return true;
+ }
+
+ private function write_raw($key, $type, $value){
+ return reg_set_value($this->r, $key, $type, $value);
+ }
+
+ function write_dword($key, $value){
+ return $this->write_raw($key, REG_DWORD, $value);
+ }
+
+ function write_string($key, $value){
+ return $this->write_raw($key, REG_SZ, $value);
+ }
+
+ function remove_value($key){
+ if(!$this->exists($key)) return;
+ $key = $this->path . '\\' . $key;
+ $this->shell->RegDelete($key);
+ }
+
+ }
+
+}
diff --git a/app/services/service_edit.php b/app/services/service_edit.php
index cb64aaac3a..aaaf09c584 100644
--- a/app/services/service_edit.php
+++ b/app/services/service_edit.php
@@ -221,6 +221,12 @@ if (count($_POST)>0 && strlen($_POST["persistformvar"]) == 0) {
else {
echo " \n";
}
+ if ($service_type == "svc") {
+ echo " \n";
+ }
+ else {
+ echo " \n";
+ }
echo " \n";
echo "
\n";
echo $text['description-type']."\n";
diff --git a/app/services/services.php b/app/services/services.php
index 9a1799550c..dc970bf43e 100644
--- a/app/services/services.php
+++ b/app/services/services.php
@@ -34,6 +34,18 @@ else {
exit;
}
+global $IS_WINDOWS;
+
+if ($IS_WINDOWS == null) {
+ if (stristr(PHP_OS, 'WIN')) { $IS_WINDOWS = true; } else { $IS_WINDOWS = false; }
+}
+
+$HAS_WIN_SVC = false;
+if($IS_WINDOWS){
+ require_once "resources/classes/lib_win.php";
+ $HAS_WIN_SVC = class_exists('win_service');
+}
+
//add multi-lingual support
$language = new text;
$text = $language->get();
@@ -63,13 +75,28 @@ if (strlen($_GET["a"]) > 0) {
}
unset ($prep_statement);
- if ($_GET["a"] == "stop") {
- $_SESSION["message"] = $text['message-stopping'].': '.$service_name;
- shell_exec($service_cmd_stop);
+ if($service_type == 'svc'){
+ if($HAS_WIN_SVC){
+ $svc = new win_service($service_data);
+ if ($_GET["a"] == "stop") {
+ $_SESSION["message"] = $text['message-stopping'].': '.$service_name;
+ $svc->stop();
+ }
+ if ($_GET["a"] == "start") {
+ $_SESSION["message"] = $text['message-starting'].': '.$service_name;
+ $svc->start();
+ }
+ }
}
- if ($_GET["a"] == "start") {
- $_SESSION["message"] = $text['message-starting'].': '.$service_name;
- shell_exec($service_cmd_start);
+ else {
+ if ($_GET["a"] == "stop") {
+ $_SESSION["message"] = $text['message-stopping'].': '.$service_name;
+ shell_exec($service_cmd_stop);
+ }
+ if ($_GET["a"] == "start") {
+ $_SESSION["message"] = $text['message-starting'].': '.$service_name;
+ shell_exec($service_cmd_start);
+ }
}
header("Location: services.php");
return;
@@ -152,42 +179,69 @@ if (strlen($_GET["a"]) > 0) {
}
echo " \n";
echo "