Index: /trunk/src/VBox/Devices/VMMDev/VBoxDev.cpp
===================================================================
--- /trunk/src/VBox/Devices/VMMDev/VBoxDev.cpp	(revision 2026)
+++ /trunk/src/VBox/Devices/VMMDev/VBoxDev.cpp	(revision 2027)
@@ -953,5 +953,5 @@
             break;
         }
-#endif
+#endif /* VBOX_HGCM */
 
         case VMMDevReq_VideoAccelEnable:
Index: /trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp
===================================================================
--- /trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp	(revision 2026)
+++ /trunk/src/VBox/Devices/VMMDev/VMMDevHGCM.cpp	(revision 2027)
@@ -35,4 +35,13 @@
 #include "VMMDevHGCM.h"
 
+typedef enum _VBOXHGCMCMDTYPE
+{
+    VBOXHGCMCMDTYPE_LOADSTATE,
+    VBOXHGCMCMDTYPE_CONNECT,
+    VBOXHGCMCMDTYPE_DISCONNECT,
+    VBOXHGCMCMDTYPE_CALL,
+    VBOXHGCMCMDTYPE_SizeHack = 0x7fffffff
+} VBOXHGCMCMDTYPE;
+
 /* Information about a linear ptr parameter. */
 typedef struct _VBOXHGCMLINPTR
@@ -60,9 +69,12 @@
     struct VBOXHGCMCMD *pNext;
     struct VBOXHGCMCMD *pPrev;
-    
-    /* GC ptr of the command header. */
+
+    /* The type of the command. */
+    VBOXHGCMCMDTYPE enmCmdType;
+
+    /* GC pointer of the guest request. */
     RTGCPHYS GCPtr;
 
-    /* Pointer to guest request. */
+    /* HC pointer to guest request. */
     VMMDevHGCMRequestHeader *pHeader;
 
@@ -90,5 +102,5 @@
 }
 
-static int vmmdevHGCMAddCommand (VMMDevState *pVMMDevState, PVBOXHGCMCMD pCmd, RTGCPHYS GCPtr)
+static int vmmdevHGCMAddCommand (VMMDevState *pVMMDevState, PVBOXHGCMCMD pCmd, RTGCPHYS GCPtr, VBOXHGCMCMDTYPE enmCmdType)
 {
     /* PPDMDEVINS pDevIns = pVMMDevState->pDevIns; */
@@ -111,4 +123,5 @@
         pVMMDevState->pHGCMCmdList = pCmd;
         
+        pCmd->enmCmdType = enmCmdType;
         pCmd->GCPtr = GCPtr;
 
@@ -274,5 +287,5 @@
     if (pCmd)
     {
-        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
+        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr, VBOXHGCMCMDTYPE_CONNECT);
 
         pCmd->pHeader = &pHGCMConnect->header;
@@ -303,5 +316,5 @@
     if (pCmd)
     {
-        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
+        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr, VBOXHGCMCMDTYPE_DISCONNECT);
 
         pCmd->pHeader = &pHGCMDisconnect->header;
@@ -531,5 +544,5 @@
     if (VBOX_SUCCESS (rc))
     {
-        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
+        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr, VBOXHGCMCMDTYPE_CALL);
 
         /* Pass the function call to HGCM connector for actual processing */
@@ -549,4 +562,31 @@
 }
 
+static int vmmdevHGCMCmdVerify (PVBOXHGCMCMD pCmd)
+{
+    VMMDevHGCMRequestHeader *pHeader = pCmd->pHeader;
+
+    switch (pCmd->enmCmdType)
+    {
+        case VBOXHGCMCMDTYPE_CONNECT:
+            if (pHeader->header.requestType == VMMDevReq_HGCMConnect) return VINF_SUCCESS;
+            break;
+
+        case VBOXHGCMCMDTYPE_DISCONNECT:
+            if (pHeader->header.requestType == VMMDevReq_HGCMDisconnect) return VINF_SUCCESS;
+            break;
+
+        case VBOXHGCMCMDTYPE_CALL:
+            if (pHeader->header.requestType == VMMDevReq_HGCMCall) return VINF_SUCCESS;
+            break;
+
+        default:
+            AssertFailed ();
+    }
+
+    LogRel(("VMMDEV: Invalid HGCM command: pCmd->enmCmdType = 0x%08X, pHeader->header.requestType = 0x%08X\n",
+          pCmd->enmCmdType, pHeader->header.requestType));
+    return VERR_INVALID_PARAMETER;
+}
+
 #define PDMIHGCMPORT_2_VMMDEVSTATE(pInterface) ( (VMMDevState *) ((uintptr_t)pInterface - RT_OFFSETOF(VMMDevState, HGCMPort)) )
 
