command executor class implemented for Windows; fixed WIndows build errors and warnin...
authorVictor Kirhenshtein <victor@netxms.org>
Tue, 24 Jan 2017 16:35:55 +0000 (18:35 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Tue, 24 Jan 2017 16:35:55 +0000 (18:35 +0200)
include/nms_agent.h
src/agent/libnxagent/Makefile.am
src/agent/libnxagent/cmdexec.cpp [new file with mode: 0644]
src/agent/libnxagent/command_exec.cpp [deleted file]
src/agent/libnxagent/libnxagent.vcproj
src/server/core/epp.cpp
src/server/core/npe.cpp
src/server/core/nxcore.vcproj
src/server/core/session.cpp

index b1d6268..98f7e31 100644 (file)
@@ -517,19 +517,28 @@ public:
 /**
  * Execute server command
  */
-class CommandExec
+class LIBNXAGENT_EXPORTABLE CommandExec
 {
 private:
-   int m_pipe[2];
-   pid_t m_pid;
    UINT32 m_streamId;
    THREAD m_outputThread;
+#ifdef _WIN32
+   HANDLE m_phandle;
+   HANDLE m_pipe;
+#else
+   pid_t m_pid;
+   int m_pipe[2];
+#endif
 
 protected:
    TCHAR *m_cmd;
    bool m_sendOutput;
 
+#ifdef _WIN32
+   HANDLE getOutputPipe() { return m_pipe; }
+#else
    int getOutputPipe() { return m_pipe[0]; }
+#endif
 
    static THREAD_RESULT THREAD_CALL readOutput(void *pArg);
 
@@ -546,7 +555,6 @@ public:
 
    bool execute();
    void stop();
-
 };
 
 /**
index fac9171..af4f029 100644 (file)
@@ -1,4 +1,4 @@
-SOURCES = bridge.cpp main.cpp registry.cpp tools.cpp command_exec.cpp
+SOURCES = bridge.cpp cmdexec.cpp main.cpp registry.cpp tools.cpp
 
 lib_LTLIBRARIES = libnxagent.la
 
diff --git a/src/agent/libnxagent/cmdexec.cpp b/src/agent/libnxagent/cmdexec.cpp
new file mode 100644 (file)
index 0000000..2349020
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+** NetXMS - Network Management System
+** Copyright (C) 2003-2017 Raden Solutions
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: command_exec.cpp
+**
+**/
+
+#include "libnxagent.h"
+#include <signal.h>
+
+/**
+ * Next free stream ID
+ */
+static VolatileCounter s_nextStreamId = 0;
+
+#ifdef _WIN32
+
+/**
+ * Next free pipe ID
+ */
+static VolatileCounter s_pipeId = 0;
+
+/**
+ * Create pipe
+ */
+static bool CreatePipeEx(LPHANDLE lpReadPipe, LPHANDLE lpWritePipe, bool asyncRead)
+{
+   TCHAR name[MAX_PATH];
+   _sntprintf(name, MAX_PATH, _T("\\\\.\\Pipe\\nxexec.%08x.%08x"), GetCurrentProcessId(), InterlockedIncrement(&s_pipeId));
+
+       SECURITY_ATTRIBUTES sa;
+       sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+       sa.lpSecurityDescriptor = NULL;
+       sa.bInheritHandle = TRUE;
+
+   HANDLE readHandle = CreateNamedPipe(
+      name,
+      PIPE_ACCESS_INBOUND | (asyncRead ? FILE_FLAG_OVERLAPPED : 0),
+      PIPE_TYPE_BYTE | PIPE_WAIT,
+      1,           // Number of pipes
+      8192,        // Out buffer size
+      8192,        // In buffer size
+      60000,       // Timeout in ms
+      &sa
+   );
+   if (readHandle == NULL)
+      return false;
+
+   HANDLE writeHandle = CreateFile(
+      name,
+      GENERIC_WRITE,
+      0,                         // No sharing
+      &sa,
+      OPEN_EXISTING,
+      FILE_ATTRIBUTE_NORMAL,
+      NULL                       // Template file
+   );
+   if (writeHandle == INVALID_HANDLE_VALUE)
+   {
+      DWORD error = GetLastError();
+      CloseHandle(readHandle);
+      SetLastError(error);
+      return false;
+   }
+
+   *lpReadPipe = readHandle;
+   *lpWritePipe = writeHandle;
+   return true;
+}
+
+#endif /* _WIN32 */
+
+/**
+ * Create new server command execution object from command
+ */
+CommandExec::CommandExec(const TCHAR *cmd)
+{
+#ifdef _WIN32
+   m_phandle = INVALID_HANDLE_VALUE;
+   m_pipe = INVALID_HANDLE_VALUE;
+#else
+   m_pid = 0;
+   m_pipe[0] = -1;
+   m_pipe[1] = -1;
+#endif
+   m_cmd = _tcsdup_ex(cmd);
+   m_streamId = InterlockedIncrement(&s_nextStreamId);
+   m_sendOutput = false;
+   m_outputThread = INVALID_THREAD_HANDLE;
+}
+
+/**
+ * Create new server execution object
+ */
+CommandExec::CommandExec()
+{
+#ifdef _WIN32
+   m_phandle = INVALID_HANDLE_VALUE;
+   m_pipe = INVALID_HANDLE_VALUE;
+#else
+   m_pid = 0;
+   m_pipe[0] = -1;
+   m_pipe[1] = -1;
+#endif
+   m_cmd = NULL;
+   m_streamId = InterlockedIncrement(&s_nextStreamId);
+   m_sendOutput = false;
+   m_outputThread = INVALID_THREAD_HANDLE;
+}
+
+/**
+ * Destructor
+ */
+CommandExec::~CommandExec()
+{
+   stop();
+   ThreadJoin(m_outputThread);
+   free(m_cmd);
+#ifdef _WIN32
+   CloseHandle(m_phandle);
+#endif
+}
+
+/**
+ * Execute command
+ */
+bool CommandExec::execute()
+{
+   bool success = false;
+
+#ifdef _WIN32  /* Windows implementation */
+
+       SECURITY_ATTRIBUTES sa;
+       sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+       sa.lpSecurityDescriptor = NULL;
+       sa.bInheritHandle = TRUE;
+
+   HANDLE stdoutRead, stdoutWrite;
+   if (!CreatePipeEx(&stdoutRead, &stdoutWrite, true))
+   {
+      TCHAR buffer[1024];
+      nxlog_debug(4, _T("CommandExec::execute(): cannot create pipe (%s)"), GetSystemErrorText(GetLastError(), buffer, 1024));
+      return false;
+   }
+
+   // Ensure the read handle to the pipe for STDOUT is not inherited.
+   SetHandleInformation(stdoutRead, HANDLE_FLAG_INHERIT, 0);
+
+   HANDLE stdinRead, stdinWrite;
+   if (!CreatePipe(&stdinRead, &stdinWrite, &sa, 0))
+   {
+      TCHAR buffer[1024];
+      nxlog_debug(4, _T("CommandExec::execute(): cannot create pipe (%s)"), GetSystemErrorText(GetLastError(), buffer, 1024));
+      CloseHandle(stdoutRead);
+      CloseHandle(stdoutWrite);
+      return false;
+   }
+
+   // Ensure the write handle to the pipe for STDIN is not inherited. 
+   SetHandleInformation(stdinWrite, HANDLE_FLAG_INHERIT, 0);
+
+   STARTUPINFO si;
+   PROCESS_INFORMATION pi;
+
+   memset(&si, 0, sizeof(STARTUPINFO));
+   si.cb = sizeof(STARTUPINFO);
+   si.dwFlags = STARTF_USESTDHANDLES;
+   si.hStdInput = stdinRead;
+   si.hStdOutput = stdoutWrite;
+   si.hStdError = stdoutWrite;
+
+   String cmdLine = _T("CMD.EXE /C ");
+   cmdLine.append(m_cmd);
+   if (CreateProcess(NULL, cmdLine.getBuffer(), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
+   {
+      nxlog_debug(5, _T("CommandExec::execute(): process \"%s\" started"), cmdLine.getBuffer());
+
+      m_phandle = pi.hProcess;
+      CloseHandle(pi.hThread);
+      CloseHandle(stdoutWrite);
+      CloseHandle(stdinRead);
+      CloseHandle(stdinWrite);
+      if (m_sendOutput)
+      {
+         m_pipe = stdoutRead;
+         m_outputThread = ThreadCreateEx(readOutput, 0, this);
+      }
+      else
+      {
+         CloseHandle(stdoutRead);
+      }
+      success = true;
+   }
+   else
+   {
+      TCHAR buffer[1024];
+      nxlog_debug(4, _T("CommandExec::execute(): cannot create process \"%s\" (%s)"), 
+         cmdLine.getBuffer(), GetSystemErrorText(GetLastError(), buffer, 1024));
+
+      CloseHandle(stdoutRead);
+      CloseHandle(stdoutWrite);
+      CloseHandle(stdinRead);
+      CloseHandle(stdinWrite);
+   }
+
+#else /* UNIX implementation */
+
+   if (pipe(m_pipe) == -1)
+   {
+      nxlog_debug(4, _T("CommandExec::execute(): pipe() call failed (%s)"), _tcserror(errno));
+      return false;
+   }
+
+   m_pid = fork();
+   switch(m_pid)
+   {
+      case -1: // error
+         nxlog_debug(4, _T("CommandExec::execute(): fork() call failed (%s)"), _tcserror(errno));
+         close(m_pipe[0]);
+         close(m_pipe[1]);
+         break;
+      case 0: // child
+         close(m_pipe[0]);
+         close(1);
+         close(2);
+         dup2(m_pipe[1], 1);
+         dup2(m_pipe[1], 2);
+         close(m_pipe[1]);
+#ifdef UNICODE
+         execl("/bin/sh", "/bin/sh", "-c", UTF8StringFromWideString(m_cmd), NULL);
+#else
+         execl("/bin/sh", "/bin/sh", "-c", m_cmd, NULL);
+#endif
+         exit(127);
+         break;
+      default: // parent
+         close(m_pipe[1]);
+         if (m_sendOutput)
+         {
+            m_outputThread = ThreadCreateEx(readOutput, 0, this);
+         }
+         else
+         {
+            close(m_pipe[0]);
+         }
+         success = true;
+         break;
+   }
+
+#endif
+
+   return success;
+}
+
+/**
+ * Start read output thread
+ */
+THREAD_RESULT THREAD_CALL CommandExec::readOutput(void *pArg)
+{
+   char buffer[4096];
+
+#ifdef _WIN32  /* Windows implementation */
+
+   OVERLAPPED ov;
+       memset(&ov, 0, sizeof(OVERLAPPED));
+   ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+   HANDLE pipe = ((CommandExec *)pArg)->getOutputPipe();
+   while(true)
+   {
+      if (!ReadFile(pipe, buffer, sizeof(buffer) - 1, NULL, &ov))
+      {
+         if (GetLastError() != ERROR_IO_PENDING)
+         {
+            TCHAR emsg[1024];
+            nxlog_debug(6, _T("CommandExec::readOutput(): stopped on ReadFile (%s)"), GetSystemErrorText(GetLastError(), emsg, 1024));
+            break;
+         }
+      }
+
+      HANDLE handles[2];
+      handles[0] = ov.hEvent;
+      handles[1] = ((CommandExec *)pArg)->m_phandle;
+      DWORD rc = WaitForMultipleObjects(2, handles, FALSE, 5000);
+      if (rc == WAIT_OBJECT_0 + 1)
+      {
+         nxlog_debug(6, _T("CommandExec::readOutput(): process termination detected"));
+         break;   // Process terminated
+      }
+      if (rc == WAIT_OBJECT_0)
+      {
+         DWORD bytes;
+         if (GetOverlappedResult(pipe, &ov, &bytes, TRUE))
+         {
+            buffer[bytes] = 0;
+            ((CommandExec *)pArg)->onOutput(buffer);
+         }
+         else
+         {
+            TCHAR emsg[1024];
+            nxlog_debug(6, _T("CommandExec::readOutput(): stopped on GetOverlappedResult (%s)"), GetSystemErrorText(GetLastError(), emsg, 1024));
+            break;
+         }
+      }
+      else
+      {
+         // Send empty output on timeout
+         ((CommandExec *)pArg)->onOutput("");
+      }
+   }
+
+   CloseHandle(ov.hEvent);
+   CloseHandle(pipe);
+
+#else /* UNIX implementation */
+
+   int pipe = ((CommandExec *)pArg)->getOutputPipe();
+   fcntl(pipe, F_SETFD, fcntl(pipe, F_GETFD) | O_NONBLOCK);
+
+   SocketPoller sp;
+   while(true)
+   {
+      sp.reset();
+      sp.add(pipe);
+      int rc = sp.poll(10000);
+      if (rc > 0)
+      {
+         rc = read(pipe, buffer, sizeof(buffer) - 1);
+         if (rc > 0)
+         {
+            buffer[rc] = 0;
+            ((CommandExec *)pArg)->onOutput(buffer);
+         }
+         else
+         {
+            if ((rc == -1) && ((errno == EAGAIN) || (errno == EINTR)))
+            {
+               ((CommandExec *)pArg)->onOutput("");
+               continue;
+            }
+            nxlog_debug(6, _T("CommandExec::readOutput(): stopped on read (rc=%d err=%s)"), rc, _tcserror(errno));
+            break;
+         }
+      }
+      else if (rc == 0)
+      {
+         // Send empty output on timeout
+         ((CommandExec *)pArg)->onOutput("");
+      }
+      else
+      {
+         nxlog_debug(6, _T("CommandExec::readOutput(): stopped on poll (%s)"), _tcserror(errno));
+         break;
+      }
+   }
+   close(pipe);
+
+#endif
+
+   ((CommandExec *)pArg)->endOfOutput();
+   return THREAD_OK;
+}
+
+/**
+ * kill command
+ */
+void CommandExec::stop()
+{
+#ifdef _WIN32
+   TerminateProcess(m_phandle, 127);
+#else
+   kill(m_pid, SIGKILL);
+#endif
+}
+
+/**
+ * Perform action when output is generated
+ */
+void CommandExec::onOutput(const char *text)
+{
+}
+
+/**
+ * Perform action after output is generated
+ */
+void CommandExec::endOfOutput()
+{
+}
diff --git a/src/agent/libnxagent/command_exec.cpp b/src/agent/libnxagent/command_exec.cpp
deleted file mode 100644 (file)
index 769416a..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-** NetXMS - Network Management System
-** Copyright (C) 2003-2017 Raden Solutions
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-** File: command_exec.cpp
-**
-**/
-
-#include "libnxagent.h"
-#include <signal.h>
-
-/**
- * Next free stream ID
- */
-static VolatileCounter s_nextStreamId = 0;
-
-/**
- * Create new server command execution object from command
- */
-CommandExec::CommandExec(const TCHAR *cmd)
-{
-   m_pid = 0;
-   m_cmd = _tcsdup_ex(cmd);
-   m_streamId = InterlockedIncrement(&s_nextStreamId);
-   m_sendOutput = false;
-   m_outputThread = INVALID_THREAD_HANDLE;
-}
-
-/**
- * Create new server execution object
- */
-CommandExec::CommandExec()
-{
-   m_pid = 0;
-   m_cmd = NULL;
-   m_streamId = InterlockedIncrement(&s_nextStreamId);
-   m_sendOutput = false;
-   m_outputThread = INVALID_THREAD_HANDLE;
-}
-
-/**
- * Destructor
- */
-CommandExec::~CommandExec()
-{
-   ThreadJoin(m_outputThread);
-   free(m_cmd);
-   stop();
-}
-
-/**
- * Execute command
- */
-bool CommandExec::execute()
-{
-   if (pipe(m_pipe) == -1)
-   {
-      nxlog_debug(4, _T("CommandExec::execute(): pipe() call failed (%s)"), _tcserror(errno));
-      return false;
-   }
-
-   m_pid = fork();
-   switch(m_pid)
-   {
-      case -1: // error
-         nxlog_debug(4, _T("CommandExec::execute(): fork() call failed (%s)"), _tcserror(errno));
-         close(m_pipe[0]);
-         close(m_pipe[1]);
-         return false;
-      case 0: // child
-         close(m_pipe[0]);
-         close(1);
-         close(2);
-         dup2(m_pipe[1], 1);
-         dup2(m_pipe[1], 2);
-         close(m_pipe[1]);
-#ifdef UNICODE
-         execl("/bin/sh", "/bin/sh", "-c", UTF8StringFromWideString(m_cmd), NULL);
-#else
-         execl("/bin/sh", "/bin/sh", "-c", m_cmd, NULL);
-#endif
-         exit(127);
-         break;
-      default: // parent
-         close(m_pipe[1]);
-         if (m_sendOutput)
-         {
-            m_outputThread = ThreadCreateEx(readOutput, 0, this);
-         }
-         else
-         {
-            close(m_pipe[0]);
-         }
-         return true;
-   }
-
-   return false;
-}
-
-/**
- * Start read output thread
- */
-THREAD_RESULT THREAD_CALL CommandExec::readOutput(void *pArg)
-{
-   int pipe = ((CommandExec *)pArg)->getOutputPipe();
-   fcntl(pipe, F_SETFD, fcntl(pipe, F_GETFD) | O_NONBLOCK);
-
-   char buffer[4096];
-   SocketPoller sp;
-   while(true)
-   {
-      sp.reset();
-      sp.add(pipe);
-      int rc = sp.poll(10000);
-      if (rc > 0)
-      {
-         rc = read(pipe, buffer, 4096);
-         if (rc > 0)
-         {
-            ((CommandExec *)pArg)->onOutput(buffer);
-         }
-         else
-         {
-            if ((rc == -1) && ((errno == EAGAIN) || (errno == EINTR)))
-            {
-               ((CommandExec *)pArg)->onOutput("");
-               continue;
-            }
-            nxlog_debug(6, _T("CommandExec::readOutput(): stopped on read (rc=%d err=%s)"), rc, _tcserror(errno));
-            break;
-         }
-      }
-      else if (rc == 0)
-      {
-         // Send empty output on timeout
-         ((CommandExec *)pArg)->onOutput("");
-      }
-      else
-      {
-         nxlog_debug(6, _T("CommandExec::readOutput(): stopped on poll (%s)"), _tcserror(errno));
-         break;
-      }
-   }
-   ((CommandExec *)pArg)->endOfOutput();
-
-   close(pipe);
-   return THREAD_OK;
-}
-
-/**
- * kill command
- */
-void CommandExec::stop()
-{
-   kill(m_pid, SIGKILL);
-}
-
-/**
- * Perform action when output is generated
- */
-void CommandExec::onOutput(const char *text)
-{
-}
-
-/**
- * Perform action after output is generated
- */
-void CommandExec::endOfOutput()
-{
-}
index bbc0952..b420745 100644 (file)
                                RelativePath=".\bridge.cpp"
                                >
                        </File>
+                       <File
+                               RelativePath=".\cmdexec.cpp"
+                               >
+                       </File>
                        <File
                                RelativePath=".\main.cpp"
                                >
index cad2f28..664269b 100644 (file)
@@ -183,9 +183,6 @@ EPRule::EPRule(DB_RESULT hResult, int row)
  */
 EPRule::EPRule(NXCPMessage *msg)
 {
-       UINT32 i, id;
-       TCHAR *name, *value;
-
    m_dwFlags = msg->getFieldAsUInt32(VID_FLAGS);
    m_id = msg->getFieldAsUInt32(VID_RULE_ID);
    m_guid = msg->getFieldAsGUID(VID_GUID);
@@ -212,14 +209,14 @@ EPRule::EPRule(NXCPMessage *msg)
    m_alarmCategoryList = new IntegerArray<UINT32>(16, 16);
    msg->getFieldAsInt32Array(VID_ALARM_CATEGORY_ID, m_alarmCategoryList);
 
-   int count = msg->getFieldAsUInt32(VID_NUM_SET_PSTORAGE);
+   int count = msg->getFieldAsInt32(VID_NUM_SET_PSTORAGE);
    int base = VID_PSTORAGE_SET_LIST_BASE;
    for(int i = 0; i < count; i++, base+=2)
    {
       m_pstorageSetActions.setPreallocated(msg->getFieldAsString(base), msg->getFieldAsString(base+1));
    }
 
-   count = msg->getFieldAsUInt32(VID_NUM_DELETE_PSTORAGE);
+   count = msg->getFieldAsInt32(VID_NUM_DELETE_PSTORAGE);
    base = VID_PSTORAGE_DELETE_LIST_BASE;
    for(int i = 0; i < count; i++, base++)
    {
@@ -918,13 +915,9 @@ bool EventPolicy::loadFromDB()
  */
 bool EventPolicy::saveToDB()
 {
-   int i;
-   bool success = false;
-
        DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
-
-   readLock();
-   if(DBBegin(hdb))
+   bool success = DBBegin(hdb);
+   if (success)
    {
       success = DBQuery(hdb, _T("DELETE FROM event_policy")) &&
                 DBQuery(hdb, _T("DELETE FROM policy_action_list")) &&
@@ -932,14 +925,20 @@ bool EventPolicy::saveToDB()
                 DBQuery(hdb, _T("DELETE FROM policy_source_list")) &&
                 DBQuery(hdb, _T("DELETE FROM policy_pstorage_actions")) &&
                 DBQuery(hdb, _T("DELETE FROM alarm_category_map"));
-      for(i = 0; i < m_dwNumRules && success; i++)
-         success = m_ppRuleList[i]->saveToDB(hdb);
-      if(success)
+
+      if (success)
+      {
+         readLock();
+         for(UINT32 i = 0; (i < m_dwNumRules) && success; i++)
+            success = m_ppRuleList[i]->saveToDB(hdb);
+         unlock();
+      }
+
+      if (success)
          DBCommit(hdb);
       else
          DBRollback(hdb);
    }
-   unlock();
        DBConnectionPoolReleaseConnection(hdb);
        return success;
 }
index 46a8b9b..3fab125 100644 (file)
@@ -186,7 +186,7 @@ bool GetPredictedData(ClientSession *session, const NXCPMessage *request, NXCPMe
       rows++;
 
       double value = engine->getPredictedValue(dci->getId(), timestamp);
-      pCurr->timeStamp = timestamp;
+      pCurr->timeStamp = (UINT32)timestamp;
       switch(dataType)
       {
          case DCI_DT_INT:
index beb977c..ddad9cb 100644 (file)
                                RelativePath=".\poll.cpp"
                                >
                        </File>
+                       <File
+                               RelativePath=".\ps.cpp"
+                               >
+                       </File>
                        <File
                                RelativePath=".\rack.cpp"
                                >
                                RelativePath=".\session.cpp"
                                >
                        </File>
-                       <File
-                               RelativePath=".\situation.cpp"
-                               >
-                       </File>
                        <File
                                RelativePath=".\slmcheck.cpp"
                                >
index 1b205ae..45c9773 100644 (file)
@@ -12552,7 +12552,7 @@ void ClientSession::stopServerCommand(NXCPMessage *request)
    msg.setId(request->getId());
    msg.setCode(CMD_REQUEST_COMPLETED);
 
-   CommandExec *cmd = m_serverCommands->get(request->getFieldAsInt64(VID_COMMAND_ID));
+   CommandExec *cmd = m_serverCommands->get(request->getFieldAsUInt32(VID_COMMAND_ID));
    if (cmd != NULL)
    {
       cmd->stop();