Index: /trunk/Config.kmk
===================================================================
--- /trunk/Config.kmk	(revision 43362)
+++ /trunk/Config.kmk	(revision 43363)
@@ -252,4 +252,6 @@
 else ifeq ($(KBUILD_TARGET),os2)
   VBOX_PACKAGE_OS = OS2
+else ifeq ($(KBUILD_TARGET),haiku)
+  VBOX_PACKAGE_OS = HAIKU
 else if1of ($(KBUILD_TARGET), dragonfly freebsd netbsd openbsd)
   VBOX_PACKAGE_OS = BSD
@@ -686,4 +688,6 @@
  else ifeq ($(KBUILD_TARGET),freebsd)
   VBOX_PATH_APP_PRIVATE      = /usr/local/lib/virtualbox
+ else ifeq ($(KBUILD_TARGET),haiku)
+  VBOX_PATH_APP_PRIVATE      = /boot/apps/VirtualBox
  endif
 endif
@@ -846,4 +850,30 @@
  VBOX_WITH_DOCS=
 endif
+
+ifeq ($(KBUILD_TARGET),haiku)
+ # Don't bother with SDL ttf for now.
+ VBOX_WITH_SECURELABEL=
+ # We'll use the native html/help viewer.
+ VBOX_WITH_KCHMVIEWER=
+ VBOX_WITH_VRDP_RDESKTOP=
+ # Permanent (no working SDL).
+ VBOX_WITH_VBOXSDL=
+ VBOX_WITH_VBOXBFE=
+ VBOX_WITH_DOCS=
+ VBOX_WITH_VBOXDRV=
+ VBOX_WITH_VRDP=
+ VBOX_WITH_HEADLESS=
+ VBOX_WITH_VBOXSDL=
+ VBOX_WITH_QTGUI=
+# VBOX_WITH_MAIN=
+ VBOX_WITH_DOCS=
+ VBOX_WITH_ISCSI=
+ VBOX_WITH_INIP=
+ VBOX_WITH_INTERNAL_NETWORKING=
+ VBOX_WITH_PDM_ASYNC_COMPLETION=
+ VBOX_WITH_KCHMVIEWER=
+ VBOX_WITH_HARDENING=
+endif
+
 
 ifeq ($(KBUILD_TARGET),l4)
@@ -1159,5 +1189,5 @@
 # Image and object format config.
 #
-if1of ($(KBUILD_TARGET), freebsd linux l4 netbsd openbsd solaris)
+if1of ($(KBUILD_TARGET), freebsd haiku linux l4 netbsd openbsd solaris)
  VBOX_LDR_FMT = elf
 endif
@@ -1284,4 +1314,7 @@
  else ifeq ($(KBUILD_TARGET),darwin)
   VBOX_GCC_TOOL := GXX4MACHO
+ else ifeq ($(KBUILD_TARGET),haiku)
+  # Haiku shouldn't pass '-r' to the linker by default
+  VBOX_GCC_TOOL := GXX3PLAIN
  else ifeq ($(KBUILD_TARGET),solaris)
   VBOX_GCC_TOOL := GXX3PLAIN
@@ -1400,4 +1433,5 @@
 DEFS.darwin  = RT_OS_DARWIN __DARWIN__
 DEFS.freebsd = RT_OS_FREEBSD __FREEBSD__
+DEFS.haiku   = RT_OS_HAIKU
 DEFS.l4      = RT_OS_L4 __L4__ __L4ENV__ L4API_l4v2 ARCH_$(KBUILD_TARGET_ARCH) __NO_CTYPE _FILE_OFFSET_BITS=64
 DEFS.linux   = RT_OS_LINUX _FILE_OFFSET_BITS=64
@@ -1598,4 +1632,7 @@
  export LD_LIBRARY_PATH:=$(PATH_STAGE_BIN):$(PATH_STAGE_LIB):$(LD_LIBRARY_PATH)
 endif
+ifeq ($(KBUILD_HOST),haiku)
+ export LIBRARY_PATH:=$(PATH_STAGE_BIN):$(PATH_STAGE_LIB):$(LIBRARY_PATH)
+endif
 ifeq ($(KBUILD_HOST),os2)
  #fixme! export BEGINLIBPATH:=$(PATH_STAGE_BIN);$(PATH_STAGE_LIB);$(BEGINLIBPATH)
@@ -1628,5 +1665,5 @@
  LIB_DDU         = $(PATH_STAGE_BIN)/VBoxDDU.s.so
 endif
-if1of ($(KBUILD_TARGET), freebsd linux netbsd openbsd solaris)
+if1of ($(KBUILD_TARGET), freebsd haiku linux netbsd openbsd solaris)
  LIB_RUNTIME     = $(PATH_STAGE_BIN)/VBoxRT.so
  LIB_RUNTIME_EF  = $(PATH_STAGE_LIB)/RuntimeEFCPP.a
@@ -1738,4 +1775,6 @@
 else ifeq ($(KBUILD_HOST),os2)
  VBOX_XSLTPROC  ?= BEGINLIBPATH="$(PATH_DEVTOOLS_BLD)/bin;$$BEGINLIBPATH" $(PATH_DEVTOOLS_BLD)/bin/xsltproc.exe
+else ifeq ($(KBUILD_HOST),haiku)
+ VBOX_XSLTPROC ?= $(PATH_DEVTOOLS)/haiku.x86/bin/xsltproc
 else
  VBOX_XSLTPROC  ?= xsltproc$(HOSTSUFF_EXE)
@@ -2196,5 +2235,5 @@
 # Some versions of gcc (e.g. openSUSE11) return only major.minor on `gcc -dumpversion`.
 VBOX_GCC_VERSION = $(shell \
-  $(1) -dumpversion | $(SED_EXT) 's|\([0-9]\)\.\([0-9]\)\.\{0,1\}\([0-9]\{0,1\}\)|$$(int-add $$(int-mul 10000, \1), $$(int-mul 100, \2), $$(firstword \3 0))|' )
+  $(1) -dumpversion | $(SED_EXT) 's|\([0-9]\)\.\([0-9]\)\.\{0,1\}\([0-9]\{0,1\}\).*|$$(int-add $$(int-mul 10000, \1), $$(int-mul 100, \2), $$(firstword \3 0))|' )
 endif
 
@@ -2248,5 +2287,5 @@
 	$(QUIET)$(APPEND) '$@' 'endif'
 endif
-ifneq ($(KBUILD_TARGET),l4)
+ifn1of ($(KBUILD_TARGET),haiku l4)
 # Set default attribute for inline functions to ``hidden'' to reduce the number
 # of relocation entries and PLT indirections in shared libraries. Don't allow for gcc version < 4.
@@ -2578,4 +2617,33 @@
 endif
 
+
+#
+# Haiku resource and version generation.
+#
+ifeq ($(KBUILD_HOST),haiku)
+ VBOX_HAIKU_RCTOOL := rc
+ VBOX_HAIKU_XRESTOOL := xres
+ VBOX_HAIKU_SETVERSIONTOOL := setversion
+ # XXX: install won't preserve attributes...
+ VBOX_HAIKU_MIMESETTOOL := mimeset
+
+  ## Add optional resources to the program, set its version info, and sniff its mime properties.
+  # @param 1  The file to add resources to.
+  # @param 2  The resource files.
+  # @param 3  The target name.
+define VBOX_HAIKU_XRES_SETVER_FN
+	$(if $(2),$(call MSG_TOOL,HaikuAddResources,$(3),$(2))
+	$(QUIET)$(VBOX_HAIKU_XRESTOOL) -o $(1) $(2),)
+	$(call MSG_TOOL,HaikuSetVersion,$(3))
+	$(QUIET)$(VBOX_HAIKU_SETVERSIONTOOL) $(1) \
+		-app $(VBOX_VERSION_MAJOR) $(VBOX_VERSION_MINOR) $(VBOX_VERSION_BUILD) d $(VBOX_SVN_REV) \
+		-short "$(VBOX_PRODUCT)" \
+		-long "$(VBOX_PRODUCT) $(VBOX_VERSION_STRING) $(shell /bin/echo -e '\xC2\xA9')2009-$(VBOX_C_YEAR) $(VBOX_VENDOR)"
+	$(call MSG_TOOL,HaikuMimeSet,$(3))
+	$(QUIET)$(VBOX_HAIKU_MIMESETTOOL) -f $(1)
+endef
+
+ VBOX_HAIKU_XRES_SETVER_CMDS  ?= $(if $(eq $(tool_do),LINK_PROGRAM),$(call VBOX_HAIKU_XRES_SETVER_FN,$(out),$($(target)_RSRCS),$(target)),)
+endif
 
 #
@@ -3297,4 +3365,30 @@
 
 endif # FreeBSD
+
+ifeq ($(KBUILD_TARGET),haiku)
+## The Haiku include directories
+VBOX_HAIKU_SYS_INCS ?= /boot/develop/headers/os/kernel /boot/develop/headers/os/drivers
+
+TEMPLATE_VBOXR0DRV_TOOL                = $(VBOX_GCC_TOOL)
+TEMPLATE_VBOXR0DRV_LDTOOL              = $(VBOX_GCC_TOOL)
+TEMPLATE_VBOXR0DRV_DEFS                = _KERNEL_MODE=1 _STRICT_STDC IN_RING0 IN_RT_R0
+TEMPLATE_VBOXR0DRV_INCS                = $(VBOX_HAIKU_SYS_INCS)
+#TODO: sort this out
+TEMPLATE_VBOXR0DRV_LDFLAGS             = -shared -no-undefined -dc -dy -nostdlib -rpath-link /boot/develop/lib/x86 --no-add-needed /boot/develop/lib/x86/_KERNEL_ --no-add-needed /boot/develop/lib/x86/haiku_version_glue.o
+TEMPLATE_VBOXR0DRV_CFLAGS              = -no-fpic \
+	$(VBOX_GCC_WARN) -Wstrict-prototypes $(VBOX_GCC_Wno-pointer-sign) -Wno-sign-compare \
+	$(VBOX_GCC_fno-stack-protector) $(VBOX_GCC_R0_OPT) $(VBOX_GCC_R0_FP) -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration
+TEMPLATE_VBOXR0DRV_CFLAGS.x86          = -mno-sse -mno-mmx -mno-sse2 -mno-3dnow
+TEMPLATE_VBOXR0DRV_CFLAGS.x86          = -m32 -mno-sse -mno-mmx -mno-sse2 -mno-3dnow
+TEMPLATE_VBOXR0DRV_CFLAGS.amd64        = -m64 -mno-sse -mno-mmx -mno-sse2 -mno-3dnow \
+	-fno-reorder-blocks -ffreestanding -fno-asynchronous-unwind-tables -funit-at-a-time \
+	-Wno-sign-compare -Wdeclaration-after-statement
+TEMPLATE_VBOXR0DRV_CXXFLAGS           = -no-fpic -Wpointer-arith \
+	-Wshadow -Wuninitialized -Wunused-function -Wunused-label -Wunused-value -Wunused-variable \
+	-Wformat \
+	-O2 -nodefaultlibs -fno-omit-frame-pointer -fno-strict-aliasing -fno-common -fno-exceptions -fno-rtti
+TEMPLATE_VBOXR0DRV_CXXFLAGS.x86       = $(TEMPLATE_VBOXR0DRV_CFLAGS.x86) -fno-exceptions -fno-rtti
+TEMPLATE_VBOXR0DRV_CXXFLAGS.amd64     = $(TEMPLATE_VBOXR0DRV_CFLAGS.amd64) -fno-exceptions -fno-rtti
+endif # Haiku
 
 ifdef VBOX_WITH_VBOXDRV
@@ -3460,4 +3554,14 @@
    TEMPLATE_VBOXR3EXE_CXXFLAGS := $(filter-out -pedantic,$(TEMPLATE_VBOXR3EXE_CXXFLAGS)) -fdollars-in-identifiers # annoying gcc option precedence.
   endif
+ else ifeq ($(KBUILD_TARGET),haiku)
+TEMPLATE_VBOXR3EXE_TOOL                = GXX3
+TEMPLATE_VBOXR3EXE_POST_CMDS          = $(VBOX_HAIKU_XRES_SETVER_CMDS)
+TEMPLATE_VBOXR3EXE_LIBS                = network iconv stdc++ supc++
+TEMPLATE_VBOXR3EXE_LIBPATH            += \
+	/boot/common/lib
+# Haiku uses PIC by default...
+TEMPLATE_VBOXR3EXE_CFLAGS             += -fno-pic
+TEMPLATE_VBOXR3EXE_CXXFLAGS           += -fno-pic
+TEMPLATE_VBOXR3EXE_LDFLAGS            += -fno-pic
  else if1of ($(KBUILD_TARGET), freebsd netbsd openbsd)
 TEMPLATE_VBOXR3EXE_TOOL                = GXX3
@@ -3508,4 +3612,10 @@
  TEMPLATE_VBOXR3_CXXFLAGS              = $(TEMPLATE_VBOXR3EXE_CXXFLAGS) -fPIC
  TEMPLATE_VBOXR3_LDFLAGS               = $(TEMPLATE_VBOXR3EXE_LDFLAGS) -fPIC
+endif
+ifeq ($(KBUILD_TARGET),haiku)
+ # Haiku uses PIC by default...
+ TEMPLATE_VBOXR3_CFLAGS               = $(TEMPLATE_VBOXR3EXE_CFLAGS) -fno-pic
+ TEMPLATE_VBOXR3_CXXFLAGS             = $(TEMPLATE_VBOXR3EXE_CXXFLAGS) -fno-pic
+ TEMPLATE_VBOXR3_LDFLAGS              = $(TEMPLATE_VBOXR3EXE_LDFLAGS) -fno-pic
 endif
 
@@ -3949,4 +4059,7 @@
 TEMPLATE_VBOXMAINEXE_LDFLAGS            += $(VBOX_DARWIN_DEF_SDK_LDFLAGS) -framework Carbon
 TEMPLATE_VBOXMAINEXE_LIBS                = $(LIB_RUNTIME)
+ else ifeq ($(KBUILD_TARGET),haiku)
+TEMPLATE_VBOXMAINEXE_TOOL                = GXX3
+TEMPLATE_VBOXMAINEXE_LIBS                = $(LIB_RUNTIME) network stdc++ supc++
  else if1of ($(KBUILD_TARGET), freebsd netbsd openbsd)
 TEMPLATE_VBOXMAINEXE_TOOL                = GXX3
@@ -4011,5 +4124,5 @@
 TEMPLATE_VBOXMAINDLL  = VBox Main Component (shared library)
 TEMPLATE_VBOXMAINDLL_EXTENDS = VBOXMAINEXE
-ifn1of ($(KBUILD_TARGET), darwin os2 win)
+ifn1of ($(KBUILD_TARGET), darwin haiku os2 win)
  TEMPLATE_VBOXMAINDLL_DEFS     = PIC $(TEMPLATE_VBOXMAINEXE_DEFS)
  TEMPLATE_VBOXMAINDLL_CFLAGS   = -fPIC $(TEMPLATE_VBOXMAINEXE_CFLAGS)
@@ -4549,4 +4662,9 @@
   endif
 TEMPLATE_VBOXBLDPROG_LIBS                =
+ else ifeq ($(KBUILD_HOST),haiku)
+TEMPLATE_VBOXBLDPROG_TOOL                = GXX3
+TEMPLATE_VBOXBLDPROG_LIBS                = network iconv
+TEMPLATE_VBOXBLDPROG_LIBPATH            += \
+	/boot/common/lib
  else if1of ($(KBUILD_HOST), freebsd netbsd openbsd)
 TEMPLATE_VBOXBLDPROG_TOOL                = GXX3
@@ -4889,5 +5007,5 @@
 	$(PATH_SDK_$(VBOX_WINDDK)_LIB)/int64.lib
 TEMPLATE_VBOXGUESTR0_DEFS        = $(TEMPLATE_VBOXR0DRV_DEFS) IN_GUEST IN_GUEST_R0
-ifeq ($(KBUILD_TARGET),solaris) # No VBI for the guest additions yet.
+ifeq ($(KBUILD_TARGET),solaris)
  TEMPLATE_VBOXGUESTR0_LDFLAGS    = -r -dy
 endif
@@ -4905,4 +5023,7 @@
 TEMPLATE_VBOXGUESTR0LIB_INSTTYPE.linux = stage
 TEMPLATE_VBOXGUESTR0LIB_INST     = $(INST_ADDITIONS_LIB)
+ifeq ($(KBUILD_TARGET),haiku)
+ TEMPLATE_VBOXGUESTR0LIB_LDFLAGS = -r -dy
+endif
 
 #
Index: /trunk/configure
===================================================================
--- /trunk/configure	(revision 43362)
+++ /trunk/configure	(revision 43363)
@@ -54,4 +54,6 @@
   sunos)
     OS='solaris'
+    ;;
+  haiku)
     ;;
   *)
@@ -333,5 +335,5 @@
   [ "$OS" = "solaris" ] && BUILD_CPU=`isainfo | cut -f 1 -d ' '`
   case "$BUILD_CPU" in
-    i[3456789]86|x86|i86pc)
+    i[3456789]86|x86|i86pc|BePC)
       BUILD_MACHINE='x86'
       LIB='lib'
@@ -650,4 +652,7 @@
 check_xsltproc()
 {
+  if [ -n "$BUILD_LIBXSLT" ]; then
+      return 0;
+  fi
   test_header xslt
   if check_avail "$XSLTPROC" XSLTPROC; then
@@ -897,5 +902,5 @@
   if test_compile "$LIBZ $I_INCZ" zlib zlib; then
     if test_execute; then
-      echo "if1of (\$(KBUILD_TARGET),darwin freebsd linux solaris)" >> $CNF
+      echo "if1of (\$(KBUILD_TARGET),darwin freebsd haiku linux solaris)" >> $CNF
       cnf_append " SDK_VBOX_ZLIB_LIBS" "`strip_l "$LIBZ"`"
       cnf_append " SDK_VBOX_ZLIB_INCS" "$INCZ"
@@ -2246,4 +2251,21 @@
   BUILD_LIBXML2=1
   [ $OSE -eq 1 ] || BUILD_LIBCURL=1
+elif [ "$OS" = "haiku" ]; then
+  #WITH_SDL=0
+  WITH_SDL_TTF=0
+  WITH_X11=0
+  WITH_ALSA=0
+  WITH_PULSE=0
+  WITH_DBUS=0
+  WITH_KMODS=0
+  WITH_LIBIDL=0
+  WITH_XPCOM=0
+  BUILD_LIBXSLT=1
+  BUILD_LIBXML2=1
+  # it is part of libroot, which is linked by default,
+  # but the script wants something
+  LIBPTHREAD="-lroot"
+  #[ $OSE -eq 1] || BUILD_LIBCURL=1
+  [ $OSE -eq 1] || BUILD_LIBSSL=1
 fi
 
Index: /trunk/include/VBox/VBoxGuest.h
===================================================================
--- /trunk/include/VBox/VBoxGuest.h	(revision 43362)
+++ /trunk/include/VBox/VBoxGuest.h	(revision 43363)
@@ -6,5 +6,5 @@
 
 /*
- * Copyright (C) 2006-2009 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -62,4 +62,7 @@
 # define VBOXGUEST_DEVICE_NAME_DOS      L"\\DosDevices\\VBoxGuest"
 
+#elif defined(RT_OS_HAIKU)
+# define VBOXGUEST_DEVICE_NAME          "/dev/misc/vboxguest"
+
 #else /* (PORTME) */
 # define VBOXGUEST_DEVICE_NAME          "/dev/vboxguest"
@@ -175,4 +178,11 @@
 # define VBOXGUEST_IOCTL_CODE_FAST_(Function)       _IO(  'V', (Function))
 # define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           VBOXGUEST_IOCTL_CODE_(_IOC_NR((Code)), 0)
+
+#elif defined(RT_OS_HAIKU)
+  /* No automatic buffering, size not encoded. */
+  /** @todo do something better */
+# define VBOXGUEST_IOCTL_CODE_(Function, Size)      (0x56420000 | (Function))
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function)       (0x56420000 | (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code)           (Code)
 
 #elif defined(RT_OS_FREEBSD) /** @todo r=bird: Please do it like SUPDRVIOC to keep it as similar as possible. */
Index: /trunk/include/VBox/ostypes.h
===================================================================
--- /trunk/include/VBox/ostypes.h	(revision 43362)
+++ /trunk/include/VBox/ostypes.h	(revision 43363)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -117,4 +117,6 @@
     VBOXOSTYPE_MacOS_x64        = 0xB0100,
     VBOXOSTYPE_JRockitVE        = 0xC0000,
+    VBOXOSTYPE_Haiku            = 0xD0000,
+    VBOXOSTYPE_Haiku_x64        = 0xD0100,
 /** The bit number which indicates 64-bit or 32-bit. */
 #define VBOXOSTYPE_x64_BIT       8
Index: /trunk/include/iprt/assert.h
===================================================================
--- /trunk/include/iprt/assert.h	(revision 43362)
+++ /trunk/include/iprt/assert.h	(revision 43363)
@@ -505,5 +505,5 @@
  */
 #if defined(IN_RING0) \
- && (defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS))
+ && (defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU) || defined(RT_OS_SOLARIS))
 # define RTAssertDoPanic()      RTR0AssertPanicSystem()
 #else
Index: /trunk/include/iprt/thread.h
===================================================================
--- /trunk/include/iprt/thread.h	(revision 43362)
+++ /trunk/include/iprt/thread.h	(revision 43363)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -534,4 +534,8 @@
     uint8_t         bReserved3;
 #   define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 255, 0, 0, 0 }
+#  elif defined(RT_OS_HAIKU)
+    /** The cpu_state. Don't touch! */
+    uint32_t        uOldCpuState;
+#   define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 }
 #  elif defined(RT_OS_SOLARIS)
     /** The Old PIL. Don't touch! */
Index: /trunk/include/iprt/types.h
===================================================================
--- /trunk/include/iprt/types.h	(revision 43362)
+++ /trunk/include/iprt/types.h	(revision 43363)
@@ -4,5 +4,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -206,5 +206,5 @@
 #   endif
 #  else
-#   if defined(RT_OS_DARWIN) && defined(_STDBOOL_H)
+#   if (defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU)) && defined(_STDBOOL_H)
 #    undef bool
 #   endif
Index: /trunk/src/VBox/Additions/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/Makefile.kmk	(revision 43362)
+++ /trunk/src/VBox/Additions/Makefile.kmk	(revision 43363)
@@ -70,4 +70,7 @@
  ifeq ($(KBUILD_TARGET),darwin)
   include $(PATH_SUB_CURRENT)/darwin/Makefile.kmk
+ endif
+ ifeq ($(KBUILD_TARGET),haiku)
+  include $(PATH_SUB_CURRENT)/haiku/Makefile.kmk
  endif
 
@@ -286,4 +289,11 @@
 endif # win.x86
 
+ifdef VBOX_WITH_ADDITIONS_ISO.haiku.x86
+ VBOX_PATH_ADDITIONS.haiku.x86 = $(PATH_OUT_BASE)/haiku.x86/$(KBUILD_TYPE)/bin/additions
+ # or bfs?
+ GUESTADDITIONS_FILESPEC.haiku.x86 = \
+	VBoxHaikuAdditions-x86.run=$(VBOX_PATH_ADDITIONS.haiku.x86)/VBoxHaikuAdditions-x86.run
+endif
+
 
 #
@@ -303,4 +313,5 @@
 				$(GUESTADDITIONS_FILESPEC.freebsd.x86) \
 				$(GUESTADDITIONS_FILESPEC.freebsd.amd64) \
+				$(GUESTADDITIONS_FILESPEC.haiku.x86) \
 				$(GUESTADDITIONS_FILESPEC.darwin.x86) \
 				$(GUESTADDITIONS_FILESPEC.darwin.amd64) \
@@ -325,4 +336,5 @@
 		$(GUESTADDITIONS_FILESPEC.freebsd.x86) \
 		$(GUESTADDITIONS_FILESPEC.freebsd.amd64) \
+		$(GUESTADDITIONS_FILESPEC.haiku.x86) \
 		$(GUESTADDITIONS_FILESPEC.darwin.x86) \
 		$(GUESTADDITIONS_FILESPEC.darwin.amd64)
Index: /trunk/src/VBox/Additions/common/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/common/Makefile.kmk	(revision 43362)
+++ /trunk/src/VBox/Additions/common/Makefile.kmk	(revision 43363)
@@ -23,8 +23,8 @@
  include $(PATH_SUB_CURRENT)/VBoxGuestLib/Makefile.kmk
  include $(PATH_SUB_CURRENT)/VBoxControl/Makefile.kmk
- if1of ($(KBUILD_TARGET), freebsd linux os2 solaris win)
+ if1of ($(KBUILD_TARGET), freebsd haiku linux os2 solaris win)
   include $(PATH_SUB_CURRENT)/VBoxGuest/Makefile.kmk
  endif
- if1of ($(KBUILD_TARGET), freebsd linux os2 solaris win)
+ if1of ($(KBUILD_TARGET), freebsd haiku linux os2 solaris win)
   include $(PATH_SUB_CURRENT)/VBoxService/Makefile.kmk
  endif
Index: /trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 43362)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 43363)
@@ -20,5 +20,5 @@
 
 
-if1of ($(KBUILD_TARGET), freebsd $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
+if1of ($(KBUILD_TARGET), freebsd haiku $(if $(defined VBOX_WITH_ADDITION_DRIVERS),linux,) os2 solaris win)
  #
  # VBoxGuest - The Guest Additions Driver.
@@ -27,4 +27,5 @@
  VBoxGuest_TEMPLATE      = VBOXGUESTR0
  VBoxGuest_NAME.freebsd  = vboxguest
+ VBoxGuest_NAME.haiku    = vboxguest
  VBoxGuest_NAME.linux    = vboxguest
  VBoxGuest_NAME.solaris  = vboxguest
@@ -33,4 +34,5 @@
   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)
@@ -50,4 +52,5 @@
  VBoxGuest_DEPS.linux   += $(VBOX_SVN_REV_HEADER)
  VBoxGuest_DEPS.freebsd += $(VBOX_SVN_REV_HEADER)
+ VBoxGuest_DEPS.haiku   += $(VBOX_SVN_REV_HEADER)
  VBoxGuest_DEFS          = VBGL_VBOXGUEST VBOX_WITH_HGCM
  VBoxGuest_INCS          = .
@@ -75,5 +78,5 @@
    endif
   endif # win
-  ifn1of ($(KBUILD_TARGET), linux freebsd solaris)
+  ifn1of ($(KBUILD_TARGET), linux freebsd solaris haiku)
    VBoxGuest_SOURCES    = VBoxGuest-$(KBUILD_TARGET).cpp
   else
