summaryrefslogtreecommitdiff
path: root/src/VBox/Additions/common/VBoxGuest
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Additions/common/VBoxGuest
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Additions/common/VBoxGuest')
-rw-r--r--src/VBox/Additions/common/VBoxGuest/Makefile.kmk46
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxDev-haiku.c446
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp1085
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c448
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c553
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.h226
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c16
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp4
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.conf2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-legacy.cpp202
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp252
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp902
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h115
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp343
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm4
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h19
-rw-r--r--src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h34
-rw-r--r--src/VBox/Additions/common/VBoxGuest/darwin/Info.plist50
-rw-r--r--src/VBox/Additions/common/VBoxGuest/freebsd/Makefile2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/linux/Makefile4
-rwxr-xr-xsrc/VBox/Additions/common/VBoxGuest/linux/files_vboxguest2
-rw-r--r--src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf7
-rw-r--r--src/VBox/Additions/common/VBoxGuest/win/VBoxGuestInst.cpp83
-rw-r--r--src/VBox/Additions/common/VBoxGuest/win/VBoxGuestMsg.mc60
27 files changed, 3986 insertions, 925 deletions
diff --git a/src/VBox/Additions/common/VBoxGuest/Makefile.kmk b/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
index 8ff81a91..ecaa22c4 100644
--- a/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
+++ b/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
@@ -19,22 +19,26 @@ SUB_DEPTH = ../../../../..
include $(KBUILD_PATH)/subheader.kmk
-if1of ($(KBUILD_TARGET), freebsd $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
+if1of ($(KBUILD_TARGET), darwin freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
#
# VBoxGuest - The Guest Additions Driver.
#
SYSMODS += VBoxGuest
VBoxGuest_TEMPLATE = VBOXGUESTR0
VBoxGuest_NAME.freebsd = vboxguest
+ VBoxGuest_NAME.haiku = vboxguest
VBoxGuest_NAME.linux = vboxguest
VBoxGuest_NAME.solaris = vboxguest
+ VBoxGuest_INST.darwin = $(INST_ADDITIONS)VBoxGuest.kext/Contents/MacOS/
ifdef VBOX_SIGN_ADDITIONS # See Additions/WINNT/Makefile.kmk?
VBoxGuest_INSTTYPE.win = none
VBoxGuest_DEBUG_INSTTYPE.win = both
endif
+ VBoxGuest_DEFS.haiku = VBOX_SVN_REV=$(VBOX_SVN_REV) _KERNEL_MODE=1
VBoxGuest_DEFS.linux = KBUILD_MODNAME=KBUILD_STR\(vboxguest\) KBUILD_BASENAME=KBUILD_STR\(vboxguest\) DEBUG_HASH=2 DEBUG_HASH2=3 EXPORT_SYMTAB
VBoxGuest_DEFS.solaris = VBOX_SVN_REV=$(VBOX_SVN_REV)
VBoxGuest_DEFS.win = # VBOX_WITH_VRDP_SESSION_HANDLING
+ VBoxGuest_DEFS.darwin = VBOX_GUESTDRV_WITH_RELEASE_LOGGER
ifeq ($(KBUILD_TYPE),release)
# Allow stopping/removing the driver without a reboot
# in debug mode; this is very useful for testing the shutdown stuff!
@@ -48,7 +52,9 @@ if1of ($(KBUILD_TARGET), freebsd $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linu
$(if $(VBOX_WITH_DPC_LATENCY_CHECKER),VBOX_WITH_DPC_LATENCY_CHECKER,)
VBoxGuest_DEPS.solaris += $(VBOX_SVN_REV_KMK)
VBoxGuest_DEPS.linux += $(VBOX_SVN_REV_HEADER)
+ VBoxGuest_DEPS.haiku += $(VBOX_SVN_REV_HEADER)
VBoxGuest_DEPS.freebsd += $(VBOX_SVN_REV_HEADER)
+ VBoxGuest_DEPS.darwin += $(VBOX_SVN_REV_HEADER)
VBoxGuest_DEFS = VBGL_VBOXGUEST VBOX_WITH_HGCM
VBoxGuest_INCS = .
VBoxGuest_INCS.freebsd = $(VBoxGuest_0_OUTDIR) $(PATH_STAGE)/gen-sys-hdrs
@@ -74,7 +80,7 @@ if1of ($(KBUILD_TARGET), freebsd $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linu
VBoxGuest.cpp_SDKS = $(VBOX_WINDDK_GST_WLH)
endif
endif # win
- ifn1of ($(KBUILD_TARGET), linux freebsd solaris)
+ ifn1of ($(KBUILD_TARGET), linux freebsd solaris haiku)
VBoxGuest_SOURCES = VBoxGuest-$(KBUILD_TARGET).cpp
else
VBoxGuest_SOURCES = VBoxGuest-$(KBUILD_TARGET).c
@@ -94,6 +100,16 @@ if1of ($(KBUILD_TARGET), freebsd $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linu
$(PATH_STAGE)/gen-sys-hdrs/pci_if.h \
$(PATH_STAGE)/gen-sys-hdrs/bus_if.h \
$(PATH_STAGE)/gen-sys-hdrs/device_if.h
+ ifeq ($(KBUILD_TARGET),haiku)
+ # Haiku drivers cannot export symbols for other drivers, but modules can.
+ # Therefore vboxguest is a module containing the ring-0 guest lib, and vboxdev/vboxsf
+ # use this module to access the guest lib
+ SYSMODS += VBoxDev
+ VBoxDev_TEMPLATE = VBOXGUESTR0
+ VBoxDev_NAME = vboxdev
+ VBoxDev_DEFS = VBOX_SVN_REV=$(VBOX_SVN_REV) _KERNEL_MODE=1 VBGL_VBOXGUEST VBOX_WITH_HGCM IN_RING0
+ VBoxDev_SOURCES = VBoxDev-haiku.c VBoxGuest-haiku-stubs.c
+ endif
else # OS/2:
# The library order is crucial, so a bit of trickery is necessary.
# A library is used to make sure that VBoxGuestA-os2.asm is first in the link. (temporary hack?)
@@ -151,6 +167,32 @@ if1of ($(KBUILD_TARGET), freebsd $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linu
endif # win
endif # enabled
+
+ifeq ($(KBUILD_TARGET), darwin)
+ # Files necessary to make a darwin kernel extension bundle.
+ INSTALLS += VBoxGuest.kext
+ VBoxGuest.kext_INST = $(INST_ADDITIONS)/VBoxGuest.kext/Contents/
+ VBoxGuest.kext_SOURCES = $(VBoxGuest.kext_0_OUTDIR)/Info.plist
+ VBoxGuest.kext_CLEAN = $(VBoxGuest.kext_0_OUTDIR)/Info.plist
+
+$$(VBoxGuest.kext_0_OUTDIR)/Info.plist: \
+ $(PATH_SUB_CURRENT)/darwin/Info.plist \
+ $(VBOX_VERSION_MK) | $$(dir $$@)
+ $(call MSG_GENERATE,VBoxGuest,$@,$<)
+ $(QUIET)$(RM) -f $@
+ $(QUIET)$(SED) \
+ -e 's/@VBOX_VERSION_STRING@/$(VBOX_VERSION_STRING)/g' \
+ -e 's/@VBOX_VERSION_MAJOR@/$(VBOX_VERSION_MAJOR)/g' \
+ -e 's/@VBOX_VERSION_MINOR@/$(VBOX_VERSION_MINOR)/g' \
+ -e 's/@VBOX_VERSION_BUILD@/$(VBOX_VERSION_BUILD)/g' \
+ -e 's/@VBOX_VENDOR@/$(VBOX_VENDOR)/g' \
+ -e 's/@VBOX_PRODUCT@/$(VBOX_PRODUCT)/g' \
+ -e 's/@VBOX_C_YEAR@/$(VBOX_C_YEAR)/g' \
+ --output $@ \
+ $<
+endif # darwin
+
+
ifeq ($(KBUILD_TARGET),linux)
#
# Install the source files and script(s).
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxDev-haiku.c b/src/VBox/Additions/common/VBoxGuest/VBoxDev-haiku.c
new file mode 100644
index 00000000..82163323
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxDev-haiku.c
@@ -0,0 +1,446 @@
+/* $Id: VBoxDev-haiku.c $ */
+/** @file
+ * VBoxGuest kernel driver, Haiku Guest Additions, implementation.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <OS.h>
+#include <Drivers.h>
+#include <KernelExport.h>
+#include <PCI.h>
+
+#include "VBoxGuest-haiku.h"
+#include "VBoxGuestInternal.h"
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/initterm.h>
+#include <iprt/process.h>
+#include <iprt/mem.h>
+#include <iprt/asm.h>
+
+#define DRIVER_NAME "vboxdev"
+#define DEVICE_NAME "misc/vboxguest"
+#define MODULE_NAME "generic/vboxguest"
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+static status_t VBoxGuestHaikuOpen(const char *name, uint32 flags, void **cookie);
+static status_t VBoxGuestHaikuClose(void *cookie);
+static status_t VBoxGuestHaikuFree(void *cookie);
+static status_t VBoxGuestHaikuIOCtl(void *cookie, uint32 op, void *data, size_t len);
+static status_t VBoxGuestHaikuSelect(void *cookie, uint8 event, uint32 ref, selectsync *sync);
+static status_t VBoxGuestHaikuDeselect(void *cookie, uint8 event, selectsync *sync);
+static status_t VBoxGuestHaikuWrite(void *cookie, off_t position, const void *data, size_t *numBytes);
+static status_t VBoxGuestHaikuRead(void *cookie, off_t position, void *data, size_t *numBytes);
+
+static device_hooks g_VBoxGuestHaikuDeviceHooks =
+{
+ VBoxGuestHaikuOpen,
+ VBoxGuestHaikuClose,
+ VBoxGuestHaikuFree,
+ VBoxGuestHaikuIOCtl,
+ VBoxGuestHaikuRead,
+ VBoxGuestHaikuWrite,
+ VBoxGuestHaikuSelect,
+ VBoxGuestHaikuDeselect,
+};
+
+
+/**
+ * Driver open hook.
+ *
+ * @param name The name of the device as returned by publish_devices.
+ * @param flags Open flags.
+ * @param cookie Where to store the session pointer.
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuOpen(const char *name, uint32 flags, void **cookie)
+{
+ int rc;
+ PVBOXGUESTSESSION pSession;
+
+ LogFlow((DRIVER_NAME ":VBoxGuestHaikuOpen\n"));
+
+ /*
+ * Create a new session.
+ */
+ rc = VBoxGuestCreateUserSession(&g_DevExt, &pSession);
+ if (RT_SUCCESS(rc))
+ {
+ Log((DRIVER_NAME ":VBoxGuestHaikuOpen success: g_DevExt=%p pSession=%p rc=%d pid=%d\n",&g_DevExt, pSession, rc,(int)RTProcSelf()));
+ ASMAtomicIncU32(&cUsers);
+ *cookie = pSession;
+ return B_OK;
+ }
+
+ LogRel((DRIVER_NAME ":VBoxGuestHaikuOpen: failed. rc=%d\n", rc));
+ return RTErrConvertToErrno(rc);
+}
+
+
+/**
+ * Driver close hook.
+ * @param cookie The session.
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuClose(void *cookie)
+{
+ PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
+ Log(("VBoxGuestHaikuClose: pSession=%p\n", pSession));
+
+ /** @todo r=ramshankar: should we really be using the session spinlock here? */
+ RTSpinlockAcquire(g_DevExt.SessionSpinlock);
+
+ /* @todo we don't know if it belongs to this session!! */
+ if (sState.selectSync)
+ {
+ //dprintf(DRIVER_NAME "close: unblocking select %p %x\n", sState.selectSync, sState.selectEvent);
+ notify_select_event(sState.selectSync, sState.selectEvent);
+ sState.selectEvent = (uint8_t)0;
+ sState.selectRef = (uint32_t)0;
+ sState.selectSync = (void *)NULL;
+ }
+
+ RTSpinlockRelease(g_DevExt.SessionSpinlock);
+ return B_OK;
+}
+
+
+/**
+ * Driver free hook.
+ * @param cookie The session.
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuFree(void *cookie)
+{
+ PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
+ Log(("VBoxGuestHaikuFree: pSession=%p\n", pSession));
+
+ /*
+ * Close the session if it's still hanging on to the device...
+ */
+ if (VALID_PTR(pSession))
+ {
+ VBoxGuestCloseSession(&g_DevExt, pSession);
+ ASMAtomicDecU32(&cUsers);
+ }
+ else
+ Log(("VBoxGuestHaikuFree: si_drv1=%p!\n", pSession));
+ return B_OK;
+}
+
+
+/**
+ * Driver IOCtl entry.
+ * @param cookie The session.
+ * @param op The operation to perform.
+ * @param data The data associated with the operation.
+ * @param len Size of the data in bytes.
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuIOCtl(void *cookie, uint32 op, void *data, size_t len)
+{
+ PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
+ Log((DRIVER_NAME ":VBoxGuestHaikuIOCtl cookie=%p op=0x%08x data=%p len=%lu)\n", cookie, op, data, len));
+
+ int rc = B_OK;
+
+ /*
+ * Validate the input.
+ */
+ if (RT_UNLIKELY(!VALID_PTR(pSession)))
+ return EINVAL;
+
+ /*
+ * Validate the request wrapper.
+ */
+#if 0
+ if (IOCPARM_LEN(ulCmd) != sizeof(VBGLBIGREQ))
+ {
+ Log((DRIVER_NAME ": VBoxGuestHaikuIOCtl: bad request %lu size=%lu expected=%d\n", ulCmd, IOCPARM_LEN(ulCmd),
+ sizeof(VBGLBIGREQ)));
+ return ENOTTY;
+ }
+#endif
+
+ if (RT_UNLIKELY(len > _1M * 16))
+ {
+ dprintf(DRIVER_NAME ": VBoxGuestHaikuIOCtl: bad size %#x; pArg=%p Cmd=%lu.\n", (unsigned)len, data, op);
+ return EINVAL;
+ }
+
+ /*
+ * Read the request.
+ */
+ void *pvBuf = NULL;
+ if (RT_LIKELY(len > 0))
+ {
+ pvBuf = RTMemTmpAlloc(len);
+ if (RT_UNLIKELY(!pvBuf))
+ {
+ LogRel((DRIVER_NAME ":VBoxGuestHaikuIOCtl: RTMemTmpAlloc failed to alloc %d bytes.\n", len));
+ return ENOMEM;
+ }
+
+ /** @todo r=ramshankar: replace with RTR0MemUserCopyFrom() */
+ rc = user_memcpy(pvBuf, data, len);
+ if (RT_UNLIKELY(rc < 0))
+ {
+ RTMemTmpFree(pvBuf);
+ LogRel((DRIVER_NAME ":VBoxGuestHaikuIOCtl: user_memcpy failed; pvBuf=%p data=%p op=%d. rc=%d\n", pvBuf, data, op, rc));
+ return EFAULT;
+ }
+ if (RT_UNLIKELY(!VALID_PTR(pvBuf)))
+ {
+ RTMemTmpFree(pvBuf);
+ LogRel((DRIVER_NAME ":VBoxGuestHaikuIOCtl: pvBuf invalid pointer %p\n", pvBuf));
+ return EINVAL;
+ }
+ }
+ Log((DRIVER_NAME ":VBoxGuestHaikuIOCtl: pSession=%p pid=%d.\n", pSession,(int)RTProcSelf()));
+
+ /*
+ * Process the IOCtl.
+ */
+ size_t cbDataReturned;
+ rc = VBoxGuestCommonIOCtl(op, &g_DevExt, pSession, pvBuf, len, &cbDataReturned);
+ if (RT_SUCCESS(rc))
+ {
+ rc = 0;
+ if (RT_UNLIKELY(cbDataReturned > len))
+ {
+ Log((DRIVER_NAME ":VBoxGuestHaikuIOCtl: too much output data %d expected %d\n", cbDataReturned, len));
+ cbDataReturned = len;
+ }
+ if (cbDataReturned > 0)
+ {
+ rc = user_memcpy(data, pvBuf, cbDataReturned);
+ if (RT_UNLIKELY(rc < 0))
+ {
+ Log((DRIVER_NAME ":VBoxGuestHaikuIOCtl: user_memcpy failed; pvBuf=%p pArg=%p Cmd=%lu. rc=%d\n", pvBuf, data, op, rc));
+ rc = EFAULT;
+ }
+ }
+ }
+ else
+ {
+ Log((DRIVER_NAME ":VBoxGuestHaikuIOCtl: VBoxGuestCommonIOCtl failed. rc=%d\n", rc));
+ rc = EFAULT;
+ }
+ RTMemTmpFree(pvBuf);
+ return rc;
+}
+
+
+/**
+ * Driver select hook.
+ *
+ * @param cookie The session.
+ * @param event The event.
+ * @param ref ???
+ * @param sync ???
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuSelect(void *cookie, uint8 event, uint32 ref, selectsync *sync)
+{
+ PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
+ status_t err = B_OK;
+
+ switch (event)
+ {
+ case B_SELECT_READ:
+ break;
+ default:
+ return EINVAL;
+ }
+
+ RTSpinlockAcquire(g_DevExt.SessionSpinlock);
+
+ uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
+ if (pSession->u32MousePosChangedSeq != u32CurSeq)
+ {
+ pSession->u32MousePosChangedSeq = u32CurSeq;
+ notify_select_event(sync, event);
+ }
+ else if (sState.selectSync == NULL)
+ {
+ sState.selectEvent = (uint8_t)event;
+ sState.selectRef = (uint32_t)ref;
+ sState.selectSync = (void *)sync;
+ }
+ else
+ err = B_WOULD_BLOCK;
+
+ RTSpinlockRelease(g_DevExt.SessionSpinlock);
+
+ return err;
+}
+
+
+/**
+ * Driver deselect hook.
+ * @param cookie The session.
+ * @param event The event.
+ * @param sync ???
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuDeselect(void *cookie, uint8 event, selectsync *sync)
+{
+ PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
+ status_t err = B_OK;
+ //dprintf(DRIVER_NAME "deselect(,%d,%p)\n", event, sync);
+
+ RTSpinlockAcquire(g_DevExt.SessionSpinlock);
+
+ if (sState.selectSync == sync)
+ {
+ //dprintf(DRIVER_NAME "deselect: dropping: %p %x\n", sState.selectSync, sState.selectEvent);
+ sState.selectEvent = (uint8_t)0;
+ sState.selectRef = (uint32_t)0;
+ sState.selectSync = NULL;
+ }
+ else
+ err = B_OK;
+
+ RTSpinlockRelease(g_DevExt.SessionSpinlock);
+ return err;
+}
+
+
+/**
+ * Driver write hook.
+ * @param cookie The session.
+ * @param position The offset.
+ * @param data Pointer to the data.
+ * @param numBytes Where to store the number of bytes written.
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuWrite(void *cookie, off_t position, const void *data, size_t *numBytes)
+{
+ *numBytes = 0;
+ return B_OK;
+}
+
+
+/**
+ * Driver read hook.
+ * @param cookie The session.
+ * @param position The offset.
+ * @param data Pointer to the data.
+ * @param numBytes Where to store the number of bytes read.
+ *
+ * @return Haiku status code.
+ */
+static status_t VBoxGuestHaikuRead(void *cookie, off_t position, void *data, size_t *numBytes)
+{
+ PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie;
+
+ if (*numBytes == 0)
+ return B_OK;
+
+ uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq);
+ if (pSession->u32MousePosChangedSeq != u32CurSeq)
+ {
+ pSession->u32MousePosChangedSeq = u32CurSeq;
+ *numBytes = 1;
+ return B_OK;
+ }
+
+ *numBytes = 0;
+ return B_OK;
+}
+
+
+int32 api_version = B_CUR_DRIVER_API_VERSION;
+
+status_t init_hardware()
+{
+ return get_module(MODULE_NAME, (module_info **)&g_VBoxGuest);
+}
+
+status_t init_driver()
+{
+ return B_OK;
+}
+
+device_hooks* find_device(const char *name)
+{
+ static device_hooks g_VBoxGuestHaikuDeviceHooks =
+ {
+ VBoxGuestHaikuOpen,
+ VBoxGuestHaikuClose,
+ VBoxGuestHaikuFree,
+ VBoxGuestHaikuIOCtl,
+ VBoxGuestHaikuRead,
+ VBoxGuestHaikuWrite,
+ VBoxGuestHaikuSelect,
+ VBoxGuestHaikuDeselect
+ };
+ return &g_VBoxGuestHaikuDeviceHooks;
+}
+
+const char** publish_devices()
+{
+ static const char *devices[] = { DEVICE_NAME, NULL };
+ return devices;
+}
+
+void uninit_driver()
+{
+ put_module(MODULE_NAME);
+}
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp
new file mode 100644
index 00000000..3eb7dab4
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-darwin.cpp
@@ -0,0 +1,1085 @@
+/* $Id: VBoxGuest-darwin.cpp $ */
+/** @file
+ * VBoxGuest - Darwin Specifics.
+ */
+
+/*
+ * Copyright (C) 2006-2013 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define LOG_GROUP LOG_GROUP_VBGD
+/*
+ * Deal with conflicts first.
+ * PVM - BSD mess, that FreeBSD has correct a long time ago.
+ * iprt/types.h before sys/param.h - prevents UINT32_C and friends.
+ */
+#include <iprt/types.h>
+#include <sys/param.h>
+#undef PVM
+
+#include <IOKit/IOLib.h> /* Assert as function */
+
+#include <VBox/version.h>
+#include <iprt/asm.h>
+#include <iprt/initterm.h>
+#include <iprt/assert.h>
+#include <iprt/spinlock.h>
+#include <iprt/semaphore.h>
+#include <iprt/process.h>
+#include <iprt/alloc.h>
+#include <iprt/power.h>
+#include <VBox/err.h>
+#include <VBox/log.h>
+
+#include <mach/kmod.h>
+#include <miscfs/devfs/devfs.h>
+#include <sys/conf.h>
+#include <sys/errno.h>
+#include <sys/ioccom.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/kauth.h>
+#include <IOKit/IOService.h>
+#include <IOKit/IOUserClient.h>
+#include <IOKit/pwr_mgt/RootDomain.h>
+#include <IOKit/pci/IOPCIDevice.h>
+#include <IOKit/IOBufferMemoryDescriptor.h>
+#include <IOKit/IOFilterInterruptEventSource.h>
+#include "VBoxGuestInternal.h"
+
+
+/*******************************************************************************
+* Defined Constants And Macros *
+*******************************************************************************/
+
+/** The system device node name. */
+#define DEVICE_NAME_SYS "vboxguest"
+/** The user device node name. */
+#define DEVICE_NAME_USR "vboxguestu"
+
+
+
+/*******************************************************************************
+* Internal Functions *
+*******************************************************************************/
+RT_C_DECLS_BEGIN
+static kern_return_t VbgdDarwinStart(struct kmod_info *pKModInfo, void *pvData);
+static kern_return_t VbgdDarwinStop(struct kmod_info *pKModInfo, void *pvData);
+static int VbgdDarwinCharDevRemove(void);
+
+static int VbgdDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
+static int VbgdDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess);
+static int VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess);
+static int VbgdDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess);
+
+static int VbgdDarwinErr2DarwinErr(int rc);
+
+static IOReturn VbgdDarwinSleepHandler(void *pvTarget, void *pvRefCon, UInt32 uMessageType, IOService *pProvider, void *pvMessageArgument, vm_size_t argSize);
+RT_C_DECLS_END
+
+
+/*******************************************************************************
+* Structures and Typedefs *
+*******************************************************************************/
+/**
+ * The service class for handling the VMMDev PCI device.
+ *
+ * Instantiated when the module is loaded (and on PCI hotplugging?).
+ */
+class org_virtualbox_VBoxGuest : public IOService
+{
+ OSDeclareDefaultStructors(org_virtualbox_VBoxGuest);
+
+private:
+ IOPCIDevice *m_pIOPCIDevice;
+ IOMemoryMap *m_pMap;
+ IOFilterInterruptEventSource *m_pInterruptSrc;
+
+ bool setupVmmDevInterrupts(IOService *pProvider);
+ bool disableVmmDevInterrupts(void);
+ bool isVmmDev(IOPCIDevice *pIOPCIDevice);
+
+public:
+ virtual bool start(IOService *pProvider);
+ virtual void stop(IOService *pProvider);
+ virtual bool terminate(IOOptionBits fOptions);
+};
+
+OSDefineMetaClassAndStructors(org_virtualbox_VBoxGuest, IOService);
+
+
+/**
+ * An attempt at getting that clientDied() notification.
+ * I don't think it'll work as I cannot figure out where/what creates the correct
+ * port right.
+ *
+ * Instantiated when userland does IOServiceOpen().
+ */
+class org_virtualbox_VBoxGuestClient : public IOUserClient
+{
+ OSDeclareDefaultStructors(org_virtualbox_VBoxGuestClient);
+
+private:
+ PVBOXGUESTSESSION m_pSession; /**< The session. */
+ task_t m_Task; /**< The client task. */
+ org_virtualbox_VBoxGuest *m_pProvider; /**< The service provider. */
+
+public:
+ virtual bool initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type);
+ virtual bool start(IOService *pProvider);
+ static void sessionClose(RTPROCESS Process);
+ virtual IOReturn clientClose(void);
+};
+
+OSDefineMetaClassAndStructors(org_virtualbox_VBoxGuestClient, IOUserClient);
+
+
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/**
+ * Declare the module stuff.
+ */
+RT_C_DECLS_BEGIN
+extern kern_return_t _start(struct kmod_info *pKModInfo, void *pvData);
+extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
+
+KMOD_EXPLICIT_DECL(VBoxGuest, VBOX_VERSION_STRING, _start, _stop)
+DECLHIDDEN(kmod_start_func_t *) _realmain = VbgdDarwinStart;
+DECLHIDDEN(kmod_stop_func_t *) _antimain = VbgdDarwinStop;
+DECLHIDDEN(int) _kext_apple_cc = __APPLE_CC__;
+RT_C_DECLS_END
+
+
+/**
+ * Device extention & session data association structure.
+ */
+static VBOXGUESTDEVEXT g_DevExt;
+
+/**
+ * The character device switch table for the driver.
+ */
+static struct cdevsw g_DevCW =
+{
+ /*.d_open = */ VbgdDarwinOpen,
+ /*.d_close = */ VbgdDarwinClose,
+ /*.d_read = */ eno_rdwrt,
+ /*.d_write = */ eno_rdwrt,
+ /*.d_ioctl = */ VbgdDarwinIOCtl,
+ /*.d_stop = */ eno_stop,
+ /*.d_reset = */ eno_reset,
+ /*.d_ttys = */ NULL,
+ /*.d_select = */ eno_select,
+ /*.d_mmap = */ eno_mmap,
+ /*.d_strategy = */ eno_strat,
+ /*.d_getc = */ eno_getc,
+ /*.d_putc = */ eno_putc,
+ /*.d_type = */ 0
+};
+
+/** Major device number. */
+static int g_iMajorDeviceNo = -1;
+/** Registered devfs device handle. */
+static void *g_hDevFsDeviceSys = NULL;
+/** Registered devfs device handle for the user device. */
+static void *g_hDevFsDeviceUsr = NULL; /**< @todo 4 later */
+
+/** Spinlock protecting g_apSessionHashTab. */
+static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
+/** Hash table */
+static PVBOXGUESTSESSION g_apSessionHashTab[19];
+/** Calculates the index into g_apSessionHashTab.*/
+#define SESSION_HASH(pid) ((pid) % RT_ELEMENTS(g_apSessionHashTab))
+/** The number of open sessions. */
+static int32_t volatile g_cSessions = 0;
+/** The number of IOService class instances. */
+static bool volatile g_fInstantiated = 0;
+/** The notifier handle for the sleep callback handler. */
+static IONotifier *g_pSleepNotifier = NULL;
+
+
+
+/**
+ * Start the kernel module.
+ */
+static kern_return_t VbgdDarwinStart(struct kmod_info *pKModInfo, void *pvData)
+{
+#ifdef DEBUG
+ printf("VbgdDarwinStart\n");
+#endif
+
+ /*
+ * Initialize IPRT.
+ */
+ int rc = RTR0Init(0);
+ if (RT_FAILURE(rc))
+ {
+ printf("VBoxGuest: RTR0Init failed with rc=%d\n", rc);
+ return KMOD_RETURN_FAILURE;
+ }
+
+ return KMOD_RETURN_SUCCESS;
+}
+
+
+/* Register VBoxGuest char device */
+static int VbgdDarwinCharDevInit(void)
+{
+ int rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestDarwin");
+ if (RT_FAILURE(rc))
+ {
+ return KMOD_RETURN_FAILURE;
+ }
+
+ /*
+ * Registering ourselves as a character device.
+ */
+ g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
+ if (g_iMajorDeviceNo < 0)
+ {
+ VbgdDarwinCharDevRemove();
+ return KMOD_RETURN_FAILURE;
+ }
+
+ g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
+ UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
+ if (!g_hDevFsDeviceSys)
+ {
+ VbgdDarwinCharDevRemove();
+ return KMOD_RETURN_FAILURE;
+ }
+
+ /* Register a sleep/wakeup notification callback */
+ g_pSleepNotifier = registerPrioritySleepWakeInterest(&VbgdDarwinSleepHandler, &g_DevExt, NULL);
+ if (g_pSleepNotifier == NULL)
+ {
+ VbgdDarwinCharDevRemove();
+ return KMOD_RETURN_FAILURE;
+ }
+
+ return KMOD_RETURN_SUCCESS;
+}
+
+
+/**
+ * Stop the kernel module.
+ */
+static kern_return_t VbgdDarwinStop(struct kmod_info *pKModInfo, void *pvData)
+{
+ RTR0TermForced();
+#ifdef DEBUG
+ printf("VbgdDarwinStop - done\n");
+#endif
+ return KMOD_RETURN_SUCCESS;
+}
+
+
+/* Unregister VBoxGuest char device */
+static int
+VbgdDarwinCharDevRemove(void)
+{
+ int rc = KMOD_RETURN_SUCCESS;
+
+ if (g_pSleepNotifier)
+ {
+ g_pSleepNotifier->remove();
+ g_pSleepNotifier = NULL;
+ }
+
+ if (g_hDevFsDeviceSys)
+ {
+ devfs_remove(g_hDevFsDeviceSys);
+ g_hDevFsDeviceSys = NULL;
+ }
+
+ if (g_hDevFsDeviceUsr)
+ {
+ devfs_remove(g_hDevFsDeviceUsr);
+ g_hDevFsDeviceUsr = NULL;
+ }
+
+ if (g_iMajorDeviceNo != -1)
+ {
+ int rc2 = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
+ Assert(rc2 == g_iMajorDeviceNo);
+ g_iMajorDeviceNo = -1;
+ }
+
+ if (g_Spinlock != NIL_RTSPINLOCK)
+ {
+ int rc2 = RTSpinlockDestroy(g_Spinlock); AssertRC(rc2);
+ g_Spinlock = NIL_RTSPINLOCK;
+ }
+
+ return rc;
+}
+
+
+/**
+ * Device open. Called on open /dev/vboxguest and (later) /dev/vboxguestu.
+ *
+ * @param Dev The device number.
+ * @param fFlags ???.
+ * @param fDevType ???.
+ * @param pProcess The process issuing this request.
+ */
+static int VbgdDarwinOpen(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
+{
+ /*
+ * Only two minor devices numbers are allowed.
+ */
+ if (minor(Dev) != 0 && minor(Dev) != 1)
+ return EACCES;
+
+ /*
+ * Find the session created by org_virtualbox_VBoxGuestClient, fail
+ * if no such session, and mark it as opened. We set the uid & gid
+ * here too, since that is more straight forward at this point.
+ */
+ //const bool fUnrestricted = minor(Dev) == 0;
+ int rc = VINF_SUCCESS;
+ PVBOXGUESTSESSION pSession = NULL;
+ kauth_cred_t pCred = kauth_cred_proc_ref(pProcess);
+ if (pCred)
+ {
+ RTPROCESS Process = RTProcSelf();
+ unsigned iHash = SESSION_HASH(Process);
+ RTSpinlockAcquire(g_Spinlock);
+
+ pSession = g_apSessionHashTab[iHash];
+ while (pSession && pSession->Process != Process)
+ pSession = pSession->pNextHash;
+ if (pSession)
+ {
+ if (!pSession->fOpened)
+ {
+ pSession->fOpened = true;
+ /*pSession->fUnrestricted = fUnrestricted; - later */
+ }
+ else
+ rc = VERR_ALREADY_LOADED;
+ }
+ else
+ rc = VERR_GENERAL_FAILURE;
+
+ RTSpinlockReleaseNoInts(g_Spinlock);
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
+ kauth_cred_unref(&pCred);
+#else /* 10.4 */
+ /* The 10.4u SDK headers and 10.4.11 kernel source have inconsistent definitions
+ of kauth_cred_unref(), so use the other (now deprecated) API for releasing it. */
+ kauth_cred_rele(pCred);
+#endif /* 10.4 */
+ }
+ else
+ rc = VERR_INVALID_PARAMETER;
+
+ Log(("VbgdDarwinOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, proc_pid(pProcess)));
+ return VbgdDarwinErr2DarwinErr(rc);
+}
+
+
+/**
+ * Close device.
+ */
+static int VbgdDarwinClose(dev_t Dev, int fFlags, int fDevType, struct proc *pProcess)
+{
+ Log(("VbgdDarwinClose: pid=%d\n", (int)RTProcSelf()));
+ Assert(proc_pid(pProcess) == (int)RTProcSelf());
+
+ /*
+ * Hand the session closing to org_virtualbox_VBoxGuestClient.
+ */
+ org_virtualbox_VBoxGuestClient::sessionClose(RTProcSelf());
+ return 0;
+}
+
+
+/**
+ * Device I/O Control entry point.
+ *
+ * @returns Darwin for slow IOCtls and VBox status code for the fast ones.
+ * @param Dev The device number (major+minor).
+ * @param iCmd The IOCtl command.
+ * @param pData Pointer to the data (if any it's a VBOXGUESTIOCTLDATA (kernel copy)).
+ * @param fFlags Flag saying we're a character device (like we didn't know already).
+ * @param pProcess The process issuing this request.
+ */
+static int VbgdDarwinIOCtl(dev_t Dev, u_long iCmd, caddr_t pData, int fFlags, struct proc *pProcess)
+{
+ //const bool fUnrestricted = minor(Dev) == 0;
+ const RTPROCESS Process = proc_pid(pProcess);
+ const unsigned iHash = SESSION_HASH(Process);
+ PVBOXGUESTSESSION pSession;
+
+ /*
+ * Find the session.
+ */
+ RTSpinlockAcquire(g_Spinlock);
+ pSession = g_apSessionHashTab[iHash];
+ while (pSession && pSession->Process != Process /*later: && pSession->fUnrestricted == fUnrestricted*/ && pSession->fOpened)
+ pSession = pSession->pNextHash;
+ RTSpinlockReleaseNoInts(g_Spinlock);
+ if (!pSession)
+ {
+ Log(("VBoxDrvDarwinIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#lx\n",
+ (int)Process, iCmd));
+ return EINVAL;
+ }
+
+ /*
+ * No high speed IOCtls here yet.
+ */
+
+ return VbgdDarwinIOCtlSlow(pSession, iCmd, pData, pProcess);
+}
+
+
+/**
+ * Worker for VbgdDarwinIOCtl that takes the slow IOCtl functions.
+ *
+ * @returns Darwin errno.
+ *
+ * @param pSession The session.
+ * @param iCmd The IOCtl command.
+ * @param pData Pointer to the kernel copy of the data buffer.
+ * @param pProcess The calling process.
+ */
+static int VbgdDarwinIOCtlSlow(PVBOXGUESTSESSION pSession, u_long iCmd, caddr_t pData, struct proc *pProcess)
+{
+ LogFlow(("VbgdDarwinIOCtlSlow: pSession=%p iCmd=%p pData=%p pProcess=%p\n", pSession, iCmd, pData, pProcess));
+
+
+ /*
+ * Buffered or unbuffered?
+ */
+ void *pvReqData;
+ user_addr_t pUser = 0;
+ void *pvPageBuf = NULL;
+ uint32_t cbReq = IOCPARM_LEN(iCmd);
+ if ((IOC_DIRMASK & iCmd) == IOC_INOUT)
+ {
+ /*
+ * Raw buffered request data, common code validates it.
+ */
+ pvReqData = pData;
+ }
+ else if ((IOC_DIRMASK & iCmd) == IOC_VOID && !cbReq)
+ {
+ /*
+ * Get the header and figure out how much we're gonna have to read.
+ */
+ VBGLBIGREQ Hdr;
+ pUser = (user_addr_t)*(void **)pData;
+ int rc = copyin(pUser, &Hdr, sizeof(Hdr));
+ if (RT_UNLIKELY(rc))
+ {
+ Log(("VbgdDarwinIOCtlSlow: copyin(%llx,Hdr,) -> %#x; iCmd=%#lx\n", (unsigned long long)pUser, rc, iCmd));
+ return rc;
+ }
+ if (RT_UNLIKELY(Hdr.u32Magic != VBGLBIGREQ_MAGIC))
+ {
+ Log(("VbgdDarwinIOCtlSlow: bad magic u32Magic=%#x; iCmd=%#lx\n", Hdr.u32Magic, iCmd));
+ return EINVAL;
+ }
+ cbReq = Hdr.cbData;
+ if (RT_UNLIKELY(cbReq > _1M*16))
+ {
+ Log(("VbgdDarwinIOCtlSlow: %#x; iCmd=%#lx\n", Hdr.cbData, iCmd));
+ return EINVAL;
+ }
+ pUser = Hdr.pvDataR3;
+
+ /*
+ * Allocate buffer and copy in the data.
+ */
+ pvReqData = RTMemTmpAlloc(cbReq);
+ if (!pvReqData)
+ pvPageBuf = pvReqData = IOMallocAligned(RT_ALIGN_Z(cbReq, PAGE_SIZE), 8);
+ if (RT_UNLIKELY(!pvReqData))
+ {
+ Log(("VbgdDarwinIOCtlSlow: failed to allocate buffer of %d bytes; iCmd=%#lx\n", cbReq, iCmd));
+ return ENOMEM;
+ }
+ rc = copyin(pUser, pvReqData, Hdr.cbData);
+ if (RT_UNLIKELY(rc))
+ {
+ Log(("VbgdDarwinIOCtlSlow: copyin(%llx,%p,%#x) -> %#x; iCmd=%#lx\n",
+ (unsigned long long)pUser, pvReqData, Hdr.cbData, rc, iCmd));
+ if (pvPageBuf)
+ IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
+ else
+ RTMemTmpFree(pvReqData);
+ return rc;
+ }
+ }
+ else
+ {
+ Log(("VbgdDarwinIOCtlSlow: huh? cbReq=%#x iCmd=%#lx\n", cbReq, iCmd));
+ return EINVAL;
+ }
+
+ /*
+ * Process the IOCtl.
+ */
+ size_t cbReqRet = 0;
+ int rc = VBoxGuestCommonIOCtl(iCmd, &g_DevExt, pSession, pvReqData, cbReq, &cbReqRet);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * If not buffered, copy back the buffer before returning.
+ */
+ if (pUser)
+ {
+ if (cbReqRet > cbReq)
+ {
+ Log(("VbgdDarwinIOCtlSlow: too much output! %#x > %#x; uCmd=%#lx!\n", cbReqRet, cbReq, iCmd));
+ cbReqRet = cbReq;
+ }
+ rc = copyout(pvReqData, pUser, cbReqRet);
+ if (RT_UNLIKELY(rc))
+ Log(("VbgdDarwinIOCtlSlow: copyout(%p,%llx,%#x) -> %d; uCmd=%#lx!\n",
+ pvReqData, (unsigned long long)pUser, cbReqRet, rc, iCmd));
+
+ /* cleanup */
+ if (pvPageBuf)
+ IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
+ else
+ RTMemTmpFree(pvReqData);
+ }
+ else
+ rc = 0;
+ }
+ else
+ {
+ /*
+ * The request failed, just clean up.
+ */
+ if (pUser)
+ {
+ if (pvPageBuf)
+ IOFreeAligned(pvPageBuf, RT_ALIGN_Z(cbReq, PAGE_SIZE));
+ else
+ RTMemTmpFree(pvReqData);
+ }
+
+ Log(("VbgdDarwinIOCtlSlow: pid=%d iCmd=%lx pData=%p failed, rc=%d\n", proc_pid(pProcess), iCmd, (void *)pData, rc));
+ rc = EINVAL;
+ }
+
+ Log2(("VbgdDarwinIOCtlSlow: returns %d\n", rc));
+ return rc;
+}
+
+
+/*
+ * The VBoxGuest IDC entry points.
+ *
+ * This code is shared with the other unixy OSes.
+ */
+#include "VBoxGuestIDC-unix.c.h"
+
+
+void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
+{
+ NOREF(pDevExt);
+}
+
+
+/**
+ * Callback for blah blah blah.
+ */
+IOReturn VbgdDarwinSleepHandler(void * /* pvTarget */, void *pvRefCon, UInt32 uMessageType, IOService * /* pProvider */, void * /* pvMessageArgument */, vm_size_t /* argSize */)
+{
+ LogFlow(("VBoxGuest: Got sleep/wake notice. Message type was %X\n", (uint)uMessageType));
+
+ if (uMessageType == kIOMessageSystemWillSleep)
+ RTPowerSignalEvent(RTPOWEREVENT_SUSPEND);
+ else if (uMessageType == kIOMessageSystemHasPoweredOn)
+ RTPowerSignalEvent(RTPOWEREVENT_RESUME);
+
+ acknowledgeSleepWakeNotification(pvRefCon);
+
+ return 0;
+}
+
+
+/**
+ * Converts an IPRT error code to a darwin error code.
+ *
+ * @returns corresponding darwin error code.
+ * @param rc IPRT status code.
+ */
+static int VbgdDarwinErr2DarwinErr(int rc)
+{
+ switch (rc)
+ {
+ case VINF_SUCCESS: return 0;
+ case VERR_GENERAL_FAILURE: return EACCES;
+ case VERR_INVALID_PARAMETER: return EINVAL;
+ case VERR_INVALID_MAGIC: return EILSEQ;
+ case VERR_INVALID_HANDLE: return ENXIO;
+ case VERR_INVALID_POINTER: return EFAULT;
+ case VERR_LOCK_FAILED: return ENOLCK;
+ case VERR_ALREADY_LOADED: return EEXIST;
+ case VERR_PERMISSION_DENIED: return EPERM;
+ case VERR_VERSION_MISMATCH: return ENOSYS;
+ }
+
+ return EPERM;
+}
+
+
+/*
+ *
+ * org_virtualbox_VBoxGuest
+ *
+ */
+
+/**
+ * Just a plug
+ */
+static void
+interruptHandler(OSObject *pOwner, IOInterruptEventSource *pSrc, int cInts)
+{
+ NOREF(pOwner);
+ NOREF(pSrc);
+ NOREF(cInts);
+}
+
+/**
+ * Callback triggered when interrupt occurs.
+ */
+static bool
+checkForInterrupt(OSObject *pOwner, IOFilterInterruptEventSource *pSrc)
+{
+ if (!pSrc)
+ return false;
+
+ bool fTaken = VBoxGuestCommonISR(&g_DevExt);
+ if (!fTaken)
+ printf("VBoxGuestCommonISR error\n");
+
+ return fTaken;
+}
+
+bool
+org_virtualbox_VBoxGuest::setupVmmDevInterrupts(IOService *pProvider)
+{
+ IOWorkLoop *pWorkLoop = (IOWorkLoop *)getWorkLoop();
+
+ if (!pWorkLoop)
+ return false;
+
+ m_pInterruptSrc = IOFilterInterruptEventSource::filterInterruptEventSource(this,
+ &interruptHandler,
+ &checkForInterrupt,
+ pProvider);
+
+ if (kIOReturnSuccess != pWorkLoop->addEventSource(m_pInterruptSrc))
+ {
+ m_pInterruptSrc->disable();
+ m_pInterruptSrc->release();
+ m_pInterruptSrc = 0;
+ return false;
+ }
+
+ m_pInterruptSrc->enable();
+
+ return true;
+}
+
+bool
+org_virtualbox_VBoxGuest::disableVmmDevInterrupts(void)
+{
+ IOWorkLoop *pWorkLoop = (IOWorkLoop *)getWorkLoop();
+
+ if (!pWorkLoop)
+ return false;
+
+ if (!m_pInterruptSrc)
+ return false;
+
+ m_pInterruptSrc->disable();
+ pWorkLoop->removeEventSource(m_pInterruptSrc);
+ m_pInterruptSrc->release();
+ m_pInterruptSrc = 0;
+
+ return true;
+}
+
+bool org_virtualbox_VBoxGuest::isVmmDev(IOPCIDevice *pIOPCIDevice)
+{
+ UInt16 uVendorId, uDeviceId;
+
+ if (!pIOPCIDevice)
+ return false;
+
+ uVendorId = m_pIOPCIDevice->configRead16(kIOPCIConfigVendorID);
+ uDeviceId = m_pIOPCIDevice->configRead16(kIOPCIConfigDeviceID);
+
+ if (uVendorId == VMMDEV_VENDORID && uDeviceId == VMMDEV_DEVICEID)
+ return true;
+
+ return true;
+}
+
+
+/**
+ * Start this service.
+ */
+bool org_virtualbox_VBoxGuest::start(IOService *pProvider)
+{
+ if (!IOService::start(pProvider))
+ return false;
+
+ /* Low level initialization should be performed only once */
+ if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false))
+ {
+ IOService::stop(pProvider);
+ return false;
+ }
+
+ m_pIOPCIDevice = OSDynamicCast(IOPCIDevice, pProvider);
+ if (m_pIOPCIDevice)
+ {
+ if (isVmmDev(m_pIOPCIDevice))
+ {
+ /* Enable memory response from VMM device */
+ m_pIOPCIDevice->setMemoryEnable(true);
+ m_pIOPCIDevice->setIOEnable(true);
+
+ IOMemoryDescriptor *pMem = m_pIOPCIDevice->getDeviceMemoryWithIndex(0);
+ if (pMem)
+ {
+ IOPhysicalAddress IOPortBasePhys = pMem->getPhysicalAddress();
+ /* Check that returned value is from I/O port range (at least it is 16-bit lenght) */
+ if((IOPortBasePhys >> 16) == 0)
+ {
+
+ RTIOPORT IOPortBase = (RTIOPORT)IOPortBasePhys;
+ void *pvMMIOBase = NULL;
+ uint32_t cbMMIO = 0;
+ m_pMap = m_pIOPCIDevice->mapDeviceMemoryWithIndex(1);
+ if (m_pMap)
+ {
+ pvMMIOBase = (void *)m_pMap->getVirtualAddress();
+ cbMMIO = m_pMap->getLength();
+ }
+
+ int rc = VBoxGuestInitDevExt(&g_DevExt,
+ IOPortBase,
+ pvMMIOBase,
+ cbMMIO,
+#if ARCH_BITS == 64
+ VBOXOSTYPE_MacOS_x64,
+#else
+ VBOXOSTYPE_MacOS,
+#endif
+ 0);
+ if (RT_SUCCESS(rc))
+ {
+ rc = VbgdDarwinCharDevInit();
+ if (rc == KMOD_RETURN_SUCCESS)
+ {
+ if (setupVmmDevInterrupts(pProvider))
+ {
+ /* register the service. */
+ registerService();
+ LogRel(("VBoxGuest: Successfully started I/O kit class instance.\n"));
+ return true;
+ }
+
+ LogRel(("VBoxGuest: Failed to set up interrupts\n"));
+ VbgdDarwinCharDevRemove();
+ }
+ else
+ LogRel(("VBoxGuest: Failed to initialize character device (rc=%d).\n", rc));
+
+ VBoxGuestDeleteDevExt(&g_DevExt);
+ }
+ else
+ LogRel(("VBoxGuest: Failed to initialize common code (rc=%d).\n", rc));
+
+ if (m_pMap)
+ {
+ m_pMap->release();
+ m_pMap = NULL;
+ }
+ }
+ }
+ else
+ LogRel(("VBoxGuest: The device missing is the I/O port range (#0).\n"));
+ }
+ else
+ LogRel(("VBoxGuest: Not the VMMDev (%#x:%#x).\n",
+ m_pIOPCIDevice->configRead16(kIOPCIConfigVendorID), m_pIOPCIDevice->configRead16(kIOPCIConfigDeviceID)));
+ }
+ else
+ LogRel(("VBoxGuest: Provider is not an instance of IOPCIDevice.\n"));
+
+ ASMAtomicXchgBool(&g_fInstantiated, false);
+
+ IOService::stop(pProvider);
+
+ return false;
+}
+
+
+/**
+ * Stop this service.
+ */
+void org_virtualbox_VBoxGuest::stop(IOService *pProvider)
+{
+ LogFlow(("org_virtualbox_VBoxGuest::stop([%p], %p)\n", this, pProvider));
+
+ AssertReturnVoid(ASMAtomicReadBool(&g_fInstantiated));
+
+ /* Low level termination should be performed only once */
+ if (!disableVmmDevInterrupts())
+ LogRel(("vboxguest: unable to unregister interrupt handler\n"));
+
+ VbgdDarwinCharDevRemove();
+ VBoxGuestDeleteDevExt(&g_DevExt);
+
+ if (m_pMap)
+ {
+ m_pMap->release();
+ m_pMap = NULL;
+ }
+
+ IOService::stop(pProvider);
+
+ ASMAtomicWriteBool(&g_fInstantiated, false);
+
+ LogRel(("vboxguest module unloaded\n"));
+}
+
+
+/**
+ * Termination request.
+ *
+ * @return true if we're ok with shutting down now, false if we're not.
+ * @param fOptions Flags.
+ */
+bool org_virtualbox_VBoxGuest::terminate(IOOptionBits fOptions)
+{
+ bool fRc;
+ LogFlow(("org_virtualbox_VBoxGuest::terminate: reference_count=%d g_cSessions=%d (fOptions=%#x)\n",
+ KMOD_INFO_NAME.reference_count, ASMAtomicUoReadS32(&g_cSessions), fOptions));
+ if ( KMOD_INFO_NAME.reference_count != 0
+ || ASMAtomicUoReadS32(&g_cSessions))
+ fRc = false;
+ else
+ fRc = IOService::terminate(fOptions);
+ LogFlow(("org_virtualbox_SupDrv::terminate: returns %d\n", fRc));
+ return fRc;
+}
+
+
+/*
+ *
+ * org_virtualbox_VBoxGuestClient
+ *
+ */
+
+
+/**
+ * Initializer called when the client opens the service.
+ */
+bool org_virtualbox_VBoxGuestClient::initWithTask(task_t OwningTask, void *pvSecurityId, UInt32 u32Type)
+{
+ LogFlow(("org_virtualbox_VBoxGuestClient::initWithTask([%p], %#x, %p, %#x) (cur pid=%d proc=%p)\n",
+ this, OwningTask, pvSecurityId, u32Type, RTProcSelf(), RTR0ProcHandleSelf()));
+ AssertMsg((RTR0PROCESS)OwningTask == RTR0ProcHandleSelf(), ("%p %p\n", OwningTask, RTR0ProcHandleSelf()));
+
+ if (!OwningTask)
+ return false;
+ if (IOUserClient::initWithTask(OwningTask, pvSecurityId , u32Type))
+ {
+ m_Task = OwningTask;
+ m_pSession = NULL;
+ m_pProvider = NULL;
+ return true;
+ }
+ return false;
+}
+
+
+/**
+ * Start the client service.
+ */
+bool org_virtualbox_VBoxGuestClient::start(IOService *pProvider)
+{
+ LogFlow(("org_virtualbox_VBoxGuestClient::start([%p], %p) (cur pid=%d proc=%p)\n",
+ this, pProvider, RTProcSelf(), RTR0ProcHandleSelf() ));
+ AssertMsgReturn((RTR0PROCESS)m_Task == RTR0ProcHandleSelf(),
+ ("%p %p\n", m_Task, RTR0ProcHandleSelf()),
+ false);
+
+ if (IOUserClient::start(pProvider))
+ {
+ m_pProvider = OSDynamicCast(org_virtualbox_VBoxGuest, pProvider);
+ if (m_pProvider)
+ {
+ Assert(!m_pSession);
+
+ /*
+ * Create a new session.
+ */
+ int rc = VBoxGuestCreateUserSession(&g_DevExt, &m_pSession);
+ if (RT_SUCCESS(rc))
+ {
+ m_pSession->fOpened = false;
+ /* The fUnrestricted field is set on open. */
+
+ /*
+ * Insert it into the hash table, checking that there isn't
+ * already one for this process first. (One session per proc!)
+ */
+ unsigned iHash = SESSION_HASH(m_pSession->Process);
+ RTSpinlockAcquire(g_Spinlock);
+
+ PVBOXGUESTSESSION pCur = g_apSessionHashTab[iHash];
+ if (pCur && pCur->Process != m_pSession->Process)
+ {
+ do pCur = pCur->pNextHash;
+ while (pCur && pCur->Process != m_pSession->Process);
+ }
+ if (!pCur)
+ {
+ m_pSession->pNextHash = g_apSessionHashTab[iHash];
+ g_apSessionHashTab[iHash] = m_pSession;
+ m_pSession->pvVBoxGuestClient = this;
+ ASMAtomicIncS32(&g_cSessions);
+ rc = VINF_SUCCESS;
+ }
+ else
+ rc = VERR_ALREADY_LOADED;
+
+ RTSpinlockRelease(g_Spinlock);
+ if (RT_SUCCESS(rc))
+ {
+ Log(("org_virtualbox_VBoxGuestClient::start: created session %p for pid %d\n", m_pSession, (int)RTProcSelf()));
+ return true;
+ }
+
+ LogFlow(("org_virtualbox_VBoxGuestClient::start: already got a session for this process (%p)\n", pCur));
+ VBoxGuestCloseSession(&g_DevExt, m_pSession);
+ }
+
+ m_pSession = NULL;
+ LogFlow(("org_virtualbox_VBoxGuestClient::start: rc=%Rrc from supdrvCreateSession\n", rc));
+ }
+ else
+ LogFlow(("org_virtualbox_VBoxGuestClient::start: %p isn't org_virtualbox_VBoxGuest\n", pProvider));
+ }
+ return false;
+}
+
+
+/**
+ * Common worker for clientClose and VBoxDrvDarwinClose.
+ */
+/* static */ void org_virtualbox_VBoxGuestClient::sessionClose(RTPROCESS Process)
+{
+ /*
+ * Find the session and remove it from the hash table.
+ *
+ * Note! Only one session per process. (Both start() and
+ * VbgdDarwinOpen makes sure this is so.)
+ */
+ const unsigned iHash = SESSION_HASH(Process);
+ RTSpinlockAcquire(g_Spinlock);
+ PVBOXGUESTSESSION pSession = g_apSessionHashTab[iHash];
+ if (pSession)
+ {
+ if (pSession->Process == Process)
+ {
+ g_apSessionHashTab[iHash] = pSession->pNextHash;
+ pSession->pNextHash = NULL;
+ ASMAtomicDecS32(&g_cSessions);
+ }
+ else
+ {
+ PVBOXGUESTSESSION pPrev = pSession;
+ pSession = pSession->pNextHash;
+ while (pSession)
+ {
+ if (pSession->Process == Process)
+ {
+ pPrev->pNextHash = pSession->pNextHash;
+ pSession->pNextHash = NULL;
+ ASMAtomicDecS32(&g_cSessions);
+ break;
+ }
+
+ /* next */
+ pPrev = pSession;
+ pSession = pSession->pNextHash;
+ }
+ }
+ }
+ RTSpinlockRelease(g_Spinlock);
+ if (!pSession)
+ {
+ Log(("VBoxGuestClient::sessionClose: pSession == NULL, pid=%d; freed already?\n", (int)Process));
+ return;
+ }
+
+ /*
+ * Remove it from the client object.
+ */
+ org_virtualbox_VBoxGuestClient *pThis = (org_virtualbox_VBoxGuestClient *)pSession->pvVBoxGuestClient;
+ pSession->pvVBoxGuestClient = NULL;
+ if (pThis)
+ {
+ Assert(pThis->m_pSession == pSession);
+ pThis->m_pSession = NULL;
+ }
+
+ /*
+ * Close the session.
+ */
+ VBoxGuestCloseSession(&g_DevExt, pSession);
+}
+
+
+/**
+ * Client exits normally.
+ */
+IOReturn org_virtualbox_VBoxGuestClient::clientClose(void)
+{
+ LogFlow(("org_virtualbox_VBoxGuestClient::clientClose([%p]) (cur pid=%d proc=%p)\n", this, RTProcSelf(), RTR0ProcHandleSelf()));
+ AssertMsg((RTR0PROCESS)m_Task == RTR0ProcHandleSelf(), ("%p %p\n", m_Task, RTR0ProcHandleSelf()));
+
+ /*
+ * Clean up the session if it's still around.
+ *
+ * We cannot rely 100% on close, and in the case of a dead client
+ * we'll end up hanging inside vm_map_remove() if we postpone it.
+ */
+ if (m_pSession)
+ {
+ sessionClose(RTProcSelf());
+ Assert(!m_pSession);
+ }
+
+ m_pProvider = NULL;
+ terminate();
+
+ return kIOReturnSuccess;
+}
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
index 1720abb2..1552f715 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-freebsd.c
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007 Oracle Corporation
+ * Copyright (C) 2007-2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c
new file mode 100644
index 00000000..122df9e7
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c
@@ -0,0 +1,448 @@
+/* $Id: VBoxGuest-haiku-stubs.c $ */
+/** @file
+ * VBoxGuest kernel module, Haiku Guest Additions, stubs.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * This file provides stubs for calling VBox runtime functions through the vboxguest module.
+ * It should be linked into any driver or module that uses the VBox runtime, except vboxguest
+ * itself (which contains the actual library and therefore doesn't need stubs to call it).
+ */
+
+#include "VBoxGuest-haiku.h"
+#include "VBoxGuestInternal.h"
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/initterm.h>
+#include <iprt/process.h>
+#include <iprt/mem.h>
+#include <iprt/asm.h>
+#include <iprt/mp.h>
+#include <iprt/power.h>
+#include <iprt/thread.h>
+
+// >>> file('/tmp/stubs.c', 'w').writelines([re.sub(r'^(?P<returntype>[^(]+) \(\*_(?P<functionname>[A-Za-z0-9_]+)\)\((?P<params>[^)]+)\);', lambda m: '%s %s(%s)\n{\n %sg_VBoxGuest->_%s(%s);\n}\n' % (m.group(1), m.group(2), m.group(3), ('return ' if m.group(1) != 'void' else ''), m.group(2), (', '.join(a.split(' ')[-1].replace('*', '') for a in m.group(3).split(',')) if m.group(3) != 'void' else '')), f) for f in functions])
+
+struct vboxguest_module_info *g_VBoxGuest;
+
+size_t RTLogBackdoorPrintf(const char *pszFormat, ...)
+{
+ va_list args;
+ size_t cb;
+
+ va_start(args, pszFormat);
+ cb = g_VBoxGuest->_RTLogBackdoorPrintf(pszFormat, args);
+ va_end(args);
+
+ return cb;
+}
+size_t RTLogBackdoorPrintfV(const char *pszFormat, va_list args)
+{
+ return g_VBoxGuest->_RTLogBackdoorPrintfV(pszFormat, args);
+}
+int RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey)
+{
+ return g_VBoxGuest->_RTLogSetDefaultInstanceThread(pLogger, uKey);
+}
+int RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv)
+{
+ return g_VBoxGuest->_RTMemAllocExTag(cb, cbAlignment, fFlags, pszTag, ppv);
+}
+void* RTMemContAlloc(PRTCCPHYS pPhys, size_t cb)
+{
+ return g_VBoxGuest->_RTMemContAlloc(pPhys, cb);
+}
+void RTMemContFree(void *pv, size_t cb)
+{
+ g_VBoxGuest->_RTMemContFree(pv, cb);
+}
+void RTMemFreeEx(void *pv, size_t cb)
+{
+ g_VBoxGuest->_RTMemFreeEx(pv, cb);
+}
+bool RTMpIsCpuPossible(RTCPUID idCpu)
+{
+ return g_VBoxGuest->_RTMpIsCpuPossible(idCpu);
+}
+int RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser)
+{
+ return g_VBoxGuest->_RTMpNotificationDeregister(pfnCallback, pvUser);
+}
+int RTMpNotificationRegister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser)
+{
+ return g_VBoxGuest->_RTMpNotificationRegister(pfnCallback, pvUser);
+}
+int RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+ return g_VBoxGuest->_RTMpOnAll(pfnWorker, pvUser1, pvUser2);
+}
+int RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+ return g_VBoxGuest->_RTMpOnOthers(pfnWorker, pvUser1, pvUser2);
+}
+int RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+ return g_VBoxGuest->_RTMpOnSpecific(idCpu, pfnWorker, pvUser1, pvUser2);
+}
+int RTPowerNotificationDeregister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser)
+{
+ return g_VBoxGuest->_RTPowerNotificationDeregister(pfnCallback, pvUser);
+}
+int RTPowerNotificationRegister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser)
+{
+ return g_VBoxGuest->_RTPowerNotificationRegister(pfnCallback, pvUser);
+}
+int RTPowerSignalEvent(RTPOWEREVENT enmEvent)
+{
+ return g_VBoxGuest->_RTPowerSignalEvent(enmEvent);
+}
+void RTR0AssertPanicSystem(void)
+{
+ g_VBoxGuest->_RTR0AssertPanicSystem();
+}
+int RTR0Init(unsigned fReserved)
+{
+ return g_VBoxGuest->_RTR0Init(fReserved);
+}
+void* RTR0MemObjAddress(RTR0MEMOBJ MemObj)
+{
+ return g_VBoxGuest->_RTR0MemObjAddress(MemObj);
+}
+RTR3PTR RTR0MemObjAddressR3(RTR0MEMOBJ MemObj)
+{
+ return g_VBoxGuest->_RTR0MemObjAddressR3(MemObj);
+}
+int RTR0MemObjAllocContTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjAllocContTag(pMemObj, cb, fExecutable, pszTag);
+}
+int RTR0MemObjAllocLowTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjAllocLowTag(pMemObj, cb, fExecutable, pszTag);
+}
+int RTR0MemObjAllocPageTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjAllocPageTag(pMemObj, cb, fExecutable, pszTag);
+}
+int RTR0MemObjAllocPhysExTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjAllocPhysExTag(pMemObj, cb, PhysHighest, uAlignment, pszTag);
+}
+int RTR0MemObjAllocPhysNCTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjAllocPhysNCTag(pMemObj, cb, PhysHighest, pszTag);
+}
+int RTR0MemObjAllocPhysTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjAllocPhysTag(pMemObj, cb, PhysHighest, pszTag);
+}
+int RTR0MemObjEnterPhysTag(PRTR0MEMOBJ pMemObj, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjEnterPhysTag(pMemObj, Phys, cb, uCachePolicy, pszTag);
+}
+int RTR0MemObjFree(RTR0MEMOBJ MemObj, bool fFreeMappings)
+{
+ return g_VBoxGuest->_RTR0MemObjFree(MemObj, fFreeMappings);
+}
+RTHCPHYS RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage)
+{
+ return g_VBoxGuest->_RTR0MemObjGetPagePhysAddr(MemObj, iPage);
+}
+bool RTR0MemObjIsMapping(RTR0MEMOBJ MemObj)
+{
+ return g_VBoxGuest->_RTR0MemObjIsMapping(MemObj);
+}
+int RTR0MemObjLockKernelTag(PRTR0MEMOBJ pMemObj, void *pv, size_t cb, uint32_t fAccess, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjLockKernelTag(pMemObj, pv, cb, fAccess, pszTag);
+}
+int RTR0MemObjLockUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjLockUserTag(pMemObj, R3Ptr, cb, fAccess, R0Process, pszTag);
+}
+int RTR0MemObjMapKernelExTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment, unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjMapKernelExTag(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt, offSub, cbSub, pszTag);
+}
+int RTR0MemObjMapKernelTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment, unsigned fProt, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjMapKernelTag(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt, pszTag);
+}
+int RTR0MemObjMapUserTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjMapUserTag(pMemObj, MemObjToMap, R3PtrFixed, uAlignment, fProt, R0Process, pszTag);
+}
+int RTR0MemObjProtect(RTR0MEMOBJ hMemObj, size_t offSub, size_t cbSub, uint32_t fProt)
+{
+ return g_VBoxGuest->_RTR0MemObjProtect(hMemObj, offSub, cbSub, fProt);
+}
+int RTR0MemObjReserveKernelTag(PRTR0MEMOBJ pMemObj, void *pvFixed, size_t cb, size_t uAlignment, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjReserveKernelTag(pMemObj, pvFixed, cb, uAlignment, pszTag);
+}
+int RTR0MemObjReserveUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process, const char *pszTag)
+{
+ return g_VBoxGuest->_RTR0MemObjReserveUserTag(pMemObj, R3PtrFixed, cb, uAlignment, R0Process, pszTag);
+}
+size_t RTR0MemObjSize(RTR0MEMOBJ MemObj)
+{
+ return g_VBoxGuest->_RTR0MemObjSize(MemObj);
+}
+RTR0PROCESS RTR0ProcHandleSelf(void)
+{
+ return g_VBoxGuest->_RTR0ProcHandleSelf();
+}
+void RTR0Term(void)
+{
+ g_VBoxGuest->_RTR0Term();
+}
+void RTR0TermForced(void)
+{
+ g_VBoxGuest->_RTR0TermForced();
+}
+RTPROCESS RTProcSelf(void)
+{
+ return g_VBoxGuest->_RTProcSelf();
+}
+uint32_t RTSemEventGetResolution(void)
+{
+ return g_VBoxGuest->_RTSemEventGetResolution();
+}
+uint32_t RTSemEventMultiGetResolution(void)
+{
+ return g_VBoxGuest->_RTSemEventMultiGetResolution();
+}
+int RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
+{
+ return g_VBoxGuest->_RTSemEventMultiWaitEx(hEventMultiSem, fFlags, uTimeout);
+}
+int RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+ return g_VBoxGuest->_RTSemEventMultiWaitExDebug(hEventMultiSem, fFlags, uTimeout, uId, pszFile, iLine, pszFunction);
+}
+int RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout)
+{
+ return g_VBoxGuest->_RTSemEventWaitEx(hEventSem, fFlags, uTimeout);
+}
+int RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+ return g_VBoxGuest->_RTSemEventWaitExDebug(hEventSem, fFlags, uTimeout, uId, pszFile, iLine, pszFunction);
+}
+bool RTThreadIsInInterrupt(RTTHREAD hThread)
+{
+ return g_VBoxGuest->_RTThreadIsInInterrupt(hThread);
+}
+void RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
+{
+ g_VBoxGuest->_RTThreadPreemptDisable(pState);
+}
+bool RTThreadPreemptIsEnabled(RTTHREAD hThread)
+{
+ return g_VBoxGuest->_RTThreadPreemptIsEnabled(hThread);
+}
+bool RTThreadPreemptIsPending(RTTHREAD hThread)
+{
+ return g_VBoxGuest->_RTThreadPreemptIsPending(hThread);
+}
+bool RTThreadPreemptIsPendingTrusty(void)
+{
+ return g_VBoxGuest->_RTThreadPreemptIsPendingTrusty();
+}
+bool RTThreadPreemptIsPossible(void)
+{
+ return g_VBoxGuest->_RTThreadPreemptIsPossible();
+}
+void RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState)
+{
+ g_VBoxGuest->_RTThreadPreemptRestore(pState);
+}
+uint32_t RTTimerGetSystemGranularity(void)
+{
+ return g_VBoxGuest->_RTTimerGetSystemGranularity();
+}
+int RTTimerReleaseSystemGranularity(uint32_t u32Granted)
+{
+ return g_VBoxGuest->_RTTimerReleaseSystemGranularity(u32Granted);
+}
+int RTTimerRequestSystemGranularity(uint32_t u32Request, uint32_t *pu32Granted)
+{
+ return g_VBoxGuest->_RTTimerRequestSystemGranularity(u32Request, pu32Granted);
+}
+void RTSpinlockAcquire(RTSPINLOCK Spinlock)
+{
+ g_VBoxGuest->_RTSpinlockAcquire(Spinlock);
+}
+void RTSpinlockRelease(RTSPINLOCK Spinlock)
+{
+ g_VBoxGuest->_RTSpinlockRelease(Spinlock);
+}
+void RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock)
+{
+ g_VBoxGuest->_RTSpinlockReleaseNoInts(Spinlock);
+}
+void* RTMemTmpAllocTag(size_t cb, const char *pszTag)
+{
+ return g_VBoxGuest->_RTMemTmpAllocTag(cb, pszTag);
+}
+void RTMemTmpFree(void *pv)
+{
+ g_VBoxGuest->_RTMemTmpFree(pv);
+}
+PRTLOGGER RTLogDefaultInstance(void)
+{
+ return g_VBoxGuest->_RTLogDefaultInstance();
+}
+PRTLOGGER RTLogRelDefaultInstance(void)
+{
+ return g_VBoxGuest->_RTLogRelDefaultInstance();
+}
+int RTErrConvertToErrno(int iErr)
+{
+ return g_VBoxGuest->_RTErrConvertToErrno(iErr);
+}
+int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, void *pvData, size_t cbData, size_t *pcbDataReturned)
+{
+ return g_VBoxGuest->_VBoxGuestCommonIOCtl(iFunction, pDevExt, pSession, pvData, cbData, pcbDataReturned);
+}
+int VBoxGuestCreateUserSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession)
+{
+ return g_VBoxGuest->_VBoxGuestCreateUserSession(pDevExt, ppSession);
+}
+void VBoxGuestCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+ g_VBoxGuest->_VBoxGuestCloseSession(pDevExt, pSession);
+}
+void* VBoxGuestIDCOpen(uint32_t *pu32Version)
+{
+ return g_VBoxGuest->_VBoxGuestIDCOpen(pu32Version);
+}
+int VBoxGuestIDCClose(void *pvSession)
+{
+ return g_VBoxGuest->_VBoxGuestIDCClose(pvSession);
+}
+int VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
+{
+ return g_VBoxGuest->_VBoxGuestIDCCall(pvSession, iCmd, pvData, cbData, pcbDataReturned);
+}
+void RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+{
+ g_VBoxGuest->_RTAssertMsg1Weak(pszExpr, uLine, pszFile, pszFunction);
+}
+void RTAssertMsg2Weak(const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ RTAssertMsg2WeakV(pszFormat, va);
+ va_end(va);
+}
+void RTAssertMsg2WeakV(const char *pszFormat, va_list va)
+{
+ g_VBoxGuest->_RTAssertMsg2WeakV(pszFormat, va);
+}
+bool RTAssertShouldPanic(void)
+{
+ return g_VBoxGuest->_RTAssertShouldPanic();
+}
+int RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx)
+{
+ return g_VBoxGuest->_RTSemFastMutexCreate(phFastMtx);
+}
+int RTSemFastMutexDestroy(RTSEMFASTMUTEX hFastMtx)
+{
+ return g_VBoxGuest->_RTSemFastMutexDestroy(hFastMtx);
+}
+int RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx)
+{
+ return g_VBoxGuest->_RTSemFastMutexRelease(hFastMtx);
+}
+int RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx)
+{
+ return g_VBoxGuest->_RTSemFastMutexRequest(hFastMtx);
+}
+int RTSemMutexCreate(PRTSEMMUTEX phFastMtx)
+{
+ return g_VBoxGuest->_RTSemMutexCreate(phFastMtx);
+}
+int RTSemMutexDestroy(RTSEMMUTEX hFastMtx)
+{
+ return g_VBoxGuest->_RTSemMutexDestroy(hFastMtx);
+}
+int RTSemMutexRelease(RTSEMMUTEX hFastMtx)
+{
+ return g_VBoxGuest->_RTSemMutexRelease(hFastMtx);
+}
+int RTSemMutexRequest(RTSEMMUTEX hFastMtx, RTMSINTERVAL cMillies)
+{
+ return g_VBoxGuest->_RTSemMutexRequest(hFastMtx, cMillies);
+}
+int RTHeapSimpleRelocate(RTHEAPSIMPLE hHeap, uintptr_t offDelta)
+{
+ return g_VBoxGuest->_RTHeapSimpleRelocate(hHeap, offDelta);
+}
+int RTHeapOffsetInit(PRTHEAPOFFSET phHeap, void *pvMemory, size_t cbMemory)
+{
+ return g_VBoxGuest->_RTHeapOffsetInit(phHeap, pvMemory, cbMemory);
+}
+int RTHeapSimpleInit(PRTHEAPSIMPLE pHeap, void *pvMemory, size_t cbMemory)
+{
+ return g_VBoxGuest->_RTHeapSimpleInit(pHeap, pvMemory, cbMemory);
+}
+void* RTHeapOffsetAlloc(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment)
+{
+ return g_VBoxGuest->_RTHeapOffsetAlloc(hHeap, cb, cbAlignment);
+}
+void* RTHeapSimpleAlloc(RTHEAPSIMPLE Heap, size_t cb, size_t cbAlignment)
+{
+ return g_VBoxGuest->_RTHeapSimpleAlloc(Heap, cb, cbAlignment);
+}
+void RTHeapOffsetFree(RTHEAPOFFSET hHeap, void *pv)
+{
+ g_VBoxGuest->_RTHeapOffsetFree(hHeap, pv);
+}
+void RTHeapSimpleFree(RTHEAPSIMPLE Heap, void *pv)
+{
+ g_VBoxGuest->_RTHeapSimpleFree(Heap, pv);
+}
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c
new file mode 100644
index 00000000..5aa31702
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c
@@ -0,0 +1,553 @@
+/* $Id: VBoxGuest-haiku.c $ */
+/** @file
+ * VBoxGuest kernel module, Haiku Guest Additions, implementation.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+#define IN_VBOXGUEST
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <OS.h>
+#include <Drivers.h>
+#include <KernelExport.h>
+#include <PCI.h>
+
+#include "VBoxGuest-haiku.h"
+#include "VBoxGuestInternal.h"
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/initterm.h>
+#include <iprt/process.h>
+#include <iprt/mem.h>
+#include <iprt/memobj.h>
+#include <iprt/asm.h>
+#include <iprt/timer.h>
+#include <iprt/heap.h>
+
+#define MODULE_NAME VBOXGUEST_MODULE_NAME
+
+/*
+ * IRQ related functions.
+ */
+static void VBoxGuestHaikuRemoveIRQ(void *pvState);
+static int VBoxGuestHaikuAddIRQ(void *pvState);
+static int32 VBoxGuestHaikuISR(void *pvState);
+
+/*
+ * Available functions for kernel drivers.
+ */
+DECLVBGL(int) VBoxGuestHaikuServiceCall(void *pvSession, unsigned uCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
+DECLVBGL(void *) VBoxGuestHaikuServiceOpen(uint32_t *pu32Version);
+DECLVBGL(int) VBoxGuestHaikuServiceClose(void *pvSession);
+DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version);
+DECLVBGL(int) VBoxGuestIDCClose(void *pvSession);
+DECLVBGL(int) VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
+
+static status_t std_ops(int32 op, ...);
+
+static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
+
+int32 api_version = B_CUR_DRIVER_API_VERSION;
+
+/** List of cloned device. Managed by the kernel. */
+//static struct clonedevs *g_pVBoxGuestHaikuClones;
+/** The dev_clone event handler tag. */
+//static eventhandler_tag g_VBoxGuestHaikuEHTag;
+/** selinfo structure used for polling. */
+//static struct selinfo g_SelInfo;
+/** PCI Bus Manager Module */
+static pci_module_info *gPCI;
+
+static struct vboxguest_module_info g_VBoxGuest =
+{
+ {
+ MODULE_NAME,
+ 0,
+ std_ops
+ },
+ { 0 },
+ { 0 },
+ 0,
+ RTLogBackdoorPrintf,
+ RTLogBackdoorPrintfV,
+ RTLogSetDefaultInstanceThread,
+ RTMemAllocExTag,
+ RTMemContAlloc,
+ RTMemContFree,
+ RTMemFreeEx,
+ RTMpIsCpuPossible,
+ RTMpNotificationDeregister,
+ RTMpNotificationRegister,
+ RTMpOnAll,
+ RTMpOnOthers,
+ RTMpOnSpecific,
+ RTPowerNotificationDeregister,
+ RTPowerNotificationRegister,
+ RTPowerSignalEvent,
+ RTR0AssertPanicSystem,
+ RTR0Init,
+ RTR0MemObjAddress,
+ RTR0MemObjAddressR3,
+ RTR0MemObjAllocContTag,
+ RTR0MemObjAllocLowTag,
+ RTR0MemObjAllocPageTag,
+ RTR0MemObjAllocPhysExTag,
+ RTR0MemObjAllocPhysNCTag,
+ RTR0MemObjAllocPhysTag,
+ RTR0MemObjEnterPhysTag,
+ RTR0MemObjFree,
+ RTR0MemObjGetPagePhysAddr,
+ RTR0MemObjIsMapping,
+ RTR0MemObjLockKernelTag,
+ RTR0MemObjLockUserTag,
+ RTR0MemObjMapKernelExTag,
+ RTR0MemObjMapKernelTag,
+ RTR0MemObjMapUserTag,
+ RTR0MemObjProtect,
+ RTR0MemObjReserveKernelTag,
+ RTR0MemObjReserveUserTag,
+ RTR0MemObjSize,
+ RTR0ProcHandleSelf,
+ RTR0Term,
+ RTR0TermForced,
+ RTProcSelf,
+ RTSemEventGetResolution,
+ RTSemEventMultiGetResolution,
+ RTSemEventMultiWaitEx,
+ RTSemEventMultiWaitExDebug,
+ RTSemEventWaitEx,
+ RTSemEventWaitExDebug,
+ RTThreadIsInInterrupt,
+ RTThreadPreemptDisable,
+ RTThreadPreemptIsEnabled,
+ RTThreadPreemptIsPending,
+ RTThreadPreemptIsPendingTrusty,
+ RTThreadPreemptIsPossible,
+ RTThreadPreemptRestore,
+ RTTimerGetSystemGranularity,
+ RTTimerReleaseSystemGranularity,
+ RTTimerRequestSystemGranularity,
+ RTSpinlockAcquire,
+ RTSpinlockRelease,
+ RTSpinlockReleaseNoInts,
+ RTMemTmpAllocTag,
+ RTMemTmpFree,
+ RTLogDefaultInstance,
+ RTLogRelDefaultInstance,
+ RTErrConvertToErrno,
+ VBoxGuestCommonIOCtl,
+ VBoxGuestCreateUserSession,
+ VBoxGuestCloseSession,
+ VBoxGuestIDCOpen,
+ VBoxGuestIDCClose,
+ VBoxGuestIDCCall,
+ RTAssertMsg1Weak,
+ RTAssertMsg2Weak,
+ RTAssertMsg2WeakV,
+ RTAssertShouldPanic,
+ RTSemFastMutexCreate,
+ RTSemFastMutexDestroy,
+ RTSemFastMutexRelease,
+ RTSemFastMutexRequest,
+ RTSemMutexCreate,
+ RTSemMutexDestroy,
+ RTSemMutexRelease,
+ RTSemMutexRequest,
+ RTHeapSimpleRelocate,
+ RTHeapOffsetInit,
+ RTHeapSimpleInit,
+ RTHeapOffsetAlloc,
+ RTHeapSimpleAlloc,
+ RTHeapOffsetFree,
+ RTHeapSimpleFree
+};
+
+#if 0
+/**
+ * DEVFS event handler.
+ */
+static void VBoxGuestHaikuClone(void *pvArg, struct ucred *pCred, char *pszName, int cchName, struct cdev **ppDev)
+{
+ int iUnit;
+ int rc;
+
+ Log(("VBoxGuestHaikuClone: pszName=%s ppDev=%p\n", pszName, ppDev));
+
+ /*
+ * One device node per user, si_drv1 points to the session.
+ * /dev/vboxguest<N> where N = {0...255}.
+ */
+ if (!ppDev)
+ return;
+ if (strcmp(pszName, "vboxguest") == 0)
+ iUnit = -1;
+ else if (dev_stdclone(pszName, NULL, "vboxguest", &iUnit) != 1)
+ return;
+ if (iUnit >= 256)
+ {
+ Log(("VBoxGuestHaikuClone: iUnit=%d >= 256 - rejected\n", iUnit));
+ return;
+ }
+
+ Log(("VBoxGuestHaikuClone: pszName=%s iUnit=%d\n", pszName, iUnit));
+
+ rc = clone_create(&g_pVBoxGuestHaikuClones, &g_VBoxGuestHaikuDeviceHooks, &iUnit, ppDev, 0);
+ Log(("VBoxGuestHaikuClone: clone_create -> %d; iUnit=%d\n", rc, iUnit));
+ if (rc)
+ {
+ *ppDev = make_dev(&g_VBoxGuestHaikuDeviceHooks,
+ iUnit,
+ UID_ROOT,
+ GID_WHEEL,
+ 0644,
+ "vboxguest%d", iUnit);
+ if (*ppDev)
+ {
+ dev_ref(*ppDev);
+ (*ppDev)->si_flags |= SI_CHEAPCLONE;
+ Log(("VBoxGuestHaikuClone: Created *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
+ *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
+ (*ppDev)->si_drv1 = (*ppDev)->si_drv2 = NULL;
+ }
+ else
+ Log(("VBoxGuestHaikuClone: make_dev iUnit=%d failed\n", iUnit));
+ }
+ else
+ Log(("VBoxGuestHaikuClone: Existing *ppDev=%p iUnit=%d si_drv1=%p si_drv2=%p\n",
+ *ppDev, iUnit, (*ppDev)->si_drv1, (*ppDev)->si_drv2));
+}
+#endif
+
+
+static status_t VBoxGuestHaikuDetach(void)
+{
+ struct VBoxGuestDeviceState *pState = &sState;
+
+ if (cUsers > 0)
+ return EBUSY;
+
+ /*
+ * Reverse what we did in VBoxGuestHaikuAttach.
+ */
+ VBoxGuestHaikuRemoveIRQ(pState);
+
+ if (pState->iVMMDevMemAreaId)
+ delete_area(pState->iVMMDevMemAreaId);
+
+ VBoxGuestDeleteDevExt(&g_DevExt);
+
+#ifdef DO_LOG
+ RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
+ RTLogSetDefaultInstance(NULL);
+// RTLogDestroy(RTLogSetDefaultInstance(NULL));
+#endif
+
+ RTSpinlockDestroy(g_Spinlock);
+ g_Spinlock = NIL_RTSPINLOCK;
+
+ RTR0Term();
+ return B_OK;
+}
+
+
+/**
+ * Interrupt service routine.
+ *
+ * @returns Whether the interrupt was from VMMDev.
+ * @param pvState Opaque pointer to the device state.
+ */
+static int32 VBoxGuestHaikuISR(void *pvState)
+{
+ LogFlow((MODULE_NAME ":VBoxGuestHaikuISR pvState=%p\n", pvState));
+
+ bool fOurIRQ = VBoxGuestCommonISR(&g_DevExt);
+ if (fOurIRQ)
+ return B_HANDLED_INTERRUPT;
+ return B_UNHANDLED_INTERRUPT;
+}
+
+
+void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
+{
+ LogFlow((MODULE_NAME "::NativeISRMousePollEvent:\n"));
+
+ status_t err = B_OK;
+ //dprintf(MODULE_NAME ": isr mouse\n");
+
+ /*
+ * Wake up poll waiters.
+ */
+ //selwakeup(&g_SelInfo);
+ //XXX:notify_select_event();
+ RTSpinlockAcquire(g_Spinlock);
+
+ if (sState.selectSync)
+ {
+ //dprintf(MODULE_NAME ": isr mouse: notify\n");
+ notify_select_event(sState.selectSync, sState.selectEvent);
+ sState.selectEvent = (uint8_t)0;
+ sState.selectRef = (uint32_t)0;
+ sState.selectSync = NULL;
+ }
+ else
+ err = B_ERROR;
+
+ RTSpinlockRelease(g_Spinlock);
+}
+
+
+/**
+ * Sets IRQ for VMMDev.
+ *
+ * @returns Haiku error code.
+ * @param pvState Pointer to the state info structure.
+ */
+static int VBoxGuestHaikuAddIRQ(void *pvState)
+{
+ status_t err;
+ struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
+
+ AssertReturn(pState, VERR_INVALID_PARAMETER);
+
+ err = install_io_interrupt_handler(pState->iIrqResId, VBoxGuestHaikuISR, pState, 0);
+ if (err == B_OK)
+ return VINF_SUCCESS;
+ return VERR_DEV_IO_ERROR;
+}
+
+
+/**
+ * Removes IRQ for VMMDev.
+ *
+ * @param pvState Opaque pointer to the state info structure.
+ */
+static void VBoxGuestHaikuRemoveIRQ(void *pvState)
+{
+ struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
+ AssertPtr(pState);
+
+ remove_io_interrupt_handler(pState->iIrqResId, VBoxGuestHaikuISR, pState);
+}
+
+
+static status_t VBoxGuestHaikuAttach(const pci_info *pDevice)
+{
+ status_t status;
+ int rc = VINF_SUCCESS;
+ int iResId = 0;
+ struct VBoxGuestDeviceState *pState = &sState;
+ static const char *const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
+ PRTLOGGER pRelLogger;
+
+ AssertReturn(pDevice, B_BAD_VALUE);
+
+ cUsers = 0;
+
+ /*
+ * Initialize IPRT R0 driver, which internally calls OS-specific r0 init.
+ */
+ rc = RTR0Init(0);
+ if (RT_FAILURE(rc))
+ {
+ /** @todo r=ramshankar: use dprintf here. */
+ LogFunc(("RTR0Init failed.\n"));
+ return ENXIO;
+ }
+
+ rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxGuestHaiku");
+ if (RT_FAILURE(rc))
+ {
+ LogRel(("VBoxGuestHaikuAttach: RTSpinlock create failed. rc=%Rrc\n", rc));
+ return ENXIO;
+ }
+
+#ifdef DO_LOG
+ /*
+ * Create the release log.
+ * (We do that here instead of common code because we want to log
+ * early failures using the LogRel macro.)
+ */
+ rc = RTLogCreate(&pRelLogger, 0 | RTLOGFLAGS_PREFIX_THREAD /* fFlags */, "all",
+ "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups,
+ RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER | RTLOGDEST_USER, NULL);
+ dprintf(MODULE_NAME ": RTLogCreate: %d\n", rc);
+ if (RT_SUCCESS(rc))
+ {
+ //RTLogGroupSettings(pRelLogger, g_szLogGrp);
+ //RTLogFlags(pRelLogger, g_szLogFlags);
+ //RTLogDestinations(pRelLogger, "/var/log/vboxguest.log");
+ RTLogRelSetDefaultInstance(pRelLogger);
+ RTLogSetDefaultInstance(pRelLogger); //XXX
+ }
+#endif
+
+ /*
+ * Allocate I/O port resource.
+ */
+ pState->uIOPortBase = pDevice->u.h0.base_registers[0];
+ /* @todo check flags for IO? */
+ if (pState->uIOPortBase)
+ {
+ /*
+ * Map the MMIO region.
+ */
+ uint32 phys = pDevice->u.h0.base_registers[1];
+ /* @todo Check flags for mem? */
+ pState->VMMDevMemSize = pDevice->u.h0.base_register_sizes[1];
+ pState->iVMMDevMemAreaId = map_physical_memory("VirtualBox Guest MMIO", phys, pState->VMMDevMemSize,
+ B_ANY_KERNEL_BLOCK_ADDRESS, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA,
+ &pState->pMMIOBase);
+ if (pState->iVMMDevMemAreaId > 0 && pState->pMMIOBase)
+ {
+ /*
+ * Call the common device extension initializer.
+ */
+ rc = VBoxGuestInitDevExt(&g_DevExt, pState->uIOPortBase, pState->pMMIOBase, pState->VMMDevMemSize,
+#if ARCH_BITS == 64
+ VBOXOSTYPE_Haiku_x64,
+#else
+ VBOXOSTYPE_Haiku,
+#endif
+ VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * Add IRQ of VMMDev.
+ */
+ pState->iIrqResId = pDevice->u.h0.interrupt_line;
+ rc = VBoxGuestHaikuAddIRQ(pState);
+ if (RT_SUCCESS(rc))
+ {
+ LogRel((MODULE_NAME ": loaded successfully\n"));
+ return B_OK;
+ }
+
+ LogRel((MODULE_NAME ":VBoxGuestInitDevExt failed.\n"));
+ VBoxGuestDeleteDevExt(&g_DevExt);
+ }
+ else
+ LogRel((MODULE_NAME ":VBoxGuestHaikuAddIRQ failed.\n"));
+ }
+ else
+ LogRel((MODULE_NAME ":MMIO region setup failed.\n"));
+ }
+ else
+ LogRel((MODULE_NAME ":IOport setup failed.\n"));
+
+ RTR0Term();
+ return ENXIO;
+}
+
+
+static status_t VBoxGuestHaikuProbe(pci_info *pDevice)
+{
+ if ((pDevice->vendor_id == VMMDEV_VENDORID) && (pDevice->device_id == VMMDEV_DEVICEID))
+ return B_OK;
+
+ return ENXIO;
+}
+
+
+status_t init_module(void)
+{
+ status_t err = B_ENTRY_NOT_FOUND;
+ pci_info info;
+ int ix = 0;
+
+ err = get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI);
+ if (err != B_OK)
+ return err;
+
+ while ((*gPCI->get_nth_pci_info)(ix++, &info) == B_OK)
+ {
+ if (VBoxGuestHaikuProbe(&info) == 0)
+ {
+ /* We found it */
+ err = VBoxGuestHaikuAttach(&info);
+ return err;
+ }
+ }
+
+ return B_ENTRY_NOT_FOUND;
+}
+
+
+void uninit_module(void)
+{
+ VBoxGuestHaikuDetach();
+ put_module(B_PCI_MODULE_NAME);
+}
+
+
+static status_t std_ops(int32 op, ...)
+{
+ switch (op)
+ {
+ case B_MODULE_INIT:
+ return init_module();
+
+ case B_MODULE_UNINIT:
+ {
+ uninit_module();
+ return B_OK;
+ }
+
+ default:
+ return B_ERROR;
+ }
+}
+
+
+_EXPORT module_info *modules[] =
+{
+ (module_info *)&g_VBoxGuest,
+ NULL
+};
+
+/* Common code that depend on g_DevExt. */
+#include "VBoxGuestIDC-unix.c.h"
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.h
new file mode 100644
index 00000000..d577448c
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.h
@@ -0,0 +1,226 @@
+/* $Id: VBoxGuest-haiku.h $ */
+/** @file
+ * VBoxGuest kernel module, Haiku Guest Additions, header.
+ */
+
+/*
+ * Copyright (C) 2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
+ * This code is based on:
+ *
+ * VirtualBox Guest Additions for Haiku.
+ * Copyright (c) 2011 Mike Smith <mike@scgtrp.net>
+ * François Revol <revol@free.fr>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef ___VBoxGuest_haiku_h
+#define ___VBoxGuest_haiku_h
+
+#include <OS.h>
+#include <Drivers.h>
+#include <drivers/module.h>
+
+#include "VBoxGuestInternal.h"
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/initterm.h>
+#include <iprt/process.h>
+#include <iprt/mem.h>
+#include <iprt/asm.h>
+#include <iprt/mp.h>
+#include <iprt/power.h>
+#include <iprt/thread.h>
+
+/** The module name. */
+#define VBOXGUEST_MODULE_NAME "generic/vboxguest"
+
+struct VBoxGuestDeviceState
+{
+ /** Resource ID of the I/O port */
+ int iIOPortResId;
+ /** Pointer to the I/O port resource. */
+// struct resource *pIOPortRes;
+ /** Start address of the IO Port. */
+ uint16_t uIOPortBase;
+ /** Resource ID of the MMIO area */
+ area_id iVMMDevMemAreaId;
+ /** Pointer to the MMIO resource. */
+// struct resource *pVMMDevMemRes;
+ /** Handle of the MMIO resource. */
+// bus_space_handle_t VMMDevMemHandle;
+ /** Size of the memory area. */
+ size_t VMMDevMemSize;
+ /** Mapping of the register space */
+ void *pMMIOBase;
+ /** IRQ number */
+ int iIrqResId;
+ /** IRQ resource handle. */
+// struct resource *pIrqRes;
+ /** Pointer to the IRQ handler. */
+// void *pfnIrqHandler;
+ /** VMMDev version */
+ uint32_t u32Version;
+
+ /** The (only) select data we wait on. */
+ //XXX: should leave in pSession ?
+ uint8_t selectEvent;
+ uint32_t selectRef;
+ void *selectSync;
+};
+
+struct vboxguest_module_info
+{
+ module_info module;
+
+ VBOXGUESTDEVEXT devExt;
+ struct VBoxGuestDeviceState _sState;
+ volatile uint32_t _cUsers;
+
+ size_t(*_RTLogBackdoorPrintf)(const char *pszFormat, ...);
+ size_t(*_RTLogBackdoorPrintfV)(const char *pszFormat, va_list args);
+ int (*_RTLogSetDefaultInstanceThread)(PRTLOGGER pLogger, uintptr_t uKey);
+ int (*_RTMemAllocExTag)(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv);
+ void* (*_RTMemContAlloc)(PRTCCPHYS pPhys, size_t cb);
+ void (*_RTMemContFree)(void *pv, size_t cb);
+ void (*_RTMemFreeEx)(void *pv, size_t cb);
+ bool (*_RTMpIsCpuPossible)(RTCPUID idCpu);
+ int (*_RTMpNotificationDeregister)(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
+ int (*_RTMpNotificationRegister)(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
+ int (*_RTMpOnAll)(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+ int (*_RTMpOnOthers)(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+ int (*_RTMpOnSpecific)(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+ int (*_RTPowerNotificationDeregister)(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser);
+ int (*_RTPowerNotificationRegister)(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser);
+ int (*_RTPowerSignalEvent)(RTPOWEREVENT enmEvent);
+ void (*_RTR0AssertPanicSystem)(void);
+ int (*_RTR0Init)(unsigned fReserved);
+ void* (*_RTR0MemObjAddress)(RTR0MEMOBJ MemObj);
+ RTR3PTR(*_RTR0MemObjAddressR3)(RTR0MEMOBJ MemObj);
+ int (*_RTR0MemObjAllocContTag)(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+ int (*_RTR0MemObjAllocLowTag)(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+ int (*_RTR0MemObjAllocPageTag)(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+ int (*_RTR0MemObjAllocPhysExTag)(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment, const char *pszTag);
+ int (*_RTR0MemObjAllocPhysNCTag)(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag);
+ int (*_RTR0MemObjAllocPhysTag)(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag);
+ int (*_RTR0MemObjEnterPhysTag)(PRTR0MEMOBJ pMemObj, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy, const char *pszTag);
+ int (*_RTR0MemObjFree)(RTR0MEMOBJ MemObj, bool fFreeMappings);
+ RTHCPHYS(*_RTR0MemObjGetPagePhysAddr)(RTR0MEMOBJ MemObj, size_t iPage);
+ bool (*_RTR0MemObjIsMapping)(RTR0MEMOBJ MemObj);
+ int (*_RTR0MemObjLockKernelTag)(PRTR0MEMOBJ pMemObj, void *pv, size_t cb, uint32_t fAccess, const char *pszTag);
+ int (*_RTR0MemObjLockUserTag)(PRTR0MEMOBJ pMemObj, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
+ RTR0PROCESS R0Process, const char *pszTag);
+ int (*_RTR0MemObjMapKernelExTag)(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag);
+ int (*_RTR0MemObjMapKernelTag)(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed,
+ size_t uAlignment, unsigned fProt, const char *pszTag);
+ int (*_RTR0MemObjMapUserTag)(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, RTR3PTR R3PtrFixed,
+ size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process, const char *pszTag);
+ int (*_RTR0MemObjProtect)(RTR0MEMOBJ hMemObj, size_t offSub, size_t cbSub, uint32_t fProt);
+ int (*_RTR0MemObjReserveKernelTag)(PRTR0MEMOBJ pMemObj, void *pvFixed, size_t cb, size_t uAlignment, const char *pszTag);
+ int (*_RTR0MemObjReserveUserTag)(PRTR0MEMOBJ pMemObj, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
+ RTR0PROCESS R0Process, const char *pszTag);
+ size_t(*_RTR0MemObjSize)(RTR0MEMOBJ MemObj);
+ RTR0PROCESS(*_RTR0ProcHandleSelf)(void);
+ void (*_RTR0Term)(void);
+ void (*_RTR0TermForced)(void);
+ RTPROCESS(*_RTProcSelf)(void);
+ uint32_t(*_RTSemEventGetResolution)(void);
+ uint32_t(*_RTSemEventMultiGetResolution)(void);
+ int (*_RTSemEventMultiWaitEx)(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout);
+ int (*_RTSemEventMultiWaitExDebug)(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL);
+ int (*_RTSemEventWaitEx)(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout);
+ int (*_RTSemEventWaitExDebug)(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL);
+ bool (*_RTThreadIsInInterrupt)(RTTHREAD hThread);
+ void (*_RTThreadPreemptDisable)(PRTTHREADPREEMPTSTATE pState);
+ bool (*_RTThreadPreemptIsEnabled)(RTTHREAD hThread);
+ bool (*_RTThreadPreemptIsPending)(RTTHREAD hThread);
+ bool (*_RTThreadPreemptIsPendingTrusty)(void);
+ bool (*_RTThreadPreemptIsPossible)(void);
+ void (*_RTThreadPreemptRestore)(PRTTHREADPREEMPTSTATE pState);
+ uint32_t(*_RTTimerGetSystemGranularity)(void);
+ int (*_RTTimerReleaseSystemGranularity)(uint32_t u32Granted);
+ int (*_RTTimerRequestSystemGranularity)(uint32_t u32Request, uint32_t *pu32Granted);
+ void (*_RTSpinlockAcquire)(RTSPINLOCK Spinlock);
+ void (*_RTSpinlockRelease)(RTSPINLOCK Spinlock);
+ void (*_RTSpinlockReleaseNoInts)(RTSPINLOCK Spinlock);
+ void* (*_RTMemTmpAllocTag)(size_t cb, const char *pszTag);
+ void (*_RTMemTmpFree)(void *pv);
+ PRTLOGGER(*_RTLogDefaultInstance)(void);
+ PRTLOGGER(*_RTLogRelDefaultInstance)(void);
+ int (*_RTErrConvertToErrno)(int iErr);
+ int (*_VBoxGuestCommonIOCtl)(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
+ void *pvData, size_t cbData, size_t *pcbDataReturned);
+ int (*_VBoxGuestCreateUserSession)(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *ppSession);
+ void (*_VBoxGuestCloseSession)(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
+ void* (*_VBoxGuestIDCOpen)(uint32_t *pu32Version);
+ int (*_VBoxGuestIDCClose)(void *pvSession);
+ int (*_VBoxGuestIDCCall)(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
+ void (*_RTAssertMsg1Weak)(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
+ void (*_RTAssertMsg2Weak)(const char *pszFormat, ...);
+ void (*_RTAssertMsg2WeakV)(const char *pszFormat, va_list va);
+ bool (*_RTAssertShouldPanic)(void);
+ int (*_RTSemFastMutexCreate)(PRTSEMFASTMUTEX phFastMtx);
+ int (*_RTSemFastMutexDestroy)(RTSEMFASTMUTEX hFastMtx);
+ int (*_RTSemFastMutexRelease)(RTSEMFASTMUTEX hFastMtx);
+ int (*_RTSemFastMutexRequest)(RTSEMFASTMUTEX hFastMtx);
+ int (*_RTSemMutexCreate)(PRTSEMMUTEX phFastMtx);
+ int (*_RTSemMutexDestroy)(RTSEMMUTEX hFastMtx);
+ int (*_RTSemMutexRelease)(RTSEMMUTEX hFastMtx);
+ int (*_RTSemMutexRequest)(RTSEMMUTEX hFastMtx, RTMSINTERVAL cMillies);
+ int (*_RTHeapSimpleRelocate)(RTHEAPSIMPLE hHeap, uintptr_t offDelta);
+ int (*_RTHeapOffsetInit)(PRTHEAPOFFSET phHeap, void *pvMemory, size_t cbMemory);
+ int (*_RTHeapSimpleInit)(PRTHEAPSIMPLE pHeap, void *pvMemory, size_t cbMemory);
+ void* (*_RTHeapOffsetAlloc)(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment);
+ void* (*_RTHeapSimpleAlloc)(RTHEAPSIMPLE Heap, size_t cb, size_t cbAlignment);
+ void (*_RTHeapOffsetFree)(RTHEAPOFFSET hHeap, void *pv);
+ void (*_RTHeapSimpleFree)(RTHEAPSIMPLE Heap, void *pv);
+};
+
+
+#ifdef IN_VBOXGUEST
+#define g_DevExt (g_VBoxGuest.devExt)
+#define cUsers (g_VBoxGuest._cUsers)
+#define sState (g_VBoxGuest._sState)
+#else
+#define g_DevExt (g_VBoxGuest->devExt)
+#define cUsers (g_VBoxGuest->_cUsers)
+#define sState (g_VBoxGuest->_sState)
+extern struct vboxguest_module_info *g_VBoxGuest;
+#endif
+
+#endif /* ___VBoxGuest_haiku_h */
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
index b4270bae..a4824893 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-linux.c
@@ -1,4 +1,4 @@
-/* $Rev: 80789 $ */
+/* $Rev: 88900 $ */
/** @file
* VBoxGuest - Linux specifics.
*
@@ -7,7 +7,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -196,7 +196,11 @@ static struct miscdevice g_MiscDeviceUser =
/** PCI hotplug structure. */
-static const struct pci_device_id __devinitdata g_VBoxGuestPciId[] =
+static const struct pci_device_id
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
+__devinitdata
+#endif
+g_VBoxGuestPciId[] =
{
{
vendor: VMMDEV_VENDORID,
@@ -936,9 +940,9 @@ void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
* Wake up everyone that's in a poll() and post anyone that has
* subscribed to async notifications.
*/
- Log(("VBoxGuestNativeISRMousePollEvent: wake_up_all\n"));
+ Log3(("VBoxGuestNativeISRMousePollEvent: wake_up_all\n"));
wake_up_all(&g_PollEventQueue);
- Log(("VBoxGuestNativeISRMousePollEvent: kill_fasync\n"));
+ Log3(("VBoxGuestNativeISRMousePollEvent: kill_fasync\n"));
kill_fasync(&g_pFAsyncQueue, SIGIO, POLL_IN);
#ifdef VBOXGUEST_WITH_INPUT_DRIVER
/* Report events to the kernel input device */
@@ -957,7 +961,7 @@ void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
# endif
}
#endif
- Log(("VBoxGuestNativeISRMousePollEvent: done\n"));
+ Log3(("VBoxGuestNativeISRMousePollEvent: done\n"));
}
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp
index a74f5595..c4ba2219 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
+ * Copyright (C) 2007-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -19,7 +19,7 @@
*
* VBoxDrv - OS/2 specifics.
*
- * Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
+ * Copyright (c) 2007-2012 knut st. osmundsen <bird-src-spam@anduin.net>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def
index 4728686e..15c04914 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-os2.def
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2007 Oracle Corporation
+; Copyright (C) 2007-2010 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
index a94e3848..7c7ff3fc 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.c
@@ -696,6 +696,8 @@ static int VBoxGuestSolarisIOCtl(dev_t Dev, int Cmd, intptr_t pArg, int Mode, cr
* which are not really failures that require logging.
*/
Log((DEVICE_NAME "::IOCtl: VBoxGuestCommonIOCtl failed. Cmd=%#x rc=%d\n", Cmd, rc));
+ if (rc == VERR_PERMISSION_DENIED) /* RTErrConvertToErrno() below will ring-0 debug assert if we don't do this. */
+ rc = VERR_ACCESS_DENIED;
rc = RTErrConvertToErrno(rc);
}
*pVal = rc;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.conf b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.conf
index 6c23af13..1e2c814f 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.conf
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-solaris.conf
@@ -1,7 +1,7 @@
#
# OpenSolaris Guest Driver Configuration
#
-# Copyright (C) 2007-2010 Oracle Corporation
+# Copyright (C) 2007-2012 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-legacy.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-legacy.cpp
index 5f1ce5d7..3dd55441 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-legacy.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-legacy.cpp
@@ -1,8 +1,10 @@
+/* $Id: VBoxGuest-win-legacy.cpp $ */
/** @file
- *
* VBoxGuest-win-legacy - Windows NT4 specifics.
- *
- * Copyright (C) 2010 Oracle Corporation
+ */
+
+/*
+ * Copyright (C) 2010-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -22,15 +24,12 @@
#include <VBox/log.h>
#include <VBox/version.h>
#include <VBox/VBoxGuestLib.h>
+#include <iprt/string.h>
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
-
-/* Reenable logging, this was #undef'ed on iprt/log.h for RING0. */
-#define LOG_ENABLED
-
#ifndef PCI_MAX_BUSES
# define PCI_MAX_BUSES 256
#endif
@@ -40,13 +39,12 @@
* Internal Functions *
*******************************************************************************/
RT_C_DECLS_BEGIN
-NTSTATUS vboxguestwinnt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath);
-static NTSTATUS vboxguestwinnt4FindPCIDevice(PULONG pBusNumber, PPCI_SLOT_NUMBER pSlotNumber);
+static NTSTATUS vbgdNt4FindPciDevice(PULONG pulBusNumber, PPCI_SLOT_NUMBER pSlotNumber);
RT_C_DECLS_END
#ifdef ALLOC_PRAGMA
-#pragma alloc_text (INIT, vboxguestwinnt4CreateDevice)
-#pragma alloc_text (INIT, vboxguestwinnt4FindPCIDevice)
+# pragma alloc_text(INIT, vbgdNt4CreateDevice)
+# pragma alloc_text(INIT, vbgdNt4FindPciDevice)
#endif
@@ -55,97 +53,86 @@ RT_C_DECLS_END
*
* @returns NT status code.
*
- * @param pDrvObj
- * @param pDevObj
- * @param pRegPath
+ * @param pDrvObj The driver object.
+ * @param pDevObj Unused. NULL. Dunno why it's here, makes no sense.
+ * @param pRegPath The driver registry path.
*/
-NTSTATUS vboxguestwinnt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath)
+NTSTATUS vbgdNt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath)
{
- int vrc = VINF_SUCCESS;
- NTSTATUS rc = STATUS_SUCCESS;
-
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: pDrvObj=%p, pDevObj=%p, pRegPath=%p\n",
- pDrvObj, pDevObj, pRegPath));
+ Log(("VBoxGuest::vbgdNt4CreateDevice: pDrvObj=%p, pDevObj=%p, pRegPath=%p\n", pDrvObj, pDevObj, pRegPath));
/*
* Find our virtual PCI device
*/
- ULONG uBusNumber, uSlotNumber;
- rc = vboxguestwinnt4FindPCIDevice(&uBusNumber, (PCI_SLOT_NUMBER*)&uSlotNumber);
+ ULONG uBusNumber;
+ PCI_SLOT_NUMBER SlotNumber;
+ NTSTATUS rc = vbgdNt4FindPciDevice(&uBusNumber, &SlotNumber);
if (NT_ERROR(rc))
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Device not found!\n"));
-
- bool fSymbolicLinkCreated = false;
- UNICODE_STRING szDosName;
- PDEVICE_OBJECT pDeviceObject = NULL;
- if (NT_SUCCESS(rc))
{
- /*
- * Create device.
- */
- UNICODE_STRING szDevName;
- RtlInitUnicodeString(&szDevName, VBOXGUEST_DEVICE_NAME_NT);
- rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXT), &szDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
- if (NT_SUCCESS(rc))
- {
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Device created\n"));
-
- RtlInitUnicodeString(&szDosName, VBOXGUEST_DEVICE_NAME_DOS);
- rc = IoCreateSymbolicLink(&szDosName, &szDevName);
- if (NT_SUCCESS(rc))
- {
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Symlink created\n"));
- fSymbolicLinkCreated = true;
- }
- else
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: IoCreateSymbolicLink failed with rc = %#x\n", rc));
- }
- else
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: IoCreateDevice failed with rc = %#x\n", rc));
+ Log(("VBoxGuest::vbgdNt4CreateDevice: Device not found!\n"));
+ return rc;
}
/*
- * Setup the device extension.
+ * Create device.
*/
- PVBOXGUESTDEVEXT pDevExt = NULL;
+ UNICODE_STRING szDevName;
+ RtlInitUnicodeString(&szDevName, VBOXGUEST_DEVICE_NAME_NT);
+ PDEVICE_OBJECT pDeviceObject = NULL;
+ rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXTWIN), &szDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
if (NT_SUCCESS(rc))
{
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Setting up device extension ...\n"));
+ Log(("VBoxGuest::vbgdNt4CreateDevice: Device created\n"));
- pDevExt = (PVBOXGUESTDEVEXT)pDeviceObject->DeviceExtension;
- RtlZeroMemory(pDevExt, sizeof(VBOXGUESTDEVEXT));
- }
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, VBOXGUEST_DEVICE_NAME_DOS);
+ rc = IoCreateSymbolicLink(&DosName, &szDevName);
+ if (NT_SUCCESS(rc))
+ {
+ Log(("VBoxGuest::vbgdNt4CreateDevice: Symlink created\n"));
- if (NT_SUCCESS(rc) && pDevExt)
- {
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Device extension created\n"));
+ /*
+ * Setup the device extension.
+ */
+ Log(("VBoxGuest::vbgdNt4CreateDevice: Setting up device extension ...\n"));
- /* Store a reference to ourself. */
- pDevExt->win.s.pDeviceObject = pDeviceObject;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDeviceObject->DeviceExtension;
+ RT_ZERO(*pDevExt);
- /* Store bus and slot number we've queried before. */
- pDevExt->win.s.busNumber = uBusNumber;
- pDevExt->win.s.slotNumber = uSlotNumber;
+ Log(("VBoxGuest::vbgdNt4CreateDevice: Device extension created\n"));
- #ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
- rc = hlpRegisterBugCheckCallback(pDevExt);
- #endif
- }
+ /* Store a reference to ourself. */
+ pDevExt->pDeviceObject = pDeviceObject;
- /* Do the actual VBox init ... */
- if (NT_SUCCESS(rc))
- rc = vboxguestwinInit(pDrvObj, pDeviceObject, pRegPath);
+ /* Store bus and slot number we've queried before. */
+ pDevExt->busNumber = uBusNumber;
+ pDevExt->slotNumber = SlotNumber.u.AsULONG;
- /* Clean up in case of errors. */
- if (NT_ERROR(rc))
- {
- if (fSymbolicLinkCreated && szDosName.Length > 0)
- IoDeleteSymbolicLink(&szDosName);
- if (pDeviceObject)
- IoDeleteDevice(pDeviceObject);
- }
+#ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
+ rc = hlpRegisterBugCheckCallback(pDevExt);
+#endif
- Log(("VBoxGuest::vboxguestwinnt4CreateDevice: Returning rc = 0x%x\n", rc));
+ /* Do the actual VBox init ... */
+ if (NT_SUCCESS(rc))
+ {
+ rc = vbgdNtInit(pDrvObj, pDeviceObject, pRegPath);
+ if (NT_SUCCESS(rc))
+ {
+ Log(("VBoxGuest::vbgdNt4CreateDevice: Returning rc = 0x%x (succcess)\n", rc));
+ return rc;
+ }
+
+ /* bail out */
+ }
+ IoDeleteSymbolicLink(&DosName);
+ }
+ else
+ Log(("VBoxGuest::vbgdNt4CreateDevice: IoCreateSymbolicLink failed with rc = %#x\n", rc));
+ IoDeleteDevice(pDeviceObject);
+ }
+ else
+ Log(("VBoxGuest::vbgdNt4CreateDevice: IoCreateDevice failed with rc = %#x\n", rc));
+ Log(("VBoxGuest::vbgdNt4CreateDevice: Returning rc = 0x%x\n", rc));
return rc;
}
@@ -155,70 +142,57 @@ NTSTATUS vboxguestwinnt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDev
*
* @returns NT status code.
*
- * @param pBusNumber
- * @param pSlotNumber
- *
+ * @param pulBusNumber Where to return the bus number on success.
+ * @param pSlotNumber Where to return the slot number on success.
*/
-static NTSTATUS vboxguestwinnt4FindPCIDevice(PULONG pBusNumber, PPCI_SLOT_NUMBER pSlotNumber)
+static NTSTATUS vbgdNt4FindPciDevice(PULONG pulBusNumber, PPCI_SLOT_NUMBER pSlotNumber)
{
- NTSTATUS rc;
-
- ULONG busNumber;
- ULONG deviceNumber;
- ULONG functionNumber;
- PCI_SLOT_NUMBER slotNumber;
- PCI_COMMON_CONFIG pciData;
-
- Log(("VBoxGuest::vboxguestwinnt4FindPCIDevice\n"));
+ Log(("VBoxGuest::vbgdNt4FindPciDevice\n"));
- rc = STATUS_DEVICE_DOES_NOT_EXIST;
- slotNumber.u.AsULONG = 0;
+ PCI_SLOT_NUMBER SlotNumber;
+ SlotNumber.u.AsULONG = 0;
/* Scan each bus. */
- for (busNumber = 0; busNumber < PCI_MAX_BUSES; busNumber++)
+ for (ULONG ulBusNumber = 0; ulBusNumber < PCI_MAX_BUSES; ulBusNumber++)
{
/* Scan each device. */
- for (deviceNumber = 0; deviceNumber < PCI_MAX_DEVICES; deviceNumber++)
+ for (ULONG deviceNumber = 0; deviceNumber < PCI_MAX_DEVICES; deviceNumber++)
{
- slotNumber.u.bits.DeviceNumber = deviceNumber;
+ SlotNumber.u.bits.DeviceNumber = deviceNumber;
/* Scan each function (not really required...). */
- for (functionNumber = 0; functionNumber < PCI_MAX_FUNCTION; functionNumber++)
+ for (ULONG functionNumber = 0; functionNumber < PCI_MAX_FUNCTION; functionNumber++)
{
- slotNumber.u.bits.FunctionNumber = functionNumber;
+ SlotNumber.u.bits.FunctionNumber = functionNumber;
/* Have a look at what's in this slot. */
- if (!HalGetBusData(PCIConfiguration, busNumber, slotNumber.u.AsULONG,
- &pciData, sizeof(ULONG)))
+ PCI_COMMON_CONFIG PciData;
+ if (!HalGetBusData(PCIConfiguration, ulBusNumber, SlotNumber.u.AsULONG, &PciData, sizeof(ULONG)))
{
/* No such bus, we're done with it. */
deviceNumber = PCI_MAX_DEVICES;
break;
}
- if (pciData.VendorID == PCI_INVALID_VENDORID)
- {
+ if (PciData.VendorID == PCI_INVALID_VENDORID)
/* We have to proceed to the next function. */
continue;
- }
/* Check if it's another device. */
- if ((pciData.VendorID != VMMDEV_VENDORID) ||
- (pciData.DeviceID != VMMDEV_DEVICEID))
- {
+ if ( PciData.VendorID != VMMDEV_VENDORID
+ || PciData.DeviceID != VMMDEV_DEVICEID)
continue;
- }
/* Hooray, we've found it! */
- Log(("VBoxGuest::vboxguestwinnt4FindPCIDevice: Device found!\n"));
+ Log(("VBoxGuest::vbgdNt4FindPciDevice: Device found!\n"));
- *pBusNumber = busNumber;
- *pSlotNumber = slotNumber;
- rc = STATUS_SUCCESS;
+ *pulBusNumber = ulBusNumber;
+ *pSlotNumber = SlotNumber;
+ return STATUS_SUCCESS;
}
}
}
- return rc;
+ return STATUS_DEVICE_DOES_NOT_EXIST;
}
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp
index fb844b78..73ec6ff4 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win-pnp.cpp
@@ -1,8 +1,10 @@
+/* $Id: VBoxGuest-win-pnp.cpp $ */
/** @file
- *
* VBoxGuest-win-pnp - Windows Plug'n'Play specifics.
- *
- * Copyright (C) 2010 Oracle Corporation
+ */
+
+/*
+ * Copyright (C) 2010-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -27,38 +29,29 @@
/*******************************************************************************
* Defined Constants And Macros *
*******************************************************************************/
-extern winVersion_t g_winVersion;
-
RT_C_DECLS_BEGIN
-static NTSTATUS vboxguestwinSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pIrp, BOOLEAN fStrict);
-static NTSTATUS vboxguestwinPnPIrpComplete(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent);
-static VOID vboxguestwinShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceList);
+static NTSTATUS vbgdNtSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pIrp, BOOLEAN fStrict);
+static NTSTATUS vbgdNtPnPIrpComplete(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent);
+static VOID vbgdNtShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceList);
RT_C_DECLS_END
#ifdef ALLOC_PRAGMA
-#pragma alloc_text (PAGE, vboxguestwinPnP)
-#pragma alloc_text (PAGE, vboxguestwinPower)
-#pragma alloc_text (PAGE, vboxguestwinSendIrpSynchronously)
-#pragma alloc_text (PAGE, vboxguestwinShowDeviceResources)
+# pragma alloc_text(PAGE, vbgdNtPnP)
+# pragma alloc_text(PAGE, vbgdNtPower)
+# pragma alloc_text(PAGE, vbgdNtSendIrpSynchronously)
+# pragma alloc_text(PAGE, vbgdNtShowDeviceResources)
#endif
-/* Reenable logging, this was #undef'ed on iprt/log.h for RING0. */
-#define LOG_ENABLED
-
-
-/*******************************************************************************
-* Internal Functions *
-*******************************************************************************/
/**
* Irp completion routine for PnP Irps we send.
*
* @param pDevObj Device object.
* @param pIrp Request packet.
- * @param event Semaphore.
+ * @param pEvent Semaphore.
* @return NT status code
*/
-static NTSTATUS vboxguestwinPnpIrpComplete(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent)
+static NTSTATUS vbgdNtPnpIrpComplete(PDEVICE_OBJECT pDevObj, PIRP pIrp, PKEVENT pEvent)
{
KeSetEvent(pEvent, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
@@ -73,21 +66,21 @@ static NTSTATUS vboxguestwinPnpIrpComplete(PDEVICE_OBJECT pDevObj, PIRP pIrp, PK
* @param fStrict When set, returns an error if the IRP gives an error.
* @return NT status code
*/
-static NTSTATUS vboxguestwinSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pIrp, BOOLEAN fStrict)
+static NTSTATUS vbgdNtSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pIrp, BOOLEAN fStrict)
{
- KEVENT event;
+ KEVENT Event;
- KeInitializeEvent(&event, SynchronizationEvent, FALSE);
+ KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(pIrp);
- IoSetCompletionRoutine(pIrp, (PIO_COMPLETION_ROUTINE)vboxguestwinPnpIrpComplete,
- &event, TRUE, TRUE, TRUE);
+ IoSetCompletionRoutine(pIrp, (PIO_COMPLETION_ROUTINE)vbgdNtPnpIrpComplete,
+ &Event, TRUE, TRUE, TRUE);
NTSTATUS rc = IoCallDriver(pDevObj, pIrp);
if (rc == STATUS_PENDING)
{
- KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
rc = pIrp->IoStatus.Status;
}
@@ -97,7 +90,7 @@ static NTSTATUS vboxguestwinSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pI
rc = STATUS_SUCCESS;
}
- Log(("VBoxGuest::vboxguestwinSendIrpSynchronously: Returning 0x%x\n", rc));
+ Log(("VBoxGuest::vbgdNtSendIrpSynchronously: Returning 0x%x\n", rc));
return rc;
}
@@ -108,13 +101,13 @@ static NTSTATUS vboxguestwinSendIrpSynchronously(PDEVICE_OBJECT pDevObj, PIRP pI
* @param pDevObj Device object.
* @param pIrp Request packet.
*/
-NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+NTSTATUS vbgdNtPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
#ifdef LOG_ENABLED
- static char* aszFnctName[] =
+ static char *s_apszFnctName[] =
{
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
@@ -130,7 +123,7 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
- "",
+ "IRP_MN_0xE",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
@@ -141,10 +134,8 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
};
- Log(("VBoxGuest::vboxguestwinGuestPnp: MinorFunction: %s\n",
- pStack->MinorFunction < (sizeof(aszFnctName) / sizeof(aszFnctName[0]))
- ? aszFnctName[pStack->MinorFunction]
- : "Unknown"));
+ Log(("VBoxGuest::vbgdNtGuestPnp: MinorFunction: %s\n",
+ pStack->MinorFunction < RT_ELEMENTS(s_apszFnctName) ? s_apszFnctName[pStack->MinorFunction] : "Unknown"));
#endif
NTSTATUS rc = STATUS_SUCCESS;
@@ -152,50 +143,50 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
case IRP_MN_START_DEVICE:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: START_DEVICE\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: START_DEVICE\n"));
/* This must be handled first by the lower driver. */
- rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
+ rc = vbgdNtSendIrpSynchronously(pDevExt->pNextLowerDriver, pIrp, TRUE);
if ( NT_SUCCESS(rc)
&& NT_SUCCESS(pIrp->IoStatus.Status))
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: START_DEVICE: pStack->Parameters.StartDevice.AllocatedResources = %p\n",
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: START_DEVICE: pStack->Parameters.StartDevice.AllocatedResources = %p\n",
pStack->Parameters.StartDevice.AllocatedResources));
if (!pStack->Parameters.StartDevice.AllocatedResources)
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: START_DEVICE: No resources, pDevExt = %p, nextLowerDriver = %p!\n",
- pDevExt, pDevExt ? pDevExt->win.s.pNextLowerDriver : NULL));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: START_DEVICE: No resources, pDevExt = %p, nextLowerDriver = %p!\n",
+ pDevExt, pDevExt ? pDevExt->pNextLowerDriver : NULL));
rc = STATUS_UNSUCCESSFUL;
}
else
{
- rc = vboxguestwinInit(pDevObj, pIrp);
+ rc = vbgdNtInit(pDevObj, pIrp);
}
}
if (NT_ERROR(rc))
{
- Log(("VBoxGuest::vboxguestwinGuestPnp: START_DEVICE: Error: rc = 0x%x\n", rc));
+ Log(("VBoxGuest::vbgdNtGuestPnp: START_DEVICE: Error: rc = 0x%x\n", rc));
/* Need to unmap memory in case of errors ... */
- vboxguestwinUnmapVMMDevMemory(pDevExt);
+ vbgdNtUnmapVMMDevMemory(pDevExt);
}
break;
}
case IRP_MN_CANCEL_REMOVE_DEVICE:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_REMOVE_DEVICE\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: CANCEL_REMOVE_DEVICE\n"));
/* This must be handled first by the lower driver. */
- rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
+ rc = vbgdNtSendIrpSynchronously(pDevExt->pNextLowerDriver, pIrp, TRUE);
- if (NT_SUCCESS(rc) && pDevExt->win.s.devState == PENDINGREMOVE)
+ if (NT_SUCCESS(rc) && pDevExt->devState == PENDINGREMOVE)
{
/* Return to the state prior to receiving the IRP_MN_QUERY_REMOVE_DEVICE request. */
- pDevExt->win.s.devState = pDevExt->win.s.prevDevState;
+ pDevExt->devState = pDevExt->prevDevState;
}
/* Complete the IRP. */
@@ -204,7 +195,7 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case IRP_MN_SURPRISE_REMOVAL:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: IRP_MN_SURPRISE_REMOVAL\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: IRP_MN_SURPRISE_REMOVAL\n"));
VBOXGUEST_UPDATE_DEVSTATE(pDevExt, SURPRISEREMOVED);
@@ -218,7 +209,7 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
IoSkipCurrentIrpStackLocation(pIrp);
- rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
+ rc = IoCallDriver(pDevExt->pNextLowerDriver, pIrp);
/* Do not complete the IRP. */
return rc;
@@ -226,12 +217,12 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case IRP_MN_QUERY_REMOVE_DEVICE:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_REMOVE_DEVICE\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: QUERY_REMOVE_DEVICE\n"));
#ifdef VBOX_REBOOT_ON_UNINSTALL
- Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Device cannot be removed without a reboot.\n"));
+ Log(("VBoxGuest::vbgdNtGuestPnp: QUERY_REMOVE_DEVICE: Device cannot be removed without a reboot.\n"));
rc = STATUS_UNSUCCESSFUL;
-#endif /* VBOX_REBOOT_ON_UNINSTALL */
+#endif
if (NT_SUCCESS(rc))
{
@@ -242,8 +233,8 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
IoSkipCurrentIrpStackLocation(pIrp);
- rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
- Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
+ rc = IoCallDriver(pDevExt->pNextLowerDriver, pIrp);
+ Log(("VBoxGuest::vbgdNtGuestPnp: QUERY_REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
/* we must not do anything the IRP after doing IoSkip & CallDriver
* since the driver below us will complete (or already have completed) the IRP.
@@ -257,14 +248,15 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case IRP_MN_REMOVE_DEVICE:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: REMOVE_DEVICE\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: REMOVE_DEVICE\n"));
VBOXGUEST_UPDATE_DEVSTATE(pDevExt, REMOVED);
/* Free hardware resources. */
- /* @todo this should actually free I/O ports, interrupts, etc. */
- rc = vboxguestwinCleanup(pDevObj);
- Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: vboxguestwinCleanup rc = 0x%08X\n", rc));
+ /** @todo this should actually free I/O ports, interrupts, etc.
+ * Update/bird: vbgdNtCleanup actually does that... So, what's there to do? */
+ rc = vbgdNtCleanup(pDevObj);
+ Log(("VBoxGuest::vbgdNtGuestPnp: REMOVE_DEVICE: vbgdNtCleanup rc = 0x%08X\n", rc));
/*
* We need to send the remove down the stack before we detach,
@@ -275,28 +267,28 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
IoSkipCurrentIrpStackLocation(pIrp);
- rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
- Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
+ rc = IoCallDriver(pDevExt->pNextLowerDriver, pIrp);
+ Log(("VBoxGuest::vbgdNtGuestPnp: REMOVE_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
- IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
+ IoDetachDevice(pDevExt->pNextLowerDriver);
- Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Removing device ...\n"));
+ Log(("VBoxGuest::vbgdNtGuestPnp: REMOVE_DEVICE: Removing device ...\n"));
/* Destroy device extension and clean up everything else. */
- VBoxGuestDeleteDevExt(pDevExt);
+ VBoxGuestDeleteDevExt(&pDevExt->Core);
/* Remove DOS device + symbolic link. */
UNICODE_STRING win32Name;
RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
IoDeleteSymbolicLink(&win32Name);
- Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Deleting device ...\n"));
+ Log(("VBoxGuest::vbgdNtGuestPnp: REMOVE_DEVICE: Deleting device ...\n"));
/* Last action: Delete our device! pDevObj is *not* failed
* anymore after this call! */
IoDeleteDevice(pDevObj);
- Log(("VBoxGuest::vboxguestwinGuestPnp: REMOVE_DEVICE: Device removed!\n"));
+ Log(("VBoxGuest::vbgdNtGuestPnp: REMOVE_DEVICE: Device removed!\n"));
/* Propagating rc from IoCallDriver. */
return rc; /* Make sure that we don't do anything below here anymore! */
@@ -304,15 +296,15 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case IRP_MN_CANCEL_STOP_DEVICE:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: CANCEL_STOP_DEVICE\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: CANCEL_STOP_DEVICE\n"));
/* This must be handled first by the lower driver. */
- rc = vboxguestwinSendIrpSynchronously(pDevExt->win.s.pNextLowerDriver, pIrp, TRUE);
+ rc = vbgdNtSendIrpSynchronously(pDevExt->pNextLowerDriver, pIrp, TRUE);
- if (NT_SUCCESS(rc) && pDevExt->win.s.devState == PENDINGSTOP)
+ if (NT_SUCCESS(rc) && pDevExt->devState == PENDINGSTOP)
{
/* Return to the state prior to receiving the IRP_MN_QUERY_STOP_DEVICE request. */
- pDevExt->win.s.devState = pDevExt->win.s.prevDevState;
+ pDevExt->devState = pDevExt->prevDevState;
}
/* Complete the IRP. */
@@ -321,12 +313,12 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case IRP_MN_QUERY_STOP_DEVICE:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: QUERY_STOP_DEVICE\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: QUERY_STOP_DEVICE\n"));
#ifdef VBOX_REBOOT_ON_UNINSTALL
- Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Device cannot be stopped without a reboot!\n"));
+ Log(("VBoxGuest::vbgdNtGuestPnp: QUERY_STOP_DEVICE: Device cannot be stopped without a reboot!\n"));
pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-#endif /* VBOX_REBOOT_ON_UNINSTALL */
+#endif
if (NT_SUCCESS(rc))
{
@@ -337,8 +329,8 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
IoSkipCurrentIrpStackLocation(pIrp);
- rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
- Log(("VBoxGuest::vboxguestwinGuestPnp: QUERY_STOP_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
+ rc = IoCallDriver(pDevExt->pNextLowerDriver, pIrp);
+ Log(("VBoxGuest::vbgdNtGuestPnp: QUERY_STOP_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
/* we must not do anything with the IRP after doing IoSkip & CallDriver
* since the driver below us will complete (or already have completed) the IRP.
@@ -352,22 +344,23 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case IRP_MN_STOP_DEVICE:
{
- Log(("VBoxGuest::vboxguestwinVBoxGuestPnP: STOP_DEVICE\n"));
+ Log(("VBoxGuest::vbgdNtVBoxGuestPnP: STOP_DEVICE\n"));
VBOXGUEST_UPDATE_DEVSTATE(pDevExt, STOPPED);
/* Free hardware resources. */
- /* @todo this should actually free I/O ports, interrupts, etc. */
- rc = vboxguestwinCleanup(pDevObj);
- Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: cleaning up, rc = 0x%x\n", rc));
+ /** @todo this should actually free I/O ports, interrupts, etc.
+ * Update/bird: vbgdNtCleanup actually does that... So, what's there to do? */
+ rc = vbgdNtCleanup(pDevObj);
+ Log(("VBoxGuest::vbgdNtGuestPnp: STOP_DEVICE: cleaning up, rc = 0x%x\n", rc));
/* Pass to the lower driver. */
pIrp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(pIrp);
- rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
- Log(("VBoxGuest::vboxguestwinGuestPnp: STOP_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
+ rc = IoCallDriver(pDevExt->pNextLowerDriver, pIrp);
+ Log(("VBoxGuest::vbgdNtGuestPnp: STOP_DEVICE: Next lower driver replied rc = 0x%x\n", rc));
return rc;
}
@@ -375,7 +368,7 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
default:
{
IoSkipCurrentIrpStackLocation(pIrp);
- rc = IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
+ rc = IoCallDriver(pDevExt->pNextLowerDriver, pIrp);
return rc;
}
}
@@ -383,7 +376,7 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
pIrp->IoStatus.Status = rc;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- Log(("VBoxGuest::vboxguestwinGuestPnp: Returning with rc = 0x%x\n", rc));
+ Log(("VBoxGuest::vbgdNtGuestPnp: Returning with rc = 0x%x\n", rc));
return rc;
}
@@ -396,19 +389,17 @@ NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pIrp IO request packet.
* @param pContext Context value passed to IoSetCompletionRoutine in VBoxGuestPower.
*/
-NTSTATUS vboxguestwinPowerComplete(IN PDEVICE_OBJECT pDevObj,
- IN PIRP pIrp, IN PVOID pContext)
+static NTSTATUS vbgdNtPowerComplete(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pContext)
{
- PIO_STACK_LOCATION pIrpSp;
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pContext;
+#ifdef VBOX_STRICT
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pContext;
+ PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
- ASSERT(pDevExt);
- ASSERT(pDevExt->signature == DEVICE_EXTENSION_SIGNATURE);
+ Assert(pDevExt);
- pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
if (pIrpSp)
{
- ASSERT(pIrpSp->MajorFunction == IRP_MJ_POWER);
+ Assert(pIrpSp->MajorFunction == IRP_MJ_POWER);
if (NT_SUCCESS(pIrp->IoStatus.Status))
{
switch (pIrpSp->MinorFunction)
@@ -429,6 +420,7 @@ NTSTATUS vboxguestwinPowerComplete(IN PDEVICE_OBJECT pDevObj,
}
}
}
+#endif
return STATUS_SUCCESS;
}
@@ -441,56 +433,55 @@ NTSTATUS vboxguestwinPowerComplete(IN PDEVICE_OBJECT pDevObj,
* @param pDevObj device object
* @param pIrp IRP
*/
-NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+NTSTATUS vbgdNtPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
- POWER_STATE_TYPE powerType;
- POWER_STATE powerState;
- POWER_ACTION powerAction;
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
+ POWER_STATE_TYPE enmPowerType = pStack->Parameters.Power.Type;
+ POWER_STATE PowerState = pStack->Parameters.Power.State;
+ POWER_ACTION enmPowerAction = pStack->Parameters.Power.ShutdownType;
- Log(("VBoxGuest::vboxguestwinGuestPower\n"));
-
- powerType = pStack->Parameters.Power.Type;
- powerAction = pStack->Parameters.Power.ShutdownType;
- powerState = pStack->Parameters.Power.State;
+ Log(("VBoxGuest::vbgdNtGuestPower\n"));
switch (pStack->MinorFunction)
{
case IRP_MN_SET_POWER:
{
- Log(("VBoxGuest::vboxguestwinGuestPower: IRP_MN_SET_POWER, type= %d\n", powerType));
- switch (powerType)
+ Log(("VBoxGuest::vbgdNtGuestPower: IRP_MN_SET_POWER, type= %d\n", enmPowerType));
+ switch (enmPowerType)
{
case SystemPowerState:
{
- Log(("VBoxGuest::vboxguestwinGuestPower: SystemPowerState, action = %d, state = %d\n", powerAction, powerState));
+ Log(("VBoxGuest::vbgdNtGuestPower: SystemPowerState, action = %d, state = %d/%d\n",
+ enmPowerAction, PowerState.SystemState, PowerState.DeviceState));
- switch (powerAction)
+ switch (enmPowerAction)
{
case PowerActionSleep:
/* System now is in a working state. */
- if (powerState.SystemState == PowerSystemWorking)
+ if (PowerState.SystemState == PowerSystemWorking)
{
if ( pDevExt
- && pDevExt->win.s.LastSystemPowerAction == PowerActionHibernate)
+ && pDevExt->LastSystemPowerAction == PowerActionHibernate)
{
- Log(("VBoxGuest::vboxguestwinGuestPower: Returning from hibernation!\n"));
- int rc = VBoxGuestReinitDevExtAfterHibernation(pDevExt, vboxguestwinVersionToOSType(g_winVersion));
+ Log(("VBoxGuest::vbgdNtGuestPower: Returning from hibernation!\n"));
+ int rc = VBoxGuestReinitDevExtAfterHibernation(&pDevExt->Core,
+ vbgdNtVersionToOSType(g_enmVbgdNtVer));
if (RT_FAILURE(rc))
- Log(("VBoxGuest::vboxguestwinGuestPower: Cannot re-init VMMDev chain, rc = %d!\n", rc));
+ Log(("VBoxGuest::vbgdNtGuestPower: Cannot re-init VMMDev chain, rc = %d!\n", rc));
}
}
break;
case PowerActionShutdownReset:
{
- Log(("VBoxGuest::vboxguestwinGuestPower: Power action reset!\n"));
+ Log(("VBoxGuest::vbgdNtGuestPower: Power action reset!\n"));
/* Tell the VMM that we no longer support mouse pointer integration. */
VMMDevReqMouseStatus *pReq = NULL;
- int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReqMouseStatus), VMMDevReq_SetMouseStatus);
+ int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReqMouseStatus),
+ VMMDevReq_SetMouseStatus);
if (RT_SUCCESS(vrc))
{
pReq->mouseFeatures = 0;
@@ -500,8 +491,7 @@ NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
vrc = VbglGRPerform(&pReq->header);
if (RT_FAILURE(vrc))
{
- Log(("VBoxGuest::PowerStateRequest: error communicating new power status to VMMDev. "
- "vrc = %Rrc\n", vrc));
+ Log(("VBoxGuest::PowerStateRequest: error communicating new power status to VMMDev. vrc = %Rrc\n", vrc));
}
VbglGRFree(&pReq->header);
@@ -515,12 +505,12 @@ NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case PowerActionShutdown:
case PowerActionShutdownOff:
{
- Log(("VBoxGuest::vboxguestwinGuestPower: Power action shutdown!\n"));
- if (powerState.SystemState >= PowerSystemShutdown)
+ Log(("VBoxGuest::vbgdNtGuestPower: Power action shutdown!\n"));
+ if (PowerState.SystemState >= PowerSystemShutdown)
{
- Log(("VBoxGuest::vboxguestwinGuestPower: Telling the VMMDev to close the VM ...\n"));
+ Log(("VBoxGuest::vbgdNtGuestPower: Telling the VMMDev to close the VM ...\n"));
- VMMDevPowerStateRequest *pReq = pDevExt->win.s.pPowerStateRequest;
+ VMMDevPowerStateRequest *pReq = pDevExt->pPowerStateRequest;
int vrc = VERR_NOT_IMPLEMENTED;
if (pReq)
{
@@ -530,10 +520,7 @@ NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
vrc = VbglGRPerform(&pReq->header);
}
if (RT_FAILURE(vrc))
- {
- Log(("VBoxGuest::PowerStateRequest: Error communicating new power status to VMMDev. "
- "vrc = %Rrc\n", vrc));
- }
+ Log(("VBoxGuest::PowerStateRequest: Error communicating new power status to VMMDev. vrc = %Rrc\n", vrc));
/* No need to do cleanup here; at this point we should've been
* turned off by VMMDev already! */
@@ -543,7 +530,7 @@ NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case PowerActionHibernate:
- Log(("VBoxGuest::vboxguestwinGuestPower: Power action hibernate!\n"));
+ Log(("VBoxGuest::vbgdNtGuestPower: Power action hibernate!\n"));
break;
}
@@ -552,7 +539,7 @@ NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* This becomes handy when we return from hibernation for example.
*/
if (pDevExt)
- pDevExt->win.s.LastSystemPowerAction = powerAction;
+ pDevExt->LastSystemPowerAction = enmPowerAction;
break;
}
@@ -566,21 +553,22 @@ NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp)
}
/*
- * Whether we are completing or relaying this power IRP,
- * we must call PoStartNextPowerIrp.
+ * Whether we are completing or relaying this power IRP,
+ * we must call PoStartNextPowerIrp.
*/
PoStartNextPowerIrp(pIrp);
/*
- * Send the IRP down the driver stack,
- * using PoCallDriver (not IoCallDriver, as for non-power irps).
+ * Send the IRP down the driver stack, using PoCallDriver
+ * (not IoCallDriver, as for non-power irps).
*/
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine(pIrp,
- vboxguestwinPowerComplete,
+ vbgdNtPowerComplete,
(PVOID)pDevExt,
TRUE,
TRUE,
TRUE);
- return PoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
+ return PoCallDriver(pDevExt->pNextLowerDriver, pIrp);
}
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
index 9299ae5b..d4ba77b2 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
@@ -1,8 +1,10 @@
+/* $Id: VBoxGuest-win.cpp $ */
/** @file
- *
* VBoxGuest - Windows specifics.
- *
- * Copyright (C) 2010 Oracle Corporation
+ */
+
+/*
+ * Copyright (C) 2010-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -25,6 +27,7 @@
#include <VBox/log.h>
#include <VBox/VBoxGuestLib.h>
+#include <iprt/string.h>
/*
* XP DDK #defines ExFreePool to ExFreePoolWithTag. The latter does not exist
@@ -35,22 +38,23 @@
# undef ExFreePool
#endif
+
/*******************************************************************************
* Internal Functions *
*******************************************************************************/
RT_C_DECLS_BEGIN
-static NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj);
-static void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj);
-static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-static NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-static NTSTATUS vboxguestwinRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName, PULONG puValue);
-static NTSTATUS vboxguestwinSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-static NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-static NTSTATUS vboxguestwinNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vbgdNtAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj);
+static void vbgdNtUnload(PDRIVER_OBJECT pDrvObj);
+static NTSTATUS vbgdNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vbgdNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vbgdNtIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vbgdNtInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vbgdNtRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName, PULONG puValue);
+static NTSTATUS vbgdNtSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vbgdNtShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+static NTSTATUS vbgdNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp);
#ifdef DEBUG
-static void vboxguestwinDoTests(void);
+static void vbgdNtDoTests(void);
#endif
RT_C_DECLS_END
@@ -63,19 +67,24 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
RT_C_DECLS_END
#ifdef ALLOC_PRAGMA
-#pragma alloc_text (INIT, DriverEntry)
-#pragma alloc_text (PAGE, vboxguestwinAddDevice)
-#pragma alloc_text (PAGE, vboxguestwinUnload)
-#pragma alloc_text (PAGE, vboxguestwinCreate)
-#pragma alloc_text (PAGE, vboxguestwinClose)
-#pragma alloc_text (PAGE, vboxguestwinIOCtl)
-#pragma alloc_text (PAGE, vboxguestwinShutdown)
-#pragma alloc_text (PAGE, vboxguestwinNotSupportedStub)
-#pragma alloc_text (PAGE, vboxguestwinScanPCIResourceList)
+# pragma alloc_text(INIT, DriverEntry)
+# pragma alloc_text(PAGE, vbgdNtAddDevice)
+# pragma alloc_text(PAGE, vbgdNtUnload)
+# pragma alloc_text(PAGE, vbgdNtCreate)
+# pragma alloc_text(PAGE, vbgdNtClose)
+# pragma alloc_text(PAGE, vbgdNtShutdown)
+# pragma alloc_text(PAGE, vbgdNtNotSupportedStub)
+# pragma alloc_text(PAGE, vbgdNtScanPCIResourceList)
#endif
-/** The detected Windows version. */
-winVersion_t g_winVersion;
+
+/*******************************************************************************
+* Global Variables *
+*******************************************************************************/
+/** The detected NT (windows) version. */
+VBGDNTVER g_enmVbgdNtVer = VBGDNTVER_INVALID;
+
+
/**
* Driver entry point.
@@ -90,61 +99,70 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
Log(("VBoxGuest::DriverEntry. Driver built: %s %s\n", __DATE__, __TIME__));
- ULONG majorVersion;
- ULONG minorVersion;
- ULONG buildNumber;
- BOOLEAN bCheckedBuild = PsGetVersion(&majorVersion, &minorVersion, &buildNumber, NULL);
- Log(("VBoxGuest::DriverEntry: Running on Windows NT version %d.%d, build %d\n", majorVersion, minorVersion, buildNumber));
- if (bCheckedBuild)
+ /*
+ * Check if the the NT version is supported and initializing
+ * g_enmVbgdNtVer in the process.
+ */
+ ULONG ulMajorVer;
+ ULONG ulMinorVer;
+ ULONG ulBuildNo;
+ BOOLEAN fCheckedBuild = PsGetVersion(&ulMajorVer, &ulMinorVer, &ulBuildNo, NULL);
+ Log(("VBoxGuest::DriverEntry: Running on Windows NT version %u.%u, build %u\n", ulMajorVer, ulMinorVer, ulBuildNo));
+ if (fCheckedBuild)
Log(("VBoxGuest::DriverEntry: Running on a Windows checked build (debug)!\n"));
#ifdef DEBUG
- vboxguestwinDoTests();
+ vbgdNtDoTests();
#endif
- switch (majorVersion)
+ switch (ulMajorVer)
{
case 6: /* Windows Vista or Windows 7 (based on minor ver) */
- switch (minorVersion)
+ switch (ulMinorVer)
{
case 0: /* Note: Also could be Windows 2008 Server! */
- g_winVersion = WINVISTA;
+ g_enmVbgdNtVer = VBGDNTVER_WINVISTA;
break;
case 1: /* Note: Also could be Windows 2008 Server R2! */
- g_winVersion = WIN7;
+ g_enmVbgdNtVer = VBGDNTVER_WIN7;
break;
case 2:
- g_winVersion = WIN8;
+ g_enmVbgdNtVer = VBGDNTVER_WIN8;
+ break;
+ case 3:
+ g_enmVbgdNtVer = VBGDNTVER_WIN81;
break;
default:
- Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n",
- majorVersion, minorVersion));
+ Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n", ulMajorVer, ulMinorVer));
rc = STATUS_DRIVER_UNABLE_TO_LOAD;
break;
}
break;
case 5:
- switch (minorVersion)
+ switch (ulMinorVer)
{
case 2:
- g_winVersion = WIN2K3;
+ g_enmVbgdNtVer = VBGDNTVER_WIN2K3;
break;
case 1:
- g_winVersion = WINXP;
+ g_enmVbgdNtVer = VBGDNTVER_WINXP;
break;
case 0:
- g_winVersion = WIN2K;
+ g_enmVbgdNtVer = VBGDNTVER_WIN2K;
break;
default:
- Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n",
- majorVersion, minorVersion));
+ Log(("VBoxGuest::DriverEntry: Unknown version of Windows (%u.%u), refusing!\n", ulMajorVer, ulMinorVer));
rc = STATUS_DRIVER_UNABLE_TO_LOAD;
}
break;
case 4:
- g_winVersion = WINNT4;
+ g_enmVbgdNtVer = VBGDNTVER_WINNT4;
break;
default:
- Log(("VBoxGuest::DriverEntry: At least Windows NT4 required!\n"));
+ if (ulMajorVer < 4)
+ Log(("VBoxGuest::DriverEntry: At least Windows NT4 required! (%u.%u)\n", ulMajorVer, ulMinorVer));
+ else
+ Log(("VBoxGuest::DriverEntry: Too new version %u.%u!\n", ulMajorVer, ulMinorVer));
rc = STATUS_DRIVER_UNABLE_TO_LOAD;
+ break;
}
if (NT_SUCCESS(rc))
@@ -152,21 +170,21 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
/*
* Setup the driver entry points in pDrvObj.
*/
- pDrvObj->DriverUnload = vboxguestwinUnload;
- pDrvObj->MajorFunction[IRP_MJ_CREATE] = vboxguestwinCreate;
- pDrvObj->MajorFunction[IRP_MJ_CLOSE] = vboxguestwinClose;
- pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vboxguestwinIOCtl;
- pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vboxguestwinInternalIOCtl;
- pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN] = vboxguestwinShutdown;
- pDrvObj->MajorFunction[IRP_MJ_READ] = vboxguestwinNotSupportedStub;
- pDrvObj->MajorFunction[IRP_MJ_WRITE] = vboxguestwinNotSupportedStub;
+ pDrvObj->DriverUnload = vbgdNtUnload;
+ pDrvObj->MajorFunction[IRP_MJ_CREATE] = vbgdNtCreate;
+ pDrvObj->MajorFunction[IRP_MJ_CLOSE] = vbgdNtClose;
+ pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = vbgdNtIOCtl;
+ pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vbgdNtInternalIOCtl;
+ pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN] = vbgdNtShutdown;
+ pDrvObj->MajorFunction[IRP_MJ_READ] = vbgdNtNotSupportedStub;
+ pDrvObj->MajorFunction[IRP_MJ_WRITE] = vbgdNtNotSupportedStub;
#ifdef TARGET_NT4
- rc = vboxguestwinnt4CreateDevice(pDrvObj, NULL /* pDevObj */, pRegPath);
+ rc = vbgdNt4CreateDevice(pDrvObj, NULL /* pDevObj */, pRegPath);
#else
- pDrvObj->MajorFunction[IRP_MJ_PNP] = vboxguestwinPnP;
- pDrvObj->MajorFunction[IRP_MJ_POWER] = vboxguestwinPower;
- pDrvObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vboxguestwinSystemControl;
- pDrvObj->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)vboxguestwinAddDevice;
+ pDrvObj->MajorFunction[IRP_MJ_PNP] = vbgdNtPnP;
+ pDrvObj->MajorFunction[IRP_MJ_POWER] = vbgdNtPower;
+ pDrvObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = vbgdNtSystemControl;
+ pDrvObj->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE)vbgdNtAddDevice;
#endif
}
@@ -183,84 +201,79 @@ ULONG DriverEntry(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath)
* @param pDrvObj Driver object
* @param pDevObj Device object
*/
-static NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
+static NTSTATUS vbgdNtAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj)
{
NTSTATUS rc;
- Log(("VBoxGuest::vboxguestwinGuestAddDevice\n"));
+ Log(("VBoxGuest::vbgdNtGuestAddDevice\n"));
/*
* Create device.
*/
+ UNICODE_STRING DevName;
+ RtlInitUnicodeString(&DevName, VBOXGUEST_DEVICE_NAME_NT);
PDEVICE_OBJECT pDeviceObject = NULL;
- PVBOXGUESTDEVEXT pDevExt = NULL;
- UNICODE_STRING devName;
- UNICODE_STRING win32Name;
- RtlInitUnicodeString(&devName, VBOXGUEST_DEVICE_NAME_NT);
- rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXT), &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
+ rc = IoCreateDevice(pDrvObj, sizeof(VBOXGUESTDEVEXTWIN), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject);
if (NT_SUCCESS(rc))
{
/*
* Create symbolic link (DOS devices).
*/
- RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
- rc = IoCreateSymbolicLink(&win32Name, &devName);
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, VBOXGUEST_DEVICE_NAME_DOS);
+ rc = IoCreateSymbolicLink(&DosName, &DevName);
if (NT_SUCCESS(rc))
{
/*
* Setup the device extension.
*/
- pDevExt = (PVBOXGUESTDEVEXT)pDeviceObject->DeviceExtension;
- RtlZeroMemory(pDevExt, sizeof(VBOXGUESTDEVEXT));
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDeviceObject->DeviceExtension;
+ RT_ZERO(*pDevExt);
- KeInitializeSpinLock(&pDevExt->win.s.MouseEventAccessLock);
+ KeInitializeSpinLock(&pDevExt->MouseEventAccessLock);
- pDevExt->win.s.pDeviceObject = pDeviceObject;
- pDevExt->win.s.prevDevState = STOPPED;
- pDevExt->win.s.devState = STOPPED;
+ pDevExt->pDeviceObject = pDeviceObject;
+ pDevExt->prevDevState = STOPPED;
+ pDevExt->devState = STOPPED;
- pDevExt->win.s.pNextLowerDriver = IoAttachDeviceToDeviceStack(pDeviceObject, pDevObj);
- if (pDevExt->win.s.pNextLowerDriver == NULL)
+ pDevExt->pNextLowerDriver = IoAttachDeviceToDeviceStack(pDeviceObject, pDevObj);
+ if (pDevExt->pNextLowerDriver != NULL)
{
- Log(("VBoxGuest::vboxguestwinGuestAddDevice: IoAttachDeviceToDeviceStack did not give a nextLowerDriver!\n"));
- rc = STATUS_DEVICE_NOT_CONNECTED;
- }
- }
- else
- Log(("VBoxGuest::vboxguestwinGuestAddDevice: IoCreateSymbolicLink failed with rc=%#x!\n", rc));
- }
- else
- Log(("VBoxGuest::vboxguestwinGuestAddDevice: IoCreateDevice failed with rc=%#x!\n", rc));
-
- if (NT_SUCCESS(rc))
- {
- /*
- * If we reached this point we're fine with the basic driver setup,
- * so continue to init our own things.
- */
+ /*
+ * If we reached this point we're fine with the basic driver setup,
+ * so continue to init our own things.
+ */
#ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
- vboxguestwinBugCheckCallback(pDevExt); /* Ignore failure! */
+ vbgdNtBugCheckCallback(pDevExt); /* Ignore failure! */
#endif
- /* VBoxGuestPower is pageable; ensure we are not called at elevated IRQL */
- pDeviceObject->Flags |= DO_POWER_PAGABLE;
+ if (NT_SUCCESS(rc))
+ {
+ /* VBoxGuestPower is pageable; ensure we are not called at elevated IRQL */
+ pDeviceObject->Flags |= DO_POWER_PAGABLE;
- /* Driver is ready now. */
- pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
- }
+ /* Driver is ready now. */
+ pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+ Log(("VBoxGuest::vbgdNtGuestAddDevice: returning with rc = 0x%x (success)\n", rc));
+ return rc;
+ }
- /* Cleanup on error. */
- if (NT_ERROR(rc))
- {
- if (pDevExt)
- {
- if (pDevExt->win.s.pNextLowerDriver)
- IoDetachDevice(pDevExt->win.s.pNextLowerDriver);
+ IoDetachDevice(pDevExt->pNextLowerDriver);
+ }
+ else
+ {
+ Log(("VBoxGuest::vbgdNtGuestAddDevice: IoAttachDeviceToDeviceStack did not give a nextLowerDriver!\n"));
+ rc = STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ /* bail out */
+ IoDeleteSymbolicLink(&DosName);
}
- IoDeleteSymbolicLink(&win32Name);
- if (pDeviceObject)
- IoDeleteDevice(pDeviceObject);
+ else
+ Log(("VBoxGuest::vbgdNtGuestAddDevice: IoCreateSymbolicLink failed with rc=%#x!\n", rc));
+ IoDeleteDevice(pDeviceObject);
}
-
- Log(("VBoxGuest::vboxguestwinGuestAddDevice: returning with rc = 0x%x\n", rc));
+ else
+ Log(("VBoxGuest::vbgdNtGuestAddDevice: IoCreateDevice failed with rc=%#x!\n", rc));
+ Log(("VBoxGuest::vbgdNtGuestAddDevice: returning with rc = 0x%x\n", rc));
return rc;
}
#endif
@@ -271,17 +284,16 @@ static NTSTATUS vboxguestwinAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDe
*
* @param pResourceList list of device resources.
*/
-static void vboxguestwinShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceList)
+static void vbgdNtShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceList)
{
#ifdef LOG_ENABLED
- PCM_PARTIAL_RESOURCE_DESCRIPTOR resource = pResourceList->PartialDescriptors;
- ULONG nres = pResourceList->Count;
- ULONG i;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR pResource = pResourceList->PartialDescriptors;
+ ULONG cResources = pResourceList->Count;
- for (i = 0; i < nres; ++i, ++resource)
+ for (ULONG i = 0; i < cResources; ++i, ++pResource)
{
- ULONG uType = resource->Type;
- static char* aszName[] =
+ ULONG uType = pResource->Type;
+ static char const * const s_apszName[] =
{
"CmResourceTypeNull",
"CmResourceTypePort",
@@ -295,28 +307,27 @@ static void vboxguestwinShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceL
"CmResourceTypeSubAllocateFrom",
};
- Log(("VBoxGuest::vboxguestwinShowDeviceResources: Type %s",
- uType < (sizeof(aszName) / sizeof(aszName[0]))
- ? aszName[uType] : "Unknown"));
+ Log(("VBoxGuest::vbgdNtShowDeviceResources: Type %s",
+ uType < RT_ELEMENTS(s_apszName) ? s_apszName[uType] : "Unknown"));
switch (uType)
{
case CmResourceTypePort:
case CmResourceTypeMemory:
- Log(("VBoxGuest::vboxguestwinShowDeviceResources: Start %8X%8.8lX length %X\n",
- resource->u.Port.Start.HighPart, resource->u.Port.Start.LowPart,
- resource->u.Port.Length));
+ Log(("VBoxGuest::vbgdNtShowDeviceResources: Start %8X%8.8lX length %X\n",
+ pResource->u.Port.Start.HighPart, pResource->u.Port.Start.LowPart,
+ pResource->u.Port.Length));
break;
case CmResourceTypeInterrupt:
- Log(("VBoxGuest::vboxguestwinShowDeviceResources: Level %X, Vector %X, Affinity %X\n",
- resource->u.Interrupt.Level, resource->u.Interrupt.Vector,
- resource->u.Interrupt.Affinity));
+ Log(("VBoxGuest::vbgdNtShowDeviceResources: Level %X, Vector %X, Affinity %X\n",
+ pResource->u.Interrupt.Level, pResource->u.Interrupt.Vector,
+ pResource->u.Interrupt.Affinity));
break;
case CmResourceTypeDma:
- Log(("VBoxGuest::vboxguestwinShowDeviceResources: Channel %d, Port %X\n",
- resource->u.Dma.Channel, resource->u.Dma.Port));
+ Log(("VBoxGuest::vbgdNtShowDeviceResources: Channel %d, Port %X\n",
+ pResource->u.Dma.Channel, pResource->u.Dma.Port));
break;
default:
@@ -335,24 +346,24 @@ static void vboxguestwinShowDeviceResources(PCM_PARTIAL_RESOURCE_LIST pResourceL
* @param pIrp Request packet.
*/
#ifndef TARGET_NT4
-NTSTATUS vboxguestwinInit(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+NTSTATUS vbgdNtInit(PDEVICE_OBJECT pDevObj, PIRP pIrp)
#else
-NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath)
+NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath)
#endif
{
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
#ifndef TARGET_NT4
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
#endif
- Log(("VBoxGuest::vboxguestwinInit\n"));
+ Log(("VBoxGuest::vbgdNtInit\n"));
int rc = STATUS_SUCCESS;
#ifdef TARGET_NT4
/*
* Let's have a look at what our PCI adapter offers.
*/
- Log(("VBoxGuest::vboxguestwinInit: Starting to scan PCI resources of VBoxGuest ...\n"));
+ Log(("VBoxGuest::vbgdNtInit: Starting to scan PCI resources of VBoxGuest ...\n"));
/* Assign the PCI resources. */
PCM_RESOURCE_LIST pResourceList = NULL;
@@ -360,18 +371,17 @@ NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICO
RtlInitUnicodeString(&classNameString, L"VBoxGuestAdapter");
rc = HalAssignSlotResources(pRegPath, &classNameString,
pDrvObj, pDevObj,
- PCIBus, pDevExt->win.s.busNumber, pDevExt->win.s.slotNumber,
+ PCIBus, pDevExt->busNumber, pDevExt->slotNumber,
&pResourceList);
if (pResourceList && pResourceList->Count > 0)
- vboxguestwinShowDeviceResources(&pResourceList->List[0].PartialResourceList);
+ vbgdNtShowDeviceResources(&pResourceList->List[0].PartialResourceList);
if (NT_SUCCESS(rc))
- rc = vboxguestwinScanPCIResourceList(pResourceList, pDevExt);
+ rc = vbgdNtScanPCIResourceList(pResourceList, pDevExt);
#else
if (pStack->Parameters.StartDevice.AllocatedResources->Count > 0)
- vboxguestwinShowDeviceResources(&pStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList);
+ vbgdNtShowDeviceResources(&pStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList);
if (NT_SUCCESS(rc))
- rc = vboxguestwinScanPCIResourceList(pStack->Parameters.StartDevice.AllocatedResourcesTranslated,
- pDevExt);
+ rc = vbgdNtScanPCIResourceList(pStack->Parameters.StartDevice.AllocatedResourcesTranslated, pDevExt);
#endif
if (NT_SUCCESS(rc))
{
@@ -381,40 +391,40 @@ NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICO
*/
void *pvMMIOBase = NULL;
uint32_t cbMMIO = 0;
- rc = vboxguestwinMapVMMDevMemory(pDevExt,
- pDevExt->win.s.vmmDevPhysMemoryAddress,
- pDevExt->win.s.vmmDevPhysMemoryLength,
- &pvMMIOBase,
- &cbMMIO);
+ rc = vbgdNtMapVMMDevMemory(pDevExt,
+ pDevExt->vmmDevPhysMemoryAddress,
+ pDevExt->vmmDevPhysMemoryLength,
+ &pvMMIOBase,
+ &cbMMIO);
if (NT_SUCCESS(rc))
{
- pDevExt->pVMMDevMemory = (VMMDevMemory *)pvMMIOBase;
+ pDevExt->Core.pVMMDevMemory = (VMMDevMemory *)pvMMIOBase;
- Log(("VBoxGuest::vboxguestwinInit: pvMMIOBase = 0x%p, pDevExt = 0x%p, pDevExt->pVMMDevMemory = 0x%p\n",
- pvMMIOBase, pDevExt, pDevExt ? pDevExt->pVMMDevMemory : NULL));
+ Log(("VBoxGuest::vbgdNtInit: pvMMIOBase = 0x%p, pDevExt = 0x%p, pDevExt->Core.pVMMDevMemory = 0x%p\n",
+ pvMMIOBase, pDevExt, pDevExt ? pDevExt->Core.pVMMDevMemory : NULL));
- int vrc = VBoxGuestInitDevExt(pDevExt,
- pDevExt->IOPortBase,
+ int vrc = VBoxGuestInitDevExt(&pDevExt->Core,
+ pDevExt->Core.IOPortBase,
pvMMIOBase, cbMMIO,
- vboxguestwinVersionToOSType(g_winVersion),
+ vbgdNtVersionToOSType(g_enmVbgdNtVer),
VMMDEV_EVENT_MOUSE_POSITION_CHANGED);
if (RT_FAILURE(vrc))
{
- Log(("VBoxGuest::vboxguestwinInit: Could not init device extension, rc = %Rrc!\n", vrc));
+ Log(("VBoxGuest::vbgdNtInit: Could not init device extension, rc = %Rrc!\n", vrc));
rc = STATUS_DEVICE_CONFIGURATION_ERROR;
}
}
else
- Log(("VBoxGuest::vboxguestwinInit: Could not map physical address of VMMDev, rc = 0x%x!\n", rc));
+ Log(("VBoxGuest::vbgdNtInit: Could not map physical address of VMMDev, rc = 0x%x!\n", rc));
}
if (NT_SUCCESS(rc))
{
- int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pDevExt->win.s.pPowerStateRequest,
- sizeof (VMMDevPowerStateRequest), VMMDevReq_SetPowerStatus);
+ int vrc = VbglGRAlloc((VMMDevRequestHeader **)&pDevExt->pPowerStateRequest,
+ sizeof(VMMDevPowerStateRequest), VMMDevReq_SetPowerStatus);
if (RT_FAILURE(vrc))
{
- Log(("VBoxGuest::vboxguestwinInit: Alloc for pPowerStateRequest failed, rc = %Rrc\n", vrc));
+ Log(("VBoxGuest::vbgdNtInit: Alloc for pPowerStateRequest failed, rc = %Rrc\n", vrc));
rc = STATUS_UNSUCCESSFUL;
}
}
@@ -424,68 +434,68 @@ NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICO
/*
* Register DPC and ISR.
*/
- Log(("VBoxGuest::vboxguestwinInit: Initializing DPC/ISR ...\n"));
+ Log(("VBoxGuest::vbgdNtInit: Initializing DPC/ISR ...\n"));
- IoInitializeDpcRequest(pDevExt->win.s.pDeviceObject, vboxguestwinDpcHandler);
+ IoInitializeDpcRequest(pDevExt->pDeviceObject, vbgdNtDpcHandler);
#ifdef TARGET_NT4
ULONG uInterruptVector;
KIRQL irqLevel;
/* Get an interrupt vector. */
/* Only proceed if the device provides an interrupt. */
- if ( pDevExt->win.s.interruptLevel
- || pDevExt->win.s.interruptVector)
+ if ( pDevExt->interruptLevel
+ || pDevExt->interruptVector)
{
- Log(("VBoxGuest::vboxguestwinInit: Getting interrupt vector (HAL): Bus: %u, IRQL: %u, Vector: %u\n",
- pDevExt->win.s.busNumber, pDevExt->win.s.interruptLevel, pDevExt->win.s.interruptVector));
+ Log(("VBoxGuest::vbgdNtInit: Getting interrupt vector (HAL): Bus: %u, IRQL: %u, Vector: %u\n",
+ pDevExt->busNumber, pDevExt->interruptLevel, pDevExt->interruptVector));
uInterruptVector = HalGetInterruptVector(PCIBus,
- pDevExt->win.s.busNumber,
- pDevExt->win.s.interruptLevel,
- pDevExt->win.s.interruptVector,
+ pDevExt->busNumber,
+ pDevExt->interruptLevel,
+ pDevExt->interruptVector,
&irqLevel,
- &pDevExt->win.s.interruptAffinity);
- Log(("VBoxGuest::vboxguestwinInit: HalGetInterruptVector returns vector %u\n", uInterruptVector));
+ &pDevExt->interruptAffinity);
+ Log(("VBoxGuest::vbgdNtInit: HalGetInterruptVector returns vector %u\n", uInterruptVector));
if (uInterruptVector == 0)
- Log(("VBoxGuest::vboxguestwinInit: No interrupt vector found!\n"));
+ Log(("VBoxGuest::vbgdNtInit: No interrupt vector found!\n"));
}
else
- Log(("VBoxGuest::vboxguestwinInit: Device does not provide an interrupt!\n"));
+ Log(("VBoxGuest::vbgdNtInit: Device does not provide an interrupt!\n"));
#endif
- if (pDevExt->win.s.interruptVector)
+ if (pDevExt->interruptVector)
{
- Log(("VBoxGuest::vboxguestwinInit: Connecting interrupt ...\n"));
+ Log(("VBoxGuest::vbgdNtInit: Connecting interrupt ...\n"));
- rc = IoConnectInterrupt(&pDevExt->win.s.pInterruptObject, /* Out: interrupt object. */
- (PKSERVICE_ROUTINE)vboxguestwinIsrHandler, /* Our ISR handler. */
- pDevExt, /* Device context. */
- NULL, /* Optional spinlock. */
+ rc = IoConnectInterrupt(&pDevExt->pInterruptObject, /* Out: interrupt object. */
+ (PKSERVICE_ROUTINE)vbgdNtIsrHandler, /* Our ISR handler. */
+ pDevExt, /* Device context. */
+ NULL, /* Optional spinlock. */
#ifdef TARGET_NT4
- uInterruptVector, /* Interrupt vector. */
- irqLevel, /* Interrupt level. */
- irqLevel, /* Interrupt level. */
+ uInterruptVector, /* Interrupt vector. */
+ irqLevel, /* Interrupt level. */
+ irqLevel, /* Interrupt level. */
#else
- pDevExt->win.s.interruptVector, /* Interrupt vector. */
- (KIRQL)pDevExt->win.s.interruptLevel, /* Interrupt level. */
- (KIRQL)pDevExt->win.s.interruptLevel, /* Interrupt level. */
+ pDevExt->interruptVector, /* Interrupt vector. */
+ (KIRQL)pDevExt->interruptLevel, /* Interrupt level. */
+ (KIRQL)pDevExt->interruptLevel, /* Interrupt level. */
#endif
- pDevExt->win.s.interruptMode, /* LevelSensitive or Latched. */
- TRUE, /* Shareable interrupt. */
- pDevExt->win.s.interruptAffinity, /* CPU affinity. */
- FALSE); /* Don't save FPU stack. */
+ pDevExt->interruptMode, /* LevelSensitive or Latched. */
+ TRUE, /* Shareable interrupt. */
+ pDevExt->interruptAffinity, /* CPU affinity. */
+ FALSE); /* Don't save FPU stack. */
if (NT_ERROR(rc))
- Log(("VBoxGuest::vboxguestwinInit: Could not connect interrupt, rc = 0x%x\n", rc));
+ Log(("VBoxGuest::vbgdNtInit: Could not connect interrupt, rc = 0x%x\n", rc));
}
else
- Log(("VBoxGuest::vboxguestwinInit: No interrupt vector found!\n"));
+ Log(("VBoxGuest::vbgdNtInit: No interrupt vector found!\n"));
}
#ifdef VBOX_WITH_HGCM
- Log(("VBoxGuest::vboxguestwinInit: Allocating kernel session data ...\n"));
- int vrc = VBoxGuestCreateKernelSession(pDevExt, &pDevExt->win.s.pKernelSession);
+ Log(("VBoxGuest::vbgdNtInit: Allocating kernel session data ...\n"));
+ int vrc = VBoxGuestCreateKernelSession(&pDevExt->Core, &pDevExt->pKernelSession);
if (RT_FAILURE(vrc))
{
- Log(("VBoxGuest::vboxguestwinInit: Failed to allocated kernel session data! rc = %Rrc\n", rc));
+ Log(("VBoxGuest::vbgdNtInit: Failed to allocated kernel session data! rc = %Rrc\n", rc));
rc = STATUS_UNSUCCESSFUL;
}
#endif
@@ -493,25 +503,25 @@ NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICO
if (RT_SUCCESS(rc))
{
ULONG ulValue = 0;
- NTSTATUS s = vboxguestwinRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled",
- &ulValue);
- if (NT_SUCCESS(s))
+ NTSTATUS rcNt = vbgdNtRegistryReadDWORD(RTL_REGISTRY_SERVICES, L"VBoxGuest", L"LoggingEnabled", &ulValue);
+ if (NT_SUCCESS(rcNt))
{
- pDevExt->fLoggingEnabled = ulValue >= 0xFF;
- if (pDevExt->fLoggingEnabled)
+ pDevExt->Core.fLoggingEnabled = ulValue >= 0xFF;
+ if (pDevExt->Core.fLoggingEnabled)
Log(("Logging to release log enabled (0x%x)", ulValue));
}
/* Ready to rumble! */
- Log(("VBoxGuest::vboxguestwinInit: Device is ready!\n"));
+ Log(("VBoxGuest::vbgdNtInit: Device is ready!\n"));
VBOXGUEST_UPDATE_DEVSTATE(pDevExt, WORKING);
}
else
- {
- pDevExt->win.s.pInterruptObject = NULL;
- }
+ pDevExt->pInterruptObject = NULL;
- Log(("VBoxGuest::vboxguestwinInit: Returned with rc = 0x%x\n", rc));
+ /** @todo r=bird: The error cleanup here is completely missing. We'll leak a
+ * whole bunch of things... */
+
+ Log(("VBoxGuest::vbgdNtInit: Returned with rc = 0x%x\n", rc));
return rc;
}
@@ -522,38 +532,38 @@ NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICO
*
* @param pDrvObj Driver object.
*/
-NTSTATUS vboxguestwinCleanup(PDEVICE_OBJECT pDevObj)
+NTSTATUS vbgdNtCleanup(PDEVICE_OBJECT pDevObj)
{
- Log(("VBoxGuest::vboxguestwinCleanup\n"));
+ Log(("VBoxGuest::vbgdNtCleanup\n"));
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
if (pDevExt)
{
#if 0 /* @todo: test & enable cleaning global session data */
#ifdef VBOX_WITH_HGCM
- if (pDevExt->win.s.pKernelSession)
+ if (pDevExt->pKernelSession)
{
- VBoxGuestCloseSession(pDevExt, pDevExt->win.s.pKernelSession);
- pDevExt->win.s.pKernelSession = NULL;
+ VBoxGuestCloseSession(pDevExt, pDevExt->pKernelSession);
+ pDevExt->pKernelSession = NULL;
}
#endif
#endif
- if (pDevExt->win.s.pInterruptObject)
+ if (pDevExt->pInterruptObject)
{
- IoDisconnectInterrupt(pDevExt->win.s.pInterruptObject);
- pDevExt->win.s.pInterruptObject = NULL;
+ IoDisconnectInterrupt(pDevExt->pInterruptObject);
+ pDevExt->pInterruptObject = NULL;
}
- /* @todo: cleanup the rest stuff */
+ /** @todo: cleanup the rest stuff */
#ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
hlpDeregisterBugCheckCallback(pDevExt); /* ignore failure! */
#endif
/* According to MSDN we have to unmap previously mapped memory. */
- vboxguestwinUnmapVMMDevMemory(pDevExt);
+ vbgdNtUnmapVMMDevMemory(pDevExt);
}
return STATUS_SUCCESS;
}
@@ -564,11 +574,11 @@ NTSTATUS vboxguestwinCleanup(PDEVICE_OBJECT pDevObj)
*
* @param pDrvObj Driver object.
*/
-static void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj)
+static void vbgdNtUnload(PDRIVER_OBJECT pDrvObj)
{
- Log(("VBoxGuest::vboxguestwinGuestUnload\n"));
+ Log(("VBoxGuest::vbgdNtGuestUnload\n"));
#ifdef TARGET_NT4
- vboxguestwinCleanup(pDrvObj->DeviceObject);
+ vbgdNtCleanup(pDrvObj->DeviceObject);
/* Destroy device extension and clean up everything else. */
if (pDrvObj->DeviceObject && pDrvObj->DeviceObject->DeviceExtension)
@@ -578,18 +588,18 @@ static void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj)
* I don't think it's possible to unload a driver which processes have
* opened, at least we'll blindly assume that here.
*/
- UNICODE_STRING win32Name;
- RtlInitUnicodeString(&win32Name, VBOXGUEST_DEVICE_NAME_DOS);
- NTSTATUS rc = IoDeleteSymbolicLink(&win32Name);
+ UNICODE_STRING DosName;
+ RtlInitUnicodeString(&DosName, VBOXGUEST_DEVICE_NAME_DOS);
+ NTSTATUS rc = IoDeleteSymbolicLink(&DosName);
IoDeleteDevice(pDrvObj->DeviceObject);
-#else /* TARGET_NT4 */
+#else /* !TARGET_NT4 */
/* On a PnP driver this routine will be called after
* IRP_MN_REMOVE_DEVICE (where we already did the cleanup),
* so don't do anything here (yet). */
-#endif
+#endif /* !TARGET_NT4 */
- Log(("VBoxGuest::vboxguestwinGuestUnload: returning\n"));
+ Log(("VBoxGuest::vbgdNtGuestUnload: returning\n"));
}
@@ -599,19 +609,18 @@ static void vboxguestwinUnload(PDRIVER_OBJECT pDrvObj)
* @param pDevObj Device object.
* @param pIrp Request packet.
*/
-static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+static NTSTATUS vbgdNtCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
/** @todo AssertPtrReturn(pIrp); */
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
/** @todo AssertPtrReturn(pStack); */
- PFILE_OBJECT pFileObj = pStack->FileObject;
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
- NTSTATUS rc = STATUS_SUCCESS;
+ PFILE_OBJECT pFileObj = pStack->FileObject;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
+ NTSTATUS rc = STATUS_SUCCESS;
- if (pDevExt->win.s.devState != WORKING)
+ if (pDevExt->devState != WORKING)
{
- Log(("VBoxGuest::vboxguestwinGuestCreate: device is not working currently: %d!\n",
- pDevExt->win.s.devState));
+ Log(("VBoxGuest::vbgdNtGuestCreate: device is not working currently: %d!\n", pDevExt->devState));
rc = STATUS_UNSUCCESSFUL;
}
else if (pStack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
@@ -620,7 +629,7 @@ static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* We are not remotely similar to a directory...
* (But this is possible.)
*/
- Log(("VBoxGuest::vboxguestwinGuestCreate: Uhm, we're not a directory!\n"));
+ Log(("VBoxGuest::vbgdNtGuestCreate: Uhm, we're not a directory!\n"));
rc = STATUS_NOT_A_DIRECTORY;
}
else
@@ -628,7 +637,7 @@ static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
#ifdef VBOX_WITH_HGCM
if (pFileObj)
{
- Log(("VBoxGuest::vboxguestwinGuestCreate: File object type = %d\n",
+ Log(("VBoxGuest::vbgdNtGuestCreate: File object type = %d\n",
pFileObj->Type));
int vrc;
@@ -639,12 +648,12 @@ static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* Create a session object if we have a valid file object. This session object
* exists for every R3 process.
*/
- vrc = VBoxGuestCreateUserSession(pDevExt, &pSession);
+ vrc = VBoxGuestCreateUserSession(&pDevExt->Core, &pSession);
}
else
{
/* ... otherwise we've been called from R0! */
- vrc = VBoxGuestCreateKernelSession(pDevExt, &pSession);
+ vrc = VBoxGuestCreateKernelSession(&pDevExt->Core, &pSession);
}
if (RT_SUCCESS(vrc))
pFileObj->FsContext = pSession;
@@ -657,7 +666,7 @@ static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
pIrp->IoStatus.Status = rc;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- Log(("VBoxGuest::vboxguestwinGuestCreate: Returning 0x%x\n", rc));
+ Log(("VBoxGuest::vbgdNtGuestCreate: Returning 0x%x\n", rc));
return rc;
}
@@ -668,20 +677,20 @@ static NTSTATUS vboxguestwinCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pDevObj Device object.
* @param pIrp Request packet.
*/
-static NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+static NTSTATUS vbgdNtClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
- PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
- PFILE_OBJECT pFileObj = pStack->FileObject;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
+ PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
+ PFILE_OBJECT pFileObj = pStack->FileObject;
- Log(("VBoxGuest::vboxguestwinGuestClose: pDevExt=0x%p pFileObj=0x%p FsContext=0x%p\n",
+ Log(("VBoxGuest::vbgdNtGuestClose: pDevExt=0x%p pFileObj=0x%p FsContext=0x%p\n",
pDevExt, pFileObj, pFileObj->FsContext));
#ifdef VBOX_WITH_HGCM
/* Close both, R0 and R3 sessions. */
PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pFileObj->FsContext;
if (pSession)
- VBoxGuestCloseSession(pDevExt, pSession);
+ VBoxGuestCloseSession(&pDevExt->Core, pSession);
#endif
pFileObj->FsContext = NULL;
@@ -699,16 +708,16 @@ static NTSTATUS vboxguestwinClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pDevObj Device object.
* @param pIrp Request packet.
*/
-static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+static NTSTATUS vbgdNtIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS Status = STATUS_SUCCESS;
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
unsigned int uCmd = (unsigned int)pStack->Parameters.DeviceIoControl.IoControlCode;
char *pBuf = (char *)pIrp->AssociatedIrp.SystemBuffer; /* All requests are buffered. */
size_t cbData = pStack->Parameters.DeviceIoControl.InputBufferLength;
- unsigned cbOut = 0;
+ size_t cbOut = 0;
/* Do we have a file object associated?*/
PFILE_OBJECT pFileObj = pStack->FileObject;
@@ -716,7 +725,7 @@ static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
if (pFileObj) /* ... then we might have a session object as well! */
pSession = (PVBOXGUESTSESSION)pFileObj->FsContext;
- Log(("VBoxGuest::vboxguestwinIOCtl: uCmd=%u, pDevExt=0x%p, pSession=0x%p\n",
+ Log(("VBoxGuest::vbgdNtIOCtl: uCmd=%u, pDevExt=0x%p, pSession=0x%p\n",
uCmd, pDevExt, pSession));
/* We don't have a session associated with the file object? So this seems
@@ -725,8 +734,8 @@ static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* shall have its own context of course, no hacks, pleeease. */
if (pSession == NULL)
{
- Log(("VBoxGuest::vboxguestwinIOCtl: Using kernel session data ...\n"));
- pSession = pDevExt->win.s.pKernelSession;
+ Log(("VBoxGuest::vbgdNtIOCtl: Using kernel session data ...\n"));
+ pSession = pDevExt->pKernelSession;
}
/*
@@ -739,14 +748,14 @@ static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
#ifdef VBOX_WITH_VRDP_SESSION_HANDLING
case VBOXGUEST_IOCTL_ENABLE_VRDP_SESSION:
{
- LogRel(("VBoxGuest::vboxguestwinIOCtl: ENABLE_VRDP_SESSION: Currently: %sabled\n",
+ LogRel(("VBoxGuest::vbgdNtIOCtl: ENABLE_VRDP_SESSION: Currently: %sabled\n",
pDevExt->fVRDPEnabled? "en": "dis"));
if (!pDevExt->fVRDPEnabled)
{
KUSER_SHARED_DATA *pSharedUserData = (KUSER_SHARED_DATA *)KI_USER_SHARED_DATA;
pDevExt->fVRDPEnabled = true;
- LogRel(("VBoxGuest::vboxguestwinIOCtl: ENABLE_VRDP_SESSION: Current active console ID: 0x%08X\n",
+ LogRel(("VBoxGuest::vbgdNtIOCtl: ENABLE_VRDP_SESSION: Current active console ID: 0x%08X\n",
pSharedUserData->ActiveConsoleId));
pDevExt->ulOldActiveConsoleId = pSharedUserData->ActiveConsoleId;
pSharedUserData->ActiveConsoleId = 2;
@@ -756,14 +765,14 @@ static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
case VBOXGUEST_IOCTL_DISABLE_VRDP_SESSION:
{
- LogRel(("VBoxGuest::vboxguestwinIOCtl: DISABLE_VRDP_SESSION: Currently: %sabled\n",
+ LogRel(("VBoxGuest::vbgdNtIOCtl: DISABLE_VRDP_SESSION: Currently: %sabled\n",
pDevExt->fVRDPEnabled? "en": "dis"));
if (pDevExt->fVRDPEnabled)
{
KUSER_SHARED_DATA *pSharedUserData = (KUSER_SHARED_DATA *)KI_USER_SHARED_DATA;
pDevExt->fVRDPEnabled = false;
- Log(("VBoxGuest::vboxguestwinIOCtl: DISABLE_VRDP_SESSION: Current active console ID: 0x%08X\n",
+ Log(("VBoxGuest::vbgdNtIOCtl: DISABLE_VRDP_SESSION: Current active console ID: 0x%08X\n",
pSharedUserData->ActiveConsoleId));
pSharedUserData->ActiveConsoleId = pDevExt->ulOldActiveConsoleId;
pDevExt->ulOldActiveConsoleId = 0;
@@ -780,16 +789,16 @@ static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* Process the common IOCtls.
*/
size_t cbDataReturned;
- int vrc = VBoxGuestCommonIOCtl(uCmd, pDevExt, pSession, pBuf, cbData, &cbDataReturned);
+ int vrc = VBoxGuestCommonIOCtl(uCmd, &pDevExt->Core, pSession, pBuf, cbData, &cbDataReturned);
- Log(("VBoxGuest::vboxguestwinGuestDeviceControl: rc=%Rrc, pBuf=0x%p, cbData=%u, cbDataReturned=%u\n",
+ Log(("VBoxGuest::vbgdNtGuestDeviceControl: rc=%Rrc, pBuf=0x%p, cbData=%u, cbDataReturned=%u\n",
vrc, pBuf, cbData, cbDataReturned));
if (RT_SUCCESS(vrc))
{
if (RT_UNLIKELY(cbDataReturned > cbData))
{
- Log(("VBoxGuest::vboxguestwinGuestDeviceControl: Too much output data %u - expected %u!\n", cbDataReturned, cbData));
+ Log(("VBoxGuest::vbgdNtGuestDeviceControl: Too much output data %u - expected %u!\n", cbDataReturned, cbData));
cbDataReturned = cbData;
Status = STATUS_BUFFER_TOO_SMALL;
}
@@ -800,9 +809,9 @@ static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
if ( vrc == VERR_NOT_SUPPORTED
|| vrc == VERR_INVALID_PARAMETER)
- {
Status = STATUS_INVALID_PARAMETER;
- }
+ else if (vrc == VERR_OUT_OF_RANGE)
+ Status = STATUS_INVALID_BUFFER_SIZE;
else
Status = STATUS_UNSUCCESSFUL;
}
@@ -815,32 +824,29 @@ static NTSTATUS vboxguestwinIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- //Log(("VBoxGuest::vboxguestwinGuestDeviceControl: returned cbOut=%d rc=%#x\n", cbOut, Status));
+ //Log(("VBoxGuest::vbgdNtGuestDeviceControl: returned cbOut=%d rc=%#x\n", cbOut, Status));
return Status;
}
/**
* Internal Device I/O Control entry point.
*
- * We do not want to allow some IOCTLs to be originated from user mode, this is
- * why we have a different entry point for internal IOCTLs.
- *
* @param pDevObj Device object.
* @param pIrp Request packet.
- *
- * @todo r=bird: This is no need for this extra function for the purpose of
- * securing an IOCTL from user space access. VBoxGuestCommonIOCtl
- * has a way to do this already, see VBOXGUEST_IOCTL_GETVMMDEVPORT.
*/
-static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+static NTSTATUS vbgdNtInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
NTSTATUS Status = STATUS_SUCCESS;
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
PIO_STACK_LOCATION pStack = IoGetCurrentIrpStackLocation(pIrp);
unsigned int uCmd = (unsigned int)pStack->Parameters.DeviceIoControl.IoControlCode;
bool fProcessed = false;
unsigned Info = 0;
+ /*
+ * Override common behavior of some operations.
+ */
+ /** @todo r=bird: Better to add dedicated worker functions for this! */
switch (uCmd)
{
case VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK:
@@ -859,9 +865,9 @@ static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
/* we need a lock here to avoid concurrency with the set event functionality */
KIRQL OldIrql;
- KeAcquireSpinLock(&pDevExt->win.s.MouseEventAccessLock, &OldIrql);
- pDevExt->MouseNotifyCallback = *pInfo;
- KeReleaseSpinLock(&pDevExt->win.s.MouseEventAccessLock, OldIrql);
+ KeAcquireSpinLock(&pDevExt->MouseEventAccessLock, &OldIrql);
+ pDevExt->Core.MouseNotifyCallback = *pInfo;
+ KeReleaseSpinLock(&pDevExt->MouseEventAccessLock, OldIrql);
Status = STATUS_SUCCESS;
break;
@@ -870,8 +876,6 @@ static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
default:
break;
}
-
-
if (fProcessed)
{
pIrp->IoStatus.Status = Status;
@@ -881,7 +885,10 @@ static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
return Status;
}
- return vboxguestwinIOCtl(pDevObj, pIrp);
+ /*
+ * No override, go to common code.
+ */
+ return vbgdNtIOCtl(pDevObj, pIrp);
}
@@ -892,16 +899,16 @@ static NTSTATUS vboxguestwinInternalIOCtl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pDevObj Device object.
* @param pIrp IRP.
*/
-NTSTATUS vboxguestwinSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+NTSTATUS vbgdNtSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
- Log(("VBoxGuest::vboxguestwinGuestSystemControl\n"));
+ Log(("VBoxGuest::vbgdNtGuestSystemControl\n"));
/* Always pass it on to the next driver. */
IoSkipCurrentIrpStackLocation(pIrp);
- return IoCallDriver(pDevExt->win.s.pNextLowerDriver, pIrp);
+ return IoCallDriver(pDevExt->pNextLowerDriver, pIrp);
}
@@ -912,13 +919,13 @@ NTSTATUS vboxguestwinSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pDevObj Device object.
* @param pIrp IRP.
*/
-NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+NTSTATUS vbgdNtShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
- Log(("VBoxGuest::vboxguestwinGuestShutdown\n"));
+ Log(("VBoxGuest::vbgdNtGuestShutdown\n"));
- VMMDevPowerStateRequest *pReq = pDevExt->win.s.pPowerStateRequest;
+ VMMDevPowerStateRequest *pReq = pDevExt->pPowerStateRequest;
if (pReq)
{
pReq->header.requestType = VMMDevReq_SetPowerStatus;
@@ -927,7 +934,7 @@ NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
int rc = VbglGRPerform(&pReq->header);
if (RT_FAILURE(rc))
{
- Log(("VBoxGuest::vboxguestwinGuestShutdown: Error performing request to VMMDev! "
+ Log(("VBoxGuest::vbgdNtGuestShutdown: Error performing request to VMMDev! "
"rc = %Rrc\n", rc));
}
}
@@ -942,9 +949,9 @@ NTSTATUS vboxguestwinShutdown(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pDevObj Device object.
* @param pIrp IRP.
*/
-NTSTATUS vboxguestwinNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp)
+NTSTATUS vbgdNtNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
- Log(("VBoxGuest::vboxguestwinGuestNotSupportedStub\n"));
+ Log(("VBoxGuest::vbgdNtGuestNotSupportedStub\n"));
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
@@ -962,28 +969,28 @@ NTSTATUS vboxguestwinNotSupportedStub(PDEVICE_OBJECT pDevObj, PIRP pIrp)
* @param pIrp Interrupt request packet.
* @param pContext Context specific pointer.
*/
-void vboxguestwinDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext)
+void vbgdNtDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext)
{
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pDevObj->DeviceExtension;
- Log(("VBoxGuest::vboxguestwinGuestDpcHandler: pDevExt=0x%p\n", pDevExt));
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pDevObj->DeviceExtension;
+ Log(("VBoxGuest::vbgdNtGuestDpcHandler: pDevExt=0x%p\n", pDevExt));
/* test & reset the counter */
- if (ASMAtomicXchgU32(&pDevExt->u32MousePosChangedSeq, 0))
+ if (ASMAtomicXchgU32(&pDevExt->Core.u32MousePosChangedSeq, 0))
{
/* we need a lock here to avoid concurrency with the set event ioctl handler thread,
* i.e. to prevent the event from destroyed while we're using it */
Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
- KeAcquireSpinLockAtDpcLevel(&pDevExt->win.s.MouseEventAccessLock);
+ KeAcquireSpinLockAtDpcLevel(&pDevExt->MouseEventAccessLock);
- if (pDevExt->MouseNotifyCallback.pfnNotify)
- pDevExt->MouseNotifyCallback.pfnNotify(pDevExt->MouseNotifyCallback.pvUser);
+ if (pDevExt->Core.MouseNotifyCallback.pfnNotify)
+ pDevExt->Core.MouseNotifyCallback.pfnNotify(pDevExt->Core.MouseNotifyCallback.pvUser);
- KeReleaseSpinLockFromDpcLevel(&pDevExt->win.s.MouseEventAccessLock);
+ KeReleaseSpinLockFromDpcLevel(&pDevExt->MouseEventAccessLock);
}
/* Process the wake-up list we were asked by the scheduling a DPC
- * in vboxguestwinIsrHandler(). */
- VBoxGuestWaitDoWakeUps(pDevExt);
+ * in vbgdNtIsrHandler(). */
+ VBoxGuestWaitDoWakeUps(&pDevExt->Core);
}
@@ -994,35 +1001,35 @@ void vboxguestwinDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID
* @param pInterrupt Interrupt that was triggered.
* @param pServiceContext Context specific pointer.
*/
-BOOLEAN vboxguestwinIsrHandler(PKINTERRUPT pInterrupt, PVOID pServiceContext)
+BOOLEAN vbgdNtIsrHandler(PKINTERRUPT pInterrupt, PVOID pServiceContext)
{
- PVBOXGUESTDEVEXT pDevExt = (PVBOXGUESTDEVEXT)pServiceContext;
+ PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pServiceContext;
if (pDevExt == NULL)
return FALSE;
- /*Log(("VBoxGuest::vboxguestwinGuestIsrHandler: pDevExt = 0x%p, pVMMDevMemory = 0x%p\n",
+ /*Log(("VBoxGuest::vbgdNtGuestIsrHandler: pDevExt = 0x%p, pVMMDevMemory = 0x%p\n",
pDevExt, pDevExt ? pDevExt->pVMMDevMemory : NULL));*/
/* Enter the common ISR routine and do the actual work. */
- BOOLEAN fIRQTaken = VBoxGuestCommonISR(pDevExt);
+ BOOLEAN fIRQTaken = VBoxGuestCommonISR(&pDevExt->Core);
/* If we need to wake up some events we do that in a DPC to make
* sure we're called at the right IRQL. */
if (fIRQTaken)
{
- Log(("VBoxGuest::vboxguestwinGuestIsrHandler: IRQ was taken! pInterrupt = 0x%p, pDevExt = 0x%p\n",
+ Log(("VBoxGuest::vbgdNtGuestIsrHandler: IRQ was taken! pInterrupt = 0x%p, pDevExt = 0x%p\n",
pInterrupt, pDevExt));
- if (ASMAtomicUoReadU32(&pDevExt->u32MousePosChangedSeq) || !RTListIsEmpty(&pDevExt->WakeUpList))
+ if (ASMAtomicUoReadU32(&pDevExt->Core.u32MousePosChangedSeq) || !RTListIsEmpty(&pDevExt->Core.WakeUpList))
{
- Log(("VBoxGuest::vboxguestwinGuestIsrHandler: Requesting DPC ...\n"));
- IoRequestDpc(pDevExt->win.s.pDeviceObject, pDevExt->win.s.pCurrentIrp, NULL);
+ Log(("VBoxGuest::vbgdNtGuestIsrHandler: Requesting DPC ...\n"));
+ IoRequestDpc(pDevExt->pDeviceObject, pDevExt->pCurrentIrp, NULL);
}
}
return fIRQTaken;
}
-/*
+/**
* Overridden routine for mouse polling events.
*
* @param pDevExt Device extension structure.
@@ -1047,8 +1054,7 @@ void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt)
* not specified in ulRoot), on output this will retrieve the looked up
* registry value if found.
*/
-NTSTATUS vboxguestwinRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName,
- PULONG puValue)
+NTSTATUS vbgdNtRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwszName, PULONG puValue)
{
if (!pwszPath || !pwszName || !puValue)
return STATUS_INVALID_PARAMETER;
@@ -1079,17 +1085,17 @@ NTSTATUS vboxguestwinRegistryReadDWORD(ULONG ulRoot, PCWSTR pwszPath, PWSTR pwsz
* @param pResList Resource list
* @param pDevExt Device extension
*/
-NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXT pDevExt)
+NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTWIN pDevExt)
{
/* Enumerate the resource list. */
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Found %d resources\n",
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: Found %d resources\n",
pResList->List->PartialResourceList.Count));
NTSTATUS rc = STATUS_SUCCESS;
PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialData = NULL;
ULONG rangeCount = 0;
ULONG cMMIORange = 0;
- PVBOXGUESTWINBASEADDRESS pBaseAddress = pDevExt->win.s.pciBaseAddress;
+ PVBOXGUESTWINBASEADDRESS pBaseAddress = pDevExt->pciBaseAddress;
for (ULONG i = 0; i < pResList->List->PartialResourceList.Count; i++)
{
pPartialData = &pResList->List->PartialResourceList.PartialDescriptors[i];
@@ -1100,14 +1106,15 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
/* Overflow protection. */
if (rangeCount < PCI_TYPE0_ADDRESSES)
{
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: I/O range: Base = %08x:%08x, Length = %08x\n",
- pPartialData->u.Port.Start.HighPart,
- pPartialData->u.Port.Start.LowPart,
- pPartialData->u.Port.Length));
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: I/O range: Base = %08x:%08x, Length = %08x\n",
+ pPartialData->u.Port.Start.HighPart,
+ pPartialData->u.Port.Start.LowPart,
+ pPartialData->u.Port.Length));
/* Save the IO port base. */
- /** @todo Not so good. */
- pDevExt->IOPortBase = (RTIOPORT)pPartialData->u.Port.Start.LowPart;
+ /** @todo Not so good.
+ * Update/bird: What is not so good? That we just consider the last range? */
+ pDevExt->Core.IOPortBase = (RTIOPORT)pPartialData->u.Port.Start.LowPart;
/* Save resource information. */
pBaseAddress->RangeStart = pPartialData->u.Port.Start;
@@ -1115,10 +1122,10 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
pBaseAddress->RangeInMemory = FALSE;
pBaseAddress->ResourceMapped = FALSE;
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: I/O range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
- pPartialData->u.Port.Start.HighPart,
- pPartialData->u.Port.Start.LowPart,
- pPartialData->u.Port.Length));
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: I/O range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
+ pPartialData->u.Port.Start.HighPart,
+ pPartialData->u.Port.Start.LowPart,
+ pPartialData->u.Port.Length));
/* Next item ... */
rangeCount++; pBaseAddress++;
@@ -1128,25 +1135,21 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
case CmResourceTypeInterrupt:
{
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Interrupt: Level = %x, Vector = %x, Mode = %x\n",
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: Interrupt: Level = %x, Vector = %x, Mode = %x\n",
pPartialData->u.Interrupt.Level,
pPartialData->u.Interrupt.Vector,
pPartialData->Flags));
/* Save information. */
- pDevExt->win.s.interruptLevel = pPartialData->u.Interrupt.Level;
- pDevExt->win.s.interruptVector = pPartialData->u.Interrupt.Vector;
- pDevExt->win.s.interruptAffinity = pPartialData->u.Interrupt.Affinity;
+ pDevExt->interruptLevel = pPartialData->u.Interrupt.Level;
+ pDevExt->interruptVector = pPartialData->u.Interrupt.Vector;
+ pDevExt->interruptAffinity = pPartialData->u.Interrupt.Affinity;
/* Check interrupt mode. */
if (pPartialData->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
- {
- pDevExt->win.s.interruptMode = Latched;
- }
+ pDevExt->interruptMode = Latched;
else
- {
- pDevExt->win.s.interruptMode = LevelSensitive;
- }
+ pDevExt->interruptMode = LevelSensitive;
break;
}
@@ -1155,7 +1158,7 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
/* Overflow protection. */
if (rangeCount < PCI_TYPE0_ADDRESSES)
{
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Memory range: Base = %08x:%08x, Length = %08x\n",
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: Memory range: Base = %08x:%08x, Length = %08x\n",
pPartialData->u.Memory.Start.HighPart,
pPartialData->u.Memory.Start.LowPart,
pPartialData->u.Memory.Length));
@@ -1166,8 +1169,8 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
&& (pPartialData->Flags & VBOX_CM_PRE_VISTA_MASK) == CM_RESOURCE_MEMORY_READ_WRITE)
{
/* Save physical MMIO base + length for VMMDev. */
- pDevExt->win.s.vmmDevPhysMemoryAddress = pPartialData->u.Memory.Start;
- pDevExt->win.s.vmmDevPhysMemoryLength = (ULONG)pPartialData->u.Memory.Length;
+ pDevExt->vmmDevPhysMemoryAddress = pPartialData->u.Memory.Start;
+ pDevExt->vmmDevPhysMemoryLength = (ULONG)pPartialData->u.Memory.Length;
/* Save resource information. */
pBaseAddress->RangeStart = pPartialData->u.Memory.Start;
@@ -1175,7 +1178,7 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
pBaseAddress->RangeInMemory = TRUE;
pBaseAddress->ResourceMapped = FALSE;
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Memory range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: Memory range for VMMDev found! Base = %08x:%08x, Length = %08x\n",
pPartialData->u.Memory.Start.HighPart,
pPartialData->u.Memory.Start.LowPart,
pPartialData->u.Memory.Length));
@@ -1185,7 +1188,7 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
}
else
{
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Ignoring memory: Flags = %08x\n",
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: Ignoring memory: Flags = %08x\n",
pPartialData->Flags));
}
}
@@ -1194,14 +1197,14 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
default:
{
- Log(("VBoxGuest::vboxguestwinScanPCIResourceList: Unhandled resource found, type = %d\n", pPartialData->Type));
+ Log(("VBoxGuest::vbgdNtScanPCIResourceList: Unhandled resource found, type = %d\n", pPartialData->Type));
break;
}
}
}
/* Memorize the number of resources found. */
- pDevExt->win.s.pciAddressCount = rangeCount;
+ pDevExt->pciAddressCount = rangeCount;
return rc;
}
@@ -1212,48 +1215,46 @@ NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTD
* @return NTSTATUS
*
* @param pDevExt The device extension.
- * @param physicalAdr Physical address to map.
- * @param ulLength Length (in bytes) to map.
+ * @param PhysAddr Physical address to map.
+ * @param cbToMap Number of bytes to map.
* @param ppvMMIOBase Pointer of mapped I/O base.
* @param pcbMMIO Length of mapped I/O base.
*/
-NTSTATUS vboxguestwinMapVMMDevMemory(PVBOXGUESTDEVEXT pDevExt, PHYSICAL_ADDRESS physicalAdr, ULONG ulLength,
- void **ppvMMIOBase, uint32_t *pcbMMIO)
+NTSTATUS vbgdNtMapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt, PHYSICAL_ADDRESS PhysAddr, ULONG cbToMap,
+ void **ppvMMIOBase, uint32_t *pcbMMIO)
{
AssertPtrReturn(pDevExt, VERR_INVALID_POINTER);
AssertPtrReturn(ppvMMIOBase, VERR_INVALID_POINTER);
/* pcbMMIO is optional. */
NTSTATUS rc = STATUS_SUCCESS;
- if (physicalAdr.LowPart > 0) /* We're mapping below 4GB. */
+ if (PhysAddr.LowPart > 0) /* We're mapping below 4GB. */
{
- VMMDevMemory *pVMMDevMemory = (VMMDevMemory *)MmMapIoSpace(physicalAdr, ulLength, MmNonCached);
- Log(("VBoxGuest::vboxguestwinMapVMMDevMemory: pVMMDevMemory = 0x%x\n", pVMMDevMemory));
+ VMMDevMemory *pVMMDevMemory = (VMMDevMemory *)MmMapIoSpace(PhysAddr, cbToMap, MmNonCached);
+ Log(("VBoxGuest::vbgdNtMapVMMDevMemory: pVMMDevMemory = 0x%x\n", pVMMDevMemory));
if (pVMMDevMemory)
{
- Log(("VBoxGuest::vboxguestwinMapVMMDevMemory: VMMDevMemory: Version = 0x%x, Size = %d\n",
+ Log(("VBoxGuest::vbgdNtMapVMMDevMemory: VMMDevMemory: Version = 0x%x, Size = %d\n",
pVMMDevMemory->u32Version, pVMMDevMemory->u32Size));
/* Check version of the structure; do we have the right memory version? */
- if (pVMMDevMemory->u32Version != VMMDEV_MEMORY_VERSION)
- {
- Log(("VBoxGuest::vboxguestwinMapVMMDevMemory: Wrong version (%u), refusing operation!\n",
- pVMMDevMemory->u32Version));
-
- /* Not our version, refuse operation and unmap the memory. */
- vboxguestwinUnmapVMMDevMemory(pDevExt);
- rc = STATUS_UNSUCCESSFUL;
- }
- else
+ if (pVMMDevMemory->u32Version == VMMDEV_MEMORY_VERSION)
{
/* Save results. */
*ppvMMIOBase = pVMMDevMemory;
if (pcbMMIO) /* Optional. */
*pcbMMIO = pVMMDevMemory->u32Size;
- Log(("VBoxGuest::vboxguestwinMapVMMDevMemory: VMMDevMemory found and mapped! pvMMIOBase = 0x%p\n",
+ Log(("VBoxGuest::vbgdNtMapVMMDevMemory: VMMDevMemory found and mapped! pvMMIOBase = 0x%p\n",
*ppvMMIOBase));
}
+ else
+ {
+ /* Not our version, refuse operation and unmap the memory. */
+ Log(("VBoxGuest::vbgdNtMapVMMDevMemory: Wrong version (%u), refusing operation!\n", pVMMDevMemory->u32Version));
+ vbgdNtUnmapVMMDevMemory(pDevExt);
+ rc = STATUS_UNSUCCESSFUL;
+ }
}
else
rc = STATUS_UNSUCCESSFUL;
@@ -1267,34 +1268,34 @@ NTSTATUS vboxguestwinMapVMMDevMemory(PVBOXGUESTDEVEXT pDevExt, PHYSICAL_ADDRESS
*
* @param pDevExt The device extension.
*/
-void vboxguestwinUnmapVMMDevMemory(PVBOXGUESTDEVEXT pDevExt)
+void vbgdNtUnmapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt)
{
- Log(("VBoxGuest::vboxguestwinUnmapVMMDevMemory: pVMMDevMemory = 0x%x\n", pDevExt->pVMMDevMemory));
- if (pDevExt->pVMMDevMemory)
+ Log(("VBoxGuest::vbgdNtUnmapVMMDevMemory: pVMMDevMemory = 0x%x\n", pDevExt->Core.pVMMDevMemory));
+ if (pDevExt->Core.pVMMDevMemory)
{
- MmUnmapIoSpace((void*)pDevExt->pVMMDevMemory, pDevExt->win.s.vmmDevPhysMemoryLength);
- pDevExt->pVMMDevMemory = NULL;
+ MmUnmapIoSpace((void*)pDevExt->Core.pVMMDevMemory, pDevExt->vmmDevPhysMemoryLength);
+ pDevExt->Core.pVMMDevMemory = NULL;
}
- pDevExt->win.s.vmmDevPhysMemoryAddress.QuadPart = 0;
- pDevExt->win.s.vmmDevPhysMemoryLength = 0;
+ pDevExt->vmmDevPhysMemoryAddress.QuadPart = 0;
+ pDevExt->vmmDevPhysMemoryLength = 0;
}
-VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
+VBOXOSTYPE vbgdNtVersionToOSType(VBGDNTVER enmNtVer)
{
VBOXOSTYPE enmOsType;
- switch (winVer)
+ switch (enmNtVer)
{
- case WINNT4:
+ case VBGDNTVER_WINNT4:
enmOsType = VBOXOSTYPE_WinNT4;
break;
- case WIN2K:
+ case VBGDNTVER_WIN2K:
enmOsType = VBOXOSTYPE_Win2k;
break;
- case WINXP:
+ case VBGDNTVER_WINXP:
#if ARCH_BITS == 64
enmOsType = VBOXOSTYPE_WinXP_x64;
#else
@@ -1302,7 +1303,7 @@ VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
#endif
break;
- case WIN2K3:
+ case VBGDNTVER_WIN2K3:
#if ARCH_BITS == 64
enmOsType = VBOXOSTYPE_Win2k3_x64;
#else
@@ -1310,7 +1311,7 @@ VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
#endif
break;
- case WINVISTA:
+ case VBGDNTVER_WINVISTA:
#if ARCH_BITS == 64
enmOsType = VBOXOSTYPE_WinVista_x64;
#else
@@ -1318,7 +1319,7 @@ VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
#endif
break;
- case WIN7:
+ case VBGDNTVER_WIN7:
#if ARCH_BITS == 64
enmOsType = VBOXOSTYPE_Win7_x64;
#else
@@ -1326,7 +1327,7 @@ VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
#endif
break;
- case WIN8:
+ case VBGDNTVER_WIN8:
#if ARCH_BITS == 64
enmOsType = VBOXOSTYPE_Win8_x64;
#else
@@ -1334,6 +1335,14 @@ VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
#endif
break;
+ case VBGDNTVER_WIN81:
+#if ARCH_BITS == 64
+ enmOsType = VBOXOSTYPE_Win81_x64;
+#else
+ enmOsType = VBOXOSTYPE_Win81;
+#endif
+ break;
+
default:
/* We don't know, therefore NT family. */
enmOsType = VBOXOSTYPE_WinNT;
@@ -1350,8 +1359,7 @@ VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer)
static uint32_t vboxugestwinAtomicBitsTestAndClear(void *pu32Bits, uint32_t u32Mask)
{
AssertPtrReturn(pu32Bits, 0);
- LogFlowFunc(("*pu32Bits=0x%x, u32Mask=0x%x\n", *(long *)pu32Bits,
- u32Mask));
+ LogFlowFunc(("*pu32Bits=0x%x, u32Mask=0x%x\n", *(uint32_t *)pu32Bits, u32Mask));
uint32_t u32Result = 0;
uint32_t u32WorkingMask = u32Mask;
int iBitOffset = ASMBitFirstSetU32 (u32WorkingMask);
@@ -1369,8 +1377,7 @@ static uint32_t vboxugestwinAtomicBitsTestAndClear(void *pu32Bits, uint32_t u32M
}
-static void vboxguestwinTestAtomicTestAndClearBitsU32(uint32_t u32Mask, uint32_t u32Bits,
- uint32_t u32Exp)
+static void vbgdNtTestAtomicTestAndClearBitsU32(uint32_t u32Mask, uint32_t u32Bits, uint32_t u32Exp)
{
ULONG u32Bits2 = u32Bits;
uint32_t u32Result = vboxugestwinAtomicBitsTestAndClear(&u32Bits2, u32Mask);
@@ -1385,104 +1392,134 @@ static void vboxguestwinTestAtomicTestAndClearBitsU32(uint32_t u32Mask, uint32_t
}
-static void vboxguestwinDoTests()
+static void vbgdNtDoTests(void)
{
- vboxguestwinTestAtomicTestAndClearBitsU32(0x00, 0x23, 0);
- vboxguestwinTestAtomicTestAndClearBitsU32(0x11, 0, 0);
- vboxguestwinTestAtomicTestAndClearBitsU32(0x11, 0x22, 0);
- vboxguestwinTestAtomicTestAndClearBitsU32(0x11, 0x23, 0x1);
- vboxguestwinTestAtomicTestAndClearBitsU32(0x11, 0x32, 0x10);
- vboxguestwinTestAtomicTestAndClearBitsU32(0x22, 0x23, 0x22);
+ vbgdNtTestAtomicTestAndClearBitsU32(0x00, 0x23, 0);
+ vbgdNtTestAtomicTestAndClearBitsU32(0x11, 0, 0);
+ vbgdNtTestAtomicTestAndClearBitsU32(0x11, 0x22, 0);
+ vbgdNtTestAtomicTestAndClearBitsU32(0x11, 0x23, 0x1);
+ vbgdNtTestAtomicTestAndClearBitsU32(0x11, 0x32, 0x10);
+ vbgdNtTestAtomicTestAndClearBitsU32(0x22, 0x23, 0x22);
}
#endif /* DEBUG */
#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
-#pragma pack(1)
+
+/*
+ * DPC latency checker.
+ */
+
+/**
+ * One DPC latency sample.
+ */
typedef struct DPCSAMPLE
{
- LARGE_INTEGER PerfDelta;
- LARGE_INTEGER PerfCounter;
- LARGE_INTEGER PerfFrequency;
- uint64_t u64TSC;
+ LARGE_INTEGER PerfDelta;
+ LARGE_INTEGER PerfCounter;
+ LARGE_INTEGER PerfFrequency;
+ uint64_t u64TSC;
} DPCSAMPLE;
+AssertCompileSize(DPCSAMPLE, 4*8);
+/**
+ * The DPC latency measurement workset.
+ */
typedef struct DPCDATA
{
- KDPC Dpc;
- KTIMER Timer;
- KSPIN_LOCK SpinLock;
+ KDPC Dpc;
+ KTIMER Timer;
+ KSPIN_LOCK SpinLock;
+
+ ULONG ulTimerRes;
- ULONG ulTimerRes;
+ bool volatile fFinished;
- LARGE_INTEGER DueTime;
+ /** The timer interval (relative). */
+ LARGE_INTEGER DueTime;
- BOOLEAN fFinished;
+ LARGE_INTEGER PerfCounterPrev;
- LARGE_INTEGER PerfCounterPrev;
+ /** Align the sample array on a 64 byte boundrary just for the off chance
+ * that we'll get cache line aligned memory backing this structure. */
+ uint32_t auPadding[ARCH_BITS == 32 ? 5 : 7];
- int iSampleCount;
- DPCSAMPLE aSamples[8192];
+ int cSamples;
+ DPCSAMPLE aSamples[8192];
} DPCDATA;
-#pragma pack(1)
-#define VBOXGUEST_DPC_TAG 'DPCS'
+AssertCompileMemberAlignment(DPCDATA, aSamples, 64);
+
+# define VBOXGUEST_DPC_TAG 'DPCS'
+
-static VOID DPCDeferredRoutine(struct _KDPC *Dpc,
- PVOID DeferredContext,
- PVOID SystemArgument1,
- PVOID SystemArgument2)
+/**
+ * DPC callback routine for the DPC latency measurement code.
+ *
+ * @param pDpc The DPC, not used.
+ * @param pvDeferredContext Pointer to the DPCDATA.
+ * @param SystemArgument1 System use, ignored.
+ * @param SystemArgument2 System use, ignored.
+ */
+static VOID vbgdNtDpcLatencyCallback(PKDPC pDpc, PVOID pvDeferredContext, PVOID SystemArgument1, PVOID SystemArgument2)
{
- DPCDATA *pData = (DPCDATA *)DeferredContext;
+ DPCDATA *pData = (DPCDATA *)pvDeferredContext;
KeAcquireSpinLockAtDpcLevel(&pData->SpinLock);
- if (pData->iSampleCount >= RT_ELEMENTS(pData->aSamples))
+ if (pData->cSamples >= RT_ELEMENTS(pData->aSamples))
+ pData->fFinished = true;
+ else
{
- pData->fFinished = 1;
- KeReleaseSpinLockFromDpcLevel(&pData->SpinLock);
- return;
- }
-
- DPCSAMPLE *pSample = &pData->aSamples[pData->iSampleCount++];
+ DPCSAMPLE *pSample = &pData->aSamples[pData->cSamples++];
- pSample->u64TSC = ASMReadTSC();
- pSample->PerfCounter = KeQueryPerformanceCounter(&pSample->PerfFrequency);
- pSample->PerfDelta.QuadPart = pSample->PerfCounter.QuadPart - pData->PerfCounterPrev.QuadPart;
+ pSample->u64TSC = ASMReadTSC();
+ pSample->PerfCounter = KeQueryPerformanceCounter(&pSample->PerfFrequency);
+ pSample->PerfDelta.QuadPart = pSample->PerfCounter.QuadPart - pData->PerfCounterPrev.QuadPart;
- pData->PerfCounterPrev.QuadPart = pSample->PerfCounter.QuadPart;
+ pData->PerfCounterPrev.QuadPart = pSample->PerfCounter.QuadPart;
- KeSetTimer(&pData->Timer, pData->DueTime, &pData->Dpc);
+ KeSetTimer(&pData->Timer, pData->DueTime, &pData->Dpc);
+ }
KeReleaseSpinLockFromDpcLevel(&pData->SpinLock);
}
-int VBoxGuestCommonIOCtl_DPC(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
- void *pvData, size_t cbData, size_t *pcbDataReturned)
-{
- int rc = VINF_SUCCESS;
- /* Allocate a non paged memory for samples and related data. */
+/**
+ * Handles the DPC latency checker request.
+ *
+ * @returns VBox status code.
+ */
+int VbgdNtIOCtl_DpcLatencyChecker(void)
+{
+ /*
+ * Allocate a block of non paged memory for samples and related data.
+ */
DPCDATA *pData = (DPCDATA *)ExAllocatePoolWithTag(NonPagedPool, sizeof(DPCDATA), VBOXGUEST_DPC_TAG);
-
if (!pData)
{
RTLogBackdoorPrintf("VBoxGuest: DPC: DPCDATA allocation failed.\n");
return VERR_NO_MEMORY;
}
- KeInitializeDpc(&pData->Dpc, DPCDeferredRoutine, pData);
+ /*
+ * Initialize the data.
+ */
+ KeInitializeDpc(&pData->Dpc, vbgdNtDpcLatencyCallback, pData);
KeInitializeTimer(&pData->Timer);
KeInitializeSpinLock(&pData->SpinLock);
- pData->fFinished = 0;
- pData->iSampleCount = 0;
+ pData->fFinished = false;
+ pData->cSamples = 0;
pData->PerfCounterPrev.QuadPart = 0;
pData->ulTimerRes = ExSetTimerResolution(1000 * 10, 1);
pData->DueTime.QuadPart = -(int64_t)pData->ulTimerRes / 10;
- /* Start the DPC measurements. */
+ /*
+ * Start the DPC measurements and wait for a full set.
+ */
KeSetTimer(&pData->Timer, pData->DueTime, &pData->Dpc);
while (!pData->fFinished)
@@ -1494,22 +1531,25 @@ int VBoxGuestCommonIOCtl_DPC(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSessio
ExSetTimerResolution(0, 0);
- /* Log everything to the host. */
+ /*
+ * Log everything to the host.
+ */
RTLogBackdoorPrintf("DPC: ulTimerRes = %d\n", pData->ulTimerRes);
- int i;
- for (i = 0; i < pData->iSampleCount; i++)
+ for (int i = 0; i < pData->cSamples; i++)
{
DPCSAMPLE *pSample = &pData->aSamples[i];
RTLogBackdoorPrintf("[%d] pd %lld pc %lld pf %lld t %lld\n",
- i,
- pSample->PerfDelta.QuadPart,
- pSample->PerfCounter.QuadPart,
- pSample->PerfFrequency.QuadPart,
- pSample->u64TSC);
+ i,
+ pSample->PerfDelta.QuadPart,
+ pSample->PerfCounter.QuadPart,
+ pSample->PerfFrequency.QuadPart,
+ pSample->u64TSC);
}
ExFreePoolWithTag(pData, VBOXGUEST_DPC_TAG);
- return rc;
+ return VINF_SUCCESS;
}
+
#endif /* VBOX_WITH_DPC_LATENCY_CHECKER */
+
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h
index a3b02659..aee63677 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.h
@@ -1,8 +1,10 @@
+/* $Id: VBoxGuest-win.h $ */
/** @file
- *
* VBoxGuest - Windows specifics.
- *
- * Copyright (C) 2010 Oracle Corporation
+ */
+
+/*
+ * Copyright (C) 2010-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -16,9 +18,6 @@
#ifndef ___VBoxGuest_win_h
#define ___VBoxGuest_win_h
-/*******************************************************************************
-* Header Files *
-*******************************************************************************/
#include <iprt/cdefs.h>
@@ -37,14 +36,9 @@ RT_C_DECLS_END
#include <VBox/VMMDev.h>
#include <VBox/VBoxGuest.h>
+#include "VBoxGuestInternal.h"
-/*******************************************************************************
-* Structures and Typedefs *
-*******************************************************************************/
-
-/** Pointer to the VBoxGuest per session data. */
-typedef struct VBOXGUESTSESSION *PVBOXGUESTSESSION;
/** Possible device states for our state machine. */
enum DEVSTATE
@@ -77,6 +71,8 @@ typedef struct VBOXGUESTWINBASEADDRESS
/** Windows-specific device extension bits. */
typedef struct VBOXGUESTDEVEXTWIN
{
+ VBOXGUESTDEVEXT Core;
+
/** Our functional driver object. */
PDEVICE_OBJECT pDeviceObject;
/** Top of the stack. */
@@ -119,64 +115,69 @@ typedef struct VBOXGUESTDEVEXTWIN
VMMDevEvents *pIrqAckEvents;
/** Pre-allocated kernel session data. This is needed
- * for handling kernel IOCtls. */
- PVBOXGUESTSESSION pKernelSession;
+ * for handling kernel IOCtls. */
+ struct VBOXGUESTSESSION *pKernelSession;
/** Spinlock protecting MouseNotifyCallback. Required since the consumer is
* in a DPC callback and not the ISR. */
KSPIN_LOCK MouseEventAccessLock;
} VBOXGUESTDEVEXTWIN, *PVBOXGUESTDEVEXTWIN;
-#define VBOXGUEST_UPDATE_DEVSTATE(_pDevExt, _newDevState) do { \
- (_pDevExt)->win.s.prevDevState = (_pDevExt)->win.s.devState; \
- (_pDevExt)->win.s.devState = (_newDevState); \
-} while (0)
-
-/*******************************************************************************
-* Defined Constants And Macros *
-*******************************************************************************/
+/** NT (windows) version identifier. */
+typedef enum VBGDNTVER
+{
+ VBGDNTVER_INVALID = 0,
+ VBGDNTVER_WINNT4,
+ VBGDNTVER_WIN2K,
+ VBGDNTVER_WINXP,
+ VBGDNTVER_WIN2K3,
+ VBGDNTVER_WINVISTA,
+ VBGDNTVER_WIN7,
+ VBGDNTVER_WIN8,
+ VBGDNTVER_WIN81,
+} VBGDNTVER;
+extern VBGDNTVER g_enmVbgdNtVer;
+
+
+#define VBOXGUEST_UPDATE_DEVSTATE(a_pDevExt, a_newDevState) \
+ do { \
+ (a_pDevExt)->prevDevState = (a_pDevExt)->devState; \
+ (a_pDevExt)->devState = (a_newDevState); \
+ } while (0)
/** CM_RESOURCE_MEMORY_* flags which were used on XP or earlier. */
#define VBOX_CM_PRE_VISTA_MASK (0x3f)
-/** Windows version identifier. */
-typedef enum
-{
- WINNT4 = 1,
- WIN2K = 2,
- WINXP = 3,
- WIN2K3 = 4,
- WINVISTA = 5,
- WIN7 = 6,
- WIN8 = 7
-} winVersion_t;
-extern winVersion_t winVersion;
-
-
-/*******************************************************************************
-* Declared prototypes for helper routines used in both (PnP and legacy) *
-* driver versions. *
-*******************************************************************************/
-#include "VBoxGuestInternal.h"
RT_C_DECLS_BEGIN
+
#ifdef TARGET_NT4
-NTSTATUS vboxguestwinnt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath);
-NTSTATUS vboxguestwinInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath);
+NTSTATUS vbgdNt4CreateDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath);
#else
-NTSTATUS vboxguestwinInit(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+NTSTATUS vbgdNtInit(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+NTSTATUS vbgdNtPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+NTSTATUS vbgdNtPower(PDEVICE_OBJECT pDevObj, PIRP pIrp);
#endif
-NTSTATUS vboxguestwinCleanup(PDEVICE_OBJECT pDevObj);
-NTSTATUS vboxguestwinPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-VOID vboxguestwinDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext);
-BOOLEAN vboxguestwinIsrHandler(PKINTERRUPT interrupt, PVOID serviceContext);
-NTSTATUS vboxguestwinScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXT pDevExt);
-NTSTATUS vboxguestwinMapVMMDevMemory(PVBOXGUESTDEVEXT pDevExt, PHYSICAL_ADDRESS physicalAdr, ULONG ulLength,
- void **ppvMMIOBase, uint32_t *pcbMMIO);
-void vboxguestwinUnmapVMMDevMemory(PVBOXGUESTDEVEXT pDevExt);
-VBOXOSTYPE vboxguestwinVersionToOSType(winVersion_t winVer);
-NTSTATUS vboxguestwinPower(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+
+/** @name Common routines used in both (PnP and legacy) driver versions.
+ * @{
+ */
+#ifdef TARGET_NT4
+NTSTATUS vbgdNtInit(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj, PUNICODE_STRING pRegPath);
+#else
+NTSTATUS vbgdNtInit(PDEVICE_OBJECT pDevObj, PIRP pIrp);
+#endif
+NTSTATUS vbgdNtCleanup(PDEVICE_OBJECT pDevObj);
+VOID vbgdNtDpcHandler(PKDPC pDPC, PDEVICE_OBJECT pDevObj, PIRP pIrp, PVOID pContext);
+BOOLEAN vbgdNtIsrHandler(PKINTERRUPT interrupt, PVOID serviceContext);
+NTSTATUS vbgdNtScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXTWIN pDevExt);
+NTSTATUS vbgdNtMapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt, PHYSICAL_ADDRESS PhysAddr, ULONG cbToMap,
+ void **ppvMMIOBase, uint32_t *pcbMMIO);
+void vbgdNtUnmapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt);
+VBOXOSTYPE vbgdNtVersionToOSType(VBGDNTVER enmNtVer);
+/** @} */
+
RT_C_DECLS_END
#ifdef TARGET_NT4
@@ -184,9 +185,9 @@ RT_C_DECLS_END
* XP DDK #defines ExFreePool to ExFreePoolWithTag. The latter does not exist
* on NT4, so... The same for ExAllocatePool.
*/
-#undef ExAllocatePool
-#undef ExFreePool
+# undef ExAllocatePool
+# undef ExFreePool
#endif
-#endif /* ___VBoxGuest_win_h */
+#endif /* !___VBoxGuest_win_h */
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
index 594e0921..b1ffd3ba 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuest.cpp
@@ -4,7 +4,7 @@
*/
/*
- * Copyright (C) 2007-2012 Oracle Corporation
+ * Copyright (C) 2007-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -54,7 +54,7 @@
# include <Windows.h>
# endif
#endif
-#if defined(RT_OS_SOLARIS)
+#if defined(RT_OS_SOLARIS) || defined(RT_OS_DARWIN)
# include <iprt/rand.h>
#endif
@@ -70,17 +70,61 @@ static void testSetMouseStatus(void);
#endif
static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fFeatures);
-#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
-int VBoxGuestCommonIOCtl_DPC(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession,
- void *pvData, size_t cbData, size_t *pcbDataReturned);
-#endif /* VBOX_WITH_DPC_LATENCY_CHECKER */
+static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags);
+
+#define VBOXGUEST_ACQUIRE_STYLE_EVENTS (VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST | VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST)
+
+DECLINLINE(uint32_t) VBoxGuestCommonGetHandledEventsLocked(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
+{
+ if (!pDevExt->u32AcquireModeGuestCaps)
+ return VMMDEV_EVENT_VALID_EVENT_MASK;
+
+ uint32_t u32AllowedGuestCaps = pSession->u32AquiredGuestCaps | (VMMDEV_EVENT_VALID_EVENT_MASK & ~pDevExt->u32AcquireModeGuestCaps);
+ uint32_t u32CleanupEvents = VBOXGUEST_ACQUIRE_STYLE_EVENTS;
+ if (u32AllowedGuestCaps & VMMDEV_GUEST_SUPPORTS_GRAPHICS)
+ u32CleanupEvents &= ~VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST;
+ if (u32AllowedGuestCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS)
+ u32CleanupEvents &= ~VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
+
+ return VMMDEV_EVENT_VALID_EVENT_MASK & ~u32CleanupEvents;
+}
+
+DECLINLINE(uint32_t) VBoxGuestCommonGetAndCleanPendingEventsLocked(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fReqEvents)
+{
+ uint32_t fMatches = pDevExt->f32PendingEvents & fReqEvents & VBoxGuestCommonGetHandledEventsLocked(pDevExt, pSession);
+ if (fMatches)
+ ASMAtomicAndU32(&pDevExt->f32PendingEvents, ~fMatches);
+ return fMatches;
+}
+
+DECLINLINE(bool) VBoxGuestCommonGuestCapsModeSet(PVBOXGUESTDEVEXT pDevExt, uint32_t fCaps, bool fAcquire, uint32_t *pu32OtherVal)
+{
+ uint32_t *pVal = fAcquire ? &pDevExt->u32AcquireModeGuestCaps : &pDevExt->u32SetModeGuestCaps;
+ const uint32_t fNotVal = !fAcquire ? pDevExt->u32AcquireModeGuestCaps : pDevExt->u32SetModeGuestCaps;
+ bool fResult = true;
+ RTSpinlockAcquire(pDevExt->EventSpinlock);
+
+ if (!(fNotVal & fCaps))
+ *pVal |= fCaps;
+ else
+ {
+ AssertMsgFailed(("trying to change caps mode\n"));
+ fResult = false;
+ }
+
+ RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
+
+ if (pu32OtherVal)
+ *pu32OtherVal = fNotVal;
+ return fResult;
+}
/*******************************************************************************
* Global Variables *
*******************************************************************************/
static const size_t cbChangeMemBalloonReq = RT_OFFSETOF(VMMDevChangeMemBalloon, aPhysPage[VMMDEV_MEMORY_BALLOON_CHUNK_PAGES]);
-#if defined(RT_OS_SOLARIS)
+#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
/**
* Drag in the rest of IRPT since we share it with the
* rest of the kernel modules on Solaris.
@@ -100,7 +144,7 @@ PFNRT g_apfnVBoxGuestIPRTDeps[] =
(PFNRT)RTSemMutexIsOwned,
NULL
};
-#endif /* RT_OS_SOLARIS */
+#endif /* RT_OS_DARWIN || RT_OS_SOLARIS */
/**
@@ -418,7 +462,7 @@ static int vboxGuestSetBalloonSizeKernel(PVBOXGUESTDEVEXT pDevExt, uint32_t cBal
pDevExt->MemBalloon.paMemObj = (PRTR0MEMOBJ)RTMemAllocZ(sizeof(RTR0MEMOBJ) * pDevExt->MemBalloon.cMaxChunks);
if (!pDevExt->MemBalloon.paMemObj)
{
- LogRel(("VBoxGuestSetBalloonSizeKernel: no memory for paMemObj!\n"));
+ LogRel(("vboxGuestSetBalloonSizeKernel: no memory for paMemObj!\n"));
return VERR_NO_MEMORY;
}
}
@@ -706,6 +750,20 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
int rc, rc2;
unsigned i;
+#ifdef VBOX_GUESTDRV_WITH_RELEASE_LOGGER
+ /*
+ * Create the release log.
+ */
+ static const char * const s_apszGroups[] = VBOX_LOGGROUP_NAMES;
+ PRTLOGGER pRelLogger;
+ rc = RTLogCreate(&pRelLogger, 0 /* fFlags */, "all",
+ "VBOX_RELEASE_LOG", RT_ELEMENTS(s_apszGroups), s_apszGroups, RTLOGDEST_STDOUT | RTLOGDEST_DEBUGGER, NULL);
+ if (RT_SUCCESS(rc))
+ RTLogRelSetDefaultInstance(pRelLogger);
+ /** @todo Add native hook for getting logger config parameters and setting
+ * them. On linux we should use the module parameter stuff... */
+#endif
+
/*
* Adjust fFixedEvents.
*/
@@ -772,6 +830,10 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
pVMMDev->u32Version, VMMDEV_MEMORY_VERSION, pVMMDev->u32Size, cbMMIO));
}
+ pDevExt->u32AcquireModeGuestCaps = 0;
+ pDevExt->u32SetModeGuestCaps = 0;
+ pDevExt->u32GuestCaps = 0;
+
/*
* Create the wait and session spinlocks as well as the ballooning mutex.
*/
@@ -856,6 +918,11 @@ int VBoxGuestInitDevExt(PVBOXGUESTDEVEXT pDevExt, uint16_t IOPortBase,
rc2 = RTSemFastMutexDestroy(pDevExt->MemBalloon.hMtx); AssertRC(rc2);
rc2 = RTSpinlockDestroy(pDevExt->EventSpinlock); AssertRC(rc2);
rc2 = RTSpinlockDestroy(pDevExt->SessionSpinlock); AssertRC(rc2);
+
+#ifdef VBOX_GUESTDRV_WITH_RELEASE_LOGGER
+ RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
+ RTLogDestroy(RTLogSetDefaultInstance(NULL));
+#endif
return rc; /* (failed) */
}
@@ -925,6 +992,12 @@ void VBoxGuestDeleteDevExt(PVBOXGUESTDEVEXT pDevExt)
pDevExt->IOPortBase = 0;
pDevExt->pIrqAckEvents = NULL;
+
+#ifdef VBOX_GUESTDRV_WITH_RELEASE_LOGGER
+ RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
+ RTLogDestroy(RTLogSetDefaultInstance(NULL));
+#endif
+
}
@@ -987,7 +1060,7 @@ int VBoxGuestCreateKernelSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION *pp
return VINF_SUCCESS;
}
-
+static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession);
/**
* Closes a VBoxGuest session.
@@ -1001,6 +1074,10 @@ void VBoxGuestCloseSession(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession)
Log(("VBoxGuestCloseSession: pSession=%p proc=%RTproc (%d) r0proc=%p\n",
pSession, pSession->Process, (int)pSession->Process, (uintptr_t)pSession->R0Process)); /** @todo %RTr0proc */
+ VBoxGuestCommonGuestCapsAcquire(pDevExt, pSession, 0, UINT32_MAX, VBOXGUESTCAPSACQUIRE_FLAGS_NONE);
+
+ VBoxGuestCommonIOCtl_CancelAllWaitEvents(pDevExt, pSession);
+
#ifdef VBOX_WITH_HGCM
for (i = 0; i < RT_ELEMENTS(pSession->aHGCMClientIds); i++)
if (pSession->aHGCMClientIds[i])
@@ -1291,13 +1368,12 @@ int VBoxGuestCommonIOCtl_SetMouseNotifyCallback(PVBOXGUESTDEVEXT pDevExt, VBoxGu
*
* @returns VINF_SUCCESS if we've left the spinlock and can return immediately.
*/
-DECLINLINE(int) WaitEventCheckCondition(PVBOXGUESTDEVEXT pDevExt, VBoxGuestWaitEventInfo *pInfo,
+DECLINLINE(int) WaitEventCheckCondition(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestWaitEventInfo *pInfo,
int iEvent, const uint32_t fReqEvents)
{
- uint32_t fMatches = pDevExt->f32PendingEvents & fReqEvents;
+ uint32_t fMatches = VBoxGuestCommonGetAndCleanPendingEventsLocked(pDevExt, pSession, fReqEvents);
if (fMatches)
{
- ASMAtomicAndU32(&pDevExt->f32PendingEvents, ~fMatches);
RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
pInfo->u32EventFlagsOut = fMatches;
@@ -1333,7 +1409,7 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
iEvent = ASMBitFirstSetU32(fReqEvents) - 1;
if (RT_UNLIKELY(iEvent < 0))
{
- Log(("VBoxGuestCommonIOCtl: WAITEVENT: Invalid input mask %#x!!\n", fReqEvents));
+ LogRel(("VBoxGuestCommonIOCtl: WAITEVENT: Invalid input mask %#x!!\n", fReqEvents));
return VERR_INVALID_PARAMETER;
}
@@ -1341,7 +1417,7 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
* Check the condition up front, before doing the wait-for-event allocations.
*/
RTSpinlockAcquire(pDevExt->EventSpinlock);
- rc = WaitEventCheckCondition(pDevExt, pInfo, iEvent, fReqEvents);
+ rc = WaitEventCheckCondition(pDevExt, pSession, pInfo, iEvent, fReqEvents);
if (rc == VINF_SUCCESS)
return rc;
@@ -1364,7 +1440,7 @@ static int VBoxGuestCommonIOCtl_WaitEvent(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSE
*/
RTSpinlockAcquire(pDevExt->EventSpinlock);
RTListAppend(&pDevExt->WaitList, &pWait->ListNode);
- rc = WaitEventCheckCondition(pDevExt, pInfo, iEvent, fReqEvents);
+ rc = WaitEventCheckCondition(pDevExt, pSession, pInfo, iEvent, fReqEvents);
if (rc == VINF_SUCCESS)
{
VBoxGuestWaitFreeUnlocked(pDevExt, pWait);
@@ -1465,6 +1541,7 @@ static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PV
}
RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
Assert(rc == 0);
+ NOREF(rc);
#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
VBoxGuestWaitDoWakeUps(pDevExt);
@@ -1481,7 +1558,7 @@ static int VBoxGuestCommonIOCtl_CancelAllWaitEvents(PVBOXGUESTDEVEXT pDevExt, PV
* @param enmType The request type.
* @param pReqHdr The request.
*/
-static int VBoxGuestCheckIfVMMReqAllowed(PVBOXGUESTSESSION pSession, VMMDevRequestType enmType,
+static int VBoxGuestCheckIfVMMReqAllowed(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VMMDevRequestType enmType,
VMMDevRequestHeader const *pReqHdr)
{
/*
@@ -1541,12 +1618,34 @@ static int VBoxGuestCheckIfVMMReqAllowed(PVBOXGUESTSESSION pSession, VMMDevReque
case VMMDevReq_GetPageSharingStatus:
case VMMDevReq_DebugIsPageShared:
case VMMDevReq_ReportGuestStats:
+ case VMMDevReq_ReportGuestUserState:
case VMMDevReq_GetStatisticsChangeRequest:
case VMMDevReq_ChangeMemBalloon:
enmRequired = kLevel_TrustedUsers;
break;
/*
+ * Anyone. But not for CapsAcquire mode
+ */
+ case VMMDevReq_SetGuestCapabilities:
+ {
+ VMMDevReqGuestCapabilities2 *pCaps = (VMMDevReqGuestCapabilities2*)pReqHdr;
+ uint32_t fAcquireCaps = 0;
+ if (!VBoxGuestCommonGuestCapsModeSet(pDevExt, pCaps->u32OrMask, false, &fAcquireCaps))
+ {
+ AssertFailed();
+ LogRel(("calling caps set for acquired caps %d\n", pCaps->u32OrMask));
+ enmRequired = kLevel_NoOne;
+ break;
+ }
+ /* hack to adjust the notcaps.
+ * @todo: move to a better place
+ * user-mode apps are allowed to pass any mask to the notmask,
+ * the driver cleans up them accordingly */
+ pCaps->u32NotMask &= ~fAcquireCaps;
+ /* do not break, make it fall through to the below enmRequired setting */
+ }
+ /*
* Anyone.
*/
case VMMDevReq_GetMouseStatus:
@@ -1563,11 +1662,11 @@ static int VBoxGuestCheckIfVMMReqAllowed(PVBOXGUESTSESSION pSession, VMMDevReque
case VMMDevReq_VideoModeSupported:
case VMMDevReq_GetHeightReduction:
case VMMDevReq_GetDisplayChangeRequest2:
- case VMMDevReq_SetGuestCapabilities:
case VMMDevReq_VideoModeSupported2:
case VMMDevReq_VideoAccelEnable:
case VMMDevReq_VideoAccelFlush:
case VMMDevReq_VideoSetVisibleRegion:
+ case VMMDevReq_GetDisplayChangeRequestEx:
case VMMDevReq_GetSeamlessChangeRequest:
case VMMDevReq_GetVRDPChangeRequest:
case VMMDevReq_LogString:
@@ -1641,13 +1740,13 @@ static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
if (cbReq < cbMinSize)
{
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid hdr size %#x, expected >= %#x; type=%#x!!\n",
+ LogRel(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid hdr size %#x, expected >= %#x; type=%#x!!\n",
cbReq, cbMinSize, enmType));
return VERR_INVALID_PARAMETER;
}
if (cbReq > cbData)
{
- Log(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid size %#x, expected >= %#x (hdr); type=%#x!!\n",
+ LogRel(("VBoxGuestCommonIOCtl: VMMREQUEST: invalid size %#x, expected >= %#x (hdr); type=%#x!!\n",
cbData, cbReq, enmType));
return VERR_INVALID_PARAMETER;
}
@@ -1659,7 +1758,7 @@ static int VBoxGuestCommonIOCtl_VMMRequest(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTS
return rc;
}
- rc = VBoxGuestCheckIfVMMReqAllowed(pSession, enmType, pReqHdr);
+ rc = VBoxGuestCheckIfVMMReqAllowed(pDevExt, pSession, enmType, pReqHdr);
if (RT_FAILURE(rc))
{
Log(("VBoxGuestCommonIOCtl: VMMREQUEST: Operation not allowed! type=%#x rc=%Rrc\n", enmType, rc));
@@ -1974,7 +2073,7 @@ static int VBoxGuestCommonIOCtl_HGCMCall(PVBOXGUESTDEVEXT pDevExt,
if (cbData < cbActual)
{
LogRel(("VBoxGuestCommonIOCtl: HGCM_CALL: cbData=%#zx (%zu) required size is %#zx (%zu)\n",
- cbData, cbActual));
+ cbData, cbData, cbActual, cbActual));
return VERR_INVALID_PARAMETER;
}
@@ -2283,6 +2382,9 @@ static int VBoxGuestCommonIOCtl_SetMouseStatus(PVBOXGUESTDEVEXT pDevExt, PVBOXGU
RTSpinlockAcquire(pDevExt->SessionSpinlock);
+ /* For all the bits which the guest is allowed to set, check whether the
+ * requested value is different to the current one and adjust the global
+ * usage counter and if appropriate the global state if so. */
for (i = 0; i < sizeof(fFeatures) * 8; i++)
{
if (RT_BIT_32(i) & VMMDEV_MOUSE_GUEST_MASK)
@@ -2417,6 +2519,170 @@ static int VBoxGuestCommonIOCtl_Log(PVBOXGUESTDEVEXT pDevExt, const char *pch, s
return VINF_SUCCESS;
}
+static bool VBoxGuestCommonGuestCapsValidateValues(uint32_t fCaps)
+{
+ if (fCaps & (~(VMMDEV_GUEST_SUPPORTS_SEAMLESS | VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING | VMMDEV_GUEST_SUPPORTS_GRAPHICS)))
+ return false;
+
+ return true;
+}
+
+static void VBoxGuestCommonCheckEvents(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fGenFakeEvents)
+{
+ RTSpinlockAcquire(pDevExt->EventSpinlock);
+ uint32_t fEvents = fGenFakeEvents | pDevExt->f32PendingEvents;
+ PVBOXGUESTWAIT pWait;
+ PVBOXGUESTWAIT pSafe;
+
+ RTListForEachSafe(&pDevExt->WaitList, pWait, pSafe, VBOXGUESTWAIT, ListNode)
+ {
+ uint32_t fHandledEvents = VBoxGuestCommonGetHandledEventsLocked(pDevExt, pWait->pSession);
+ if ( (pWait->fReqEvents & fEvents & fHandledEvents)
+ && !pWait->fResEvents)
+ {
+ pWait->fResEvents = pWait->fReqEvents & fEvents & fHandledEvents;
+ Assert(!(fGenFakeEvents & pWait->fResEvents) || pSession == pWait->pSession);
+ fEvents &= ~pWait->fResEvents;
+ RTListNodeRemove(&pWait->ListNode);
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+ RTListAppend(&pDevExt->WakeUpList, &pWait->ListNode);
+#else
+ RTListAppend(&pDevExt->WokenUpList, &pWait->ListNode);
+ int rc = RTSemEventMultiSignal(pWait->Event);
+ AssertRC(rc);
+#endif
+ if (!fEvents)
+ break;
+ }
+ }
+ ASMAtomicWriteU32(&pDevExt->f32PendingEvents, fEvents);
+
+ RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
+
+#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
+ VBoxGuestWaitDoWakeUps(pDevExt);
+#endif
+}
+
+static int VBoxGuestCommonGuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, uint32_t fOrMask, uint32_t fNotMask, VBOXGUESTCAPSACQUIRE_FLAGS enmFlags)
+{
+ uint32_t fSetCaps = 0;
+
+ if (!VBoxGuestCommonGuestCapsValidateValues(fOrMask))
+ {
+ LogRel(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- invalid fOrMask\n",
+ pSession, fOrMask, fNotMask, enmFlags));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if ( enmFlags != VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE
+ && enmFlags != VBOXGUESTCAPSACQUIRE_FLAGS_NONE)
+ {
+ LogRel(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- invalid enmFlags %d\n",
+ pSession, fOrMask, fNotMask, enmFlags));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ if (!VBoxGuestCommonGuestCapsModeSet(pDevExt, fOrMask, true, &fSetCaps))
+ {
+ LogRel(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- calling caps acquire for set caps\n",
+ pSession, fOrMask, fNotMask, enmFlags));
+ return VERR_INVALID_STATE;
+ }
+
+ if (enmFlags & VBOXGUESTCAPSACQUIRE_FLAGS_CONFIG_ACQUIRE_MODE)
+ {
+ Log(("VBoxGuestCommonGuestCapsAcquire: pSession(0x%p), OR(0x%x), NOT(0x%x), flags(0x%x) -- configured acquire caps: 0x%x\n",
+ pSession, fOrMask, fNotMask, enmFlags));
+ return VINF_SUCCESS;
+ }
+
+ /* the fNotMask no need to have all values valid,
+ * invalid ones will simply be ignored */
+ uint32_t fCurrentOwnedCaps;
+ uint32_t fSessionNotCaps;
+ uint32_t fSessionOrCaps;
+ uint32_t fOtherConflictingCaps;
+
+ fNotMask &= ~fOrMask;
+
+ RTSpinlockAcquire(pDevExt->EventSpinlock);
+
+ fCurrentOwnedCaps = pSession->u32AquiredGuestCaps;
+ fSessionNotCaps = fCurrentOwnedCaps & fNotMask;
+ fSessionOrCaps = fOrMask & ~fCurrentOwnedCaps;
+ fOtherConflictingCaps = pDevExt->u32GuestCaps & ~fCurrentOwnedCaps;
+ fOtherConflictingCaps &= fSessionOrCaps;
+
+ if (!fOtherConflictingCaps)
+ {
+ if (fSessionOrCaps)
+ {
+ pSession->u32AquiredGuestCaps |= fSessionOrCaps;
+ pDevExt->u32GuestCaps |= fSessionOrCaps;
+ }
+
+ if (fSessionNotCaps)
+ {
+ pSession->u32AquiredGuestCaps &= ~fSessionNotCaps;
+ pDevExt->u32GuestCaps &= ~fSessionNotCaps;
+ }
+ }
+
+ RTSpinlockReleaseNoInts(pDevExt->EventSpinlock);
+
+ if (fOtherConflictingCaps)
+ {
+ Log(("VBoxGuest: Caps 0x%x were busy\n", fOtherConflictingCaps));
+ return VERR_RESOURCE_BUSY;
+ }
+
+ /* now do host notification outside the lock */
+ if (!fSessionOrCaps && !fSessionNotCaps)
+ {
+ /* no changes, return */
+ return VINF_SUCCESS;
+ }
+
+ int rc = VBoxGuestSetGuestCapabilities(fSessionOrCaps, fSessionNotCaps);
+ if (RT_FAILURE(rc))
+ {
+ LogRel(("VBoxGuestCommonGuestCapsAcquire: VBoxGuestSetGuestCapabilities failed, rc=%Rrc\n", rc));
+
+ /* Failure branch
+ * this is generally bad since e.g. failure to release the caps may result in other sessions not being able to use it
+ * so we are not trying to restore the caps back to their values before the VBoxGuestCommonGuestCapsAcquire call,
+ * but just pretend everithing is OK.
+ * @todo: better failure handling mechanism? */
+ }
+
+ /* success! */
+ uint32_t fGenFakeEvents = 0;
+
+ if (fSessionOrCaps & VMMDEV_GUEST_SUPPORTS_SEAMLESS)
+ {
+ /* generate the seamless change event so that the r3 app could synch with the seamless state
+ * although this introduces a false alarming of r3 client, it still solve the problem of
+ * client state inconsistency in multiuser environment */
+ fGenFakeEvents |= VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST;
+ }
+
+ /* since the acquire filter mask has changed, we need to process events in any way to ensure they go from pending events field
+ * to the proper (un-filtered) entries */
+ VBoxGuestCommonCheckEvents(pDevExt, pSession, fGenFakeEvents);
+
+ return VINF_SUCCESS;
+}
+
+static int VBoxGuestCommonIOCTL_GuestCapsAcquire(PVBOXGUESTDEVEXT pDevExt, PVBOXGUESTSESSION pSession, VBoxGuestCapsAquire *pAcquire)
+{
+ int rc = VBoxGuestCommonGuestCapsAcquire(pDevExt, pSession, pAcquire->u32OrMask, pAcquire->u32NotMask, pAcquire->enmFlags);
+ if (RT_FAILURE(rc))
+ LogRel(("VBoxGuestCommonGuestCapsAcquire: failed rc=%Rrc\n", rc));
+ pAcquire->rc = rc;
+ return VINF_SUCCESS;
+}
+
/**
* Common IOCtl for user to kernel and kernel to kernel communication.
@@ -2477,7 +2743,7 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
if (cbData != (cb)) \
{ \
LogFunc((mnemonic ": cbData=%#zx (%zu) expected is %#zx (%zu)\n", \
- cbData, cbData, (size_t)(cb), (size_t)(cb))); \
+ cbData, cbData, (size_t)(cb), (size_t)(cb))); \
return VERR_BUFFER_OVERFLOW; \
} \
if ((cb) != 0 && !VALID_PTR(pvData)) \
@@ -2497,12 +2763,6 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
CHECKRET_MIN_SIZE("VMMREQUEST", sizeof(VMMDevRequestHeader));
rc = VBoxGuestCommonIOCtl_VMMRequest(pDevExt, pSession, (VMMDevRequestHeader *)pvData, cbData, pcbDataReturned);
}
-#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
- else if (VBOXGUEST_IOCTL_STRIP_SIZE(iFunction) == VBOXGUEST_IOCTL_STRIP_SIZE(VBOXGUEST_IOCTL_DPC))
- {
- rc = VBoxGuestCommonIOCtl_DPC(pDevExt, pSession, pvData, cbData, pcbDataReturned);
- }
-#endif /* VBOX_WITH_DPC_LATENCY_CHECKER */
#ifdef VBOX_WITH_HGCM
/*
* These ones are a bit tricky.
@@ -2640,10 +2900,23 @@ int VBoxGuestCommonIOCtl(unsigned iFunction, PVBOXGUESTDEVEXT pDevExt, PVBOXGUES
*(uint32_t *)pvData);
break;
+#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
+ case VBOXGUEST_IOCTL_DPC_LATENCY_CHECKER:
+ CHECKRET_SIZE("DPC_LATENCY_CHECKER", 0);
+ rc = VbgdNtIOCtl_DpcLatencyChecker();
+ break;
+#endif
+
+ case VBOXGUEST_IOCTL_GUEST_CAPS_ACQUIRE:
+ CHECKRET_SIZE("GUEST_CAPS_ACQUIRE", sizeof(VBoxGuestCapsAquire));
+ rc = VBoxGuestCommonIOCTL_GuestCapsAcquire(pDevExt, pSession, (VBoxGuestCapsAquire*)pvData);
+ *pcbDataReturned = sizeof(VBoxGuestCapsAquire);
+ break;
+
default:
{
- LogRel(("VBoxGuestCommonIOCtl: Unknown request iFunction=%#x Stripped size=%#x\n", iFunction,
- VBOXGUEST_IOCTL_STRIP_SIZE(iFunction)));
+ LogRel(("VBoxGuestCommonIOCtl: Unknown request iFunction=%#x stripped size=%#x\n",
+ iFunction, VBOXGUEST_IOCTL_STRIP_SIZE(iFunction)));
rc = VERR_NOT_SUPPORTED;
break;
}
@@ -2704,7 +2977,7 @@ bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
PVBOXGUESTWAIT pWait;
PVBOXGUESTWAIT pSafe;
- Log(("VBoxGuestCommonISR: acknowledge events succeeded %#RX32\n", fEvents));
+ Log3(("VBoxGuestCommonISR: acknowledge events succeeded %#RX32\n", fEvents));
/*
* VMMDEV_EVENT_MOUSE_POSITION_CHANGED can only be polled for.
@@ -2748,10 +3021,11 @@ bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
fEvents |= pDevExt->f32PendingEvents;
RTListForEachSafe(&pDevExt->WaitList, pWait, pSafe, VBOXGUESTWAIT, ListNode)
{
- if ( (pWait->fReqEvents & fEvents)
+ uint32_t fHandledEvents = VBoxGuestCommonGetHandledEventsLocked(pDevExt, pWait->pSession);
+ if ( (pWait->fReqEvents & fEvents & fHandledEvents)
&& !pWait->fResEvents)
{
- pWait->fResEvents = pWait->fReqEvents & fEvents;
+ pWait->fResEvents = pWait->fReqEvents & fEvents & fHandledEvents;
fEvents &= ~pWait->fResEvents;
RTListNodeRemove(&pWait->ListNode);
#ifdef VBOXGUEST_USE_DEFERRED_WAKE_UP
@@ -2800,6 +3074,7 @@ bool VBoxGuestCommonISR(PVBOXGUESTDEVEXT pDevExt)
ASMAtomicDecU32(&pDevExt->cISR);
Assert(rc == 0);
+ NOREF(rc);
return fOurIrq;
}
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm b/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm
index bb8757f1..008dd625 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestA-os2.asm
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
+; Copyright (C) 2007-2013 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -20,7 +20,7 @@
;
; VBoxDrv - OS/2 assembly file, the first file in the link.
;
-; Copyright (c) 2007 knut st. osmundsen <bird-src-spam@anduin.net>
+; Copyright (c) 2007-2010 knut st. osmundsen <bird-src-spam@anduin.net>
;
; Permission is hereby granted, free of charge, to any person
; obtaining a copy of this software and associated documentation
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h
index 87ad299b..de0a5125 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestIDC-unix.c.h
@@ -1,4 +1,4 @@
-/* $Rev: 78530 $ */
+/* $Rev: 84795 $ */
/** @file
* VBoxGuest - Inter Driver Communication, unix implementation.
*
@@ -6,7 +6,7 @@
*/
/*
- * Copyright (C) 2006-2012 Oracle Corporation
+ * Copyright (C) 2006-2013 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -28,9 +28,12 @@
/** @todo Use some header that we have in common with VBoxGuestLib.h... */
-DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version);
-DECLVBGL(int) VBoxGuestIDCClose(void *pvSession);
-DECLVBGL(int) VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
+/** @todo fix DECLVBGL usage. */
+RT_C_DECLS_BEGIN
+DECLEXPORT(void *) VBOXCALL VBoxGuestIDCOpen(uint32_t *pu32Version);
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCClose(void *pvSession);
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned);
+RT_C_DECLS_END
/**
@@ -39,7 +42,7 @@ DECLVBGL(int) VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, siz
* @returns Opaque pointer to session object.
* @param pu32Version Where to store VMMDev version.
*/
-DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version)
+DECLEXPORT(void *) VBOXCALL VBoxGuestIDCOpen(uint32_t *pu32Version)
{
PVBOXGUESTSESSION pSession;
int rc;
@@ -96,7 +99,7 @@ DECLVBGL(void *) VBoxGuestIDCOpen(uint32_t *pu32Version)
* @returns VBox error code.
* @param pvState Opaque pointer to the session object.
*/
-DECLVBGL(int) VBoxGuestIDCClose(void *pvSession)
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCClose(void *pvSession)
{
PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
LogFlow(("VBoxGuestIDCClose:\n"));
@@ -131,7 +134,7 @@ DECLVBGL(int) VBoxGuestIDCClose(void *pvSession)
* @param cbData Size of the data buffer.
* @param pcbDataReturned Where to store the amount of returned data.
*/
-DECLVBGL(int) VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
+DECLEXPORT(int) VBOXCALL VBoxGuestIDCCall(void *pvSession, unsigned iCmd, void *pvData, size_t cbData, size_t *pcbDataReturned)
{
PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)pvSession;
LogFlow(("VBoxGuestIDCCall: %pvSession=%p Cmd=%u pvData=%p cbData=%d\n", pvSession, iCmd, pvData, cbData));
diff --git a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
index 5a15aeee..e91b7678 100644
--- a/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
+++ b/src/VBox/Additions/common/VBoxGuest/VBoxGuestInternal.h
@@ -107,7 +107,6 @@ typedef struct VBOXGUESTMEMBALLOON
/** Pointer to a memory balloon. */
typedef VBOXGUESTMEMBALLOON *PVBOXGUESTMEMBALLOON;
-
/**
* VBox guest device (data) extension.
*/
@@ -180,17 +179,12 @@ typedef struct VBOXGUESTDEVEXT
uint32_t volatile cISR;
/** Callback and user data for a kernel mouse handler. */
VBoxGuestMouseSetNotifyCallback MouseNotifyCallback;
-
- /** Windows part. */
- union
- {
-#ifdef ___VBoxGuest_win_h
- VBOXGUESTDEVEXTWIN s;
-#else
- uint32_t dummy;
-#endif
- } win;
-
+ /* list of caps used in acquire mode */
+ uint32_t u32AcquireModeGuestCaps;
+ /* list of caps used in set mode */
+ uint32_t u32SetModeGuestCaps;
+ /* currently acquired (and reported) guest caps */
+ uint32_t u32GuestCaps;
} VBOXGUESTDEVEXT;
/** Pointer to the VBoxGuest driver data. */
typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT;
@@ -205,7 +199,7 @@ typedef VBOXGUESTDEVEXT *PVBOXGUESTDEVEXT;
*/
typedef struct VBOXGUESTSESSION
{
-#if defined(RT_OS_OS2) || defined(RT_OS_FREEBSD) || defined(RT_OS_SOLARIS)
+#if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_OS2) || defined(RT_OS_SOLARIS)
/** Pointer to the next session with the same hash. */
PVBOXGUESTSESSION pNextHash;
#endif
@@ -234,7 +228,14 @@ typedef struct VBOXGUESTSESSION
/** Mouse features supported. A feature enabled in any guest session will
* be enabled for the host. */
uint32_t volatile fMouseStatus;
-
+#ifdef RT_OS_DARWIN
+ /** Pointer to the associated org_virtualbox_VBoxGuestClient object. */
+ void *pvVBoxGuestClient;
+ /** Whether this session has been opened or not. */
+ bool fOpened;
+#endif
+ /* Guest Caps Acquired & Reported by this session */
+ uint32_t u32AquiredGuestCaps;
} VBOXGUESTSESSION;
RT_C_DECLS_BEGIN
@@ -274,6 +275,11 @@ DECLVBGL(int) VBoxGuestNativeServiceCall(void *pvOpaque, unsigned int iCmd, v
*/
void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt);
+
+#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
+int VbgdNtIOCtl_DpcLatencyChecker(void);
+#endif
+
RT_C_DECLS_END
#endif
diff --git a/src/VBox/Additions/common/VBoxGuest/darwin/Info.plist b/src/VBox/Additions/common/VBoxGuest/darwin/Info.plist
new file mode 100644
index 00000000..30cd22b9
--- /dev/null
+++ b/src/VBox/Additions/common/VBoxGuest/darwin/Info.plist
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key> <string>English</string>
+ <key>CFBundleExecutable</key> <string>VBoxGuest</string>
+ <key>CFBundleIdentifier</key> <string>org.virtualbox.kext.VBoxGuest</string>
+ <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string>
+ <key>CFBundleName</key> <string>VBoxGuest</string>
+ <key>CFBundlePackageType</key> <string>KEXT</string>
+ <key>CFBundleSignature</key> <string>????</string>
+ <key>NSHumanReadableCopyright</key> <string>Copyright © 2007-@VBOX_C_YEAR@ @VBOX_VENDOR@</string>
+ <key>CFBundleGetInfoString</key> <string>@VBOX_PRODUCT@ @VBOX_VERSION_STRING@, © 2007-@VBOX_C_YEAR@ @VBOX_VENDOR@</string>
+ <key>CFBundleVersion</key> <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
+ <key>CFBundleShortVersionString</key> <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
+ <key>OSBundleCompatibleVersion</key> <string>@VBOX_VERSION_MAJOR@.@VBOX_VERSION_MINOR@.@VBOX_VERSION_BUILD@</string>
+ <key>IOKitPersonalities</key>
+ <dict>
+ <key>VBoxGuest</key>
+ <dict>
+ <key>CFBundleIdentifier</key> <string>org.virtualbox.kext.VBoxGuest</string>
+ <key>IOClass</key> <string>org_virtualbox_VBoxGuest</string>
+ <key>IOMatchCategory</key> <string>org_virtualbox_VBoxGuest</string>
+ <key>IOUserClientClass</key> <string>org_virtualbox_VBoxGuestClient</string>
+ <key>IOKitDebug</key> <integer>65535</integer>
+ <key>IOProviderClass</key> <string>IOPCIDevice</string>
+ <key>IONameMatch</key> <string>pci80ee,cafe</string>
+ </dict>
+ </dict>
+ <key>OSBundleLibraries</key>
+ <dict>
+ <key>com.apple.iokit.IOPCIFamily</key> <string>2.5</string> <!-- TODO: Figure the version in mac os x 10.4. -->
+ <key>com.apple.kpi.bsd</key> <string>8.0.0</string>
+ <key>com.apple.kpi.mach</key> <string>8.0.0</string>
+ <key>com.apple.kpi.libkern</key> <string>8.0.0</string>
+ <key>com.apple.kpi.unsupported</key> <string>8.0.0</string>
+ <key>com.apple.kpi.iokit</key> <string>8.0.0</string>
+ </dict>
+ <key>OSBundleLibraries_x86_64</key>
+ <dict>
+ <key>com.apple.iokit.IOPCIFamily</key> <string>2.6</string>
+ <key>com.apple.kpi.bsd</key> <string>10.0.0d4</string>
+ <key>com.apple.kpi.mach</key> <string>10.0.0d3</string>
+ <key>com.apple.kpi.libkern</key> <string>10.0.0d3</string>
+ <key>com.apple.kpi.iokit</key> <string>10.0.0d3</string>
+ <key>com.apple.kpi.unsupported</key> <string>10.0.0d3</string>
+ </dict>
+</dict>
+</plist>
+
diff --git a/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile b/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
index c0326547..a25cc9f2 100644
--- a/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
+++ b/src/VBox/Additions/common/VBoxGuest/freebsd/Makefile
@@ -4,7 +4,7 @@
#
#
-# Copyright (C) 2006-2009 Oracle Corporation
+# Copyright (C) 2006-2012 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/VBoxGuest/linux/Makefile b/src/VBox/Additions/common/VBoxGuest/linux/Makefile
index 5b03a9a1..09f8bbc1 100644
--- a/src/VBox/Additions/common/VBoxGuest/linux/Makefile
+++ b/src/VBox/Additions/common/VBoxGuest/linux/Makefile
@@ -1,10 +1,10 @@
-# $Revision: 79403 $
+# $Revision: 83575 $
## @file
# VirtualBox Guest Additions Module Makefile.
#
#
-# Copyright (C) 2006-2011 Oracle Corporation
+# Copyright (C) 2006-2012 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest b/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
index f733baa0..f9f8a9d7 100755
--- a/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
+++ b/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest
@@ -5,7 +5,7 @@
#
#
-# Copyright (C) 2007-2010 Oracle Corporation
+# Copyright (C) 2007-2012 Oracle Corporation
#
# This file is part of VirtualBox Open Source Edition (OSE), as
# available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf
index 09b56d39..04932fca 100644
--- a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf
+++ b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuest.inf
@@ -1,7 +1,10 @@
+; $Id: VBoxGuest.inf $
+;; @file
+; INF file for installing the VirtualBox Windows guest driver.
;
-; INF file for installing the VirtualBox Windows guest driver
+
;
-; Copyright (C) 2006-2011 Oracle Corporation
+; Copyright (C) 2006-2013 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
diff --git a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestInst.cpp b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestInst.cpp
index eb9a7b69..3f76ef9d 100644
--- a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestInst.cpp
+++ b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestInst.cpp
@@ -1,8 +1,10 @@
+/* $Id: VBoxGuestInst.cpp $ */
/** @file
- *
- * Small tool to (un)install the VBoxGuest device driver
- *
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Small tool to (un)install the VBoxGuest device driver.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
@@ -30,7 +32,7 @@
-int installDriver(void)
+static int installDriver(void)
{
/*
* Assume it didn't exist, so we'll create the service.
@@ -57,17 +59,14 @@ int installDriver(void)
"System",
NULL, NULL, NULL, NULL);
if (!hService)
- {
printf("CreateService failed! lasterr=%d\n", GetLastError());
- } else
- {
+ else
CloseServiceHandle(hService);
- }
CloseServiceHandle(hSMgrCreate);
return hService ? 0 : -1;
}
-int uninstallDriver(void)
+static int uninstallDriver(void)
{
int rc = -1;
SC_HANDLE hSMgr = OpenSCManager(NULL, NULL, SERVICE_CHANGE_CONFIG);
@@ -96,8 +95,9 @@ int uninstallDriver(void)
return rc;
}
+#ifdef TESTMODE
-HANDLE openDriver(void)
+static HANDLE openDriver(void)
{
HANDLE hDevice;
@@ -115,43 +115,32 @@ HANDLE openDriver(void)
return hDevice;
}
-int closeDriver(HANDLE hDevice)
+static int closeDriver(HANDLE hDevice)
{
CloseHandle(hDevice);
return 0;
}
-#ifdef TESTMODE
-typedef struct TESTFOO
-{
- int values[16];
-} TESTFOO, *PTESTFOO;
-
-int performTest(void)
+static int performTest(void)
{
int rc = 0;
HANDLE hDevice = openDriver();
if (hDevice != INVALID_HANDLE_VALUE)
- {
- DWORD cbReturned;
-
closeDriver(hDevice);
- } else
- {
+ else
printf("openDriver failed!\n");
- }
-
return rc;
}
-#endif
-void displayHelpAndExit(char *programName)
+#endif /* TESTMODE */
+
+static int usage(char *programName)
{
printf("error, syntax: %s [install|uninstall]\n", programName);
- exit(1);
+ return 1;
}
int main(int argc, char **argv)
@@ -162,50 +151,36 @@ int main(int argc, char **argv)
#endif
if (argc != 2)
- {
- displayHelpAndExit(argv[0]);
- }
+ return usage(argv[0]);
+
if (strcmp(argv[1], "install") == 0)
- {
installMode = true;
- } else
- if (strcmp(argv[1], "uninstall") == 0)
- {
+ else if (strcmp(argv[1], "uninstall") == 0)
installMode = false;
- } else
#ifdef TESTMODE
- if (strcmp(argv[1], "test") == 0)
- {
+ else if (strcmp(argv[1], "test") == 0)
testMode = true;
- } else
#endif
- {
- displayHelpAndExit(argv[0]);
- }
+ else
+ return usage(argv[0]);
- int rc;
+ int rc;
#ifdef TESTMODE
if (testMode)
- {
rc = performTest();
- } else
+ else
#endif
if (installMode)
- {
rc = installDriver();
- } else
- {
+ else
rc = uninstallDriver();
- }
if (rc == 0)
- {
printf("operation completed successfully!\n");
- } else
- {
+ else
printf("error: operation failed with status code %d\n", rc);
- }
return rc;
}
+
diff --git a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestMsg.mc b/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestMsg.mc
deleted file mode 100644
index 65a14b5f..00000000
--- a/src/VBox/Additions/common/VBoxGuest/win/VBoxGuestMsg.mc
+++ /dev/null
@@ -1,60 +0,0 @@
-;
-; VBoxGuest Device Driver Messages
-;
-; Copyright (C) 2006-2007 Oracle Corporation
-;
-; This file is part of VirtualBox Open Source Edition (OSE), as
-; available from http://www.virtualbox.org. This file is free software;
-; you can redistribute it and/or modify it under the terms of the GNU
-; General Public License (GPL) as published by the Free Software
-; Foundation, in version 2 as it comes in the "COPYING" file of the
-; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
-; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
-;
-
-
-;//
-;// Status values are 32 bit values arranged as follows:
-;//
-;// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
-;// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
-;// +---+-+-------------------------+-------------------------------+
-;// |Sev|C| Facility | Code |
-;// +---+-+-------------------------+-------------------------------+
-;//
-;// where
-;//
-;// Sev - is the severity code
-;//
-;// 00 - Success
-;// 01 - Informational
-;// 10 - Warning
-;// 11 - Error
-;//
-;// C - is the Customer code flag
-;//
-;// Facility - is the facility code
-;//
-;// Code - is the facility's status code
-;//
-;
-MessageIdTypedef=NTSTATUS
-
-SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
- Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
- Warning=0x2:STATUS_SEVERITY_WARNING
- Error=0x3:STATUS_SEVERITY_ERROR
- )
-
-FacilityNames=(System=0x0
- RpcRuntime=0x2:FACILITY_RPC_RUNTIME
- RpcStubs=0x3:FACILITY_RPC_STUBS
- Io=0x4:FACILITY_IO_ERROR_CODE
- VBoxGuestClass=0xee:FACILITY_VBOXGUESTCLASS_ERROR_CODE
- )
-
-
-MessageId=0x0001 Facility=VBoxGuestClass Severity=Informational SymbolicName=VBOXGUESTCLASS_FOO
-Language=English
-VBoxGuest has something to say %1.
-.