Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 17209)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp	(revision 17210)
@@ -1051,5 +1051,5 @@
                                          PVBOXGUESTSESSION pSession,
                                          VBoxGuestHGCMCallInfo *pInfo,
-                                         uint32_t cMillies, bool fInterruptible,
+                                         uint32_t cMillies, bool fInterruptible, bool f32bit,
                                          size_t cbExtra, size_t cbData, size_t *pcbDataReturned)
 {
@@ -1062,5 +1062,11 @@
         return VERR_INVALID_PARAMETER;
     }
-    const size_t cbActual = cbExtra + sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter);
+    size_t cbActual = cbExtra + sizeof(*pInfo);
+#ifdef RT_ARCH_AMD64
+    if (f32bit)
+        cbActual += pInfo->cParms * sizeof(HGCMFunctionParameter32);
+    else
+#endif
+        cbActual += pInfo->cParms * sizeof(HGCMFunctionParameter);
     if (cbData < cbActual)
     {
@@ -1097,8 +1103,20 @@
     Log(("VBoxGuestCommonIOCtl: HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID));
     int rc;
-    if (fInterruptible)
-        rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
+#ifdef RT_ARCH_AMD64
+    if (f32bit)
+    {
+        if (fInterruptible)
+            rc = VbglHGCMCall32(pInfo, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
+        else
+            rc = VbglHGCMCall32(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
+    }
     else
-        rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
+#endif
+    {
+        if (fInterruptible)
+            rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
+        else
+            rc = VbglHGCMCall(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
+    }
     if (RT_SUCCESS(rc))
     {
@@ -1110,71 +1128,4 @@
     return rc;
 }
-
-
-#ifdef RT_ARCH_AMD64
-/** The 32-bit version HGCM call for 64-bit driver. */
-static int VBoxGuestCommonIOCtl_HGCMCall32(PVBOXGUESTDEVEXT pDevExt,
-                                           PVBOXGUESTSESSION pSession,
-                                           VBoxGuestHGCMCallInfo *pInfo,
-                                           uint32_t cMillies, bool fInterruptible,
-                                           size_t cbExtra, size_t cbData, size_t *pcbDataReturned)
-{
-    /*
-     * Some more validations.
-     */
-    if (pInfo->cParms > 4096) /* (Just make sure it doesn't overflow the next check.) */
-    {
-        Log(("VBoxGuestCommonIOCtl: HGCM_CALL: cParm=%RX32 is not sane\n", pInfo->cParms));
-        return VERR_INVALID_PARAMETER;
-    }
-    const size_t cbActual = cbExtra + sizeof(*pInfo) + pInfo->cParms * sizeof(HGCMFunctionParameter32);
-    if (cbData < cbActual)
-    {
-        Log(("VBoxGuestCommonIOCtl: HGCM_CALL: cbData=%#zx (%zu) required size is %#zx (%zu)\n",
-             cbData, cbActual));
-        return VERR_INVALID_PARAMETER;
-    }
-
-    /*
-     * Validate the client id.
-     */
-    const uint32_t u32ClientId = pInfo->u32ClientID;
-    unsigned i;
-    RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;
-    RTSpinlockAcquireNoInts(pDevExt->SessionSpinlock, &Tmp);
-    for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)
-        if (pSession->aHGCMClientIds[i] == u32ClientId)
-            break;
-    RTSpinlockReleaseNoInts(pDevExt->SessionSpinlock, &Tmp);
-    if (RT_UNLIKELY(i >= RT_ELEMENTS(pSession->aHGCMClientIds)))
-    {
-        static unsigned s_cErrors = 0;
-        if (s_cErrors++ > 32)
-            LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: Invalid handle. u32Client=%RX32\n", u32ClientId));
-        return VERR_INVALID_HANDLE;
-    }
-
-    /*
-     * The VbglHGCMCall call will invoke the callback if the HGCM
-     * call is performed in an ASYNC fashion. This function can
-     * deal with cancelled requests, so we let user more requests
-     * be interruptible (should add a flag for this later I guess).
-     */
-    Log(("VBoxGuestCommonIOCtl: HGCM_CALL: u32Client=%RX32\n", pInfo->u32ClientID));
-    int rc;
-    if (fInterruptible)
-        rc = VbglHGCMCall32(pInfo, VBoxGuestHGCMAsyncWaitCallbackInterruptible, pDevExt, cMillies);
-    else
-        rc = VbglHGCMCall32(pInfo, VBoxGuestHGCMAsyncWaitCallback, pDevExt, cMillies);
-    if (RT_SUCCESS(rc))
-    {
-        Log(("VBoxGuestCommonIOCtl: HGCM_CALL: result=%Rrc\n", pInfo->result));
-        if (pcbDataReturned)
-            *pcbDataReturned = cbActual;
-    }
-    Log(("VBoxGuestCommonIOCtl: HGCM_CALL: Failed. rc=%Rrc.\n", rc));
-    return rc;
-}
-#endif
 
 
@@ -1329,5 +1280,5 @@
         bool fInterruptible = pSession->R0Process != NIL_RTR0PROCESS;
         rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, RT_INDEFINITE_WAIT,
-                                           fInterruptible,
+                                           fInterruptible, false /*f32bit*/,
                                            0, cbData, pcbDataReturned);
     }
@@ -1338,4 +1289,5 @@
         rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, &pInfo->info, pInfo->u32Timeout,
                                            !!pInfo->fInterruptible || pSession->R0Process != NIL_RTR0PROCESS,
+                                           false /*f32bit*/,
                                            RT_OFFSETOF(VBoxGuestHGCMCallInfoTimed, info), cbData, pcbDataReturned);
     }
@@ -1345,7 +1297,7 @@
         CHECKRET_MIN_SIZE("HGCM_CALL", sizeof(VBoxGuestHGCMCallInfo));
         bool fInterruptible = pSession->R0Process != NIL_RTR0PROCESS;
-        rc = VBoxGuestCommonIOCtl_HGCMCall32(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, RT_INDEFINITE_WAIT,
-                                             fInterruptible,
-                                             0, cbData, pcbDataReturned);
+        rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, (VBoxGuestHGCMCallInfo *)pvData, RT_INDEFINITE_WAIT,
+                                           fInterruptible, true /*f32bit*/,
+                                           0, cbData, pcbDataReturned);
     }
     else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_HGCM_CALL_TIMED_32(0)))