@@ -95,4 +98,14 @@
   	$(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.
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c	(revision 43363)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c	(revision 43363)
@@ -0,0 +1,355 @@
+/* $Id$ */
+/** @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\t%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);
+}
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.c	(revision 43363)
@@ -0,0 +1,538 @@
+/* $Id$ */
+/** @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.
+ */
+
+#define IN_VBOXGUEST
+#define LOG_GROUP LOG_GROUP_SUP_DRV
+//#undef LOG_DISABLED
+//#define LOG_ENABLED
+//#define LOG_ENABLE_FLOW
+//#define DO_LOG
+#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);
+
+    return fOurIRQ ? B_HANDLED_INTERRUPT : 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 status;
+    struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
+
+    status = install_io_interrupt_handler(pState->iIrqResId, VBoxGuestHaikuISR, pState,  0);
+
+    if (status != B_OK)
+    {
+        return VERR_DEV_IO_ERROR;
+    }
+
+    return VINF_SUCCESS;
+}
+
+/**
+ * Removes IRQ for VMMDev.
+ *
+ * @param   pvState  Opaque pointer to the state info structure.
+ */
+static void VBoxGuestHaikuRemoveIRQ(void *pvState)
+{
+    struct VBoxGuestDeviceState *pState = (struct VBoxGuestDeviceState *)pvState;
+
+    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;
+
+    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
+    Log((MODULE_NAME ": plip!\n"));
+    LogAlways((MODULE_NAME ": plop!\n"));
+
+
+    /*
+     * Allocate I/O port resource.
+     */
+    pState->uIOPortBase = pDevice->u.h0.base_registers[0];
+    //XXX check flags for IO ?
+    if (pState->uIOPortBase)
+    {
+        /*
+         * Map the MMIO region.
+         */
+        uint32 phys = pDevice->u.h0.base_registers[1];
+        //XXX 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))
+                {
+                    dprintf(MODULE_NAME ": loaded successfully\n");
+                    return 0;
+                }
+                else
+                    dprintf((MODULE_NAME ":VBoxGuestInitDevExt failed.\n"));
+                VBoxGuestDeleteDevExt(&g_DevExt);
+            }
+            else
+                dprintf((MODULE_NAME ":VBoxGuestHaikuAddIRQ failed.\n"));
+        }
+        else
+            dprintf((MODULE_NAME ":MMIO region setup failed.\n"));
+    }
+    else
+        dprintf((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 0;
+
+    return ENXIO;
+}
+
+status_t init_module(void)
+{
+    status_t status = B_ENTRY_NOT_FOUND;
+    pci_info info;
+    int ix = 0;
+
+    if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI))
+        return ENOSYS;
+
+    while ((*gPCI->get_nth_pci_info)(ix++, &info) == B_OK) {
+        if (VBoxGuestHaikuProbe(&info) == 0) {
+            // we found it
+            status = VBoxGuestHaikuAttach(&info);
+            break;
+        }
+    }
+
+    return status;
+}
+
+void uninit_module(void)
+{
+    VBoxGuestHaikuDetach();
+
+    put_module(B_PCI_MODULE_NAME);
+}
+
+static status_t std_ops(int32 op, ...) {
+    switch(op) {
+    case B_MODULE_INIT:
+        dprintf(MODULE_NAME ": B_MODULE_INIT\n");
+        return init_module();
+    case B_MODULE_UNINIT:
+        dprintf(MODULE_NAME ": B_MODULE_UNINIT\n");
+        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"
Index: /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.h
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.h	(revision 43363)
+++ /trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku.h	(revision 43363)
@@ -0,0 +1,224 @@
+/* $Id$ */
+/** @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
Index: /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp	(revision 43362)
+++ /trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3Lib.cpp	(revision 43363)
@@ -38,4 +38,5 @@
 
 #elif defined(RT_OS_FREEBSD) \
+   || defined(RT_OS_HAIKU) \
    || defined(RT_OS_LINUX) \
    || defined(RT_OS_SOLARIS)
@@ -198,5 +199,5 @@
 #else
 
-    /* The default implementation. (linux, solaris, freebsd) */
+    /* The default implementation. (linux, solaris, freebsd, haiku) */
     RTFILE File;
     int rc = RTFileOpen(&File, pszDeviceName, RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
@@ -381,4 +382,19 @@
     return rc;
 
+#elif defined(RT_OS_HAIKU)
+	/* The ioctl hook in Haiku does take the len parameter when specified,
+	 * so just use it.
+	 */
+    int rc = ioctl((int)g_File, iFunction, pvData, cbData);
+    if (RT_LIKELY(rc == 0))
+        return VINF_SUCCESS;
+
+    /* Positive values are negated VBox error status codes. */
+    if (rc > 0)
+        rc = -rc;
+    else
+        rc = RTErrConvertFromErrno(errno);
+    return rc;
+
 #elif defined(VBOX_VBGLR3_XFREE86)
     /* PORTME - This is preferred over the RTFileIOCtl variant below, just be careful with the (int). */
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp	(revision 43362)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceTimeSync.cpp	(revision 43363)
@@ -411,5 +411,5 @@
         VBoxServiceError("VBoxServiceTimeSyncAdjust: GetSystemTimeAdjustment failed, error=%ld\n", GetLastError());
 
-#elif defined(RT_OS_OS2)
+#elif defined(RT_OS_OS2) || defined(RT_OS_HAIKU)
     /* No API for doing gradual time adjustments. */
 
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp	(revision 43362)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceVMInfo.cpp	(revision 43363)
@@ -40,8 +40,6 @@
 # include <net/if.h>
 # include <unistd.h>
-# ifndef RT_OS_OS2
-#  ifndef RT_OS_FREEBSD
-#   include <utmpx.h> /* @todo FreeBSD 9 should have this. */
-#  endif
+# if !defined(RT_OS_OS2) && !defined(RT_OS_FREEBSD) && !defined(RT_OS_HAIKU)
+#  include <utmpx.h> /* @todo FreeBSD 9 should have this. */
 # endif
 # ifdef RT_OS_SOLARIS
@@ -266,4 +264,8 @@
     rc = VERR_NOT_IMPLEMENTED;
 
+#elif defined(RT_OS_HAIKU)
+    /** @todo Haiku: Port logged on user info retrieval. */
+    rc = VERR_NOT_IMPLEMENTED;
+
 #elif defined(RT_OS_OS2)
     /** @todo OS/2: Port logged on (LAN/local/whatever) user info retrieval. */
@@ -519,4 +521,8 @@
     if (sd >= 0)
         closesocket(sd);
+
+#elif defined(RT_OS_HAIKU)
+    /** @todo Haiku: implement network info. retreival */
+    return VERR_NOT_IMPLEMENTED;
 
 #elif defined(RT_OS_FREEBSD)
Index: /trunk/src/VBox/Additions/haiku/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/haiku/Makefile.kmk	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/Makefile.kmk	(revision 43363)
@@ -0,0 +1,63 @@
+# $Id$
+## @file
+# Sub-Makefile for Haiku Guest Additions.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../..
+include	$(KBUILD_PATH)/subheader.kmk
+
+ifneq ($(KBUILD_HOST),haiku)
+$(error "The Haiku guest additions installer can only be built on Haiku!")
+endif
+
+#
+# Include sub-makefiles.
+#
+include $(PATH_SUB_CURRENT)/SharedFolders/Makefile.kmk
+include $(PATH_SUB_CURRENT)/VBoxMouse/Makefile.kmk
+include $(PATH_SUB_CURRENT)/VBoxTray/Makefile.kmk
+include $(PATH_SUB_CURRENT)/VBoxVideo/Makefile.kmk
+
+include $(KBUILD_PATH)/subfooter.kmk
+
Index: /trunk/src/VBox/Additions/haiku/SharedFolders/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/haiku/SharedFolders/Makefile.kmk	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/SharedFolders/Makefile.kmk	(revision 43363)
@@ -0,0 +1,80 @@
+# $Id$
+## @file
+# Sub-Makefile for shared folders, Haiku Guest Additions.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../../..
+include	$(KBUILD_PATH)/subheader.kmk
+
+ifdef VBOX_WITH_ADDITION_DRIVERS
+ SYSMODS += vboxsf
+endif
+
+#
+# Populate FILES_VBOXSF_NOBIN
+#
+#include $(PATH_SUB_CURRENT)/files_vboxsf
+
+#
+# The module (for syntax checking).
+# The DEBUG_HASH* stuff is for CONFIG_DYNAMIC_DEBUG-enabled kernels
+#
+vboxsf_TEMPLATE        = VBOXGUESTR0
+vboxsf_DEFS            = \
+	MODULE IN_RT_R0 VBOXGUEST VBOX_WITH_HGCM \
+	KBUILD_MODNAME=KBUILD_STR\(vboxsf\) \
+        KBUILD_BASENAME=KBUILD_STR\(vboxsf\)
+vboxsf_INCS            = \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxGuestLib \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest \
+	$(PATH_ROOT)/src/VBox/Runtime/r0drv/haiku
+vboxsf_SOURCES         = \
+	vboxsf.c \
+	vnode_cache.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c
+vboxsf_LIBS            = \
+	$(VBOX_LIB_VBGL_R0)
+
+include	$(KBUILD_PATH)/subfooter.kmk
+
Index: /trunk/src/VBox/Additions/haiku/SharedFolders/OpenHashTable.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/SharedFolders/OpenHashTable.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/SharedFolders/OpenHashTable.h	(revision 43363)
@@ -0,0 +1,477 @@
+/* $Id$ */
+/** @file
+ * OpenHashTable, Haiku Guest Additions.
+ */
+
+/*
+ * 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 2007, Hugo Santos. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
+#ifndef _KERNEL_UTIL_OPEN_HASH_TABLE_H
+#define _KERNEL_UTIL_OPEN_HASH_TABLE_H
+
+
+#include <OS.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef _KERNEL_MODE
+#	include <KernelExport.h>
+#	include "kernel_cpp.h"
+#endif
+
+/*!
+	The Definition template must have four methods: `HashKey', `Hash',
+	`Compare' and `GetLink;. It must also define several types as shown in the
+	following example:
+
+	struct Foo {
+		int bar;
+
+		Foo* fNext;
+	};
+
+	struct HashTableDefinition {
+		typedef int		KeyType;
+		typedef	Foo		ValueType;
+
+		size_t HashKey(int key) const
+		{
+			return key >> 1;
+		}
+
+		size_t Hash(Foo* value) const
+		{
+			return HashKey(value->bar);
+		}
+
+		bool Compare(int key, Foo* value) const
+		{
+			return value->bar == key;
+		}
+
+		Foo*& GetLink(Foo* value) const
+		{
+			return value->fNext;
+		}
+	};
+*/
+
+
+struct MallocAllocator {
+	void* Allocate(size_t size) const
+	{
+		return malloc(size);
+	}
+
+	void Free(void* memory) const
+	{
+		free(memory);
+	}
+};
+
+
+template<typename Definition, bool AutoExpand = true,
+	bool CheckDuplicates = false, typename Allocator = MallocAllocator>
+class BOpenHashTable {
+public:
+	typedef BOpenHashTable<Definition, AutoExpand, CheckDuplicates> HashTable;
+	typedef typename Definition::KeyType	KeyType;
+	typedef typename Definition::ValueType	ValueType;
+
+	static const size_t kMinimumSize = 8;
+
+	// All allocations are of power of 2 lengths.
+
+	// regrowth factor: 200 / 256 = 78.125%
+	//                   50 / 256 = 19.53125%
+
+	BOpenHashTable()
+		:
+		fTableSize(0),
+		fItemCount(0),
+		fTable(NULL)
+	{
+	}
+
+	BOpenHashTable(const Definition& definition)
+		:
+		fDefinition(definition),
+		fTableSize(0),
+		fItemCount(0),
+		fTable(NULL)
+	{
+	}
+
+	BOpenHashTable(const Definition& definition, const Allocator& allocator)
+		:
+		fDefinition(definition),
+		fAllocator(allocator),
+		fTableSize(0),
+		fItemCount(0),
+		fTable(NULL)
+	{
+	}
+
+	~BOpenHashTable()
+	{
+		fAllocator.Free(fTable);
+	}
+
+	status_t Init(size_t initialSize = kMinimumSize)
+	{
+		if (initialSize > 0 && !_Resize(initialSize))
+			return B_NO_MEMORY;
+		return B_OK;
+	}
+
+	size_t TableSize() const
+	{
+		return fTableSize;
+	}
+
+	size_t CountElements() const
+	{
+		return fItemCount;
+	}
+
+	ValueType* Lookup(const KeyType& key) const
+	{
+		if (fTableSize == 0)
+			return NULL;
+
+		size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
+		ValueType* slot = fTable[index];
+
+		while (slot) {
+			if (fDefinition.Compare(key, slot))
+				break;
+			slot = _Link(slot);
+		}
+
+		return slot;
+	}
+
+	status_t Insert(ValueType* value)
+	{
+		if (fTableSize == 0) {
+			if (!_Resize(kMinimumSize))
+				return B_NO_MEMORY;
+		} else if (AutoExpand && fItemCount >= (fTableSize * 200 / 256))
+			_Resize(fTableSize * 2);
+
+		InsertUnchecked(value);
+		return B_OK;
+	}
+
+	void InsertUnchecked(ValueType* value)
+	{
+		if (CheckDuplicates && _ExhaustiveSearch(value)) {
+#ifdef _KERNEL_MODE
+			panic("Hash Table: value already in table.");
+#else
+			debugger("Hash Table: value already in table.");
+#endif
+		}
+
+		_Insert(fTable, fTableSize, value);
+		fItemCount++;
+	}
+
+	// TODO: a ValueType* Remove(const KeyType& key) method is missing
+
+	bool Remove(ValueType* value)
+	{
+		if (!RemoveUnchecked(value))
+			return false;
+
+		if (AutoExpand && fTableSize > kMinimumSize
+			&& fItemCount < (fTableSize * 50 / 256))
+			_Resize(fTableSize / 2);
+
+		return true;
+	}
+
+	bool RemoveUnchecked(ValueType* value)
+	{
+		size_t index = fDefinition.Hash(value) & (fTableSize - 1);
+		ValueType* previous = NULL;
+		ValueType* slot = fTable[index];
+
+		while (slot) {
+			ValueType* next = _Link(slot);
+
+			if (value == slot) {
+				if (previous)
+					_Link(previous) = next;
+				else
+					fTable[index] = next;
+				break;
+			}
+
+			previous = slot;
+			slot = next;
+		}
+
+		if (slot == NULL)
+			return false;
+
+		if (CheckDuplicates && _ExhaustiveSearch(value)) {
+#ifdef _KERNEL_MODE
+			panic("Hash Table: duplicate detected.");
+#else
+			debugger("Hash Table: duplicate detected.");
+#endif
+		}
+
+		fItemCount--;
+		return true;
+	}
+
+	/*!	Removes all elements from the hash table. No resizing happens. The
+		elements are not deleted. If \a returnElements is \c true, the method
+		returns all elements chained via their hash table link.
+	*/
+	ValueType* Clear(bool returnElements = false)
+	{
+		if (this->fItemCount == 0)
+			return NULL;
+
+		ValueType* result = NULL;
+
+		if (returnElements) {
+			ValueType** nextPointer = &result;
+
+			// iterate through all buckets
+			for (size_t i = 0; i < fTableSize; i++) {
+				ValueType* element = fTable[i];
+				if (element != NULL) {
+					// add the bucket to the list
+					*nextPointer = element;
+
+					// update nextPointer to point to the fNext of the last
+					// element in the bucket
+					while (element != NULL) {
+						nextPointer = &_Link(element);
+						element = *nextPointer;
+					}
+				}
+			}
+		}
+
+		memset(this->fTable, 0, sizeof(ValueType*) * this->fTableSize);
+
+		return result;
+	}
+
+	/*!	If the table needs resizing, the number of bytes for the required
+		allocation is returned. If no resizing is needed, 0 is returned.
+	*/
+	size_t ResizeNeeded() const
+	{
+		size_t size = fTableSize;
+		if (size == 0 || fItemCount >= (size * 200 / 256)) {
+			// grow table
+			if (size == 0)
+				size = kMinimumSize;
+			while (fItemCount >= size * 200 / 256)
+				size <<= 1;
+		} else if (size > kMinimumSize && fItemCount < size * 50 / 256) {
+			// shrink table
+			while (fItemCount < size * 50 / 256)
+				size >>= 1;
+			if (size < kMinimumSize)
+				size = kMinimumSize;
+		}
+
+		if (size == fTableSize)
+			return 0;
+
+		return size * sizeof(ValueType*);
+	}
+
+	/*!	Resizes the table using the given allocation. The allocation must not
+		be \c NULL. It must be of size \a size, which must a value returned
+		earlier by ResizeNeeded(). If the size requirements have changed in the
+		meantime, the method free()s the given allocation and returns \c false,
+		unless \a force is \c true, in which case the supplied allocation is
+		used in any event.
+		Otherwise \c true is returned.
+		If \a oldTable is non-null and resizing is successful, the old table
+		will not be freed, but will be returned via this parameter instead.
+	*/
+	bool Resize(void* allocation, size_t size, bool force = false,
+		void** oldTable = NULL)
+	{
+		if (!force && size != ResizeNeeded()) {
+			fAllocator.Free(allocation);
+			return false;
+		}
+
+		_Resize((ValueType**)allocation, size / sizeof(ValueType*), oldTable);
+		return true;
+	}
+
+	class Iterator {
+	public:
+		Iterator(const HashTable* table)
+			: fTable(table)
+		{
+			Rewind();
+		}
+
+		Iterator(const HashTable* table, size_t index, ValueType* value)
+			: fTable(table), fIndex(index), fNext(value) {}
+
+		bool HasNext() const { return fNext != NULL; }
+
+		ValueType* Next()
+		{
+			ValueType* current = fNext;
+			_GetNext();
+			return current;
+		}
+
+		void Rewind()
+		{
+			// get the first one
+			fIndex = 0;
+			fNext = NULL;
+			_GetNext();
+		}
+
+	protected:
+		Iterator() {}
+
+		void _GetNext()
+		{
+			if (fNext)
+				fNext = fTable->_Link(fNext);
+
+			while (fNext == NULL && fIndex < fTable->fTableSize)
+				fNext = fTable->fTable[fIndex++];
+		}
+
+		const HashTable* fTable;
+		size_t fIndex;
+		ValueType* fNext;
+	};
+
+	Iterator GetIterator() const
+	{
+		return Iterator(this);
+	}
+
+	Iterator GetIterator(const KeyType& key) const
+	{
+		if (fTableSize == 0)
+			return Iterator(this, fTableSize, NULL);
+
+		size_t index = fDefinition.HashKey(key) & (fTableSize - 1);
+		ValueType* slot = fTable[index];
+
+		while (slot) {
+			if (fDefinition.Compare(key, slot))
+				break;
+			slot = _Link(slot);
+		}
+
+		if (slot == NULL)
+			return Iterator(this, fTableSize, NULL);
+
+		return Iterator(this, index + 1, slot);
+	}
+
+protected:
+	// for g++ 2.95
+	friend class Iterator;
+
+	void _Insert(ValueType** table, size_t tableSize, ValueType* value)
+	{
+		size_t index = fDefinition.Hash(value) & (tableSize - 1);
+
+		_Link(value) = table[index];
+		table[index] = value;
+	}
+
+	bool _Resize(size_t newSize)
+	{
+		ValueType** newTable
+			= (ValueType**)fAllocator.Allocate(sizeof(ValueType*) * newSize);
+		if (newTable == NULL)
+			return false;
+
+		_Resize(newTable, newSize);
+		return true;
+	}
+
+	void _Resize(ValueType** newTable, size_t newSize, void** _oldTable = NULL)
+	{
+		for (size_t i = 0; i < newSize; i++)
+			newTable[i] = NULL;
+
+		if (fTable) {
+			for (size_t i = 0; i < fTableSize; i++) {
+				ValueType* bucket = fTable[i];
+				while (bucket) {
+					ValueType* next = _Link(bucket);
+					_Insert(newTable, newSize, bucket);
+					bucket = next;
+				}
+			}
+
+			if (_oldTable != NULL)
+				*_oldTable = fTable;
+			else
+				fAllocator.Free(fTable);
+		} else if (_oldTable != NULL)
+			*_oldTable = NULL;
+
+		fTableSize = newSize;
+		fTable = newTable;
+	}
+
+	ValueType*& _Link(ValueType* bucket) const
+	{
+		return fDefinition.GetLink(bucket);
+	}
+
+	bool _ExhaustiveSearch(ValueType* value) const
+	{
+		for (size_t i = 0; i < fTableSize; i++) {
+			ValueType* bucket = fTable[i];
+			while (bucket) {
+				if (bucket == value)
+					return true;
+				bucket = _Link(bucket);
+			}
+		}
+
+		return false;
+	}
+
+	Definition		fDefinition;
+	Allocator		fAllocator;
+	size_t			fTableSize;
+	size_t			fItemCount;
+	ValueType**		fTable;
+};
+
+#endif	// _KERNEL_UTIL_OPEN_HASH_TABLE_H
Index: /trunk/src/VBox/Additions/haiku/SharedFolders/kernel_cpp.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/SharedFolders/kernel_cpp.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/SharedFolders/kernel_cpp.h	(revision 43363)
@@ -0,0 +1,109 @@
+/* $Id$ */
+/** @file
+ * Kernel C++, Haiku private.
+ */
+
+/*
+ * 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. C++ in the kernel.
+ *
+ * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
+ * Distributed under the terms of the MIT License.
+ */
+
+#ifndef KERNEL_CPP_H
+#define KERNEL_CPP_H
+
+#ifdef __cplusplus
+
+#include <new>
+#include <stdlib.h>
+
+#if _KERNEL_MODE || _LOADER_MODE
+
+using namespace std;
+extern const nothrow_t std::nothrow;
+
+// We need new() versions we can use when also linking against libgcc.
+// std::nothrow can't be used since it's defined in both libgcc and
+// kernel_cpp.cpp.
+typedef struct {} mynothrow_t;
+extern const mynothrow_t mynothrow;
+
+
+inline void *
+operator new(size_t size) throw (std::bad_alloc)
+{
+	// we don't actually throw any exceptions, but we have to
+	// keep the prototype as specified in <new>, or else GCC 3
+	// won't like us
+	return malloc(size);
+}
+
+
+inline void *
+operator new[](size_t size) throw (std::bad_alloc)
+{
+	return malloc(size);
+}
+
+
+inline void *
+operator new(size_t size, const std::nothrow_t &) throw ()
+{
+	return malloc(size);
+}
+
+
+inline void *
+operator new[](size_t size, const std::nothrow_t &) throw ()
+{
+	return malloc(size);
+}
+
+
+inline void *
+operator new(size_t size, const mynothrow_t &) throw ()
+{
+	return malloc(size);
+}
+
+
+inline void *
+operator new[](size_t size, const mynothrow_t &) throw ()
+{
+	return malloc(size);
+}
+
+
+inline void
+operator delete(void *ptr) throw ()
+{
+	free(ptr);
+}
+
+
+inline void
+operator delete[](void *ptr) throw ()
+{
+	free(ptr);
+}
+
+#endif	// #if _KERNEL_MODE
+
+#endif	// __cplusplus
+
+#endif	/* KERNEL_CPP_H */
Index: /trunk/src/VBox/Additions/haiku/SharedFolders/lock.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/SharedFolders/lock.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/SharedFolders/lock.h	(revision 43363)
@@ -0,0 +1,302 @@
+/* $Id$ */
+/** @file
+ * Lock.h - Haiku, private locking internals.
+ */
+
+/*
+ * 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 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
+ * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
+ * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
+#ifndef _KERNEL_LOCK_H
+#define _KERNEL_LOCK_H
+
+#include <OS.h>
+
+
+struct mutex_waiter;
+
+typedef struct mutex {
+	const char*				name;
+	struct mutex_waiter*	waiters;
+#if KDEBUG
+	thread_id				holder;
+#else
+	int32					count;
+	uint16					ignore_unlock_count;
+#endif
+	uint8					flags;
+} mutex;
+
+#define MUTEX_FLAG_CLONE_NAME	0x1
+
+
+typedef struct recursive_lock {
+	mutex		lock;
+#if !KDEBUG
+	thread_id	holder;
+#endif
+	int			recursion;
+} recursive_lock;
+
+
+struct rw_lock_waiter;
+
+typedef struct rw_lock {
+	const char*				name;
+	struct rw_lock_waiter*	waiters;
+	thread_id				holder;
+	vint32					count;
+	int32					owner_count;
+	int16					active_readers;
+								// Only > 0 while a writer is waiting: number
+								// of active readers when the first waiting
+								// writer started waiting.
+	int16					pending_readers;
+								// Number of readers that have already
+								// incremented "count", but have not yet started
+								// to wait at the time the last writer unlocked.
+	uint32					flags;
+} rw_lock;
+
+#define RW_LOCK_WRITER_COUNT_BASE	0x10000
+
+#define RW_LOCK_FLAG_CLONE_NAME	0x1
+
+
+#if KDEBUG
+#	define KDEBUG_RW_LOCK_DEBUG 0
+		// Define to 1 if you want to use ASSERT_READ_LOCKED_RW_LOCK().
+		// The rw_lock will just behave like a recursive locker then.
+#	define ASSERT_LOCKED_RECURSIVE(r) \
+		{ ASSERT(find_thread(NULL) == (r)->lock.holder); }
+#	define ASSERT_LOCKED_MUTEX(m) { ASSERT(find_thread(NULL) == (m)->holder); }
+#	define ASSERT_WRITE_LOCKED_RW_LOCK(l) \
+		{ ASSERT(find_thread(NULL) == (l)->holder); }
+#	if KDEBUG_RW_LOCK_DEBUG
+#		define ASSERT_READ_LOCKED_RW_LOCK(l) \
+			{ ASSERT(find_thread(NULL) == (l)->holder); }
+#	else
+#		define ASSERT_READ_LOCKED_RW_LOCK(l) do {} while (false)
+#	endif
+#else
+#	define ASSERT_LOCKED_RECURSIVE(r)		do {} while (false)
+#	define ASSERT_LOCKED_MUTEX(m)			do {} while (false)
+#	define ASSERT_WRITE_LOCKED_RW_LOCK(m)	do {} while (false)
+#	define ASSERT_READ_LOCKED_RW_LOCK(l)	do {} while (false)
+#endif
+
+
+// static initializers
+#if KDEBUG
+#	define MUTEX_INITIALIZER(name)			{ name, NULL, -1, 0 }
+#	define RECURSIVE_LOCK_INITIALIZER(name)	{ MUTEX_INITIALIZER(name), 0 }
+#else
+#	define MUTEX_INITIALIZER(name)			{ name, NULL, 0, 0, 0 }
+#	define RECURSIVE_LOCK_INITIALIZER(name)	{ MUTEX_INITIALIZER(name), -1, 0 }
+#endif
+
+#define RW_LOCK_INITIALIZER(name)			{ name, NULL, -1, 0, 0, 0 }
+
+
+#if KDEBUG
+#	define RECURSIVE_LOCK_HOLDER(recursiveLock)	((recursiveLock)->lock.holder)
+#else
+#	define RECURSIVE_LOCK_HOLDER(recursiveLock)	((recursiveLock)->holder)
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void	recursive_lock_init(recursive_lock *lock, const char *name);
+	// name is *not* cloned nor freed in recursive_lock_destroy()
+extern void recursive_lock_init_etc(recursive_lock *lock, const char *name,
+	uint32 flags);
+extern void recursive_lock_destroy(recursive_lock *lock);
+extern status_t recursive_lock_lock(recursive_lock *lock);
+extern status_t recursive_lock_trylock(recursive_lock *lock);
+extern void recursive_lock_unlock(recursive_lock *lock);
+extern int32 recursive_lock_get_recursion(recursive_lock *lock);
+
+extern void rw_lock_init(rw_lock* lock, const char* name);
+	// name is *not* cloned nor freed in rw_lock_destroy()
+extern void rw_lock_init_etc(rw_lock* lock, const char* name, uint32 flags);
+extern void rw_lock_destroy(rw_lock* lock);
+extern status_t rw_lock_write_lock(rw_lock* lock);
+
+extern void mutex_init(mutex* lock, const char* name);
+	// name is *not* cloned nor freed in mutex_destroy()
+extern void mutex_init_etc(mutex* lock, const char* name, uint32 flags);
+extern void mutex_destroy(mutex* lock);
+extern status_t mutex_switch_lock(mutex* from, mutex* to);
+	// Unlocks "from" and locks "to" such that unlocking and starting to wait
+	// for the lock is atomically. I.e. if "from" guards the object "to" belongs
+	// to, the operation is safe as long as "from" is held while destroying
+	// "to".
+extern status_t mutex_switch_from_read_lock(rw_lock* from, mutex* to);
+	// Like mutex_switch_lock(), just for a switching from a read-locked
+	// rw_lock.
+
+
+// implementation private:
+
+extern status_t _rw_lock_read_lock(rw_lock* lock);
+extern status_t _rw_lock_read_lock_with_timeout(rw_lock* lock,
+	uint32 timeoutFlags, bigtime_t timeout);
+extern void _rw_lock_read_unlock(rw_lock* lock, bool threadsLocked);
+extern void _rw_lock_write_unlock(rw_lock* lock, bool threadsLocked);
+
+extern status_t _mutex_lock(mutex* lock, bool threadsLocked);
+extern void _mutex_unlock(mutex* lock, bool threadsLocked);
+extern status_t _mutex_trylock(mutex* lock);
+extern status_t _mutex_lock_with_timeout(mutex* lock, uint32 timeoutFlags,
+	bigtime_t timeout);
+
+
+static inline status_t
+rw_lock_read_lock(rw_lock* lock)
+{
+#if KDEBUG_RW_LOCK_DEBUG
+	return rw_lock_write_lock(lock);
+#else
+	int32 oldCount = atomic_add(&lock->count, 1);
+	if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
+		return _rw_lock_read_lock(lock);
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+rw_lock_read_lock_with_timeout(rw_lock* lock, uint32 timeoutFlags,
+	bigtime_t timeout)
+{
+#if KDEBUG_RW_LOCK_DEBUG
+	return mutex_lock_with_timeout(lock, timeoutFlags, timeout);
+#else
+	int32 oldCount = atomic_add(&lock->count, 1);
+	if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
+		return _rw_lock_read_lock_with_timeout(lock, timeoutFlags, timeout);
+	return B_OK;
+#endif
+}
+
+
+static inline void
+rw_lock_read_unlock(rw_lock* lock)
+{
+#if KDEBUG_RW_LOCK_DEBUG
+	rw_lock_write_unlock(lock);
+#else
+	int32 oldCount = atomic_add(&lock->count, -1);
+	if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
+		_rw_lock_read_unlock(lock, false);
+#endif
+}
+
+
+static inline void
+rw_lock_write_unlock(rw_lock* lock)
+{
+	_rw_lock_write_unlock(lock, false);
+}
+
+
+static inline status_t
+mutex_lock(mutex* lock)
+{
+#if KDEBUG
+	return _mutex_lock(lock, false);
+#else
+	if (atomic_add(&lock->count, -1) < 0)
+		return _mutex_lock(lock, false);
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+mutex_lock_threads_locked(mutex* lock)
+{
+#if KDEBUG
+	return _mutex_lock(lock, true);
+#else
+	if (atomic_add(&lock->count, -1) < 0)
+		return _mutex_lock(lock, true);
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+mutex_trylock(mutex* lock)
+{
+#if KDEBUG
+	return _mutex_trylock(lock);
+#else
+	if (atomic_test_and_set(&lock->count, -1, 0) != 0)
+		return B_WOULD_BLOCK;
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+mutex_lock_with_timeout(mutex* lock, uint32 timeoutFlags, bigtime_t timeout)
+{
+#if KDEBUG
+	return _mutex_lock_with_timeout(lock, timeoutFlags, timeout);
+#else
+	if (atomic_add(&lock->count, -1) < 0)
+		return _mutex_lock_with_timeout(lock, timeoutFlags, timeout);
+	return B_OK;
+#endif
+}
+
+
+static inline void
+mutex_unlock(mutex* lock)
+{
+#if !KDEBUG
+	if (atomic_add(&lock->count, 1) < -1)
+#endif
+		_mutex_unlock(lock, false);
+}
+
+
+static inline void
+mutex_transfer_lock(mutex* lock, thread_id thread)
+{
+#if KDEBUG
+	lock->holder = thread;
+#endif
+}
+
+
+extern void lock_debug_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _KERNEL_LOCK_H */
Index: /trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.c
===================================================================
--- /trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.c	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.c	(revision 43363)
@@ -0,0 +1,912 @@
+/* $Id$ */
+/** @file
+ * Shared folders - 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>
+ *
+ * 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.
+ */
+
+#include "vboxsf.h"
+
+#define MODULE_NAME "file_systems/vboxsf"
+#define FS_NAME "vboxsf"
+
+VBSFCLIENT g_clientHandle;
+static fs_volume_ops vboxsf_volume_ops;
+static fs_vnode_ops vboxsf_vnode_ops;
+
+status_t init_module(void)
+{
+	if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK) {
+		dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME);
+		return B_ERROR;
+	}
+
+	if (RT_FAILURE(vboxInit())) {
+		dprintf("vboxInit failed\n");
+		return B_ERROR;
+	}
+
+	if (RT_FAILURE(vboxConnect(&g_clientHandle))) {
+		dprintf("vboxConnect failed\n");
+		return B_ERROR;
+	}
+
+	if (RT_FAILURE(vboxCallSetUtf8(&g_clientHandle))) {
+		dprintf("vboxCallSetUtf8 failed\n");
+		return B_ERROR;
+	}
+
+	if (RT_FAILURE(vboxCallSetSymlinks(&g_clientHandle))) {
+		dprintf("warning: vboxCallSetSymlinks failed (old vbox?) - symlinks will appear as copies\n");
+	}
+
+	mutex_init(&g_vnodeCacheLock, "vboxsf vnode cache lock");
+
+	dprintf(FS_NAME ": inited successfully\n");
+	return B_OK;
+}
+
+void uninit_module(void)
+{
+	mutex_destroy(&g_vnodeCacheLock);
+	put_module(VBOXGUEST_MODULE_NAME);
+}
+
+PSHFLSTRING make_shflstring(const char* const s) {
+	int len = strlen(s);
+	if (len > 0xFFFE) {
+		dprintf(FS_NAME ": make_shflstring: string too long\n");
+		return NULL;
+	}
+
+	PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + len);
+	if (!rv) {
+		return NULL;
+	}
+
+	rv->u16Length = len;
+    rv->u16Size = len + 1;
+    strcpy(rv->String.utf8, s);
+	return rv;
+}
+
+PSHFLSTRING clone_shflstring(PSHFLSTRING s) {
+	PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s->u16Length);
+	if (rv)
+		memcpy(rv, s, sizeof(SHFLSTRING) + s->u16Length);
+	return rv;
+}
+
+PSHFLSTRING concat_shflstring_cstr(PSHFLSTRING s1, const char* const s2) {
+	size_t s2len = strlen(s2);
+	PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s1->u16Length + s2len);
+	if (rv) {
+		memcpy(rv, s1, sizeof(SHFLSTRING) + s1->u16Length);
+		strcat(rv->String.utf8, s2);
+		rv->u16Length += s2len;
+		rv->u16Size += s2len;
+	}
+	return rv;
+}
+
+PSHFLSTRING concat_cstr_shflstring(const char* const s1, PSHFLSTRING s2) {
+	size_t s1len = strlen(s1);
+	PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + s1len + s2->u16Length);
+	if (rv) {
+		strcpy(rv->String.utf8, s1);
+		strcat(rv->String.utf8, s2->String.utf8);
+		rv->u16Length = s1len + s2->u16Length;
+		rv->u16Size = rv->u16Length + 1;
+	}
+	return rv;
+}
+
+PSHFLSTRING build_path(vboxsf_vnode* dir, const char* const name) {
+
+	dprintf("*** build_path(%p, %p)\n", dir, name);
+	if (!dir || !name)
+		return NULL;
+
+	size_t len = dir->path->u16Length + strlen(name) + 1;
+
+	PSHFLSTRING rv = malloc(sizeof(SHFLSTRING) + len);
+	if (rv) {
+		strcpy(rv->String.utf8, dir->path->String.utf8);
+		strcat(rv->String.utf8, "/");
+		strcat(rv->String.utf8, name);
+		rv->u16Length = len;
+		rv->u16Size = rv->u16Length + 1;
+	}
+	return rv;
+}
+
+status_t mount(fs_volume *volume, const char *device, uint32 flags, const char *args, ino_t *_rootVnodeID) {
+	if (device) {
+		dprintf(FS_NAME ": trying to mount a real device as a vbox share is silly\n");
+		return B_BAD_TYPE;
+	}
+
+	dprintf(FS_NAME ": mount(%s)\n", args);
+
+	PSHFLSTRING sharename = make_shflstring(args);
+
+	vboxsf_volume* vbsfvolume = malloc(sizeof(vboxsf_volume));
+	volume->private_volume = vbsfvolume;
+	int rv = vboxCallMapFolder(&g_clientHandle, sharename, &(vbsfvolume->map));
+	free(sharename);
+
+	if (rv == 0) {
+		vboxsf_vnode* root_vnode;
+
+		PSHFLSTRING name = make_shflstring("");
+		if (!name) {
+			dprintf(FS_NAME ": make_shflstring() failed\n");
+			return B_NO_MEMORY;
+		}
+
+		status_t rs = vboxsf_new_vnode(&vbsfvolume->map, name, name, &root_vnode);
+		dprintf(FS_NAME ": allocated %p (path=%p name=%p)\n", root_vnode, root_vnode->path, root_vnode->name);
+
+		if (rs != B_OK) {
+			dprintf(FS_NAME ": vboxsf_new_vnode() failed (%d)\n", (int)rs);
+			return rs;
+		}
+
+		rs = publish_vnode(volume, root_vnode->vnode, root_vnode, &vboxsf_vnode_ops, S_IFDIR, 0);
+		dprintf(FS_NAME ": publish_vnode(): %d\n", (int)rs);
+		*_rootVnodeID = root_vnode->vnode;
+		volume->ops = &vboxsf_volume_ops;
+		return B_OK;
+	}
+	else {
+		dprintf(FS_NAME ": vboxCallMapFolder failed (%d)\n", rv);
+		free(volume->private_volume);
+		return vbox_err_to_haiku_err(rv);
+	}
+}
+
+status_t unmount(fs_volume *volume) {
+	dprintf(FS_NAME ": unmount\n");
+	vboxCallUnmapFolder(&g_clientHandle, volume->private_volume);
+	return B_OK;
+}
+
+status_t vboxsf_read_stat(fs_volume* _volume, fs_vnode* _vnode, struct stat* st) {
+	vboxsf_vnode* vnode = _vnode->private_node;
+	vboxsf_volume* volume = _volume->private_volume;
+	SHFLCREATEPARMS params;
+	int rc;
+
+	dprintf("vboxsf_read_stat (_vnode=%p, vnode=%p, path=%p (%s))\n", _vnode, vnode, vnode->path->String.utf8, vnode->path->String.utf8);
+
+	params.Handle = SHFL_HANDLE_NIL;
+	params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
+	dprintf("sf_stat: calling vboxCallCreate, file %s, flags %x\n", vnode->path->String.utf8, params.CreateFlags);
+	rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
+	if (rc == VERR_INVALID_NAME)
+	{
+		/* this can happen for names like 'foo*' on a Windows host */
+		return B_ENTRY_NOT_FOUND;
+	}
+	if (RT_FAILURE(rc))
+	{
+		dprintf("vboxCallCreate: %d\n", params.Result);
+		return vbox_err_to_haiku_err(params.Result);
+	}
+	if (params.Result != SHFL_FILE_EXISTS)
+	{
+		dprintf("vboxCallCreate: %d\n", params.Result);
+		return B_ENTRY_NOT_FOUND;
+	}
+
+	st->st_dev = 0;
+	st->st_ino = vnode->vnode;
+	st->st_mode = mode_from_fmode(params.Info.Attr.fMode);
+	st->st_nlink = 1;
+	st->st_uid = 0;
+	st->st_gid = 0;
+	st->st_rdev = 0;
+	st->st_size = params.Info.cbObject;
+	st->st_blksize = 1;
+	st->st_blocks = params.Info.cbAllocated;
+	st->st_atime = RTTimeSpecGetSeconds(&params.Info.AccessTime);
+	st->st_mtime = RTTimeSpecGetSeconds(&params.Info.ModificationTime);
+	st->st_ctime = RTTimeSpecGetSeconds(&params.Info.BirthTime);
+	return B_OK;
+}
+
+status_t vboxsf_open_dir(fs_volume* _volume, fs_vnode* _vnode, void** _cookie) {
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_vnode* vnode = _vnode->private_node;
+	SHFLCREATEPARMS params;
+
+	RT_ZERO(params);
+	params.Handle = SHFL_HANDLE_NIL;
+	params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_OPEN_IF_EXISTS
+		| SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ;
+
+	int rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
+	if (RT_SUCCESS(rc)) {
+		if (params.Result == SHFL_FILE_EXISTS && params.Handle != SHFL_HANDLE_NIL) {
+			vboxsf_dir_cookie* cookie = malloc(sizeof(vboxsf_dir_cookie));
+			*_cookie = cookie;
+			cookie->index = 0;
+			cookie->path = build_path(vnode, "*");
+			cookie->handle = params.Handle;
+			cookie->has_more_files = true;
+			cookie->buffer_start = cookie->buffer = NULL;
+			cookie->buffer_length = cookie->num_files = 0;
+			return B_OK;
+		}
+		else {
+			return B_ENTRY_NOT_FOUND;
+		}
+	}
+	else {
+		dprintf(FS_NAME ": vboxCallCreate: %d\n", rc);
+		return vbox_err_to_haiku_err(rc);
+	}
+}
+
+/** read a single entry from a dir */
+status_t vboxsf_read_dir_1(vboxsf_volume* volume, vboxsf_vnode* vnode, vboxsf_dir_cookie* cookie,
+	struct dirent* buffer, size_t bufferSize) {
+	dprintf("%p, %d, %p\n", cookie, cookie->has_more_files, cookie->buffer);
+	if (!cookie->has_more_files) {
+		return B_ENTRY_NOT_FOUND;
+	}
+	if (!cookie->buffer) {
+		cookie->buffer_length = 16384;
+		cookie->buffer_start = cookie->buffer = malloc(cookie->buffer_length);
+
+		int rc = vboxCallDirInfo(&g_clientHandle, &volume->map, cookie->handle, cookie->path,
+			0, cookie->index, &cookie->buffer_length, cookie->buffer, &cookie->num_files);
+
+		if (rc != 0 && rc != VERR_NO_MORE_FILES) {
+			dprintf(FS_NAME ": vboxCallDirInfo failed: %d\n", rc);
+			free(cookie->buffer_start);
+			cookie->buffer_start = NULL;
+			return vbox_err_to_haiku_err(rc);
+		}
+
+		if (rc == VERR_NO_MORE_FILES) {
+			free(cookie->buffer_start);
+			cookie->buffer_start = NULL;
+			cookie->has_more_files = false;
+			return B_ENTRY_NOT_FOUND;
+		}
+	}
+
+	if (bufferSize <= sizeof(struct dirent) + cookie->buffer->name.u16Length) {
+		dprintf("hit end of buffer\n");
+		return B_BUFFER_OVERFLOW;
+	}
+
+	PSHFLSTRING name1 = clone_shflstring(&cookie->buffer->name);
+	if (!name1) {
+		dprintf(FS_NAME ": make_shflstring() failed\n");
+		return B_NO_MEMORY;
+	}
+
+	vboxsf_vnode* new_vnode;
+	int rv = vboxsf_new_vnode(&volume->map, build_path(vnode, name1->String.utf8), name1, &new_vnode);
+	if (rv != B_OK) {
+		dprintf(FS_NAME ": vboxsf_new_vnode() failed\n");
+		return rv;
+	}
+	buffer->d_dev = 0;
+	buffer->d_pdev = 0;
+	buffer->d_ino = new_vnode->vnode;
+	buffer->d_pino = vnode->vnode;
+	buffer->d_reclen = sizeof(struct dirent) + cookie->buffer->name.u16Length;
+	strncpy(buffer->d_name, cookie->buffer->name.String.utf8, NAME_MAX);
+
+	size_t size = offsetof(SHFLDIRINFO, name.String) + cookie->buffer->name.u16Size;
+	cookie->buffer = ((void*)cookie->buffer + size);
+	cookie->index++;
+
+	if (cookie->index >= cookie->num_files) {
+		// hit end of this buffer, next call will reallocate a new one
+		free(cookie->buffer_start);
+		cookie->buffer_start = cookie->buffer = NULL;
+	}
+	return B_OK;
+}
+
+status_t vboxsf_read_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie,
+	struct dirent* buffer, size_t bufferSize, uint32* _num) {
+	vboxsf_dir_cookie* cookie = _cookie;
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_vnode* vnode = _vnode->private_node;
+	uint32 num_read = 0;
+	status_t rv = B_OK;
+
+	for (num_read = 0; num_read < *_num && cookie->has_more_files; num_read++) {
+		rv = vboxsf_read_dir_1(volume, vnode, cookie, buffer, bufferSize);
+		if (rv == B_BUFFER_OVERFLOW || rv == B_ENTRY_NOT_FOUND) {
+			// hit end of at least one of the buffers - not really an error
+			rv = B_OK;
+			break;
+		}
+		bufferSize -= buffer->d_reclen;
+		buffer = ((void*)(buffer)) + buffer->d_reclen;
+	}
+
+	*_num = num_read;
+	return rv;
+}
+
+status_t vboxsf_free_dir_cookie(fs_volume* _volume, fs_vnode* vnode, void* _cookie) {
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_dir_cookie* cookie = _cookie;
+
+	vboxCallClose(&g_clientHandle, &volume->map, cookie->handle);
+	free(cookie->path);
+	free(cookie);
+
+	return B_OK;
+}
+
+status_t vboxsf_read_fs_info(fs_volume* _volume, struct fs_info* info) {
+	vboxsf_volume* volume = _volume->private_volume;
+
+	SHFLVOLINFO volume_info;
+	uint32_t bytes = sizeof(SHFLVOLINFO);
+
+	int rc = vboxCallFSInfo(&g_clientHandle, &volume->map, 0,
+		(SHFL_INFO_GET | SHFL_INFO_VOLUME), &bytes, (PSHFLDIRINFO)&volume_info);
+
+	if (RT_FAILURE(rc)) {
+		dprintf(FS_NAME ": vboxCallFSInfo failed (%d)\n", rc);
+		return vbox_err_to_haiku_err(rc);
+	}
+
+	info->flags = B_FS_IS_PERSISTENT;
+	if (volume_info.fsProperties.fReadOnly)
+		info->flags |= B_FS_IS_READONLY;
+
+	info->dev = 0;
+	info->root = 1;
+	info->block_size = volume_info.ulBytesPerAllocationUnit;
+	info->io_size = volume_info.ulBytesPerAllocationUnit;
+	info->total_blocks = volume_info.ullTotalAllocationBytes / info->block_size;
+	info->free_blocks = volume_info.ullAvailableAllocationBytes / info->block_size;
+	info->total_nodes = LONGLONG_MAX;
+	info->free_nodes = LONGLONG_MAX;
+	strcpy(info->volume_name, "VBox share");
+	return B_OK;
+}
+
+status_t vboxsf_lookup(fs_volume* _volume, fs_vnode* dir, const char* name, ino_t* _id) {
+	dprintf(FS_NAME ": lookup %s\n", name);
+	vboxsf_volume* volume = _volume->private_volume;
+	SHFLCREATEPARMS params;
+
+	RT_ZERO(params);
+	params.Handle = SHFL_HANDLE_NIL;
+	params.CreateFlags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
+
+	PSHFLSTRING path = build_path(dir->private_node, name);
+	if (!path) {
+		dprintf(FS_NAME ": make_shflstring() failed\n");
+		return B_NO_MEMORY;
+	}
+
+	int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
+	if (RT_SUCCESS(rc)) {
+		if (params.Result == SHFL_FILE_EXISTS) {
+			vboxsf_vnode* vn;
+			status_t rv = vboxsf_new_vnode(&volume->map, path, path, &vn);
+			if (rv == B_OK) {
+				*_id = vn->vnode;
+				rv = publish_vnode(_volume, vn->vnode, vn, &vboxsf_vnode_ops, mode_from_fmode(params.Info.Attr.fMode), 0);
+			}
+			return rv;
+		}
+		else {
+			free(path);
+			return B_ENTRY_NOT_FOUND;
+		}
+	}
+	else {
+		free(path);
+		dprintf(FS_NAME ": vboxCallCreate: %d\n", rc);
+		return vbox_err_to_haiku_err(rc);
+	}
+}
+
+mode_t mode_from_fmode(RTFMODE fMode) {
+	mode_t m = 0;
+
+	if (RTFS_IS_DIRECTORY(fMode))
+		m |= S_IFDIR;
+	else if (RTFS_IS_FILE(fMode))
+		m |= S_IFREG;
+	else if (RTFS_IS_FIFO(fMode))
+		m |= S_IFIFO;
+	else if (RTFS_IS_DEV_CHAR(fMode))
+		m |= S_IFCHR;
+	else if (RTFS_IS_DEV_BLOCK(fMode))
+		m |= S_IFBLK;
+	else if (RTFS_IS_SYMLINK(fMode))
+		m |= S_IFLNK;
+	else if (RTFS_IS_SOCKET(fMode))
+		m |= S_IFSOCK;
+
+	if (fMode & RTFS_UNIX_IRUSR)
+		m |= S_IRUSR;
+	if (fMode & RTFS_UNIX_IWUSR)
+		m |= S_IWUSR;
+	if (fMode & RTFS_UNIX_IXUSR)
+		m |= S_IXUSR;
+	if (fMode & RTFS_UNIX_IRGRP)
+		m |= S_IRGRP;
+	if (fMode & RTFS_UNIX_IWGRP)
+		m |= S_IWGRP;
+	if (fMode & RTFS_UNIX_IXGRP)
+		m |= S_IXGRP;
+	if (fMode & RTFS_UNIX_IROTH)
+		m |= S_IROTH;
+	if (fMode & RTFS_UNIX_IWOTH)
+		m |= S_IWOTH;
+	if (fMode & RTFS_UNIX_IXOTH)
+		m |= S_IXOTH;
+	if (fMode & RTFS_UNIX_ISUID)
+		m |= S_ISUID;
+	if (fMode & RTFS_UNIX_ISGID)
+		m |= S_ISGID;
+	if (fMode & RTFS_UNIX_ISTXT)
+		m |= S_ISVTX;
+
+	return m;
+}
+
+status_t vboxsf_open(fs_volume* _volume, fs_vnode* _vnode, int openMode, void** _cookie) {
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_vnode* vnode = _vnode->private_node;
+
+	dprintf(FS_NAME ": open %s (mode=%x)\n", vnode->path->String.utf8, openMode);
+
+	SHFLCREATEPARMS params;
+
+	RT_ZERO(params);
+	params.Handle = SHFL_HANDLE_NIL;
+
+	if (openMode & O_RDWR)
+		params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
+	else if (openMode & O_RDONLY)
+		params.CreateFlags |= SHFL_CF_ACCESS_READ;
+	else if (openMode & O_WRONLY)
+		params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
+
+	if (openMode & O_APPEND)
+		params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
+
+	if (openMode & O_CREAT) {
+		params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
+		if (openMode & O_EXCL)
+			params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
+		else if (openMode & O_TRUNC)
+			params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
+		else
+			params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
+	}
+	else {
+		params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
+		if (openMode & O_TRUNC)
+			params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
+		else
+			params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
+	}
+
+	int rc = vboxCallCreate(&g_clientHandle, &volume->map, vnode->path, &params);
+	if (!RT_SUCCESS(rc)) {
+		dprintf("vboxCallCreate returned %d\n", rc);
+		return vbox_err_to_haiku_err(rc);
+	}
+
+	vboxsf_file_cookie* cookie = malloc(sizeof(vboxsf_file_cookie));
+	if (!cookie) {
+		dprintf("couldn't allocate file cookie\n");
+		return B_NO_MEMORY;
+	}
+
+	cookie->handle = params.Handle;
+	cookie->path = vnode->path;
+
+	*_cookie = cookie;
+
+	return B_OK;
+}
+
+status_t vboxsf_create(fs_volume* _volume, fs_vnode* _dir, const char *name, int openMode, int perms, void **_cookie, ino_t *_newVnodeID) {
+	vboxsf_volume* volume = _volume->private_volume;
+
+	SHFLCREATEPARMS params;
+
+	RT_ZERO(params);
+	params.Handle = SHFL_HANDLE_NIL;
+
+	if (openMode & O_RDWR)
+		params.CreateFlags |= SHFL_CF_ACCESS_READWRITE;
+	else if (openMode & O_RDONLY)
+		params.CreateFlags |= SHFL_CF_ACCESS_READ;
+	else if (openMode & O_WRONLY)
+		params.CreateFlags |= SHFL_CF_ACCESS_WRITE;
+
+	if (openMode & O_APPEND)
+		params.CreateFlags |= SHFL_CF_ACCESS_APPEND;
+
+	if (openMode & O_CREAT) {
+		params.CreateFlags |= SHFL_CF_ACT_CREATE_IF_NEW;
+		if (openMode & O_EXCL)
+			params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_EXISTS;
+		else if (openMode & O_TRUNC)
+			params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
+		else
+			params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
+	}
+	else {
+		params.CreateFlags |= SHFL_CF_ACT_FAIL_IF_NEW;
+		if (openMode & O_TRUNC)
+			params.CreateFlags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
+		else
+			params.CreateFlags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
+	}
+
+	PSHFLSTRING path = build_path(_dir->private_node, name);
+	int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
+
+	if (!RT_SUCCESS(rc)) {
+		dprintf("vboxCallCreate returned %d\n", rc);
+		free(path);
+		return vbox_err_to_haiku_err(rc);
+	}
+
+	vboxsf_file_cookie* cookie = malloc(sizeof(vboxsf_file_cookie));
+	if (!cookie) {
+		dprintf("couldn't allocate file cookie\n");
+		free(path);
+		return B_NO_MEMORY;
+	}
+
+	cookie->handle = params.Handle;
+	cookie->path = path;
+
+	*_cookie = cookie;
+	return vboxsf_lookup(_volume, _dir, name, _newVnodeID);
+}
+
+status_t vboxsf_close(fs_volume* _volume, fs_vnode* _vnode, void* _cookie) {
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_file_cookie* cookie = _cookie;
+
+	int rc = vboxCallClose(&g_clientHandle, &volume->map, cookie->handle);
+	dprintf("vboxCallClose returned %d\n", rc);
+	return vbox_err_to_haiku_err(rc);
+}
+
+status_t vboxsf_rewind_dir(fs_volume* _volume, fs_vnode* _vnode, void* _cookie) {
+	vboxsf_dir_cookie* cookie = _cookie;
+	cookie->index = 0;
+	return B_OK;
+}
+
+status_t vboxsf_close_dir(fs_volume *volume, fs_vnode *vnode, void *cookie) {
+	return B_OK;
+}
+
+status_t vboxsf_free_cookie(fs_volume *volume, fs_vnode *vnode, void *_cookie) {
+	vboxsf_dir_cookie* cookie = _cookie;
+	free(cookie);
+	return B_OK;
+}
+
+status_t vboxsf_read(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, off_t pos, void *buffer, size_t *length) {
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_vnode* vnode = _vnode->private_node;
+	vboxsf_file_cookie* cookie = _cookie;
+
+	if (*length > 0xFFFFFFFF) {
+		*length = 0xFFFFFFFF;
+	}
+
+	uint32_t l = *length;
+	void* other_buffer = malloc(l); // TODO map the user memory into kernel space here for efficiency
+	int rc = vboxCallRead(&g_clientHandle, &volume->map, cookie->handle, pos, &l, other_buffer, false);
+	memcpy(buffer, other_buffer, l);
+	free(other_buffer);
+
+	dprintf("vboxCallRead returned %d\n", rc);
+	*length = l;
+	return vbox_err_to_haiku_err(rc);
+}
+
+status_t vboxsf_write(fs_volume* _volume, fs_vnode* _vnode, void* _cookie, off_t pos, const void *buffer, size_t *length) {
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_vnode* vnode = _vnode->private_node;
+	vboxsf_file_cookie* cookie = _cookie;
+
+	if (*length > 0xFFFFFFFF) {
+		*length = 0xFFFFFFFF;
+	}
+
+	uint32_t l = *length;
+	void* other_buffer = malloc(l); // TODO map the user memory into kernel space here for efficiency
+	memcpy(other_buffer, buffer, l);
+	int rc = vboxCallWrite(&g_clientHandle, &volume->map, cookie->handle, pos, &l, other_buffer, false);
+	free(other_buffer);
+
+	*length = l;
+	return vbox_err_to_haiku_err(rc);
+}
+
+status_t vboxsf_write_stat(fs_volume *volume, fs_vnode *vnode, const struct stat *stat, uint32 statMask) {
+	// the host handles updating the stat info - in the guest, this is a no-op
+	return B_OK;
+}
+
+status_t vboxsf_create_dir(fs_volume *_volume, fs_vnode *parent, const char *name, int perms) {
+	vboxsf_volume* volume = _volume->private_volume;
+
+	SHFLCREATEPARMS params;
+	params.Handle = 0;
+	params.Info.cbObject = 0;
+	params.CreateFlags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_CREATE_IF_NEW |
+	    SHFL_CF_ACT_FAIL_IF_EXISTS | SHFL_CF_ACCESS_READ;
+
+	PSHFLSTRING path = build_path(parent->private_node, name);
+	int rc = vboxCallCreate(&g_clientHandle, &volume->map, path, &params);
+	free(path);
+	if (params.Handle == SHFL_HANDLE_NIL) {
+		return vbox_err_to_haiku_err(rc);
+	}
+	else {
+		vboxCallClose(&g_clientHandle, &volume->map, params.Handle);
+		return B_OK;
+	}
+}
+
+status_t vboxsf_remove_dir(fs_volume *_volume, fs_vnode *parent, const char *name) {
+	vboxsf_volume* volume = _volume->private_volume;
+
+	PSHFLSTRING path = build_path(parent->private_node, name);
+	int rc = vboxCallRemove(&g_clientHandle, &volume->map, path, SHFL_REMOVE_DIR);
+	free(path);
+
+	return vbox_err_to_haiku_err(rc);
+}
+
+status_t vboxsf_unlink(fs_volume *_volume, fs_vnode *parent, const char *name) {
+	vboxsf_volume* volume = _volume->private_volume;
+
+	PSHFLSTRING path = build_path(parent->private_node, name);
+	int rc = vboxCallRemove(&g_clientHandle, &volume->map, path, SHFL_REMOVE_FILE);
+	free(path);
+
+	return vbox_err_to_haiku_err(rc);
+}
+
+status_t vboxsf_link(fs_volume *volume, fs_vnode *dir, const char *name, fs_vnode *vnode) {
+	return B_UNSUPPORTED;
+}
+
+status_t vboxsf_rename(fs_volume* _volume, fs_vnode* fromDir, const char* fromName, fs_vnode* toDir, const char* toName) {
+	vboxsf_volume* volume = _volume->private_volume;
+
+	PSHFLSTRING oldpath = build_path(fromDir->private_node, fromName);
+	PSHFLSTRING newpath = build_path(toDir->private_node, toName);
+	int rc = vboxCallRename(&g_clientHandle, &volume->map, oldpath, newpath, SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS);
+	free(oldpath);
+	free(newpath);
+
+	return vbox_err_to_haiku_err(rc);
+}
+
+status_t vboxsf_create_symlink(fs_volume* _volume, fs_vnode* dir, const char* name, const char* path, int mode) {
+	vboxsf_volume* volume = _volume->private_volume;
+
+	PSHFLSTRING target = make_shflstring(path);
+	PSHFLSTRING linkpath = build_path(dir->private_node, name);
+	SHFLFSOBJINFO stuff;
+	RT_ZERO(stuff);
+
+	int rc = vboxCallSymlink(&g_clientHandle, &volume->map, linkpath, target, &stuff);
+
+	free(target);
+	free(linkpath);
+
+	return vbox_err_to_haiku_err(rc);
+}
+
+status_t vboxsf_read_symlink(fs_volume* _volume, fs_vnode* link, char* buffer, size_t* _bufferSize) {
+	vboxsf_volume* volume = _volume->private_volume;
+	vboxsf_vnode* vnode = link->private_node;
+
+	int rc = vboxReadLink(&g_clientHandle, &volume->map, vnode->path, *_bufferSize, buffer);
+	*_bufferSize = strlen(buffer);
+
+	return vbox_err_to_haiku_err(rc);
+}
+
+// TODO move this into the runtime
+status_t vbox_err_to_haiku_err(int rc) {
+	switch (rc) {
+		case VINF_SUCCESS: return B_OK;
+		case VERR_INVALID_POINTER: return B_BAD_ADDRESS;
+		case VERR_INVALID_PARAMETER: return B_BAD_VALUE;
+		case VERR_PERMISSION_DENIED: return B_PERMISSION_DENIED;
+		case VERR_NOT_IMPLEMENTED: return B_UNSUPPORTED;
+		case VERR_FILE_NOT_FOUND: return B_ENTRY_NOT_FOUND;
+
+		case SHFL_FILE_EXISTS: return B_FILE_EXISTS;
+		case SHFL_PATH_NOT_FOUND:
+		case SHFL_FILE_NOT_FOUND: return B_ENTRY_NOT_FOUND;
+
+		default: return B_ERROR;
+	}
+}
+
+static status_t std_ops(int32 op, ...) {
+	switch(op) {
+	case B_MODULE_INIT:
+		dprintf(MODULE_NAME ": B_MODULE_INIT\n");
+		return init_module();
+	case B_MODULE_UNINIT:
+		dprintf(MODULE_NAME ": B_MODULE_UNINIT\n");
+		uninit_module();
+		return B_OK;
+	default:
+		return B_ERROR;
+	}
+}
+
+static fs_volume_ops vboxsf_volume_ops = {
+	unmount,
+
+	vboxsf_read_fs_info, // read_fs_info
+	NULL, // write_fs_info
+	NULL, // sync
+
+	vboxsf_get_vnode, // get_vnode
+
+	NULL, // open_index_dir
+	NULL, // close_index_dir
+	NULL, // free_index_dir_cookie
+	NULL, // read_index_dir
+	NULL, // rewind_index_dir
+
+	NULL, // create_index
+	NULL, // remove_index
+	NULL, // read_index_stat
+
+	NULL, // open_query
+	NULL, // close_query
+	NULL, // free_query_cookie
+	NULL, // read_query
+	NULL, // rewind_query
+
+	NULL, // all_layers_mounted
+	NULL, // create_sub_vnode
+	NULL, // delete_sub_vnode
+};
+
+static fs_vnode_ops vboxsf_vnode_ops = {
+	vboxsf_lookup, // lookup
+	NULL, // get_vnode_name
+	vboxsf_put_vnode, // put_vnode
+	NULL, // remove_vnode
+	NULL, // can_page
+	NULL, // read_pages
+	NULL, // write_pages
+	NULL, // io
+	NULL, // cancel_io
+	NULL, // get_file_map
+	NULL, // ioctl
+	NULL, // set_flags
+	NULL, // select
+	NULL, // deselect
+	NULL, // fsync
+	vboxsf_read_symlink, // read_symlink
+	vboxsf_create_symlink, // create_symlink
+	vboxsf_link, // link
+	vboxsf_unlink, // unlink
+	vboxsf_rename, // rename
+	NULL, // access
+	vboxsf_read_stat, // read_stat
+	vboxsf_write_stat, // write_stat
+	NULL, // preallocate
+	vboxsf_create, // create
+	vboxsf_open, // open
+	vboxsf_close, // close
+	vboxsf_free_cookie, // free_cookie
+	vboxsf_read, // read
+	vboxsf_write, // write
+	vboxsf_create_dir, // create_dir
+	vboxsf_remove_dir, // remove_dir
+	vboxsf_open_dir, // open_dir
+	vboxsf_close_dir, // close_dir
+	vboxsf_free_dir_cookie, // free_dir_cookie
+	vboxsf_read_dir, // read_dir
+	vboxsf_rewind_dir, // rewind_dir
+	NULL, // open_attr_dir
+	NULL, // close_attr_dir
+	NULL, // free_attr_dir_cookie
+	NULL, // read_attr_dir
+	NULL, // rewind_attr_dir
+	NULL, // create_attr
+	NULL, // open_attr
+	NULL, // close_attr
+	NULL, // free_attr_cookie
+	NULL, // read_attr
+	NULL, // write_attr
+	NULL, // read_attr_stat
+	NULL, // write_attr_stat
+	NULL, // rename_attr
+	NULL, // remove_attr
+	NULL, // create_special_node
+	NULL, // get_super_vnode
+};
+
+static file_system_module_info sVBoxSharedFileSystem = {
+	{
+		MODULE_NAME B_CURRENT_FS_API_VERSION,
+		0,
+		std_ops,
+	},
+
+	FS_NAME,						// short_name
+	"VirtualBox shared folders",	// pretty_name
+	0, //B_DISK_SYSTEM_SUPPORTS_WRITING,	// DDM flags
+
+	// scanning
+	NULL, // identify_partition
+	NULL, // scan_partition
+	NULL, // free_identify_partition_cookie
+	NULL,	// free_partition_content_cookie()
+
+	mount,
+};
+
+module_info *modules[] = {
+	(module_info *)&sVBoxSharedFileSystem,
+	NULL,
+};
Index: /trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/SharedFolders/vboxsf.h	(revision 43363)
@@ -0,0 +1,101 @@
+/* $Id$ */
+/** @file
+ * Shared folders - 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>
+ *
+ * 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 ___vboxsf_h
+#define ___vboxsf_h
+
+#include <malloc.h>
+#include <dirent.h>
+#include <fs_info.h>
+#include <sys/stat.h>
+#include <fs_interface.h>
+#include <KernelExport.h>
+#include <VBoxGuest-haiku.h>
+#include <VBoxGuestR0LibSharedFolders.h>
+#include "lock.h"
+
+typedef struct vboxsf_volume {
+	VBSFMAP map;
+	ino_t rootid;
+} vboxsf_volume;
+
+typedef struct vboxsf_vnode {
+	PVBSFMAP map;
+	PSHFLSTRING name;
+	PSHFLSTRING path;
+
+	ino_t vnode;
+	struct vboxsf_vnode* next;
+} vboxsf_vnode;
+
+typedef struct vboxsf_dir_cookie {
+	SHFLHANDLE handle;
+	PSHFLSTRING path;
+	uint32_t index;
+	bool has_more_files;
+	PSHFLDIRINFO buffer_start, buffer;
+	uint32_t buffer_length, num_files;
+} vboxsf_dir_cookie;
+
+typedef struct vboxsf_file_cookie {
+	SHFLHANDLE handle;
+	PSHFLSTRING path;
+} vboxsf_file_cookie;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+status_t vboxsf_new_vnode(PVBSFMAP map, PSHFLSTRING path, PSHFLSTRING name, vboxsf_vnode** p);
+status_t vboxsf_get_vnode(fs_volume* volume, ino_t id, fs_vnode* vnode, int* _type, uint32* _flags, bool reenter);
+status_t vboxsf_put_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter);
+PSHFLSTRING make_shflstring(const char* const s);
+mode_t mode_from_fmode(RTFMODE fMode);
+status_t vbox_err_to_haiku_err(int rc);
+extern mutex g_vnodeCacheLock;
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /trunk/src/VBox/Additions/haiku/SharedFolders/vnode_cache.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/SharedFolders/vnode_cache.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/SharedFolders/vnode_cache.cpp	(revision 43363)
@@ -0,0 +1,126 @@
+/* $Id$ */
+/** @file
+ * Shared folders - Haiku Guest Additions, vnode cache 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>
+ *
+ * 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.
+ */
+
+#include "vboxsf.h"
+#include "OpenHashTable.h"
+
+struct HashTableDefinition {
+	typedef uint32 KeyType;
+	typedef	vboxsf_vnode ValueType;
+
+	size_t HashKey(uint32 key) const
+	{
+		return key;
+	}
+
+	size_t Hash(vboxsf_vnode* value) const
+	{
+		return HashKey(value->vnode);
+	}
+
+	bool Compare(uint32 key, vboxsf_vnode* value) const
+	{
+		return value->vnode == key;
+	}
+
+	vboxsf_vnode*& GetLink(vboxsf_vnode* value) const
+	{
+		return value->next;
+	}
+};
+
+static BOpenHashTable<HashTableDefinition> g_cache;
+static ino_t g_nextVnid = 1;
+mutex g_vnodeCacheLock;
+
+extern "C" status_t vboxsf_new_vnode(PVBSFMAP map, PSHFLSTRING path, PSHFLSTRING name, vboxsf_vnode** p) {
+	vboxsf_vnode* vn = (vboxsf_vnode*)malloc(sizeof(vboxsf_vnode));
+	if (vn == NULL) {
+		return B_NO_MEMORY;
+	}
+	dprintf("creating new vnode at %p with path=%p (%s)\n", vn, path->String.utf8, path->String.utf8);
+	vn->map = map;
+	vn->path = path;
+	if (name) {
+		vn->name = name;
+	}
+	else {
+		const char* cname = strrchr((char*)path->String.utf8, '/');
+		if (!cname)
+			vn->name = path; // no slash, assume this *is* the filename
+		else
+			vn->name = make_shflstring(cname);
+	}
+
+	if (mutex_lock(&g_vnodeCacheLock) < B_OK) {
+		free(vn);
+		return B_ERROR;
+	}
+
+	vn->vnode = g_nextVnid++;
+	*p = vn;
+	dprintf("vboxsf: allocated %p (path=%p name=%p)\n", vn, vn->path, vn->name);
+	status_t rv = g_cache.Insert(vn);
+
+	mutex_unlock(&g_vnodeCacheLock);
+
+	return rv;
+}
+
+extern "C" status_t vboxsf_get_vnode(fs_volume* volume, ino_t id, fs_vnode* vnode,
+	int* _type, uint32* _flags, bool reenter) {
+	vboxsf_vnode* vn = g_cache.Lookup(id);
+	if (vn) {
+		vnode->private_node = vn;
+		return B_OK;
+	}
+	else {
+		return B_ERROR;
+	}
+}
+
+extern "C" status_t vboxsf_put_vnode(fs_volume* volume, fs_vnode* vnode, bool reenter) {
+	g_cache.Remove((vboxsf_vnode*)vnode->private_node);
+}
Index: /trunk/src/VBox/Additions/haiku/VBoxMouse/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxMouse/Makefile.kmk	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxMouse/Makefile.kmk	(revision 43363)
@@ -0,0 +1,80 @@
+# $Id$
+## @file
+# Sub-Makefile for VBoxMouse, Haiku Additions.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../../..
+include	$(KBUILD_PATH)/subheader.kmk
+
+# @todo split the mouse code to communicate with VBoxMouse/VBoxService
+# to allow building with gcc2.
+# R1 will need gcc2-built input_server add-ons.
+
+PROGRAMS += VBoxMouse
+VBoxMouse_TEMPLATE = VBOXGUESTR3EXE
+VBoxMouse_DEFS     = VBOX_WITH_HGCM LOG_TO_BACKDOOR
+VBoxMouse_DEFS    += LOG_ENABLED
+VBoxMouse_INCS     = ../include
+VBoxMouse_SOURCES  = \
+	VBoxMouse.cpp
+
+VBoxMouse_LIBS     = \
+	be \
+	device \
+	$(VBOX_LIB_IPRT_GUEST_R3) \
+	$(VBOX_LIB_VBGL_R3) \
+	/system/servers/input_server
+
+PROGRAMS += VBoxMouseFilter
+VBoxMouseFilter_TEMPLATE = VBOXGUESTR3EXE
+VBoxMouseFilter_DEFS     = VBOX_WITH_HGCM LOG_TO_BACKDOOR
+VBoxMouseFilter_DEFS    += LOG_ENABLED
+VBoxMouseFilter_INCS     = ../include
+VBoxMouseFilter_SOURCES  = \
+	VBoxMouseFilter.cpp
+
+VBoxMouseFilter_LIBS = $(VBoxMouse_LIBS)
+
+include	$(KBUILD_PATH)/subfooter.kmk
+
Index: /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.cpp	(revision 43363)
@@ -0,0 +1,250 @@
+/* $Id$ */
+/** @file
+ * VBoxMouse; input_server add-on - 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <Clipboard.h>
+#include <Debug.h>
+#include <Message.h>
+#include <String.h>
+
+#include "VBoxMouse.h"
+#include <VBox/VBoxGuest.h> /** @todo use the VbglR3 interface! */
+#include <VBox/VBoxGuestLib.h>
+#include <VBoxGuestInternal.h>
+#include <VBox/VMMDev.h>
+#include <VBox/log.h>
+#include <iprt/err.h>
+
+/* Export as global symbol with C linkage, RTDECL is necessary. */
+RTDECL(BInputServerDevice*)
+instantiate_input_device()
+{
+    return new VBoxMouse();
+}
+
+VBoxMouse::VBoxMouse()
+	: BInputServerDevice(),
+	fDriverFD(-1),
+	fServiceThreadID(-1),
+	fExiting(false)
+{
+}
+
+VBoxMouse::~VBoxMouse()
+{
+}
+
+status_t VBoxMouse::InitCheck()
+{
+    int rc = VbglR3Init();
+    if (!RT_SUCCESS(rc))
+		return ENXIO;
+
+	//// Start() will *not* Init() again
+    //VbglR3Term();
+
+//		return B_DEVICE_NOT_FOUND;
+
+	input_device_ref device = { (char *)"VBoxMouse",
+		B_POINTING_DEVICE, (void*)this };
+	input_device_ref* deviceList[2] = { &device, NULL };
+	RegisterDevices(deviceList);
+
+	return B_OK;
+}
+
+status_t VBoxMouse::SystemShuttingDown()
+{
+    VbglR3Term();
+
+	return B_OK;
+}
+
+status_t VBoxMouse::Start(const char* device, void* cookie)
+{
+	status_t err;
+	int rc;
+    uint32_t fFeatures = 0;
+    Log(("VBoxMouse::%s()\n", __FUNCTION__));
+
+    rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
+    if (RT_SUCCESS(rc))
+        rc = VbglR3SetMouseStatus(  fFeatures
+                                  | VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
+                                  | VMMDEV_MOUSE_NEW_PROTOCOL);
+    if (!RT_SUCCESS(rc)) {
+		LogRel(("VBoxMouse: Error switching guest mouse into absolute mode: %d\n", rc));
+        return B_DEVICE_NOT_FOUND;
+    }
+
+	err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
+			"VBoxMouse", B_NORMAL_PRIORITY, this);
+	if (err >= B_OK) {
+		resume_thread(fServiceThreadID);
+		return B_OK;
+	} else
+        LogRel(("VBoxMouse: Error starting service thread: 0x%08lx\n",
+   	    	err));
+
+	// release the mouse
+    rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
+    if (RT_SUCCESS(rc))
+        rc = VbglR3SetMouseStatus(  fFeatures
+                                  & ~VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
+                                  & ~VMMDEV_MOUSE_NEW_PROTOCOL);
+
+   	 return B_ERROR;
+}
+
+status_t VBoxMouse::Stop(const char* device, void* cookie)
+{
+	status_t status;
+	int rc;
+    uint32_t fFeatures = 0;
+    Log(("VBoxMouse::%s()\n", __FUNCTION__));
+
+	fExiting = true;
+
+
+    rc = VbglR3GetMouseStatus(&fFeatures, NULL, NULL);
+    if (RT_SUCCESS(rc))
+        rc = VbglR3SetMouseStatus(  fFeatures
+                                  & ~VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE
+                                  & ~VMMDEV_MOUSE_NEW_PROTOCOL);
+
+
+	close(fDriverFD);
+	fDriverFD = -1;
+	//XXX WTF ?
+	suspend_thread(fServiceThreadID);
+	resume_thread(fServiceThreadID);
+	wait_for_thread(fServiceThreadID, &status);
+	fServiceThreadID = -1;
+	fExiting = false;
+    return B_OK;
+}
+
+status_t VBoxMouse::Control(const char	*device,
+						void		*cookie,
+						uint32		code,
+						BMessage	*message)
+{
+	// respond to changes in the system
+	switch (code) {
+		case B_MOUSE_SPEED_CHANGED:
+		case B_CLICK_SPEED_CHANGED:
+		case B_MOUSE_ACCELERATION_CHANGED:
+		default:
+			return BInputServerDevice::Control(device, cookie, code, message);
+	}
+	return B_OK;
+}
+
+status_t VBoxMouse::_ServiceThreadNub(void *_this)
+{
+	VBoxMouse *service = (VBoxMouse *)_this;
+	return service->_ServiceThread();
+}
+
+status_t VBoxMouse::_ServiceThread()
+{
+    Log(("VBoxMouse::%s()\n", __FUNCTION__));
+
+	fDriverFD = open(VBOXGUEST_DEVICE_NAME, O_RDWR);
+	if (fDriverFD < 0)
+		return ENXIO;
+
+    /* The thread waits for incoming messages from the host. */
+    while (!fExiting)
+    {
+	    uint32_t cx, cy, fFeatures;
+    	int rc;
+
+
+		fd_set readSet, writeSet, errorSet;
+		FD_ZERO(&readSet);
+		FD_ZERO(&writeSet);
+		FD_ZERO(&errorSet);
+		FD_SET(fDriverFD, &readSet);
+		if (fDriverFD < 0)
+			break;
+		rc = select(fDriverFD + 1, &readSet, &writeSet, &errorSet, NULL);
+		if (rc < 0) {
+			if (errno == EINTR || errno == EAGAIN)
+				continue;
+			break;
+		}
+
+	    if (RT_SUCCESS(VbglR3GetMouseStatus(&fFeatures, &cx, &cy))
+    	    && (fFeatures & VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE))
+    	{
+	    	float x = cx * 1.0 / 65535;
+	    	float y = cy * 1.0 / 65535;
+
+        	_debugPrintf("VBoxMouse: at %d,%d %f,%f\n", cx, cy, x, y);
+
+        	/* send absolute movement */
+
+			bigtime_t now = system_time();
+			BMessage* event = new BMessage(B_MOUSE_MOVED);
+			event->AddInt64("when", now);
+			event->AddFloat("x", x);
+			event->AddFloat("y", y);
+			event->AddFloat("be:tablet_x", x);
+			event->AddFloat("be:tablet_y", y);
+			//event->PrintToStream();
+			EnqueueMessage(event);
+
+        	//LogRelFlow(("processed host event rc = %d\n", rc));
+    	}
+    }
+	return 0;
+}
+
+
Index: /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouse.h	(revision 43363)
@@ -0,0 +1,81 @@
+/* $Id$ */
+/** @file
+ * VBoxMouse; input_server add-on - 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 __VBOXMOUSE__H
+#define __VBOXMOUSE__H
+
+#include <InputServerDevice.h>
+
+extern "C" _EXPORT BInputServerDevice* instantiate_input_device();
+
+class VBoxMouse : public BInputServerDevice {
+public:
+	VBoxMouse();
+	virtual ~VBoxMouse();
+
+	virtual status_t		InitCheck();
+	virtual status_t		SystemShuttingDown();
+
+	virtual status_t		Start(const char* device, void* cookie);
+	virtual	status_t		Stop(const char* device, void* cookie);
+	virtual status_t		Control(const char	*device,
+									void		*cookie,
+									uint32		code,
+									BMessage	*message);
+
+private:
+
+static status_t	_ServiceThreadNub(void *_this);
+	status_t	_ServiceThread();
+
+	int			fDriverFD;
+	thread_id	fServiceThreadID;
+	bool		fExiting;
+
+};
+
+
+#endif /* __VBOXMOUSE__H */
Index: /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouseFilter.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouseFilter.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouseFilter.cpp	(revision 43363)
@@ -0,0 +1,102 @@
+/* $Id$ */
+/** @file
+ * VBoxMouse; input_server filter - 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <Clipboard.h>
+#include <Debug.h>
+#include <Message.h>
+#include <String.h>
+
+#include "VBoxMouseFilter.h"
+#include <VBox/VBoxGuest.h> /** @todo use the VbglR3 interface! */
+#include <VBox/VBoxGuestLib.h>
+#include <VBoxGuestInternal.h>
+#include <VBox/VMMDev.h>
+#include <VBox/log.h>
+#include <iprt/err.h>
+
+// TODO can this be merged with VBoxMouse?
+
+RTDECL(BInputServerFilter*)
+instantiate_input_filter()
+{
+	return new VBoxMouseFilter();
+}
+
+VBoxMouseFilter::VBoxMouseFilter()
+	: BInputServerFilter(),
+	fDriverFD(-1),
+	fServiceThreadID(-1),
+	fExiting(false),
+	fCurrentButtons(0)
+{
+}
+
+VBoxMouseFilter::~VBoxMouseFilter()
+{
+}
+
+filter_result VBoxMouseFilter::Filter(BMessage* message, BList* outList)
+{
+	switch(message->what) {
+		case B_MOUSE_UP:
+		case B_MOUSE_DOWN:
+		{
+			printf("click|release\n");
+			message->FindInt32("buttons", &fCurrentButtons);
+		}
+		case B_MOUSE_MOVED:
+		{
+			printf("mouse moved\n");
+			message->ReplaceInt32("buttons", fCurrentButtons);
+		}
+	}
+
+	return B_DISPATCH_MESSAGE;
+}
Index: /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouseFilter.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouseFilter.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxMouse/VBoxMouseFilter.h	(revision 43363)
@@ -0,0 +1,75 @@
+/* $Id$ */
+/** @file
+ * VBoxMouse; input_server filter - 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 __VBOXMOUSE__H
+#define __VBOXMOUSE__H
+
+#include <InputServerFilter.h>
+
+extern "C" _EXPORT BInputServerFilter* instantiate_input_filter();
+
+class VBoxMouseFilter : public BInputServerFilter {
+public:
+	VBoxMouseFilter();
+	virtual ~VBoxMouseFilter();
+// 	virtual status_t InitCheck();
+	virtual filter_result Filter(BMessage* message, BList* outList);
+
+private:
+
+static status_t	_ServiceThreadNub(void *_this);
+	status_t	_ServiceThread();
+
+	int			fDriverFD;
+	thread_id	fServiceThreadID;
+	bool		fExiting;
+	bool		fEnabled;
+	int32		fCurrentButtons;
+};
+
+
+#endif /* __VBOXMOUSE__H */
+
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/Makefile.kmk	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/Makefile.kmk	(revision 43363)
@@ -0,0 +1,118 @@
+# $Id$
+## @file
+# Sub-Makefile for VBoxTray, Haiku Guest Additions.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../../..
+include	$(KBUILD_PATH)/subheader.kmk
+
+# @todo split the tray code,
+# single bin will cause problems loading gcc4 binary from a gcc2-built Deskbar!
+
+PROGRAMS += VBoxTray
+VBoxTray_TEMPLATE = VBOXGUESTR3EXE
+VBoxTray_DEFS     = VBOX_WITH_HGCM LOG_TO_BACKDOOR
+VBoxTray_DEFS    += LOG_ENABLED
+VBoxTray_INCS     = ../include
+VBoxTray_SOURCES  = \
+	VBoxClipboard.cpp \
+	VBoxDisplay.cpp \
+	VBoxGuestApplication.cpp \
+	VBoxGuestDeskbarView.cpp
+
+VBoxTray_SOURCES += \
+  	$(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-helper.cpp
+
+VBoxTray_LIBS     = \
+	be translation \
+	$(VBOX_LIB_VBGL_R3) \
+	$(VBOX_LIB_IPRT_GUEST_R3) \
+	$(VBOX_LIB_VBGL_R3)
+
+VBoxTray_RSRCS   += $(VBoxTray_0_OUTDIR)/VBoxTray.rsrc
+VBoxTray_DEPS    += $(VBoxTray_0_OUTDIR)/VBoxTray.rsrc
+VBoxTray_CLEAN   += $(VBoxTray_0_OUTDIR)/VBoxTray.rsrc
+
+# VBoxGuestApplication.cpp uses VBOX_SVN_REV.
+VBoxGuestApplication.cpp_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV)
+VBoxGuestApplication.cpp_DEPS = $(VBOX_SVN_REV_KMK)
+VBoxGuestDeskbarView.cpp_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV)
+VBoxGuestDeskbarView.cpp_DEPS = $(VBOX_SVN_REV_KMK)
+
+## The icon location is configurable.
+VBoxTray.rdef_INCS = $(VBoxTray_0_OUTDIR)
+VBoxTray.rdef_DEFS += VBOX_SVN_REV=$(VBOX_SVN_REV) \
+	VBOX_HAIKU_DESKBAR_ICON_PNG=\"$(VBOX_BRAND_GUI_VBOX_16PX_PNG)\"
+VBoxTray.rdef_DEPS = $(VBOX_SVN_REV_KMK)
+
+VBoxTray.rsrc_DEPS = VBoxTray.rdef
+VBoxTray.rsrc_CLEAN = VBoxTray.rdef
+
+
+
+#XXX: cleanup!
+#XXX: handle deps correctly
+#XXX: -I / is due to a bug in rc with absolute paths
+## Resource file.
+$$(VBoxTray_0_OUTDIR)/VBoxTray.rsrc: $$(VBoxTray_DEFPATH)/VBoxTray.rdef $$(VBoxTray_DEFPATH)/Makefile.kmk | $$(dir $$@)
+	$(call MSG_TOOL,$(VBOX_HAIKU_RCTOOL),HaikuResources,$<,$@)
+	$(QUIET)cat $< | gcc -E -I $(dir $<) -I $(dir $<)/../include $(foreach name, $(INCS), -I $(name)) $(foreach dname, $(VBoxTray.rdef_DEFS), -D$(dname)) - | grep -v '^#' | $(VBOX_HAIKU_RCTOOL) -I / -I $(dir $<) -I $(dir $<)/../include -o "$@" -
+
+
+#	rc -I $(VBoxTray_DEFPATH)/../include -o $@ $<
+#	$(RM) -f $@
+#	$(APPEND) $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ADDITIONS_ICON_FILE))"'
+
+## The icon location is configurable.
+#VBoxTray.rc_INCS = $(VBoxTray_0_OUTDIR)
+#VBoxTray.rc_DEPS = $(VBoxTray_0_OUTDIR)/VBoxTray-icon.rc
+#VBoxTray.rc_CLEAN = $(VBoxTray_0_OUTDIR)/VBoxTray-icon.rc
+
+## Icon include file.
+#$$(VBoxTray_0_OUTDIR)/VBoxTray-icon.rc: $(VBOX_WINDOWS_ADDITIONS_ICON_FILE) $$(VBoxTray_DEFPATH)/Makefile.kmk | $$(dir $$@)
+#	$(RM) -f $@
+#	$(APPEND) $@ 'IDI_VIRTUALBOX ICON DISCARDABLE "$(subst /,\\,$(VBOX_WINDOWS_ADDITIONS_ICON_FILE))"'
+
+include	$(KBUILD_PATH)/subfooter.kmk
+
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.cpp	(revision 43363)
@@ -0,0 +1,424 @@
+/* $Id$ */
+/** @file
+ * VBoxClipboard; 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <new>
+#include <Bitmap.h>
+#include <BitmapStream.h>
+#include <Clipboard.h>
+#include <DataIO.h>
+#include <Message.h>
+#include <TranslationUtils.h>
+#include <TranslatorFormats.h>
+#include <TranslatorRoster.h>
+#include <String.h>
+
+#include "VBoxGuestApplication.h"
+#include "VBoxClipboard.h"
+#include <VBoxGuestInternal.h>
+
+#include <iprt/mem.h>
+#include <VBox/GuestHost/clipboard-helper.h>
+#include <VBox/HostServices/VBoxClipboardSvc.h>
+#include <VBox/log.h>
+
+#undef Log
+#define Log(x) printf x
+#undef LogRel
+#define LogRel(x) printf x
+#undef LogRelFlowFunc
+#define LogRelFlowFunc(x) printf x
+
+VBoxClipboardService::VBoxClipboardService()
+	: BHandler("VBoxClipboardService"),
+	fClientId(-1),
+	fServiceThreadID(-1),
+	fExiting(false)
+{
+}
+
+VBoxClipboardService::~VBoxClipboardService()
+{
+}
+
+status_t VBoxClipboardService::Connect()
+{
+	status_t err;
+    printf("VBoxClipboardService::%s()\n", __FUNCTION__);
+
+    int rc = VbglR3ClipboardConnect(&fClientId);
+    if (RT_SUCCESS (rc)) {
+		err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
+			"VBoxClipboardService", B_NORMAL_PRIORITY, this);
+
+		if (err >= B_OK) {
+			resume_thread(fServiceThreadID);
+
+			err = be_clipboard->StartWatching(BMessenger(this));
+			printf("be_clipboard->StartWatching: %ld\n", err);
+			if (err == B_OK)
+				return B_OK;
+			else
+		        LogRel(("VBoxClipboardService: Error watching the system clipboard: %ld\n", err));
+		} else
+	        LogRel(("VBoxClipboardService: Error starting service thread: %ld\n", err));
+
+		//rc = RTErrConvertFromErrno(err);
+        VbglR3ClipboardDisconnect(fClientId);
+	} else
+        LogRel(("VBoxClipboardService: Error starting service thread: %d\n", rc));
+   	 return B_ERROR;
+}
+
+status_t VBoxClipboardService::Disconnect()
+{
+	status_t status;
+
+	be_clipboard->StopWatching(BMessenger(this));
+
+	fExiting = true;
+
+    VbglR3ClipboardDisconnect(fClientId);
+
+	wait_for_thread(fServiceThreadID, &status);
+    return B_OK;
+}
+
+void VBoxClipboardService::MessageReceived(BMessage* message)
+{
+	uint32_t formats = 0;
+	message->PrintToStream();
+	switch (message->what) {
+		case VBOX_GUEST_CLIPBOARD_HOST_MSG_FORMATS:
+		{
+			int rc;
+			uint32_t cb;
+			void *pv;
+			bool commit = false;
+
+			if (message->FindInt32("Formats", (int32 *)&formats) != B_OK)
+				break;
+
+			if (!formats)
+				break;
+			if (!be_clipboard->Lock())
+				break;
+
+			be_clipboard->Clear();
+			BMessage *clip = be_clipboard->Data();
+			if (!clip) {
+				be_clipboard->Unlock();
+				break;
+			}
+
+			if (formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) {
+				pv = _VBoxReadHostClipboard(VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &cb);
+				if (pv) {
+					char *text;
+					rc = RTUtf16ToUtf8((PCRTUTF16)pv, &text);
+                    if (RT_SUCCESS(rc))
+                    {
+                    	BString str(text);
+                    	// @todo use vboxClipboardUtf16WinToLin()
+                    	// convert Windows CRLF to LF
+                    	str.ReplaceAll("\r\n", "\n");
+                    	// don't include the \0
+        				clip->AddData("text/plain", B_MIME_TYPE, str.String(), str.Length());
+        				RTStrFree(text);
+        				commit = true;
+                    }
+					free(pv);
+				}
+			}
+
+			if (formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) {
+				pv = _VBoxReadHostClipboard(VBOX_SHARED_CLIPBOARD_FMT_BITMAP, &cb);
+				if (pv) {
+					void *pBmp;
+					size_t cbBmp;
+					rc = vboxClipboardDibToBmp(pv, cb, &pBmp, &cbBmp);
+                    if (RT_SUCCESS(rc))
+                    {
+                    	BMemoryIO mio(pBmp, cbBmp);
+                    	BBitmap *bitmap = BTranslationUtils::GetBitmap(&mio);
+                    	if (bitmap)
+                    	{
+                    		BMessage bitmapArchive;
+                    		if (bitmap->IsValid() &&
+                    			bitmap->Archive(&bitmapArchive) == B_OK &&
+                    			clip->AddMessage("image/bitmap", &bitmapArchive) == B_OK)
+                    		{
+	        					commit = true;
+                    		}
+       						delete bitmap;
+                    	}
+                    	RTMemFree(pBmp);
+                    }
+					free(pv);
+				}
+			}
+
+			/* make sure we don't bounce this data back to the host,
+			 * it's impolite.
+			 * It can also be used as a hint to applications probably. */
+			clip->AddBool("FromVirtualBoxHost", true);
+
+			if (commit)
+				be_clipboard->Commit();
+			be_clipboard->Unlock();
+			break;
+		}
+
+		case VBOX_GUEST_CLIPBOARD_HOST_MSG_READ_DATA:
+		{
+			int rc;
+
+			if (message->FindInt32("Formats", (int32 *)&formats) != B_OK)
+				break;
+
+			if (!formats)
+				break;
+			if (!be_clipboard->Lock())
+				break;
+
+			BMessage *clip = be_clipboard->Data();
+			if (!clip) {
+				be_clipboard->Unlock();
+				break;
+			}
+			clip->PrintToStream();
+
+			if (formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) {
+				const char *text;
+				int32 textLen;
+				if (clip->FindData("text/plain", B_MIME_TYPE, (const void **)&text, &textLen) == B_OK) {
+                   	// usually doesn't include the \0 so be safe
+					BString str(text, textLen);
+					// convert from LF to Windows CRLF
+					str.ReplaceAll("\n", "\r\n");
+                    PRTUTF16 pwsz;
+                    rc = RTStrToUtf16(str.String(), &pwsz);
+                    if (RT_SUCCESS(rc))
+                    {
+                        uint32_t cb = (RTUtf16Len(pwsz) + 1) * sizeof(RTUTF16);
+
+			        	rc = VbglR3ClipboardWriteData(fClientId,
+			        		VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, pwsz, cb);
+						//printf("VbglR3ClipboardWriteData: %d\n", rc);
+
+        				RTUtf16Free(pwsz);
+                    }
+				}
+			}
+			else if (formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
+			{
+				BMessage archivedBitmap;
+				if (clip->FindMessage("image/bitmap", &archivedBitmap) == B_OK ||
+					clip->FindMessage("image/x-be-bitmap", &archivedBitmap) == B_OK) {
+					BBitmap *bitmap = new(std::nothrow) BBitmap(&archivedBitmap);
+					if (bitmap)
+					{
+						// Don't delete bitmap, BBitmapStream will.
+						BBitmapStream stream(bitmap);
+						BTranslatorRoster *roster = BTranslatorRoster::Default();
+						if (roster && bitmap->IsValid())
+						{
+							BMallocIO bmpStream;
+							if (roster->Translate(&stream, NULL, NULL, &bmpStream, B_BMP_FORMAT) == B_OK)
+							{
+								const void *pDib;
+								size_t cbDibSize;
+								/* Strip out the BM header */
+								rc = vboxClipboardBmpGetDib(bmpStream.Buffer(), bmpStream.BufferLength(), &pDib, &cbDibSize);
+								if (RT_SUCCESS(rc))
+								{
+					        	    rc = VbglR3ClipboardWriteData(fClientId,
+					        		    VBOX_SHARED_CLIPBOARD_FMT_BITMAP, (void *)pDib, cbDibSize);
+								}
+							}
+						}
+					}
+				}
+			}
+
+			be_clipboard->Unlock();
+			break;
+		}
+
+		case B_CLIPBOARD_CHANGED:
+		{
+			printf("B_CLIPBOARD_CHANGED\n");
+			const void *data;
+			int32 dataLen;
+			if (!be_clipboard->Lock())
+				break;
+
+			BMessage *clip = be_clipboard->Data();
+			if (!clip) {
+				be_clipboard->Unlock();
+				break;
+			}
+
+			bool fromVBox;
+			if (clip->FindBool("FromVirtualBoxHost", &fromVBox) == B_OK && fromVBox) {
+				// It already comes from the host, discard.
+				be_clipboard->Unlock();
+				break;
+			}
+
+			if (clip->FindData("text/plain", B_MIME_TYPE, &data, &dataLen) == B_OK)
+				formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
+			if (clip->HasMessage("image/bitmap") || clip->HasMessage("image/x-be-bitmap"))
+				formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
+
+			be_clipboard->Unlock();
+
+		    VbglR3ClipboardReportFormats(fClientId, formats);
+			break;
+		}
+
+		case B_QUIT_REQUESTED:
+			fExiting = true;
+			break;
+
+		default:
+			BHandler::MessageReceived(message);
+	}
+}
+
+status_t VBoxClipboardService::_ServiceThreadNub(void *_this)
+{
+	VBoxClipboardService *service = (VBoxClipboardService *)_this;
+	return service->_ServiceThread();
+}
+
+status_t VBoxClipboardService::_ServiceThread()
+{
+    printf("VBoxClipboardService::%s()\n", __FUNCTION__);
+
+    /* The thread waits for incoming messages from the host. */
+    for (;;)
+    {
+        uint32_t u32Msg;
+        uint32_t u32Formats;
+        int rc = VbglR3ClipboardGetHostMsg(fClientId, &u32Msg, &u32Formats);
+        if (RT_SUCCESS(rc)) {
+            switch (u32Msg) {
+                case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS:
+                {
+                    /* The host has announced available clipboard formats.
+                     * Forward the information to the handler. */
+                    LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS u32Formats=%x\n", u32Formats));
+                    BMessage msg(VBOX_GUEST_CLIPBOARD_HOST_MSG_FORMATS);
+                    msg.AddInt32("Formats", (uint32)u32Formats);
+                    Looper()->PostMessage(&msg, this);
+                    break;
+                }
+
+                case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA:
+                {
+                    /* The host needs data in the specified format. */
+                    LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA u32Formats=%x\n", u32Formats));
+                    BMessage msg(VBOX_GUEST_CLIPBOARD_HOST_MSG_READ_DATA);
+                    msg.AddInt32("Formats", (uint32)u32Formats);
+                    Looper()->PostMessage(&msg, this);
+                    break;
+                }
+
+                case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT:
+                {
+                    /* The host is terminating. */
+                    LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT\n"));
+					fExiting = true;
+                    return VERR_INTERRUPTED;
+                }
+
+                default:
+                    Log(("VBoxClipboardService::%s: Unsupported message from host! Message = %u\n", __FUNCTION__, u32Msg));
+            }
+        } else
+        	fExiting = true;
+
+        LogRelFlow(("processed host event rc = %d\n", rc));
+
+        if (fExiting)
+        	break;
+    }
+	return 0;
+}
+
+
+void *VBoxClipboardService::_VBoxReadHostClipboard(uint32_t format, uint32_t *pcb)
+{
+	uint32_t cb = 1024;
+	void *pv;
+	int rc;
+
+	pv = malloc(cb);
+	if (pv == NULL)
+		return NULL;
+
+	rc = VbglR3ClipboardReadData(fClientId, format, pv, cb, pcb);
+    if (RT_SUCCESS(rc) && (rc != VINF_BUFFER_OVERFLOW))
+        return pv;
+    if (rc == VINF_BUFFER_OVERFLOW)
+    {
+	    free(pv);
+	    cb = *pcb;
+    	pv = malloc(cb);
+		if (pv == NULL)
+			return NULL;
+
+		rc = VbglR3ClipboardReadData(fClientId, format, pv, cb, pcb);
+    	if (RT_SUCCESS(rc) && (rc != VINF_BUFFER_OVERFLOW))
+	        return pv;
+
+	    free(pv);
+    }
+    return NULL;
+}
+
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxClipboard.h	(revision 43363)
@@ -0,0 +1,76 @@
+/* $Id$ */
+/** @file
+ * VBoxClipboard, 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 __VBOXSERVICESHAREDCLIPLBOARD__H
+#define __VBOXSERVICESHAREDCLIPLBOARD__H
+
+#include <Handler.h>
+
+class VBoxClipboardService : public BHandler {
+public:
+	VBoxClipboardService();
+	virtual ~VBoxClipboardService();
+
+	virtual status_t	Connect();
+	virtual status_t	Disconnect();
+
+	virtual	void		MessageReceived(BMessage* message);
+
+private:
+
+static status_t	_ServiceThreadNub(void *_this);
+	status_t	_ServiceThread();
+
+	void		*_VBoxReadHostClipboard(uint32_t format, uint32_t *pcb);
+
+	uint32_t	fClientId;
+	thread_id	fServiceThreadID;
+	bool		fExiting;
+
+};
+
+
+#endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.cpp	(revision 43363)
@@ -0,0 +1,161 @@
+/* $Id$ */
+/** @file
+ * VBoxDisplayService, 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <new>
+#include <DataIO.h>
+#include <Message.h>
+#include <TranslationUtils.h>
+#include <TranslatorFormats.h>
+#include <TranslatorRoster.h>
+#include <String.h>
+
+#include "VBoxGuestApplication.h"
+#include "VBoxDisplay.h"
+#include <VBoxGuestInternal.h>
+#include "../VBoxVideo/common/VBoxVideo_common.h"
+
+#include <iprt/mem.h>
+#include <VBox/log.h>
+
+#undef Log
+#define Log(x) printf x
+#undef LogRel
+#define LogRel(x) printf x
+#undef LogRelFlowFunc
+#define LogRelFlowFunc(x) printf x
+
+VBoxDisplayService::VBoxDisplayService()
+	: BHandler("VBoxDisplayService"),
+	fClientId(-1),
+	fServiceThreadID(-1),
+	fExiting(false),
+	fScreen(B_MAIN_SCREEN_ID)
+{
+}
+
+VBoxDisplayService::~VBoxDisplayService()
+{
+}
+
+void VBoxDisplayService::Start()
+{
+	status_t err;
+	err = fServiceThreadID = spawn_thread(_ServiceThreadNub,
+		"VBoxDisplayService", B_NORMAL_PRIORITY, this);
+
+	if (err >= B_OK) {
+		resume_thread(fServiceThreadID);
+	} else
+		LogRel(("VBoxDisplayService: Error starting service thread: %s\n", strerror(err)));
+
+}
+
+void VBoxDisplayService::MessageReceived(BMessage* message)
+{
+	if (message->what == B_QUIT_REQUESTED)
+		fExiting = true;
+	else
+		BHandler::MessageReceived(message);
+}
+
+status_t VBoxDisplayService::_ServiceThreadNub(void *_this)
+{
+	VBoxDisplayService *service = (VBoxDisplayService *)_this;
+	return service->_ServiceThread();
+}
+
+status_t VBoxDisplayService::_ServiceThread()
+{
+    printf("VBoxDisplayService::%s()\n", __FUNCTION__);
+
+    VbglR3CtlFilterMask(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 0);
+	VbglR3SetGuestCaps(VMMDEV_GUEST_SUPPORTS_GRAPHICS, 0);
+
+    for (;;) {
+		uint32_t events;
+
+		int rc = VbglR3WaitEvent(VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST, 5000, &events);
+		if (rc == -6) // timed out?
+			continue;
+
+		if (RT_SUCCESS(rc)) {
+			uint32_t cx, cy, cBits, iDisplay;
+            int rc2 = VbglR3GetDisplayChangeRequest(&cx, &cy, &cBits, &iDisplay, true);
+			printf("rc2=%d screen %d size changed (%d, %d, %d)\n", rc2, iDisplay, cx, cy, cBits);
+
+			if (RT_SUCCESS(rc2)) {
+				display_mode mode;
+				fScreen.GetMode(&mode);
+				if (cBits == 0) {
+					cBits = get_depth_for_color_space(mode.space);
+				}
+				mode.timing.h_display = cx;
+				mode.timing.v_display = cy;
+				mode.space = get_color_space_for_depth(cBits);
+				mode.virtual_width = cx;
+				mode.virtual_height = cy;
+
+				/*= {
+					{0, cx, 0, 0, cBits * cx / 8, cy, 0, 0, cBits * cy / 8, 0},
+					get_color_space_for_depth(cBits),
+					cx, cy, 0, 0, 0
+				};*/
+
+				fScreen.SetMode(&mode, false);
+			}
+        }
+        else
+        	fExiting = true;
+
+        LogRelFlow(("processed host event rc = %d\n", rc));
+
+        if (fExiting)
+        	break;
+    }
+	return 0;
+}
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxDisplay.h	(revision 43363)
@@ -0,0 +1,74 @@
+/* $Id$ */
+/** @file
+ * VBoxDisplayService, 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 __VBOXDISPLAY__H
+#define __VBOXDISPLAY__H
+
+#include <Handler.h>
+#include <Screen.h>
+
+class VBoxDisplayService : public BHandler {
+public:
+	VBoxDisplayService();
+	virtual ~VBoxDisplayService();
+
+	void		Start();
+
+	virtual	void		MessageReceived(BMessage* message);
+
+private:
+
+static status_t	_ServiceThreadNub(void *_this);
+	status_t	_ServiceThread();
+
+	uint32_t	fClientId;
+	thread_id	fServiceThreadID;
+volatile bool	fExiting;
+	BScreen		fScreen;
+};
+
+
+#endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestApplication.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestApplication.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestApplication.cpp	(revision 43363)
@@ -0,0 +1,117 @@
+/* $Id$ */
+/** @file
+ * VBoxGuestApplication, 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 <errno.h>
+#define DEBUG 1
+#include <Alert.h>
+#include <Debug.h>
+#include <Invoker.h>
+#include <String.h>
+
+#include "VBoxClipboard.h"
+#include "VBoxGuestApplication.h"
+#include "VBoxGuestDeskbarView.h"
+
+VBoxGuestApplication::VBoxGuestApplication()
+	: BApplication(VBOX_GUEST_APP_SIG)
+{
+	PRINT(("%s()\n", __FUNCTION__));
+}
+
+VBoxGuestApplication::~VBoxGuestApplication()
+{
+	PRINT(("%s()\n", __FUNCTION__));
+}
+
+void VBoxGuestApplication::ReadyToRun()
+{
+	status_t err;
+
+	err = VBoxGuestDeskbarView::AddToDeskbar();
+	PRINT(("%s: VBoxGuestDeskbarView::AddToDeskbar: 0x%08lx\n", __FUNCTION__, err));
+
+	exit(0);
+}
+
+int main(int argc, const char **argv)
+{
+	new VBoxGuestApplication();
+	be_app->Run();
+	delete be_app;
+
+/*    int rc = RTR3Init();
+    if (RT_SUCCESS(rc))
+    {
+        rc = VbglR3Init();
+        if (RT_SUCCESS(rc))
+            rc = vboxOpenBaseDriver();
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+	    Log(("VBoxGuestApp: Init successful\n"));
+
+		new VBoxGuestApplication(gVBoxDriverFD);
+		be_app->Run();
+		delete be_app;
+
+    }
+
+	if (RT_FAILURE(rc))
+    {
+        LogRel(("VBoxGuestApp: Error while starting, rc=%Rrc\n", rc));
+    }
+    LogRel(("VBoxGuestApp: Ended\n"));
+
+	vboxCloseBaseDriver();
+
+    VbglR3Term();*/
+
+	return 0;
+}
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestApplication.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestApplication.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestApplication.h	(revision 43363)
@@ -0,0 +1,73 @@
+/* $Id$ */
+/** @file
+ * VBoxGuestApplication, 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 __VBOXGUESTAPPLICATION__H
+#define __VBOXGUESTAPPLICATION__H
+
+#include <Application.h>
+
+#include <iprt/initterm.h>
+#include <iprt/string.h>
+
+#include <VBox/version.h>
+#include <VBox/log.h>
+#include <VBox/VBoxGuest.h> /** @todo use the VbglR3 interface! */
+#include <VBox/VBoxGuestLib.h>
+
+#include <VBoxGuestInternal.h>
+
+class VBoxClipboardService;
+
+class VBoxGuestApplication : public BApplication {
+public:
+	VBoxGuestApplication();
+	virtual ~VBoxGuestApplication();
+
+	virtual void ReadyToRun();
+};
+
+#endif /* __VBOXGUESTAPPLICATION__H */
+
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.cpp	(revision 43363)
@@ -0,0 +1,277 @@
+/* $Id$ */
+/** @file
+ * VBoxGuestDeskbarView, 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 <errno.h>
+#define DEBUG 1
+#include <Alert.h>
+#include <Roster.h>
+#include <Debug.h>
+#include <Deskbar.h>
+#include <File.h>
+#include <MenuItem.h>
+#include <Path.h>
+#include <PopUpMenu.h>
+#include <Resources.h>
+#include <String.h>
+#include <TranslationUtils.h>
+
+#include "VBoxGuestDeskbarView.h"
+#include "VBoxGuestApplication.h"
+
+#define VIEWNAME "VBoxGuestDeskbarView"
+
+static status_t
+our_image(image_info& image)
+{
+	/** @todo r=ramshankar: find a way to do this without annoying the compiler, probably uintptr_t? */
+	int32 cookie = 0;
+	while (get_next_image_info(B_CURRENT_TEAM, &cookie, &image) == B_OK) {
+		if ((char *)our_image >= (char *)image.text
+			&& (char *)our_image <= (char *)image.text + image.text_size)
+			return B_OK;
+	}
+
+	return B_ERROR;
+}
+
+
+VBoxGuestDeskbarView::VBoxGuestDeskbarView()
+	: BView(BRect(0, 0, 15, 15), VIEWNAME, B_FOLLOW_NONE,
+		B_WILL_DRAW | B_NAVIGABLE),
+	fIcon(NULL), fClipboardService(NULL), fDisplayService(NULL)
+{
+	PRINT(("%s()\n", __FUNCTION__));
+	_Init();
+}
+
+VBoxGuestDeskbarView::VBoxGuestDeskbarView(BMessage *archive)
+	: BView(archive),
+	fIcon(NULL)
+{
+	PRINT(("%s()\n", __FUNCTION__));
+	archive->PrintToStream();
+
+	_Init(archive);
+}
+
+VBoxGuestDeskbarView::~VBoxGuestDeskbarView()
+{
+	PRINT(("%s()\n", __FUNCTION__));
+	delete fIcon;
+	if (fClipboardService) {
+		fClipboardService->Disconnect();
+		delete fClipboardService;
+	}
+	VbglR3Term();
+}
+
+BArchivable *VBoxGuestDeskbarView::Instantiate(BMessage *data)
+{
+	PRINT(("%s()\n", __FUNCTION__));
+	if (!validate_instantiation(data, VIEWNAME))
+		return NULL;
+
+	return new VBoxGuestDeskbarView(data);
+}
+
+status_t VBoxGuestDeskbarView::Archive(BMessage *data, bool deep) const
+{
+	status_t err;
+	PRINT(("%s()\n", __FUNCTION__));
+
+	err = BView::Archive(data, false);
+	if (err < B_OK)
+		return err;
+	data->AddString("add_on", VBOX_GUEST_APP_SIG);
+	data->AddString("class", "VBoxGuestDeskbarView");
+	return B_OK;
+}
+
+void VBoxGuestDeskbarView::Draw(BRect rect)
+{
+	SetDrawingMode(B_OP_ALPHA);
+	DrawBitmap(fIcon);
+}
+
+void VBoxGuestDeskbarView::AttachedToWindow()
+{
+	BView::AttachedToWindow();
+	if (Parent()) {
+		SetViewColor(Parent()->ViewColor());
+		SetLowColor(Parent()->LowColor());
+	}
+
+	if (fClipboardService) { // don't repeatedly crash deskbar if vboxdev not loaded
+		Looper()->AddHandler(fClipboardService);
+		fClipboardService->Connect();
+	}
+
+	if (fDisplayService) {
+		fDisplayService->Start();
+	}
+}
+
+void VBoxGuestDeskbarView::DetachedFromWindow()
+{
+	BMessage message(B_QUIT_REQUESTED);
+	fClipboardService->MessageReceived(&message);
+	fDisplayService->MessageReceived(&message);
+}
+
+void VBoxGuestDeskbarView::MouseDown(BPoint point)
+{
+	printf("MouseDown\n");
+	int32 buttons = B_PRIMARY_MOUSE_BUTTON;
+	if (Looper() != NULL && Looper()->CurrentMessage() != NULL)
+		Looper()->CurrentMessage()->FindInt32("buttons", &buttons);
+
+	BPoint where = ConvertToScreen(point);
+
+	if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) {
+		BPopUpMenu* menu = new BPopUpMenu(B_EMPTY_STRING, false, false);
+		menu->SetAsyncAutoDestruct(true);
+		menu->SetFont(be_plain_font);
+
+		menu->AddItem(new BMenuItem("Quit", new BMessage(B_QUIT_REQUESTED)));
+		menu->SetTargetForItems(this);
+
+		menu->Go(where, true, true, true);
+	}
+}
+
+void VBoxGuestDeskbarView::MessageReceived(BMessage* message)
+{
+	if (message->what == B_QUIT_REQUESTED)
+		RemoveFromDeskbar();
+	else
+		BHandler::MessageReceived(message);
+}
+
+status_t VBoxGuestDeskbarView::AddToDeskbar(bool force)
+{
+	BDeskbar deskbar;
+	status_t err;
+	PRINT(("%s()\n", __FUNCTION__));
+
+	if (force)
+		RemoveFromDeskbar();
+	else if (deskbar.HasItem(VIEWNAME))
+		return B_OK;
+
+	app_info info;
+	err = be_app->GetAppInfo(&info);
+	PRINT(("%s: be_app->GetAppInfo: 0x%08lx\n", __FUNCTION__, err));
+	if (err < B_OK)
+		return err;
+
+	BPath p(&info.ref);
+	PRINT(("%s: app path: '%s'\n", __FUNCTION__, p.Path()));
+
+	return deskbar.AddItem(&info.ref);
+}
+
+status_t VBoxGuestDeskbarView::RemoveFromDeskbar()
+{
+	BDeskbar deskbar;
+	PRINT(("%s()\n", __FUNCTION__));
+
+	return deskbar.RemoveItem(VIEWNAME);
+}
+
+status_t VBoxGuestDeskbarView::_Init(BMessage *archive)
+{
+	BString toolTipText;
+	toolTipText << VBOX_PRODUCT << " Guest Additions ";
+	toolTipText << VBOX_VERSION_MAJOR << "." << VBOX_VERSION_MINOR << "." << VBOX_VERSION_BUILD;
+	toolTipText << "r" << VBOX_SVN_REV;
+
+	SetToolTip(toolTipText.String());
+
+	image_info info;
+	if (our_image(info) != B_OK)
+		return B_ERROR;
+
+	BFile file(info.name, B_READ_ONLY);
+	if (file.InitCheck() < B_OK)
+		return B_ERROR;
+
+	BResources resources(&file);
+	if (resources.InitCheck() < B_OK)
+		return B_ERROR;
+
+	const void* data = NULL;
+	size_t size;
+	//data = resources.LoadResource(B_VECTOR_ICON_TYPE,
+	//	kNetworkStatusNoDevice + i, &size);
+	data = resources.LoadResource('data', 400, &size);
+	if (data != NULL) {
+		BMemoryIO mem(data, size);
+		fIcon = BTranslationUtils::GetBitmap(&mem);
+	}
+
+    int rc = RTR3InitDll(0);
+	printf("%d\n", rc);
+    if (RT_SUCCESS(rc)) {
+        rc = VbglR3Init();
+    }
+	printf("%d\n", rc);
+	if (RT_SUCCESS(rc)) {
+		fClipboardService = new VBoxClipboardService();
+		fDisplayService = new VBoxDisplayService();
+	}
+
+	return RTErrConvertToErrno(rc);
+}
+
+extern "C" BView*
+instantiate_deskbar_item(void)
+{
+	PRINT(("%s()\n", __FUNCTION__));
+	return new VBoxGuestDeskbarView();
+}
+
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxGuestDeskbarView.h	(revision 43363)
@@ -0,0 +1,93 @@
+/* $Id$ */
+/** @file
+ * VBoxGuestDeskbarView, 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 __VBOXGUESTTRAYVIEW__H
+#define __VBOXGUESTTRAYVIEW__H
+
+#include <Bitmap.h>
+#include <View.h>
+
+#include <iprt/initterm.h>
+#include <iprt/string.h>
+
+#include <VBox/version.h>
+#include <VBox/log.h>
+#include <VBox/VBoxGuest.h> /** @todo use the VbglR3 interface! */
+#include <VBox/VBoxGuestLib.h>
+
+#include <VBoxGuestInternal.h>
+#include "VBoxClipboard.h"
+#include "VBoxDisplay.h"
+
+#define REMOVE_FROM_DESKBAR_MSG 'vbqr'
+
+class VBoxGuestDeskbarView : public BView {
+public:
+			VBoxGuestDeskbarView();
+			VBoxGuestDeskbarView(BMessage *archive);
+	virtual ~VBoxGuestDeskbarView();
+	static  BArchivable	*Instantiate(BMessage *data);
+	virtual	status_t	Archive(BMessage *data, bool deep = true) const;
+
+			void		Draw(BRect rect);
+			void		AttachedToWindow();
+			void		DetachedFromWindow();
+
+	virtual	void		MouseDown(BPoint point);
+	virtual void		MessageReceived(BMessage* message);
+
+	static status_t		AddToDeskbar(bool force=true);
+	static status_t		RemoveFromDeskbar();
+
+private:
+	status_t			_Init(BMessage *archive=NULL);
+	BBitmap				*fIcon;
+
+	VBoxClipboardService *fClipboardService;
+	VBoxDisplayService *fDisplayService;
+};
+
+#endif /* __VBOXGUESTTRAYVIEW__H */
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxServiceDescriptor.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxServiceDescriptor.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxServiceDescriptor.h	(revision 43363)
@@ -0,0 +1,67 @@
+/* $Id$ */
+/** @file
+ * VBoxGuestServiceDescriptor, 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 __VBOXSERVICESHAREDCLIPLBOARD__H
+#define __VBOXSERVICESHAREDCLIPLBOARD__H
+
+#include <Handler.h>
+
+class VBoxClipboardService : public BHandler {
+public:
+	VBoxClipboardService();
+	virtual ~VBoxClipboardService();
+
+private:
+
+};
+
+/* The shared clipboard service prototypes. */
+int                VBoxClipboardInit    (const VBOXSERVICEENV *pEnv, void **ppInstance, bool *pfStartThread);
+unsigned __stdcall VBoxClipboardThread  (void *pInstance);
+void               VBoxClipboardDestroy (const VBOXSERVICEENV *pEnv, void *pInstance);
+
+
+#endif /* __VBOXSERVICESHAREDCLIPLBOARD__H */
+
Index: /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxTray.rdef
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxTray.rdef	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxTray/VBoxTray.rdef	(revision 43363)
@@ -0,0 +1,106 @@
+/* $Id$ */
+/** @file
+ * VBoxApp - Resource definition file containing version info and icon, Haiku Guest Additions.
+ */
+
+/*
+ * 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.
+ */
+
+#include "VBoxGuestInternal.h"
+
+resource(1, "BEOS:APP_SIG") #'MIMS' VBOX_GUEST_APP_SIG;
+
+resource app_flags B_SINGLE_LAUNCH;
+
+/* This is done for all binaries with VBOX_HAIKU_XRES_SETVER_CMDS
+resource app_version {
+	major  = VBOX_VERSION_MAJOR,
+	middle = VBOX_VERSION_MINOR,
+	minor  = VBOX_VERSION_BUILD,
+
+	variety = B_APPV_DEVELOPMENT,
+	internal = VBOX_SVN_REV,
+
+	short_info = VBOX_PRODUCT,
+	long_info = VBOX_PRODUCT " " VBOX_VERSION_STRING " Â©2009-" VBOX_C_YEAR " " VBOX_VENDOR
+};
+*/
+
+/* Maybe one day ? */
+//resource(1, "BEOS:FILE_TYPES") message {
+//	"types" = "application/x-vnd.Be.URL.vboxsf"
+//};
+
+//FIXME
+#if 0
+resource vector_icon {
+	$"6E6369660A010100007503010000020106023D80000000000000003D80004900"
+	$"004A1000AAFFFFFFFF95BCDD020106023D00000000000000003D000048E00049"
+	$"2000AAFFFFFFFF95BCDD020106023C40000000000000003C4000492000474000"
+	$"AAFFFFFFFF95BCDD0387AFD1020106033772203457DEB6B0FC39F52B48F3ED48"
+	$"7E9B00FFDE069BFFAA00FFF67D06020106043D00000000000000003D000048C0"
+	$"0048C0005DFF000080C00505AAFF0000FFC00505020116023B00000000000000"
+	$"003B00004A2000450000005CFF00020106023A40000000000000003A40004480"
+	$"00448000AAFFFFFFFF95BCDD0C02043E36BA7D36C36A36524A52BF4552C8323E"
+	$"5EC36A5EBA7D5E2A4A2AC8322ABF4502043E30BB6230C285304E404EBC2E4EC3"
+	$"513E50C28550BB62502E402EC3512EBC2E02043E26BC4626C1A1264A324AB77E"
+	$"4ABCD93E3EC1A13EBC463E323232BCD932B77E02033C363C363C3438343A3238"
+	$"34343A3836383A020244364634423840343E3642320609BABB0349415346524E"
+	$"5149534856485C4D59495A49C967C2D85D475847594556464B3F4B3F493F060D"
+	$"F6EFFA023A41423646374436463747374738453A443A443A473B4B3B4B3E4B40"
+	$"4C404840483C463C423E40483A473D403E3337373C343A393F02024228442840"
+	$"28482C482E482A06041E3C3E4A3C44405038343C06042E3E50504A4C5054444E"
+	$"3E3E06042E3E5E5B585162654E524C3E02042822B4D922B786222E282EB4D92E"
+	$"B786282EB7862EB4D92E222822B78622B4D9160A00010A1001158200040A0101"
+	$"001001178400040A020100000A01010502BFFFFB30DC88B0DC88BFFFFB4C0172"
+	$"4B6C250A030109000A010101123FAC9D3D297FBCEE693F67F547B66BC686A701"
+	$"178400040A030101000A040108000A010104023FD07C3C6897BC68973FD07CC4"
+	$"8CCB45DE750A010104023FEC8F3B1A4DBB1A4D3FEC8FC5A41F4467140A070106"
+	$"000A010102123FBBBE3CDF30BC9B533F6386460747C668CA01178400040A0401"
+	$"02000A05010302C000000000000000004000004B40000000000A060103000A01"
+	$"0104023FDB50BC1F483C1F483FDB50C52D234631630A010104023C62D23EDA76"
+	$"BECEB13CF6DB49653CC7C4CB0A010105000A010107301E1E01178C00040A0801"
+	$"07301E1E01158800040A01010B1001178400040A09010B00"
+};
+#endif
+
+resource(400, "DeskbarShelfIcon.png") #'data' import VBOX_HAIKU_DESKBAR_ICON_PNG;
+
Index: /trunk/src/VBox/Additions/haiku/VBoxVideo/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxVideo/Makefile.kmk	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxVideo/Makefile.kmk	(revision 43363)
@@ -0,0 +1,54 @@
+# $Id$
+## @file
+# Sub-Makefile for Haiku VBoxVideo.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../../..
+include	$(KBUILD_PATH)/subheader.kmk
+
+include $(PATH_SUB_CURRENT)/accelerant/Makefile.kmk
+include $(PATH_SUB_CURRENT)/driver/Makefile.kmk
+
+include	$(KBUILD_PATH)/subfooter.kmk
+
Index: /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/Makefile.kmk	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/Makefile.kmk	(revision 43363)
@@ -0,0 +1,65 @@
+# $Id$
+## @file
+# Sub-Makefile for VBoxVideo accelerant, Haiku Guest Additions.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../../../..
+include	$(KBUILD_PATH)/subheader.kmk
+
+PROGRAMS += vboxvideo.accelerant
+vboxvideo.accelerant_TEMPLATE = VBOXGUESTR3EXE
+vboxvideo.accelerant_DEFS     = VBOX_WITH_HGCM LOG_TO_BACKDOOR
+vboxvideo.accelerant_DEFS    += LOG_ENABLED
+vboxvideo.accelerant_INCS     = ../include
+vboxvideo.accelerant_SOURCES  = \
+	accelerant.cpp
+
+vboxvideo.accelerant_LIBS     = \
+	be device \
+	$(VBOX_LIB_IPRT_GUEST_R3) \
+	$(VBOX_LIB_VBGL_R3) \
+	/system/servers/app_server
+
+include	$(KBUILD_PATH)/subfooter.kmk
+
Index: /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.cpp	(revision 43363)
@@ -0,0 +1,374 @@
+/* $Id$ */
+/** @file
+ * VBoxVideo Accelerant; 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.
+ */
+
+#include <Accelerant.h>
+#include "accelerant.h"
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#define TRACE(x...) do { FILE* logfile = fopen("/var/log/vboxvideo.accelerant.log", "a"); fprintf(logfile, x); fflush(logfile); fsync(fileno(logfile)); fclose(logfile); sync(); } while(0)
+
+class AreaCloner {
+	public:
+		AreaCloner() : fArea(-1) {}
+		~AreaCloner() {
+			if (fArea >= B_OK)
+				delete_area(fArea);
+		}
+
+		area_id Clone(const char *name, void **_address, uint32 spec, uint32 protection, area_id sourceArea) {
+			fArea = clone_area(name, _address, spec, protection, sourceArea);
+			return fArea;
+		}
+
+		status_t InitCheck() { return fArea < B_OK ? (status_t)fArea : B_OK; }
+		void Keep() { fArea = -1; }
+
+	private:
+		area_id	fArea;
+};
+
+AccelerantInfo gInfo;
+
+static engine_token sEngineToken = {1, 0 /*B_2D_ACCELERATION*/, NULL};
+
+extern "C" void* get_accelerant_hook(uint32 feature, void* data) {
+	TRACE("%s\n", __FUNCTION__);
+	switch (feature) {
+		/* general */
+		case B_INIT_ACCELERANT:
+			return (void*)vboxvideo_init_accelerant;
+		case B_UNINIT_ACCELERANT:
+			return (void*)vboxvideo_uninit_accelerant;
+		case B_CLONE_ACCELERANT:
+			return (void*)vboxvideo_clone_accelerant;
+		case B_ACCELERANT_CLONE_INFO_SIZE:
+			return (void*)vboxvideo_accelerant_clone_info_size;
+		case B_GET_ACCELERANT_CLONE_INFO:
+			return (void*)vboxvideo_get_accelerant_clone_info;
+		case B_GET_ACCELERANT_DEVICE_INFO:
+			return (void*)vboxvideo_get_accelerant_device_info;
+		case B_ACCELERANT_RETRACE_SEMAPHORE:
+			return (void*)vboxvideo_accelerant_retrace_semaphore;
+
+		/* mode configuration */
+		case B_ACCELERANT_MODE_COUNT:
+			return (void*)vboxvideo_accelerant_mode_count;
+		case B_GET_MODE_LIST:
+			return (void*)vboxvideo_get_mode_list;
+		case B_SET_DISPLAY_MODE:
+			return (void*)vboxvideo_set_display_mode;
+		case B_GET_DISPLAY_MODE:
+			return (void*)vboxvideo_get_display_mode;
+		case B_GET_EDID_INFO:
+			return (void*)vboxvideo_get_edid_info;
+		case B_GET_FRAME_BUFFER_CONFIG:
+			return (void*)vboxvideo_get_frame_buffer_config;
+		case B_GET_PIXEL_CLOCK_LIMITS:
+			return (void*)vboxvideo_get_pixel_clock_limits;
+
+		/* cursor managment */
+		/*case B_SET_CURSOR_SHAPE:
+			return (void*)vboxvideo_set_cursor_shape;
+		case B_MOVE_CURSOR:
+			return (void*)vboxvideo_move_cursor;
+		case B_SHOW_CURSOR:
+			return (void*)vboxvideo_show_cursor;*/
+
+		/* engine/synchronization */
+		case B_ACCELERANT_ENGINE_COUNT:
+			return (void*)vboxvideo_accelerant_engine_count;
+		case B_ACQUIRE_ENGINE:
+			return (void*)vboxvideo_acquire_engine;
+		case B_RELEASE_ENGINE:
+			return (void*)vboxvideo_release_engine;
+		case B_WAIT_ENGINE_IDLE:
+			return (void*)vboxvideo_wait_engine_idle;
+		case B_GET_SYNC_TOKEN:
+			return (void*)vboxvideo_get_sync_token;
+		case B_SYNC_TO_TOKEN:
+			return (void*)vboxvideo_sync_to_token;
+	}
+
+	return NULL;
+}
+
+status_t vboxvideo_init_common(int fd, bool cloned) {
+	unlink("/var/log/vboxvideo.accelerant.log"); // clear old log - next TRACE() will recreate it
+	TRACE("%s\n", __FUNCTION__);
+
+	gInfo.deviceFD = fd;
+	gInfo.isClone = cloned;
+	gInfo.sharedInfo = NULL;
+	gInfo.sharedInfoArea = -1;
+
+	area_id sharedArea;
+	if (ioctl(gInfo.deviceFD, VBOXVIDEO_GET_PRIVATE_DATA, &sharedArea, sizeof(area_id)) != 0) {
+		TRACE("ioctl failed\n");
+		return B_ERROR;
+	}
+
+	AreaCloner sharedCloner;
+	gInfo.sharedInfoArea = sharedCloner.Clone("vboxvideo shared info",
+		(void **)&gInfo.sharedInfo, B_ANY_ADDRESS,
+		B_READ_AREA | B_WRITE_AREA, sharedArea);
+	status_t status = sharedCloner.InitCheck();
+	if (status < B_OK) {
+		TRACE("InitCheck failed (%s)\n", strerror(status));
+		return status;
+	}
+	sharedCloner.Keep();
+
+	return B_OK;
+}
+
+status_t vboxvideo_init_accelerant(int fd) {
+	return vboxvideo_init_common(fd, false);
+}
+
+ssize_t vboxvideo_accelerant_clone_info_size(void) {
+	TRACE("%s\n", __FUNCTION__);
+	return B_PATH_NAME_LENGTH;
+}
+
+void vboxvideo_get_accelerant_clone_info(void *data) {
+	TRACE("%s\n", __FUNCTION__);
+	ioctl(gInfo.deviceFD, VBOXVIDEO_GET_DEVICE_NAME, data, B_PATH_NAME_LENGTH);
+}
+
+status_t vboxvideo_clone_accelerant(void *data) {
+	TRACE("%s\n", __FUNCTION__);
+
+	// create full device name
+	char path[MAXPATHLEN];
+	strcpy(path, "/dev/");
+	strcat(path, (const char *)data);
+
+	int fd = open(path, B_READ_WRITE);
+	if (fd < 0)
+		return errno;
+
+	return vboxvideo_init_common(fd, true);
+}
+
+void vboxvideo_uninit_accelerant(void) {
+	delete_area(gInfo.sharedInfoArea);
+	gInfo.sharedInfo = NULL;
+	gInfo.sharedInfoArea = -1;
+
+	if (gInfo.isClone)
+		close(gInfo.deviceFD);
+
+	TRACE("%s\n", __FUNCTION__);
+}
+
+status_t vboxvideo_get_accelerant_device_info(accelerant_device_info *adi) {
+	TRACE("%s\n", __FUNCTION__);
+	adi->version = B_ACCELERANT_VERSION;
+	strcpy(adi->name, "Virtual display");
+	strcpy(adi->chipset, "VirtualBox Graphics Adapter");
+	strcpy(adi->serial_no, "9001");
+	return B_OK;
+}
+
+sem_id vboxvideo_accelerant_retrace_semaphore(void) {
+	TRACE("%s\n", __FUNCTION__);
+	return -1;
+}
+
+// modes & constraints
+uint32 vboxvideo_accelerant_mode_count(void) {
+	TRACE("%s\n", __FUNCTION__);
+	return 1;
+}
+
+status_t vboxvideo_get_mode_list(display_mode *dm) {
+	// TODO return some standard modes here
+	TRACE("%s\n", __FUNCTION__);
+	return vboxvideo_get_display_mode(dm);
+}
+
+status_t vboxvideo_set_display_mode(display_mode *modeToSet) {
+	TRACE("%s\n", __FUNCTION__);
+	TRACE("trying to set mode %dx%d\n", modeToSet->timing.h_display, modeToSet->timing.v_display);
+	return ioctl(gInfo.deviceFD, VBOXVIDEO_SET_DISPLAY_MODE, modeToSet, sizeof(display_mode));
+}
+
+status_t vboxvideo_get_display_mode(display_mode *currentMode) {
+	TRACE("%s\n", __FUNCTION__);
+	*currentMode = gInfo.sharedInfo->currentMode;
+	TRACE("current mode is %dx%d\n", currentMode->timing.h_display, currentMode->timing.v_display);
+	return B_OK;
+}
+
+status_t vboxvideo_get_edid_info(void *info, size_t size, uint32 *_version) {
+	TRACE("%s\n", __FUNCTION__);
+
+	// copied from the X11 implementation:
+	static const uint8 edid_data[128] = {
+		0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
+		0x58, 0x58, /* manufacturer (VBX) */
+		0x00, 0x00, /* product code */
+		0x00, 0x00, 0x00, 0x00, /* serial number goes here */
+		0x01, /* week of manufacture */
+		0x00, /* year of manufacture */
+		0x01, 0x03, /* EDID version */
+		0x80, /* capabilities - digital */
+		0x00, /* horiz. res in cm, zero for projectors */
+		0x00, /* vert. res in cm */
+		0x78, /* display gamma (120 == 2.2).  Should we ask the host for this? */
+		0xEE, /* features (standby, suspend, off, RGB, standard colour space,
+				* preferred timing mode) */
+		0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
+			/* chromaticity for standard colour space - should we ask the host? */
+		0x00, 0x00, 0x00, /* no default timings */
+		0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+		0x01, 0x01, 0x01, 0x01, /* no standard timings */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* descriptor block 1 goes here */
+		0x00, 0x00, 0x00, 0xFD, 0x00, /* descriptor block 2, monitor ranges */
+		0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
+		0x20, /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
+		0x00, 0x00, 0x00, 0xFC, 0x00, /* descriptor block 3, monitor name */
+		'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r', '\n',
+		0x00, 0x00, 0x00, 0x10, 0x00, /* descriptor block 4: dummy data */
+		0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+		0x20,
+		0x00, /* number of extensions */
+		0x00 /* checksum goes here */
+	};
+
+	if (size < 128)
+		return B_BUFFER_OVERFLOW;
+
+	*_version = 1; /*EDID_VERSION_1*/
+	memcpy(info, edid_data, 128);
+	return B_OK;
+}
+
+status_t vboxvideo_get_frame_buffer_config(frame_buffer_config *config) {
+	TRACE("%s\n", __FUNCTION__);
+	config->frame_buffer = gInfo.sharedInfo->framebuffer;
+	config->frame_buffer_dma = NULL;
+	config->bytes_per_row = get_depth_for_color_space(gInfo.sharedInfo->currentMode.space)
+		* gInfo.sharedInfo->currentMode.timing.h_display / 8;
+	return B_OK;
+}
+
+status_t vboxvideo_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high) {
+	TRACE("%s\n", __FUNCTION__);
+	// irrelevant for virtual monitors
+	*low = 0;
+	*high = 9001;
+	return B_OK;
+}
+
+// cursor
+status_t vboxvideo_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, uint8 *andMask, uint8 *xorMask) {
+	TRACE("%s\n", __FUNCTION__);
+	// VBoxHGSMIUpdatePointerShape
+	return B_UNSUPPORTED;
+}
+
+void vboxvideo_move_cursor(uint16 x, uint16 y) {
+	TRACE("%s\n", __FUNCTION__);
+}
+
+void vboxvideo_show_cursor(bool is_visible) {
+	TRACE("%s\n", __FUNCTION__);
+}
+
+// accelerant engine
+uint32 vboxvideo_accelerant_engine_count(void) {
+	TRACE("%s\n", __FUNCTION__);
+	return 1;
+}
+
+status_t vboxvideo_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *st, engine_token **et) {
+	TRACE("%s\n", __FUNCTION__);
+	*et = &sEngineToken;
+	return B_OK;
+}
+
+status_t vboxvideo_release_engine(engine_token *et, sync_token *st) {
+	TRACE("%s\n", __FUNCTION__);
+	if (st != NULL)
+		st->engine_id = et->engine_id;
+
+	return B_OK;
+}
+
+void vboxvideo_wait_engine_idle(void) {
+	TRACE("%s\n", __FUNCTION__);
+}
+
+status_t vboxvideo_get_sync_token(engine_token *et, sync_token *st) {
+	TRACE("%s\n", __FUNCTION__);
+	return B_OK;
+}
+
+status_t vboxvideo_sync_to_token(sync_token *st) {
+	TRACE("%s\n", __FUNCTION__);
+	return B_OK;
+}
+
+// 2D acceleration
+void vboxvideo_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count) {
+	TRACE("%s\n", __FUNCTION__);
+}
+
+void vboxvideo_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count) {
+	TRACE("%s\n", __FUNCTION__);
+}
+
+void vboxvideo_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count) {
+	TRACE("%s\n", __FUNCTION__);
+}
+
+void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count) {
+	TRACE("%s\n", __FUNCTION__);
+}
Index: /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxVideo/accelerant/accelerant.h	(revision 43363)
@@ -0,0 +1,99 @@
+/* $Id$ */
+/** @file
+ * VBoxVideo Accelerant; 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 _ACCELERANT_H
+#define _ACCELERANT_H
+
+#include <Accelerant.h>
+#include "../common/VBoxVideo_common.h"
+
+struct AccelerantInfo {
+	int deviceFD;
+	bool isClone;
+
+	SharedInfo* sharedInfo;
+	area_id sharedInfoArea;
+};
+extern AccelerantInfo gInfo;
+
+// general
+status_t vboxvideo_init_accelerant(int fd);
+ssize_t vboxvideo_accelerant_clone_info_size(void);
+void vboxvideo_get_accelerant_clone_info(void *data);
+status_t vboxvideo_clone_accelerant(void *data);
+void vboxvideo_uninit_accelerant(void);
+status_t vboxvideo_get_accelerant_device_info(accelerant_device_info *adi);
+sem_id vboxvideo_accelerant_retrace_semaphore(void);
+
+// modes & constraints
+uint32 vboxvideo_accelerant_mode_count(void);
+status_t vboxvideo_get_mode_list(display_mode *dm);
+status_t vboxvideo_set_display_mode(display_mode *modeToSet);
+status_t vboxvideo_get_display_mode(display_mode *currentMode);
+status_t vboxvideo_get_edid_info(void *info, size_t size, uint32 *_version);
+status_t vboxvideo_get_frame_buffer_config(frame_buffer_config *config);
+status_t vboxvideo_get_pixel_clock_limits(display_mode *dm, uint32 *low, uint32 *high);
+
+// cursor
+status_t vboxvideo_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, uint8 *andMask, uint8 *xorMask);
+void vboxvideo_move_cursor(uint16 x, uint16 y);
+void vboxvideo_show_cursor(bool is_visible);
+
+// accelerant engine
+uint32 vboxvideo_accelerant_engine_count(void);
+status_t vboxvideo_acquire_engine(uint32 capabilities, uint32 maxWait, sync_token *st, engine_token **et);
+status_t vboxvideo_release_engine(engine_token *et, sync_token *st);
+void vboxvideo_wait_engine_idle(void);
+status_t vboxvideo_get_sync_token(engine_token *et, sync_token *st);
+status_t vboxvideo_sync_to_token(sync_token *st);
+
+// 2D acceleration
+void vboxvideo_screen_to_screen_blit(engine_token *et, blit_params *list, uint32 count);
+void vboxvideo_fill_rectangle(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
+void vboxvideo_invert_rectangle(engine_token *et, fill_rect_params *list, uint32 count);
+void vboxvideo_fill_span(engine_token *et, uint32 color, uint16 *list, uint32 count);
+
+#endif	/* _ACCELERANT_PROTOS_H */
Index: /trunk/src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxVideo/common/VBoxVideo_common.h	(revision 43363)
@@ -0,0 +1,112 @@
+/* $Id$ */
+/** @file
+ * VBoxVideo, Haiku Guest Additions, common 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 _VBOXVIDEO_COMMON_H
+#define _VBOXVIDEO_COMMON_H
+
+#include <Drivers.h>
+#include <Accelerant.h>
+#include <PCI.h>
+
+struct SharedInfo {
+	display_mode currentMode;
+
+	area_id framebufferArea;
+	void* framebuffer;
+};
+
+enum {
+	VBOXVIDEO_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
+	VBOXVIDEO_GET_DEVICE_NAME,
+	VBOXVIDEO_SET_DISPLAY_MODE
+};
+
+static inline uint32 get_color_space_for_depth(uint32 depth)
+{
+	switch (depth) {
+		case 1:
+			return B_GRAY1;
+		case 4:
+			return B_GRAY8;
+				// the app_server is smart enough to translate this to VGA mode
+		case 8:
+			return B_CMAP8;
+		case 15:
+			return B_RGB15;
+		case 16:
+			return B_RGB16;
+		case 24:
+			return B_RGB24;
+		case 32:
+			return B_RGB32;
+	}
+
+	return 0;
+}
+
+static inline uint32 get_depth_for_color_space(uint32 depth)
+{
+	switch (depth) {
+		case B_GRAY1:
+			return 1;
+		case B_GRAY8:
+			return 4;
+		case B_CMAP8:
+			return 8;
+		case B_RGB15:
+			return 15;
+		case B_RGB16:
+			return 16;
+		case B_RGB24:
+			return 24;
+		case B_RGB32:
+			return 32;
+	}
+
+	return 0;
+}
+
+#endif
Index: /trunk/src/VBox/Additions/haiku/VBoxVideo/driver/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxVideo/driver/Makefile.kmk	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxVideo/driver/Makefile.kmk	(revision 43363)
@@ -0,0 +1,83 @@
+# $Id$
+## @file
+# Sub-Makefile for VBoxVideo driver, Haiku Guest Additions.
+#
+
+#
+# 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.
+#
+
+SUB_DEPTH = ../../../../../..
+include	$(KBUILD_PATH)/subheader.kmk
+
+ifdef VBOX_WITH_ADDITION_DRIVERS
+ SYSMODS += vboxvideo
+endif
+
+#
+# Populate FILES_VBOXSF_NOBIN
+#
+#include $(PATH_SUB_CURRENT)/files_VBoxVideo
+
+#
+# The module (for syntax checking).
+# The DEBUG_HASH* stuff is for CONFIG_DYNAMIC_DEBUG-enabled kernels
+#
+vboxvideo_TEMPLATE        = VBOXGUESTR0
+vboxvideo_DEFS            = \
+	MODULE IN_RT_R0 VBOXGUEST VBOX_WITH_HGCM \
+	KBUILD_MODNAME=KBUILD_STR\(VBoxVideo\) \
+        KBUILD_BASENAME=KBUILD_STR\(VBoxVideo\)
+vboxvideo_INCS            = \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxGuestLib \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest \
+	$(PATH_ROOT)/src/VBox/Runtime/r0drv/haiku
+vboxvideo_SOURCES         = \
+	driver.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/Modesetting.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxVideo/VBVABase.cpp \
+	$(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/VBoxGuest-haiku-stubs.c
+vboxvideo_LIBS            = \
+	$(VBOX_LIB_VBGL_R0) \
+	$(VBOX_PATH_ADDITIONS_LIB)/HGSMIGuestR0Lib$(VBOX_SUFF_LIB)
+
+include	$(KBUILD_PATH)/subfooter.kmk
+
Index: /trunk/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp
===================================================================
--- /trunk/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/VBoxVideo/driver/driver.cpp	(revision 43363)
@@ -0,0 +1,337 @@
+/* $Id$ */
+/** @file
+ * VBoxVideo 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.
+ */
+
+#include <KernelExport.h>
+#include <PCI.h>
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <graphic_driver.h>
+#include <VBoxGuest-haiku.h>
+#include <VBox/VBoxVideoGuest.h>
+#include "../common/VBoxVideo_common.h"
+
+#define VENDOR_ID 0x80ee
+#define DEVICE_ID 0xbeef
+
+#define DEVICE_FORMAT "vd_%04X_%04X_%02X%02X%02X"
+
+#define ROUND_TO_PAGE_SIZE(x) (((x) + (B_PAGE_SIZE) - 1) & ~((B_PAGE_SIZE) - 1))
+
+#define ENABLE_DEBUG_TRACE
+
+#undef TRACE
+#ifdef ENABLE_DEBUG_TRACE
+#	define TRACE(x...) dprintf("VBoxVideo: " x)
+#else
+#	define TRACE(x...) ;
+#endif
+
+int32 api_version = B_CUR_DRIVER_API_VERSION; // revision of driver API we support
+
+extern "C" status_t vm_set_area_memory_type(area_id id, phys_addr_t physicalBase, uint32 type);
+
+struct Benaphore {
+	sem_id	sem;
+	int32	count;
+
+	status_t Init(const char* name)
+	{
+		count = 0;
+		sem = create_sem(0, name);
+		return sem < 0 ? sem : B_OK;
+	}
+
+	status_t Acquire()
+	{
+		if (atomic_add(&count, 1) > 0)
+			return acquire_sem(sem);
+		return B_OK;
+	}
+
+	status_t Release()
+	{
+		if (atomic_add(&count, -1) > 1)
+			return release_sem(sem);
+		return B_OK;
+	}
+
+	void Delete() { delete_sem(sem); }
+};
+
+struct DeviceInfo {
+	uint32			openCount;		// count of how many times device has been opened
+	uint32			flags;
+	area_id 		sharedArea;		// area shared between driver and all accelerants
+	SharedInfo*		sharedInfo;		// pointer to shared info area memory
+	pci_info		pciInfo;		// copy of pci info for this device
+	char			name[B_OS_NAME_LENGTH]; // name of device
+};
+
+// at most one virtual video card ever appears, no reason for this to be an array
+static DeviceInfo gDeviceInfo;
+static char* gDeviceNames[2] = {gDeviceInfo.name, NULL};
+static bool gCanHasDevice = false; // is the device present?
+static Benaphore gLock;
+static pci_module_info*	gPCI;
+
+status_t device_open(const char* name, uint32 flags, void** cookie);
+status_t device_close(void* dev);
+status_t device_free(void* dev);
+status_t device_read(void* dev, off_t pos, void* buf, size_t* len);
+status_t device_write(void* dev, off_t pos, const void* buf, size_t* len);
+status_t device_ioctl(void* dev, uint32 msg, void* buf, size_t len);
+static uint32 get_color_space_for_depth(uint32 depth);
+
+static device_hooks gDeviceHooks = {
+	device_open, // open
+	device_close, // close
+	device_free, // free
+	device_ioctl, // control
+	device_read, // read
+	device_write, // write
+	NULL, // select
+	NULL, // deselect
+	NULL, // read_pages
+	NULL  // write_pages
+};
+
+status_t init_hardware()
+{
+	TRACE("init_hardware\n");
+
+	if (get_module(VBOXGUEST_MODULE_NAME, (module_info **)&g_VBoxGuest) != B_OK) {
+		dprintf("get_module(%s) failed\n", VBOXGUEST_MODULE_NAME);
+		return B_ERROR;
+	}
+
+	if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) != B_OK) {
+		dprintf("get_module(%s) failed\n", B_PCI_MODULE_NAME);
+		return B_ERROR;
+	}
+
+	return B_OK;
+}
+
+status_t init_driver()
+{
+	TRACE("init_driver\n");
+
+	gLock.Init("VBoxVideo driver lock");
+
+	uint32 pciIndex = 0;
+
+	while (gPCI->get_nth_pci_info(pciIndex, &gDeviceInfo.pciInfo) == B_OK) {
+		if (gDeviceInfo.pciInfo.vendor_id == VENDOR_ID && gDeviceInfo.pciInfo.device_id == DEVICE_ID) {
+			sprintf(gDeviceInfo.name, "graphics/" DEVICE_FORMAT,
+				gDeviceInfo.pciInfo.vendor_id, gDeviceInfo.pciInfo.device_id,
+				gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function);
+			TRACE("found device %s\n", gDeviceInfo.name);
+
+			gCanHasDevice = true;
+			gDeviceInfo.openCount = 0;
+
+			size_t sharedSize = (sizeof(SharedInfo) + 7) & ~7;
+			gDeviceInfo.sharedArea = create_area("vboxvideo shared info",
+				(void**)&gDeviceInfo.sharedInfo, B_ANY_KERNEL_ADDRESS,
+				ROUND_TO_PAGE_SIZE(sharedSize), B_FULL_LOCK,
+				B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA | B_USER_CLONEABLE_AREA);
+
+			uint16_t width, height, vwidth, bpp, flags;
+			VBoxVideoGetModeRegisters(&width, &height, &vwidth, &bpp, &flags);
+
+			gDeviceInfo.sharedInfo->currentMode.space = get_color_space_for_depth(bpp);
+			gDeviceInfo.sharedInfo->currentMode.virtual_width = width;
+			gDeviceInfo.sharedInfo->currentMode.virtual_height = height;
+			gDeviceInfo.sharedInfo->currentMode.h_display_start = 0;
+			gDeviceInfo.sharedInfo->currentMode.v_display_start = 0;
+			gDeviceInfo.sharedInfo->currentMode.flags = 0;
+			gDeviceInfo.sharedInfo->currentMode.timing.h_display = width;
+			gDeviceInfo.sharedInfo->currentMode.timing.v_display = height;
+			// not used, but this makes a reasonable-sounding refresh rate show in screen prefs:
+			gDeviceInfo.sharedInfo->currentMode.timing.h_total = 1000;
+			gDeviceInfo.sharedInfo->currentMode.timing.v_total = 1;
+			gDeviceInfo.sharedInfo->currentMode.timing.pixel_clock = 850;
+
+			// map the PCI memory space
+			uint32 command_reg = gPCI->read_pci_config(gDeviceInfo.pciInfo.bus,
+				gDeviceInfo.pciInfo.device, gDeviceInfo.pciInfo.function,  PCI_command, 2);
+			command_reg |= PCI_command_io | PCI_command_memory | PCI_command_master;
+			gPCI->write_pci_config(gDeviceInfo.pciInfo.bus, gDeviceInfo.pciInfo.device,
+				gDeviceInfo.pciInfo.function, PCI_command, 2, command_reg);
+
+			gDeviceInfo.sharedInfo->framebufferArea =
+				map_physical_memory("vboxvideo framebuffer", (phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0],
+					gDeviceInfo.pciInfo.u.h0.base_register_sizes[0], B_ANY_KERNEL_BLOCK_ADDRESS,
+					B_READ_AREA | B_WRITE_AREA, &(gDeviceInfo.sharedInfo->framebuffer));
+			vm_set_area_memory_type(gDeviceInfo.sharedInfo->framebufferArea,
+				(phys_addr_t)gDeviceInfo.pciInfo.u.h0.base_registers[0], B_MTR_WC);
+
+			break;
+		}
+
+		pciIndex++;
+	}
+
+	return B_OK;
+}
+
+const char** publish_devices()
+{
+	TRACE("publish_devices\n");
+	if (gCanHasDevice) {
+		return (const char**)gDeviceNames;
+	}
+	else {
+		return NULL;
+	}
+}
+
+device_hooks* find_device(const char* name)
+{
+	TRACE("find_device\n");
+	if (gCanHasDevice && strcmp(name, gDeviceInfo.name) == 0) {
+		return &gDeviceHooks;
+	}
+	else {
+		return NULL;
+	}
+}
+
+void uninit_driver()
+{
+	TRACE("uninit_driver\n");
+	gLock.Delete();
+	put_module(VBOXGUEST_MODULE_NAME);
+}
+
+status_t device_open(const char* name, uint32 flags, void** cookie)
+{
+	TRACE("device_open\n");
+
+	if (!gCanHasDevice || strcmp(name, gDeviceInfo.name) != 0)
+		return B_BAD_VALUE;
+
+	// TODO init device!
+
+	*cookie = (void*)&gDeviceInfo;
+
+	return B_OK;
+}
+
+status_t device_close(void* dev)
+{
+	TRACE("device_close\n");
+	return B_ERROR;
+}
+
+status_t device_free(void* dev)
+{
+	TRACE("device_free\n");
+
+	DeviceInfo& di = *(DeviceInfo*)dev;
+	gLock.Acquire();
+
+	if (di.openCount <= 1) {
+		// TODO deinit device!
+
+		delete_area(di.sharedArea);
+		di.sharedArea = -1;
+		di.sharedInfo = NULL;
+	}
+
+	if (di.openCount > 0)
+		di.openCount--;
+
+	gLock.Release();
+
+	return B_OK;
+}
+
+status_t device_read(void* dev, off_t pos, void* buf, size_t* len)
+{
+	TRACE("device_read\n");
+	return B_NOT_ALLOWED;
+}
+
+status_t device_write(void* dev, off_t pos, const void* buf, size_t* len)
+{
+	TRACE("device_write\n");
+	return B_NOT_ALLOWED;
+}
+
+status_t device_ioctl(void* cookie, uint32 msg, void* buf, size_t len)
+{
+	TRACE("device_ioctl\n");
+
+	DeviceInfo* dev = (DeviceInfo*)cookie;
+
+	switch (msg) {
+	case B_GET_ACCELERANT_SIGNATURE:
+		strcpy((char*)buf, "vboxvideo.accelerant");
+		return B_OK;
+
+	case VBOXVIDEO_GET_PRIVATE_DATA:
+		return user_memcpy(buf, &dev->sharedArea, sizeof(area_id));
+
+	case VBOXVIDEO_GET_DEVICE_NAME:
+		if (user_strlcpy((char*)buf, gDeviceInfo.name, len) < B_OK)
+			return B_BAD_ADDRESS;
+		else
+			return B_OK;
+
+	case VBOXVIDEO_SET_DISPLAY_MODE: {
+		display_mode* mode = (display_mode*)buf;
+		VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display,
+			mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0);
+		gDeviceInfo.sharedInfo->currentMode = *mode;
+		return B_OK;
+	}
+	default:
+		return B_BAD_VALUE;
+	}
+
+}
Index: /trunk/src/VBox/Additions/haiku/include/VBoxGuestInternal.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/include/VBoxGuestInternal.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/include/VBoxGuestInternal.h	(revision 43363)
@@ -0,0 +1,61 @@
+/* $$ */
+/** @file
+ * VBoxGuestInternal - Private Haiku additions declarations.
+ */
+
+/*
+ * 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 ___VBoxGuestInternal_h_
+#define ___VBoxGuestInternal_h_
+
+/** The MIME signature of the VBoxGuest application. */
+#define VBOX_GUEST_APP_SIG                       "application/x-vnd.Oracle-VBoxGuest"
+
+/** The code used for messages sent by and to the system tray. */
+#define VBOX_GUEST_CLIPBOARD_HOST_MSG_READ_DATA  'vbC2'
+#define VBOX_GUEST_CLIPBOARD_HOST_MSG_FORMATS    'vbC3'
+
+/** The code used for messages sent by and to the system tray. */
+#define VBOX_GUEST_APP_ACTION                    'vbox'
+
+#endif /* ___VBoxGuestInternal_h_ */
+
Index: /trunk/src/VBox/Additions/haiku/include/lock.h
===================================================================
--- /trunk/src/VBox/Additions/haiku/include/lock.h	(revision 43363)
+++ /trunk/src/VBox/Additions/haiku/include/lock.h	(revision 43363)
@@ -0,0 +1,305 @@
+/* $Id$ */
+/** @file
+ * Lock.h - Haiku, private locking internals.
+ */
+
+/*
+ * 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 2008-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
+ * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
+ * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ */
+
+/** @todo r=ramshankar: Eventually this file should be shipped by Haiku and
+ *  	  should be removed from the VBox tree. */
+
+#ifndef _KERNEL_LOCK_H
+#define _KERNEL_LOCK_H
+
+#include <OS.h>
+
+
+struct mutex_waiter;
+
+typedef struct mutex {
+	const char*				name;
+	struct mutex_waiter*	waiters;
+#if KDEBUG
+	thread_id				holder;
+#else
+	int32					count;
+	uint16					ignore_unlock_count;
+#endif
+	uint8					flags;
+} mutex;
+
+#define MUTEX_FLAG_CLONE_NAME	0x1
+
+
+typedef struct recursive_lock {
+	mutex		lock;
+#if !KDEBUG
+	thread_id	holder;
+#endif
+	int			recursion;
+} recursive_lock;
+
+
+struct rw_lock_waiter;
+
+typedef struct rw_lock {
+	const char*				name;
+	struct rw_lock_waiter*	waiters;
+	thread_id				holder;
+	vint32					count;
+	int32					owner_count;
+	int16					active_readers;
+								// Only > 0 while a writer is waiting: number
+								// of active readers when the first waiting
+								// writer started waiting.
+	int16					pending_readers;
+								// Number of readers that have already
+								// incremented "count", but have not yet started
+								// to wait at the time the last writer unlocked.
+	uint32					flags;
+} rw_lock;
+
+#define RW_LOCK_WRITER_COUNT_BASE	0x10000
+
+#define RW_LOCK_FLAG_CLONE_NAME	0x1
+
+
+#if KDEBUG
+#	define KDEBUG_RW_LOCK_DEBUG 0
+		// Define to 1 if you want to use ASSERT_READ_LOCKED_RW_LOCK().
+		// The rw_lock will just behave like a recursive locker then.
+#	define ASSERT_LOCKED_RECURSIVE(r) \
+		{ ASSERT(find_thread(NULL) == (r)->lock.holder); }
+#	define ASSERT_LOCKED_MUTEX(m) { ASSERT(find_thread(NULL) == (m)->holder); }
+#	define ASSERT_WRITE_LOCKED_RW_LOCK(l) \
+		{ ASSERT(find_thread(NULL) == (l)->holder); }
+#	if KDEBUG_RW_LOCK_DEBUG
+#		define ASSERT_READ_LOCKED_RW_LOCK(l) \
+			{ ASSERT(find_thread(NULL) == (l)->holder); }
+#	else
+#		define ASSERT_READ_LOCKED_RW_LOCK(l) do {} while (false)
+#	endif
+#else
+#	define ASSERT_LOCKED_RECURSIVE(r)		do {} while (false)
+#	define ASSERT_LOCKED_MUTEX(m)			do {} while (false)
+#	define ASSERT_WRITE_LOCKED_RW_LOCK(m)	do {} while (false)
+#	define ASSERT_READ_LOCKED_RW_LOCK(l)	do {} while (false)
+#endif
+
+
+// static initializers
+#if KDEBUG
+#	define MUTEX_INITIALIZER(name)			{ name, NULL, -1, 0 }
+#	define RECURSIVE_LOCK_INITIALIZER(name)	{ MUTEX_INITIALIZER(name), 0 }
+#else
+#	define MUTEX_INITIALIZER(name)			{ name, NULL, 0, 0, 0 }
+#	define RECURSIVE_LOCK_INITIALIZER(name)	{ MUTEX_INITIALIZER(name), -1, 0 }
+#endif
+
+#define RW_LOCK_INITIALIZER(name)			{ name, NULL, -1, 0, 0, 0 }
+
+
+#if KDEBUG
+#	define RECURSIVE_LOCK_HOLDER(recursiveLock)	((recursiveLock)->lock.holder)
+#else
+#	define RECURSIVE_LOCK_HOLDER(recursiveLock)	((recursiveLock)->holder)
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void	recursive_lock_init(recursive_lock *lock, const char *name);
+	// name is *not* cloned nor freed in recursive_lock_destroy()
+extern void recursive_lock_init_etc(recursive_lock *lock, const char *name,
+	uint32 flags);
+extern void recursive_lock_destroy(recursive_lock *lock);
+extern status_t recursive_lock_lock(recursive_lock *lock);
+extern status_t recursive_lock_trylock(recursive_lock *lock);
+extern void recursive_lock_unlock(recursive_lock *lock);
+extern int32 recursive_lock_get_recursion(recursive_lock *lock);
+
+extern void rw_lock_init(rw_lock* lock, const char* name);
+	// name is *not* cloned nor freed in rw_lock_destroy()
+extern void rw_lock_init_etc(rw_lock* lock, const char* name, uint32 flags);
+extern void rw_lock_destroy(rw_lock* lock);
+extern status_t rw_lock_write_lock(rw_lock* lock);
+
+extern void mutex_init(mutex* lock, const char* name);
+	// name is *not* cloned nor freed in mutex_destroy()
+extern void mutex_init_etc(mutex* lock, const char* name, uint32 flags);
+extern void mutex_destroy(mutex* lock);
+extern status_t mutex_switch_lock(mutex* from, mutex* to);
+	// Unlocks "from" and locks "to" such that unlocking and starting to wait
+	// for the lock is atomically. I.e. if "from" guards the object "to" belongs
+	// to, the operation is safe as long as "from" is held while destroying
+	// "to".
+extern status_t mutex_switch_from_read_lock(rw_lock* from, mutex* to);
+	// Like mutex_switch_lock(), just for a switching from a read-locked
+	// rw_lock.
+
+
+// implementation private:
+
+extern status_t _rw_lock_read_lock(rw_lock* lock);
+extern status_t _rw_lock_read_lock_with_timeout(rw_lock* lock,
+	uint32 timeoutFlags, bigtime_t timeout);
+extern void _rw_lock_read_unlock(rw_lock* lock, bool threadsLocked);
+extern void _rw_lock_write_unlock(rw_lock* lock, bool threadsLocked);
+
+extern status_t _mutex_lock(mutex* lock, bool threadsLocked);
+extern void _mutex_unlock(mutex* lock, bool threadsLocked);
+extern status_t _mutex_trylock(mutex* lock);
+extern status_t _mutex_lock_with_timeout(mutex* lock, uint32 timeoutFlags,
+	bigtime_t timeout);
+
+
+static inline status_t
+rw_lock_read_lock(rw_lock* lock)
+{
+#if KDEBUG_RW_LOCK_DEBUG
+	return rw_lock_write_lock(lock);
+#else
+	int32 oldCount = atomic_add(&lock->count, 1);
+	if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
+		return _rw_lock_read_lock(lock);
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+rw_lock_read_lock_with_timeout(rw_lock* lock, uint32 timeoutFlags,
+	bigtime_t timeout)
+{
+#if KDEBUG_RW_LOCK_DEBUG
+	return mutex_lock_with_timeout(lock, timeoutFlags, timeout);
+#else
+	int32 oldCount = atomic_add(&lock->count, 1);
+	if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
+		return _rw_lock_read_lock_with_timeout(lock, timeoutFlags, timeout);
+	return B_OK;
+#endif
+}
+
+
+static inline void
+rw_lock_read_unlock(rw_lock* lock)
+{
+#if KDEBUG_RW_LOCK_DEBUG
+	rw_lock_write_unlock(lock);
+#else
+	int32 oldCount = atomic_add(&lock->count, -1);
+	if (oldCount >= RW_LOCK_WRITER_COUNT_BASE)
+		_rw_lock_read_unlock(lock, false);
+#endif
+}
+
+
+static inline void
+rw_lock_write_unlock(rw_lock* lock)
+{
+	_rw_lock_write_unlock(lock, false);
+}
+
+
+static inline status_t
+mutex_lock(mutex* lock)
+{
+#if KDEBUG
+	return _mutex_lock(lock, false);
+#else
+	if (atomic_add(&lock->count, -1) < 0)
+		return _mutex_lock(lock, false);
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+mutex_lock_threads_locked(mutex* lock)
+{
+#if KDEBUG
+	return _mutex_lock(lock, true);
+#else
+	if (atomic_add(&lock->count, -1) < 0)
+		return _mutex_lock(lock, true);
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+mutex_trylock(mutex* lock)
+{
+#if KDEBUG
+	return _mutex_trylock(lock);
+#else
+	if (atomic_test_and_set(&lock->count, -1, 0) != 0)
+		return B_WOULD_BLOCK;
+	return B_OK;
+#endif
+}
+
+
+static inline status_t
+mutex_lock_with_timeout(mutex* lock, uint32 timeoutFlags, bigtime_t timeout)
+{
+#if KDEBUG
+	return _mutex_lock_with_timeout(lock, timeoutFlags, timeout);
+#else
+	if (atomic_add(&lock->count, -1) < 0)
+		return _mutex_lock_with_timeout(lock, timeoutFlags, timeout);
+	return B_OK;
+#endif
+}
+
+
+static inline void
+mutex_unlock(mutex* lock)
+{
+#if !KDEBUG
+	if (atomic_add(&lock->count, 1) < -1)
+#endif
+		_mutex_unlock(lock, false);
+}
+
+
+static inline void
+mutex_transfer_lock(mutex* lock, thread_id thread)
+{
+#if KDEBUG
+	lock->holder = thread;
+#endif
+}
+
+
+extern void lock_debug_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif	/* _KERNEL_LOCK_H */
Index: /trunk/src/VBox/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Makefile.kmk	(revision 43362)
+++ /trunk/src/VBox/Makefile.kmk	(revision 43363)
@@ -22,6 +22,6 @@
 ifdef VBOX_ONLY_ADDITIONS
  include $(PATH_SUB_CURRENT)/Runtime/Makefile.kmk
- ifdef VBOX_WITH_CROGL
-  if1of ($(KBUILD_TARGET),win linux solaris freebsd)
+ if defined(VBOX_WITH_CROGL) || defined(VBOX_WITH_HGSMI)
+  if1of ($(KBUILD_TARGET),win linux solaris freebsd haiku)
    include $(PATH_SUB_CURRENT)/GuestHost/Makefile.kmk
   endif
Index: /trunk/src/VBox/Runtime/VBox/log-vbox.cpp
===================================================================
--- /trunk/src/VBox/Runtime/VBox/log-vbox.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/VBox/log-vbox.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -138,4 +138,6 @@
 #  include <stdlib.h>
 #  include <unistd.h>
+# elif defined(RT_OS_HAIKU)
+#  include <OS.h>
 # elif defined(RT_OS_SOLARIS)
 #  define _STRUCTURED_PROC 1
@@ -369,4 +371,12 @@
         }
 
+#  elif defined(RT_OS_HAIKU)
+        team_info info;
+        if (get_team_info(0, &info) == B_OK)
+        {
+        	/* there is an info.argc, but no way to know arg boundaries */
+            RTLogLoggerEx(pLogger, 0, ~0U, "Commandline: %.64s\n", info.args);
+        }
+
 #  elif defined(RT_OS_FREEBSD)
         /* Retrieve the required length first */
Index: /trunk/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp
===================================================================
--- /trunk/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/common/err/RTErrConvertFromErrno.cpp	(revision 43363)
@@ -431,5 +431,7 @@
 #endif
 #ifdef EDOOFUS
+# if EDOOFUS != EINVAL
         case EDOOFUS:           return VERR_INTERNAL_ERROR;
+# endif
 #endif
 #ifdef ENOTSUP
Index: /trunk/src/VBox/Runtime/r0drv/haiku/RTLogWriteDebugger-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/RTLogWriteDebugger-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/RTLogWriteDebugger-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,42 @@
+/* $Id$ */
+/** @file
+ * IPRT - Log To Debugger, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/log.h>
+
+
+RTDECL(void) RTLogWriteDebugger(const char *pch, size_t cb)
+{
+	/** @todo implement this */
+    /*kprintf("%.*s", (int)cb, pch);*/
+    return;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/RTLogWriteStdOut-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/RTLogWriteStdOut-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/RTLogWriteStdOut-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,41 @@
+/* $Id$ */
+/** @file
+ * IPRT - Log To StdOut, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/log.h>
+
+
+RTDECL(void) RTLogWriteStdOut(const char *pch, size_t cb)
+{
+    dprintf("%.*s", (int)cb, pch);
+    return;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/alloc-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/alloc-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/alloc-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,125 @@
+/* $Id$ */
+/** @file
+ * IPRT - Memory Allocation, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/mem.h>
+#include <iprt/log.h>
+
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/thread.h>
+#include "r0drv/alloc-r0drv.h"
+
+
+/**
+ * OS specific allocation function.
+ */
+int rtR0MemAllocEx(size_t cb, uint32_t fFlags, PRTMEMHDR *ppHdr)
+{
+    if (RT_UNLIKELY(fFlags & RTMEMHDR_FLAG_ANY_CTX))
+        return VERR_NOT_SUPPORTED;
+
+    PRTMEMHDR pHdr = (PRTMEMHDR)malloc(cb + sizeof(*pHdr));
+    if (RT_UNLIKELY(!pHdr))
+    {
+        LogRel(("rtR0MemAllocEx(%u, %#x) failed\n", (unsigned)cb + sizeof(*pHdr), fFlags));
+        return VERR_NO_MEMORY;
+    }
+
+    pHdr->u32Magic  = RTMEMHDR_MAGIC;
+    pHdr->fFlags    = fFlags;
+    pHdr->cb        = cb;
+    pHdr->cbReq     = cb;
+    *ppHdr = pHdr;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * OS specific free function.
+ */
+void rtR0MemFree(PRTMEMHDR pHdr)
+{
+    pHdr->u32Magic += 1;
+    free(pHdr);
+}
+
+
+RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb) RT_NO_THROW
+{
+    /*
+     * Validate input.
+     */
+    AssertPtr(pPhys);
+    Assert(cb > 0);
+    RT_ASSERT_PREEMPTIBLE();
+
+    /*
+     * Allocate the memory and ensure that the API is still providing
+     * memory that's always below 4GB.
+     */
+    cb = RT_ALIGN_Z(cb, PAGE_SIZE);
+    void *pv;
+    area_id area = create_area("VirtualBox Contig Alloc", &pv,
+    	B_ANY_KERNEL_ADDRESS, cb, B_32_BIT_CONTIGUOUS,
+    	B_READ_AREA | B_WRITE_AREA);
+
+    if (area >= 0)
+    {
+    	physical_entry physMap[2];
+		if (get_memory_map(pv, cb, physMap, 2) >= B_OK)
+		{
+           	*pPhys = physMap[0].address;
+            return pv;
+        }
+        delete_area(area);
+        AssertMsgFailed(("Cannot get_memory_map for contig alloc! cb=%u\n", (unsigned)cb));
+    }
+    else
+    	AssertMsgFailed(("Cannot create_area for contig alloc! cb=%u error=0x%08lx\n", (unsigned)cb, area));
+    return NULL;
+}
+
+
+RTR0DECL(void) RTMemContFree(void *pv, size_t cb) RT_NO_THROW
+{
+    RT_ASSERT_PREEMPTIBLE();
+    if (pv)
+    {
+        Assert(cb > 0);
+
+        area_id area = area_for(pv);
+        if (area >= B_OK)
+        	delete_area(area);
+		else
+        	AssertMsgFailed(("Cannot find area to delete! cb=%u error=0x%08lx\n", (unsigned)cb, area));
+    }
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/assert-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/assert-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/assert-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,67 @@
+/* $Id$ */
+/** @file
+ * IPRT - Assertion Workers, Ring-0 Drivers, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/assert.h>
+
+#include <iprt/asm.h>
+#include <iprt/log.h>
+#include <iprt/stdarg.h>
+#include <iprt/string.h>
+
+#include "internal/assert.h"
+
+
+void rtR0AssertNativeMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
+{
+    dprintf("\r\n!!Assertion Failed!!\r\n"
+           "Expression: %s\r\n"
+           "Location  : %s(%d) %s\r\n",
+           pszExpr, pszFile, uLine, pszFunction);
+}
+
+
+void rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va)
+{
+    char szMsg[256];
+
+    RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va);
+    szMsg[sizeof(szMsg) - 1] = '\0';
+    dprintf("%s", szMsg);
+
+    NOREF(fInitial);
+}
+
+
+RTR0DECL(void) RTR0AssertPanicSystem(void)
+{
+    panic("%s%s", g_szRTAssertMsg1, g_szRTAssertMsg2);
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/initterm-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/initterm-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/initterm-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,47 @@
+/* $Id$ */
+/** @file
+ * IPRT - Initialization & Termination, R0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include "internal/initterm.h"
+
+
+int rtR0InitNative(void)
+{
+	return VINF_SUCCESS;
+}
+
+
+void rtR0TermNative(void)
+{
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,659 @@
+/* $Id$ */
+/** @file
+ * IPRT - Ring-0 Memory Objects, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+
+#include <iprt/memobj.h>
+#include <iprt/mem.h>
+#include <iprt/err.h>
+#include <iprt/assert.h>
+#include <iprt/log.h>
+#include <iprt/param.h>
+#include <iprt/process.h>
+#include "internal/memobj.h"
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * The Haiku version of the memory object structure.
+ */
+typedef struct RTR0MEMOBJHAIKU
+{
+    /** The core structure. */
+    RTR0MEMOBJINTERNAL  Core;
+    /** Area identifier */
+    area_id             AreaId;
+} RTR0MEMOBJHAIKU, *PRTR0MEMOBJHAIKU;
+
+
+//MALLOC_DEFINE(M_IPRTMOBJ, "iprtmobj", "IPRT - R0MemObj");
+#if 0
+/**
+ * Gets the virtual memory map the specified object is mapped into.
+ *
+ * @returns VM map handle on success, NULL if no map.
+ * @param   pMem                The memory object.
+ */
+static vm_map_t rtR0MemObjHaikuGetMap(PRTR0MEMOBJINTERNAL pMem)
+{
+    switch (pMem->enmType)
+    {
+        case RTR0MEMOBJTYPE_PAGE:
+        case RTR0MEMOBJTYPE_LOW:
+        case RTR0MEMOBJTYPE_CONT:
+            return kernel_map;
+
+        case RTR0MEMOBJTYPE_PHYS:
+        case RTR0MEMOBJTYPE_PHYS_NC:
+            return NULL; /* pretend these have no mapping atm. */
+
+        case RTR0MEMOBJTYPE_LOCK:
+            return pMem->u.Lock.R0Process == NIL_RTR0PROCESS
+                ? kernel_map
+                : &((struct proc *)pMem->u.Lock.R0Process)->p_vmspace->vm_map;
+
+        case RTR0MEMOBJTYPE_RES_VIRT:
+            return pMem->u.ResVirt.R0Process == NIL_RTR0PROCESS
+                ? kernel_map
+                : &((struct proc *)pMem->u.ResVirt.R0Process)->p_vmspace->vm_map;
+
+        case RTR0MEMOBJTYPE_MAPPING:
+            return pMem->u.Mapping.R0Process == NIL_RTR0PROCESS
+                ? kernel_map
+                : &((struct proc *)pMem->u.Mapping.R0Process)->p_vmspace->vm_map;
+
+        default:
+            return NULL;
+    }
+}
+#endif
+
+int rtR0MemObjNativeFree(RTR0MEMOBJ pMem)
+{
+    PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
+    int rc = B_OK;
+
+    switch (pMemHaiku->Core.enmType)
+    {
+        case RTR0MEMOBJTYPE_PAGE:
+        case RTR0MEMOBJTYPE_LOW:
+        case RTR0MEMOBJTYPE_CONT:
+        case RTR0MEMOBJTYPE_MAPPING:
+        case RTR0MEMOBJTYPE_PHYS:
+        case RTR0MEMOBJTYPE_PHYS_NC:
+        {
+            if (pMemHaiku->AreaId > -1)
+                rc = delete_area(pMemHaiku->AreaId);
+
+            AssertMsg(rc == B_OK, ("%#x", rc));
+            break;
+        }
+
+        case RTR0MEMOBJTYPE_LOCK:
+        {
+            team_id team = B_SYSTEM_TEAM;
+
+            if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
+                team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
+
+            rc = unlock_memory_etc(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb, B_READ_DEVICE);
+            AssertMsg(rc == B_OK, ("%#x", rc));
+            break;
+        }
+
+        case RTR0MEMOBJTYPE_RES_VIRT:
+        {
+            team_id team = B_SYSTEM_TEAM;
+            if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
+                team = ((team_id)pMemHaiku->Core.u.Lock.R0Process);
+
+            rc = vm_unreserve_address_range(team, pMemHaiku->Core.pv, pMemHaiku->Core.cb);
+            AssertMsg(rc == B_OK, ("%#x", rc));
+            break;
+        }
+
+        default:
+            AssertMsgFailed(("enmType=%d\n", pMemHaiku->Core.enmType));
+            return VERR_INTERNAL_ERROR;
+    }
+
+    return VINF_SUCCESS;
+}
+
+static int rtR0MemObjNativeAllocArea(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
+    bool fExecutable, RTR0MEMOBJTYPE type, RTHCPHYS PhysHighest, size_t uAlignment)
+{
+    NOREF(fExecutable);
+
+    int rc;
+    void *pvMap         = NULL;
+    const char *pszName = NULL;
+    uint32 addressSpec  = B_ANY_KERNEL_ADDRESS;
+    uint32 fLock        = ~0U;
+    LogFlowFunc(("ppMem=%p cb=%u, fExecutable=%s, type=%08x, PhysHighest=%RX64 uAlignment=%u\n", ppMem, (unsigned)cb,
+               fExecutable ? "true" : "false", type, PhysHighest, (unsigned)uAlignment));
+
+    switch (type)
+    {
+        case RTR0MEMOBJTYPE_PAGE:
+            pszName = "IPRT R0MemObj Alloc";
+            fLock = B_FULL_LOCK;
+            break;
+        case RTR0MEMOBJTYPE_LOW:
+            pszName = "IPRT R0MemObj AllocLow";
+            fLock = B_32_BIT_FULL_LOCK;
+            break;
+        case RTR0MEMOBJTYPE_CONT:
+            pszName = "IPRT R0MemObj AllocCont";
+            fLock = B_32_BIT_CONTIGUOUS;
+            break;
+#if 0
+        case RTR0MEMOBJTYPE_MAPPING:
+            pszName = "IPRT R0MemObj Mapping";
+            fLock = B_FULL_LOCK;
+            break;
+#endif
+        case RTR0MEMOBJTYPE_PHYS:
+            /** @todo alignment  */
+            if (uAlignment != PAGE_SIZE)
+                return VERR_NOT_SUPPORTED;
+            /** @todo r=ramshankar: no 'break' here?? */
+        case RTR0MEMOBJTYPE_PHYS_NC:
+            pszName = "IPRT R0MemObj AllocPhys";
+            fLock   = (PhysHighest < _4G ? B_LOMEM : B_32_BIT_CONTIGUOUS);
+            break;
+#if 0
+        case RTR0MEMOBJTYPE_LOCK:
+            break;
+#endif        
+        default:
+            return VERR_INTERNAL_ERROR;
+    }
+
+    /* Create the object. */
+    PRTR0MEMOBJHAIKU pMemHaiku;
+    pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), type, NULL, cb);
+    if (RT_UNLIKELY(!pMemHaiku))
+        return VERR_NO_MEMORY;
+
+    rc = pMemHaiku->AreaId = create_area(pszName, &pvMap, addressSpec, cb, fLock, B_READ_AREA | B_WRITE_AREA);
+    if (pMemHaiku->AreaId >= 0)
+    {
+        physical_entry physMap[2];
+        pMemHaiku->Core.pv = pvMap;   /* store start address */
+        switch (type)
+        {
+            case RTR0MEMOBJTYPE_CONT:
+                rc = get_memory_map(pvMap, cb, physMap, 2);
+                if (rc == B_OK)
+                    pMemHaiku->Core.u.Cont.Phys = physMap[0].address;
+                break;
+
+            case RTR0MEMOBJTYPE_PHYS:
+            case RTR0MEMOBJTYPE_PHYS_NC:
+                rc = get_memory_map(pvMap, cb, physMap, 2);
+                if (rc == B_OK)
+                {
+                    pMemHaiku->Core.u.Phys.PhysBase = physMap[0].address;
+                    pMemHaiku->Core.u.Phys.fAllocated = true;
+                }
+                break;
+
+            default:
+                break;
+        }
+        if (rc >= B_OK)
+        {
+            *ppMem = &pMemHaiku->Core;
+            return VINF_SUCCESS;
+        }
+
+           delete_area(pMemHaiku->AreaId);
+    }
+
+    rtR0MemObjDelete(&pMemHaiku->Core);
+    return RTErrConvertFromHaikuKernReturn(rc);
+}
+
+
+int rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+    return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_PAGE, 0 /* PhysHighest */, 0 /* uAlignment */);
+}
+
+
+int rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+    return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_LOW, 0 /* PhysHighest */, 0 /* uAlignment */);
+}
+
+
+int rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable)
+{
+    return rtR0MemObjNativeAllocArea(ppMem, cb, fExecutable, RTR0MEMOBJTYPE_CONT, 0 /* PhysHighest */, 0 /* uAlignment */);
+}
+
+int rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
+{
+    return rtR0MemObjNativeAllocArea(ppMem, cb, false, RTR0MEMOBJTYPE_PHYS, PhysHighest, uAlignment);
+}
+
+
+int rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest)
+{
+    return rtR0MemObjNativeAllocPhys(ppMem, cb, PhysHighest, PAGE_SIZE);
+}
+
+
+int rtR0MemObjNativeEnterPhys(PPRTR0MEMOBJINTERNAL ppMem, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy)
+{
+    AssertReturn(uCachePolicy == RTMEM_CACHE_POLICY_DONT_CARE, VERR_NOT_SUPPORTED);
+    LogFlowFunc(("ppMem=%p Phys=%08x cb=%u uCachePolicy=%x\n", ppMem, Phys, (unsigned)cb, uCachePolicy));
+
+    /* Create the object. */
+    PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_PHYS, NULL, cb);
+    if (!pMemHaiku)
+        return VERR_NO_MEMORY;
+
+    /* There is no allocation here, it needs to be mapped somewhere first. */
+    pMemHaiku->AreaId = -1;
+    pMemHaiku->Core.u.Phys.fAllocated = false;
+    pMemHaiku->Core.u.Phys.PhysBase = Phys;
+    pMemHaiku->Core.u.Phys.uCachePolicy = uCachePolicy;
+    *ppMem = &pMemHaiku->Core;
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker locking the memory in either kernel or user maps.
+ *
+ * @returns IPRT status code.
+ * @param   ppMem        Where to store the allocated memory object.
+ * @param   pvStart      The starting address.
+ * @param   cb           The size of the block.
+ * @param   fAccess      The mapping protection to apply.
+ * @param   R0Process    The process to map the memory to (use NIL_RTR0PROCESS
+ *                       for the kernel)
+ * @param   fFlags       Memory flags (B_READ_DEVICE indicates the memory is
+ *                       intended to be written from a "device").
+ */
+static int rtR0MemObjNativeLockInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvStart, size_t cb, uint32_t fAccess,
+                                     RTR0PROCESS R0Process, int fFlags)
+{
+    NOREF(fAccess);
+    int rc;
+    team_id TeamId = B_SYSTEM_TEAM;
+
+    LogFlowFunc(("ppMem=%p pvStart=%p cb=%u fAccess=%x R0Process=%d fFlags=%x\n", ppMem, pvStart, cb, fAccess, R0Process,
+                fFlags));
+
+    /* Create the object. */
+    PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_LOCK, pvStart, cb);
+    if (RT_UNLIKELY(!pMemHaiku))
+        return VERR_NO_MEMORY;
+
+    if (R0Process != NIL_RTR0PROCESS)
+        TeamId = (team_id)R0Process;
+    rc = lock_memory_etc(TeamId, pvStart, cb, fFlags);
+    if (rc == B_OK)
+    {
+        pMemHaiku->AreaId = -1;
+        pMemHaiku->Core.u.Lock.R0Process = R0Process;
+        *ppMem = &pMemHaiku->Core;
+        return VINF_SUCCESS;
+    }
+    rtR0MemObjDelete(&pMemHaiku->Core);
+    return RTErrConvertFromHaikuKernReturn(rc);
+}
+
+
+int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess, RTR0PROCESS R0Process)
+{
+    return rtR0MemObjNativeLockInMap(ppMem, (void *)R3Ptr, cb, fAccess, R0Process, B_READ_DEVICE);
+}
+
+
+int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, uint32_t fAccess)
+{
+    return rtR0MemObjNativeLockInMap(ppMem, pv, cb, fAccess, NIL_RTR0PROCESS, B_READ_DEVICE);
+}
+
+
+#if 0
+/** @todo Reserve address space */
+/**
+ * Worker for the two virtual address space reservers.
+ *
+ * We're leaning on the examples provided by mmap and vm_mmap in vm_mmap.c here.
+ */
+static int rtR0MemObjNativeReserveInMap(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment,
+                                        RTR0PROCESS R0Process)
+{
+    int rc;
+    team_id TeamId = B_SYSTEM_TEAM;
+
+    LogFlowFunc(("ppMem=%p pvFixed=%p cb=%u uAlignment=%u R0Process=%d\n", ppMem, pvFixed, (unsigned)cb, uAlignment, R0Process));
+
+    if (R0Process != NIL_RTR0PROCESS)
+        team = (team_id)R0Process;
+
+    /* Check that the specified alignment is supported. */
+    if (uAlignment > PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+
+    /* Create the object. */
+    PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(*pMemHaiku), RTR0MEMOBJTYPE_RES_VIRT, NULL, cb);
+    if (!pMemHaiku)
+        return VERR_NO_MEMORY;
+
+    /* Ask the kernel to reserve the address range. */
+    //XXX: vm_reserve_address_range ?
+    return VERR_NOT_SUPPORTED;
+}
+#endif
+
+
+int rtR0MemObjNativeReserveKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pvFixed, size_t cb, size_t uAlignment)
+{
+    return VERR_NOT_SUPPORTED;
+}
+
+
+int rtR0MemObjNativeReserveUser(PPRTR0MEMOBJINTERNAL ppMem, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment, RTR0PROCESS R0Process)
+{
+    return VERR_NOT_SUPPORTED;
+}
+
+
+int rtR0MemObjNativeMapKernel(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, void *pvFixed, size_t uAlignment,
+                              unsigned fProt, size_t offSub, size_t cbSub)
+{
+    PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
+    PRTR0MEMOBJHAIKU pMemHaiku;
+    area_id area = -1;
+    void *pvMap = pvFixed;
+    uint32 uAddrSpec = B_EXACT_ADDRESS;
+    uint32 fProtect = 0;
+    int rc = VERR_MAP_FAILED;
+    AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED);
+    AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED);
+#if 0
+    /** @todo r=ramshankar: Wrong format specifiers, fix later! */
+    dprintf("%s(%p, %p, %p, %d, %x, %u, %u)\n", __FUNCTION__, ppMem, pMemToMap, pvFixed, uAlignment,
+        fProt, offSub, cbSub);
+#endif
+    /* Check that the specified alignment is supported. */
+    if (uAlignment > PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+
+    /* We can't map anything to the first page, sorry. */
+    if (pvFixed == 0)
+        return VERR_NOT_SUPPORTED;
+
+    if (fProt & RTMEM_PROT_READ)
+        fProtect |= B_KERNEL_READ_AREA;
+    if (fProt & RTMEM_PROT_WRITE)
+        fProtect |= B_KERNEL_WRITE_AREA;
+
+    /*
+     * Either the object we map has an area associated with, which we can clone,
+     * or it's a physical address range which we must map.
+     */
+    if (pMemToMapHaiku->AreaId > -1)
+    {
+        if (pvFixed == (void *)-1)
+            uAddrSpec = B_ANY_KERNEL_ADDRESS;
+
+        rc = area = clone_area("IPRT R0MemObj MapKernel", &pvMap, uAddrSpec, fProtect, pMemToMapHaiku->AreaId);
+        LogFlow(("rtR0MemObjNativeMapKernel: clone_area uAddrSpec=%d fProtect=%x AreaId=%d rc=%d\n", uAddrSpec, fProtect,
+                pMemToMapHaiku->AreaId, rc));
+    }
+    else if (pMemToMapHaiku->Core.enmType == RTR0MEMOBJTYPE_PHYS)
+    {
+        /* map_physical_memory() won't let you choose where. */
+        if (pvFixed != (void *)-1)
+            return VERR_NOT_SUPPORTED;
+        uAddrSpec = B_ANY_KERNEL_ADDRESS;
+
+        rc = area = map_physical_memory("IPRT R0MemObj MapKernelPhys", (phys_addr_t)pMemToMapHaiku->Core.u.Phys.PhysBase,
+                                        pMemToMapHaiku->Core.cb, uAddrSpec, fProtect, &pvMap);
+    }
+    else
+        return VERR_NOT_SUPPORTED;
+
+    if (rc >= B_OK)
+    {
+        /* Create the object. */
+        pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU), RTR0MEMOBJTYPE_MAPPING, pvMap,
+                                                    pMemToMapHaiku->Core.cb);
+        if (RT_UNLIKELY(!pMemHaiku))
+               return VERR_NO_MEMORY;
+
+        pMemHaiku->Core.u.Mapping.R0Process = NIL_RTR0PROCESS;
+        pMemHaiku->Core.pv = pvMap;
+        pMemHaiku->AreaId = area;
+        *ppMem = &pMemHaiku->Core;
+        return VINF_SUCCESS;
+    }
+    rc = VERR_MAP_FAILED;
+
+    /** @todo finish the implementation. */
+
+    rtR0MemObjDelete(&pMemHaiku->Core);
+    return rc;
+}
+
+
+int rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)
+{
+#if 0
+    /*
+     * Check for unsupported stuff.
+     */
+    AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);
+    AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);
+    if (uAlignment > PAGE_SIZE)
+        return VERR_NOT_SUPPORTED;
+
+    int                rc;
+    PRTR0MEMOBJHAIKU pMemToMapHaiku = (PRTR0MEMOBJHAIKU)pMemToMap;
+    struct proc       *pProc            = (struct proc *)R0Process;
+    struct vm_map     *pProcMap         = &pProc->p_vmspace->vm_map;
+
+    /* calc protection */
+    vm_prot_t       ProtectionFlags = 0;
+    if ((fProt & RTMEM_PROT_NONE) == RTMEM_PROT_NONE)
+        ProtectionFlags = VM_PROT_NONE;
+    if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ)
+        ProtectionFlags |= VM_PROT_READ;
+    if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE)
+        ProtectionFlags |= VM_PROT_WRITE;
+    if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC)
+        ProtectionFlags |= VM_PROT_EXECUTE;
+
+    /* calc mapping address */
+    PROC_LOCK(pProc);
+    vm_offset_t AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA));
+    PROC_UNLOCK(pProc);
+
+    /* Insert the object in the map. */
+    rc = vm_map_find(pProcMap,              /* Map to insert the object in */
+                     NULL,                  /* Object to map */
+                     0,                     /* Start offset in the object */
+                     &AddrR3,               /* Start address IN/OUT */
+                     pMemToMap->cb,         /* Size of the mapping */
+                     TRUE,                  /* Whether a suitable address should be searched for first */
+                     ProtectionFlags,       /* protection flags */
+                     VM_PROT_ALL,           /* Maximum protection flags */
+                     0);                    /* Copy on write */
+
+    /* Map the memory page by page into the destination map. */
+    if (rc == KERN_SUCCESS)
+    {
+        size_t         cPages       = pMemToMap->cb >> PAGE_SHIFT;;
+        pmap_t         pPhysicalMap = pProcMap->pmap;
+        vm_offset_t    AddrR3Dst    = AddrR3;
+
+        if (   pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS
+            || pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS_NC
+            || pMemToMap->enmType == RTR0MEMOBJTYPE_PAGE)
+        {
+            /* Mapping physical allocations */
+            Assert(cPages == pMemToMapHaiku->u.Phys.cPages);
+
+            /* Insert the memory page by page into the mapping. */
+            for (uint32_t iPage = 0; iPage < cPages; iPage++)
+            {
+                vm_page_t pPage = pMemToMapHaiku->u.Phys.apPages[iPage];
+
+                MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
+                AddrR3Dst += PAGE_SIZE;
+            }
+        }
+        else
+        {
+            /* Mapping cont or low memory types */
+            vm_offset_t AddrToMap = (vm_offset_t)pMemToMap->pv;
+
+            for (uint32_t iPage = 0; iPage < cPages; iPage++)
+            {
+                vm_page_t pPage = PHYS_TO_VM_PAGE(vtophys(AddrToMap));
+
+                MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE);
+                AddrR3Dst += PAGE_SIZE;
+                AddrToMap += PAGE_SIZE;
+            }
+        }
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        /*
+         * Create a mapping object for it.
+         */
+        PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)rtR0MemObjNew(sizeof(RTR0MEMOBJHAIKU),
+                                                                           RTR0MEMOBJTYPE_MAPPING,
+                                                                           (void *)AddrR3,
+                                                                           pMemToMap->cb);
+        if (pMemHaiku)
+        {
+            Assert((vm_offset_t)pMemHaiku->Core.pv == AddrR3);
+            pMemHaiku->Core.u.Mapping.R0Process = R0Process;
+            *ppMem = &pMemHaiku->Core;
+            return VINF_SUCCESS;
+        }
+
+        rc = vm_map_remove(pProcMap, ((vm_offset_t)AddrR3), ((vm_offset_t)AddrR3) + pMemToMap->cb);
+        AssertMsg(rc == KERN_SUCCESS, ("Deleting mapping failed\n"));
+    }
+#endif
+    return VERR_NOT_SUPPORTED;
+}
+
+
+int rtR0MemObjNativeProtect(PRTR0MEMOBJINTERNAL pMem, size_t offSub, size_t cbSub, uint32_t fProt)
+{
+    return VERR_NOT_SUPPORTED;
+}
+
+
+RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage)
+{
+    PRTR0MEMOBJHAIKU pMemHaiku = (PRTR0MEMOBJHAIKU)pMem;
+    status_t rc;
+    
+    /** @todo r=ramshankar: Validate objects */
+ 
+    LogFlow(("rtR0MemObjNativeGetPagePhysAddr: pMem=%p enmType=%x iPage=%u\n", pMem, pMemHaiku->Core.enmType, (unsigned)iPage));
+
+    switch (pMemHaiku->Core.enmType)
+    {
+        case RTR0MEMOBJTYPE_LOCK:
+        {
+            team_id        TeamId = B_SYSTEM_TEAM;
+            physical_entry aPhysMap[2];
+            int32          cPhysMap = 2;	/** @todo r=ramshankar: why not use RT_ELEMENTS? */
+
+            if (pMemHaiku->Core.u.Lock.R0Process != NIL_RTR0PROCESS)
+                TeamId = (team_id)pMemHaiku->Core.u.Lock.R0Process;
+            void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
+
+            rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
+            if (rc < B_OK || cPhysMap < 1)
+                return NIL_RTHCPHYS;
+
+            return aPhysMap[0].address;
+        }
+
+#if 0
+        case RTR0MEMOBJTYPE_MAPPING:
+        {
+            vm_offset_t pb = (vm_offset_t)pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
+
+            if (pMemHaiku->Core.u.Mapping.R0Process != NIL_RTR0PROCESS)
+            {
+                struct proc    *pProc     = (struct proc *)pMemHaiku->Core.u.Mapping.R0Process;
+                struct vm_map  *pProcMap  = &pProc->p_vmspace->vm_map;
+                pmap_t pPhysicalMap       = pProcMap->pmap;
+
+                return pmap_extract(pPhysicalMap, pb);
+            }
+            return vtophys(pb);
+        }
+#endif
+        case RTR0MEMOBJTYPE_CONT:
+            return pMemHaiku->Core.u.Cont.Phys + (iPage << PAGE_SHIFT);
+
+        case RTR0MEMOBJTYPE_PHYS:
+            return pMemHaiku->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT);
+
+        case RTR0MEMOBJTYPE_LOW:
+        case RTR0MEMOBJTYPE_PAGE:
+        case RTR0MEMOBJTYPE_PHYS_NC:
+        {
+            team_id        TeamId = B_SYSTEM_TEAM;
+            physical_entry aPhysMap[2];
+            int32          cPhysMap = 2;	/** @todo r=ramshankar: why not use RT_ELEMENTS? */
+
+            void *pb = pMemHaiku->Core.pv + (iPage << PAGE_SHIFT);
+            rc = get_memory_map_etc(TeamId, pb, B_PAGE_SIZE, aPhysMap, &cPhysMap);
+            if (rc < B_OK || cPhysMap < 1)
+                return NIL_RTHCPHYS;
+
+            return aPhysMap[0].address;
+        }
+
+        case RTR0MEMOBJTYPE_RES_VIRT:
+        default:
+            return NIL_RTHCPHYS;
+    }
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/mp-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/mp-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/mp-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,218 @@
+/* $Id$ */
+/** @file
+ * IPRT - Multiprocessor, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+
+#include <iprt/mp.h>
+#include <iprt/err.h>
+#include <iprt/asm.h>
+#include <iprt/cpuset.h>
+#include "r0drv/mp-r0drv.h"
+
+
+RTDECL(RTCPUID) RTMpCpuId(void)
+{
+    return smp_get_current_cpu();
+}
+
+
+RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu)
+{
+    return idCpu < smp_get_num_cpus() ? (int)idCpu : -1;
+}
+
+
+RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu)
+{
+    return (unsigned)iCpu < smp_get_num_cpus() ? (RTCPUID)iCpu : NIL_RTCPUID;
+}
+
+
+RTDECL(RTCPUID) RTMpGetMaxCpuId(void)
+{
+    return smp_get_num_cpus() - 1;
+}
+
+
+RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu)
+{
+    return idCpu < smp_get_num_cpus();
+}
+
+
+RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet)
+{
+    RTCPUID idCpu;
+
+    RTCpuSetEmpty(pSet);
+    idCpu = RTMpGetMaxCpuId();
+    do
+    {
+        if (RTMpIsCpuPossible(idCpu))
+            RTCpuSetAdd(pSet, idCpu);
+    } while (idCpu-- > 0);
+    return pSet;
+}
+
+
+RTDECL(RTCPUID) RTMpGetCount(void)
+{
+    return smp_get_num_cpus();
+}
+
+
+RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu)
+{
+    return idCpu < smp_get_num_cpus();
+    /** @todo: FixMe && !CPU_ABSENT(idCpu) */
+}
+
+
+RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet)
+{
+    RTCPUID idCpu;
+
+    RTCpuSetEmpty(pSet);
+    idCpu = RTMpGetMaxCpuId();
+    do
+    {
+        if (RTMpIsCpuOnline(idCpu))
+            RTCpuSetAdd(pSet, idCpu);
+    } while (idCpu-- > 0);
+
+    return pSet;
+}
+
+
+RTDECL(RTCPUID) RTMpGetOnlineCount(void)
+{
+    return smp_get_num_cpus();
+}
+
+
+/**
+ * Wrapper between the native Haiku per-cpu callback and PFNRTWORKER
+ * for the RTMpOnAll API.
+ *
+ * @param   pvArg   Pointer to the RTMPARGS package.
+ */
+static void rtmpOnAllHaikuWrapper(void *pvArg, int current)
+{
+    PRTMPARGS pArgs = (PRTMPARGS)pvArg;
+    pArgs->pfnWorker(current, pArgs->pvUser1, pArgs->pvUser2);
+}
+
+
+RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+    RTMPARGS Args;
+    Args.pfnWorker = pfnWorker;
+    Args.pvUser1 = pvUser1;
+    Args.pvUser2 = pvUser2;
+    Args.idCpu = NIL_RTCPUID;
+    Args.cHits = 0;
+    /* is _sync needed ? */
+    call_all_cpus_sync(rtmpOnAllHaikuWrapper, &Args);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Wrapper between the native Haiku per-cpu callback and PFNRTWORKER
+ * for the RTMpOnOthers API.
+ *
+ * @param   pvArg   Pointer to the RTMPARGS package.
+ */
+static void rtmpOnOthersHaikuWrapper(void *pvArg, int current)
+{
+    PRTMPARGS pArgs = (PRTMPARGS)pvArg;
+    RTCPUID idCpu = current;
+    if (pArgs->idCpu != idCpu)
+        pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
+}
+
+
+RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+    /* Will panic if no rendezvousing cpus, so check up front. */
+    if (RTMpGetOnlineCount() > 1)
+    {
+        RTMPARGS    Args;
+
+        Args.pfnWorker = pfnWorker;
+        Args.pvUser1 = pvUser1;
+        Args.pvUser2 = pvUser2;
+        Args.idCpu = RTMpCpuId();
+        Args.cHits = 0;
+        /* is _sync needed ? */
+        call_all_cpus_sync(rtmpOnOthersHaikuWrapper, &Args);
+    }
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Wrapper between the native Haiku per-cpu callback and PFNRTWORKER
+ * for the RTMpOnSpecific API.
+ *
+ * @param   pvArg   Pointer to the RTMPARGS package.
+ */
+static void rtmpOnSpecificHaikuWrapper(void *pvArg, int current)
+{
+    PRTMPARGS   pArgs = (PRTMPARGS)pvArg;
+    RTCPUID     idCpu = current;
+    if (pArgs->idCpu == idCpu)
+    {
+        pArgs->pfnWorker(idCpu, pArgs->pvUser1, pArgs->pvUser2);
+        ASMAtomicIncU32(&pArgs->cHits);
+    }
+}
+
+
+RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2)
+{
+    RTMPARGS    Args;
+
+    /* Will panic if no rendezvousing cpus, so make sure the cpu is online. */
+    if (!RTMpIsCpuOnline(idCpu))
+        return VERR_CPU_NOT_FOUND;
+
+    Args.pfnWorker = pfnWorker;
+    Args.pvUser1 = pvUser1;
+    Args.pvUser2 = pvUser2;
+    Args.idCpu = idCpu;
+    Args.cHits = 0;
+    /* is _sync needed ? */
+    call_all_cpus_sync(rtmpOnSpecificHaikuWrapper, &Args);
+    return Args.cHits == 1
+         ? VINF_SUCCESS
+         : VERR_CPU_NOT_FOUND;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/process-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/process-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/process-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,45 @@
+/* $Id$ */
+/** @file
+ * IPRT - Process, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/process.h>
+
+
+RTDECL(RTPROCESS) RTProcSelf(void)
+{
+    return getpid();
+}
+
+
+RTR0DECL(RTR0PROCESS) RTR0ProcHandleSelf(void)
+{
+    return (RTR0PROCESS)(team_id)getpid();
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/semevent-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/semevent-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/semevent-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,262 @@
+/* $Id$ */
+/** @file
+ * IPRT - Single Release Event Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/lockvalidator.h>
+#include <iprt/mem.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * Haiku event semaphore.
+ */
+typedef struct RTSEMEVENTINTERNAL
+{
+    /** Magic value (RTSEMEVENT_MAGIC). */
+    uint32_t volatile   u32Magic;
+    /** Reference counter. */
+    uint32_t volatile   cRefs;
+    /** The semaphore Id. */
+    sem_id              SemId;
+} RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
+
+
+RTDECL(int)  RTSemEventCreate(PRTSEMEVENT phEventSem)
+{
+    return RTSemEventCreateEx(phEventSem, 0 /*fFlags*/, NIL_RTLOCKVALCLASS, NULL);
+}
+
+
+RTDECL(int)  RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...)
+{
+    AssertCompile(sizeof(RTSEMEVENTINTERNAL) > sizeof(void *));
+    AssertReturn(!(fFlags & ~(RTSEMEVENT_FLAGS_NO_LOCK_VAL | RTSEMEVENT_FLAGS_BOOTSTRAP_HACK)), VERR_INVALID_PARAMETER);
+    Assert(!(fFlags & RTSEMEVENT_FLAGS_BOOTSTRAP_HACK) || (fFlags & RTSEMEVENT_FLAGS_NO_LOCK_VAL));
+    AssertPtrReturn(phEventSem, VERR_INVALID_POINTER);
+
+    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)RTMemAllocZ(sizeof(*pThis));
+    if (!pThis)
+        return VERR_NO_MEMORY;
+
+    pThis->u32Magic  = RTSEMEVENT_MAGIC;
+    pThis->cRefs     = 1;
+    pThis->SemId     = create_sem(0, "IPRT Semaphore Event");
+    if (pThis->SemId >= B_OK)
+    {
+        set_sem_owner(pThis->SemId, B_SYSTEM_TEAM);
+        *phEventSem = pThis;
+        return VINF_SUCCESS;
+    }
+
+    RTMemFree(pThis);
+    return VERR_TOO_MANY_SEMAPHORES; /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+/**
+ * Retains a reference to the event semaphore.
+ *
+ * @param   pThis       The event semaphore.
+ */
+DECLINLINE(void) rtR0SemEventHkuRetain(PRTSEMEVENTINTERNAL pThis)
+{
+    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+    Assert(cRefs < 100000); NOREF(cRefs);
+}
+
+
+/**
+ * Releases a reference to the event semaphore.
+ *
+ * @param   pThis       The event semaphore.
+ */
+DECLINLINE(void) rtR0SemEventHkuRelease(PRTSEMEVENTINTERNAL pThis)
+{
+    if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
+        RTMemFree(pThis);
+}
+
+
+RTDECL(int)  RTSemEventDestroy(RTSEMEVENT hEventSem)
+{
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTINTERNAL pThis = hEventSem;
+    if (pThis == NIL_RTSEMEVENT)
+        return VINF_SUCCESS;
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+    Assert(pThis->cRefs > 0);
+
+    /*
+     * Invalidate it and delete the semaphore to unblock everyone.
+     */
+    ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENT_MAGIC);
+    delete_sem(pThis->SemId);
+    pThis->SemId = -1;
+    rtR0SemEventHkuRelease(pThis);
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSemEventSignal(RTSEMEVENT hEventSem)
+{
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTINTERNAL pThis = (PRTSEMEVENTINTERNAL)hEventSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("pThis->u32Magic=%RX32 pThis=%p\n", pThis->u32Magic, pThis), VERR_INVALID_HANDLE);
+    rtR0SemEventHkuRetain(pThis);
+
+    /*
+     * Signal the event object.
+     * We must use B_DO_NOT_RESCHEDULE since we are being used from an irq handler.
+     */
+    release_sem_etc(pThis->SemId, 1, B_DO_NOT_RESCHEDULE);
+    rtR0SemEventHkuRelease(pThis);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker for RTSemEventWaitEx and RTSemEventWaitExDebug.
+ *
+ * @returns VBox status code.
+ * @param   pThis           The event semaphore.
+ * @param   fFlags          See RTSemEventWaitEx.
+ * @param   uTimeout        See RTSemEventWaitEx.
+ * @param   pSrcPos         The source code position of the wait.
+ */
+static int rtR0SemEventWait(PRTSEMEVENTINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
+                            PCRTLOCKVALSRCPOS pSrcPos)
+{
+    status_t  status;
+    int       rc;
+    int32     flags = 0;
+    bigtime_t timeout; /* in microseconds */
+
+    /*
+     * Validate the input.
+     */
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
+
+    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+        timeout = B_INFINITE_TIMEOUT;
+    else {
+        if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
+            timeout = uTimeout / 1000;
+        else if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+            timeout = uTimeout * 1000;
+        else
+            return VERR_INVALID_PARAMETER;
+
+        if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+            flags |= B_RELATIVE_TIMEOUT;
+        else if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
+            flags |= B_ABSOLUTE_TIMEOUT;
+        else
+            return VERR_INVALID_PARAMETER;
+    }
+
+    if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
+        flags |= B_CAN_INTERRUPT;
+    // likely not:
+    //else
+    //    flags |= B_KILL_CAN_INTERRUPT;
+
+    rtR0SemEventHkuRetain(pThis);
+
+    status = acquire_sem_etc(pThis->SemId, 1, flags, timeout);
+
+    switch (status)
+    {
+        case B_OK:
+            rc = VINF_SUCCESS;
+            break;
+        case B_BAD_SEM_ID:
+            rc = VERR_SEM_DESTROYED;
+            break;
+        case B_INTERRUPTED:
+            rc = VERR_INTERRUPTED;
+            break;
+        case B_WOULD_BLOCK:
+            /* fallthrough ? */
+        case B_TIMED_OUT:
+            rc = VERR_TIMEOUT;
+            break;
+        default:
+            rc = RTErrConvertFromHaikuKernReturn(status);
+            break;
+    }
+
+    rtR0SemEventHkuRelease(pThis);
+    return rc;
+}
+
+
+RTDECL(int)  RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout)
+{
+#ifndef RTSEMEVENT_STRICT
+    return rtR0SemEventWait(hEventSem, fFlags, uTimeout, NULL);
+#else
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
+    return rtR0SemEventWait(hEventSem, fFlags, uTimeout, &SrcPos);
+#endif
+}
+RT_EXPORT_SYMBOL(RTSemEventWaitEx);
+
+
+RTDECL(int)  RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout,
+                                   RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
+    return rtR0SemEventWait(hEventSem, fFlags, uTimeout, &SrcPos);
+}
+RT_EXPORT_SYMBOL(RTSemEventWaitExDebug);
+
+
+RTDECL(uint32_t) RTSemEventGetResolution(void)
+{
+    /* At least that's what the API supports. */
+    return 1000;
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/semeventmulti-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,291 @@
+/* $Id$ */
+/** @file
+ * IPRT - Multiple Release Event Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/lockvalidator.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * Haiku multiple release event semaphore.
+ */
+typedef struct RTSEMEVENTMULTIINTERNAL
+{
+    /** Magic value (RTSEMEVENTMULTI_MAGIC). */
+    uint32_t volatile   u32Magic;
+    /** Reference counter. */
+    uint32_t volatile   cRefs;
+    /** The semaphore Id. */
+    sem_id              SemId;
+} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
+
+
+RTDECL(int)  RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem)
+{
+    return RTSemEventMultiCreateEx(phEventMultiSem, 0 /* fFlags */, NIL_RTLOCKVALCLASS, NULL);
+}
+
+
+RTDECL(int)  RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
+                                     const char *pszNameFmt, ...)
+{
+    PRTSEMEVENTMULTIINTERNAL pThis;
+
+    AssertReturn(!(fFlags & ~RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL), VERR_INVALID_PARAMETER);
+    pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));
+    if (!pThis)
+        return VERR_NO_MEMORY;
+
+    pThis->u32Magic  = RTSEMEVENTMULTI_MAGIC;
+    pThis->cRefs     = 1;
+    pThis->SemId     = create_sem(0, "IPRT Semaphore Event Multi");
+    if (pThis->SemId < B_OK)
+    {
+        set_sem_owner(pThis->SemId, B_SYSTEM_TEAM);
+        *phEventMultiSem = pThis;
+        return VINF_SUCCESS;
+    }
+
+    RTMemFree(pThis);
+    return VERR_TOO_MANY_SEMAPHORES;  /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+/**
+ * Retain a reference to the semaphore.
+ *
+ * @param   pThis       The semaphore.
+ */
+DECLINLINE(void) rtR0SemEventMultiHkuRetain(PRTSEMEVENTMULTIINTERNAL pThis)
+{
+    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
+    Assert(cRefs && cRefs < 100000);
+}
+
+
+/**
+ * Release a reference, destroy the thing if necessary.
+ *
+ * @param   pThis       The semaphore.
+ */
+DECLINLINE(void) rtR0SemEventMultiHkuRelease(PRTSEMEVENTMULTIINTERNAL pThis)
+{
+    if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
+    {
+        Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC);
+        RTMemFree(pThis);
+    }
+}
+
+
+RTDECL(int)  RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem)
+{
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+    if (pThis == NIL_RTSEMEVENTMULTI)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    Assert(pThis->cRefs > 0);
+
+    /*
+     * Invalidate it and signal the object just in case.
+     */
+    ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC);
+    delete_sem(pThis->SemId);
+    pThis->SemId = -1;
+    rtR0SemEventMultiHkuRelease(pThis);
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)
+{
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+    if (!pThis)
+        return VERR_INVALID_PARAMETER;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    rtR0SemEventMultiHkuRetain(pThis);
+
+    /*
+     * Signal the event object.
+     * We must use B_DO_NOT_RESCHEDULE since we are being used from an irq handler.
+     */
+    release_sem_etc(pThis->SemId, 1, B_RELEASE_ALL | B_DO_NOT_RESCHEDULE);
+    rtR0SemEventMultiHkuRelease(pThis);
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem)
+{
+    /*
+     * Validate input.
+     */
+    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
+    if (!pThis)
+        return VERR_INVALID_PARAMETER;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    rtR0SemEventMultiHkuRetain(pThis);
+
+    /*
+     * Reset it.
+     */
+    //FIXME: what should I do ???
+    // delete_sem + create_sem ??
+    rtR0SemEventMultiHkuRelease(pThis);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Worker for RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug.
+ *
+ * @returns VBox status code.
+ * @param   pThis           The event semaphore.
+ * @param   fFlags          See RTSemEventMultiWaitEx.
+ * @param   uTimeout        See RTSemEventMultiWaitEx.
+ * @param   pSrcPos         The source code position of the wait.
+ */
+static int rtR0SemEventMultiHkuWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
+                                    PCRTLOCKVALSRCPOS pSrcPos)
+{
+    status_t    status;
+    int         rc;
+    int32     flags = 0;
+    bigtime_t timeout; /* in microseconds */
+
+    /*
+     * Validate the input.
+     */
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
+    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
+
+    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+        timeout = B_INFINITE_TIMEOUT;
+    else
+    {
+        if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
+            timeout = uTimeout / 1000;
+        else if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+            timeout = uTimeout * 1000;
+        else
+            return VERR_INVALID_PARAMETER;
+
+        if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+            flags |= B_RELATIVE_TIMEOUT;
+        else if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
+            flags |= B_ABSOLUTE_TIMEOUT;
+        else
+            return VERR_INVALID_PARAMETER;
+    }
+
+    if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
+        flags |= B_CAN_INTERRUPT;
+    // likely not:
+    //else
+    //    flags |= B_KILL_CAN_INTERRUPT;
+
+    rtR0SemEventMultiHkuRetain(pThis);
+
+    status = acquire_sem_etc(pThis->SemId, 1, flags, timeout);
+
+    switch (status)
+    {
+        case B_OK:
+            rc = VINF_SUCCESS;
+            break;
+        case B_BAD_SEM_ID:
+            rc = VERR_SEM_DESTROYED;
+            break;
+        case B_INTERRUPTED:
+            rc = VERR_INTERRUPTED;
+            break;
+        case B_WOULD_BLOCK:
+            /* fallthrough? */
+        case B_TIMED_OUT:
+            rc = VERR_TIMEOUT;
+            break;
+        default:
+            rc = RTErrConvertFromHaikuKernReturn(status);
+            break;
+    }
+
+    rtR0SemEventMultiHkuRelease(pThis);
+    return rc;
+}
+
+
+RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
+{
+#ifndef RTSEMEVENT_STRICT
+    return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, NULL);
+#else
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
+    return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
+#endif
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWaitEx);
+
+
+RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
+    return rtR0SemEventMultiHkuWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiWaitExDebug);
+
+
+RTDECL(uint32_t) RTSemEventMultiGetResolution(void)
+{
+    /* At least that's what the API supports. */
+    return 1000;
+}
+RT_EXPORT_SYMBOL(RTSemEventMultiGetResolution);
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/semfastmutex-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/semfastmutex-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/semfastmutex-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,120 @@
+/* $Id$ */
+/** @file
+ * IPRT - Fast Mutex Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+
+#include <iprt/semaphore.h>
+#include <iprt/err.h>
+#include <iprt/alloc.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * Wrapper for the Haiku (sleep) mutex.
+ */
+typedef struct RTSEMFASTMUTEXINTERNAL
+{
+    /** Magic value (RTSEMFASTMUTEX_MAGIC). */
+    uint32_t            u32Magic;
+    /** A good old Benaphore. */
+    vint32              BenId;
+    sem_id              SemId;
+} RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
+
+
+RTDECL(int)  RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx)
+{
+    AssertCompile(sizeof(RTSEMFASTMUTEXINTERNAL) > sizeof(void *));
+    AssertPtrReturn(phFastMtx, VERR_INVALID_POINTER);
+
+    PRTSEMFASTMUTEXINTERNAL pThis = (PRTSEMFASTMUTEXINTERNAL)RTMemAllocZ(sizeof(*pThis));
+    if (RT_UNLIKELY(!pThis))
+    	return VERR_NO_MEMORY;
+
+    pThis->u32Magic = RTSEMFASTMUTEX_MAGIC;
+    pThis->BenId = 0;
+    pThis->SemId = create_sem(0, "IPRT Fast Mutex Semaphore");
+    if (pThis->SemId >= B_OK)
+    {
+        *phFastMtx = pThis;
+        return VINF_SUCCESS;
+    }
+    RTMemFree(pThis);
+    return VERR_TOO_MANY_SEMAPHORES;	 /** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+RTDECL(int)  RTSemFastMutexDestroy(RTSEMFASTMUTEX hFastMtx)
+{
+    PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+    if (pThis == NIL_RTSEMFASTMUTEX)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+    ASMAtomicWriteU32(&pThis->u32Magic, RTSEMFASTMUTEX_MAGIC_DEAD);
+    delete_sem(pThis->SemId);
+    RTMemFree(pThis);
+
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx)
+{
+    PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+    if (atomic_add(&pThis->BenId, 1) > 0)
+        acquire_sem(pThis->SemId);
+
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx)
+{
+    PRTSEMFASTMUTEXINTERNAL pThis = hFastMtx;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMFASTMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+    if (atomic_add(&pThis->BenId, -1) > 1)
+        release_sem(pThis->SemId);
+
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/semmutex-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/semmutex-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/semmutex-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,225 @@
+/* $Id$ */
+/** @file
+ * IPRT - Mutex Semaphores, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/semaphore.h>
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/thread.h>
+#include <iprt/time.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * Wrapper for the Haiku (sleep) mutex.
+ */
+/* XXX: not optimal, maybe should use the (private)
+   kernel recursive_lock ? (but it's not waitable) */
+typedef struct RTSEMMUTEXINTERNAL
+{
+    /** Magic value (RTSEMMUTEX_MAGIC). */
+    uint32_t            u32Magic;
+    /** Kernel semaphore. */
+    sem_id              SemId;
+    /** Current holder */
+    volatile thread_id  OwnerId;
+    /** Recursion count */
+    int32               cRecursion;
+} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
+
+
+RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX phMutexSem)
+{
+    AssertCompile(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));
+    AssertPtrReturn(phMutexSem, VERR_INVALID_POINTER);
+
+    PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAllocZ(sizeof(*pThis));
+    if (RT_UNLIKELY(!pThis))
+        return VERR_NO_MEMORY;
+
+    pThis->u32Magic = RTSEMMUTEX_MAGIC;
+    pThis->SemId = create_sem(0, "IPRT Mutex Semaphore");
+    if (pThis->SemId < B_OK)
+    {
+        pThis->OwnerId = -1;
+        pThis->cRecursion = 0;
+        *phMutexSem = pThis;
+        return VINF_SUCCESS;
+    }
+    RTMemFree(pThis);
+    return VERR_TOO_MANY_SEMAPHORES;	/** @todo r=ramshankar: use RTErrConvertFromHaikuKernReturn */
+}
+
+
+RTDECL(int)  RTSemMutexDestroy(RTSEMMUTEX hMutexSem)
+{
+    PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+    if (pThis == NIL_RTSEMMUTEX)
+        return VINF_SUCCESS;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+    AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
+
+    delete_sem(pThis->SemId);
+    RTMemFree(pThis);
+
+    return VINF_SUCCESS;
+}
+
+
+/** @todo doxygen */
+static int rtSemMutexRequestEx(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout)
+{
+    PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+    int                 rc;
+    status_t            status;
+    int32               flags = 0;
+    bigtime_t           timeout; /* in microseconds */
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+    if (pThis->OwnerId == find_thread(NULL))
+    {
+        pThis->OwnerId++;
+        return VINF_SUCCESS;
+    }
+
+    if (fFlags & RTSEMWAIT_FLAGS_INDEFINITE)
+        timeout = B_INFINITE_TIMEOUT;
+    else
+    {
+    	if (fFlags & RTSEMWAIT_FLAGS_NANOSECS)
+            timeout = uTimeout / 1000;
+        else if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
+            timeout = uTimeout * 1000;
+        else
+            return VERR_INVALID_PARAMETER;
+
+        if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
+            flags |= B_RELATIVE_TIMEOUT;
+        else if (fFlags & RTSEMWAIT_FLAGS_ABSOLUTE)
+            flags |= B_ABSOLUTE_TIMEOUT;
+        else
+            return VERR_INVALID_PARAMETER;
+    }
+
+    if (fFlags & RTSEMWAIT_FLAGS_INTERRUPTIBLE)
+        flags |= B_CAN_INTERRUPT;
+
+    status = acquire_sem_etc(pThis->SemId, 1, flags, timeout);
+
+    switch (status)
+    {
+        case B_OK:
+            rc = VINF_SUCCESS;
+            pThis->cRecursion = 1;
+            pThis->OwnerId = find_thread(NULL);
+            break;
+        case B_BAD_SEM_ID:
+            rc = VERR_SEM_DESTROYED;
+            break;
+        case B_INTERRUPTED:
+            rc = VERR_INTERRUPTED;
+            break;
+        case B_WOULD_BLOCK:
+            /* fallthrough? */
+        case B_TIMED_OUT:
+            rc = VERR_TIMEOUT;
+            break;
+        default:
+            rc = VERR_INVALID_PARAMETER;
+            break;
+    }
+
+    return rc;
+}
+
+
+RTDECL(int)  RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
+{
+    return rtSemMutexRequestEx(hMutexSem, RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS, cMillies);
+}
+
+
+RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    return RTSemMutexRequest(hMutexSem, cMillies);
+}
+
+
+RTDECL(int)  RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
+{
+    return rtSemMutexRequestEx(hMutexSem, RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_MILLISECS, cMillies);
+}
+
+
+RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
+{
+    return RTSemMutexRequestNoResume(hMutexSem, cMillies);
+}
+
+
+RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX hMutexSem)
+{
+    PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
+
+    if (pThis->OwnerId != find_thread(NULL))
+        return VERR_INVALID_HANDLE;
+
+    if (--pThis->cRecursion == 0)
+    {
+        pThis->OwnerId == -1;
+        release_sem(pThis->SemId);
+    }
+
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutexSem)
+{
+    PRTSEMMUTEXINTERNAL pThis = hMutexSem;
+    AssertPtrReturn(pThis, false);
+    AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), false);
+
+    return pThis->OwnerId != -1;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/spinlock-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/spinlock-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/spinlock-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,145 @@
+/* $Id$ */
+/** @file
+ * IPRT - Spinlocks, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/spinlock.h>
+
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/thread.h>
+
+#include "internal/magics.h"
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * Wrapper for the KSPIN_LOCK type.
+ */
+typedef struct RTSPINLOCKINTERNAL
+{
+    /** Spinlock magic value (RTSPINLOCK_MAGIC). */
+    uint32_t volatile     u32Magic;
+    /** Spinlock creation flags */
+    uint32_t              fFlags;
+    /** Saved interrupt CPU status. */
+    cpu_status volatile   fIntSaved;
+    /** The Haiku spinlock structure. */
+    spinlock              hSpinLock;
+} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
+
+
+
+RTDECL(int)  RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName)
+{
+    RT_ASSERT_PREEMPTIBLE();
+    NOREF(pszName);
+
+    /*
+     * Allocate.
+     */
+    AssertCompile(sizeof(RTSPINLOCKINTERNAL) > sizeof(void *));
+    PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)RTMemAllocZ(sizeof(*pSpinlockInt));
+    if (RT_UNLIKELY(!pSpinlockInt))
+        return VERR_NO_MEMORY;
+
+    /*
+     * Initialize & return.
+     */
+    pSpinlockInt->u32Magic  = RTSPINLOCK_MAGIC;
+    pSpinlockInt->fFlags    = fFlags;
+    pSpinlockInt->fIntSaved = 0;
+    B_INITIALIZE_SPINLOCK(&pSpinlockInt->hSpinLock);
+
+    *pSpinlock = pSpinlockInt;
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(int)  RTSpinlockDestroy(RTSPINLOCK Spinlock)
+{
+    /*
+     * Validate input.
+     */
+    PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
+    if (RT_UNLIKELY(!pSpinlockInt))
+        return VERR_INVALID_PARAMETER;
+    AssertMsgReturn(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC,
+                    ("Invalid spinlock %p magic=%#x\n", pSpinlockInt, pSpinlockInt->u32Magic),
+                    VERR_INVALID_PARAMETER);
+
+    /*
+     * Make the lock invalid and release the memory.
+     */
+    ASMAtomicIncU32(&pSpinlockInt->u32Magic);
+
+    B_INITIALIZE_SPINLOCK(&pSpinlockInt->hSpinLock);
+
+    RTMemFree(pSpinlockInt);
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
+{
+    PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
+    AssertPtr(pSpinlockInt);
+    Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
+
+    /* Haiku cannot take spinlocks without disabling interrupts. Ignore our spinlock creation flags. */
+    pSpinlockInt->fIntSaved = disable_interrupts();
+    acquire_spinlock(&pSpinlockInt->hSpinLock);
+}
+
+
+RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
+{
+    PRTSPINLOCKINTERNAL pSpinlockInt = (PRTSPINLOCKINTERNAL)Spinlock;
+    AssertPtr(pSpinlockInt);
+    Assert(pSpinlockInt->u32Magic == RTSPINLOCK_MAGIC);
+
+    release_spinlock(&pSpinlockInt->hSpinLock);
+    restore_interrupts(pSpinlockInt->fIntSaved);
+}
+
+
+RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock)
+{
+    if (!(Spinlock->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE))
+        RTAssertMsg2("RTSpinlockReleaseNoInts: p=%p (magic=%#x)\n", Spinlock, Spinlock->u32Magic);
+    RTSpinlockRelease(Spinlock); 
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/the-haiku-kernel.h
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/the-haiku-kernel.h	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/the-haiku-kernel.h	(revision 43363)
@@ -0,0 +1,140 @@
+/* $Id$ */
+/** @file
+ * IPRT - Include all necessary headers for the Haiku kernel.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+#ifndef ___the_haiku_kernel_h
+#define ___the_haiku_kernel_h
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#include <stdlib.h>
+
+#include <OS.h>
+#include <KernelExport.h>
+
+#include <iprt/cdefs.h>
+#include <iprt/err.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/* headers/private/kernel/smp.h */
+
+extern int32 smp_get_num_cpus(void);
+extern int32 smp_get_current_cpu(void);
+
+/* headers/private/kernel/vm/vm.h */
+extern status_t vm_unreserve_address_range(team_id team, void *address, addr_t size);
+extern status_t vm_reserve_address_range(team_id team, void **_address, uint32 addressSpec, addr_t size, uint32 flags);
+extern area_id vm_clone_area(team_id team, const char *name, void **address,uint32 addressSpec, uint32 protection,
+                             uint32 mapping,area_id sourceArea, bool kernel);
+
+/* headers/private/kernel/thread_type.h */
+
+extern spinlock gThreadSpinlock;
+#define GRAB_THREAD_LOCK()    acquire_spinlock(&gThreadSpinlock)
+#define RELEASE_THREAD_LOCK() release_spinlock(&gThreadSpinlock)
+typedef struct
+{
+	int32			flags;			// summary of events relevant in interrupt
+									// handlers (signals pending, user debugging
+									// enabled, etc.)
+#if 0
+	Thread			*all_next;
+	Thread			*team_next;
+	Thread			*queue_next;	/* i.e. run queue, release queue, etc. */
+	timer			alarm;
+	thread_id		id;
+	char			name[B_OS_NAME_LENGTH];
+	int32			priority;
+	int32			next_priority;
+	int32			io_priority;
+	int32			state;
+	int32			next_state;
+#endif
+	// and a lot more...
+} Thread;
+
+/* headers/private/kernel/thread.h */
+
+extern Thread *thread_get_thread_struct(thread_id id);
+extern Thread *thread_get_thread_struct_locked(thread_id id);
+
+extern void thread_yield(bool force);
+
+
+#if 0
+typedef callout_id_t (*PFNSOL_timeout_generic)(int type, void (*func)(void *),
+                                               void *arg, hrtime_t expiration,
+                                               hrtime_t resultion, int flags);
+typedef hrtime_t    (*PFNSOL_untimeout_generic)(callout_id_t id, int nowait);
+typedef int         (*PFNSOL_cyclic_reprogram)(cyclic_id_t id, hrtime_t expiration);
+
+
+/* IPRT globals. */
+extern bool                     g_frthaikuSplSetsEIF;
+extern struct ddi_dma_attr      g_haikuX86PhysMemLimits;
+extern RTCPUSET                 g_rtMphaikuCpuSet;
+extern PFNSOL_timeout_generic   g_pfnrtR0Sol_timeout_generic;
+extern PFNSOL_untimeout_generic g_pfnrtR0Sol_untimeout_generic;
+extern PFNSOL_cyclic_reprogram  g_pfnrtR0Sol_cyclic_reprogram;
+
+/* Haiku globals. */
+extern uintptr_t                kernelbase;
+
+/* Misc stuff from newer kernels. */
+#ifndef CALLOUT_FLAG_ABSOLUTE
+# define CALLOUT_FLAG_ABSOLUTE 2
+#endif
+#endif
+
+RT_C_DECLS_END
+
+/**
+ * Convert from Haiku kernel return code to IPRT status code.
+ * @todo put this where it belongs! (i.e. in a separate file and prototype in iprt/err.h)
+ * Or as generic call since it's not r0 specific.
+ */
+DECLINLINE(int) RTErrConvertFromHaikuKernReturn(status_t rc)
+{
+    switch (rc)
+    {
+        case B_OK:               return VINF_SUCCESS;
+		case B_BAD_SEM_ID:       return VERR_SEM_ERROR;
+		case B_NO_MORE_SEMS:     return VERR_TOO_MANY_SEMAPHORES;
+		case B_BAD_THREAD_ID:       return VERR_INVALID_PARAMETER;
+		case B_NO_MORE_THREADS:  return VERR_MAX_THRDS_REACHED;
+		case B_BAD_TEAM_ID:       return VERR_INVALID_PARAMETER;
+		case B_NO_MORE_TEAMS:    return VERR_MAX_PROCS_REACHED;
+        //default:               return VERR_GENERAL_FAILURE;
+        /** POSIX Errors are defined as a subset of system errors. */
+        default:                 return RTErrConvertFromErrno(rc);
+    }
+}
+
+#endif /* ___the_haiku_kernel_h */
Index: /trunk/src/VBox/Runtime/r0drv/haiku/thread-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/thread-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/thread-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,127 @@
+/* $Id$ */
+/** @file
+ * IPRT - Threads, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/thread.h>
+
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/mp.h>
+
+
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void)
+{
+    return (RTNATIVETHREAD)find_thread(NULL);
+}
+
+
+RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies)
+{
+    RT_ASSERT_PREEMPTIBLE();
+    snooze((bigtime_t)cMillies * 1000);
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(bool) RTThreadYield(void)
+{
+    RT_ASSERT_PREEMPTIBLE();
+    //FIXME
+    //snooze(0);
+    thread_yield(true);
+    return true; /* this is fishy */
+}
+
+
+RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread)
+{
+    Assert(hThread == NIL_RTTHREAD);
+
+	//XXX: can't do this, it might actually be held by another cpu
+    //return !B_SPINLOCK_IS_LOCKED(&gThreadSpinlock);
+    return ASMIntAreEnabled(); /** @todo find a better way. */
+}
+
+
+RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread)
+{
+    Assert(hThread == NIL_RTTHREAD);
+	/** @todo check if Thread::next_priority or
+	 *        cpu_ent::invoke_scheduler could do. */
+    return false;
+}
+
+
+RTDECL(bool) RTThreadPreemptIsPendingTrusty(void)
+{
+    /* RTThreadPreemptIsPending is not reliable yet. */
+    return false;
+}
+
+
+RTDECL(bool) RTThreadPreemptIsPossible(void)
+{
+    /* yes, kernel preemption is possible. */
+    return true;
+}
+
+
+RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState)
+{
+    AssertPtr(pState);
+    Assert(pState->uOldCpuState == 0);
+
+    pState->uOldCpuState = (uint32_t)disable_interrupts();
+    RT_ASSERT_PREEMPT_CPUID_DISABLE(pState);
+}
+
+
+RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState)
+{
+    AssertPtr(pState);
+
+    RT_ASSERT_PREEMPT_CPUID_RESTORE(pState);
+    restore_interrupts((cpu_status)pState->uOldCpuState);
+    pState->uOldCpuState = 0;
+}
+
+
+RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread)
+{
+    Assert(hThread == NIL_RTTHREAD); NOREF(hThread);
+    /** @todo Implement RTThreadIsInInterrupt. Required for guest
+     *        additions! */
+    return !ASMIntAreEnabled();
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/thread2-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/thread2-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/thread2-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,130 @@
+/* $Id$ */
+/** @file
+ * IPRT - Threads (Part 2), Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/thread.h>
+
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# include <iprt/asm-amd64-x86.h>
+#endif
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include "internal/thread.h"
+
+
+int rtThreadNativeInit(void)
+{
+    /* No TLS in Ring-0. :-/ */
+    return VINF_SUCCESS;
+}
+
+
+RTDECL(RTTHREAD) RTThreadSelf(void)
+{
+    return rtThreadGetByNative((RTNATIVETHREAD)find_thread(NULL));
+}
+
+
+int rtThreadNativeSetPriority(PRTTHREADINT pThread, RTTHREADTYPE enmType)
+{
+    int32 iPriority;
+    status_t status;
+
+    /*
+     * Convert the priority type to native priorities.
+     * (This is quite naive but should be ok.)
+     */
+    switch (enmType)
+    {
+        case RTTHREADTYPE_INFREQUENT_POLLER: iPriority = B_LOWEST_ACTIVE_PRIORITY;      break;
+        case RTTHREADTYPE_EMULATION:         iPriority = B_LOW_PRIORITY;                break;
+        case RTTHREADTYPE_DEFAULT:           iPriority = B_NORMAL_PRIORITY;             break;
+        case RTTHREADTYPE_MSG_PUMP:          iPriority = B_DISPLAY_PRIORITY;            break;
+        case RTTHREADTYPE_IO:                iPriority = B_URGENT_DISPLAY_PRIORITY;     break;
+        case RTTHREADTYPE_TIMER:             iPriority = B_REAL_TIME_DISPLAY_PRIORITY;  break;
+        default:
+            AssertMsgFailed(("enmType=%d\n", enmType));
+            return VERR_INVALID_PARAMETER;
+    }
+
+	status = set_thread_priority((thread_id)pThread->Core.Key, iPriority);
+
+	return RTErrConvertFromHaikuKernReturn(status);
+}
+
+
+int rtThreadNativeAdopt(PRTTHREADINT pThread)
+{
+    return VERR_NOT_IMPLEMENTED;
+}
+
+
+void rtThreadNativeDestroy(PRTTHREADINT pThread)
+{
+    NOREF(pThread);
+}
+
+
+/**
+ * Native kernel thread wrapper function.
+ *
+ * This will forward to rtThreadMain and do termination upon return.
+ *
+ * @param pvArg         Pointer to the argument package.
+ * @param Ignored       Wait result, which we ignore.
+ */
+static status_t rtThreadNativeMain(void *pvArg)
+{
+    const thread_id Self = find_thread(NULL);
+    PRTTHREADINT pThread = (PRTTHREADINT)pvArg;
+
+    int rc = rtThreadMain(pThread, (RTNATIVETHREAD)Self, &pThread->szName[0]);
+
+	if (rc < 0)
+		return RTErrConvertFromHaikuKernReturn(rc);
+	return rc;
+}
+
+
+int rtThreadNativeCreate(PRTTHREADINT pThreadInt, PRTNATIVETHREAD pNativeThread)
+{
+	thread_id NativeThread;
+    RT_ASSERT_PREEMPTIBLE();
+
+    NativeThread = spawn_kernel_thread(rtThreadNativeMain, pThreadInt->szName, B_NORMAL_PRIORITY, pThreadInt);
+    if (NativeThread >= B_OK)
+    {
+    	resume_thread(NativeThread);
+        *pNativeThread = (RTNATIVETHREAD)NativeThread;
+        return VINF_SUCCESS;
+    }
+    return RTErrConvertFromHaikuKernReturn(NativeThread);
+}
Index: /trunk/src/VBox/Runtime/r0drv/haiku/time-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/time-r0drv-haiku.c	(revision 43363)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/time-r0drv-haiku.c	(revision 43363)
@@ -0,0 +1,78 @@
+/* $Id$ */
+/** @file
+ * IPRT - Time, Ring-0 Driver, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_TIME
+#include "the-haiku-kernel.h"
+#include "internal/iprt.h"
+#include <iprt/time.h>
+
+#include <iprt/asm.h>
+
+
+DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
+{
+	return system_time() * 1000;
+}
+
+
+DECLINLINE(uint64_t) rtTimeGetSystemMilliTS(void)
+{
+	return system_time() / 1000;
+}
+
+
+RTDECL(uint64_t) RTTimeNanoTS(void)
+{
+    return rtTimeGetSystemNanoTS();
+}
+
+
+RTDECL(uint64_t) RTTimeMilliTS(void)
+{
+    return rtTimeGetSystemMilliTS();
+}
+
+
+RTDECL(uint64_t) RTTimeSystemNanoTS(void)
+{
+    return rtTimeGetSystemNanoTS();
+}
+
+
+RTDECL(uint64_t) RTTimeSystemMilliTS(void)
+{
+    return rtTimeGetSystemMilliTS();
+}
+
+
+RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
+{
+    return RTTimeSpecSetNano(pTime, real_time_clock_usecs() * 1000);
+}
Index: /trunk/src/VBox/Runtime/r3/haiku/rtProcInitExePath-haiku.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/haiku/rtProcInitExePath-haiku.cpp	(revision 43363)
+++ /trunk/src/VBox/Runtime/r3/haiku/rtProcInitExePath-haiku.cpp	(revision 43363)
@@ -0,0 +1,60 @@
+/* $Id$ */
+/** @file
+ * IPRT - rtProcInitName, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_PROCESS
+#ifdef RT_OS_HAIKU
+# include <image.h>
+#endif
+
+#include <iprt/string.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <iprt/path.h>
+#include "internal/process.h"
+#include "internal/path.h"
+
+
+DECLHIDDEN(int) rtProcInitExePath(char *pszPath, size_t cchPath)
+{
+    image_info ImageInfo;
+    int32 Cookie = 0;
+    status_t status;
+
+    /*
+     * Query the image name from the OS, convert and return it.
+     */
+    status = get_next_image_info(0, &Cookie, &ImageInfo);
+    AssertReturn((status == B_OK), VERR_INTERNAL_ERROR);
+
+    int rc = rtPathFromNativeCopy(pszPath, MIN(cchPath, MAXPATHLEN), ImageInfo.name, NULL);
+    AssertMsgRCReturn(rc, ("rc=%Rrc pszLink=\"%s\"\nhex: %.*Rhxs\n", rc, pszPath, MIN(cchPath, MAXPATHLEN), pszPath), rc);
+
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/Runtime/r3/haiku/time-haiku.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/haiku/time-haiku.cpp	(revision 43363)
+++ /trunk/src/VBox/Runtime/r3/haiku/time-haiku.cpp	(revision 43363)
@@ -0,0 +1,84 @@
+/* $Id$ */
+/** @file
+ * IPRT - Time, Haiku.
+ */
+
+/*
+ * 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.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#define LOG_GROUP RTLOGGROUP_TIME
+#define RTTIME_INCL_TIMEVAL
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <OS.h>
+
+#include <iprt/time.h>
+#include <iprt/err.h>
+#include "internal/time.h"
+
+
+DECLINLINE(uint64_t) rtTimeGetSystemNanoTS(void)
+{
+	return (uint64_t)system_time() * 1000;
+}
+
+
+/**
+ * Gets the current nanosecond timestamp.
+ *
+ * This differs from RTTimeNanoTS in that it will use system APIs and not do any
+ * resolution or performance optimizations.
+ *
+ * @returns nanosecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeSystemNanoTS(void)
+{
+    return rtTimeGetSystemNanoTS();
+}
+
+
+/**
+ * Gets the current millisecond timestamp.
+ *
+ * This differs from RTTimeNanoTS in that it will use system APIs and not do any
+ * resolution or performance optimizations.
+ *
+ * @returns millisecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeSystemMilliTS(void)
+{
+    return rtTimeGetSystemNanoTS() / 1000000;
+}
+
+
+RTDECL(int) RTTimeSet(PCRTTIMESPEC pTime)
+{
+    struct timeval tv;
+	RTTimeSpecGetTimeval(pTime, &tv);
+	set_real_time_clock(tv.tv_sec);
+	return VINF_SUCCESS;
+}
Index: /trunk/src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/RTHandleGetStandard-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2010 Oracle Corporation
+ * Copyright (C) 2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -33,5 +33,4 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
-#include <sys/fcntl.h>
 #include <fcntl.h>
 #ifdef _MSC_VER
Index: /trunk/src/VBox/Runtime/r3/posix/dir-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/dir-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/dir-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -34,5 +34,4 @@
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <sys/fcntl.h>
 #include <fcntl.h>
 #include <dirent.h>
@@ -54,5 +53,5 @@
 #include "internal/path.h"
 
-#if !defined(RT_OS_SOLARIS)
+#if !defined(RT_OS_SOLARIS) && !defined(RT_OS_HAIKU)
 # define HAVE_DIRENT_D_TYPE 1
 #endif
Index: /trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/fileio-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -35,5 +35,4 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
-#include <sys/fcntl.h>
 #include <fcntl.h>
 #ifdef _MSC_VER
Index: /trunk/src/VBox/Runtime/r3/posix/fileio2-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/fileio2-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/fileio2-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -57,4 +57,8 @@
 #endif
 
+#ifdef RT_OS_HAIKU
+# define USE_FUTIMENS
+#endif
+
 #include <iprt/file.h>
 #include <iprt/path.h>
@@ -144,4 +148,28 @@
         return VINF_SUCCESS;
 
+#ifdef USE_FUTIMENS
+    struct timespec aTimespecs[2];
+    if (pAccessTime && pModificationTime)
+    {
+        memcpy(&aTimespecs[0], pAccessTime, sizeof(struct timespec));
+        memcpy(&aTimespecs[1], pModificationTime, sizeof(struct timespec));
+    }
+    else
+    {
+        RTFSOBJINFO ObjInfo;
+        int rc = RTFileQueryInfo(hFile, &ObjInfo, RTFSOBJATTRADD_UNIX);
+        if (RT_FAILURE(rc))
+            return rc;
+        memcpy(&aTimespecs[0], pAccessTime ? pAccessTime : &ObjInfo.AccessTime, sizeof(struct timespec));
+        memcpy(&aTimespecs[1], pModificationTime ? pModificationTime : &ObjInfo.ModificationTime, sizeof(struct timespec));
+    }
+
+    if (futimens(RTFileToNative(hFile), aTimespecs))
+    {
+        int rc = RTErrConvertFromErrno(errno);
+        Log(("RTFileSetTimes(%RTfile,%p,%p,,): returns %Rrc\n", hFile, pAccessTime, pModificationTime, rc));
+        return rc;
+    }
+#else
     /*
      * Convert the input to timeval, getting the missing one if necessary,
@@ -172,4 +200,5 @@
         return rc;
     }
+#endif
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/Runtime/r3/posix/filelock-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/filelock-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/filelock-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -34,5 +34,4 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
-#include <sys/fcntl.h>
 #include <fcntl.h>
 #include <unistd.h>
Index: /trunk/src/VBox/Runtime/r3/posix/fs2-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/fs2-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/fs2-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -34,4 +34,7 @@
 #ifndef DEV_BSIZE
 # include <sys/stat.h>
+# if defined(RT_OS_HAIKU) && !defined(S_BLKSIZE)
+#  define S_BLKSIZE 512
+# endif
 # define DEV_BSIZE S_BLKSIZE /** @todo bird: add DEV_BSIZE to sys/param.h on OS/2. */
 #endif
