SysHlp.cpp revision a5c612799bce18e3c0afc7ca6a111740816a75d9
381a2a9a387f449fab7d0c7e97c4184c26963abfdr/* $Revision$ */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr/** @file
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * VBoxGuestLibR0 - IDC with VBoxGuest and HGCM helpers.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr/*
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Copyright (C) 2006-2009 Sun Microsystems, Inc.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr *
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 *
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 */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#define LOG_GROUP LOG_GROUP_HGCM
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#include <VBox/log.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#include <VBox/VBoxGuestLib.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#include "SysHlp.h"
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#include <iprt/assert.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#if !defined (RT_OS_WINDOWS) \
381a2a9a387f449fab7d0c7e97c4184c26963abfdr && (!defined (RT_OS_LINUX) || defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX))
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# include <iprt/memobj.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#endif
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr/**
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Internal worker for locking a range of linear addresses.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr *
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.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr */
381a2a9a387f449fab7d0c7e97c4184c26963abfdrint vbglLockLinear (void **ppvCtx, void *pv, uint32_t u32Size, bool fWriteAccess, uint32_t fFlags)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr{
381a2a9a387f449fab7d0c7e97c4184c26963abfdr int rc = VINF_SUCCESS;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /* Zero size buffers shouldn't be locked. */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr if (u32Size == 0)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr {
381a2a9a387f449fab7d0c7e97c4184c26963abfdr Assert(pv == NULL);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#ifdef RT_OS_WINDOWS
381a2a9a387f449fab7d0c7e97c4184c26963abfdr *ppvCtx = NULL;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#else
381a2a9a387f449fab7d0c7e97c4184c26963abfdr *ppvCtx = NIL_RTR0MEMOBJ;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#endif
381a2a9a387f449fab7d0c7e97c4184c26963abfdr return VINF_SUCCESS;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr }
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
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#ifdef RT_OS_WINDOWS
381a2a9a387f449fab7d0c7e97c4184c26963abfdr PMDL pMdl = IoAllocateMdl (pv, u32Size, FALSE, FALSE, NULL);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr if (pMdl == NULL)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr {
381a2a9a387f449fab7d0c7e97c4184c26963abfdr rc = VERR_NOT_SUPPORTED;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr AssertMsgFailed(("IoAllocateMdl %p %x failed!!\n", pv, u32Size));
381a2a9a387f449fab7d0c7e97c4184c26963abfdr }
381a2a9a387f449fab7d0c7e97c4184c26963abfdr else
381a2a9a387f449fab7d0c7e97c4184c26963abfdr {
381a2a9a387f449fab7d0c7e97c4184c26963abfdr __try {
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /* Calls to MmProbeAndLockPages must be enclosed in a try/except block. */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr MmProbeAndLockPages (pMdl,
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /** @todo (fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER? UserMode: KernelMode */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr KernelMode,
381a2a9a387f449fab7d0c7e97c4184c26963abfdr (fWriteAccess) ? IoModifyAccess : IoReadAccess);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr *ppvCtx = pMdl;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
381a2a9a387f449fab7d0c7e97c4184c26963abfdr } __except(EXCEPTION_EXECUTE_HANDLER) {
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr IoFreeMdl (pMdl);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr /** @todo */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr rc = VERR_INVALID_PARAMETER;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr AssertMsgFailed(("MmProbeAndLockPages %p %x failed!!\n", pv, u32Size));
381a2a9a387f449fab7d0c7e97c4184c26963abfdr }
381a2a9a387f449fab7d0c7e97c4184c26963abfdr }
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
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 *
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * bird: this will soon be obsoleted.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr NOREF(ppvCtx);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NOREF(pv);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NOREF(u32Size);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NOREF(fFlags);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#else
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
381a2a9a387f449fab7d0c7e97c4184c26963abfdr * Lock depending on context.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr *
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.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr RTR0MEMOBJ MemObj = NIL_RTR0MEMOBJ;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ((fFlags & VBGLR0_HGCMCALL_F_MODE_MASK) == VBGLR0_HGCMCALL_F_USER)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr rc = RTR0MemObjLockUser(&MemObj, (RTR3PTR)pv, u32Size, NIL_RTR0PROCESS);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed else
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed rc = RTR0MemObjLockKernel(&MemObj, pv, u32Size);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (RT_SUCCESS(rc))
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed *ppvCtx = MemObj;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed else
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed *ppvCtx = NIL_RTR0MEMOBJ;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#endif
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return rc;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedvoid vbglUnlockLinear (void *pvCtx, void *pv, uint32_t u32Size)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NOREF(pv);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NOREF(u32Size);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#ifdef RT_OS_WINDOWS
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed PMDL pMdl = (PMDL)pvCtx;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr Assert(pMdl);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr if (pMdl != NULL)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr {
381a2a9a387f449fab7d0c7e97c4184c26963abfdr MmUnlockPages (pMdl);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr IoFreeMdl (pMdl);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr NOREF(pvCtx);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed#else
381a2a9a387f449fab7d0c7e97c4184c26963abfdr RTR0MEMOBJ MemObj = (RTR0MEMOBJ)pvCtx;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr int rc = RTR0MemObjFree(MemObj, false);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr AssertRC(rc);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#endif
381a2a9a387f449fab7d0c7e97c4184c26963abfdr}
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh
381a2a9a387f449fab7d0c7e97c4184c26963abfdr#ifndef VBGL_VBOXGUEST
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# if defined (RT_OS_LINUX) && !defined (__KERNEL__) /** @todo r=bird: What is this for?????? */
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# include <unistd.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# include <errno.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# include <sys/fcntl.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# include <sys/ioctl.h>
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# endif
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# if defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
381a2a9a387f449fab7d0c7e97c4184c26963abfdrRT_C_DECLS_BEGIN
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(void *) vboxadd_cmc_open (void);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(void) vboxadd_cmc_close (void *);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern DECLVBGL(int) vboxadd_cmc_call (void *opaque, uint32_t func, void *data);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren ReedRT_C_DECLS_END
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# endif /* RT_OS_LINUX */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# ifdef RT_OS_OS2
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren ReedRT_C_DECLS_BEGIN
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed/*
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 */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedextern VBOXGUESTOS2IDCCONNECT g_VBoxGuestIDC;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren ReedRT_C_DECLS_END
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# endif
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
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 ReedRT_C_DECLS_BEGIN
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);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren ReedRT_C_DECLS_END
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# endif
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedint vbglDriverOpen (VBGLDRIVER *pDriver)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr{
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh# ifdef RT_OS_WINDOWS
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed UNICODE_STRING uszDeviceName;
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh RtlInitUnicodeString (&uszDeviceName, L"\\Device\\VBoxGuest");
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed PDEVICE_OBJECT pDeviceObject = NULL;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed PFILE_OBJECT pFileObject = NULL;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed NTSTATUS rc = IoGetDeviceObjectPointer (&uszDeviceName, FILE_ALL_ACCESS,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed &pFileObject, &pDeviceObject);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (NT_SUCCESS (rc))
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverOpen VBoxGuest successful pDeviceObject=%x\n", pDeviceObject));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed pDriver->pDeviceObject = pDeviceObject;
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh pDriver->pFileObject = pFileObject;
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh return VINF_SUCCESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /** @todo return RTErrConvertFromNtStatus(rc)! */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverOpen VBoxGuest failed with ntstatus=%x\n", rc));
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh return rc;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed void *opaque;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed opaque = (void *) vboxadd_cmc_open ();
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if (!opaque)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return VERR_NOT_IMPLEMENTED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
381a2a9a387f449fab7d0c7e97c4184c26963abfdr pDriver->opaque = opaque;
381a2a9a387f449fab7d0c7e97c4184c26963abfdr return VINF_SUCCESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
381a2a9a387f449fab7d0c7e97c4184c26963abfdr# elif defined (RT_OS_OS2)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed /*
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed * Just check whether the connection was made or not.
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed */
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ( g_VBoxGuestIDC.u32Version == VMMDEV_VERSION
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed && VALID_PTR(g_VBoxGuestIDC.u32Session)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed && VALID_PTR(g_VBoxGuestIDC.pfnServiceEP))
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed {
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed pDriver->u32Session = g_VBoxGuestIDC.u32Session;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return VINF_SUCCESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed }
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed pDriver->u32Session = UINT32_MAX;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverOpen: failed\n"));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return VERR_FILE_NOT_FOUND;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# else
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed uint32_t u32VMMDevVersion;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed pDriver->pvOpaque = VBoxGuestIDCOpen (&u32VMMDevVersion);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed if ( pDriver->pvOpaque
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed && u32VMMDevVersion == VMMDEV_VERSION)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return VINF_SUCCESS;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverOpen: failed\n"));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return VERR_FILE_NOT_FOUND;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# endif
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# ifdef RT_OS_WINDOWS
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reedstatic NTSTATUS vbglDriverIOCtlCompletion (IN PDEVICE_OBJECT DeviceObject,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed IN PIRP Irp,
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed IN PVOID Context)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("VBGL completion %x\n", Irp));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed KEVENT *pEvent = (KEVENT *)Context;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed KeSetEvent (pEvent, IO_NO_INCREMENT, FALSE);
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed return STATUS_MORE_PROCESSING_REQUIRED;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed}
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# endif
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
381a2a9a387f449fab7d0c7e97c4184c26963abfdrint vbglDriverIOCtl (VBGLDRIVER *pDriver, uint32_t u32Function, void *pvData, uint32_t cbData)
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed{
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed Log(("vbglDriverIOCtl: pDriver: %p, Func: %x, pvData: %p, cbData: %d\n", pDriver, u32Function, pvData, cbData));
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed# ifdef RT_OS_WINDOWS
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed KEVENT Event;
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed
7ddc9b1afd18f260b9fb78ec7732facd91769131Darren Reed KeInitializeEvent (&Event, NotificationEvent, FALSE);
381a2a9a387f449fab7d0c7e97c4184c26963abfdr
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.
381a2a9a387f449fab7d0c7e97c4184c26963abfdr */
PIRP irp = IoAllocateIrp (pDriver->pDeviceObject->StackSize, FALSE);
Log(("vbglDriverIOCtl: irp %p, IRQL = %d\n", irp, KeGetCurrentIrql()));
if (irp == NULL)
{
Log(("vbglDriverIOCtl: IRP allocation failed!\n"));
return VERR_NO_MEMORY;
}
/*
* Setup the IRP_MJ_DEVICE_CONTROL IRP.
*/
PIO_STACK_LOCATION nextStack = IoGetNextIrpStackLocation (irp);
nextStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
nextStack->MinorFunction = 0;
nextStack->DeviceObject = pDriver->pDeviceObject;
nextStack->Parameters.DeviceIoControl.OutputBufferLength = cbData;
nextStack->Parameters.DeviceIoControl.InputBufferLength = cbData;
nextStack->Parameters.DeviceIoControl.IoControlCode = u32Function;
nextStack->Parameters.DeviceIoControl.Type3InputBuffer = pvData;
irp->AssociatedIrp.SystemBuffer = pvData; /* Output buffer. */
irp->MdlAddress = NULL;
/* A completion routine is required to signal the Event. */
IoSetCompletionRoutine (irp, vbglDriverIOCtlCompletion, &Event, TRUE, TRUE, TRUE);
NTSTATUS rc = IoCallDriver (pDriver->pDeviceObject, irp);
if (NT_SUCCESS (rc))
{
/* Wait the event to be signalled by the completion routine. */
KeWaitForSingleObject (&Event,
Executive,
KernelMode,
FALSE,
NULL);
rc = irp->IoStatus.Status;
Log(("vbglDriverIOCtl: wait completed IRQL = %d\n", KeGetCurrentIrql()));
}
IoFreeIrp (irp);
if (rc != STATUS_SUCCESS)
Log(("vbglDriverIOCtl: ntstatus=%x\n", rc));
return NT_SUCCESS(rc)? VINF_SUCCESS: VERR_VBGL_IOCTL_FAILED;
# elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
return vboxadd_cmc_call (pDriver->opaque, u32Function, pvData);
# elif defined (RT_OS_OS2)
if ( pDriver->u32Session
&& pDriver->u32Session == g_VBoxGuestIDC.u32Session)
return g_VBoxGuestIDC.pfnServiceEP(pDriver->u32Session, u32Function, pvData, cbData, NULL);
Log(("vbglDriverIOCtl: No connection\n"));
return VERR_WRONG_ORDER;
# else
return VBoxGuestIDCCall(pDriver->pvOpaque, u32Function, pvData, cbData, NULL);
# endif
}
void vbglDriverClose (VBGLDRIVER *pDriver)
{
# ifdef RT_OS_WINDOWS
Log(("vbglDriverClose pDeviceObject=%x\n", pDriver->pDeviceObject));
ObDereferenceObject (pDriver->pFileObject);
# elif defined (RT_OS_LINUX) && !defined (VBOX_WITH_COMMON_VBOXGUEST_ON_LINUX)
vboxadd_cmc_close (pDriver->opaque);
# elif defined (RT_OS_OS2)
pDriver->u32Session = 0;
# else
VBoxGuestIDCClose (pDriver->pvOpaque);
# endif
}
#endif /* !VBGL_VBOXGUEST */