@@ -1353,9 +1305,10 @@
         CHECKRET_MIN_SIZE("HGCM_CALL_TIMED", sizeof(VBoxGuestHGCMCallInfoTimed));
         VBoxGuestHGCMCallInfoTimed *pInfo = (VBoxGuestHGCMCallInfoTimed *)pvData;
-        rc = VBoxGuestCommonIOCtl_HGCMCall32(pDevExt, pSession, &pInfo->info, pInfo->u32Timeout,
-                                             !!pInfo->fInterruptible || pSession->R0Process != NIL_RTR0PROCESS,
-                                             RT_OFFSETOF(VBoxGuestHGCMCallInfoTimed, info), cbData, pcbDataReturned);
-    }    
-# endif   
+        rc = VBoxGuestCommonIOCtl_HGCMCall(pDevExt, pSession, &pInfo->info, pInfo->u32Timeout,
+                                           !!pInfo->fInterruptible || pSession->R0Process != NIL_RTR0PROCESS,
+                                           true /*f32bit*/,
+                                           RT_OFFSETOF(VBoxGuestHGCMCallInfoTimed, info), cbData, pcbDataReturned);
+    }
+# endif
 #endif /* VBOX_WITH_HGCM */
     else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_LOG(0)))
@@ -1389,5 +1342,5 @@
 # ifdef RT_ARCH_AMD64
             case VBOXGUEST_IOCTL_HGCM_CONNECT_32:
-# endif              
+# endif
                 CHECKRET_MIN_SIZE("HGCM_CONNECT", sizeof(VBoxGuestHGCMConnectInfo));
                 rc = VBoxGuestCommonIOCtl_HGCMConnect(pDevExt, pSession, (VBoxGuestHGCMConnectInfo *)pvData, pcbDataReturned);
@@ -1397,5 +1350,5 @@
 # ifdef RT_ARCH_AMD64
             case VBOXGUEST_IOCTL_HGCM_DISCONNECT_32:
-# endif              
+# endif
                 CHECKRET_MIN_SIZE("HGCM_DISCONNECT", sizeof(VBoxGuestHGCMDisconnectInfo));
                 rc = VBoxGuestCommonIOCtl_HGCMDisconnect(pDevExt, pSession, (VBoxGuestHGCMDisconnectInfo *)pvData, pcbDataReturned);
@@ -1406,5 +1359,4 @@
                 rc = VBoxGuestCommonIOCtl_HGCMClipboardReConnect(pDevExt, (uint32_t *)pvData, pcbDataReturned);
                 break;
-                
 #endif /* VBOX_WITH_HGCM */
 