Index: /trunk/src/VBox/Runtime/r3/posix/rand-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/rand-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/rand-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -33,5 +33,4 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
-#include <sys/fcntl.h>
 #include <fcntl.h>
 #ifdef _MSC_VER
Index: /trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/semevent-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -49,5 +49,5 @@
 #endif
 
-#ifdef RT_OS_SOLARIS
+#if defined(RT_OS_SOLARIS) || defined(RT_OS_HAIKU)
 # include <sched.h>
 # define pthread_yield() sched_yield()
@@ -398,5 +398,5 @@
          */
         struct timespec     ts = {0,0};
-#ifdef RT_OS_DARWIN
+#if defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU)
         struct timeval      tv = {0,0};
         gettimeofday(&tv, NULL);
Index: /trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/semeventmulti-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -482,5 +482,5 @@
     if (!pThis->fMonotonicClock)
     {
-#ifdef RT_OS_DARWIN
+#if defined(RT_OS_DARWIN) || defined(RT_OS_HAIKU)
         struct timeval  tv = {0,0};
         gettimeofday(&tv, NULL);
Index: /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/semmutex-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2007 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -250,5 +250,12 @@
          */
         struct timespec     ts = {0,0};
+#ifdef RT_OS_HAIKU
+        struct timeval      tv = {0,0};
+        gettimeofday(&tv, NULL);
+        ts.tv_sec = tv.tv_sec;
+        ts.tv_nsec = tv.tv_usec * 1000;
+#else
         clock_gettime(CLOCK_REALTIME, &ts);
+#endif
         if (cMillies != 0)
         {
Index: /trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/thread-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -52,4 +52,7 @@
 # define IPRT_MAY_HAVE_PTHREAD_SET_NAME_NP
 # include <dlfcn.h>
+#endif
+#if defined(RT_OS_HAIKU)
+# include <OS.h>
 #endif
 
@@ -413,4 +416,13 @@
 
     return VINF_SUCCESS;
+#elif defined(RT_OS_HAIKU)
+    thread_info       ThreadInfo;
+    status_t status = get_thread_info(find_thread(NULL), &ThreadInfo);
+    AssertReturn(status == B_OK, RTErrConvertFromErrno(status));
+
+    *pKernelTime = ThreadInfo.kernel_time / 1000;
+    *pUserTime   = ThreadInfo.user_time / 1000;
+
+    return VINF_SUCCESS;
 #else
     return VERR_NOT_IMPLEMENTED;
Index: /trunk/src/VBox/Runtime/r3/posix/thread2-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/thread2-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/thread2-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2011 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -63,5 +63,5 @@
 #elif defined(RT_OS_FREEBSD) /* void pthread_yield */
         pthread_yield();
-#elif defined(RT_OS_SOLARIS)
+#elif defined(RT_OS_SOLARIS) || defined(RT_OS_HAIKU)
         sched_yield();
 #else
@@ -102,5 +102,5 @@
 #elif defined(RT_OS_FREEBSD) /* void pthread_yield */
         pthread_yield();
-#elif defined(RT_OS_SOLARIS)
+#elif defined(RT_OS_SOLARIS) || defined(RT_OS_HAIKU)
         sched_yield();
 #else
@@ -131,5 +131,5 @@
 #ifdef RT_OS_DARWIN
     pthread_yield_np();
-#elif defined(RT_OS_SOLARIS)
+#elif defined(RT_OS_SOLARIS) || defined(RT_OS_HAIKU)
     sched_yield();
 #else
Index: /trunk/src/VBox/Runtime/r3/posix/utf8-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/utf8-posix.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/posix/utf8-posix.cpp	(revision 43363)
@@ -5,5 +5,5 @@
 
 /*
- * Copyright (C) 2006-2010 Oracle Corporation
+ * Copyright (C) 2006-2012 Oracle Corporation
  *
  * This file is part of VirtualBox Open Source Edition (OSE), as
@@ -194,5 +194,5 @@
             const void *pvInputLeft = pvInput;
             void       *pvOutputLeft = pvOutput;
-#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || (defined(RT_OS_DARWIN) && defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)) /* there are different opinions about the constness of the input buffer. */
+#if defined(RT_OS_LINUX) || defined(RT_OS_HAIKU) || defined(RT_OS_SOLARIS) || (defined(RT_OS_DARWIN) && defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)) /* there are different opinions about the constness of the input buffer. */
             if (iconv(hIconv, (char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft) != (size_t)-1)
 #else
@@ -320,5 +320,5 @@
             const void *pvInputLeft = pvInput;
             void       *pvOutputLeft = pvOutput;
-#if defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || (defined(RT_OS_DARWIN) && defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)) /* there are different opinions about the constness of the input buffer. */
+#if defined(RT_OS_LINUX) || defined(RT_OS_HAIKU) || defined(RT_OS_SOLARIS) || (defined(RT_OS_DARWIN) && defined(_DARWIN_FEATURE_UNIX_CONFORMANCE)) /* there are different opinions about the constness of the input buffer. */
             if (iconv(icHandle, (char **)&pvInputLeft, &cbInLeft, (char **)&pvOutputLeft, &cbOutLeft) != (size_t)-1)
 #else
Index: /trunk/src/VBox/Runtime/r3/socket.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/socket.cpp	(revision 43362)
+++ /trunk/src/VBox/Runtime/r3/socket.cpp	(revision 43363)
@@ -34,4 +34,5 @@
 #else /* !RT_OS_WINDOWS */
 # include <errno.h>
+# include <sys/select.h>
 # include <sys/stat.h>
 # include <sys/socket.h>