@@ -563,61 +603,72 @@
         /* Setup return codes. */
         pHeader->result = result;
-
-        /* Update parameters and data buffers. */
-
-        if (pHeader->header.requestType == VMMDevReq_HGCMCall)
-        {
-            VMMDevHGCMCall *pHGCMCall = (VMMDevHGCMCall *)pHeader;
-
-            uint32_t cParms = pHGCMCall->cParms;
-
-            HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
-
-            VBOXHGCMSVCPARM *pHostParm = pCmd->paHostParms;
-
-            uint32_t i;
-            uint32_t iLinPtr = 0;
-
-            for (i = 0; i < cParms; i++, pGuestParm++, pHostParm++)
+        
+        /* Verify the request type. */
+        rc = vmmdevHGCMCmdVerify (pCmd);
+
+        if (VBOX_SUCCESS (rc))
+        {
+            /* Update parameters and data buffers. */
+
+            if (pHeader->header.requestType == VMMDevReq_HGCMCall)
             {
-                switch (pGuestParm->type)
+                VMMDevHGCMCall *pHGCMCall = (VMMDevHGCMCall *)pHeader;
+
+                uint32_t cParms = pHGCMCall->cParms;
+
+                HGCMFunctionParameter *pGuestParm = VMMDEV_HGCM_CALL_PARMS(pHGCMCall);
+
+                VBOXHGCMSVCPARM *pHostParm = pCmd->paHostParms;
+
+                uint32_t i;
+                uint32_t iLinPtr = 0;
+
+                for (i = 0; i < cParms; i++, pGuestParm++, pHostParm++)
                 {
-                    case VMMDevHGCMParmType_32bit:
+                    switch (pGuestParm->type)
                     {
-                        pGuestParm->u.value32 = pHostParm->u.uint32;
-                    } break;
-
-                    case VMMDevHGCMParmType_64bit:
-                    {
-                        pGuestParm->u.value64 = pHostParm->u.uint64;
-                    } break;
-
-                    case VMMDevHGCMParmType_PhysAddr:
-                    {
-                        /* do nothing */
-                    } break;
-
-                    case VMMDevHGCMParmType_LinAddr_In:  /* In (read) */
-                    case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
-                    case VMMDevHGCMParmType_LinAddr:     /* In & Out */
-                    {
-                        /* Copy buffer back to guest memory. */
-                        uint32_t size = pGuestParm->u.Pointer.size;
-
-                        if (size > 0 && pGuestParm->type != VMMDevHGCMParmType_LinAddr_In)
+                        case VMMDevHGCMParmType_32bit:
                         {
-                            /* Use the saved page list. */
-                            rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
-                            AssertReleaseRC(rc);
+                            pGuestParm->u.value32 = pHostParm->u.uint32;
+                        } break;
+
+                        case VMMDevHGCMParmType_64bit:
+                        {
+                            pGuestParm->u.value64 = pHostParm->u.uint64;
+                        } break;
+
+                        case VMMDevHGCMParmType_PhysAddr:
+                        {
+                            /* do nothing */
+                        } break;
+
+                        case VMMDevHGCMParmType_LinAddr_In:  /* In (read) */
+                        case VMMDevHGCMParmType_LinAddr_Out: /* Out (write) */
+                        case VMMDevHGCMParmType_LinAddr:     /* In & Out */
+                        {
+                            /* Copy buffer back to guest memory. */
+                            uint32_t size = pGuestParm->u.Pointer.size;
+
+                            if (size > 0 && pGuestParm->type != VMMDevHGCMParmType_LinAddr_In)
+                            {
+                                /* Use the saved page list. */
+                                rc = vmmdevHGCMWriteLinPtr (pVMMDevState->pDevIns, i, pHostParm->u.pointer.addr, size, iLinPtr++, pCmd->paLinPtrs);
+                                AssertReleaseRC(rc);
+                            }
+                        } break;
+
+                        default:
+                        {
+                            /* This indicates that the guest request memory was corrupted. */
+                            AssertReleaseMsgFailed(("hgcmCompleted: invalid parameter type %08X\n", pGuestParm->type));
                         }
-                    } break;
-
-                    default:
-                    {
-                        /* This indicates that the guest request memory was corrupted. */
-                        AssertReleaseMsgFailed(("hgcmCompleted: invalid parameter type %08X\n", pGuestParm->type));
                     }
                 }
             }
+        }
+        else
+        {
+            /* Return error to the guest. */
+            pHeader->header.rc = rc;
         }
 
@@ -715,5 +766,5 @@
         AssertReturn(pCmd, VERR_NO_MEMORY);
 
-        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr);
+        vmmdevHGCMAddCommand (pVMMDevState, pCmd, GCPtr, VBOXHGCMCMDTYPE_LOADSTATE);
     }
 
