DECLHIDDEN(int) rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process) { AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED); /* create the object. */ const ULONG cPages = cb >> PAGE_SHIFT; PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_OFFSETOF(RTR0MEMOBJOS2, aPages[cPages]), RTR0MEMOBJTYPE_LOCK, (void *)R3Ptr, cb); if (!pMemOs2) return VERR_NO_MEMORY; /* lock it. */ ULONG cPagesRet = cPages; int rc = KernVMLock(VMDHL_LONG | (fAccess & RTMEM_PROT_WRITE ? VMDHL_WRITE : 0), (void *)R3Ptr, cb, &pMemOs2->Lock, &pMemOs2->aPages[0], &cPagesRet); if (!rc) { rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet); Assert(cb == pMemOs2->Core.cb); Assert(R3Ptr == (RTR3PTR)pMemOs2->Core.pv); pMemOs2->Core.u.Lock.R0Process = R0Process; *ppMem = &pMemOs2->Core; return VINF_SUCCESS; } rtR0MemObjDelete(&pMemOs2->Core); return RTErrConvertFromOS2(rc); }
/** * 32-bit Ring-0 init routine. * * This is called the first time somebody tries to use the IFS. * It will initialize IPRT, Vbgl and whatever else is required. * * The caller will do the necessary AttachDD and calling of the 16 bit * IDC to initialize the g_VBoxGuestIDC global. Perhaps we should move * this bit to VbglInitClient? It's just that it's so much simpler to do it * while we're on the way here... * */ DECLASM(void) VBoxSFR0Init(void) { Log(("VBoxSFR0Init: g_fpfnDevHlp=%lx u32Version=%RX32 u32Session=%RX32 pfnServiceEP=%p g_u32Info=%u (%#x)\n", g_fpfnDevHlp, g_VBoxGuestIDC.u32Version, g_VBoxGuestIDC.u32Session, g_VBoxGuestIDC.pfnServiceEP, g_u32Info, g_u32Info)); /* * Start by initializing IPRT. */ if ( g_VBoxGuestIDC.u32Version == VMMDEV_VERSION && VALID_PTR(g_VBoxGuestIDC.u32Session) && VALID_PTR(g_VBoxGuestIDC.pfnServiceEP)) { int rc = RTR0Init(0); if (RT_SUCCESS(rc)) { rc = VbglInitClient(); if (RT_SUCCESS(rc)) { #ifndef DONT_LOCK_SEGMENTS /* * Lock the 32-bit segments in memory. */ static KernVMLock_t s_Text32, s_Data32; rc = KernVMLock(VMDHL_LONG, &_text, (uintptr_t)&_etext - (uintptr_t)&_text, &s_Text32, (KernPageList_t *)-1, NULL); AssertMsg(rc == NO_ERROR, ("locking text32 failed, rc=%d\n")); rc = KernVMLock(VMDHL_LONG | VMDHL_WRITE, &_data, (uintptr_t)&_end - (uintptr_t)&_data, &s_Data32, (KernPageList_t *)-1, NULL); AssertMsg(rc == NO_ERROR, ("locking text32 failed, rc=%d\n")); #endif Log(("VBoxSFR0Init: completed successfully\n")); return; } } LogRel(("VBoxSF: RTR0Init failed, rc=%Rrc\n", rc)); } else LogRel(("VBoxSF: Failed to connect to VBoxGuest.sys.\n")); }
DECLHIDDEN(int) rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess) { /* create the object. */ const ULONG cPages = cb >> PAGE_SHIFT; PRTR0MEMOBJOS2 pMemOs2 = (PRTR0MEMOBJOS2)rtR0MemObjNew(RT_OFFSETOF(RTR0MEMOBJOS2, aPages[cPages]), RTR0MEMOBJTYPE_LOCK, pv, cb); if (!pMemOs2) return VERR_NO_MEMORY; /* lock it. */ ULONG cPagesRet = cPages; int rc = KernVMLock(VMDHL_LONG | (fAccess & RTMEM_PROT_WRITE ? VMDHL_WRITE : 0), pv, cb, &pMemOs2->Lock, &pMemOs2->aPages[0], &cPagesRet); if (!rc) { rtR0MemObjFixPageList(&pMemOs2->aPages[0], cPages, cPagesRet); pMemOs2->Core.u.Lock.R0Process = NIL_RTR0PROCESS; *ppMem = &pMemOs2->Core; return VINF_SUCCESS; } rtR0MemObjDelete(&pMemOs2->Core); return RTErrConvertFromOS2(rc); }
DECLASM(int) VBoxDrvIOCtl(uint16_t sfn, uint8_t iCat, uint8_t iFunction, void *pvParm, void *pvData, uint16_t *pcbParm, uint16_t *pcbData) { /* * Find the session. */ const RTPROCESS Process = RTProcSelf(); const unsigned iHash = SESSION_HASH(sfn); PSUPDRVSESSION pSession; RTSpinlockAcquire(g_Spinlock); pSession = g_apSessionHashTab[iHash]; if (pSession && pSession->Process != Process) { do pSession = pSession->pNextHash; while ( pSession && ( pSession->sfn != sfn || pSession->Process != Process)); if (RT_LIKELY(pSession)) supdrvSessionRetain(pSession); } RTSpinlockReleaseNoInts(g_Spinlock); if (!pSession) { OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d\n", (int)Process)); return VERR_INVALID_PARAMETER; } /* * Verify the category and dispatch the IOCtl. */ if (RT_LIKELY(iCat == SUP_CTL_CATEGORY)) { Log(("VBoxDrvIOCtl: pSession=%p iFunction=%#x pvParm=%p pvData=%p *pcbParm=%d *pcbData=%d\n", pSession, iFunction, pvParm, pvData, *pcbParm, *pcbData)); Assert(pvParm); Assert(!pvData); /* * Lock the header. */ PSUPREQHDR pHdr = (PSUPREQHDR)pvParm; AssertReturn(*pcbParm == sizeof(*pHdr), VERR_INVALID_PARAMETER); KernVMLock_t Lock; int rc = KernVMLock(VMDHL_WRITE, pHdr, *pcbParm, &Lock, (KernPageList_t *)-1, NULL); AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, *pcbParm, &Lock, rc), VERR_LOCK_FAILED); /* * Validate the header. */ if (RT_LIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) == SUPREQHDR_FLAGS_MAGIC)) { uint32_t cbReq = RT_MAX(pHdr->cbIn, pHdr->cbOut); if (RT_LIKELY( pHdr->cbIn >= sizeof(*pHdr) && pHdr->cbOut >= sizeof(*pHdr) && cbReq <= _1M*16)) { /* * Lock the rest of the buffer if necessary. */ if (((uintptr_t)pHdr & PAGE_OFFSET_MASK) + cbReq > PAGE_SIZE) { rc = KernVMUnlock(&Lock); AssertMsgReturn(!rc, ("KernVMUnlock(Lock) -> %#x\n", rc), VERR_LOCK_FAILED); rc = KernVMLock(VMDHL_WRITE, pHdr, cbReq, &Lock, (KernPageList_t *)-1, NULL); AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, cbReq, &Lock, rc), VERR_LOCK_FAILED); } /* * Process the IOCtl. */ rc = supdrvIOCtl(iFunction, &g_DevExt, pSession, pHdr); } else { OSDBGPRINT(("VBoxDrvIOCtl: max(%#x,%#x); iCmd=%#x\n", pHdr->cbIn, pHdr->cbOut, iFunction)); rc = VERR_INVALID_PARAMETER; } } else { OSDBGPRINT(("VBoxDrvIOCtl: bad magic fFlags=%#x; iCmd=%#x\n", pHdr->fFlags, iFunction)); rc = VERR_INVALID_PARAMETER; } /* * Unlock and return. */ int rc2 = KernVMUnlock(&Lock); AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);s }