Index: trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp
===================================================================
--- trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp	(revision 93719)
+++ trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp	(revision 93720)
@@ -465,4 +465,6 @@
 /**
  * Translates a process status to a human readable string.
+ *
+ * @sa GuestProcess::i_statusToString()
  */
 const char *gctlProcessStatusToText(ProcessStatus_T enmStatus)
Index: trunk/src/VBox/Main/include/GuestProcessImpl.h
===================================================================
--- trunk/src/VBox/Main/include/GuestProcessImpl.h	(revision 93719)
+++ trunk/src/VBox/Main/include/GuestProcessImpl.h	(revision 93720)
@@ -62,4 +62,5 @@
      * @{ */
     inline int i_checkPID(uint32_t uPID);
+    ProcessStatus_T i_getStatus(void);
     int i_readData(uint32_t uHandle, uint32_t uSize, uint32_t uTimeoutMS, void *pvData, size_t cbData, uint32_t *pcbRead, int *pGuestRc);
     int i_startProcess(uint32_t cMsTimeout, int *pGuestRc);
@@ -78,4 +79,5 @@
      * @{ */
     static Utf8Str i_guestErrorToString(int rcGuest, const char *pcszWhat);
+    static Utf8Str i_statusToString(ProcessStatus_T enmStatus);
     static bool i_isGuestError(int guestRc);
     static ProcessWaitResult_T i_waitFlagsToResultEx(uint32_t fWaitFlags, ProcessStatus_T oldStatus, ProcessStatus_T newStatus, uint32_t uProcFlags, uint32_t uProtocol);
Index: trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp	(revision 93719)
+++ trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp	(revision 93720)
@@ -416,7 +416,5 @@
     LogFlowThisFuncEnter();
 
-    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
-
-    *aStatus = mData.mStatus;
+    *aStatus = i_getStatus();
 
     return S_OK;
@@ -513,4 +511,18 @@
 
     return rc;
+}
+
+/**
+ * Returns the current process status.
+ *
+ * @returns Current process status.
+ *
+ * @note    Takes the read lock.
+ */
+ProcessStatus_T GuestProcess::i_getStatus(void)
+{
+    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    return mData.mStatus;
 }
 
@@ -551,4 +563,45 @@
 
     return strErr;
+}
+
+/**
+ * Translates a process status to a human readable string.
+ *
+ * @returns Process status as a string.
+ * @param   enmStatus           Guest process status to return string for.
+ */
+/* static */
+Utf8Str GuestProcess::i_statusToString(ProcessStatus_T enmStatus)
+{
+    switch (enmStatus)
+    {
+        case ProcessStatus_Starting:
+            return "starting";
+        case ProcessStatus_Started:
+            return "started";
+        case ProcessStatus_Paused:
+            return "paused";
+        case ProcessStatus_Terminating:
+            return "terminating";
+        case ProcessStatus_TerminatedNormally:
+            return "successfully terminated";
+        case ProcessStatus_TerminatedSignal:
+            return "terminated by signal";
+        case ProcessStatus_TerminatedAbnormally:
+            return "abnormally aborted";
+        case ProcessStatus_TimedOutKilled:
+            return "timed out";
+        case ProcessStatus_TimedOutAbnormally:
+            return "timed out, hanging";
+        case ProcessStatus_Down:
+            return "killed";
+        case ProcessStatus_Error:
+            return "error";
+        default:
+            break;
+    }
+
+    AssertFailed(); /* Should never happen! */
+    return "unknown";
 }
 
@@ -2024,29 +2077,46 @@
     int rcGuest = VERR_IPE_UNINITIALIZED_STATUS;
     int vrc = i_terminateProcess(30 * 1000 /* Timeout in ms */, &rcGuest);
-    if (RT_FAILURE(vrc))
-    {
-        switch (vrc)
-        {
-            case VERR_GSTCTL_GUEST_ERROR:
-            {
-                GuestErrorInfo ge(GuestErrorInfo::Type_Process, rcGuest, mData.mProcess.mExecutable.c_str());
-                hr = setErrorBoth(VBOX_E_IPRT_ERROR, rcGuest, tr("Terminating guest process failed: %s"),
-                                  GuestBase::getErrorAsString(ge).c_str());
-                break;
-            }
-            case VERR_NOT_SUPPORTED:
-                hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
-                                  tr("Terminating guest process \"%s\" (PID %RU32) not supported by installed Guest Additions"),
-                                  mData.mProcess.mExecutable.c_str(), mData.mPID);
-                break;
-
-            default:
-                hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Terminating guest process \"%s\" (PID %RU32) failed: %Rrc"),
-                                  mData.mProcess.mExecutable.c_str(), mData.mPID, vrc);
-                break;
-        }
-    }
-
-    if (vrc == VINF_SUCCESS) /* Note: Also could be VWRN_INVALID_STATE from i_terminateProcess(). */
+
+    switch (vrc)
+    {
+        case VINF_SUCCESS:
+            /* Nothing to do here, all good. */
+            break;
+
+        case VWRN_INVALID_STATE:
+        {
+            GuestErrorInfo ge(GuestErrorInfo::Type_Process, rcGuest, mData.mProcess.mExecutable.c_str());
+            hr = setErrorBoth(VBOX_E_IPRT_ERROR, VWRN_INVALID_STATE,
+                              tr("Guest process is not in '%s' state anymore (current is in '%s')"),
+                              GuestProcess::i_statusToString(ProcessStatus_Started).c_str(),
+                              GuestProcess::i_statusToString(i_getStatus()).c_str());
+            break;
+        }
+
+        case VERR_GSTCTL_GUEST_ERROR:
+        {
+            GuestErrorInfo ge(GuestErrorInfo::Type_Process, rcGuest, mData.mProcess.mExecutable.c_str());
+            hr = setErrorBoth(VBOX_E_IPRT_ERROR, rcGuest, tr("Terminating guest process failed: %s"),
+                              GuestBase::getErrorAsString(ge).c_str());
+            break;
+        }
+
+        case VERR_NOT_SUPPORTED:
+        {
+            hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc,
+                              tr("Terminating guest process \"%s\" (PID %RU32) not supported by installed Guest Additions"),
+                              mData.mProcess.mExecutable.c_str(), mData.mPID);
+            break;
+        }
+
+        default:
+            hr = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Terminating guest process \"%s\" (PID %RU32) failed: %Rrc"),
+                              mData.mProcess.mExecutable.c_str(), mData.mPID, vrc);
+            break;
+    }
+
+    /* Note: Also could be VWRN_INVALID_STATE from i_terminateProcess().
+     *       In such a case we have to keep the process in our list in order to fullfill any upcoming responses / requests. */
+    if (vrc == VINF_SUCCESS)
     {
         /* Remove process from guest session list. Now only API clients
