Index: trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 4817)
+++ trunk/src/VBox/HostDrivers/Support/darwin/SUPDrv-darwin.cpp	(revision 4818)
@@ -466,13 +466,14 @@
      * Buffered or unbuffered?
      */
+    PSUPREQHDR pHdr;
+    user_addr_t pUser = 0;
     void *pvPageBuf = NULL;
-    PSUPREQHDR pHdr;
-    uint32_t cb = IOCPARM_LEN(iCmd);
-    if (cb)
+    uint32_t cbReq = IOCPARM_LEN(iCmd);
+    if ((IOC_DIRMASK & iCmd) == IOC_INOUT)
     {
         pHdr = (PSUPREQHDR)pData;
-        if (RT_UNLIKELY(cb < sizeof(*pHdr)))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: cb=%#x < %#x; iCmd=%#lx\n", cb, (int)sizeof(*pHdr), iCmd));
+        if (RT_UNLIKELY(cbReq < sizeof(*pHdr)))
+        {
+            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: cbReq=%#x < %#x; iCmd=%#lx\n", cbReq, (int)sizeof(*pHdr), iCmd));
             return EINVAL;
         }
@@ -482,11 +483,13 @@
             return EINVAL;
         }
-        if (RT_UNLIKELY(RT_MAX(pHdr->cbIn, pHdr->cbOut) != cb))
-        {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x) != %#x; iCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cb, iCmd));
+        if (RT_UNLIKELY(    RT_MAX(pHdr->cbIn, pHdr->cbOut) != cbReq
+                        ||  pHdr->cbIn < sizeof(*pHdr)
+                        ||  pHdr->cbOut < sizeof(*pHdr)))
+        {
+            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x) != %#x; iCmd=%#lx\n", pHdr->cbIn, pHdr->cbOut, cbReq, iCmd));
             return EINVAL;
         }
     }
-    else
+    else if ((IOC_DIRMASK & iCmd) == IOC_VOID && !cbReq)
     {
         /* 
@@ -494,8 +497,9 @@
          */ 
         SUPREQHDR Hdr;
-        int rc = copyin((const user_addr_t)pData, &Hdr, sizeof(Hdr));
+        pUser = (user_addr_t)*(void **)pData;
+        int rc = copyin(pUser, &Hdr, sizeof(Hdr));
         if (RT_UNLIKELY(rc))
         {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%lx,Hdr,) -> %#x; iCmd=%#lx\n", pData, rc, iCmd));
+            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
             return rc;
         }
@@ -505,6 +509,8 @@
             return EINVAL;
         }
-        cb = RT_MAX(Hdr.cbIn, Hdr.cbOut);
-        if (RT_UNLIKELY(cb < sizeof(Hdr) || cb > _1M*16))
+        cbReq = RT_MAX(Hdr.cbIn, Hdr.cbOut);
+        if (RT_UNLIKELY(    Hdr.cbIn < sizeof(Hdr)
+                        ||  Hdr.cbOut < sizeof(Hdr)
+                        ||  cbReq > _1M*16))
         {
             OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: max(%#x,%#x); iCmd=%#lx\n", Hdr.cbIn, Hdr.cbOut, iCmd));
@@ -515,18 +521,19 @@
          * Allocate buffer and copy in the data.
          */
-        pHdr = (PSUPREQHDR)RTMemTmpAlloc(cb);
+        pHdr = (PSUPREQHDR)RTMemTmpAlloc(cbReq);
         if (!pHdr)
-            pvPageBuf = pHdr = (PSUPREQHDR)IOMallocAligned(RT_ALIGN_Z(cb, PAGE_SIZE), 8);
+            pvPageBuf = pHdr = (PSUPREQHDR)IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8);
         if (RT_UNLIKELY(!pHdr))
         {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cb, iCmd));
+            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
             return ENOMEM;
         }
-        rc = copyin((const user_addr_t)pData, pHdr, Hdr.cbIn);
+        rc = copyin(pUser, pHdr, Hdr.cbIn);
         if (RT_UNLIKELY(rc))
         {
-            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%lx,,%#x) -> %#x; iCmd=%#lx\n", pData, Hdr.cbIn, rc, iCmd));
+            OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n", 
+                        (unsigned long long)pUser, pHdr, Hdr.cbIn, rc, iCmd));
             if (pvPageBuf)
-                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cb, PAGE_SIZE));
+                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
             else
                 RTMemTmpFree(pHdr);
@@ -534,4 +541,9 @@
         }
     }
+    else
+    {
+        dprintf(("VBoxDrvDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd));
+        return EINVAL;
+    }
 
     /*
@@ -544,19 +556,20 @@
          * If not buffered, copy back the buffer before returning.
          */
-        if (!IOCPARM_LEN(iCmd))
+        if (pUser)
         {
             uint32_t cbOut = pHdr->cbOut;
-            if (cbOut > cb)
+            if (cbOut > cbReq)
             {
-                OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cb, iCmd));
-                cbOut = cb;
+                OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbOut, cbReq, iCmd));
+                cbOut = cbReq;
             }
-            rc = copyout(pHdr, (user_addr_t)pData, cbOut);
+            rc = copyout(pHdr, pUser, cbOut);
             if (RT_UNLIKELY(rc))
-                OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyout(,%p,%#x) -> %d; uCmd=%#lx!\n", pData, cbOut, rc, iCmd));
+                OSDBGPRINT(("VBoxDrvDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n", 
+                            pHdr, (unsigned long long)pUser, cbOut, rc, iCmd));
 
             /* cleanup */
             if (pvPageBuf)
-                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cb, PAGE_SIZE));
+                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
             else
                 RTMemTmpFree(pHdr);
@@ -568,8 +581,8 @@
          * The request failed, just clean up.
          */
-        if (!IOCPARM_LEN(iCmd))
+        if (pUser)
         {
             if (pvPageBuf)
-                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cb, PAGE_SIZE));
+                IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
             else
                 RTMemTmpFree(pHdr);
Index: trunk/src/VBox/HostDrivers/Support/testcase/tstPin.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/testcase/tstPin.cpp	(revision 4817)
+++ trunk/src/VBox/HostDrivers/Support/testcase/tstPin.cpp	(revision 4818)
@@ -42,4 +42,26 @@
     if (!rc)
     {
+        /*
+         * Simple test.
+         */
+        void *pv;
+        int rc = SUPPageAlloc(1, &pv);
+        AssertRC(rc);
+        RTPrintf("pv=%p\n", pv);
+        SUPPAGE aPages[1];
+        rc = SUPPageLock(pv, 1, &aPages[0]);
+        RTPrintf("rc=%d aPages[0]=%RHp\n", rc, pv, aPages[0]);
+        RTThreadSleep(1500);
+#if 0
+        RTPrintf("Unlocking...\n");
+        RTThreadSleep(250);
+        rc = SUPPageUnlock(pv);
+        RTPrintf("rc=%d\n", rc);
+        RTThreadSleep(1500);
+#endif 
+
+        /*
+         * More extensive.
+         */
         static struct
         {
@@ -169,5 +191,4 @@
             SUPPageFree(pv, BIG_SIZEPP >> PAGE_SHIFT);
         }
-
         rc = SUPTerm();
         RTPrintf("SUPTerm -> rc=%d\n", rc);
