SysHlp.cpp revision a5c612799bce18e3c0afc7ca6a111740816a75d9
381a2a9a387f449fab7d0c7e97c4184c26963abfdr/* $Revision$ */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * VBoxGuestLibR0 - IDC with VBoxGuest and HGCM helpers.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Copyright (C) 2006-2009 Sun Microsystems, Inc.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * This file is part of VirtualBox Open Source Edition (OSE), as
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * available from http://www.virtualbox.org. This file is free software;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * you can redistribute it and/or modify it under the terms of the GNU
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * General Public License (GPL) as published by the Free Software
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Foundation, in version 2 as it comes in the "COPYING" file of the
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Clara, CA 95054 USA or visit http://www.sun.com if you need
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * additional information or have any questions.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#if !defined (RT_OS_WINDOWS) \
381a2a9a387f449fab7d0c7e97c4184c26963abfdr && (!defined (RT_OS_LINUX) || defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX))
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Internal worker for locking a range of linear addresses.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * @returns VBox status code.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * @param ppvCtx Where to store context data.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * @param pv The start of the range.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * @param u32Size The size of the range.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * @param fWriteAccess Lock for read-write (true) or readonly (false).
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * @param fFlags HGCM call flags, VBGLR0_HGCM_F_XXX.
381a2a9a387f449fab7d0c7e97c4184c26963abfdrint vbglLockLinear (void **ppvCtx, void *pv, uint32_t u32Size, bool fWriteAccess, uint32_t fFlags)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /* Zero size buffers shouldn't be locked. */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /** @todo just use IPRT here. the extra allocation shouldn't matter much...
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Then we can most all this up one level even. */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr PMDL pMdl = IoAllocateMdl (pv, u32Size, FALSE, FALSE, NULL);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr AssertMsgFailed(("IoAllocateMdl %p %x failed!!\n", pv, u32Size));
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /** @todo (fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER? UserMode: KernelMode */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /** @todo */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr AssertMsgFailed(("MmProbeAndLockPages %p %x failed!!\n", pv, u32Size));
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /** @todo r=frank: Linux: pv is at least in some cases, e.g. with VBoxMapFolder,
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * an R0 address -- the memory was allocated with kmalloc(). I don't know
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * if this is true in any case.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * r=michael: on Linux, we sometimes have R3 addresses (e.g. shared
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * clipboard) and sometimes R0 (e.g. shared folders). We really ought
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * to have two separate paths here - at any rate, Linux R0 shouldn't
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * end up calling this API. In practice, Linux R3 does it's own thing
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * before winding up in the R0 path - which calls this stub API.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * bird: this will soon be obsoleted.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Lock depending on context.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Note: We will later use the memory object here to convert the HGCM
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * linear buffer paramter into a physical page list. This is why
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * we lock both kernel pages on all systems, even those where we
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * know they aren't pagable.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr rc = RTR0MemObjLockUser(&MemObj, (RTR3PTR)pv, u32Size, NIL_RTR0PROCESS);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed rc = RTR0MemObjLockKernel(&MemObj, pv, u32Size);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedvoid vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# if defined (RT_OS_LINUX) && !defined (__KERNEL__) /** @todo r=bird: What is this for?????? */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# if defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(void) vboxadd_cmc_close (void *);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# endif /* RT_OS_LINUX */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * On OS/2 we'll do the connecting in the assembly code of the
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * client driver, exporting a g_VBoxGuestIDC symbol containing
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * the connection information obtained from the 16-bit IDC.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# if !defined(RT_OS_OS2) \
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed && !defined(RT_OS_WINDOWS) \
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed && (!defined (RT_OS_LINUX) || defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX))
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(void *) VBoxGuestIDCOpen (uint32_t *pu32Version);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(void) VBoxGuestIDCClose (void *pvOpaque);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(int) VBoxGuestIDCCall (void *pvOpaque, unsigned int iCmd, void *pvData, size_t cbSize, size_t *pcbReturn);
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh RtlInitUnicodeString (&uszDeviceName, L"\\Device\\VBoxGuest");
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NTSTATUS rc = IoGetDeviceObjectPointer (&uszDeviceName, FILE_ALL_ACCESS,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /** @todo return RTErrConvertFromNtStatus(rc)! */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Just check whether the connection was made or not.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ( g_VBoxGuestIDC.u32Version == VMMDEV_VERSION
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed pDriver->u32Session = g_VBoxGuestIDC.u32Session;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed pDriver->pvOpaque = VBoxGuestIDCOpen (&u32VMMDevVersion);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic NTSTATUS vbglDriverIOCtlCompletion (IN PDEVICE_OBJECT DeviceObject,
381a2a9a387f449fab7d0c7e97c4184c26963abfdrint vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverIOCtl: pDriver: %p, Func: %x, pvData: %p, cbData: %d\n", pDriver, u32Function, pvData, cbData));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed KeInitializeEvent (&Event, NotificationEvent, FALSE);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /* Have to use the IoAllocateIRP method because this code is generic and
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * must work in any thread context.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * The IoBuildDeviceIoControlRequest, which was used here, does not work
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * when APCs are disabled, for example.
return VERR_NO_MEMORY;
NULL);
return VERR_WRONG_ORDER;
# ifdef RT_OS_WINDOWS