summaryrefslogtreecommitdiff
path: root/include/VBox
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2012-10-26 16:25:44 +0000
committer <>2012-11-12 12:15:52 +0000
commit58ed4748338f9466599adfc8a9171280ed99e23f (patch)
tree02027d99ded4fb56a64aa9489ac2eb487e7858ab /include/VBox
downloadVirtualBox-58ed4748338f9466599adfc8a9171280ed99e23f.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.2.4.tar.bz2.VirtualBox-4.2.4
Diffstat (limited to 'include/VBox')
-rw-r--r--include/VBox/DevPCNet.h99
-rw-r--r--include/VBox/ExtPack/ExtPack.h361
-rw-r--r--include/VBox/GuestHost/SharedClipboard.h79
-rw-r--r--include/VBox/GuestHost/clipboard-helper.h164
-rw-r--r--include/VBox/HGSMI/HGSMI.h352
-rw-r--r--include/VBox/HGSMI/HGSMIChSetup.h72
-rw-r--r--include/VBox/HGSMI/HGSMIChannels.h64
-rw-r--r--include/VBox/HGSMI/Makefile.kup0
-rw-r--r--include/VBox/Hardware/VBoxVideoVBE.h86
-rw-r--r--include/VBox/HostServices/DragAndDropSvc.h429
-rw-r--r--include/VBox/HostServices/GuestControlSvc.h649
-rw-r--r--include/VBox/HostServices/GuestPropertySvc.h512
-rw-r--r--include/VBox/HostServices/Makefile.kup0
-rw-r--r--include/VBox/HostServices/Service.h472
-rw-r--r--include/VBox/HostServices/VBoxClipboardExt.h51
-rw-r--r--include/VBox/HostServices/VBoxClipboardSvc.h137
-rw-r--r--include/VBox/HostServices/VBoxCrOpenGLSvc.h346
-rw-r--r--include/VBox/HostServices/VBoxHostChannel.h209
-rw-r--r--include/VBox/HostServices/VBoxOGLOp.h1897
-rw-r--r--include/VBox/HostServices/VBoxOpenGLSvc.h202
-rw-r--r--include/VBox/HostServices/glext.h7260
-rw-r--r--include/VBox/HostServices/glxext.h785
-rw-r--r--include/VBox/HostServices/wglext.h648
-rw-r--r--include/VBox/Makefile.kup0
-rw-r--r--include/VBox/RemoteDesktop/VRDE.h1603
-rw-r--r--include/VBox/RemoteDesktop/VRDEImage.h240
-rw-r--r--include/VBox/RemoteDesktop/VRDEMousePtr.h69
-rw-r--r--include/VBox/RemoteDesktop/VRDEOrders.h297
-rw-r--r--include/VBox/RemoteDesktop/VRDESCard.h515
-rw-r--r--include/VBox/RemoteDesktop/VRDETSMF.h141
-rw-r--r--include/VBox/SUPDrvMangling.h32
-rw-r--r--include/VBox/VBoxAuth.h191
-rw-r--r--include/VBox/VBoxCocoa.h76
-rw-r--r--include/VBox/VBoxCrHgsmi.h52
-rw-r--r--include/VBox/VBoxDrvCfg-win.h77
-rw-r--r--include/VBox/VBoxGL2D.h357
-rw-r--r--include/VBox/VBoxGuest.h461
-rw-r--r--include/VBox/VBoxGuest.inc46
-rw-r--r--include/VBox/VBoxGuest.mac50
-rw-r--r--include/VBox/VBoxGuest16.h109
-rw-r--r--include/VBox/VBoxGuest2.h108
-rw-r--r--include/VBox/VBoxGuestLib.h751
-rw-r--r--include/VBox/VBoxGuestMangling.h32
-rw-r--r--include/VBox/VBoxKeyboard.h53
-rw-r--r--include/VBox/VBoxNetCfg-win.h107
-rw-r--r--include/VBox/VBoxOGLTest.h36
-rw-r--r--include/VBox/VBoxTpG.h425
-rw-r--r--include/VBox/VBoxUhgsmi.h137
-rw-r--r--include/VBox/VBoxVideo.h1468
-rw-r--r--include/VBox/VBoxVideo3D.h136
-rw-r--r--include/VBox/VBoxVideoGuest.h318
-rw-r--r--include/VBox/VDEPlug.h44
-rw-r--r--include/VBox/VDEPlugSymDefs.h82
-rw-r--r--include/VBox/VMMDev.h2077
-rw-r--r--include/VBox/VMMDev2.h114
-rw-r--r--include/VBox/VMMDevTesting.h122
-rw-r--r--include/VBox/VMMDevTesting.mac52
-rw-r--r--include/VBox/apic.h58
-rw-r--r--include/VBox/apic.mac19
-rw-r--r--include/VBox/asmdefs.mac775
-rw-r--r--include/VBox/bioslogo.h90
-rw-r--r--include/VBox/cdefs.h439
-rw-r--r--include/VBox/com/AutoLock.h638
-rw-r--r--include/VBox/com/ErrorInfo.h495
-rw-r--r--include/VBox/com/EventQueue.h140
-rw-r--r--include/VBox/com/Guid.h353
-rw-r--r--include/VBox/com/Makefile.kup0
-rw-r--r--include/VBox/com/MultiResult.h262
-rw-r--r--include/VBox/com/VirtualBox.h55
-rw-r--r--include/VBox/com/array.h1702
-rw-r--r--include/VBox/com/assert.h108
-rw-r--r--include/VBox/com/com.h111
-rw-r--r--include/VBox/com/defs.h549
-rw-r--r--include/VBox/com/errorprint.h261
-rw-r--r--include/VBox/com/list.h197
-rw-r--r--include/VBox/com/listeners.h171
-rw-r--r--include/VBox/com/mtlist.h197
-rw-r--r--include/VBox/com/ptr.h493
-rw-r--r--include/VBox/com/string.h810
-rw-r--r--include/VBox/dbg.h1209
-rw-r--r--include/VBox/dbggui.h173
-rw-r--r--include/VBox/dbus-calls.h146
-rw-r--r--include/VBox/dbus.h116
-rw-r--r--include/VBox/dis.h807
-rw-r--r--include/VBox/disopcode.h849
-rw-r--r--include/VBox/err.h2233
-rw-r--r--include/VBox/err.mac812
-rw-r--r--include/VBox/err.sed45
-rw-r--r--include/VBox/hgcmsvc.h409
-rw-r--r--include/VBox/intnet.h1223
-rw-r--r--include/VBox/intnetinline.h822
-rw-r--r--include/VBox/log.h557
-rw-r--r--include/VBox/msi.h121
-rw-r--r--include/VBox/nasm.mac34
-rw-r--r--include/VBox/ostypes.h150
-rw-r--r--include/VBox/param.h178
-rw-r--r--include/VBox/param.mac41
-rw-r--r--include/VBox/pci.h1174
-rw-r--r--include/VBox/rawpci.h588
-rw-r--r--include/VBox/scsi.h277
-rw-r--r--include/VBox/settings.h1166
-rw-r--r--include/VBox/shflsvc.h1364
-rw-r--r--include/VBox/sup.h1745
-rw-r--r--include/VBox/sup.mac123
-rw-r--r--include/VBox/types.h1057
-rw-r--r--include/VBox/usb.h255
-rw-r--r--include/VBox/usbfilter.h257
-rw-r--r--include/VBox/usblib-darwin.h55
-rw-r--r--include/VBox/usblib-solaris.h269
-rw-r--r--include/VBox/usblib-win.h313
-rw-r--r--include/VBox/usblib.h119
-rw-r--r--include/VBox/various.sed93
-rw-r--r--include/VBox/vd-cache-plugin.h357
-rw-r--r--include/VBox/vd-ifs-internal.h569
-rw-r--r--include/VBox/vd-ifs.h1291
-rw-r--r--include/VBox/vd-plugin.h679
-rw-r--r--include/VBox/vd.h1251
-rw-r--r--include/VBox/vddbg.h265
-rw-r--r--include/VBox/version.h111
-rw-r--r--include/VBox/vmm/Makefile.kup0
-rw-r--r--include/VBox/vmm/cfgm.h220
-rw-r--r--include/VBox/vmm/cpum.h492
-rw-r--r--include/VBox/vmm/cpum.mac207
-rw-r--r--include/VBox/vmm/cpumctx-v1_6.h249
-rw-r--r--include/VBox/vmm/cpumctx.h477
-rw-r--r--include/VBox/vmm/cpumdis.h48
-rw-r--r--include/VBox/vmm/csam.h305
-rw-r--r--include/VBox/vmm/dbgf.h1658
-rw-r--r--include/VBox/vmm/dbgfcorefmt.h79
-rw-r--r--include/VBox/vmm/dbgfsel.h104
-rw-r--r--include/VBox/vmm/dbgftrace.h143
-rw-r--r--include/VBox/vmm/em.h276
-rw-r--r--include/VBox/vmm/ftm.h71
-rw-r--r--include/VBox/vmm/gmm.h809
-rw-r--r--include/VBox/vmm/gvm.h124
-rw-r--r--include/VBox/vmm/gvmm.h268
-rw-r--r--include/VBox/vmm/hwacc_svm.h744
-rw-r--r--include/VBox/vmm/hwacc_vmx.h1708
-rw-r--r--include/VBox/vmm/hwacc_vmx.mac154
-rw-r--r--include/VBox/vmm/hwaccm.h154
-rw-r--r--include/VBox/vmm/iem.h83
-rw-r--r--include/VBox/vmm/iom.h325
-rw-r--r--include/VBox/vmm/mm.h370
-rw-r--r--include/VBox/vmm/patm.h672
-rw-r--r--include/VBox/vmm/pdm.h40
-rw-r--r--include/VBox/vmm/pdmapi.h210
-rw-r--r--include/VBox/vmm/pdmasynccompletion.h368
-rw-r--r--include/VBox/vmm/pdmasynctask.h61
-rw-r--r--include/VBox/vmm/pdmblkcache.h422
-rw-r--r--include/VBox/vmm/pdmcardreaderinfs.h116
-rw-r--r--include/VBox/vmm/pdmcommon.h164
-rw-r--r--include/VBox/vmm/pdmcritsect.h95
-rw-r--r--include/VBox/vmm/pdmdev.h5173
-rw-r--r--include/VBox/vmm/pdmdrv.h1829
-rw-r--r--include/VBox/vmm/pdmifs.h2996
-rw-r--r--include/VBox/vmm/pdmins.h70
-rw-r--r--include/VBox/vmm/pdmnetifs.h437
-rw-r--r--include/VBox/vmm/pdmnetinline.h664
-rw-r--r--include/VBox/vmm/pdmnetshaper.h120
-rw-r--r--include/VBox/vmm/pdmnetshaperint.h94
-rw-r--r--include/VBox/vmm/pdmnvram.h70
-rw-r--r--include/VBox/vmm/pdmpci.h398
-rw-r--r--include/VBox/vmm/pdmqueue.h147
-rw-r--r--include/VBox/vmm/pdmsrv.h335
-rw-r--r--include/VBox/vmm/pdmthread.h298
-rw-r--r--include/VBox/vmm/pdmusb.h1004
-rw-r--r--include/VBox/vmm/pgm.h586
-rw-r--r--include/VBox/vmm/rem.h106
-rw-r--r--include/VBox/vmm/selm.h123
-rw-r--r--include/VBox/vmm/ssm.h1265
-rw-r--r--include/VBox/vmm/stam.h1265
-rw-r--r--include/VBox/vmm/stam.mac382
-rw-r--r--include/VBox/vmm/tm.h281
-rw-r--r--include/VBox/vmm/trpm.h150
-rw-r--r--include/VBox/vmm/trpm.mac47
-rw-r--r--include/VBox/vmm/uvm.h152
-rw-r--r--include/VBox/vmm/vm.h1106
-rw-r--r--include/VBox/vmm/vm.mac150
-rw-r--r--include/VBox/vmm/vmapi.h441
-rw-r--r--include/VBox/vmm/vmcpuset.h107
-rw-r--r--include/VBox/vmm/vmm.h522
-rw-r--r--include/VBox/vrdpusb.h75
-rw-r--r--include/VBox/vscsi.h323
-rw-r--r--include/VBox/vusb.h1077
-rw-r--r--include/VBox/x86.mac2
185 files changed, 89489 insertions, 0 deletions
diff --git a/include/VBox/DevPCNet.h b/include/VBox/DevPCNet.h
new file mode 100644
index 00000000..52e357ad
--- /dev/null
+++ b/include/VBox/DevPCNet.h
@@ -0,0 +1,99 @@
+/** @file
+ * DevPCNet - Private guest interface for the PCNet device. (DEV)
+ */
+
+/*
+ * Copyright (C) 2008 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 ___VBox_DevPCNet_h
+#define ___VBox_DevPCNet_h
+
+#include <iprt/types.h>
+
+/** @defgroup grp_devpcnet AMD PCnet-PCI II / PCnet-FAST III (Am79C970A / Am79C973) Ethernet Controller Emulation.
+ * {
+ */
+
+#define PCNET_GUEST_INTERFACE_VERSION (1)
+#define PCNET_GUEST_SHARED_MEMORY_SIZE _512K
+#define PCNET_GUEST_TX_DESCRIPTOR_SIZE 16
+#define PCNET_GUEST_RX_DESCRIPTOR_SIZE 16
+#define PCNET_GUEST_MAX_TX_DESCRIPTORS 128
+#define PCNET_GUEST_MAX_RX_DESCRIPTORS 256
+#define PCNET_GUEST_NIC_BUFFER_SIZE 1536
+
+/* 256*16 + 128*16 + 256*1536 + 128*1536 = 582KB */
+
+/**
+ * The header of the PCNet shared memory (VBox specific).
+ */
+#pragma pack(1) /* paranoia */
+typedef struct
+{
+ /** The size of the shared memory that's being used.
+ * (This is <= PCNET_GUEST_SHARED_MEMORY_SIZE.) */
+ uint32_t cbUsed;
+ /** Version (PCNET_GUEST_INTERFACE_VERSION). */
+ uint32_t u32Version;
+ /** Flags (See PCNET_GUEST_FLAGS_*). */
+ uint32_t fFlags;
+ /** Align the following members to 64 bit. */
+ uint32_t u32Alignment;
+
+ union
+ {
+ struct
+ {
+ /** The size (in bytes) of the transmit descriptor array. */
+ uint32_t cbTxDescriptors;
+ /** The size (in bytes) of the receive descriptor array. */
+ uint32_t cbRxDescriptors;
+ /** Offset of the transmit descriptors relative to this header. */
+ uint32_t offTxDescriptors;
+ /** Offset of the receive descriptors relative to this header. */
+ uint32_t offRxDescriptors;
+ /** Offset of the transmit buffers relative to this header. */
+ uint32_t offTxBuffers;
+ /** Offset of the receive buffers relative to this header. */
+ uint32_t offRxBuffers;
+ } V1;
+ } V;
+
+} PCNETGUESTSHAREDMEMORY;
+#pragma pack()
+/** Pointer to the PCNet shared memory header. */
+typedef PCNETGUESTSHAREDMEMORY *PPCNETGUESTSHAREDMEMORY;
+/** Const pointer to the PCNet shared memory header. */
+typedef const PCNETGUESTSHAREDMEMORY *PCPCNETGUESTSHAREDMEMORY;
+
+/** @name fFlags definitions
+ * @{
+ */
+/** Host admits existence private PCNet interface. */
+#define PCNET_GUEST_FLAGS_ADMIT_HOST RT_BIT(0)
+/** Guest admits using the private PCNet interface. */
+#define PCNET_GUEST_FLAGS_ADMIT_GUEST RT_BIT(1)
+/** @} */
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/ExtPack/ExtPack.h b/include/VBox/ExtPack/ExtPack.h
new file mode 100644
index 00000000..4e03b382
--- /dev/null
+++ b/include/VBox/ExtPack/ExtPack.h
@@ -0,0 +1,361 @@
+/** @file
+ * VirtualBox - Extension Pack Interface.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_ExtPack_ExtPack_h
+#define ___VBox_ExtPack_ExtPack_h
+
+#include <VBox/types.h>
+
+/** @def VBOXEXTPACK_IF_CS
+ * Selects 'class' on 'struct' for interface references.
+ * @param I The interface name
+ */
+#if defined(__cplusplus) && !defined(RT_OS_WINDOWS)
+# define VBOXEXTPACK_IF_CS(I) class I
+#else
+# define VBOXEXTPACK_IF_CS(I) struct I
+#endif
+
+VBOXEXTPACK_IF_CS(IConsole);
+VBOXEXTPACK_IF_CS(IMachine);
+VBOXEXTPACK_IF_CS(IVirtualBox);
+
+/**
+ * Module kind for use with VBOXEXTPACKHLP::pfnFindModule.
+ */
+typedef enum VBOXEXTPACKMODKIND
+{
+ /** Zero is invalid as alwasy. */
+ VBOXEXTPACKMODKIND_INVALID = 0,
+ /** Raw-mode context module. */
+ VBOXEXTPACKMODKIND_RC,
+ /** Ring-0 context module. */
+ VBOXEXTPACKMODKIND_R0,
+ /** Ring-3 context module. */
+ VBOXEXTPACKMODKIND_R3,
+ /** End of the valid values (exclusive). */
+ VBOXEXTPACKMODKIND_END,
+ /** The usual 32-bit type hack. */
+ VBOXEXTPACKMODKIND_32BIT_HACK = 0x7fffffff
+} VBOXEXTPACKMODKIND;
+
+/**
+ * Contexts returned by VBOXEXTPACKHLP::pfnGetContext.
+ */
+typedef enum VBOXEXTPACKCTX
+{
+ /** Zero is invalid as alwasy. */
+ VBOXEXTPACKCTX_INVALID = 0,
+ /** The per-user daemon process (VBoxSVC). */
+ VBOXEXTPACKCTX_PER_USER_DAEMON,
+ /** A VM process.
+ * @remarks This will also include the client processes in v4.0. */
+ VBOXEXTPACKCTX_VM_PROCESS,
+ /** A API client process.
+ * @remarks This will not be returned by VirtualBox 4.0. */
+ VBOXEXTPACKCTX_CLIENT_PROCESS,
+ /** End of the valid values (exclusive). */
+ VBOXEXTPACKCTX_END,
+ /** The usual 32-bit type hack. */
+ VBOXEXTPACKCTX_32BIT_HACK = 0x7fffffff
+} VBOXEXTPACKCTX;
+
+
+/** Pointer to const helpers passed to the VBoxExtPackRegister() call. */
+typedef const struct VBOXEXTPACKHLP *PCVBOXEXTPACKHLP;
+/**
+ * Extension pack helpers passed to VBoxExtPackRegister().
+ *
+ * This will be valid until the module is unloaded.
+ */
+typedef struct VBOXEXTPACKHLP
+{
+ /** Interface version.
+ * This is set to VBOXEXTPACKHLP_VERSION. */
+ uint32_t u32Version;
+
+ /** The VirtualBox full version (see VBOX_FULL_VERSION). */
+ uint32_t uVBoxFullVersion;
+ /** The VirtualBox subversion tree revision. */
+ uint32_t uVBoxInternalRevision;
+ /** Explicit alignment padding, must be zero. */
+ uint32_t u32Padding;
+ /** Pointer to the version string (read-only). */
+ const char *pszVBoxVersion;
+
+ /**
+ * Finds a module belonging to this extension pack.
+ *
+ * @returns VBox status code.
+ * @param pHlp Pointer to this helper structure.
+ * @param pszName The module base name.
+ * @param pszExt The extension. If NULL the default ring-3
+ * library extension will be used.
+ * @param enmKind The kind of module to locate.
+ * @param pszFound Where to return the path to the module on
+ * success.
+ * @param cbFound The size of the buffer @a pszFound points to.
+ * @param pfNative Where to return the native/agnostic indicator.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFindModule,(PCVBOXEXTPACKHLP pHlp, const char *pszName, const char *pszExt,
+ VBOXEXTPACKMODKIND enmKind,
+ char *pszFound, size_t cbFound, bool *pfNative));
+
+ /**
+ * Gets the path to a file belonging to this extension pack.
+ *
+ * @returns VBox status code.
+ * @retval VERR_INVALID_POINTER if any of the pointers are invalid.
+ * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. The buffer
+ * will contain nothing.
+ *
+ * @param pHlp Pointer to this helper structure.
+ * @param pszFilename The filename.
+ * @param pszPath Where to return the path to the file on
+ * success.
+ * @param cbPath The size of the buffer @a pszPath.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetFilePath,(PCVBOXEXTPACKHLP pHlp, const char *pszFilename, char *pszPath, size_t cbPath));
+
+ /**
+ * Gets the context the extension pack is operating in.
+ *
+ * @returns The context.
+ * @retval VBOXEXTPACKCTX_INVALID if @a pHlp is invalid.
+ *
+ * @param pHlp Pointer to this helper structure.
+ */
+ DECLR3CALLBACKMEMBER(VBOXEXTPACKCTX, pfnGetContext,(PCVBOXEXTPACKHLP pHlp));
+
+ DECLR3CALLBACKMEMBER(int, pfnReserved1,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved2,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved3,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved4,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved5,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved6,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved7,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved8,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+ DECLR3CALLBACKMEMBER(int, pfnReserved9,(PCVBOXEXTPACKHLP pHlp)); /**< Reserved for minor structure revisions. */
+
+ /** End of structure marker (VBOXEXTPACKHLP_VERSION). */
+ uint32_t u32EndMarker;
+} VBOXEXTPACKHLP;
+/** Current version of the VBOXEXTPACKHLP structure. */
+#define VBOXEXTPACKHLP_VERSION RT_MAKE_U32(0, 1)
+
+
+/** Pointer to the extension pack callback table. */
+typedef struct VBOXEXTPACKREG const *PCVBOXEXTPACKREG;
+/**
+ * Callback table returned by VBoxExtPackRegister.
+ *
+ * This must be valid until the extension pack main module is unloaded.
+ */
+typedef struct VBOXEXTPACKREG
+{
+ /** Interface version.
+ * This is set to VBOXEXTPACKREG_VERSION. */
+ uint32_t u32Version;
+
+ /**
+ * Hook for doing setups after the extension pack was installed.
+ *
+ * This is called in the context of the per-user service (VBoxSVC).
+ *
+ * @returns VBox status code.
+ * @retval VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL if the extension pack
+ * requires some different host version or a prerequisite is
+ * missing from the host. Automatic uninstall will be attempted.
+ * Must set error info.
+ *
+ * @param pThis Pointer to this structure.
+ * @param pVirtualBox The VirtualBox interface.
+ * @param pErrInfo Where to return extended error information.
+ */
+ DECLCALLBACKMEMBER(int, pfnInstalled)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox,
+ PRTERRINFO pErrInfo);
+
+ /**
+ * Hook for cleaning up before the extension pack is uninstalled.
+ *
+ * This is called in the context of the per-user service (VBoxSVC).
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to this structure.
+ * @param pVirtualBox The VirtualBox interface.
+ *
+ * @todo This is currently called holding locks making pVirtualBox
+ * relatively unusable.
+ */
+ DECLCALLBACKMEMBER(int, pfnUninstall)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox);
+
+ /**
+ * Hook for doing work after the VirtualBox object is ready.
+ *
+ * This is called in the context of the per-user service (VBoxSVC). The
+ * pfnConsoleReady method is the equivalent for the VM/client process.
+ *
+ * @param pThis Pointer to this structure.
+ * @param pVirtualBox The VirtualBox interface.
+ */
+ DECLCALLBACKMEMBER(void, pfnVirtualBoxReady)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox);
+
+ /**
+ * Hook for doing work after the Console object is ready.
+ *
+ * This is called in the context of the VM/client process. The
+ * pfnVirtualBoxReady method is the equivalent for the per-user service
+ * (VBoxSVC).
+ *
+ * @param pThis Pointer to this structure.
+ * @param pConsole The Console interface.
+ */
+ DECLCALLBACKMEMBER(void, pfnConsoleReady)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IConsole) *pConsole);
+
+ /**
+ * Hook for doing work before unloading.
+ *
+ * This is called both in the context of the per-user service (VBoxSVC) and
+ * in context of the VM process (VBoxC).
+ *
+ * @param pThis Pointer to this structure.
+ *
+ * @remarks The helpers are not available at this point in time.
+ * @remarks This is not called on uninstall, then pfnUninstall will be the
+ * last callback.
+ */
+ DECLCALLBACKMEMBER(void, pfnUnload)(PCVBOXEXTPACKREG pThis);
+
+ /**
+ * Hook for changing the default VM configuration upon creation.
+ *
+ * This is called in the context of the per-user service (VBoxSVC).
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to this structure.
+ * @param pVirtualBox The VirtualBox interface.
+ * @param pMachine The machine interface.
+ */
+ DECLCALLBACKMEMBER(int, pfnVMCreated)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IVirtualBox) *pVirtualBox,
+ VBOXEXTPACK_IF_CS(IMachine) *pMachine);
+
+ /**
+ * Hook for configuring the VMM for a VM.
+ *
+ * This is called in the context of the VM process (VBoxC).
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to this structure.
+ * @param pConsole The console interface.
+ * @param pVM The VM handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnVMConfigureVMM)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IConsole) *pConsole, PVM pVM);
+
+ /**
+ * Hook for doing work right before powering on the VM.
+ *
+ * This is called in the context of the VM process (VBoxC).
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to this structure.
+ * @param pConsole The console interface.
+ * @param pVM The VM handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnVMPowerOn)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IConsole) *pConsole, PVM pVM);
+
+ /**
+ * Hook for doing work after powering on the VM.
+ *
+ * This is called in the context of the VM process (VBoxC).
+ *
+ * @param pThis Pointer to this structure.
+ * @param pConsole The console interface.
+ * @param pVM The VM handle. Can be NULL.
+ */
+ DECLCALLBACKMEMBER(void, pfnVMPowerOff)(PCVBOXEXTPACKREG pThis, VBOXEXTPACK_IF_CS(IConsole) *pConsole, PVM pVM);
+
+ /**
+ * Query the IUnknown interface to an object in the main module.
+ *
+ * This is can be called in any context.
+ *
+ * @returns IUnknown pointer (referenced) on success, NULL on failure.
+ * @param pThis Pointer to this structure.
+ * @param pObjectId Pointer to the object ID (UUID).
+ */
+ DECLCALLBACKMEMBER(void *, pfnQueryObject)(PCVBOXEXTPACKREG pThis, PCRTUUID pObjectId);
+
+ /** End of structure marker (VBOXEXTPACKREG_VERSION). */
+ uint32_t u32EndMarker;
+} VBOXEXTPACKREG;
+/** Current version of the VBOXEXTPACKREG structure. */
+#define VBOXEXTPACKREG_VERSION RT_MAKE_U32(0, 1)
+
+
+/**
+ * The VBoxExtPackRegister callback function.
+ *
+ * PDM will invoke this function after loading a driver module and letting
+ * the module decide which drivers to register and how to handle conflicts.
+ *
+ * @returns VBox status code.
+ * @param pHlp Pointer to the extension pack helper function
+ * table. This is valid until the module is unloaded.
+ * @param ppReg Where to return the pointer to the registration
+ * structure containing all the hooks. This structure
+ * be valid and unchanged until the module is unloaded
+ * (i.e. use some static const data for it).
+ * @param pErrInfo Where to return extended error information.
+ */
+typedef DECLCALLBACK(int) FNVBOXEXTPACKREGISTER(PCVBOXEXTPACKHLP pHlp, PCVBOXEXTPACKREG *ppReg, PRTERRINFO pErrInfo);
+/** Pointer to a FNVBOXEXTPACKREGISTER. */
+typedef FNVBOXEXTPACKREGISTER *PFNVBOXEXTPACKREGISTER;
+
+/** The name of the main module entry point. */
+#define VBOX_EXTPACK_MAIN_MOD_ENTRY_POINT "VBoxExtPackRegister"
+
+
+/**
+ * Checks if extension pack interface version is compatible.
+ *
+ * @returns true if the do, false if they don't.
+ * @param u32Provider The provider version.
+ * @param u32User The user version.
+ */
+#define VBOXEXTPACK_IS_VER_COMPAT(u32Provider, u32User) \
+ ( VBOXEXTPACK_IS_MAJOR_VER_EQUAL(u32Provider, u32User) \
+ && (int32_t)RT_LOWORD(u32Provider) >= (int32_t)RT_LOWORD(u32User) ) /* stupid casts to shut up gcc */
+
+/**
+ * Check if two extension pack interface versions has the same major version.
+ *
+ * @returns true if the do, false if they don't.
+ * @param u32Ver1 The first version number.
+ * @param u32Ver2 The second version number.
+ */
+#define VBOXEXTPACK_IS_MAJOR_VER_EQUAL(u32Ver1, u32Ver2) (RT_HIWORD(u32Ver1) == RT_HIWORD(u32Ver2))
+
+#endif
+
diff --git a/include/VBox/GuestHost/SharedClipboard.h b/include/VBox/GuestHost/SharedClipboard.h
new file mode 100644
index 00000000..c6c39f50
--- /dev/null
+++ b/include/VBox/GuestHost/SharedClipboard.h
@@ -0,0 +1,79 @@
+/** @file
+ * Shared Clipboard - Common Guest and Host Code.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_GuestHost_SharedClipboard_h
+#define ___VBox_GuestHost_SharedClipboard_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+enum
+{
+ /** The number of milliseconds before the clipboard times out. */
+#ifndef TESTCASE
+ CLIPBOARD_TIMEOUT = 5000
+#else
+ CLIPBOARD_TIMEOUT = 1
+#endif
+};
+
+/** Opaque data structure for the X11/VBox frontend/glue code. */
+struct _VBOXCLIPBOARDCONTEXT;
+typedef struct _VBOXCLIPBOARDCONTEXT VBOXCLIPBOARDCONTEXT;
+
+/** Opaque data structure for the X11/VBox backend code. */
+struct _CLIPBACKEND;
+typedef struct _CLIPBACKEND CLIPBACKEND;
+
+/** Opaque request structure for clipboard data.
+ * @todo All use of single and double underscore prefixes is banned! */
+struct _CLIPREADCBREQ;
+typedef struct _CLIPREADCBREQ CLIPREADCBREQ;
+
+/* APIs exported by the X11 backend */
+extern CLIPBACKEND *ClipConstructX11(VBOXCLIPBOARDCONTEXT *pFrontend, bool fHeadless);
+extern void ClipDestructX11(CLIPBACKEND *pBackend);
+#ifdef __cplusplus
+extern int ClipStartX11(CLIPBACKEND *pBackend, bool grab = false);
+#else
+extern int ClipStartX11(CLIPBACKEND *pBackend, bool grab);
+#endif
+extern int ClipStopX11(CLIPBACKEND *pBackend);
+extern void ClipAnnounceFormatToX11(CLIPBACKEND *pBackend,
+ uint32_t u32Formats);
+extern int ClipRequestDataFromX11(CLIPBACKEND *pBackend, uint32_t u32Format,
+ CLIPREADCBREQ *pReq);
+
+/* APIs exported by the X11/VBox frontend */
+extern int ClipRequestDataForX11(VBOXCLIPBOARDCONTEXT *pCtx,
+ uint32_t u32Format, void **ppv,
+ uint32_t *pcb);
+extern void ClipReportX11Formats(VBOXCLIPBOARDCONTEXT *pCtx,
+ uint32_t u32Formats);
+extern void ClipCompleteDataRequestFromX11(VBOXCLIPBOARDCONTEXT *pCtx, int rc,
+ CLIPREADCBREQ *pReq, void *pv,
+ uint32_t cb);
+#endif
+
diff --git a/include/VBox/GuestHost/clipboard-helper.h b/include/VBox/GuestHost/clipboard-helper.h
new file mode 100644
index 00000000..70d1653e
--- /dev/null
+++ b/include/VBox/GuestHost/clipboard-helper.h
@@ -0,0 +1,164 @@
+/* $Id: clipboard-helper.h $ */
+/** @file
+ * Shared Clipboard: Some helper function for converting between the various eol.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___CLIPBOARD_HELPER_H
+#define ___CLIPBOARD_HELPER_H
+
+#include <iprt/string.h>
+
+/** Constants needed for string conversions done by the Linux/Mac clipboard code. */
+enum {
+ /** In Linux, lines end with a linefeed character. */
+ LINEFEED = 0xa,
+ /** In Windows, lines end with a carriage return and a linefeed character. */
+ CARRIAGERETURN = 0xd,
+ /** Little endian "real" Utf16 strings start with this marker. */
+ UTF16LEMARKER = 0xfeff,
+ /** Big endian "real" Utf16 strings start with this marker. */
+ UTF16BEMARKER = 0xfffe
+};
+
+/**
+ * Get the size of the buffer needed to hold a Utf16-LE zero terminated string with Windows EOLs
+ * converted from a Utf16 string with Linux EOLs.
+ *
+ * @returns RT error code
+ *
+ * @param pwszSrc The source Utf16 string
+ * @param cwSrc The length in 16 bit words of the source string
+ * @retval pcwDest The length of the destination string in 16 bit words
+ */
+int vboxClipboardUtf16GetWinSize(PRTUTF16 pwszSrc, size_t cwSrc, size_t *pcwDest);
+
+/**
+ * Convert a Utf16 text with Linux EOLs to null-terminated Utf16-LE with Windows EOLs. Does no
+ * checking for validity.
+ *
+ * @returns VBox status code
+ *
+ * @param pwszSrc Source Utf16 text to convert
+ * @param cwSrc Size of the source text in 16 bit words
+ * @retval pu16Dest Buffer to store the converted text to.
+ * @retval pcwDest Size of the buffer for the converted text in 16 bit words
+ */
+int vboxClipboardUtf16LinToWin(PRTUTF16 pwszSrc, size_t cwSrc, PRTUTF16 pu16Dest, size_t cwDest);
+
+/**
+ * Get the size of the buffer needed to hold a zero-terminated Utf16 string with Linux EOLs
+ * converted from a Utf16 string with Windows EOLs.
+ *
+ * @returns RT status code
+ *
+ * @param pwszSrc The source Utf16 string
+ * @param cwSrc The length in 16 bit words of the source string
+ * @retval pcwDest The length of the destination string in 16 bit words
+ */
+int vboxClipboardUtf16GetLinSize(PRTUTF16 pwszSrc, size_t cwSrc, size_t *pcwDest);
+
+/**
+ * Convert Utf16-LE text with Windows EOLs to zero-terminated Utf16 with Linux EOLs. This
+ * function does not verify that the Utf16 is valid.
+ *
+ * @returns VBox status code
+ *
+ * @param pwszSrc Text to convert
+ * @param cwSrc Size of the source text in 16 bit words
+ * @param pu16Dest The buffer to store the converted text to
+ * @param cwDest The size of the buffer for the destination text in 16 bit words
+ */
+int vboxClipboardUtf16WinToLin(PRTUTF16 pwszSrc, size_t cwSrc, PRTUTF16 pu16Dest, size_t cwDest);
+
+#pragma pack(1)
+/** @todo r=bird: Why duplicate these structures here, we've got them in
+ * DevVGA.cpp already! */
+/**
+ * Bitmap File Header. Official win32 name is BITMAPFILEHEADER
+ * Always Little Endian.
+ */
+typedef struct BMFILEHEADER
+{
+ uint16_t u16Type;
+ uint32_t u32Size;
+ uint16_t u16Reserved1;
+ uint16_t u16Reserved2;
+ uint32_t u32OffBits;
+} BMFILEHEADER;
+/** Pointer to a BMFILEHEADER structure. */
+typedef BMFILEHEADER *PBMFILEHEADER;
+/** BMP file magic number */
+#define BITMAPHEADERMAGIC (RT_H2LE_U16_C(0x4d42))
+
+/**
+ * Bitmap Info Header. Official win32 name is BITMAPINFOHEADER
+ * Always Little Endian.
+ */
+typedef struct BMINFOHEADER
+{
+ uint32_t u32Size;
+ uint32_t u32Width;
+ uint32_t u32Height;
+ uint16_t u16Planes;
+ uint16_t u16BitCount;
+ uint32_t u32Compression;
+ uint32_t u32SizeImage;
+ uint32_t u32XBitsPerMeter;
+ uint32_t u32YBitsPerMeter;
+ uint32_t u32ClrUsed;
+ uint32_t u32ClrImportant;
+} BMINFOHEADER;
+/** Pointer to a BMINFOHEADER structure. */
+typedef BMINFOHEADER *PBMINFOHEADER;
+#pragma pack()
+
+/**
+ * Convert CF_DIB data to full BMP data by prepending the BM header.
+ * Allocates with RTMemAlloc.
+ *
+ * @returns VBox status code
+ *
+ * @param pSrc DIB data to convert
+ * @param cbSrc Size of the DIB data to convert in bytes
+ * @param ppDest Where to store the pointer to the buffer for the destination data
+ * @param pcbDest Pointer to the size of the buffer for the destination data in bytes
+ */
+int vboxClipboardDibToBmp(const void *pvSrc, size_t cbSrc, void **ppvDest, size_t *pcbDest);
+
+/**
+ * Get the address and size of CF_DIB data in a full BMP data in the input buffer.
+ * Does not do any allocation.
+ *
+ * @returns VBox status code
+ *
+ * @param pSrc BMP data to convert
+ * @param cbSrc Size of the BMP data to convert in bytes
+ * @param ppDest Where to store the pointer to the destination data
+ * @param pcbDest Pointer to the size of the destination data in bytes
+ */
+int vboxClipboardBmpGetDib(const void *pvSrc, size_t cbSrc, const void **ppvDest, size_t *pcbDest);
+
+
+#endif
+
diff --git a/include/VBox/HGSMI/HGSMI.h b/include/VBox/HGSMI/HGSMI.h
new file mode 100644
index 00000000..352487d9
--- /dev/null
+++ b/include/VBox/HGSMI/HGSMI.h
@@ -0,0 +1,352 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * Host/Guest shared part.
+ */
+
+/*
+ * Copyright (C) 2006-2008 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 ___VBox_HGSMI_HGSMI_h
+#define ___VBox_HGSMI_HGSMI_h
+
+#include <iprt/assert.h>
+#include <iprt/types.h>
+
+#include <VBox/HGSMI/HGSMIChannels.h>
+
+/* HGSMI uses 32 bit offsets and sizes. */
+typedef uint32_t HGSMISIZE;
+typedef uint32_t HGSMIOFFSET;
+
+#define HGSMIOFFSET_VOID ((HGSMIOFFSET)~0)
+
+/*
+ * Basic mechanism for the HGSMI is to prepare and pass data buffer to the host and the guest.
+ * Data inside these buffers are opaque for the HGSMI and are interpreted by higher levels.
+ *
+ * Every shared memory buffer passed between the guest/host has the following structure:
+ *
+ * HGSMIBUFFERHEADER header;
+ * uint8_t data[header.u32BufferSize];
+ * HGSMIBUFFERTAIL tail;
+ *
+ * Note: Offset of the 'header' in the memory is used for virtual hardware IO.
+ *
+ * Buffers are verifyed using the offset and the content of the header and the tail,
+ * which are constant during a call.
+ *
+ * Invalid buffers are ignored.
+ *
+ * Actual 'data' is not verifyed, as it is expected that the data can be changed by the
+ * called function.
+ *
+ * Since only the offset of the buffer is passed in a IO operation, the header and tail
+ * must contain:
+ * * size of data in this buffer;
+ * * checksum for buffer verification.
+ *
+ * For segmented transfers:
+ * * the sequence identifier;
+ * * offset of the current segment in the sequence;
+ * * total bytes in the transfer.
+ *
+ * Additionally contains:
+ * * the channel ID;
+ * * the channel information.
+ */
+
+
+/* Describes a shared memory area buffer.
+ * Used for calculations with offsets and for buffers verification.
+ */
+typedef struct _HGSMIAREA
+{
+ uint8_t *pu8Base; /* The starting address of the area. Corresponds to offset 'offBase'. */
+ HGSMIOFFSET offBase; /* The starting offset of the area. */
+ HGSMIOFFSET offLast; /* The last valid offset:
+ * offBase + cbArea - 1 - (sizeof (header) + sizeof (tail)).
+ */
+ HGSMISIZE cbArea; /* Size of the area. */
+} HGSMIAREA;
+
+
+/* The buffer description flags. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_MASK 0x03 /* Buffer sequence type mask. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_SINGLE 0x00 /* Single buffer, not a part of a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_START 0x01 /* The first buffer in a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE 0x02 /* A middle buffer in a sequence. */
+#define HGSMI_BUFFER_HEADER_F_SEQ_END 0x03 /* The last buffer in a sequence. */
+
+
+#pragma pack(1)
+/* 16 bytes buffer header. */
+typedef struct _HGSMIBUFFERHEADER
+{
+ uint32_t u32DataSize; /* Size of data that follows the header. */
+
+ uint8_t u8Flags; /* The buffer description: HGSMI_BUFFER_HEADER_F_* */
+
+ uint8_t u8Channel; /* The channel the data must be routed to. */
+ uint16_t u16ChannelInfo; /* Opaque to the HGSMI, used by the channel. */
+
+ union {
+ uint8_t au8Union[8]; /* Opaque placeholder to make the union 8 bytes. */
+
+ struct
+ { /* HGSMI_BUFFER_HEADER_F_SEQ_SINGLE */
+ uint32_t u32Reserved1; /* A reserved field, initialize to 0. */
+ uint32_t u32Reserved2; /* A reserved field, initialize to 0. */
+ } Buffer;
+
+ struct
+ { /* HGSMI_BUFFER_HEADER_F_SEQ_START */
+ uint32_t u32SequenceNumber; /* The sequence number, the same for all buffers in the sequence. */
+ uint32_t u32SequenceSize; /* The total size of the sequence. */
+ } SequenceStart;
+
+ struct
+ { /* HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE and HGSMI_BUFFER_HEADER_F_SEQ_END */
+ uint32_t u32SequenceNumber; /* The sequence number, the same for all buffers in the sequence. */
+ uint32_t u32SequenceOffset; /* Data offset in the entire sequence. */
+ } SequenceContinue;
+ } u;
+
+} HGSMIBUFFERHEADER;
+
+/* 8 bytes buffer tail. */
+typedef struct _HGSMIBUFFERTAIL
+{
+ uint32_t u32Reserved; /* Reserved, must be initialized to 0. */
+ uint32_t u32Checksum; /* Verifyer for the buffer header and offset and for first 4 bytes of the tail. */
+} HGSMIBUFFERTAIL;
+#pragma pack()
+
+AssertCompile(sizeof (HGSMIBUFFERHEADER) == 16);
+AssertCompile(sizeof (HGSMIBUFFERTAIL) == 8);
+
+
+#pragma pack(1)
+typedef struct _HGSMIHEAP
+{
+ union
+ {
+ RTHEAPSIMPLE hPtr; /**< Pointer based heap. */
+ RTHEAPOFFSET hOff; /**< Offset based heap. */
+ } u;
+ HGSMIAREA area; /**< Description. */
+ int cRefs; /**< Number of heap allocations. */
+ bool fOffsetBased; /**< Set if offset based. */
+} HGSMIHEAP;
+#pragma pack()
+
+#pragma pack(1)
+/* The size of the array of channels. Array indexes are uint8_t. Note: the value must not be changed. */
+#define HGSMI_NUMBER_OF_CHANNELS 0x100
+
+/* Channel handler called when the guest submits a buffer. */
+typedef DECLCALLBACK(int) FNHGSMICHANNELHANDLER(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer);
+typedef FNHGSMICHANNELHANDLER *PFNHGSMICHANNELHANDLER;
+
+/* Information about a handler: pfn + context. */
+typedef struct _HGSMICHANNELHANDLER
+{
+ PFNHGSMICHANNELHANDLER pfnHandler;
+ void *pvHandler;
+} HGSMICHANNELHANDLER;
+
+/* Channel description. */
+typedef struct _HGSMICHANNEL
+{
+ HGSMICHANNELHANDLER handler; /* The channel handler. */
+ const char *pszName; /* NULL for hardcoded channels or RTStrDup'ed name. */
+ uint8_t u8Channel; /* The channel id, equal to the channel index in the array. */
+ uint8_t u8Flags; /* HGSMI_CH_F_* */
+} HGSMICHANNEL;
+
+typedef struct _HGSMICHANNELINFO
+{
+ HGSMICHANNEL Channels[HGSMI_NUMBER_OF_CHANNELS]; /* Channel handlers indexed by the channel id.
+ * The array is accessed under the instance lock.
+ */
+} HGSMICHANNELINFO;
+#pragma pack()
+
+
+RT_C_DECLS_BEGIN
+
+DECLINLINE(HGSMISIZE) HGSMIBufferMinimumSize (void)
+{
+ return sizeof (HGSMIBUFFERHEADER) + sizeof (HGSMIBUFFERTAIL);
+}
+
+DECLINLINE(uint8_t *) HGSMIBufferData (const HGSMIBUFFERHEADER *pHeader)
+{
+ return (uint8_t *)pHeader + sizeof (HGSMIBUFFERHEADER);
+}
+
+DECLINLINE(HGSMIBUFFERTAIL *) HGSMIBufferTail (const HGSMIBUFFERHEADER *pHeader)
+{
+ return (HGSMIBUFFERTAIL *)(HGSMIBufferData (pHeader) + pHeader->u32DataSize);
+}
+
+DECLINLINE(HGSMIBUFFERHEADER *) HGSMIBufferHeaderFromData (const void *pvData)
+{
+ return (HGSMIBUFFERHEADER *)((uint8_t *)pvData - sizeof (HGSMIBUFFERHEADER));
+}
+
+DECLINLINE(HGSMISIZE) HGSMIBufferRequiredSize (uint32_t u32DataSize)
+{
+ return HGSMIBufferMinimumSize () + u32DataSize;
+}
+
+DECLINLINE(HGSMIOFFSET) HGSMIPointerToOffset (const HGSMIAREA *pArea,
+ const HGSMIBUFFERHEADER *pHeader)
+{
+ return pArea->offBase + (HGSMIOFFSET)((uint8_t *)pHeader - pArea->pu8Base);
+}
+
+DECLINLINE(HGSMIBUFFERHEADER *) HGSMIOffsetToPointer (const HGSMIAREA *pArea,
+ HGSMIOFFSET offBuffer)
+{
+ return (HGSMIBUFFERHEADER *)(pArea->pu8Base + (offBuffer - pArea->offBase));
+}
+
+DECLINLINE(uint8_t *) HGSMIBufferDataFromOffset (const HGSMIAREA *pArea, HGSMIOFFSET offBuffer)
+{
+ HGSMIBUFFERHEADER *pHeader = HGSMIOffsetToPointer (pArea, offBuffer);
+ Assert(pHeader);
+ if(pHeader)
+ return HGSMIBufferData(pHeader);
+ return NULL;
+}
+
+DECLINLINE(uint8_t *) HGSMIBufferDataAndChInfoFromOffset (const HGSMIAREA *pArea, HGSMIOFFSET offBuffer, uint16_t * pChInfo)
+{
+ HGSMIBUFFERHEADER *pHeader = HGSMIOffsetToPointer (pArea, offBuffer);
+ Assert(pHeader);
+ if(pHeader)
+ {
+ *pChInfo = pHeader->u16ChannelInfo;
+ return HGSMIBufferData(pHeader);
+ }
+ return NULL;
+}
+
+HGSMICHANNEL *HGSMIChannelFindById (HGSMICHANNELINFO * pChannelInfo, uint8_t u8Channel);
+
+uint32_t HGSMIChecksum (HGSMIOFFSET offBuffer,
+ const HGSMIBUFFERHEADER *pHeader,
+ const HGSMIBUFFERTAIL *pTail);
+
+int HGSMIAreaInitialize (HGSMIAREA *pArea,
+ void *pvBase,
+ HGSMISIZE cbArea,
+ HGSMIOFFSET offBase);
+
+void HGSMIAreaClear (HGSMIAREA *pArea);
+
+DECLINLINE(bool) HGSMIAreaContainsOffset(HGSMIAREA *pArea, HGSMIOFFSET offSet)
+{
+ return pArea->offBase <= offSet && pArea->offBase + pArea->cbArea > offSet;
+}
+
+HGSMIOFFSET HGSMIBufferInitializeSingle (const HGSMIAREA *pArea,
+ HGSMIBUFFERHEADER *pHeader,
+ HGSMISIZE cbBuffer,
+ uint8_t u8Channel,
+ uint16_t u16ChannelInfo);
+
+int HGSMIHeapSetup (HGSMIHEAP *pHeap,
+ void *pvBase,
+ HGSMISIZE cbArea,
+ HGSMIOFFSET offBase,
+ bool fOffsetBased);
+
+int HGSMIHeapRelocate (HGSMIHEAP *pHeap,
+ void *pvBase,
+ uint32_t offHeapHandle,
+ uintptr_t offDelta,
+ HGSMISIZE cbArea,
+ HGSMIOFFSET offBase,
+ bool fOffsetBased);
+
+void HGSMIHeapSetupUnitialized (HGSMIHEAP *pHeap);
+bool HGSMIHeapIsItialized (HGSMIHEAP *pHeap);
+
+void HGSMIHeapDestroy (HGSMIHEAP *pHeap);
+
+void* HGSMIHeapBufferAlloc (HGSMIHEAP *pHeap,
+ HGSMISIZE cbBuffer);
+
+void HGSMIHeapBufferFree(HGSMIHEAP *pHeap,
+ void *pvBuf);
+
+void *HGSMIHeapAlloc (HGSMIHEAP *pHeap,
+ HGSMISIZE cbData,
+ uint8_t u8Channel,
+ uint16_t u16ChannelInfo);
+
+HGSMIOFFSET HGSMIHeapBufferOffset (HGSMIHEAP *pHeap,
+ void *pvData);
+
+void HGSMIHeapFree (HGSMIHEAP *pHeap,
+ void *pvData);
+
+DECLINLINE(HGSMIOFFSET) HGSMIHeapOffset(HGSMIHEAP *pHeap)
+{
+ return pHeap->area.offBase;
+}
+
+#ifdef IN_RING3
+/* needed for heap relocation */
+DECLINLINE(HGSMIOFFSET) HGSMIHeapHandleLocationOffset(HGSMIHEAP *pHeap)
+{
+#if (__GNUC__ * 100 + __GNUC_MINOR__) < 405
+ /* does not work with gcc-4.5 */
+ AssertCompile((uintptr_t)NIL_RTHEAPSIMPLE == (uintptr_t)NIL_RTHEAPOFFSET);
+#endif
+ return pHeap->u.hPtr != NIL_RTHEAPSIMPLE
+ ? (HGSMIOFFSET)(pHeap->area.pu8Base - (uint8_t*)pHeap->u.hPtr)
+ : HGSMIOFFSET_VOID;
+}
+#endif /* IN_RING3 */
+
+DECLINLINE(HGSMISIZE) HGSMIHeapSize(HGSMIHEAP *pHeap)
+{
+ return pHeap->area.cbArea;
+}
+
+int HGSMIChannelRegister (HGSMICHANNELINFO * pChannelInfo,
+ uint8_t u8Channel,
+ const char *pszName,
+ PFNHGSMICHANNELHANDLER pfnChannelHandler,
+ void *pvChannelHandler,
+ HGSMICHANNELHANDLER *pOldHandler);
+
+int HGSMIBufferProcess (HGSMIAREA *pArea,
+ HGSMICHANNELINFO * pChannelInfo,
+ HGSMIOFFSET offBuffer);
+RT_C_DECLS_END
+
+#endif /* !___VBox_HGSMI_HGSMI_h */
+
diff --git a/include/VBox/HGSMI/HGSMIChSetup.h b/include/VBox/HGSMI/HGSMIChSetup.h
new file mode 100644
index 00000000..5f116510
--- /dev/null
+++ b/include/VBox/HGSMI/HGSMIChSetup.h
@@ -0,0 +1,72 @@
+/** @file
+ * VBox Host Guest Shared Memory Interface (HGSMI), sHost/Guest shared part.
+ */
+
+/*
+ * Copyright (C) 2006-2009 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 ___VBox_HGSMI_HGSMIChSetup_h
+#define ___VBox_HGSMI_HGSMIChSetup_h
+
+#include <VBox/HGSMI/HGSMI.h>
+
+/* HGSMI setup and configuration channel commands and data structures. */
+#define HGSMI_CC_HOST_FLAGS_LOCATION 0 /* Tell the host the location of HGSMIHOSTFLAGS structure,
+ * where the host can write information about pending
+ * buffers, etc, and which can be quickly polled by
+ * the guest without a need to port IO.
+ */
+
+typedef struct _HGSMIBUFFERLOCATION
+{
+ HGSMIOFFSET offLocation;
+ HGSMISIZE cbLocation;
+} HGSMIBUFFERLOCATION;
+AssertCompileSize(HGSMIBUFFERLOCATION, 8);
+
+/* HGSMI setup and configuration data structures. */
+/* host->guest commands pending, should be accessed under FIFO lock only */
+#define HGSMIHOSTFLAGS_COMMANDS_PENDING 0x1
+/* IRQ is fired, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_IRQ 0x2
+#ifdef VBOX_WITH_WDDM
+/* one or more guest commands is completed, should be accessed under FIFO lock only */
+# define HGSMIHOSTFLAGS_GCOMMAND_COMPLETED 0x4
+/* watchdog timer interrupt flag (used for debugging), should be accessed under VGAState::lock only */
+# define HGSMIHOSTFLAGS_WATCHDOG 0x8
+#endif
+/* vsync interrupt flag, should be accessed under VGAState::lock only */
+#define HGSMIHOSTFLAGS_VSYNC 0x10
+
+typedef struct _HGSMIHOSTFLAGS
+{
+ /* host flags can be accessed and modified in multiple threads concurrently,
+ * e.g. CrOpenGL HGCM and GUI threads when to completing HGSMI 3D and Video Accel respectively,
+ * EMT thread when dealing with HGSMI command processing, etc.
+ * Besides settings/cleaning flags atomically, some each flag has its own special sync restrictions,
+ * see commants for flags definitions above */
+ volatile uint32_t u32HostFlags;
+ uint32_t au32Reserved[3];
+} HGSMIHOSTFLAGS;
+AssertCompileSize(HGSMIHOSTFLAGS, 16);
+
+#endif
+
diff --git a/include/VBox/HGSMI/HGSMIChannels.h b/include/VBox/HGSMI/HGSMIChannels.h
new file mode 100644
index 00000000..3b5bd6db
--- /dev/null
+++ b/include/VBox/HGSMI/HGSMIChannels.h
@@ -0,0 +1,64 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * Host/Guest shared part.
+ * Channel identifiers.
+ */
+
+/*
+ * Copyright (C) 2006-2008 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 __HGSMIChannels_h__
+#define __HGSMIChannels_h__
+
+
+/* Each channel has an 8 bit identifier. There are a number of predefined
+ * (hardcoded) channels.
+ *
+ * HGSMI_CH_HGSMI channel can be used to map a string channel identifier
+ * to a free 16 bit numerical value. values are allocated in range
+ * [HGSMI_CH_STRING_FIRST;HGSMI_CH_STRING_LAST].
+ *
+ */
+
+
+/* Predefined channel identifiers. Used internally by VBOX to simplify the channel setup. */
+#define HGSMI_CH_RESERVED (0x00) /* A reserved channel value. */
+
+#define HGSMI_CH_HGSMI (0x01) /* HGCMI: setup and configuration channel. */
+
+#define HGSMI_CH_VBVA (0x02) /* Graphics: VBVA. */
+#define HGSMI_CH_SEAMLESS (0x03) /* Graphics: Seamless with a single guest region. */
+#define HGSMI_CH_SEAMLESS2 (0x04) /* Graphics: Seamless with separate host windows. */
+#define HGSMI_CH_OPENGL (0x05) /* Graphics: OpenGL HW acceleration. */
+
+
+/* Dynamically allocated channel identifiers. */
+#define HGSMI_CH_STRING_FIRST (0x20) /* The first channel index to be used for string mappings (inclusive). */
+#define HGSMI_CH_STRING_LAST (0xff) /* The last channel index for string mappings (inclusive). */
+
+
+/* Check whether the channel identifier is allocated for a dynamic channel. */
+#define HGSMI_IS_DYNAMIC_CHANNEL(_channel) (((uint8_t)(_channel) & 0xE0) != 0)
+
+
+#endif /* !__HGSMIChannels_h__*/
diff --git a/include/VBox/HGSMI/Makefile.kup b/include/VBox/HGSMI/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/VBox/HGSMI/Makefile.kup
diff --git a/include/VBox/Hardware/VBoxVideoVBE.h b/include/VBox/Hardware/VBoxVideoVBE.h
new file mode 100644
index 00000000..405ab3d2
--- /dev/null
+++ b/include/VBox/Hardware/VBoxVideoVBE.h
@@ -0,0 +1,86 @@
+/** @file
+ * VirtualBox graphics card port I/O definitions
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_Hardware_VBoxVideoVBE_h
+#define ___VBox_Hardware_VBoxVideoVBE_h
+
+/* GUEST <-> HOST Communication API */
+
+/** @todo FIXME: Either dynamicly ask host for this or put somewhere high in
+ * physical memory like 0xE0000000. */
+
+#define VBE_DISPI_BANK_ADDRESS 0xA0000
+#define VBE_DISPI_BANK_SIZE_KB 64
+
+#define VBE_DISPI_MAX_XRES 16384
+#define VBE_DISPI_MAX_YRES 16384
+#define VBE_DISPI_MAX_BPP 32
+
+#define VBE_DISPI_IOPORT_INDEX 0x01CE
+#define VBE_DISPI_IOPORT_DATA 0x01CF
+
+#define VBE_DISPI_IOPORT_DAC_WRITE_INDEX 0x03C8
+#define VBE_DISPI_IOPORT_DAC_DATA 0x03C9
+
+#define VBE_DISPI_INDEX_ID 0x0
+#define VBE_DISPI_INDEX_XRES 0x1
+#define VBE_DISPI_INDEX_YRES 0x2
+#define VBE_DISPI_INDEX_BPP 0x3
+#define VBE_DISPI_INDEX_ENABLE 0x4
+#define VBE_DISPI_INDEX_BANK 0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7
+#define VBE_DISPI_INDEX_X_OFFSET 0x8
+#define VBE_DISPI_INDEX_Y_OFFSET 0x9
+#define VBE_DISPI_INDEX_VBOX_VIDEO 0xa
+#define VBE_DISPI_INDEX_FB_BASE_HI 0xb
+
+#define VBE_DISPI_ID0 0xB0C0
+#define VBE_DISPI_ID1 0xB0C1
+#define VBE_DISPI_ID2 0xB0C2
+#define VBE_DISPI_ID3 0xB0C3
+#define VBE_DISPI_ID4 0xB0C4
+
+#define VBE_DISPI_ID_VBOX_VIDEO 0xBE00
+/* The VBOX interface id. Indicates support for VBVA shared memory interface. */
+#define VBE_DISPI_ID_HGSMI 0xBE01
+#define VBE_DISPI_ID_ANYX 0xBE02
+
+#define VBE_DISPI_DISABLED 0x00
+#define VBE_DISPI_ENABLED 0x01
+#define VBE_DISPI_GETCAPS 0x02
+#define VBE_DISPI_8BIT_DAC 0x20
+/** @note this definition is a BOCHS legacy, used only in the video BIOS
+ * code and ignored by the emulated hardware. */
+#define VBE_DISPI_LFB_ENABLED 0x40
+#define VBE_DISPI_NOCLEARMEM 0x80
+
+#define VGA_PORT_HGSMI_HOST 0x3b0
+#define VGA_PORT_HGSMI_GUEST 0x3d0
+
+#define VBOX_VIDEO_MAX_SCREENS 64
+
+#endif /* !___VBox_Hardware_VBoxVideoVBE_h */
+
diff --git a/include/VBox/HostServices/DragAndDropSvc.h b/include/VBox/HostServices/DragAndDropSvc.h
new file mode 100644
index 00000000..51289cb0
--- /dev/null
+++ b/include/VBox/HostServices/DragAndDropSvc.h
@@ -0,0 +1,429 @@
+/** @file
+ * Drag and Drop service - Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2011-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 ___VBox_HostService_DragAndDropSvc_h
+#define ___VBox_HostService_DragAndDropSvc_h
+
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest2.h>
+
+/*
+ * The mode of operations.
+ */
+#define VBOX_DRAG_AND_DROP_MODE_OFF 0
+#define VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST 1
+#define VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST 2
+#define VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL 3
+
+#define DND_IGNORE_ACTION UINT32_C(0)
+#define DND_COPY_ACTION RT_BIT_32(0)
+#define DND_MOVE_ACTION RT_BIT_32(1)
+#define DND_LINK_ACTION RT_BIT_32(2)
+
+#define hasDnDCopyAction(a) ((a) && DND_COPY_ACTION)
+#define hasDnDMoveAction(a) ((a) && DND_MOVE_ACTION)
+#define hasDnDLinkAction(a) ((a) && DND_LINK_ACTION)
+
+#define isDnDIgnoreAction(a) ((a) == DND_IGNORE_ACTION)
+#define isDnDCopyAction(a) ((a) == DND_COPY_ACTION)
+#define isDnDMoveAction(a) ((a) == DND_MOVE_ACTION)
+#define isDnDLinkAction(a) ((a) == DND_LINK_ACTION)
+
+/* Everything defined in this file lives in this namespace. */
+namespace DragAndDropSvc {
+
+/******************************************************************************
+* Typedefs, constants and inlines *
+******************************************************************************/
+
+/**
+ * The service functions which are callable by host.
+ */
+enum eHostFn
+{
+ HOST_DND_SET_MODE = 100,
+
+ /* H->G */
+ HOST_DND_HG_EVT_ENTER = 200,
+ HOST_DND_HG_EVT_MOVE,
+ HOST_DND_HG_EVT_LEAVE,
+ HOST_DND_HG_EVT_DROPPED,
+ HOST_DND_HG_EVT_CANCEL,
+ HOST_DND_HG_SND_DATA,
+ HOST_DND_HG_SND_MORE_DATA,
+ HOST_DND_HG_SND_DIR,
+ HOST_DND_HG_SND_FILE,
+
+ /* G->H */
+ HOST_DND_GH_REQ_PENDING = 300,
+ HOST_DND_GH_EVT_DROPPED
+};
+
+/**
+ * The service functions which are called by guest.
+ */
+enum eGuestFn
+{
+ /**
+ * Guest waits for a new message the host wants to process on the guest side.
+ * This is a blocking call and can be deferred.
+ */
+ GUEST_DND_GET_NEXT_HOST_MSG = 300,
+
+ /* H->G */
+ GUEST_DND_HG_ACK_OP = 400,
+ GUEST_DND_HG_REQ_DATA,
+ GUEST_DND_HG_EVT_PROGRESS,
+
+ /* G->H */
+ GUEST_DND_GH_ACK_PENDING = 500,
+ GUEST_DND_GH_SND_DATA,
+ GUEST_DND_GH_EVT_ERROR
+};
+
+/**
+ * The possible states for the progress operations.
+ */
+enum
+{
+ DND_PROGRESS_RUNNING = 1,
+ DND_PROGRESS_COMPLETE,
+ DND_PROGRESS_CANCELLED,
+ DND_PROGRESS_ERROR
+};
+
+#pragma pack (1)
+
+/*
+ * Host events
+ */
+
+typedef struct VBOXDNDHGACTIONMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG Action event.
+ *
+ * Used by:
+ * HOST_DND_HG_EVT_ENTER
+ * HOST_DND_HG_EVT_MOVE
+ * HOST_DND_HG_EVT_DROPPED
+ */
+ HGCMFunctionParameter uScreenId; /* OUT uint32_t */
+ HGCMFunctionParameter uX; /* OUT uint32_t */
+ HGCMFunctionParameter uY; /* OUT uint32_t */
+ HGCMFunctionParameter uDefAction; /* OUT uint32_t */
+ HGCMFunctionParameter uAllActions; /* OUT uint32_t */
+ HGCMFunctionParameter pvFormats; /* OUT ptr */
+ HGCMFunctionParameter cFormats; /* OUT uint32_t */
+} VBOXDNDHGACTIONMSG;
+
+typedef struct VBOXDNDHGLEAVEMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /**
+ * HG Leave event.
+ *
+ * Used by:
+ * HOST_DND_HG_EVT_LEAVE
+ */
+} VBOXDNDHGLEAVEMSG;
+
+typedef struct VBOXDNDHGCANCELMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG Cancel return event.
+ *
+ * Used by:
+ * HOST_DND_HG_EVT_CANCEL
+ */
+} VBOXDNDHGCANCELMSG;
+
+typedef struct VBOXDNDHGSENDDATAMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG Send Data event.
+ *
+ * Used by:
+ * HOST_DND_HG_SND_DATA
+ */
+ HGCMFunctionParameter uScreenId; /* OUT uint32_t */
+ HGCMFunctionParameter pvFormat; /* OUT ptr */
+ HGCMFunctionParameter cFormat; /* OUT uint32_t */
+ HGCMFunctionParameter pvData; /* OUT ptr */
+ HGCMFunctionParameter cData; /* OUT uint32_t */
+} VBOXDNDHGSENDDATAMSG;
+
+typedef struct VBOXDNDHGSENDMOREDATAMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG Send More Data event.
+ *
+ * Used by:
+ * HOST_DND_HG_SND_MORE_DATA
+ */
+ HGCMFunctionParameter pvData; /* OUT ptr */
+ HGCMFunctionParameter cData; /* OUT uint32_t */
+} VBOXDNDHGSENDMOREDATAMSG;
+
+typedef struct VBOXDNDHGSENDDIRMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG Directory event.
+ *
+ * Used by:
+ * HOST_DND_HG_SND_DIR
+ */
+ HGCMFunctionParameter pvName; /* OUT ptr */
+ HGCMFunctionParameter cName; /* OUT uint32_t */
+ HGCMFunctionParameter fMode; /* OUT uint32_t */
+} VBOXDNDHGSENDDIRMSG;
+
+typedef struct VBOXDNDHGSENDFILEMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG File event.
+ *
+ * Used by:
+ * HOST_DND_HG_SND_FILE
+ */
+ HGCMFunctionParameter pvName; /* OUT ptr */
+ HGCMFunctionParameter cName; /* OUT uint32_t */
+ HGCMFunctionParameter pvData; /* OUT ptr */
+ HGCMFunctionParameter cData; /* OUT uint32_t */
+ HGCMFunctionParameter fMode; /* OUT uint32_t */
+} VBOXDNDHGSENDFILEMSG;
+
+typedef struct VBOXDNDGHREQPENDINGMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * GH Request Pending event.
+ *
+ * Used by:
+ * HOST_DND_GH_REQ_PENDING
+ */
+ HGCMFunctionParameter uScreenId; /* OUT uint32_t */
+} VBOXDNDGHREQPENDINGMSG;
+
+typedef struct VBOXDNDGHDROPPEDMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * GH Dropped event.
+ *
+ * Used by:
+ * HOST_DND_GH_EVT_DROPPED
+ */
+ HGCMFunctionParameter pvFormat; /* OUT ptr */
+ HGCMFunctionParameter cFormat; /* OUT uint32_t */
+ HGCMFunctionParameter uAction; /* OUT uint32_t */
+} VBOXDNDGHDROPPEDMSG;
+
+/*
+ * Guest events
+ */
+
+typedef struct VBOXDNDNEXTMSGMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * The returned command the host wants to
+ * run on the guest.
+ *
+ * Used by:
+ * GUEST_DND_GET_NEXT_HOST_MSG
+ */
+ HGCMFunctionParameter msg; /* OUT uint32_t */
+ /** Number of parameters the message needs. */
+ HGCMFunctionParameter num_parms; /* OUT uint32_t */
+ HGCMFunctionParameter block; /* OUT uint32_t */
+
+} VBOXDNDNEXTMSGMSG;
+
+typedef struct VBOXDNDHGACKOPMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG Acknowledge Operation event.
+ *
+ * Used by:
+ * GUEST_DND_HG_ACK_OP
+ */
+ HGCMFunctionParameter uAction; /* OUT uint32_t */
+} VBOXDNDHGACKOPMSG;
+
+typedef struct VBOXDNDHGREQDATAMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * HG request for data event.
+ *
+ * Used by:
+ * GUEST_DND_HG_REQ_DATA
+ */
+ HGCMFunctionParameter pFormat; /* OUT ptr */
+} VBOXDNDHGREQDATAMSG;
+
+typedef struct VBOXDNDGHACKPENDINGMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * GH Acknowledge Pending event.
+ *
+ * Used by:
+ * GUEST_DND_GH_ACK_PENDING
+ */
+ HGCMFunctionParameter uDefAction; /* OUT uint32_t */
+ HGCMFunctionParameter uAllActions; /* OUT uint32_t */
+ HGCMFunctionParameter pFormat; /* OUT ptr */
+} VBOXDNDGHACKPENDINGMSG;
+
+typedef struct VBOXDNDGHSENDDATAMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * GH Send Data event.
+ *
+ * Used by:
+ * GUEST_DND_GH_SND_DATA
+ */
+ HGCMFunctionParameter pData; /* OUT ptr */
+ HGCMFunctionParameter uSize; /* OUT uint32_t */
+} VBOXDNDGHSENDDATAMSG;
+
+typedef struct VBOXDNDGHEVTERRORMSG
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * GH Cancel Data event.
+ *
+ * Used by:
+ * GUEST_DND_GH_EVT_CANCEL
+ */
+ HGCMFunctionParameter uRC; /* OUT uint32_t */
+} VBOXDNDGHEVTERRORMSG;
+
+#pragma pack()
+
+/*
+ * Callback handler
+ */
+enum
+{
+ CB_MAGIC_DND_HG_ACK_OP = 0xe2100b93,
+ CB_MAGIC_DND_HG_REQ_DATA = 0x5cb3faf9,
+ CB_MAGIC_DND_HG_EVT_PROGRESS = 0x8c8a6956,
+ CB_MAGIC_DND_GH_ACK_PENDING = 0xbe975a14,
+ CB_MAGIC_DND_GH_SND_DATA = 0x4eb61bff,
+ CB_MAGIC_DND_GH_EVT_ERROR = 0x117a87c4
+};
+
+typedef struct VBOXDNDCBHEADERDATA
+{
+ /** Magic number to identify the structure. */
+ uint32_t u32Magic;
+ /** Context ID to identify callback data. */
+ uint32_t u32ContextID;
+} VBOXDNDCBHEADERDATA;
+typedef VBOXDNDCBHEADERDATA *PVBOXDNDCBHEADERDATA;
+
+typedef struct VBOXDNDCBHGACKOPDATA
+{
+ /** Callback data header. */
+ VBOXDNDCBHEADERDATA hdr;
+ uint32_t uAction;
+} VBOXDNDCBHGACKOPDATA;
+typedef VBOXDNDCBHGACKOPDATA *PVBOXDNDCBHGACKOPDATA;
+
+typedef struct VBOXDNDCBHGREQDATADATA
+{
+ /** Callback data header. */
+ VBOXDNDCBHEADERDATA hdr;
+ char *pszFormat;
+} VBOXDNDCBHGREQDATADATA;
+typedef VBOXDNDCBHGREQDATADATA *PVBOXDNDCBHGREQDATADATA;
+
+typedef struct VBOXDNDCBHGEVTPROGRESSDATA
+{
+ /** Callback data header. */
+ VBOXDNDCBHEADERDATA hdr;
+ uint32_t uPercentage;
+ uint32_t uState;
+} VBOXDNDCBHGEVTPROGRESSDATA;
+typedef VBOXDNDCBHGEVTPROGRESSDATA *PVBOXDNDCBHGEVTPROGRESSDATA ;
+
+typedef struct VBOXDNDCBGHACKPENDINGDATA
+{
+ /** Callback data header. */
+ VBOXDNDCBHEADERDATA hdr;
+ uint32_t uDefAction;
+ uint32_t uAllActions;
+ char *pszFormat;
+} VBOXDNDCBGHACKPENDINGDATA;
+typedef VBOXDNDCBGHACKPENDINGDATA *PVBOXDNDCBGHACKPENDINGDATA;
+
+typedef struct VBOXDNDCBSNDDATADATA
+{
+ /** Callback data header. */
+ VBOXDNDCBHEADERDATA hdr;
+ void *pvData;
+ uint32_t cbData;
+ uint32_t cbAllSize;
+} VBOXDNDCBSNDDATADATA;
+typedef VBOXDNDCBSNDDATADATA *PVBOXDNDCBSNDDATADATA;
+
+typedef struct VBOXDNDCBEVTERRORDATA
+{
+ /** Callback data header. */
+ VBOXDNDCBHEADERDATA hdr;
+ int32_t rc;
+} VBOXDNDCBEVTERRORDATA;
+typedef VBOXDNDCBEVTERRORDATA *PVBOXDNDCBEVTERRORDATA;
+
+
+} /* namespace DragAndDropSvc */
+
+#endif /* !___VBox_HostService_DragAndDropSvc_h */
+
diff --git a/include/VBox/HostServices/GuestControlSvc.h b/include/VBox/HostServices/GuestControlSvc.h
new file mode 100644
index 00000000..d7864601
--- /dev/null
+++ b/include/VBox/HostServices/GuestControlSvc.h
@@ -0,0 +1,649 @@
+/** @file
+ * Guest control service - Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2011-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 ___VBox_HostService_GuestControlService_h
+#define ___VBox_HostService_GuestControlService_h
+
+#include <VBox/types.h>
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest2.h>
+#include <VBox/hgcmsvc.h>
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+/* Everything defined in this file lives in this namespace. */
+namespace guestControl {
+
+/******************************************************************************
+* Typedefs, constants and inlines *
+******************************************************************************/
+
+/**
+ * Process status when executed in the guest.
+ */
+enum eProcessStatus
+{
+ /** Process is in an undefined state. */
+ PROC_STS_UNDEFINED = 0,
+ /** Process has been started. */
+ PROC_STS_STARTED = 1,
+ /** Process terminated normally. */
+ PROC_STS_TEN = 2,
+ /** Process terminated via signal. */
+ PROC_STS_TES = 3,
+ /** Process terminated abnormally. */
+ PROC_STS_TEA = 4,
+ /** Process timed out and was killed. */
+ PROC_STS_TOK = 5,
+ /** Process timed out and was not killed successfully. */
+ PROC_STS_TOA = 6,
+ /** Service/OS is stopping, process was killed. */
+ PROC_STS_DWN = 7,
+ /** Something went wrong (error code in flags). */
+ PROC_STS_ERROR = 8
+};
+
+/**
+ * Input flags, set by the host. This is needed for
+ * handling flags on the guest side.
+ * Note: Has to match Main's ProcessInputFlag_* flags!
+ */
+#define INPUT_FLAG_NONE 0x0
+#define INPUT_FLAG_EOF RT_BIT(0)
+
+/**
+ * Execution flags.
+ * Note: Has to match Main's ProcessCreateFlag_* flags!
+ */
+#define EXECUTEPROCESSFLAG_NONE 0x0
+#define EXECUTEPROCESSFLAG_WAIT_START RT_BIT(0)
+#define EXECUTEPROCESSFLAG_IGNORE_ORPHANED RT_BIT(1)
+#define EXECUTEPROCESSFLAG_HIDDEN RT_BIT(2)
+#define EXECUTEPROCESSFLAG_NO_PROFILE RT_BIT(3)
+#define EXECUTEPROCESSFLAG_WAIT_STDOUT RT_BIT(4)
+#define EXECUTEPROCESSFLAG_WAIT_STDERR RT_BIT(5)
+#define EXECUTEPROCESSFLAG_EXPAND_ARGUMENTS RT_BIT(6)
+
+/**
+ * Pipe handle IDs used internally for referencing to
+ * a certain pipe buffer.
+ */
+#define OUTPUT_HANDLE_ID_STDOUT_DEPRECATED 0 /* Needed for VBox hosts < 4.1.0. */
+#define OUTPUT_HANDLE_ID_STDOUT 1
+#define OUTPUT_HANDLE_ID_STDERR 2
+
+/**
+ * Defines for guest process array lengths.
+ */
+#define GUESTPROCESS_MAX_CMD_LEN _1K
+#define GUESTPROCESS_MAX_ARGS_LEN _1K
+#define GUESTPROCESS_MAX_ENV_LEN _64K
+#define GUESTPROCESS_MAX_USER_LEN 128
+#define GUESTPROCESS_MAX_PASSWORD_LEN 128
+
+/** @name Internal tools built into VBoxService which are used in order to
+ * accomplish tasks host<->guest.
+ * @{
+ */
+#define VBOXSERVICE_TOOL_CAT "vbox_cat"
+#define VBOXSERVICE_TOOL_LS "vbox_ls"
+#define VBOXSERVICE_TOOL_RM "vbox_rm"
+#define VBOXSERVICE_TOOL_MKDIR "vbox_mkdir"
+#define VBOXSERVICE_TOOL_MKTEMP "vbox_mktemp"
+#define VBOXSERVICE_TOOL_STAT "vbox_stat"
+/** @} */
+
+/**
+ * Input status, reported by the client.
+ */
+enum eInputStatus
+{
+ /** Input is in an undefined state. */
+ INPUT_STS_UNDEFINED = 0,
+ /** Input was written (partially, see cbProcessed). */
+ INPUT_STS_WRITTEN = 1,
+ /** Input failed with an error (see flags for rc). */
+ INPUT_STS_ERROR = 20,
+ /** Process has abandoned / terminated input handling. */
+ INPUT_STS_TERMINATED = 21,
+ /** Too much input data. */
+ INPUT_STS_OVERFLOW = 30
+};
+
+/**
+ * The guest control callback data header. Must come first
+ * on each callback structure defined below this struct.
+ */
+typedef struct VBoxGuestCtrlCallbackHeader
+{
+ /** Magic number to identify the structure. */
+ uint32_t u32Magic;
+ /** Context ID to identify callback data. */
+ uint32_t u32ContextID;
+} CALLBACKHEADER;
+typedef CALLBACKHEADER *PCALLBACKHEADER;
+
+typedef struct VBoxGuestCtrlCallbackDataClientDisconnected
+{
+ /** Callback data header. */
+ CALLBACKHEADER hdr;
+} CALLBACKDATACLIENTDISCONNECTED;
+typedef CALLBACKDATACLIENTDISCONNECTED *PCALLBACKDATACLIENTDISCONNECTED;
+
+/**
+ * Data structure to pass to the service extension callback. We use this to
+ * notify the host of changes to properties.
+ */
+typedef struct VBoxGuestCtrlCallbackDataExecStatus
+{
+ /** Callback data header. */
+ CALLBACKHEADER hdr;
+ /** The process ID (PID). */
+ uint32_t u32PID;
+ /** The process status. */
+ uint32_t u32Status;
+ /** Optional flags, varies, based on u32Status. */
+ uint32_t u32Flags;
+ /** Optional data buffer (not used atm). */
+ void *pvData;
+ /** Size of optional data buffer (not used atm). */
+ uint32_t cbData;
+} CALLBACKDATAEXECSTATUS;
+typedef CALLBACKDATAEXECSTATUS *PCALLBACKDATAEXECSTATUS;
+
+typedef struct VBoxGuestCtrlCallbackDataExecOut
+{
+ /** Callback data header. */
+ CALLBACKHEADER hdr;
+ /** The process ID (PID). */
+ uint32_t u32PID;
+ /** The handle ID (stdout/stderr). */
+ uint32_t u32HandleId;
+ /** Optional flags (not used atm). */
+ uint32_t u32Flags;
+ /** Optional data buffer. */
+ void *pvData;
+ /** Size (in bytes) of optional data buffer. */
+ uint32_t cbData;
+} CALLBACKDATAEXECOUT;
+typedef CALLBACKDATAEXECOUT *PCALLBACKDATAEXECOUT;
+
+typedef struct VBoxGuestCtrlCallbackDataExecInStatus
+{
+ /** Callback data header. */
+ CALLBACKHEADER hdr;
+ /** The process ID (PID). */
+ uint32_t u32PID;
+ /** Current input status. */
+ uint32_t u32Status;
+ /** Optional flags. */
+ uint32_t u32Flags;
+ /** Size (in bytes) of processed input data. */
+ uint32_t cbProcessed;
+} CALLBACKDATAEXECINSTATUS;
+typedef CALLBACKDATAEXECINSTATUS *PCALLBACKDATAEXECINSTATUS;
+
+enum eVBoxGuestCtrlCallbackDataMagic
+{
+ CALLBACKDATAMAGIC_CLIENT_DISCONNECTED = 0x08041984,
+
+ CALLBACKDATAMAGIC_EXEC_STATUS = 0x26011982,
+ CALLBACKDATAMAGIC_EXEC_OUT = 0x11061949,
+ CALLBACKDATAMAGIC_EXEC_IN_STATUS = 0x19091951
+};
+
+enum eVBoxGuestCtrlCallbackType
+{
+ VBOXGUESTCTRLCALLBACKTYPE_UNKNOWN = 0,
+
+ VBOXGUESTCTRLCALLBACKTYPE_EXEC_START = 1,
+ VBOXGUESTCTRLCALLBACKTYPE_EXEC_OUTPUT = 2,
+ VBOXGUESTCTRLCALLBACKTYPE_EXEC_INPUT_STATUS = 3
+};
+
+/**
+ * The service functions which are callable by host.
+ */
+enum eHostFn
+{
+ /**
+ * The host asks the client to cancel all pending waits and exit.
+ */
+ HOST_CANCEL_PENDING_WAITS = 0,
+
+ /*
+ * Execution handling.
+ */
+
+ /**
+ * The host wants to execute something in the guest. This can be a command line
+ * or starting a program.
+ */
+ HOST_EXEC_CMD = 100,
+ /**
+ * Sends input data for stdin to a running process executed by HOST_EXEC_CMD.
+ */
+ HOST_EXEC_SET_INPUT = 101,
+ /**
+ * Gets the current status of a running process, e.g.
+ * new data on stdout/stderr, process terminated etc.
+ */
+ HOST_EXEC_GET_OUTPUT = 102,
+
+ /*
+ * Guest control 2.0 commands start in the 2xx number space.
+ */
+
+ /**
+ * Waits for a certain event to happen. This can be an input, output
+ * or status event.
+ */
+ HOST_EXEC_WAIT_FOR = 210,
+ /**
+ * Opens a guest file.
+ */
+ HOST_FILE_OPEN = 240,
+ /**
+ * Closes a guest file.
+ */
+ HOST_FILE_CLOSE = 241,
+ /**
+ * Reads from an opened guest file.
+ */
+ HOST_FILE_READ = 242,
+ /**
+ * Write to an opened guest file.
+ */
+ HOST_FILE_WRITE = 243,
+ /**
+ * Changes the read & write position of an opened guest file.
+ */
+ HOST_FILE_SEEK = 244,
+ /**
+ * Gets the current file position of an opened guest file.
+ */
+ HOST_FILE_TELL = 245
+};
+
+/**
+ * The service functions which are called by guest. The numbers may not change,
+ * so we hardcode them.
+ */
+enum eGuestFn
+{
+ /**
+ * Guest waits for a new message the host wants to process on the guest side.
+ * This is a blocking call and can be deferred.
+ */
+ GUEST_GET_HOST_MSG = 1,
+ /**
+ * Guest asks the host to cancel all pending waits the guest itself waits on.
+ * This becomes necessary when the guest wants to quit but still waits for
+ * commands from the host.
+ */
+ GUEST_CANCEL_PENDING_WAITS = 2,
+ /**
+ * Guest disconnected (terminated normally or due to a crash HGCM
+ * detected when calling service::clientDisconnect().
+ */
+ GUEST_DISCONNECTED = 3,
+
+ /*
+ * Process execution.
+ * The 1xx commands are legacy guest control commands and
+ * will be replaced by newer commands in the future.
+ */
+
+ /**
+ * Guests sends output from an executed process.
+ */
+ GUEST_EXEC_SEND_OUTPUT = 100,
+ /**
+ * Guest sends a status update of an executed process to the host.
+ */
+ GUEST_EXEC_SEND_STATUS = 101,
+ /**
+ * Guests sends an input status notification to the host.
+ */
+ GUEST_EXEC_SEND_INPUT_STATUS = 102,
+
+ /*
+ * Guest control 2.0 commands start in the 2xx number space.
+ */
+
+ /**
+ * Guest notifies the host about some I/O event. This can be
+ * a stdout, stderr or a stdin event. The actual event only tells
+ * how many data is available / can be sent without actually
+ * transmitting the data.
+ */
+ GUEST_EXEC_IO_NOTIFY = 210,
+ /** Guest notifies the host about a file event, like opening,
+ * closing, seeking etc.
+ */
+ GUEST_FILE_NOTIFY = 240
+};
+
+/**
+ * Guest file notification types.
+ */
+enum eGuestFileNotifyType
+{
+ GUESTFILENOTIFYTYPE_ERROR = 0,
+ GUESTFILENOTIFYTYPE_OPEN = 10,
+ GUESTFILENOTIFYTYPE_CLOSE = 20,
+ GUESTFILENOTIFYTYPE_READ = 30,
+ GUESTFILENOTIFYTYPE_WRITE = 40,
+ GUESTFILENOTIFYTYPE_SEEK = 50,
+ GUESTFILENOTIFYTYPE_TELL = 60
+};
+
+/*
+ * HGCM parameter structures.
+ */
+#pragma pack (1)
+
+typedef struct VBoxGuestCtrlHGCMMsgType
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * The returned command the host wants to
+ * run on the guest.
+ */
+ HGCMFunctionParameter msg; /* OUT uint32_t */
+ /** Number of parameters the message needs. */
+ HGCMFunctionParameter num_parms; /* OUT uint32_t */
+
+} VBoxGuestCtrlHGCMMsgType;
+
+/**
+ * Asks the guest control host service to cancel all pending (outstanding)
+ * waits which were not processed yet. This is handy for a graceful shutdown.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgCancelPendingWaits
+{
+ VBoxGuestHGCMCallInfo hdr;
+} VBoxGuestCtrlHGCMMsgCancelPendingWaits;
+
+/**
+ * Executes a command inside the guest.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgExecCmd
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** The command to execute on the guest. */
+ HGCMFunctionParameter cmd;
+ /** Execution flags (see IGuest::ProcessCreateFlag_*). */
+ HGCMFunctionParameter flags;
+ /** Number of arguments. */
+ HGCMFunctionParameter num_args;
+ /** The actual arguments. */
+ HGCMFunctionParameter args;
+ /** Number of environment value pairs. */
+ HGCMFunctionParameter num_env;
+ /** Size (in bytes) of environment block, including terminating zeros. */
+ HGCMFunctionParameter cb_env;
+ /** The actual environment block. */
+ HGCMFunctionParameter env;
+ /** The user name to run the executed command under. */
+ HGCMFunctionParameter username;
+ /** The user's password. */
+ HGCMFunctionParameter password;
+ /** Timeout (in msec) which either specifies the
+ * overall lifetime of the process or how long it
+ * can take to bring the process up and running -
+ * (depends on the IGuest::ProcessCreateFlag_*). */
+ HGCMFunctionParameter timeout;
+
+} VBoxGuestCtrlHGCMMsgExecCmd;
+
+/**
+ * Injects input to a previously executed process via stdin.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgExecIn
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** The process ID (PID) to send the input to. */
+ HGCMFunctionParameter pid;
+ /** Input flags (see IGuest::ProcessInputFlag_*). */
+ HGCMFunctionParameter flags;
+ /** Data buffer. */
+ HGCMFunctionParameter data;
+ /** Actual size of data (in bytes). */
+ HGCMFunctionParameter size;
+
+} VBoxGuestCtrlHGCMMsgExecIn;
+
+/**
+ * Retrieves ouptut from a previously executed process
+ * from stdout/stderr.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgExecOut
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** The process ID (PID). */
+ HGCMFunctionParameter pid;
+ /** The pipe handle ID (stdout/stderr). */
+ HGCMFunctionParameter handle;
+ /** Optional flags. */
+ HGCMFunctionParameter flags;
+ /** Data buffer. */
+ HGCMFunctionParameter data;
+
+} VBoxGuestCtrlHGCMMsgExecOut;
+
+/**
+ * Reports the current status of a (just) started
+ * or terminated process.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgExecStatus
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** The process ID (PID). */
+ HGCMFunctionParameter pid;
+ /** The process status. */
+ HGCMFunctionParameter status;
+ /** Optional flags (based on status). */
+ HGCMFunctionParameter flags;
+ /** Optional data buffer (not used atm). */
+ HGCMFunctionParameter data;
+
+} VBoxGuestCtrlHGCMMsgExecStatus;
+
+/**
+ * Reports back the status of data written to a process.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgExecStatusIn
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** The process ID (PID). */
+ HGCMFunctionParameter pid;
+ /** Status of the operation. */
+ HGCMFunctionParameter status;
+ /** Optional flags. */
+ HGCMFunctionParameter flags;
+ /** Data written. */
+ HGCMFunctionParameter written;
+
+} VBoxGuestCtrlHGCMMsgExecStatusIn;
+
+/*
+ * Guest control 2.0 messages.
+ */
+
+/**
+ * Reports back the currente I/O status of a guest process.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgExecIONotify
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** Data written. */
+ HGCMFunctionParameter written;
+
+} VBoxGuestCtrlHGCMMsgExecIONotify;
+
+/**
+ * Opens a guest file.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgFileOpen
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** File to open. */
+ HGCMFunctionParameter filename;
+ /** Open mode. */
+ HGCMFunctionParameter openmode;
+ /** Disposition. */
+ HGCMFunctionParameter disposition;
+ /** Creation mode. */
+ HGCMFunctionParameter creationmode;
+ /** Offset. */
+ HGCMFunctionParameter offset;
+
+} VBoxGuestCtrlHGCMMsgFileOpen;
+
+/**
+ * Closes a guest file.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgFileClose
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** File handle to close. */
+ HGCMFunctionParameter handle;
+
+} VBoxGuestCtrlHGCMMsgFileClose;
+
+/**
+ * Reads from a guest file.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgFileRead
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** File handle to read from. */
+ HGCMFunctionParameter handle;
+ /** Actual size of data (in bytes). */
+ HGCMFunctionParameter size;
+ /** Where to put the read data into. */
+ HGCMFunctionParameter data;
+
+} VBoxGuestCtrlHGCMMsgFileRead;
+
+/**
+ * Writes to a guest file.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgFileWrite
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** File handle to write to. */
+ HGCMFunctionParameter handle;
+ /** Actual size of data (in bytes). */
+ HGCMFunctionParameter size;
+ /** Data buffer to write to the file. */
+ HGCMFunctionParameter data;
+
+} VBoxGuestCtrlHGCMMsgFileWrite;
+
+/**
+ * Seeks the read/write position of a guest file.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgFileSeek
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** File handle to seek. */
+ HGCMFunctionParameter handle;
+ /** The seeking method. */
+ HGCMFunctionParameter method;
+ /** The seeking offset. */
+ HGCMFunctionParameter offset;
+
+} VBoxGuestCtrlHGCMMsgFileSeek;
+
+/**
+ * Tells the current read/write position of a guest file.
+ */
+typedef struct VBoxGuestCtrlHGCMMsgFileTell
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** File handle to get the current position for. */
+ HGCMFunctionParameter handle;
+
+} VBoxGuestCtrlHGCMMsgFileTell;
+
+typedef struct VBoxGuestCtrlHGCMMsgFileNotify
+{
+ VBoxGuestHGCMCallInfo hdr;
+ /** Context ID. */
+ HGCMFunctionParameter context;
+ /** The file handle. */
+ HGCMFunctionParameter handle;
+ /** Notification type. */
+ HGCMFunctionParameter type;
+ /** Notification payload. */
+ HGCMFunctionParameter payload;
+
+} VBoxGuestCtrlHGCMMsgFileNotify;
+
+#pragma pack ()
+
+/**
+ * Structure for buffering execution requests in the host service.
+ */
+typedef struct VBoxGuestCtrlParamBuffer
+{
+ uint32_t uMsg;
+ uint32_t uParmCount;
+ PVBOXHGCMSVCPARM pParms;
+} VBOXGUESTCTRPARAMBUFFER;
+typedef VBOXGUESTCTRPARAMBUFFER *PVBOXGUESTCTRPARAMBUFFER;
+
+} /* namespace guestControl */
+
+#endif /* !___VBox_HostService_GuestControlService_h */
+
diff --git a/include/VBox/HostServices/GuestPropertySvc.h b/include/VBox/HostServices/GuestPropertySvc.h
new file mode 100644
index 00000000..7e99d2ec
--- /dev/null
+++ b/include/VBox/HostServices/GuestPropertySvc.h
@@ -0,0 +1,512 @@
+/** @file
+ * Guest property service:
+ * Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_HostService_GuestPropertyService_h
+#define ___VBox_HostService_GuestPropertyService_h
+
+#include <VBox/types.h>
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest2.h>
+#include <VBox/hgcmsvc.h>
+#include <VBox/log.h>
+#include <iprt/assert.h>
+#include <iprt/string.h>
+
+/** Everything defined in this file lives in this namespace. */
+namespace guestProp {
+
+/******************************************************************************
+* Typedefs, constants and inlines *
+******************************************************************************/
+
+/** Maximum length for property names */
+enum { MAX_NAME_LEN = 64 };
+/** Maximum length for property values */
+enum { MAX_VALUE_LEN = 128 };
+/** Maximum number of properties per guest */
+enum { MAX_PROPS = 256 };
+/** Maximum size for enumeration patterns */
+enum { MAX_PATTERN_LEN = 1024 };
+/** Maximum number of changes we remember for guest notifications */
+enum { MAX_GUEST_NOTIFICATIONS = 256 };
+
+/**
+ * The guest property flag values which are currently accepted.
+ */
+enum ePropFlags
+{
+ NILFLAG = 0,
+ /** Transient until VM gets shut down. */
+ TRANSIENT = RT_BIT(1),
+ RDONLYGUEST = RT_BIT(2),
+ RDONLYHOST = RT_BIT(3),
+ /** Transient until VM gets a reset / restarts.
+ * Implies TRANSIENT. */
+ TRANSRESET = RT_BIT(4),
+ READONLY = RDONLYGUEST | RDONLYHOST,
+ ALLFLAGS = TRANSIENT | READONLY | TRANSRESET
+};
+
+/**
+ * Get the name of a flag as a string.
+ * @returns the name, or NULL if fFlag is invalid.
+ * @param fFlag the flag. Must be a value from the ePropFlags enumeration
+ * list.
+ */
+DECLINLINE(const char *) flagName(uint32_t fFlag)
+{
+ switch (fFlag)
+ {
+ case TRANSIENT:
+ return "TRANSIENT";
+ case RDONLYGUEST:
+ return "RDONLYGUEST";
+ case RDONLYHOST:
+ return "RDONLYHOST";
+ case READONLY:
+ return "READONLY";
+ case TRANSRESET:
+ return "TRANSRESET";
+ default:
+ break;
+ }
+ return NULL;
+}
+
+/**
+ * Get the length of a flag name as returned by flagName.
+ * @returns the length, or 0 if fFlag is invalid.
+ * @param fFlag the flag. Must be a value from the ePropFlags enumeration
+ * list.
+ */
+DECLINLINE(size_t) flagNameLen(uint32_t fFlag)
+{
+ const char *pcszName = flagName(fFlag);
+ return RT_LIKELY(pcszName != NULL) ? strlen(pcszName) : 0;
+}
+
+/**
+ * Maximum length for the property flags field. We only ever return one of
+ * RDONLYGUEST, RDONLYHOST and RDONLY
+ */
+enum { MAX_FLAGS_LEN = sizeof("TRANSIENT, RDONLYGUEST, TRANSRESET") };
+
+/**
+ * Parse a guest properties flags string for flag names and make sure that
+ * there is no junk text in the string.
+ * @returns IPRT status code
+ * @returns VERR_INVALID_PARAM if the flag string is not valid
+ * @param pcszFlags the flag string to parse
+ * @param pfFlags where to store the parse result. May not be NULL.
+ * @note This function is also inline because it must be accessible from
+ * several modules and it does not seem reasonable to put it into
+ * its own library.
+ */
+DECLINLINE(int) validateFlags(const char *pcszFlags, uint32_t *pfFlags)
+{
+ static const uint32_t s_aFlagList[] =
+ {
+ TRANSIENT, READONLY, RDONLYGUEST, RDONLYHOST, TRANSRESET
+ };
+ const char *pcszNext = pcszFlags;
+ int rc = VINF_SUCCESS;
+ uint32_t fFlags = 0;
+ AssertLogRelReturn(VALID_PTR(pfFlags), VERR_INVALID_POINTER);
+
+ if (pcszFlags)
+ {
+ while (' ' == *pcszNext)
+ ++pcszNext;
+ while ((*pcszNext != '\0') && RT_SUCCESS(rc))
+ {
+ unsigned i = 0;
+ for (; i < RT_ELEMENTS(s_aFlagList); ++i)
+ if (RTStrNICmp(pcszNext, flagName(s_aFlagList[i]),
+ flagNameLen(s_aFlagList[i])) == 0)
+ break;
+ if (RT_ELEMENTS(s_aFlagList) == i)
+ rc = VERR_PARSE_ERROR;
+ else
+ {
+ fFlags |= s_aFlagList[i];
+ pcszNext += flagNameLen(s_aFlagList[i]);
+ while (' ' == *pcszNext)
+ ++pcszNext;
+ if (',' == *pcszNext)
+ ++pcszNext;
+ else if (*pcszNext != '\0')
+ rc = VERR_PARSE_ERROR;
+ while (' ' == *pcszNext)
+ ++pcszNext;
+ }
+ }
+ }
+ if (RT_SUCCESS(rc))
+ *pfFlags = fFlags;
+ return rc;
+}
+
+/**
+ * Write out flags to a string.
+ * @returns IPRT status code
+ * @param fFlags the flags to write out
+ * @param pszFlags where to write the flags string. This must point to
+ * a buffer of size (at least) MAX_FLAGS_LEN.
+ */
+DECLINLINE(int) writeFlags(uint32_t fFlags, char *pszFlags)
+{
+ /* Putting READONLY before the other RDONLY flags keeps the result short. */
+ static const uint32_t s_aFlagList[] =
+ {
+ TRANSIENT, READONLY, RDONLYGUEST, RDONLYHOST, TRANSRESET
+ };
+ int rc = VINF_SUCCESS;
+
+ AssertLogRelReturn(VALID_PTR(pszFlags), VERR_INVALID_POINTER);
+ if ((fFlags & ~ALLFLAGS) == NILFLAG)
+ {
+ /* TRANSRESET implies TRANSIENT. For compatability with old clients we
+ always set TRANSIENT when TRANSRESET appears. */
+ if (fFlags & TRANSRESET)
+ fFlags |= TRANSIENT;
+
+ char *pszNext = pszFlags;
+ for (unsigned i = 0; i < RT_ELEMENTS(s_aFlagList); ++i)
+ {
+ if (s_aFlagList[i] == (fFlags & s_aFlagList[i]))
+ {
+ strcpy(pszNext, flagName(s_aFlagList[i]));
+ pszNext += flagNameLen(s_aFlagList[i]);
+ fFlags &= ~s_aFlagList[i];
+ if (fFlags != NILFLAG)
+ {
+ strcpy(pszNext, ", ");
+ pszNext += 2;
+ }
+ }
+ }
+ *pszNext = '\0';
+
+ Assert(fFlags == NILFLAG); /* bad s_aFlagList */
+ }
+ else
+ rc = VERR_INVALID_PARAMETER;
+ return rc;
+}
+
+/**
+ * The service functions which are callable by host.
+ */
+enum eHostFn
+{
+ /**
+ * Set properties in a block. The parameters are pointers to
+ * NULL-terminated arrays containing the parameters. These are, in order,
+ * name, value, timestamp, flags. Strings are stored as pointers to
+ * mutable utf8 data. All parameters must be supplied.
+ */
+ SET_PROPS_HOST = 1,
+ /**
+ * Get the value attached to a guest property
+ * The parameter format matches that of GET_PROP.
+ */
+ GET_PROP_HOST = 2,
+ /**
+ * Set the value attached to a guest property
+ * The parameter format matches that of SET_PROP.
+ */
+ SET_PROP_HOST = 3,
+ /**
+ * Set the value attached to a guest property
+ * The parameter format matches that of SET_PROP_VALUE.
+ */
+ SET_PROP_VALUE_HOST = 4,
+ /**
+ * Remove a guest property.
+ * The parameter format matches that of DEL_PROP.
+ */
+ DEL_PROP_HOST = 5,
+ /**
+ * Enumerate guest properties.
+ * The parameter format matches that of ENUM_PROPS.
+ */
+ ENUM_PROPS_HOST = 6,
+
+ /**
+ * Set global flags for the service. Currently RDONLYGUEST is supported.
+ * Takes one 32-bit unsigned integer parameter for the flags.
+ */
+ SET_GLOBAL_FLAGS_HOST = 7,
+
+ /**
+ * Return the pointer to a debug info function enumerating all guest properties.
+ */
+ GET_DBGF_INFO_FN = 8
+};
+
+/**
+ * The service functions which are called by guest. The numbers may not change,
+ * so we hardcode them.
+ */
+enum eGuestFn
+{
+ /** Get a guest property */
+ GET_PROP = 1,
+ /** Set a guest property */
+ SET_PROP = 2,
+ /** Set just the value of a guest property */
+ SET_PROP_VALUE = 3,
+ /** Delete a guest property */
+ DEL_PROP = 4,
+ /** Enumerate guest properties */
+ ENUM_PROPS = 5,
+ /** Poll for guest notifications */
+ GET_NOTIFICATION = 6
+};
+
+/**
+ * Data structure to pass to the service extension callback. We use this to
+ * notify the host of changes to properties.
+ */
+typedef struct _HOSTCALLBACKDATA
+{
+ /** Magic number to identify the structure */
+ uint32_t u32Magic;
+ /** The name of the property that was changed */
+ const char *pcszName;
+ /** The new property value, or NULL if the property was deleted */
+ const char *pcszValue;
+ /** The timestamp of the modification */
+ uint64_t u64Timestamp;
+ /** The flags field of the modified property */
+ const char *pcszFlags;
+} HOSTCALLBACKDATA, *PHOSTCALLBACKDATA;
+
+enum
+{
+ /** Magic number for sanity checking the HOSTCALLBACKDATA structure */
+ HOSTCALLBACKMAGIC = 0x69c87a78
+};
+
+/**
+ * HGCM parameter structures. Packing is explicitly defined as this is a wire format.
+ */
+#pragma pack (1)
+/** The guest is requesting the value of a property */
+typedef struct _GetProperty
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * The property name (IN pointer)
+ * This must fit to a number of criteria, namely
+ * - Only Utf8 strings are allowed
+ * - Less than or equal to MAX_NAME_LEN bytes in length
+ * - Zero terminated
+ */
+ HGCMFunctionParameter name;
+
+ /**
+ * The returned string data will be placed here. (OUT pointer)
+ * This call returns two null-terminated strings which will be placed one
+ * after another: value and flags.
+ */
+ HGCMFunctionParameter buffer;
+
+ /**
+ * The property timestamp. (OUT uint64_t)
+ */
+ HGCMFunctionParameter timestamp;
+
+ /**
+ * If the buffer provided was large enough this will contain the size of
+ * the returned data. Otherwise it will contain the size of the buffer
+ * needed to hold the data and VERR_BUFFER_OVERFLOW will be returned.
+ * (OUT uint32_t)
+ */
+ HGCMFunctionParameter size;
+} GetProperty;
+
+/** The guest is requesting to change a property */
+typedef struct _SetProperty
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * The property name. (IN pointer)
+ * This must fit to a number of criteria, namely
+ * - Only Utf8 strings are allowed
+ * - Less than or equal to MAX_NAME_LEN bytes in length
+ * - Zero terminated
+ */
+ HGCMFunctionParameter name;
+
+ /**
+ * The value of the property (IN pointer)
+ * Criteria as for the name parameter, but with length less than or equal to
+ * MAX_VALUE_LEN.
+ */
+ HGCMFunctionParameter value;
+
+ /**
+ * The property flags (IN pointer)
+ * This is a comma-separated list of the format flag=value
+ * The length must be less than or equal to MAX_FLAGS_LEN and only
+ * known flag names and values will be accepted.
+ */
+ HGCMFunctionParameter flags;
+} SetProperty;
+
+/** The guest is requesting to change the value of a property */
+typedef struct _SetPropertyValue
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * The property name. (IN pointer)
+ * This must fit to a number of criteria, namely
+ * - Only Utf8 strings are allowed
+ * - Less than or equal to MAX_NAME_LEN bytes in length
+ * - Zero terminated
+ */
+ HGCMFunctionParameter name;
+
+ /**
+ * The value of the property (IN pointer)
+ * Criteria as for the name parameter, but with length less than or equal to
+ * MAX_VALUE_LEN.
+ */
+ HGCMFunctionParameter value;
+} SetPropertyValue;
+
+/** The guest is requesting to remove a property */
+typedef struct _DelProperty
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * The property name. This must fit to a number of criteria, namely
+ * - Only Utf8 strings are allowed
+ * - Less than or equal to MAX_NAME_LEN bytes in length
+ * - Zero terminated
+ */
+ HGCMFunctionParameter name;
+} DelProperty;
+
+/** The guest is requesting to enumerate properties */
+typedef struct _EnumProperties
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /**
+ * Array of patterns to match the properties against, separated by '|'
+ * characters. For backwards compatibility, '\\0' is also accepted
+ * as a separater.
+ * (IN pointer)
+ * If only a single, empty pattern is given then match all.
+ */
+ HGCMFunctionParameter patterns;
+ /**
+ * On success, null-separated array of strings in which the properties are
+ * returned. (OUT pointer)
+ * The number of strings in the array is always a multiple of four,
+ * and in sequences of name, value, timestamp (hexadecimal string) and the
+ * flags as a comma-separated list in the format "name=value". The list
+ * is terminated by an empty string after a "flags" entry (or at the
+ * start).
+ */
+ HGCMFunctionParameter strings;
+ /**
+ * On success, the size of the returned data. If the buffer provided is
+ * too small, the size of buffer needed. (OUT uint32_t)
+ */
+ HGCMFunctionParameter size;
+} EnumProperties;
+
+/**
+ * The guest is polling for notifications on changes to properties, specifying
+ * a set of patterns to match the names of changed properties against and
+ * optionally the timestamp of the last notification seen.
+ * On success, VINF_SUCCESS will be returned and the buffer will contain
+ * details of a property notification. If no new notification is available
+ * which matches one of the specified patterns, the call will block until one
+ * is.
+ * If the last notification could not be found by timestamp, VWRN_NOT_FOUND
+ * will be returned and the oldest available notification will be returned.
+ * If a zero timestamp is specified, the call will always wait for a new
+ * notification to arrive.
+ * If the buffer supplied was not large enough to hold the notification,
+ * VERR_BUFFER_OVERFLOW will be returned and the size parameter will contain
+ * the size of the buffer needed.
+ *
+ * The protocol for a guest to obtain notifications is to call
+ * GET_NOTIFICATION in a loop. On the first call, the ingoing timestamp
+ * parameter should be set to zero. On subsequent calls, it should be set to
+ * the outgoing timestamp from the previous call.
+ */
+typedef struct _GetNotification
+{
+ VBoxGuestHGCMCallInfoTimed hdr;
+
+ /**
+ * A list of patterns to match the guest event name against, separated by
+ * vertical bars (|) (IN pointer)
+ * An empty string means match all.
+ */
+ HGCMFunctionParameter patterns;
+ /**
+ * The timestamp of the last change seen (IN uint64_t)
+ * This may be zero, in which case the oldest available change will be
+ * sent. If the service does not remember an event matching the
+ * timestamp, then VWRN_NOT_FOUND will be returned, and the guest should
+ * assume that it has missed a certain number of notifications.
+ *
+ * The timestamp of the change being notified of (OUT uint64_t)
+ * Undefined on failure.
+ */
+ HGCMFunctionParameter timestamp;
+
+ /**
+ * The returned data, if any, will be placed here. (OUT pointer)
+ * This call returns three null-terminated strings which will be placed
+ * one after another: name, value and flags. For a delete notification,
+ * value and flags will be empty strings. Undefined on failure.
+ */
+ HGCMFunctionParameter buffer;
+
+ /**
+ * On success, the size of the returned data. (OUT uint32_t)
+ * On buffer overflow, the size of the buffer needed to hold the data.
+ * Undefined on failure.
+ */
+ HGCMFunctionParameter size;
+} GetNotification;
+#pragma pack ()
+
+} /* namespace guestProp */
+
+#endif /* !___VBox_HostService_GuestPropertySvc_h */
+
diff --git a/include/VBox/HostServices/Makefile.kup b/include/VBox/HostServices/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/VBox/HostServices/Makefile.kup
diff --git a/include/VBox/HostServices/Service.h b/include/VBox/HostServices/Service.h
new file mode 100644
index 00000000..98e227a2
--- /dev/null
+++ b/include/VBox/HostServices/Service.h
@@ -0,0 +1,472 @@
+/** @file
+ * Base class for an host-guest service.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_HostService_Service_h
+#define ___VBox_HostService_Service_h
+
+#include <VBox/log.h>
+#include <VBox/hgcmsvc.h>
+#include <iprt/assert.h>
+#include <iprt/alloc.h>
+#include <iprt/cpp/utils.h>
+
+#include <memory> /* for auto_ptr */
+
+namespace HGCM
+{
+
+class Message
+{
+public:
+ Message(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[])
+ : m_uMsg(0)
+ , m_cParms(0)
+ , m_paParms(0)
+ {
+ setData(uMsg, cParms, aParms);
+ }
+ ~Message()
+ {
+ cleanup();
+ }
+
+ uint32_t message() const { return m_uMsg; }
+ uint32_t paramsCount() const { return m_cParms; }
+
+ int getData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[]) const
+ {
+ if (m_uMsg != uMsg)
+ {
+ LogFlowFunc(("Message type does not match (%u (buffer), %u (guest))\n",
+ m_uMsg, uMsg));
+ return VERR_INVALID_PARAMETER;
+ }
+ if (m_cParms != cParms)
+ {
+ LogFlowFunc(("Parameter count does not match (%u (buffer), %u (guest))\n",
+ m_cParms, cParms));
+ return VERR_INVALID_PARAMETER;
+ }
+
+ int rc = copyParms(cParms, m_paParms, &aParms[0], false /* fCreatePtrs */);
+
+// if (RT_FAILURE(rc))
+// cleanup(aParms);
+ return rc;
+ }
+ int setData(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[])
+ {
+ AssertReturn(cParms < 256, VERR_INVALID_PARAMETER);
+ AssertPtrNullReturn(aParms, VERR_INVALID_PARAMETER);
+
+ /* Cleanup old messages. */
+ cleanup();
+
+ m_uMsg = uMsg;
+ m_cParms = cParms;
+
+ if (cParms > 0)
+ {
+ m_paParms = (VBOXHGCMSVCPARM*)RTMemAllocZ(sizeof(VBOXHGCMSVCPARM) * m_cParms);
+ if (!m_paParms)
+ return VERR_NO_MEMORY;
+ }
+
+ int rc = copyParms(cParms, &aParms[0], m_paParms, true /* fCreatePtrs */);
+
+ if (RT_FAILURE(rc))
+ cleanup();
+
+ return rc;
+ }
+
+ int getParmU32Info(uint32_t iParm, uint32_t *pu32Info) const
+ {
+ AssertPtrNullReturn(pu32Info, VERR_INVALID_PARAMETER);
+ AssertReturn(iParm < m_cParms, VERR_INVALID_PARAMETER);
+ AssertReturn(m_paParms[iParm].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_INVALID_PARAMETER);
+
+ *pu32Info = m_paParms[iParm].u.uint32;
+
+ return VINF_SUCCESS;
+ }
+ int getParmU64Info(uint32_t iParm, uint64_t *pu64Info) const
+ {
+ AssertPtrNullReturn(pu64Info, VERR_INVALID_PARAMETER);
+ AssertReturn(iParm < m_cParms, VERR_INVALID_PARAMETER);
+ AssertReturn(m_paParms[iParm].type == VBOX_HGCM_SVC_PARM_64BIT, VERR_INVALID_PARAMETER);
+
+ *pu64Info = m_paParms[iParm].u.uint64;
+
+ return VINF_SUCCESS;
+ }
+ int getParmPtrInfo(uint32_t iParm, void **ppvAddr, uint32_t *pcSize) const
+ {
+ AssertPtrNullReturn(ppvAddr, VERR_INVALID_PARAMETER);
+ AssertPtrNullReturn(pcSize, VERR_INVALID_PARAMETER);
+ AssertReturn(iParm < m_cParms, VERR_INVALID_PARAMETER);
+ AssertReturn(m_paParms[iParm].type == VBOX_HGCM_SVC_PARM_PTR, VERR_INVALID_PARAMETER);
+
+ *ppvAddr = m_paParms[iParm].u.pointer.addr;
+ *pcSize = m_paParms[iParm].u.pointer.size;
+
+ return VINF_SUCCESS;
+ }
+
+ int copyParms(uint32_t cParms, PVBOXHGCMSVCPARM paParmsSrc, PVBOXHGCMSVCPARM paParmsDst, bool fCreatePtrs) const
+ {
+ int rc = VINF_SUCCESS;
+ for (uint32_t i = 0; i < cParms; ++i)
+ {
+ paParmsDst[i].type = paParmsSrc[i].type;
+ switch (paParmsSrc[i].type)
+ {
+ case VBOX_HGCM_SVC_PARM_32BIT:
+ {
+ paParmsDst[i].u.uint32 = paParmsSrc[i].u.uint32;
+ break;
+ }
+ case VBOX_HGCM_SVC_PARM_64BIT:
+ {
+ paParmsDst[i].u.uint64 = paParmsSrc[i].u.uint64;
+ break;
+ }
+ case VBOX_HGCM_SVC_PARM_PTR:
+ {
+ /* Do we have to recreate the memory? */
+ if (fCreatePtrs)
+ {
+ /* Yes, do so. */
+ paParmsDst[i].u.pointer.size = paParmsSrc[i].u.pointer.size;
+ if (paParmsDst[i].u.pointer.size > 0)
+ {
+ paParmsDst[i].u.pointer.addr = RTMemAlloc(paParmsDst[i].u.pointer.size);
+ if (!paParmsDst[i].u.pointer.addr)
+ {
+ rc = VERR_NO_MEMORY;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* No, but we have to check if there is enough room. */
+ if (paParmsDst[i].u.pointer.size < paParmsSrc[i].u.pointer.size)
+ rc = VERR_BUFFER_OVERFLOW;
+ }
+ if ( paParmsDst[i].u.pointer.addr
+ && paParmsSrc[i].u.pointer.size > 0
+ && paParmsDst[i].u.pointer.size > 0)
+ memcpy(paParmsDst[i].u.pointer.addr,
+ paParmsSrc[i].u.pointer.addr,
+ RT_MIN(paParmsDst[i].u.pointer.size, paParmsSrc[i].u.pointer.size));
+ break;
+ }
+ default:
+ {
+ AssertMsgFailed(("Unknown HGCM type %u\n", paParmsSrc[i].type));
+ rc = VERR_INVALID_PARAMETER;
+ break;
+ }
+ }
+ if (RT_FAILURE(rc))
+ break;
+ }
+ return rc;
+ }
+
+ void cleanup()
+ {
+ if (m_paParms)
+ {
+ for (uint32_t i = 0; i < m_cParms; ++i)
+ {
+ switch (m_paParms[i].type)
+ {
+ case VBOX_HGCM_SVC_PARM_PTR:
+ if (m_paParms[i].u.pointer.size)
+ RTMemFree(m_paParms[i].u.pointer.addr);
+ break;
+ }
+ }
+ RTMemFree(m_paParms);
+ m_paParms = 0;
+ }
+ m_cParms = 0;
+ m_uMsg = 0;
+ }
+
+protected:
+ uint32_t m_uMsg;
+ uint32_t m_cParms;
+ PVBOXHGCMSVCPARM m_paParms;
+};
+
+class Client
+{
+public:
+ Client(uint32_t uClientId, VBOXHGCMCALLHANDLE hHandle, uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[])
+ : m_uClientId(uClientId)
+ , m_hHandle(hHandle)
+ , m_uMsg(uMsg)
+ , m_cParms(cParms)
+ , m_paParms(aParms) {}
+
+ VBOXHGCMCALLHANDLE handle() const { return m_hHandle; }
+ uint32_t message() const { return m_uMsg; }
+ uint32_t clientId() const { return m_uClientId; }
+
+ int addMessageInfo(uint32_t uMsg, uint32_t cParms)
+ {
+ if (m_cParms != 3)
+ return VERR_INVALID_PARAMETER;
+
+ m_paParms[0].setUInt32(uMsg);
+ m_paParms[1].setUInt32(cParms);
+
+ return VINF_SUCCESS;
+ }
+ int addMessageInfo(const Message *pMessage)
+ {
+ if (m_cParms != 3)
+ return VERR_INVALID_PARAMETER;
+
+ m_paParms[0].setUInt32(pMessage->message());
+ m_paParms[1].setUInt32(pMessage->paramsCount());
+
+ return VINF_SUCCESS;
+ }
+ int addMessage(const Message *pMessage)
+ {
+ return pMessage->getData(m_uMsg, m_cParms, m_paParms);
+ }
+private:
+ uint32_t m_uClientId;
+ VBOXHGCMCALLHANDLE m_hHandle;
+ uint32_t m_uMsg;
+ uint32_t m_cParms;
+ PVBOXHGCMSVCPARM m_paParms;
+};
+
+template <class T>
+class AbstractService: public RTCNonCopyable
+{
+public:
+ /**
+ * @copydoc VBOXHGCMSVCLOAD
+ */
+ static DECLCALLBACK(int) svcLoad(VBOXHGCMSVCFNTABLE *pTable)
+ {
+ LogFlowFunc(("ptable = %p\n", pTable));
+ int rc = VINF_SUCCESS;
+
+ if (!VALID_PTR(pTable))
+ rc = VERR_INVALID_PARAMETER;
+ else
+ {
+ LogFlowFunc(("ptable->cbSize = %d, ptable->u32Version = 0x%08X\n", pTable->cbSize, pTable->u32Version));
+
+ if ( pTable->cbSize != sizeof (VBOXHGCMSVCFNTABLE)
+ || pTable->u32Version != VBOX_HGCM_SVC_VERSION)
+ rc = VERR_VERSION_MISMATCH;
+ else
+ {
+ std::auto_ptr<AbstractService> apService;
+ /* No exceptions may propagate outside. */
+ try
+ {
+ apService = std::auto_ptr<AbstractService>(new T(pTable->pHelpers));
+ } catch (int rcThrown)
+ {
+ rc = rcThrown;
+ } catch (...)
+ {
+ rc = VERR_UNRESOLVED_ERROR;
+ }
+
+ if (RT_SUCCESS(rc))
+ {
+ /*
+ * We don't need an additional client data area on the host,
+ * because we're a class which can have members for that :-).
+ */
+ pTable->cbClient = 0;
+
+ /* These functions are mandatory */
+ pTable->pfnUnload = svcUnload;
+ pTable->pfnConnect = svcConnect;
+ pTable->pfnDisconnect = svcDisconnect;
+ pTable->pfnCall = svcCall;
+ /* Clear obligatory functions. */
+ pTable->pfnHostCall = NULL;
+ pTable->pfnSaveState = NULL;
+ pTable->pfnLoadState = NULL;
+ pTable->pfnRegisterExtension = NULL;
+
+ /* Let the service itself initialize. */
+ rc = apService->init(pTable);
+
+ /* Only on success stop the auto release of the auto_ptr. */
+ if (RT_SUCCESS(rc))
+ pTable->pvService = apService.release();
+ }
+ }
+ }
+
+ LogFlowFunc(("returning %Rrc\n", rc));
+ return rc;
+ }
+ virtual ~AbstractService() {};
+
+protected:
+ explicit AbstractService(PVBOXHGCMSVCHELPERS pHelpers)
+ : m_pHelpers(pHelpers)
+ , m_pfnHostCallback(NULL)
+ , m_pvHostData(NULL)
+ {}
+ virtual int init(VBOXHGCMSVCFNTABLE *ptable) { return VINF_SUCCESS; }
+ virtual int uninit() { return VINF_SUCCESS; }
+ virtual int clientConnect(uint32_t u32ClientID, void *pvClient) = 0;
+ virtual int clientDisconnect(uint32_t u32ClientID, void *pvClient) = 0;
+ virtual void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) = 0;
+ virtual int hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) { return VINF_SUCCESS; }
+
+ /** Type definition for use in callback functions. */
+ typedef AbstractService SELF;
+ /** HGCM helper functions. */
+ PVBOXHGCMSVCHELPERS m_pHelpers;
+ /*
+ * Callback function supplied by the host for notification of updates
+ * to properties.
+ */
+ PFNHGCMSVCEXT m_pfnHostCallback;
+ /** User data pointer to be supplied to the host callback function. */
+ void *m_pvHostData;
+
+ /**
+ * @copydoc VBOXHGCMSVCHELPERS::pfnUnload
+ * Simply deletes the service object
+ */
+ static DECLCALLBACK(int) svcUnload(void *pvService)
+ {
+ AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
+ SELF *pSelf = reinterpret_cast<SELF *>(pvService);
+ int rc = pSelf->uninit();
+ AssertRC(rc);
+ if (RT_SUCCESS(rc))
+ delete pSelf;
+ return rc;
+ }
+
+ /**
+ * @copydoc VBOXHGCMSVCHELPERS::pfnConnect
+ * Stub implementation of pfnConnect and pfnDisconnect.
+ */
+ static DECLCALLBACK(int) svcConnect(void *pvService,
+ uint32_t u32ClientID,
+ void *pvClient)
+ {
+ AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
+ LogFlowFunc(("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));
+ SELF *pSelf = reinterpret_cast<SELF *>(pvService);
+ int rc = pSelf->clientConnect(u32ClientID, pvClient);
+ LogFlowFunc(("rc=%Rrc\n", rc));
+ return rc;
+ }
+
+ /**
+ * @copydoc VBOXHGCMSVCHELPERS::pfnConnect
+ * Stub implementation of pfnConnect and pfnDisconnect.
+ */
+ static DECLCALLBACK(int) svcDisconnect(void *pvService,
+ uint32_t u32ClientID,
+ void *pvClient)
+ {
+ AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
+ LogFlowFunc(("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));
+ SELF *pSelf = reinterpret_cast<SELF *>(pvService);
+ int rc = pSelf->clientDisconnect(u32ClientID, pvClient);
+ LogFlowFunc(("rc=%Rrc\n", rc));
+ return rc;
+ }
+
+ /**
+ * @copydoc VBOXHGCMSVCHELPERS::pfnCall
+ * Wraps to the call member function
+ */
+ static DECLCALLBACK(void) svcCall(void * pvService,
+ VBOXHGCMCALLHANDLE callHandle,
+ uint32_t u32ClientID,
+ void *pvClient,
+ uint32_t u32Function,
+ uint32_t cParms,
+ VBOXHGCMSVCPARM paParms[])
+ {
+ AssertLogRelReturnVoid(VALID_PTR(pvService));
+ LogFlowFunc(("pvService=%p, callHandle=%p, u32ClientID=%u, pvClient=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, callHandle, u32ClientID, pvClient, u32Function, cParms, paParms));
+ SELF *pSelf = reinterpret_cast<SELF *>(pvService);
+ pSelf->guestCall(callHandle, u32ClientID, pvClient, u32Function, cParms, paParms);
+ LogFlowFunc(("returning\n"));
+ }
+
+ /**
+ * @copydoc VBOXHGCMSVCHELPERS::pfnHostCall
+ * Wraps to the hostCall member function
+ */
+ static DECLCALLBACK(int) svcHostCall(void *pvService,
+ uint32_t u32Function,
+ uint32_t cParms,
+ VBOXHGCMSVCPARM paParms[])
+ {
+ AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
+ LogFlowFunc(("pvService=%p, u32Function=%u, cParms=%u, paParms=%p\n", pvService, u32Function, cParms, paParms));
+ SELF *pSelf = reinterpret_cast<SELF *>(pvService);
+ int rc = pSelf->hostCall(u32Function, cParms, paParms);
+ LogFlowFunc(("rc=%Rrc\n", rc));
+ return rc;
+ }
+
+ /**
+ * @copydoc VBOXHGCMSVCHELPERS::pfnRegisterExtension
+ * Installs a host callback for notifications of property changes.
+ */
+ static DECLCALLBACK(int) svcRegisterExtension(void *pvService,
+ PFNHGCMSVCEXT pfnExtension,
+ void *pvExtension)
+ {
+ AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
+ LogFlowFunc(("pvService=%p, pfnExtension=%p, pvExtention=%p\n", pvService, pfnExtension, pvExtension));
+ SELF *pSelf = reinterpret_cast<SELF *>(pvService);
+ pSelf->m_pfnHostCallback = pfnExtension;
+ pSelf->m_pvHostData = pvExtension;
+ return VINF_SUCCESS;
+ }
+};
+
+}
+
+#endif /* !___VBox_HostService_Service_h */
+
diff --git a/include/VBox/HostServices/VBoxClipboardExt.h b/include/VBox/HostServices/VBoxClipboardExt.h
new file mode 100644
index 00000000..a1392ec0
--- /dev/null
+++ b/include/VBox/HostServices/VBoxClipboardExt.h
@@ -0,0 +1,51 @@
+/** @file
+ * Shared Clipboard:
+ * Common header for the service extension.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_HostService_VBoxClipboardExt_h
+#define ___VBox_HostService_VBoxClipboardExt_h
+
+#include <VBox/types.h>
+
+#define VBOX_CLIPBOARD_EXT_FN_SET_CALLBACK (0)
+#define VBOX_CLIPBOARD_EXT_FN_FORMAT_ANNOUNCE (1)
+#define VBOX_CLIPBOARD_EXT_FN_DATA_READ (2)
+#define VBOX_CLIPBOARD_EXT_FN_DATA_WRITE (3)
+
+typedef DECLCALLBACK(int) VRDPCLIPBOARDEXTCALLBACK (uint32_t u32Function, uint32_t u32Format, void *pvData, uint32_t cbData);
+typedef VRDPCLIPBOARDEXTCALLBACK *PFNVRDPCLIPBOARDEXTCALLBACK;
+
+typedef struct _VBOXCLIPBOARDEXTPARMS
+{
+ uint32_t u32Format;
+ union
+ {
+ void *pvData;
+ PFNVRDPCLIPBOARDEXTCALLBACK pfnCallback;
+ } u;
+ uint32_t cbData;
+} VBOXCLIPBOARDEXTPARMS;
+
+#endif
diff --git a/include/VBox/HostServices/VBoxClipboardSvc.h b/include/VBox/HostServices/VBoxClipboardSvc.h
new file mode 100644
index 00000000..0bb5607c
--- /dev/null
+++ b/include/VBox/HostServices/VBoxClipboardSvc.h
@@ -0,0 +1,137 @@
+/** @file
+ * Shared Clipboard:
+ * Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_HostService_VBoxClipboardSvc_h
+#define ___VBox_HostService_VBoxClipboardSvc_h
+
+#include <VBox/types.h>
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest2.h>
+#include <VBox/hgcmsvc.h>
+
+/*
+ * The mode of operations.
+ */
+#define VBOX_SHARED_CLIPBOARD_MODE_OFF 0
+#define VBOX_SHARED_CLIPBOARD_MODE_HOST_TO_GUEST 1
+#define VBOX_SHARED_CLIPBOARD_MODE_GUEST_TO_HOST 2
+#define VBOX_SHARED_CLIPBOARD_MODE_BIDIRECTIONAL 3
+
+/*
+ * Supported data formats. Bit mask.
+ */
+#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT 0x01
+#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP 0x02
+#define VBOX_SHARED_CLIPBOARD_FMT_HTML 0x04
+
+/*
+ * The service functions which are callable by host.
+ */
+#define VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE 1
+/** Run headless on the host, i.e. do not touch the host clipboard. */
+#define VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS 2
+
+/*
+ * The service functions which are called by guest.
+ */
+/* Call host and wait blocking for an host event VBOX_SHARED_CLIPBOARD_HOST_MSG_* */
+#define VBOX_SHARED_CLIPBOARD_FN_GET_HOST_MSG 1
+/* Send list of available formats to host. */
+#define VBOX_SHARED_CLIPBOARD_FN_FORMATS 2
+/* Obtain data in specified format from host. */
+#define VBOX_SHARED_CLIPBOARD_FN_READ_DATA 3
+/* Send data in requested format to host. */
+#define VBOX_SHARED_CLIPBOARD_FN_WRITE_DATA 4
+
+/*
+ * The host messages for the guest.
+ */
+#define VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT 1
+#define VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA 2
+#define VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS 3
+
+/*
+ * HGCM parameter structures.
+ */
+#pragma pack (1)
+typedef struct _VBoxClipboardGetHostMsg
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /* VBOX_SHARED_CLIPBOARD_HOST_MSG_* */
+ HGCMFunctionParameter msg; /* OUT uint32_t */
+
+ /* VBOX_SHARED_CLIPBOARD_FMT_*, depends on the 'msg'. */
+ HGCMFunctionParameter formats; /* OUT uint32_t */
+} VBoxClipboardGetHostMsg;
+
+#define VBOX_SHARED_CLIPBOARD_CPARMS_GET_HOST_MSG 2
+
+typedef struct _VBoxClipboardFormats
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /* VBOX_SHARED_CLIPBOARD_FMT_* */
+ HGCMFunctionParameter formats; /* OUT uint32_t */
+} VBoxClipboardFormats;
+
+#define VBOX_SHARED_CLIPBOARD_CPARMS_FORMATS 1
+
+typedef struct _VBoxClipboardReadData
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /* Requested format. */
+ HGCMFunctionParameter format; /* IN uint32_t */
+
+ /* The data buffer. */
+ HGCMFunctionParameter ptr; /* IN linear pointer. */
+
+ /* Size of returned data, if > ptr->cb, then no data was
+ * actually transferred and the guest must repeat the call.
+ */
+ HGCMFunctionParameter size; /* OUT uint32_t */
+
+} VBoxClipboardReadData;
+
+#define VBOX_SHARED_CLIPBOARD_CPARMS_READ_DATA 3
+
+typedef struct _VBoxClipboardWriteData
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /* Returned format as requested in the VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA message. */
+ HGCMFunctionParameter format; /* IN uint32_t */
+
+ /* Data. */
+ HGCMFunctionParameter ptr; /* IN linear pointer. */
+} VBoxClipboardWriteData;
+
+#define VBOX_SHARED_CLIPBOARD_CPARMS_WRITE_DATA 2
+
+#pragma pack ()
+
+#endif
diff --git a/include/VBox/HostServices/VBoxCrOpenGLSvc.h b/include/VBox/HostServices/VBoxCrOpenGLSvc.h
new file mode 100644
index 00000000..150faac7
--- /dev/null
+++ b/include/VBox/HostServices/VBoxCrOpenGLSvc.h
@@ -0,0 +1,346 @@
+/** @file
+ * OpenGL:
+ * Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_HostService_VBoxCrOpenGLSvc_h
+#define ___VBox_HostService_VBoxCrOpenGLSvc_h
+
+#include <VBox/types.h>
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest2.h>
+#include <VBox/hgcmsvc.h>
+
+/* crOpenGL host functions */
+#define SHCRGL_HOST_FN_SET_CONSOLE (1)
+#define SHCRGL_HOST_FN_SET_VISIBLE_REGION (5)
+#define SHCRGL_HOST_FN_SET_VM (7)
+#define SHCRGL_HOST_FN_SCREEN_CHANGED (8)
+#ifdef VBOX_WITH_CRHGSMI
+#define SHCRGL_HOST_FN_CRHGSMI_CMD (10)
+#define SHCRGL_HOST_FN_CRHGSMI_CTL (11)
+#endif
+#define SHCRGL_HOST_FN_VIEWPORT_CHANGED (15)
+#define SHCRGL_HOST_FN_SET_OUTPUT_REDIRECT (20)
+/* crOpenGL guest functions */
+#define SHCRGL_GUEST_FN_WRITE (2)
+#define SHCRGL_GUEST_FN_READ (3)
+#define SHCRGL_GUEST_FN_WRITE_READ (4)
+#define SHCRGL_GUEST_FN_SET_VERSION (6)
+#define SHCRGL_GUEST_FN_INJECT (9)
+#define SHCRGL_GUEST_FN_SET_PID (12)
+#define SHCRGL_GUEST_FN_WRITE_BUFFER (13)
+#define SHCRGL_GUEST_FN_WRITE_READ_BUFFERED (14)
+
+/* Parameters count */
+#define SHCRGL_CPARMS_SET_CONSOLE (1)
+#define SHCRGL_CPARMS_SET_VM (1)
+#define SHCRGL_CPARMS_SET_VISIBLE_REGION (2)
+#define SHCRGL_CPARMS_WRITE (1)
+#define SHCRGL_CPARMS_READ (2)
+#define SHCRGL_CPARMS_WRITE_READ (3)
+#define SHCRGL_CPARMS_SET_VERSION (2)
+#define SHCRGL_CPARMS_SCREEN_CHANGED (1)
+#define SHCRGL_CPARMS_INJECT (2)
+#define SHCRGL_CPARMS_SET_PID (1)
+#define SHCRGL_CPARMS_WRITE_BUFFER (4)
+#define SHCRGL_CPARMS_WRITE_READ_BUFFERED (3)
+#define SHCRGL_CPARMS_SET_OUTPUT_REDIRECT (1)
+#define SHCRGL_CPARMS_VIEWPORT_CHANGED (5)
+
+/* @todo Move to H3DOR.h begin */
+
+/* Names of supported output redirect formats. */
+#define H3DOR_FMT_RGBA_TOPDOWN "H3DOR_FMT_RGBA_TOPDOWN"
+
+/* Comma separated list of output formats supported by the output redirect target. */
+#define H3DOR_PROP_FORMATS 0
+
+#pragma pack(1)
+typedef struct {
+ /* The caller's context of the redirection. */
+ const void *pvContext;
+ /* Inform caller that a new window will be redirected. */
+ DECLR3CALLBACKMEMBER(void, H3DORBegin, (const void *pvContext, void **ppvInstance,
+ const char *pszFormat));
+ /* The window dimension has been changed. */
+ DECLR3CALLBACKMEMBER(void, H3DORGeometry, (void *pvInstance,
+ int32_t x, int32_t y, uint32_t w, uint32_t h));
+ /* Update the window visible region. */
+ DECLR3CALLBACKMEMBER(void, H3DORVisibleRegion, (void *pvInstance,
+ uint32_t cRects, RTRECT *paRects));
+ /* A rendered 3D frame is ready. Format of pvData is "pszFormat" parameter of H3DORBegin. */
+ DECLR3CALLBACKMEMBER(void, H3DORFrame, (void *pvInstance,
+ void *pvData, uint32_t cbData));
+ /* The window is closed. */
+ DECLR3CALLBACKMEMBER(void, H3DOREnd, (void *pvInstance));
+ /* Obtain caller's parameters: the list of supported formats, etc. */
+ DECLR3CALLBACKMEMBER(int, H3DORContextProperty, (const void *pvContext, uint32_t index,
+ void *pvBuffer, uint32_t cbBuffer, uint32_t *pcbOut));
+} H3DOUTPUTREDIRECT;
+#pragma pack()
+
+/* @todo Move to H3DOR.h end */
+
+#ifdef VBOX_WITH_CRHGSMI
+#pragma pack(1)
+typedef struct
+{
+ int32_t result; /**< OUT Host HGSMI return code.*/
+ uint32_t u32ClientID; /**< IN The id of the caller. */
+ uint32_t u32Function; /**< IN Function number. */
+ uint32_t u32Reserved;
+} CRVBOXHGSMIHDR;
+AssertCompileSize(CRVBOXHGSMIHDR, 16);
+
+/** GUEST_FN_WRITE Parameters structure. */
+typedef struct
+{
+ CRVBOXHGSMIHDR hdr;
+ /** buffer index, in
+ * Data buffer
+ */
+ uint32_t iBuffer;
+} CRVBOXHGSMIWRITE;
+
+/** GUEST_FN_READ Parameters structure. */
+typedef struct
+{
+ CRVBOXHGSMIHDR hdr;
+
+ /** buffer index, in/out
+ * Data buffer
+ */
+ uint32_t iBuffer;
+ uint32_t cbBuffer;
+} CRVBOXHGSMIREAD;
+
+/** GUEST_FN_WRITE_READ Parameters structure. */
+typedef struct
+{
+ CRVBOXHGSMIHDR hdr;
+
+ /** buffer index, in
+ * Data buffer
+ */
+ uint32_t iBuffer;
+
+ /** buffer index, out
+ * Writeback buffer
+ */
+ uint32_t iWriteback;
+ uint32_t cbWriteback;
+} CRVBOXHGSMIWRITEREAD;
+
+/** GUEST_FN_SET_VERSION Parameters structure. */
+typedef struct
+{
+ CRVBOXHGSMIHDR hdr;
+
+ /** 32bit, in
+ * Major version
+ */
+ uint32_t vMajor;
+
+ /** 32bit, in
+ * Minor version
+ */
+ uint32_t vMinor;
+} CRVBOXHGSMISETVERSION;
+
+/** GUEST_FN_INJECT Parameters structure. */
+typedef struct
+{
+ CRVBOXHGSMIHDR hdr;
+
+ /** 32bit, in
+ * ClientID to inject commands buffer for
+ */
+ uint32_t u32ClientID;
+ /** buffer index, in
+ * Data buffer
+ */
+ uint32_t iBuffer;
+} CRVBOXHGSMIINJECT;
+
+/** GUEST_FN_SET_PID Parameters structure. */
+typedef struct
+{
+ CRVBOXHGSMIHDR hdr;
+
+ /** 64bit, in
+ * PID
+ */
+ uint64_t u64PID;
+} CRVBOXHGSMISETPID;
+
+#pragma pack()
+#endif
+/**
+ * SHCRGL_GUEST_FN_WRITE
+ */
+
+/** GUEST_FN_WRITE Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** pointer, in
+ * Data buffer
+ */
+ HGCMFunctionParameter pBuffer;
+} CRVBOXHGCMWRITE;
+
+/** GUEST_FN_READ Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** pointer, in/out
+ * Data buffer
+ */
+ HGCMFunctionParameter pBuffer;
+
+ /** 32bit, out
+ * Count of bytes written to buffer
+ */
+ HGCMFunctionParameter cbBuffer;
+
+} CRVBOXHGCMREAD;
+
+/** GUEST_FN_WRITE_READ Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** pointer, in
+ * Data buffer
+ */
+ HGCMFunctionParameter pBuffer;
+
+ /** pointer, out
+ * Writeback buffer
+ */
+ HGCMFunctionParameter pWriteback;
+
+ /** 32bit, out
+ * Count of bytes written to writeback buffer
+ */
+ HGCMFunctionParameter cbWriteback;
+
+} CRVBOXHGCMWRITEREAD;
+
+/** GUEST_FN_SET_VERSION Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** 32bit, in
+ * Major version
+ */
+ HGCMFunctionParameter vMajor;
+
+ /** 32bit, in
+ * Minor version
+ */
+ HGCMFunctionParameter vMinor;
+
+} CRVBOXHGCMSETVERSION;
+
+/** GUEST_FN_INJECT Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** 32bit, in
+ * ClientID to inject commands buffer for
+ */
+ HGCMFunctionParameter u32ClientID;
+ /** pointer, in
+ * Data buffer
+ */
+ HGCMFunctionParameter pBuffer;
+} CRVBOXHGCMINJECT;
+
+/** GUEST_FN_SET_PID Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** 64bit, in
+ * PID
+ */
+ HGCMFunctionParameter u64PID;
+} CRVBOXHGCMSETPID;
+
+/** GUEST_FN_WRITE_BUFFER Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** 32bit, in/out
+ * Buffer id, 0 means host have to allocate one
+ */
+ HGCMFunctionParameter iBufferID;
+
+ /** 32bit, in
+ * Buffer size
+ */
+ HGCMFunctionParameter cbBufferSize;
+
+ /** 32bit, in
+ * Write offset in buffer
+ */
+ HGCMFunctionParameter ui32Offset;
+
+ /** pointer, in
+ * Data buffer
+ */
+ HGCMFunctionParameter pBuffer;
+
+} CRVBOXHGCMWRITEBUFFER;
+
+/** GUEST_FN_WRITE_READ_BUFFERED Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** 32bit, in
+ * Buffer id.
+ */
+ HGCMFunctionParameter iBufferID;
+
+ /** pointer, out
+ * Writeback buffer
+ */
+ HGCMFunctionParameter pWriteback;
+
+ /** 32bit, out
+ * Count of bytes written to writeback buffer
+ */
+ HGCMFunctionParameter cbWriteback;
+
+} CRVBOXHGCMWRITEREADBUFFERED;
+
+#endif
diff --git a/include/VBox/HostServices/VBoxHostChannel.h b/include/VBox/HostServices/VBoxHostChannel.h
new file mode 100644
index 00000000..e3c30337
--- /dev/null
+++ b/include/VBox/HostServices/VBoxHostChannel.h
@@ -0,0 +1,209 @@
+/** @file
+ *
+ * Host Channel: the service definition.
+ */
+
+/*
+ * 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 ___VBox_HostService_VBoxHostChannel_h
+#define ___VBox_HostService_VBoxHostChannel_h
+
+#include <VBox/VMMDev.h>
+#include <VBox/VBoxGuest2.h>
+#include <VBox/hgcmsvc.h>
+
+/*
+ * Host calls.
+ */
+#define VBOX_HOST_CHANNEL_HOST_FN_REGISTER 1
+#define VBOX_HOST_CHANNEL_HOST_FN_UNREGISTER 2
+
+/*
+ * Guest calls.
+ */
+#define VBOX_HOST_CHANNEL_FN_ATTACH 1 /* Attach to a channel. */
+#define VBOX_HOST_CHANNEL_FN_DETACH 2 /* Detach from the channel. */
+#define VBOX_HOST_CHANNEL_FN_SEND 3 /* Send data to the host. */
+#define VBOX_HOST_CHANNEL_FN_RECV 4 /* Receive data from the host. */
+#define VBOX_HOST_CHANNEL_FN_CONTROL 5 /* Generic data exchange using a channel instance. */
+#define VBOX_HOST_CHANNEL_FN_EVENT_WAIT 6 /* Blocking wait for a host event. */
+#define VBOX_HOST_CHANNEL_FN_EVENT_CANCEL 7 /* Cancel the blocking wait. */
+#define VBOX_HOST_CHANNEL_FN_QUERY 8 /* Generic data exchange using a channel name. */
+
+/*
+ * The host event ids for the guest.
+ */
+#define VBOX_HOST_CHANNEL_EVENT_CANCELLED 0 /* Event was cancelled by FN_EVENT_CANCEL. */
+#define VBOX_HOST_CHANNEL_EVENT_UNREGISTERED 1 /* Channel was unregistered on host. */
+#define VBOX_HOST_CHANNEL_EVENT_RECV 2 /* Data is available for receiving. */
+#define VBOX_HOST_CHANNEL_EVENT_USER 1000 /* Base of channel specific events. */
+
+/*
+ * The common control code ids for the VBOX_HOST_CHANNEL_FN_[CONTROL|QUERY]
+ */
+#define VBOX_HOST_CHANNEL_CTRL_EXISTS 0 /* Whether the channel instance or provider exists. */
+#define VBOX_HOST_CHANNEL_CTRL_USER 1000 /* Base of channel specific events. */
+
+#pragma pack(1)
+
+/* Parameter of VBOX_HOST_CHANNEL_EVENT_RECV */
+typedef struct VBOXHOSTCHANNELEVENTRECV
+{
+ uint32_t u32SizeAvailable; /* How many bytes can be read from the channel. */
+} VBOXHOSTCHANNELEVENTRECV;
+
+/*
+ * Guest calls.
+ */
+
+typedef struct VBoxHostChannelAttach
+{
+ VBoxGuestHGCMCallInfo hdr;
+ HGCMFunctionParameter name; /* IN linear ptr: Channel name utf8 nul terminated. */
+ HGCMFunctionParameter flags; /* IN uint32_t: Channel specific flags. */
+ HGCMFunctionParameter handle; /* OUT uint32_t: The channel handle. */
+} VBoxHostChannelAttach;
+
+typedef struct VBoxHostChannelDetach
+{
+ VBoxGuestHGCMCallInfo hdr;
+ HGCMFunctionParameter handle; /* IN uint32_t: The channel handle. */
+} VBoxHostChannelDetach;
+
+typedef struct VBoxHostChannelSend
+{
+ VBoxGuestHGCMCallInfo hdr;
+ HGCMFunctionParameter handle; /* IN uint32_t: The channel handle. */
+ HGCMFunctionParameter data; /* IN linear pointer: Data to be sent. */
+} VBoxHostChannelSend;
+
+typedef struct VBoxHostChannelRecv
+{
+ VBoxGuestHGCMCallInfo hdr;
+ HGCMFunctionParameter handle; /* IN uint32_t: The channel handle. */
+ HGCMFunctionParameter data; /* OUT linear pointer: Buffer for data to be received. */
+ HGCMFunctionParameter sizeReceived; /* OUT uint32_t: Bytes received. */
+ HGCMFunctionParameter sizeRemaining; /* OUT uint32_t: Bytes remaining in the channel. */
+} VBoxHostChannelRecv;
+
+typedef struct VBoxHostChannelControl
+{
+ VBoxGuestHGCMCallInfo hdr;
+ HGCMFunctionParameter handle; /* IN uint32_t: The channel handle. */
+ HGCMFunctionParameter code; /* IN uint32_t: The channel specific control code. */
+ HGCMFunctionParameter parm; /* IN linear pointer: Parameters of the function. */
+ HGCMFunctionParameter data; /* OUT linear pointer: Buffer for results. */
+ HGCMFunctionParameter sizeDataReturned; /* OUT uint32_t: Bytes returned in the 'data' buffer. */
+} VBoxHostChannelControl;
+
+typedef struct VBoxHostChannelEventWait
+{
+ VBoxGuestHGCMCallInfo hdr;
+ HGCMFunctionParameter handle; /* OUT uint32_t: The channel which generated the event. */
+ HGCMFunctionParameter id; /* OUT uint32_t: The event VBOX_HOST_CHANNEL_EVENT_*. */
+ HGCMFunctionParameter parm; /* OUT linear pointer: Parameters of the event. */
+ HGCMFunctionParameter sizeReturned; /* OUT uint32_t: Size of the parameters. */
+} VBoxHostChannelEventWait;
+
+typedef struct VBoxHostChannelEventCancel
+{
+ VBoxGuestHGCMCallInfo hdr;
+} VBoxHostChannelEventCancel;
+
+typedef struct VBoxHostChannelQuery
+{
+ VBoxGuestHGCMCallInfo hdr;
+ HGCMFunctionParameter name; /* IN linear ptr: Channel name utf8 nul terminated. */
+ HGCMFunctionParameter code; /* IN uint32_t: The control code. */
+ HGCMFunctionParameter parm; /* IN linear pointer: Parameters of the function. */
+ HGCMFunctionParameter data; /* OUT linear pointer: Buffer for results. */
+ HGCMFunctionParameter sizeDataReturned; /* OUT uint32_t: Bytes returned in the 'data' buffer. */
+} VBoxHostChannelQuery;
+
+
+/*
+ * Host calls
+ */
+
+typedef struct VBoxHostChannelHostRegister
+{
+ VBOXHGCMSVCPARM name; /* IN ptr: Channel name utf8 nul terminated. */
+ VBOXHGCMSVCPARM iface; /* IN ptr: VBOXHOSTCHANNELINTERFACE. */
+} VBoxHostChannelHostRegister;
+
+typedef struct VBoxHostChannelHostUnregister
+{
+ VBOXHGCMSVCPARM name; /* IN ptr: Channel name utf8 nul terminated */
+} VBoxHostChannelHostUnregister;
+
+/* The channel provider will invoke this callback to report channel events. */
+typedef struct VBOXHOSTCHANNELCALLBACKS
+{
+ /* A channel event occured.
+ *
+ * @param pvCallbacks The callback context specified in HostChannelAttach.
+ * @param pvChannel The channel instance returned by HostChannelAttach.
+ * @param u32Id The event id.
+ * @param pvEvent The event parameters.
+ * @param cbEvent The size of event parameters.
+ */
+ DECLR3CALLBACKMEMBER(void, HostChannelCallbackEvent, (void *pvCallbacks, void *pvChannel,
+ uint32_t u32Id, const void *pvEvent, uint32_t cbEvent));
+} VBOXHOSTCHANNELCALLBACKS;
+
+typedef struct VBOXHOSTCHANNELINTERFACE
+{
+ /* The channel provider context. */
+ void *pvProvider;
+
+ /* A new channel is requested.
+ *
+ * @param pvProvider The provider context VBOXHOSTCHANNELINTERFACE::pvProvider.
+ * @param ppvChannel Where to store pointer to the channel instance created by the provider.
+ * @param u32Flags Channel specific flags.
+ * @param pCallbacks Callbacks to be invoked by the channel provider.
+ * @param pvCallbacks The context of callbacks.
+ */
+ DECLR3CALLBACKMEMBER(int, HostChannelAttach, (void *pvProvider, void **ppvChannel, uint32_t u32Flags,
+ VBOXHOSTCHANNELCALLBACKS *pCallbacks, void *pvCallbacks));
+
+ /* The channel is closed. */
+ DECLR3CALLBACKMEMBER(void, HostChannelDetach, (void *pvChannel));
+
+ /* The guest sends data to the channel. */
+ DECLR3CALLBACKMEMBER(int, HostChannelSend, (void *pvChannel, const void *pvData, uint32_t cbData));
+
+ /* The guest reads data from the channel. */
+ DECLR3CALLBACKMEMBER(int, HostChannelRecv, (void *pvChannel, void *pvData, uint32_t cbData,
+ uint32_t *pcbReceived, uint32_t *pcbRemaining));
+
+ /* The guest talks to the provider of the channel.
+ * @param pvChannel The channel instance. NULL if the target is the provider, rather than a channel.
+ */
+ DECLR3CALLBACKMEMBER(int, HostChannelControl, (void *pvChannel, uint32_t u32Code,
+ const void *pvParm, uint32_t cbParm,
+ const void *pvData, uint32_t cbData, uint32_t *pcbDataReturned));
+} VBOXHOSTCHANNELINTERFACE;
+
+#pragma pack()
+
+#endif
diff --git a/include/VBox/HostServices/VBoxOGLOp.h b/include/VBox/HostServices/VBoxOGLOp.h
new file mode 100644
index 00000000..d125c254
--- /dev/null
+++ b/include/VBox/HostServices/VBoxOGLOp.h
@@ -0,0 +1,1897 @@
+/** @file
+ * VirtualBox OpenGL command pack/unpack header
+ */
+
+/*
+ *
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_HostService_VBoxOGLOp_h
+#define ___VBox_HostService_VBoxOGLOp_h
+
+#ifdef VBOX_OGL_GUEST_SIDE
+/************************************************************************************************************
+ * Guest side macro's for packing OpenGL function calls into the command buffer. *
+ * *
+ ************************************************************************************************************/
+
+#define VBOX_OGL_NAME_PREFIX(Function) gl##Function
+
+#define OGL_CMD(op, numpar, size) \
+ VBoxCmdStart(VBOX_OGL_OP_##op, numpar, size);
+
+#define OGL_PARAM(val, size) \
+ VBoxCmdSaveParameter((uint8_t *)&val, size);
+
+#define OGL_MEMPARAM(ptr, size) \
+ VBoxCmdSaveMemParameter((uint8_t *)ptr, size);
+
+#define OGL_CMD_END(op) \
+ VBoxCmdStop(VBOX_OGL_OP_##op);
+
+
+#define VBOX_OGL_GEN_OP(op) \
+ OGL_CMD(op, 0, 0); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP1(op, p1) \
+ OGL_CMD(op, 1, sizeof(p1)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP2(op, p1, p2) \
+ OGL_CMD(op, 2, sizeof(p1)+sizeof(p2)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP3(op, p1, p2, p3) \
+ OGL_CMD(op, 3, sizeof(p1)+sizeof(p2)+sizeof(p3)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP4(op, p1, p2, p3, p4) \
+ OGL_CMD(op, 4, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP5(op, p1, p2, p3, p4, p5) \
+ OGL_CMD(op, 5, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP6(op, p1, p2, p3, p4, p5, p6) \
+ OGL_CMD(op, 6, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+sizeof(p6)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_PARAM(p6, sizeof(p6)); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP7(op, p1, p2, p3, p4, p5, p6, p7) \
+ OGL_CMD(op, 7, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+sizeof(p6)+sizeof(p7)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_PARAM(p6, sizeof(p6)); \
+ OGL_PARAM(p7, sizeof(p7)); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP8(op, p1, p2, p3, p4, p5, p6, p7, p8) \
+ OGL_CMD(op, 8, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+sizeof(p6)+sizeof(p7)+sizeof(p8)); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_PARAM(p6, sizeof(p6)); \
+ OGL_PARAM(p7, sizeof(p7)); \
+ OGL_PARAM(p8, sizeof(p8)); \
+ OGL_CMD_END(op);
+
+
+/* last parameter is a memory block */
+#define VBOX_OGL_GEN_OP1PTR(op, size, p1ptr) \
+ OGL_CMD(op, 1, size); \
+ OGL_MEMPARAM(p1ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP2PTR(op, p1, size, p2ptr) \
+ OGL_CMD(op, 2, sizeof(p1)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_MEMPARAM(p2ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP3PTR(op, p1, p2, size, p3ptr) \
+ OGL_CMD(op, 3, sizeof(p1)+sizeof(p2)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_MEMPARAM(p3ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP4PTR(op, p1, p2, p3, size, p4ptr) \
+ OGL_CMD(op, 4, sizeof(p1)+sizeof(p2)+sizeof(p3)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_MEMPARAM(p4ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP5PTR(op, p1, p2, p3, p4, size, p5ptr) \
+ OGL_CMD(op, 5, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_MEMPARAM(p5ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP6PTR(op, p1, p2, p3, p4, p5, size, p6ptr) \
+ OGL_CMD(op, 6, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_MEMPARAM(p6ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP7PTR(op, p1, p2, p3, p4, p5, p6, size, p7ptr) \
+ OGL_CMD(op, 7, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+sizeof(p6)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_PARAM(p6, sizeof(p6)); \
+ OGL_MEMPARAM(p7ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP8PTR(op, p1, p2, p3, p4, p5, p6, p7, size, p8ptr) \
+ OGL_CMD(op, 8, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+sizeof(p6)+sizeof(p7)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_PARAM(p6, sizeof(p6)); \
+ OGL_PARAM(p7, sizeof(p7)); \
+ OGL_MEMPARAM(p8ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP9PTR(op, p1, p2, p3, p4, p5, p6, p7, p8, size, p9ptr) \
+ OGL_CMD(op, 9, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+sizeof(p6)+sizeof(p7)+sizeof(p8)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_PARAM(p6, sizeof(p6)); \
+ OGL_PARAM(p7, sizeof(p7)); \
+ OGL_PARAM(p8, sizeof(p8)); \
+ OGL_MEMPARAM(p9ptr, size); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP10PTR(op, p1, p2, p3, p4, p5, p6, p7, p8, p9, size, p10ptr) \
+ OGL_CMD(op, 10, sizeof(p1)+sizeof(p2)+sizeof(p3)+sizeof(p4)+sizeof(p5)+sizeof(p6)+sizeof(p7)+sizeof(p8)+sizeof(p9)+size); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_PARAM(p2, sizeof(p2)); \
+ OGL_PARAM(p3, sizeof(p3)); \
+ OGL_PARAM(p4, sizeof(p4)); \
+ OGL_PARAM(p5, sizeof(p5)); \
+ OGL_PARAM(p6, sizeof(p6)); \
+ OGL_PARAM(p7, sizeof(p7)); \
+ OGL_PARAM(p8, sizeof(p8)); \
+ OGL_PARAM(p9, sizeof(p9)); \
+ OGL_MEMPARAM(p10ptr, size); \
+ OGL_CMD_END(op);
+
+
+/* two memory blocks */
+#define VBOX_OGL_GEN_OP2PTRPTR(op, size1, p1ptr, size2, p2ptr) \
+ OGL_CMD(op, 2, size1+size2); \
+ OGL_MEMPARAM(p1ptr, size1); \
+ OGL_MEMPARAM(p2ptr, size2); \
+ OGL_CMD_END(op);
+
+#define VBOX_OGL_GEN_OP3PTRPTR(op, p1, size2, p2ptr, size3, p3ptr) \
+ OGL_CMD(op, 3, sizeof(p1)+size2+size3); \
+ OGL_PARAM(p1, sizeof(p1)); \
+ OGL_MEMPARAM(p2ptr, size2); \
+ OGL_MEMPARAM(p3ptr, size3); \
+ OGL_CMD_END(op);
+
+/* Note: sync operations always set the last error */
+/* sync operation that returns a value */
+#define VBOX_OGL_GEN_SYNC_OP_RET(rettype, op) \
+ VBOX_OGL_GEN_OP(op) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP1_RET(rettype, op, p1) \
+ VBOX_OGL_GEN_OP1(op, p1) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP2_RET(rettype, op, p1, p2) \
+ VBOX_OGL_GEN_OP2(op, p1, p2) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP3_RET(rettype, op, p1, p2, p3) \
+ VBOX_OGL_GEN_OP3(op, p1, p2, p3) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP4_RET(rettype, op, p1, p2, p3, p4) \
+ VBOX_OGL_GEN_OP4(op, p1, p2, p3, p4) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP5_RET(rettype, op, p1, p2, p3, p4, p5) \
+ VBOX_OGL_GEN_OP5(op, p1, p2, p3, p4, p5) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP6_RET(rettype, op, p1, p2, p3, p4, p5, p6) \
+ VBOX_OGL_GEN_OP6(op, p1, p2, p3, p4, p5, p6) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP7_RET(rettype, op, p1, p2, p3, p4, p5, p6, p7) \
+ VBOX_OGL_GEN_OP7(op, p1, p2, p3, p4, p5, p6, p7) \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+
+#define VBOX_OGL_GEN_SYNC_OP(op) \
+ VBOX_OGL_GEN_OP(op) \
+ VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP1(op, p1) \
+ VBOX_OGL_GEN_OP1(op, p1) \
+ VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP2(op, p1, p2) \
+ VBOX_OGL_GEN_OP2(op, p1, p2) \
+ VBoxOGLFlush();
+
+
+/* Sync operation whose last parameter is a block of memory */
+#define VBOX_OGL_GEN_SYNC_OP2_PTR(op, p1, size, p2ptr) \
+ VBOX_OGL_GEN_OP2PTR(op, p1, size, p2ptr); \
+ VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP5_PTR(op, p1, p2, p3, p4, size, p5ptr) \
+ VBOX_OGL_GEN_OP2PTR(op, p1, p2, p3, p4, size, p5ptr); \
+ VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP6_PTR(op, p1, p2, p3, p4, p5, size, p6ptr) \
+ VBOX_OGL_GEN_OP6PTR(op, p1, p2, p3, p4, p5, size, p6ptr); \
+ VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP7_PTR(op, p1, p2, p3, p4, p5, p6, size, p7ptr) \
+ VBOX_OGL_GEN_OP7PTR(op, p1, p2, p3, p4, p5, p6, size, p7ptr); \
+ VBoxOGLFlush();
+
+/* Sync operation whose last parameter is a block of memory in which results are returned */
+#define VBOX_OGL_GEN_SYNC_OP1_PASS_PTR(op, size, p1ptr) \
+ VBOX_OGL_GEN_OP(op); \
+ VBoxOGLFlushPtr(p1ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP2_PASS_PTR(op, p1, size, p2ptr) \
+ VBOX_OGL_GEN_OP1(op, p1); \
+ VBoxOGLFlushPtr(p2ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP3_PASS_PTR(op, p1, p2, size, p3ptr) \
+ VBOX_OGL_GEN_OP2(op, p1, p2); \
+ VBoxOGLFlushPtr(p3ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP4_PASS_PTR(op, p1, p2, p3, size, p4ptr) \
+ VBOX_OGL_GEN_OP3(op, p1, p2, p3); \
+ VBoxOGLFlushPtr(p4ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP5_PASS_PTR(op, p1, p2, p3, p4, size, p5ptr) \
+ VBOX_OGL_GEN_OP4(op, p1, p2, p3, p4); \
+ VBoxOGLFlushPtr(p5ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP6_PASS_PTR(op, p1, p2, p3, p4, p5, size, p6ptr) \
+ VBOX_OGL_GEN_OP5(op, p1, p2, p3, p4, p5); \
+ VBoxOGLFlushPtr(p6ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP7_PASS_PTR(op, p1, p2, p3, p4, p5, p6, size, p7ptr) \
+ VBOX_OGL_GEN_OP6(op, p1, p2, p3, p4, p5, p6); \
+ VBoxOGLFlushPtr(p7ptr, size);
+
+
+/* Sync operation whose last parameter is a block of memory and return a value */
+#define VBOX_OGL_GEN_SYNC_OP2_PTR_RET(rettype, op, p1, size, p2ptr) \
+ VBOX_OGL_GEN_OP2PTR(op, p1, size, p2ptr); \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP4_PTR_RET(rettype, op, p1, p2, p3, size, p4ptr) \
+ VBOX_OGL_GEN_OP4PTR(op, p1, p2, p3, size, p4ptr); \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP5_PTR_RET(rettype, op, p1, p2, p3, p4, size, p5ptr) \
+ VBOX_OGL_GEN_OP5PTR(op, p1, p2, p3, p4, size, p5ptr); \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP6_PTR_RET(rettype, op, p1, p2, p3, p4, p5, size, p6ptr) \
+ VBOX_OGL_GEN_OP6PTR(op, p1, p2, p3, p4, p5, size, p6ptr); \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+#define VBOX_OGL_GEN_SYNC_OP7_PTR_RET(rettype, op, p1, p2, p3, p4, p5, p6, size, p7ptr) \
+ VBOX_OGL_GEN_OP7PTR(op, p1, p2, p3, p4, p5, p6, size, p7ptr); \
+ rettype retval = (rettype)VBoxOGLFlush();
+
+
+/* Sync operation whose last parameter is a block of memory in which results are returned and return a value */
+#define VBOX_OGL_GEN_SYNC_OP2_PASS_PTR_RET(rettype, op, p1, size, p2ptr) \
+ VBOX_OGL_GEN_OP1(op, p1); \
+ rettype retval = (rettype)VBoxOGLFlushPtr(p2ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP4_PASS_PTR_RET(rettype, op, p1, p2, p3, size, p4ptr) \
+ VBOX_OGL_GEN_OP3(op, p1, p2, p3); \
+ rettype retval = (rettype)VBoxOGLFlushPtr(p4ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP5_PASS_PTR_RET(rettype, op, p1, p2, p3, p4, size, p5ptr) \
+ VBOX_OGL_GEN_OP4(op, p1, p2, p3, p4); \
+ rettype retval = (rettype)VBoxOGLFlushPtr(p5ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP6_PASS_PTR_RET(rettype, op, p1, p2, p3, p4, p5, size, p6ptr) \
+ VBOX_OGL_GEN_OP5(op, p1, p2, p3, p4, p5); \
+ rettype retval = (rettype)VBoxOGLFlushPtr(p6ptr, size);
+
+#define VBOX_OGL_GEN_SYNC_OP7_PASS_PTR_RET(rettype, op, p1, p2, p3, p4, p5, p6, size, p7ptr) \
+ VBOX_OGL_GEN_OP6(op, p1, p2, p3, p4, p5, p6); \
+ rettype retval = (rettype)VBoxOGLFlushPtr(p7ptr, size);
+
+
+/* Generate async functions elements in the command queue */
+#define GL_GEN_FUNC(Function) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (void) \
+ { \
+ VBOX_OGL_GEN_OP(Function); \
+ }
+
+#define GL_GEN_FUNC1(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a) \
+ { \
+ VBOX_OGL_GEN_OP1(Function, a); \
+ }
+
+#define GL_GEN_FUNC1V(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a) \
+ { \
+ VBOX_OGL_GEN_OP1(Function, a); \
+ } \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function)##v (const Type *v) \
+ { \
+ VBOX_OGL_GEN_OP1(Function, v[0]); \
+ } \
+
+#define GL_GEN_FUNC2(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a, Type b) \
+ { \
+ VBOX_OGL_GEN_OP2(Function, a, b); \
+ }
+
+#define GL_GEN_FUNC2V(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a, Type b) \
+ { \
+ VBOX_OGL_GEN_OP2(Function, a, b); \
+ } \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function)##v (const Type *v) \
+ { \
+ VBOX_OGL_GEN_OP2(Function, v[0], v[1]); \
+ } \
+
+#define GL_GEN_FUNC3(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a, Type b, Type c) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, a, b, c); \
+ }
+
+#define GL_GEN_FUNC3V(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a, Type b, Type c) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, a, b, c); \
+ } \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function)##v (const Type *v) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, v[0], v[1], v[2]); \
+ } \
+
+#define GL_GEN_FUNC4(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a, Type b, Type c, Type d) \
+ { \
+ VBOX_OGL_GEN_OP4(Function, a, b, c, d); \
+ }
+
+#define GL_GEN_FUNC4V(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a, Type b, Type c, Type d) \
+ { \
+ VBOX_OGL_GEN_OP4(Function, a, b, c, d); \
+ } \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function)##v (const Type *v) \
+ { \
+ VBOX_OGL_GEN_OP4(Function, v[0], v[1], v[2], v[3]); \
+ } \
+
+#define GL_GEN_FUNC6(Function, Type) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type a, Type b, Type c, Type d, Type e, Type f) \
+ { \
+ VBOX_OGL_GEN_OP6(Function, a, b, c, d, e, f); \
+ }
+
+#define GL_GEN_VPAR_FUNC2(Function, Type1, Type2) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b) \
+ { \
+ VBOX_OGL_GEN_OP2(Function, a, b); \
+ }
+
+#define GL_GEN_VPAR_FUNC2V(Function, Type1, Type2) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b) \
+ { \
+ VBOX_OGL_GEN_OP2(Function, a, b); \
+ } \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function)##v (Type1 a, const Type2 *v) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, a, v[0], v[1]); \
+ } \
+
+#define GL_GEN_VPAR_FUNC3(Function, Type1, Type2, Type3) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, a, b, c); \
+ }
+
+#define GL_GEN_VPAR_FUNC3V(Function, Type1, Type2, Type3) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, a, b, c); \
+ } \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function)##v (Type1 a, Type2 b, const Type3 *v) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, a, v[0], v[1]); \
+ } \
+
+#define GL_GEN_VPAR_FUNC4(Function, Type1, Type2, Type3, Type4) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c, Type4 d) \
+ { \
+ VBOX_OGL_GEN_OP4(Function, a, b, c, d); \
+ }
+
+#define GL_GEN_VPAR_FUNC5(Function, Type1, Type2, Type3, Type4, Type5) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c, Type4 d, Type5 e) \
+ { \
+ VBOX_OGL_GEN_OP5(Function, a, b, c, d, e); \
+ }
+
+#define GL_GEN_VPAR_FUNC6(Function, Type1, Type2, Type3, Type4, Type5, Type6) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c, Type4 d, Type5 e, Type6 f) \
+ { \
+ VBOX_OGL_GEN_OP6(Function, a, b, c, d, e, f); \
+ }
+
+#define GL_GEN_VPAR_FUNC7(Function, Type1, Type2, Type3, Type4, Type5, Type6, Type7) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c, Type4 d, Type5 e, Type6 f, Type7 g) \
+ { \
+ VBOX_OGL_GEN_OP7(Function, a, b, c, d, e, f, g); \
+ }
+
+#define GL_GEN_VPAR_FUNC8(Function, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c, Type4 d, Type5 e, Type6 f, Type7 g, Type8 h) \
+ { \
+ VBOX_OGL_GEN_OP8(Function, a, b, c, d, e, f, g, h); \
+ }
+
+#define GL_GEN_VPAR_FUNC9(Function, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8 ,Type9) \
+ void APIENTRY VBOX_OGL_NAME_PREFIX(Function) (Type1 a, Type2 b, Type3 c, Type4 d, Type5 e, Type6 f, Type7 g, Type8 h, Type9 i) \
+ { \
+ VBOX_OGL_GEN_OP9(Function, a, b, c, d, e, f, g, h, i); \
+ }
+
+#elif VBOX_OGL_HOST_SIDE
+
+/************************************************************************************************************
+ * Host side macro's for generating OpenGL function calls from the packed commands in the command buffer. *
+ * *
+ ************************************************************************************************************/
+
+#include <iprt/assert.h>
+
+#define VBOX_OGL_NAME_PREFIX(Function) vboxgl##Function
+
+#ifdef VBOX_OGL_CMD_STRICT
+#define VBOX_OGL_CHECK_MAGIC(pParVal) Assert(pParVal->Magic == VBOX_OGL_CMD_MAGIC)
+#else
+#define VBOX_OGL_CHECK_MAGIC(pParVal)
+#endif
+
+#define OGL_CMD(op, numpar) \
+ PVBOX_OGL_CMD pCmd = (PVBOX_OGL_CMD)pCmdBuffer; \
+ Assert(pCmd->enmOp == VBOX_OGL_OP_##op); \
+ Assert(pCmd->cParams == numpar); \
+ uint8_t *pParam = (uint8_t *)(pCmd+1); \
+ NOREF(pParam)
+
+#define OGL_PARAM(Type, par) \
+ Type par; \
+ par = *(Type *)pParam; \
+ pParam += sizeof(par); \
+ pParam = RT_ALIGN_PT(pParam, VBOX_OGL_CMD_ALIGN, uint8_t *);
+
+#define OGL_MEMPARAM(Type, par) \
+ PVBOX_OGL_VAR_PARAM pParVal = (PVBOX_OGL_VAR_PARAM)pParam; \
+ Type *par; \
+ VBOX_OGL_CHECK_MAGIC(pParVal); \
+ if (pParVal->cbParam) \
+ par = (Type *)(pParVal+1); \
+ else \
+ par = NULL; \
+ pParam += sizeof(*pParVal) + pParVal->cbParam; \
+ pParam = RT_ALIGN_PT(pParam, VBOX_OGL_CMD_ALIGN, uint8_t *);
+
+#define OGL_MEMPARAM_NODEF(Type, par) \
+ pParVal = (PVBOX_OGL_VAR_PARAM)pParam; \
+ Type *par; \
+ VBOX_OGL_CHECK_MAGIC(pParVal); \
+ if (pParVal->cbParam) \
+ par = (Type *)(pParVal+1); \
+ else \
+ par = NULL; \
+ pParam += sizeof(*pParVal) + pParVal->cbParam; \
+ pParam = RT_ALIGN_PT(pParam, VBOX_OGL_CMD_ALIGN, uint8_t *);
+
+#define VBOX_OGL_GEN_OP(op) \
+ OGL_CMD(op, 0); \
+ gl##op();
+
+#define VBOX_OGL_GEN_OP1(op, Type1) \
+ OGL_CMD(op, 1); \
+ OGL_PARAM(Type1, p1); \
+ gl##op(p1);
+
+#define VBOX_OGL_GEN_OP2(op, Type1, Type2) \
+ OGL_CMD(op, 2); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ gl##op(p1, p2);
+
+#define VBOX_OGL_GEN_OP3(op, Type1, Type2, Type3) \
+ OGL_CMD(op, 3); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ gl##op(p1, p2, p3);
+
+#define VBOX_OGL_GEN_OP4(op, Type1, Type2, Type3, Type4) \
+ OGL_CMD(op, 4); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ gl##op(p1, p2, p3, p4);
+
+#define VBOX_OGL_GEN_OP5(op, Type1, Type2, Type3, Type4, Type5) \
+ OGL_CMD(op, 5); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ gl##op(p1, p2, p3, p4, p5);
+
+#define VBOX_OGL_GEN_OP6(op, Type1, Type2, Type3, Type4, Type5, Type6) \
+ OGL_CMD(op, 6); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ gl##op(p1, p2, p3, p4, p5, p6);
+
+#define VBOX_OGL_GEN_OP7(op, Type1, Type2, Type3, Type4, Type5, Type6, Type7) \
+ OGL_CMD(op, 7); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ OGL_PARAM(Type7, p7); \
+ gl##op(p1, p2, p3, p4, p5, p6, p7);
+
+#define VBOX_OGL_GEN_OP8(op, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8) \
+ OGL_CMD(op, 8); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ OGL_PARAM(Type7, p7); \
+ OGL_PARAM(Type8, p8); \
+ gl##op(p1, p2, p3, p4, p5, p6, p7, p8);
+
+
+/* last parameter is a memory block */
+#define VBOX_OGL_GEN_OP1PTR(op, Type1) \
+ OGL_CMD(op, 1); \
+ OGL_MEMPARAM(Type1, p1); \
+ gl##op(p1);
+
+#define VBOX_OGL_GEN_OP2PTR(op, Type1, Type2) \
+ OGL_CMD(op, 2); \
+ OGL_PARAM(Type1, p1); \
+ OGL_MEMPARAM(Type2, p2); \
+ gl##op(p1, p2);
+
+#define VBOX_OGL_GEN_OP3PTR(op, Type1, Type2, Type3) \
+ OGL_CMD(op, 3); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_MEMPARAM(Type3, p3); \
+ gl##op(p1, p2, p3);
+
+#define VBOX_OGL_GEN_OP4PTR(op, Type1, Type2, Type3, Type4) \
+ OGL_CMD(op, 4); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_MEMPARAM(Type4, p4); \
+ gl##op(p1, p2, p3, p4);
+
+#define VBOX_OGL_GEN_OP5PTR(op, Type1, Type2, Type3, Type4, Type5) \
+ OGL_CMD(op, 5); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_MEMPARAM(Type5, p5); \
+ gl##op(p1, p2, p3, p4, p5);
+
+#define VBOX_OGL_GEN_OP6PTR(op, Type1, Type2, Type3, Type4, Type5, Type6) \
+ OGL_CMD(op, 6); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_MEMPARAM(Type6, p6); \
+ gl##op(p1, p2, p3, p4, p5, p6);
+
+#define VBOX_OGL_GEN_OP7PTR(op, Type1, Type2, Type3, Type4, Type5, Type6, Type7) \
+ OGL_CMD(op, 7); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ OGL_MEMPARAM(Type7, p7); \
+ gl##op(p1, p2, p3, p4, p5, p6, p7);
+
+#define VBOX_OGL_GEN_OP8PTR(op, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8) \
+ OGL_CMD(op, 8); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ OGL_PARAM(Type7, p7); \
+ OGL_MEMPARAM(Type8, p8); \
+ gl##op(p1, p2, p3, p4, p5, p6, p7, p8);
+
+#define VBOX_OGL_GEN_OP9PTR(op, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9) \
+ OGL_CMD(op, 9); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ OGL_PARAM(Type7, p7); \
+ OGL_PARAM(Type8, p8); \
+ OGL_MEMPARAM(Type9, p9); \
+ gl##op(p1, p2, p3, p4, p5, p6, p7, p8 ,p9);
+
+#define VBOX_OGL_GEN_OP10PTR(op, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9, Type10) \
+ OGL_CMD(op, 10); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ OGL_PARAM(Type7, p7); \
+ OGL_PARAM(Type8, p8); \
+ OGL_PARAM(Type9, p9); \
+ OGL_MEMPARAM(Type10, p10); \
+ gl##op(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+
+
+/* two memory blocks */
+#define VBOX_OGL_GEN_OP2PTRPTR(op, Type1, Type2) \
+ OGL_CMD(op, 2); \
+ OGL_MEMPARAM(Type1, p1); \
+ OGL_MEMPARAM_NODEF(Type2, p2); \
+ gl##op(p1, p2);
+
+#define VBOX_OGL_GEN_OP3PTRPTR(op, Type1, Type2, Type3) \
+ OGL_CMD(op, 3); \
+ OGL_PARAM(Type1, p1); \
+ OGL_MEMPARAM(Type2, p2); \
+ OGL_MEMPARAM_NODEF(Type3, p3); \
+ gl##op(p1, p2, p3);
+
+/* Note: sync operations always set the last error */
+/* sync operation that returns a value */
+#define VBOX_OGL_GEN_SYNC_OP_RET(rettype, op) \
+ OGL_CMD(op, 0); \
+ pClient->lastretval = gl##op();
+
+#define VBOX_OGL_GEN_SYNC_OP1_RET(rettype, op, Type1) \
+ OGL_CMD(op, 1); \
+ OGL_PARAM(Type1, p1); \
+ pClient->lastretval = gl##op(p1);
+
+#define VBOX_OGL_GEN_SYNC_OP2_RET(rettype, op, Type1, Type2) \
+ OGL_CMD(op, 2); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ pClient->lastretval = gl##op(p1, p2);
+
+#define VBOX_OGL_GEN_SYNC_OP3_RET(rettype, op, Type1, Type2, Type3) \
+ OGL_CMD(op, 3); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_MEMPARAM(Type3, p3); \
+ pClient->lastretval = gl##op(p1, p2, p3);
+
+#define VBOX_OGL_GEN_SYNC_OP(op) \
+ VBOX_OGL_GEN_OP(op);
+
+#define VBOX_OGL_GEN_SYNC_OP1(op, p1) \
+ VBOX_OGL_GEN_OP1(op, p1);
+
+#define VBOX_OGL_GEN_SYNC_OP2(op, p1, p2) \
+ VBOX_OGL_GEN_OP2(op, p1, p2);
+
+
+/* Sync operation whose last parameter is a block of memory */
+#define VBOX_OGL_GEN_SYNC_OP2_PTR(op, p1, p2ptr) \
+ VBOX_OGL_GEN_OP2PTR(op, p1, p2ptr);
+
+#define VBOX_OGL_GEN_SYNC_OP5_PTR(op, p1, p2, p3, p4, p5ptr) \
+ VBOX_OGL_GEN_OP2PTR(op, p1, p2, p3, p4, size, p5ptr);
+
+#define VBOX_OGL_GEN_SYNC_OP6_PTR(op, p1, p2, p3, p4, p5, p6ptr) \
+ VBOX_OGL_GEN_OP6PTR(op, p1, p2, p3, p4, p5, size, p6ptr);
+
+#define VBOX_OGL_GEN_SYNC_OP7_PTR(op, p1, p2, p3, p4, p5, p6, p7ptr) \
+ VBOX_OGL_GEN_OP7PTR(op, p1, p2, p3, p4, p5, p6, p7ptr);
+
+
+/* Sync operation whose last parameter is a block of memory in which results are returned */
+#define VBOX_OGL_GEN_SYNC_OP1_PASS_PTR(op, Type1) \
+ OGL_CMD(op, 0); \
+ Assert(pClient->pLastParam && pClient->cbLastParam); \
+ gl##op((Type1 *)pClient->pLastParam);
+
+#define VBOX_OGL_GEN_SYNC_OP2_PASS_PTR(op, Type1, Type2) \
+ OGL_CMD(op, 1); \
+ OGL_PARAM(Type1, p1); \
+ Assert(pClient->pLastParam && pClient->cbLastParam); \
+ gl##op(p1, (Type2 *)pClient->pLastParam);
+
+#define VBOX_OGL_GEN_SYNC_OP3_PASS_PTR(op, Type1, Type2, Type3) \
+ OGL_CMD(op, 2); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ Assert(pClient->pLastParam && pClient->cbLastParam); \
+ gl##op(p1, p2, (Type3 *)pClient->pLastParam);
+
+#define VBOX_OGL_GEN_SYNC_OP4_PASS_PTR(op, Type1, Type2, Type3, Type4) \
+ OGL_CMD(op, 3); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ Assert(pClient->pLastParam && pClient->cbLastParam); \
+ gl##op(p1, p2, p3, (Type4 *)pClient->pLastParam);
+
+#define VBOX_OGL_GEN_SYNC_OP5_PASS_PTR(op, Type1, Type2, Type3, Type4, Type5) \
+ OGL_CMD(op, 4); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ Assert(pClient->pLastParam && pClient->cbLastParam); \
+ gl##op(p1, p2, p3, p4, (Type5 *)pClient->pLastParam);
+
+#define VBOX_OGL_GEN_SYNC_OP6_PASS_PTR(op, Type1, Type2, Type3, Type4, Type5, Type6) \
+ OGL_CMD(op, 5); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ Assert(pClient->pLastParam && pClient->cbLastParam); \
+ gl##op(p1, p2, p3, p4, p5, (Type6 *)pClient->pLastParam);
+
+#define VBOX_OGL_GEN_SYNC_OP7_PASS_PTR(op, Type1, Type2, Type3, Type4, Type5, Type6, Type7) \
+ OGL_CMD(op, 6); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ Assert(pClient->pLastParam && pClient->cbLastParam); \
+ gl##op(p1, p2, p3, p4, p5, p6, (Type7 *)pClient->pLastParam);
+
+
+/* Sync operation whose last parameter is a block of memory and returns a value */
+#define VBOX_OGL_GEN_SYNC_OP2_PTR_RET(rettype, op, Type1, Type2) \
+ OGL_CMD(op, 2); \
+ OGL_PARAM(Type1, p1); \
+ OGL_MEMPARAM(Type2, p2); \
+ pClient->lastretval = gl##op(p1);
+
+#define VBOX_OGL_GEN_SYNC_OP4_PTR_RET(rettype, op, Type1, Type2, Type3, Type4) \
+ OGL_CMD(op, 4); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_MEMPARAM(Type4, p4); \
+ pClient->lastretval = gl##op(p1, p2, p3, p4);
+
+#define VBOX_OGL_GEN_SYNC_OP5_PTR_RET(rettype, op, Type1, Type2, Type3, Type4, Type5) \
+ OGL_CMD(op, 5); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_MEMPARAM(Type5, p5); \
+ pClient->lastretval = gl##op(p1, p2, p3, p4, p5);
+
+#define VBOX_OGL_GEN_SYNC_OP6_PTR_RET(rettype, op, Type1, Type2, Type3, Type4, Type5, Type6) \
+ OGL_CMD(op, 6); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_MEMPARAM(Type6, p6); \
+ pClient->lastretval = gl##op(p1, p2, p3, p4, p5, p6);
+
+#define VBOX_OGL_GEN_SYNC_OP7_PTR_RET(rettype, op, Type1, Type2, Type3, Type4, Type5, Type6, Type7) \
+ OGL_CMD(op, 7); \
+ OGL_PARAM(Type1, p1); \
+ OGL_PARAM(Type2, p2); \
+ OGL_PARAM(Type3, p3); \
+ OGL_PARAM(Type4, p4); \
+ OGL_PARAM(Type5, p5); \
+ OGL_PARAM(Type6, p6); \
+ OGL_MEMPARAM(Type7, p7); \
+ pClient->lastretval = gl##op(p1, p2, p3, p4, p5, p6, p7);
+
+
+
+
+
+/* Generate async functions elements in the command queue */
+#define GL_GEN_FUNC(Function) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP(Function); \
+ }
+
+#define GL_GEN_FUNC1(Function, Type) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP1(Function, Type); \
+ }
+
+#define GL_GEN_FUNC1V(Function, Type) GL_GEN_FUNC1(Function, Type)
+
+#define GL_GEN_FUNC2(Function, Type) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP2(Function, Type, Type); \
+ }
+
+#define GL_GEN_FUNC2V(Function, Type) GL_GEN_FUNC2(Function, Type)
+
+#define GL_GEN_FUNC3(Function, Type) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, Type, Type, Type); \
+ }
+
+#define GL_GEN_FUNC3V(Function, Type) GL_GEN_FUNC3(Function, Type)
+
+#define GL_GEN_FUNC4(Function, Type) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP4(Function, Type, Type, Type, Type); \
+ }
+
+#define GL_GEN_FUNC4V(Function, Type) GL_GEN_FUNC4(Function, Type)
+
+#define GL_GEN_FUNC6(Function, Type) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP6(Function, Type, Type, Type, Type, Type, Type); \
+ }
+
+#define GL_GEN_VPAR_FUNC2(Function, Type1, Type2) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP2(Function, Type1, Type2); \
+ }
+
+#define GL_GEN_VPAR_FUNC2V(Function, Type) GL_GEN_VPAR_FUNC2(Function, Type)
+
+#define GL_GEN_VPAR_FUNC3(Function, Type1, Type2, Type3) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP3(Function, Type1, Type2, Type3); \
+ }
+
+#define GL_GEN_VPAR_FUNC3V(Function, Type) GL_GEN_VPAR_FUNC3(Function, Type)
+
+#define GL_GEN_VPAR_FUNC4(Function, Type1, Type2, Type3, Type4) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP4(Function, Type1, Type2, Type3, Type4); \
+ }
+
+#define GL_GEN_VPAR_FUNC5(Function, Type1, Type2, Type3, Type4, Type5) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP5(Function, Type1, Type2, Type3, Type4 ,Type5); \
+ }
+
+#define GL_GEN_VPAR_FUNC6(Function, Type1, Type2, Type3, Type4, Type5, Type6) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP6(Function, Type1, Type2, Type3, Type4 ,Type5, Type6); \
+ }
+
+#define GL_GEN_VPAR_FUNC7(Function, Type1, Type2, Type3, Type4, Type5, Type6, Type7) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP7(Function, Type1, Type2, Type3, Type4 ,Type5, Type6, Type7); \
+ }
+
+#define GL_GEN_VPAR_FUNC8(Function, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP8(Function, Type1, Type2, Type3, Type4 ,Type5, Type6, Type7, Type8); \
+ }
+
+#define GL_GEN_VPAR_FUNC9(Function, Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8 ,Type9) \
+ void VBOX_OGL_NAME_PREFIX(Function) (VBOXOGLCTX *pClient, uint8_t *pCmdBuffer) \
+ { \
+ VBOX_OGL_GEN_OP9(Function, Type1, Type2, Type3, Type4 ,Type5, Type6, Type7, Type8, Type9); \
+ }
+
+#endif /* VBOX_OGL_HOST_SIDE */
+
+
+
+
+/* OpenGL opcodes */
+/* Note: keep all three tables in sync! */
+typedef enum
+{
+ VBOX_OGL_OP_Illegal = 0,
+ VBOX_OGL_OP_ArrayElement,
+ VBOX_OGL_OP_Begin,
+ VBOX_OGL_OP_BindTexture,
+ VBOX_OGL_OP_BlendFunc,
+ VBOX_OGL_OP_CallList,
+ VBOX_OGL_OP_Color3b,
+ VBOX_OGL_OP_Color3d,
+ VBOX_OGL_OP_Color3f,
+ VBOX_OGL_OP_Color3i,
+ VBOX_OGL_OP_Color3s,
+ VBOX_OGL_OP_Color3ub,
+ VBOX_OGL_OP_Color3ui,
+ VBOX_OGL_OP_Color3us,
+ VBOX_OGL_OP_Color4b,
+ VBOX_OGL_OP_Color4d,
+ VBOX_OGL_OP_Color4f,
+ VBOX_OGL_OP_Color4i,
+ VBOX_OGL_OP_Color4s,
+ VBOX_OGL_OP_Color4ub,
+ VBOX_OGL_OP_Color4ui,
+ VBOX_OGL_OP_Color4us,
+ VBOX_OGL_OP_Clear,
+ VBOX_OGL_OP_ClearAccum,
+ VBOX_OGL_OP_ClearColor,
+ VBOX_OGL_OP_ClearDepth,
+ VBOX_OGL_OP_ClearIndex,
+ VBOX_OGL_OP_ClearStencil,
+ VBOX_OGL_OP_Accum,
+ VBOX_OGL_OP_AlphaFunc,
+ VBOX_OGL_OP_Vertex2d,
+ VBOX_OGL_OP_Vertex2f,
+ VBOX_OGL_OP_Vertex2i,
+ VBOX_OGL_OP_Vertex2s,
+ VBOX_OGL_OP_Vertex3d,
+ VBOX_OGL_OP_Vertex3f,
+ VBOX_OGL_OP_Vertex3i,
+ VBOX_OGL_OP_Vertex3s,
+ VBOX_OGL_OP_Vertex4d,
+ VBOX_OGL_OP_Vertex4f,
+ VBOX_OGL_OP_Vertex4i,
+ VBOX_OGL_OP_Vertex4s,
+ VBOX_OGL_OP_TexCoord1d,
+ VBOX_OGL_OP_TexCoord1f,
+ VBOX_OGL_OP_TexCoord1i,
+ VBOX_OGL_OP_TexCoord1s,
+ VBOX_OGL_OP_TexCoord2d,
+ VBOX_OGL_OP_TexCoord2f,
+ VBOX_OGL_OP_TexCoord2i,
+ VBOX_OGL_OP_TexCoord2s,
+ VBOX_OGL_OP_TexCoord3d,
+ VBOX_OGL_OP_TexCoord3f,
+ VBOX_OGL_OP_TexCoord3i,
+ VBOX_OGL_OP_TexCoord3s,
+ VBOX_OGL_OP_TexCoord4d,
+ VBOX_OGL_OP_TexCoord4f,
+ VBOX_OGL_OP_TexCoord4i,
+ VBOX_OGL_OP_TexCoord4s,
+ VBOX_OGL_OP_Normal3b,
+ VBOX_OGL_OP_Normal3d,
+ VBOX_OGL_OP_Normal3f,
+ VBOX_OGL_OP_Normal3i,
+ VBOX_OGL_OP_Normal3s,
+ VBOX_OGL_OP_RasterPos2d,
+ VBOX_OGL_OP_RasterPos2f,
+ VBOX_OGL_OP_RasterPos2i,
+ VBOX_OGL_OP_RasterPos2s,
+ VBOX_OGL_OP_RasterPos3d,
+ VBOX_OGL_OP_RasterPos3f,
+ VBOX_OGL_OP_RasterPos3i,
+ VBOX_OGL_OP_RasterPos3s,
+ VBOX_OGL_OP_RasterPos4d,
+ VBOX_OGL_OP_RasterPos4f,
+ VBOX_OGL_OP_RasterPos4i,
+ VBOX_OGL_OP_RasterPos4s,
+ VBOX_OGL_OP_EvalCoord1d,
+ VBOX_OGL_OP_EvalCoord1f,
+ VBOX_OGL_OP_EvalCoord2d,
+ VBOX_OGL_OP_EvalCoord2f,
+ VBOX_OGL_OP_EvalPoint1,
+ VBOX_OGL_OP_EvalPoint2,
+ VBOX_OGL_OP_Indexd,
+ VBOX_OGL_OP_Indexf,
+ VBOX_OGL_OP_Indexi,
+ VBOX_OGL_OP_Indexs,
+ VBOX_OGL_OP_Indexub,
+ VBOX_OGL_OP_Rotated,
+ VBOX_OGL_OP_Rotatef,
+ VBOX_OGL_OP_Scaled,
+ VBOX_OGL_OP_Scalef,
+ VBOX_OGL_OP_Translated,
+ VBOX_OGL_OP_Translatef,
+ VBOX_OGL_OP_DepthFunc,
+ VBOX_OGL_OP_DepthMask,
+ VBOX_OGL_OP_Finish,
+ VBOX_OGL_OP_Flush,
+ VBOX_OGL_OP_DeleteLists,
+ VBOX_OGL_OP_CullFace,
+ VBOX_OGL_OP_DeleteTextures,
+ VBOX_OGL_OP_DepthRange,
+ VBOX_OGL_OP_DisableClientState,
+ VBOX_OGL_OP_EnableClientState,
+ VBOX_OGL_OP_EvalMesh1,
+ VBOX_OGL_OP_EvalMesh2,
+ VBOX_OGL_OP_Fogf,
+ VBOX_OGL_OP_Fogfv,
+ VBOX_OGL_OP_Fogi,
+ VBOX_OGL_OP_Fogiv,
+ VBOX_OGL_OP_LightModelf,
+ VBOX_OGL_OP_LightModelfv,
+ VBOX_OGL_OP_LightModeli,
+ VBOX_OGL_OP_LightModeliv,
+ VBOX_OGL_OP_Lightf,
+ VBOX_OGL_OP_Lightfv,
+ VBOX_OGL_OP_Lighti,
+ VBOX_OGL_OP_Lightiv,
+ VBOX_OGL_OP_LineStipple,
+ VBOX_OGL_OP_LineWidth,
+ VBOX_OGL_OP_ListBase,
+ VBOX_OGL_OP_DrawArrays,
+ VBOX_OGL_OP_DrawBuffer,
+ VBOX_OGL_OP_EdgeFlag,
+ VBOX_OGL_OP_End,
+ VBOX_OGL_OP_EndList,
+ VBOX_OGL_OP_CopyTexImage1D,
+ VBOX_OGL_OP_CopyTexImage2D,
+ VBOX_OGL_OP_ColorMaterial,
+ VBOX_OGL_OP_Materiali,
+ VBOX_OGL_OP_Materialf,
+ VBOX_OGL_OP_Materialfv,
+ VBOX_OGL_OP_Materialiv,
+ VBOX_OGL_OP_PopAttrib,
+ VBOX_OGL_OP_PopClientAttrib,
+ VBOX_OGL_OP_PopMatrix,
+ VBOX_OGL_OP_PopName,
+ VBOX_OGL_OP_PushAttrib,
+ VBOX_OGL_OP_PushClientAttrib,
+ VBOX_OGL_OP_PushMatrix,
+ VBOX_OGL_OP_PushName,
+ VBOX_OGL_OP_ReadBuffer,
+ VBOX_OGL_OP_TexGendv,
+ VBOX_OGL_OP_TexGenf,
+ VBOX_OGL_OP_TexGend,
+ VBOX_OGL_OP_TexGeni,
+ VBOX_OGL_OP_TexEnvi,
+ VBOX_OGL_OP_TexEnvf,
+ VBOX_OGL_OP_TexEnviv,
+ VBOX_OGL_OP_TexEnvfv,
+ VBOX_OGL_OP_TexGeniv,
+ VBOX_OGL_OP_TexGenfv,
+ VBOX_OGL_OP_TexParameterf,
+ VBOX_OGL_OP_TexParameteri,
+ VBOX_OGL_OP_TexParameterfv,
+ VBOX_OGL_OP_TexParameteriv,
+ VBOX_OGL_OP_LoadIdentity,
+ VBOX_OGL_OP_LoadName,
+ VBOX_OGL_OP_LoadMatrixd,
+ VBOX_OGL_OP_LoadMatrixf,
+ VBOX_OGL_OP_StencilFunc,
+ VBOX_OGL_OP_ShadeModel,
+ VBOX_OGL_OP_StencilMask,
+ VBOX_OGL_OP_StencilOp,
+ VBOX_OGL_OP_Scissor,
+ VBOX_OGL_OP_Viewport,
+ VBOX_OGL_OP_Rectd,
+ VBOX_OGL_OP_Rectf,
+ VBOX_OGL_OP_Recti,
+ VBOX_OGL_OP_Rects,
+ VBOX_OGL_OP_Rectdv,
+ VBOX_OGL_OP_Rectfv,
+ VBOX_OGL_OP_Rectiv,
+ VBOX_OGL_OP_Rectsv,
+ VBOX_OGL_OP_MultMatrixd,
+ VBOX_OGL_OP_MultMatrixf,
+ VBOX_OGL_OP_NewList,
+ VBOX_OGL_OP_Hint,
+ VBOX_OGL_OP_IndexMask,
+ VBOX_OGL_OP_InitNames,
+ VBOX_OGL_OP_TexCoordPointer,
+ VBOX_OGL_OP_VertexPointer,
+ VBOX_OGL_OP_ColorPointer,
+ VBOX_OGL_OP_EdgeFlagPointer,
+ VBOX_OGL_OP_IndexPointer,
+ VBOX_OGL_OP_NormalPointer,
+ VBOX_OGL_OP_PolygonStipple,
+ VBOX_OGL_OP_CallLists,
+ VBOX_OGL_OP_ClipPlane,
+ VBOX_OGL_OP_Frustum,
+ VBOX_OGL_OP_GenTextures,
+ VBOX_OGL_OP_Map1d,
+ VBOX_OGL_OP_Map1f,
+ VBOX_OGL_OP_Map2d,
+ VBOX_OGL_OP_Map2f,
+ VBOX_OGL_OP_MapGrid1d,
+ VBOX_OGL_OP_MapGrid1f,
+ VBOX_OGL_OP_MapGrid2d,
+ VBOX_OGL_OP_MapGrid2f,
+ VBOX_OGL_OP_CopyPixels,
+ VBOX_OGL_OP_TexImage1D,
+ VBOX_OGL_OP_TexImage2D,
+ VBOX_OGL_OP_TexSubImage1D,
+ VBOX_OGL_OP_TexSubImage2D,
+ VBOX_OGL_OP_FeedbackBuffer,
+ VBOX_OGL_OP_SelectBuffer,
+ VBOX_OGL_OP_IsList,
+ VBOX_OGL_OP_IsTexture,
+ VBOX_OGL_OP_RenderMode,
+ VBOX_OGL_OP_ReadPixels,
+ VBOX_OGL_OP_IsEnabled,
+ VBOX_OGL_OP_GenLists,
+ VBOX_OGL_OP_PixelTransferf,
+ VBOX_OGL_OP_PixelTransferi,
+ VBOX_OGL_OP_PixelZoom,
+ VBOX_OGL_OP_PixelStorei,
+ VBOX_OGL_OP_PixelStoref,
+ VBOX_OGL_OP_PixelMapfv,
+ VBOX_OGL_OP_PixelMapuiv,
+ VBOX_OGL_OP_PixelMapusv,
+ VBOX_OGL_OP_PointSize,
+ VBOX_OGL_OP_PolygonMode,
+ VBOX_OGL_OP_PolygonOffset,
+ VBOX_OGL_OP_PassThrough,
+ VBOX_OGL_OP_Ortho,
+ VBOX_OGL_OP_MatrixMode,
+ VBOX_OGL_OP_LogicOp,
+ VBOX_OGL_OP_ColorMask,
+ VBOX_OGL_OP_CopyTexSubImage1D,
+ VBOX_OGL_OP_CopyTexSubImage2D,
+ VBOX_OGL_OP_FrontFace,
+ VBOX_OGL_OP_Disable,
+ VBOX_OGL_OP_Enable,
+ VBOX_OGL_OP_PrioritizeTextures,
+ VBOX_OGL_OP_GetBooleanv,
+ VBOX_OGL_OP_GetDoublev,
+ VBOX_OGL_OP_GetFloatv,
+ VBOX_OGL_OP_GetIntegerv,
+ VBOX_OGL_OP_GetLightfv,
+ VBOX_OGL_OP_GetLightiv,
+ VBOX_OGL_OP_GetMaterialfv,
+ VBOX_OGL_OP_GetMaterialiv,
+ VBOX_OGL_OP_GetPixelMapfv,
+ VBOX_OGL_OP_GetPixelMapuiv,
+ VBOX_OGL_OP_GetPixelMapusv,
+ VBOX_OGL_OP_GetTexEnviv,
+ VBOX_OGL_OP_GetTexEnvfv,
+ VBOX_OGL_OP_GetTexGendv,
+ VBOX_OGL_OP_GetTexGenfv,
+ VBOX_OGL_OP_GetTexGeniv,
+ VBOX_OGL_OP_GetTexParameterfv,
+ VBOX_OGL_OP_GetTexParameteriv,
+ VBOX_OGL_OP_GetClipPlane,
+ VBOX_OGL_OP_GetPolygonStipple,
+ VBOX_OGL_OP_GetTexLevelParameterfv,
+ VBOX_OGL_OP_GetTexLevelParameteriv,
+ VBOX_OGL_OP_GetTexImage,
+
+ /* Windows ICD exports */
+ VBOX_OGL_OP_DrvReleaseContext,
+ VBOX_OGL_OP_DrvCreateContext,
+ VBOX_OGL_OP_DrvDeleteContext,
+ VBOX_OGL_OP_DrvCopyContext,
+ VBOX_OGL_OP_DrvSetContext,
+ VBOX_OGL_OP_DrvCreateLayerContext,
+ VBOX_OGL_OP_DrvShareLists,
+ VBOX_OGL_OP_DrvDescribeLayerPlane,
+ VBOX_OGL_OP_DrvSetLayerPaletteEntries,
+ VBOX_OGL_OP_DrvGetLayerPaletteEntries,
+ VBOX_OGL_OP_DrvRealizeLayerPalette,
+ VBOX_OGL_OP_DrvSwapLayerBuffers,
+ VBOX_OGL_OP_DrvDescribePixelFormat,
+ VBOX_OGL_OP_DrvSetPixelFormat,
+ VBOX_OGL_OP_DrvSwapBuffers,
+
+ /* OpenGL Extensions */
+ VBOX_OGL_OP_wglSwapIntervalEXT,
+ VBOX_OGL_OP_wglGetSwapIntervalEXT,
+
+ VBOX_OGL_OP_Last,
+
+ VBOX_OGL_OP_SizeHack = 0x7fffffff
+} VBOX_OGL_OP;
+
+#if defined(DEBUG) && defined(VBOX_OGL_WITH_CMD_STRINGS)
+static const char *pszVBoxOGLCmd[VBOX_OGL_OP_Last] =
+{
+ "ILLEGAL",
+ "glArrayElement",
+ "glBegin",
+ "glBindTexture",
+ "glBlendFunc",
+ "glCallList",
+ "glColor3b",
+ "glColor3d",
+ "glColor3f",
+ "glColor3i",
+ "glColor3s",
+ "glColor3ub",
+ "glColor3ui",
+ "glColor3us",
+ "glColor4b",
+ "glColor4d",
+ "glColor4f",
+ "glColor4i",
+ "glColor4s",
+ "glColor4ub",
+ "glColor4ui",
+ "glColor4us",
+ "glClear",
+ "glClearAccum",
+ "glClearColor",
+ "glClearDepth",
+ "glClearIndex",
+ "glClearStencil",
+ "glAccum",
+ "glAlphaFunc",
+ "glVertex2d",
+ "glVertex2f",
+ "glVertex2i",
+ "glVertex2s",
+ "glVertex3d",
+ "glVertex3f",
+ "glVertex3i",
+ "glVertex3s",
+ "glVertex4d",
+ "glVertex4f",
+ "glVertex4i",
+ "glVertex4s",
+ "glTexCoord1d",
+ "glTexCoord1f",
+ "glTexCoord1i",
+ "glTexCoord1s",
+ "glTexCoord2d",
+ "glTexCoord2f",
+ "glTexCoord2i",
+ "glTexCoord2s",
+ "glTexCoord3d",
+ "glTexCoord3f",
+ "glTexCoord3i",
+ "glTexCoord3s",
+ "glTexCoord4d",
+ "glTexCoord4f",
+ "glTexCoord4i",
+ "glTexCoord4s",
+ "glNormal3b",
+ "glNormal3d",
+ "glNormal3f",
+ "glNormal3i",
+ "glNormal3s",
+ "glRasterPos2d",
+ "glRasterPos2f",
+ "glRasterPos2i",
+ "glRasterPos2s",
+ "glRasterPos3d",
+ "glRasterPos3f",
+ "glRasterPos3i",
+ "glRasterPos3s",
+ "glRasterPos4d",
+ "glRasterPos4f",
+ "glRasterPos4i",
+ "glRasterPos4s",
+ "glEvalCoord1d",
+ "glEvalCoord1f",
+ "glEvalCoord2d",
+ "glEvalCoord2f",
+ "glEvalPoint1",
+ "glEvalPoint2",
+ "glIndexd",
+ "glIndexf",
+ "glIndexi",
+ "glIndexs",
+ "glIndexub",
+ "glRotated",
+ "glRotatef",
+ "glScaled",
+ "glScalef",
+ "glTranslated",
+ "glTranslatef",
+ "glDepthFunc",
+ "glDepthMask",
+ "glFinish",
+ "glFlush",
+ "glDeleteLists",
+ "glCullFace",
+ "glDeleteTextures",
+ "glDepthRange",
+ "glDisableClientState",
+ "glEnableClientState",
+ "glEvalMesh1",
+ "glEvalMesh2",
+ "glFogf",
+ "glFogfv",
+ "glFogi",
+ "glFogiv",
+ "glLightModelf",
+ "glLightModelfv",
+ "glLightModeli",
+ "glLightModeliv",
+ "glLightf",
+ "glLightfv",
+ "glLighti",
+ "glLightiv",
+ "glLineStipple",
+ "glLineWidth",
+ "glListBase",
+ "glDrawArrays",
+ "glDrawBuffer",
+ "glEdgeFlag",
+ "glEnd",
+ "glEndList",
+ "glCopyTexImage1D",
+ "glCopyTexImage2D",
+ "glColorMaterial",
+ "glMateriali",
+ "glMaterialf",
+ "glMaterialfv",
+ "glMaterialiv",
+ "glPopAttrib",
+ "glPopClientAttrib",
+ "glPopMatrix",
+ "glPopName",
+ "glPushAttrib",
+ "glPushClientAttrib",
+ "glPushMatrix",
+ "glPushName",
+ "glReadBuffer",
+ "glTexGendv",
+ "glTexGenf",
+ "glTexGend",
+ "glTexGeni",
+ "glTexEnvi",
+ "glTexEnvf",
+ "glTexEnviv",
+ "glTexEnvfv",
+ "glTexGeniv",
+ "glTexGenfv",
+ "glTexParameterf",
+ "glTexParameteri",
+ "glTexParameterfv",
+ "glTexParameteriv",
+ "glLoadIdentity",
+ "glLoadName",
+ "glLoadMatrixd",
+ "glLoadMatrixf",
+ "glStencilFunc",
+ "glShadeModel",
+ "glStencilMask",
+ "glStencilOp",
+ "glScissor",
+ "glViewport",
+ "glRectd",
+ "glRectf",
+ "glRecti",
+ "glRects",
+ "glRectdv",
+ "glRectfv",
+ "glRectiv",
+ "glRectsv",
+ "glMultMatrixd",
+ "glMultMatrixf",
+ "glNewList",
+ "glHint",
+ "glIndexMask",
+ "glInitNames",
+ "glTexCoordPointer",
+ "glVertexPointer",
+ "glColorPointer",
+ "glEdgeFlagPointer",
+ "glIndexPointer",
+ "glNormalPointer",
+ "glPolygonStipple",
+ "glCallLists",
+ "glClipPlane",
+ "glFrustum",
+ "glGenTextures",
+ "glMap1d",
+ "glMap1f",
+ "glMap2d",
+ "glMap2f",
+ "glMapGrid1d",
+ "glMapGrid1f",
+ "glMapGrid2d",
+ "glMapGrid2f",
+ "glCopyPixels",
+ "glTexImage1D",
+ "glTexImage2D",
+ "glTexSubImage1D",
+ "glTexSubImage2D",
+ "glFeedbackBuffer",
+ "glSelectBuffer",
+ "glIsList",
+ "glIsTexture",
+ "glRenderMode",
+ "glReadPixels",
+ "glIsEnabled",
+ "glGenLists",
+ "glPixelTransferf",
+ "glPixelTransferi",
+ "glPixelZoom",
+ "glPixelStorei",
+ "glPixelStoref",
+ "glPixelMapfv",
+ "glPixelMapuiv",
+ "glPixelMapusv",
+ "glPointSize",
+ "glPolygonMode",
+ "glPolygonOffset",
+ "glPassThrough",
+ "glOrtho",
+ "glMatrixMode",
+ "glLogicOp",
+ "glColorMask",
+ "glCopyTexSubImage1D",
+ "glCopyTexSubImage2D",
+ "glFrontFace",
+ "glDisable",
+ "glEnable",
+ "glPrioritizeTextures",
+ "glGetBooleanv",
+ "glGetDoublev",
+ "glGetFloatv",
+ "glGetIntegerv",
+ "glGetLightfv",
+ "glGetLightiv",
+ "glGetMaterialfv",
+ "glGetMaterialiv",
+ "glGetPixelMapfv",
+ "glGetPixelMapuiv",
+ "glGetPixelMapusv",
+ "glGetTexEnviv",
+ "glGetTexEnvfv",
+ "glGetTexGendv",
+ "glGetTexGenfv",
+ "glGetTexGeniv",
+ "glGetTexParameterfv",
+ "glGetTexParameteriv",
+ "glGetClipPlane",
+ "glGetPolygonStipple",
+ "glGetTexLevelParameterfv",
+ "glGetTexLevelParameteriv",
+ "glGetTexImage",
+
+ /* Windows ICD exports */
+ "DrvReleaseContext",
+ "DrvCreateContext",
+ "DrvDeleteContext",
+ "DrvCopyContext",
+ "DrvSetContext",
+ "DrvCreateLayerContext",
+ "DrvShareLists",
+ "DrvDescribeLayerPlane",
+ "DrvSetLayerPaletteEntries",
+ "DrvGetLayerPaletteEntries",
+ "DrvRealizeLayerPalette",
+ "DrvSwapLayerBuffers",
+ "DrvDescribePixelFormat",
+ "DrvSetPixelFormat",
+ "DrvSwapBuffers",
+
+ /* OpenGL Extensions */
+ "wglSwapIntervalEXT",
+ "wglGetSwapIntervalEXT",
+};
+#endif
+
+#ifdef VBOX_OGL_WITH_FUNCTION_WRAPPERS
+/* OpenGL function wrappers. */
+static PFN_VBOXGLWRAPPER pfnOGLWrapper[VBOX_OGL_OP_Last] =
+{
+ NULL,
+ vboxglArrayElement,
+ vboxglBegin,
+ vboxglBindTexture,
+ vboxglBlendFunc,
+ vboxglCallList,
+ vboxglColor3b,
+ vboxglColor3d,
+ vboxglColor3f,
+ vboxglColor3i,
+ vboxglColor3s,
+ vboxglColor3ub,
+ vboxglColor3ui,
+ vboxglColor3us,
+ vboxglColor4b,
+ vboxglColor4d,
+ vboxglColor4f,
+ vboxglColor4i,
+ vboxglColor4s,
+ vboxglColor4ub,
+ vboxglColor4ui,
+ vboxglColor4us,
+ vboxglClear,
+ vboxglClearAccum,
+ vboxglClearColor,
+ vboxglClearDepth,
+ vboxglClearIndex,
+ vboxglClearStencil,
+ vboxglAccum,
+ vboxglAlphaFunc,
+ vboxglVertex2d,
+ vboxglVertex2f,
+ vboxglVertex2i,
+ vboxglVertex2s,
+ vboxglVertex3d,
+ vboxglVertex3f,
+ vboxglVertex3i,
+ vboxglVertex3s,
+ vboxglVertex4d,
+ vboxglVertex4f,
+ vboxglVertex4i,
+ vboxglVertex4s,
+ vboxglTexCoord1d,
+ vboxglTexCoord1f,
+ vboxglTexCoord1i,
+ vboxglTexCoord1s,
+ vboxglTexCoord2d,
+ vboxglTexCoord2f,
+ vboxglTexCoord2i,
+ vboxglTexCoord2s,
+ vboxglTexCoord3d,
+ vboxglTexCoord3f,
+ vboxglTexCoord3i,
+ vboxglTexCoord3s,
+ vboxglTexCoord4d,
+ vboxglTexCoord4f,
+ vboxglTexCoord4i,
+ vboxglTexCoord4s,
+ vboxglNormal3b,
+ vboxglNormal3d,
+ vboxglNormal3f,
+ vboxglNormal3i,
+ vboxglNormal3s,
+ vboxglRasterPos2d,
+ vboxglRasterPos2f,
+ vboxglRasterPos2i,
+ vboxglRasterPos2s,
+ vboxglRasterPos3d,
+ vboxglRasterPos3f,
+ vboxglRasterPos3i,
+ vboxglRasterPos3s,
+ vboxglRasterPos4d,
+ vboxglRasterPos4f,
+ vboxglRasterPos4i,
+ vboxglRasterPos4s,
+ vboxglEvalCoord1d,
+ vboxglEvalCoord1f,
+ vboxglEvalCoord2d,
+ vboxglEvalCoord2f,
+ vboxglEvalPoint1,
+ vboxglEvalPoint2,
+ vboxglIndexd,
+ vboxglIndexf,
+ vboxglIndexi,
+ vboxglIndexs,
+ vboxglIndexub,
+ vboxglRotated,
+ vboxglRotatef,
+ vboxglScaled,
+ vboxglScalef,
+ vboxglTranslated,
+ vboxglTranslatef,
+ vboxglDepthFunc,
+ vboxglDepthMask,
+ vboxglFinish,
+ vboxglFlush,
+ vboxglDeleteLists,
+ vboxglCullFace,
+ vboxglDeleteTextures,
+ vboxglDepthRange,
+ vboxglDisableClientState,
+ vboxglEnableClientState,
+ vboxglEvalMesh1,
+ vboxglEvalMesh2,
+ vboxglFogf,
+ vboxglFogfv,
+ vboxglFogi,
+ vboxglFogiv,
+ vboxglLightModelf,
+ vboxglLightModelfv,
+ vboxglLightModeli,
+ vboxglLightModeliv,
+ vboxglLightf,
+ vboxglLightfv,
+ vboxglLighti,
+ vboxglLightiv,
+ vboxglLineStipple,
+ vboxglLineWidth,
+ vboxglListBase,
+ vboxglDrawArrays,
+ vboxglDrawBuffer,
+ vboxglEdgeFlag,
+ vboxglEnd,
+ vboxglEndList,
+ vboxglCopyTexImage1D,
+ vboxglCopyTexImage2D,
+ vboxglColorMaterial,
+ vboxglMateriali,
+ vboxglMaterialf,
+ vboxglMaterialfv,
+ vboxglMaterialiv,
+ vboxglPopAttrib,
+ vboxglPopClientAttrib,
+ vboxglPopMatrix,
+ vboxglPopName,
+ vboxglPushAttrib,
+ vboxglPushClientAttrib,
+ vboxglPushMatrix,
+ vboxglPushName,
+ vboxglReadBuffer,
+ vboxglTexGendv,
+ vboxglTexGenf,
+ vboxglTexGend,
+ vboxglTexGeni,
+ vboxglTexEnvi,
+ vboxglTexEnvf,
+ vboxglTexEnviv,
+ vboxglTexEnvfv,
+ vboxglTexGeniv,
+ vboxglTexGenfv,
+ vboxglTexParameterf,
+ vboxglTexParameteri,
+ vboxglTexParameterfv,
+ vboxglTexParameteriv,
+ vboxglLoadIdentity,
+ vboxglLoadName,
+ vboxglLoadMatrixd,
+ vboxglLoadMatrixf,
+ vboxglStencilFunc,
+ vboxglShadeModel,
+ vboxglStencilMask,
+ vboxglStencilOp,
+ vboxglScissor,
+ vboxglViewport,
+ vboxglRectd,
+ vboxglRectf,
+ vboxglRecti,
+ vboxglRects,
+ vboxglRectdv,
+ vboxglRectfv,
+ vboxglRectiv,
+ vboxglRectsv,
+ vboxglMultMatrixd,
+ vboxglMultMatrixf,
+ vboxglNewList,
+ vboxglHint,
+ vboxglIndexMask,
+ vboxglInitNames,
+ vboxglTexCoordPointer,
+ vboxglVertexPointer,
+ vboxglColorPointer,
+ vboxglEdgeFlagPointer,
+ vboxglIndexPointer,
+ vboxglNormalPointer,
+ vboxglPolygonStipple,
+ vboxglCallLists,
+ vboxglClipPlane,
+ vboxglFrustum,
+ vboxglGenTextures,
+ vboxglMap1d,
+ vboxglMap1f,
+ vboxglMap2d,
+ vboxglMap2f,
+ vboxglMapGrid1d,
+ vboxglMapGrid1f,
+ vboxglMapGrid2d,
+ vboxglMapGrid2f,
+ vboxglCopyPixels,
+ vboxglTexImage1D,
+ vboxglTexImage2D,
+ vboxglTexSubImage1D,
+ vboxglTexSubImage2D,
+ vboxglFeedbackBuffer,
+ vboxglSelectBuffer,
+ vboxglIsList,
+ vboxglIsTexture,
+ vboxglRenderMode,
+ vboxglReadPixels,
+ vboxglIsEnabled,
+ vboxglGenLists,
+ vboxglPixelTransferf,
+ vboxglPixelTransferi,
+ vboxglPixelZoom,
+ vboxglPixelStorei,
+ vboxglPixelStoref,
+ vboxglPixelMapfv,
+ vboxglPixelMapuiv,
+ vboxglPixelMapusv,
+ vboxglPointSize,
+ vboxglPolygonMode,
+ vboxglPolygonOffset,
+ vboxglPassThrough,
+ vboxglOrtho,
+ vboxglMatrixMode,
+ vboxglLogicOp,
+ vboxglColorMask,
+ vboxglCopyTexSubImage1D,
+ vboxglCopyTexSubImage2D,
+ vboxglFrontFace,
+ vboxglDisable,
+ vboxglEnable,
+ vboxglPrioritizeTextures,
+ vboxglGetBooleanv,
+ vboxglGetDoublev,
+ vboxglGetFloatv,
+ vboxglGetIntegerv,
+ vboxglGetLightfv,
+ vboxglGetLightiv,
+ vboxglGetMaterialfv,
+ vboxglGetMaterialiv,
+ vboxglGetPixelMapfv,
+ vboxglGetPixelMapuiv,
+ vboxglGetPixelMapusv,
+ vboxglGetTexEnviv,
+ vboxglGetTexEnvfv,
+ vboxglGetTexGendv,
+ vboxglGetTexGenfv,
+ vboxglGetTexGeniv,
+ vboxglGetTexParameterfv,
+ vboxglGetTexParameteriv,
+ vboxglGetClipPlane,
+ vboxglGetPolygonStipple,
+ vboxglGetTexLevelParameterfv,
+ vboxglGetTexLevelParameteriv,
+ vboxglGetTexImage,
+
+ /* Windows ICD exports */
+ vboxglDrvReleaseContext,
+ vboxglDrvCreateContext,
+ vboxglDrvDeleteContext,
+ vboxglDrvCopyContext,
+ vboxglDrvSetContext,
+ vboxglDrvCreateLayerContext,
+ vboxglDrvShareLists,
+ vboxglDrvDescribeLayerPlane,
+ vboxglDrvSetLayerPaletteEntries,
+ vboxglDrvGetLayerPaletteEntries,
+ vboxglDrvRealizeLayerPalette,
+ vboxglDrvSwapLayerBuffers,
+ vboxglDrvDescribePixelFormat,
+ vboxglDrvSetPixelFormat,
+ vboxglDrvSwapBuffers,
+
+#ifdef RT_OS_WINDOWS
+ /* OpenGL Extensions */
+ vboxwglSwapIntervalEXT,
+ vboxwglGetSwapIntervalEXT,
+#endif
+};
+#endif
+
+
+#ifdef VBOX_OGL_WITH_EXTENSION_ARRAY
+typedef struct
+{
+ const char *pszExtName;
+ const char *pszExtFunctionName;
+#ifdef VBOX_OGL_GUEST_SIDE
+ RTUINTPTR pfnFunction;
+#else
+ RTUINTPTR *ppfnFunction;
+#endif
+ bool fAvailable;
+} OPENGL_EXT, *POPENGL_EXT;
+
+#ifdef VBOX_OGL_GUEST_SIDE
+#define VBOX_OGL_EXTENSION(a) (RTUINTPTR)a
+#else
+#define VBOX_OGL_EXTENSION(a) (RTUINTPTR *)&pfn##a
+
+static PFNWGLSWAPINTERVALEXTPROC pfnwglSwapIntervalEXT = NULL;
+static PFNWGLGETSWAPINTERVALEXTPROC pfnwglGetSwapIntervalEXT = NULL;
+
+#endif
+
+static OPENGL_EXT OpenGLExtensions[] =
+{
+ { "WGL_EXT_swap_control", "wglSwapIntervalEXT", VBOX_OGL_EXTENSION(wglSwapIntervalEXT), false },
+ { "WGL_EXT_swap_control", "wglGetSwapIntervalEXT", VBOX_OGL_EXTENSION(wglGetSwapIntervalEXT), false },
+};
+#endif /* VBOX_OGL_WITH_EXTENSION_ARRAY */
+
+#endif
+
diff --git a/include/VBox/HostServices/VBoxOpenGLSvc.h b/include/VBox/HostServices/VBoxOpenGLSvc.h
new file mode 100644
index 00000000..be31f049
--- /dev/null
+++ b/include/VBox/HostServices/VBoxOpenGLSvc.h
@@ -0,0 +1,202 @@
+/** @file
+ * OpenGL: Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_HostService_VBoxOpenGLSvc_h
+#define ___VBox_HostService_VBoxOpenGLSvc_h
+
+#include <VBox/types.h>
+#include <VBox/VBoxGuest.h>
+#include <VBox/hgcmsvc.h>
+#include <VBox/VMMDev.h>
+
+/* OpenGL command buffer size */
+#define VBOX_OGL_MAX_CMD_BUFFER (128*1024)
+#define VBOX_OGL_CMD_ALIGN 4
+#define VBOX_OGL_CMD_ALIGN_MASK (VBOX_OGL_CMD_ALIGN-1)
+#define VBOX_OGL_CMD_MAGIC 0x1234ABCD
+
+/* for debugging */
+#define VBOX_OGL_CMD_STRICT
+
+/* OpenGL command block */
+typedef struct
+{
+#ifdef VBOX_OGL_CMD_STRICT
+ uint32_t Magic;
+#endif
+ uint32_t enmOp;
+ uint32_t cbCmd;
+ uint32_t cParams;
+ /* start of variable size parameter array */
+} VBOX_OGL_CMD, *PVBOX_OGL_CMD;
+
+typedef struct
+{
+#ifdef VBOX_OGL_CMD_STRICT
+ uint32_t Magic;
+#endif
+ uint32_t cbParam;
+ /* start of variable size parameter */
+} VBOX_OGL_VAR_PARAM, *PVBOX_OGL_VAR_PARAM;
+
+/** OpenGL Folders service functions. (guest)
+ * @{
+ */
+
+/** Query mappings changes. */
+#define VBOXOGL_FN_GLGETSTRING (1)
+#define VBOXOGL_FN_GLFLUSH (2)
+#define VBOXOGL_FN_GLFLUSHPTR (3)
+#define VBOXOGL_FN_GLCHECKEXT (4)
+
+/** @} */
+
+/** Function parameter structures.
+ * @{
+ */
+
+/**
+ * VBOXOGL_FN_GLGETSTRING
+ */
+
+/** Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** 32bit, in: name
+ * GLenum name parameter
+ */
+ HGCMFunctionParameter name;
+
+ /** pointer, in/out
+ * Buffer for requested string
+ */
+ HGCMFunctionParameter pString;
+} VBoxOGLglGetString;
+
+/** Number of parameters */
+#define VBOXOGL_CPARMS_GLGETSTRING (2)
+
+
+
+/**
+ * VBOXOGL_FN_GLFLUSH
+ */
+
+/** Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** pointer, in
+ * Command buffer
+ */
+ HGCMFunctionParameter pCmdBuffer;
+
+ /** 32bit, out: cCommands
+ * Number of commands in the buffer
+ */
+ HGCMFunctionParameter cCommands;
+
+ /** 64bit, out: retval
+ * uint64_t return code of last command
+ */
+ HGCMFunctionParameter retval;
+
+ /** 32bit, out: lasterror
+ * GLenum current last error
+ */
+ HGCMFunctionParameter lasterror;
+
+} VBoxOGLglFlush;
+
+/** Number of parameters */
+#define VBOXOGL_CPARMS_GLFLUSH (4)
+
+/**
+ * VBOXOGL_FN_GLFLUSHPTR
+ */
+
+/** Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** pointer, in
+ * Command buffer
+ */
+ HGCMFunctionParameter pCmdBuffer;
+
+ /** 32bit, out: cCommands
+ * Number of commands in the buffer
+ */
+ HGCMFunctionParameter cCommands;
+
+ /** pointer, in
+ * Last command's final parameter memory block
+ */
+ HGCMFunctionParameter pLastParam;
+
+ /** 64bit, out: retval
+ * uint64_t return code of last command
+ */
+ HGCMFunctionParameter retval;
+
+ /** 32bit, out: lasterror
+ * GLenum current last error
+ */
+ HGCMFunctionParameter lasterror;
+
+} VBoxOGLglFlushPtr;
+
+/** Number of parameters */
+#define VBOXOGL_CPARMS_GLFLUSHPTR (5)
+
+
+/**
+ * VBOXOGL_FN_GLCHECKEXT
+ */
+
+/** Parameters structure. */
+typedef struct
+{
+ VBoxGuestHGCMCallInfo hdr;
+
+ /** pointer, in
+ * Extension function name
+ */
+ HGCMFunctionParameter pszExtFnName;
+
+} VBoxOGLglCheckExt;
+
+/** Number of parameters */
+#define VBOXOGL_CPARMS_GLCHECKEXT (1)
+
+/** @} */
+
+
+#endif
+
diff --git a/include/VBox/HostServices/glext.h b/include/VBox/HostServices/glext.h
new file mode 100644
index 00000000..2519a6cc
--- /dev/null
+++ b/include/VBox/HostServices/glext.h
@@ -0,0 +1,7260 @@
+#ifndef __glext_h_
+#define __glext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number, required by OpenGL ABI for Linux */
+/* glext.h last updated 2007/02/12 */
+/* Current version at http://www.opengl.org/registry/ */
+#define GL_GLEXT_VERSION 39
+
+#ifndef GL_VERSION_1_2
+#define GL_UNSIGNED_BYTE_3_3_2 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2 0x8036
+#define GL_RESCALE_NORMAL 0x803A
+#define GL_TEXTURE_BINDING_3D 0x806A
+#define GL_PACK_SKIP_IMAGES 0x806B
+#define GL_PACK_IMAGE_HEIGHT 0x806C
+#define GL_UNPACK_SKIP_IMAGES 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT 0x806E
+#define GL_TEXTURE_3D 0x806F
+#define GL_PROXY_TEXTURE_3D 0x8070
+#define GL_TEXTURE_DEPTH 0x8071
+#define GL_TEXTURE_WRAP_R 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE 0x8073
+#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
+#define GL_UNSIGNED_SHORT_5_6_5 0x8363
+#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
+#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
+#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368
+#define GL_BGR 0x80E0
+#define GL_BGRA 0x80E1
+#define GL_MAX_ELEMENTS_VERTICES 0x80E8
+#define GL_MAX_ELEMENTS_INDICES 0x80E9
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_TEXTURE_MIN_LOD 0x813A
+#define GL_TEXTURE_MAX_LOD 0x813B
+#define GL_TEXTURE_BASE_LEVEL 0x813C
+#define GL_TEXTURE_MAX_LEVEL 0x813D
+#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
+#define GL_SINGLE_COLOR 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
+#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
+#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
+#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
+#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
+#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
+#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
+#endif
+
+#ifndef GL_ARB_imaging
+#define GL_CONSTANT_COLOR 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
+#define GL_CONSTANT_ALPHA 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_BLEND_COLOR 0x8005
+#define GL_FUNC_ADD 0x8006
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
+#define GL_BLEND_EQUATION 0x8009
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_CONVOLUTION_1D 0x8010
+#define GL_CONVOLUTION_2D 0x8011
+#define GL_SEPARABLE_2D 0x8012
+#define GL_CONVOLUTION_BORDER_MODE 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS 0x8015
+#define GL_REDUCE 0x8016
+#define GL_CONVOLUTION_FORMAT 0x8017
+#define GL_CONVOLUTION_WIDTH 0x8018
+#define GL_CONVOLUTION_HEIGHT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023
+#define GL_HISTOGRAM 0x8024
+#define GL_PROXY_HISTOGRAM 0x8025
+#define GL_HISTOGRAM_WIDTH 0x8026
+#define GL_HISTOGRAM_FORMAT 0x8027
+#define GL_HISTOGRAM_RED_SIZE 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C
+#define GL_HISTOGRAM_SINK 0x802D
+#define GL_MINMAX 0x802E
+#define GL_MINMAX_FORMAT 0x802F
+#define GL_MINMAX_SINK 0x8030
+#define GL_TABLE_TOO_LARGE 0x8031
+#define GL_COLOR_MATRIX 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB
+#define GL_COLOR_TABLE 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2
+#define GL_PROXY_COLOR_TABLE 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5
+#define GL_COLOR_TABLE_SCALE 0x80D6
+#define GL_COLOR_TABLE_BIAS 0x80D7
+#define GL_COLOR_TABLE_FORMAT 0x80D8
+#define GL_COLOR_TABLE_WIDTH 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF
+#define GL_CONSTANT_BORDER 0x8151
+#define GL_REPLICATE_BORDER 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR 0x8154
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_TEXTURE0 0x84C0
+#define GL_TEXTURE1 0x84C1
+#define GL_TEXTURE2 0x84C2
+#define GL_TEXTURE3 0x84C3
+#define GL_TEXTURE4 0x84C4
+#define GL_TEXTURE5 0x84C5
+#define GL_TEXTURE6 0x84C6
+#define GL_TEXTURE7 0x84C7
+#define GL_TEXTURE8 0x84C8
+#define GL_TEXTURE9 0x84C9
+#define GL_TEXTURE10 0x84CA
+#define GL_TEXTURE11 0x84CB
+#define GL_TEXTURE12 0x84CC
+#define GL_TEXTURE13 0x84CD
+#define GL_TEXTURE14 0x84CE
+#define GL_TEXTURE15 0x84CF
+#define GL_TEXTURE16 0x84D0
+#define GL_TEXTURE17 0x84D1
+#define GL_TEXTURE18 0x84D2
+#define GL_TEXTURE19 0x84D3
+#define GL_TEXTURE20 0x84D4
+#define GL_TEXTURE21 0x84D5
+#define GL_TEXTURE22 0x84D6
+#define GL_TEXTURE23 0x84D7
+#define GL_TEXTURE24 0x84D8
+#define GL_TEXTURE25 0x84D9
+#define GL_TEXTURE26 0x84DA
+#define GL_TEXTURE27 0x84DB
+#define GL_TEXTURE28 0x84DC
+#define GL_TEXTURE29 0x84DD
+#define GL_TEXTURE30 0x84DE
+#define GL_TEXTURE31 0x84DF
+#define GL_ACTIVE_TEXTURE 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
+#define GL_MAX_TEXTURE_UNITS 0x84E2
+#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
+#define GL_MULTISAMPLE 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
+#define GL_SAMPLE_COVERAGE 0x80A0
+#define GL_SAMPLE_BUFFERS 0x80A8
+#define GL_SAMPLES 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
+#define GL_MULTISAMPLE_BIT 0x20000000
+#define GL_NORMAL_MAP 0x8511
+#define GL_REFLECTION_MAP 0x8512
+#define GL_TEXTURE_CUBE_MAP 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
+#define GL_COMPRESSED_ALPHA 0x84E9
+#define GL_COMPRESSED_LUMINANCE 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
+#define GL_COMPRESSED_INTENSITY 0x84EC
+#define GL_COMPRESSED_RGB 0x84ED
+#define GL_COMPRESSED_RGBA 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
+#define GL_TEXTURE_COMPRESSED 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
+#define GL_CLAMP_TO_BORDER 0x812D
+#define GL_COMBINE 0x8570
+#define GL_COMBINE_RGB 0x8571
+#define GL_COMBINE_ALPHA 0x8572
+#define GL_SOURCE0_RGB 0x8580
+#define GL_SOURCE1_RGB 0x8581
+#define GL_SOURCE2_RGB 0x8582
+#define GL_SOURCE0_ALPHA 0x8588
+#define GL_SOURCE1_ALPHA 0x8589
+#define GL_SOURCE2_ALPHA 0x858A
+#define GL_OPERAND0_RGB 0x8590
+#define GL_OPERAND1_RGB 0x8591
+#define GL_OPERAND2_RGB 0x8592
+#define GL_OPERAND0_ALPHA 0x8598
+#define GL_OPERAND1_ALPHA 0x8599
+#define GL_OPERAND2_ALPHA 0x859A
+#define GL_RGB_SCALE 0x8573
+#define GL_ADD_SIGNED 0x8574
+#define GL_INTERPOLATE 0x8575
+#define GL_SUBTRACT 0x84E7
+#define GL_CONSTANT 0x8576
+#define GL_PRIMARY_COLOR 0x8577
+#define GL_PREVIOUS 0x8578
+#define GL_DOT3_RGB 0x86AE
+#define GL_DOT3_RGBA 0x86AF
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_BLEND_DST_RGB 0x80C8
+#define GL_BLEND_SRC_RGB 0x80C9
+#define GL_BLEND_DST_ALPHA 0x80CA
+#define GL_BLEND_SRC_ALPHA 0x80CB
+#define GL_POINT_SIZE_MIN 0x8126
+#define GL_POINT_SIZE_MAX 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION 0x8129
+#define GL_GENERATE_MIPMAP 0x8191
+#define GL_GENERATE_MIPMAP_HINT 0x8192
+#define GL_DEPTH_COMPONENT16 0x81A5
+#define GL_DEPTH_COMPONENT24 0x81A6
+#define GL_DEPTH_COMPONENT32 0x81A7
+#define GL_MIRRORED_REPEAT 0x8370
+#define GL_FOG_COORDINATE_SOURCE 0x8450
+#define GL_FOG_COORDINATE 0x8451
+#define GL_FRAGMENT_DEPTH 0x8452
+#define GL_CURRENT_FOG_COORDINATE 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456
+#define GL_FOG_COORDINATE_ARRAY 0x8457
+#define GL_COLOR_SUM 0x8458
+#define GL_CURRENT_SECONDARY_COLOR 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D
+#define GL_SECONDARY_COLOR_ARRAY 0x845E
+#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL 0x8500
+#define GL_TEXTURE_LOD_BIAS 0x8501
+#define GL_INCR_WRAP 0x8507
+#define GL_DECR_WRAP 0x8508
+#define GL_TEXTURE_DEPTH_SIZE 0x884A
+#define GL_DEPTH_TEXTURE_MODE 0x884B
+#define GL_TEXTURE_COMPARE_MODE 0x884C
+#define GL_TEXTURE_COMPARE_FUNC 0x884D
+#define GL_COMPARE_R_TO_TEXTURE 0x884E
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_BUFFER_SIZE 0x8764
+#define GL_BUFFER_USAGE 0x8765
+#define GL_QUERY_COUNTER_BITS 0x8864
+#define GL_CURRENT_QUERY 0x8865
+#define GL_QUERY_RESULT 0x8866
+#define GL_QUERY_RESULT_AVAILABLE 0x8867
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER 0x8893
+#define GL_ARRAY_BUFFER_BINDING 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
+#define GL_READ_ONLY 0x88B8
+#define GL_WRITE_ONLY 0x88B9
+#define GL_READ_WRITE 0x88BA
+#define GL_BUFFER_ACCESS 0x88BB
+#define GL_BUFFER_MAPPED 0x88BC
+#define GL_BUFFER_MAP_POINTER 0x88BD
+#define GL_STREAM_DRAW 0x88E0
+#define GL_STREAM_READ 0x88E1
+#define GL_STREAM_COPY 0x88E2
+#define GL_STATIC_DRAW 0x88E4
+#define GL_STATIC_READ 0x88E5
+#define GL_STATIC_COPY 0x88E6
+#define GL_DYNAMIC_DRAW 0x88E8
+#define GL_DYNAMIC_READ 0x88E9
+#define GL_DYNAMIC_COPY 0x88EA
+#define GL_SAMPLES_PASSED 0x8914
+#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE
+#define GL_FOG_COORD GL_FOG_COORDINATE
+#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE
+#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE
+#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE
+#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER
+#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY
+#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING
+#define GL_SRC0_RGB GL_SOURCE0_RGB
+#define GL_SRC1_RGB GL_SOURCE1_RGB
+#define GL_SRC2_RGB GL_SOURCE2_RGB
+#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA
+#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA
+#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB 0x8626
+#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
+#define GL_STENCIL_BACK_FUNC 0x8800
+#define GL_STENCIL_BACK_FAIL 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
+#define GL_MAX_DRAW_BUFFERS 0x8824
+#define GL_DRAW_BUFFER0 0x8825
+#define GL_DRAW_BUFFER1 0x8826
+#define GL_DRAW_BUFFER2 0x8827
+#define GL_DRAW_BUFFER3 0x8828
+#define GL_DRAW_BUFFER4 0x8829
+#define GL_DRAW_BUFFER5 0x882A
+#define GL_DRAW_BUFFER6 0x882B
+#define GL_DRAW_BUFFER7 0x882C
+#define GL_DRAW_BUFFER8 0x882D
+#define GL_DRAW_BUFFER9 0x882E
+#define GL_DRAW_BUFFER10 0x882F
+#define GL_DRAW_BUFFER11 0x8830
+#define GL_DRAW_BUFFER12 0x8831
+#define GL_DRAW_BUFFER13 0x8832
+#define GL_DRAW_BUFFER14 0x8833
+#define GL_DRAW_BUFFER15 0x8834
+#define GL_BLEND_EQUATION_ALPHA 0x883D
+#define GL_POINT_SPRITE 0x8861
+#define GL_COORD_REPLACE 0x8862
+#define GL_MAX_VERTEX_ATTRIBS 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
+#define GL_MAX_TEXTURE_COORDS 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
+#define GL_MAX_VARYING_FLOATS 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
+#define GL_SHADER_TYPE 0x8B4F
+#define GL_FLOAT_VEC2 0x8B50
+#define GL_FLOAT_VEC3 0x8B51
+#define GL_FLOAT_VEC4 0x8B52
+#define GL_INT_VEC2 0x8B53
+#define GL_INT_VEC3 0x8B54
+#define GL_INT_VEC4 0x8B55
+#define GL_BOOL 0x8B56
+#define GL_BOOL_VEC2 0x8B57
+#define GL_BOOL_VEC3 0x8B58
+#define GL_BOOL_VEC4 0x8B59
+#define GL_FLOAT_MAT2 0x8B5A
+#define GL_FLOAT_MAT3 0x8B5B
+#define GL_FLOAT_MAT4 0x8B5C
+#define GL_SAMPLER_1D 0x8B5D
+#define GL_SAMPLER_2D 0x8B5E
+#define GL_SAMPLER_3D 0x8B5F
+#define GL_SAMPLER_CUBE 0x8B60
+#define GL_SAMPLER_1D_SHADOW 0x8B61
+#define GL_SAMPLER_2D_SHADOW 0x8B62
+#define GL_DELETE_STATUS 0x8B80
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+#define GL_VALIDATE_STATUS 0x8B83
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_ATTACHED_SHADERS 0x8B85
+#define GL_ACTIVE_UNIFORMS 0x8B86
+#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
+#define GL_SHADER_SOURCE_LENGTH 0x8B88
+#define GL_ACTIVE_ATTRIBUTES 0x8B89
+#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
+#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
+#define GL_CURRENT_PROGRAM 0x8B8D
+#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
+#define GL_LOWER_LEFT 0x8CA1
+#define GL_UPPER_LEFT 0x8CA2
+#define GL_STENCIL_BACK_REF 0x8CA3
+#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
+#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
+#define GL_PIXEL_PACK_BUFFER 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#define GL_FLOAT_MAT2x3 0x8B65
+#define GL_FLOAT_MAT2x4 0x8B66
+#define GL_FLOAT_MAT3x2 0x8B67
+#define GL_FLOAT_MAT3x4 0x8B68
+#define GL_FLOAT_MAT4x2 0x8B69
+#define GL_FLOAT_MAT4x3 0x8B6A
+#define GL_SRGB 0x8C40
+#define GL_SRGB8 0x8C41
+#define GL_SRGB_ALPHA 0x8C42
+#define GL_SRGB8_ALPHA8 0x8C43
+#define GL_SLUMINANCE_ALPHA 0x8C44
+#define GL_SLUMINANCE8_ALPHA8 0x8C45
+#define GL_SLUMINANCE 0x8C46
+#define GL_SLUMINANCE8 0x8C47
+#define GL_COMPRESSED_SRGB 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
+#define GL_COMPRESSED_SLUMINANCE 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_TEXTURE0_ARB 0x84C0
+#define GL_TEXTURE1_ARB 0x84C1
+#define GL_TEXTURE2_ARB 0x84C2
+#define GL_TEXTURE3_ARB 0x84C3
+#define GL_TEXTURE4_ARB 0x84C4
+#define GL_TEXTURE5_ARB 0x84C5
+#define GL_TEXTURE6_ARB 0x84C6
+#define GL_TEXTURE7_ARB 0x84C7
+#define GL_TEXTURE8_ARB 0x84C8
+#define GL_TEXTURE9_ARB 0x84C9
+#define GL_TEXTURE10_ARB 0x84CA
+#define GL_TEXTURE11_ARB 0x84CB
+#define GL_TEXTURE12_ARB 0x84CC
+#define GL_TEXTURE13_ARB 0x84CD
+#define GL_TEXTURE14_ARB 0x84CE
+#define GL_TEXTURE15_ARB 0x84CF
+#define GL_TEXTURE16_ARB 0x84D0
+#define GL_TEXTURE17_ARB 0x84D1
+#define GL_TEXTURE18_ARB 0x84D2
+#define GL_TEXTURE19_ARB 0x84D3
+#define GL_TEXTURE20_ARB 0x84D4
+#define GL_TEXTURE21_ARB 0x84D5
+#define GL_TEXTURE22_ARB 0x84D6
+#define GL_TEXTURE23_ARB 0x84D7
+#define GL_TEXTURE24_ARB 0x84D8
+#define GL_TEXTURE25_ARB 0x84D9
+#define GL_TEXTURE26_ARB 0x84DA
+#define GL_TEXTURE27_ARB 0x84DB
+#define GL_TEXTURE28_ARB 0x84DC
+#define GL_TEXTURE29_ARB 0x84DD
+#define GL_TEXTURE30_ARB 0x84DE
+#define GL_TEXTURE31_ARB 0x84DF
+#define GL_ACTIVE_TEXTURE_ARB 0x84E0
+#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
+#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
+#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
+#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
+#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_MULTISAMPLE_ARB 0x809D
+#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
+#define GL_SAMPLE_COVERAGE_ARB 0x80A0
+#define GL_SAMPLE_BUFFERS_ARB 0x80A8
+#define GL_SAMPLES_ARB 0x80A9
+#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
+#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
+#define GL_MULTISAMPLE_BIT_ARB 0x20000000
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_NORMAL_MAP_ARB 0x8511
+#define GL_REFLECTION_MAP_ARB 0x8512
+#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_COMPRESSED_ALPHA_ARB 0x84E9
+#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
+#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
+#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
+#define GL_COMPRESSED_RGB_ARB 0x84ED
+#define GL_COMPRESSED_RGBA_ARB 0x84EE
+#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
+#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
+#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
+#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
+#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_ARB 0x812D
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_POINT_SIZE_MIN_ARB 0x8126
+#define GL_POINT_SIZE_MAX_ARB 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128
+#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_MAX_VERTEX_UNITS_ARB 0x86A4
+#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5
+#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6
+#define GL_VERTEX_BLEND_ARB 0x86A7
+#define GL_CURRENT_WEIGHT_ARB 0x86A8
+#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9
+#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA
+#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB
+#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC
+#define GL_WEIGHT_ARRAY_ARB 0x86AD
+#define GL_MODELVIEW0_ARB 0x1700
+#define GL_MODELVIEW1_ARB 0x850A
+#define GL_MODELVIEW2_ARB 0x8722
+#define GL_MODELVIEW3_ARB 0x8723
+#define GL_MODELVIEW4_ARB 0x8724
+#define GL_MODELVIEW5_ARB 0x8725
+#define GL_MODELVIEW6_ARB 0x8726
+#define GL_MODELVIEW7_ARB 0x8727
+#define GL_MODELVIEW8_ARB 0x8728
+#define GL_MODELVIEW9_ARB 0x8729
+#define GL_MODELVIEW10_ARB 0x872A
+#define GL_MODELVIEW11_ARB 0x872B
+#define GL_MODELVIEW12_ARB 0x872C
+#define GL_MODELVIEW13_ARB 0x872D
+#define GL_MODELVIEW14_ARB 0x872E
+#define GL_MODELVIEW15_ARB 0x872F
+#define GL_MODELVIEW16_ARB 0x8730
+#define GL_MODELVIEW17_ARB 0x8731
+#define GL_MODELVIEW18_ARB 0x8732
+#define GL_MODELVIEW19_ARB 0x8733
+#define GL_MODELVIEW20_ARB 0x8734
+#define GL_MODELVIEW21_ARB 0x8735
+#define GL_MODELVIEW22_ARB 0x8736
+#define GL_MODELVIEW23_ARB 0x8737
+#define GL_MODELVIEW24_ARB 0x8738
+#define GL_MODELVIEW25_ARB 0x8739
+#define GL_MODELVIEW26_ARB 0x873A
+#define GL_MODELVIEW27_ARB 0x873B
+#define GL_MODELVIEW28_ARB 0x873C
+#define GL_MODELVIEW29_ARB 0x873D
+#define GL_MODELVIEW30_ARB 0x873E
+#define GL_MODELVIEW31_ARB 0x873F
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_MATRIX_PALETTE_ARB 0x8840
+#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841
+#define GL_MAX_PALETTE_MATRICES_ARB 0x8842
+#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843
+#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844
+#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845
+#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846
+#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847
+#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848
+#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_COMBINE_ARB 0x8570
+#define GL_COMBINE_RGB_ARB 0x8571
+#define GL_COMBINE_ALPHA_ARB 0x8572
+#define GL_SOURCE0_RGB_ARB 0x8580
+#define GL_SOURCE1_RGB_ARB 0x8581
+#define GL_SOURCE2_RGB_ARB 0x8582
+#define GL_SOURCE0_ALPHA_ARB 0x8588
+#define GL_SOURCE1_ALPHA_ARB 0x8589
+#define GL_SOURCE2_ALPHA_ARB 0x858A
+#define GL_OPERAND0_RGB_ARB 0x8590
+#define GL_OPERAND1_RGB_ARB 0x8591
+#define GL_OPERAND2_RGB_ARB 0x8592
+#define GL_OPERAND0_ALPHA_ARB 0x8598
+#define GL_OPERAND1_ALPHA_ARB 0x8599
+#define GL_OPERAND2_ALPHA_ARB 0x859A
+#define GL_RGB_SCALE_ARB 0x8573
+#define GL_ADD_SIGNED_ARB 0x8574
+#define GL_INTERPOLATE_ARB 0x8575
+#define GL_SUBTRACT_ARB 0x84E7
+#define GL_CONSTANT_ARB 0x8576
+#define GL_PRIMARY_COLOR_ARB 0x8577
+#define GL_PREVIOUS_ARB 0x8578
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_DOT3_RGB_ARB 0x86AE
+#define GL_DOT3_RGBA_ARB 0x86AF
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_ARB 0x8370
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_DEPTH_COMPONENT16_ARB 0x81A5
+#define GL_DEPTH_COMPONENT24_ARB 0x81A6
+#define GL_DEPTH_COMPONENT32_ARB 0x81A7
+#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A
+#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
+#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
+#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF
+#endif
+
+#ifndef GL_ARB_window_pos
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_COLOR_SUM_ARB 0x8458
+#define GL_VERTEX_PROGRAM_ARB 0x8620
+#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622
+#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623
+#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624
+#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625
+#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626
+#define GL_PROGRAM_LENGTH_ARB 0x8627
+#define GL_PROGRAM_STRING_ARB 0x8628
+#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E
+#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F
+#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640
+#define GL_CURRENT_MATRIX_ARB 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643
+#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645
+#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B
+#define GL_PROGRAM_BINDING_ARB 0x8677
+#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869
+#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A
+#define GL_PROGRAM_ERROR_STRING_ARB 0x8874
+#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875
+#define GL_PROGRAM_FORMAT_ARB 0x8876
+#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0
+#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1
+#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2
+#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3
+#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4
+#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5
+#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6
+#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7
+#define GL_PROGRAM_PARAMETERS_ARB 0x88A8
+#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9
+#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA
+#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB
+#define GL_PROGRAM_ATTRIBS_ARB 0x88AC
+#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD
+#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE
+#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF
+#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0
+#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1
+#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2
+#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3
+#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4
+#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5
+#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6
+#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7
+#define GL_MATRIX0_ARB 0x88C0
+#define GL_MATRIX1_ARB 0x88C1
+#define GL_MATRIX2_ARB 0x88C2
+#define GL_MATRIX3_ARB 0x88C3
+#define GL_MATRIX4_ARB 0x88C4
+#define GL_MATRIX5_ARB 0x88C5
+#define GL_MATRIX6_ARB 0x88C6
+#define GL_MATRIX7_ARB 0x88C7
+#define GL_MATRIX8_ARB 0x88C8
+#define GL_MATRIX9_ARB 0x88C9
+#define GL_MATRIX10_ARB 0x88CA
+#define GL_MATRIX11_ARB 0x88CB
+#define GL_MATRIX12_ARB 0x88CC
+#define GL_MATRIX13_ARB 0x88CD
+#define GL_MATRIX14_ARB 0x88CE
+#define GL_MATRIX15_ARB 0x88CF
+#define GL_MATRIX16_ARB 0x88D0
+#define GL_MATRIX17_ARB 0x88D1
+#define GL_MATRIX18_ARB 0x88D2
+#define GL_MATRIX19_ARB 0x88D3
+#define GL_MATRIX20_ARB 0x88D4
+#define GL_MATRIX21_ARB 0x88D5
+#define GL_MATRIX22_ARB 0x88D6
+#define GL_MATRIX23_ARB 0x88D7
+#define GL_MATRIX24_ARB 0x88D8
+#define GL_MATRIX25_ARB 0x88D9
+#define GL_MATRIX26_ARB 0x88DA
+#define GL_MATRIX27_ARB 0x88DB
+#define GL_MATRIX28_ARB 0x88DC
+#define GL_MATRIX29_ARB 0x88DD
+#define GL_MATRIX30_ARB 0x88DE
+#define GL_MATRIX31_ARB 0x88DF
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_FRAGMENT_PROGRAM_ARB 0x8804
+#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805
+#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806
+#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807
+#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808
+#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809
+#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A
+#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B
+#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C
+#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D
+#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E
+#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F
+#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810
+#define GL_MAX_TEXTURE_COORDS_ARB 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_BUFFER_SIZE_ARB 0x8764
+#define GL_BUFFER_USAGE_ARB 0x8765
+#define GL_ARRAY_BUFFER_ARB 0x8892
+#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
+#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
+#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
+#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
+#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
+#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
+#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
+#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
+#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
+#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
+#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
+#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
+#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
+#define GL_READ_ONLY_ARB 0x88B8
+#define GL_WRITE_ONLY_ARB 0x88B9
+#define GL_READ_WRITE_ARB 0x88BA
+#define GL_BUFFER_ACCESS_ARB 0x88BB
+#define GL_BUFFER_MAPPED_ARB 0x88BC
+#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
+#define GL_STREAM_DRAW_ARB 0x88E0
+#define GL_STREAM_READ_ARB 0x88E1
+#define GL_STREAM_COPY_ARB 0x88E2
+#define GL_STATIC_DRAW_ARB 0x88E4
+#define GL_STATIC_READ_ARB 0x88E5
+#define GL_STATIC_COPY_ARB 0x88E6
+#define GL_DYNAMIC_DRAW_ARB 0x88E8
+#define GL_DYNAMIC_READ_ARB 0x88E9
+#define GL_DYNAMIC_COPY_ARB 0x88EA
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_QUERY_COUNTER_BITS_ARB 0x8864
+#define GL_CURRENT_QUERY_ARB 0x8865
+#define GL_QUERY_RESULT_ARB 0x8866
+#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
+#define GL_SAMPLES_PASSED_ARB 0x8914
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_PROGRAM_OBJECT_ARB 0x8B40
+#define GL_SHADER_OBJECT_ARB 0x8B48
+#define GL_OBJECT_TYPE_ARB 0x8B4E
+#define GL_OBJECT_SUBTYPE_ARB 0x8B4F
+#define GL_FLOAT_VEC2_ARB 0x8B50
+#define GL_FLOAT_VEC3_ARB 0x8B51
+#define GL_FLOAT_VEC4_ARB 0x8B52
+#define GL_INT_VEC2_ARB 0x8B53
+#define GL_INT_VEC3_ARB 0x8B54
+#define GL_INT_VEC4_ARB 0x8B55
+#define GL_BOOL_ARB 0x8B56
+#define GL_BOOL_VEC2_ARB 0x8B57
+#define GL_BOOL_VEC3_ARB 0x8B58
+#define GL_BOOL_VEC4_ARB 0x8B59
+#define GL_FLOAT_MAT2_ARB 0x8B5A
+#define GL_FLOAT_MAT3_ARB 0x8B5B
+#define GL_FLOAT_MAT4_ARB 0x8B5C
+#define GL_SAMPLER_1D_ARB 0x8B5D
+#define GL_SAMPLER_2D_ARB 0x8B5E
+#define GL_SAMPLER_3D_ARB 0x8B5F
+#define GL_SAMPLER_CUBE_ARB 0x8B60
+#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61
+#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62
+#define GL_SAMPLER_2D_RECT_ARB 0x8B63
+#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64
+#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80
+#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
+#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
+#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83
+#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
+#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85
+#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86
+#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87
+#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_VERTEX_SHADER_ARB 0x8B31
+#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A
+#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B
+#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C
+#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D
+#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89
+#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_FRAGMENT_SHADER_ARB 0x8B30
+#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49
+#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_POINT_SPRITE_ARB 0x8861
+#define GL_COORD_REPLACE_ARB 0x8862
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ARB 0x8824
+#define GL_DRAW_BUFFER0_ARB 0x8825
+#define GL_DRAW_BUFFER1_ARB 0x8826
+#define GL_DRAW_BUFFER2_ARB 0x8827
+#define GL_DRAW_BUFFER3_ARB 0x8828
+#define GL_DRAW_BUFFER4_ARB 0x8829
+#define GL_DRAW_BUFFER5_ARB 0x882A
+#define GL_DRAW_BUFFER6_ARB 0x882B
+#define GL_DRAW_BUFFER7_ARB 0x882C
+#define GL_DRAW_BUFFER8_ARB 0x882D
+#define GL_DRAW_BUFFER9_ARB 0x882E
+#define GL_DRAW_BUFFER10_ARB 0x882F
+#define GL_DRAW_BUFFER11_ARB 0x8830
+#define GL_DRAW_BUFFER12_ARB 0x8831
+#define GL_DRAW_BUFFER13_ARB 0x8832
+#define GL_DRAW_BUFFER14_ARB 0x8833
+#define GL_DRAW_BUFFER15_ARB 0x8834
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_RGBA_FLOAT_MODE_ARB 0x8820
+#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A
+#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B
+#define GL_CLAMP_READ_COLOR_ARB 0x891C
+#define GL_FIXED_ONLY_ARB 0x891D
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_HALF_FLOAT_ARB 0x140B
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_TEXTURE_RED_TYPE_ARB 0x8C10
+#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11
+#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12
+#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13
+#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
+#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15
+#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16
+#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17
+#define GL_RGBA32F_ARB 0x8814
+#define GL_RGB32F_ARB 0x8815
+#define GL_ALPHA32F_ARB 0x8816
+#define GL_INTENSITY32F_ARB 0x8817
+#define GL_LUMINANCE32F_ARB 0x8818
+#define GL_LUMINANCE_ALPHA32F_ARB 0x8819
+#define GL_RGBA16F_ARB 0x881A
+#define GL_RGB16F_ARB 0x881B
+#define GL_ALPHA16F_ARB 0x881C
+#define GL_INTENSITY16F_ARB 0x881D
+#define GL_LUMINANCE16F_ARB 0x881E
+#define GL_LUMINANCE_ALPHA16F_ARB 0x881F
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_ABGR_EXT 0x8000
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_CONSTANT_COLOR_EXT 0x8001
+#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002
+#define GL_CONSTANT_ALPHA_EXT 0x8003
+#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004
+#define GL_BLEND_COLOR_EXT 0x8005
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_POLYGON_OFFSET_EXT 0x8037
+#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038
+#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_ALPHA4_EXT 0x803B
+#define GL_ALPHA8_EXT 0x803C
+#define GL_ALPHA12_EXT 0x803D
+#define GL_ALPHA16_EXT 0x803E
+#define GL_LUMINANCE4_EXT 0x803F
+#define GL_LUMINANCE8_EXT 0x8040
+#define GL_LUMINANCE12_EXT 0x8041
+#define GL_LUMINANCE16_EXT 0x8042
+#define GL_LUMINANCE4_ALPHA4_EXT 0x8043
+#define GL_LUMINANCE6_ALPHA2_EXT 0x8044
+#define GL_LUMINANCE8_ALPHA8_EXT 0x8045
+#define GL_LUMINANCE12_ALPHA4_EXT 0x8046
+#define GL_LUMINANCE12_ALPHA12_EXT 0x8047
+#define GL_LUMINANCE16_ALPHA16_EXT 0x8048
+#define GL_INTENSITY_EXT 0x8049
+#define GL_INTENSITY4_EXT 0x804A
+#define GL_INTENSITY8_EXT 0x804B
+#define GL_INTENSITY12_EXT 0x804C
+#define GL_INTENSITY16_EXT 0x804D
+#define GL_RGB2_EXT 0x804E
+#define GL_RGB4_EXT 0x804F
+#define GL_RGB5_EXT 0x8050
+#define GL_RGB8_EXT 0x8051
+#define GL_RGB10_EXT 0x8052
+#define GL_RGB12_EXT 0x8053
+#define GL_RGB16_EXT 0x8054
+#define GL_RGBA2_EXT 0x8055
+#define GL_RGBA4_EXT 0x8056
+#define GL_RGB5_A1_EXT 0x8057
+#define GL_RGBA8_EXT 0x8058
+#define GL_RGB10_A2_EXT 0x8059
+#define GL_RGBA12_EXT 0x805A
+#define GL_RGBA16_EXT 0x805B
+#define GL_TEXTURE_RED_SIZE_EXT 0x805C
+#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D
+#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E
+#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F
+#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061
+#define GL_REPLACE_EXT 0x8062
+#define GL_PROXY_TEXTURE_1D_EXT 0x8063
+#define GL_PROXY_TEXTURE_2D_EXT 0x8064
+#define GL_TEXTURE_TOO_LARGE_EXT 0x8065
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_PACK_SKIP_IMAGES_EXT 0x806B
+#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C
+#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D
+#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E
+#define GL_TEXTURE_3D_EXT 0x806F
+#define GL_PROXY_TEXTURE_3D_EXT 0x8070
+#define GL_TEXTURE_DEPTH_EXT 0x8071
+#define GL_TEXTURE_WRAP_R_EXT 0x8072
+#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_FILTER4_SGIS 0x8146
+#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147
+#endif
+
+#ifndef GL_EXT_subtexture
+#endif
+
+#ifndef GL_EXT_copy_texture
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_HISTOGRAM_EXT 0x8024
+#define GL_PROXY_HISTOGRAM_EXT 0x8025
+#define GL_HISTOGRAM_WIDTH_EXT 0x8026
+#define GL_HISTOGRAM_FORMAT_EXT 0x8027
+#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028
+#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029
+#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A
+#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B
+#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C
+#define GL_HISTOGRAM_SINK_EXT 0x802D
+#define GL_MINMAX_EXT 0x802E
+#define GL_MINMAX_FORMAT_EXT 0x802F
+#define GL_MINMAX_SINK_EXT 0x8030
+#define GL_TABLE_TOO_LARGE_EXT 0x8031
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_CONVOLUTION_1D_EXT 0x8010
+#define GL_CONVOLUTION_2D_EXT 0x8011
+#define GL_SEPARABLE_2D_EXT 0x8012
+#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013
+#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014
+#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015
+#define GL_REDUCE_EXT 0x8016
+#define GL_CONVOLUTION_FORMAT_EXT 0x8017
+#define GL_CONVOLUTION_WIDTH_EXT 0x8018
+#define GL_CONVOLUTION_HEIGHT_EXT 0x8019
+#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A
+#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B
+#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C
+#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D
+#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E
+#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F
+#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020
+#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021
+#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022
+#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_COLOR_MATRIX_SGI 0x80B1
+#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2
+#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3
+#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4
+#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5
+#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6
+#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7
+#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8
+#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9
+#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA
+#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_COLOR_TABLE_SGI 0x80D0
+#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1
+#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2
+#define GL_PROXY_COLOR_TABLE_SGI 0x80D3
+#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4
+#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5
+#define GL_COLOR_TABLE_SCALE_SGI 0x80D6
+#define GL_COLOR_TABLE_BIAS_SGI 0x80D7
+#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8
+#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9
+#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA
+#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB
+#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC
+#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD
+#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE
+#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_PIXEL_TEXTURE_SGIS 0x8353
+#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354
+#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355
+#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_PIXEL_TEX_GEN_SGIX 0x8139
+#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130
+#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131
+#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132
+#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133
+#define GL_TEXTURE_4D_SGIS 0x8134
+#define GL_PROXY_TEXTURE_4D_SGIS 0x8135
+#define GL_TEXTURE_4DSIZE_SGIS 0x8136
+#define GL_TEXTURE_WRAP_Q_SGIS 0x8137
+#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138
+#define GL_TEXTURE_4D_BINDING_SGIS 0x814F
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC
+#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_CMYK_EXT 0x800C
+#define GL_CMYKA_EXT 0x800D
+#define GL_PACK_CMYK_HINT_EXT 0x800E
+#define GL_UNPACK_CMYK_HINT_EXT 0x800F
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_TEXTURE_PRIORITY_EXT 0x8066
+#define GL_TEXTURE_RESIDENT_EXT 0x8067
+#define GL_TEXTURE_1D_BINDING_EXT 0x8068
+#define GL_TEXTURE_2D_BINDING_EXT 0x8069
+#define GL_TEXTURE_3D_BINDING_EXT 0x806A
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095
+#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096
+#define GL_LINEAR_DETAIL_SGIS 0x8097
+#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098
+#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099
+#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A
+#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B
+#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_LINEAR_SHARPEN_SGIS 0x80AD
+#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE
+#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF
+#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
+#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
+#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
+#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
+#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_TEXTURE_MIN_LOD_SGIS 0x813A
+#define GL_TEXTURE_MAX_LOD_SGIS 0x813B
+#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C
+#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_MULTISAMPLE_SGIS 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F
+#define GL_SAMPLE_MASK_SGIS 0x80A0
+#define GL_1PASS_SGIS 0x80A1
+#define GL_2PASS_0_SGIS 0x80A2
+#define GL_2PASS_1_SGIS 0x80A3
+#define GL_4PASS_0_SGIS 0x80A4
+#define GL_4PASS_1_SGIS 0x80A5
+#define GL_4PASS_2_SGIS 0x80A6
+#define GL_4PASS_3_SGIS 0x80A7
+#define GL_SAMPLE_BUFFERS_SGIS 0x80A8
+#define GL_SAMPLES_SGIS 0x80A9
+#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA
+#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB
+#define GL_SAMPLE_PATTERN_SGIS 0x80AC
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_RESCALE_NORMAL_EXT 0x803A
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_VERTEX_ARRAY_EXT 0x8074
+#define GL_NORMAL_ARRAY_EXT 0x8075
+#define GL_COLOR_ARRAY_EXT 0x8076
+#define GL_INDEX_ARRAY_EXT 0x8077
+#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078
+#define GL_EDGE_FLAG_ARRAY_EXT 0x8079
+#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A
+#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B
+#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C
+#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D
+#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E
+#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F
+#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080
+#define GL_COLOR_ARRAY_SIZE_EXT 0x8081
+#define GL_COLOR_ARRAY_TYPE_EXT 0x8082
+#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083
+#define GL_COLOR_ARRAY_COUNT_EXT 0x8084
+#define GL_INDEX_ARRAY_TYPE_EXT 0x8085
+#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086
+#define GL_INDEX_ARRAY_COUNT_EXT 0x8087
+#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A
+#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B
+#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C
+#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D
+#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E
+#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F
+#define GL_COLOR_ARRAY_POINTER_EXT 0x8090
+#define GL_INDEX_ARRAY_POINTER_EXT 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_GENERATE_MIPMAP_SGIS 0x8191
+#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170
+#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171
+#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172
+#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173
+#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174
+#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175
+#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176
+#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177
+#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178
+#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D
+#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E
+#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_TEXTURE_COMPARE_SGIX 0x819A
+#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B
+#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C
+#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_CLAMP_TO_EDGE_SGIS 0x812F
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_CLAMP_TO_BORDER_SGIS 0x812D
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_FUNC_ADD_EXT 0x8006
+#define GL_MIN_EXT 0x8007
+#define GL_MAX_EXT 0x8008
+#define GL_BLEND_EQUATION_EXT 0x8009
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_FUNC_SUBTRACT_EXT 0x800A
+#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_INTERLACE_SGIX 0x8094
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E
+#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F
+#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140
+#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141
+#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142
+#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143
+#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144
+#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145
+#endif
+
+#ifndef GL_SGIS_texture_select
+#define GL_DUAL_ALPHA4_SGIS 0x8110
+#define GL_DUAL_ALPHA8_SGIS 0x8111
+#define GL_DUAL_ALPHA12_SGIS 0x8112
+#define GL_DUAL_ALPHA16_SGIS 0x8113
+#define GL_DUAL_LUMINANCE4_SGIS 0x8114
+#define GL_DUAL_LUMINANCE8_SGIS 0x8115
+#define GL_DUAL_LUMINANCE12_SGIS 0x8116
+#define GL_DUAL_LUMINANCE16_SGIS 0x8117
+#define GL_DUAL_INTENSITY4_SGIS 0x8118
+#define GL_DUAL_INTENSITY8_SGIS 0x8119
+#define GL_DUAL_INTENSITY12_SGIS 0x811A
+#define GL_DUAL_INTENSITY16_SGIS 0x811B
+#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C
+#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D
+#define GL_QUAD_ALPHA4_SGIS 0x811E
+#define GL_QUAD_ALPHA8_SGIS 0x811F
+#define GL_QUAD_LUMINANCE4_SGIS 0x8120
+#define GL_QUAD_LUMINANCE8_SGIS 0x8121
+#define GL_QUAD_INTENSITY4_SGIS 0x8122
+#define GL_QUAD_INTENSITY8_SGIS 0x8123
+#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124
+#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SPRITE_SGIX 0x8148
+#define GL_SPRITE_MODE_SGIX 0x8149
+#define GL_SPRITE_AXIS_SGIX 0x814A
+#define GL_SPRITE_TRANSLATION_SGIX 0x814B
+#define GL_SPRITE_AXIAL_SGIX 0x814C
+#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D
+#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_POINT_SIZE_MIN_EXT 0x8126
+#define GL_POINT_SIZE_MAX_EXT 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128
+#define GL_DISTANCE_ATTENUATION_EXT 0x8129
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_POINT_SIZE_MIN_SGIS 0x8126
+#define GL_POINT_SIZE_MAX_SGIS 0x8127
+#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128
+#define GL_DISTANCE_ATTENUATION_SGIS 0x8129
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180
+#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179
+#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A
+#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B
+#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_FRAMEZOOM_SGIX 0x818B
+#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C
+#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#endif
+
+#ifndef GL_FfdMaskSGIX
+#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001
+#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194
+#define GL_TEXTURE_DEFORMATION_SGIX 0x8195
+#define GL_DEFORMATIONS_MASK_SGIX 0x8196
+#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_REFERENCE_PLANE_SGIX 0x817D
+#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_DEPTH_COMPONENT16_SGIX 0x81A5
+#define GL_DEPTH_COMPONENT24_SGIX 0x81A6
+#define GL_DEPTH_COMPONENT32_SGIX 0x81A7
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_FOG_FUNC_SGIS 0x812A
+#define GL_FOG_FUNC_POINTS_SGIS 0x812B
+#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_FOG_OFFSET_SGIX 0x8198
+#define GL_FOG_OFFSET_VALUE_SGIX 0x8199
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_IMAGE_SCALE_X_HP 0x8155
+#define GL_IMAGE_SCALE_Y_HP 0x8156
+#define GL_IMAGE_TRANSLATE_X_HP 0x8157
+#define GL_IMAGE_TRANSLATE_Y_HP 0x8158
+#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159
+#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A
+#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B
+#define GL_IMAGE_MAG_FILTER_HP 0x815C
+#define GL_IMAGE_MIN_FILTER_HP 0x815D
+#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E
+#define GL_CUBIC_HP 0x815F
+#define GL_AVERAGE_HP 0x8160
+#define GL_IMAGE_TRANSFORM_2D_HP 0x8161
+#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162
+#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_IGNORE_BORDER_HP 0x8150
+#define GL_CONSTANT_BORDER_HP 0x8151
+#define GL_REPLICATE_BORDER_HP 0x8153
+#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154
+#endif
+
+#ifndef GL_INGR_palette_buffer
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE
+#endif
+
+#ifndef GL_EXT_color_subtable
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_VERTEX_DATA_HINT_PGI 0x1A22A
+#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B
+#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C
+#define GL_MAX_VERTEX_HINT_PGI 0x1A22D
+#define GL_COLOR3_BIT_PGI 0x00010000
+#define GL_COLOR4_BIT_PGI 0x00020000
+#define GL_EDGEFLAG_BIT_PGI 0x00040000
+#define GL_INDEX_BIT_PGI 0x00080000
+#define GL_MAT_AMBIENT_BIT_PGI 0x00100000
+#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000
+#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000
+#define GL_MAT_EMISSION_BIT_PGI 0x00800000
+#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000
+#define GL_MAT_SHININESS_BIT_PGI 0x02000000
+#define GL_MAT_SPECULAR_BIT_PGI 0x04000000
+#define GL_NORMAL_BIT_PGI 0x08000000
+#define GL_TEXCOORD1_BIT_PGI 0x10000000
+#define GL_TEXCOORD2_BIT_PGI 0x20000000
+#define GL_TEXCOORD3_BIT_PGI 0x40000000
+#define GL_TEXCOORD4_BIT_PGI 0x80000000
+#define GL_VERTEX23_BIT_PGI 0x00000004
+#define GL_VERTEX4_BIT_PGI 0x00000008
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8
+#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD
+#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE
+#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202
+#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203
+#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204
+#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C
+#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D
+#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E
+#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F
+#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210
+#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211
+#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216
+#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217
+#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218
+#define GL_FULL_STIPPLE_HINT_PGI 0x1A219
+#define GL_CLIP_NEAR_HINT_PGI 0x1A220
+#define GL_CLIP_FAR_HINT_PGI 0x1A221
+#define GL_WIDE_LINE_HINT_PGI 0x1A222
+#define GL_BACK_NORMALS_HINT_PGI 0x1A223
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_COLOR_INDEX1_EXT 0x80E2
+#define GL_COLOR_INDEX2_EXT 0x80E3
+#define GL_COLOR_INDEX4_EXT 0x80E4
+#define GL_COLOR_INDEX8_EXT 0x80E5
+#define GL_COLOR_INDEX12_EXT 0x80E6
+#define GL_COLOR_INDEX16_EXT 0x80E7
+#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_LIST_PRIORITY_SGIX 0x8182
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_IR_INSTRUMENT1_SGIX 0x817F
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E
+#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F
+#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SHADOW_AMBIENT_SGIX 0x80BF
+#endif
+
+#ifndef GL_EXT_index_texture
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_INDEX_MATERIAL_EXT 0x81B8
+#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9
+#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_INDEX_TEST_EXT 0x81B5
+#define GL_INDEX_TEST_FUNC_EXT 0x81B6
+#define GL_INDEX_TEST_REF_EXT 0x81B7
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_IUI_V2F_EXT 0x81AD
+#define GL_IUI_V3F_EXT 0x81AE
+#define GL_IUI_N3F_V2F_EXT 0x81AF
+#define GL_IUI_N3F_V3F_EXT 0x81B0
+#define GL_T2F_IUI_V2F_EXT 0x81B1
+#define GL_T2F_IUI_V3F_EXT 0x81B2
+#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3
+#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8
+#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_CULL_VERTEX_EXT 0x81AA
+#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB
+#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_YCRCB_422_SGIX 0x81BB
+#define GL_YCRCB_444_SGIX 0x81BC
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_FRAGMENT_LIGHTING_SGIX 0x8400
+#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401
+#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402
+#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403
+#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404
+#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405
+#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406
+#define GL_LIGHT_ENV_MODE_SGIX 0x8407
+#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408
+#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409
+#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A
+#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B
+#define GL_FRAGMENT_LIGHT0_SGIX 0x840C
+#define GL_FRAGMENT_LIGHT1_SGIX 0x840D
+#define GL_FRAGMENT_LIGHT2_SGIX 0x840E
+#define GL_FRAGMENT_LIGHT3_SGIX 0x840F
+#define GL_FRAGMENT_LIGHT4_SGIX 0x8410
+#define GL_FRAGMENT_LIGHT5_SGIX 0x8411
+#define GL_FRAGMENT_LIGHT6_SGIX 0x8412
+#define GL_FRAGMENT_LIGHT7_SGIX 0x8413
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167
+#define GL_TEXTURE_POST_SPECULAR_HP 0x8168
+#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8
+#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_PHONG_WIN 0x80EA
+#define GL_PHONG_HINT_WIN 0x80EB
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_FRAGMENT_MATERIAL_EXT 0x8349
+#define GL_FRAGMENT_NORMAL_EXT 0x834A
+#define GL_FRAGMENT_COLOR_EXT 0x834C
+#define GL_ATTENUATION_EXT 0x834D
+#define GL_SHADOW_ATTENUATION_EXT 0x834E
+#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F
+#define GL_TEXTURE_LIGHT_EXT 0x8350
+#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351
+#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352
+/* reuse GL_FRAGMENT_DEPTH_EXT */
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_ALPHA_MIN_SGIX 0x8320
+#define GL_ALPHA_MAX_SGIX 0x8321
+#endif
+
+#ifndef GL_SGIX_impact_pixel_texture
+#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184
+#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185
+#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186
+#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187
+#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188
+#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189
+#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_BGR_EXT 0x80E0
+#define GL_BGRA_EXT 0x80E1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_ASYNC_MARKER_SGIX 0x8329
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C
+#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D
+#define GL_ASYNC_READ_PIXELS_SGIX 0x835E
+#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F
+#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360
+#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_ASYNC_HISTOGRAM_SGIX 0x832C
+#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D
+#endif
+
+#ifndef GL_INTEL_texture_scissor
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_PARALLEL_ARRAYS_INTEL 0x83F4
+#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5
+#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6
+#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7
+#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_OCCLUSION_TEST_HP 0x8165
+#define GL_OCCLUSION_TEST_RESULT_HP 0x8166
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330
+#define GL_PIXEL_MAG_FILTER_EXT 0x8331
+#define GL_PIXEL_MIN_FILTER_EXT 0x8332
+#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333
+#define GL_CUBIC_EXT 0x8334
+#define GL_AVERAGE_EXT 0x8335
+#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336
+#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337
+#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8
+#define GL_SINGLE_COLOR_EXT 0x81F9
+#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_COLOR_SUM_EXT 0x8458
+#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459
+#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A
+#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B
+#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C
+#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D
+#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_PERTURB_EXT 0x85AE
+#define GL_TEXTURE_NORMAL_EXT 0x85AF
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
+#define GL_FOG_COORDINATE_EXT 0x8451
+#define GL_FRAGMENT_DEPTH_EXT 0x8452
+#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453
+#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454
+#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455
+#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456
+#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_SCREEN_COORDINATES_REND 0x8490
+#define GL_INVERTED_SCREEN_W_REND 0x8491
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_TANGENT_ARRAY_EXT 0x8439
+#define GL_BINORMAL_ARRAY_EXT 0x843A
+#define GL_CURRENT_TANGENT_EXT 0x843B
+#define GL_CURRENT_BINORMAL_EXT 0x843C
+#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E
+#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F
+#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440
+#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441
+#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442
+#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443
+#define GL_MAP1_TANGENT_EXT 0x8444
+#define GL_MAP2_TANGENT_EXT 0x8445
+#define GL_MAP1_BINORMAL_EXT 0x8446
+#define GL_MAP2_BINORMAL_EXT 0x8447
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_COMBINE_EXT 0x8570
+#define GL_COMBINE_RGB_EXT 0x8571
+#define GL_COMBINE_ALPHA_EXT 0x8572
+#define GL_RGB_SCALE_EXT 0x8573
+#define GL_ADD_SIGNED_EXT 0x8574
+#define GL_INTERPOLATE_EXT 0x8575
+#define GL_CONSTANT_EXT 0x8576
+#define GL_PRIMARY_COLOR_EXT 0x8577
+#define GL_PREVIOUS_EXT 0x8578
+#define GL_SOURCE0_RGB_EXT 0x8580
+#define GL_SOURCE1_RGB_EXT 0x8581
+#define GL_SOURCE2_RGB_EXT 0x8582
+#define GL_SOURCE0_ALPHA_EXT 0x8588
+#define GL_SOURCE1_ALPHA_EXT 0x8589
+#define GL_SOURCE2_ALPHA_EXT 0x858A
+#define GL_OPERAND0_RGB_EXT 0x8590
+#define GL_OPERAND1_RGB_EXT 0x8591
+#define GL_OPERAND2_RGB_EXT 0x8592
+#define GL_OPERAND0_ALPHA_EXT 0x8598
+#define GL_OPERAND1_ALPHA_EXT 0x8599
+#define GL_OPERAND2_ALPHA_EXT 0x859A
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_TRANSFORM_HINT_APPLE 0x85B1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_FOG_SCALE_SGIX 0x81FC
+#define GL_FOG_SCALE_VALUE_SGIX 0x81FD
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5
+#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_GLOBAL_ALPHA_SUN 0x81D9
+#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_RESTART_SUN 0x0001
+#define GL_REPLACE_MIDDLE_SUN 0x0002
+#define GL_REPLACE_OLDEST_SUN 0x0003
+#define GL_TRIANGLE_LIST_SUN 0x81D7
+#define GL_REPLACEMENT_CODE_SUN 0x81D8
+#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0
+#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1
+#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2
+#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3
+#define GL_R1UI_V3F_SUN 0x85C4
+#define GL_R1UI_C4UB_V3F_SUN 0x85C5
+#define GL_R1UI_C3F_V3F_SUN 0x85C6
+#define GL_R1UI_N3F_V3F_SUN 0x85C7
+#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8
+#define GL_R1UI_T2F_V3F_SUN 0x85C9
+#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA
+#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB
+#endif
+
+#ifndef GL_SUN_vertex
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_BLEND_DST_RGB_EXT 0x80C8
+#define GL_BLEND_SRC_RGB_EXT 0x80C9
+#define GL_BLEND_DST_ALPHA_EXT 0x80CA
+#define GL_BLEND_SRC_ALPHA_EXT 0x80CB
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_RED_MIN_CLAMP_INGR 0x8560
+#define GL_GREEN_MIN_CLAMP_INGR 0x8561
+#define GL_BLUE_MIN_CLAMP_INGR 0x8562
+#define GL_ALPHA_MIN_CLAMP_INGR 0x8563
+#define GL_RED_MAX_CLAMP_INGR 0x8564
+#define GL_GREEN_MAX_CLAMP_INGR 0x8565
+#define GL_BLUE_MAX_CLAMP_INGR 0x8566
+#define GL_ALPHA_MAX_CLAMP_INGR 0x8567
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INTERLACE_READ_INGR 0x8568
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_INCR_WRAP_EXT 0x8507
+#define GL_DECR_WRAP_EXT 0x8508
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_422_EXT 0x80CC
+#define GL_422_REV_EXT 0x80CD
+#define GL_422_AVERAGE_EXT 0x80CE
+#define GL_422_REV_AVERAGE_EXT 0x80CF
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NORMAL_MAP_NV 0x8511
+#define GL_REFLECTION_MAP_NV 0x8512
+#endif
+
+#ifndef GL_EXT_texture_cube_map
+#define GL_NORMAL_MAP_EXT 0x8511
+#define GL_REFLECTION_MAP_EXT 0x8512
+#define GL_TEXTURE_CUBE_MAP_EXT 0x8513
+#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518
+#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519
+#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A
+#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B
+#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_WRAP_BORDER_SUN 0x81D4
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT 0x8501
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH
+#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502
+#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX
+#define GL_MODELVIEW1_MATRIX_EXT 0x8506
+#define GL_VERTEX_WEIGHTING_EXT 0x8509
+#define GL_MODELVIEW0_EXT GL_MODELVIEW
+#define GL_MODELVIEW1_EXT 0x850A
+#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B
+#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C
+#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D
+#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E
+#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F
+#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_MAX_SHININESS_NV 0x8504
+#define GL_MAX_SPOT_EXPONENT_NV 0x8505
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E
+#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F
+#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520
+#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_REGISTER_COMBINERS_NV 0x8522
+#define GL_VARIABLE_A_NV 0x8523
+#define GL_VARIABLE_B_NV 0x8524
+#define GL_VARIABLE_C_NV 0x8525
+#define GL_VARIABLE_D_NV 0x8526
+#define GL_VARIABLE_E_NV 0x8527
+#define GL_VARIABLE_F_NV 0x8528
+#define GL_VARIABLE_G_NV 0x8529
+#define GL_CONSTANT_COLOR0_NV 0x852A
+#define GL_CONSTANT_COLOR1_NV 0x852B
+#define GL_PRIMARY_COLOR_NV 0x852C
+#define GL_SECONDARY_COLOR_NV 0x852D
+#define GL_SPARE0_NV 0x852E
+#define GL_SPARE1_NV 0x852F
+#define GL_DISCARD_NV 0x8530
+#define GL_E_TIMES_F_NV 0x8531
+#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532
+#define GL_UNSIGNED_IDENTITY_NV 0x8536
+#define GL_UNSIGNED_INVERT_NV 0x8537
+#define GL_EXPAND_NORMAL_NV 0x8538
+#define GL_EXPAND_NEGATE_NV 0x8539
+#define GL_HALF_BIAS_NORMAL_NV 0x853A
+#define GL_HALF_BIAS_NEGATE_NV 0x853B
+#define GL_SIGNED_IDENTITY_NV 0x853C
+#define GL_SIGNED_NEGATE_NV 0x853D
+#define GL_SCALE_BY_TWO_NV 0x853E
+#define GL_SCALE_BY_FOUR_NV 0x853F
+#define GL_SCALE_BY_ONE_HALF_NV 0x8540
+#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541
+#define GL_COMBINER_INPUT_NV 0x8542
+#define GL_COMBINER_MAPPING_NV 0x8543
+#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544
+#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545
+#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546
+#define GL_COMBINER_MUX_SUM_NV 0x8547
+#define GL_COMBINER_SCALE_NV 0x8548
+#define GL_COMBINER_BIAS_NV 0x8549
+#define GL_COMBINER_AB_OUTPUT_NV 0x854A
+#define GL_COMBINER_CD_OUTPUT_NV 0x854B
+#define GL_COMBINER_SUM_OUTPUT_NV 0x854C
+#define GL_MAX_GENERAL_COMBINERS_NV 0x854D
+#define GL_NUM_GENERAL_COMBINERS_NV 0x854E
+#define GL_COLOR_SUM_CLAMP_NV 0x854F
+#define GL_COMBINER0_NV 0x8550
+#define GL_COMBINER1_NV 0x8551
+#define GL_COMBINER2_NV 0x8552
+#define GL_COMBINER3_NV 0x8553
+#define GL_COMBINER4_NV 0x8554
+#define GL_COMBINER5_NV 0x8555
+#define GL_COMBINER6_NV 0x8556
+#define GL_COMBINER7_NV 0x8557
+/* reuse GL_TEXTURE0_ARB */
+/* reuse GL_TEXTURE1_ARB */
+/* reuse GL_ZERO */
+/* reuse GL_NONE */
+/* reuse GL_FOG */
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_FOG_DISTANCE_MODE_NV 0x855A
+#define GL_EYE_RADIAL_NV 0x855B
+#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C
+/* reuse GL_EYE_PLANE */
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_EMBOSS_LIGHT_NV 0x855D
+#define GL_EMBOSS_CONSTANT_NV 0x855E
+#define GL_EMBOSS_MAP_NV 0x855F
+#endif
+
+#ifndef GL_NV_blend_square
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_COMBINE4_NV 0x8503
+#define GL_SOURCE3_RGB_NV 0x8583
+#define GL_SOURCE3_ALPHA_NV 0x858B
+#define GL_OPERAND3_RGB_NV 0x8593
+#define GL_OPERAND3_ALPHA_NV 0x859B
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#endif
+
+#ifndef GL_MESA_window_pos
+#endif
+
+#ifndef GL_EXT_texture_compression_s3tc
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
+#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_CULL_VERTEX_IBM 103050
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_VERTEX_ARRAY_LIST_IBM 103070
+#define GL_NORMAL_ARRAY_LIST_IBM 103071
+#define GL_COLOR_ARRAY_LIST_IBM 103072
+#define GL_INDEX_ARRAY_LIST_IBM 103073
+#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074
+#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075
+#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076
+#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077
+#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080
+#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081
+#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082
+#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083
+#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084
+#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085
+#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086
+#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0
+#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1
+#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2
+#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3
+#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_YCRCB_SGIX 0x8318
+#define GL_YCRCBA_SGIX 0x8319
+#endif
+
+#ifndef GL_SGI_depth_pass_instrument
+#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310
+#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311
+#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0
+#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_MULTISAMPLE_3DFX 0x86B2
+#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
+#define GL_SAMPLES_3DFX 0x86B4
+#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_MULTISAMPLE_EXT 0x809D
+#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E
+#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F
+#define GL_SAMPLE_MASK_EXT 0x80A0
+#define GL_1PASS_EXT 0x80A1
+#define GL_2PASS_0_EXT 0x80A2
+#define GL_2PASS_1_EXT 0x80A3
+#define GL_4PASS_0_EXT 0x80A4
+#define GL_4PASS_1_EXT 0x80A5
+#define GL_4PASS_2_EXT 0x80A6
+#define GL_4PASS_3_EXT 0x80A7
+#define GL_SAMPLE_BUFFERS_EXT 0x80A8
+#define GL_SAMPLES_EXT 0x80A9
+#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA
+#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB
+#define GL_SAMPLE_PATTERN_EXT 0x80AC
+#define GL_MULTISAMPLE_BIT_EXT 0x20000000
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_VERTEX_PRECLIP_SGIX 0x83EE
+#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_CONVOLUTION_HINT_SGIX 0x8316
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_PACK_RESAMPLE_SGIX 0x842C
+#define GL_UNPACK_RESAMPLE_SGIX 0x842D
+#define GL_RESAMPLE_REPLICATE_SGIX 0x842E
+#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F
+#define GL_RESAMPLE_DECIMATE_SGIX 0x8430
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0
+#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1
+#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2
+#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3
+#define GL_EYE_POINT_SGIS 0x81F4
+#define GL_OBJECT_POINT_SGIS 0x81F5
+#define GL_EYE_LINE_SGIS 0x81F6
+#define GL_OBJECT_LINE_SGIS 0x81F7
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_DOT3_RGB_EXT 0x8740
+#define GL_DOT3_RGBA_EXT 0x8741
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_MIRROR_CLAMP_ATI 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743
+#endif
+
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV 0x84F2
+#define GL_FENCE_STATUS_NV 0x84F3
+#define GL_FENCE_CONDITION_NV 0x84F4
+#endif
+
+#ifndef GL_IBM_texture_mirrored_repeat
+#define GL_MIRRORED_REPEAT_IBM 0x8370
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_EVAL_2D_NV 0x86C0
+#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1
+#define GL_MAP_TESSELLATION_NV 0x86C2
+#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3
+#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4
+#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5
+#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6
+#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7
+#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8
+#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9
+#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA
+#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB
+#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC
+#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD
+#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE
+#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF
+#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0
+#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1
+#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2
+#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3
+#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4
+#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5
+#define GL_MAX_MAP_TESSELLATION_NV 0x86D6
+#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_DEPTH_STENCIL_NV 0x84F9
+#define GL_UNSIGNED_INT_24_8_NV 0x84FA
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_PER_STAGE_CONSTANTS_NV 0x8535
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_TEXTURE_RECTANGLE_NV 0x84F5
+#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6
+#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7
+#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
+#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D
+#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E
+#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9
+#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA
+#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB
+#define GL_DSDT_MAG_INTENSITY_NV 0x86DC
+#define GL_SHADER_CONSISTENT_NV 0x86DD
+#define GL_TEXTURE_SHADER_NV 0x86DE
+#define GL_SHADER_OPERATION_NV 0x86DF
+#define GL_CULL_MODES_NV 0x86E0
+#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1
+#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2
+#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3
+#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV
+#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV
+#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV
+#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4
+#define GL_CONST_EYE_NV 0x86E5
+#define GL_PASS_THROUGH_NV 0x86E6
+#define GL_CULL_FRAGMENT_NV 0x86E7
+#define GL_OFFSET_TEXTURE_2D_NV 0x86E8
+#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9
+#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA
+#define GL_DOT_PRODUCT_NV 0x86EC
+#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED
+#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE
+#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0
+#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1
+#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2
+#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3
+#define GL_HILO_NV 0x86F4
+#define GL_DSDT_NV 0x86F5
+#define GL_DSDT_MAG_NV 0x86F6
+#define GL_DSDT_MAG_VIB_NV 0x86F7
+#define GL_HILO16_NV 0x86F8
+#define GL_SIGNED_HILO_NV 0x86F9
+#define GL_SIGNED_HILO16_NV 0x86FA
+#define GL_SIGNED_RGBA_NV 0x86FB
+#define GL_SIGNED_RGBA8_NV 0x86FC
+#define GL_SIGNED_RGB_NV 0x86FE
+#define GL_SIGNED_RGB8_NV 0x86FF
+#define GL_SIGNED_LUMINANCE_NV 0x8701
+#define GL_SIGNED_LUMINANCE8_NV 0x8702
+#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703
+#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704
+#define GL_SIGNED_ALPHA_NV 0x8705
+#define GL_SIGNED_ALPHA8_NV 0x8706
+#define GL_SIGNED_INTENSITY_NV 0x8707
+#define GL_SIGNED_INTENSITY8_NV 0x8708
+#define GL_DSDT8_NV 0x8709
+#define GL_DSDT8_MAG8_NV 0x870A
+#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B
+#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C
+#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D
+#define GL_HI_SCALE_NV 0x870E
+#define GL_LO_SCALE_NV 0x870F
+#define GL_DS_SCALE_NV 0x8710
+#define GL_DT_SCALE_NV 0x8711
+#define GL_MAGNITUDE_SCALE_NV 0x8712
+#define GL_VIBRANCE_SCALE_NV 0x8713
+#define GL_HI_BIAS_NV 0x8714
+#define GL_LO_BIAS_NV 0x8715
+#define GL_DS_BIAS_NV 0x8716
+#define GL_DT_BIAS_NV 0x8717
+#define GL_MAGNITUDE_BIAS_NV 0x8718
+#define GL_VIBRANCE_BIAS_NV 0x8719
+#define GL_TEXTURE_BORDER_VALUES_NV 0x871A
+#define GL_TEXTURE_HI_SIZE_NV 0x871B
+#define GL_TEXTURE_LO_SIZE_NV 0x871C
+#define GL_TEXTURE_DS_SIZE_NV 0x871D
+#define GL_TEXTURE_DT_SIZE_NV 0x871E
+#define GL_TEXTURE_MAG_SIZE_NV 0x871F
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_VERTEX_PROGRAM_NV 0x8620
+#define GL_VERTEX_STATE_PROGRAM_NV 0x8621
+#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623
+#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624
+#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625
+#define GL_CURRENT_ATTRIB_NV 0x8626
+#define GL_PROGRAM_LENGTH_NV 0x8627
+#define GL_PROGRAM_STRING_NV 0x8628
+#define GL_MODELVIEW_PROJECTION_NV 0x8629
+#define GL_IDENTITY_NV 0x862A
+#define GL_INVERSE_NV 0x862B
+#define GL_TRANSPOSE_NV 0x862C
+#define GL_INVERSE_TRANSPOSE_NV 0x862D
+#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E
+#define GL_MAX_TRACK_MATRICES_NV 0x862F
+#define GL_MATRIX0_NV 0x8630
+#define GL_MATRIX1_NV 0x8631
+#define GL_MATRIX2_NV 0x8632
+#define GL_MATRIX3_NV 0x8633
+#define GL_MATRIX4_NV 0x8634
+#define GL_MATRIX5_NV 0x8635
+#define GL_MATRIX6_NV 0x8636
+#define GL_MATRIX7_NV 0x8637
+#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640
+#define GL_CURRENT_MATRIX_NV 0x8641
+#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642
+#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643
+#define GL_PROGRAM_PARAMETER_NV 0x8644
+#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645
+#define GL_PROGRAM_TARGET_NV 0x8646
+#define GL_PROGRAM_RESIDENT_NV 0x8647
+#define GL_TRACK_MATRIX_NV 0x8648
+#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649
+#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A
+#define GL_PROGRAM_ERROR_POSITION_NV 0x864B
+#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650
+#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651
+#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652
+#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653
+#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654
+#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655
+#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656
+#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657
+#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658
+#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659
+#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A
+#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B
+#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C
+#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D
+#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E
+#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F
+#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660
+#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661
+#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662
+#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663
+#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664
+#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665
+#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666
+#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667
+#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668
+#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669
+#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A
+#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B
+#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C
+#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D
+#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E
+#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F
+#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670
+#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671
+#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672
+#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673
+#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674
+#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675
+#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676
+#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677
+#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678
+#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679
+#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A
+#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B
+#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C
+#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D
+#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E
+#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369
+#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A
+#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SCALEBIAS_HINT_SGIX 0x8322
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_INTERLACE_OML 0x8980
+#define GL_INTERLACE_READ_OML 0x8981
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982
+#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983
+#endif
+
+#ifndef GL_OML_resample
+#define GL_PACK_RESAMPLE_OML 0x8984
+#define GL_UNPACK_RESAMPLE_OML 0x8985
+#define GL_RESAMPLE_REPLICATE_OML 0x8986
+#define GL_RESAMPLE_ZERO_FILL_OML 0x8987
+#define GL_RESAMPLE_AVERAGE_OML 0x8988
+#define GL_RESAMPLE_DECIMATE_OML 0x8989
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
+#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_BUMP_ROT_MATRIX_ATI 0x8775
+#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776
+#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777
+#define GL_BUMP_TEX_UNITS_ATI 0x8778
+#define GL_DUDV_ATI 0x8779
+#define GL_DU8DV8_ATI 0x877A
+#define GL_BUMP_ENVMAP_ATI 0x877B
+#define GL_BUMP_TARGET_ATI 0x877C
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_FRAGMENT_SHADER_ATI 0x8920
+#define GL_REG_0_ATI 0x8921
+#define GL_REG_1_ATI 0x8922
+#define GL_REG_2_ATI 0x8923
+#define GL_REG_3_ATI 0x8924
+#define GL_REG_4_ATI 0x8925
+#define GL_REG_5_ATI 0x8926
+#define GL_REG_6_ATI 0x8927
+#define GL_REG_7_ATI 0x8928
+#define GL_REG_8_ATI 0x8929
+#define GL_REG_9_ATI 0x892A
+#define GL_REG_10_ATI 0x892B
+#define GL_REG_11_ATI 0x892C
+#define GL_REG_12_ATI 0x892D
+#define GL_REG_13_ATI 0x892E
+#define GL_REG_14_ATI 0x892F
+#define GL_REG_15_ATI 0x8930
+#define GL_REG_16_ATI 0x8931
+#define GL_REG_17_ATI 0x8932
+#define GL_REG_18_ATI 0x8933
+#define GL_REG_19_ATI 0x8934
+#define GL_REG_20_ATI 0x8935
+#define GL_REG_21_ATI 0x8936
+#define GL_REG_22_ATI 0x8937
+#define GL_REG_23_ATI 0x8938
+#define GL_REG_24_ATI 0x8939
+#define GL_REG_25_ATI 0x893A
+#define GL_REG_26_ATI 0x893B
+#define GL_REG_27_ATI 0x893C
+#define GL_REG_28_ATI 0x893D
+#define GL_REG_29_ATI 0x893E
+#define GL_REG_30_ATI 0x893F
+#define GL_REG_31_ATI 0x8940
+#define GL_CON_0_ATI 0x8941
+#define GL_CON_1_ATI 0x8942
+#define GL_CON_2_ATI 0x8943
+#define GL_CON_3_ATI 0x8944
+#define GL_CON_4_ATI 0x8945
+#define GL_CON_5_ATI 0x8946
+#define GL_CON_6_ATI 0x8947
+#define GL_CON_7_ATI 0x8948
+#define GL_CON_8_ATI 0x8949
+#define GL_CON_9_ATI 0x894A
+#define GL_CON_10_ATI 0x894B
+#define GL_CON_11_ATI 0x894C
+#define GL_CON_12_ATI 0x894D
+#define GL_CON_13_ATI 0x894E
+#define GL_CON_14_ATI 0x894F
+#define GL_CON_15_ATI 0x8950
+#define GL_CON_16_ATI 0x8951
+#define GL_CON_17_ATI 0x8952
+#define GL_CON_18_ATI 0x8953
+#define GL_CON_19_ATI 0x8954
+#define GL_CON_20_ATI 0x8955
+#define GL_CON_21_ATI 0x8956
+#define GL_CON_22_ATI 0x8957
+#define GL_CON_23_ATI 0x8958
+#define GL_CON_24_ATI 0x8959
+#define GL_CON_25_ATI 0x895A
+#define GL_CON_26_ATI 0x895B
+#define GL_CON_27_ATI 0x895C
+#define GL_CON_28_ATI 0x895D
+#define GL_CON_29_ATI 0x895E
+#define GL_CON_30_ATI 0x895F
+#define GL_CON_31_ATI 0x8960
+#define GL_MOV_ATI 0x8961
+#define GL_ADD_ATI 0x8963
+#define GL_MUL_ATI 0x8964
+#define GL_SUB_ATI 0x8965
+#define GL_DOT3_ATI 0x8966
+#define GL_DOT4_ATI 0x8967
+#define GL_MAD_ATI 0x8968
+#define GL_LERP_ATI 0x8969
+#define GL_CND_ATI 0x896A
+#define GL_CND0_ATI 0x896B
+#define GL_DOT2_ADD_ATI 0x896C
+#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D
+#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E
+#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F
+#define GL_NUM_PASSES_ATI 0x8970
+#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971
+#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972
+#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973
+#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974
+#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975
+#define GL_SWIZZLE_STR_ATI 0x8976
+#define GL_SWIZZLE_STQ_ATI 0x8977
+#define GL_SWIZZLE_STR_DR_ATI 0x8978
+#define GL_SWIZZLE_STQ_DQ_ATI 0x8979
+#define GL_SWIZZLE_STRQ_ATI 0x897A
+#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B
+#define GL_RED_BIT_ATI 0x00000001
+#define GL_GREEN_BIT_ATI 0x00000002
+#define GL_BLUE_BIT_ATI 0x00000004
+#define GL_2X_BIT_ATI 0x00000001
+#define GL_4X_BIT_ATI 0x00000002
+#define GL_8X_BIT_ATI 0x00000004
+#define GL_HALF_BIT_ATI 0x00000008
+#define GL_QUARTER_BIT_ATI 0x00000010
+#define GL_EIGHTH_BIT_ATI 0x00000020
+#define GL_SATURATE_BIT_ATI 0x00000040
+#define GL_COMP_BIT_ATI 0x00000002
+#define GL_NEGATE_BIT_ATI 0x00000004
+#define GL_BIAS_BIT_ATI 0x00000008
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_PN_TRIANGLES_ATI 0x87F0
+#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1
+#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2
+#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3
+#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4
+#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5
+#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6
+#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7
+#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_STATIC_ATI 0x8760
+#define GL_DYNAMIC_ATI 0x8761
+#define GL_PRESERVE_ATI 0x8762
+#define GL_DISCARD_ATI 0x8763
+#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764
+#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765
+#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766
+#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_VERTEX_SHADER_EXT 0x8780
+#define GL_VERTEX_SHADER_BINDING_EXT 0x8781
+#define GL_OP_INDEX_EXT 0x8782
+#define GL_OP_NEGATE_EXT 0x8783
+#define GL_OP_DOT3_EXT 0x8784
+#define GL_OP_DOT4_EXT 0x8785
+#define GL_OP_MUL_EXT 0x8786
+#define GL_OP_ADD_EXT 0x8787
+#define GL_OP_MADD_EXT 0x8788
+#define GL_OP_FRAC_EXT 0x8789
+#define GL_OP_MAX_EXT 0x878A
+#define GL_OP_MIN_EXT 0x878B
+#define GL_OP_SET_GE_EXT 0x878C
+#define GL_OP_SET_LT_EXT 0x878D
+#define GL_OP_CLAMP_EXT 0x878E
+#define GL_OP_FLOOR_EXT 0x878F
+#define GL_OP_ROUND_EXT 0x8790
+#define GL_OP_EXP_BASE_2_EXT 0x8791
+#define GL_OP_LOG_BASE_2_EXT 0x8792
+#define GL_OP_POWER_EXT 0x8793
+#define GL_OP_RECIP_EXT 0x8794
+#define GL_OP_RECIP_SQRT_EXT 0x8795
+#define GL_OP_SUB_EXT 0x8796
+#define GL_OP_CROSS_PRODUCT_EXT 0x8797
+#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798
+#define GL_OP_MOV_EXT 0x8799
+#define GL_OUTPUT_VERTEX_EXT 0x879A
+#define GL_OUTPUT_COLOR0_EXT 0x879B
+#define GL_OUTPUT_COLOR1_EXT 0x879C
+#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D
+#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E
+#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F
+#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0
+#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1
+#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2
+#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3
+#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4
+#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5
+#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6
+#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7
+#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8
+#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9
+#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA
+#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB
+#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC
+#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD
+#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE
+#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF
+#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0
+#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1
+#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2
+#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3
+#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4
+#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5
+#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6
+#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7
+#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8
+#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9
+#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA
+#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB
+#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC
+#define GL_OUTPUT_FOG_EXT 0x87BD
+#define GL_SCALAR_EXT 0x87BE
+#define GL_VECTOR_EXT 0x87BF
+#define GL_MATRIX_EXT 0x87C0
+#define GL_VARIANT_EXT 0x87C1
+#define GL_INVARIANT_EXT 0x87C2
+#define GL_LOCAL_CONSTANT_EXT 0x87C3
+#define GL_LOCAL_EXT 0x87C4
+#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5
+#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6
+#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7
+#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8
+#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD
+#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE
+#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF
+#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0
+#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1
+#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2
+#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3
+#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4
+#define GL_X_EXT 0x87D5
+#define GL_Y_EXT 0x87D6
+#define GL_Z_EXT 0x87D7
+#define GL_W_EXT 0x87D8
+#define GL_NEGATIVE_X_EXT 0x87D9
+#define GL_NEGATIVE_Y_EXT 0x87DA
+#define GL_NEGATIVE_Z_EXT 0x87DB
+#define GL_NEGATIVE_W_EXT 0x87DC
+#define GL_ZERO_EXT 0x87DD
+#define GL_ONE_EXT 0x87DE
+#define GL_NEGATIVE_ONE_EXT 0x87DF
+#define GL_NORMALIZED_RANGE_EXT 0x87E0
+#define GL_FULL_RANGE_EXT 0x87E1
+#define GL_CURRENT_VERTEX_EXT 0x87E2
+#define GL_MVP_MATRIX_EXT 0x87E3
+#define GL_VARIANT_VALUE_EXT 0x87E4
+#define GL_VARIANT_DATATYPE_EXT 0x87E5
+#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6
+#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7
+#define GL_VARIANT_ARRAY_EXT 0x87E8
+#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9
+#define GL_INVARIANT_VALUE_EXT 0x87EA
+#define GL_INVARIANT_DATATYPE_EXT 0x87EB
+#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC
+#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_MAX_VERTEX_STREAMS_ATI 0x876B
+#define GL_VERTEX_STREAM0_ATI 0x876C
+#define GL_VERTEX_STREAM1_ATI 0x876D
+#define GL_VERTEX_STREAM2_ATI 0x876E
+#define GL_VERTEX_STREAM3_ATI 0x876F
+#define GL_VERTEX_STREAM4_ATI 0x8770
+#define GL_VERTEX_STREAM5_ATI 0x8771
+#define GL_VERTEX_STREAM6_ATI 0x8772
+#define GL_VERTEX_STREAM7_ATI 0x8773
+#define GL_VERTEX_SOURCE_ATI 0x8774
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ELEMENT_ARRAY_ATI 0x8768
+#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769
+#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_QUAD_MESH_SUN 0x8614
+#define GL_TRIANGLE_MESH_SUN 0x8615
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SLICE_ACCUM_SUN 0x85CC
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_DEPTH_CLAMP_NV 0x864F
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_PIXEL_COUNTER_BITS_NV 0x8864
+#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
+#define GL_PIXEL_COUNT_NV 0x8866
+#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_POINT_SPRITE_NV 0x8861
+#define GL_COORD_REPLACE_NV 0x8862
+#define GL_POINT_SPRITE_R_MODE_NV 0x8863
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850
+#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852
+#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853
+#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854
+#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856
+#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857
+#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858
+#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859
+#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A
+#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B
+#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C
+#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D
+#define GL_HILO8_NV 0x885E
+#define GL_SIGNED_HILO8_NV 0x885F
+#define GL_FORCE_BLUE_TO_ONE_NV 0x8860
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910
+#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_ELEMENT_ARRAY_APPLE 0x8768
+#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8769
+#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x876A
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_DRAW_PIXELS_APPLE 0x8A0A
+#define GL_FENCE_APPLE 0x8A0B
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D
+#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E
+#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F
+#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521
+#define GL_STORAGE_CACHED_APPLE 0x85BE
+#define GL_STORAGE_SHARED_APPLE 0x85BF
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_YCBCR_422_APPLE 0x85B9
+#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_RGB_S3TC 0x83A0
+#define GL_RGB4_S3TC 0x83A1
+#define GL_RGBA_S3TC 0x83A2
+#define GL_RGBA4_S3TC 0x83A3
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_ATI 0x8824
+#define GL_DRAW_BUFFER0_ATI 0x8825
+#define GL_DRAW_BUFFER1_ATI 0x8826
+#define GL_DRAW_BUFFER2_ATI 0x8827
+#define GL_DRAW_BUFFER3_ATI 0x8828
+#define GL_DRAW_BUFFER4_ATI 0x8829
+#define GL_DRAW_BUFFER5_ATI 0x882A
+#define GL_DRAW_BUFFER6_ATI 0x882B
+#define GL_DRAW_BUFFER7_ATI 0x882C
+#define GL_DRAW_BUFFER8_ATI 0x882D
+#define GL_DRAW_BUFFER9_ATI 0x882E
+#define GL_DRAW_BUFFER10_ATI 0x882F
+#define GL_DRAW_BUFFER11_ATI 0x8830
+#define GL_DRAW_BUFFER12_ATI 0x8831
+#define GL_DRAW_BUFFER13_ATI 0x8832
+#define GL_DRAW_BUFFER14_ATI 0x8833
+#define GL_DRAW_BUFFER15_ATI 0x8834
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_TYPE_RGBA_FLOAT_ATI 0x8820
+#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_MODULATE_ADD_ATI 0x8744
+#define GL_MODULATE_SIGNED_ADD_ATI 0x8745
+#define GL_MODULATE_SUBTRACT_ATI 0x8746
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_RGBA_FLOAT32_ATI 0x8814
+#define GL_RGB_FLOAT32_ATI 0x8815
+#define GL_ALPHA_FLOAT32_ATI 0x8816
+#define GL_INTENSITY_FLOAT32_ATI 0x8817
+#define GL_LUMINANCE_FLOAT32_ATI 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819
+#define GL_RGBA_FLOAT16_ATI 0x881A
+#define GL_RGB_FLOAT16_ATI 0x881B
+#define GL_ALPHA_FLOAT16_ATI 0x881C
+#define GL_INTENSITY_FLOAT16_ATI 0x881D
+#define GL_LUMINANCE_FLOAT16_ATI 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_FLOAT_R_NV 0x8880
+#define GL_FLOAT_RG_NV 0x8881
+#define GL_FLOAT_RGB_NV 0x8882
+#define GL_FLOAT_RGBA_NV 0x8883
+#define GL_FLOAT_R16_NV 0x8884
+#define GL_FLOAT_R32_NV 0x8885
+#define GL_FLOAT_RG16_NV 0x8886
+#define GL_FLOAT_RG32_NV 0x8887
+#define GL_FLOAT_RGB16_NV 0x8888
+#define GL_FLOAT_RGB32_NV 0x8889
+#define GL_FLOAT_RGBA16_NV 0x888A
+#define GL_FLOAT_RGBA32_NV 0x888B
+#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C
+#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D
+#define GL_FLOAT_RGBA_MODE_NV 0x888E
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868
+#define GL_FRAGMENT_PROGRAM_NV 0x8870
+#define GL_MAX_TEXTURE_COORDS_NV 0x8871
+#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872
+#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873
+#define GL_PROGRAM_ERROR_STRING_NV 0x8874
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_HALF_FLOAT_NV 0x140B
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878
+#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879
+#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A
+#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B
+#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C
+#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_PRIMITIVE_RESTART_NV 0x8558
+#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F
+#endif
+
+#ifndef GL_NV_vertex_program2
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_STENCIL_BACK_FUNC_ATI 0x8800
+#define GL_STENCIL_BACK_FAIL_ATI 0x8801
+#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802
+#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A
+#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890
+#define GL_DEPTH_BOUNDS_EXT 0x8891
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_MIRROR_CLAMP_EXT 0x8742
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_BLEND_EQUATION_RGB_EXT GL_BLEND_EQUATION
+#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_PACK_INVERT_MESA 0x8758
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA
+#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB
+#define GL_YCBCR_MESA 0x8757
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4
+#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5
+#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6
+#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7
+#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */
+#endif
+
+#ifndef GL_NV_vertex_program3
+/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
+#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
+#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
+#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
+#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4
+#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
+#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
+#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
+#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
+#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
+#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB
+#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC
+#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
+#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
+#define GL_FRAMEBUFFER_EXT 0x8D40
+#define GL_RENDERBUFFER_EXT 0x8D41
+#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
+#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
+#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
+#define GL_STENCIL_INDEX1_EXT 0x8D46
+#define GL_STENCIL_INDEX4_EXT 0x8D47
+#define GL_STENCIL_INDEX8_EXT 0x8D48
+#define GL_STENCIL_INDEX16_EXT 0x8D49
+#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
+#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
+#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
+#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
+#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
+#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_DEPTH_STENCIL_EXT 0x84F9
+#define GL_UNSIGNED_INT_24_8_EXT 0x84FA
+#define GL_DEPTH24_STENCIL8_EXT 0x88F0
+#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_STENCIL_TAG_BITS_EXT 0x88F2
+#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_SRGB_EXT 0x8C40
+#define GL_SRGB8_EXT 0x8C41
+#define GL_SRGB_ALPHA_EXT 0x8C42
+#define GL_SRGB8_ALPHA8_EXT 0x8C43
+#define GL_SLUMINANCE_ALPHA_EXT 0x8C44
+#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45
+#define GL_SLUMINANCE_EXT 0x8C46
+#define GL_SLUMINANCE8_EXT 0x8C47
+#define GL_COMPRESSED_SRGB_EXT 0x8C48
+#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49
+#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A
+#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
+#define GL_READ_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CAA
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
+#define GL_MAX_SAMPLES_EXT 0x8D57
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_TEXTURE_1D_STACK_MESAX 0x8759
+#define GL_TEXTURE_2D_STACK_MESAX 0x875A
+#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B
+#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C
+#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D
+#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_TIME_ELAPSED_EXT 0x88BF
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12
+#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904
+#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905
+#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906
+#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907
+#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908
+#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909
+#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5
+#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_LINES_ADJACENCY_EXT 0x000A
+#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B
+#define GL_TRIANGLES_ADJACENCY_EXT 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D
+#define GL_GEOMETRY_PROGRAM_NV 0x8C26
+#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27
+#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28
+#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA
+#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB
+#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9
+#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4
+#define GL_PROGRAM_POINT_SIZE_EXT 0x8642
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_GEOMETRY_SHADER_EXT 0x8DD9
+/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */
+/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */
+/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */
+/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */
+#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD
+#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE
+#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1
+/* reuse GL_LINES_ADJACENCY_EXT */
+/* reuse GL_LINE_STRIP_ADJACENCY_EXT */
+/* reuse GL_TRIANGLES_ADJACENCY_EXT */
+/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */
+/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+/* reuse GL_PROGRAM_POINT_SIZE_EXT */
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0
+#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1
+#define GL_SAMPLER_BUFFER_EXT 0x8DC2
+#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3
+#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4
+#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5
+#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6
+#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7
+#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8
+#define GL_INT_SAMPLER_1D_EXT 0x8DC9
+#define GL_INT_SAMPLER_2D_EXT 0x8DCA
+#define GL_INT_SAMPLER_3D_EXT 0x8DCB
+#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC
+#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD
+#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE
+#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF
+#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0
+#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1
+#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2
+#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4
+#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5
+#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6
+#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7
+#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_R11F_G11F_B10F_EXT 0x8C3A
+#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B
+#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18
+#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19
+#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A
+#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B
+#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C
+#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D
+#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF
+#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_TEXTURE_BUFFER_EXT 0x8C2A
+#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B
+#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C
+#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D
+#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
+#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
+#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
+#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_RGB9_E5_EXT 0x8C3D
+#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E
+#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_DEPTH_COMPONENT32F_NV 0x8DAB
+#define GL_DEPTH32F_STENCIL8_NV 0x8DAC
+#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD
+#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF
+#endif
+
+#ifndef GL_NV_fragment_program4
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB
+#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10
+#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11
+#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
+#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0
+#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1
+#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2
+#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3
+#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_BACK_PRIMARY_COLOR_NV 0x8C77
+#define GL_BACK_SECONDARY_COLOR_NV 0x8C78
+#define GL_TEXTURE_COORD_NV 0x8C79
+#define GL_CLIP_DISTANCE_NV 0x8C7A
+#define GL_VERTEX_ID_NV 0x8C7B
+#define GL_PRIMITIVE_ID_NV 0x8C7C
+#define GL_GENERIC_ATTRIB_NV 0x8C7D
+#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80
+#define GL_ACTIVE_VARYINGS_NV 0x8C81
+#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82
+#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83
+#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84
+#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85
+#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86
+#define GL_PRIMITIVES_GENERATED_NV 0x8C87
+#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88
+#define GL_RASTERIZER_DISCARD_NV 0x8C89
+#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A
+#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B
+#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C
+#define GL_SEPARATE_ATTRIBS_NV 0x8C8D
+#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E
+#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2
+#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3
+#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4
+#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED
+#define GL_UNIFORM_BUFFER_EXT 0x8DEE
+#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_RGBA32UI_EXT 0x8D70
+#define GL_RGB32UI_EXT 0x8D71
+#define GL_ALPHA32UI_EXT 0x8D72
+#define GL_INTENSITY32UI_EXT 0x8D73
+#define GL_LUMINANCE32UI_EXT 0x8D74
+#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75
+#define GL_RGBA16UI_EXT 0x8D76
+#define GL_RGB16UI_EXT 0x8D77
+#define GL_ALPHA16UI_EXT 0x8D78
+#define GL_INTENSITY16UI_EXT 0x8D79
+#define GL_LUMINANCE16UI_EXT 0x8D7A
+#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B
+#define GL_RGBA8UI_EXT 0x8D7C
+#define GL_RGB8UI_EXT 0x8D7D
+#define GL_ALPHA8UI_EXT 0x8D7E
+#define GL_INTENSITY8UI_EXT 0x8D7F
+#define GL_LUMINANCE8UI_EXT 0x8D80
+#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81
+#define GL_RGBA32I_EXT 0x8D82
+#define GL_RGB32I_EXT 0x8D83
+#define GL_ALPHA32I_EXT 0x8D84
+#define GL_INTENSITY32I_EXT 0x8D85
+#define GL_LUMINANCE32I_EXT 0x8D86
+#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87
+#define GL_RGBA16I_EXT 0x8D88
+#define GL_RGB16I_EXT 0x8D89
+#define GL_ALPHA16I_EXT 0x8D8A
+#define GL_INTENSITY16I_EXT 0x8D8B
+#define GL_LUMINANCE16I_EXT 0x8D8C
+#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D
+#define GL_RGBA8I_EXT 0x8D8E
+#define GL_RGB8I_EXT 0x8D8F
+#define GL_ALPHA8I_EXT 0x8D90
+#define GL_INTENSITY8I_EXT 0x8D91
+#define GL_LUMINANCE8I_EXT 0x8D92
+#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93
+#define GL_RED_INTEGER_EXT 0x8D94
+#define GL_GREEN_INTEGER_EXT 0x8D95
+#define GL_BLUE_INTEGER_EXT 0x8D96
+#define GL_ALPHA_INTEGER_EXT 0x8D97
+#define GL_RGB_INTEGER_EXT 0x8D98
+#define GL_RGBA_INTEGER_EXT 0x8D99
+#define GL_BGR_INTEGER_EXT 0x8D9A
+#define GL_BGRA_INTEGER_EXT 0x8D9B
+#define GL_LUMINANCE_INTEGER_EXT 0x8D9C
+#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D
+#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E
+#endif
+
+
+/*************************************************************/
+
+#include <stddef.h>
+#ifndef GL_VERSION_2_0
+/* GL type for program/shader text */
+typedef char GLchar; /* native character */
+#endif
+
+#ifndef GL_VERSION_1_5
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptr;
+typedef ptrdiff_t GLsizeiptr;
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+/* GL types for handling large vertex buffer objects */
+typedef ptrdiff_t GLintptrARB;
+typedef ptrdiff_t GLsizeiptrARB;
+#endif
+
+#ifndef GL_ARB_shader_objects
+/* GL types for handling shader object handles and program/shader text */
+typedef char GLcharARB; /* native character */
+typedef unsigned int GLhandleARB; /* shader object handle */
+#endif
+
+/* GL types for "half" precision (s10e5) float data in host memory */
+#ifndef GL_ARB_half_float_pixel
+typedef unsigned short GLhalfARB;
+#endif
+
+#ifndef GL_NV_half_float
+typedef unsigned short GLhalfNV;
+#endif
+
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GL_EXT_timer_query extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS )
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <inttypes.h> /* Fallback option */
+#endif
+#endif
+
+#ifndef GL_EXT_timer_query
+typedef int64_t GLint64EXT;
+typedef uint64_t GLuint64EXT;
+#endif
+
+#ifndef GL_VERSION_1_2
+#define GL_VERSION_1_2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColor (GLclampf, GLclampf, GLclampf, GLclampf);
+GLAPI void APIENTRY glBlendEquation (GLenum);
+GLAPI void APIENTRY glDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
+GLAPI void APIENTRY glColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glColorTableParameterfv (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glColorTableParameteriv (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei);
+GLAPI void APIENTRY glGetColorTable (GLenum, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetColorTableParameterfv (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetColorTableParameteriv (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei);
+GLAPI void APIENTRY glConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glConvolutionParameterf (GLenum, GLenum, GLfloat);
+GLAPI void APIENTRY glConvolutionParameterfv (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glConvolutionParameteri (GLenum, GLenum, GLint);
+GLAPI void APIENTRY glConvolutionParameteriv (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei);
+GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei);
+GLAPI void APIENTRY glGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *);
+GLAPI void APIENTRY glSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *);
+GLAPI void APIENTRY glGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetHistogramParameterfv (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetHistogramParameteriv (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glHistogram (GLenum, GLsizei, GLenum, GLboolean);
+GLAPI void APIENTRY glMinmax (GLenum, GLenum, GLboolean);
+GLAPI void APIENTRY glResetHistogram (GLenum);
+GLAPI void APIENTRY glResetMinmax (GLenum);
+GLAPI void APIENTRY glTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_VERSION_1_3
+#define GL_VERSION_1_3 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTexture (GLenum);
+GLAPI void APIENTRY glClientActiveTexture (GLenum);
+GLAPI void APIENTRY glMultiTexCoord1d (GLenum, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord1dv (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord1f (GLenum, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord1fv (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord1i (GLenum, GLint);
+GLAPI void APIENTRY glMultiTexCoord1iv (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord1s (GLenum, GLshort);
+GLAPI void APIENTRY glMultiTexCoord1sv (GLenum, const GLshort *);
+GLAPI void APIENTRY glMultiTexCoord2d (GLenum, GLdouble, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord2dv (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord2f (GLenum, GLfloat, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord2fv (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord2i (GLenum, GLint, GLint);
+GLAPI void APIENTRY glMultiTexCoord2iv (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord2s (GLenum, GLshort, GLshort);
+GLAPI void APIENTRY glMultiTexCoord2sv (GLenum, const GLshort *);
+GLAPI void APIENTRY glMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord3dv (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord3fv (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord3i (GLenum, GLint, GLint, GLint);
+GLAPI void APIENTRY glMultiTexCoord3iv (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glMultiTexCoord3sv (GLenum, const GLshort *);
+GLAPI void APIENTRY glMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord4dv (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord4fv (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glMultiTexCoord4iv (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glMultiTexCoord4sv (GLenum, const GLshort *);
+GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *);
+GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *);
+GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *);
+GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *);
+GLAPI void APIENTRY glSampleCoverage (GLclampf, GLboolean);
+GLAPI void APIENTRY glCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glGetCompressedTexImage (GLenum, GLint, GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_VERSION_1_4
+#define GL_VERSION_1_4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glFogCoordf (GLfloat);
+GLAPI void APIENTRY glFogCoordfv (const GLfloat *);
+GLAPI void APIENTRY glFogCoordd (GLdouble);
+GLAPI void APIENTRY glFogCoorddv (const GLdouble *);
+GLAPI void APIENTRY glFogCoordPointer (GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei);
+GLAPI void APIENTRY glMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei);
+GLAPI void APIENTRY glPointParameterf (GLenum, GLfloat);
+GLAPI void APIENTRY glPointParameterfv (GLenum, const GLfloat *);
+GLAPI void APIENTRY glPointParameteri (GLenum, GLint);
+GLAPI void APIENTRY glPointParameteriv (GLenum, const GLint *);
+GLAPI void APIENTRY glSecondaryColor3b (GLbyte, GLbyte, GLbyte);
+GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *);
+GLAPI void APIENTRY glSecondaryColor3d (GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *);
+GLAPI void APIENTRY glSecondaryColor3f (GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *);
+GLAPI void APIENTRY glSecondaryColor3i (GLint, GLint, GLint);
+GLAPI void APIENTRY glSecondaryColor3iv (const GLint *);
+GLAPI void APIENTRY glSecondaryColor3s (GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *);
+GLAPI void APIENTRY glSecondaryColor3ub (GLubyte, GLubyte, GLubyte);
+GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *);
+GLAPI void APIENTRY glSecondaryColor3ui (GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *);
+GLAPI void APIENTRY glSecondaryColor3us (GLushort, GLushort, GLushort);
+GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *);
+GLAPI void APIENTRY glSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glWindowPos2d (GLdouble, GLdouble);
+GLAPI void APIENTRY glWindowPos2dv (const GLdouble *);
+GLAPI void APIENTRY glWindowPos2f (GLfloat, GLfloat);
+GLAPI void APIENTRY glWindowPos2fv (const GLfloat *);
+GLAPI void APIENTRY glWindowPos2i (GLint, GLint);
+GLAPI void APIENTRY glWindowPos2iv (const GLint *);
+GLAPI void APIENTRY glWindowPos2s (GLshort, GLshort);
+GLAPI void APIENTRY glWindowPos2sv (const GLshort *);
+GLAPI void APIENTRY glWindowPos3d (GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glWindowPos3dv (const GLdouble *);
+GLAPI void APIENTRY glWindowPos3f (GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glWindowPos3fv (const GLfloat *);
+GLAPI void APIENTRY glWindowPos3i (GLint, GLint, GLint);
+GLAPI void APIENTRY glWindowPos3iv (const GLint *);
+GLAPI void APIENTRY glWindowPos3s (GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glWindowPos3sv (const GLshort *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_VERSION_1_5
+#define GL_VERSION_1_5 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueries (GLsizei, GLuint *);
+GLAPI void APIENTRY glDeleteQueries (GLsizei, const GLuint *);
+GLAPI GLboolean APIENTRY glIsQuery (GLuint);
+GLAPI void APIENTRY glBeginQuery (GLenum, GLuint);
+GLAPI void APIENTRY glEndQuery (GLenum);
+GLAPI void APIENTRY glGetQueryiv (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetQueryObjectiv (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetQueryObjectuiv (GLuint, GLenum, GLuint *);
+GLAPI void APIENTRY glBindBuffer (GLenum, GLuint);
+GLAPI void APIENTRY glDeleteBuffers (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenBuffers (GLsizei, GLuint *);
+GLAPI GLboolean APIENTRY glIsBuffer (GLuint);
+GLAPI void APIENTRY glBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum);
+GLAPI void APIENTRY glBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *);
+GLAPI void APIENTRY glGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *);
+GLAPI GLvoid* APIENTRY glMapBuffer (GLenum, GLenum);
+GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum);
+GLAPI void APIENTRY glGetBufferParameteriv (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetBufferPointerv (GLenum, GLenum, GLvoid* *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_VERSION_2_0
+#define GL_VERSION_2_0 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparate (GLenum, GLenum);
+GLAPI void APIENTRY glDrawBuffers (GLsizei, const GLenum *);
+GLAPI void APIENTRY glStencilOpSeparate (GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glStencilFuncSeparate (GLenum, GLenum, GLint, GLuint);
+GLAPI void APIENTRY glStencilMaskSeparate (GLenum, GLuint);
+GLAPI void APIENTRY glAttachShader (GLuint, GLuint);
+GLAPI void APIENTRY glBindAttribLocation (GLuint, GLuint, const GLchar *);
+GLAPI void APIENTRY glCompileShader (GLuint);
+GLAPI GLuint APIENTRY glCreateProgram (void);
+GLAPI GLuint APIENTRY glCreateShader (GLenum);
+GLAPI void APIENTRY glDeleteProgram (GLuint);
+GLAPI void APIENTRY glDeleteShader (GLuint);
+GLAPI void APIENTRY glDetachShader (GLuint, GLuint);
+GLAPI void APIENTRY glDisableVertexAttribArray (GLuint);
+GLAPI void APIENTRY glEnableVertexAttribArray (GLuint);
+GLAPI void APIENTRY glGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *);
+GLAPI void APIENTRY glGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *);
+GLAPI void APIENTRY glGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *);
+GLAPI GLint APIENTRY glGetAttribLocation (GLuint, const GLchar *);
+GLAPI void APIENTRY glGetProgramiv (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *);
+GLAPI void APIENTRY glGetShaderiv (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *);
+GLAPI void APIENTRY glGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *);
+GLAPI GLint APIENTRY glGetUniformLocation (GLuint, const GLchar *);
+GLAPI void APIENTRY glGetUniformfv (GLuint, GLint, GLfloat *);
+GLAPI void APIENTRY glGetUniformiv (GLuint, GLint, GLint *);
+GLAPI void APIENTRY glGetVertexAttribdv (GLuint, GLenum, GLdouble *);
+GLAPI void APIENTRY glGetVertexAttribfv (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetVertexAttribiv (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *);
+GLAPI GLboolean APIENTRY glIsProgram (GLuint);
+GLAPI GLboolean APIENTRY glIsShader (GLuint);
+GLAPI void APIENTRY glLinkProgram (GLuint);
+GLAPI void APIENTRY glShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *);
+GLAPI void APIENTRY glUseProgram (GLuint);
+GLAPI void APIENTRY glUniform1f (GLint, GLfloat);
+GLAPI void APIENTRY glUniform2f (GLint, GLfloat, GLfloat);
+GLAPI void APIENTRY glUniform3f (GLint, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glUniform1i (GLint, GLint);
+GLAPI void APIENTRY glUniform2i (GLint, GLint, GLint);
+GLAPI void APIENTRY glUniform3i (GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glUniform4i (GLint, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glUniform1fv (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform2fv (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform3fv (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform4fv (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform1iv (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniform2iv (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniform3iv (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniform4iv (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glValidateProgram (GLuint);
+GLAPI void APIENTRY glVertexAttrib1d (GLuint, GLdouble);
+GLAPI void APIENTRY glVertexAttrib1dv (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib1f (GLuint, GLfloat);
+GLAPI void APIENTRY glVertexAttrib1fv (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib1s (GLuint, GLshort);
+GLAPI void APIENTRY glVertexAttrib1sv (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib2d (GLuint, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib2dv (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib2f (GLuint, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib2fv (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib2s (GLuint, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib2sv (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib3dv (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib3fv (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib3s (GLuint, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib3sv (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint, const GLbyte *);
+GLAPI void APIENTRY glVertexAttrib4Niv (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte);
+GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint, const GLushort *);
+GLAPI void APIENTRY glVertexAttrib4bv (GLuint, const GLbyte *);
+GLAPI void APIENTRY glVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib4dv (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib4fv (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib4iv (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib4sv (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4ubv (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVertexAttrib4uiv (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttrib4usv (GLuint, const GLushort *);
+GLAPI void APIENTRY glVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs);
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask);
+typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name);
+typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
+typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
+typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
+typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader);
+typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_VERSION_2_1
+#define GL_VERSION_2_1 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformMatrix2x3fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix3x2fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix2x4fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix4x2fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix3x4fv (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix4x3fv (GLint, GLsizei, GLboolean, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+#endif
+
+#ifndef GL_ARB_multitexture
+#define GL_ARB_multitexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveTextureARB (GLenum);
+GLAPI void APIENTRY glClientActiveTextureARB (GLenum);
+GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum, GLint);
+GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum, GLshort);
+GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum, const GLshort *);
+GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum, GLdouble, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum, GLfloat, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum, GLint, GLint);
+GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum, GLshort, GLshort);
+GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum, const GLshort *);
+GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum, GLint, GLint, GLint);
+GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum, const GLshort *);
+GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum, const GLdouble *);
+GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum, const GLfloat *);
+GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum, const GLint *);
+GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum, const GLshort *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v);
+#endif
+
+#ifndef GL_ARB_transpose_matrix
+#define GL_ARB_transpose_matrix 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *);
+GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *);
+GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *);
+GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m);
+typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m);
+#endif
+
+#ifndef GL_ARB_multisample
+#define GL_ARB_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleCoverageARB (GLclampf, GLboolean);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert);
+#endif
+
+#ifndef GL_ARB_texture_env_add
+#define GL_ARB_texture_env_add 1
+#endif
+
+#ifndef GL_ARB_texture_cube_map
+#define GL_ARB_texture_cube_map 1
+#endif
+
+#ifndef GL_ARB_texture_compression
+#define GL_ARB_texture_compression 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum, GLint, GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img);
+#endif
+
+#ifndef GL_ARB_texture_border_clamp
+#define GL_ARB_texture_border_clamp 1
+#endif
+
+#ifndef GL_ARB_point_parameters
+#define GL_ARB_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfARB (GLenum, GLfloat);
+GLAPI void APIENTRY glPointParameterfvARB (GLenum, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_ARB_vertex_blend
+#define GL_ARB_vertex_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWeightbvARB (GLint, const GLbyte *);
+GLAPI void APIENTRY glWeightsvARB (GLint, const GLshort *);
+GLAPI void APIENTRY glWeightivARB (GLint, const GLint *);
+GLAPI void APIENTRY glWeightfvARB (GLint, const GLfloat *);
+GLAPI void APIENTRY glWeightdvARB (GLint, const GLdouble *);
+GLAPI void APIENTRY glWeightubvARB (GLint, const GLubyte *);
+GLAPI void APIENTRY glWeightusvARB (GLint, const GLushort *);
+GLAPI void APIENTRY glWeightuivARB (GLint, const GLuint *);
+GLAPI void APIENTRY glWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glVertexBlendARB (GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights);
+typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights);
+typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights);
+typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count);
+#endif
+
+#ifndef GL_ARB_matrix_palette
+#define GL_ARB_matrix_palette 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint);
+GLAPI void APIENTRY glMatrixIndexubvARB (GLint, const GLubyte *);
+GLAPI void APIENTRY glMatrixIndexusvARB (GLint, const GLushort *);
+GLAPI void APIENTRY glMatrixIndexuivARB (GLint, const GLuint *);
+GLAPI void APIENTRY glMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices);
+typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_ARB_texture_env_combine
+#define GL_ARB_texture_env_combine 1
+#endif
+
+#ifndef GL_ARB_texture_env_crossbar
+#define GL_ARB_texture_env_crossbar 1
+#endif
+
+#ifndef GL_ARB_texture_env_dot3
+#define GL_ARB_texture_env_dot3 1
+#endif
+
+#ifndef GL_ARB_texture_mirrored_repeat
+#define GL_ARB_texture_mirrored_repeat 1
+#endif
+
+#ifndef GL_ARB_depth_texture
+#define GL_ARB_depth_texture 1
+#endif
+
+#ifndef GL_ARB_shadow
+#define GL_ARB_shadow 1
+#endif
+
+#ifndef GL_ARB_shadow_ambient
+#define GL_ARB_shadow_ambient 1
+#endif
+
+#ifndef GL_ARB_window_pos
+#define GL_ARB_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dARB (GLdouble, GLdouble);
+GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *);
+GLAPI void APIENTRY glWindowPos2fARB (GLfloat, GLfloat);
+GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *);
+GLAPI void APIENTRY glWindowPos2iARB (GLint, GLint);
+GLAPI void APIENTRY glWindowPos2ivARB (const GLint *);
+GLAPI void APIENTRY glWindowPos2sARB (GLshort, GLshort);
+GLAPI void APIENTRY glWindowPos2svARB (const GLshort *);
+GLAPI void APIENTRY glWindowPos3dARB (GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *);
+GLAPI void APIENTRY glWindowPos3fARB (GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *);
+GLAPI void APIENTRY glWindowPos3iARB (GLint, GLint, GLint);
+GLAPI void APIENTRY glWindowPos3ivARB (const GLint *);
+GLAPI void APIENTRY glWindowPos3sARB (GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glWindowPos3svARB (const GLshort *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_ARB_vertex_program
+#define GL_ARB_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttrib1dARB (GLuint, GLdouble);
+GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib1fARB (GLuint, GLfloat);
+GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib1sARB (GLuint, GLshort);
+GLAPI void APIENTRY glVertexAttrib1svARB (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib2dARB (GLuint, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib2fARB (GLuint, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib2sARB (GLuint, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib2svARB (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib3svARB (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint, const GLbyte *);
+GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte);
+GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint, const GLushort *);
+GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint, const GLbyte *);
+GLAPI void APIENTRY glVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib4svARB (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint, const GLushort *);
+GLAPI void APIENTRY glVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint);
+GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint);
+GLAPI void APIENTRY glProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glBindProgramARB (GLenum, GLuint);
+GLAPI void APIENTRY glDeleteProgramsARB (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenProgramsARB (GLsizei, GLuint *);
+GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *);
+GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *);
+GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *);
+GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *);
+GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *);
+GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *);
+GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *);
+GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *);
+GLAPI void APIENTRY glGetProgramivARB (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetProgramStringARB (GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint, GLenum, GLdouble *);
+GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetVertexAttribivARB (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *);
+GLAPI GLboolean APIENTRY glIsProgramARB (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index);
+typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string);
+typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program);
+#endif
+
+#ifndef GL_ARB_fragment_program
+#define GL_ARB_fragment_program 1
+/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */
+#endif
+
+#ifndef GL_ARB_vertex_buffer_object
+#define GL_ARB_vertex_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindBufferARB (GLenum, GLuint);
+GLAPI void APIENTRY glDeleteBuffersARB (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenBuffersARB (GLsizei, GLuint *);
+GLAPI GLboolean APIENTRY glIsBufferARB (GLuint);
+GLAPI void APIENTRY glBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum);
+GLAPI void APIENTRY glBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *);
+GLAPI void APIENTRY glGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *);
+GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum, GLenum);
+GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum);
+GLAPI void APIENTRY glGetBufferParameterivARB (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
+typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
+typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
+typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
+typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data);
+typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access);
+typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_ARB_occlusion_query
+#define GL_ARB_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueriesARB (GLsizei, GLuint *);
+GLAPI void APIENTRY glDeleteQueriesARB (GLsizei, const GLuint *);
+GLAPI GLboolean APIENTRY glIsQueryARB (GLuint);
+GLAPI void APIENTRY glBeginQueryARB (GLenum, GLuint);
+GLAPI void APIENTRY glEndQueryARB (GLenum);
+GLAPI void APIENTRY glGetQueryivARB (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetQueryObjectivARB (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint, GLenum, GLuint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_ARB_shader_objects
+#define GL_ARB_shader_objects 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB);
+GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum);
+GLAPI void APIENTRY glDetachObjectARB (GLhandleARB, GLhandleARB);
+GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum);
+GLAPI void APIENTRY glShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
+GLAPI void APIENTRY glCompileShaderARB (GLhandleARB);
+GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void);
+GLAPI void APIENTRY glAttachObjectARB (GLhandleARB, GLhandleARB);
+GLAPI void APIENTRY glLinkProgramARB (GLhandleARB);
+GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB);
+GLAPI void APIENTRY glValidateProgramARB (GLhandleARB);
+GLAPI void APIENTRY glUniform1fARB (GLint, GLfloat);
+GLAPI void APIENTRY glUniform2fARB (GLint, GLfloat, GLfloat);
+GLAPI void APIENTRY glUniform3fARB (GLint, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glUniform1iARB (GLint, GLint);
+GLAPI void APIENTRY glUniform2iARB (GLint, GLint, GLint);
+GLAPI void APIENTRY glUniform3iARB (GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glUniform4iARB (GLint, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glUniform1fvARB (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform2fvARB (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform3fvARB (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform4fvARB (GLint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glUniform1ivARB (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniform2ivARB (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniform3ivARB (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniform4ivARB (GLint, GLsizei, const GLint *);
+GLAPI void APIENTRY glUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB, GLenum, GLint *);
+GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
+GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB, const GLcharARB *);
+GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB, GLint, GLfloat *);
+GLAPI void APIENTRY glGetUniformivARB (GLhandleARB, GLint, GLint *);
+GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj);
+typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType);
+typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length);
+typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj);
+typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void);
+typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj);
+typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj);
+typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0);
+typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1);
+typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog);
+typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params);
+typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source);
+#endif
+
+#ifndef GL_ARB_vertex_shader
+#define GL_ARB_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *);
+GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB, const GLcharARB *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name);
+typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name);
+typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name);
+#endif
+
+#ifndef GL_ARB_fragment_shader
+#define GL_ARB_fragment_shader 1
+#endif
+
+#ifndef GL_ARB_shading_language_100
+#define GL_ARB_shading_language_100 1
+#endif
+
+#ifndef GL_ARB_texture_non_power_of_two
+#define GL_ARB_texture_non_power_of_two 1
+#endif
+
+#ifndef GL_ARB_point_sprite
+#define GL_ARB_point_sprite 1
+#endif
+
+#ifndef GL_ARB_fragment_program_shadow
+#define GL_ARB_fragment_program_shadow 1
+#endif
+
+#ifndef GL_ARB_draw_buffers
+#define GL_ARB_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersARB (GLsizei, const GLenum *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ARB_texture_rectangle
+#define GL_ARB_texture_rectangle 1
+#endif
+
+#ifndef GL_ARB_color_buffer_float
+#define GL_ARB_color_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glClampColorARB (GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp);
+#endif
+
+#ifndef GL_ARB_half_float_pixel
+#define GL_ARB_half_float_pixel 1
+#endif
+
+#ifndef GL_ARB_texture_float
+#define GL_ARB_texture_float 1
+#endif
+
+#ifndef GL_ARB_pixel_buffer_object
+#define GL_ARB_pixel_buffer_object 1
+#endif
+
+#ifndef GL_EXT_abgr
+#define GL_EXT_abgr 1
+#endif
+
+#ifndef GL_EXT_blend_color
+#define GL_EXT_blend_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+#endif
+
+#ifndef GL_EXT_polygon_offset
+#define GL_EXT_polygon_offset 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat, GLfloat);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias);
+#endif
+
+#ifndef GL_EXT_texture
+#define GL_EXT_texture 1
+#endif
+
+#ifndef GL_EXT_texture3D
+#define GL_EXT_texture3D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGIS_texture_filter4
+#define GL_SGIS_texture_filter4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights);
+typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights);
+#endif
+
+#ifndef GL_EXT_subtexture
+#define GL_EXT_subtexture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_EXT_copy_texture
+#define GL_EXT_copy_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint);
+GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
+GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei);
+GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_histogram
+#define GL_EXT_histogram 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glHistogramEXT (GLenum, GLsizei, GLenum, GLboolean);
+GLAPI void APIENTRY glMinmaxEXT (GLenum, GLenum, GLboolean);
+GLAPI void APIENTRY glResetHistogramEXT (GLenum);
+GLAPI void APIENTRY glResetMinmaxEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink);
+typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_EXT_convolution
+#define GL_EXT_convolution 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum, GLenum, GLfloat);
+GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum, GLenum, GLint);
+GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei);
+GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei);
+GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *);
+GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params);
+typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span);
+typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column);
+#endif
+
+#ifndef GL_SGI_color_matrix
+#define GL_SGI_color_matrix 1
+#endif
+
+#ifndef GL_SGI_color_table
+#define GL_SGI_color_table 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glColorTableParameterivSGI (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei);
+GLAPI void APIENTRY glGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum, GLenum, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width);
+typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_SGIX_pixel_texture
+#define GL_SGIX_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenSGIX (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_SGIS_pixel_texture
+#define GL_SGIS_pixel_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum, GLint);
+GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum, const GLint *);
+GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum, GLfloat);
+GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum, const GLfloat *);
+GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum, GLint *);
+GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_texture4D
+#define GL_SGIS_texture4D 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
+typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels);
+#endif
+
+#ifndef GL_SGI_texture_color_table
+#define GL_SGI_texture_color_table 1
+#endif
+
+#ifndef GL_EXT_cmyka
+#define GL_EXT_cmyka 1
+#endif
+
+#ifndef GL_EXT_texture_object
+#define GL_EXT_texture_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *);
+GLAPI void APIENTRY glBindTextureEXT (GLenum, GLuint);
+GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenTexturesEXT (GLsizei, GLuint *);
+GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint);
+GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture);
+typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures);
+typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures);
+typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture);
+typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities);
+#endif
+
+#ifndef GL_SGIS_detail_texture
+#define GL_SGIS_detail_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_SGIS_sharpen_texture
+#define GL_SGIS_sharpen_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points);
+#endif
+
+#ifndef GL_EXT_packed_pixels
+#define GL_EXT_packed_pixels 1
+#endif
+
+#ifndef GL_SGIS_texture_lod
+#define GL_SGIS_texture_lod 1
+#endif
+
+#ifndef GL_SGIS_multisample
+#define GL_SGIS_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskSGIS (GLclampf, GLboolean);
+GLAPI void APIENTRY glSamplePatternSGIS (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_EXT_rescale_normal
+#define GL_EXT_rescale_normal 1
+#endif
+
+#ifndef GL_EXT_vertex_array
+#define GL_EXT_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glArrayElementEXT (GLint);
+GLAPI void APIENTRY glColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glDrawArraysEXT (GLenum, GLint, GLsizei);
+GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *);
+GLAPI void APIENTRY glGetPointervEXT (GLenum, GLvoid* *);
+GLAPI void APIENTRY glIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i);
+typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer);
+typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params);
+typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_misc_attribute
+#define GL_EXT_misc_attribute 1
+#endif
+
+#ifndef GL_SGIS_generate_mipmap
+#define GL_SGIS_generate_mipmap 1
+#endif
+
+#ifndef GL_SGIX_clipmap
+#define GL_SGIX_clipmap 1
+#endif
+
+#ifndef GL_SGIX_shadow
+#define GL_SGIX_shadow 1
+#endif
+
+#ifndef GL_SGIS_texture_edge_clamp
+#define GL_SGIS_texture_edge_clamp 1
+#endif
+
+#ifndef GL_SGIS_texture_border_clamp
+#define GL_SGIS_texture_border_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_blend_subtract
+#define GL_EXT_blend_subtract 1
+#endif
+
+#ifndef GL_EXT_blend_logic_op
+#define GL_EXT_blend_logic_op 1
+#endif
+
+#ifndef GL_SGIX_interlace
+#define GL_SGIX_interlace 1
+#endif
+
+#ifndef GL_SGIX_pixel_tiles
+#define GL_SGIX_pixel_tiles 1
+#endif
+
+#ifndef GL_SGIX_texture_select
+#define GL_SGIX_texture_select 1
+#endif
+
+#ifndef GL_SGIX_sprite
+#define GL_SGIX_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum, GLfloat);
+GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum, const GLfloat *);
+GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum, GLint);
+GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum, const GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_texture_multi_buffer
+#define GL_SGIX_texture_multi_buffer 1
+#endif
+
+#ifndef GL_EXT_point_parameters
+#define GL_EXT_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfEXT (GLenum, GLfloat);
+GLAPI void APIENTRY glPointParameterfvEXT (GLenum, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIS_point_parameters
+#define GL_SGIS_point_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameterfSGIS (GLenum, GLfloat);
+GLAPI void APIENTRY glPointParameterfvSGIS (GLenum, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_instruments
+#define GL_SGIX_instruments 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glGetInstrumentsSGIX (void);
+GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei, GLint *);
+GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *);
+GLAPI void APIENTRY glReadInstrumentsSGIX (GLint);
+GLAPI void APIENTRY glStartInstrumentsSGIX (void);
+GLAPI void APIENTRY glStopInstrumentsSGIX (GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer);
+typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p);
+typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker);
+typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void);
+typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker);
+#endif
+
+#ifndef GL_SGIX_texture_scale_bias
+#define GL_SGIX_texture_scale_bias 1
+#endif
+
+#ifndef GL_SGIX_framezoom
+#define GL_SGIX_framezoom 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFrameZoomSGIX (GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor);
+#endif
+
+#ifndef GL_SGIX_tag_sample_buffer
+#define GL_SGIX_tag_sample_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTagSampleBufferSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_polynomial_ffd
+#define GL_SGIX_polynomial_ffd 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *);
+GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *);
+GLAPI void APIENTRY glDeformSGIX (GLbitfield);
+GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points);
+typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask);
+typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask);
+#endif
+
+#ifndef GL_SGIX_reference_plane
+#define GL_SGIX_reference_plane 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation);
+#endif
+
+#ifndef GL_SGIX_flush_raster
+#define GL_SGIX_flush_raster 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushRasterSGIX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void);
+#endif
+
+#ifndef GL_SGIX_depth_texture
+#define GL_SGIX_depth_texture 1
+#endif
+
+#ifndef GL_SGIS_fog_function
+#define GL_SGIS_fog_function 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogFuncSGIS (GLsizei, const GLfloat *);
+GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points);
+typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points);
+#endif
+
+#ifndef GL_SGIX_fog_offset
+#define GL_SGIX_fog_offset 1
+#endif
+
+#ifndef GL_HP_image_transform
+#define GL_HP_image_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImageTransformParameteriHP (GLenum, GLenum, GLint);
+GLAPI void APIENTRY glImageTransformParameterfHP (GLenum, GLenum, GLfloat);
+GLAPI void APIENTRY glImageTransformParameterivHP (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_HP_convolution_border_modes
+#define GL_HP_convolution_border_modes 1
+#endif
+
+#ifndef GL_SGIX_texture_add_env
+#define GL_SGIX_texture_add_env 1
+#endif
+
+#ifndef GL_EXT_color_subtable
+#define GL_EXT_color_subtable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width);
+#endif
+
+#ifndef GL_PGI_vertex_hints
+#define GL_PGI_vertex_hints 1
+#endif
+
+#ifndef GL_PGI_misc_hints
+#define GL_PGI_misc_hints 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glHintPGI (GLenum, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode);
+#endif
+
+#ifndef GL_EXT_paletted_texture
+#define GL_EXT_paletted_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *);
+GLAPI void APIENTRY glGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *);
+GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_EXT_clip_volume_hint
+#define GL_EXT_clip_volume_hint 1
+#endif
+
+#ifndef GL_SGIX_list_priority
+#define GL_SGIX_list_priority 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetListParameterivSGIX (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glListParameterfSGIX (GLuint, GLenum, GLfloat);
+GLAPI void APIENTRY glListParameterfvSGIX (GLuint, GLenum, const GLfloat *);
+GLAPI void APIENTRY glListParameteriSGIX (GLuint, GLenum, GLint);
+GLAPI void APIENTRY glListParameterivSGIX (GLuint, GLenum, const GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_SGIX_ir_instrument1
+#define GL_SGIX_ir_instrument1 1
+#endif
+
+#ifndef GL_SGIX_calligraphic_fragment
+#define GL_SGIX_calligraphic_fragment 1
+#endif
+
+#ifndef GL_SGIX_texture_lod_bias
+#define GL_SGIX_texture_lod_bias 1
+#endif
+
+#ifndef GL_SGIX_shadow_ambient
+#define GL_SGIX_shadow_ambient 1
+#endif
+
+#ifndef GL_EXT_index_texture
+#define GL_EXT_index_texture 1
+#endif
+
+#ifndef GL_EXT_index_material
+#define GL_EXT_index_material 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexMaterialEXT (GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_EXT_index_func
+#define GL_EXT_index_func 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIndexFuncEXT (GLenum, GLclampf);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref);
+#endif
+
+#ifndef GL_EXT_index_array_formats
+#define GL_EXT_index_array_formats 1
+#endif
+
+#ifndef GL_EXT_compiled_vertex_array
+#define GL_EXT_compiled_vertex_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glLockArraysEXT (GLint, GLsizei);
+GLAPI void APIENTRY glUnlockArraysEXT (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void);
+#endif
+
+#ifndef GL_EXT_cull_vertex
+#define GL_EXT_cull_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCullParameterdvEXT (GLenum, GLdouble *);
+GLAPI void APIENTRY glCullParameterfvEXT (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_SGIX_ycrcb
+#define GL_SGIX_ycrcb 1
+#endif
+
+#ifndef GL_SGIX_fragment_lighting
+#define GL_SGIX_fragment_lighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum, GLenum);
+GLAPI void APIENTRY glFragmentLightfSGIX (GLenum, GLenum, GLfloat);
+GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glFragmentLightiSGIX (GLenum, GLenum, GLint);
+GLAPI void APIENTRY glFragmentLightivSGIX (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum, GLfloat);
+GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum, const GLfloat *);
+GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum, GLint);
+GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum, const GLint *);
+GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum, GLenum, GLfloat);
+GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum, GLenum, GLint);
+GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glLightEnviSGIX (GLenum, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_IBM_rasterpos_clip
+#define GL_IBM_rasterpos_clip 1
+#endif
+
+#ifndef GL_HP_texture_lighting
+#define GL_HP_texture_lighting 1
+#endif
+
+#ifndef GL_EXT_draw_range_elements
+#define GL_EXT_draw_range_elements 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
+#endif
+
+#ifndef GL_WIN_phong_shading
+#define GL_WIN_phong_shading 1
+#endif
+
+#ifndef GL_WIN_specular_fog
+#define GL_WIN_specular_fog 1
+#endif
+
+#ifndef GL_EXT_light_texture
+#define GL_EXT_light_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glApplyTextureEXT (GLenum);
+GLAPI void APIENTRY glTextureLightEXT (GLenum);
+GLAPI void APIENTRY glTextureMaterialEXT (GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode);
+typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname);
+typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode);
+#endif
+
+#ifndef GL_SGIX_blend_alpha_minmax
+#define GL_SGIX_blend_alpha_minmax 1
+#endif
+
+#ifndef GL_EXT_bgra
+#define GL_EXT_bgra 1
+#endif
+
+#ifndef GL_SGIX_async
+#define GL_SGIX_async 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint);
+GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *);
+GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *);
+GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei);
+GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint, GLsizei);
+GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker);
+typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp);
+typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp);
+typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range);
+typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range);
+typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker);
+#endif
+
+#ifndef GL_SGIX_async_pixel
+#define GL_SGIX_async_pixel 1
+#endif
+
+#ifndef GL_SGIX_async_histogram
+#define GL_SGIX_async_histogram 1
+#endif
+
+#ifndef GL_INTEL_parallel_arrays
+#define GL_INTEL_parallel_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexPointervINTEL (GLint, GLenum, const GLvoid* *);
+GLAPI void APIENTRY glNormalPointervINTEL (GLenum, const GLvoid* *);
+GLAPI void APIENTRY glColorPointervINTEL (GLint, GLenum, const GLvoid* *);
+GLAPI void APIENTRY glTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_HP_occlusion_test
+#define GL_HP_occlusion_test 1
+#endif
+
+#ifndef GL_EXT_pixel_transform
+#define GL_EXT_pixel_transform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum, GLenum, GLint);
+GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum, GLenum, GLfloat);
+GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params);
+#endif
+
+#ifndef GL_EXT_pixel_transform_color_table
+#define GL_EXT_pixel_transform_color_table 1
+#endif
+
+#ifndef GL_EXT_shared_texture_palette
+#define GL_EXT_shared_texture_palette 1
+#endif
+
+#ifndef GL_EXT_separate_specular_color
+#define GL_EXT_separate_specular_color 1
+#endif
+
+#ifndef GL_EXT_secondary_color
+#define GL_EXT_secondary_color 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte);
+GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *);
+GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *);
+GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *);
+GLAPI void APIENTRY glSecondaryColor3iEXT (GLint, GLint, GLint);
+GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *);
+GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *);
+GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte);
+GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *);
+GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *);
+GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort, GLushort, GLushort);
+GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *);
+GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_perturb_normal
+#define GL_EXT_texture_perturb_normal 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureNormalEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei);
+GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_fog_coord
+#define GL_EXT_fog_coord 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFogCoordfEXT (GLfloat);
+GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *);
+GLAPI void APIENTRY glFogCoorddEXT (GLdouble);
+GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *);
+GLAPI void APIENTRY glFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord);
+typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord);
+typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_REND_screen_coordinates
+#define GL_REND_screen_coordinates 1
+#endif
+
+#ifndef GL_EXT_coordinate_frame
+#define GL_EXT_coordinate_frame 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTangent3bEXT (GLbyte, GLbyte, GLbyte);
+GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *);
+GLAPI void APIENTRY glTangent3dEXT (GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *);
+GLAPI void APIENTRY glTangent3fEXT (GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *);
+GLAPI void APIENTRY glTangent3iEXT (GLint, GLint, GLint);
+GLAPI void APIENTRY glTangent3ivEXT (const GLint *);
+GLAPI void APIENTRY glTangent3sEXT (GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glTangent3svEXT (const GLshort *);
+GLAPI void APIENTRY glBinormal3bEXT (GLbyte, GLbyte, GLbyte);
+GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *);
+GLAPI void APIENTRY glBinormal3dEXT (GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *);
+GLAPI void APIENTRY glBinormal3fEXT (GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *);
+GLAPI void APIENTRY glBinormal3iEXT (GLint, GLint, GLint);
+GLAPI void APIENTRY glBinormal3ivEXT (const GLint *);
+GLAPI void APIENTRY glBinormal3sEXT (GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glBinormal3svEXT (const GLshort *);
+GLAPI void APIENTRY glTangentPointerEXT (GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glBinormalPointerEXT (GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz);
+typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz);
+typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz);
+typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz);
+typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz);
+typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz);
+typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v);
+typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz);
+typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz);
+typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz);
+typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz);
+typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_EXT_texture_env_combine
+#define GL_EXT_texture_env_combine 1
+#endif
+
+#ifndef GL_APPLE_specular_vector
+#define GL_APPLE_specular_vector 1
+#endif
+
+#ifndef GL_APPLE_transform_hint
+#define GL_APPLE_transform_hint 1
+#endif
+
+#ifndef GL_SGIX_fog_scale
+#define GL_SGIX_fog_scale 1
+#endif
+
+#ifndef GL_SUNX_constant_data
+#define GL_SUNX_constant_data 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFinishTextureSUNX (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void);
+#endif
+
+#ifndef GL_SUN_global_alpha
+#define GL_SUN_global_alpha 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte);
+GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort);
+GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint);
+GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat);
+GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble);
+GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte);
+GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort);
+GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor);
+typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor);
+#endif
+
+#ifndef GL_SUN_triangle_list
+#define GL_SUN_triangle_list 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint);
+GLAPI void APIENTRY glReplacementCodeusSUN (GLushort);
+GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte);
+GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *);
+GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *);
+GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *);
+GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer);
+#endif
+
+#ifndef GL_SUN_vertex
+#define GL_SUN_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat);
+GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *);
+GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *);
+GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v);
+#endif
+
+#ifndef GL_EXT_blend_func_separate
+#define GL_EXT_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_blend_func_separate
+#define GL_INGR_blend_func_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+#endif
+
+#ifndef GL_INGR_color_clamp
+#define GL_INGR_color_clamp 1
+#endif
+
+#ifndef GL_INGR_interlace_read
+#define GL_INGR_interlace_read 1
+#endif
+
+#ifndef GL_EXT_stencil_wrap
+#define GL_EXT_stencil_wrap 1
+#endif
+
+#ifndef GL_EXT_422_pixels
+#define GL_EXT_422_pixels 1
+#endif
+
+#ifndef GL_NV_texgen_reflection
+#define GL_NV_texgen_reflection 1
+#endif
+
+#ifndef GL_SUN_convolution_border_modes
+#define GL_SUN_convolution_border_modes 1
+#endif
+
+#ifndef GL_EXT_texture_env_add
+#define GL_EXT_texture_env_add 1
+#endif
+
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
+
+#ifndef GL_EXT_texture_filter_anisotropic
+#define GL_EXT_texture_filter_anisotropic 1
+#endif
+
+#ifndef GL_EXT_vertex_weighting
+#define GL_EXT_vertex_weighting 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexWeightfEXT (GLfloat);
+GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *);
+GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_light_max_exponent
+#define GL_NV_light_max_exponent 1
+#endif
+
+#ifndef GL_NV_vertex_array_range
+#define GL_NV_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFlushVertexArrayRangeNV (void);
+GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void);
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer);
+#endif
+
+#ifndef GL_NV_register_combiners
+#define GL_NV_register_combiners 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerParameterfvNV (GLenum, const GLfloat *);
+GLAPI void APIENTRY glCombinerParameterfNV (GLenum, GLfloat);
+GLAPI void APIENTRY glCombinerParameterivNV (GLenum, const GLint *);
+GLAPI void APIENTRY glCombinerParameteriNV (GLenum, GLint);
+GLAPI void APIENTRY glCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean);
+GLAPI void APIENTRY glFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum);
+typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_NV_fog_distance
+#define GL_NV_fog_distance 1
+#endif
+
+#ifndef GL_NV_texgen_emboss
+#define GL_NV_texgen_emboss 1
+#endif
+
+#ifndef GL_NV_blend_square
+#define GL_NV_blend_square 1
+#endif
+
+#ifndef GL_NV_texture_env_combine4
+#define GL_NV_texture_env_combine4 1
+#endif
+
+#ifndef GL_MESA_resize_buffers
+#define GL_MESA_resize_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glResizeBuffersMESA (void);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void);
+#endif
+
+#ifndef GL_MESA_window_pos
+#define GL_MESA_window_pos 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glWindowPos2dMESA (GLdouble, GLdouble);
+GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *);
+GLAPI void APIENTRY glWindowPos2fMESA (GLfloat, GLfloat);
+GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *);
+GLAPI void APIENTRY glWindowPos2iMESA (GLint, GLint);
+GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *);
+GLAPI void APIENTRY glWindowPos2sMESA (GLshort, GLshort);
+GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *);
+GLAPI void APIENTRY glWindowPos3dMESA (GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *);
+GLAPI void APIENTRY glWindowPos3fMESA (GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *);
+GLAPI void APIENTRY glWindowPos3iMESA (GLint, GLint, GLint);
+GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *);
+GLAPI void APIENTRY glWindowPos3sMESA (GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *);
+GLAPI void APIENTRY glWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *);
+GLAPI void APIENTRY glWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *);
+GLAPI void APIENTRY glWindowPos4iMESA (GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *);
+GLAPI void APIENTRY glWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v);
+#endif
+
+#ifndef GL_IBM_cull_vertex
+#define GL_IBM_cull_vertex 1
+#endif
+
+#ifndef GL_IBM_multimode_draw_arrays
+#define GL_IBM_multimode_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint);
+GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride);
+typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride);
+#endif
+
+#ifndef GL_IBM_vertex_array_lists
+#define GL_IBM_vertex_array_lists 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint);
+GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint);
+GLAPI void APIENTRY glIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint);
+GLAPI void APIENTRY glNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint);
+GLAPI void APIENTRY glTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+GLAPI void APIENTRY glVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride);
+#endif
+
+#ifndef GL_SGIX_subsample
+#define GL_SGIX_subsample 1
+#endif
+
+#ifndef GL_SGIX_ycrcba
+#define GL_SGIX_ycrcba 1
+#endif
+
+#ifndef GL_SGIX_ycrcb_subsample
+#define GL_SGIX_ycrcb_subsample 1
+#endif
+
+#ifndef GL_SGIX_depth_pass_instrument
+#define GL_SGIX_depth_pass_instrument 1
+#endif
+
+#ifndef GL_3DFX_texture_compression_FXT1
+#define GL_3DFX_texture_compression_FXT1 1
+#endif
+
+#ifndef GL_3DFX_multisample
+#define GL_3DFX_multisample 1
+#endif
+
+#ifndef GL_3DFX_tbuffer
+#define GL_3DFX_tbuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTbufferMask3DFX (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask);
+#endif
+
+#ifndef GL_EXT_multisample
+#define GL_EXT_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSampleMaskEXT (GLclampf, GLboolean);
+GLAPI void APIENTRY glSamplePatternEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern);
+#endif
+
+#ifndef GL_SGIX_vertex_preclip
+#define GL_SGIX_vertex_preclip 1
+#endif
+
+#ifndef GL_SGIX_convolution_accuracy
+#define GL_SGIX_convolution_accuracy 1
+#endif
+
+#ifndef GL_SGIX_resample
+#define GL_SGIX_resample 1
+#endif
+
+#ifndef GL_SGIS_point_line_texgen
+#define GL_SGIS_point_line_texgen 1
+#endif
+
+#ifndef GL_SGIS_texture_color_mask
+#define GL_SGIS_texture_color_mask 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+#endif
+
+#ifndef GL_SGIX_igloo_interface
+#define GL_SGIX_igloo_interface 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params);
+#endif
+
+#ifndef GL_EXT_texture_env_dot3
+#define GL_EXT_texture_env_dot3 1
+#endif
+
+#ifndef GL_ATI_texture_mirror_once
+#define GL_ATI_texture_mirror_once 1
+#endif
+
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDeleteFencesNV (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenFencesNV (GLsizei, GLuint *);
+GLAPI GLboolean APIENTRY glIsFenceNV (GLuint);
+GLAPI GLboolean APIENTRY glTestFenceNV (GLuint);
+GLAPI void APIENTRY glGetFenceivNV (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glFinishFenceNV (GLuint);
+GLAPI void APIENTRY glSetFenceNV (GLuint, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+#ifndef GL_NV_evaluators
+#define GL_NV_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *);
+GLAPI void APIENTRY glMapParameterivNV (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glMapParameterfvNV (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *);
+GLAPI void APIENTRY glGetMapParameterivNV (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetMapParameterfvNV (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glEvalMapsNV (GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points);
+typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode);
+#endif
+
+#ifndef GL_NV_packed_depth_stencil
+#define GL_NV_packed_depth_stencil 1
+#endif
+
+#ifndef GL_NV_register_combiners2
+#define GL_NV_register_combiners2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *);
+GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params);
+#endif
+
+#ifndef GL_NV_texture_compression_vtc
+#define GL_NV_texture_compression_vtc 1
+#endif
+
+#ifndef GL_NV_texture_rectangle
+#define GL_NV_texture_rectangle 1
+#endif
+
+#ifndef GL_NV_texture_shader
+#define GL_NV_texture_shader 1
+#endif
+
+#ifndef GL_NV_texture_shader2
+#define GL_NV_texture_shader2 1
+#endif
+
+#ifndef GL_NV_vertex_array_range2
+#define GL_NV_vertex_array_range2 1
+#endif
+
+#ifndef GL_NV_vertex_program
+#define GL_NV_vertex_program 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *);
+GLAPI void APIENTRY glBindProgramNV (GLenum, GLuint);
+GLAPI void APIENTRY glDeleteProgramsNV (GLsizei, const GLuint *);
+GLAPI void APIENTRY glExecuteProgramNV (GLenum, GLuint, const GLfloat *);
+GLAPI void APIENTRY glGenProgramsNV (GLsizei, GLuint *);
+GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *);
+GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetProgramivNV (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetProgramStringNV (GLuint, GLenum, GLubyte *);
+GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint, GLenum, GLdouble *);
+GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetVertexAttribivNV (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *);
+GLAPI GLboolean APIENTRY glIsProgramNV (GLuint);
+GLAPI void APIENTRY glLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *);
+GLAPI void APIENTRY glProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glProgramParameter4dvNV (GLenum, GLuint, const GLdouble *);
+GLAPI void APIENTRY glProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glProgramParameter4fvNV (GLenum, GLuint, const GLfloat *);
+GLAPI void APIENTRY glProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *);
+GLAPI void APIENTRY glProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *);
+GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei, const GLuint *);
+GLAPI void APIENTRY glTrackMatrixNV (GLenum, GLuint, GLenum, GLenum);
+GLAPI void APIENTRY glVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glVertexAttrib1dNV (GLuint, GLdouble);
+GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib1fNV (GLuint, GLfloat);
+GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib1sNV (GLuint, GLshort);
+GLAPI void APIENTRY glVertexAttrib1svNV (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib2dNV (GLuint, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib2fNV (GLuint, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib2sNV (GLuint, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib2svNV (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib3svNV (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexAttrib4svNV (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte);
+GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *);
+GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glVertexAttribs1svNV (GLuint, GLsizei, const GLshort *);
+GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *);
+GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glVertexAttribs2svNV (GLuint, GLsizei, const GLshort *);
+GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *);
+GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glVertexAttribs3svNV (GLuint, GLsizei, const GLshort *);
+GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *);
+GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glVertexAttribs4svNV (GLuint, GLsizei, const GLshort *);
+GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences);
+typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id);
+typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params);
+typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program);
+typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer);
+typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs);
+typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v);
+#endif
+
+#ifndef GL_SGIX_texture_coordinate_clamp
+#define GL_SGIX_texture_coordinate_clamp 1
+#endif
+
+#ifndef GL_SGIX_scalebias_hint
+#define GL_SGIX_scalebias_hint 1
+#endif
+
+#ifndef GL_OML_interlace
+#define GL_OML_interlace 1
+#endif
+
+#ifndef GL_OML_subsample
+#define GL_OML_subsample 1
+#endif
+
+#ifndef GL_OML_resample
+#define GL_OML_resample 1
+#endif
+
+#ifndef GL_NV_copy_depth_to_color
+#define GL_NV_copy_depth_to_color 1
+#endif
+
+#ifndef GL_ATI_envmap_bumpmap
+#define GL_ATI_envmap_bumpmap 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBumpParameterivATI (GLenum, const GLint *);
+GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum, const GLfloat *);
+GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum, GLint *);
+GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param);
+typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param);
+typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param);
+#endif
+
+#ifndef GL_ATI_fragment_shader
+#define GL_ATI_fragment_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint);
+GLAPI void APIENTRY glBindFragmentShaderATI (GLuint);
+GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint);
+GLAPI void APIENTRY glBeginFragmentShaderATI (void);
+GLAPI void APIENTRY glEndFragmentShaderATI (void);
+GLAPI void APIENTRY glPassTexCoordATI (GLuint, GLuint, GLenum);
+GLAPI void APIENTRY glSampleMapATI (GLuint, GLuint, GLenum);
+GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void);
+typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle);
+typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod);
+typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod);
+typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value);
+#endif
+
+#ifndef GL_ATI_pn_triangles
+#define GL_ATI_pn_triangles 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPNTrianglesiATI (GLenum, GLint);
+GLAPI void APIENTRY glPNTrianglesfATI (GLenum, GLfloat);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_vertex_array_object
+#define GL_ATI_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei, const GLvoid *, GLenum);
+GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint);
+GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum);
+GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetObjectBufferivATI (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glFreeObjectBufferATI (GLuint);
+GLAPI void APIENTRY glArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint);
+GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetArrayObjectivATI (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint);
+GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint, GLenum, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage);
+typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_EXT_vertex_shader
+#define GL_EXT_vertex_shader 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginVertexShaderEXT (void);
+GLAPI void APIENTRY glEndVertexShaderEXT (void);
+GLAPI void APIENTRY glBindVertexShaderEXT (GLuint);
+GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint);
+GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint);
+GLAPI void APIENTRY glShaderOp1EXT (GLenum, GLuint, GLuint);
+GLAPI void APIENTRY glShaderOp2EXT (GLenum, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glInsertComponentEXT (GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glExtractComponentEXT (GLuint, GLuint, GLuint);
+GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint);
+GLAPI void APIENTRY glSetInvariantEXT (GLuint, GLenum, const GLvoid *);
+GLAPI void APIENTRY glSetLocalConstantEXT (GLuint, GLenum, const GLvoid *);
+GLAPI void APIENTRY glVariantbvEXT (GLuint, const GLbyte *);
+GLAPI void APIENTRY glVariantsvEXT (GLuint, const GLshort *);
+GLAPI void APIENTRY glVariantivEXT (GLuint, const GLint *);
+GLAPI void APIENTRY glVariantfvEXT (GLuint, const GLfloat *);
+GLAPI void APIENTRY glVariantdvEXT (GLuint, const GLdouble *);
+GLAPI void APIENTRY glVariantubvEXT (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVariantusvEXT (GLuint, const GLushort *);
+GLAPI void APIENTRY glVariantuivEXT (GLuint, const GLuint *);
+GLAPI void APIENTRY glVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *);
+GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint);
+GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint);
+GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum, GLenum);
+GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum, GLenum);
+GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum, GLenum, GLenum);
+GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum, GLenum);
+GLAPI GLuint APIENTRY glBindParameterEXT (GLenum);
+GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint, GLenum);
+GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *);
+GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetVariantPointervEXT (GLuint, GLenum, GLvoid* *);
+GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *);
+GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *);
+GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void);
+typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range);
+typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1);
+typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2);
+typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3);
+typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW);
+typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num);
+typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components);
+typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr);
+typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr);
+typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr);
+typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr);
+typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr);
+typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr);
+typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr);
+typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr);
+typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id);
+typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value);
+typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value);
+typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap);
+typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data);
+typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data);
+#endif
+
+#ifndef GL_ATI_vertex_streams
+#define GL_ATI_vertex_streams 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexStream1sATI (GLenum, GLshort);
+GLAPI void APIENTRY glVertexStream1svATI (GLenum, const GLshort *);
+GLAPI void APIENTRY glVertexStream1iATI (GLenum, GLint);
+GLAPI void APIENTRY glVertexStream1ivATI (GLenum, const GLint *);
+GLAPI void APIENTRY glVertexStream1fATI (GLenum, GLfloat);
+GLAPI void APIENTRY glVertexStream1fvATI (GLenum, const GLfloat *);
+GLAPI void APIENTRY glVertexStream1dATI (GLenum, GLdouble);
+GLAPI void APIENTRY glVertexStream1dvATI (GLenum, const GLdouble *);
+GLAPI void APIENTRY glVertexStream2sATI (GLenum, GLshort, GLshort);
+GLAPI void APIENTRY glVertexStream2svATI (GLenum, const GLshort *);
+GLAPI void APIENTRY glVertexStream2iATI (GLenum, GLint, GLint);
+GLAPI void APIENTRY glVertexStream2ivATI (GLenum, const GLint *);
+GLAPI void APIENTRY glVertexStream2fATI (GLenum, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexStream2fvATI (GLenum, const GLfloat *);
+GLAPI void APIENTRY glVertexStream2dATI (GLenum, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexStream2dvATI (GLenum, const GLdouble *);
+GLAPI void APIENTRY glVertexStream3sATI (GLenum, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexStream3svATI (GLenum, const GLshort *);
+GLAPI void APIENTRY glVertexStream3iATI (GLenum, GLint, GLint, GLint);
+GLAPI void APIENTRY glVertexStream3ivATI (GLenum, const GLint *);
+GLAPI void APIENTRY glVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexStream3fvATI (GLenum, const GLfloat *);
+GLAPI void APIENTRY glVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexStream3dvATI (GLenum, const GLdouble *);
+GLAPI void APIENTRY glVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glVertexStream4svATI (GLenum, const GLshort *);
+GLAPI void APIENTRY glVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glVertexStream4ivATI (GLenum, const GLint *);
+GLAPI void APIENTRY glVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glVertexStream4fvATI (GLenum, const GLfloat *);
+GLAPI void APIENTRY glVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glVertexStream4dvATI (GLenum, const GLdouble *);
+GLAPI void APIENTRY glNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte);
+GLAPI void APIENTRY glNormalStream3bvATI (GLenum, const GLbyte *);
+GLAPI void APIENTRY glNormalStream3sATI (GLenum, GLshort, GLshort, GLshort);
+GLAPI void APIENTRY glNormalStream3svATI (GLenum, const GLshort *);
+GLAPI void APIENTRY glNormalStream3iATI (GLenum, GLint, GLint, GLint);
+GLAPI void APIENTRY glNormalStream3ivATI (GLenum, const GLint *);
+GLAPI void APIENTRY glNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glNormalStream3fvATI (GLenum, const GLfloat *);
+GLAPI void APIENTRY glNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glNormalStream3dvATI (GLenum, const GLdouble *);
+GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum);
+GLAPI void APIENTRY glVertexBlendEnviATI (GLenum, GLint);
+GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum, GLfloat);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz);
+typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords);
+typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param);
+#endif
+
+#ifndef GL_ATI_element_array
+#define GL_ATI_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerATI (GLenum, const GLvoid *);
+GLAPI void APIENTRY glDrawElementArrayATI (GLenum, GLsizei);
+GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count);
+#endif
+
+#ifndef GL_SUN_mesh_array
+#define GL_SUN_mesh_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width);
+#endif
+
+#ifndef GL_SUN_slice_accum
+#define GL_SUN_slice_accum 1
+#endif
+
+#ifndef GL_NV_multisample_filter_hint
+#define GL_NV_multisample_filter_hint 1
+#endif
+
+#ifndef GL_NV_depth_clamp
+#define GL_NV_depth_clamp 1
+#endif
+
+#ifndef GL_NV_occlusion_query
+#define GL_NV_occlusion_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei, GLuint *);
+GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei, const GLuint *);
+GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint);
+GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint);
+GLAPI void APIENTRY glEndOcclusionQueryNV (void);
+GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids);
+typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids);
+typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id);
+typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_NV_point_sprite
+#define GL_NV_point_sprite 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPointParameteriNV (GLenum, GLint);
+GLAPI void APIENTRY glPointParameterivNV (GLenum, const GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params);
+#endif
+
+#ifndef GL_NV_texture_shader3
+#define GL_NV_texture_shader3 1
+#endif
+
+#ifndef GL_NV_vertex_program1_1
+#define GL_NV_vertex_program1_1 1
+#endif
+
+#ifndef GL_EXT_shadow_funcs
+#define GL_EXT_shadow_funcs 1
+#endif
+
+#ifndef GL_EXT_stencil_two_side
+#define GL_EXT_stencil_two_side 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face);
+#endif
+
+#ifndef GL_ATI_text_fragment_shader
+#define GL_ATI_text_fragment_shader 1
+#endif
+
+#ifndef GL_APPLE_client_storage
+#define GL_APPLE_client_storage 1
+#endif
+
+#ifndef GL_APPLE_element_array
+#define GL_APPLE_element_array 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glElementPointerAPPLE (GLenum, const GLvoid *);
+GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum, GLint, GLsizei);
+GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei);
+GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei);
+GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount);
+#endif
+
+#ifndef GL_APPLE_fence
+#define GL_APPLE_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenFencesAPPLE (GLsizei, GLuint *);
+GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei, const GLuint *);
+GLAPI void APIENTRY glSetFenceAPPLE (GLuint);
+GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint);
+GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint);
+GLAPI void APIENTRY glFinishFenceAPPLE (GLuint);
+GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum, GLuint);
+GLAPI void APIENTRY glFinishObjectAPPLE (GLenum, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences);
+typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences);
+typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence);
+typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence);
+typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name);
+typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name);
+#endif
+
+#ifndef GL_APPLE_vertex_array_object
+#define GL_APPLE_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint);
+GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei, GLuint *);
+GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array);
+typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays);
+typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array);
+#endif
+
+#ifndef GL_APPLE_vertex_array_range
+#define GL_APPLE_vertex_array_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei, GLvoid *);
+GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *);
+GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param);
+#endif
+
+#ifndef GL_APPLE_ycbcr_422
+#define GL_APPLE_ycbcr_422 1
+#endif
+
+#ifndef GL_S3_s3tc
+#define GL_S3_s3tc 1
+#endif
+
+#ifndef GL_ATI_draw_buffers
+#define GL_ATI_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawBuffersATI (GLsizei, const GLenum *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
+#ifndef GL_ATI_pixel_format_float
+#define GL_ATI_pixel_format_float 1
+/* This is really a WGL extension, but defines some associated GL enums.
+ * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string.
+ */
+#endif
+
+#ifndef GL_ATI_texture_env_combine3
+#define GL_ATI_texture_env_combine3 1
+#endif
+
+#ifndef GL_ATI_texture_float
+#define GL_ATI_texture_float 1
+#endif
+
+#ifndef GL_NV_float_buffer
+#define GL_NV_float_buffer 1
+#endif
+
+#ifndef GL_NV_fragment_program
+#define GL_NV_fragment_program 1
+/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat);
+GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble);
+GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *);
+GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *);
+GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *);
+GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v);
+typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params);
+#endif
+
+#ifndef GL_NV_half_float
+#define GL_NV_half_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertex2hNV (GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV);
+GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum, GLhalfNV);
+GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum, const GLhalfNV *);
+GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum, const GLhalfNV *);
+GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum, const GLhalfNV *);
+GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum, const GLhalfNV *);
+GLAPI void APIENTRY glFogCoordhNV (GLhalfNV);
+GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *);
+GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *);
+GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV);
+GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttrib1hNV (GLuint, GLhalfNV);
+GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint, const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint, const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint, const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV);
+GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint, const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *);
+GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz);
+typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha);
+typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s);
+typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q);
+typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog);
+typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue);
+typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight);
+typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v);
+#endif
+
+#ifndef GL_NV_pixel_data_range
+#define GL_NV_pixel_data_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPixelDataRangeNV (GLenum, GLsizei, GLvoid *);
+GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer);
+typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target);
+#endif
+
+#ifndef GL_NV_primitive_restart
+#define GL_NV_primitive_restart 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glPrimitiveRestartNV (void);
+GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void);
+typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index);
+#endif
+
+#ifndef GL_NV_texture_expand_normal
+#define GL_NV_texture_expand_normal 1
+#endif
+
+#ifndef GL_NV_vertex_program2
+#define GL_NV_vertex_program2 1
+#endif
+
+#ifndef GL_ATI_map_object_buffer
+#define GL_ATI_map_object_buffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint);
+GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer);
+#endif
+
+#ifndef GL_ATI_separate_stencil
+#define GL_ATI_separate_stencil 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass);
+typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+#endif
+
+#ifndef GL_ATI_vertex_attrib_array_object
+#define GL_ATI_vertex_attrib_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *);
+GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_OES_read_format
+#define GL_OES_read_format 1
+#endif
+
+#ifndef GL_EXT_depth_bounds_test
+#define GL_EXT_depth_bounds_test 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthBoundsEXT (GLclampd, GLclampd);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax);
+#endif
+
+#ifndef GL_EXT_texture_mirror_clamp
+#define GL_EXT_texture_mirror_clamp 1
+#endif
+
+#ifndef GL_EXT_blend_equation_separate
+#define GL_EXT_blend_equation_separate 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_MESA_pack_invert
+#define GL_MESA_pack_invert 1
+#endif
+
+#ifndef GL_MESA_ycbcr_texture
+#define GL_MESA_ycbcr_texture 1
+#endif
+
+#ifndef GL_EXT_pixel_buffer_object
+#define GL_EXT_pixel_buffer_object 1
+#endif
+
+#ifndef GL_NV_fragment_program_option
+#define GL_NV_fragment_program_option 1
+#endif
+
+#ifndef GL_NV_fragment_program2
+#define GL_NV_fragment_program2 1
+#endif
+
+#ifndef GL_NV_vertex_program2_option
+#define GL_NV_vertex_program2_option 1
+#endif
+
+#ifndef GL_NV_vertex_program3
+#define GL_NV_vertex_program3 1
+#endif
+
+#ifndef GL_EXT_framebuffer_object
+#define GL_EXT_framebuffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint);
+GLAPI void APIENTRY glBindRenderbufferEXT (GLenum, GLuint);
+GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei, GLuint *);
+GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei);
+GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *);
+GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint);
+GLAPI void APIENTRY glBindFramebufferEXT (GLenum, GLuint);
+GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei, const GLuint *);
+GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei, GLuint *);
+GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum);
+GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint);
+GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint);
+GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint);
+GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint);
+GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGenerateMipmapEXT (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers);
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer);
+typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer);
+typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers);
+typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
+typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target);
+#endif
+
+#ifndef GL_GREMEDY_string_marker
+#define GL_GREMEDY_string_marker 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei, const GLvoid *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string);
+#endif
+
+#ifndef GL_EXT_packed_depth_stencil
+#define GL_EXT_packed_depth_stencil 1
+#endif
+
+#ifndef GL_EXT_stencil_clear_tag
+#define GL_EXT_stencil_clear_tag 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glStencilClearTagEXT (GLsizei, GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag);
+#endif
+
+#ifndef GL_EXT_texture_sRGB
+#define GL_EXT_texture_sRGB 1
+#endif
+
+#ifndef GL_EXT_framebuffer_blit
+#define GL_EXT_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlitFramebufferEXT (GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+#endif
+
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_MESAX_texture_stack
+#define GL_MESAX_texture_stack 1
+#endif
+
+#ifndef GL_EXT_timer_query
+#define GL_EXT_timer_query 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint, GLenum, GLint64EXT *);
+GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint, GLenum, GLuint64EXT *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params);
+typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params);
+#endif
+
+#ifndef GL_EXT_gpu_program_parameters
+#define GL_EXT_gpu_program_parameters 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum, GLuint, GLsizei, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params);
+#endif
+
+#ifndef GL_APPLE_flush_buffer_range
+#define GL_APPLE_flush_buffer_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum, GLenum, GLint);
+GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum, GLintptr, GLsizeiptr);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size);
+#endif
+
+#ifndef GL_NV_gpu_program4
+#define GL_NV_gpu_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum, GLuint, const GLint *);
+GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *);
+GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum, GLuint, const GLuint *);
+GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *);
+GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum, GLuint, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum, GLuint, const GLint *);
+GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum, GLuint, GLsizei, const GLint *);
+GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum, GLuint, const GLuint *);
+GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum, GLuint, GLsizei, const GLuint *);
+GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum, GLuint, GLint *);
+GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum, GLuint, GLuint *);
+GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum, GLuint, GLint *);
+GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum, GLuint, GLuint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params);
+typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params);
+typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params);
+#endif
+
+#ifndef GL_NV_geometry_program4
+#define GL_NV_geometry_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramVertexLimitNV (GLenum, GLint);
+GLAPI void APIENTRY glFramebufferTextureEXT (GLenum, GLenum, GLuint, GLint);
+GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum, GLenum, GLuint, GLint, GLint);
+GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum, GLenum, GLuint, GLint, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
+#ifndef GL_EXT_geometry_shader4
+#define GL_EXT_geometry_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramParameteriEXT (GLuint, GLenum, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
+#endif
+
+#ifndef GL_NV_vertex_program4
+#define GL_NV_vertex_program4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint, GLint);
+GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint, GLint, GLint);
+GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint, GLint, GLint, GLint);
+GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint, const GLbyte *);
+GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint, const GLushort *);
+GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint, GLint, GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint, GLenum, GLint *);
+GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint, GLenum, GLuint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params);
+#endif
+
+#ifndef GL_EXT_gpu_shader4
+#define GL_EXT_gpu_shader4 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUniformuivEXT (GLuint, GLint, GLuint *);
+GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint, GLuint, const GLchar *);
+GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint, const GLchar *);
+GLAPI void APIENTRY glUniform1uiEXT (GLint, GLuint);
+GLAPI void APIENTRY glUniform2uiEXT (GLint, GLuint, GLuint);
+GLAPI void APIENTRY glUniform3uiEXT (GLint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glUniform4uiEXT (GLint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glUniform1uivEXT (GLint, GLsizei, const GLuint *);
+GLAPI void APIENTRY glUniform2uivEXT (GLint, GLsizei, const GLuint *);
+GLAPI void APIENTRY glUniform3uivEXT (GLint, GLsizei, const GLuint *);
+GLAPI void APIENTRY glUniform4uivEXT (GLint, GLsizei, const GLuint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value);
+#endif
+
+#ifndef GL_EXT_draw_instanced
+#define GL_EXT_draw_instanced 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum, GLint, GLsizei, GLsizei);
+GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
+#endif
+
+#ifndef GL_EXT_packed_float
+#define GL_EXT_packed_float 1
+#endif
+
+#ifndef GL_EXT_texture_array
+#define GL_EXT_texture_array 1
+#endif
+
+#ifndef GL_EXT_texture_buffer_object
+#define GL_EXT_texture_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexBufferEXT (GLenum, GLenum, GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer);
+#endif
+
+#ifndef GL_EXT_texture_compression_latc
+#define GL_EXT_texture_compression_latc 1
+#endif
+
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#endif
+
+#ifndef GL_EXT_texture_shared_exponent
+#define GL_EXT_texture_shared_exponent 1
+#endif
+
+#ifndef GL_NV_depth_buffer_float
+#define GL_NV_depth_buffer_float 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDepthRangedNV (GLdouble, GLdouble);
+GLAPI void APIENTRY glClearDepthdNV (GLdouble);
+GLAPI void APIENTRY glDepthBoundsdNV (GLdouble, GLdouble);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar);
+typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth);
+typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax);
+#endif
+
+#ifndef GL_NV_fragment_program4
+#define GL_NV_fragment_program4 1
+#endif
+
+#ifndef GL_NV_framebuffer_multisample_coverage
+#define GL_NV_framebuffer_multisample_coverage 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum, GLsizei, GLsizei, GLenum, GLsizei, GLsizei);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
+#ifndef GL_EXT_framebuffer_sRGB
+#define GL_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef GL_NV_geometry_shader4
+#define GL_NV_geometry_shader4 1
+#endif
+
+#ifndef GL_NV_parameter_buffer_object
+#define GL_NV_parameter_buffer_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum, GLuint, GLuint, GLsizei, const GLfloat *);
+GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum, GLuint, GLuint, GLsizei, const GLint *);
+GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum, GLuint, GLuint, GLsizei, const GLuint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params);
+typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params);
+#endif
+
+#ifndef GL_EXT_draw_buffers2
+#define GL_EXT_draw_buffers2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint, GLboolean, GLboolean, GLboolean, GLboolean);
+GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum, GLuint, GLboolean *);
+GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum, GLuint, GLint *);
+GLAPI void APIENTRY glEnableIndexedEXT (GLenum, GLuint);
+GLAPI void APIENTRY glDisableIndexedEXT (GLenum, GLuint);
+GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum, GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a);
+typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data);
+typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data);
+typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index);
+typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index);
+#endif
+
+#ifndef GL_NV_transform_feedback
+#define GL_NV_transform_feedback 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum);
+GLAPI void APIENTRY glEndTransformFeedbackNV (void);
+GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint, const GLint *, GLenum);
+GLAPI void APIENTRY glBindBufferRangeNV (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
+GLAPI void APIENTRY glBindBufferOffsetNV (GLenum, GLuint, GLuint, GLintptr);
+GLAPI void APIENTRY glBindBufferBaseNV (GLenum, GLuint, GLuint);
+GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLint *, GLenum);
+GLAPI void APIENTRY glActiveVaryingNV (GLuint, const GLchar *);
+GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint, const GLchar *);
+GLAPI void APIENTRY glGetActiveVaryingNV (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *);
+GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint, GLuint, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode);
+typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
+typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
+typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
+typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location);
+#endif
+
+#ifndef GL_EXT_bindable_uniform
+#define GL_EXT_bindable_uniform 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glUniformBufferEXT (GLuint, GLint, GLuint);
+GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint, GLint);
+GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint, GLint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer);
+typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location);
+typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location);
+#endif
+
+#ifndef GL_EXT_texture_integer
+#define GL_EXT_texture_integer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexParameterIivEXT (GLenum, GLenum, const GLint *);
+GLAPI void APIENTRY glTexParameterIuivEXT (GLenum, GLenum, const GLuint *);
+GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum, GLenum, GLint *);
+GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum, GLenum, GLuint *);
+GLAPI void APIENTRY glClearColorIiEXT (GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glClearColorIuiEXT (GLuint, GLuint, GLuint, GLuint);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha);
+typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/VBox/HostServices/glxext.h b/include/VBox/HostServices/glxext.h
new file mode 100644
index 00000000..0f66df62
--- /dev/null
+++ b/include/VBox/HostServices/glxext.h
@@ -0,0 +1,785 @@
+#ifndef __glxext_h_
+#define __glxext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number, required by OpenGL ABI for Linux */
+/* glxext.h last updated 2007/04/21 */
+/* Current version at http://www.opengl.org/registry/ */
+#define GLX_GLXEXT_VERSION 19
+
+#ifndef GLX_VERSION_1_3
+#define GLX_WINDOW_BIT 0x00000001
+#define GLX_PIXMAP_BIT 0x00000002
+#define GLX_PBUFFER_BIT 0x00000004
+#define GLX_RGBA_BIT 0x00000001
+#define GLX_COLOR_INDEX_BIT 0x00000002
+#define GLX_PBUFFER_CLOBBER_MASK 0x08000000
+#define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008
+#define GLX_AUX_BUFFERS_BIT 0x00000010
+#define GLX_DEPTH_BUFFER_BIT 0x00000020
+#define GLX_STENCIL_BUFFER_BIT 0x00000040
+#define GLX_ACCUM_BUFFER_BIT 0x00000080
+#define GLX_CONFIG_CAVEAT 0x20
+#define GLX_X_VISUAL_TYPE 0x22
+#define GLX_TRANSPARENT_TYPE 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE 0x24
+#define GLX_TRANSPARENT_RED_VALUE 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE 0x28
+#define GLX_DONT_CARE 0xFFFFFFFF
+#define GLX_NONE 0x8000
+#define GLX_SLOW_CONFIG 0x8001
+#define GLX_TRUE_COLOR 0x8002
+#define GLX_DIRECT_COLOR 0x8003
+#define GLX_PSEUDO_COLOR 0x8004
+#define GLX_STATIC_COLOR 0x8005
+#define GLX_GRAY_SCALE 0x8006
+#define GLX_STATIC_GRAY 0x8007
+#define GLX_TRANSPARENT_RGB 0x8008
+#define GLX_TRANSPARENT_INDEX 0x8009
+#define GLX_VISUAL_ID 0x800B
+#define GLX_SCREEN 0x800C
+#define GLX_NON_CONFORMANT_CONFIG 0x800D
+#define GLX_DRAWABLE_TYPE 0x8010
+#define GLX_RENDER_TYPE 0x8011
+#define GLX_X_RENDERABLE 0x8012
+#define GLX_FBCONFIG_ID 0x8013
+#define GLX_RGBA_TYPE 0x8014
+#define GLX_COLOR_INDEX_TYPE 0x8015
+#define GLX_MAX_PBUFFER_WIDTH 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT 0x8017
+#define GLX_MAX_PBUFFER_PIXELS 0x8018
+#define GLX_PRESERVED_CONTENTS 0x801B
+#define GLX_LARGEST_PBUFFER 0x801C
+#define GLX_WIDTH 0x801D
+#define GLX_HEIGHT 0x801E
+#define GLX_EVENT_MASK 0x801F
+#define GLX_DAMAGED 0x8020
+#define GLX_SAVED 0x8021
+#define GLX_WINDOW 0x8022
+#define GLX_PBUFFER 0x8023
+#define GLX_PBUFFER_HEIGHT 0x8040
+#define GLX_PBUFFER_WIDTH 0x8041
+#endif
+
+#ifndef GLX_VERSION_1_4
+#define GLX_SAMPLE_BUFFERS 100000
+#define GLX_SAMPLES 100001
+#endif
+
+#ifndef GLX_ARB_get_proc_address
+#endif
+
+#ifndef GLX_ARB_multisample
+#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_SAMPLES_ARB 100001
+#endif
+
+#ifndef GLX_ARB_fbconfig_float
+#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9
+#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
+#endif
+
+#ifndef GLX_SGIS_multisample
+#define GLX_SAMPLE_BUFFERS_SGIS 100000
+#define GLX_SAMPLES_SGIS 100001
+#endif
+
+#ifndef GLX_EXT_visual_info
+#define GLX_X_VISUAL_TYPE_EXT 0x22
+#define GLX_TRANSPARENT_TYPE_EXT 0x23
+#define GLX_TRANSPARENT_INDEX_VALUE_EXT 0x24
+#define GLX_TRANSPARENT_RED_VALUE_EXT 0x25
+#define GLX_TRANSPARENT_GREEN_VALUE_EXT 0x26
+#define GLX_TRANSPARENT_BLUE_VALUE_EXT 0x27
+#define GLX_TRANSPARENT_ALPHA_VALUE_EXT 0x28
+#define GLX_NONE_EXT 0x8000
+#define GLX_TRUE_COLOR_EXT 0x8002
+#define GLX_DIRECT_COLOR_EXT 0x8003
+#define GLX_PSEUDO_COLOR_EXT 0x8004
+#define GLX_STATIC_COLOR_EXT 0x8005
+#define GLX_GRAY_SCALE_EXT 0x8006
+#define GLX_STATIC_GRAY_EXT 0x8007
+#define GLX_TRANSPARENT_RGB_EXT 0x8008
+#define GLX_TRANSPARENT_INDEX_EXT 0x8009
+#endif
+
+#ifndef GLX_SGI_swap_control
+#endif
+
+#ifndef GLX_SGI_video_sync
+#endif
+
+#ifndef GLX_SGI_make_current_read
+#endif
+
+#ifndef GLX_SGIX_video_source
+#endif
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_VISUAL_CAVEAT_EXT 0x20
+#define GLX_SLOW_VISUAL_EXT 0x8001
+#define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
+/* reuse GLX_NONE_EXT */
+#endif
+
+#ifndef GLX_EXT_import_context
+#define GLX_SHARE_CONTEXT_EXT 0x800A
+#define GLX_VISUAL_ID_EXT 0x800B
+#define GLX_SCREEN_EXT 0x800C
+#endif
+
+#ifndef GLX_SGIX_fbconfig
+#define GLX_WINDOW_BIT_SGIX 0x00000001
+#define GLX_PIXMAP_BIT_SGIX 0x00000002
+#define GLX_RGBA_BIT_SGIX 0x00000001
+#define GLX_COLOR_INDEX_BIT_SGIX 0x00000002
+#define GLX_DRAWABLE_TYPE_SGIX 0x8010
+#define GLX_RENDER_TYPE_SGIX 0x8011
+#define GLX_X_RENDERABLE_SGIX 0x8012
+#define GLX_FBCONFIG_ID_SGIX 0x8013
+#define GLX_RGBA_TYPE_SGIX 0x8014
+#define GLX_COLOR_INDEX_TYPE_SGIX 0x8015
+/* reuse GLX_SCREEN_EXT */
+#endif
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_PBUFFER_BIT_SGIX 0x00000004
+#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
+#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
+#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
+#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
+#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
+#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
+#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
+#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
+#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
+#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
+#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
+#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
+#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
+#define GLX_PRESERVED_CONTENTS_SGIX 0x801B
+#define GLX_LARGEST_PBUFFER_SGIX 0x801C
+#define GLX_WIDTH_SGIX 0x801D
+#define GLX_HEIGHT_SGIX 0x801E
+#define GLX_EVENT_MASK_SGIX 0x801F
+#define GLX_DAMAGED_SGIX 0x8020
+#define GLX_SAVED_SGIX 0x8021
+#define GLX_WINDOW_SGIX 0x8022
+#define GLX_PBUFFER_SGIX 0x8023
+#endif
+
+#ifndef GLX_SGI_cushion
+#endif
+
+#ifndef GLX_SGIX_video_resize
+#define GLX_SYNC_FRAME_SGIX 0x00000000
+#define GLX_SYNC_SWAP_SGIX 0x00000001
+#endif
+
+#ifndef GLX_SGIX_dmbuffer
+#define GLX_DIGITAL_MEDIA_PBUFFER_SGIX 0x8024
+#endif
+
+#ifndef GLX_SGIX_swap_group
+#endif
+
+#ifndef GLX_SGIX_swap_barrier
+#endif
+
+#ifndef GLX_SGIS_blended_overlay
+#define GLX_BLENDED_RGBA_SGIS 0x8025
+#endif
+
+#ifndef GLX_SGIS_shared_multisample
+#define GLX_MULTISAMPLE_SUB_RECT_WIDTH_SGIS 0x8026
+#define GLX_MULTISAMPLE_SUB_RECT_HEIGHT_SGIS 0x8027
+#endif
+
+#ifndef GLX_SUN_get_transparent_index
+#endif
+
+#ifndef GLX_3DFX_multisample
+#define GLX_SAMPLE_BUFFERS_3DFX 0x8050
+#define GLX_SAMPLES_3DFX 0x8051
+#endif
+
+#ifndef GLX_MESA_copy_sub_buffer
+#endif
+
+#ifndef GLX_MESA_pixmap_colormap
+#endif
+
+#ifndef GLX_MESA_release_buffers
+#endif
+
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_3DFX_WINDOW_MODE_MESA 0x1
+#define GLX_3DFX_FULLSCREEN_MODE_MESA 0x2
+#endif
+
+#ifndef GLX_SGIX_visual_select_group
+#define GLX_VISUAL_SELECT_GROUP_SGIX 0x8028
+#endif
+
+#ifndef GLX_OML_swap_method
+#define GLX_SWAP_METHOD_OML 0x8060
+#define GLX_SWAP_EXCHANGE_OML 0x8061
+#define GLX_SWAP_COPY_OML 0x8062
+#define GLX_SWAP_UNDEFINED_OML 0x8063
+#endif
+
+#ifndef GLX_OML_sync_control
+#endif
+
+#ifndef GLX_NV_float_buffer
+#define GLX_FLOAT_COMPONENTS_NV 0x20B0
+#endif
+
+#ifndef GLX_SGIX_hyperpipe
+#define GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX 80
+#define GLX_BAD_HYPERPIPE_CONFIG_SGIX 91
+#define GLX_BAD_HYPERPIPE_SGIX 92
+#define GLX_HYPERPIPE_DISPLAY_PIPE_SGIX 0x00000001
+#define GLX_HYPERPIPE_RENDER_PIPE_SGIX 0x00000002
+#define GLX_PIPE_RECT_SGIX 0x00000001
+#define GLX_PIPE_RECT_LIMITS_SGIX 0x00000002
+#define GLX_HYPERPIPE_STEREO_SGIX 0x00000003
+#define GLX_HYPERPIPE_PIXEL_AVERAGE_SGIX 0x00000004
+#define GLX_HYPERPIPE_ID_SGIX 0x8030
+#endif
+
+#ifndef GLX_MESA_agp_offset
+#endif
+
+#ifndef GLX_EXT_fbconfig_packed_float
+#define GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT 0x20B1
+#define GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT 0x00000008
+#endif
+
+#ifndef GLX_EXT_framebuffer_sRGB
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
+#endif
+
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_TEXTURE_1D_BIT_EXT 0x00000001
+#define GLX_TEXTURE_2D_BIT_EXT 0x00000002
+#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004
+#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0
+#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1
+#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2
+#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3
+#define GLX_Y_INVERTED_EXT 0x20D4
+#define GLX_TEXTURE_FORMAT_EXT 0x20D5
+#define GLX_TEXTURE_TARGET_EXT 0x20D6
+#define GLX_MIPMAP_TEXTURE_EXT 0x20D7
+#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA
+#define GLX_TEXTURE_1D_EXT 0x20DB
+#define GLX_TEXTURE_2D_EXT 0x20DC
+#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD
+#define GLX_FRONT_LEFT_EXT 0x20DE
+#define GLX_FRONT_RIGHT_EXT 0x20DF
+#define GLX_BACK_LEFT_EXT 0x20E0
+#define GLX_BACK_RIGHT_EXT 0x20E1
+#define GLX_FRONT_EXT GLX_FRONT_LEFT_EXT
+#define GLX_BACK_EXT GLX_BACK_LEFT_EXT
+#define GLX_AUX0_EXT 0x20E2
+#define GLX_AUX1_EXT 0x20E3
+#define GLX_AUX2_EXT 0x20E4
+#define GLX_AUX3_EXT 0x20E5
+#define GLX_AUX4_EXT 0x20E6
+#define GLX_AUX5_EXT 0x20E7
+#define GLX_AUX6_EXT 0x20E8
+#define GLX_AUX7_EXT 0x20E9
+#define GLX_AUX8_EXT 0x20EA
+#define GLX_AUX9_EXT 0x20EB
+#endif
+
+
+/*************************************************************/
+
+#ifndef GLX_ARB_get_proc_address
+typedef void (*__GLXextFuncPtr)(void);
+#endif
+
+#ifndef GLX_SGIX_video_source
+typedef XID GLXVideoSourceSGIX;
+#endif
+
+#ifndef GLX_SGIX_fbconfig
+typedef XID GLXFBConfigIDSGIX;
+typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
+#endif
+
+#ifndef GLX_SGIX_pbuffer
+typedef XID GLXPbufferSGIX;
+typedef struct {
+ int type;
+ unsigned long serial; /* # of last request processed by server */
+ Bool send_event; /* true if this came for SendEvent request */
+ Display *display; /* display the event was read from */
+ GLXDrawable drawable; /* i.d. of Drawable */
+ int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */
+ int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */
+ unsigned int mask; /* mask indicating which buffers are affected*/
+ int x, y;
+ int width, height;
+ int count; /* if nonzero, at least this many more */
+} GLXBufferClobberEventSGIX;
+#endif
+
+#ifndef GLEXT_64_TYPES_DEFINED
+/* This code block is duplicated in glxext.h, so must be protected */
+#define GLEXT_64_TYPES_DEFINED
+/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
+/* (as used in the GLX_OML_sync_control extension). */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(__sun__) || defined(__digital__)
+#include <inttypes.h>
+#if defined(__STDC__)
+#if defined(__arch64__)
+typedef long int int64_t;
+typedef unsigned long int uint64_t;
+#else
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#endif /* __arch64__ */
+#endif /* __STDC__ */
+#elif defined( __VMS )
+#include <inttypes.h>
+#elif defined(__SCO__) || defined(__USLC__)
+#include <stdint.h>
+#elif defined(__UNIXOS2__) || defined(__SOL64__)
+typedef long int int32_t;
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int32 int32_t;
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+#include <inttypes.h> /* Fallback option */
+#endif
+#endif
+
+#ifndef GLX_VERSION_1_3
+#define GLX_VERSION_1_3 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXFBConfig * glXGetFBConfigs (Display *, int, int *);
+extern GLXFBConfig * glXChooseFBConfig (Display *, int, const int *, int *);
+extern int glXGetFBConfigAttrib (Display *, GLXFBConfig, int, int *);
+extern XVisualInfo * glXGetVisualFromFBConfig (Display *, GLXFBConfig);
+extern GLXWindow glXCreateWindow (Display *, GLXFBConfig, Window, const int *);
+extern void glXDestroyWindow (Display *, GLXWindow);
+extern GLXPixmap glXCreatePixmap (Display *, GLXFBConfig, Pixmap, const int *);
+extern void glXDestroyPixmap (Display *, GLXPixmap);
+extern GLXPbuffer glXCreatePbuffer (Display *, GLXFBConfig, const int *);
+extern void glXDestroyPbuffer (Display *, GLXPbuffer);
+extern void glXQueryDrawable (Display *, GLXDrawable, int, unsigned int *);
+extern GLXContext glXCreateNewContext (Display *, GLXFBConfig, int, GLXContext, Bool);
+extern Bool glXMakeContextCurrent (Display *, GLXDrawable, GLXDrawable, GLXContext);
+extern GLXDrawable glXGetCurrentReadDrawable (void);
+extern Display * glXGetCurrentDisplay (void);
+extern int glXQueryContext (Display *, GLXContext, int, int *);
+extern void glXSelectEvent (Display *, GLXDrawable, unsigned long);
+extern void glXGetSelectedEvent (Display *, GLXDrawable, unsigned long *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXFBConfig * ( * PFNGLXGETFBCONFIGSPROC) (Display *dpy, int screen, int *nelements);
+typedef GLXFBConfig * ( * PFNGLXCHOOSEFBCONFIGPROC) (Display *dpy, int screen, const int *attrib_list, int *nelements);
+typedef int ( * PFNGLXGETFBCONFIGATTRIBPROC) (Display *dpy, GLXFBConfig config, int attribute, int *value);
+typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGPROC) (Display *dpy, GLXFBConfig config);
+typedef GLXWindow ( * PFNGLXCREATEWINDOWPROC) (Display *dpy, GLXFBConfig config, Window win, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYWINDOWPROC) (Display *dpy, GLXWindow win);
+typedef GLXPixmap ( * PFNGLXCREATEPIXMAPPROC) (Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYPIXMAPPROC) (Display *dpy, GLXPixmap pixmap);
+typedef GLXPbuffer ( * PFNGLXCREATEPBUFFERPROC) (Display *dpy, GLXFBConfig config, const int *attrib_list);
+typedef void ( * PFNGLXDESTROYPBUFFERPROC) (Display *dpy, GLXPbuffer pbuf);
+typedef void ( * PFNGLXQUERYDRAWABLEPROC) (Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+typedef GLXContext ( * PFNGLXCREATENEWCONTEXTPROC) (Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+typedef Bool ( * PFNGLXMAKECONTEXTCURRENTPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLEPROC) (void);
+typedef Display * ( * PFNGLXGETCURRENTDISPLAYPROC) (void);
+typedef int ( * PFNGLXQUERYCONTEXTPROC) (Display *dpy, GLXContext ctx, int attribute, int *value);
+typedef void ( * PFNGLXSELECTEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long event_mask);
+typedef void ( * PFNGLXGETSELECTEDEVENTPROC) (Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+#endif
+
+#ifndef GLX_VERSION_1_4
+#define GLX_VERSION_1_4 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern __GLXextFuncPtr glXGetProcAddress (const GLubyte *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSPROC) (const GLubyte *procName);
+#endif
+
+#ifndef GLX_ARB_get_proc_address
+#define GLX_ARB_get_proc_address 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern __GLXextFuncPtr glXGetProcAddressARB (const GLubyte *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef __GLXextFuncPtr ( * PFNGLXGETPROCADDRESSARBPROC) (const GLubyte *procName);
+#endif
+
+#ifndef GLX_ARB_multisample
+#define GLX_ARB_multisample 1
+#endif
+
+#ifndef GLX_ARB_fbconfig_float
+#define GLX_ARB_fbconfig_float 1
+#endif
+
+#ifndef GLX_SGIS_multisample
+#define GLX_SGIS_multisample 1
+#endif
+
+#ifndef GLX_EXT_visual_info
+#define GLX_EXT_visual_info 1
+#endif
+
+#ifndef GLX_SGI_swap_control
+#define GLX_SGI_swap_control 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXSwapIntervalSGI (int);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval);
+#endif
+
+#ifndef GLX_SGI_video_sync
+#define GLX_SGI_video_sync 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXGetVideoSyncSGI (unsigned int *);
+extern int glXWaitVideoSyncSGI (int, int, unsigned int *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXGETVIDEOSYNCSGIPROC) (unsigned int *count);
+typedef int ( * PFNGLXWAITVIDEOSYNCSGIPROC) (int divisor, int remainder, unsigned int *count);
+#endif
+
+#ifndef GLX_SGI_make_current_read
+#define GLX_SGI_make_current_read 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXMakeCurrentReadSGI (Display *, GLXDrawable, GLXDrawable, GLXContext);
+extern GLXDrawable glXGetCurrentReadDrawableSGI (void);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXMAKECURRENTREADSGIPROC) (Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef GLXDrawable ( * PFNGLXGETCURRENTREADDRAWABLESGIPROC) (void);
+#endif
+
+#ifndef GLX_SGIX_video_source
+#define GLX_SGIX_video_source 1
+#ifdef _VL_H
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXVideoSourceSGIX glXCreateGLXVideoSourceSGIX (Display *, int, VLServer, VLPath, int, VLNode);
+extern void glXDestroyGLXVideoSourceSGIX (Display *, GLXVideoSourceSGIX);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXVideoSourceSGIX ( * PFNGLXCREATEGLXVIDEOSOURCESGIXPROC) (Display *display, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode);
+typedef void ( * PFNGLXDESTROYGLXVIDEOSOURCESGIXPROC) (Display *dpy, GLXVideoSourceSGIX glxvideosource);
+#endif /* _VL_H */
+#endif
+
+#ifndef GLX_EXT_visual_rating
+#define GLX_EXT_visual_rating 1
+#endif
+
+#ifndef GLX_EXT_import_context
+#define GLX_EXT_import_context 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Display * glXGetCurrentDisplayEXT (void);
+extern int glXQueryContextInfoEXT (Display *, GLXContext, int, int *);
+extern GLXContextID glXGetContextIDEXT (const GLXContext);
+extern GLXContext glXImportContextEXT (Display *, GLXContextID);
+extern void glXFreeContextEXT (Display *, GLXContext);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Display * ( * PFNGLXGETCURRENTDISPLAYEXTPROC) (void);
+typedef int ( * PFNGLXQUERYCONTEXTINFOEXTPROC) (Display *dpy, GLXContext context, int attribute, int *value);
+typedef GLXContextID ( * PFNGLXGETCONTEXTIDEXTPROC) (const GLXContext context);
+typedef GLXContext ( * PFNGLXIMPORTCONTEXTEXTPROC) (Display *dpy, GLXContextID contextID);
+typedef void ( * PFNGLXFREECONTEXTEXTPROC) (Display *dpy, GLXContext context);
+#endif
+
+#ifndef GLX_SGIX_fbconfig
+#define GLX_SGIX_fbconfig 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXGetFBConfigAttribSGIX (Display *, GLXFBConfigSGIX, int, int *);
+extern GLXFBConfigSGIX * glXChooseFBConfigSGIX (Display *, int, int *, int *);
+extern GLXPixmap glXCreateGLXPixmapWithConfigSGIX (Display *, GLXFBConfigSGIX, Pixmap);
+extern GLXContext glXCreateContextWithConfigSGIX (Display *, GLXFBConfigSGIX, int, GLXContext, Bool);
+extern XVisualInfo * glXGetVisualFromFBConfigSGIX (Display *, GLXFBConfigSGIX);
+extern GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX (Display *, XVisualInfo *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXGETFBCONFIGATTRIBSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value);
+typedef GLXFBConfigSGIX * ( * PFNGLXCHOOSEFBCONFIGSGIXPROC) (Display *dpy, int screen, int *attrib_list, int *nelements);
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap);
+typedef GLXContext ( * PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct);
+typedef XVisualInfo * ( * PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) (Display *dpy, GLXFBConfigSGIX config);
+typedef GLXFBConfigSGIX ( * PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) (Display *dpy, XVisualInfo *vis);
+#endif
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_SGIX_pbuffer 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXPbufferSGIX glXCreateGLXPbufferSGIX (Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *);
+extern void glXDestroyGLXPbufferSGIX (Display *, GLXPbufferSGIX);
+extern int glXQueryGLXPbufferSGIX (Display *, GLXPbufferSGIX, int, unsigned int *);
+extern void glXSelectEventSGIX (Display *, GLXDrawable, unsigned long);
+extern void glXGetSelectedEventSGIX (Display *, GLXDrawable, unsigned long *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXPbufferSGIX ( * PFNGLXCREATEGLXPBUFFERSGIXPROC) (Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+typedef void ( * PFNGLXDESTROYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf);
+typedef int ( * PFNGLXQUERYGLXPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value);
+typedef void ( * PFNGLXSELECTEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long mask);
+typedef void ( * PFNGLXGETSELECTEDEVENTSGIXPROC) (Display *dpy, GLXDrawable drawable, unsigned long *mask);
+#endif
+
+#ifndef GLX_SGI_cushion
+#define GLX_SGI_cushion 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXCushionSGI (Display *, Window, float);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXCUSHIONSGIPROC) (Display *dpy, Window window, float cushion);
+#endif
+
+#ifndef GLX_SGIX_video_resize
+#define GLX_SGIX_video_resize 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern int glXBindChannelToWindowSGIX (Display *, int, int, Window);
+extern int glXChannelRectSGIX (Display *, int, int, int, int, int, int);
+extern int glXQueryChannelRectSGIX (Display *, int, int, int *, int *, int *, int *);
+extern int glXQueryChannelDeltasSGIX (Display *, int, int, int *, int *, int *, int *);
+extern int glXChannelRectSyncSGIX (Display *, int, int, GLenum);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef int ( * PFNGLXBINDCHANNELTOWINDOWSGIXPROC) (Display *display, int screen, int channel, Window window);
+typedef int ( * PFNGLXCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int x, int y, int w, int h);
+typedef int ( * PFNGLXQUERYCHANNELRECTSGIXPROC) (Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh);
+typedef int ( * PFNGLXQUERYCHANNELDELTASSGIXPROC) (Display *display, int screen, int channel, int *x, int *y, int *w, int *h);
+typedef int ( * PFNGLXCHANNELRECTSYNCSGIXPROC) (Display *display, int screen, int channel, GLenum synctype);
+#endif
+
+#ifndef GLX_SGIX_dmbuffer
+#define GLX_SGIX_dmbuffer 1
+#ifdef _DM_BUFFER_H_
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXAssociateDMPbufferSGIX (Display *, GLXPbufferSGIX, DMparams *, DMbuffer);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXASSOCIATEDMPBUFFERSGIXPROC) (Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer);
+#endif /* _DM_BUFFER_H_ */
+#endif
+
+#ifndef GLX_SGIX_swap_group
+#define GLX_SGIX_swap_group 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXJoinSwapGroupSGIX (Display *, GLXDrawable, GLXDrawable);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXJOINSWAPGROUPSGIXPROC) (Display *dpy, GLXDrawable drawable, GLXDrawable member);
+#endif
+
+#ifndef GLX_SGIX_swap_barrier
+#define GLX_SGIX_swap_barrier 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXBindSwapBarrierSGIX (Display *, GLXDrawable, int);
+extern Bool glXQueryMaxSwapBarriersSGIX (Display *, int, int *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXBINDSWAPBARRIERSGIXPROC) (Display *dpy, GLXDrawable drawable, int barrier);
+typedef Bool ( * PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) (Display *dpy, int screen, int *max);
+#endif
+
+#ifndef GLX_SUN_get_transparent_index
+#define GLX_SUN_get_transparent_index 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Status glXGetTransparentIndexSUN (Display *, Window, Window, long *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Status ( * PFNGLXGETTRANSPARENTINDEXSUNPROC) (Display *dpy, Window overlay, Window underlay, long *pTransparentIndex);
+#endif
+
+#ifndef GLX_MESA_copy_sub_buffer
+#define GLX_MESA_copy_sub_buffer 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXCopySubBufferMESA (Display *, GLXDrawable, int, int, int, int);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXCOPYSUBBUFFERMESAPROC) (Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
+#endif
+
+#ifndef GLX_MESA_pixmap_colormap
+#define GLX_MESA_pixmap_colormap 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXPixmap glXCreateGLXPixmapMESA (Display *, XVisualInfo *, Pixmap, Colormap);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXPixmap ( * PFNGLXCREATEGLXPIXMAPMESAPROC) (Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+#endif
+
+#ifndef GLX_MESA_release_buffers
+#define GLX_MESA_release_buffers 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXReleaseBuffersMESA (Display *, GLXDrawable);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXRELEASEBUFFERSMESAPROC) (Display *dpy, GLXDrawable drawable);
+#endif
+
+#ifndef GLX_MESA_set_3dfx_mode
+#define GLX_MESA_set_3dfx_mode 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXSet3DfxModeMESA (int);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXSET3DFXMODEMESAPROC) (int mode);
+#endif
+
+#ifndef GLX_SGIX_visual_select_group
+#define GLX_SGIX_visual_select_group 1
+#endif
+
+#ifndef GLX_OML_swap_method
+#define GLX_OML_swap_method 1
+#endif
+
+#ifndef GLX_OML_sync_control
+#define GLX_OML_sync_control 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern Bool glXGetSyncValuesOML (Display *, GLXDrawable, int64_t *, int64_t *, int64_t *);
+extern Bool glXGetMscRateOML (Display *, GLXDrawable, int32_t *, int32_t *);
+extern int64_t glXSwapBuffersMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t);
+extern Bool glXWaitForMscOML (Display *, GLXDrawable, int64_t, int64_t, int64_t, int64_t *, int64_t *, int64_t *);
+extern Bool glXWaitForSbcOML (Display *, GLXDrawable, int64_t, int64_t *, int64_t *, int64_t *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef Bool ( * PFNGLXGETSYNCVALUESOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc);
+typedef Bool ( * PFNGLXGETMSCRATEOMLPROC) (Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator);
+typedef int64_t ( * PFNGLXSWAPBUFFERSMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder);
+typedef Bool ( * PFNGLXWAITFORMSCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc);
+typedef Bool ( * PFNGLXWAITFORSBCOMLPROC) (Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc);
+#endif
+
+#ifndef GLX_NV_float_buffer
+#define GLX_NV_float_buffer 1
+#endif
+
+#ifndef GLX_SGIX_hyperpipe
+#define GLX_SGIX_hyperpipe 1
+
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int networkId;
+} GLXHyperpipeNetworkSGIX;
+
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int channel;
+ unsigned int
+ participationType;
+ int timeSlice;
+} GLXHyperpipeConfigSGIX;
+
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
+ int destXOrigin, destYOrigin, destWidth, destHeight;
+} GLXPipeRect;
+
+typedef struct {
+ char pipeName[GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX];
+ int XOrigin, YOrigin, maxHeight, maxWidth;
+} GLXPipeRectLimits;
+
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern GLXHyperpipeNetworkSGIX * glXQueryHyperpipeNetworkSGIX (Display *, int *);
+extern int glXHyperpipeConfigSGIX (Display *, int, int, GLXHyperpipeConfigSGIX *, int *);
+extern GLXHyperpipeConfigSGIX * glXQueryHyperpipeConfigSGIX (Display *, int, int *);
+extern int glXDestroyHyperpipeConfigSGIX (Display *, int);
+extern int glXBindHyperpipeSGIX (Display *, int);
+extern int glXQueryHyperpipeBestAttribSGIX (Display *, int, int, int, void *, void *);
+extern int glXHyperpipeAttribSGIX (Display *, int, int, int, void *);
+extern int glXQueryHyperpipeAttribSGIX (Display *, int, int, int, void *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef GLXHyperpipeNetworkSGIX * ( * PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) (Display *dpy, int *npipes);
+typedef int ( * PFNGLXHYPERPIPECONFIGSGIXPROC) (Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId);
+typedef GLXHyperpipeConfigSGIX * ( * PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId, int *npipes);
+typedef int ( * PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXBINDHYPERPIPESGIXPROC) (Display *dpy, int hpId);
+typedef int ( * PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList);
+typedef int ( * PFNGLXHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *attribList);
+typedef int ( * PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) (Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList);
+#endif
+
+#ifndef GLX_MESA_agp_offset
+#define GLX_MESA_agp_offset 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern unsigned int glXGetAGPOffsetMESA (const void *);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef unsigned int ( * PFNGLXGETAGPOFFSETMESAPROC) (const void *pointer);
+#endif
+
+#ifndef GLX_EXT_fbconfig_packed_float
+#define GLX_EXT_fbconfig_packed_float 1
+#endif
+
+#ifndef GLX_EXT_framebuffer_sRGB
+#define GLX_EXT_framebuffer_sRGB 1
+#endif
+
+#ifndef GLX_EXT_texture_from_pixmap
+#define GLX_EXT_texture_from_pixmap 1
+#ifdef GLX_GLXEXT_PROTOTYPES
+extern void glXBindTexImageEXT (Display *, GLXDrawable, int, const int *);
+extern void glXReleaseTexImageEXT (Display *, GLXDrawable, int);
+#endif /* GLX_GLXEXT_PROTOTYPES */
+typedef void ( * PFNGLXBINDTEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list);
+typedef void ( * PFNGLXRELEASETEXIMAGEEXTPROC) (Display *dpy, GLXDrawable drawable, int buffer);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/VBox/HostServices/wglext.h b/include/VBox/HostServices/wglext.h
new file mode 100644
index 00000000..18804bed
--- /dev/null
+++ b/include/VBox/HostServices/wglext.h
@@ -0,0 +1,648 @@
+#ifndef __wglext_h_
+#define __wglext_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** Copyright (c) 2007 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are 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 Materials.
+**
+** THE MATERIALS ARE 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
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+#ifndef APIENTRY
+#define APIENTRY
+#endif
+#ifndef APIENTRYP
+#define APIENTRYP APIENTRY *
+#endif
+#ifndef GLAPI
+#define GLAPI extern
+#endif
+
+/*************************************************************/
+
+/* Header file version number */
+/* wglext.h last updated 2007/02/09 */
+/* Current version at http://www.opengl.org/registry/ */
+#define WGL_WGLEXT_VERSION 9
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
+#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
+#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
+#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_SAMPLE_BUFFERS_ARB 0x2041
+#define WGL_SAMPLES_ARB 0x2042
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
+#define WGL_DRAW_TO_WINDOW_ARB 0x2001
+#define WGL_DRAW_TO_BITMAP_ARB 0x2002
+#define WGL_ACCELERATION_ARB 0x2003
+#define WGL_NEED_PALETTE_ARB 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
+#define WGL_SWAP_METHOD_ARB 0x2007
+#define WGL_NUMBER_OVERLAYS_ARB 0x2008
+#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
+#define WGL_TRANSPARENT_ARB 0x200A
+#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
+#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
+#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
+#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
+#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
+#define WGL_SHARE_DEPTH_ARB 0x200C
+#define WGL_SHARE_STENCIL_ARB 0x200D
+#define WGL_SHARE_ACCUM_ARB 0x200E
+#define WGL_SUPPORT_GDI_ARB 0x200F
+#define WGL_SUPPORT_OPENGL_ARB 0x2010
+#define WGL_DOUBLE_BUFFER_ARB 0x2011
+#define WGL_STEREO_ARB 0x2012
+#define WGL_PIXEL_TYPE_ARB 0x2013
+#define WGL_COLOR_BITS_ARB 0x2014
+#define WGL_RED_BITS_ARB 0x2015
+#define WGL_RED_SHIFT_ARB 0x2016
+#define WGL_GREEN_BITS_ARB 0x2017
+#define WGL_GREEN_SHIFT_ARB 0x2018
+#define WGL_BLUE_BITS_ARB 0x2019
+#define WGL_BLUE_SHIFT_ARB 0x201A
+#define WGL_ALPHA_BITS_ARB 0x201B
+#define WGL_ALPHA_SHIFT_ARB 0x201C
+#define WGL_ACCUM_BITS_ARB 0x201D
+#define WGL_ACCUM_RED_BITS_ARB 0x201E
+#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
+#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
+#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
+#define WGL_DEPTH_BITS_ARB 0x2022
+#define WGL_STENCIL_BITS_ARB 0x2023
+#define WGL_AUX_BUFFERS_ARB 0x2024
+#define WGL_NO_ACCELERATION_ARB 0x2025
+#define WGL_GENERIC_ACCELERATION_ARB 0x2026
+#define WGL_FULL_ACCELERATION_ARB 0x2027
+#define WGL_SWAP_EXCHANGE_ARB 0x2028
+#define WGL_SWAP_COPY_ARB 0x2029
+#define WGL_SWAP_UNDEFINED_ARB 0x202A
+#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_TYPE_COLORINDEX_ARB 0x202C
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
+#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LOST_ARB 0x2036
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
+#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
+#define WGL_TEXTURE_FORMAT_ARB 0x2072
+#define WGL_TEXTURE_TARGET_ARB 0x2073
+#define WGL_MIPMAP_TEXTURE_ARB 0x2074
+#define WGL_TEXTURE_RGB_ARB 0x2075
+#define WGL_TEXTURE_RGBA_ARB 0x2076
+#define WGL_NO_TEXTURE_ARB 0x2077
+#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
+#define WGL_TEXTURE_1D_ARB 0x2079
+#define WGL_TEXTURE_2D_ARB 0x207A
+#define WGL_MIPMAP_LEVEL_ARB 0x207B
+#define WGL_CUBE_MAP_FACE_ARB 0x207C
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
+#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
+#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
+#define WGL_FRONT_LEFT_ARB 0x2083
+#define WGL_FRONT_RIGHT_ARB 0x2084
+#define WGL_BACK_LEFT_ARB 0x2085
+#define WGL_BACK_RIGHT_ARB 0x2086
+#define WGL_AUX0_ARB 0x2087
+#define WGL_AUX1_ARB 0x2088
+#define WGL_AUX2_ARB 0x2089
+#define WGL_AUX3_ARB 0x208A
+#define WGL_AUX4_ARB 0x208B
+#define WGL_AUX5_ARB 0x208C
+#define WGL_AUX6_ARB 0x208D
+#define WGL_AUX7_ARB 0x208E
+#define WGL_AUX8_ARB 0x208F
+#define WGL_AUX9_ARB 0x2090
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
+#define WGL_DRAW_TO_WINDOW_EXT 0x2001
+#define WGL_DRAW_TO_BITMAP_EXT 0x2002
+#define WGL_ACCELERATION_EXT 0x2003
+#define WGL_NEED_PALETTE_EXT 0x2004
+#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
+#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
+#define WGL_SWAP_METHOD_EXT 0x2007
+#define WGL_NUMBER_OVERLAYS_EXT 0x2008
+#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
+#define WGL_TRANSPARENT_EXT 0x200A
+#define WGL_TRANSPARENT_VALUE_EXT 0x200B
+#define WGL_SHARE_DEPTH_EXT 0x200C
+#define WGL_SHARE_STENCIL_EXT 0x200D
+#define WGL_SHARE_ACCUM_EXT 0x200E
+#define WGL_SUPPORT_GDI_EXT 0x200F
+#define WGL_SUPPORT_OPENGL_EXT 0x2010
+#define WGL_DOUBLE_BUFFER_EXT 0x2011
+#define WGL_STEREO_EXT 0x2012
+#define WGL_PIXEL_TYPE_EXT 0x2013
+#define WGL_COLOR_BITS_EXT 0x2014
+#define WGL_RED_BITS_EXT 0x2015
+#define WGL_RED_SHIFT_EXT 0x2016
+#define WGL_GREEN_BITS_EXT 0x2017
+#define WGL_GREEN_SHIFT_EXT 0x2018
+#define WGL_BLUE_BITS_EXT 0x2019
+#define WGL_BLUE_SHIFT_EXT 0x201A
+#define WGL_ALPHA_BITS_EXT 0x201B
+#define WGL_ALPHA_SHIFT_EXT 0x201C
+#define WGL_ACCUM_BITS_EXT 0x201D
+#define WGL_ACCUM_RED_BITS_EXT 0x201E
+#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
+#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
+#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
+#define WGL_DEPTH_BITS_EXT 0x2022
+#define WGL_STENCIL_BITS_EXT 0x2023
+#define WGL_AUX_BUFFERS_EXT 0x2024
+#define WGL_NO_ACCELERATION_EXT 0x2025
+#define WGL_GENERIC_ACCELERATION_EXT 0x2026
+#define WGL_FULL_ACCELERATION_EXT 0x2027
+#define WGL_SWAP_EXCHANGE_EXT 0x2028
+#define WGL_SWAP_COPY_EXT 0x2029
+#define WGL_SWAP_UNDEFINED_EXT 0x202A
+#define WGL_TYPE_RGBA_EXT 0x202B
+#define WGL_TYPE_COLORINDEX_EXT 0x202C
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
+#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
+#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
+#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
+#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
+#define WGL_PBUFFER_LARGEST_EXT 0x2033
+#define WGL_PBUFFER_WIDTH_EXT 0x2034
+#define WGL_PBUFFER_HEIGHT_EXT 0x2035
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_DEPTH_FLOAT_EXT 0x2040
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
+#define WGL_SAMPLES_3DFX 0x2061
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_SAMPLE_BUFFERS_EXT 0x2041
+#define WGL_SAMPLES_EXT 0x2042
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
+#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
+#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
+#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
+#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
+#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045
+#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046
+#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047
+#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
+#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
+#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
+#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
+#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
+#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#endif
+
+#ifndef WGL_NV_render_depth_texture
+#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
+#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
+#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
+#define WGL_DEPTH_COMPONENT_NV 0x20A7
+#endif
+
+#ifndef WGL_NV_render_texture_rectangle
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
+#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_FLOAT_COMPONENTS_NV 0x20B0
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
+#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
+#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
+#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
+#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
+#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
+#endif
+
+#ifndef WGL_3DL_stereo_control
+#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
+#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
+#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
+#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+#endif
+
+
+/*************************************************************/
+
+#ifndef WGL_ARB_pbuffer
+DECLARE_HANDLE(HPBUFFERARB);
+#endif
+#ifndef WGL_EXT_pbuffer
+DECLARE_HANDLE(HPBUFFEREXT);
+#endif
+
+#ifndef WGL_ARB_buffer_region
+#define WGL_ARB_buffer_region 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT);
+extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE);
+extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int);
+extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
+typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
+typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
+typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
+#endif
+
+#ifndef WGL_ARB_multisample
+#define WGL_ARB_multisample 1
+#endif
+
+#ifndef WGL_ARB_extensions_string
+#define WGL_ARB_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringARB (HDC);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
+#endif
+
+#ifndef WGL_ARB_pixel_format
+#define WGL_ARB_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *);
+extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *);
+extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_ARB_make_current_read
+#define WGL_ARB_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC);
+extern HDC WINAPI wglGetCurrentReadDCARB (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
+#endif
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *);
+extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB);
+extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC);
+extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB);
+extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_ARB_render_texture
+#define WGL_ARB_render_texture 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int);
+extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int);
+extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
+typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
+#endif
+
+#ifndef WGL_ARB_pixel_format_float
+#define WGL_ARB_pixel_format_float 1
+#endif
+
+#ifndef WGL_EXT_display_color_table
+#define WGL_EXT_display_color_table 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort);
+extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint);
+extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort);
+extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
+typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
+#endif
+
+#ifndef WGL_EXT_extensions_string
+#define WGL_EXT_extensions_string 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern const char * WINAPI wglGetExtensionsStringEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_make_current_read
+#define WGL_EXT_make_current_read 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC);
+extern HDC WINAPI wglGetCurrentReadDCEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
+typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_pbuffer
+#define WGL_EXT_pbuffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *);
+extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT);
+extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC);
+extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT);
+extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
+typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
+typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
+typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
+#endif
+
+#ifndef WGL_EXT_pixel_format
+#define WGL_EXT_pixel_format 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *);
+extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *);
+extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
+typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
+typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+#endif
+
+#ifndef WGL_EXT_swap_control
+#define WGL_EXT_swap_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglSwapIntervalEXT (int);
+extern int WINAPI wglGetSwapIntervalEXT (void);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
+typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
+#endif
+
+#ifndef WGL_EXT_depth_float
+#define WGL_EXT_depth_float 1
+#endif
+
+#ifndef WGL_NV_vertex_array_range
+#define WGL_NV_vertex_array_range 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat);
+extern void WINAPI wglFreeMemoryNV (void *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
+typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
+#endif
+
+#ifndef WGL_3DFX_multisample
+#define WGL_3DFX_multisample 1
+#endif
+
+#ifndef WGL_EXT_multisample
+#define WGL_EXT_multisample 1
+#endif
+
+#ifndef WGL_OML_sync_control
+#define WGL_OML_sync_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *);
+extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *);
+extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64);
+extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64);
+extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *);
+extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
+typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
+typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
+typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
+#endif
+
+#ifndef WGL_I3D_digital_video_control
+#define WGL_I3D_digital_video_control 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *);
+extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+#endif
+
+#ifndef WGL_I3D_gamma
+#define WGL_I3D_gamma 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *);
+extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *);
+extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *);
+extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
+typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
+typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
+#endif
+
+#ifndef WGL_I3D_genlock
+#define WGL_I3D_genlock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableGenlockI3D (HDC);
+extern BOOL WINAPI wglDisableGenlockI3D (HDC);
+extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *);
+extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT);
+extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *);
+extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT);
+extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *);
+extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT);
+extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *);
+extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT);
+extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *);
+extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
+typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
+typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
+typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
+typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
+#endif
+
+#ifndef WGL_I3D_image_buffer
+#define WGL_I3D_image_buffer 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT);
+extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID);
+extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT);
+extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
+typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
+typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
+typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
+#endif
+
+#ifndef WGL_I3D_swap_frame_lock
+#define WGL_I3D_swap_frame_lock 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglEnableFrameLockI3D (void);
+extern BOOL WINAPI wglDisableFrameLockI3D (void);
+extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *);
+extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
+#endif
+
+#ifndef WGL_I3D_swap_frame_usage
+#define WGL_I3D_swap_frame_usage 1
+#ifdef WGL_WGLEXT_PROTOTYPES
+extern BOOL WINAPI wglGetFrameUsageI3D (float *);
+extern BOOL WINAPI wglBeginFrameTrackingI3D (void);
+extern BOOL WINAPI wglEndFrameTrackingI3D (void);
+extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *);
+#endif /* WGL_WGLEXT_PROTOTYPES */
+typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
+typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
+typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
+#endif
+
+#ifndef WGL_ATI_pixel_format_float
+#define WGL_ATI_pixel_format_float 1
+#endif
+
+#ifndef WGL_NV_float_buffer
+#define WGL_NV_float_buffer 1
+#endif
+
+#ifndef WGL_EXT_pixel_format_packed_float
+#define WGL_EXT_pixel_format_packed_float 1
+#endif
+
+#ifndef WGL_EXT_framebuffer_sRGB
+#define WGL_EXT_framebuffer_sRGB 1
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/VBox/Makefile.kup b/include/VBox/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/VBox/Makefile.kup
diff --git a/include/VBox/RemoteDesktop/VRDE.h b/include/VBox/RemoteDesktop/VRDE.h
new file mode 100644
index 00000000..d8a4946d
--- /dev/null
+++ b/include/VBox/RemoteDesktop/VRDE.h
@@ -0,0 +1,1603 @@
+/** @file
+ * VBox Remote Desktop Extension (VRDE) - Public APIs.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_RemoteDesktop_VRDE_h
+#define ___VBox_RemoteDesktop_VRDE_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+/** @defgroup grp_vrdp VRDE
+ * VirtualBox Remote Desktop Extension (VRDE) interface that lets to use
+ * a Remote Desktop server like RDP.
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/* Forward declaration of the VRDE server instance handle.
+ * This is an opaque pointer for VirtualBox.
+ * The VRDE library uses it as a pointer to some internal data.
+ */
+#ifdef __cplusplus
+class VRDEServer;
+typedef class VRDEServerType *HVRDESERVER;
+#else
+struct VRDEServer;
+typedef struct VRDEServerType *HVRDESERVER;
+#endif /* !__cplusplus */
+
+/* Callback based VRDE server interface declarations. */
+
+/** The color mouse pointer information. */
+typedef struct _VRDECOLORPOINTER
+{
+ uint16_t u16HotX;
+ uint16_t u16HotY;
+ uint16_t u16Width;
+ uint16_t u16Height;
+ uint16_t u16MaskLen;
+ uint16_t u16DataLen;
+ /* The 1BPP mask and the 24BPP bitmap follow. */
+} VRDECOLORPOINTER;
+
+/** Audio format information packed in a 32 bit value. */
+typedef uint32_t VRDEAUDIOFORMAT;
+
+/** Constructs 32 bit value for given frequency, number of channel and bits per sample. */
+#define VRDE_AUDIO_FMT_MAKE(freq, c, bps, s) ((((s) & 0x1) << 28) + (((bps) & 0xFF) << 20) + (((c) & 0xF) << 16) + ((freq) & 0xFFFF))
+
+/** Decode frequency. */
+#define VRDE_AUDIO_FMT_SAMPLE_FREQ(a) ((a) & 0xFFFF)
+/** Decode number of channels. */
+#define VRDE_AUDIO_FMT_CHANNELS(a) (((a) >> 16) & 0xF)
+/** Decode number signess. */
+#define VRDE_AUDIO_FMT_SIGNED(a) (((a) >> 28) & 0x1)
+/** Decode number of bits per sample. */
+#define VRDE_AUDIO_FMT_BITS_PER_SAMPLE(a) (((a) >> 20) & 0xFF)
+/** Decode number of bytes per sample. */
+#define VRDE_AUDIO_FMT_BYTES_PER_SAMPLE(a) ((VRDE_AUDIO_FMT_BITS_PER_SAMPLE(a) + 7) / 8)
+
+
+/*
+ * Audio input.
+ */
+
+/* Audio input notifications. */
+#define VRDE_AUDIOIN_BEGIN 1
+#define VRDE_AUDIOIN_DATA 2
+#define VRDE_AUDIOIN_END 3
+
+typedef struct VRDEAUDIOINBEGIN
+{
+ VRDEAUDIOFORMAT fmt; /* Actual format of data, which will be sent in VRDE_AUDIOIN_DATA events. */
+} VRDEAUDIOINBEGIN;
+
+
+/*
+ * Remote USB protocol.
+ */
+
+/* The initial version 1. */
+#define VRDE_USB_VERSION_1 (1)
+/* Version 2: look for VRDE_USB_VERSION_2 comments in the code. */
+#define VRDE_USB_VERSION_2 (2)
+/* Version 3: look for VRDE_USB_VERSION_3 comments in the code. */
+#define VRDE_USB_VERSION_3 (3)
+
+/* The default VRDE server version of Remote USB Protocol. */
+#define VRDE_USB_VERSION VRDE_USB_VERSION_3
+
+
+/** USB backend operations. */
+#define VRDE_USB_REQ_OPEN (0)
+#define VRDE_USB_REQ_CLOSE (1)
+#define VRDE_USB_REQ_RESET (2)
+#define VRDE_USB_REQ_SET_CONFIG (3)
+#define VRDE_USB_REQ_CLAIM_INTERFACE (4)
+#define VRDE_USB_REQ_RELEASE_INTERFACE (5)
+#define VRDE_USB_REQ_INTERFACE_SETTING (6)
+#define VRDE_USB_REQ_QUEUE_URB (7)
+#define VRDE_USB_REQ_REAP_URB (8)
+#define VRDE_USB_REQ_CLEAR_HALTED_EP (9)
+#define VRDE_USB_REQ_CANCEL_URB (10)
+
+/** USB service operations. */
+#define VRDE_USB_REQ_DEVICE_LIST (11)
+#define VRDE_USB_REQ_NEGOTIATE (12)
+
+/** An operation completion status is a byte. */
+typedef uint8_t VRDEUSBSTATUS;
+
+/** USB device identifier is an 32 bit value. */
+typedef uint32_t VRDEUSBDEVID;
+
+/** Status codes. */
+#define VRDE_USB_STATUS_SUCCESS ((VRDEUSBSTATUS)0)
+#define VRDE_USB_STATUS_ACCESS_DENIED ((VRDEUSBSTATUS)1)
+#define VRDE_USB_STATUS_DEVICE_REMOVED ((VRDEUSBSTATUS)2)
+
+/*
+ * Data structures to use with VRDEUSBRequest.
+ * The *RET* structures always represent the layout of VRDE data.
+ * The *PARM* structures normally the same as VRDE layout.
+ * However the VRDE_USB_REQ_QUEUE_URB_PARM has a pointer to
+ * URB data in place where actual data will be in VRDE layout.
+ *
+ * Since replies (*RET*) are asynchronous, the 'success'
+ * replies are not required for operations which return
+ * only the status code (VRDEUSBREQRETHDR only):
+ * VRDE_USB_REQ_OPEN
+ * VRDE_USB_REQ_RESET
+ * VRDE_USB_REQ_SET_CONFIG
+ * VRDE_USB_REQ_CLAIM_INTERFACE
+ * VRDE_USB_REQ_RELEASE_INTERFACE
+ * VRDE_USB_REQ_INTERFACE_SETTING
+ * VRDE_USB_REQ_CLEAR_HALTED_EP
+ *
+ */
+
+/* VRDE layout has no alignments. */
+#pragma pack(1)
+/* Common header for all VRDE USB packets. After the reply hdr follows *PARM* or *RET* data. */
+typedef struct _VRDEUSBPKTHDR
+{
+ /* Total length of the reply NOT including the 'length' field. */
+ uint32_t length;
+ /* The operation code for which the reply was sent by the client. */
+ uint8_t code;
+} VRDEUSBPKTHDR;
+
+/* Common header for all return structures. */
+typedef struct _VRDEUSBREQRETHDR
+{
+ /* Device status. */
+ VRDEUSBSTATUS status;
+ /* Device id. */
+ VRDEUSBDEVID id;
+} VRDEUSBREQRETHDR;
+
+
+/* VRDE_USB_REQ_OPEN
+ */
+typedef struct _VRDE_USB_REQ_OPEN_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+} VRDE_USB_REQ_OPEN_PARM;
+
+typedef struct _VRDE_USB_REQ_OPEN_RET
+{
+ VRDEUSBREQRETHDR hdr;
+} VRDE_USB_REQ_OPEN_RET;
+
+
+/* VRDE_USB_REQ_CLOSE
+ */
+typedef struct _VRDE_USB_REQ_CLOSE_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+} VRDE_USB_REQ_CLOSE_PARM;
+
+/* The close request has no returned data. */
+
+
+/* VRDE_USB_REQ_RESET
+ */
+typedef struct _VRDE_USB_REQ_RESET_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+} VRDE_USB_REQ_RESET_PARM;
+
+typedef struct _VRDE_USB_REQ_RESET_RET
+{
+ VRDEUSBREQRETHDR hdr;
+} VRDE_USB_REQ_RESET_RET;
+
+
+/* VRDE_USB_REQ_SET_CONFIG
+ */
+typedef struct _VRDE_USB_REQ_SET_CONFIG_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+ uint8_t configuration;
+} VRDE_USB_REQ_SET_CONFIG_PARM;
+
+typedef struct _VRDE_USB_REQ_SET_CONFIG_RET
+{
+ VRDEUSBREQRETHDR hdr;
+} VRDE_USB_REQ_SET_CONFIG_RET;
+
+
+/* VRDE_USB_REQ_CLAIM_INTERFACE
+ */
+typedef struct _VRDE_USB_REQ_CLAIM_INTERFACE_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+ uint8_t iface;
+} VRDE_USB_REQ_CLAIM_INTERFACE_PARM;
+
+typedef struct _VRDE_USB_REQ_CLAIM_INTERFACE_RET
+{
+ VRDEUSBREQRETHDR hdr;
+} VRDE_USB_REQ_CLAIM_INTERFACE_RET;
+
+
+/* VRDE_USB_REQ_RELEASE_INTERFACE
+ */
+typedef struct _VRDE_USB_REQ_RELEASE_INTERFACE_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+ uint8_t iface;
+} VRDE_USB_REQ_RELEASE_INTERFACE_PARM;
+
+typedef struct _VRDE_USB_REQ_RELEASE_INTERFACE_RET
+{
+ VRDEUSBREQRETHDR hdr;
+} VRDE_USB_REQ_RELEASE_INTERFACE_RET;
+
+
+/* VRDE_USB_REQ_INTERFACE_SETTING
+ */
+typedef struct _VRDE_USB_REQ_INTERFACE_SETTING_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+ uint8_t iface;
+ uint8_t setting;
+} VRDE_USB_REQ_INTERFACE_SETTING_PARM;
+
+typedef struct _VRDE_USB_REQ_INTERFACE_SETTING_RET
+{
+ VRDEUSBREQRETHDR hdr;
+} VRDE_USB_REQ_INTERFACE_SETTING_RET;
+
+
+/* VRDE_USB_REQ_QUEUE_URB
+ */
+
+#define VRDE_USB_TRANSFER_TYPE_CTRL (0)
+#define VRDE_USB_TRANSFER_TYPE_ISOC (1)
+#define VRDE_USB_TRANSFER_TYPE_BULK (2)
+#define VRDE_USB_TRANSFER_TYPE_INTR (3)
+#define VRDE_USB_TRANSFER_TYPE_MSG (4)
+
+#define VRDE_USB_DIRECTION_SETUP (0)
+#define VRDE_USB_DIRECTION_IN (1)
+#define VRDE_USB_DIRECTION_OUT (2)
+
+typedef struct _VRDE_USB_REQ_QUEUE_URB_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+ uint32_t handle; /* Distinguishes that particular URB. Later used in CancelURB and returned by ReapURB */
+ uint8_t type;
+ uint8_t ep;
+ uint8_t direction;
+ uint32_t urblen; /* Length of the URB. */
+ uint32_t datalen; /* Length of the data. */
+ void *data; /* In RDP layout the data follow. */
+} VRDE_USB_REQ_QUEUE_URB_PARM;
+
+/* The queue URB has no explicit return. The reap URB reply will be
+ * eventually the indirect result.
+ */
+
+
+/* VRDE_USB_REQ_REAP_URB
+ * Notificationg from server to client that server expects an URB
+ * from any device.
+ * Only sent if negotiated URB return method is polling.
+ * Normally, the client will send URBs back as soon as they are ready.
+ */
+typedef struct _VRDE_USB_REQ_REAP_URB_PARM
+{
+ uint8_t code;
+} VRDE_USB_REQ_REAP_URB_PARM;
+
+
+#define VRDE_USB_XFER_OK (0)
+#define VRDE_USB_XFER_STALL (1)
+#define VRDE_USB_XFER_DNR (2)
+#define VRDE_USB_XFER_CRC (3)
+/* VRDE_USB_VERSION_2: New error codes. OHCI Completion Codes. */
+#define VRDE_USB_XFER_BS (4) /* BitStuffing */
+#define VRDE_USB_XFER_DTM (5) /* DataToggleMismatch */
+#define VRDE_USB_XFER_PCF (6) /* PIDCheckFailure */
+#define VRDE_USB_XFER_UPID (7) /* UnexpectedPID */
+#define VRDE_USB_XFER_DO (8) /* DataOverrun */
+#define VRDE_USB_XFER_DU (9) /* DataUnderrun */
+#define VRDE_USB_XFER_BO (10) /* BufferOverrun */
+#define VRDE_USB_XFER_BU (11) /* BufferUnderrun */
+#define VRDE_USB_XFER_ERR (12) /* VBox protocol error. */
+
+#define VRDE_USB_REAP_FLAG_CONTINUED (0x0)
+#define VRDE_USB_REAP_FLAG_LAST (0x1)
+/* VRDE_USB_VERSION_3: Fragmented URBs. */
+#define VRDE_USB_REAP_FLAG_FRAGMENT (0x2)
+
+#define VRDE_USB_REAP_VALID_FLAGS (VRDE_USB_REAP_FLAG_LAST)
+/* VRDE_USB_VERSION_3: Fragmented URBs. */
+#define VRDE_USB_REAP_VALID_FLAGS_3 (VRDE_USB_REAP_FLAG_LAST | VRDE_USB_REAP_FLAG_FRAGMENT)
+
+typedef struct _VRDEUSBREQREAPURBBODY
+{
+ VRDEUSBDEVID id; /* From which device the URB arrives. */
+ uint8_t flags; /* VRDE_USB_REAP_FLAG_* */
+ uint8_t error; /* VRDE_USB_XFER_* */
+ uint32_t handle; /* Handle of returned URB. Not 0. */
+ uint32_t len; /* Length of data actually transferred. */
+ /* 'len' bytes of data follow if direction of this URB was VRDE_USB_DIRECTION_IN. */
+} VRDEUSBREQREAPURBBODY;
+
+typedef struct _VRDE_USB_REQ_REAP_URB_RET
+{
+ /* The REAP URB has no header, only completed URBs are returned. */
+ VRDEUSBREQREAPURBBODY body;
+ /* Another body may follow, depending on flags. */
+} VRDE_USB_REQ_REAP_URB_RET;
+
+
+/* VRDE_USB_REQ_CLEAR_HALTED_EP
+ */
+typedef struct _VRDE_USB_REQ_CLEAR_HALTED_EP_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+ uint8_t ep;
+} VRDE_USB_REQ_CLEAR_HALTED_EP_PARM;
+
+typedef struct _VRDE_USB_REQ_CLEAR_HALTED_EP_RET
+{
+ VRDEUSBREQRETHDR hdr;
+} VRDE_USB_REQ_CLEAR_HALTED_EP_RET;
+
+
+/* VRDE_USB_REQ_CANCEL_URB
+ */
+typedef struct _VRDE_USB_REQ_CANCEL_URB_PARM
+{
+ uint8_t code;
+ VRDEUSBDEVID id;
+ uint32_t handle;
+} VRDE_USB_REQ_CANCEL_URB_PARM;
+
+/* The cancel URB request has no return. */
+
+
+/* VRDE_USB_REQ_DEVICE_LIST
+ *
+ * Server polls USB devices on client by sending this request
+ * periodically. Client sends back a list of all devices
+ * connected to it. Each device is assigned with an identifier,
+ * that is used to distinguish the particular device.
+ */
+typedef struct _VRDE_USB_REQ_DEVICE_LIST_PARM
+{
+ uint8_t code;
+} VRDE_USB_REQ_DEVICE_LIST_PARM;
+
+/* Data is a list of the following variable length structures. */
+typedef struct _VRDEUSBDEVICEDESC
+{
+ /* Offset of the next structure. 0 if last. */
+ uint16_t oNext;
+
+ /* Identifier of the device assigned by client. */
+ VRDEUSBDEVID id;
+
+ /** USB version number. */
+ uint16_t bcdUSB;
+ /** Device class. */
+ uint8_t bDeviceClass;
+ /** Device subclass. */
+ uint8_t bDeviceSubClass;
+ /** Device protocol */
+ uint8_t bDeviceProtocol;
+ /** Vendor ID. */
+ uint16_t idVendor;
+ /** Product ID. */
+ uint16_t idProduct;
+ /** Revision, integer part. */
+ uint16_t bcdRev;
+ /** Offset of the UTF8 manufacturer string relative to the structure start. */
+ uint16_t oManufacturer;
+ /** Offset of the UTF8 product string relative to the structure start. */
+ uint16_t oProduct;
+ /** Offset of the UTF8 serial number string relative to the structure start. */
+ uint16_t oSerialNumber;
+ /** Physical USB port the device is connected to. */
+ uint16_t idPort;
+
+} VRDEUSBDEVICEDESC;
+
+#define VRDE_USBDEVICESPEED_UNKNOWN 0 /* Unknown. */
+#define VRDE_USBDEVICESPEED_LOW 1 /* Low speed (1.5 Mbit/s). */
+#define VRDE_USBDEVICESPEED_FULL 2 /* Full speed (12 Mbit/s). */
+#define VRDE_USBDEVICESPEED_HIGH 3 /* High speed (480 Mbit/s). */
+#define VRDE_USBDEVICESPEED_VARIABLE 4 /* Variable speed - USB 2.5 / wireless. */
+#define VRDE_USBDEVICESPEED_SUPERSPEED 5 /* Super Speed - USB 3.0 */
+
+typedef struct _VRDEUSBDEVICEDESCEXT
+{
+ VRDEUSBDEVICEDESC desc;
+
+ /* Extended info.
+ */
+
+ /** The USB device speed: VRDE_USBDEVICESPEED_*. */
+ uint16_t u16DeviceSpeed;
+} VRDEUSBDEVICEDESCEXT;
+
+typedef struct _VRDE_USB_REQ_DEVICE_LIST_RET
+{
+ VRDEUSBDEVICEDESC body;
+ /* Other devices may follow.
+ * The list ends with (uint16_t)0,
+ * which means that an empty list consists of 2 zero bytes.
+ */
+} VRDE_USB_REQ_DEVICE_LIST_RET;
+
+typedef struct _VRDE_USB_REQ_DEVICE_LIST_EXT_RET
+{
+ VRDEUSBDEVICEDESCEXT body;
+ /* Other devices may follow.
+ * The list ends with (uint16_t)0,
+ * which means that an empty list consists of 2 zero bytes.
+ */
+} VRDE_USB_REQ_DEVICE_LIST_EXT_RET;
+
+/* The server requests the version of the port the device is attached to.
+ * The client must use VRDEUSBDEVICEDESCEXT structure.
+ */
+#define VRDE_USB_SERVER_CAPS_PORT_VERSION 0x0001
+
+typedef struct _VRDEUSBREQNEGOTIATEPARM
+{
+ uint8_t code;
+
+ /* Remote USB Protocol version. */
+ /* VRDE_USB_VERSION_3: the 32 bit field is splitted to 16 bit version and 16 bit flags.
+ * Version 1 and 2 servers therefore have 'flags' == 0.
+ * Version 3+ servers can send some capabilities in this field, this way it is possible to add
+ * a new capability without increasing the protocol version.
+ */
+ uint16_t version;
+ uint16_t flags; /* See VRDE_USB_SERVER_CAPS_* */
+
+} VRDEUSBREQNEGOTIATEPARM;
+
+/* VRDEUSBREQNEGOTIATERET flags. */
+#define VRDE_USB_CAPS_FLAG_ASYNC (0x0)
+#define VRDE_USB_CAPS_FLAG_POLL (0x1)
+/* VRDE_USB_VERSION_2: New flag. */
+#define VRDE_USB_CAPS2_FLAG_VERSION (0x2) /* The client is negotiating the protocol version. */
+/* VRDE_USB_VERSION_3: New flag. */
+#define VRDE_USB_CAPS3_FLAG_EXT (0x4) /* The client is negotiating the extended flags.
+ * If this flag is set, then the VRDE_USB_CAPS2_FLAG_VERSION
+ * must also be set.
+ */
+
+
+#define VRDE_USB_CAPS_VALID_FLAGS (VRDE_USB_CAPS_FLAG_POLL)
+/* VRDE_USB_VERSION_2: A set of valid flags. */
+#define VRDE_USB_CAPS2_VALID_FLAGS (VRDE_USB_CAPS_FLAG_POLL | VRDE_USB_CAPS2_FLAG_VERSION)
+/* VRDE_USB_VERSION_3: A set of valid flags. */
+#define VRDE_USB_CAPS3_VALID_FLAGS (VRDE_USB_CAPS_FLAG_POLL | VRDE_USB_CAPS2_FLAG_VERSION | VRDE_USB_CAPS3_FLAG_EXT)
+
+typedef struct _VRDEUSBREQNEGOTIATERET
+{
+ uint8_t flags;
+} VRDEUSBREQNEGOTIATERET;
+
+typedef struct _VRDEUSBREQNEGOTIATERET_2
+{
+ uint8_t flags;
+ uint32_t u32Version; /* This field presents only if the VRDE_USB_CAPS2_FLAG_VERSION flag is set. */
+} VRDEUSBREQNEGOTIATERET_2;
+
+/* The server requests the version of the port the device is attached to.
+ * The client must use VRDEUSBDEVICEDESCEXT structure.
+ */
+#define VRDE_USB_CLIENT_CAPS_PORT_VERSION 0x00000001
+
+typedef struct _VRDEUSBREQNEGOTIATERET_3
+{
+ uint8_t flags;
+ uint32_t u32Version; /* This field presents only if the VRDE_USB_CAPS2_FLAG_VERSION flag is set. */
+ uint32_t u32Flags; /* This field presents only if both VRDE_USB_CAPS2_FLAG_VERSION and
+ * VRDE_USB_CAPS2_FLAG_EXT flag are set.
+ * See VRDE_USB_CLIENT_CAPS_*
+ */
+} VRDEUSBREQNEGOTIATERET_3;
+#pragma pack()
+
+#define VRDE_CLIPBOARD_FORMAT_NULL (0x0)
+#define VRDE_CLIPBOARD_FORMAT_UNICODE_TEXT (0x1)
+#define VRDE_CLIPBOARD_FORMAT_BITMAP (0x2)
+#define VRDE_CLIPBOARD_FORMAT_HTML (0x4)
+
+#define VRDE_CLIPBOARD_FUNCTION_FORMAT_ANNOUNCE (0)
+#define VRDE_CLIPBOARD_FUNCTION_DATA_READ (1)
+#define VRDE_CLIPBOARD_FUNCTION_DATA_WRITE (2)
+
+
+/** Indexes of information values. */
+
+/** Whether a client is connected at the moment.
+ * uint32_t
+ */
+#define VRDE_QI_ACTIVE (0)
+
+/** How many times a client connected up to current moment.
+ * uint32_t
+ */
+#define VRDE_QI_NUMBER_OF_CLIENTS (1)
+
+/** When last connection was established.
+ * int64_t time in milliseconds since 1970-01-01 00:00:00 UTC
+ */
+#define VRDE_QI_BEGIN_TIME (2)
+
+/** When last connection was terminated or current time if connection still active.
+ * int64_t time in milliseconds since 1970-01-01 00:00:00 UTC
+ */
+#define VRDE_QI_END_TIME (3)
+
+/** How many bytes were sent in last (current) connection.
+ * uint64_t
+ */
+#define VRDE_QI_BYTES_SENT (4)
+
+/** How many bytes were sent in all connections.
+ * uint64_t
+ */
+#define VRDE_QI_BYTES_SENT_TOTAL (5)
+
+/** How many bytes were received in last (current) connection.
+ * uint64_t
+ */
+#define VRDE_QI_BYTES_RECEIVED (6)
+
+/** How many bytes were received in all connections.
+ * uint64_t
+ */
+#define VRDE_QI_BYTES_RECEIVED_TOTAL (7)
+
+/** Login user name supplied by the client.
+ * UTF8 nul terminated string.
+ */
+#define VRDE_QI_USER (8)
+
+/** Login domain supplied by the client.
+ * UTF8 nul terminated string.
+ */
+#define VRDE_QI_DOMAIN (9)
+
+/** The client name supplied by the client.
+ * UTF8 nul terminated string.
+ */
+#define VRDE_QI_CLIENT_NAME (10)
+
+/** IP address of the client.
+ * UTF8 nul terminated string.
+ */
+#define VRDE_QI_CLIENT_IP (11)
+
+/** The client software version number.
+ * uint32_t.
+ */
+#define VRDE_QI_CLIENT_VERSION (12)
+
+/** Public key exchange method used when connection was established.
+ * Values: 0 - RDP4 public key exchange scheme.
+ * 1 - X509 sertificates were sent to client.
+ * uint32_t.
+ */
+#define VRDE_QI_ENCRYPTION_STYLE (13)
+
+/** TCP port where the server listens.
+ * Values: 0 - VRDE server failed to start.
+ * -1 - .
+ * int32_t.
+ */
+#define VRDE_QI_PORT (14)
+
+
+/** Hints what has been intercepted by the application. */
+#define VRDE_CLIENT_INTERCEPT_AUDIO (0x1)
+#define VRDE_CLIENT_INTERCEPT_USB (0x2)
+#define VRDE_CLIENT_INTERCEPT_CLIPBOARD (0x4)
+#define VRDE_CLIENT_INTERCEPT_AUDIO_INPUT (0x8)
+
+
+/** The version of the VRDE server interface. */
+#define VRDE_INTERFACE_VERSION_1 (1)
+#define VRDE_INTERFACE_VERSION_2 (2)
+#define VRDE_INTERFACE_VERSION_3 (3)
+#define VRDE_INTERFACE_VERSION_4 (4)
+
+/** The header that does not change when the interface changes. */
+typedef struct _VRDEINTERFACEHDR
+{
+ /** The version of the interface. */
+ uint64_t u64Version;
+
+ /** The size of the structure. */
+ uint64_t u64Size;
+
+} VRDEINTERFACEHDR;
+
+/** The VRDE server entry points. Interface version 1. */
+typedef struct _VRDEENTRYPOINTS_1
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /** Destroy the server instance.
+ *
+ * @param hServer The server instance handle.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEDestroy,(HVRDESERVER hServer));
+
+ /** The server should start to accept clients connections.
+ *
+ * @param hServer The server instance handle.
+ * @param fEnable Whether to enable or disable client connections.
+ * When is false, all existing clients are disconnected.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEEnableConnections,(HVRDESERVER hServer,
+ bool fEnable));
+
+ /** The server should disconnect the client.
+ *
+ * @param hServer The server instance handle.
+ * @param u32ClientId The client identifier.
+ * @param fReconnect Whether to send a "REDIRECT to the same server" packet to the
+ * client before disconnecting.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEDisconnect,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ bool fReconnect));
+
+ /**
+ * Inform the server that the display was resized.
+ * The server will query information about display
+ * from the application via callbacks.
+ *
+ * @param hServer Handle of VRDE server instance.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEResize,(HVRDESERVER hServer));
+
+ /**
+ * Send a update.
+ *
+ * Note: the server must access the framebuffer bitmap only when VRDEUpdate is called.
+ * If the have to access the bitmap later or from another thread, then
+ * it must used an intermediate buffer and copy the framebuffer data to the
+ * intermediate buffer in VRDEUpdate.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param uScreenId The screen index.
+ * @param pvUpdate Pointer to VRDEOrders.h::VRDEORDERHDR structure with extra data.
+ * @param cbUpdate Size of the update data.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEUpdate,(HVRDESERVER hServer,
+ unsigned uScreenId,
+ void *pvUpdate,
+ uint32_t cbUpdate));
+
+ /**
+ * Set the mouse pointer shape.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param pPointer The pointer shape information.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEColorPointer,(HVRDESERVER hServer,
+ const VRDECOLORPOINTER *pPointer));
+
+ /**
+ * Hide the mouse pointer.
+ *
+ * @param hServer Handle of VRDE server instance.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEHidePointer,(HVRDESERVER hServer));
+
+ /**
+ * Queues the samples to be sent to clients.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param pvSamples Address of samples to be sent.
+ * @param cSamples Number of samples.
+ * @param format Encoded audio format for these samples.
+ *
+ * @note Initialized to NULL when the application audio callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEAudioSamples,(HVRDESERVER hServer,
+ const void *pvSamples,
+ uint32_t cSamples,
+ VRDEAUDIOFORMAT format));
+
+ /**
+ * Sets the sound volume on clients.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param left 0..0xFFFF volume level for left channel.
+ * @param right 0..0xFFFF volume level for right channel.
+ *
+ * @note Initialized to NULL when the application audio callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEAudioVolume,(HVRDESERVER hServer,
+ uint16_t u16Left,
+ uint16_t u16Right));
+
+ /**
+ * Sends a USB request.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param u32ClientId An identifier that allows the server to find the corresponding client.
+ * The identifier is always passed by the server as a parameter
+ * of the FNVRDEUSBCALLBACK. Note that the value is the same as
+ * in the VRDESERVERCALLBACK functions.
+ * @param pvParm Function specific parameters buffer.
+ * @param cbParm Size of the buffer.
+ *
+ * @note Initialized to NULL when the application USB callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEUSBRequest,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ void *pvParm,
+ uint32_t cbParm));
+
+ /**
+ * Called by the application when (VRDE_CLIPBOARD_FUNCTION_*):
+ * - (0) guest announces available clipboard formats;
+ * - (1) guest requests clipboard data;
+ * - (2) guest responds to the client's request for clipboard data.
+ *
+ * @param hServer The VRDE server handle.
+ * @param u32Function The cause of the call.
+ * @param u32Format Bitmask of announced formats or the format of data.
+ * @param pvData Points to: (1) buffer to be filled with clients data;
+ * (2) data from the host.
+ * @param cbData Size of 'pvData' buffer in bytes.
+ * @param pcbActualRead Size of the copied data in bytes.
+ *
+ * @note Initialized to NULL when the application clipboard callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEClipboard,(HVRDESERVER hServer,
+ uint32_t u32Function,
+ uint32_t u32Format,
+ void *pvData,
+ uint32_t cbData,
+ uint32_t *pcbActualRead));
+
+ /**
+ * Query various information from the VRDE server.
+ *
+ * @param hServer The VRDE server handle.
+ * @param index VRDE_QI_* identifier of information to be returned.
+ * @param pvBuffer Address of memory buffer to which the information must be written.
+ * @param cbBuffer Size of the memory buffer in bytes.
+ * @param pcbOut Size in bytes of returned information value.
+ *
+ * @remark The caller must check the *pcbOut. 0 there means no information was returned.
+ * A value greater than cbBuffer means that information is too big to fit in the
+ * buffer, in that case no information was placed to the buffer.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEQueryInfo,(HVRDESERVER hServer,
+ uint32_t index,
+ void *pvBuffer,
+ uint32_t cbBuffer,
+ uint32_t *pcbOut));
+} VRDEENTRYPOINTS_1;
+
+/** The VRDE server entry points. Interface version 2.
+ * A new entry point VRDERedirect has been added relative to version 1.
+ */
+typedef struct _VRDEENTRYPOINTS_2
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /** Destroy the server instance.
+ *
+ * @param hServer The server instance handle.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEDestroy,(HVRDESERVER hServer));
+
+ /** The server should start to accept clients connections.
+ *
+ * @param hServer The server instance handle.
+ * @param fEnable Whether to enable or disable client connections.
+ * When is false, all existing clients are disconnected.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEEnableConnections,(HVRDESERVER hServer,
+ bool fEnable));
+
+ /** The server should disconnect the client.
+ *
+ * @param hServer The server instance handle.
+ * @param u32ClientId The client identifier.
+ * @param fReconnect Whether to send a "REDIRECT to the same server" packet to the
+ * client before disconnecting.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEDisconnect,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ bool fReconnect));
+
+ /**
+ * Inform the server that the display was resized.
+ * The server will query information about display
+ * from the application via callbacks.
+ *
+ * @param hServer Handle of VRDE server instance.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEResize,(HVRDESERVER hServer));
+
+ /**
+ * Send a update.
+ *
+ * Note: the server must access the framebuffer bitmap only when VRDEUpdate is called.
+ * If the have to access the bitmap later or from another thread, then
+ * it must used an intermediate buffer and copy the framebuffer data to the
+ * intermediate buffer in VRDEUpdate.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param uScreenId The screen index.
+ * @param pvUpdate Pointer to VRDEOrders.h::VRDEORDERHDR structure with extra data.
+ * @param cbUpdate Size of the update data.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEUpdate,(HVRDESERVER hServer,
+ unsigned uScreenId,
+ void *pvUpdate,
+ uint32_t cbUpdate));
+
+ /**
+ * Set the mouse pointer shape.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param pPointer The pointer shape information.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEColorPointer,(HVRDESERVER hServer,
+ const VRDECOLORPOINTER *pPointer));
+
+ /**
+ * Hide the mouse pointer.
+ *
+ * @param hServer Handle of VRDE server instance.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEHidePointer,(HVRDESERVER hServer));
+
+ /**
+ * Queues the samples to be sent to clients.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param pvSamples Address of samples to be sent.
+ * @param cSamples Number of samples.
+ * @param format Encoded audio format for these samples.
+ *
+ * @note Initialized to NULL when the application audio callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEAudioSamples,(HVRDESERVER hServer,
+ const void *pvSamples,
+ uint32_t cSamples,
+ VRDEAUDIOFORMAT format));
+
+ /**
+ * Sets the sound volume on clients.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param left 0..0xFFFF volume level for left channel.
+ * @param right 0..0xFFFF volume level for right channel.
+ *
+ * @note Initialized to NULL when the application audio callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEAudioVolume,(HVRDESERVER hServer,
+ uint16_t u16Left,
+ uint16_t u16Right));
+
+ /**
+ * Sends a USB request.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param u32ClientId An identifier that allows the server to find the corresponding client.
+ * The identifier is always passed by the server as a parameter
+ * of the FNVRDEUSBCALLBACK. Note that the value is the same as
+ * in the VRDESERVERCALLBACK functions.
+ * @param pvParm Function specific parameters buffer.
+ * @param cbParm Size of the buffer.
+ *
+ * @note Initialized to NULL when the application USB callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEUSBRequest,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ void *pvParm,
+ uint32_t cbParm));
+
+ /**
+ * Called by the application when (VRDE_CLIPBOARD_FUNCTION_*):
+ * - (0) guest announces available clipboard formats;
+ * - (1) guest requests clipboard data;
+ * - (2) guest responds to the client's request for clipboard data.
+ *
+ * @param hServer The VRDE server handle.
+ * @param u32Function The cause of the call.
+ * @param u32Format Bitmask of announced formats or the format of data.
+ * @param pvData Points to: (1) buffer to be filled with clients data;
+ * (2) data from the host.
+ * @param cbData Size of 'pvData' buffer in bytes.
+ * @param pcbActualRead Size of the copied data in bytes.
+ *
+ * @note Initialized to NULL when the application clipboard callbacks are NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEClipboard,(HVRDESERVER hServer,
+ uint32_t u32Function,
+ uint32_t u32Format,
+ void *pvData,
+ uint32_t cbData,
+ uint32_t *pcbActualRead));
+
+ /**
+ * Query various information from the VRDE server.
+ *
+ * @param hServer The VRDE server handle.
+ * @param index VRDE_QI_* identifier of information to be returned.
+ * @param pvBuffer Address of memory buffer to which the information must be written.
+ * @param cbBuffer Size of the memory buffer in bytes.
+ * @param pcbOut Size in bytes of returned information value.
+ *
+ * @remark The caller must check the *pcbOut. 0 there means no information was returned.
+ * A value greater than cbBuffer means that information is too big to fit in the
+ * buffer, in that case no information was placed to the buffer.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEQueryInfo,(HVRDESERVER hServer,
+ uint32_t index,
+ void *pvBuffer,
+ uint32_t cbBuffer,
+ uint32_t *pcbOut));
+
+ /**
+ * The server should redirect the client to the specified server.
+ *
+ * @param hServer The server instance handle.
+ * @param u32ClientId The client identifier.
+ * @param pszServer The server to redirect the client to.
+ * @param pszUser The username to use for the redirection.
+ * Can be NULL.
+ * @param pszDomain The domain. Can be NULL.
+ * @param pszPassword The password. Can be NULL.
+ * @param u32SessionId The ID of the session to redirect to.
+ * @param pszCookie The routing token used by a load balancer to
+ * route the redirection. Can be NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDERedirect,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ const char *pszServer,
+ const char *pszUser,
+ const char *pszDomain,
+ const char *pszPassword,
+ uint32_t u32SessionId,
+ const char *pszCookie));
+} VRDEENTRYPOINTS_2;
+
+/** The VRDE server entry points. Interface version 3.
+ * New entry points VRDEAudioInOpen and VRDEAudioInClose has been added relative to version 2.
+ */
+typedef struct _VRDEENTRYPOINTS_3
+{
+ /* The header. */
+ VRDEINTERFACEHDR header;
+
+ /*
+ * Same as version 2. See comment in VRDEENTRYPOINTS_2.
+ */
+
+ DECLR3CALLBACKMEMBER(void, VRDEDestroy,(HVRDESERVER hServer));
+
+ DECLR3CALLBACKMEMBER(int, VRDEEnableConnections,(HVRDESERVER hServer,
+ bool fEnable));
+
+ DECLR3CALLBACKMEMBER(void, VRDEDisconnect,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ bool fReconnect));
+
+ DECLR3CALLBACKMEMBER(void, VRDEResize,(HVRDESERVER hServer));
+
+ DECLR3CALLBACKMEMBER(void, VRDEUpdate,(HVRDESERVER hServer,
+ unsigned uScreenId,
+ void *pvUpdate,
+ uint32_t cbUpdate));
+
+ DECLR3CALLBACKMEMBER(void, VRDEColorPointer,(HVRDESERVER hServer,
+ const VRDECOLORPOINTER *pPointer));
+
+ DECLR3CALLBACKMEMBER(void, VRDEHidePointer,(HVRDESERVER hServer));
+
+ DECLR3CALLBACKMEMBER(void, VRDEAudioSamples,(HVRDESERVER hServer,
+ const void *pvSamples,
+ uint32_t cSamples,
+ VRDEAUDIOFORMAT format));
+
+ DECLR3CALLBACKMEMBER(void, VRDEAudioVolume,(HVRDESERVER hServer,
+ uint16_t u16Left,
+ uint16_t u16Right));
+
+ DECLR3CALLBACKMEMBER(void, VRDEUSBRequest,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ void *pvParm,
+ uint32_t cbParm));
+
+ DECLR3CALLBACKMEMBER(void, VRDEClipboard,(HVRDESERVER hServer,
+ uint32_t u32Function,
+ uint32_t u32Format,
+ void *pvData,
+ uint32_t cbData,
+ uint32_t *pcbActualRead));
+
+ DECLR3CALLBACKMEMBER(void, VRDEQueryInfo,(HVRDESERVER hServer,
+ uint32_t index,
+ void *pvBuffer,
+ uint32_t cbBuffer,
+ uint32_t *pcbOut));
+
+ DECLR3CALLBACKMEMBER(void, VRDERedirect,(HVRDESERVER hServer,
+ uint32_t u32ClientId,
+ const char *pszServer,
+ const char *pszUser,
+ const char *pszDomain,
+ const char *pszPassword,
+ uint32_t u32SessionId,
+ const char *pszCookie));
+
+ /*
+ * New for version 3.
+ */
+
+ /**
+ * Audio input open request.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param pvCtx To be used in VRDECallbackAudioIn.
+ * @param u32ClientId An identifier that allows the server to find the corresponding client.
+ * @param audioFormat Preferred format of audio data.
+ * @param u32SamplesPerBlock Preferred number of samples in one block of audio input data.
+ *
+ * @note Initialized to NULL when the VRDECallbackAudioIn callback is NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEAudioInOpen,(HVRDESERVER hServer,
+ void *pvCtx,
+ uint32_t u32ClientId,
+ VRDEAUDIOFORMAT audioFormat,
+ uint32_t u32SamplesPerBlock));
+
+ /**
+ * Audio input close request.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param u32ClientId An identifier that allows the server to find the corresponding client.
+ *
+ * @note Initialized to NULL when the VRDECallbackAudioIn callback is NULL.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEAudioInClose,(HVRDESERVER hServer,
+ uint32_t u32ClientId));
+} VRDEENTRYPOINTS_3;
+
+
+/* Indexes for VRDECallbackProperty.
+ * *_QP_* queries a property.
+ * *_SP_* sets a property.
+ */
+#define VRDE_QP_NETWORK_PORT (1) /* Obsolete. Use VRDE_QP_NETWORK_PORT_RANGE instead. */
+#define VRDE_QP_NETWORK_ADDRESS (2) /* UTF8 string. Host network interface IP address to bind to. */
+#define VRDE_QP_NUMBER_MONITORS (3) /* 32 bit. Number of monitors in the VM. */
+#define VRDE_QP_NETWORK_PORT_RANGE (4) /* UTF8 string. List of ports. The server must bind to one of
+ * free ports from the list. Example: "3000,3010-3012,4000",
+ * which tells the server to bind to either of ports:
+ * 3000, 3010, 3011, 3012, 4000.
+ */
+#ifdef VBOX_WITH_VRDP_VIDEO_CHANNEL
+#define VRDE_QP_VIDEO_CHANNEL (5)
+#define VRDE_QP_VIDEO_CHANNEL_QUALITY (6)
+#define VRDE_QP_VIDEO_CHANNEL_SUNFLSH (7)
+#endif /* VBOX_WITH_VRDP_VIDEO_CHANNEL */
+#define VRDE_QP_FEATURE (8) /* VRDEFEATURE structure. Generic interface to query named VRDE properties. */
+
+#define VRDE_SP_BASE 0x1000
+#define VRDE_SP_NETWORK_BIND_PORT (VRDE_SP_BASE + 1) /* 32 bit. The port number actually used by the server.
+ * If VRDECreateServer fails, it should set the port to 0.
+ * If VRDECreateServer succeeds, then the port must be set
+ * in VRDEEnableConnections to the actually used value.
+ * VRDEDestroy must set the port to 0xFFFFFFFF.
+ */
+#define VRDE_SP_CLIENT_STATUS (VRDE_SP_BASE + 2) /* UTF8 string. The change of the generic client status:
+ * "ATTACH" - the client is attached;
+ * "DETACH" - the client is detached;
+ * "NAME=..." - the client name changes.
+ * Can be used for other notifications.
+ */
+
+#pragma pack(1)
+/* VRDE_QP_FEATURE data. */
+typedef struct _VRDEFEATURE
+{
+ uint32_t u32ClientId;
+ char achInfo[1]; /* UTF8 property input name and output value. */
+} VRDEFEATURE;
+
+/* VRDE_SP_CLIENT_STATUS data. */
+typedef struct VRDECLIENTSTATUS
+{
+ uint32_t u32ClientId;
+ uint32_t cbStatus;
+ char achStatus[1]; /* UTF8 status string. */
+} VRDECLIENTSTATUS;
+
+/* A framebuffer description. */
+typedef struct _VRDEFRAMEBUFFERINFO
+{
+ const uint8_t *pu8Bits;
+ int xOrigin;
+ int yOrigin;
+ unsigned cWidth;
+ unsigned cHeight;
+ unsigned cBitsPerPixel;
+ unsigned cbLine;
+} VRDEFRAMEBUFFERINFO;
+
+#define VRDE_INPUT_SCANCODE 0
+#define VRDE_INPUT_POINT 1
+#define VRDE_INPUT_CAD 2
+#define VRDE_INPUT_RESET 3
+#define VRDE_INPUT_SYNCH 4
+
+typedef struct _VRDEINPUTSCANCODE
+{
+ unsigned uScancode;
+} VRDEINPUTSCANCODE;
+
+#define VRDE_INPUT_POINT_BUTTON1 0x01
+#define VRDE_INPUT_POINT_BUTTON2 0x02
+#define VRDE_INPUT_POINT_BUTTON3 0x04
+#define VRDE_INPUT_POINT_WHEEL_UP 0x08
+#define VRDE_INPUT_POINT_WHEEL_DOWN 0x10
+
+typedef struct _VRDEINPUTPOINT
+{
+ int x;
+ int y;
+ unsigned uButtons;
+} VRDEINPUTPOINT;
+
+#define VRDE_INPUT_SYNCH_SCROLL 0x01
+#define VRDE_INPUT_SYNCH_NUMLOCK 0x02
+#define VRDE_INPUT_SYNCH_CAPITAL 0x04
+
+typedef struct _VRDEINPUTSYNCH
+{
+ unsigned uLockStatus;
+} VRDEINPUTSYNCH;
+#pragma pack()
+
+/** The VRDE server callbacks. Interface version 1. */
+typedef struct _VRDECALLBACKS_1
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /**
+ * Query or set various information, on how the VRDE server operates, from or to the application.
+ * Queries for properties will always return success, and if the key is not known or has no
+ * value associated with it an empty string is returned.
+ *
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param index VRDE_[Q|S]P_* identifier of information to be returned or set.
+ * @param pvBuffer Address of memory buffer to which the information must be written or read.
+ * @param cbBuffer Size of the memory buffer in bytes.
+ * @param pcbOut Size in bytes of returned information value.
+ *
+ * @return IPRT status code. VINF_BUFFER_OVERFLOW if the buffer is too small for the value.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDECallbackProperty,(void *pvCallback,
+ uint32_t index,
+ void *pvBuffer,
+ uint32_t cbBuffer,
+ uint32_t *pcbOut));
+
+ /* A client is logging in, the application must decide whether
+ * to let to connect the client. The server will drop the connection,
+ * when an error code is returned by the callback.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param u32ClientId An unique client identifier generated by the server.
+ * @param pszUser The username.
+ * @param pszPassword The password.
+ * @param pszDomain The domain.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDECallbackClientLogon,(void *pvCallback,
+ uint32_t u32ClientId,
+ const char *pszUser,
+ const char *pszPassword,
+ const char *pszDomain));
+
+ /* The client has been successfully connected. That is logon was successful and the
+ * remote desktop protocol connection completely established.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param u32ClientId An unique client identifier generated by the server.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDECallbackClientConnect,(void *pvCallback,
+ uint32_t u32ClientId));
+
+ /* The client has been disconnected.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param u32ClientId An unique client identifier generated by the server.
+ * @param fu32Intercepted What was intercepted by the client (VRDE_CLIENT_INTERCEPT_*).
+ */
+ DECLR3CALLBACKMEMBER(void, VRDECallbackClientDisconnect,(void *pvCallback,
+ uint32_t u32ClientId,
+ uint32_t fu32Intercepted));
+ /* The client supports one of RDP channels.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param u32ClientId An unique client identifier generated by the server.
+ * @param fu32Intercept What the client wants to intercept. One of VRDE_CLIENT_INTERCEPT_* flags.
+ * @param ppvIntercept The value to be passed to the channel specific callback.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDECallbackIntercept,(void *pvCallback,
+ uint32_t u32ClientId,
+ uint32_t fu32Intercept,
+ void **ppvIntercept));
+
+ /**
+ * Called by the server when a reply is received from a client.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param ppvIntercept The value returned by VRDECallbackIntercept for the VRDE_CLIENT_INTERCEPT_USB.
+ * @param u32ClientId Identifies the client that sent the reply.
+ * @param u8Code The operation code VRDE_USB_REQ_*.
+ * @param pvRet Points to data received from the client.
+ * @param cbRet Size of the data in bytes.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDECallbackUSB,(void *pvCallback,
+ void *pvIntercept,
+ uint32_t u32ClientId,
+ uint8_t u8Code,
+ const void *pvRet,
+ uint32_t cbRet));
+
+ /**
+ * Called by the server when (VRDE_CLIPBOARD_FUNCTION_*):
+ * - (0) client announces available clipboard formats;
+ * - (1) client requests clipboard data.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param ppvIntercept The value returned by VRDECallbackIntercept for the VRDE_CLIENT_INTERCEPT_CLIPBOARD.
+ * @param u32ClientId Identifies the RDP client that sent the reply.
+ * @param u32Function The cause of the callback.
+ * @param u32Format Bitmask of reported formats or the format of received data.
+ * @param pvData Reserved.
+ * @param cbData Reserved.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDECallbackClipboard,(void *pvCallback,
+ void *pvIntercept,
+ uint32_t u32ClientId,
+ uint32_t u32Function,
+ uint32_t u32Format,
+ const void *pvData,
+ uint32_t cbData));
+
+ /* The framebuffer information is queried.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param uScreenId The framebuffer index.
+ * @param pInfo The information structure to ber filled.
+ *
+ * @return Whether the framebuffer is available.
+ */
+ DECLR3CALLBACKMEMBER(bool, VRDECallbackFramebufferQuery,(void *pvCallback,
+ unsigned uScreenId,
+ VRDEFRAMEBUFFERINFO *pInfo));
+
+ /* Request the exclusive access to the framebuffer bitmap.
+ * Currently not used because VirtualBox makes sure that the framebuffer is available
+ * when VRDEUpdate is called.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param uScreenId The framebuffer index.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDECallbackFramebufferLock,(void *pvCallback,
+ unsigned uScreenId));
+
+ /* Release the exclusive access to the framebuffer bitmap.
+ * Currently not used because VirtualBox makes sure that the framebuffer is available
+ * when VRDEUpdate is called.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param uScreenId The framebuffer index.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDECallbackFramebufferUnlock,(void *pvCallback,
+ unsigned uScreenId));
+
+ /* Input from the client.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param pvInput The input information.
+ * @param cbInput The size of the input information.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDECallbackInput,(void *pvCallback,
+ int type,
+ const void *pvInput,
+ unsigned cbInput));
+
+ /* Video mode hint from the client.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param cWidth Requested width.
+ * @param cHeight Requested height.
+ * @param cBitsPerPixel Requested color depth.
+ * @param uScreenId The framebuffer index.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDECallbackVideoModeHint,(void *pvCallback,
+ unsigned cWidth,
+ unsigned cHeight,
+ unsigned cBitsPerPixel,
+ unsigned uScreenId));
+
+} VRDECALLBACKS_1;
+
+/* Callbacks are the same for the version 1 and version 2 interfaces. */
+typedef VRDECALLBACKS_1 VRDECALLBACKS_2;
+
+/** The VRDE server callbacks. Interface version 3. */
+typedef struct _VRDECALLBACKS_3
+{
+ /* The header. */
+ VRDEINTERFACEHDR header;
+
+ /*
+ * Same as in version 1 and 2. See comment in VRDECALLBACKS_1.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDECallbackProperty,(void *pvCallback,
+ uint32_t index,
+ void *pvBuffer,
+ uint32_t cbBuffer,
+ uint32_t *pcbOut));
+
+ DECLR3CALLBACKMEMBER(int, VRDECallbackClientLogon,(void *pvCallback,
+ uint32_t u32ClientId,
+ const char *pszUser,
+ const char *pszPassword,
+ const char *pszDomain));
+
+ DECLR3CALLBACKMEMBER(void, VRDECallbackClientConnect,(void *pvCallback,
+ uint32_t u32ClientId));
+
+ DECLR3CALLBACKMEMBER(void, VRDECallbackClientDisconnect,(void *pvCallback,
+ uint32_t u32ClientId,
+ uint32_t fu32Intercepted));
+ DECLR3CALLBACKMEMBER(int, VRDECallbackIntercept,(void *pvCallback,
+ uint32_t u32ClientId,
+ uint32_t fu32Intercept,
+ void **ppvIntercept));
+
+ DECLR3CALLBACKMEMBER(int, VRDECallbackUSB,(void *pvCallback,
+ void *pvIntercept,
+ uint32_t u32ClientId,
+ uint8_t u8Code,
+ const void *pvRet,
+ uint32_t cbRet));
+
+ DECLR3CALLBACKMEMBER(int, VRDECallbackClipboard,(void *pvCallback,
+ void *pvIntercept,
+ uint32_t u32ClientId,
+ uint32_t u32Function,
+ uint32_t u32Format,
+ const void *pvData,
+ uint32_t cbData));
+
+ DECLR3CALLBACKMEMBER(bool, VRDECallbackFramebufferQuery,(void *pvCallback,
+ unsigned uScreenId,
+ VRDEFRAMEBUFFERINFO *pInfo));
+
+ DECLR3CALLBACKMEMBER(void, VRDECallbackFramebufferLock,(void *pvCallback,
+ unsigned uScreenId));
+
+ DECLR3CALLBACKMEMBER(void, VRDECallbackFramebufferUnlock,(void *pvCallback,
+ unsigned uScreenId));
+
+ DECLR3CALLBACKMEMBER(void, VRDECallbackInput,(void *pvCallback,
+ int type,
+ const void *pvInput,
+ unsigned cbInput));
+
+ DECLR3CALLBACKMEMBER(void, VRDECallbackVideoModeHint,(void *pvCallback,
+ unsigned cWidth,
+ unsigned cHeight,
+ unsigned cBitsPerPixel,
+ unsigned uScreenId));
+
+ /*
+ * New for version 3.
+ */
+
+ /**
+ * Called by the server when something happens with audio input.
+ *
+ * @param pvCallback The callback specific pointer.
+ * @param pvCtx The value passed in VRDEAudioInOpen.
+ * @param u32ClientId Identifies the client that sent the reply.
+ * @param u32Event The event code VRDE_AUDIOIN_*.
+ * @param pvData Points to data received from the client.
+ * @param cbData Size of the data in bytes.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDECallbackAudioIn,(void *pvCallback,
+ void *pvCtx,
+ uint32_t u32ClientId,
+ uint32_t u32Event,
+ const void *pvData,
+ uint32_t cbData));
+} VRDECALLBACKS_3;
+
+/** The VRDE server entry points. Interface version 4.
+ * New entry point VRDEGetInterface has been added relative to version 3.
+ */
+typedef struct _VRDEENTRYPOINTS_4
+{
+ /* The header. */
+ VRDEINTERFACEHDR header;
+
+ /*
+ * Same as version 3. See comment in VRDEENTRYPOINTS_3.
+ */
+
+ DECLR3CALLBACKMEMBER(void, VRDEDestroy,(HVRDESERVER hServer));
+ DECLR3CALLBACKMEMBER(int, VRDEEnableConnections,(HVRDESERVER hServer, bool fEnable));
+ DECLR3CALLBACKMEMBER(void, VRDEDisconnect,(HVRDESERVER hServer, uint32_t u32ClientId, bool fReconnect));
+ DECLR3CALLBACKMEMBER(void, VRDEResize,(HVRDESERVER hServer));
+ DECLR3CALLBACKMEMBER(void, VRDEUpdate,(HVRDESERVER hServer, unsigned uScreenId, void *pvUpdate,
+ uint32_t cbUpdate));
+ DECLR3CALLBACKMEMBER(void, VRDEColorPointer,(HVRDESERVER hServer, const VRDECOLORPOINTER *pPointer));
+ DECLR3CALLBACKMEMBER(void, VRDEHidePointer,(HVRDESERVER hServer));
+ DECLR3CALLBACKMEMBER(void, VRDEAudioSamples,(HVRDESERVER hServer, const void *pvSamples, uint32_t cSamples,
+ VRDEAUDIOFORMAT format));
+ DECLR3CALLBACKMEMBER(void, VRDEAudioVolume,(HVRDESERVER hServer, uint16_t u16Left, uint16_t u16Right));
+ DECLR3CALLBACKMEMBER(void, VRDEUSBRequest,(HVRDESERVER hServer, uint32_t u32ClientId, void *pvParm,
+ uint32_t cbParm));
+ DECLR3CALLBACKMEMBER(void, VRDEClipboard,(HVRDESERVER hServer, uint32_t u32Function, uint32_t u32Format,
+ void *pvData, uint32_t cbData, uint32_t *pcbActualRead));
+ DECLR3CALLBACKMEMBER(void, VRDEQueryInfo,(HVRDESERVER hServer, uint32_t index, void *pvBuffer, uint32_t cbBuffer,
+ uint32_t *pcbOut));
+ DECLR3CALLBACKMEMBER(void, VRDERedirect,(HVRDESERVER hServer, uint32_t u32ClientId, const char *pszServer,
+ const char *pszUser, const char *pszDomain, const char *pszPassword,
+ uint32_t u32SessionId, const char *pszCookie));
+ DECLR3CALLBACKMEMBER(void, VRDEAudioInOpen,(HVRDESERVER hServer, void *pvCtx, uint32_t u32ClientId,
+ VRDEAUDIOFORMAT audioFormat, uint32_t u32SamplesPerBlock));
+ DECLR3CALLBACKMEMBER(void, VRDEAudioInClose,(HVRDESERVER hServer, uint32_t u32ClientId));
+
+ /**
+ * Generic interface query. An interface is a set of entry points and callbacks.
+ * It is not a reference counted interface.
+ *
+ * @param hServer Handle of VRDE server instance.
+ * @param pszId String identifier of the interface, like uuid.
+ * @param pInterface The interface structure to be initialized by the VRDE server.
+ * Only VRDEINTERFACEHDR is initialized by the caller.
+ * @param pCallbacks Callbacks required by the interface. The server makes a local copy.
+ * VRDEINTERFACEHDR version must correspond to the requested interface version.
+ * @param pvContext The context to be used in callbacks.
+ */
+
+ DECLR3CALLBACKMEMBER(int, VRDEGetInterface, (HVRDESERVER hServer,
+ const char *pszId,
+ VRDEINTERFACEHDR *pInterface,
+ const VRDEINTERFACEHDR *pCallbacks,
+ void *pvContext));
+} VRDEENTRYPOINTS_4;
+
+/* Callbacks are the same for the version 3 and version 4 interfaces. */
+typedef VRDECALLBACKS_3 VRDECALLBACKS_4;
+
+/**
+ * Create a new VRDE server instance. The instance is fully functional but refuses
+ * client connections until the entry point VRDEEnableConnections is called by the application.
+ *
+ * The caller prepares the VRDECALLBACKS_* structure. The header.u64Version field of the
+ * structure must be initialized with the version of the interface to use.
+ * The server will return pointer to VRDEENTRYPOINTS_* table in *ppEntryPoints
+ * to match the requested interface.
+ * That is if pCallbacks->header.u64Version == VRDE_INTERFACE_VERSION_1, then the server
+ * expects pCallbacks to point to VRDECALLBACKS_1 and will return a pointer to VRDEENTRYPOINTS_1.
+ *
+ * @param pCallback Pointer to the application callbacks which let the server to fetch
+ * the configuration data and to access the desktop.
+ * @param pvCallback The callback specific pointer to be passed back to the application.
+ * @param ppEntryPoints Where to store the pointer to the VRDE entry points structure.
+ * @param phServer Pointer to the created server instance handle.
+ *
+ * @return IPRT status code.
+ */
+DECLEXPORT(int) VRDECreateServer (const VRDEINTERFACEHDR *pCallbacks,
+ void *pvCallback,
+ VRDEINTERFACEHDR **ppEntryPoints,
+ HVRDESERVER *phServer);
+
+typedef DECLCALLBACK(int) FNVRDECREATESERVER (const VRDEINTERFACEHDR *pCallbacks,
+ void *pvCallback,
+ VRDEINTERFACEHDR **ppEntryPoints,
+ HVRDESERVER *phServer);
+typedef FNVRDECREATESERVER *PFNVRDECREATESERVER;
+
+/**
+ * List of names of the VRDE properties, which are recognized by the VRDE.
+ *
+ * For example VRDESupportedProperties should return gapszProperties declared as:
+ *
+ * static const char * const gapszProperties[] =
+ * {
+ * "TCP/Ports",
+ * "TCP/Address",
+ * NULL
+ * };
+ *
+ * @returns pointer to array of pointers to name strings (UTF8).
+ */
+DECLEXPORT(const char * const *) VRDESupportedProperties (void);
+
+typedef DECLCALLBACK(const char * const *) FNVRDESUPPORTEDPROPERTIES (void);
+typedef FNVRDESUPPORTEDPROPERTIES *PFNVRDESUPPORTEDPROPERTIES;
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/VBox/RemoteDesktop/VRDEImage.h b/include/VBox/RemoteDesktop/VRDEImage.h
new file mode 100644
index 00000000..929b08ba
--- /dev/null
+++ b/include/VBox/RemoteDesktop/VRDEImage.h
@@ -0,0 +1,240 @@
+/** @file
+ * VBox Remote Desktop Extension (VRDE) - Image updates interface.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_RemoteDesktop_VRDEImage_h
+#define ___VBox_RemoteDesktop_VRDEImage_h
+
+#include <VBox/RemoteDesktop/VRDE.h>
+
+/*
+ * Generic interface for external image updates with a clipping region to be sent
+ * to the client.
+ *
+ * Async callbacks are used for reporting errors, providing feedback, etc.
+ */
+
+#define VRDE_IMAGE_INTERFACE_NAME "IMAGE"
+
+#ifdef __cplusplus
+class VRDEImage;
+typedef class VRDEImage *HVRDEIMAGE;
+#else
+struct VRDEImage;
+typedef struct VRDEImage *HVRDEIMAGE;
+#endif /* __cplusplus */
+
+/*
+ * Format description structures for VRDEImageHandleCreate.
+ */
+typedef struct VRDEIMAGEFORMATBITMAP
+{
+ uint32_t u32BytesPerPixel; //@todo
+} VRDEIMAGEFORMATBITMAP;
+
+typedef struct VRDEIMAGEBITMAP
+{
+ uint32_t cWidth; /* The width of the bitmap in pixels. */
+ uint32_t cHeight; /* The height of the bitmap in pixels. */
+ const void *pvData; /* Address of pixel buffer. */
+ uint32_t cbData; /* Size of pixel buffer. */
+ const void *pvScanLine0; /* Address of first scanline. */
+ int32_t iScanDelta; /* Difference between two scanlines. */
+} VRDEIMAGEBITMAP;
+
+/*
+ * Image update handle creation flags.
+ */
+#define VRDE_IMAGE_F_CREATE_DEFAULT 0x00000000
+#define VRDE_IMAGE_F_CREATE_CONTENT_3D 0x00000001 /* Input image data is a rendered 3d scene. */
+#define VRDE_IMAGE_F_CREATE_CONTENT_VIDEO 0x00000002 /* Input image data is a sequence of video frames. */
+#define VRDE_IMAGE_F_CREATE_WINDOW 0x00000004 /* pRect parameter is the image update area. */
+
+/*
+ * Completion flags for image update handle creation.
+ */
+#define VRDE_IMAGE_F_COMPLETE_DEFAULT 0x00000000 /* The handle has been created. */
+#define VRDE_IMAGE_F_COMPLETE_ASYNC 0x00000001 /* The server will call VRDEImageCbNotify when the handle is ready. */
+
+/*
+ * Supported input image formats.
+ *
+ * The identifiers are arbitrary and new formats can be introduced later.
+ *
+ */
+#define VRDE_IMAGE_FMT_ID_BITMAP_BGRA8 "BITMAP_BGRA8.07e46a64-e93e-41d4-a845-204094f5ccf1"
+
+/** The VRDE server external image updates interface entry points. Interface version 1. */
+typedef struct VRDEIMAGEINTERFACE
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /** Create image updates handle.
+ *
+ * The server can setup a context which will speed up further updates.
+ *
+ * A failure is returned if the server either does not support requested updates
+ * or it failed to create a handle.
+ *
+ * A success means that the server was able to create an internal context for
+ * the updates.
+ *
+ * @param hServer The server instance handle.
+ * @param phImage The returned image updates handle.
+ * @param pvUser The caller context of the call.
+ * @param u32ScreenId Updates are for this screen in a multimonitor config.
+ * @param fu32Flags VRDE_IMAGE_F_CREATE_* flags, which describe input data.
+ * @param pRect If VRDE_IMAGE_F_CREATE_WINDOW is set, this is the area of expected updates.
+ * Otherwise the entire screen will be used for updates.
+ * @param pvFormat Format specific data.
+ * @param cbFormat Size of format specific data.
+ * @param *pfu32CompletionFlags VRDE_IMAGE_F_COMPLETE_* flags. Async handle creation, etc.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEImageHandleCreate, (HVRDESERVER hServer,
+ HVRDEIMAGE *phImage,
+ void *pvUser,
+ uint32_t u32ScreenId,
+ uint32_t fu32Flags,
+ const RTRECT *pRect,
+ const char *pszFormatId,
+ const void *pvFormat,
+ uint32_t cbFormat,
+ uint32_t *pfu32CompletionFlags));
+
+ /** Create image updates handle.
+ *
+ * @param hImage The image updates handle, which the caller will not use anymore.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEImageHandleClose, (HVRDEIMAGE hImage));
+
+ /** Set a clipping region for a particular screen.
+ *
+ * @param hImage The image updates handle.
+ * @param cRects How many rectangles. 0 clears region for this screen.
+ * @param paRects Rectangles in the screen coordinates.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEImageRegionSet, (HVRDEIMAGE hImage,
+ uint32_t cRects,
+ const RTRECT *paRects));
+
+ /** Set the new position of the update area. Only works if the image handle
+ * has been created with VRDE_IMAGE_F_CREATE_WINDOW.
+ *
+ * @param hImage The image updates handle.
+ * @param pRect New area rectangle in the screen coordinates.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEImageGeometrySet, (HVRDEIMAGE hImage,
+ const RTRECT *pRect));
+
+ /** Set a configuration parameter.
+ *
+ * @param hImage The image updates handle.
+ * @param pszName The parameter name.
+ * @param pszValue The parameter value.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEImagePropertySet, (HVRDEIMAGE hImage,
+ const char *pszName,
+ const char *pszValue));
+
+ /** Query a configuration parameter.
+ *
+ * @param hImage The image updates handle.
+ * @param pszName The parameter name.
+ * @param pszValue The parameter value.
+ * @param cbValueIn The size of pszValue buffer.
+ * @param pcbValueOut The length of data returned in pszValue buffer.
+ *
+ * Properties names:
+ * "ID" - an unique string for this hImage.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEImagePropertyQuery, (HVRDEIMAGE hImage,
+ const char *pszName,
+ char *pszValue,
+ uint32_t cbValueIn,
+ uint32_t *pcbValueOut));
+
+ /** Data for an image update.
+ *
+ * @param hImage The image updates handle.
+ * @param i32TargetX Target x.
+ * @param i32TargetY Target y.
+ * @param i32TargetW Target width.
+ * @param i32TargetH Target height.
+ * @param pvImageData Format specific image data (for example VRDEIMAGEBITMAP).
+ * @param cbImageData Size of format specific image data.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEImageUpdate, (HVRDEIMAGE hImage,
+ int32_t i32TargetX,
+ int32_t i32TargetY,
+ uint32_t u32TargetW,
+ uint32_t u32TargetH,
+ const void *pvImageData,
+ uint32_t cbImageData));
+} VRDEIMAGEINTERFACE;
+
+/*
+ * Notifications.
+ * u32Id paramater of VRDEIMAGECALLBACKS::VRDEImageCbNotify.
+ */
+#define VRDE_IMAGE_NOTIFY_HANDLE_CREATE 1 /* Result of an image handle create request. */
+
+typedef struct VRDEIMAGECALLBACKS
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /** Generic notification callback. Reserved for future use.
+ *
+ * @param hServer The server instance handle.
+ * @param pvContext The callbacks context specified in VRDEGetInterface.
+ * @param pvUser The pvUser parameter of VRDEImageHandleCreate.
+ * @param hImage The handle, same as returned by VRDEImageHandleCreate.
+ * @param u32Id The notification identifier: VRDE_IMAGE_NOTIFY_*.
+ * @param pvData The callback specific data.
+ * @param cbData The size of buffer pointed by pvData.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDEImageCbNotify,(void *pvContext,
+ void *pvUser,
+ HVRDEIMAGE hVideo,
+ uint32_t u32Id,
+ void *pvData,
+ uint32_t cbData));
+} VRDEIMAGECALLBACKS;
+
+#endif
diff --git a/include/VBox/RemoteDesktop/VRDEMousePtr.h b/include/VBox/RemoteDesktop/VRDEMousePtr.h
new file mode 100644
index 00000000..5bed85c3
--- /dev/null
+++ b/include/VBox/RemoteDesktop/VRDEMousePtr.h
@@ -0,0 +1,69 @@
+/** @file
+ * VBox Remote Desktop Extension (VRDE) - Mouse pointer updates interface.
+ */
+
+/*
+ * 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 ___VBox_RemoteDesktop_VRDEMousePtr_h
+#define ___VBox_RemoteDesktop_VRDEMousePtr_h
+
+#include <VBox/RemoteDesktop/VRDE.h>
+
+/*
+ * Interface for mouse pointer updates.
+ */
+
+#define VRDE_MOUSEPTR_INTERFACE_NAME "MOUSEPTR"
+
+#pragma pack(1)
+/* The color mouse pointer information: maximum allowed pointer size is 256x256. */
+typedef struct VRDEMOUSEPTRDATA
+{
+ uint16_t u16HotX;
+ uint16_t u16HotY;
+ uint16_t u16Width;
+ uint16_t u16Height;
+ uint16_t u16MaskLen; /* 0 for 32BPP pointers with alpha channel. */
+ uint32_t u32DataLen;
+ /* uint8_t au8Mask[u16MaskLen]; The 1BPP mask. Optional: does not exist if u16MaskLen == 0. */
+ /* uint8_t au8Data[u16DataLen]; The color bitmap, 32 bits color depth. */
+} VRDEMOUSEPTRDATA;
+#pragma pack()
+
+/** The VRDE server external mouse pointer updates interface entry points. Interface version 1. */
+typedef struct VRDEMOUSEPTRINTERFACE
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /** Set the mouse pointer.
+ *
+ * @param hServer The server instance handle.
+ * @param pPointer The mouse pointer description.
+ *
+ */
+ DECLR3CALLBACKMEMBER(void, VRDEMousePtr, (HVRDESERVER hServer,
+ const VRDEMOUSEPTRDATA *pPointer));
+
+} VRDEMOUSEPTRINTERFACE;
+
+#endif
diff --git a/include/VBox/RemoteDesktop/VRDEOrders.h b/include/VBox/RemoteDesktop/VRDEOrders.h
new file mode 100644
index 00000000..35a65143
--- /dev/null
+++ b/include/VBox/RemoteDesktop/VRDEOrders.h
@@ -0,0 +1,297 @@
+/** @file
+ * VBox Remote Desktop Extension (VRDE) - Graphics Orders Structures.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_RemoteDesktop_VRDEOrders_h
+#define ___VBox_RemoteDesktop_VRDEOrders_h
+
+#include <iprt/types.h>
+
+/*
+ * VRDE gets an information about a graphical update as a pointer
+ * to a memory block and the size of the memory block.
+ * The memory block layout is:
+ * VRDEORDERHDR - Describes the affected rectangle.
+ * Then VRDE orders follow:
+ * VRDEORDERCODE;
+ * a VRDEORDER* structure.
+ *
+ * If size of the memory block is equal to the VRDEORDERHDR, then a bitmap
+ * update is assumed.
+ */
+
+/* VRDE order codes. Must be >= 0, because the VRDE internally
+ * uses negative values to mark some operations.
+ */
+#define VRDE_ORDER_DIRTY_RECT (0)
+#define VRDE_ORDER_SOLIDRECT (1)
+#define VRDE_ORDER_SOLIDBLT (2)
+#define VRDE_ORDER_DSTBLT (3)
+#define VRDE_ORDER_SCREENBLT (4)
+#define VRDE_ORDER_PATBLTBRUSH (5)
+#define VRDE_ORDER_MEMBLT (6)
+#define VRDE_ORDER_CACHED_BITMAP (7)
+#define VRDE_ORDER_DELETED_BITMAP (8)
+#define VRDE_ORDER_LINE (9)
+#define VRDE_ORDER_BOUNDS (10)
+#define VRDE_ORDER_REPEAT (11)
+#define VRDE_ORDER_POLYLINE (12)
+#define VRDE_ORDER_ELLIPSE (13)
+#define VRDE_ORDER_SAVESCREEN (14)
+#define VRDE_ORDER_TEXT (15)
+
+/* 128 bit bitmap hash. */
+typedef uint8_t VRDEBITMAPHASH[16];
+
+#pragma pack(1)
+typedef struct _VRDEORDERHDR
+{
+ /** Coordinates of the affected rectangle. */
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+} VRDEORDERHDR;
+
+typedef struct _VRDEORDERCODE
+{
+ uint32_t u32Code;
+} VRDEORDERCODE;
+
+typedef struct _VRDEORDERPOINT
+{
+ int16_t x;
+ int16_t y;
+} VRDEORDERPOINT;
+
+typedef struct _VRDEORDERPOLYPOINTS
+{
+ uint8_t c;
+ VRDEORDERPOINT a[16];
+} VRDEORDERPOLYPOINTS;
+
+typedef struct _VRDEORDERAREA
+{
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+} VRDEORDERAREA;
+
+typedef struct _VRDEORDERRECT
+{
+ int16_t left;
+ int16_t top;
+ int16_t right;
+ int16_t bottom;
+} VRDEORDERRECT;
+
+
+typedef struct _VRDEORDERBOUNDS
+{
+ VRDEORDERPOINT pt1;
+ VRDEORDERPOINT pt2;
+} VRDEORDERBOUNDS;
+
+typedef struct _VRDEORDERREPEAT
+{
+ VRDEORDERBOUNDS bounds;
+} VRDEORDERREPEAT;
+
+
+/* Header for bitmap bits. */
+typedef struct _VRDEDATABITS
+{
+ uint32_t cb; /* Size of bitmap data without the header. */
+ int16_t x;
+ int16_t y;
+ uint16_t cWidth;
+ uint16_t cHeight;
+ uint8_t cbPixel;
+ /* Bitmap data follow. */
+} VRDEDATABITS;
+
+typedef struct _VRDEORDERSOLIDRECT
+{
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+ uint32_t rgb;
+} VRDEORDERSOLIDRECT;
+
+typedef struct _VRDEORDERSOLIDBLT
+{
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+ uint32_t rgb;
+ uint8_t rop;
+} VRDEORDERSOLIDBLT;
+
+typedef struct _VRDEORDERDSTBLT
+{
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+ uint8_t rop;
+} VRDEORDERDSTBLT;
+
+typedef struct _VRDEORDERSCREENBLT
+{
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+ int16_t xSrc;
+ int16_t ySrc;
+ uint8_t rop;
+} VRDEORDERSCREENBLT;
+
+typedef struct _VRDEORDERPATBLTBRUSH
+{
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+ int8_t xSrc;
+ int8_t ySrc;
+ uint32_t rgbFG;
+ uint32_t rgbBG;
+ uint8_t rop;
+ uint8_t pattern[8];
+} VRDEORDERPATBLTBRUSH;
+
+typedef struct _VRDEORDERMEMBLT
+{
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+ int16_t xSrc;
+ int16_t ySrc;
+ uint8_t rop;
+ VRDEBITMAPHASH hash;
+} VRDEORDERMEMBLT;
+
+typedef struct _VRDEORDERCACHEDBITMAP
+{
+ VRDEBITMAPHASH hash;
+ /* VRDEDATABITS and the bitmap data follow. */
+} VRDEORDERCACHEDBITMAP;
+
+typedef struct _VRDEORDERDELETEDBITMAP
+{
+ VRDEBITMAPHASH hash;
+} VRDEORDERDELETEDBITMAP;
+
+typedef struct _VRDEORDERLINE
+{
+ int16_t x1;
+ int16_t y1;
+ int16_t x2;
+ int16_t y2;
+ int16_t xBounds1;
+ int16_t yBounds1;
+ int16_t xBounds2;
+ int16_t yBounds2;
+ uint8_t mix;
+ uint32_t rgb;
+} VRDEORDERLINE;
+
+typedef struct _VRDEORDERPOLYLINE
+{
+ VRDEORDERPOINT ptStart;
+ uint8_t mix;
+ uint32_t rgb;
+ VRDEORDERPOLYPOINTS points;
+} VRDEORDERPOLYLINE;
+
+typedef struct _VRDEORDERELLIPSE
+{
+ VRDEORDERPOINT pt1;
+ VRDEORDERPOINT pt2;
+ uint8_t mix;
+ uint8_t fillMode;
+ uint32_t rgb;
+} VRDEORDERELLIPSE;
+
+typedef struct _VRDEORDERSAVESCREEN
+{
+ VRDEORDERPOINT pt1;
+ VRDEORDERPOINT pt2;
+ uint8_t ident;
+ uint8_t restore;
+} VRDEORDERSAVESCREEN;
+
+typedef struct _VRDEORDERGLYPH
+{
+ uint32_t o32NextGlyph;
+ uint64_t u64Handle;
+
+ /* The glyph origin position on the screen. */
+ int16_t x;
+ int16_t y;
+
+ /* The glyph bitmap dimensions. Note w == h == 0 for the space character. */
+ uint16_t w;
+ uint16_t h;
+
+ /* The character origin in the bitmap. */
+ int16_t xOrigin;
+ int16_t yOrigin;
+
+ /* 1BPP bitmap. Rows are byte aligned. Size is (((w + 7)/8) * h + 3) & ~3. */
+ uint8_t au8Bitmap[1];
+} VRDEORDERGLYPH;
+
+typedef struct _VRDEORDERTEXT
+{
+ uint32_t cbOrder;
+
+ int16_t xBkGround;
+ int16_t yBkGround;
+ uint16_t wBkGround;
+ uint16_t hBkGround;
+
+ int16_t xOpaque;
+ int16_t yOpaque;
+ uint16_t wOpaque;
+ uint16_t hOpaque;
+
+ uint16_t u16MaxGlyph;
+
+ uint8_t u8Glyphs;
+ uint8_t u8Flags;
+ uint16_t u8CharInc;
+ uint32_t u32FgRGB;
+ uint32_t u32BgRGB;
+
+ /* u8Glyphs glyphs follow. Size of each glyph structure may vary. */
+} VRDEORDERTEXT;
+#pragma pack()
+
+#endif
diff --git a/include/VBox/RemoteDesktop/VRDESCard.h b/include/VBox/RemoteDesktop/VRDESCard.h
new file mode 100644
index 00000000..4d915d63
--- /dev/null
+++ b/include/VBox/RemoteDesktop/VRDESCard.h
@@ -0,0 +1,515 @@
+/** @file
+ * VBox Remote Desktop Extension (VRDE) - SmartCard interface.
+ */
+
+/*
+ * Copyright (C) 2011-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 ___VBox_RemoteDesktop_VRDESCard_h
+#define ___VBox_RemoteDesktop_VRDESCard_h
+
+#include <VBox/RemoteDesktop/VRDE.h>
+
+/*
+ * Interface for accessing the smart card reader devices on the client.
+ *
+ * Async callbacks are used for providing feedback, reporting errors, etc.
+ *
+ * The caller prepares a VRDESCARD*REQ structure and submits it.
+ */
+
+#define VRDE_SCARD_INTERFACE_NAME "SCARD"
+
+/** The VRDE server smart card access interface entry points. Interface version 1. */
+typedef struct VRDESCARDINTERFACE
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /** Submit an async IO request to the client.
+ *
+ * @param hServer The VRDE server instance.
+ * @param pvUser The callers context of this request.
+ * @param u32Function The function: VRDE_SCARD_FN_*.
+ * @param pvData Function specific data: VRDESCARD*REQ.
+ * @param cbData Size of data.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDESCardRequest, (HVRDESERVER hServer,
+ void *pvUser,
+ uint32_t u32Function,
+ const void *pvData,
+ uint32_t cbData));
+
+} VRDESCARDINTERFACE;
+
+/* Smartcard interface callbacks. */
+typedef struct VRDESCARDCALLBACKS
+{
+ /** The header. */
+ VRDEINTERFACEHDR header;
+
+ /** Notifications.
+ *
+ * @param pvContext The callbacks context specified in VRDEGetInterface.
+ * @param u32Id The notification identifier: VRDE_SCARD_NOTIFY_*.
+ * @param pvData The notification specific data.
+ * @param cbData The size of buffer pointed by pvData.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDESCardCbNotify, (void *pvContext,
+ uint32_t u32Id,
+ void *pvData,
+ uint32_t cbData));
+
+ /** IO response.
+ *
+ * @param pvContext The callbacks context specified in VRDEGetInterface.
+ * @param rcRequest The IPRT status code for the request.
+ * @param pvUser The pvUser parameter of VRDESCardRequest.
+ * @param u32Function The completed function: VRDE_SCARD_FN_*.
+ * @param pvData Function specific response data: VRDESCARD*RSP.
+ * @param cbData The size of the buffer pointed by pvData.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDESCardCbResponse, (void *pvContext,
+ int rcRequest,
+ void *pvUser,
+ uint32_t u32Function,
+ void *pvData,
+ uint32_t cbData));
+} VRDESCARDCALLBACKS;
+
+
+/*
+ * Notifications.
+ * u32Id parameter of VRDESCARDCALLBACKS::VRDESCardCbNotify.
+ */
+
+#define VRDE_SCARD_NOTIFY_ATTACH 1 /* A SCARD RDPDR device has been attached. */
+#define VRDE_SCARD_NOTIFY_DETACH 2 /* A SCARD RDPDR device has been detached. */
+
+/*
+ * Notifications.
+ * Data structures: pvData of VRDESCARDCALLBACKS::VRDESCardCbNotify.
+ */
+typedef struct VRDESCARDNOTIFYATTACH
+{
+ uint32_t u32ClientId;
+ uint32_t u32DeviceId;
+} VRDESCARDNOTIFYATTACH;
+
+typedef struct VRDESCARDNOTIFYDETACH
+{
+ uint32_t u32ClientId;
+ uint32_t u32DeviceId;
+} VRDESCARDNOTIFYDETACH;
+
+
+/*
+ * IO request codes.
+ * Must be not 0, which is used internally.
+ */
+
+#define VRDE_SCARD_FN_ESTABLISHCONTEXT 1
+#define VRDE_SCARD_FN_LISTREADERS 2
+#define VRDE_SCARD_FN_RELEASECONTEXT 3
+#define VRDE_SCARD_FN_GETSTATUSCHANGE 4
+#define VRDE_SCARD_FN_CANCEL 5
+#define VRDE_SCARD_FN_CONNECT 6
+#define VRDE_SCARD_FN_RECONNECT 7
+#define VRDE_SCARD_FN_DISCONNECT 8
+#define VRDE_SCARD_FN_BEGINTRANSACTION 9
+#define VRDE_SCARD_FN_ENDTRANSACTION 10
+#define VRDE_SCARD_FN_STATE 11
+#define VRDE_SCARD_FN_STATUS 12
+#define VRDE_SCARD_FN_TRANSMIT 13
+#define VRDE_SCARD_FN_CONTROL 14
+#define VRDE_SCARD_FN_GETATTRIB 15
+#define VRDE_SCARD_FN_SETATTRIB 16
+
+#define VRDE_SCARD_MAX_READERS 10
+#define VRDE_SCARD_MAX_ATR_LENGTH 36
+#define VRDE_SCARD_MAX_PCI_DATA 1024
+
+#define VRDE_SCARD_S_SUCCESS 0x00000000
+#define VRDE_SCARD_F_INTERNAL_ERROR 0x80100001
+#define VRDE_SCARD_E_CANCELLED 0x80100002
+#define VRDE_SCARD_E_INVALID_HANDLE 0x80100003
+#define VRDE_SCARD_E_INVALID_PARAMETER 0x80100004
+#define VRDE_SCARD_E_INVALID_TARGET 0x80100005
+#define VRDE_SCARD_E_NO_MEMORY 0x80100006
+#define VRDE_SCARD_F_WAITED_TOO_LONG 0x80100007
+#define VRDE_SCARD_E_INSUFFICIENT_BUFFER 0x80100008
+#define VRDE_SCARD_E_UNKNOWN_READER 0x80100009
+#define VRDE_SCARD_E_TIMEOUT 0x8010000A
+#define VRDE_SCARD_E_SHARING_VIOLATION 0x8010000B
+#define VRDE_SCARD_E_NO_SMARTCARD 0x8010000C
+#define VRDE_SCARD_E_UNKNOWN_CARD 0x8010000D
+#define VRDE_SCARD_E_CANT_DISPOSE 0x8010000E
+#define VRDE_SCARD_E_PROTO_MISMATCH 0x8010000F
+#define VRDE_SCARD_E_NOT_READY 0x80100010
+#define VRDE_SCARD_E_INVALID_VALUE 0x80100011
+#define VRDE_SCARD_E_SYSTEM_CANCELLED 0x80100012
+#define VRDE_SCARD_F_COMM_ERROR 0x80100013
+#define VRDE_SCARD_F_UNKNOWN_ERROR 0x80100014
+#define VRDE_SCARD_E_INVALID_ATR 0x80100015
+#define VRDE_SCARD_E_NOT_TRANSACTED 0x80100016
+#define VRDE_SCARD_E_READER_UNAVAILABLE 0x80100017
+#define VRDE_SCARD_P_SHUTDOWN 0x80100018
+#define VRDE_SCARD_E_PCI_TOO_SMALL 0x80100019
+#define VRDE_SCARD_E_ICC_INSTALLATION 0x80100020
+#define VRDE_SCARD_E_ICC_CREATEORDER 0x80100021
+#define VRDE_SCARD_E_UNSUPPORTED_FEATURE 0x80100022
+#define VRDE_SCARD_E_DIR_NOT_FOUND 0x80100023
+#define VRDE_SCARD_E_FILE_NOT_FOUND 0x80100024
+#define VRDE_SCARD_E_NO_DIR 0x80100025
+#define VRDE_SCARD_E_READER_UNSUPPORTED 0x8010001A
+#define VRDE_SCARD_E_DUPLICATE_READER 0x8010001B
+#define VRDE_SCARD_E_CARD_UNSUPPORTED 0x8010001C
+#define VRDE_SCARD_E_NO_SERVICE 0x8010001D
+#define VRDE_SCARD_E_SERVICE_STOPPED 0x8010001E
+#define VRDE_SCARD_E_UNEXPECTED 0x8010001F
+#define VRDE_SCARD_E_NO_FILE 0x80100026
+#define VRDE_SCARD_E_NO_ACCESS 0x80100027
+#define VRDE_SCARD_E_WRITE_TOO_MANY 0x80100028
+#define VRDE_SCARD_E_BAD_SEEK 0x80100029
+#define VRDE_SCARD_E_INVALID_CHV 0x8010002A
+#define VRDE_SCARD_E_UNKNOWN_RES_MSG 0x8010002B
+#define VRDE_SCARD_E_NO_SUCH_CERTIFICATE 0x8010002C
+#define VRDE_SCARD_E_CERTIFICATE_UNAVAILABLE 0x8010002D
+#define VRDE_SCARD_E_NO_READERS_AVAILABLE 0x8010002E
+#define VRDE_SCARD_E_COMM_DATA_LOST 0x8010002F
+#define VRDE_SCARD_E_NO_KEY_CONTAINER 0x80100030
+#define VRDE_SCARD_E_SERVER_TOO_BUSY 0x80100031
+#define VRDE_SCARD_E_PIN_CACHE_EXPIRED 0x80100032
+#define VRDE_SCARD_E_NO_PIN_CACHE 0x80100033
+#define VRDE_SCARD_E_READ_ONLY_CARD 0x80100034
+#define VRDE_SCARD_W_UNSUPPORTED_CARD 0x80100065
+#define VRDE_SCARD_W_UNRESPONSIVE_CARD 0x80100066
+#define VRDE_SCARD_W_UNPOWERED_CARD 0x80100067
+#define VRDE_SCARD_W_RESET_CARD 0x80100068
+#define VRDE_SCARD_W_REMOVED_CARD 0x80100069
+#define VRDE_SCARD_W_SECURITY_VIOLATION 0x8010006A
+#define VRDE_SCARD_W_WRONG_CHV 0x8010006B
+#define VRDE_SCARD_W_CHV_BLOCKED 0x8010006C
+#define VRDE_SCARD_W_EOF 0x8010006D
+#define VRDE_SCARD_W_CANCELLED_BY_USER 0x8010006E
+#define VRDE_SCARD_W_CARD_NOT_AUTHENTICATED 0x8010006F
+#define VRDE_SCARD_W_CACHE_ITEM_NOT_FOUND 0x80100070
+#define VRDE_SCARD_W_CACHE_ITEM_STALE 0x80100071
+#define VRDE_SCARD_W_CACHE_ITEM_TOO_BIG 0x80100072
+
+#define VRDE_SCARD_STATE_UNAWARE 0x0000
+#define VRDE_SCARD_STATE_IGNORE 0x0001
+#define VRDE_SCARD_STATE_CHANGED 0x0002
+#define VRDE_SCARD_STATE_UNKNOWN 0x0004
+#define VRDE_SCARD_STATE_UNAVAILABLE 0x0008
+#define VRDE_SCARD_STATE_EMPTY 0x0010
+#define VRDE_SCARD_STATE_PRESENT 0x0020
+#define VRDE_SCARD_STATE_ATRMATCH 0x0040
+#define VRDE_SCARD_STATE_EXCLUSIVE 0x0080
+#define VRDE_SCARD_STATE_INUSE 0x0100
+#define VRDE_SCARD_STATE_MUTE 0x0200
+#define VRDE_SCARD_STATE_UNPOWERED 0x0400
+#define VRDE_SCARD_STATE_MASK UINT32_C(0x0000FFFF)
+#define VRDE_SCARD_STATE_COUNT_MASK UINT32_C(0xFFFF0000)
+
+#define VRDE_SCARD_PROTOCOL_UNDEFINED 0x00000000
+#define VRDE_SCARD_PROTOCOL_T0 0x00000001
+#define VRDE_SCARD_PROTOCOL_T1 0x00000002
+#define VRDE_SCARD_PROTOCOL_Tx 0x00000003
+#define VRDE_SCARD_PROTOCOL_RAW 0x00010000
+
+#define VRDE_SCARD_PROTOCOL_DEFAULT 0x80000000
+#define VRDE_SCARD_PROTOCOL_OPTIMAL 0x00000000
+
+#define VRDE_SCARD_SHARE_EXCLUSIVE 0x00000001
+#define VRDE_SCARD_SHARE_SHARED 0x00000002
+#define VRDE_SCARD_SHARE_DIRECT 0x00000003
+
+/* u32Initialization, u32Disposition */
+#define VRDE_SCARD_LEAVE_CARD 0x00000000
+#define VRDE_SCARD_RESET_CARD 0x00000001
+#define VRDE_SCARD_UNPOWER_CARD 0x00000002
+#define VRDE_SCARD_EJECT_CARD 0x00000003
+
+/* VRDESCARDSTATUSRSP::u32State */
+#define VRDE_SCARD_UNKNOWN 0x00000000
+#define VRDE_SCARD_ABSENT 0x00000001
+#define VRDE_SCARD_PRESENT 0x00000002
+#define VRDE_SCARD_SWALLOWED 0x00000003
+#define VRDE_SCARD_POWERED 0x00000004
+#define VRDE_SCARD_NEGOTIABLE 0x00000005
+#define VRDE_SCARD_SPECIFICMODE 0x00000006
+
+
+/*
+ * IO request data structures.
+ */
+typedef struct VRDESCARDCONTEXT
+{
+ uint32_t u32ContextSize;
+ uint8_t au8Context[16];
+} VRDESCARDCONTEXT;
+
+typedef struct VRDESCARDHANDLE
+{
+ VRDESCARDCONTEXT Context;
+ uint32_t u32HandleSize;
+ uint8_t au8Handle[16];
+} VRDESCARDHANDLE;
+
+typedef struct VRDESCARDREADERSTATECALL
+{
+ char *pszReader; /* UTF8 */
+ uint32_t u32CurrentState; /* VRDE_SCARD_STATE_* */
+} VRDESCARDREADERSTATECALL;
+
+typedef struct VRDESCARDREADERSTATERETURN
+{
+ uint32_t u32CurrentState; /* VRDE_SCARD_STATE_* */
+ uint32_t u32EventState; /* VRDE_SCARD_STATE_* */
+ uint32_t u32AtrLength;
+ uint8_t au8Atr[VRDE_SCARD_MAX_ATR_LENGTH];
+} VRDESCARDREADERSTATERETURN;
+
+typedef struct VRDESCARDPCI
+{
+ uint32_t u32Protocol; /* VRDE_SCARD_PROTOCOL_* */
+ uint32_t u32PciLength; /* Includes u32Protocol and u32PciLength fields. 8 if no data in au8PciData. */
+ uint8_t au8PciData[VRDE_SCARD_MAX_PCI_DATA];
+} VRDESCARDPCI;
+
+typedef struct VRDESCARDESTABLISHCONTEXTREQ
+{
+ uint32_t u32ClientId;
+ uint32_t u32DeviceId;
+} VRDESCARDESTABLISHCONTEXTREQ;
+
+typedef struct VRDESCARDESTABLISHCONTEXTRSP
+{
+ uint32_t u32ReturnCode;
+ VRDESCARDCONTEXT Context;
+} VRDESCARDESTABLISHCONTEXTRSP;
+
+typedef struct VRDESCARDLISTREADERSREQ
+{
+ VRDESCARDCONTEXT Context;
+} VRDESCARDLISTREADERSREQ;
+
+typedef struct VRDESCARDLISTREADERSRSP
+{
+ uint32_t u32ReturnCode;
+ uint32_t cReaders;
+ char *apszNames[VRDE_SCARD_MAX_READERS]; /* UTF8 */
+} VRDESCARDLISTREADERSRSP;
+
+typedef struct VRDESCARDRELEASECONTEXTREQ
+{
+ VRDESCARDCONTEXT Context;
+} VRDESCARDRELEASECONTEXTREQ;
+
+typedef struct VRDESCARDRELEASECONTEXTRSP
+{
+ uint32_t u32ReturnCode;
+} VRDESCARDRELEASECONTEXTRSP;
+
+typedef struct VRDESCARDGETSTATUSCHANGEREQ
+{
+ VRDESCARDCONTEXT Context;
+ uint32_t u32Timeout; /* Milliseconds. 0xFFFFFFFF = INFINITE */
+ uint32_t cReaders;
+ VRDESCARDREADERSTATECALL aReaderStates[VRDE_SCARD_MAX_READERS];
+} VRDESCARDGETSTATUSCHANGEREQ;
+
+typedef struct VRDESCARDGETSTATUSCHANGERSP
+{
+ uint32_t u32ReturnCode;
+ uint32_t cReaders;
+ VRDESCARDREADERSTATERETURN aReaderStates[VRDE_SCARD_MAX_READERS];
+} VRDESCARDGETSTATUSCHANGERSP;
+
+typedef struct VRDESCARDCANCELREQ
+{
+ VRDESCARDCONTEXT Context;
+} VRDESCARDCANCELREQ;
+
+typedef struct VRDESCARDCANCELRSP
+{
+ uint32_t u32ReturnCode;
+} VRDESCARDCANCELRSP;
+
+typedef struct VRDESCARDCONNECTREQ
+{
+ VRDESCARDCONTEXT Context;
+ char *pszReader; /* UTF8 */
+ uint32_t u32ShareMode; /* VRDE_SCARD_SHARE_* */
+ uint32_t u32PreferredProtocols;
+} VRDESCARDCONNECTREQ;
+
+typedef struct VRDESCARDCONNECTRSP
+{
+ uint32_t u32ReturnCode;
+ VRDESCARDHANDLE hCard;
+ uint32_t u32ActiveProtocol;
+} VRDESCARDCONNECTRSP;
+
+typedef struct VRDESCARDRECONNECTREQ
+{
+ VRDESCARDHANDLE hCard;
+ uint32_t u32ShareMode;
+ uint32_t u32PreferredProtocols;
+ uint32_t u32Initialization;
+} VRDESCARDRECONNECTREQ;
+
+typedef struct VRDESCARDRECONNECTRSP
+{
+ uint32_t u32ReturnCode;
+ uint32_t u32ActiveProtocol;
+} VRDESCARDRECONNECTRSP;
+
+typedef struct VRDESCARDDISCONNECTREQ
+{
+ VRDESCARDHANDLE hCard;
+ uint32_t u32Disposition;
+} VRDESCARDDISCONNECTREQ;
+
+typedef struct VRDESCARDDISCONNECTRSP
+{
+ uint32_t u32ReturnCode;
+} VRDESCARDDISCONNECTRSP;
+
+typedef struct VRDESCARDBEGINTRANSACTIONREQ
+{
+ VRDESCARDHANDLE hCard;
+ uint32_t u32Disposition;
+} VRDESCARDBEGINTRANSACTIONREQ;
+
+typedef struct VRDESCARDBEGINTRANSACTIONRSP
+{
+ uint32_t u32ReturnCode;
+} VRDESCARDBEGINTRANSACTIONRSP;
+
+typedef struct VRDESCARDENDTRANSACTIONREQ
+{
+ VRDESCARDHANDLE hCard;
+ uint32_t u32Disposition;
+} VRDESCARDENDTRANSACTIONREQ;
+
+typedef struct VRDESCARDENDTRANSACTIONRSP
+{
+ uint32_t u32ReturnCode;
+} VRDESCARDENDTRANSACTIONRSP;
+
+typedef struct VRDESCARDSTATEREQ
+{
+ VRDESCARDHANDLE hCard;
+} VRDESCARDSTATEREQ;
+
+typedef struct VRDESCARDSTATERSP
+{
+ uint32_t u32ReturnCode;
+ uint32_t u32State;
+ uint32_t u32Protocol;
+ uint32_t u32AtrLength;
+ uint8_t au8Atr[VRDE_SCARD_MAX_ATR_LENGTH];
+} VRDESCARDSTATERSP;
+
+typedef struct VRDESCARDSTATUSREQ
+{
+ VRDESCARDHANDLE hCard;
+} VRDESCARDSTATUSREQ;
+
+typedef struct VRDESCARDSTATUSRSP
+{
+ uint32_t u32ReturnCode;
+ char *szReader;
+ uint32_t u32State;
+ uint32_t u32Protocol;
+ uint32_t u32AtrLength;
+ uint8_t au8Atr[VRDE_SCARD_MAX_ATR_LENGTH];
+} VRDESCARDSTATUSRSP;
+
+typedef struct VRDESCARDTRANSMITREQ
+{
+ VRDESCARDHANDLE hCard;
+ VRDESCARDPCI ioSendPci;
+ uint32_t u32SendLength;
+ uint8_t *pu8SendBuffer;
+ uint32_t u32RecvLength;
+} VRDESCARDTRANSMITREQ;
+
+typedef struct VRDESCARDTRANSMITRSP
+{
+ uint32_t u32ReturnCode;
+ VRDESCARDPCI ioRecvPci;
+ uint32_t u32RecvLength;
+ uint8_t *pu8RecvBuffer;
+} VRDESCARDTRANSMITRSP;
+
+typedef struct VRDESCARDCONTROLREQ
+{
+ VRDESCARDHANDLE hCard;
+ uint32_t u32ControlCode;
+ uint32_t u32InBufferSize;
+ uint8_t *pu8InBuffer;
+ uint32_t u32OutBufferSize;
+} VRDESCARDCONTROLREQ;
+
+typedef struct VRDESCARDCONTROLRSP
+{
+ uint32_t u32ReturnCode;
+ uint32_t u32OutBufferSize;
+ uint8_t *pu8OutBuffer;
+} VRDESCARDCONTROLRSP;
+
+typedef struct VRDESCARDGETATTRIBREQ
+{
+ VRDESCARDHANDLE hCard;
+ uint32_t u32AttrId;
+ uint32_t u32AttrLen;
+} VRDESCARDGETATTRIBREQ;
+
+typedef struct VRDESCARDGETATTRIBRSP
+{
+ uint32_t u32ReturnCode;
+ uint32_t u32AttrLength;
+ uint8_t *pu8Attr;
+} VRDESCARDGETATTRIBRSP;
+
+typedef struct VRDESCARDSETATTRIBREQ
+{
+ VRDESCARDHANDLE hCard;
+ uint32_t u32AttrId;
+ uint32_t u32AttrLen;
+ uint8_t *pu8Attr;
+} VRDESCARDSETATTRIBREQ;
+
+typedef struct VRDESCARDSETATTRIBRSP
+{
+ uint32_t u32ReturnCode;
+} VRDESCARDSETATTRIBRSP;
+
+#endif
diff --git a/include/VBox/RemoteDesktop/VRDETSMF.h b/include/VBox/RemoteDesktop/VRDETSMF.h
new file mode 100644
index 00000000..2758924a
--- /dev/null
+++ b/include/VBox/RemoteDesktop/VRDETSMF.h
@@ -0,0 +1,141 @@
+/* @file
+ * VBox Remote Desktop Extension (VRDE) - raw TSMF dynamic channel interface.
+ */
+
+/*
+ * 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 ___VBox_RemoteDesktop_VRDETSMF_h
+#define ___VBox_RemoteDesktop_VRDETSMF_h
+
+#include <VBox/RemoteDesktop/VRDE.h>
+
+/*
+ * Interface creating a TSMF dynamic channel instances and sending/receving data.
+ *
+ * Async callbacks are used for providing feedback, reporting errors, etc.
+ */
+
+#define VRDE_TSMF_INTERFACE_NAME "TSMFRAW"
+
+/* The VRDE server TSMF interface entry points. Interface version 1. */
+typedef struct VRDETSMFINTERFACE
+{
+ /* The header. */
+ VRDEINTERFACEHDR header;
+
+ /* Create a new TSMF channel instance.
+ * The channel is created only for one client, which is connected to the server.
+ * The client is the first which supports dynamic RDP channels.
+ *
+ * If this method return success then the server will use the VRDE_TSMF_N_CREATE_*
+ * notification to report the channel handle.
+ *
+ * @param hServer The VRDE server instance.
+ * @param pvChannel A context to be associated with the channel.
+ * @param u32Flags VRDE_TSMF_F_*
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDETSMFChannelCreate, (HVRDESERVER hServer,
+ void *pvChannel,
+ uint32_t u32Flags));
+
+ /* Close a TSMF channel instance.
+ *
+ * @param hServer The VRDE server instance.
+ * @param u32ChannelHandle Which channel to close.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDETSMFChannelClose, (HVRDESERVER hServer,
+ uint32_t u32ChannelHandle));
+
+ /* Send data to the TSMF channel instance.
+ *
+ * @param hServer The VRDE server instance.
+ * @param u32ChannelHandle Channel to send data.
+ * @param pvData Raw data to be sent, the format depends on which
+ * u32Flags were specified in Create: TSMF message,
+ * or channel header + TSMF message.
+ * @param cbData Size of data.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, VRDETSMFChannelSend, (HVRDESERVER hServer,
+ uint32_t u32ChannelHandle,
+ const void *pvData,
+ uint32_t cbData));
+} VRDETSMFINTERFACE;
+
+/* TSMF interface callbacks. */
+typedef struct VRDETSMFCALLBACKS
+{
+ /* The header. */
+ VRDEINTERFACEHDR header;
+
+ /* Channel event notification.
+ *
+ * @param pvContext The callbacks context specified in VRDEGetInterface.
+ * @param u32Notification The kind of the notification: VRDE_TSMF_N_*.
+ * @param pvChannel A context which was used in VRDETSMFChannelCreate.
+ * @param pvParm The notification specific data.
+ * @param cbParm The size of buffer pointed by pvParm.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(void, VRDETSMFCbNotify, (void *pvContext,
+ uint32_t u32Notification,
+ void *pvChannel,
+ const void *pvParm,
+ uint32_t cbParm));
+} VRDETSMFCALLBACKS;
+
+
+/* VRDETSMFChannelCreate::u32Flags */
+#define VRDE_TSMF_F_CHANNEL_HEADER 0x00000001
+
+
+/* VRDETSMFCbNotify::u32Notification */
+#define VRDE_TSMF_N_CREATE_ACCEPTED 1
+#define VRDE_TSMF_N_CREATE_DECLINED 2
+#define VRDE_TSMF_N_DATA 3 /* Data received. */
+#define VRDE_TSMF_N_DISCONNECTED 4 /* The channel is not connected anymore. */
+
+
+/*
+ * Notification parameters.
+ */
+
+/* VRDE_TSMF_N_CREATE_ACCEPTED */
+typedef struct VRDETSMFNOTIFYCREATEACCEPTED
+{
+ uint32_t u32ChannelHandle;
+} VRDETSMFNOTIFYCREATEACCEPTED;
+
+/* VRDE_TSMF_N_EVENT_DATA */
+typedef struct VRDETSMFNOTIFYDATA
+{
+ const void *pvData;
+ uint32_t cbData; /* How many bytes available. */
+} VRDETSMFNOTIFYDATA;
+
+#endif
diff --git a/include/VBox/SUPDrvMangling.h b/include/VBox/SUPDrvMangling.h
new file mode 100644
index 00000000..58b0896e
--- /dev/null
+++ b/include/VBox/SUPDrvMangling.h
@@ -0,0 +1,32 @@
+/** @file
+ * SUPDrv - Mangling of IPRT symbols for host drivers.
+ *
+ * This is included via a compiler directive on platforms with a global kernel
+ * symbol name space (i.e. not Windows, OS/2 and Mac OS X (?)).
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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.
+ */
+
+
+#define RT_MANGLER(symbol) VBoxHost_##symbol
+#include <iprt/mangling.h>
+
diff --git a/include/VBox/VBoxAuth.h b/include/VBox/VBoxAuth.h
new file mode 100644
index 00000000..34dcd06d
--- /dev/null
+++ b/include/VBox/VBoxAuth.h
@@ -0,0 +1,191 @@
+/** @file
+ * VirtualBox External Authentication Library Interface.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vboxauth_h
+#define ___VBox_vboxauth_h
+
+/* The following 2 enums are 32 bits values.*/
+typedef enum AuthResult
+{
+ AuthResultAccessDenied = 0,
+ AuthResultAccessGranted = 1,
+ AuthResultDelegateToGuest = 2,
+ AuthResultSizeHack = 0x7fffffff
+} AuthResult;
+
+typedef enum AuthGuestJudgement
+{
+ AuthGuestNotAsked = 0,
+ AuthGuestAccessDenied = 1,
+ AuthGuestNoJudgement = 2,
+ AuthGuestAccessGranted = 3,
+ AuthGuestNotReacted = 4,
+ AuthGuestSizeHack = 0x7fffffff
+} AuthGuestJudgement;
+
+/* UUID memory representation. Array of 16 bytes. */
+typedef unsigned char AUTHUUID[16];
+typedef AUTHUUID *PAUTHUUID;
+/*
+Note: VirtualBox uses a consistent binary representation of UUIDs on all platforms. For this reason
+the integer fields comprising the UUID are stored as little endian values. If you want to pass such
+UUIDs to code which assumes that the integer fields are big endian (often also called network byte
+order), you need to adjust the contents of the UUID to e.g. achieve the same string representation.
+The required changes are:
+ * reverse the order of byte 0, 1, 2 and 3
+ * reverse the order of byte 4 and 5
+ * reverse the order of byte 6 and 7.
+Using this conversion you will get identical results when converting the binary UUID to the string
+representation.
+*/
+
+/* The library entry point calling convention. */
+#ifdef _MSC_VER
+# define AUTHCALL __cdecl
+#elif defined(__GNUC__)
+# define AUTHCALL
+#else
+# error "Unsupported compiler"
+#endif
+
+
+/**
+ * Authentication library entry point.
+ *
+ * Parameters:
+ *
+ * pUuid Pointer to the UUID of the accessed virtual machine. Can be NULL.
+ * guestJudgement Result of the guest authentication.
+ * szUser User name passed in by the client (UTF8).
+ * szPassword Password passed in by the client (UTF8).
+ * szDomain Domain passed in by the client (UTF8).
+ *
+ * Return code:
+ *
+ * AuthAccessDenied Client access has been denied.
+ * AuthAccessGranted Client has the right to use the
+ * virtual machine.
+ * AuthDelegateToGuest Guest operating system must
+ * authenticate the client and the
+ * library must be called again with
+ * the result of the guest
+ * authentication.
+ */
+typedef AuthResult AUTHCALL AUTHENTRY(PAUTHUUID pUuid,
+ AuthGuestJudgement guestJudgement,
+ const char *szUser,
+ const char *szPassword,
+ const char *szDomain);
+
+
+typedef AUTHENTRY *PAUTHENTRY;
+
+#define AUTHENTRY_NAME "VRDPAuth"
+
+/**
+ * Authentication library entry point version 2.
+ *
+ * Parameters:
+ *
+ * pUuid Pointer to the UUID of the accessed virtual machine. Can be NULL.
+ * guestJudgement Result of the guest authentication.
+ * szUser User name passed in by the client (UTF8).
+ * szPassword Password passed in by the client (UTF8).
+ * szDomain Domain passed in by the client (UTF8).
+ * fLogon Boolean flag. Indicates whether the entry point is called
+ * for a client logon or the client disconnect.
+ * clientId Server side unique identifier of the client.
+ *
+ * Return code:
+ *
+ * AuthAccessDenied Client access has been denied.
+ * AuthAccessGranted Client has the right to use the
+ * virtual machine.
+ * AuthDelegateToGuest Guest operating system must
+ * authenticate the client and the
+ * library must be called again with
+ * the result of the guest
+ * authentication.
+ *
+ * Note: When 'fLogon' is 0, only pUuid and clientId are valid and the return
+ * code is ignored.
+ */
+typedef AuthResult AUTHCALL AUTHENTRY2(PAUTHUUID pUuid,
+ AuthGuestJudgement guestJudgement,
+ const char *szUser,
+ const char *szPassword,
+ const char *szDomain,
+ int fLogon,
+ unsigned clientId);
+
+
+typedef AUTHENTRY2 *PAUTHENTRY2;
+
+#define AUTHENTRY2_NAME "VRDPAuth2"
+
+/**
+ * Authentication library entry point version 3.
+ *
+ * Parameters:
+ *
+ * szCaller The name of the component which calls the library (UTF8).
+ * pUuid Pointer to the UUID of the accessed virtual machine. Can be NULL.
+ * guestJudgement Result of the guest authentication.
+ * szUser User name passed in by the client (UTF8).
+ * szPassword Password passed in by the client (UTF8).
+ * szDomain Domain passed in by the client (UTF8).
+ * fLogon Boolean flag. Indicates whether the entry point is called
+ * for a client logon or the client disconnect.
+ * clientId Server side unique identifier of the client.
+ *
+ * Return code:
+ *
+ * AuthResultAccessDenied Client access has been denied.
+ * AuthResultAccessGranted Client has the right to use the
+ * virtual machine.
+ * AuthResultDelegateToGuest Guest operating system must
+ * authenticate the client and the
+ * library must be called again with
+ * the result of the guest
+ * authentication.
+ *
+ * Note: When 'fLogon' is 0, only pszCaller, pUuid and clientId are valid and the return
+ * code is ignored.
+ */
+typedef AuthResult AUTHCALL AUTHENTRY3(const char *szCaller,
+ PAUTHUUID pUuid,
+ AuthGuestJudgement guestJudgement,
+ const char *szUser,
+ const char *szPassword,
+ const char *szDomain,
+ int fLogon,
+ unsigned clientId);
+
+
+typedef AUTHENTRY3 *PAUTHENTRY3;
+
+#define AUTHENTRY3_NAME "AuthEntry"
+
+#endif
diff --git a/include/VBox/VBoxCocoa.h b/include/VBox/VBoxCocoa.h
new file mode 100644
index 00000000..f31520c6
--- /dev/null
+++ b/include/VBox/VBoxCocoa.h
@@ -0,0 +1,76 @@
+/** @file
+ * VBoxCocoa Helper
+ */
+
+/*
+ * Copyright (C) 2009-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VBoxCocoa_h
+#define ___VBox_VBoxCocoa_h
+
+/** Macro which add a typedef of the given Cocoa class in an appropriate form
+ * for the current context. This means void* in the C/CPP context and
+ * NSWhatever* in the ObjC/ObjCPP context. Use
+ * NativeNSWhateverRef/ConstNativeNSWhateverRef when you reference the Cocoa
+ * type somewhere. The use of this prevents extensive casting of void* to the
+ * right type in the Cocoa context. */
+#ifdef __OBJC__
+# define ADD_COCOA_NATIVE_REF(CocoaClass) \
+ @class CocoaClass; \
+ typedef CocoaClass *Native##CocoaClass##Ref; \
+ typedef const CocoaClass *ConstNative##CocoaClass##Ref
+#else /* !__OBJC__ */
+# define ADD_COCOA_NATIVE_REF(CocoaClass) \
+ typedef void *Native##CocoaClass##Ref; \
+ typedef const void *ConstNative##CocoaClass##Ref
+#endif /* !__OBJC__ */
+
+
+/*
+ * Objective-C++ Helpers.
+ */
+#if defined(__OBJC__) && defined (__cplusplus)
+
+/* Global includes */
+# import <Foundation/NSAutoreleasePool.h>
+
+/** Helper class for automatic creation & destroying of a cocoa auto release
+ * pool. */
+class CocoaAutoreleasePool
+{
+public:
+ inline CocoaAutoreleasePool()
+ {
+ mPool = [[NSAutoreleasePool alloc] init];
+ }
+ inline ~CocoaAutoreleasePool()
+ {
+ [mPool release];
+ }
+
+private:
+ NSAutoreleasePool *mPool;
+};
+
+#endif /* __OBJC__ && __cplusplus */
+
+#endif /* !___VBox_VBoxCocoa_h */
+
diff --git a/include/VBox/VBoxCrHgsmi.h b/include/VBox/VBoxCrHgsmi.h
new file mode 100644
index 00000000..9d25a5df
--- /dev/null
+++ b/include/VBox/VBoxCrHgsmi.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VBoxCrHgsmi_h
+#define ___VBox_VBoxCrHgsmi_h
+
+#include <iprt/cdefs.h>
+#include <VBox/VBoxUhgsmi.h>
+
+RT_C_DECLS_BEGIN
+
+#if 0
+/* enable this in case we include this in a dll*/
+# ifdef IN_VBOXCRHGSMI
+# define VBOXCRHGSMI_DECL(a_Type) DECLEXPORT(a_Type) RTCALL
+# else
+# define VBOXCRHGSMI_DECL(a_Type) DECLIMPORT(a_Type) RTCALL
+# endif
+#else
+/*enable this in case we include this in a static lib*/
+# define VBOXCRHGSMI_DECL(a_Type) a_Type RTCALL
+#endif
+
+VBOXCRHGSMI_DECL(int) VBoxCrHgsmiInit();
+VBOXCRHGSMI_DECL(PVBOXUHGSMI) VBoxCrHgsmiCreate(void);
+VBOXCRHGSMI_DECL(void) VBoxCrHgsmiDestroy(PVBOXUHGSMI pHgsmi);
+VBOXCRHGSMI_DECL(int) VBoxCrHgsmiTerm(void);
+
+VBOXCRHGSMI_DECL(int) VBoxCrHgsmiCtlConGetClientID(PVBOXUHGSMI pHgsmi, uint32_t *pu32ClientID);
+VBOXCRHGSMI_DECL(int) VBoxCrHgsmiCtlConCall(PVBOXUHGSMI pHgsmi, struct VBoxGuestHGCMCallInfo *pCallInfo, int cbCallInfo);
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/VBoxDrvCfg-win.h b/include/VBox/VBoxDrvCfg-win.h
new file mode 100644
index 00000000..ac8092a4
--- /dev/null
+++ b/include/VBox/VBoxDrvCfg-win.h
@@ -0,0 +1,77 @@
+/* $Id: VBoxDrvCfg-win.h $ */
+/** @file
+ * Windows Driver Manipulation API.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VBoxDrvCfg_win_h
+#define ___VBox_VBoxDrvCfg_win_h
+
+#include <Windows.h>
+#include <VBox/cdefs.h>
+
+RT_C_DECLS_BEGIN
+
+#if 0
+/* enable this in case we include this in a dll*/
+# ifdef IN_VBOXDRVCFG
+# define VBOXDRVCFG_DECL(a_Type) DECLEXPORT(a_Type)
+# else
+# define VBOXDRVCFG_DECL(a_Type) DECLIMPORT(a_Type)
+# endif
+#else
+/*enable this in case we include this in a static lib*/
+# define VBOXDRVCFG_DECL(a_Type) a_Type VBOXCALL
+#endif
+
+typedef enum
+{
+ VBOXDRVCFG_LOG_SEVERITY_FLOW = 1,
+ VBOXDRVCFG_LOG_SEVERITY_REGULAR,
+ VBOXDRVCFG_LOG_SEVERITY_REL
+} VBOXDRVCFG_LOG_SEVERITY;
+
+typedef DECLCALLBACK(void) FNVBOXDRVCFG_LOG(VBOXDRVCFG_LOG_SEVERITY enmSeverity, char *pszMsg, void *pvContext);
+typedef FNVBOXDRVCFG_LOG *PFNVBOXDRVCFG_LOG;
+
+VBOXDRVCFG_DECL(void) VBoxDrvCfgLoggerSet(PFNVBOXDRVCFG_LOG pfnLog, void *pvLog);
+
+typedef DECLCALLBACK(void) FNVBOXDRVCFG_PANIC(void * pvPanic);
+typedef FNVBOXDRVCFG_PANIC *PFNVBOXDRVCFG_PANIC;
+VBOXDRVCFG_DECL(void) VBoxDrvCfgPanicSet(PFNVBOXDRVCFG_PANIC pfnPanic, void *pvPanic);
+
+/* Driver package API*/
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfInstall(IN LPCWSTR lpszInfPath);
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstall(IN LPCWSTR lpszInfPath, IN DWORD fFlags);
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllSetupDi(IN const GUID * pGuidClass, IN LPCWSTR lpszClassName, IN LPCWSTR lpszPnPId, IN DWORD fFlags);
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgInfUninstallAllF(IN LPCWSTR lpszClassName, IN LPCWSTR lpszPnPId, IN DWORD fFlags);
+
+/* Service API */
+VBOXDRVCFG_DECL(HRESULT) VBoxDrvCfgSvcStart(LPCWSTR lpszSvcName);
+
+HRESULT VBoxDrvCfgDrvUpdate(LPCWSTR pcszwHwId, LPCWSTR pcsxwInf, BOOL *pbRebootRequired);
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/VBoxGL2D.h b/include/VBox/VBoxGL2D.h
new file mode 100644
index 00000000..ab0f99db
--- /dev/null
+++ b/include/VBox/VBoxGL2D.h
@@ -0,0 +1,357 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * OpenGL support info used for 2D support detection
+ */
+
+/*
+ * Copyright (C) 2009 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 __VBoxGLSupportInfo_h__
+#define __VBoxGLSupportInfo_h__
+
+#include <iprt/types.h>
+
+typedef char GLchar;
+
+#ifndef GL_COMPILE_STATUS
+# define GL_COMPILE_STATUS 0x8b81
+#endif
+#ifndef GL_LINK_STATUS
+# define GL_LINK_STATUS 0x8b82
+#endif
+#ifndef GL_FRAGMENT_SHADER
+# define GL_FRAGMENT_SHADER 0x8b30
+#endif
+#ifndef GL_VERTEX_SHADER
+# define GL_VERTEX_SHADER 0x8b31
+#endif
+
+/* GL_ARB_multitexture */
+#ifndef GL_TEXTURE0
+# define GL_TEXTURE0 0x84c0
+#endif
+#ifndef GL_TEXTURE1
+# define GL_TEXTURE1 0x84c1
+#endif
+#ifndef GL_MAX_TEXTURE_COORDS
+# define GL_MAX_TEXTURE_COORDS 0x8871
+#endif
+#ifndef GL_MAX_TEXTURE_IMAGE_UNITS
+# define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
+#endif
+
+#ifndef APIENTRY
+# define APIENTRY
+#endif
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_ACTIVE_TEXTURE) (GLenum texture);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2I) (GLenum texture, GLint v0, GLint v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2F) (GLenum texture, GLfloat v0, GLfloat v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_MULTI_TEX_COORD2D) (GLenum texture, GLdouble v0, GLdouble v1);
+
+/* GL_ARB_texture_rectangle */
+#ifndef GL_TEXTURE_RECTANGLE
+# define GL_TEXTURE_RECTANGLE 0x84F5
+#endif
+
+/* GL_ARB_shader_objects */
+/* GL_ARB_fragment_shader */
+
+typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_SHADER) (GLenum type);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_SHADER_SOURCE) (GLuint shader, GLsizei count, const GLchar **string, const GLint *length);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_COMPILE_SHADER) (GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_SHADER) (GLuint shader);
+
+typedef GLuint (APIENTRY *PFNVBOXVHWA_CREATE_PROGRAM) ();
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_ATTACH_SHADER) (GLuint program, GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DETACH_SHADER) (GLuint program, GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_LINK_PROGRAM) (GLuint program);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_USE_PROGRAM) (GLuint program);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_PROGRAM) (GLuint program);
+
+typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_SHADER) (GLuint shader);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADERIV) (GLuint shader, GLenum pname, GLint *params);
+typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_PROGRAM) (GLuint program);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAMIV) (GLuint program, GLenum pname, GLint *params);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_ATTACHED_SHADERS) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_SHADER_INFO_LOG) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_PROGRAM_INFO_LOG) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
+typedef GLint (APIENTRY *PFNVBOXVHWA_GET_UNIFORM_LOCATION) (GLint programObj, const GLchar *name);
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1F)(GLint location, GLfloat v0);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2F)(GLint location, GLfloat v0, GLfloat v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4F)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM1I)(GLint location, GLint v0);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM2I)(GLint location, GLint v0, GLint v1);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM3I)(GLint location, GLint v0, GLint v1, GLint v2);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_UNIFORM4I)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3);
+
+/* GL_ARB_pixel_buffer_object*/
+#ifndef Q_WS_MAC
+/* apears to be defined on mac */
+typedef ptrdiff_t GLsizeiptr;
+#endif
+
+#ifndef GL_READ_ONLY
+# define GL_READ_ONLY 0x88B8
+#endif
+#ifndef GL_WRITE_ONLY
+# define GL_WRITE_ONLY 0x88B9
+#endif
+#ifndef GL_READ_WRITE
+# define GL_READ_WRITE 0x88BA
+#endif
+#ifndef GL_STREAM_DRAW
+# define GL_STREAM_DRAW 0x88E0
+#endif
+#ifndef GL_STREAM_READ
+# define GL_STREAM_READ 0x88E1
+#endif
+#ifndef GL_STREAM_COPY
+# define GL_STREAM_COPY 0x88E2
+#endif
+#ifndef GL_DYNAMIC_DRAW
+# define GL_DYNAMIC_DRAW 0x88E8
+#endif
+
+#ifndef GL_PIXEL_PACK_BUFFER
+# define GL_PIXEL_PACK_BUFFER 0x88EB
+#endif
+#ifndef GL_PIXEL_UNPACK_BUFFER
+# define GL_PIXEL_UNPACK_BUFFER 0x88EC
+#endif
+#ifndef GL_PIXEL_PACK_BUFFER_BINDING
+# define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
+#endif
+#ifndef GL_PIXEL_UNPACK_BUFFER_BINDING
+# define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
+#endif
+
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GEN_BUFFERS)(GLsizei n, GLuint *buffers);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_BUFFERS)(GLsizei n, const GLuint *buffers);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_BIND_BUFFER)(GLenum target, GLuint buffer);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_BUFFER_DATA)(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
+typedef GLvoid* (APIENTRY *PFNVBOXVHWA_MAP_BUFFER)(GLenum target, GLenum access);
+typedef GLboolean (APIENTRY *PFNVBOXVHWA_UNMAP_BUFFER)(GLenum target);
+
+/* GL_EXT_framebuffer_object */
+#ifndef GL_FRAMEBUFFER
+# define GL_FRAMEBUFFER 0x8D40
+#endif
+#ifndef GL_COLOR_ATTACHMENT0
+# define GL_COLOR_ATTACHMENT0 0x8CE0
+#endif
+
+typedef GLboolean (APIENTRY *PFNVBOXVHWA_IS_FRAMEBUFFER)(GLuint framebuffer);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_BIND_FRAMEBUFFER)(GLenum target, GLuint framebuffer);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_DELETE_FRAMEBUFFERS)(GLsizei n, const GLuint *framebuffers);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GEN_FRAMEBUFFERS)(GLsizei n, GLuint *framebuffers);
+typedef GLenum (APIENTRY *PFNVBOXVHWA_CHECK_FRAMEBUFFER_STATUS)(GLenum target);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_FRAMEBUFFER_TEXTURE1D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_FRAMEBUFFER_TEXTURE2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_FRAMEBUFFER_TEXTURE3D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
+typedef GLvoid (APIENTRY *PFNVBOXVHWA_GET_FRAMEBUFFER_ATTACHMENT_PARAMETRIV)(GLenum target, GLenum attachment, GLenum pname, GLint *params);
+
+
+/*****************/
+
+/* functions */
+
+/* @todo: move those to VBoxGLInfo class instance members ??? */
+extern PFNVBOXVHWA_ACTIVE_TEXTURE vboxglActiveTexture;
+extern PFNVBOXVHWA_MULTI_TEX_COORD2I vboxglMultiTexCoord2i;
+extern PFNVBOXVHWA_MULTI_TEX_COORD2D vboxglMultiTexCoord2d;
+extern PFNVBOXVHWA_MULTI_TEX_COORD2F vboxglMultiTexCoord2f;
+
+
+extern PFNVBOXVHWA_CREATE_SHADER vboxglCreateShader;
+extern PFNVBOXVHWA_SHADER_SOURCE vboxglShaderSource;
+extern PFNVBOXVHWA_COMPILE_SHADER vboxglCompileShader;
+extern PFNVBOXVHWA_DELETE_SHADER vboxglDeleteShader;
+
+extern PFNVBOXVHWA_CREATE_PROGRAM vboxglCreateProgram;
+extern PFNVBOXVHWA_ATTACH_SHADER vboxglAttachShader;
+extern PFNVBOXVHWA_DETACH_SHADER vboxglDetachShader;
+extern PFNVBOXVHWA_LINK_PROGRAM vboxglLinkProgram;
+extern PFNVBOXVHWA_USE_PROGRAM vboxglUseProgram;
+extern PFNVBOXVHWA_DELETE_PROGRAM vboxglDeleteProgram;
+
+extern PFNVBOXVHWA_IS_SHADER vboxglIsShader;
+extern PFNVBOXVHWA_GET_SHADERIV vboxglGetShaderiv;
+extern PFNVBOXVHWA_IS_PROGRAM vboxglIsProgram;
+extern PFNVBOXVHWA_GET_PROGRAMIV vboxglGetProgramiv;
+extern PFNVBOXVHWA_GET_ATTACHED_SHADERS vboxglGetAttachedShaders;
+extern PFNVBOXVHWA_GET_SHADER_INFO_LOG vboxglGetShaderInfoLog;
+extern PFNVBOXVHWA_GET_PROGRAM_INFO_LOG vboxglGetProgramInfoLog;
+
+extern PFNVBOXVHWA_GET_UNIFORM_LOCATION vboxglGetUniformLocation;
+
+extern PFNVBOXVHWA_UNIFORM1F vboxglUniform1f;
+extern PFNVBOXVHWA_UNIFORM2F vboxglUniform2f;
+extern PFNVBOXVHWA_UNIFORM3F vboxglUniform3f;
+extern PFNVBOXVHWA_UNIFORM4F vboxglUniform4f;
+
+extern PFNVBOXVHWA_UNIFORM1I vboxglUniform1i;
+extern PFNVBOXVHWA_UNIFORM2I vboxglUniform2i;
+extern PFNVBOXVHWA_UNIFORM3I vboxglUniform3i;
+extern PFNVBOXVHWA_UNIFORM4I vboxglUniform4i;
+
+extern PFNVBOXVHWA_GEN_BUFFERS vboxglGenBuffers;
+extern PFNVBOXVHWA_DELETE_BUFFERS vboxglDeleteBuffers;
+extern PFNVBOXVHWA_BIND_BUFFER vboxglBindBuffer;
+extern PFNVBOXVHWA_BUFFER_DATA vboxglBufferData;
+extern PFNVBOXVHWA_MAP_BUFFER vboxglMapBuffer;
+extern PFNVBOXVHWA_UNMAP_BUFFER vboxglUnmapBuffer;
+
+extern PFNVBOXVHWA_IS_FRAMEBUFFER vboxglIsFramebuffer;
+extern PFNVBOXVHWA_BIND_FRAMEBUFFER vboxglBindFramebuffer;
+extern PFNVBOXVHWA_DELETE_FRAMEBUFFERS vboxglDeleteFramebuffers;
+extern PFNVBOXVHWA_GEN_FRAMEBUFFERS vboxglGenFramebuffers;
+extern PFNVBOXVHWA_CHECK_FRAMEBUFFER_STATUS vboxglCheckFramebufferStatus;
+extern PFNVBOXVHWA_FRAMEBUFFER_TEXTURE1D vboxglFramebufferTexture1D;
+extern PFNVBOXVHWA_FRAMEBUFFER_TEXTURE2D vboxglFramebufferTexture2D;
+extern PFNVBOXVHWA_FRAMEBUFFER_TEXTURE3D vboxglFramebufferTexture3D;
+extern PFNVBOXVHWA_GET_FRAMEBUFFER_ATTACHMENT_PARAMETRIV vboxglGetFramebufferAttachmentParameteriv;
+
+
+class VBoxGLInfo
+{
+public:
+ VBoxGLInfo() :
+ mGLVersion(0),
+ mFragmentShaderSupported(false),
+ mTextureRectangleSupported(false),
+ mTextureNP2Supported(false),
+ mPBOSupported(false),
+ mFBOSupported(false),
+ mMultiTexNumSupported(1), /* 1 would mean it is not supported */
+ m_GL_ARB_multitexture(false),
+ m_GL_ARB_shader_objects(false),
+ m_GL_ARB_fragment_shader(false),
+ m_GL_ARB_pixel_buffer_object(false),
+ m_GL_ARB_texture_rectangle(false),
+ m_GL_EXT_texture_rectangle(false),
+ m_GL_NV_texture_rectangle(false),
+ m_GL_ARB_texture_non_power_of_two(false),
+ m_GL_EXT_framebuffer_object(false),
+ mInitialized(false)
+ {}
+
+ void init(const class QGLContext * pContext);
+
+ bool isInitialized() const { return mInitialized; }
+
+ int getGLVersion() const { return mGLVersion; }
+ bool isFragmentShaderSupported() const { return mFragmentShaderSupported; }
+ bool isTextureRectangleSupported() const { return mTextureRectangleSupported; }
+ bool isTextureNP2Supported() const { return mTextureNP2Supported; }
+ bool isPBOSupported() const { return mPBOSupported; }
+ /* some ATI drivers do not seem to support non-zero offsets when dealing with PBOs
+ * @todo: add a check for that, always unsupported currently */
+ bool isPBOOffsetSupported() const { return false; }
+ bool isFBOSupported() const { return mFBOSupported; }
+ /* 1 would mean it is not supported */
+ int getMultiTexNumSupported() const { return mMultiTexNumSupported; }
+
+ static int parseVersion(const GLubyte * ver);
+private:
+ void initExtSupport(const class QGLContext & context);
+
+ int mGLVersion;
+ bool mFragmentShaderSupported;
+ bool mTextureRectangleSupported;
+ bool mTextureNP2Supported;
+ bool mPBOSupported;
+ bool mFBOSupported;
+ int mMultiTexNumSupported; /* 1 would mean it is not supported */
+
+ bool m_GL_ARB_multitexture;
+ bool m_GL_ARB_shader_objects;
+ bool m_GL_ARB_fragment_shader;
+ bool m_GL_ARB_pixel_buffer_object;
+ bool m_GL_ARB_texture_rectangle;
+ bool m_GL_EXT_texture_rectangle;
+ bool m_GL_NV_texture_rectangle;
+ bool m_GL_ARB_texture_non_power_of_two;
+ bool m_GL_EXT_framebuffer_object;
+
+ bool mInitialized;
+};
+
+class VBoxGLTmpContext
+{
+public:
+ VBoxGLTmpContext();
+ ~VBoxGLTmpContext();
+
+ const class QGLContext * makeCurrent();
+private:
+ class QGLWidget * mWidget;
+};
+
+
+#define VBOXQGL_MAKEFOURCC(ch0, ch1, ch2, ch3) \
+ ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \
+ ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
+
+#define FOURCC_AYUV VBOXQGL_MAKEFOURCC('A', 'Y', 'U', 'V')
+#define FOURCC_UYVY VBOXQGL_MAKEFOURCC('U', 'Y', 'V', 'Y')
+#define FOURCC_YUY2 VBOXQGL_MAKEFOURCC('Y', 'U', 'Y', '2')
+#define FOURCC_YV12 VBOXQGL_MAKEFOURCC('Y', 'V', '1', '2')
+#define VBOXVHWA_NUMFOURCC 4
+
+class VBoxVHWAInfo
+{
+public:
+ VBoxVHWAInfo() :
+ mFourccSupportedCount(0),
+ mInitialized(false)
+ {}
+
+ VBoxVHWAInfo(const VBoxGLInfo & glInfo) :
+ mglInfo(glInfo),
+ mFourccSupportedCount(0),
+ mInitialized(false)
+ {}
+
+ void init(const class QGLContext * pContext);
+
+ bool isInitialized() const { return mInitialized; }
+
+ const VBoxGLInfo & getGlInfo() const { return mglInfo; }
+
+ bool isVHWASupported() const;
+
+ int getFourccSupportedCount() const { return mFourccSupportedCount; }
+ const uint32_t * getFourccSupportedList() const { return mFourccSupportedList; }
+
+ static bool checkVHWASupport();
+private:
+ VBoxGLInfo mglInfo;
+ uint32_t mFourccSupportedList[VBOXVHWA_NUMFOURCC];
+ int mFourccSupportedCount;
+
+ bool mInitialized;
+};
+
+#endif /* #ifndef __VBoxGLSupportInfo_h__ */
diff --git a/include/VBox/VBoxGuest.h b/include/VBox/VBoxGuest.h
new file mode 100644
index 00000000..d23e5a2d
--- /dev/null
+++ b/include/VBox/VBoxGuest.h
@@ -0,0 +1,461 @@
+/** @file
+ * VBoxGuest - VirtualBox Guest Additions Driver Interface. (ADD,DEV)
+ *
+ * @remarks This is in the process of being split up and usage cleaned up.
+ */
+
+/*
+ * Copyright (C) 2006-2009 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 ___VBox_VBoxGuest_h
+#define ___VBox_VBoxGuest_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/assert.h>
+#include <VBox/VMMDev2.h>
+#include <VBox/VBoxGuest2.h>
+
+
+/** @defgroup grp_vboxguest VirtualBox Guest Additions Driver Interface
+ * @{
+ */
+
+/** @todo it would be nice if we could have two define without paths. */
+
+/** @def VBOXGUEST_DEVICE_NAME
+ * The support device name. */
+/** @def VBOXGUEST_USER_DEVICE_NAME
+ * The support device name of the user accessible device node. */
+
+#if defined(RT_OS_OS2)
+# define VBOXGUEST_DEVICE_NAME "\\Dev\\VBoxGst$"
+
+#elif defined(RT_OS_WINDOWS)
+# define VBOXGUEST_DEVICE_NAME "\\\\.\\VBoxGuest"
+
+/** The support service name. */
+# define VBOXGUEST_SERVICE_NAME "VBoxGuest"
+/** Global name for Win2k+ */
+# define VBOXGUEST_DEVICE_NAME_GLOBAL "\\\\.\\Global\\VBoxGuest"
+/** Win32 driver name */
+# define VBOXGUEST_DEVICE_NAME_NT L"\\Device\\VBoxGuest"
+/** Device name. */
+# define VBOXGUEST_DEVICE_NAME_DOS L"\\DosDevices\\VBoxGuest"
+
+#else /* (PORTME) */
+# define VBOXGUEST_DEVICE_NAME "/dev/vboxguest"
+# if defined(RT_OS_LINUX)
+# define VBOXGUEST_USER_DEVICE_NAME "/dev/vboxuser"
+# endif
+#endif
+
+#ifndef VBOXGUEST_USER_DEVICE_NAME
+# define VBOXGUEST_USER_DEVICE_NAME VBOXGUEST_DEVICE_NAME
+#endif
+
+/** Fictive start address of the hypervisor physical memory for MmMapIoSpace. */
+#define VBOXGUEST_HYPERVISOR_PHYSICAL_START UINT32_C(0xf8000000)
+
+
+#if !defined(IN_RC) && !defined(IN_RING0_AGNOSTIC) && !defined(IPRT_NO_CRT)
+/** @name VBoxGuest IOCTL codes and structures.
+ *
+ * The range 0..15 is for basic driver communication.
+ * The range 16..31 is for HGCM communication.
+ * The range 32..47 is reserved for future use.
+ * The range 48..63 is for OS specific communication.
+ * The 7th bit is reserved for future hacks.
+ * The 8th bit is reserved for distinguishing between 32-bit and 64-bit
+ * processes in future 64-bit guest additions.
+ *
+ * @remarks When creating new IOCtl interfaces keep in mind that not all OSes supports
+ * reporting back the output size. (This got messed up a little bit in VBoxDrv.)
+ *
+ * The request size is also a little bit tricky as it's passed as part of the
+ * request code on unix. The size field is 14 bits on Linux, 12 bits on *BSD,
+ * 13 bits Darwin, and 8-bits on Solaris. All the BSDs and Darwin kernels
+ * will make use of the size field, while Linux and Solaris will not. We're of
+ * course using the size to validate and/or map/lock the request, so it has
+ * to be valid.
+ *
+ * For Solaris we will have to do something special though, 255 isn't
+ * sufficient for all we need. A 4KB restriction (BSD) is probably not
+ * too problematic (yet) as a general one.
+ *
+ * More info can be found in SUPDRVIOC.h and related sources.
+ *
+ * @remarks If adding interfaces that only has input or only has output, some new macros
+ * needs to be created so the most efficient IOCtl data buffering method can be
+ * used.
+ * @{
+ */
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64)
+# define VBOXGUEST_IOCTL_FLAG 128
+#elif defined(RT_ARCH_X86) || defined(RT_ARCH_SPARC)
+# define VBOXGUEST_IOCTL_FLAG 0
+#else
+# error "dunno which arch this is!"
+#endif
+/** @} */
+
+/** Ring-3 request wrapper for big requests.
+ *
+ * This is necessary because the ioctl number scheme on many Unixy OSes (esp. Solaris)
+ * only allows a relatively small size to be encoded into the request. So, for big
+ * request this generic form is used instead. */
+typedef struct VBGLBIGREQ
+{
+ /** Magic value (VBGLBIGREQ_MAGIC). */
+ uint32_t u32Magic;
+ /** The size of the data buffer. */
+ uint32_t cbData;
+ /** The user address of the data buffer. */
+ RTR3PTR pvDataR3;
+#if HC_ARCH_BITS == 32
+ uint32_t u32Padding;
+#endif
+/** @todo r=bird: We need a 'rc' field for passing VBox status codes. Reused
+ * some input field as rc on output. */
+} VBGLBIGREQ;
+/** Pointer to a request wrapper for solaris guests. */
+typedef VBGLBIGREQ *PVBGLBIGREQ;
+/** Pointer to a const request wrapper for solaris guests. */
+typedef const VBGLBIGREQ *PCVBGLBIGREQ;
+
+/** The VBGLBIGREQ::u32Magic value (Ryuu Murakami). */
+#define VBGLBIGREQ_MAGIC 0x19520219
+
+
+#if defined(RT_OS_WINDOWS)
+/* @todo Remove IOCTL_CODE later! Integrate it in VBOXGUEST_IOCTL_CODE below. */
+/** @todo r=bird: IOCTL_CODE is supposedly defined in some header included by Windows.h or ntddk.h, which is why it wasn't in the #if 0 earlier. See HostDrivers/Support/SUPDrvIOC.h... */
+# define IOCTL_CODE(DeviceType, Function, Method, Access, DataSize_ignored) \
+ ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
+# define VBOXGUEST_IOCTL_CODE_(Function, Size) IOCTL_CODE(FILE_DEVICE_UNKNOWN, 2048 + (Function), METHOD_BUFFERED, FILE_WRITE_ACCESS, 0)
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code) (Code)
+
+#elif defined(RT_OS_OS2)
+ /* No automatic buffering, size not encoded. */
+# define VBOXGUEST_IOCTL_CATEGORY 0xc2
+# define VBOXGUEST_IOCTL_CODE_(Function, Size) ((unsigned char)(Function))
+# define VBOXGUEST_IOCTL_CATEGORY_FAST 0xc3 /**< Also defined in VBoxGuestA-os2.asm. */
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function) ((unsigned char)(Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code) (Code)
+
+#elif defined(RT_OS_SOLARIS)
+ /* No automatic buffering, size limited to 255 bytes => use VBGLBIGREQ for everything. */
+# include <sys/ioccom.h>
+# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOWRN('V', (Function), sizeof(VBGLBIGREQ))
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO( 'V', (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code) (Code)
+
+#elif defined(RT_OS_LINUX)
+ /* No automatic buffering, size limited to 16KB. */
+# include <linux/ioctl.h>
+# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOC(_IOC_READ|_IOC_WRITE, 'V', (Function), (Size))
+# 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_FREEBSD) /** @todo r=bird: Please do it like SUPDRVIOC to keep it as similar as possible. */
+# include <sys/ioccom.h>
+
+# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOWR('V', (Function), VBGLBIGREQ)
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO( 'V', (Function))
+# define VBOXGUEST_IOCTL_STRIP_SIZE(Code) IOCBASECMD(Code)
+
+#else /* BSD Like */
+ /* Automatic buffering, size limited to 4KB on *BSD and 8KB on Darwin - commands the limit, 4KB. */
+# include <sys/ioccom.h>
+# define VBOXGUEST_IOCTL_CODE_(Function, Size) _IOC(IOC_INOUT, 'V', (Function) | VBOXGUEST_IOCTL_FLAG, (Size))
+# define VBOXGUEST_IOCTL_CODE_FAST_(Function) _IO('V', (Function) | VBOXGUEST_IOCTL_FLAG)
+# define VBOXGUEST_IOCTL_STRIP_SIZE(uIOCtl) ( (uIOCtl) & ~_IOC(0,0,0,IOCPARM_MASK) )
+#endif
+
+#define VBOXGUEST_IOCTL_CODE(Function, Size) VBOXGUEST_IOCTL_CODE_((Function) | VBOXGUEST_IOCTL_FLAG, Size)
+#define VBOXGUEST_IOCTL_CODE_FAST(Function) VBOXGUEST_IOCTL_CODE_FAST_((Function) | VBOXGUEST_IOCTL_FLAG)
+
+/* Define 32 bit codes to support 32 bit applications requests in the 64 bit guest driver. */
+#ifdef RT_ARCH_AMD64
+# define VBOXGUEST_IOCTL_CODE_32(Function, Size) VBOXGUEST_IOCTL_CODE_(Function, Size)
+# define VBOXGUEST_IOCTL_CODE_FAST_32(Function) VBOXGUEST_IOCTL_CODE_FAST_(Function)
+#endif /* RT_ARCH_AMD64 */
+
+
+
+/** IOCTL to VBoxGuest to query the VMMDev IO port region start.
+ * @remarks Ring-0 only. */
+#define VBOXGUEST_IOCTL_GETVMMDEVPORT VBOXGUEST_IOCTL_CODE(1, sizeof(VBoxGuestPortInfo))
+
+#pragma pack(4)
+typedef struct VBoxGuestPortInfo
+{
+ uint32_t portAddress;
+ struct VMMDevMemory *pVMMDevMemory;
+} VBoxGuestPortInfo;
+
+
+/** IOCTL to VBoxGuest to wait for a VMMDev host notification */
+#define VBOXGUEST_IOCTL_WAITEVENT VBOXGUEST_IOCTL_CODE_(2, sizeof(VBoxGuestWaitEventInfo))
+
+/** @name Result codes for VBoxGuestWaitEventInfo::u32Result
+ * @{
+ */
+/** Successful completion, an event occurred. */
+#define VBOXGUEST_WAITEVENT_OK (0)
+/** Successful completion, timed out. */
+#define VBOXGUEST_WAITEVENT_TIMEOUT (1)
+/** Wait was interrupted. */
+#define VBOXGUEST_WAITEVENT_INTERRUPTED (2)
+/** An error occurred while processing the request. */
+#define VBOXGUEST_WAITEVENT_ERROR (3)
+/** @} */
+
+/** Input and output buffers layout of the IOCTL_VBOXGUEST_WAITEVENT */
+typedef struct VBoxGuestWaitEventInfo
+{
+ /** timeout in milliseconds */
+ uint32_t u32TimeoutIn;
+ /** events to wait for */
+ uint32_t u32EventMaskIn;
+ /** result code */
+ uint32_t u32Result;
+ /** events occurred */
+ uint32_t u32EventFlagsOut;
+} VBoxGuestWaitEventInfo;
+AssertCompileSize(VBoxGuestWaitEventInfo, 16);
+
+
+/** IOCTL to VBoxGuest to perform a VMM request
+ * @remark The data buffer for this IOCtl has an variable size, keep this in mind
+ * on systems where this matters. */
+#define VBOXGUEST_IOCTL_VMMREQUEST(Size) VBOXGUEST_IOCTL_CODE_(3, (Size))
+
+
+/** IOCTL to VBoxGuest to control event filter mask. */
+#define VBOXGUEST_IOCTL_CTL_FILTER_MASK VBOXGUEST_IOCTL_CODE_(4, sizeof(VBoxGuestFilterMaskInfo))
+
+/** Input and output buffer layout of the IOCTL_VBOXGUEST_CTL_FILTER_MASK. */
+typedef struct VBoxGuestFilterMaskInfo
+{
+ uint32_t u32OrMask;
+ uint32_t u32NotMask;
+} VBoxGuestFilterMaskInfo;
+AssertCompileSize(VBoxGuestFilterMaskInfo, 8);
+#pragma pack()
+
+/** IOCTL to VBoxGuest to interrupt (cancel) any pending WAITEVENTs and return.
+ * Handled inside the guest additions and not seen by the host at all.
+ * @see VBOXGUEST_IOCTL_WAITEVENT */
+#define VBOXGUEST_IOCTL_CANCEL_ALL_WAITEVENTS VBOXGUEST_IOCTL_CODE_(5, 0)
+
+/** IOCTL to VBoxGuest to perform backdoor logging.
+ * The argument is a string buffer of the specified size. */
+#define VBOXGUEST_IOCTL_LOG(Size) VBOXGUEST_IOCTL_CODE_(6, (Size))
+
+/** IOCTL to VBoxGuest to check memory ballooning.
+ * The guest kernel module / device driver will ask the host for the current size of
+ * the balloon and adjust the size. Or it will set fHandledInR0 = false and R3 is
+ * responsible for allocating memory and calling R0 (VBOXGUEST_IOCTL_CHANGE_BALLOON). */
+#define VBOXGUEST_IOCTL_CHECK_BALLOON VBOXGUEST_IOCTL_CODE_(7, sizeof(VBoxGuestCheckBalloonInfo))
+
+/** Output buffer layout of the VBOXGUEST_IOCTL_CHECK_BALLOON. */
+typedef struct VBoxGuestCheckBalloonInfo
+{
+ /** The size of the balloon in chunks of 1MB. */
+ uint32_t cBalloonChunks;
+ /** false = handled in R0, no further action required.
+ * true = allocate balloon memory in R3. */
+ uint32_t fHandleInR3;
+} VBoxGuestCheckBalloonInfo;
+AssertCompileSize(VBoxGuestCheckBalloonInfo, 8);
+
+
+/** IOCTL to VBoxGuest to supply or revoke one chunk for ballooning.
+ * The guest kernel module / device driver will lock down supplied memory or
+ * unlock reclaimed memory and then forward the physical addresses of the
+ * changed balloon chunk to the host. */
+#define VBOXGUEST_IOCTL_CHANGE_BALLOON VBOXGUEST_IOCTL_CODE_(8, sizeof(VBoxGuestChangeBalloonInfo))
+
+/** Input buffer layout of the VBOXGUEST_IOCTL_CHANGE_BALLOON request.
+ * Information about a memory chunk used to inflate or deflate the balloon. */
+typedef struct VBoxGuestChangeBalloonInfo
+{
+ /** Address of the chunk. */
+ uint64_t u64ChunkAddr;
+ /** true = inflate, false = deflate. */
+ uint32_t fInflate;
+ /** Alignment padding. */
+ uint32_t u32Align;
+} VBoxGuestChangeBalloonInfo;
+AssertCompileSize(VBoxGuestChangeBalloonInfo, 16);
+
+/** IOCTL to VBoxGuest to write guest core. */
+#define VBOXGUEST_IOCTL_WRITE_CORE_DUMP VBOXGUEST_IOCTL_CODE(9, sizeof(VBoxGuestWriteCoreDump))
+
+/** Input and output buffer layout of the VBOXGUEST_IOCTL_WRITE_CORE
+ * request. */
+typedef struct VBoxGuestWriteCoreDump
+{
+ /** Flags (reserved, MBZ). */
+ uint32_t fFlags;
+} VBoxGuestWriteCoreDump;
+AssertCompileSize(VBoxGuestWriteCoreDump, 4);
+
+/** IOCTL to VBoxGuest to update the mouse status features. */
+# define VBOXGUEST_IOCTL_SET_MOUSE_STATUS VBOXGUEST_IOCTL_CODE_(10, sizeof(uint32_t))
+
+#ifdef VBOX_WITH_HGCM
+/** IOCTL to VBoxGuest to connect to a HGCM service. */
+# define VBOXGUEST_IOCTL_HGCM_CONNECT VBOXGUEST_IOCTL_CODE(16, sizeof(VBoxGuestHGCMConnectInfo))
+
+/** IOCTL to VBoxGuest to disconnect from a HGCM service. */
+# define VBOXGUEST_IOCTL_HGCM_DISCONNECT VBOXGUEST_IOCTL_CODE(17, sizeof(VBoxGuestHGCMDisconnectInfo))
+
+/** IOCTL to VBoxGuest to make a call to a HGCM service.
+ * @see VBoxGuestHGCMCallInfo */
+# define VBOXGUEST_IOCTL_HGCM_CALL(Size) VBOXGUEST_IOCTL_CODE(18, (Size))
+
+/** IOCTL to VBoxGuest to make a timed call to a HGCM service. */
+# define VBOXGUEST_IOCTL_HGCM_CALL_TIMED(Size) VBOXGUEST_IOCTL_CODE(20, (Size))
+
+/** IOCTL to VBoxGuest passed from the Kernel Mode driver, but containing a user mode data in VBoxGuestHGCMCallInfo
+ * the driver received from the UM. Called in the context of the process passing the data.
+ * @see VBoxGuestHGCMCallInfo */
+# define VBOXGUEST_IOCTL_HGCM_CALL_USERDATA(Size) VBOXGUEST_IOCTL_CODE(21, (Size))
+
+# ifdef RT_ARCH_AMD64
+/** @name IOCTL numbers that 32-bit clients, like the Windows OpenGL guest
+ * driver, will use when taking to a 64-bit driver.
+ * @remarks These are only used by the driver implementation! */
+# define VBOXGUEST_IOCTL_HGCM_CONNECT_32 VBOXGUEST_IOCTL_CODE_32(16, sizeof(VBoxGuestHGCMConnectInfo))
+# define VBOXGUEST_IOCTL_HGCM_DISCONNECT_32 VBOXGUEST_IOCTL_CODE_32(17, sizeof(VBoxGuestHGCMDisconnectInfo))
+# define VBOXGUEST_IOCTL_HGCM_CALL_32(Size) VBOXGUEST_IOCTL_CODE_32(18, (Size))
+# define VBOXGUEST_IOCTL_HGCM_CALL_TIMED_32(Size) VBOXGUEST_IOCTL_CODE_32(20, (Size))
+/** @} */
+# endif /* RT_ARCH_AMD64 */
+
+#ifdef VBOX_WITH_DPC_LATENCY_CHECKER
+#define VBOXGUEST_IOCTL_DPC VBOXGUEST_IOCTL_CODE(30, 0)
+#endif
+
+/** Get the pointer to the first HGCM parameter. */
+# define VBOXGUEST_HGCM_CALL_PARMS(a) ( (HGCMFunctionParameter *)((uint8_t *)(a) + sizeof(VBoxGuestHGCMCallInfo)) )
+/** Get the pointer to the first HGCM parameter in a 32-bit request. */
+# define VBOXGUEST_HGCM_CALL_PARMS32(a) ( (HGCMFunctionParameter32 *)((uint8_t *)(a) + sizeof(VBoxGuestHGCMCallInfo)) )
+
+#endif /* VBOX_WITH_HGCM */
+
+/** IOCTL to for setting the mouse driver callback. (kernel only) */
+#define VBOXGUEST_IOCTL_SET_MOUSE_NOTIFY_CALLBACK VBOXGUEST_IOCTL_CODE_(31, sizeof(VBoxGuestMouseSetNotifyCallback))
+
+typedef DECLCALLBACK(void) FNVBOXGUESTMOUSENOTIFY(void *pfnUser);
+typedef FNVBOXGUESTMOUSENOTIFY *PFNVBOXGUESTMOUSENOTIFY;
+
+/** Input buffer for VBOXGUEST_IOCTL_INTERNAL_SET_MOUSE_NOTIFY_CALLBACK. */
+typedef struct VBoxGuestMouseSetNotifyCallback
+{
+ /**
+ * Mouse notification callback.
+ *
+ * @param pvUser The callback argument.
+ */
+ PFNVBOXGUESTMOUSENOTIFY pfnNotify;
+ /** The callback argument*/
+ void *pvUser;
+} VBoxGuestMouseSetNotifyCallback;
+
+
+#ifdef RT_OS_OS2
+
+/**
+ * The data buffer layout for the IDC entry point (AttachDD).
+ *
+ * @remark This is defined in multiple 16-bit headers / sources.
+ * Some places it's called VBGOS2IDC to short things a bit.
+ */
+typedef struct VBOXGUESTOS2IDCCONNECT
+{
+ /** VMMDEV_VERSION. */
+ uint32_t u32Version;
+ /** Opaque session handle. */
+ uint32_t u32Session;
+
+ /**
+ * The 32-bit service entry point.
+ *
+ * @returns VBox status code.
+ * @param u32Session The above session handle.
+ * @param iFunction The requested function.
+ * @param pvData The input/output data buffer. The caller ensures that this
+ * cannot be swapped out, or that it's acceptable to take a
+ * page in fault in the current context. If the request doesn't
+ * take input or produces output, apssing NULL is okay.
+ * @param cbData The size of the data buffer.
+ * @param pcbDataReturned Where to store the amount of data that's returned.
+ * This can be NULL if pvData is NULL.
+ */
+ DECLCALLBACKMEMBER(int, pfnServiceEP)(uint32_t u32Session, unsigned iFunction, void *pvData, size_t cbData, size_t *pcbDataReturned);
+
+ /** The 16-bit service entry point for C code (cdecl).
+ *
+ * It's the same as the 32-bit entry point, but the types has
+ * changed to 16-bit equivalents.
+ *
+ * @code
+ * int far cdecl
+ * VBoxGuestOs2IDCService16(uint32_t u32Session, uint16_t iFunction,
+ * void far *fpvData, uint16_t cbData, uint16_t far *pcbDataReturned);
+ * @endcode
+ */
+ RTFAR16 fpfnServiceEP;
+
+ /** The 16-bit service entry point for Assembly code (register).
+ *
+ * This is just a wrapper around fpfnServiceEP to simplify calls
+ * from 16-bit assembly code.
+ *
+ * @returns (e)ax: VBox status code; cx: The amount of data returned.
+ *
+ * @param u32Session eax - The above session handle.
+ * @param iFunction dl - The requested function.
+ * @param pvData es:bx - The input/output data buffer.
+ * @param cbData cx - The size of the data buffer.
+ */
+ RTFAR16 fpfnServiceAsmEP;
+} VBOXGUESTOS2IDCCONNECT;
+/** Pointer to VBOXGUESTOS2IDCCONNECT buffer. */
+typedef VBOXGUESTOS2IDCCONNECT *PVBOXGUESTOS2IDCCONNECT;
+
+/** OS/2 specific: IDC client disconnect request.
+ *
+ * This takes no input and it doesn't return anything. Obviously this
+ * is only recognized if it arrives thru the IDC service EP.
+ */
+# define VBOXGUEST_IOCTL_OS2_IDC_DISCONNECT VBOXGUEST_IOCTL_CODE(48, sizeof(uint32_t))
+
+#endif /* RT_OS_OS2 */
+
+/** @} */
+#endif /* !defined(IN_RC) && !defined(IN_RING0_AGNOSTIC) && !defined(IPRT_NO_CRT) */
+
+#endif
+
diff --git a/include/VBox/VBoxGuest.inc b/include/VBox/VBoxGuest.inc
new file mode 100644
index 00000000..87982549
--- /dev/null
+++ b/include/VBox/VBoxGuest.inc
@@ -0,0 +1,46 @@
+;; @file
+; VBoxGuest - VirtualBox Guest Additions Interface, MASM/ALP header.
+;
+
+;/*
+; Copyright (C) 2006-2007 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; 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.
+;
+; */
+
+
+;; ASSUMES OS/2 for now.
+VBOXGUEST_DEVICE_NAME EQU "VBoxGst$"
+
+
+;; aka VBOXGUESTOS2IDCCONNECT
+VBGOS2IDC STRUC
+u32Version DD ?
+u32Session DD ?
+pfnServiceEP DD ?
+fpfnServiceEP DD ?
+fpfnServiceAsmEP DD ?
+VBGOS2IDC ENDS
+
+
+; From VMMDev.h
+VMMDEV_VERSION_MAJOR EQU 1
+VMMDEV_VERSION_MINOR EQU 4
+VMMDEV_VERSION EQU 000010004h
+
diff --git a/include/VBox/VBoxGuest.mac b/include/VBox/VBoxGuest.mac
new file mode 100644
index 00000000..9d0cd6a1
--- /dev/null
+++ b/include/VBox/VBoxGuest.mac
@@ -0,0 +1,50 @@
+;; @file
+; VBoxGuest - VirtualBox Guest Additions Interface, NASM/YASM header.
+;
+
+;/*
+; Copyright (C) 2006-2007 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; 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 ___VBox_VBoxGuest_mac___
+%define ___VBox_VBoxGuest_mac___
+
+%ifdef RT_OS_OS2
+%define VBOXGUEST_DEVICE_NAME "vboxgst$"
+
+;; aka VBOXGUESTOS2IDCCONNECT
+struc VBGOS2IDC
+ .u32Version resd 1
+ .u32Session resd 1
+ .pfnServiceEP resd 1
+ .fpfnServiceEP resd 1
+ .fpfnServiceAsmEP resd 1
+endstruc
+
+%endif ; RT_OS_OS2
+
+; From VMMDev.h
+%define VMMDEV_VERSION_MAJOR 1
+%define VMMDEV_VERSION_MINOR 4
+%define VMMDEV_VERSION 000010004h
+
+%endif
+
diff --git a/include/VBox/VBoxGuest16.h b/include/VBox/VBoxGuest16.h
new file mode 100644
index 00000000..15aa986c
--- /dev/null
+++ b/include/VBox/VBoxGuest16.h
@@ -0,0 +1,109 @@
+/** @file
+ * VBoxGuest - VirtualBox Guest Additions Driver Interface, 16-bit (OS/2) header.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_VBoxGuest16_h
+#define ___VBox_VBoxGuest16_h
+
+#define RT_BIT(bit) (1UL << (bit))
+
+#define VBOXGUEST_DEVICE_NAME "vboxgst$"
+
+/* aka VBOXGUESTOS2IDCCONNECT */
+typedef struct VBGOS2IDC
+{
+ unsigned long u32Version;
+ unsigned long u32Session;
+ unsigned long pfnServiceEP;
+ short (__cdecl __far *fpfnServiceEP)(unsigned long u32Session, unsigned short iFunction,
+ void __far *fpvData, unsigned short cbData, unsigned short __far *pcbDataReturned);
+ unsigned long fpfnServiceAsmEP;
+} VBGOS2IDC;
+typedef VBGOS2IDC *PVBGOS2IDC;
+
+#define VBOXGUEST_IOCTL_WAITEVENT 2
+#define VBOXGUEST_IOCTL_VMMREQUEST 3
+#define VBOXGUEST_IOCTL_OS2_IDC_DISCONNECT 48
+
+#define VBOXGUEST_WAITEVENT_OK 0
+#define VBOXGUEST_WAITEVENT_TIMEOUT 1
+#define VBOXGUEST_WAITEVENT_INTERRUPTED 2
+#define VBOXGUEST_WAITEVENT_ERROR 3
+
+typedef struct _VBoxGuestWaitEventInfo
+{
+ unsigned long u32TimeoutIn;
+ unsigned long u32EventMaskIn;
+ unsigned long u32Result;
+ unsigned long u32EventFlagsOut;
+} VBoxGuestWaitEventInfo;
+
+
+#define VMMDEV_REQUEST_HEADER_VERSION (0x10001UL)
+typedef struct
+{
+ unsigned long size;
+ unsigned long version;
+ unsigned long requestType;
+ signed long rc;
+ unsigned long reserved1;
+ unsigned long reserved2;
+} VMMDevRequestHeader;
+
+#define VMMDevReq_GetMouseStatus 1
+#define VMMDevReq_SetMouseStatus 2
+#define VMMDevReq_CtlGuestFilterMask 42
+
+#define VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE RT_BIT(0)
+#define VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE RT_BIT(1)
+#define VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR RT_BIT(2)
+#define VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER RT_BIT(3)
+
+typedef struct
+{
+ VMMDevRequestHeader header;
+ unsigned long mouseFeatures;
+ unsigned long pointerXPos;
+ unsigned long pointerYPos;
+} VMMDevReqMouseStatus;
+
+typedef struct
+{
+ VMMDevRequestHeader header;
+ unsigned long u32OrMask;
+ unsigned long u32NotMask;
+} VMMDevCtlGuestFilterMask;
+
+
+/* From VMMDev.h: */
+#define VMMDEV_VERSION 0x00010004UL
+
+#define VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED RT_BIT(0)
+#define VMMDEV_EVENT_HGCM RT_BIT(1)
+#define VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST RT_BIT(2)
+#define VMMDEV_EVENT_JUDGE_CREDENTIALS RT_BIT(3)
+#define VMMDEV_EVENT_RESTORED RT_BIT(4)
+
+#endif
+
diff --git a/include/VBox/VBoxGuest2.h b/include/VBox/VBoxGuest2.h
new file mode 100644
index 00000000..4e17b2df
--- /dev/null
+++ b/include/VBox/VBoxGuest2.h
@@ -0,0 +1,108 @@
+/** @file
+ * VBoxGuest - VirtualBox Guest Additions Driver Interface, Mixed Up Mess.
+ * (ADD,DEV)
+ */
+
+/*
+ * Copyright (C) 2006-2009 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 ___VBox_VBoxGuest2_h
+#define ___VBox_VBoxGuest2_h
+
+#include <iprt/assert.h>
+
+#ifdef VBOX_WITH_HGCM
+# include <VBox/VMMDev2.h>
+
+
+/**
+ * HGCM connect info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_CONNECT and in VbglR0.
+ *
+ * @ingroup grp_vboxguest
+ */
+# pragma pack(1) /* explicit packing for good measure. */
+typedef struct VBoxGuestHGCMConnectInfo
+{
+ int32_t result; /**< OUT */
+ HGCMServiceLocation Loc; /**< IN */
+ uint32_t u32ClientID; /**< OUT */
+} VBoxGuestHGCMConnectInfo;
+AssertCompileSize(VBoxGuestHGCMConnectInfo, 4+4+128+4);
+# pragma pack()
+
+
+/**
+ * HGCM connect info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_DISCONNECT and in VbglR0.
+ *
+ * @ingroup grp_vboxguest
+ */
+typedef struct VBoxGuestHGCMDisconnectInfo
+{
+ int32_t result; /**< OUT */
+ uint32_t u32ClientID; /**< IN */
+} VBoxGuestHGCMDisconnectInfo;
+AssertCompileSize(VBoxGuestHGCMDisconnectInfo, 8);
+
+/**
+ * HGCM call info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_CALL.
+ *
+ * @ingroup grp_vboxguest
+ */
+typedef struct VBoxGuestHGCMCallInfo
+{
+ int32_t result; /**< OUT Host HGCM return code.*/
+ uint32_t u32ClientID; /**< IN The id of the caller. */
+ uint32_t u32Function; /**< IN Function number. */
+ uint32_t cParms; /**< IN How many parms. */
+ /* Parameters follow in form HGCMFunctionParameter aParms[cParms] */
+} VBoxGuestHGCMCallInfo;
+AssertCompileSize(VBoxGuestHGCMCallInfo, 16);
+
+
+/**
+ * HGCM call info structure.
+ *
+ * This is used by VBOXGUEST_IOCTL_HGCM_CALL_TIMED.
+ *
+ * @ingroup grp_vboxguest
+ */
+# pragma pack(1) /* explicit packing for good measure. */
+typedef struct VBoxGuestHGCMCallInfoTimed
+{
+ uint32_t u32Timeout; /**< IN How long to wait for completion before cancelling the call. */
+ uint32_t fInterruptible; /**< IN Is this request interruptible? */
+ VBoxGuestHGCMCallInfo info; /**< IN/OUT The rest of the call information. Placed after the timeout
+ * so that the parameters follow as they would for a normal call. */
+ /* Parameters follow in form HGCMFunctionParameter aParms[cParms] */
+} VBoxGuestHGCMCallInfoTimed;
+AssertCompileSize(VBoxGuestHGCMCallInfoTimed, 8+16);
+# pragma pack()
+
+#endif /* VBOX_WITH_HGCM */
+
+#endif
+
diff --git a/include/VBox/VBoxGuestLib.h b/include/VBox/VBoxGuestLib.h
new file mode 100644
index 00000000..c860a073
--- /dev/null
+++ b/include/VBox/VBoxGuestLib.h
@@ -0,0 +1,751 @@
+/** @file
+ * VBoxGuestLib - VirtualBox Guest Additions Library.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VBoxGuestLib_h
+#define ___VBox_VBoxGuestLib_h
+
+#include <VBox/types.h>
+#include <VBox/VMMDev2.h>
+#include <VBox/VMMDev.h> /* grumble */
+#ifdef IN_RING0
+# include <VBox/VBoxGuest.h>
+# include <VBox/VBoxGuest2.h>
+#endif
+
+
+/** @defgroup grp_guest_lib VirtualBox Guest Additions Library
+ * @{
+ */
+
+/** @page pg_guest_lib VirtualBox Guest Library
+ *
+ * This is a library for abstracting the additions driver interface. There are
+ * multiple versions of the library depending on the context. The main
+ * distinction is between kernel and user mode where the interfaces are very
+ * different.
+ *
+ *
+ * @section sec_guest_lib_ring0 Ring-0
+ *
+ * In ring-0 there are two version:
+ * - VBOX_LIB_VBGL_R0_BASE / VBoxGuestR0LibBase for the VBoxGuest main driver,
+ * who is responsible for managing the VMMDev virtual hardware.
+ * - VBOX_LIB_VBGL_R0 / VBoxGuestR0Lib for other (client) guest drivers.
+ *
+ *
+ * The library source code and the header have a define VBGL_VBOXGUEST, which is
+ * defined for VBoxGuest and undefined for other drivers. Drivers must choose
+ * right library in their makefiles and set VBGL_VBOXGUEST accordingly.
+ *
+ * The libraries consists of:
+ * - common code to be used by both VBoxGuest and other drivers;
+ * - VBoxGuest specific code;
+ * - code for other drivers which communicate with VBoxGuest via an IOCTL.
+ *
+ *
+ * @section sec_guest_lib_ring3 Ring-3
+ *
+ * There are more variants of the library here:
+ * - VBOX_LIB_VBGL_R3 / VBoxGuestR3Lib for programs.
+ * - VBOX_LIB_VBGL_R3_XFREE86 / VBoxGuestR3LibXFree86 for old style XFree
+ * drivers which uses special loader and or symbol resolving strategy.
+ * - VBOX_LIB_VBGL_R3_SHARED / VBoxGuestR3LibShared for shared objects / DLLs /
+ * Dylibs.
+ *
+ */
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_guest_lib_r0 Ring-0 interface.
+ * @{
+ */
+#if defined(IN_RING0) && !defined(IN_RING0_AGNOSTIC)
+/** @def DECLR0VBGL
+ * Declare a VBGL ring-0 API with the right calling convention and visibilitiy.
+ * @param type Return type. */
+# define DECLR0VBGL(type) type VBOXCALL
+# define DECLVBGL(type) DECLR0VBGL(type)
+
+typedef uint32_t VBGLIOPORT; /**< @todo r=bird: We have RTIOPORT (uint16_t) for this. */
+
+
+# ifdef VBGL_VBOXGUEST
+
+/**
+ * The library initialization function to be used by the main
+ * VBoxGuest system driver.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglInit (VBGLIOPORT portVMMDev, struct VMMDevMemory *pVMMDevMemory);
+
+# else
+
+/**
+ * The library initialization function to be used by all drivers
+ * other than the main VBoxGuest system driver.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglInit (void);
+
+# endif
+
+/**
+ * The library termination function.
+ */
+DECLVBGL(void) VbglTerminate (void);
+
+
+/** @name Generic request functions.
+ * @{
+ */
+
+/**
+ * Allocate memory for generic request and initialize the request header.
+ *
+ * @param ppReq pointer to resulting memory address.
+ * @param cbSize size of memory block required for the request.
+ * @param reqType the generic request type.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglGRAlloc (VMMDevRequestHeader **ppReq, uint32_t cbSize, VMMDevRequestType reqType);
+
+/**
+ * Perform the generic request.
+ *
+ * @param pReq pointer the request structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglGRPerform (VMMDevRequestHeader *pReq);
+
+/**
+ * Free the generic request memory.
+ *
+ * @param pReq pointer the request structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(void) VbglGRFree (VMMDevRequestHeader *pReq);
+
+/**
+ * Verify the generic request header.
+ *
+ * @param pReq pointer the request header structure.
+ * @param cbReq size of the request memory block. It should be equal to the request size
+ * for fixed size requests. It can be greater than the request size for
+ * variable size requests.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglGRVerify (const VMMDevRequestHeader *pReq, size_t cbReq);
+/** @} */
+
+# ifdef VBOX_WITH_HGCM
+
+# ifdef VBGL_VBOXGUEST
+
+/**
+ * Callback function called from HGCM helpers when a wait for request
+ * completion IRQ is required.
+ *
+ * @returns VINF_SUCCESS, VERR_INTERRUPT or VERR_TIMEOUT.
+ * @param pvData VBoxGuest pointer to be passed to callback.
+ * @param u32Data VBoxGuest 32 bit value to be passed to callback.
+ */
+typedef DECLVBGL(int) FNVBGLHGCMCALLBACK(VMMDevHGCMRequestHeader *pHeader, void *pvData, uint32_t u32Data);
+/** Pointer to a FNVBGLHGCMCALLBACK. */
+typedef FNVBGLHGCMCALLBACK *PFNVBGLHGCMCALLBACK;
+
+/**
+ * Perform a connect request. That is locate required service and
+ * obtain a client identifier for future access.
+ *
+ * @note This function can NOT handle cancelled requests!
+ *
+ * @param pConnectInfo The request data.
+ * @param pfnAsyncCallback Required pointer to function that is calledwhen
+ * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ * implements waiting for an IRQ in this function.
+ * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback.
+ *
+ * @return VBox status code.
+ */
+
+DECLR0VBGL(int) VbglR0HGCMInternalConnect (VBoxGuestHGCMConnectInfo *pConnectInfo,
+ PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+
+/**
+ * Perform a disconnect request. That is tell the host that
+ * the client will not call the service anymore.
+ *
+ * @note This function can NOT handle cancelled requests!
+ *
+ * @param pDisconnectInfo The request data.
+ * @param pfnAsyncCallback Required pointer to function that is called when
+ * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ * implements waiting for an IRQ in this function.
+ * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to
+ * callback.
+ *
+ * @return VBox status code.
+ */
+
+DECLR0VBGL(int) VbglR0HGCMInternalDisconnect (VBoxGuestHGCMDisconnectInfo *pDisconnectInfo,
+ PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+/** Call a HGCM service.
+ *
+ * @note This function can deal with cancelled requests.
+ *
+ * @param pCallInfo The request data.
+ * @param fFlags Flags, see VBGLR0_HGCMCALL_F_XXX.
+ * @param pfnAsyncCallback Required pointer to function that is called when
+ * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ * implements waiting for an IRQ in this function.
+ * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback.
+ *
+ * @return VBox status code.
+ */
+DECLR0VBGL(int) VbglR0HGCMInternalCall (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
+ PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+/** Call a HGCM service. (32 bits packet structure in a 64 bits guest)
+ *
+ * @note This function can deal with cancelled requests.
+ *
+ * @param pCallInfo The request data.
+ * @param fFlags Flags, see VBGLR0_HGCMCALL_F_XXX.
+ * @param pfnAsyncCallback Required pointer to function that is called when
+ * host returns VINF_HGCM_ASYNC_EXECUTE. VBoxGuest
+ * implements waiting for an IRQ in this function.
+ * @param pvAsyncData An arbitrary VBoxGuest pointer to be passed to callback.
+ * @param u32AsyncData An arbitrary VBoxGuest 32 bit value to be passed to callback.
+ *
+ * @return VBox status code.
+ */
+DECLR0VBGL(int) VbglR0HGCMInternalCall32 (VBoxGuestHGCMCallInfo *pCallInfo, uint32_t cbCallInfo, uint32_t fFlags,
+ PFNVBGLHGCMCALLBACK pfnAsyncCallback, void *pvAsyncData, uint32_t u32AsyncData);
+
+/** @name VbglR0HGCMInternalCall flags
+ * @{ */
+/** User mode request.
+ * Indicates that only user mode addresses are permitted as parameters. */
+#define VBGLR0_HGCMCALL_F_USER UINT32_C(0)
+/** Kernel mode request.
+ * Indicates that kernel mode addresses are permitted as parameters. Whether or
+ * not user mode addresses are permitted is, unfortunately, OS specific. The
+ * following OSes allows user mode addresses: Windows, TODO.
+ */
+#define VBGLR0_HGCMCALL_F_KERNEL UINT32_C(1)
+/** Mode mask. */
+#define VBGLR0_HGCMCALL_F_MODE_MASK UINT32_C(1)
+/** @} */
+
+# else /* !VBGL_VBOXGUEST */
+
+struct VBGLHGCMHANDLEDATA;
+typedef struct VBGLHGCMHANDLEDATA *VBGLHGCMHANDLE;
+
+/** @name HGCM functions
+ * @{
+ */
+
+/**
+ * Connect to a service.
+ *
+ * @param pHandle Pointer to variable that will hold a handle to be used
+ * further in VbglHGCMCall and VbglHGCMClose.
+ * @param pData Connection information structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMConnect (VBGLHGCMHANDLE *pHandle, VBoxGuestHGCMConnectInfo *pData);
+
+/**
+ * Connect to a service.
+ *
+ * @param handle Handle of the connection.
+ * @param pData Disconnect request information structure.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMDisconnect (VBGLHGCMHANDLE handle, VBoxGuestHGCMDisconnectInfo *pData);
+
+/**
+ * Call to a service.
+ *
+ * @param handle Handle of the connection.
+ * @param pData Call request information structure, including function parameters.
+ * @param cbData Length in bytes of data.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMCall (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData);
+
+/**
+ * Call to a service with user-mode data received by the calling driver from the User-Mode process.
+ * The call must be done in the context of a calling process.
+ *
+ * @param handle Handle of the connection.
+ * @param pData Call request information structure, including function parameters.
+ * @param cbData Length in bytes of data.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMCallUserData (VBGLHGCMHANDLE handle, VBoxGuestHGCMCallInfo *pData, uint32_t cbData);
+
+/**
+ * Call to a service with timeout.
+ *
+ * @param handle Handle of the connection.
+ * @param pData Call request information structure, including function parameters.
+ * @param cbData Length in bytes of data.
+ * @param cMillies Timeout in milliseconds. Use RT_INDEFINITE_WAIT to wait forever.
+ *
+ * @return VBox status code.
+ */
+DECLVBGL(int) VbglHGCMCallTimed (VBGLHGCMHANDLE handle,
+ VBoxGuestHGCMCallInfoTimed *pData, uint32_t cbData);
+/** @} */
+
+# endif /* !VBGL_VBOXGUEST */
+
+# endif /* VBOX_WITH_HGCM */
+
+
+/**
+ * Initialize the heap.
+ *
+ * @return VBox error code.
+ */
+DECLVBGL(int) VbglPhysHeapInit (void);
+
+/**
+ * Shutdown the heap.
+ */
+DECLVBGL(void) VbglPhysHeapTerminate (void);
+
+
+/**
+ * Allocate a memory block.
+ *
+ * @param cbSize Size of block to be allocated.
+ * @return Virtual address of allocated memory block.
+ */
+DECLVBGL(void *) VbglPhysHeapAlloc (uint32_t cbSize);
+
+/**
+ * Get physical address of memory block pointed by
+ * the virtual address.
+ *
+ * @note WARNING!
+ * The function does not acquire the Heap mutex!
+ * When calling the function make sure that
+ * the pointer is a valid one and is not being
+ * deallocated.
+ * This function can NOT be used for verifying
+ * if the given pointer is a valid one allocated
+ * from the heap.
+ *
+ *
+ * @param p Virtual address of memory block.
+ * @return Physical memory block.
+ */
+DECLVBGL(RTCCPHYS) VbglPhysHeapGetPhysAddr (void *p);
+
+/**
+ * Free a memory block.
+ *
+ * @param p Virtual address of memory block.
+ */
+DECLVBGL(void) VbglPhysHeapFree (void *p);
+
+DECLVBGL(int) VbglQueryVMMDevMemory (VMMDevMemory **ppVMMDevMemory);
+DECLR0VBGL(bool) VbglR0CanUsePhysPageList(void);
+
+# ifndef VBOX_GUEST
+/** @name Mouse
+ * @{ */
+DECLVBGL(int) VbglSetMouseNotifyCallback(PFNVBOXGUESTMOUSENOTIFY pfnNotify, void *pvUser);
+DECLVBGL(int) VbglGetMouseStatus(uint32_t *pfFeatures, uint32_t *px, uint32_t *py);
+DECLVBGL(int) VbglSetMouseStatus(uint32_t fFeatures);
+/** @} */
+# endif /* VBOX_GUEST */
+
+#endif /* IN_RING0 && !IN_RING0_AGNOSTIC */
+/** @} */
+
+
+/** @defgroup grp_guest_lib_r3 Ring-3 interface.
+ * @{
+ */
+#ifdef IN_RING3
+
+/** @def VBGLR3DECL
+ * Ring 3 VBGL declaration.
+ * @param type The return type of the function declaration.
+ */
+# define VBGLR3DECL(type) type VBOXCALL
+
+/** @name General-purpose functions
+ * @{ */
+VBGLR3DECL(int) VbglR3Init(void);
+VBGLR3DECL(int) VbglR3InitUser(void);
+VBGLR3DECL(void) VbglR3Term(void);
+# ifdef ___iprt_time_h
+VBGLR3DECL(int) VbglR3GetHostTime(PRTTIMESPEC pTime);
+# endif
+VBGLR3DECL(int) VbglR3InterruptEventWaits(void);
+VBGLR3DECL(int) VbglR3WriteLog(const char *pch, size_t cch);
+VBGLR3DECL(int) VbglR3CtlFilterMask(uint32_t fOr, uint32_t fNot);
+VBGLR3DECL(int) VbglR3Daemonize(bool fNoChDir, bool fNoClose);
+VBGLR3DECL(int) VbglR3PidFile(const char *pszPath, PRTFILE phFile);
+VBGLR3DECL(void) VbglR3ClosePidFile(const char *pszPath, RTFILE hFile);
+VBGLR3DECL(int) VbglR3SetGuestCaps(uint32_t fOr, uint32_t fNot);
+VBGLR3DECL(int) VbglR3WaitEvent(uint32_t fMask, uint32_t cMillies, uint32_t *pfEvents);
+
+VBGLR3DECL(int) VbglR3ReportAdditionsStatus(VBoxGuestFacilityType Facility, VBoxGuestFacilityStatus StatusCurrent, uint32_t uFlags);
+VBGLR3DECL(int) VbglR3GetAdditionsVersion(char **ppszVer, char **ppszVerEx, char **ppszRev);
+VBGLR3DECL(int) VbglR3GetAdditionsInstallationPath(char **ppszPath);
+VBGLR3DECL(int) VbglR3GetSessionId(uint64_t *pu64IdSession);
+
+/** @} */
+
+/** @name Shared clipboard
+ * @{ */
+VBGLR3DECL(int) VbglR3ClipboardConnect(uint32_t *pu32ClientId);
+VBGLR3DECL(int) VbglR3ClipboardDisconnect(uint32_t u32ClientId);
+VBGLR3DECL(int) VbglR3ClipboardGetHostMsg(uint32_t u32ClientId, uint32_t *pMsg, uint32_t *pfFormats);
+VBGLR3DECL(int) VbglR3ClipboardReadData(uint32_t u32ClientId, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcb);
+VBGLR3DECL(int) VbglR3ClipboardReportFormats(uint32_t u32ClientId, uint32_t fFormats);
+VBGLR3DECL(int) VbglR3ClipboardWriteData(uint32_t u32ClientId, uint32_t fFormat, void *pv, uint32_t cb);
+/** @} */
+
+/** @name Seamless mode
+ * @{ */
+VBGLR3DECL(int) VbglR3SeamlessSetCap(bool fState);
+VBGLR3DECL(int) VbglR3SeamlessWaitEvent(VMMDevSeamlessMode *pMode);
+VBGLR3DECL(int) VbglR3SeamlessSendRects(uint32_t cRects, PRTRECT pRects);
+VBGLR3DECL(int) VbglR3SeamlessGetLastEvent(VMMDevSeamlessMode *pMode);
+
+/** @} */
+
+/** @name Mouse
+ * @{ */
+VBGLR3DECL(int) VbglR3GetMouseStatus(uint32_t *pfFeatures, uint32_t *px, uint32_t *py);
+VBGLR3DECL(int) VbglR3SetMouseStatus(uint32_t fFeatures);
+/** @} */
+
+/** @name Video
+ * @{ */
+VBGLR3DECL(int) VbglR3VideoAccelEnable(bool fEnable);
+VBGLR3DECL(int) VbglR3VideoAccelFlush(void);
+VBGLR3DECL(int) VbglR3SetPointerShape(uint32_t fFlags, uint32_t xHot, uint32_t yHot, uint32_t cx, uint32_t cy, const void *pvImg, size_t cbImg);
+VBGLR3DECL(int) VbglR3SetPointerShapeReq(struct VMMDevReqMousePointer *pReq);
+/** @} */
+
+/** @name Display
+ * @{ */
+VBGLR3DECL(int) VbglR3GetDisplayChangeRequest(uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits, uint32_t *piDisplay, bool fAck);
+VBGLR3DECL(bool) VbglR3HostLikesVideoMode(uint32_t cx, uint32_t cy, uint32_t cBits);
+VBGLR3DECL(int) VbglR3SaveVideoMode(const char *pszName, uint32_t cx, uint32_t cy, uint32_t cBits);
+VBGLR3DECL(int) VbglR3RetrieveVideoMode(const char *pszName, uint32_t *pcx, uint32_t *pcy, uint32_t *pcBits);
+/** @} */
+
+/** @name VM Statistics
+ * @{ */
+VBGLR3DECL(int) VbglR3StatQueryInterval(uint32_t *pu32Interval);
+VBGLR3DECL(int) VbglR3StatReport(VMMDevReportGuestStats *pReq);
+/** @} */
+
+/** @name Memory ballooning
+ * @{ */
+VBGLR3DECL(int) VbglR3MemBalloonRefresh(uint32_t *pcChunks, bool *pfHandleInR3);
+VBGLR3DECL(int) VbglR3MemBalloonChange(void *pv, bool fInflate);
+/** @} */
+
+/** @name Core Dump
+ * @{ */
+VBGLR3DECL(int) VbglR3WriteCoreDump(void);
+
+/** @} */
+
+# ifdef VBOX_WITH_GUEST_PROPS
+/** @name Guest properties
+ * @{ */
+/** @todo Docs. */
+typedef struct VBGLR3GUESTPROPENUM VBGLR3GUESTPROPENUM;
+/** @todo Docs. */
+typedef VBGLR3GUESTPROPENUM *PVBGLR3GUESTPROPENUM;
+VBGLR3DECL(int) VbglR3GuestPropConnect(uint32_t *pu32ClientId);
+VBGLR3DECL(int) VbglR3GuestPropDisconnect(uint32_t u32ClientId);
+VBGLR3DECL(int) VbglR3GuestPropWrite(uint32_t u32ClientId, const char *pszName, const char *pszValue, const char *pszFlags);
+VBGLR3DECL(int) VbglR3GuestPropWriteValue(uint32_t u32ClientId, const char *pszName, const char *pszValue);
+VBGLR3DECL(int) VbglR3GuestPropWriteValueV(uint32_t u32ClientId, const char *pszName, const char *pszValueFormat, va_list va);
+VBGLR3DECL(int) VbglR3GuestPropWriteValueF(uint32_t u32ClientId, const char *pszName, const char *pszValueFormat, ...);
+VBGLR3DECL(int) VbglR3GuestPropRead(uint32_t u32ClientId, const char *pszName, void *pvBuf, uint32_t cbBuf, char **ppszValue, uint64_t *pu64Timestamp, char **ppszFlags, uint32_t *pcbBufActual);
+VBGLR3DECL(int) VbglR3GuestPropReadValue(uint32_t ClientId, const char *pszName, char *pszValue, uint32_t cchValue, uint32_t *pcchValueActual);
+VBGLR3DECL(int) VbglR3GuestPropReadValueAlloc(uint32_t u32ClientId, const char *pszName, char **ppszValue);
+VBGLR3DECL(void) VbglR3GuestPropReadValueFree(char *pszValue);
+VBGLR3DECL(int) VbglR3GuestPropEnumRaw(uint32_t u32ClientId, const char *paszPatterns, char *pcBuf, uint32_t cbBuf, uint32_t *pcbBufActual);
+VBGLR3DECL(int) VbglR3GuestPropEnum(uint32_t u32ClientId, char const * const *ppaszPatterns, uint32_t cPatterns, PVBGLR3GUESTPROPENUM *ppHandle,
+ char const **ppszName, char const **ppszValue, uint64_t *pu64Timestamp, char const **ppszFlags);
+VBGLR3DECL(int) VbglR3GuestPropEnumNext(PVBGLR3GUESTPROPENUM pHandle, char const **ppszName, char const **ppszValue, uint64_t *pu64Timestamp,
+ char const **ppszFlags);
+VBGLR3DECL(void) VbglR3GuestPropEnumFree(PVBGLR3GUESTPROPENUM pHandle);
+VBGLR3DECL(int) VbglR3GuestPropDelSet(uint32_t u32ClientId, char const * const *papszPatterns, uint32_t cPatterns);
+VBGLR3DECL(int) VbglR3GuestPropWait(uint32_t u32ClientId, const char *pszPatterns, void *pvBuf, uint32_t cbBuf, uint64_t u64Timestamp, uint32_t cMillies, char ** ppszName, char **ppszValue, uint64_t *pu64Timestamp, char **ppszFlags, uint32_t *pcbBufActual);
+/** @} */
+
+/** @name Host version handling
+ * @{ */
+VBGLR3DECL(int) VbglR3HostVersionCheckForUpdate(uint32_t u32ClientId, bool *pfUpdate, char **ppszHostVersion, char **ppszGuestVersion);
+VBGLR3DECL(int) VbglR3HostVersionLastCheckedLoad(uint32_t u32ClientId, char **ppszVer);
+VBGLR3DECL(int) VbglR3HostVersionLastCheckedStore(uint32_t u32ClientId, const char *pszVer);
+/** @} */
+# endif /* VBOX_WITH_GUEST_PROPS defined */
+
+# ifdef VBOX_WITH_SHARED_FOLDERS
+/** @name Shared folders
+ * @{ */
+/**
+ * Structure containing mapping information for a shared folder.
+ */
+typedef struct VBGLR3SHAREDFOLDERMAPPING
+{
+ /** Mapping status. */
+ uint32_t u32Status;
+ /** Root handle. */
+ uint32_t u32Root;
+} VBGLR3SHAREDFOLDERMAPPING;
+/** Pointer to a shared folder mapping information struct. */
+typedef VBGLR3SHAREDFOLDERMAPPING *PVBGLR3SHAREDFOLDERMAPPING;
+
+VBGLR3DECL(int) VbglR3SharedFolderConnect(uint32_t *pu32ClientId);
+VBGLR3DECL(int) VbglR3SharedFolderDisconnect(uint32_t u32ClientId);
+VBGLR3DECL(bool) VbglR3SharedFolderExists(uint32_t u32ClientId, const char *pszShareName);
+VBGLR3DECL(int) VbglR3SharedFolderGetMappings(uint32_t u32ClientId, bool fAutoMountOnly,
+ PVBGLR3SHAREDFOLDERMAPPING *ppaMappings, uint32_t *pcMappings);
+VBGLR3DECL(void) VbglR3SharedFolderFreeMappings(PVBGLR3SHAREDFOLDERMAPPING paMappings);
+VBGLR3DECL(int) VbglR3SharedFolderGetName(uint32_t u32ClientId,uint32_t u32Root, char **ppszName);
+VBGLR3DECL(int) VbglR3SharedFolderGetMountPrefix(char **ppszPrefix);
+VBGLR3DECL(int) VbglR3SharedFolderGetMountDir(char **ppszDir);
+/** @} */
+# endif /* VBOX_WITH_SHARED_FOLDERS defined */
+
+# ifdef VBOX_WITH_GUEST_CONTROL
+/** @name Guest control
+ * @{ */
+/** @todo Clean this up, uniform formatting. */
+VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pu32ClientId);
+VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId);
+VBGLR3DECL(int) VbglR3GuestCtrlWaitForHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms);
+VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId);
+/* Process execution. */
+VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdExec(uint32_t u32ClientId, uint32_t cParms,
+ uint32_t *puContext,
+ char *pszCmd, uint32_t cbCmd,
+ uint32_t *puFlags,
+ char *pszArgs, uint32_t cbArgs, uint32_t *puNumArgs,
+ char *pszEnv, uint32_t *pcbEnv, uint32_t *puNumEnvVars,
+ char *pszUser, uint32_t cbUser,
+ char *pszPassword, uint32_t cbPassword,
+ uint32_t *puTimeLimit);
+VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t u32ClientId, uint32_t uNumParms,
+ uint32_t *puContext, uint32_t *puPID,
+ uint32_t *puFlags, void *pvData,
+ uint32_t cbData, uint32_t *pcbSize);
+VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t u32ClientId, uint32_t uNumParms,
+ uint32_t *puContext, uint32_t *puPID,
+ uint32_t *puHandle, uint32_t *puFlags);
+VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatus(uint32_t u32ClientId,
+ uint32_t u32Context,
+ uint32_t u32PID,
+ uint32_t u32Status,
+ uint32_t u32Flags,
+ void *pvData,
+ uint32_t cbData);
+VBGLR3DECL(int) VbglR3GuestCtrlExecSendOut(uint32_t u32ClientId,
+ uint32_t u32Context,
+ uint32_t u32PID,
+ uint32_t u32Handle,
+ uint32_t u32Flags,
+ void *pvData,
+ uint32_t cbData);
+VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatusIn(uint32_t u32ClientId,
+ uint32_t u32Context,
+ uint32_t u32PID,
+ uint32_t u32Status,
+ uint32_t u32Flags,
+ uint32_t cbWritten);
+/* Native file handling. */
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdOpen(uint32_t uClientId, uint32_t cParms,
+ uint32_t *puContext,
+ char *pszFileName, uint32_t cbFileName,
+ char *pszOpenMode, uint32_t cbOpenMode,
+ char *pszDisposition, uint32_t cbDisposition,
+ uint32_t *puCreationMode,
+ uint64_t *puOffset);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdClose(uint32_t uClientId, uint32_t cParms,
+ uint32_t *puContext,
+ uint32_t *puHandle);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdRead(uint32_t uClientId, uint32_t cParms,
+ uint32_t *puContext,
+ uint32_t *puHandle, uint32_t *puToRead);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdWrite(uint32_t uClientId, uint32_t cParms,
+ uint32_t *puContext,
+ uint32_t *puHandle,
+ void *pvData, uint32_t cbData,
+ uint32_t *pcbSize);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdSeek(uint32_t uClientId, uint32_t cParms,
+ uint32_t *puContext,
+ uint32_t *puHandle,
+ uint32_t *puSeekMethod, uint64_t *puOffset);
+VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdTell(uint32_t uClientId, uint32_t cParms,
+ uint32_t *puContext,
+ uint32_t *puHandle);
+VBGLR3DECL(int) VbglR3GuestCtrlFileNotify(uint32_t uClientId,
+ uint32_t uContext, uint32_t uHandle,
+ uint32_t uType,
+ void *pvPayload, uint32_t cbPayload);
+/** @} */
+# endif /* VBOX_WITH_GUEST_CONTROL defined */
+
+/** @name Auto-logon handling
+ * @{ */
+VBGLR3DECL(int) VbglR3AutoLogonReportStatus(VBoxGuestFacilityStatus enmStatus);
+VBGLR3DECL(bool) VbglR3AutoLogonIsRemoteSession(void);
+/** @} */
+
+/** @name User credentials handling
+ * @{ */
+VBGLR3DECL(int) VbglR3CredentialsQueryAvailability(void);
+VBGLR3DECL(int) VbglR3CredentialsRetrieve(char **ppszUser, char **ppszPassword, char **ppszDomain);
+VBGLR3DECL(int) VbglR3CredentialsRetrieveUtf16(PRTUTF16 *ppwszUser, PRTUTF16 *ppwszPassword, PRTUTF16 *ppwszDomain);
+VBGLR3DECL(void) VbglR3CredentialsDestroy(char *pszUser, char *pszPassword, char *pszDomain, uint32_t cPasses);
+VBGLR3DECL(void) VbglR3CredentialsDestroyUtf16(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 pwszDomain,
+ uint32_t cPasses);
+/** @} */
+
+/** @name CPU hotplug monitor
+ * @{ */
+VBGLR3DECL(int) VbglR3CpuHotPlugInit(void);
+VBGLR3DECL(int) VbglR3CpuHotPlugTerm(void);
+VBGLR3DECL(int) VbglR3CpuHotPlugWaitForEvent(VMMDevCpuEventType *penmEventType, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
+/** @} */
+
+/** @name Page sharing
+ * @{ */
+VBGLR3DECL(int) VbglR3RegisterSharedModule(char *pszModuleName, char *pszVersion, RTGCPTR64 GCBaseAddr, uint32_t cbModule, unsigned cRegions, VMMDEVSHAREDREGIONDESC *pRegions);
+VBGLR3DECL(int) VbglR3UnregisterSharedModule(char *pszModuleName, char *pszVersion, RTGCPTR64 GCBaseAddr, uint32_t cbModule);
+VBGLR3DECL(int) VbglR3CheckSharedModules(void);
+VBGLR3DECL(bool) VbglR3PageSharingIsEnabled(void);
+VBGLR3DECL(int) VbglR3PageIsShared(RTGCPTR pPage, bool *pfShared, uint64_t *puPageFlags);
+/** @} */
+
+# ifdef VBOX_WITH_DRAG_AND_DROP
+/** @name Drag and Drop
+ * @{ */
+typedef struct VBGLR3DNDHGCMEVENT
+{
+ uint32_t uType; /** The event type this struct contains */
+ uint32_t uScreenId; /** Screen id this request belongs to */
+ char *pszFormats; /** Format list (\r\n separated) */
+ uint32_t cbFormats; /** Size of pszFormats (\0 included) */
+ union
+ {
+ struct
+ {
+ uint32_t uXpos; /** X position of guest screen */
+ uint32_t uYpos; /** Y position of guest screen */
+ uint32_t uDefAction; /** Proposed DnD action */
+ uint32_t uAllActions; /** Allowed DnD actions */
+ }a; /** Values used in init, move and drop event type */
+ struct
+ {
+ void *pvData; /** Data request */
+ size_t cbData; /** Size of pvData */
+ }b; /** Values used in drop data event type */
+ }u;
+} VBGLR3DNDHGCMEVENT;
+typedef VBGLR3DNDHGCMEVENT *PVBGLR3DNDHGCMEVENT;
+typedef const PVBGLR3DNDHGCMEVENT CPVBGLR3DNDHGCMEVENT;
+VBGLR3DECL(int) VbglR3DnDInit(void);
+VBGLR3DECL(int) VbglR3DnDTerm(void);
+
+VBGLR3DECL(int) VbglR3DnDConnect(uint32_t *pu32ClientId);
+VBGLR3DECL(int) VbglR3DnDDisconnect(uint32_t u32ClientId);
+
+VBGLR3DECL(int) VbglR3DnDProcessNextMessage(CPVBGLR3DNDHGCMEVENT pEvent);
+
+VBGLR3DECL(int) VbglR3DnDHGAcknowledgeOperation(uint32_t uAction);
+VBGLR3DECL(int) VbglR3DnDHGRequestData(const char* pcszFormat);
+# ifdef VBOX_WITH_DRAG_AND_DROP_GH
+VBGLR3DECL(int) VbglR3DnDGHAcknowledgePending(uint32_t uDefAction, uint32_t uAllActions, const char* pcszFormat);
+VBGLR3DECL(int) VbglR3DnDGHSendData(void *pvData, uint32_t cbData);
+VBGLR3DECL(int) VbglR3DnDGHErrorEvent(int rcOp);
+# endif /* VBOX_WITH_DRAG_AND_DROP_GH */
+/** @} */
+# endif /* VBOX_WITH_DRAG_AND_DROP */
+
+/* Generic Host Channel Service. */
+VBGLR3DECL(int) VbglR3HostChannelInit(uint32_t *pu32HGCMClientId);
+VBGLR3DECL(void) VbglR3HostChannelTerm(uint32_t u32HGCMClientId);
+VBGLR3DECL(int) VbglR3HostChannelAttach(uint32_t *pu32ChannelHandle, uint32_t u32HGCMClientId,
+ const char *pszName, uint32_t u32Flags);
+VBGLR3DECL(void) VbglR3HostChannelDetach(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId);
+VBGLR3DECL(int) VbglR3HostChannelSend(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId,
+ void *pvData, uint32_t cbData);
+VBGLR3DECL(int) VbglR3HostChannelRecv(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId,
+ void *pvData, uint32_t cbData,
+ uint32_t *pu32SizeReceived, uint32_t *pu32SizeRemaining);
+VBGLR3DECL(int) VbglR3HostChannelControl(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId,
+ uint32_t u32Code, void *pvParm, uint32_t cbParm,
+ void *pvData, uint32_t cbData, uint32_t *pu32SizeDataReturned);
+VBGLR3DECL(int) VbglR3HostChannelEventWait(uint32_t *pu32ChannelHandle, uint32_t u32HGCMClientId,
+ uint32_t *pu32EventId, void *pvParm, uint32_t cbParm,
+ uint32_t *pu32SizeReturned);
+VBGLR3DECL(int) VbglR3HostChannelEventCancel(uint32_t u32ChannelHandle, uint32_t u32HGCMClientId);
+VBGLR3DECL(int) VbglR3HostChannelQuery(const char *pszName, uint32_t u32HGCMClientId, uint32_t u32Code,
+ void *pvParm, uint32_t cbParm, void *pvData, uint32_t cbData,
+ uint32_t *pu32SizeDataReturned);
+
+#endif /* IN_RING3 */
+/** @} */
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/VBoxGuestMangling.h b/include/VBox/VBoxGuestMangling.h
new file mode 100644
index 00000000..350c1bae
--- /dev/null
+++ b/include/VBox/VBoxGuestMangling.h
@@ -0,0 +1,32 @@
+/** @file
+ * VBoxGuest - Mangling of IPRT symbols for guest drivers.
+ *
+ * This is included via a compiler directive on platforms with a global kernel
+ * symbol name space (i.e. not Windows, OS/2 and Mac OS X (?)).
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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.
+ */
+
+
+#define RT_MANGLER(symbol) VBoxGuest_##symbol
+#include <iprt/mangling.h>
+
diff --git a/include/VBox/VBoxKeyboard.h b/include/VBox/VBoxKeyboard.h
new file mode 100644
index 00000000..8353a944
--- /dev/null
+++ b/include/VBox/VBoxKeyboard.h
@@ -0,0 +1,53 @@
+/** @file
+ * Frontends/Common - X11 keyboard driver interface.
+ */
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * Oracle LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
+ * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
+ * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
+ * a choice of LGPL license versions is made available with the language indicating
+ * that LGPLv2 or any later version may be used, or where a choice of which version
+ * of the LGPL is applied is otherwise unspecified.
+ */
+
+#ifndef ___VBox_VBoxKeyboard_h
+#define ___VBox_VBoxKeyboard_h
+
+#include <X11/Xlib.h>
+
+/* Exported definitions */
+#undef CCALL
+#ifdef __cplusplus
+# define CCALL "C"
+#else
+# define CCALL
+#endif
+#ifdef VBOX_HAVE_VISIBILITY_HIDDEN
+extern CCALL __attribute__((visibility("default"))) unsigned *X11DRV_getKeyc2scan(void);
+extern CCALL __attribute__((visibility("default"))) unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK, unsigned *byXkbOK, int (*remapScancodes)[2]);
+extern CCALL __attribute__((visibility("default"))) unsigned X11DRV_KeyEvent(Display *dpy, KeyCode code);
+#else
+extern CCALL unsigned *X11DRV_getKeyc2scan(void);
+extern CCALL unsigned X11DRV_InitKeyboard(Display *dpy, unsigned *byLayoutOK, unsigned *byTypeOK, unsigned *byXkbOK, int (*remapScancodes)[2]);
+extern CCALL unsigned X11DRV_KeyEvent(Display *dpy, KeyCode code);
+#endif
+
+#endif
+
diff --git a/include/VBox/VBoxNetCfg-win.h b/include/VBox/VBoxNetCfg-win.h
new file mode 100644
index 00000000..8e327c0d
--- /dev/null
+++ b/include/VBox/VBoxNetCfg-win.h
@@ -0,0 +1,107 @@
+/* $Id: VBoxNetCfg-win.h $ */
+/** @file
+ * Network Configuration API for Windows platforms.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VBoxNetCfg_win_h
+#define ___VBox_VBoxNetCfg_win_h
+
+#include <winsock2.h>
+#include <Windows.h>
+#include <Netcfgn.h>
+#include <Setupapi.h>
+#include <VBox/cdefs.h>
+
+/** @defgroup grp_vboxnetcfgwin The Windows Network Configration Library
+ * @{ */
+
+/** @def VBOXNETCFGWIN_DECL
+ * The usual declaration wrapper.
+ */
+#if 0
+/* enable this in case we include this in a dll*/
+# ifdef IN_VBOXDDU
+# define VBOXNETCFGWIN_DECL(a_Type) DECLEXPORT(a_Type)
+# else
+# define VBOXNETCFGWIN_DECL(a_Type) DECLIMPORT(a_Type)
+# endif
+#else
+/*enable this in case we include this in a static lib*/
+# define VBOXNETCFGWIN_DECL(a_Type) a_Type VBOXCALL
+#endif
+
+RT_C_DECLS_BEGIN
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinQueryINetCfg(OUT INetCfg **ppNetCfg,
+ IN BOOL fGetWriteLock,
+ IN LPCWSTR pszwClientDescription,
+ IN DWORD cmsTimeout,
+ OUT LPWSTR *ppszwClientDescription);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinReleaseINetCfg(IN INetCfg *pNetCfg, IN BOOL fHasWriteLock);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetComponentByGuid(IN INetCfg *pNc, IN const GUID *pguidClass,
+ IN const GUID * pComponentGuid, OUT INetCfgComponent **ppncc);
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltInstall(IN INetCfg *pNc, IN LPCWSTR const * apInfFullPaths, IN UINT cInfFullPaths);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinNetFltUninstall(IN INetCfg *pNc);
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinCreateHostOnlyNetworkInterface(IN LPCWSTR pInfPath, IN bool bIsInfPathFile,
+ OUT GUID *pGuid, OUT BSTR *lppszName,
+ OUT BSTR *pErrMsg);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinUpdateHostOnlyNetworkInterface(LPCWSTR pcsxwInf, BOOL *pbRebootRequired);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveHostOnlyNetworkInterface(IN const GUID *pGUID, OUT BSTR *pErrMsg);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinRemoveAllNetDevicesOfId(IN LPCWSTR lpszPnPId);
+
+typedef enum
+{
+ VBOXNECTFGWINPROPCHANGE_TYPE_UNDEFINED = 0,
+ VBOXNECTFGWINPROPCHANGE_TYPE_DISABLE,
+ VBOXNECTFGWINPROPCHANGE_TYPE_ENABLE
+} VBOXNECTFGWINPROPCHANGE_TYPE;
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinPropChangeAllNetDevicesOfId(IN LPCWSTR lpszPnPId, VBOXNECTFGWINPROPCHANGE_TYPE enmPcType);
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGenHostOnlyNetworkNetworkIp(OUT PULONG pNetIp, OUT PULONG pNetMask);
+
+typedef struct ADAPTER_SETTINGS
+{
+ ULONG ip;
+ ULONG mask;
+ BOOL bDhcp;
+} ADAPTER_SETTINGS, *PADAPTER_SETTINGS; /**< I'm not prefixed */
+
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableStaticIpConfig(IN const GUID *pGuid, IN ULONG ip, IN ULONG mask);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinGetAdapterSettings(IN const GUID * pGuid, OUT PADAPTER_SETTINGS pSettings);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinEnableDynamicIpConfig(IN const GUID *pGuid);
+VBOXNETCFGWIN_DECL(HRESULT) VBoxNetCfgWinDhcpRediscover(IN const GUID *pGuid);
+
+
+typedef VOID (*LOG_ROUTINE)(LPCSTR szString); /**< I'm not prefixed. */
+VBOXNETCFGWIN_DECL(VOID) VBoxNetCfgWinSetLogging(IN LOG_ROUTINE pfnLog);
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/VBoxOGLTest.h b/include/VBox/VBoxOGLTest.h
new file mode 100644
index 00000000..a9e31118
--- /dev/null
+++ b/include/VBox/VBoxOGLTest.h
@@ -0,0 +1,36 @@
+/* $Id: VBoxOGLTest.h $ */
+/** @file
+ * VBox 3D Support test API
+ */
+/*
+ * 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 ___VBoxOGLTest_h__
+#define ___VBoxOGLTest_h__
+
+#include <iprt/cdefs.h>
+
+RT_C_DECLS_BEGIN
+
+bool RTCALL VBoxOglIs3DAccelerationSupported();
+
+RT_C_DECLS_END
+
+#endif /*#ifndef ___VBoxOGLTest_h__*/
diff --git a/include/VBox/VBoxTpG.h b/include/VBox/VBoxTpG.h
new file mode 100644
index 00000000..260ee6f2
--- /dev/null
+++ b/include/VBox/VBoxTpG.h
@@ -0,0 +1,425 @@
+/* $Id: VBoxTpG.h $ */
+/** @file
+ * VBox Tracepoint Generator Structures.
+ */
+
+/*
+ * 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 ___VBox_VTG_h___
+#define ___VBox_VTG_h___
+
+#include <iprt/types.h>
+#include <iprt/assert.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * 32-bit probe location.
+ */
+typedef struct VTGPROBELOC32
+{
+ uint32_t uLine : 31;
+ uint32_t fEnabled : 1;
+ uint32_t idProbe;
+ uint32_t pszFunction;
+ uint32_t pProbe;
+} VTGPROBELOC32;
+AssertCompileSize(VTGPROBELOC32, 16);
+/** Pointer to a 32-bit probe location. */
+typedef VTGPROBELOC32 *PVTGPROBELOC32;
+/** Pointer to a const 32-bit probe location. */
+typedef VTGPROBELOC32 const *PCVTGPROBELOC32;
+
+/**
+ * 64-bit probe location.
+ */
+typedef struct VTGPROBELOC64
+{
+ uint32_t uLine : 31;
+ uint32_t fEnabled : 1;
+ uint32_t idProbe;
+ uint64_t pszFunction;
+ uint64_t pProbe;
+ uint64_t uAlignment;
+} VTGPROBELOC64;
+AssertCompileSize(VTGPROBELOC64, 32);
+/** Pointer to a 64-bit probe location. */
+typedef VTGPROBELOC64 *PVTGPROBELOC64;
+/** Pointer to a const 64-bit probe location. */
+typedef VTGPROBELOC64 const *PCVTGPROBELOC64;
+
+
+/**
+ * Probe location.
+ */
+typedef struct VTGPROBELOC
+{
+ uint32_t uLine : 31;
+ uint32_t fEnabled : 1;
+ uint32_t idProbe;
+ const char *pszFunction;
+ struct VTGDESCPROBE *pProbe;
+#if ARCH_BITS == 64
+ uintptr_t uAlignment;
+#endif
+} VTGPROBELOC;
+AssertCompileSizeAlignment(VTGPROBELOC, 16);
+/** Pointer to a probe location. */
+typedef VTGPROBELOC *PVTGPROBELOC;
+/** Pointer to a const probe location. */
+typedef VTGPROBELOC const *PCVTGPROBELOC;
+
+/** @def VTG_OBJ_SECT
+ * The name of the section containing the other probe data provided by the
+ * assembly / object generated by VBoxTpG. */
+/** @def VTG_LOC_SECT
+ * The name of the section containing the VTGPROBELOC structures. This is
+ * filled by the probe macros, @see VTG_DECL_VTGPROBELOC. */
+/** @def VTG_DECL_VTGPROBELOC
+ * Declares a static variable, @a a_VarName, of type VTGPROBELOC in the section
+ * indicated by VTG_LOC_SECT. */
+#if defined(RT_OS_WINDOWS)
+# define VTG_OBJ_SECT "VTGObj"
+# define VTG_LOC_SECT "VTGPrLc.Data"
+# ifdef _MSC_VER
+# define VTG_DECL_VTGPROBELOC(a_VarName) \
+ __declspec(allocate(VTG_LOC_SECT)) static VTGPROBELOC a_VarName
+# elif defined(__GNUC__)
+# define VTG_DECL_VTGPROBELOC(a_VarName) \
+ static VTGPROBELOC __attribute__((section(VTG_LOC_SECT))) a_VarName
+# else
+# error "Unsupported Windows compiler!"
+# endif
+
+#elif defined(RT_OS_DARWIN)
+# define VTG_OBJ_SECT "__VTGObj"
+# define VTG_LOC_SECT "__VTGPrLc"
+# define VTG_LOC_SEG "__VTG"
+# ifdef __GNUC__
+# define VTG_DECL_VTGPROBELOC(a_VarName) \
+ static VTGPROBELOC __attribute__((section(VTG_LOC_SEG "," VTG_LOC_SECT ",regular")/*, aligned(16)*/)) a_VarName
+# else
+# error "Unsupported Darwin compiler!"
+# endif
+
+#elif defined(RT_OS_OS2)
+# error "OS/2 is not supported"
+
+#else /* Assume the rest uses ELF. */
+# define VTG_OBJ_SECT ".VTGObj"
+# define VTG_LOC_SECT ".VTGPrLc"
+# ifdef __GNUC__
+# define VTG_DECL_VTGPROBELOC(a_VarName) \
+ static VTGPROBELOC __attribute__((section(VTG_LOC_SECT))) a_VarName
+# else
+# error "Unsupported compiler!"
+# endif
+#endif
+
+/** VTG string table offset. */
+typedef uint32_t VTGSTROFF;
+
+
+/** @name VTG type flags
+ * @{ */
+/** Masking out the fixed size if given. */
+#define VTG_TYPE_SIZE_MASK UINT32_C(0x000000ff)
+/** Indicates that VTG_TYPE_SIZE_MASK can be applied, UNSIGNED or SIGNED is
+ * usually set as well, so may PHYS. */
+#define VTG_TYPE_FIXED_SIZED RT_BIT_32(8)
+/** It's a pointer type, the size is given by the context the probe fired in. */
+#define VTG_TYPE_POINTER RT_BIT_32(9)
+/** A context specfic pointer or address, consult VTG_TYPE_CTX_XXX. */
+#define VTG_TYPE_CTX_POINTER RT_BIT_32(10)
+/** The type has the same size as the host architecture. */
+#define VTG_TYPE_HC_ARCH_SIZED RT_BIT_32(11)
+/** The type applies to ring-3 context. */
+#define VTG_TYPE_CTX_R3 RT_BIT_32(24)
+/** The type applies to ring-0 context. */
+#define VTG_TYPE_CTX_R0 RT_BIT_32(25)
+/** The type applies to raw-mode context. */
+#define VTG_TYPE_CTX_RC RT_BIT_32(26)
+/** The type applies to guest context. */
+#define VTG_TYPE_CTX_GST RT_BIT_32(27)
+/** The type context mask. */
+#define VTG_TYPE_CTX_MASK UINT32_C(0x0f000000)
+/** The type is automatically converted to a ring-0 pointer. */
+#define VTG_TYPE_AUTO_CONV_PTR RT_BIT_32(28)
+/** The type is a physical address. */
+#define VTG_TYPE_PHYS RT_BIT_32(29)
+/** The type is unsigned. */
+#define VTG_TYPE_UNSIGNED RT_BIT_32(30)
+/** The type is signed. */
+#define VTG_TYPE_SIGNED RT_BIT_32(31)
+/** Mask of valid bits (for simple validation). */
+#define VTG_TYPE_VALID_MASK UINT32_C(0xff000fff)
+/** @} */
+
+/**
+ * Checks if the VTG type flags indicates a large fixed size argument.
+ */
+#define VTG_TYPE_IS_LARGE(a_fType) \
+ ( ((a_fType) & VTG_TYPE_SIZE_MASK) > 4 && ((a_fType) & VTG_TYPE_FIXED_SIZED) )
+
+
+/**
+ * VTG argument descriptor.
+ */
+typedef struct VTGDESCARG
+{
+ VTGSTROFF offType;
+ uint32_t fType;
+} VTGDESCARG;
+/** Pointer to an argument descriptor. */
+typedef VTGDESCARG *PVTGDESCARG;
+/** Pointer to a const argument descriptor. */
+typedef VTGDESCARG const *PCVTGDESCARG;
+
+
+/**
+ * VTG argument list descriptor.
+ */
+typedef struct VTGDESCARGLIST
+{
+ uint8_t cArgs;
+ uint8_t fHaveLargeArgs;
+ uint8_t abReserved[2];
+ VTGDESCARG aArgs[1];
+} VTGDESCARGLIST;
+/** Pointer to a VTG argument list descriptor. */
+typedef VTGDESCARGLIST *PVTGDESCARGLIST;
+/** Pointer to a const VTG argument list descriptor. */
+typedef VTGDESCARGLIST const *PCVTGDESCARGLIST;
+
+
+/**
+ * VTG probe descriptor.
+ */
+typedef struct VTGDESCPROBE
+{
+ VTGSTROFF offName;
+ uint32_t offArgList;
+ uint16_t idxEnabled;
+ uint16_t idxProvider;
+ /** The distance from this structure to the VTG object header. */
+ int32_t offObjHdr;
+} VTGDESCPROBE;
+AssertCompileSize(VTGDESCPROBE, 16);
+/** Pointer to a VTG probe descriptor. */
+typedef VTGDESCPROBE *PVTGDESCPROBE;
+/** Pointer to a const VTG probe descriptor. */
+typedef VTGDESCPROBE const *PCVTGDESCPROBE;
+
+
+/**
+ * Code/data stability.
+ */
+typedef enum kVTGStability
+{
+ kVTGStability_Invalid = 0,
+ kVTGStability_Internal,
+ kVTGStability_Private,
+ kVTGStability_Obsolete,
+ kVTGStability_External,
+ kVTGStability_Unstable,
+ kVTGStability_Evolving,
+ kVTGStability_Stable,
+ kVTGStability_Standard,
+ kVTGStability_End
+} kVTGStability;
+
+/**
+ * Data dependency.
+ */
+typedef enum kVTGClass
+{
+ kVTGClass_Invalid = 0,
+ kVTGClass_Unknown,
+ kVTGClass_Cpu,
+ kVTGClass_Platform,
+ kVTGClass_Group,
+ kVTGClass_Isa,
+ kVTGClass_Common,
+ kVTGClass_End
+} kVTGClass;
+
+
+/**
+ * VTG attributes.
+ */
+typedef struct VTGDESCATTR
+{
+ uint8_t u8Code;
+ uint8_t u8Data;
+ uint8_t u8DataDep;
+} VTGDESCATTR;
+AssertCompileSize(VTGDESCATTR, 3);
+/** Pointer to a const VTG attribute. */
+typedef VTGDESCATTR const *PCVTGDESCATTR;
+
+
+/**
+ * VTG provider descriptor.
+ */
+typedef struct VTGDESCPROVIDER
+{
+ VTGSTROFF offName;
+ uint16_t iFirstProbe;
+ uint16_t cProbes;
+ VTGDESCATTR AttrSelf;
+ VTGDESCATTR AttrModules;
+ VTGDESCATTR AttrFunctions;
+ VTGDESCATTR AttrNames;
+ VTGDESCATTR AttrArguments;
+ uint8_t bReserved;
+} VTGDESCPROVIDER;
+/** Pointer to a VTG provider descriptor. */
+typedef VTGDESCPROVIDER *PVTGDESCPROVIDER;
+/** Pointer to a const VTG provider descriptor. */
+typedef VTGDESCPROVIDER const *PCVTGDESCPROVIDER;
+
+
+/**
+ * VTG data object header.
+ */
+typedef struct VTGOBJHDR
+{
+ /** Magic value (VTGOBJHDR_MAGIC). */
+ char szMagic[24];
+ /** The bitness of the structures.
+ * This only affects the probe location pointers and structures. */
+ uint32_t cBits;
+ /** The size of the VTG object. This excludes the probe locations. */
+ uint32_t cbObj;
+
+ /** @name Area Descriptors
+ * @remarks The offsets are relative to the header. The members are
+ * ordered by ascending offset (maybe with the exception of the
+ * probe locations). No overlaps, though there might be zero
+ * filled gaps between them due to alignment.
+ * @{ */
+ /* 32: */
+ /** Offset of the string table (char) relative to this header. */
+ uint32_t offStrTab;
+ /** The size of the string table, in bytes. */
+ uint32_t cbStrTab;
+ /** Offset of the argument lists (VTGDESCARGLIST - variable size) relative
+ * to this header. */
+ uint32_t offArgLists;
+ /** The size of the argument lists, in bytes. */
+ uint32_t cbArgLists;
+ /* 48: */
+ /** Offset of the probe array (VTGDESCPROBE) relative to this header. */
+ uint32_t offProbes;
+ /** The size of the probe array, in bytes. */
+ uint32_t cbProbes;
+ /** Offset of the provider array (VTGDESCPROVIDER) relative to this
+ * header. */
+ uint32_t offProviders;
+ /** The size of the provider array, in bytes. */
+ uint32_t cbProviders;
+ /* 64: */
+ /** Offset of the probe-enabled array (uint32_t) relative to this
+ * header. */
+ uint32_t offProbeEnabled;
+ /** The size of the probe-enabled array, in bytes. */
+ uint32_t cbProbeEnabled;
+ /** Offset of the probe location array (VTGPROBELOC) relative to this
+ * header.
+ * @remarks This is filled in by the first VTG user using uProbeLocs. */
+ int32_t offProbeLocs;
+ /** The size of the probe location array, in bytes.
+ * @remarks This is filled in by the first VTG user using uProbeLocs. */
+ uint32_t cbProbeLocs;
+ /** @} */
+ /* 80: */
+ /**
+ * The probe location array is generated by C code and lives in a
+ * different section/subsection/segment than the rest of the data.
+ *
+ * The assembler cannot generate offsets across sections for most (if not
+ * all) object formats, so we have to store pointers here. The first user
+ * of the data will convert these two members into offset and size and fill
+ * in the offProbeLocs and cbProbeLocs members above.
+ *
+ * @remarks Converting these members to offset+size and reusing the members
+ * to store the converted values isn't possible because of
+ * raw-mode context modules having relocations associated with the
+ * fields.
+ */
+ union
+ {
+ PVTGPROBELOC p;
+ uintptr_t uPtr;
+ uint32_t u32;
+ uint64_t u64;
+ }
+ /** Pointer to the probe location array. */
+ uProbeLocs,
+ /** Pointer to the end of the probe location array. */
+ uProbeLocsEnd;
+ /** UUID for making sharing ring-0 structures for the same ring-3
+ * modules easier. */
+ RTUUID Uuid;
+ /** Mac 10.6.x load workaround.
+ * The linker or/and load messes up the uProbeLocs and uProbeLocsEnd fields
+ * so that they will be link addresses instead of load addresses. To be
+ * able to work around it we store the start address of the __VTGObj section
+ * here and uses it to validate the probe location addresses. */
+ uint64_t u64VtgObjSectionStart;
+ /** Reserved / alignment. */
+ uint32_t au32Reserved1[2];
+} VTGOBJHDR;
+AssertCompileSize(VTGOBJHDR, 128);
+AssertCompileMemberAlignment(VTGOBJHDR, uProbeLocs, 8);
+AssertCompileMemberAlignment(VTGOBJHDR, uProbeLocsEnd, 8);
+/** Pointer to a VTG data object header. */
+typedef VTGOBJHDR *PVTGOBJHDR;
+/** Pointer to a const VTG data object header. */
+typedef VTGOBJHDR const *PCVTGOBJHDR;
+
+/** The current VTGOBJHDR::szMagic value. */
+#define VTGOBJHDR_MAGIC "VTG Object Header v1.5\0"
+
+/** The name of the VTG data object header symbol in the object file. */
+extern VTGOBJHDR g_VTGObjHeader;
+
+
+/** @name Macros for converting typical pointer arguments to ring-0 pointers.
+ * @{ */
+#ifdef IN_RING0
+# define VTG_VM_TO_R0(a_pVM) (a_pVM)
+# define VTG_VMCPU_TO_R0(a_pVCpu) (a_pVCpu)
+# define VTG_CPUMCTX_TO_R0(a_pVCpu, a_pCtx) (a_pCtx)
+#else
+# define VTG_VM_TO_R0(a_pVM) ((a_pVM) ? (a_pVM)->pVMR0 : NIL_RTR0PTR)
+# define VTG_VMCPU_TO_R0(a_pVCpu) ((a_pVCpu) ? VM_R0_ADDR((a_pVCpu)->CTX_SUFF(pVM), a_pVCpu) : NIL_RTR0PTR)
+# define VTG_CPUMCTX_TO_R0(a_pVCpu, a_pCtx) ((a_pVCpu) ? VM_R0_ADDR((a_pVCpu)->CTX_SUFF(pVM), a_pCtx) : NIL_RTR0PTR)
+#endif
+/** @} */
+
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/VBoxUhgsmi.h b/include/VBox/VBoxUhgsmi.h
new file mode 100644
index 00000000..459c6352
--- /dev/null
+++ b/include/VBox/VBoxUhgsmi.h
@@ -0,0 +1,137 @@
+/** @file
+ * Document me, pretty please.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VBoxUhgsmi_h
+#define ___VBox_VBoxUhgsmi_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+typedef struct VBOXUHGSMI *PVBOXUHGSMI;
+
+typedef struct VBOXUHGSMI_BUFFER *PVBOXUHGSMI_BUFFER;
+
+typedef struct VBOXUHGSMI_BUFFER_TYPE_FLAGS
+{
+ union
+ {
+ struct
+ {
+ uint32_t fCommand : 1;
+ uint32_t Reserved : 31;
+ };
+ uint32_t Value;
+ };
+} VBOXUHGSMI_BUFFER_TYPE_FLAGS;
+
+typedef struct VBOXUHGSMI_BUFFER_LOCK_FLAGS
+{
+ union
+ {
+ struct
+ {
+ uint32_t bReadOnly : 1;
+ uint32_t bWriteOnly : 1;
+ uint32_t bDonotWait : 1;
+ uint32_t bDiscard : 1;
+ uint32_t bLockEntire : 1;
+ uint32_t Reserved : 27;
+ };
+ uint32_t Value;
+ };
+} VBOXUHGSMI_BUFFER_LOCK_FLAGS;
+
+typedef struct VBOXUHGSMI_BUFFER_SUBMIT_FLAGS
+{
+ union
+ {
+ struct
+ {
+ uint32_t bHostReadOnly : 1;
+ uint32_t bHostWriteOnly : 1;
+ uint32_t bDoNotRetire : 1; /**< the buffer will be used in a subsequent command */
+ uint32_t bEntireBuffer : 1;
+ uint32_t Reserved : 28;
+ };
+ uint32_t Value;
+ };
+} VBOXUHGSMI_BUFFER_SUBMIT_FLAGS, *PVBOXUHGSMI_BUFFER_SUBMIT_FLAGS;
+
+/* the caller can specify NULL as a hSynch and specify a valid enmSynchType to make UHGSMI create a proper object itself,
+ * */
+typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_CREATE(PVBOXUHGSMI pHgsmi, uint32_t cbBuf, VBOXUHGSMI_BUFFER_TYPE_FLAGS fType, PVBOXUHGSMI_BUFFER* ppBuf);
+typedef FNVBOXUHGSMI_BUFFER_CREATE *PFNVBOXUHGSMI_BUFFER_CREATE;
+
+typedef struct VBOXUHGSMI_BUFFER_SUBMIT
+{
+ PVBOXUHGSMI_BUFFER pBuf;
+ uint32_t offData;
+ uint32_t cbData;
+ VBOXUHGSMI_BUFFER_SUBMIT_FLAGS fFlags;
+} VBOXUHGSMI_BUFFER_SUBMIT, *PVBOXUHGSMI_BUFFER_SUBMIT;
+
+typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_SUBMIT(PVBOXUHGSMI pHgsmi, PVBOXUHGSMI_BUFFER_SUBMIT aBuffers, uint32_t cBuffers);
+typedef FNVBOXUHGSMI_BUFFER_SUBMIT *PFNVBOXUHGSMI_BUFFER_SUBMIT;
+
+typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_DESTROY(PVBOXUHGSMI_BUFFER pBuf);
+typedef FNVBOXUHGSMI_BUFFER_DESTROY *PFNVBOXUHGSMI_BUFFER_DESTROY;
+
+typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_LOCK(PVBOXUHGSMI_BUFFER pBuf, uint32_t offLock, uint32_t cbLock, VBOXUHGSMI_BUFFER_LOCK_FLAGS fFlags, void**pvLock);
+typedef FNVBOXUHGSMI_BUFFER_LOCK *PFNVBOXUHGSMI_BUFFER_LOCK;
+
+typedef DECLCALLBACK(int) FNVBOXUHGSMI_BUFFER_UNLOCK(PVBOXUHGSMI_BUFFER pBuf);
+typedef FNVBOXUHGSMI_BUFFER_UNLOCK *PFNVBOXUHGSMI_BUFFER_UNLOCK;
+
+typedef struct VBOXUHGSMI
+{
+ PFNVBOXUHGSMI_BUFFER_CREATE pfnBufferCreate;
+ PFNVBOXUHGSMI_BUFFER_SUBMIT pfnBufferSubmit;
+ /** User custom data. */
+ void *pvUserData;
+} VBOXUHGSMI;
+
+typedef struct VBOXUHGSMI_BUFFER
+{
+ PFNVBOXUHGSMI_BUFFER_LOCK pfnLock;
+ PFNVBOXUHGSMI_BUFFER_UNLOCK pfnUnlock;
+ PFNVBOXUHGSMI_BUFFER_DESTROY pfnDestroy;
+
+ /* r/o data added for ease of access and simplicity
+ * modifying it leads to unpredictable behavior */
+ VBOXUHGSMI_BUFFER_TYPE_FLAGS fType;
+ uint32_t cbBuffer;
+ /** User custom data. */
+ void *pvUserData;
+} VBOXUHGSMI_BUFFER;
+
+#define VBoxUhgsmiBufferCreate(_pUhgsmi, _cbBuf, _fType, _ppBuf) ((_pUhgsmi)->pfnBufferCreate(_pUhgsmi, _cbBuf, _fType, _ppBuf))
+#define VBoxUhgsmiBufferSubmit(_pUhgsmi, _aBuffers, _cBuffers) ((_pUhgsmi)->pfnBufferSubmit(_pUhgsmi, _aBuffers, _cBuffers))
+
+#define VBoxUhgsmiBufferLock(_pBuf, _offLock, _cbLock, _fFlags, _pvLock) ((_pBuf)->pfnLock(_pBuf, _offLock, _cbLock, _fFlags, _pvLock))
+#define VBoxUhgsmiBufferUnlock(_pBuf) ((_pBuf)->pfnUnlock(_pBuf))
+#define VBoxUhgsmiBufferDestroy(_pBuf) ((_pBuf)->pfnDestroy(_pBuf))
+
+#endif
+
diff --git a/include/VBox/VBoxVideo.h b/include/VBox/VBoxVideo.h
new file mode 100644
index 00000000..bbc6d7b5
--- /dev/null
+++ b/include/VBox/VBoxVideo.h
@@ -0,0 +1,1468 @@
+/** @file
+ * VirtualBox Video interface.
+ */
+
+/*
+ * Copyright (C) 2006 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 ___VBox_VBoxVideo_h
+#define ___VBox_VBoxVideo_h
+
+#include <VBox/VMMDev.h>
+#include <VBox/Hardware/VBoxVideoVBE.h>
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+/*
+ * The last 4096 bytes of the guest VRAM contains the generic info for all
+ * DualView chunks: sizes and offsets of chunks. This is filled by miniport.
+ *
+ * Last 4096 bytes of each chunk contain chunk specific data: framebuffer info,
+ * etc. This is used exclusively by the corresponding instance of a display driver.
+ *
+ * The VRAM layout:
+ * Last 4096 bytes - Adapter information area.
+ * 4096 bytes aligned miniport heap (value specified in the config rouded up).
+ * Slack - what left after dividing the VRAM.
+ * 4096 bytes aligned framebuffers:
+ * last 4096 bytes of each framebuffer is the display information area.
+ *
+ * The Virtual Graphics Adapter information in the guest VRAM is stored by the
+ * guest video driver using structures prepended by VBOXVIDEOINFOHDR.
+ *
+ * When the guest driver writes dword 0 to the VBE_DISPI_INDEX_VBOX_VIDEO
+ * the host starts to process the info. The first element at the start of
+ * the 4096 bytes region should be normally be a LINK that points to
+ * actual information chain. That way the guest driver can have some
+ * fixed layout of the information memory block and just rewrite
+ * the link to point to relevant memory chain.
+ *
+ * The processing stops at the END element.
+ *
+ * The host can access the memory only when the port IO is processed.
+ * All data that will be needed later must be copied from these 4096 bytes.
+ * But other VRAM can be used by host until the mode is disabled.
+ *
+ * The guest driver writes dword 0xffffffff to the VBE_DISPI_INDEX_VBOX_VIDEO
+ * to disable the mode.
+ *
+ * VBE_DISPI_INDEX_VBOX_VIDEO is used to read the configuration information
+ * from the host and issue commands to the host.
+ *
+ * The guest writes the VBE_DISPI_INDEX_VBOX_VIDEO index register, the the
+ * following operations with the VBE data register can be performed:
+ *
+ * Operation Result
+ * write 16 bit value NOP
+ * read 16 bit value count of monitors
+ * write 32 bit value sets the vbox command value and the command processed by the host
+ * read 32 bit value result of the last vbox command is returned
+ */
+
+#define VBOX_VIDEO_PRIMARY_SCREEN 0
+#define VBOX_VIDEO_NO_SCREEN ~0
+
+/* The size of the information. */
+/*
+ * The minimum HGSMI heap size is PAGE_SIZE (4096 bytes) and is a restriction of the
+ * runtime heapsimple API. Use minimum 2 pages here, because the info area also may
+ * contain other data (for example HGSMIHOSTFLAGS structure).
+ */
+#ifndef VBOX_XPDM_MINIPORT
+# define VBVA_ADAPTER_INFORMATION_SIZE (64*_1K)
+#else
+#define VBVA_ADAPTER_INFORMATION_SIZE (16*_1K)
+#define VBVA_DISPLAY_INFORMATION_SIZE (64*_1K)
+#endif
+#define VBVA_MIN_BUFFER_SIZE (64*_1K)
+
+
+/* The value for port IO to let the adapter to interpret the adapter memory. */
+#define VBOX_VIDEO_DISABLE_ADAPTER_MEMORY 0xFFFFFFFF
+
+/* The value for port IO to let the adapter to interpret the adapter memory. */
+#define VBOX_VIDEO_INTERPRET_ADAPTER_MEMORY 0x00000000
+
+/* The value for port IO to let the adapter to interpret the display memory.
+ * The display number is encoded in low 16 bits.
+ */
+#define VBOX_VIDEO_INTERPRET_DISPLAY_MEMORY_BASE 0x00010000
+
+
+/* The end of the information. */
+#define VBOX_VIDEO_INFO_TYPE_END 0
+/* Instructs the host to fetch the next VBOXVIDEOINFOHDR at the given offset of VRAM. */
+#define VBOX_VIDEO_INFO_TYPE_LINK 1
+/* Information about a display memory position. */
+#define VBOX_VIDEO_INFO_TYPE_DISPLAY 2
+/* Information about a screen. */
+#define VBOX_VIDEO_INFO_TYPE_SCREEN 3
+/* Information about host notifications for the driver. */
+#define VBOX_VIDEO_INFO_TYPE_HOST_EVENTS 4
+/* Information about non-volatile guest VRAM heap. */
+#define VBOX_VIDEO_INFO_TYPE_NV_HEAP 5
+/* VBVA enable/disable. */
+#define VBOX_VIDEO_INFO_TYPE_VBVA_STATUS 6
+/* VBVA flush. */
+#define VBOX_VIDEO_INFO_TYPE_VBVA_FLUSH 7
+/* Query configuration value. */
+#define VBOX_VIDEO_INFO_TYPE_QUERY_CONF32 8
+
+
+#pragma pack(1)
+typedef struct VBOXVIDEOINFOHDR
+{
+ uint8_t u8Type;
+ uint8_t u8Reserved;
+ uint16_t u16Length;
+} VBOXVIDEOINFOHDR;
+
+
+typedef struct VBOXVIDEOINFOLINK
+{
+ /* Relative offset in VRAM */
+ int32_t i32Offset;
+} VBOXVIDEOINFOLINK;
+
+
+/* Resides in adapter info memory. Describes a display VRAM chunk. */
+typedef struct VBOXVIDEOINFODISPLAY
+{
+ /* Index of the framebuffer assigned by guest. */
+ uint32_t u32Index;
+
+ /* Absolute offset in VRAM of the framebuffer to be displayed on the monitor. */
+ uint32_t u32Offset;
+
+ /* The size of the memory that can be used for the screen. */
+ uint32_t u32FramebufferSize;
+
+ /* The size of the memory that is used for the Display information.
+ * The information is at u32Offset + u32FramebufferSize
+ */
+ uint32_t u32InformationSize;
+
+} VBOXVIDEOINFODISPLAY;
+
+
+/* Resides in display info area, describes the current video mode. */
+#define VBOX_VIDEO_INFO_SCREEN_F_NONE 0x00
+#define VBOX_VIDEO_INFO_SCREEN_F_ACTIVE 0x01
+
+typedef struct VBOXVIDEOINFOSCREEN
+{
+ /* Physical X origin relative to the primary screen. */
+ int32_t xOrigin;
+
+ /* Physical Y origin relative to the primary screen. */
+ int32_t yOrigin;
+
+ /* The scan line size in bytes. */
+ uint32_t u32LineSize;
+
+ /* Width of the screen. */
+ uint16_t u16Width;
+
+ /* Height of the screen. */
+ uint16_t u16Height;
+
+ /* Color depth. */
+ uint8_t bitsPerPixel;
+
+ /* VBOX_VIDEO_INFO_SCREEN_F_* */
+ uint8_t u8Flags;
+} VBOXVIDEOINFOSCREEN;
+
+/* The guest initializes the structure to 0. The positions of the structure in the
+ * display info area must not be changed, host will update the structure. Guest checks
+ * the events and modifies the structure as a response to host.
+ */
+#define VBOX_VIDEO_INFO_HOST_EVENTS_F_NONE 0x00000000
+#define VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET 0x00000080
+
+typedef struct VBOXVIDEOINFOHOSTEVENTS
+{
+ /* Host events. */
+ uint32_t fu32Events;
+} VBOXVIDEOINFOHOSTEVENTS;
+
+/* Resides in adapter info memory. Describes the non-volatile VRAM heap. */
+typedef struct VBOXVIDEOINFONVHEAP
+{
+ /* Absolute offset in VRAM of the start of the heap. */
+ uint32_t u32HeapOffset;
+
+ /* The size of the heap. */
+ uint32_t u32HeapSize;
+
+} VBOXVIDEOINFONVHEAP;
+
+/* Display information area. */
+typedef struct VBOXVIDEOINFOVBVASTATUS
+{
+ /* Absolute offset in VRAM of the start of the VBVA QUEUE. 0 to disable VBVA. */
+ uint32_t u32QueueOffset;
+
+ /* The size of the VBVA QUEUE. 0 to disable VBVA. */
+ uint32_t u32QueueSize;
+
+} VBOXVIDEOINFOVBVASTATUS;
+
+typedef struct VBOXVIDEOINFOVBVAFLUSH
+{
+ uint32_t u32DataStart;
+
+ uint32_t u32DataEnd;
+
+} VBOXVIDEOINFOVBVAFLUSH;
+
+#define VBOX_VIDEO_QCI32_MONITOR_COUNT 0
+#define VBOX_VIDEO_QCI32_OFFSCREEN_HEAP_SIZE 1
+
+typedef struct VBOXVIDEOINFOQUERYCONF32
+{
+ uint32_t u32Index;
+
+ uint32_t u32Value;
+
+} VBOXVIDEOINFOQUERYCONF32;
+#pragma pack()
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+#pragma pack(1)
+
+#define VBOXVHWA_VERSION_MAJ 0
+#define VBOXVHWA_VERSION_MIN 0
+#define VBOXVHWA_VERSION_BLD 6
+#define VBOXVHWA_VERSION_RSV 0
+
+typedef enum
+{
+ VBOXVHWACMD_TYPE_SURF_CANCREATE = 1,
+ VBOXVHWACMD_TYPE_SURF_CREATE,
+ VBOXVHWACMD_TYPE_SURF_DESTROY,
+ VBOXVHWACMD_TYPE_SURF_LOCK,
+ VBOXVHWACMD_TYPE_SURF_UNLOCK,
+ VBOXVHWACMD_TYPE_SURF_BLT,
+ VBOXVHWACMD_TYPE_SURF_FLIP,
+ VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE,
+ VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION,
+ VBOXVHWACMD_TYPE_SURF_COLORKEY_SET,
+ VBOXVHWACMD_TYPE_QUERY_INFO1,
+ VBOXVHWACMD_TYPE_QUERY_INFO2,
+ VBOXVHWACMD_TYPE_ENABLE,
+ VBOXVHWACMD_TYPE_DISABLE,
+ VBOXVHWACMD_TYPE_HH_CONSTRUCT,
+ VBOXVHWACMD_TYPE_HH_RESET
+#ifdef VBOX_WITH_WDDM
+ , VBOXVHWACMD_TYPE_SURF_GETINFO
+ , VBOXVHWACMD_TYPE_SURF_COLORFILL
+#endif
+ , VBOXVHWACMD_TYPE_HH_DISABLE
+ , VBOXVHWACMD_TYPE_HH_ENABLE
+ , VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEBEGIN
+ , VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEEND
+ , VBOXVHWACMD_TYPE_HH_SAVESTATE_SAVEPERFORM
+ , VBOXVHWACMD_TYPE_HH_SAVESTATE_LOADPERFORM
+} VBOXVHWACMD_TYPE;
+
+/* the command processing was asynch, set by the host to indicate asynch command completion
+ * must not be cleared once set, the command completion is performed by issuing a host->guest completion command
+ * while keeping this flag unchanged */
+#define VBOXVHWACMD_FLAG_HG_ASYNCH 0x00010000
+/* asynch completion is performed by issuing the event */
+#define VBOXVHWACMD_FLAG_GH_ASYNCH_EVENT 0x00000001
+/* issue interrupt on asynch completion */
+#define VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ 0x00000002
+/* guest does not do any op on completion of this command, the host may copy the command and indicate that it does not need the command anymore
+ * by setting the VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED flag */
+#define VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION 0x00000004
+/* the host has copied the VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION command and returned it to the guest */
+#define VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED 0x00020000
+/* this is the host->host cmd, i.e. a configuration command posted by the host to the framebuffer */
+#define VBOXVHWACMD_FLAG_HH_CMD 0x10000000
+
+typedef struct VBOXVHWACMD
+{
+ VBOXVHWACMD_TYPE enmCmd; /* command type */
+ volatile int32_t rc; /* command result */
+ int32_t iDisplay; /* display index */
+ volatile int32_t Flags; /* ored VBOXVHWACMD_FLAG_xxx values */
+ uint64_t GuestVBVAReserved1; /* field internally used by the guest VBVA cmd handling, must NOT be modified by clients */
+ uint64_t GuestVBVAReserved2; /* field internally used by the guest VBVA cmd handling, must NOT be modified by clients */
+ volatile uint32_t cRefs;
+ int32_t Reserved;
+ union
+ {
+ struct VBOXVHWACMD *pNext;
+ uint32_t offNext;
+ uint64_t Data; /* the body is 64-bit aligned */
+ } u;
+ char body[1];
+} VBOXVHWACMD;
+
+#define VBOXVHWACMD_HEADSIZE() (RT_OFFSETOF(VBOXVHWACMD, body))
+#define VBOXVHWACMD_SIZE_FROMBODYSIZE(_s) (VBOXVHWACMD_HEADSIZE() + (_s))
+#define VBOXVHWACMD_SIZE(_tCmd) (VBOXVHWACMD_SIZE_FROMBODYSIZE(sizeof(_tCmd)))
+typedef unsigned int VBOXVHWACMD_LENGTH;
+typedef uint64_t VBOXVHWA_SURFHANDLE;
+#define VBOXVHWA_SURFHANDLE_INVALID 0ULL
+#define VBOXVHWACMD_BODY(_p, _t) ((_t*)(_p)->body)
+#define VBOXVHWACMD_HEAD(_pb) ((VBOXVHWACMD*)((uint8_t *)(_pb) - RT_OFFSETOF(VBOXVHWACMD, body)))
+
+typedef struct VBOXVHWA_RECTL
+{
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+} VBOXVHWA_RECTL;
+
+typedef struct VBOXVHWA_COLORKEY
+{
+ uint32_t low;
+ uint32_t high;
+} VBOXVHWA_COLORKEY;
+
+typedef struct VBOXVHWA_PIXELFORMAT
+{
+ uint32_t flags;
+ uint32_t fourCC;
+ union
+ {
+ uint32_t rgbBitCount;
+ uint32_t yuvBitCount;
+ } c;
+
+ union
+ {
+ uint32_t rgbRBitMask;
+ uint32_t yuvYBitMask;
+ } m1;
+
+ union
+ {
+ uint32_t rgbGBitMask;
+ uint32_t yuvUBitMask;
+ } m2;
+
+ union
+ {
+ uint32_t rgbBBitMask;
+ uint32_t yuvVBitMask;
+ } m3;
+
+ union
+ {
+ uint32_t rgbABitMask;
+ } m4;
+
+ uint32_t Reserved;
+} VBOXVHWA_PIXELFORMAT;
+
+typedef struct VBOXVHWA_SURFACEDESC
+{
+ uint32_t flags;
+ uint32_t height;
+ uint32_t width;
+ uint32_t pitch;
+ uint32_t sizeX;
+ uint32_t sizeY;
+ uint32_t cBackBuffers;
+ uint32_t Reserved;
+ VBOXVHWA_COLORKEY DstOverlayCK;
+ VBOXVHWA_COLORKEY DstBltCK;
+ VBOXVHWA_COLORKEY SrcOverlayCK;
+ VBOXVHWA_COLORKEY SrcBltCK;
+ VBOXVHWA_PIXELFORMAT PixelFormat;
+ uint32_t surfCaps;
+ uint32_t Reserved2;
+ VBOXVHWA_SURFHANDLE hSurf;
+ uint64_t offSurface;
+} VBOXVHWA_SURFACEDESC;
+
+typedef struct VBOXVHWA_BLTFX
+{
+ uint32_t flags;
+ uint32_t rop;
+ uint32_t rotationOp;
+ uint32_t rotation;
+ uint32_t fillColor;
+ uint32_t Reserved;
+ VBOXVHWA_COLORKEY DstCK;
+ VBOXVHWA_COLORKEY SrcCK;
+} VBOXVHWA_BLTFX;
+
+typedef struct VBOXVHWA_OVERLAYFX
+{
+ uint32_t flags;
+ uint32_t Reserved1;
+ uint32_t fxFlags;
+ uint32_t Reserved2;
+ VBOXVHWA_COLORKEY DstCK;
+ VBOXVHWA_COLORKEY SrcCK;
+} VBOXVHWA_OVERLAYFX;
+
+#define VBOXVHWA_CAPS_BLT 0x00000040
+#define VBOXVHWA_CAPS_BLTCOLORFILL 0x04000000
+#define VBOXVHWA_CAPS_BLTFOURCC 0x00000100
+#define VBOXVHWA_CAPS_BLTSTRETCH 0x00000200
+#define VBOXVHWA_CAPS_BLTQUEUE 0x00000080
+
+#define VBOXVHWA_CAPS_OVERLAY 0x00000800
+#define VBOXVHWA_CAPS_OVERLAYFOURCC 0x00002000
+#define VBOXVHWA_CAPS_OVERLAYSTRETCH 0x00004000
+#define VBOXVHWA_CAPS_OVERLAYCANTCLIP 0x00001000
+
+#define VBOXVHWA_CAPS_COLORKEY 0x00400000
+#define VBOXVHWA_CAPS_COLORKEYHWASSIST 0x01000000
+
+#define VBOXVHWA_SCAPS_BACKBUFFER 0x00000004
+#define VBOXVHWA_SCAPS_COMPLEX 0x00000008
+#define VBOXVHWA_SCAPS_FLIP 0x00000010
+#define VBOXVHWA_SCAPS_FRONTBUFFER 0x00000020
+#define VBOXVHWA_SCAPS_OFFSCREENPLAIN 0x00000040
+#define VBOXVHWA_SCAPS_OVERLAY 0x00000080
+#define VBOXVHWA_SCAPS_PRIMARYSURFACE 0x00000200
+#define VBOXVHWA_SCAPS_SYSTEMMEMORY 0x00000800
+#define VBOXVHWA_SCAPS_VIDEOMEMORY 0x00004000
+#define VBOXVHWA_SCAPS_VISIBLE 0x00008000
+#define VBOXVHWA_SCAPS_LOCALVIDMEM 0x10000000
+
+#define VBOXVHWA_PF_PALETTEINDEXED8 0x00000020
+#define VBOXVHWA_PF_RGB 0x00000040
+#define VBOXVHWA_PF_RGBTOYUV 0x00000100
+#define VBOXVHWA_PF_YUV 0x00000200
+#define VBOXVHWA_PF_FOURCC 0x00000004
+
+#define VBOXVHWA_LOCK_DISCARDCONTENTS 0x00002000
+
+#define VBOXVHWA_CFG_ENABLED 0x00000001
+
+#define VBOXVHWA_SD_BACKBUFFERCOUNT 0x00000020
+#define VBOXVHWA_SD_CAPS 0x00000001
+#define VBOXVHWA_SD_CKDESTBLT 0x00004000
+#define VBOXVHWA_SD_CKDESTOVERLAY 0x00002000
+#define VBOXVHWA_SD_CKSRCBLT 0x00010000
+#define VBOXVHWA_SD_CKSRCOVERLAY 0x00008000
+#define VBOXVHWA_SD_HEIGHT 0x00000002
+#define VBOXVHWA_SD_PITCH 0x00000008
+#define VBOXVHWA_SD_PIXELFORMAT 0x00001000
+/*#define VBOXVHWA_SD_REFRESHRATE 0x00040000*/
+#define VBOXVHWA_SD_WIDTH 0x00000004
+
+#define VBOXVHWA_CKEYCAPS_DESTBLT 0x00000001
+#define VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACE 0x00000002
+#define VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004
+#define VBOXVHWA_CKEYCAPS_DESTBLTYUV 0x00000008
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAY 0x00000010
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080
+#define VBOXVHWA_CKEYCAPS_DESTOVERLAYYUV 0x00000100
+#define VBOXVHWA_CKEYCAPS_SRCBLT 0x00000200
+#define VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACE 0x00000400
+#define VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800
+#define VBOXVHWA_CKEYCAPS_SRCBLTYUV 0x00001000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAY 0x00002000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000
+#define VBOXVHWA_CKEYCAPS_SRCOVERLAYYUV 0x00020000
+#define VBOXVHWA_CKEYCAPS_NOCOSTOVERLAY 0x00040000
+
+#define VBOXVHWA_BLT_COLORFILL 0x00000400
+#define VBOXVHWA_BLT_DDFX 0x00000800
+#define VBOXVHWA_BLT_EXTENDED_FLAGS 0x40000000
+#define VBOXVHWA_BLT_EXTENDED_LINEAR_CONTENT 0x00000004
+#define VBOXVHWA_BLT_EXTENDED_PRESENTATION_STRETCHFACTOR 0x00000010
+#define VBOXVHWA_BLT_KEYDESTOVERRIDE 0x00004000
+#define VBOXVHWA_BLT_KEYSRCOVERRIDE 0x00010000
+#define VBOXVHWA_BLT_LAST_PRESENTATION 0x20000000
+#define VBOXVHWA_BLT_PRESENTATION 0x10000000
+#define VBOXVHWA_BLT_ROP 0x00020000
+
+
+#define VBOXVHWA_OVER_DDFX 0x00080000
+#define VBOXVHWA_OVER_HIDE 0x00000200
+#define VBOXVHWA_OVER_KEYDEST 0x00000400
+#define VBOXVHWA_OVER_KEYDESTOVERRIDE 0x00000800
+#define VBOXVHWA_OVER_KEYSRC 0x00001000
+#define VBOXVHWA_OVER_KEYSRCOVERRIDE 0x00002000
+#define VBOXVHWA_OVER_SHOW 0x00004000
+
+#define VBOXVHWA_CKEY_COLORSPACE 0x00000001
+#define VBOXVHWA_CKEY_DESTBLT 0x00000002
+#define VBOXVHWA_CKEY_DESTOVERLAY 0x00000004
+#define VBOXVHWA_CKEY_SRCBLT 0x00000008
+#define VBOXVHWA_CKEY_SRCOVERLAY 0x00000010
+
+#define VBOXVHWA_BLT_ARITHSTRETCHY 0x00000001
+#define VBOXVHWA_BLT_MIRRORLEFTRIGHT 0x00000002
+#define VBOXVHWA_BLT_MIRRORUPDOWN 0x00000004
+
+#define VBOXVHWA_OVERFX_ARITHSTRETCHY 0x00000001
+#define VBOXVHWA_OVERFX_MIRRORLEFTRIGHT 0x00000002
+#define VBOXVHWA_OVERFX_MIRRORUPDOWN 0x00000004
+
+#define VBOXVHWA_CAPS2_CANRENDERWINDOWED 0x00080000
+#define VBOXVHWA_CAPS2_WIDESURFACES 0x00001000
+#define VBOXVHWA_CAPS2_COPYFOURCC 0x00008000
+/*#define VBOXVHWA_CAPS2_FLIPINTERVAL 0x00200000*/
+/*#define VBOXVHWA_CAPS2_FLIPNOVSYNC 0x00400000*/
+
+
+#define VBOXVHWA_OFFSET64_VOID (UINT64_MAX)
+
+typedef struct VBOXVHWA_VERSION
+{
+ uint32_t maj;
+ uint32_t min;
+ uint32_t bld;
+ uint32_t reserved;
+} VBOXVHWA_VERSION;
+
+#define VBOXVHWA_VERSION_INIT(_pv) do { \
+ (_pv)->maj = VBOXVHWA_VERSION_MAJ; \
+ (_pv)->min = VBOXVHWA_VERSION_MIN; \
+ (_pv)->bld = VBOXVHWA_VERSION_BLD; \
+ (_pv)->reserved = VBOXVHWA_VERSION_RSV; \
+ } while(0)
+
+typedef struct VBOXVHWACMD_QUERYINFO1
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_VERSION guestVersion;
+ } in;
+
+ struct
+ {
+ uint32_t cfgFlags;
+ uint32_t caps;
+
+ uint32_t caps2;
+ uint32_t colorKeyCaps;
+
+ uint32_t stretchCaps;
+ uint32_t surfaceCaps;
+
+ uint32_t numOverlays;
+ uint32_t curOverlays;
+
+ uint32_t numFourCC;
+ uint32_t reserved;
+ } out;
+ } u;
+} VBOXVHWACMD_QUERYINFO1;
+
+typedef struct VBOXVHWACMD_QUERYINFO2
+{
+ uint32_t numFourCC;
+ uint32_t FourCC[1];
+} VBOXVHWACMD_QUERYINFO2;
+
+#define VBOXVHWAINFO2_SIZE(_cFourCC) RT_OFFSETOF(VBOXVHWACMD_QUERYINFO2, FourCC[_cFourCC])
+
+typedef struct VBOXVHWACMD_SURF_CANCREATE
+{
+ VBOXVHWA_SURFACEDESC SurfInfo;
+ union
+ {
+ struct
+ {
+ uint32_t bIsDifferentPixelFormat;
+ uint32_t Reserved;
+ } in;
+
+ struct
+ {
+ int32_t ErrInfo;
+ } out;
+ } u;
+} VBOXVHWACMD_SURF_CANCREATE;
+
+typedef struct VBOXVHWACMD_SURF_CREATE
+{
+ VBOXVHWA_SURFACEDESC SurfInfo;
+} VBOXVHWACMD_SURF_CREATE;
+
+#ifdef VBOX_WITH_WDDM
+typedef struct VBOXVHWACMD_SURF_GETINFO
+{
+ VBOXVHWA_SURFACEDESC SurfInfo;
+} VBOXVHWACMD_SURF_GETINFO;
+#endif
+
+typedef struct VBOXVHWACMD_SURF_DESTROY
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hSurf;
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_DESTROY;
+
+typedef struct VBOXVHWACMD_SURF_LOCK
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hSurf;
+ uint64_t offSurface;
+ uint32_t flags;
+ uint32_t rectValid;
+ VBOXVHWA_RECTL rect;
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_LOCK;
+
+typedef struct VBOXVHWACMD_SURF_UNLOCK
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hSurf;
+ uint32_t xUpdatedMemValid;
+ uint32_t reserved;
+ VBOXVHWA_RECTL xUpdatedMemRect;
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_UNLOCK;
+
+typedef struct VBOXVHWACMD_SURF_BLT
+{
+ uint64_t DstGuestSurfInfo;
+ uint64_t SrcGuestSurfInfo;
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hDstSurf;
+ uint64_t offDstSurface;
+ VBOXVHWA_RECTL dstRect;
+ VBOXVHWA_SURFHANDLE hSrcSurf;
+ uint64_t offSrcSurface;
+ VBOXVHWA_RECTL srcRect;
+ uint32_t flags;
+ uint32_t xUpdatedSrcMemValid;
+ VBOXVHWA_BLTFX desc;
+ VBOXVHWA_RECTL xUpdatedSrcMemRect;
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_BLT;
+
+#ifdef VBOX_WITH_WDDM
+typedef struct VBOXVHWACMD_SURF_COLORFILL
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hSurf;
+ uint64_t offSurface;
+ uint32_t u32Reserved;
+ uint32_t cRects;
+ VBOXVHWA_RECTL aRects[1];
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_COLORFILL;
+#endif
+
+typedef struct VBOXVHWACMD_SURF_FLIP
+{
+ uint64_t TargGuestSurfInfo;
+ uint64_t CurrGuestSurfInfo;
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hTargSurf;
+ uint64_t offTargSurface;
+ VBOXVHWA_SURFHANDLE hCurrSurf;
+ uint64_t offCurrSurface;
+ uint32_t flags;
+ uint32_t xUpdatedTargMemValid;
+ VBOXVHWA_RECTL xUpdatedTargMemRect;
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_FLIP;
+
+typedef struct VBOXVHWACMD_SURF_COLORKEY_SET
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hSurf;
+ uint64_t offSurface;
+ VBOXVHWA_COLORKEY CKey;
+ uint32_t flags;
+ uint32_t reserved;
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_COLORKEY_SET;
+
+#define VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_SRCMEMRECT 0x00000001
+#define VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_DSTMEMRECT 0x00000002
+
+typedef struct VBOXVHWACMD_SURF_OVERLAY_UPDATE
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hDstSurf;
+ uint64_t offDstSurface;
+ VBOXVHWA_RECTL dstRect;
+ VBOXVHWA_SURFHANDLE hSrcSurf;
+ uint64_t offSrcSurface;
+ VBOXVHWA_RECTL srcRect;
+ uint32_t flags;
+ uint32_t xFlags;
+ VBOXVHWA_OVERLAYFX desc;
+ VBOXVHWA_RECTL xUpdatedSrcMemRect;
+ VBOXVHWA_RECTL xUpdatedDstMemRect;
+ } in;
+ } u;
+}VBOXVHWACMD_SURF_OVERLAY_UPDATE;
+
+typedef struct VBOXVHWACMD_SURF_OVERLAY_SETPOSITION
+{
+ union
+ {
+ struct
+ {
+ VBOXVHWA_SURFHANDLE hDstSurf;
+ uint64_t offDstSurface;
+ VBOXVHWA_SURFHANDLE hSrcSurf;
+ uint64_t offSrcSurface;
+ uint32_t xPos;
+ uint32_t yPos;
+ uint32_t flags;
+ uint32_t reserved;
+ } in;
+ } u;
+} VBOXVHWACMD_SURF_OVERLAY_SETPOSITION;
+
+typedef struct VBOXVHWACMD_HH_CONSTRUCT
+{
+ void *pVM;
+ /* VRAM info for the backend to be able to properly translate VRAM offsets */
+ void *pvVRAM;
+ uint32_t cbVRAM;
+} VBOXVHWACMD_HH_CONSTRUCT;
+
+typedef struct VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM
+{
+ struct SSMHANDLE * pSSM;
+} VBOXVHWACMD_HH_SAVESTATE_SAVEPERFORM;
+
+typedef struct VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM
+{
+ struct SSMHANDLE * pSSM;
+} VBOXVHWACMD_HH_SAVESTATE_LOADPERFORM;
+
+typedef DECLCALLBACK(void) FNVBOXVHWA_HH_CALLBACK(void*);
+typedef FNVBOXVHWA_HH_CALLBACK *PFNVBOXVHWA_HH_CALLBACK;
+
+#define VBOXVHWA_HH_CALLBACK_SET(_pCmd, _pfn, _parg) \
+ do { \
+ (_pCmd)->GuestVBVAReserved1 = (uint64_t)(uintptr_t)(_pfn); \
+ (_pCmd)->GuestVBVAReserved2 = (uint64_t)(uintptr_t)(_parg); \
+ }while(0)
+
+#define VBOXVHWA_HH_CALLBACK_GET(_pCmd) ((PFNVBOXVHWA_HH_CALLBACK)(_pCmd)->GuestVBVAReserved1)
+#define VBOXVHWA_HH_CALLBACK_GET_ARG(_pCmd) ((void*)(_pCmd)->GuestVBVAReserved2)
+
+#pragma pack()
+#endif /* #ifdef VBOX_WITH_VIDEOHWACCEL */
+
+/* All structures are without alignment. */
+#pragma pack(1)
+
+typedef struct VBVAHOSTFLAGS
+{
+ uint32_t u32HostEvents;
+ uint32_t u32SupportedOrders;
+} VBVAHOSTFLAGS;
+
+typedef struct VBVABUFFER
+{
+ VBVAHOSTFLAGS hostFlags;
+
+ /* The offset where the data start in the buffer. */
+ uint32_t off32Data;
+ /* The offset where next data must be placed in the buffer. */
+ uint32_t off32Free;
+
+ /* The queue of record descriptions. */
+ VBVARECORD aRecords[VBVA_MAX_RECORDS];
+ uint32_t indexRecordFirst;
+ uint32_t indexRecordFree;
+
+ /* Space to leave free in the buffer when large partial records are transferred. */
+ uint32_t cbPartialWriteThreshold;
+
+ uint32_t cbData;
+ uint8_t au8Data[1]; /* variable size for the rest of the VBVABUFFER area in VRAM. */
+} VBVABUFFER;
+
+/* guest->host commands */
+#define VBVA_QUERY_CONF32 1
+#define VBVA_SET_CONF32 2
+#define VBVA_INFO_VIEW 3
+#define VBVA_INFO_HEAP 4
+#define VBVA_FLUSH 5
+#define VBVA_INFO_SCREEN 6
+#define VBVA_ENABLE 7
+#define VBVA_MOUSE_POINTER_SHAPE 8
+#ifdef VBOX_WITH_VIDEOHWACCEL
+# define VBVA_VHWA_CMD 9
+#endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+#ifdef VBOX_WITH_VDMA
+# define VBVA_VDMA_CTL 10 /* setup G<->H DMA channel info */
+# define VBVA_VDMA_CMD 11 /* G->H DMA command */
+#endif
+#define VBVA_INFO_CAPS 12 /* informs host about HGSMI caps. see VBVACAPS below */
+#define VBVA_SCANLINE_CFG 13 /* configures scanline, see VBVASCANLINECFG below */
+#define VBVA_SCANLINE_INFO 14 /* requests scanline info, see VBVASCANLINEINFO below */
+
+/* host->guest commands */
+#define VBVAHG_EVENT 1
+#define VBVAHG_DISPLAY_CUSTOM 2
+#ifdef VBOX_WITH_VDMA
+#define VBVAHG_SHGSMI_COMPLETION 3
+#endif
+
+#ifdef VBOX_WITH_VIDEOHWACCEL
+#define VBVAHG_DCUSTOM_VHWA_CMDCOMPLETE 1
+#pragma pack(1)
+typedef struct VBVAHOSTCMDVHWACMDCOMPLETE
+{
+ uint32_t offCmd;
+}VBVAHOSTCMDVHWACMDCOMPLETE;
+#pragma pack()
+#endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */
+
+#pragma pack(1)
+typedef enum
+{
+ VBVAHOSTCMD_OP_EVENT = 1,
+ VBVAHOSTCMD_OP_CUSTOM
+}VBVAHOSTCMD_OP_TYPE;
+
+typedef struct VBVAHOSTCMDEVENT
+{
+ uint64_t pEvent;
+}VBVAHOSTCMDEVENT;
+
+
+typedef struct VBVAHOSTCMD
+{
+ /* destination ID if >=0 specifies display index, otherwize the command is directed to the miniport */
+ int32_t iDstID;
+ int32_t customOpCode;
+ union
+ {
+ struct VBVAHOSTCMD *pNext;
+ uint32_t offNext;
+ uint64_t Data; /* the body is 64-bit aligned */
+ } u;
+ char body[1];
+}VBVAHOSTCMD;
+
+#define VBVAHOSTCMD_SIZE(_size) (sizeof(VBVAHOSTCMD) + (_size))
+#define VBVAHOSTCMD_BODY(_pCmd, _tBody) ((_tBody*)(_pCmd)->body)
+#define VBVAHOSTCMD_HDR(_pBody) ((VBVAHOSTCMD*)(((uint8_t*)_pBody) - RT_OFFSETOF(VBVAHOSTCMD, body)))
+#define VBVAHOSTCMD_HDRSIZE (RT_OFFSETOF(VBVAHOSTCMD, body))
+
+#pragma pack()
+
+/* VBVACONF32::u32Index */
+#define VBOX_VBVA_CONF32_MONITOR_COUNT 0
+#define VBOX_VBVA_CONF32_HOST_HEAP_SIZE 1
+
+typedef struct VBVACONF32
+{
+ uint32_t u32Index;
+ uint32_t u32Value;
+} VBVACONF32;
+
+typedef struct VBVAINFOVIEW
+{
+ /* Index of the screen, assigned by the guest. */
+ uint32_t u32ViewIndex;
+
+ /* The screen offset in VRAM, the framebuffer starts here. */
+ uint32_t u32ViewOffset;
+
+ /* The size of the VRAM memory that can be used for the view. */
+ uint32_t u32ViewSize;
+
+ /* The recommended maximum size of the VRAM memory for the screen. */
+ uint32_t u32MaxScreenSize;
+} VBVAINFOVIEW;
+
+typedef struct VBVAINFOHEAP
+{
+ /* Absolute offset in VRAM of the start of the heap. */
+ uint32_t u32HeapOffset;
+
+ /* The size of the heap. */
+ uint32_t u32HeapSize;
+
+} VBVAINFOHEAP;
+
+typedef struct VBVAFLUSH
+{
+ uint32_t u32Reserved;
+
+} VBVAFLUSH;
+
+/* VBVAINFOSCREEN::u8Flags */
+#define VBVA_SCREEN_F_NONE 0x0000
+#define VBVA_SCREEN_F_ACTIVE 0x0001
+/** The virtual monitor has been disabled by the guest and should be blacked
+ * out by the host and ignored for purposes of pointer position calculation. */
+#define VBVA_SCREEN_F_DISABLED 0x0002
+
+typedef struct VBVAINFOSCREEN
+{
+ /* Which view contains the screen. */
+ uint32_t u32ViewIndex;
+
+ /* Physical X origin relative to the primary screen. */
+ int32_t i32OriginX;
+
+ /* Physical Y origin relative to the primary screen. */
+ int32_t i32OriginY;
+
+ /* Offset of visible framebuffer relative to the framebuffer start. */
+ uint32_t u32StartOffset;
+
+ /* The scan line size in bytes. */
+ uint32_t u32LineSize;
+
+ /* Width of the screen. */
+ uint32_t u32Width;
+
+ /* Height of the screen. */
+ uint32_t u32Height;
+
+ /* Color depth. */
+ uint16_t u16BitsPerPixel;
+
+ /* VBVA_SCREEN_F_* */
+ uint16_t u16Flags;
+} VBVAINFOSCREEN;
+
+
+/* VBVAENABLE::u32Flags */
+#define VBVA_F_NONE 0x00000000
+#define VBVA_F_ENABLE 0x00000001
+#define VBVA_F_DISABLE 0x00000002
+/* extended VBVA to be used with WDDM */
+#define VBVA_F_EXTENDED 0x00000004
+/* vbva offset is absolute VRAM offset */
+#define VBVA_F_ABSOFFSET 0x00000008
+
+typedef struct VBVAENABLE
+{
+ uint32_t u32Flags;
+ uint32_t u32Offset;
+ int32_t i32Result;
+} VBVAENABLE;
+
+typedef struct VBVAENABLE_EX
+{
+ VBVAENABLE Base;
+ uint32_t u32ScreenId;
+} VBVAENABLE_EX;
+
+
+typedef struct VBVAMOUSEPOINTERSHAPE
+{
+ /* The host result. */
+ int32_t i32Result;
+
+ /* VBOX_MOUSE_POINTER_* bit flags. */
+ uint32_t fu32Flags;
+
+ /* X coordinate of the hot spot. */
+ uint32_t u32HotX;
+
+ /* Y coordinate of the hot spot. */
+ uint32_t u32HotY;
+
+ /* Width of the pointer in pixels. */
+ uint32_t u32Width;
+
+ /* Height of the pointer in scanlines. */
+ uint32_t u32Height;
+
+ /* Pointer data.
+ *
+ ****
+ * The data consists of 1 bpp AND mask followed by 32 bpp XOR (color) mask.
+ *
+ * For pointers without alpha channel the XOR mask pixels are 32 bit values: (lsb)BGR0(msb).
+ * For pointers with alpha channel the XOR mask consists of (lsb)BGRA(msb) 32 bit values.
+ *
+ * Guest driver must create the AND mask for pointers with alpha channel, so if host does not
+ * support alpha, the pointer could be displayed as a normal color pointer. The AND mask can
+ * be constructed from alpha values. For example alpha value >= 0xf0 means bit 0 in the AND mask.
+ *
+ * The AND mask is 1 bpp bitmap with byte aligned scanlines. Size of AND mask,
+ * therefore, is cbAnd = (width + 7) / 8 * height. The padding bits at the
+ * end of any scanline are undefined.
+ *
+ * The XOR mask follows the AND mask on the next 4 bytes aligned offset:
+ * uint8_t *pXor = pAnd + (cbAnd + 3) & ~3
+ * Bytes in the gap between the AND and the XOR mask are undefined.
+ * XOR mask scanlines have no gap between them and size of XOR mask is:
+ * cXor = width * 4 * height.
+ ****
+ *
+ * Preallocate 4 bytes for accessing actual data as p->au8Data.
+ */
+ uint8_t au8Data[4];
+
+} VBVAMOUSEPOINTERSHAPE;
+
+/* the guest driver can handle asynch guest cmd completion by reading the command offset from io port */
+#define VBVACAPS_COMPLETEGCMD_BY_IOREAD 0x00000001
+/* the guest driver can handle video adapter IRQs */
+#define VBVACAPS_IRQ 0x00000002
+typedef struct VBVACAPS
+{
+ int32_t rc;
+ uint32_t fCaps;
+} VBVACAPS;
+
+/* makes graphics device generate IRQ on VSYNC */
+#define VBVASCANLINECFG_ENABLE_VSYNC_IRQ 0x00000001
+/* guest driver may request the current scanline */
+#define VBVASCANLINECFG_ENABLE_SCANLINE_INFO 0x00000002
+/* request the current refresh period, returned in u32RefreshPeriodMs */
+#define VBVASCANLINECFG_QUERY_REFRESH_PERIOD 0x00000004
+/* set new refresh period specified in u32RefreshPeriodMs.
+ * if used with VBVASCANLINECFG_QUERY_REFRESH_PERIOD,
+ * u32RefreshPeriodMs is set to the previous refresh period on return */
+#define VBVASCANLINECFG_SET_REFRESH_PERIOD 0x00000008
+
+typedef struct VBVASCANLINECFG
+{
+ int32_t rc;
+ uint32_t fFlags;
+ uint32_t u32RefreshPeriodMs;
+ uint32_t u32Reserved;
+} VBVASCANLINECFG;
+
+typedef struct VBVASCANLINEINFO
+{
+ int32_t rc;
+ uint32_t u32ScreenId;
+ uint32_t u32InVBlank;
+ uint32_t u32ScanLine;
+} VBVASCANLINEINFO;
+
+#pragma pack()
+
+typedef uint64_t VBOXVIDEOOFFSET;
+
+#define VBOXVIDEOOFFSET_VOID ((VBOXVIDEOOFFSET)~0)
+
+#pragma pack(1)
+
+/*
+ * VBOXSHGSMI made on top HGSMI and allows receiving notifications
+ * about G->H command completion
+ */
+/* SHGSMI command header */
+typedef struct VBOXSHGSMIHEADER
+{
+ uint64_t pvNext; /*<- completion processing queue */
+ uint32_t fFlags; /*<- see VBOXSHGSMI_FLAG_XXX Flags */
+ uint32_t cRefs; /*<- command referece count */
+ uint64_t u64Info1; /*<- contents depends on the fFlags value */
+ uint64_t u64Info2; /*<- contents depends on the fFlags value */
+} VBOXSHGSMIHEADER, *PVBOXSHGSMIHEADER;
+
+typedef enum
+{
+ VBOXVDMACMD_TYPE_UNDEFINED = 0,
+ VBOXVDMACMD_TYPE_DMA_PRESENT_BLT = 1,
+ VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER,
+ VBOXVDMACMD_TYPE_DMA_BPB_FILL,
+ VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY,
+ VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL,
+ VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP,
+ VBOXVDMACMD_TYPE_DMA_NOP,
+ VBOXVDMACMD_TYPE_CHROMIUM_CMD, /* chromium cmd */
+ VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER_VRAMSYS,
+ VBOXVDMACMD_TYPE_CHILD_STATUS_IRQ /* make the device notify child (monitor) state change IRQ */
+} VBOXVDMACMD_TYPE;
+
+#pragma pack()
+
+/* the command processing was asynch, set by the host to indicate asynch command completion
+ * must not be cleared once set, the command completion is performed by issuing a host->guest completion command
+ * while keeping this flag unchanged */
+#define VBOXSHGSMI_FLAG_HG_ASYNCH 0x00010000
+#if 0
+/* if set - asynch completion is performed by issuing the event,
+ * if cleared - asynch completion is performed by calling a callback */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_EVENT 0x00000001
+#endif
+/* issue interrupt on asynch completion, used for critical G->H commands,
+ * i.e. for completion of which guest is waiting. */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ 0x00000002
+/* guest does not do any op on completion of this command,
+ * the host may copy the command and indicate that it does not need the command anymore
+ * by not setting VBOXSHGSMI_FLAG_HG_ASYNCH */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_NOCOMPLETION 0x00000004
+/* guest requires the command to be processed asynchronously,
+ * not setting VBOXSHGSMI_FLAG_HG_ASYNCH by the host in this case is treated as command failure */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_FORCE 0x00000008
+/* force IRQ on cmd completion */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ_FORCE 0x00000010
+/* an IRQ-level callback is associated with the command */
+#define VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ 0x00000020
+/* guest expects this command to be completed synchronously */
+#define VBOXSHGSMI_FLAG_GH_SYNCH 0x00000040
+
+
+DECLINLINE(uint8_t *) VBoxSHGSMIBufferData (const VBOXSHGSMIHEADER* pHeader)
+{
+ return (uint8_t *)pHeader + sizeof (VBOXSHGSMIHEADER);
+}
+
+#define VBoxSHGSMIBufferHeaderSize() (sizeof (VBOXSHGSMIHEADER))
+
+DECLINLINE(PVBOXSHGSMIHEADER) VBoxSHGSMIBufferHeader (const void *pvData)
+{
+ return (PVBOXSHGSMIHEADER)((uint8_t *)pvData - sizeof (VBOXSHGSMIHEADER));
+}
+
+#ifdef VBOX_WITH_VDMA
+# pragma pack(1)
+
+/* VDMA - Video DMA */
+
+/* VDMA Control API */
+/* VBOXVDMA_CTL::u32Flags */
+typedef enum
+{
+ VBOXVDMA_CTL_TYPE_NONE = 0,
+ VBOXVDMA_CTL_TYPE_ENABLE,
+ VBOXVDMA_CTL_TYPE_DISABLE,
+ VBOXVDMA_CTL_TYPE_FLUSH,
+ VBOXVDMA_CTL_TYPE_WATCHDOG
+} VBOXVDMA_CTL_TYPE;
+
+typedef struct VBOXVDMA_CTL
+{
+ VBOXVDMA_CTL_TYPE enmCtl;
+ uint32_t u32Offset;
+ int32_t i32Result;
+} VBOXVDMA_CTL, *PVBOXVDMA_CTL;
+
+typedef struct VBOXVDMA_RECTL
+{
+ int16_t left;
+ int16_t top;
+ uint16_t width;
+ uint16_t height;
+} VBOXVDMA_RECTL, *PVBOXVDMA_RECTL;
+
+typedef enum
+{
+ VBOXVDMA_PIXEL_FORMAT_UNKNOWN = 0,
+ VBOXVDMA_PIXEL_FORMAT_R8G8B8 = 20,
+ VBOXVDMA_PIXEL_FORMAT_A8R8G8B8 = 21,
+ VBOXVDMA_PIXEL_FORMAT_X8R8G8B8 = 22,
+ VBOXVDMA_PIXEL_FORMAT_R5G6B5 = 23,
+ VBOXVDMA_PIXEL_FORMAT_X1R5G5B5 = 24,
+ VBOXVDMA_PIXEL_FORMAT_A1R5G5B5 = 25,
+ VBOXVDMA_PIXEL_FORMAT_A4R4G4B4 = 26,
+ VBOXVDMA_PIXEL_FORMAT_R3G3B2 = 27,
+ VBOXVDMA_PIXEL_FORMAT_A8 = 28,
+ VBOXVDMA_PIXEL_FORMAT_A8R3G3B2 = 29,
+ VBOXVDMA_PIXEL_FORMAT_X4R4G4B4 = 30,
+ VBOXVDMA_PIXEL_FORMAT_A2B10G10R10 = 31,
+ VBOXVDMA_PIXEL_FORMAT_A8B8G8R8 = 32,
+ VBOXVDMA_PIXEL_FORMAT_X8B8G8R8 = 33,
+ VBOXVDMA_PIXEL_FORMAT_G16R16 = 34,
+ VBOXVDMA_PIXEL_FORMAT_A2R10G10B10 = 35,
+ VBOXVDMA_PIXEL_FORMAT_A16B16G16R16 = 36,
+ VBOXVDMA_PIXEL_FORMAT_A8P8 = 40,
+ VBOXVDMA_PIXEL_FORMAT_P8 = 41,
+ VBOXVDMA_PIXEL_FORMAT_L8 = 50,
+ VBOXVDMA_PIXEL_FORMAT_A8L8 = 51,
+ VBOXVDMA_PIXEL_FORMAT_A4L4 = 52,
+ VBOXVDMA_PIXEL_FORMAT_V8U8 = 60,
+ VBOXVDMA_PIXEL_FORMAT_L6V5U5 = 61,
+ VBOXVDMA_PIXEL_FORMAT_X8L8V8U8 = 62,
+ VBOXVDMA_PIXEL_FORMAT_Q8W8V8U8 = 63,
+ VBOXVDMA_PIXEL_FORMAT_V16U16 = 64,
+ VBOXVDMA_PIXEL_FORMAT_W11V11U10 = 65,
+ VBOXVDMA_PIXEL_FORMAT_A2W10V10U10 = 67
+} VBOXVDMA_PIXEL_FORMAT;
+
+typedef struct VBOXVDMA_SURF_DESC
+{
+ uint32_t width;
+ uint32_t height;
+ VBOXVDMA_PIXEL_FORMAT format;
+ uint32_t bpp;
+ uint32_t pitch;
+ uint32_t fFlags;
+} VBOXVDMA_SURF_DESC, *PVBOXVDMA_SURF_DESC;
+
+/*typedef uint64_t VBOXVDMAPHADDRESS;*/
+typedef uint64_t VBOXVDMASURFHANDLE;
+
+/* region specified as a rectangle, otherwize it is a size of memory pointed to by phys address */
+#define VBOXVDMAOPERAND_FLAGS_RECTL 0x1
+/* Surface handle is valid */
+#define VBOXVDMAOPERAND_FLAGS_PRIMARY 0x2
+/* address is offset in VRAM */
+#define VBOXVDMAOPERAND_FLAGS_VRAMOFFSET 0x4
+
+
+/* VBOXVDMACBUF_DR::phBuf specifies offset in VRAM */
+#define VBOXVDMACBUF_FLAG_BUF_VRAM_OFFSET 0x00000001
+/* command buffer follows the VBOXVDMACBUF_DR in VRAM, VBOXVDMACBUF_DR::phBuf is ignored */
+#define VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR 0x00000002
+
+/*
+ * We can not submit the DMA command via VRAM since we do not have control over
+ * DMA command buffer [de]allocation, i.e. we only control the buffer contents.
+ * In other words the system may call one of our callbacks to fill a command buffer
+ * with the necessary commands and then discard the buffer w/o any notification.
+ *
+ * We have only DMA command buffer physical address at submission time.
+ *
+ * so the only way is to */
+typedef struct VBOXVDMACBUF_DR
+{
+ uint16_t fFlags;
+ uint16_t cbBuf;
+ /* RT_SUCCESS() - on success
+ * VERR_INTERRUPTED - on preemption
+ * VERR_xxx - on error */
+ int32_t rc;
+ union
+ {
+ uint64_t phBuf;
+ VBOXVIDEOOFFSET offVramBuf;
+ } Location;
+ uint64_t aGuestData[7];
+} VBOXVDMACBUF_DR, *PVBOXVDMACBUF_DR;
+
+#define VBOXVDMACBUF_DR_TAIL(_pCmd, _t) ( (_t*)(((uint8_t*)(_pCmd)) + sizeof (VBOXVDMACBUF_DR)) )
+#define VBOXVDMACBUF_DR_FROM_TAIL(_pCmd) ( (VBOXVDMACBUF_DR*)(((uint8_t*)(_pCmd)) - sizeof (VBOXVDMACBUF_DR)) )
+
+typedef struct VBOXVDMACMD
+{
+ VBOXVDMACMD_TYPE enmType;
+ uint32_t u32CmdSpecific;
+} VBOXVDMACMD, *PVBOXVDMACMD;
+
+#define VBOXVDMACMD_HEADER_SIZE() sizeof (VBOXVDMACMD)
+#define VBOXVDMACMD_SIZE_FROMBODYSIZE(_s) (VBOXVDMACMD_HEADER_SIZE() + (_s))
+#define VBOXVDMACMD_SIZE(_t) (VBOXVDMACMD_SIZE_FROMBODYSIZE(sizeof (_t)))
+#define VBOXVDMACMD_BODY(_pCmd, _t) ( (_t*)(((uint8_t*)(_pCmd)) + VBOXVDMACMD_HEADER_SIZE()) )
+#define VBOXVDMACMD_BODY_SIZE(_s) ( (_s) - VBOXVDMACMD_HEADER_SIZE() )
+#define VBOXVDMACMD_FROM_BODY(_pCmd) ( (VBOXVDMACMD*)(((uint8_t*)(_pCmd)) - VBOXVDMACMD_HEADER_SIZE()) )
+#define VBOXVDMACMD_BODY_FIELD_OFFSET(_ot, _t, _f) ( (_ot)(uintptr_t)( VBOXVDMACMD_BODY(0, uint8_t) + RT_OFFSETOF(_t, _f) ) )
+
+typedef struct VBOXVDMACMD_DMA_PRESENT_BLT
+{
+ VBOXVIDEOOFFSET offSrc;
+ VBOXVIDEOOFFSET offDst;
+ VBOXVDMA_SURF_DESC srcDesc;
+ VBOXVDMA_SURF_DESC dstDesc;
+ VBOXVDMA_RECTL srcRectl;
+ VBOXVDMA_RECTL dstRectl;
+ uint32_t u32Reserved;
+ uint32_t cDstSubRects;
+ VBOXVDMA_RECTL aDstSubRects[1];
+} VBOXVDMACMD_DMA_PRESENT_BLT, *PVBOXVDMACMD_DMA_PRESENT_BLT;
+
+typedef struct VBOXVDMACMD_DMA_PRESENT_SHADOW2PRIMARY
+{
+ VBOXVDMA_RECTL Rect;
+} VBOXVDMACMD_DMA_PRESENT_SHADOW2PRIMARY, *PVBOXVDMACMD_DMA_PRESENT_SHADOW2PRIMARY;
+
+
+#define VBOXVDMACMD_DMA_BPB_TRANSFER_F_SRC_VRAMOFFSET 0x00000001
+#define VBOXVDMACMD_DMA_BPB_TRANSFER_F_DST_VRAMOFFSET 0x00000002
+
+typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER
+{
+ uint32_t cbTransferSize;
+ uint32_t fFlags;
+ union
+ {
+ uint64_t phBuf;
+ VBOXVIDEOOFFSET offVramBuf;
+ } Src;
+ union
+ {
+ uint64_t phBuf;
+ VBOXVIDEOOFFSET offVramBuf;
+ } Dst;
+} VBOXVDMACMD_DMA_BPB_TRANSFER, *PVBOXVDMACMD_DMA_BPB_TRANSFER;
+
+#define VBOXVDMACMD_SYSMEMEL_F_PAGELIST 0x00000001
+
+typedef struct VBOXVDMACMD_SYSMEMEL
+{
+ uint32_t cPages;
+ uint32_t fFlags;
+ uint64_t phBuf[1];
+} VBOXVDMACMD_SYSMEMEL, *PVBOXVDMACMD_SYSMEMEL;
+
+#define VBOXVDMACMD_SYSMEMEL_NEXT(_pEl) (((_pEl)->fFlags & VBOXVDMACMD_SYSMEMEL_F_PAGELIST) ? \
+ ((PVBOXVDMACMD_SYSMEMEL)(((uint8_t*)(_pEl))+RT_OFFSETOF(VBOXVDMACMD_SYSMEMEL, phBuf[(_pEl)->cPages]))) \
+ : \
+ ((_pEl)+1)
+
+#define VBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS_SYS2VRAM 0x00000001
+
+typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS
+{
+ uint32_t cTransferPages;
+ uint32_t fFlags;
+ VBOXVIDEOOFFSET offVramBuf;
+ VBOXVDMACMD_SYSMEMEL FirstEl;
+} VBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS, *PVBOXVDMACMD_DMA_BPB_TRANSFER_VRAMSYS;
+
+typedef struct VBOXVDMACMD_DMA_BPB_FILL
+{
+ VBOXVIDEOOFFSET offSurf;
+ uint32_t cbFillSize;
+ uint32_t u32FillPattern;
+} VBOXVDMACMD_DMA_BPB_FILL, *PVBOXVDMACMD_DMA_BPB_FILL;
+
+#define VBOXVDMA_CHILD_STATUS_F_CONNECTED 0x01
+#define VBOXVDMA_CHILD_STATUS_F_DISCONNECTED 0x02
+#define VBOXVDMA_CHILD_STATUS_F_ROTATED 0x04
+
+typedef struct VBOXVDMA_CHILD_STATUS
+{
+ uint32_t iChild;
+ uint8_t fFlags;
+ uint8_t u8RotationAngle;
+ uint16_t u16Reserved;
+} VBOXVDMA_CHILD_STATUS, *PVBOXVDMA_CHILD_STATUS;
+
+/* apply the aInfos are applied to all targets, the iTarget is ignored */
+#define VBOXVDMACMD_CHILD_STATUS_IRQ_F_APPLY_TO_ALL 0x00000001
+
+typedef struct VBOXVDMACMD_CHILD_STATUS_IRQ
+{
+ uint32_t cInfos;
+ uint32_t fFlags;
+ VBOXVDMA_CHILD_STATUS aInfos[1];
+} VBOXVDMACMD_CHILD_STATUS_IRQ, *PVBOXVDMACMD_CHILD_STATUS_IRQ;
+
+# pragma pack()
+#endif /* #ifdef VBOX_WITH_VDMA */
+
+#ifdef VBOX_WITH_CRHGSMI
+# pragma pack(1)
+typedef struct VBOXVDMACMD_CHROMIUM_BUFFER
+{
+ VBOXVIDEOOFFSET offBuffer;
+ uint32_t cbBuffer;
+ uint32_t u32GuestData;
+ uint64_t u64GuestData;
+} VBOXVDMACMD_CHROMIUM_BUFFER, *PVBOXVDMACMD_CHROMIUM_BUFFER;
+
+typedef struct VBOXVDMACMD_CHROMIUM_CMD
+{
+ uint32_t cBuffers;
+ uint32_t u32Reserved;
+ VBOXVDMACMD_CHROMIUM_BUFFER aBuffers[1];
+} VBOXVDMACMD_CHROMIUM_CMD, *PVBOXVDMACMD_CHROMIUM_CMD;
+
+typedef enum
+{
+ VBOXVDMACMD_CHROMIUM_CTL_TYPE_UNKNOWN = 0,
+ VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP,
+ VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_BEGIN,
+ VBOXVDMACMD_CHROMIUM_CTL_TYPE_SAVESTATE_END,
+ VBOXVDMACMD_CHROMIUM_CTL_TYPE_CRHGSMI_SETUP_COMPLETION,
+ VBOXVDMACMD_CHROMIUM_CTL_TYPE_SIZEHACK = 0xfffffffe
+} VBOXVDMACMD_CHROMIUM_CTL_TYPE;
+
+typedef struct VBOXVDMACMD_CHROMIUM_CTL
+{
+ VBOXVDMACMD_CHROMIUM_CTL_TYPE enmType;
+ uint32_t cbCmd;
+} VBOXVDMACMD_CHROMIUM_CTL, *PVBOXVDMACMD_CHROMIUM_CTL;
+
+typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP
+{
+ VBOXVDMACMD_CHROMIUM_CTL Hdr;
+ union
+ {
+ void *pvVRamBase;
+ uint64_t uAlignment;
+ };
+ uint64_t cbVRam;
+} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP;
+
+typedef struct PDMIDISPLAYVBVACALLBACKS *HCRHGSMICMDCOMPLETION;
+typedef DECLCALLBACK(int) FNCRHGSMICMDCOMPLETION(HCRHGSMICMDCOMPLETION hCompletion, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc);
+typedef FNCRHGSMICMDCOMPLETION *PFNCRHGSMICMDCOMPLETION;
+
+typedef struct VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION
+{
+ VBOXVDMACMD_CHROMIUM_CTL Hdr;
+ HCRHGSMICMDCOMPLETION hCompletion;
+ PFNCRHGSMICMDCOMPLETION pfnCompletion;
+} VBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION, *PVBOXVDMACMD_CHROMIUM_CTL_CRHGSMI_SETUP_COMPLETION;
+# pragma pack()
+#endif
+
+#ifdef VBOXVDMA_WITH_VBVA
+# pragma pack(1)
+
+typedef struct VBOXVDMAVBVACMD
+{
+ HGSMIOFFSET offCmd;
+} VBOXVDMAVBVACMD;
+
+#pragma pack()
+#endif
+
+#endif
diff --git a/include/VBox/VBoxVideo3D.h b/include/VBox/VBoxVideo3D.h
new file mode 100644
index 00000000..91c6e306
--- /dev/null
+++ b/include/VBox/VBoxVideo3D.h
@@ -0,0 +1,136 @@
+/** @file
+ *
+ * VirtualBox 3D common tooling
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VBoxVideo3D_h
+#define ___VBox_VBoxVideo3D_h
+
+#include <iprt/cdefs.h>
+#include <iprt/asm.h>
+#ifndef VBoxTlsRefGetImpl
+# ifdef VBoxTlsRefSetImpl
+# error "VBoxTlsRefSetImpl is defined, unexpected!"
+# endif
+# include <iprt/thread.h>
+# define VBoxTlsRefGetImpl(_tls) (RTTlsGet((RTTLS)(_tls)))
+# define VBoxTlsRefSetImpl(_tls, _val) (RTTlsSet((RTTLS)(_tls), (_val)))
+#else
+# ifndef VBoxTlsRefSetImpl
+# error "VBoxTlsRefSetImpl is NOT defined, unexpected!"
+# endif
+#endif
+
+#ifndef VBoxTlsRefAssertImpl
+# define VBoxTlsRefAssertImpl(_a) do {} while (0)
+#endif
+
+typedef DECLCALLBACK(void) FNVBOXTLSREFDTOR(void*);
+typedef FNVBOXTLSREFDTOR *PFNVBOXTLSREFDTOR;
+
+typedef enum {
+ VBOXTLSREFDATA_STATE_UNDEFINED = 0,
+ VBOXTLSREFDATA_STATE_INITIALIZED,
+ VBOXTLSREFDATA_STATE_TOBE_DESTROYED,
+ VBOXTLSREFDATA_STATE_DESTROYING,
+ VBOXTLSREFDATA_STATE_32BIT_HACK = 0x7fffffff
+} VBOXTLSREFDATA_STATE;
+
+#define VBOXTLSREFDATA \
+ volatile int32_t cTlsRefs; \
+ VBOXTLSREFDATA_STATE enmTlsRefState; \
+ PFNVBOXTLSREFDTOR pfnTlsRefDtor; \
+
+struct VBOXTLSREFDATA_DUMMY
+{
+ VBOXTLSREFDATA
+};
+
+#define VBOXTLSREFDATA_OFFSET(_t) RT_OFFSETOF(_t, cTlsRefs)
+#define VBOXTLSREFDATA_SIZE() (sizeof (struct VBOXTLSREFDATA_DUMMY))
+#define VBOXTLSREFDATA_COPY(_pDst, _pSrc) do { \
+ (_pDst)->cTlsRefs = (_pSrc)->cTlsRefs; \
+ (_pDst)->enmTlsRefState = (_pSrc)->enmTlsRefState; \
+ (_pDst)->pfnTlsRefDtor = (_pSrc)->pfnTlsRefDtor; \
+ } while (0)
+
+#define VBOXTLSREFDATA_EQUAL(_pDst, _pSrc) ( \
+ (_pDst)->cTlsRefs == (_pSrc)->cTlsRefs \
+ && (_pDst)->enmTlsRefState == (_pSrc)->enmTlsRefState \
+ && (_pDst)->pfnTlsRefDtor == (_pSrc)->pfnTlsRefDtor \
+ )
+
+
+#define VBoxTlsRefInit(_p, _pfnDtor) do { \
+ (_p)->cTlsRefs = 1; \
+ (_p)->enmTlsRefState = VBOXTLSREFDATA_STATE_INITIALIZED; \
+ (_p)->pfnTlsRefDtor = (_pfnDtor); \
+ } while (0)
+
+#define VBoxTlsRefIsFunctional(_p) (!!((_p)->enmTlsRefState == VBOXTLSREFDATA_STATE_INITIALIZED))
+
+#define VBoxTlsRefAddRef(_p) do { \
+ int cRefs = ASMAtomicIncS32(&(_p)->cTlsRefs); \
+ VBoxTlsRefAssertImpl(cRefs > 1 || (_p)->enmTlsRefState == VBOXTLSREFDATA_STATE_DESTROYING); \
+ } while (0)
+
+#define VBoxTlsRefRelease(_p) do { \
+ int cRefs = ASMAtomicDecS32(&(_p)->cTlsRefs); \
+ VBoxTlsRefAssertImpl(cRefs >= 0); \
+ if (!cRefs && (_p)->enmTlsRefState != VBOXTLSREFDATA_STATE_DESTROYING /* <- avoid recursion if VBoxTlsRefAddRef/Release is called from dtor */) { \
+ (_p)->enmTlsRefState = VBOXTLSREFDATA_STATE_DESTROYING; \
+ (_p)->pfnTlsRefDtor((_p)); \
+ } \
+ } while (0)
+
+#define VBoxTlsRefMarkDestroy(_p) do { \
+ (_p)->enmTlsRefState = VBOXTLSREFDATA_STATE_TOBE_DESTROYED; \
+ } while (0)
+
+#define VBoxTlsRefGetCurrent(_t, _Tsd) ((_t*) VBoxTlsRefGetImpl((_Tsd)))
+
+#define VBoxTlsRefGetCurrentFunctional(_val, _t, _Tsd) do { \
+ _t * cur = VBoxTlsRefGetCurrent(_t, _Tsd); \
+ if (!cur || VBoxTlsRefIsFunctional(cur)) { \
+ (_val) = cur; \
+ } else { \
+ VBoxTlsRefSetCurrent(_t, _Tsd, NULL); \
+ (_val) = NULL; \
+ } \
+ } while (0)
+
+#define VBoxTlsRefSetCurrent(_t, _Tsd, _p) do { \
+ _t * oldCur = VBoxTlsRefGetCurrent(_t, _Tsd); \
+ if (oldCur != (_p)) { \
+ VBoxTlsRefSetImpl((_Tsd), (_p)); \
+ if (oldCur) { \
+ VBoxTlsRefRelease(oldCur); \
+ } \
+ if ((_p)) { \
+ VBoxTlsRefAddRef((_t*)(_p)); \
+ } \
+ } \
+ } while (0)
+
+#endif /* #ifndef ___VBox_VBoxVideo3D_h */
diff --git a/include/VBox/VBoxVideoGuest.h b/include/VBox/VBoxVideoGuest.h
new file mode 100644
index 00000000..b0718231
--- /dev/null
+++ b/include/VBox/VBoxVideoGuest.h
@@ -0,0 +1,318 @@
+/** @file
+ *
+ * VBox Host Guest Shared Memory Interface (HGSMI).
+ * OS-independent guest structures.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 __HGSMI_GUEST_h__
+#define __HGSMI_GUEST_h__
+
+#include <VBox/HGSMI/HGSMI.h>
+#include <VBox/HGSMI/HGSMIChSetup.h>
+
+#ifdef VBOX_XPDM_MINIPORT
+RT_C_DECLS_BEGIN
+# include "miniport.h"
+# include "ntddvdeo.h"
+# include <Video.h>
+RT_C_DECLS_END
+#else
+# include <iprt/asm-amd64-x86.h>
+#endif
+
+#ifdef VBOX_WDDM_MINIPORT
+# include "wddm/VBoxMPShgsmi.h"
+ typedef VBOXSHGSMI HGSMIGUESTCMDHEAP;
+# define HGSMIGUESTCMDHEAP_GET(_p) (&(_p)->Heap)
+#else
+ typedef HGSMIHEAP HGSMIGUESTCMDHEAP;
+# define HGSMIGUESTCMDHEAP_GET(_p) (_p)
+#endif
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Structure grouping the context needed for submitting commands to the host
+ * via HGSMI
+ */
+typedef struct HGSMIGUESTCOMMANDCONTEXT
+{
+ /** Information about the memory heap located in VRAM from which data
+ * structures to be sent to the host are allocated. */
+ HGSMIGUESTCMDHEAP heapCtx;
+ /** The I/O port used for submitting commands to the host by writing their
+ * offsets into the heap. */
+ RTIOPORT port;
+} HGSMIGUESTCOMMANDCONTEXT, *PHGSMIGUESTCOMMANDCONTEXT;
+
+
+/**
+ * Structure grouping the context needed for receiving commands from the host
+ * via HGSMI
+ */
+typedef struct HGSMIHOSTCOMMANDCONTEXT
+{
+ /** Information about the memory area located in VRAM in which the host
+ * places data structures to be read by the guest. */
+ HGSMIAREA areaCtx;
+ /** Convenience structure used for matching host commands to handlers. */
+ /** @todo handlers are registered individually in code rather than just
+ * passing a static structure in order to gain extra flexibility. There is
+ * currently no expected usage case for this though. Is the additional
+ * complexity really justified? */
+ HGSMICHANNELINFO channels;
+ /** Flag to indicate that one thread is currently processing the command
+ * queue. */
+ volatile bool fHostCmdProcessing;
+ /* Pointer to the VRAM location where the HGSMI host flags are kept. */
+ volatile HGSMIHOSTFLAGS *pfHostFlags;
+ /** The I/O port used for receiving commands from the host as offsets into
+ * the memory area and sending back confirmations (command completion,
+ * IRQ acknowlegement). */
+ RTIOPORT port;
+} HGSMIHOSTCOMMANDCONTEXT, *PHGSMIHOSTCOMMANDCONTEXT;
+
+
+/**
+ * Structure grouping the context needed for sending graphics acceleration
+ * information to the host via VBVA. Each screen has its own VBVA buffer.
+ */
+typedef struct VBVABUFFERCONTEXT
+{
+ /** Offset of the buffer in the VRAM section for the screen */
+ uint32_t offVRAMBuffer;
+ /** Length of the buffer in bytes */
+ uint32_t cbBuffer;
+ /** This flag is set if we wrote to the buffer faster than the host could
+ * read it. */
+ bool fHwBufferOverflow;
+ /** The VBVA record that we are currently preparing for the host, NULL if
+ * none. */
+ struct VBVARECORD *pRecord;
+ /** Pointer to the VBVA buffer mapped into the current address space. Will
+ * be NULL if VBVA is not enabled. */
+ struct VBVABUFFER *pVBVA;
+} VBVABUFFERCONTEXT, *PVBVABUFFERCONTEXT;
+
+/** @name Helper functions
+ * @{ */
+/** Write an 8-bit value to an I/O port. */
+DECLINLINE(void) VBoxVideoCmnPortWriteUchar(RTIOPORT Port, uint8_t Value)
+{
+#ifdef VBOX_XPDM_MINIPORT
+ VideoPortWritePortUchar((PUCHAR)Port, Value);
+#else /** @todo make these explicit */
+ ASMOutU8(Port, Value);
+#endif
+}
+
+/** Write a 16-bit value to an I/O port. */
+DECLINLINE(void) VBoxVideoCmnPortWriteUshort(RTIOPORT Port, uint16_t Value)
+{
+#ifdef VBOX_XPDM_MINIPORT
+ VideoPortWritePortUshort((PUSHORT)Port,Value);
+#else
+ ASMOutU16(Port, Value);
+#endif
+}
+
+/** Write a 32-bit value to an I/O port. */
+DECLINLINE(void) VBoxVideoCmnPortWriteUlong(RTIOPORT Port, uint32_t Value)
+{
+#ifdef VBOX_XPDM_MINIPORT
+ VideoPortWritePortUlong((PULONG)Port,Value);
+#else
+ ASMOutU32(Port, Value);
+#endif
+}
+
+/** Read an 8-bit value from an I/O port. */
+DECLINLINE(uint8_t) VBoxVideoCmnPortReadUchar(RTIOPORT Port)
+{
+#ifdef VBOX_XPDM_MINIPORT
+ return VideoPortReadPortUchar((PUCHAR)Port);
+#else
+ return ASMInU8(Port);
+#endif
+}
+
+/** Read a 16-bit value from an I/O port. */
+DECLINLINE(uint16_t) VBoxVideoCmnPortReadUshort(RTIOPORT Port)
+{
+#ifdef VBOX_XPDM_MINIPORT
+ return VideoPortReadPortUshort((PUSHORT)Port);
+#else
+ return ASMInU16(Port);
+#endif
+}
+
+/** Read a 32-bit value from an I/O port. */
+DECLINLINE(uint32_t) VBoxVideoCmnPortReadUlong(RTIOPORT Port)
+{
+#ifdef VBOX_XPDM_MINIPORT
+ return VideoPortReadPortUlong((PULONG)Port);
+#else
+ return ASMInU32(Port);
+#endif
+}
+
+/** @} */
+
+/** @name Base HGSMI APIs
+ * @{ */
+
+/** Acknowlege an IRQ. */
+DECLINLINE(void) VBoxHGSMIClearIrq(PHGSMIHOSTCOMMANDCONTEXT pCtx)
+{
+ VBoxVideoCmnPortWriteUlong(pCtx->port, HGSMIOFFSET_VOID);
+}
+
+RTDECL(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
+ void *pvMem);
+RTDECL(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx);
+RTDECL(bool) VBoxHGSMIIsSupported(void);
+RTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ HGSMISIZE cbData,
+ uint8_t u8Ch,
+ uint16_t u16Op);
+RTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ void *pvBuffer);
+RTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ void *pvBuffer);
+RTDECL(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
+ uint32_t *poffVRAMBaseMapping,
+ uint32_t *pcbMapping,
+ uint32_t *poffGuestHeapMemory,
+ uint32_t *pcbGuestHeapMemory,
+ uint32_t *poffHostFlags);
+/** @todo we should provide a cleanup function too as part of the API */
+RTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ void *pvGuestHeapMemory,
+ uint32_t cbGuestHeapMemory,
+ uint32_t offVRAMGuestHeapMemory);
+RTDECL(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t cbVRAM,
+ uint32_t offVRAMBaseMapping,
+ uint32_t *poffVRAMHostArea,
+ uint32_t *pcbHostArea);
+RTDECL(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
+ void *pvBaseMapping,
+ uint32_t offHostFlags,
+ void *pvHostAreaMapping,
+ uint32_t offVRAMHostArea,
+ uint32_t cbHostArea);
+RTDECL(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ HGSMIOFFSET offVRAMFlagsLocation,
+ uint32_t fCaps,
+ uint32_t offVRAMHostArea,
+ uint32_t cbHostArea);
+RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t u32Index, uint32_t *pulValue);
+RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t fFlags,
+ uint32_t cHotX,
+ uint32_t cHotY,
+ uint32_t cWidth,
+ uint32_t cHeight,
+ uint8_t *pPixels,
+ uint32_t cbLength);
+
+/** @} */
+
+/** @name VBVA APIs
+ * @{ */
+RTDECL(bool) VBoxVBVAEnable(PVBVABUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ struct VBVABUFFER *pVBVA, int32_t cScreen);
+RTDECL(void) VBoxVBVADisable(PVBVABUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ int32_t cScreen);
+RTDECL(bool) VBoxVBVABufferBeginUpdate(PVBVABUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx);
+RTDECL(void) VBoxVBVABufferEndUpdate(PVBVABUFFERCONTEXT pCtx);
+RTDECL(bool) VBoxVBVAWrite(PVBVABUFFERCONTEXT pCtx,
+ PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx,
+ const void *pv, uint32_t cb);
+RTDECL(bool) VBoxVBVAOrderSupported(PVBVABUFFERCONTEXT pCtx, unsigned code);
+RTDECL(void) VBoxVBVASetupBufferContext(PVBVABUFFERCONTEXT pCtx,
+ uint32_t offVRAMBuffer,
+ uint32_t cbBuffer);
+
+/** @} */
+
+/** @name Modesetting APIs
+ * @{ */
+
+RTDECL(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx);
+RTDECL(uint32_t) VBoxVideoGetVRAMSize(void);
+RTDECL(bool) VBoxVideoAnyWidthAllowed(void);
+
+struct VBVAINFOVIEW;
+/**
+ * Callback funtion called from @a VBoxHGSMISendViewInfo to initialise
+ * the @a VBVAINFOVIEW structure for each screen.
+ *
+ * @returns iprt status code
+ * @param pvData context data for the callback, passed to @a
+ * VBoxHGSMISendViewInfo along with the callback
+ * @param pInfo array of @a VBVAINFOVIEW structures to be filled in
+ * @todo explicitly pass the array size
+ */
+typedef DECLCALLBACK(int) FNHGSMIFILLVIEWINFO(void *pvData,
+ struct VBVAINFOVIEW *pInfo,
+ uint32_t cViews);
+/** Pointer to a FNHGSMIFILLVIEWINFO callback */
+typedef FNHGSMIFILLVIEWINFO *PFNHGSMIFILLVIEWINFO;
+
+RTDECL(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t u32Count,
+ PFNHGSMIFILLVIEWINFO pfnFill,
+ void *pvData);
+RTDECL(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight,
+ uint16_t cVirtWidth, uint16_t cBPP,
+ uint16_t fFlags,
+ uint16_t cx, uint16_t cy);
+RTDECL(bool) VBoxVideoGetModeRegisters(uint16_t *pcWidth,
+ uint16_t *pcHeight,
+ uint16_t *pcVirtWidth,
+ uint16_t *pcBPP,
+ uint16_t *pfFlags);
+RTDECL(void) VBoxVideoDisableVBE(void);
+RTDECL(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
+ uint32_t cDisplay,
+ int32_t cOriginX,
+ int32_t cOriginY,
+ uint32_t offStart,
+ uint32_t cbPitch,
+ uint32_t cWidth,
+ uint32_t cHeight,
+ uint16_t cBPP,
+ uint16_t fFlags);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* __HGSMI_GUEST_h__*/
diff --git a/include/VBox/VDEPlug.h b/include/VBox/VDEPlug.h
new file mode 100644
index 00000000..17664925
--- /dev/null
+++ b/include/VBox/VDEPlug.h
@@ -0,0 +1,44 @@
+/** @file
+ *
+ * Module to dynamically load libvdeplug and load all symbols
+ * which are needed by VirtualBox - header file.
+ */
+
+/*
+ * Copyright (C) 2008-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VDEPlug_h
+#define ___VBox_VDEPlug_h
+
+#define LIBVDEPLUG_INTERFACE_VERSION 1
+
+#define vde_open(vde_switch, descr, open_args) \
+ vde_open_real((vde_switch), (descr), LIBVDEPLUG_INTERFACE_VERSION, (open_args))
+
+/* Declarations of the functions that we need from the library */
+#define VDEPLUG_GENERATE_HEADER
+
+#include <VBox/VDEPlugSymDefs.h>
+
+#undef VDEPLUG_GENERATE_HEADER
+
+#endif /* ___VBox_VDEPlug_h not defined */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/include/VBox/VDEPlugSymDefs.h b/include/VBox/VDEPlugSymDefs.h
new file mode 100644
index 00000000..483b7834
--- /dev/null
+++ b/include/VBox/VDEPlugSymDefs.h
@@ -0,0 +1,82 @@
+/** @file
+ * Symbols from libvdeplug.so to be loaded at runtime for DrvVDE.cpp
+ */
+
+/*
+ * Copyright (C) 2008-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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.
+ */
+
+#include <stddef.h>
+#include <sys/types.h>
+
+/** Opaque connection type */
+struct vdeconn;
+typedef struct vdeconn VDECONN;
+
+/** Structure to be passed to the open function describing the connection.
+ * All members can be left zero to use the default values. */
+struct vde_open_args
+{
+ /** The port of the switch to connect to. */
+ int port;
+ /** The group to set ownership of the port socket to. */
+ char *group;
+ /** The file mode to set the port socket to. */
+ mode_t mode;
+};
+
+/** The file name of the DBus library */
+#define VBOX_LIB_VDE_PLUG_NAME "libvdeplug.so"
+#define RT_RUNTIME_LOADER_LIB_NAME VBOX_LIB_VDE_PLUG_NAME
+
+/** The name of the loader function */
+#define RT_RUNTIME_LOADER_FUNCTION DrvVDELoadVDEPlug
+
+/** The following are the symbols which we need from the library. */
+#define RT_RUNTIME_LOADER_INSERT_SYMBOLS \
+ RT_PROXY_STUB(vde_open_real, VDECONN *, \
+ (const char *vde_switch, const char *descr, int interface_version, struct vde_open_args *open_args), \
+ (vde_switch, descr, interface_version, open_args)) \
+ RT_PROXY_STUB(vde_recv, size_t, \
+ (VDECONN *conn, void *buf,size_t len, int flags), \
+ (conn, buf, len, flags)) \
+ RT_PROXY_STUB(vde_send, size_t, \
+ (VDECONN *conn, const void *buf, size_t len, int flags), \
+ (conn, buf, len, flags)) \
+ RT_PROXY_STUB(vde_datafd, int, (VDECONN *conn), (conn)) \
+ RT_PROXY_STUB(vde_close, void, (VDECONN *conn), (conn))
+
+#ifdef VDEPLUG_GENERATE_HEADER
+# define RT_RUNTIME_LOADER_GENERATE_HEADER
+# define RT_RUNTIME_LOADER_GENERATE_DECLS
+# include <iprt/runtime-loader.h>
+# undef RT_RUNTIME_LOADER_GENERATE_HEADER
+# undef RT_RUNTIME_LOADER_GENERATE_DECLS
+#elif defined (VDEPLUG_GENERATE_BODY)
+# define RT_RUNTIME_LOADER_GENERATE_BODY_STUBS
+# include <iprt/runtime-loader.h>
+# undef RT_RUNTIME_LOADER_GENERATE_BODY_STUBS
+#else
+# error This file should only be included to generate stubs for loading the libvdeplug library at runtime
+#endif
+
+#undef RT_RUNTIME_LOADER_LIB_NAME
+#undef RT_RUNTIME_LOADER_INSERT_SYMBOLS
+
diff --git a/include/VBox/VMMDev.h b/include/VBox/VMMDev.h
new file mode 100644
index 00000000..fe81237d
--- /dev/null
+++ b/include/VBox/VMMDev.h
@@ -0,0 +1,2077 @@
+/** @file
+ * Virtual Device for Guest <-> VMM/Host communication (ADD,DEV).
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VMMDev_h
+#define ___VBox_VMMDev_h
+
+#include <VBox/cdefs.h>
+#include <VBox/param.h> /* for the PCI IDs. */
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <VBox/ostypes.h>
+#include <VBox/VMMDev2.h>
+#include <iprt/assert.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_vmmdev VMM Device
+ *
+ * Note! This interface cannot be changed, it can only be extended!
+ *
+ * @{
+ */
+
+
+/** Size of VMMDev RAM region accessible by guest.
+ * Must be big enough to contain VMMDevMemory structure (see further down).
+ * For now: 4 megabyte.
+ */
+#define VMMDEV_RAM_SIZE (4 * 256 * PAGE_SIZE)
+
+/** Size of VMMDev heap region accessible by guest.
+ * (Must be a power of two (pci range).)
+ */
+#define VMMDEV_HEAP_SIZE (4 * PAGE_SIZE)
+
+/** Port for generic request interface (relative offset). */
+#define VMMDEV_PORT_OFF_REQUEST 0
+
+
+/** @name VMMDev events.
+ *
+ * Used mainly by VMMDevReq_AcknowledgeEvents/VMMDevEvents and version 1.3 of
+ * VMMDevMemory.
+ *
+ * @{
+ */
+/** Host mouse capabilities has been changed. */
+#define VMMDEV_EVENT_MOUSE_CAPABILITIES_CHANGED RT_BIT(0)
+/** HGCM event. */
+#define VMMDEV_EVENT_HGCM RT_BIT(1)
+/** A display change request has been issued. */
+#define VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST RT_BIT(2)
+/** Credentials are available for judgement. */
+#define VMMDEV_EVENT_JUDGE_CREDENTIALS RT_BIT(3)
+/** The guest has been restored. */
+#define VMMDEV_EVENT_RESTORED RT_BIT(4)
+/** Seamless mode state changed. */
+#define VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST RT_BIT(5)
+/** Memory balloon size changed. */
+#define VMMDEV_EVENT_BALLOON_CHANGE_REQUEST RT_BIT(6)
+/** Statistics interval changed. */
+#define VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST RT_BIT(7)
+/** VRDP status changed. */
+#define VMMDEV_EVENT_VRDP RT_BIT(8)
+/** New mouse position data available. */
+#define VMMDEV_EVENT_MOUSE_POSITION_CHANGED RT_BIT(9)
+/** CPU hotplug event occurred. */
+#define VMMDEV_EVENT_CPU_HOTPLUG RT_BIT(10)
+/** The mask of valid events, for sanity checking. */
+#define VMMDEV_EVENT_VALID_EVENT_MASK UINT32_C(0x000007ff)
+/** @} */
+
+
+/** @defgroup grp_vmmdev_req VMMDev Generic Request Interface
+ * @{
+ */
+
+/** @name Current version of the VMMDev interface.
+ *
+ * Additions are allowed to work only if
+ * additions_major == vmmdev_current && additions_minor <= vmmdev_current.
+ * Additions version is reported to host (VMMDev) by VMMDevReq_ReportGuestInfo.
+ *
+ * @remarks These defines also live in the 16-bit and assembly versions of this
+ * header.
+ */
+#define VMMDEV_VERSION 0x00010004
+#define VMMDEV_VERSION_MAJOR (VMMDEV_VERSION >> 16)
+#define VMMDEV_VERSION_MINOR (VMMDEV_VERSION & 0xffff)
+/** @} */
+
+/** Maximum request packet size. */
+#define VMMDEV_MAX_VMMDEVREQ_SIZE _1M
+
+/**
+ * VMMDev request types.
+ * @note when updating this, adjust vmmdevGetRequestSize() as well
+ */
+typedef enum
+{
+ VMMDevReq_InvalidRequest = 0,
+ VMMDevReq_GetMouseStatus = 1,
+ VMMDevReq_SetMouseStatus = 2,
+ VMMDevReq_SetPointerShape = 3,
+ VMMDevReq_GetHostVersion = 4,
+ VMMDevReq_Idle = 5,
+ VMMDevReq_GetHostTime = 10,
+ VMMDevReq_GetHypervisorInfo = 20,
+ VMMDevReq_SetHypervisorInfo = 21,
+ VMMDevReq_RegisterPatchMemory = 22, /* since version 3.0.6 */
+ VMMDevReq_DeregisterPatchMemory = 23, /* since version 3.0.6 */
+ VMMDevReq_SetPowerStatus = 30,
+ VMMDevReq_AcknowledgeEvents = 41,
+ VMMDevReq_CtlGuestFilterMask = 42,
+ VMMDevReq_ReportGuestInfo = 50,
+ VMMDevReq_ReportGuestInfo2 = 58, /* since version 3.2.0 */
+ VMMDevReq_ReportGuestStatus = 59, /* since version 3.2.8 */
+ /**
+ * Retrieve a display resize request sent by the host using
+ * @a IDisplay:setVideoModeHint. Deprecated.
+ *
+ * Similar to @a VMMDevReq_GetDisplayChangeRequest2, except that it only
+ * considers host requests sent for the first virtual display. This guest
+ * request should not be used in new guest code, and the results are
+ * undefined if a guest mixes calls to this and
+ * @a VMMDevReq_GetDisplayChangeRequest2.
+ */
+ VMMDevReq_GetDisplayChangeRequest = 51,
+ VMMDevReq_VideoModeSupported = 52,
+ VMMDevReq_GetHeightReduction = 53,
+ /**
+ * Retrieve a display resize request sent by the host using
+ * @a IDisplay:setVideoModeHint.
+ *
+ * Queries a display resize request sent from the host. If the
+ * @a eventAck member is sent to true and there is an unqueried
+ * request available for one of the virtual display then that request will
+ * be returned. If several displays have unqueried requests the lowest
+ * numbered display will be chosen first. Only the most recent unseen
+ * request for each display is remembered.
+ * If @a eventAck is set to false, the last host request queried with
+ * @a eventAck set is resent, or failing that the most recent received from
+ * the host. If no host request was ever received then all zeros are
+ * returned.
+ */
+ VMMDevReq_GetDisplayChangeRequest2 = 54,
+ VMMDevReq_ReportGuestCapabilities = 55,
+ VMMDevReq_SetGuestCapabilities = 56,
+ VMMDevReq_VideoModeSupported2 = 57, /* since version 3.2.0 */
+#ifdef VBOX_WITH_HGCM
+ VMMDevReq_HGCMConnect = 60,
+ VMMDevReq_HGCMDisconnect = 61,
+#ifdef VBOX_WITH_64_BITS_GUESTS
+ VMMDevReq_HGCMCall32 = 62,
+ VMMDevReq_HGCMCall64 = 63,
+#else
+ VMMDevReq_HGCMCall = 62,
+#endif /* VBOX_WITH_64_BITS_GUESTS */
+ VMMDevReq_HGCMCancel = 64,
+ VMMDevReq_HGCMCancel2 = 65,
+#endif
+ VMMDevReq_VideoAccelEnable = 70,
+ VMMDevReq_VideoAccelFlush = 71,
+ VMMDevReq_VideoSetVisibleRegion = 72,
+ VMMDevReq_GetSeamlessChangeRequest = 73,
+ VMMDevReq_QueryCredentials = 100,
+ VMMDevReq_ReportCredentialsJudgement = 101,
+ VMMDevReq_ReportGuestStats = 110,
+ VMMDevReq_GetMemBalloonChangeRequest = 111,
+ VMMDevReq_GetStatisticsChangeRequest = 112,
+ VMMDevReq_ChangeMemBalloon = 113,
+ VMMDevReq_GetVRDPChangeRequest = 150,
+ VMMDevReq_LogString = 200,
+ VMMDevReq_GetCpuHotPlugRequest = 210,
+ VMMDevReq_SetCpuHotPlugStatus = 211,
+ VMMDevReq_RegisterSharedModule = 212,
+ VMMDevReq_UnregisterSharedModule = 213,
+ VMMDevReq_CheckSharedModules = 214,
+ VMMDevReq_GetPageSharingStatus = 215,
+ VMMDevReq_DebugIsPageShared = 216,
+ VMMDevReq_GetSessionId = 217, /* since version 3.2.8 */
+ VMMDevReq_WriteCoreDump = 218,
+ VMMDevReq_SizeHack = 0x7fffffff
+} VMMDevRequestType;
+
+#ifdef VBOX_WITH_64_BITS_GUESTS
+/*
+ * Constants and structures are redefined for the guest.
+ *
+ * Host code MUST always use either *32 or *64 variant explicitely.
+ * Host source code will use VBOX_HGCM_HOST_CODE define to catch undefined
+ * data types and constants.
+ *
+ * This redefinition means that the new additions builds will use
+ * the *64 or *32 variants depending on the current architecture bit count (ARCH_BITS).
+ */
+# ifndef VBOX_HGCM_HOST_CODE
+# if ARCH_BITS == 64
+# define VMMDevReq_HGCMCall VMMDevReq_HGCMCall64
+# elif ARCH_BITS == 32
+# define VMMDevReq_HGCMCall VMMDevReq_HGCMCall32
+# else
+# error "Unsupported ARCH_BITS"
+# endif
+# endif /* !VBOX_HGCM_HOST_CODE */
+#endif /* VBOX_WITH_64_BITS_GUESTS */
+
+/** Version of VMMDevRequestHeader structure. */
+#define VMMDEV_REQUEST_HEADER_VERSION (0x10001)
+
+#pragma pack(4) /* force structure dword packing here. */
+
+/**
+ * Generic VMMDev request header.
+ */
+typedef struct
+{
+ /** IN: Size of the structure in bytes (including body). */
+ uint32_t size;
+ /** IN: Version of the structure. */
+ uint32_t version;
+ /** IN: Type of the request. */
+ VMMDevRequestType requestType;
+ /** OUT: Return code. */
+ int32_t rc;
+ /** Reserved field no.1. MBZ. */
+ uint32_t reserved1;
+ /** Reserved field no.2. MBZ. */
+ uint32_t reserved2;
+} VMMDevRequestHeader;
+AssertCompileSize(VMMDevRequestHeader, 24);
+
+
+/**
+ * Mouse status request structure.
+ *
+ * Used by VMMDevReq_GetMouseStatus and VMMDevReq_SetMouseStatus.
+ */
+typedef struct
+{
+ /** header */
+ VMMDevRequestHeader header;
+ /** Mouse feature mask. See VMMDEV_MOUSE_*. */
+ uint32_t mouseFeatures;
+ /** Mouse x position. */
+ int32_t pointerXPos;
+ /** Mouse y position. */
+ int32_t pointerYPos;
+} VMMDevReqMouseStatus;
+AssertCompileSize(VMMDevReqMouseStatus, 24+12);
+
+/** @name Mouse capability bits (VMMDevReqMouseStatus::mouseFeatures).
+ * @{ */
+/** The guest can (== wants to) handle absolute coordinates. */
+#define VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE RT_BIT(0)
+/** The host can (== wants to) send absolute coordinates.
+ * (Input not captured.) */
+#define VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE RT_BIT(1)
+/** The guest can *NOT* switch to software cursor and therefore depends on the
+ * host cursor.
+ *
+ * When guest additions are installed and the host has promised to display the
+ * cursor itself, the guest installs a hardware mouse driver. Don't ask the
+ * guest to switch to a software cursor then. */
+#define VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR RT_BIT(2)
+/** The host does NOT provide support for drawing the cursor itself.
+ * This is for instance the case for the L4 console. */
+#define VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER RT_BIT(3)
+/** The guest can read VMMDev events to find out about pointer movement */
+#define VMMDEV_MOUSE_NEW_PROTOCOL RT_BIT(4)
+/** If the guest changes the status of the
+ * VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR bit, the host will honour this */
+#define VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR RT_BIT(5)
+/** The host supplies an absolute pointing device. The Guest Additions may
+ * wish to use this to decide whether to install their own driver */
+#define VMMDEV_MOUSE_HOST_HAS_ABS_DEV RT_BIT(6)
+/** The mask of all VMMDEV_MOUSE_* flags */
+#define VMMDEV_MOUSE_MASK UINT32_C(0x0000007f)
+/** The mask of guest capability changes for which notification events should
+ * be sent */
+#define VMMDEV_MOUSE_NOTIFY_HOST_MASK \
+ (VMMDEV_MOUSE_GUEST_CAN_ABSOLUTE | VMMDEV_MOUSE_GUEST_NEEDS_HOST_CURSOR)
+/** The mask of all capabilities which the guest can legitimately change */
+#define VMMDEV_MOUSE_GUEST_MASK \
+ (VMMDEV_MOUSE_NOTIFY_HOST_MASK | VMMDEV_MOUSE_NEW_PROTOCOL)
+/** The mask of host capability changes for which notification events should
+ * be sent */
+#define VMMDEV_MOUSE_NOTIFY_GUEST_MASK \
+ VMMDEV_MOUSE_HOST_WANTS_ABSOLUTE
+/** The mask of all capabilities which the host can legitimately change */
+#define VMMDEV_MOUSE_HOST_MASK \
+ ( VMMDEV_MOUSE_NOTIFY_GUEST_MASK \
+ | VMMDEV_MOUSE_HOST_CANNOT_HWPOINTER \
+ | VMMDEV_MOUSE_HOST_RECHECKS_NEEDS_HOST_CURSOR \
+ | VMMDEV_MOUSE_HOST_HAS_ABS_DEV)
+/** @} */
+
+/** @name Absolute mouse reporting range
+ * @{ */
+/** @todo Should these be here? They are needed by both host and guest. */
+/** The minumum value our pointing device can return. */
+#define VMMDEV_MOUSE_RANGE_MIN 0
+/** The maximum value our pointing device can return. */
+#define VMMDEV_MOUSE_RANGE_MAX 0xFFFF
+/** The full range our pointing device can return. */
+#define VMMDEV_MOUSE_RANGE (VMMDEV_MOUSE_RANGE_MAX - VMMDEV_MOUSE_RANGE_MIN)
+/** @} */
+
+
+/**
+ * Mouse pointer shape/visibility change request.
+ *
+ * Used by VMMDevReq_SetPointerShape. The size is variable.
+ */
+typedef struct VMMDevReqMousePointer
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** VBOX_MOUSE_POINTER_* bit flags. */
+ uint32_t fFlags;
+ /** x coordinate of hot spot. */
+ uint32_t xHot;
+ /** y coordinate of hot spot. */
+ uint32_t yHot;
+ /** Width of the pointer in pixels. */
+ uint32_t width;
+ /** Height of the pointer in scanlines. */
+ uint32_t height;
+ /** Pointer data.
+ *
+ ****
+ * The data consists of 1 bpp AND mask followed by 32 bpp XOR (color) mask.
+ *
+ * For pointers without alpha channel the XOR mask pixels are 32 bit values: (lsb)BGR0(msb).
+ * For pointers with alpha channel the XOR mask consists of (lsb)BGRA(msb) 32 bit values.
+ *
+ * Guest driver must create the AND mask for pointers with alpha channel, so if host does not
+ * support alpha, the pointer could be displayed as a normal color pointer. The AND mask can
+ * be constructed from alpha values. For example alpha value >= 0xf0 means bit 0 in the AND mask.
+ *
+ * The AND mask is 1 bpp bitmap with byte aligned scanlines. Size of AND mask,
+ * therefore, is cbAnd = (width + 7) / 8 * height. The padding bits at the
+ * end of any scanline are undefined.
+ *
+ * The XOR mask follows the AND mask on the next 4 bytes aligned offset:
+ * uint8_t *pXor = pAnd + (cbAnd + 3) & ~3
+ * Bytes in the gap between the AND and the XOR mask are undefined.
+ * XOR mask scanlines have no gap between them and size of XOR mask is:
+ * cXor = width * 4 * height.
+ ****
+ *
+ * Preallocate 4 bytes for accessing actual data as p->pointerData.
+ */
+ char pointerData[4];
+} VMMDevReqMousePointer;
+AssertCompileSize(VMMDevReqMousePointer, 24+24);
+
+/**
+ * Get the size that a VMMDevReqMousePointer request should have for a given
+ * size of cursor, including the trailing cursor image and mask data.
+ * @note an "empty" request still has the four preallocated bytes of data
+ *
+ * @returns the size
+ * @param width the cursor width
+ * @param height the cursor height
+ */
+DECLINLINE(size_t) vmmdevGetMousePointerReqSize(uint32_t width, uint32_t height)
+{
+ size_t cbBase = RT_OFFSETOF(VMMDevReqMousePointer, pointerData);
+ size_t cbMask = (width + 7) / 8 * height;
+ size_t cbArgb = width * height * 4;
+ return RT_MAX(cbBase + ((cbMask + 3) & ~3) + cbArgb,
+ sizeof(VMMDevReqMousePointer));
+}
+
+/** @name VMMDevReqMousePointer::fFlags
+ * @note The VBOX_MOUSE_POINTER_* flags are used in the guest video driver,
+ * values must be <= 0x8000 and must not be changed. (try make more sense
+ * of this, please).
+ * @{
+ */
+/** pointer is visible */
+#define VBOX_MOUSE_POINTER_VISIBLE (0x0001)
+/** pointer has alpha channel */
+#define VBOX_MOUSE_POINTER_ALPHA (0x0002)
+/** pointerData contains new pointer shape */
+#define VBOX_MOUSE_POINTER_SHAPE (0x0004)
+/** @} */
+
+
+/**
+ * String log request structure.
+ *
+ * Used by VMMDevReq_LogString.
+ * @deprecated Use the IPRT logger or VbglR3WriteLog instead.
+ */
+typedef struct
+{
+ /** header */
+ VMMDevRequestHeader header;
+ /** variable length string data */
+ char szString[1];
+} VMMDevReqLogString;
+AssertCompileSize(VMMDevReqLogString, 24+4);
+
+
+/**
+ * VirtualBox host version request structure.
+ *
+ * Used by VMMDevReq_GetHostVersion.
+ *
+ * @remarks VBGL uses this to detect the precense of new features in the
+ * interface.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Major version. */
+ uint16_t major;
+ /** Minor version. */
+ uint16_t minor;
+ /** Build number. */
+ uint32_t build;
+ /** SVN revision. */
+ uint32_t revision;
+ /** Feature mask. */
+ uint32_t features;
+} VMMDevReqHostVersion;
+AssertCompileSize(VMMDevReqHostVersion, 24+16);
+
+/** @name VMMDevReqHostVersion::features
+ * @{ */
+/** Physical page lists are supported by HGCM. */
+#define VMMDEV_HVF_HGCM_PHYS_PAGE_LIST RT_BIT(0)
+/** @} */
+
+
+/**
+ * Guest capabilities structure.
+ *
+ * Used by VMMDevReq_ReportGuestCapabilities.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Capabilities (VMMDEV_GUEST_*). */
+ uint32_t caps;
+} VMMDevReqGuestCapabilities;
+AssertCompileSize(VMMDevReqGuestCapabilities, 24+4);
+
+/**
+ * Guest capabilities structure, version 2.
+ *
+ * Used by VMMDevReq_SetGuestCapabilities.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Mask of capabilities to be added. */
+ uint32_t u32OrMask;
+ /** Mask of capabilities to be removed. */
+ uint32_t u32NotMask;
+} VMMDevReqGuestCapabilities2;
+AssertCompileSize(VMMDevReqGuestCapabilities2, 24+8);
+
+/** @name Guest capability bits.
+ * Used by VMMDevReq_ReportGuestCapabilities and VMMDevReq_SetGuestCapabilities.
+ * @{ */
+/** The guest supports seamless display rendering. */
+#define VMMDEV_GUEST_SUPPORTS_SEAMLESS RT_BIT_32(0)
+/** The guest supports mapping guest to host windows. */
+#define VMMDEV_GUEST_SUPPORTS_GUEST_HOST_WINDOW_MAPPING RT_BIT_32(1)
+/** The guest graphical additions are active.
+ * Used for fast activation and deactivation of certain graphical operations
+ * (e.g. resizing & seamless). The legacy VMMDevReq_ReportGuestCapabilities
+ * request sets this automatically, but VMMDevReq_SetGuestCapabilities does
+ * not. */
+#define VMMDEV_GUEST_SUPPORTS_GRAPHICS RT_BIT_32(2)
+/** @} */
+
+
+/**
+ * Idle request structure.
+ *
+ * Used by VMMDevReq_Idle.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+} VMMDevReqIdle;
+AssertCompileSize(VMMDevReqIdle, 24);
+
+
+/**
+ * Host time request structure.
+ *
+ * Used by VMMDevReq_GetHostTime.
+ */
+typedef struct
+{
+ /** Header */
+ VMMDevRequestHeader header;
+ /** OUT: Time in milliseconds since unix epoch. */
+ uint64_t time;
+} VMMDevReqHostTime;
+AssertCompileSize(VMMDevReqHostTime, 24+8);
+
+
+/**
+ * Hypervisor info structure.
+ *
+ * Used by VMMDevReq_GetHypervisorInfo and VMMDevReq_SetHypervisorInfo.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Guest virtual address of proposed hypervisor start.
+ * Not used by VMMDevReq_GetHypervisorInfo.
+ * @todo Make this 64-bit compatible? */
+ RTGCPTR32 hypervisorStart;
+ /** Hypervisor size in bytes. */
+ uint32_t hypervisorSize;
+} VMMDevReqHypervisorInfo;
+AssertCompileSize(VMMDevReqHypervisorInfo, 24+8);
+
+/** @name Default patch memory size .
+ * Used by VMMDevReq_RegisterPatchMemory and VMMDevReq_DeregisterPatchMemory.
+ * @{ */
+#define VMMDEV_GUEST_DEFAULT_PATCHMEM_SIZE 8192
+/** @} */
+
+/**
+ * Patching memory structure. (locked executable & read-only page from the guest's perspective)
+ *
+ * Used by VMMDevReq_RegisterPatchMemory and VMMDevReq_DeregisterPatchMemory
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Guest virtual address of the patching page(s). */
+ RTGCPTR64 pPatchMem;
+ /** Patch page size in bytes. */
+ uint32_t cbPatchMem;
+} VMMDevReqPatchMemory;
+AssertCompileSize(VMMDevReqPatchMemory, 24+12);
+
+
+/**
+ * Guest power requests.
+ *
+ * See VMMDevReq_SetPowerStatus and VMMDevPowerStateRequest.
+ */
+typedef enum
+{
+ VMMDevPowerState_Invalid = 0,
+ VMMDevPowerState_Pause = 1,
+ VMMDevPowerState_PowerOff = 2,
+ VMMDevPowerState_SaveState = 3,
+ VMMDevPowerState_SizeHack = 0x7fffffff
+} VMMDevPowerState;
+AssertCompileSize(VMMDevPowerState, 4);
+
+/**
+ * VM power status structure.
+ *
+ * Used by VMMDevReq_SetPowerStatus.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Power state request. */
+ VMMDevPowerState powerState;
+} VMMDevPowerStateRequest;
+AssertCompileSize(VMMDevPowerStateRequest, 24+4);
+
+
+/**
+ * Pending events structure.
+ *
+ * Used by VMMDevReq_AcknowledgeEvents.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** OUT: Pending event mask. */
+ uint32_t events;
+} VMMDevEvents;
+AssertCompileSize(VMMDevEvents, 24+4);
+
+
+/**
+ * Guest event filter mask control.
+ *
+ * Used by VMMDevReq_CtlGuestFilterMask.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Mask of events to be added to the filter. */
+ uint32_t u32OrMask;
+ /** Mask of events to be removed from the filter. */
+ uint32_t u32NotMask;
+} VMMDevCtlGuestFilterMask;
+AssertCompileSize(VMMDevCtlGuestFilterMask, 24+8);
+
+
+/**
+ * Guest information structure.
+ *
+ * Used by VMMDevReportGuestInfo and PDMIVMMDEVCONNECTOR::pfnUpdateGuestVersion.
+ */
+typedef struct VBoxGuestInfo
+{
+ /** The VMMDev interface version expected by additions.
+ * *Deprecated*, do not use anymore! Will be removed. */
+ uint32_t interfaceVersion;
+ /** Guest OS type. */
+ VBOXOSTYPE osType;
+} VBoxGuestInfo;
+AssertCompileSize(VBoxGuestInfo, 8);
+
+/**
+ * Guest information report.
+ *
+ * Used by VMMDevReq_ReportGuestInfo.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Guest information. */
+ VBoxGuestInfo guestInfo;
+} VMMDevReportGuestInfo;
+AssertCompileSize(VMMDevReportGuestInfo, 24+8);
+
+
+/**
+ * Guest information structure, version 2.
+ *
+ * Used by VMMDevReportGuestInfo2 and PDMIVMMDEVCONNECTOR::pfnUpdateGuestVersion2.
+ */
+typedef struct VBoxGuestInfo2
+{
+ /** Major version. */
+ uint16_t additionsMajor;
+ /** Minor version. */
+ uint16_t additionsMinor;
+ /** Build number. */
+ uint32_t additionsBuild;
+ /** SVN revision. */
+ uint32_t additionsRevision;
+ /** Feature mask, currently unused. */
+ uint32_t additionsFeatures;
+ /** The intentional meaning of this field was:
+ * Some additional information, for example 'Beta 1' or something like that.
+ *
+ * The way it was implemented was implemented: VBOX_VERSION_STRING.
+ *
+ * This means the first three members are duplicated in this field (if the guest
+ * build config is sane). So, the user must check this and chop it off before
+ * usage. There is, because of the Main code's blind trust in the field's
+ * content, no way back. */
+ char szName[128];
+} VBoxGuestInfo2;
+AssertCompileSize(VBoxGuestInfo2, 144);
+
+/**
+ * Guest information report, version 2.
+ *
+ * Used by VMMDevReq_ReportGuestInfo2.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Guest information. */
+ VBoxGuestInfo2 guestInfo;
+} VMMDevReportGuestInfo2;
+AssertCompileSize(VMMDevReportGuestInfo2, 24+144);
+
+
+/**
+ * The guest facility.
+ * This needs to be kept in sync with AdditionsFacilityType of the Main API!
+ */
+typedef enum
+{
+ VBoxGuestFacilityType_Unknown = 0,
+ VBoxGuestFacilityType_VBoxGuestDriver = 20,
+ VBoxGuestFacilityType_AutoLogon = 90, /* VBoxGINA / VBoxCredProv / pam_vbox. */
+ VBoxGuestFacilityType_VBoxService = 100,
+ VBoxGuestFacilityType_VBoxTrayClient = 101, /* VBoxTray (Windows), VBoxClient (Linux, Unix). */
+ VBoxGuestFacilityType_Seamless = 1000,
+ VBoxGuestFacilityType_Graphics = 1100,
+ VBoxGuestFacilityType_All = 0x7ffffffe,
+ VBoxGuestFacilityType_SizeHack = 0x7fffffff
+} VBoxGuestFacilityType;
+AssertCompileSize(VBoxGuestFacilityType, 4);
+
+
+/**
+ * The current guest status of a facility.
+ * This needs to be kept in sync with AdditionsFacilityStatus of the Main API!
+ */
+typedef enum
+{
+ VBoxGuestFacilityStatus_Inactive = 0,
+ VBoxGuestFacilityStatus_Paused = 1,
+ VBoxGuestFacilityStatus_PreInit = 20,
+ VBoxGuestFacilityStatus_Init = 30,
+ VBoxGuestFacilityStatus_Active = 50,
+ VBoxGuestFacilityStatus_Terminating = 100,
+ VBoxGuestFacilityStatus_Terminated = 101,
+ VBoxGuestFacilityStatus_Failed = 800,
+ VBoxGuestFacilityStatus_Unknown = 999,
+ VBoxGuestFacilityStatus_SizeHack = 0x7fffffff
+} VBoxGuestFacilityStatus;
+AssertCompileSize(VBoxGuestFacilityStatus, 4);
+
+
+/**
+ * The facility class.
+ * This needs to be kept in sync with AdditionsFacilityClass of the Main API!
+ */
+typedef enum
+{
+ VBoxGuestFacilityClass_None = 0,
+ VBoxGuestFacilityClass_Driver = 10,
+ VBoxGuestFacilityClass_Service = 30,
+ VBoxGuestFacilityClass_Program = 50,
+ VBoxGuestFacilityClass_Feature = 100,
+ VBoxGuestFacilityClass_ThirdParty = 999,
+ VBoxGuestFacilityClass_All = 0x7ffffffe,
+ VBoxGuestFacilityClass_SizeHack = 0x7fffffff
+} VBoxGuestFacilityClass;
+AssertCompileSize(VBoxGuestFacilityClass, 4);
+
+
+/**
+ * Guest status structure.
+ *
+ * Used by VMMDevReqGuestStatus.
+ */
+typedef struct VBoxGuestStatus
+{
+ /** Facility the status is indicated for. */
+ VBoxGuestFacilityType facility;
+ /** Current guest status. */
+ VBoxGuestFacilityStatus status;
+ /** Flags, not used at the moment. */
+ uint32_t flags;
+} VBoxGuestStatus;
+AssertCompileSize(VBoxGuestStatus, 12);
+
+/**
+ * Guest Additions status structure.
+ *
+ * Used by VMMDevReq_ReportGuestStatus.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Guest information. */
+ VBoxGuestStatus guestStatus;
+} VMMDevReportGuestStatus;
+AssertCompileSize(VMMDevReportGuestStatus, 24+12);
+
+
+/**
+ * Guest statistics structure.
+ *
+ * Used by VMMDevReportGuestStats and PDMIVMMDEVCONNECTOR::pfnReportStatistics.
+ */
+typedef struct VBoxGuestStatistics
+{
+ /** Virtual CPU ID. */
+ uint32_t u32CpuId;
+ /** Reported statistics. */
+ uint32_t u32StatCaps;
+ /** Idle CPU load (0-100) for last interval. */
+ uint32_t u32CpuLoad_Idle;
+ /** Kernel CPU load (0-100) for last interval. */
+ uint32_t u32CpuLoad_Kernel;
+ /** User CPU load (0-100) for last interval. */
+ uint32_t u32CpuLoad_User;
+ /** Nr of threads. */
+ uint32_t u32Threads;
+ /** Nr of processes. */
+ uint32_t u32Processes;
+ /** Nr of handles. */
+ uint32_t u32Handles;
+ /** Memory load (0-100). */
+ uint32_t u32MemoryLoad;
+ /** Page size of guest system. */
+ uint32_t u32PageSize;
+ /** Total physical memory (in 4KB pages). */
+ uint32_t u32PhysMemTotal;
+ /** Available physical memory (in 4KB pages). */
+ uint32_t u32PhysMemAvail;
+ /** Ballooned physical memory (in 4KB pages). */
+ uint32_t u32PhysMemBalloon;
+ /** Total number of committed memory (which is not necessarily in-use) (in 4KB pages). */
+ uint32_t u32MemCommitTotal;
+ /** Total amount of memory used by the kernel (in 4KB pages). */
+ uint32_t u32MemKernelTotal;
+ /** Total amount of paged memory used by the kernel (in 4KB pages). */
+ uint32_t u32MemKernelPaged;
+ /** Total amount of nonpaged memory used by the kernel (in 4KB pages). */
+ uint32_t u32MemKernelNonPaged;
+ /** Total amount of memory used for the system cache (in 4KB pages). */
+ uint32_t u32MemSystemCache;
+ /** Pagefile size (in 4KB pages). */
+ uint32_t u32PageFileSize;
+} VBoxGuestStatistics;
+AssertCompileSize(VBoxGuestStatistics, 19*4);
+
+/** @name Guest statistics values (VBoxGuestStatistics::u32StatCaps).
+ * @{ */
+#define VBOX_GUEST_STAT_CPU_LOAD_IDLE RT_BIT(0)
+#define VBOX_GUEST_STAT_CPU_LOAD_KERNEL RT_BIT(1)
+#define VBOX_GUEST_STAT_CPU_LOAD_USER RT_BIT(2)
+#define VBOX_GUEST_STAT_THREADS RT_BIT(3)
+#define VBOX_GUEST_STAT_PROCESSES RT_BIT(4)
+#define VBOX_GUEST_STAT_HANDLES RT_BIT(5)
+#define VBOX_GUEST_STAT_MEMORY_LOAD RT_BIT(6)
+#define VBOX_GUEST_STAT_PHYS_MEM_TOTAL RT_BIT(7)
+#define VBOX_GUEST_STAT_PHYS_MEM_AVAIL RT_BIT(8)
+#define VBOX_GUEST_STAT_PHYS_MEM_BALLOON RT_BIT(9)
+#define VBOX_GUEST_STAT_MEM_COMMIT_TOTAL RT_BIT(10)
+#define VBOX_GUEST_STAT_MEM_KERNEL_TOTAL RT_BIT(11)
+#define VBOX_GUEST_STAT_MEM_KERNEL_PAGED RT_BIT(12)
+#define VBOX_GUEST_STAT_MEM_KERNEL_NONPAGED RT_BIT(13)
+#define VBOX_GUEST_STAT_MEM_SYSTEM_CACHE RT_BIT(14)
+#define VBOX_GUEST_STAT_PAGE_FILE_SIZE RT_BIT(15)
+/** @} */
+
+/**
+ * Guest statistics command structure.
+ *
+ * Used by VMMDevReq_ReportGuestStats.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Guest information. */
+ VBoxGuestStatistics guestStats;
+} VMMDevReportGuestStats;
+AssertCompileSize(VMMDevReportGuestStats, 24+19*4);
+
+
+/** Memory balloon change request structure. */
+#define VMMDEV_MAX_MEMORY_BALLOON(PhysMemTotal) ( (9 * (PhysMemTotal)) / 10 )
+
+/**
+ * Poll for ballooning change request.
+ *
+ * Used by VMMDevReq_GetMemBalloonChangeRequest.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Balloon size in megabytes. */
+ uint32_t cBalloonChunks;
+ /** Guest ram size in megabytes. */
+ uint32_t cPhysMemChunks;
+ /** Setting this to VMMDEV_EVENT_BALLOON_CHANGE_REQUEST indicates that the
+ * request is a response to that event.
+ * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+ uint32_t eventAck;
+} VMMDevGetMemBalloonChangeRequest;
+AssertCompileSize(VMMDevGetMemBalloonChangeRequest, 24+12);
+
+
+/**
+ * Change the size of the balloon.
+ *
+ * Used by VMMDevReq_ChangeMemBalloon.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** The number of pages in the array. */
+ uint32_t cPages;
+ /** true = inflate, false = deflate. */
+ uint32_t fInflate;
+ /** Physical address (RTGCPHYS) of each page, variable size. */
+ RTGCPHYS aPhysPage[1];
+} VMMDevChangeMemBalloon;
+AssertCompileSize(VMMDevChangeMemBalloon, 24+16);
+
+/** @name The ballooning chunk size which VMMDev works at.
+ * @{ */
+#define VMMDEV_MEMORY_BALLOON_CHUNK_PAGES (_1M/4096)
+#define VMMDEV_MEMORY_BALLOON_CHUNK_SIZE (VMMDEV_MEMORY_BALLOON_CHUNK_PAGES*4096)
+/** @} */
+
+
+/**
+ * Guest statistics interval change request structure.
+ *
+ * Used by VMMDevReq_GetStatisticsChangeRequest.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** The interval in seconds. */
+ uint32_t u32StatInterval;
+ /** Setting this to VMMDEV_EVENT_STATISTICS_INTERVAL_CHANGE_REQUEST indicates
+ * that the request is a response to that event.
+ * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+ uint32_t eventAck;
+} VMMDevGetStatisticsChangeRequest;
+AssertCompileSize(VMMDevGetStatisticsChangeRequest, 24+8);
+
+
+/** The size of a string field in the credentials request (including '\\0').
+ * @see VMMDevCredentials */
+#define VMMDEV_CREDENTIALS_SZ_SIZE 128
+
+/**
+ * Credentials request structure.
+ *
+ * Used by VMMDevReq_QueryCredentials.
+ */
+#pragma pack(4)
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** IN/OUT: Request flags. */
+ uint32_t u32Flags;
+ /** OUT: User name (UTF-8). */
+ char szUserName[VMMDEV_CREDENTIALS_SZ_SIZE];
+ /** OUT: Password (UTF-8). */
+ char szPassword[VMMDEV_CREDENTIALS_SZ_SIZE];
+ /** OUT: Domain name (UTF-8). */
+ char szDomain[VMMDEV_CREDENTIALS_SZ_SIZE];
+} VMMDevCredentials;
+AssertCompileSize(VMMDevCredentials, 24+4+3*128);
+#pragma pack()
+
+/** @name Credentials request flag (VMMDevCredentials::u32Flags)
+ * @{ */
+/** query from host whether credentials are present */
+#define VMMDEV_CREDENTIALS_QUERYPRESENCE RT_BIT(1)
+/** read credentials from host (can be combined with clear) */
+#define VMMDEV_CREDENTIALS_READ RT_BIT(2)
+/** clear credentials on host (can be combined with read) */
+#define VMMDEV_CREDENTIALS_CLEAR RT_BIT(3)
+/** read credentials for judgement in the guest */
+#define VMMDEV_CREDENTIALS_READJUDGE RT_BIT(8)
+/** clear credentials for judegement on the host */
+#define VMMDEV_CREDENTIALS_CLEARJUDGE RT_BIT(9)
+/** report credentials acceptance by guest */
+#define VMMDEV_CREDENTIALS_JUDGE_OK RT_BIT(10)
+/** report credentials denial by guest */
+#define VMMDEV_CREDENTIALS_JUDGE_DENY RT_BIT(11)
+/** report that no judgement could be made by guest */
+#define VMMDEV_CREDENTIALS_JUDGE_NOJUDGEMENT RT_BIT(12)
+
+/** flag telling the guest that credentials are present */
+#define VMMDEV_CREDENTIALS_PRESENT RT_BIT(16)
+/** flag telling guest that local logons should be prohibited */
+#define VMMDEV_CREDENTIALS_NOLOCALLOGON RT_BIT(17)
+/** @} */
+
+
+/**
+ * Seamless mode change request structure.
+ *
+ * Used by VMMDevReq_GetSeamlessChangeRequest.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+
+ /** New seamless mode. */
+ VMMDevSeamlessMode mode;
+ /** Setting this to VMMDEV_EVENT_SEAMLESS_MODE_CHANGE_REQUEST indicates
+ * that the request is a response to that event.
+ * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+ uint32_t eventAck;
+} VMMDevSeamlessChangeRequest;
+AssertCompileSize(VMMDevSeamlessChangeRequest, 24+8);
+AssertCompileMemberOffset(VMMDevSeamlessChangeRequest, eventAck, 24+4);
+
+
+/**
+ * Display change request structure.
+ *
+ * Used by VMMDevReq_GetDisplayChangeRequest.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Horizontal pixel resolution (0 = do not change). */
+ uint32_t xres;
+ /** Vertical pixel resolution (0 = do not change). */
+ uint32_t yres;
+ /** Bits per pixel (0 = do not change). */
+ uint32_t bpp;
+ /** Setting this to VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST indicates
+ * that the request is a response to that event.
+ * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+ uint32_t eventAck;
+} VMMDevDisplayChangeRequest;
+AssertCompileSize(VMMDevDisplayChangeRequest, 24+16);
+
+
+/**
+ * Display change request structure, version 2.
+ *
+ * Used by VMMDevReq_GetDisplayChangeRequest2.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Horizontal pixel resolution (0 = do not change). */
+ uint32_t xres;
+ /** Vertical pixel resolution (0 = do not change). */
+ uint32_t yres;
+ /** Bits per pixel (0 = do not change). */
+ uint32_t bpp;
+ /** Setting this to VMMDEV_EVENT_DISPLAY_CHANGE_REQUEST indicates
+ * that the request is a response to that event.
+ * (Don't confuse this with VMMDevReq_AcknowledgeEvents.) */
+ uint32_t eventAck;
+ /** 0 for primary display, 1 for the first secondary, etc. */
+ uint32_t display;
+} VMMDevDisplayChangeRequest2;
+AssertCompileSize(VMMDevDisplayChangeRequest2, 24+20);
+
+
+/**
+ * Video mode supported request structure.
+ *
+ * Used by VMMDevReq_VideoModeSupported.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** IN: Horizontal pixel resolution. */
+ uint32_t width;
+ /** IN: Vertical pixel resolution. */
+ uint32_t height;
+ /** IN: Bits per pixel. */
+ uint32_t bpp;
+ /** OUT: Support indicator. */
+ bool fSupported;
+} VMMDevVideoModeSupportedRequest;
+AssertCompileSize(VMMDevVideoModeSupportedRequest, 24+16);
+
+/**
+ * Video mode supported request structure for a specific display.
+ *
+ * Used by VMMDevReq_VideoModeSupported2.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** IN: The guest display number. */
+ uint32_t display;
+ /** IN: Horizontal pixel resolution. */
+ uint32_t width;
+ /** IN: Vertical pixel resolution. */
+ uint32_t height;
+ /** IN: Bits per pixel. */
+ uint32_t bpp;
+ /** OUT: Support indicator. */
+ bool fSupported;
+} VMMDevVideoModeSupportedRequest2;
+AssertCompileSize(VMMDevVideoModeSupportedRequest2, 24+20);
+
+/**
+ * Video modes height reduction request structure.
+ *
+ * Used by VMMDevReq_GetHeightReduction.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** OUT: Height reduction in pixels. */
+ uint32_t heightReduction;
+} VMMDevGetHeightReductionRequest;
+AssertCompileSize(VMMDevGetHeightReductionRequest, 24+4);
+
+
+/**
+ * VRDP change request structure.
+ *
+ * Used by VMMDevReq_GetVRDPChangeRequest.
+ */
+typedef struct
+{
+ /** Header */
+ VMMDevRequestHeader header;
+ /** Whether VRDP is active or not. */
+ uint8_t u8VRDPActive;
+ /** The configured experience level for active VRDP. */
+ uint32_t u32VRDPExperienceLevel;
+} VMMDevVRDPChangeRequest;
+AssertCompileSize(VMMDevVRDPChangeRequest, 24+8);
+AssertCompileMemberOffset(VMMDevVRDPChangeRequest, u8VRDPActive, 24);
+AssertCompileMemberOffset(VMMDevVRDPChangeRequest, u32VRDPExperienceLevel, 24+4);
+
+/** @name VRDP Experience level (VMMDevVRDPChangeRequest::u32VRDPExperienceLevel)
+ * @{ */
+#define VRDP_EXPERIENCE_LEVEL_ZERO 0 /**< Theming disabled. */
+#define VRDP_EXPERIENCE_LEVEL_LOW 1 /**< Full window dragging and desktop wallpaper disabled. */
+#define VRDP_EXPERIENCE_LEVEL_MEDIUM 2 /**< Font smoothing, gradients. */
+#define VRDP_EXPERIENCE_LEVEL_HIGH 3 /**< Animation effects disabled. */
+#define VRDP_EXPERIENCE_LEVEL_FULL 4 /**< Everything enabled. */
+/** @} */
+
+
+/**
+ * VBVA enable request structure.
+ *
+ * Used by VMMDevReq_VideoAccelEnable.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** 0 - disable, !0 - enable. */
+ uint32_t u32Enable;
+ /** The size of VBVAMEMORY::au8RingBuffer expected by driver.
+ * The host will refuse to enable VBVA if the size is not equal to
+ * VBVA_RING_BUFFER_SIZE.
+ */
+ uint32_t cbRingBuffer;
+ /** Guest initializes the status to 0. Host sets appropriate VBVA_F_STATUS_ flags. */
+ uint32_t fu32Status;
+} VMMDevVideoAccelEnable;
+AssertCompileSize(VMMDevVideoAccelEnable, 24+12);
+
+/** @name VMMDevVideoAccelEnable::fu32Status.
+ * @{ */
+#define VBVA_F_STATUS_ACCEPTED (0x01)
+#define VBVA_F_STATUS_ENABLED (0x02)
+/** @} */
+
+
+/**
+ * VBVA flush request structure.
+ *
+ * Used by VMMDevReq_VideoAccelFlush.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+} VMMDevVideoAccelFlush;
+AssertCompileSize(VMMDevVideoAccelFlush, 24);
+
+
+/**
+ * VBVA set visible region request structure.
+ *
+ * Used by VMMDevReq_VideoSetVisibleRegion.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Number of rectangles */
+ uint32_t cRect;
+ /** Rectangle array.
+ * @todo array is spelled aRects[1]. */
+ RTRECT Rect;
+} VMMDevVideoSetVisibleRegion;
+AssertCompileSize(RTRECT, 16);
+AssertCompileSize(VMMDevVideoSetVisibleRegion, 24+4+16);
+
+/**
+ * CPU event types.
+ */
+typedef enum
+{
+ VMMDevCpuStatusType_Invalid = 0,
+ VMMDevCpuStatusType_Disable = 1,
+ VMMDevCpuStatusType_Enable = 2,
+ VMMDevCpuStatusType_SizeHack = 0x7fffffff
+} VMMDevCpuStatusType;
+
+/**
+ * CPU hotplug event status request.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Status type */
+ VMMDevCpuStatusType enmStatusType;
+} VMMDevCpuHotPlugStatusRequest;
+AssertCompileSize(VMMDevCpuHotPlugStatusRequest, 24+4);
+
+/**
+ * Get the ID of the changed CPU and event type.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Event type */
+ VMMDevCpuEventType enmEventType;
+ /** core id of the CPU changed */
+ uint32_t idCpuCore;
+ /** package id of the CPU changed */
+ uint32_t idCpuPackage;
+} VMMDevGetCpuHotPlugRequest;
+AssertCompileSize(VMMDevGetCpuHotPlugRequest, 24+4+4+4);
+
+
+/**
+ * Shared region description
+ */
+typedef struct VMMDEVSHAREDREGIONDESC
+{
+ RTGCPTR64 GCRegionAddr;
+ uint32_t cbRegion;
+ uint32_t u32Alignment;
+} VMMDEVSHAREDREGIONDESC;
+AssertCompileSize(VMMDEVSHAREDREGIONDESC, 16);
+
+#define VMMDEVSHAREDREGIONDESC_MAX 32
+
+/**
+ * Shared module registration
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Shared module size. */
+ uint32_t cbModule;
+ /** Number of included region descriptors */
+ uint32_t cRegions;
+ /** Base address of the shared module. */
+ RTGCPTR64 GCBaseAddr;
+ /** Guest OS type. */
+ VBOXOSFAMILY enmGuestOS;
+ /** Alignment. */
+ uint32_t u32Align;
+ /** Module name */
+ char szName[128];
+ /** Module version */
+ char szVersion[16];
+ /** Shared region descriptor(s). */
+ VMMDEVSHAREDREGIONDESC aRegions[1];
+} VMMDevSharedModuleRegistrationRequest;
+AssertCompileSize(VMMDevSharedModuleRegistrationRequest, 24+4+4+8+4+4+128+16+16);
+
+
+/**
+ * Shared module unregistration
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Shared module size. */
+ uint32_t cbModule;
+ /** Align at 8 byte boundary. */
+ uint32_t u32Alignment;
+ /** Base address of the shared module. */
+ RTGCPTR64 GCBaseAddr;
+ /** Module name */
+ char szName[128];
+ /** Module version */
+ char szVersion[16];
+} VMMDevSharedModuleUnregistrationRequest;
+AssertCompileSize(VMMDevSharedModuleUnregistrationRequest, 24+4+4+8+128+16);
+
+
+/**
+ * Shared module periodic check
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+} VMMDevSharedModuleCheckRequest;
+AssertCompileSize(VMMDevSharedModuleCheckRequest, 24);
+
+/**
+ * Paging sharing enabled query
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Enabled flag (out) */
+ bool fEnabled;
+ /** Alignment */
+ bool fAlignment[3];
+} VMMDevPageSharingStatusRequest;
+AssertCompileSize(VMMDevPageSharingStatusRequest, 24+4);
+
+
+/**
+ * Page sharing status query (debug build only)
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Page address. */
+ RTGCPTR GCPtrPage;
+ /** Page flags. */
+ uint64_t uPageFlags;
+ /** Shared flag (out) */
+ bool fShared;
+ /** Alignment */
+ bool fAlignment[3];
+} VMMDevPageIsSharedRequest;
+
+/**
+ * Session id request structure.
+ *
+ * Used by VMMDevReq_GetSessionId.
+ */
+typedef struct
+{
+ /** Header */
+ VMMDevRequestHeader header;
+ /** OUT: unique session id; the id will be different after each start, reset or restore of the VM */
+ uint64_t idSession;
+} VMMDevReqSessionId;
+AssertCompileSize(VMMDevReqSessionId, 24+8);
+
+
+/**
+ * Write Core Dump request.
+ *
+ * Used by VMMDevReq_WriteCoreDump.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** Flags (reserved, MBZ). */
+ uint32_t fFlags;
+} VMMDevReqWriteCoreDump;
+AssertCompileSize(VMMDevReqWriteCoreDump, 24+4);
+
+
+#pragma pack()
+
+
+#ifdef VBOX_WITH_HGCM
+
+/** @name HGCM flags.
+ * @{
+ */
+# define VBOX_HGCM_REQ_DONE RT_BIT_32(VBOX_HGCM_REQ_DONE_BIT)
+# define VBOX_HGCM_REQ_DONE_BIT 0
+# define VBOX_HGCM_REQ_CANCELLED (0x2)
+/** @} */
+
+# pragma pack(4)
+
+/**
+ * HGCM request header.
+ */
+typedef struct VMMDevHGCMRequestHeader
+{
+ /** Request header. */
+ VMMDevRequestHeader header;
+
+ /** HGCM flags. */
+ uint32_t fu32Flags;
+
+ /** Result code. */
+ int32_t result;
+} VMMDevHGCMRequestHeader;
+AssertCompileSize(VMMDevHGCMRequestHeader, 24+8);
+
+/**
+ * HGCM connect request structure.
+ *
+ * Used by VMMDevReq_HGCMConnect.
+ */
+typedef struct
+{
+ /** HGCM request header. */
+ VMMDevHGCMRequestHeader header;
+
+ /** IN: Description of service to connect to. */
+ HGCMServiceLocation loc;
+
+ /** OUT: Client identifier assigned by local instance of HGCM. */
+ uint32_t u32ClientID;
+} VMMDevHGCMConnect;
+AssertCompileSize(VMMDevHGCMConnect, 32+132+4);
+
+
+/**
+ * HGCM disconnect request structure.
+ *
+ * Used by VMMDevReq_HGCMDisconnect.
+ */
+typedef struct
+{
+ /** HGCM request header. */
+ VMMDevHGCMRequestHeader header;
+
+ /** IN: Client identifier. */
+ uint32_t u32ClientID;
+} VMMDevHGCMDisconnect;
+AssertCompileSize(VMMDevHGCMDisconnect, 32+4);
+
+/**
+ * HGCM parameter type.
+ */
+typedef enum
+{
+ VMMDevHGCMParmType_Invalid = 0,
+ VMMDevHGCMParmType_32bit = 1,
+ VMMDevHGCMParmType_64bit = 2,
+ VMMDevHGCMParmType_PhysAddr = 3, /**< @deprecated Doesn't work, use PageList. */
+ VMMDevHGCMParmType_LinAddr = 4, /**< In and Out */
+ VMMDevHGCMParmType_LinAddr_In = 5, /**< In (read; host<-guest) */
+ VMMDevHGCMParmType_LinAddr_Out = 6, /**< Out (write; host->guest) */
+ VMMDevHGCMParmType_LinAddr_Locked = 7, /**< Locked In and Out */
+ VMMDevHGCMParmType_LinAddr_Locked_In = 8, /**< Locked In (read; host<-guest) */
+ VMMDevHGCMParmType_LinAddr_Locked_Out = 9, /**< Locked Out (write; host->guest) */
+ VMMDevHGCMParmType_PageList = 10, /**< Physical addresses of locked pages for a buffer. */
+ VMMDevHGCMParmType_SizeHack = 0x7fffffff
+} HGCMFunctionParameterType;
+AssertCompileSize(HGCMFunctionParameterType, 4);
+
+# ifdef VBOX_WITH_64_BITS_GUESTS
+/**
+ * HGCM function parameter, 32-bit client.
+ */
+typedef struct
+{
+ HGCMFunctionParameterType type;
+ union
+ {
+ uint32_t value32;
+ uint64_t value64;
+ struct
+ {
+ uint32_t size;
+
+ union
+ {
+ RTGCPHYS32 physAddr;
+ RTGCPTR32 linearAddr;
+ } u;
+ } Pointer;
+ struct
+ {
+ uint32_t size; /**< Size of the buffer described by the page list. */
+ uint32_t offset; /**< Relative to the request header, valid if size != 0. */
+ } PageList;
+ } u;
+# ifdef __cplusplus
+ void SetUInt32(uint32_t u32)
+ {
+ type = VMMDevHGCMParmType_32bit;
+ u.value64 = 0; /* init unused bits to 0 */
+ u.value32 = u32;
+ }
+
+ int GetUInt32(uint32_t *pu32)
+ {
+ if (type == VMMDevHGCMParmType_32bit)
+ {
+ *pu32 = u.value32;
+ return VINF_SUCCESS;
+ }
+ return VERR_INVALID_PARAMETER;
+ }
+
+ void SetUInt64(uint64_t u64)
+ {
+ type = VMMDevHGCMParmType_64bit;
+ u.value64 = u64;
+ }
+
+ int GetUInt64(uint64_t *pu64)
+ {
+ if (type == VMMDevHGCMParmType_64bit)
+ {
+ *pu64 = u.value64;
+ return VINF_SUCCESS;
+ }
+ return VERR_INVALID_PARAMETER;
+ }
+
+ void SetPtr(void *pv, uint32_t cb)
+ {
+ type = VMMDevHGCMParmType_LinAddr;
+ u.Pointer.size = cb;
+ u.Pointer.u.linearAddr = (RTGCPTR32)(uintptr_t)pv;
+ }
+# endif /* __cplusplus */
+} HGCMFunctionParameter32;
+AssertCompileSize(HGCMFunctionParameter32, 4+8);
+
+/**
+ * HGCM function parameter, 64-bit client.
+ */
+typedef struct
+{
+ HGCMFunctionParameterType type;
+ union
+ {
+ uint32_t value32;
+ uint64_t value64;
+ struct
+ {
+ uint32_t size;
+
+ union
+ {
+ RTGCPHYS64 physAddr;
+ RTGCPTR64 linearAddr;
+ } u;
+ } Pointer;
+ struct
+ {
+ uint32_t size; /**< Size of the buffer described by the page list. */
+ uint32_t offset; /**< Relative to the request header, valid if size != 0. */
+ } PageList;
+ } u;
+# ifdef __cplusplus
+ void SetUInt32(uint32_t u32)
+ {
+ type = VMMDevHGCMParmType_32bit;
+ u.value64 = 0; /* init unused bits to 0 */
+ u.value32 = u32;
+ }
+
+ int GetUInt32(uint32_t *pu32)
+ {
+ if (type == VMMDevHGCMParmType_32bit)
+ {
+ *pu32 = u.value32;
+ return VINF_SUCCESS;
+ }
+ return VERR_INVALID_PARAMETER;
+ }
+
+ void SetUInt64(uint64_t u64)
+ {
+ type = VMMDevHGCMParmType_64bit;
+ u.value64 = u64;
+ }
+
+ int GetUInt64(uint64_t *pu64)
+ {
+ if (type == VMMDevHGCMParmType_64bit)
+ {
+ *pu64 = u.value64;
+ return VINF_SUCCESS;
+ }
+ return VERR_INVALID_PARAMETER;
+ }
+
+ void SetPtr(void *pv, uint32_t cb)
+ {
+ type = VMMDevHGCMParmType_LinAddr;
+ u.Pointer.size = cb;
+ u.Pointer.u.linearAddr = (uintptr_t)pv;
+ }
+# endif /** __cplusplus */
+} HGCMFunctionParameter64;
+AssertCompileSize(HGCMFunctionParameter64, 4+12);
+
+/* Redefine the structure type for the guest code. */
+# ifndef VBOX_HGCM_HOST_CODE
+# if ARCH_BITS == 64
+# define HGCMFunctionParameter HGCMFunctionParameter64
+# elif ARCH_BITS == 32
+# define HGCMFunctionParameter HGCMFunctionParameter32
+# else
+# error "Unsupported sizeof (void *)"
+# endif
+# endif /* !VBOX_HGCM_HOST_CODE */
+
+# else /* !VBOX_WITH_64_BITS_GUESTS */
+
+/**
+ * HGCM function parameter, 32-bit client.
+ *
+ * @todo If this is the same as HGCMFunctionParameter32, why the duplication?
+ */
+typedef struct
+{
+ HGCMFunctionParameterType type;
+ union
+ {
+ uint32_t value32;
+ uint64_t value64;
+ struct
+ {
+ uint32_t size;
+
+ union
+ {
+ RTGCPHYS32 physAddr;
+ RTGCPTR32 linearAddr;
+ } u;
+ } Pointer;
+ struct
+ {
+ uint32_t size; /**< Size of the buffer described by the page list. */
+ uint32_t offset; /**< Relative to the request header, valid if size != 0. */
+ } PageList;
+ } u;
+# ifdef __cplusplus
+ void SetUInt32(uint32_t u32)
+ {
+ type = VMMDevHGCMParmType_32bit;
+ u.value64 = 0; /* init unused bits to 0 */
+ u.value32 = u32;
+ }
+
+ int GetUInt32(uint32_t *pu32)
+ {
+ if (type == VMMDevHGCMParmType_32bit)
+ {
+ *pu32 = u.value32;
+ return VINF_SUCCESS;
+ }
+ return VERR_INVALID_PARAMETER;
+ }
+
+ void SetUInt64(uint64_t u64)
+ {
+ type = VMMDevHGCMParmType_64bit;
+ u.value64 = u64;
+ }
+
+ int GetUInt64(uint64_t *pu64)
+ {
+ if (type == VMMDevHGCMParmType_64bit)
+ {
+ *pu64 = u.value64;
+ return VINF_SUCCESS;
+ }
+ return VERR_INVALID_PARAMETER;
+ }
+
+ void SetPtr(void *pv, uint32_t cb)
+ {
+ type = VMMDevHGCMParmType_LinAddr;
+ u.Pointer.size = cb;
+ u.Pointer.u.linearAddr = (uintptr_t)pv;
+ }
+# endif /* __cplusplus */
+} HGCMFunctionParameter;
+AssertCompileSize(HGCMFunctionParameter, 4+8);
+# endif /* !VBOX_WITH_64_BITS_GUESTS */
+
+/**
+ * HGCM call request structure.
+ *
+ * Used by VMMDevReq_HGCMCall, VMMDevReq_HGCMCall32 and VMMDevReq_HGCMCall64.
+ */
+typedef struct
+{
+ /* request header */
+ VMMDevHGCMRequestHeader header;
+
+ /** IN: Client identifier. */
+ uint32_t u32ClientID;
+ /** IN: Service function number. */
+ uint32_t u32Function;
+ /** IN: Number of parameters. */
+ uint32_t cParms;
+ /** Parameters follow in form: HGCMFunctionParameter aParms[X]; */
+} VMMDevHGCMCall;
+AssertCompileSize(VMMDevHGCMCall, 32+12);
+
+/** @name Direction of data transfer (HGCMPageListInfo::flags). Bit flags.
+ * @{ */
+#define VBOX_HGCM_F_PARM_DIRECTION_NONE UINT32_C(0x00000000)
+#define VBOX_HGCM_F_PARM_DIRECTION_TO_HOST UINT32_C(0x00000001)
+#define VBOX_HGCM_F_PARM_DIRECTION_FROM_HOST UINT32_C(0x00000002)
+#define VBOX_HGCM_F_PARM_DIRECTION_BOTH UINT32_C(0x00000003)
+/** Macro for validating that the specified flags are valid. */
+#define VBOX_HGCM_F_PARM_ARE_VALID(fFlags) \
+ ( (fFlags) > VBOX_HGCM_F_PARM_DIRECTION_NONE \
+ && (fFlags) < VBOX_HGCM_F_PARM_DIRECTION_BOTH )
+/** @} */
+
+/**
+ * VMMDevHGCMParmType_PageList points to this structure to actually describe the
+ * buffer.
+ */
+typedef struct
+{
+ uint32_t flags; /**< VBOX_HGCM_F_PARM_*. */
+ uint16_t offFirstPage; /**< Offset in the first page where data begins. */
+ uint16_t cPages; /**< Number of pages. */
+ RTGCPHYS64 aPages[1]; /**< Page addresses. */
+} HGCMPageListInfo;
+AssertCompileSize(HGCMPageListInfo, 4+2+2+8);
+
+# pragma pack()
+
+/** Get the pointer to the first parmater of a HGCM call request. */
+# define VMMDEV_HGCM_CALL_PARMS(a) ((HGCMFunctionParameter *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+/** Get the pointer to the first parmater of a 32-bit HGCM call request. */
+# define VMMDEV_HGCM_CALL_PARMS32(a) ((HGCMFunctionParameter32 *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+
+# ifdef VBOX_WITH_64_BITS_GUESTS
+/* Explicit defines for the host code. */
+# ifdef VBOX_HGCM_HOST_CODE
+# define VMMDEV_HGCM_CALL_PARMS32(a) ((HGCMFunctionParameter32 *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+# define VMMDEV_HGCM_CALL_PARMS64(a) ((HGCMFunctionParameter64 *)((uint8_t *)(a) + sizeof (VMMDevHGCMCall)))
+# endif /* VBOX_HGCM_HOST_CODE */
+# endif /* VBOX_WITH_64_BITS_GUESTS */
+
+# define VBOX_HGCM_MAX_PARMS 32
+
+/**
+ * HGCM cancel request structure.
+ *
+ * The Cancel request is issued using the same physical memory address as was
+ * used for the corresponding initial HGCMCall.
+ *
+ * Used by VMMDevReq_HGCMCancel.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevHGCMRequestHeader header;
+} VMMDevHGCMCancel;
+AssertCompileSize(VMMDevHGCMCancel, 32);
+
+/**
+ * HGCM cancel request structure, version 2.
+ *
+ * Used by VMMDevReq_HGCMCancel2.
+ *
+ * VINF_SUCCESS when cancelled.
+ * VERR_NOT_FOUND if the specified request cannot be found.
+ * VERR_INVALID_PARAMETER if the address is invalid valid.
+ */
+typedef struct
+{
+ /** Header. */
+ VMMDevRequestHeader header;
+ /** The physical address of the request to cancel. */
+ RTGCPHYS32 physReqToCancel;
+} VMMDevHGCMCancel2;
+AssertCompileSize(VMMDevHGCMCancel2, 24+4);
+
+#endif /* VBOX_WITH_HGCM */
+
+
+/**
+ * Inline helper to determine the request size for the given operation.
+ *
+ * @returns Size.
+ * @param requestType The VMMDev request type.
+ */
+DECLINLINE(size_t) vmmdevGetRequestSize(VMMDevRequestType requestType)
+{
+ switch (requestType)
+ {
+ case VMMDevReq_GetMouseStatus:
+ case VMMDevReq_SetMouseStatus:
+ return sizeof(VMMDevReqMouseStatus);
+ case VMMDevReq_SetPointerShape:
+ return sizeof(VMMDevReqMousePointer);
+ case VMMDevReq_GetHostVersion:
+ return sizeof(VMMDevReqHostVersion);
+ case VMMDevReq_Idle:
+ return sizeof(VMMDevReqIdle);
+ case VMMDevReq_GetHostTime:
+ return sizeof(VMMDevReqHostTime);
+ case VMMDevReq_GetHypervisorInfo:
+ case VMMDevReq_SetHypervisorInfo:
+ return sizeof(VMMDevReqHypervisorInfo);
+ case VMMDevReq_RegisterPatchMemory:
+ case VMMDevReq_DeregisterPatchMemory:
+ return sizeof(VMMDevReqPatchMemory);
+ case VMMDevReq_SetPowerStatus:
+ return sizeof(VMMDevPowerStateRequest);
+ case VMMDevReq_AcknowledgeEvents:
+ return sizeof(VMMDevEvents);
+ case VMMDevReq_ReportGuestInfo:
+ return sizeof(VMMDevReportGuestInfo);
+ case VMMDevReq_ReportGuestInfo2:
+ return sizeof(VMMDevReportGuestInfo2);
+ case VMMDevReq_ReportGuestStatus:
+ return sizeof(VMMDevReportGuestStatus);
+ case VMMDevReq_GetDisplayChangeRequest:
+ return sizeof(VMMDevDisplayChangeRequest);
+ case VMMDevReq_GetDisplayChangeRequest2:
+ return sizeof(VMMDevDisplayChangeRequest2);
+ case VMMDevReq_VideoModeSupported:
+ return sizeof(VMMDevVideoModeSupportedRequest);
+ case VMMDevReq_GetHeightReduction:
+ return sizeof(VMMDevGetHeightReductionRequest);
+ case VMMDevReq_ReportGuestCapabilities:
+ return sizeof(VMMDevReqGuestCapabilities);
+ case VMMDevReq_SetGuestCapabilities:
+ return sizeof(VMMDevReqGuestCapabilities2);
+#ifdef VBOX_WITH_HGCM
+ case VMMDevReq_HGCMConnect:
+ return sizeof(VMMDevHGCMConnect);
+ case VMMDevReq_HGCMDisconnect:
+ return sizeof(VMMDevHGCMDisconnect);
+#ifdef VBOX_WITH_64_BITS_GUESTS
+ case VMMDevReq_HGCMCall32:
+ return sizeof(VMMDevHGCMCall);
+ case VMMDevReq_HGCMCall64:
+ return sizeof(VMMDevHGCMCall);
+#else
+ case VMMDevReq_HGCMCall:
+ return sizeof(VMMDevHGCMCall);
+#endif /* VBOX_WITH_64_BITS_GUESTS */
+ case VMMDevReq_HGCMCancel:
+ return sizeof(VMMDevHGCMCancel);
+#endif /* VBOX_WITH_HGCM */
+ case VMMDevReq_VideoAccelEnable:
+ return sizeof(VMMDevVideoAccelEnable);
+ case VMMDevReq_VideoAccelFlush:
+ return sizeof(VMMDevVideoAccelFlush);
+ case VMMDevReq_VideoSetVisibleRegion:
+ /* The original protocol didn't consider a guest with NO visible
+ * windows */
+ return sizeof(VMMDevVideoSetVisibleRegion) - sizeof(RTRECT);
+ case VMMDevReq_GetSeamlessChangeRequest:
+ return sizeof(VMMDevSeamlessChangeRequest);
+ case VMMDevReq_QueryCredentials:
+ return sizeof(VMMDevCredentials);
+ case VMMDevReq_ReportGuestStats:
+ return sizeof(VMMDevReportGuestStats);
+ case VMMDevReq_GetMemBalloonChangeRequest:
+ return sizeof(VMMDevGetMemBalloonChangeRequest);
+ case VMMDevReq_GetStatisticsChangeRequest:
+ return sizeof(VMMDevGetStatisticsChangeRequest);
+ case VMMDevReq_ChangeMemBalloon:
+ return sizeof(VMMDevChangeMemBalloon);
+ case VMMDevReq_GetVRDPChangeRequest:
+ return sizeof(VMMDevVRDPChangeRequest);
+ case VMMDevReq_LogString:
+ return sizeof(VMMDevReqLogString);
+ case VMMDevReq_CtlGuestFilterMask:
+ return sizeof(VMMDevCtlGuestFilterMask);
+ case VMMDevReq_GetCpuHotPlugRequest:
+ return sizeof(VMMDevGetCpuHotPlugRequest);
+ case VMMDevReq_SetCpuHotPlugStatus:
+ return sizeof(VMMDevCpuHotPlugStatusRequest);
+ case VMMDevReq_RegisterSharedModule:
+ return sizeof(VMMDevSharedModuleRegistrationRequest);
+ case VMMDevReq_UnregisterSharedModule:
+ return sizeof(VMMDevSharedModuleUnregistrationRequest);
+ case VMMDevReq_CheckSharedModules:
+ return sizeof(VMMDevSharedModuleCheckRequest);
+ case VMMDevReq_GetPageSharingStatus:
+ return sizeof(VMMDevPageSharingStatusRequest);
+ case VMMDevReq_DebugIsPageShared:
+ return sizeof(VMMDevPageIsSharedRequest);
+ case VMMDevReq_GetSessionId:
+ return sizeof(VMMDevReqSessionId);
+ default:
+ return 0;
+ }
+}
+
+
+/**
+ * Initializes a request structure.
+ *
+ * @returns VBox status code.
+ * @param req The request structure to initialize.
+ * @param type The request type.
+ */
+DECLINLINE(int) vmmdevInitRequest(VMMDevRequestHeader *req, VMMDevRequestType type)
+{
+ uint32_t requestSize;
+ if (!req)
+ return VERR_INVALID_PARAMETER;
+ requestSize = (uint32_t)vmmdevGetRequestSize(type);
+ if (!requestSize)
+ return VERR_INVALID_PARAMETER;
+ req->size = requestSize;
+ req->version = VMMDEV_REQUEST_HEADER_VERSION;
+ req->requestType = type;
+ req->rc = VERR_GENERAL_FAILURE;
+ req->reserved1 = 0;
+ req->reserved2 = 0;
+ return VINF_SUCCESS;
+}
+
+/** @} */
+
+
+/**
+ * VBVA command header.
+ *
+ * @todo Where does this fit in?
+ */
+#pragma pack(1) /* unnecessary */
+typedef struct VBVACMDHDR
+{
+ /** Coordinates of affected rectangle. */
+ int16_t x;
+ int16_t y;
+ uint16_t w;
+ uint16_t h;
+} VBVACMDHDR;
+#pragma pack()
+
+/** @name VBVA ring defines.
+ *
+ * The VBVA ring buffer is suitable for transferring large (< 2GB) amount of
+ * data. For example big bitmaps which do not fit to the buffer.
+ *
+ * Guest starts writing to the buffer by initializing a record entry in the
+ * aRecords queue. VBVA_F_RECORD_PARTIAL indicates that the record is being
+ * written. As data is written to the ring buffer, the guest increases off32End
+ * for the record.
+ *
+ * The host reads the aRecords on flushes and processes all completed records.
+ * When host encounters situation when only a partial record presents and
+ * cbRecord & ~VBVA_F_RECORD_PARTIAL >= VBVA_RING_BUFFER_SIZE -
+ * VBVA_RING_BUFFER_THRESHOLD, the host fetched all record data and updates
+ * off32Head. After that on each flush the host continues fetching the data
+ * until the record is completed.
+ *
+ */
+#define VBVA_RING_BUFFER_SIZE (_4M - _1K)
+#define VBVA_RING_BUFFER_THRESHOLD (4 * _1K)
+
+#define VBVA_MAX_RECORDS (64)
+
+#define VBVA_F_MODE_ENABLED (0x00000001)
+#define VBVA_F_MODE_VRDP (0x00000002)
+#define VBVA_F_MODE_VRDP_RESET (0x00000004)
+#define VBVA_F_MODE_VRDP_ORDER_MASK (0x00000008)
+
+#define VBVA_F_RECORD_PARTIAL (0x80000000)
+/** @} */
+
+/**
+ * VBVA record.
+ */
+typedef struct VBVARECORD
+{
+ /** The length of the record. Changed by guest. */
+ uint32_t cbRecord;
+} VBVARECORD;
+AssertCompileSize(VBVARECORD, 4);
+
+
+/**
+ * VBVA memory layout.
+ *
+ * This is a subsection of the VMMDevMemory structure.
+ */
+#pragma pack(1) /* paranoia */
+typedef struct VBVAMEMORY
+{
+ /** VBVA_F_MODE_*. */
+ uint32_t fu32ModeFlags;
+
+ /** The offset where the data start in the buffer. */
+ uint32_t off32Data;
+ /** The offset where next data must be placed in the buffer. */
+ uint32_t off32Free;
+
+ /** The ring buffer for data. */
+ uint8_t au8RingBuffer[VBVA_RING_BUFFER_SIZE];
+
+ /** The queue of record descriptions. */
+ VBVARECORD aRecords[VBVA_MAX_RECORDS];
+ uint32_t indexRecordFirst;
+ uint32_t indexRecordFree;
+
+ /** RDP orders supported by the client. The guest reports only them
+ * and falls back to DIRTY rects for not supported ones.
+ *
+ * (1 << VBVA_VRDP_*)
+ */
+ uint32_t fu32SupportedOrders;
+
+} VBVAMEMORY;
+#pragma pack()
+AssertCompileSize(VBVAMEMORY, 12 + (_4M-_1K) + 4*64 + 12);
+
+
+/**
+ * The layout of VMMDEV RAM region that contains information for guest.
+ */
+#pragma pack(1) /* paranoia */
+typedef struct VMMDevMemory
+{
+ /** The size of this structure. */
+ uint32_t u32Size;
+ /** The structure version. (VMMDEV_MEMORY_VERSION) */
+ uint32_t u32Version;
+
+ union
+ {
+ struct
+ {
+ /** Flag telling that VMMDev set the IRQ and acknowlegment is required */
+ bool fHaveEvents;
+ } V1_04;
+
+ struct
+ {
+ /** Pending events flags, set by host. */
+ uint32_t u32HostEvents;
+ /** Mask of events the guest wants to see, set by guest. */
+ uint32_t u32GuestEventMask;
+ } V1_03;
+ } V;
+
+ VBVAMEMORY vbvaMemory;
+
+} VMMDevMemory;
+AssertCompileSize(VMMDevMemory, 8+8 + (12 + (_4M-_1K) + 4*64 + 12) );
+#pragma pack()
+
+/** Version of VMMDevMemory structure (VMMDevMemory::u32Version). */
+#define VMMDEV_MEMORY_VERSION (1)
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/VMMDev2.h b/include/VBox/VMMDev2.h
new file mode 100644
index 00000000..3a8ebbed
--- /dev/null
+++ b/include/VBox/VMMDev2.h
@@ -0,0 +1,114 @@
+/** @file
+ * Virtual Device for Guest <-> VMM/Host communication, Mixed Up Mess. (ADD,DEV)
+ */
+
+/*
+ * Copyright (C) 2006-2009 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 ___VBox_VMMDev2_h
+#define ___VBox_VMMDev2_h
+
+#include <iprt/assert.h>
+
+/**
+ * Seamless mode.
+ *
+ * Used by VbglR3SeamlessWaitEvent
+ *
+ * @ingroup grp_vmmdev_req
+ *
+ * @todo DARN! DARN! DARN! Who forgot to do the 32-bit hack here???
+ * FIXME! XXX!
+ *
+ * We will now have to carefully check how our compilers have treated this
+ * flag. If any are compressing it into a byte type, we'll have to check
+ * how the request memory is initialized. If we are 104% sure it's ok to
+ * expand it, we'll expand it. If not, we must redefine the field to a
+ * uint8_t and a 3 byte padding.
+ */
+typedef enum
+{
+ VMMDev_Seamless_Disabled = 0, /**< normal mode; entire guest desktop displayed. */
+ VMMDev_Seamless_Visible_Region = 1, /**< visible region mode; only top-level guest windows displayed. */
+ VMMDev_Seamless_Host_Window = 2 /**< windowed mode; each top-level guest window is represented in a host window. */
+} VMMDevSeamlessMode;
+
+/**
+ * CPU event types.
+ *
+ * Used by VbglR3CpuHotplugWaitForEvent
+ *
+ * @ingroup grp_vmmdev_req
+ */
+typedef enum
+{
+ VMMDevCpuEventType_Invalid = 0,
+ VMMDevCpuEventType_None = 1,
+ VMMDevCpuEventType_Plug = 2,
+ VMMDevCpuEventType_Unplug = 3,
+ VMMDevCpuEventType_SizeHack = 0x7fffffff
+} VMMDevCpuEventType;
+
+/**
+ * HGCM service location types.
+ * @ingroup grp_vmmdev_req
+ */
+typedef enum
+{
+ VMMDevHGCMLoc_Invalid = 0,
+ VMMDevHGCMLoc_LocalHost = 1,
+ VMMDevHGCMLoc_LocalHost_Existing = 2,
+ VMMDevHGCMLoc_SizeHack = 0x7fffffff
+} HGCMServiceLocationType;
+AssertCompileSize(HGCMServiceLocationType, 4);
+
+/**
+ * HGCM host service location.
+ * @ingroup grp_vmmdev_req
+ */
+typedef struct
+{
+ char achName[128]; /**< This is really szName. */
+} HGCMServiceLocationHost;
+AssertCompileSize(HGCMServiceLocationHost, 128);
+
+/**
+ * HGCM service location.
+ * @ingroup grp_vmmdev_req
+ */
+typedef struct HGCMSERVICELOCATION
+{
+ /** Type of the location. */
+ HGCMServiceLocationType type;
+
+ union
+ {
+ HGCMServiceLocationHost host;
+ } u;
+} HGCMServiceLocation;
+AssertCompileSize(HGCMServiceLocation, 128+4);
+
+/* forward declarations: */
+struct VMMDevReqMousePointer;
+struct VMMDevMemory;
+
+#endif
+
diff --git a/include/VBox/VMMDevTesting.h b/include/VBox/VMMDevTesting.h
new file mode 100644
index 00000000..7bc4c7a3
--- /dev/null
+++ b/include/VBox/VMMDevTesting.h
@@ -0,0 +1,122 @@
+/* $Id: VMMDevTesting.h $ */
+/** @file
+ * VMMDev - Testing Extensions.
+ */
+
+/*
+ * Copyright (C) 2010-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 ___VBox_VMMDevTesting_h
+#define ___VBox_VMMDevTesting_h
+
+#include <VBox/types.h>
+
+/** The base address of the MMIO range used for testing.
+ * This is intentionally put at the 2nd page above 1M so that it can be
+ * accessed from both real (!A20) and protected mode. */
+#define VMMDEV_TESTING_MMIO_BASE UINT32_C(0x00101000)
+/** The size of the MMIO range used for testing. */
+#define VMMDEV_TESTING_MMIO_SIZE UINT32_C(0x00001000)
+/** The NOP MMIO register - 124 RW. */
+#define VMMDEV_TESTING_MMIO_NOP (VMMDEV_TESTING_MMIO_BASE + 0x000)
+/** The XXX MMIO register - 124 RW. */
+#define VMMDEV_TESTING_MMIO_TODO (VMMDEV_TESTING_MMIO_BASE + 0x004)
+/** The real mode selector to use.
+ * @remarks Requires that the A20 gate is enabled. */
+#define VMMDEV_TESTING_MMIO_RM_SEL 0xffff
+/** Calculate the real mode offset of a MMIO register. */
+#define VMMDEV_TESTING_MMIO_RM_OFF(val) ((val) - 0xffff0)
+
+/** The base port of the I/O range used for testing. */
+#define VMMDEV_TESTING_IOPORT_BASE 0x0510
+/** The number of I/O ports reserved for testing. */
+#define VMMDEV_TESTING_IOPORT_COUNT 0x0010
+/** The NOP I/O port - 1,2,4 RW. */
+#define VMMDEV_TESTING_IOPORT_NOP (VMMDEV_TESTING_IOPORT_BASE + 0)
+/** The low nanosecond timestamp - 4 RO. */
+#define VMMDEV_TESTING_IOPORT_TS_LOW (VMMDEV_TESTING_IOPORT_BASE + 1)
+/** The high nanosecond timestamp - 4 RO. Read this after the low one! */
+#define VMMDEV_TESTING_IOPORT_TS_HIGH (VMMDEV_TESTING_IOPORT_BASE + 2)
+/** Command register usually used for preparing the data register - 4 WO. */
+#define VMMDEV_TESTING_IOPORT_CMD (VMMDEV_TESTING_IOPORT_BASE + 3)
+/** Data register which use depends on the current command - 1s, 4 WO. */
+#define VMMDEV_TESTING_IOPORT_DATA (VMMDEV_TESTING_IOPORT_BASE + 4)
+
+/** @name Commands.
+ * @{ */
+/** Initialize test, sending name (zero terminated string). (RTTestCreate) */
+#define VMMDEV_TESTING_CMD_INIT UINT32_C(0xcab1e000)
+/** Test done, no data. (RTTestSummaryAndDestroy) */
+#define VMMDEV_TESTING_CMD_TERM UINT32_C(0xcab1e001)
+/** Start a new sub-test, sending name (zero terminated string). (RTTestSub) */
+#define VMMDEV_TESTING_CMD_SUB_NEW UINT32_C(0xcab1e002)
+/** Sub-test is done, sending 32-bit error count for it. (RTTestDone) */
+#define VMMDEV_TESTING_CMD_SUB_DONE UINT32_C(0xcab1e003)
+/** Report a failure, sending reason (zero terminated string). (RTTestFailed) */
+#define VMMDEV_TESTING_CMD_FAILED UINT32_C(0xcab1e004)
+/** Report a value, sending the 64-bit value (2x4), the 32-bit unit (4), and
+ * finally the name (zero terminated string). (RTTestValue) */
+#define VMMDEV_TESTING_CMD_VALUE UINT32_C(0xcab1e005)
+/** Report a failure, sending reason (zero terminated string). (RTTestSkipped) */
+#define VMMDEV_TESTING_CMD_SKIPPED UINT32_C(0xcab1e006)
+/** Report a value found in a VMM register, sending a string on the form
+ * "value-name:register-name". */
+#define VMMDEV_TESTING_CMD_VALUE_REG UINT32_C(0xcab1e007)
+/** @} */
+
+/** @name Value units
+ * @{ */
+#define VMMDEV_TESTING_UNIT_PCT UINT8_C(0x01) /**< Percentage. */
+#define VMMDEV_TESTING_UNIT_BYTES UINT8_C(0x02) /**< Bytes. */
+#define VMMDEV_TESTING_UNIT_BYTES_PER_SEC UINT8_C(0x03) /**< Bytes per second. */
+#define VMMDEV_TESTING_UNIT_KILOBYTES UINT8_C(0x04) /**< Kilobytes. */
+#define VMMDEV_TESTING_UNIT_KILOBYTES_PER_SEC UINT8_C(0x05) /**< Kilobytes per second. */
+#define VMMDEV_TESTING_UNIT_MEGABYTES UINT8_C(0x06) /**< Megabytes. */
+#define VMMDEV_TESTING_UNIT_MEGABYTES_PER_SEC UINT8_C(0x07) /**< Megabytes per second. */
+#define VMMDEV_TESTING_UNIT_PACKETS UINT8_C(0x08) /**< Packets. */
+#define VMMDEV_TESTING_UNIT_PACKETS_PER_SEC UINT8_C(0x09) /**< Packets per second. */
+#define VMMDEV_TESTING_UNIT_FRAMES UINT8_C(0x0a) /**< Frames. */
+#define VMMDEV_TESTING_UNIT_FRAMES_PER_SEC UINT8_C(0x0b) /**< Frames per second. */
+#define VMMDEV_TESTING_UNIT_OCCURRENCES UINT8_C(0x0c) /**< Occurrences. */
+#define VMMDEV_TESTING_UNIT_OCCURRENCES_PER_SEC UINT8_C(0x0d) /**< Occurrences per second. */
+#define VMMDEV_TESTING_UNIT_CALLS UINT8_C(0x0e) /**< Calls. */
+#define VMMDEV_TESTING_UNIT_CALLS_PER_SEC UINT8_C(0x0f) /**< Calls per second. */
+#define VMMDEV_TESTING_UNIT_ROUND_TRIP UINT8_C(0x10) /**< Round trips. */
+#define VMMDEV_TESTING_UNIT_SECS UINT8_C(0x11) /**< Seconds. */
+#define VMMDEV_TESTING_UNIT_MS UINT8_C(0x12) /**< Milliseconds. */
+#define VMMDEV_TESTING_UNIT_NS UINT8_C(0x13) /**< Nanoseconds. */
+#define VMMDEV_TESTING_UNIT_NS_PER_CALL UINT8_C(0x14) /**< Nanoseconds per call. */
+#define VMMDEV_TESTING_UNIT_NS_PER_FRAME UINT8_C(0x15) /**< Nanoseconds per frame. */
+#define VMMDEV_TESTING_UNIT_NS_PER_OCCURRENCE UINT8_C(0x16) /**< Nanoseconds per occurrence. */
+#define VMMDEV_TESTING_UNIT_NS_PER_PACKET UINT8_C(0x17) /**< Nanoseconds per frame. */
+#define VMMDEV_TESTING_UNIT_NS_PER_ROUND_TRIP UINT8_C(0x18) /**< Nanoseconds per round trip. */
+#define VMMDEV_TESTING_UNIT_INSTRS UINT8_C(0x19) /**< Instructions. */
+#define VMMDEV_TESTING_UNIT_INSTRS_PER_SEC UINT8_C(0x1a) /**< Instructions per second. */
+#define VMMDEV_TESTING_UNIT_NONE UINT8_C(0x1b) /**< No unit. */
+/** @} */
+
+
+/** What the NOP accesses returns. */
+#define VMMDEV_TESTING_NOP_RET UINT32_C(0x64726962) /* bird */
+
+#endif
+
diff --git a/include/VBox/VMMDevTesting.mac b/include/VBox/VMMDevTesting.mac
new file mode 100644
index 00000000..105f7bea
--- /dev/null
+++ b/include/VBox/VMMDevTesting.mac
@@ -0,0 +1,52 @@
+%ifndef ___VBox_VMMDevTesting_h
+%define ___VBox_VMMDevTesting_h
+%define VMMDEV_TESTING_MMIO_BASE 0x00101000
+%define VMMDEV_TESTING_MMIO_SIZE 0x00001000
+%define VMMDEV_TESTING_MMIO_NOP (VMMDEV_TESTING_MMIO_BASE + 0x000)
+%define VMMDEV_TESTING_MMIO_TODO (VMMDEV_TESTING_MMIO_BASE + 0x004)
+%define VMMDEV_TESTING_MMIO_RM_SEL 0xffff
+%define VMMDEV_TESTING_MMIO_RM_OFF(val) ((val) - 0xffff0)
+%define VMMDEV_TESTING_IOPORT_BASE 0x0510
+%define VMMDEV_TESTING_IOPORT_COUNT 0x0010
+%define VMMDEV_TESTING_IOPORT_NOP (VMMDEV_TESTING_IOPORT_BASE + 0)
+%define VMMDEV_TESTING_IOPORT_TS_LOW (VMMDEV_TESTING_IOPORT_BASE + 1)
+%define VMMDEV_TESTING_IOPORT_TS_HIGH (VMMDEV_TESTING_IOPORT_BASE + 2)
+%define VMMDEV_TESTING_IOPORT_CMD (VMMDEV_TESTING_IOPORT_BASE + 3)
+%define VMMDEV_TESTING_IOPORT_DATA (VMMDEV_TESTING_IOPORT_BASE + 4)
+%define VMMDEV_TESTING_CMD_INIT 0xcab1e000
+%define VMMDEV_TESTING_CMD_TERM 0xcab1e001
+%define VMMDEV_TESTING_CMD_SUB_NEW 0xcab1e002
+%define VMMDEV_TESTING_CMD_SUB_DONE 0xcab1e003
+%define VMMDEV_TESTING_CMD_FAILED 0xcab1e004
+%define VMMDEV_TESTING_CMD_VALUE 0xcab1e005
+%define VMMDEV_TESTING_CMD_SKIPPED 0xcab1e006
+%define VMMDEV_TESTING_CMD_VALUE_REG 0xcab1e007
+%define VMMDEV_TESTING_UNIT_PCT 0x01
+%define VMMDEV_TESTING_UNIT_BYTES 0x02
+%define VMMDEV_TESTING_UNIT_BYTES_PER_SEC 0x03
+%define VMMDEV_TESTING_UNIT_KILOBYTES 0x04
+%define VMMDEV_TESTING_UNIT_KILOBYTES_PER_SEC 0x05
+%define VMMDEV_TESTING_UNIT_MEGABYTES 0x06
+%define VMMDEV_TESTING_UNIT_MEGABYTES_PER_SEC 0x07
+%define VMMDEV_TESTING_UNIT_PACKETS 0x08
+%define VMMDEV_TESTING_UNIT_PACKETS_PER_SEC 0x09
+%define VMMDEV_TESTING_UNIT_FRAMES 0x0a
+%define VMMDEV_TESTING_UNIT_FRAMES_PER_SEC 0x0b
+%define VMMDEV_TESTING_UNIT_OCCURRENCES 0x0c
+%define VMMDEV_TESTING_UNIT_OCCURRENCES_PER_SEC 0x0d
+%define VMMDEV_TESTING_UNIT_CALLS 0x0e
+%define VMMDEV_TESTING_UNIT_CALLS_PER_SEC 0x0f
+%define VMMDEV_TESTING_UNIT_ROUND_TRIP 0x10
+%define VMMDEV_TESTING_UNIT_SECS 0x11
+%define VMMDEV_TESTING_UNIT_MS 0x12
+%define VMMDEV_TESTING_UNIT_NS 0x13
+%define VMMDEV_TESTING_UNIT_NS_PER_CALL 0x14
+%define VMMDEV_TESTING_UNIT_NS_PER_FRAME 0x15
+%define VMMDEV_TESTING_UNIT_NS_PER_OCCURRENCE 0x16
+%define VMMDEV_TESTING_UNIT_NS_PER_PACKET 0x17
+%define VMMDEV_TESTING_UNIT_NS_PER_ROUND_TRIP 0x18
+%define VMMDEV_TESTING_UNIT_INSTRS 0x19
+%define VMMDEV_TESTING_UNIT_INSTRS_PER_SEC 0x1a
+%define VMMDEV_TESTING_UNIT_NONE 0x1b
+%define VMMDEV_TESTING_NOP_RET 0x64726962
+%endif
diff --git a/include/VBox/apic.h b/include/VBox/apic.h
new file mode 100644
index 00000000..2d0b8a6f
--- /dev/null
+++ b/include/VBox/apic.h
@@ -0,0 +1,58 @@
+/** @file
+ * X86 (and AMD64) Local APIC registers (VMM,++).
+ *
+ * apic.mac is generated from this file by running 'kmk incs' in the root.
+ */
+
+/*
+ * Copyright (C) 2010-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_apic_h
+#define ___VBox_apic_h
+
+#include <iprt/types.h>
+
+#define APIC_REG_VERSION 0x0030
+#define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff)
+#define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16)
+
+/* defines according to Figure 10-8 of the Intel Software Developers Manual Vol 3A */
+#define APIC_REG_LVT_LINT0 0x0350
+#define APIC_REG_LVT_LINT1 0x0360
+#define APIC_REG_LVT_ERR 0x0370
+#define APIC_REG_LVT_PC 0x0340
+#define APIC_REG_LVT_THMR 0x0330
+#define APIC_REG_LVT_MODE_MASK (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+#define APIC_REG_LVT_MODE_FIXED 0
+#define APIC_REG_LVT_MODE_NMI (RT_BIT(10))
+#define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+#define APIC_REG_LVT_PIN_POLARIY RT_BIT(13)
+#define APIC_REG_LVT_REMOTE_IRR RT_BIT(14)
+#define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15)
+#define APIC_REG_LVT_MASKED RT_BIT(16)
+
+DECLINLINE(uint32_t) ApicRegRead(void *pvBase, uint32_t offReg)
+{
+ return *(const volatile uint32_t *)((uintptr_t)pvBase + offReg);
+}
+
+#endif
+
diff --git a/include/VBox/apic.mac b/include/VBox/apic.mac
new file mode 100644
index 00000000..57eb7ca8
--- /dev/null
+++ b/include/VBox/apic.mac
@@ -0,0 +1,19 @@
+%ifndef ___VBox_apic_h
+%define ___VBox_apic_h
+%define APIC_REG_VERSION 0x0030
+%define APIC_REG_VERSION_GET_VER(u32) (u32 & 0xff)
+%define APIC_REG_VERSION_GET_MAX_LVT(u32) ((u32 & 0xff0000) >> 16)
+%define APIC_REG_LVT_LINT0 0x0350
+%define APIC_REG_LVT_LINT1 0x0360
+%define APIC_REG_LVT_ERR 0x0370
+%define APIC_REG_LVT_PC 0x0340
+%define APIC_REG_LVT_THMR 0x0330
+%define APIC_REG_LVT_MODE_MASK (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+%define APIC_REG_LVT_MODE_FIXED 0
+%define APIC_REG_LVT_MODE_NMI (RT_BIT(10))
+%define APIC_REG_LVT_MODE_EXTINT (RT_BIT(8)|RT_BIT(9)|RT_BIT(10))
+%define APIC_REG_LVT_PIN_POLARIY RT_BIT(13)
+%define APIC_REG_LVT_REMOTE_IRR RT_BIT(14)
+%define APIC_REG_LVT_LEVEL_TRIGGER RT_BIT(15)
+%define APIC_REG_LVT_MASKED RT_BIT(16)
+%endif
diff --git a/include/VBox/asmdefs.mac b/include/VBox/asmdefs.mac
new file mode 100644
index 00000000..96b0e52d
--- /dev/null
+++ b/include/VBox/asmdefs.mac
@@ -0,0 +1,775 @@
+;; @file
+; VirtualBox YASM/NASM macros, structs, etc.
+;
+
+;
+; Copyright (C) 2006-2007 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; 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 ___VBox_asmdefs_mac
+%define ___VBox_asmdefs_mac
+
+;; @def VBOX_WITH_STATISTICS
+; When defined all statistics will be included in the build.
+; This is enabled by default in all debug builds.
+%ifndef VBOX_WITH_STATISTICS
+ %ifdef DEBUG
+ %define VBOX_WITH_STATISTICS
+ %endif
+%endif
+
+%include "iprt/asmdefs.mac"
+
+;; @def VBOX_STRICT
+; Enables strict checks in the VBox code.
+; This is enabled by default in all debug builds and when RT_STRICT is enabled.
+%ifndef VBOX_STRICT
+ %ifdef DEBUG
+ %define VBOX_STRICT
+ %endif
+ %ifdef RT_STRICT
+ %define VBOX_STRICT
+ %endif
+%endif
+
+
+%ifndef VBOX_UART_BASE
+ %ifndef IPRT_UART_BASE
+ %define VBOX_UART_BASE 3f8h ; COM1 (see src/VBox/Runtime/common/log/logcom.cpp)
+ %else
+ %define VBOX_UART_BASE IPRT_UART_BASE
+ %endif
+%endif
+%ifndef VBOX_UART_RATE
+ %define VBOX_UART_RATE 12 ; 9600 bps
+%endif
+%ifndef VBOX_UART_PARAMS
+ %define VBOX_UART_PARAMS 00000011b ; 8n1
+%endif
+
+
+;;
+; Initializes the com port to 9600 baud 8n1.
+; al and dx are wasted.
+; @todo comport init doesn't quite work - therefore we no longer use this! :-/
+; @todo test again, it might work now...
+%macro COM_INIT 0
+ push eax
+ push edx
+
+ mov dx, VBOX_UART_BASE + 2
+ mov al, 0
+ out dx, al ; Disable the fifos (old software relies on it)
+
+ mov dx, VBOX_UART_BASE + 3
+ mov al, 80h
+ out dx, al ; make DL register accessible
+
+ mov dx, VBOX_UART_BASE
+ mov ax, VBOX_UART_RATE
+ out dx, al ; write low bps rate divisor
+
+ mov dx, VBOX_UART_BASE+1
+ xchg al, ah
+ out dx, al ; write high bps rate divisor
+
+ mov dx, VBOX_UART_BASE + 3
+ mov al, VBOX_UART_PARAMS
+ out dx, al ; write parameters & lock divisor
+
+ mov dx, VBOX_UART_BASE + 4 ; disconnect the UART from the int line
+ mov al, 0
+ out dx, al
+
+ mov dx, VBOX_UART_BASE + 1 ; disable UART ints
+ out dx, al
+
+ mov dx, VBOX_UART_BASE
+ in al, dx ; clear receiver
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx ; clear line status
+ inc dx
+ in al, dx ; clear modem status
+ mov dx, VBOX_UART_BASE + 2
+ in al, dx ; clear interrupts (IIR)
+
+ pop edx
+ pop eax
+%endmacro
+
+
+;;
+; writes string to comport
+; trashes nothing (uses stack though)
+
+%macro COM32_S_PRINT 1+
+ push esi
+ push ecx
+ push eax
+ mov ecx, edx
+ shl ecx, 16
+
+ call %%stringend
+%%string: db %1
+%%stringend:
+ pop esi
+ mov cx, %%stringend - %%string
+%%status:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status
+
+ mov al, [esi]
+ mov dx, VBOX_UART_BASE
+ out dx, al
+ inc esi
+ dec cx
+ jnz short %%status
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ shr ecx, 16
+ mov dx, cx
+ pop eax
+ pop ecx
+ pop esi
+%endmacro
+
+%macro COM64_S_PRINT 1+
+ push rsi
+ push rdx
+ push rcx
+ push rax
+
+ jmp %%stringend
+%%string: db %1
+%%stringend:
+ lea rsi, [%%string wrt rip]
+ mov cx, %%stringend - %%string
+%%status:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status
+
+ mov al, [rsi]
+ mov dx, VBOX_UART_BASE
+ out dx, al
+ inc rsi
+ dec cx
+ jnz short %%status
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ pop rax
+ pop rcx
+ pop rdx
+ pop rsi
+%endmacro
+
+%macro COM_S_PRINT 1+
+%ifdef RT_ARCH_AMD64
+ COM64_S_PRINT %1
+%else
+ COM32_S_PRINT %1
+%endif
+%endmacro
+
+
+;; Write char.
+; trashes esi
+%macro COM_CHAR 1
+ mov esi, eax
+ shl esi, 16
+ mov si, dx
+
+%%status:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status
+
+ mov al, %1
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ mov dx, si
+ shr esi, 16
+ mov ax, si
+%endmacro
+
+
+;; Write char.
+; trashes nothing (uses stack though)
+
+%macro COM32_S_CHAR 1
+ push eax
+ push edx
+
+%%status:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status
+
+ mov al, %1
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ pop edx
+ pop eax
+%endmacro
+
+%macro COM64_S_CHAR 1
+ push rax
+ push rdx
+
+%%status:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status
+
+ mov al, %1
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ pop rdx
+ pop rax
+%endmacro
+
+%macro COM_S_CHAR 1
+%ifdef RT_ARCH_AMD64
+ COM64_S_CHAR %1
+%else
+ COM32_S_CHAR %1
+%endif
+%endmacro
+
+
+;; Writes newline
+; trashes esi
+%macro COM_NEWLINE 0
+ mov esi, eax
+ shl esi, 16
+ mov si, dx
+
+%%status1:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status1
+
+ mov al, 13
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ mov al, 10
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status3:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status3
+
+ mov dx, si
+ shr esi, 16
+ mov ax, si
+%endmacro
+
+
+;; Writes newline
+; trashes nothing (uses stack though)
+
+%macro COM32_S_NEWLINE 0
+ push edx
+ push eax
+
+%%status1:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status1
+
+ mov al, 13
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ mov al, 10
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status3:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status3
+
+ pop eax
+ pop edx
+%endmacro
+
+%macro COM64_S_NEWLINE 0
+ push rdx
+ push rax
+
+%%status1:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status1
+
+ mov al, 13
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status2:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status2
+
+ mov al, 10
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+%%status3:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status3
+
+ pop rax
+ pop rdx
+%endmacro
+
+%macro COM_S_NEWLINE 0
+%ifdef RT_ARCH_AMD64
+ COM64_S_NEWLINE
+%else
+ COM32_S_NEWLINE
+%endif
+%endmacro
+
+
+;; Writes a dword from register to com port.
+; trashes esi, edi
+; edi cannot be used as input register
+%macro COM_DWORD_REG 1
+ mov edi, ebx ; save ebx
+ mov ebx, %1 ; get value we're supposed to print
+ mov esi, eax ; save ax
+ shl esi, 16 ; save dx
+ mov si, dx
+
+ mov ah, 8 ; loop counter.
+%%daloop:
+ rol ebx, 4 ; shift next digit to the front
+
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ dec ah
+ jnz short %%daloop ; loop
+
+ mov dx, si ; restore dx
+ shr esi, 16
+ mov ax, si ; restore ax
+ mov ebx, edi ; restore ebx
+%endmacro
+
+
+;; Writes a dword from register to com port.
+; trashes nothing (uses stack though)
+
+%macro COM32_S_DWORD_REG 1
+ push edx
+ push eax
+ push ebx
+
+ mov ebx, %1 ; get value we're supposed to print
+
+ mov ah, 8 ; loop counter.
+%%daloop:
+ rol ebx, 4 ; shift next digit to the front
+
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ dec ah
+ jnz short %%daloop ; loop
+
+ pop ebx
+ pop eax
+ pop edx
+%endmacro
+
+%macro COM64_S_DWORD_REG 1
+ push rdx
+ push rax
+ push rbx
+
+ mov ebx, %1 ; get value we're supposed to print
+
+ mov ah, 8 ; loop counter.
+%%daloop:
+ rol ebx, 4 ; shift next digit to the front
+
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ dec ah
+ jnz short %%daloop ; loop
+
+ pop rbx
+ pop rax
+ pop rdx
+%endmacro
+
+%macro COM_S_DWORD_REG 1
+%ifdef RT_ARCH_AMD64
+ COM64_S_DWORD_REG %1
+%else
+ COM32_S_DWORD_REG %1
+%endif
+%endmacro
+
+
+;; Writes a qword from register to com port.
+; trashes nothing (uses stack though)
+%macro COM64_S_QWORD_REG 1
+ push rdx
+ push rax
+ push rbx
+
+ mov rbx, %1 ; get value we're supposed to print
+
+ mov ah, 16 ; loop counter.
+%%daloop:
+ rol rbx, 4 ; shift next digit to the front
+
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ dec ah
+ jnz short %%daloop ; loop
+
+ pop rbx
+ pop rax
+ pop rdx
+%endmacro
+
+
+;; Writes a byte from register to com port.
+; trashes nothing (uses stack though)
+
+%macro COM32_S_BYTE_REG 1
+ push edx
+ push eax
+ push ebx
+
+ mov ebx, %1 ; get value we're supposed to print
+
+ mov ah, 2 ; loop counter.
+ ror ebx, 8 ; shift next digit to the front
+%%daloop:
+ rol ebx, 4 ; shift next digit to the front
+
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ dec ah
+ jnz short %%daloop ; loop
+
+ pop ebx
+ pop eax
+ pop edx
+%endmacro
+
+%macro COM64_S_BYTE_REG 1
+ push rdx
+ push rax
+ push rbx
+
+ mov ebx, %1 ; get value we're supposed to print
+
+ mov ah, 2 ; loop counter.
+ ror ebx, 8 ; shift next digit to the front
+%%daloop:
+ rol ebx, 4 ; shift next digit to the front
+
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ dec ah
+ jnz short %%daloop ; loop
+
+ pop rbx
+ pop rax
+ pop rdx
+%endmacro
+
+%macro COM_S_BYTE_REG 1
+%ifdef RT_ARCH_AMD64
+ COM64_S_BYTE_REG %1
+%else
+ COM32_S_BYTE_REG %1
+%endif
+%endmacro
+
+
+
+;; Writes a single hex digit from register to com port.
+; trashes nothing (uses stack though)
+
+%macro COM32_S_DIGIT_REG 1
+ push edx
+ push eax
+ push ebx
+
+ mov ebx, %1 ; get value we're supposed to print
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ pop ebx
+ pop eax
+ pop edx
+%endmacro
+
+%macro COM64_S_DIGIT_REG 1
+ push rdx
+ push rax
+ push rbx
+
+ mov ebx, %1 ; get value we're supposed to print
+%%status0:
+ mov dx, VBOX_UART_BASE + 5
+ in al, dx
+ test al, 20h
+ jz short %%status0
+
+ mov al, bl ; get next char
+ and al, 0fh
+ cmp al, 10
+ jae short %%hex ; yasm BUG! It sometimes generate a near jump here. YASMCHECK!
+ add al, '0'
+ jmp short %%print
+%%hex:
+ add al, 'a' - 10
+%%print:
+ mov dx, VBOX_UART_BASE
+ out dx, al
+
+ pop rbx
+ pop rax
+ pop rdx
+%endmacro
+
+%macro COM_S_DIGIT_REG 1
+%ifdef RT_ARCH_AMD64
+ COM64_S_DIGIT_REG %1
+%else
+ COM32_S_DIGIT_REG %1
+%endif
+%endmacro
+
+
+;;
+; Loops for a while.
+; ecx is trashed.
+%macro LOOP_A_WHILE 0
+
+ xor ecx, ecx
+ dec ecx
+ shr ecx, 1
+%%looplabel:
+ nop
+ nop
+ nop
+ dec ecx
+ jnz short %%looplabel
+
+%endmacro
+
+
+;;
+; Loops for a short while.
+; ecx is trashed.
+%macro LOOP_SHORT_WHILE 0
+
+ xor ecx, ecx
+ dec ecx
+ shr ecx, 4
+%%looplabel:
+ nop
+ nop
+ dec ecx
+ jnz short %%looplabel
+
+%endmacro
+
+%endif
+
diff --git a/include/VBox/bioslogo.h b/include/VBox/bioslogo.h
new file mode 100644
index 00000000..b78d1cae
--- /dev/null
+++ b/include/VBox/bioslogo.h
@@ -0,0 +1,90 @@
+/* $Id: bioslogo.h $ */
+/** @file
+ * BiosLogo - The Private BIOS Logo Interface. (DEV)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_BiosLogo_h
+#define ___VBox_BiosLogo_h
+
+#ifndef VBOX_PC_BIOS
+# include <iprt/types.h>
+# include <iprt/assert.h>
+#endif
+
+/** @defgroup grp_bios_logo The Private BIOS Logo Interface.
+ * @remark All this is currently duplicated in logo.c.
+ * @internal
+ * @{
+ */
+
+/** The extra port which is used to show the BIOS logo. */
+#define LOGO_IO_PORT 0x3b8
+
+/** The BIOS logo fade in/fade out steps. */
+#define LOGO_SHOW_STEPS 16
+
+/** @name The BIOS logo commands.
+ * @{
+ */
+#define LOGO_CMD_NOP 0
+#define LOGO_CMD_SET_OFFSET 0x100
+#define LOGO_CMD_SHOW_BMP 0x200
+/** @} */
+
+/**
+ * PC Bios logo data structure.
+ */
+typedef struct LOGOHDR
+{
+ /** Signature (LOGO_HDR_MAGIC/0x66BB). */
+ uint16_t u16Signature;
+ /** Logo time (msec). */
+ uint16_t u16LogoMillies;
+ /** Fade in - boolean. */
+ uint8_t fu8FadeIn;
+ /** Fade out - boolean. */
+ uint8_t fu8FadeOut;
+ /** Show setup - boolean. */
+ uint8_t fu8ShowBootMenu;
+ /** Reserved / padding. */
+ uint8_t u8Reserved;
+ /** Logo file size. */
+ uint32_t cbLogo;
+} LOGOHDR;
+#ifndef VBOX_PC_BIOS
+AssertCompileSize(LOGOHDR, 12);
+#endif
+/** Pointer to a PC Biso logo header. */
+typedef LOGOHDR *PLOGOHDR;
+
+/** The value of the LOGOHDR::u16Signature field. */
+#define LOGO_HDR_MAGIC 0x66BB
+
+/** The value which will switch you the default logo. */
+#define LOGO_DEFAULT_LOGO 0xFFFF
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/cdefs.h b/include/VBox/cdefs.h
new file mode 100644
index 00000000..652f7f6b
--- /dev/null
+++ b/include/VBox/cdefs.h
@@ -0,0 +1,439 @@
+/** @file
+ * VirtualBox - Common C and C++ definition.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_cdefs_h
+#define ___VBox_cdefs_h
+
+#include <iprt/cdefs.h>
+
+
+/** @def VBOX_WITH_STATISTICS
+ * When defined all statistics will be included in the build.
+ * This is enabled by default in all debug builds.
+ */
+#ifndef VBOX_WITH_STATISTICS
+# ifdef DEBUG
+# define VBOX_WITH_STATISTICS
+# endif
+#endif
+
+/** @def VBOX_STRICT
+ * Alias for RT_STRICT.
+ */
+#ifdef RT_STRICT
+# ifndef VBOX_STRICT
+# define VBOX_STRICT
+# endif
+#endif
+
+
+/*
+ * Shut up DOXYGEN warnings and guide it properly thru the code.
+ */
+#ifdef DOXYGEN_RUNNING
+#define VBOX_WITH_STATISTICS
+#define VBOX_STRICT
+#define IN_DBG
+#define IN_DIS
+#define IN_INTNET_R0
+#define IN_INTNET_R3
+#define IN_PCIRAW_R0
+#define IN_PCIRAW_R3
+#define IN_REM_R3
+#define IN_SUP_R0
+#define IN_SUP_R3
+#define IN_SUP_RC
+#define IN_SUP_STATIC
+#define IN_USBLIB
+#define IN_VBOXDDU
+#define IN_VMM_RC
+#define IN_VMM_R0
+#define IN_VMM_R3
+#define IN_VMM_STATIC
+#endif
+
+
+
+
+/** @def VBOXCALL
+ * The standard calling convention for VBOX interfaces.
+ */
+#define VBOXCALL RTCALL
+
+
+
+/** @def IN_DIS
+ * Used to indicate whether we're inside the same link module as the
+ * disassembler.
+ */
+/** @def DISDECL(type)
+ * Disassembly export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#if defined(IN_DIS)
+# define DISDECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define DISDECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_DBG
+ * Used to indicate whether we're inside the same link module as the debugger
+ * console, gui, and related things (ring-3).
+ */
+/** @def DBGDECL(type)
+ * Debugger module export or import declaration.
+ * Functions declared using this exists only in R3 since the
+ * debugger modules is R3 only.
+ * @param type The return type of the function declaration.
+ */
+#if defined(IN_DBG_R3) || defined(IN_DBG)
+# define DBGDECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define DBGDECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_INTNET_R3
+ * Used to indicate whether we're inside the same link module as the Ring-3
+ * Internal Networking Service.
+ */
+/** @def INTNETR3DECL(type)
+ * Internal Networking Service export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_INTNET_R3
+# define INTNETR3DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define INTNETR3DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_INTNET_R0
+ * Used to indicate whether we're inside the same link module as the R0
+ * Internal Network Service.
+ */
+/** @def INTNETR0DECL(type)
+ * Internal Networking Service export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_INTNET_R0
+# define INTNETR0DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define INTNETR0DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_PCIRAW_R3
+ * Used to indicate whether we're inside the same link module as the Ring-3
+ * PCI passthrough support.
+ */
+/** @def PCIRAWR3DECL(type)
+ * PCI passthrough export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_PCIRAW_R3
+# define PCIRAWR3DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define PCIRAWR3DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_PCIRAW_R0
+ * Used to indicate whether we're inside the same link module as the R0
+ * PCI passthrough support.
+ */
+/** @def PCIRAWR0DECL(type)
+ * PCI passthroug export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_PCIRAW_R0
+# define PCIRAWR0DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define PCIRAWR0DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_REM_R3
+ * Used to indicate whether we're inside the same link module as
+ * the HC Ring-3 Recompiled Execution Manager.
+ */
+/** @def REMR3DECL(type)
+ * Recompiled Execution Manager HC Ring-3 export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_REM_R3
+# define REMR3DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define REMR3DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_SUP_R3
+ * Used to indicate whether we're inside the same link module as the Ring-3
+ * Support Library or not.
+ */
+/** @def SUPR3DECL(type)
+ * Support library export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_SUP_R3
+# define SUPR3DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define SUPR3DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_SUP_R0
+ * Used to indicate whether we're inside the same link module as the Ring-0
+ * Support Library or not.
+ */
+/** @def IN_SUP_STATIC
+ * Used to indicate that the Support Library is built or used as a static
+ * library.
+ */
+/** @def SUPR0DECL(type)
+ * Support library export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_SUP_R0
+# ifdef IN_SUP_STATIC
+# define SUPR0DECL(type) DECLHIDDEN(type) VBOXCALL
+# else
+# define SUPR0DECL(type) DECLEXPORT(type) VBOXCALL
+# endif
+#else
+# ifdef IN_SUP_STATIC
+# define SUPR0DECL(type) DECLHIDDEN(type) VBOXCALL
+# else
+# define SUPR0DECL(type) DECLIMPORT(type) VBOXCALL
+# endif
+#endif
+
+/** @def IN_SUP_RC
+ * Used to indicate whether we're inside the same link module as the RC Support
+ * Library or not.
+ */
+/** @def SUPRCDECL(type)
+ * Support library export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_SUP_RC
+# define SUPRCDECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define SUPRCDECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_SUP_R0
+ * Used to indicate whether we're inside the same link module as the Ring-0
+ * Support Library or not.
+ */
+/** @def SUPR0DECL(type)
+ * Support library export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#if defined(IN_SUP_R0) || defined(IN_SUP_R3) || defined(IN_SUP_RC)
+# define SUPDECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define SUPDECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_USBLIB
+ * Used to indicate whether we're inside the same link module as the USBLib.
+ */
+/** @def USBLIB_DECL
+ * USBLIB export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_RING0
+# define USBLIB_DECL(type) type VBOXCALL
+#elif defined(IN_USBLIB)
+# define USBLIB_DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define USBLIB_DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+
+/** @def IN_VMM_STATIC
+ * Used to indicate that the virtual machine monitor is built or used as a
+ * static library.
+ */
+/** @def IN_VMM_R3
+ * Used to indicate whether we're inside the same link module as the ring 3 part of the
+ * virtual machine monitor or not.
+ */
+/** @def VMMR3DECL
+ * Ring-3 VMM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_R3
+# ifdef IN_VMM_STATIC
+# define VMMR3DECL(type) DECLHIDDEN(type) VBOXCALL
+# else
+# define VMMR3DECL(type) DECLEXPORT(type) VBOXCALL
+# endif
+#elif defined(IN_RING3)
+# ifdef IN_VMM_STATIC
+# define VMMR3DECL(type) DECLHIDDEN(type) VBOXCALL
+# else
+# define VMMR3DECL(type) DECLIMPORT(type) VBOXCALL
+# endif
+#else
+# define VMMR3DECL(type) DECL_INVALID(type)
+#endif
+
+/** @def IN_VMM_R0
+ * Used to indicate whether we're inside the same link module as the ring-0 part
+ * of the virtual machine monitor or not.
+ */
+/** @def VMMR0DECL
+ * Ring-0 VMM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_R0
+# define VMMR0DECL(type) DECLEXPORT(type) VBOXCALL
+#elif defined(IN_RING0)
+# define VMMR0DECL(type) DECLIMPORT(type) VBOXCALL
+#else
+# define VMMR0DECL(type) DECL_INVALID(type)
+#endif
+
+/** @def IN_VMM_RC
+ * Used to indicate whether we're inside the same link module as the raw-mode
+ * context part of the virtual machine monitor or not.
+ */
+/** @def VMMRCDECL
+ * Raw-mode context VMM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_RC
+# define VMMRCDECL(type) DECLEXPORT(type) VBOXCALL
+#elif defined(IN_RC)
+# define VMMRCDECL(type) DECLIMPORT(type) VBOXCALL
+#else
+# define VMMRCDECL(type) DECL_INVALID(type)
+#endif
+
+/** @def VMMRZDECL
+ * Ring-0 and Raw-mode context VMM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#if defined(IN_VMM_R0) || defined(IN_VMM_RC)
+# define VMMRZDECL(type) DECLEXPORT(type) VBOXCALL
+#elif defined(IN_RING0) || defined(IN_RZ)
+# define VMMRZDECL(type) DECLIMPORT(type) VBOXCALL
+#else
+# define VMMRZDECL(type) DECL_INVALID(type)
+#endif
+
+/** @def VMMDECL
+ * VMM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_STATIC
+# define VMMDECL(type) DECLHIDDEN(type) VBOXCALL
+#elif defined(IN_VMM_R3) || defined(IN_VMM_R0) || defined(IN_VMM_RC)
+# define VMMDECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define VMMDECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def VMM_INT_DECL
+ * VMM internal function.
+ * @param type The return type of the function declaration.
+ */
+#if defined(IN_VMM_R3) || defined(IN_VMM_R0) || defined(IN_VMM_RC)
+# define VMM_INT_DECL(type) DECLHIDDEN(type) VBOXCALL
+#else
+# define VMM_INT_DECL(type) DECL_INVALID(type)
+#endif
+
+/** @def VMMR3_INT_DECL
+ * VMM internal function, ring-3.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_R3
+# define VMMR3_INT_DECL(type) DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMR3_INT_DECL(type) DECL_INVALID(type)
+#endif
+
+/** @def VMMR0_INT_DECL
+ * VMM internal function, ring-0.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_R0
+# define VMMR0_INT_DECL(type) DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMR0_INT_DECL(type) DECL_INVALID(type)
+#endif
+
+/** @def VMMRC_INT_DECL
+ * VMM internal function, raw-mode context.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_RC
+# define VMMRC_INT_DECL(type) DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMRC_INT_DECL(type) DECL_INVALID(type)
+#endif
+
+/** @def VMMRZ_INT_DECL
+ * VMM internal function, ring-0 + raw-mode context.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VMM_RZ
+# define VMMRZ_INT_DECL(type) DECLHIDDEN(type) VBOXCALL
+#else
+# define VMMRZ_INT_DECL(type) DECL_INVALID(type)
+#endif
+
+
+
+/** @def IN_VBOXDDU
+ * Used to indicate whether we're inside the VBoxDDU shared object.
+ */
+/** @def VBOXDDU_DECL(type)
+ * VBoxDDU export or import (ring-3).
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_VBOXDDU
+# ifdef IN_VBOXDDU_STATIC
+# define VBOXDDU_DECL(type) type
+# else
+# define VBOXDDU_DECL(type) DECLEXPORT(type) VBOXCALL
+# endif
+#else
+# define VBOXDDU_DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+#endif
+
diff --git a/include/VBox/com/AutoLock.h b/include/VBox/com/AutoLock.h
new file mode 100644
index 00000000..9c700dd9
--- /dev/null
+++ b/include/VBox/com/AutoLock.h
@@ -0,0 +1,638 @@
+/** @file
+ *
+ * Automatic locks, implementation
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ____H_AUTOLOCK
+#define ____H_AUTOLOCK
+
+#include <iprt/types.h>
+
+// macros for automatic lock validation; these will amount to nothing
+// unless lock validation is enabled for the runtime
+#if defined(RT_LOCK_STRICT)
+# define VBOX_WITH_MAIN_LOCK_VALIDATION
+# define COMMA_LOCKVAL_SRC_POS , RT_SRC_POS
+# define LOCKVAL_SRC_POS_DECL RT_SRC_POS_DECL
+# define COMMA_LOCKVAL_SRC_POS_DECL , RT_SRC_POS_DECL
+# define LOCKVAL_SRC_POS_ARGS RT_SRC_POS_ARGS
+# define COMMA_LOCKVAL_SRC_POS_ARGS , RT_SRC_POS_ARGS
+#else
+# define COMMA_LOCKVAL_SRC_POS
+# define LOCKVAL_SRC_POS_DECL
+# define COMMA_LOCKVAL_SRC_POS_DECL
+# define LOCKVAL_SRC_POS_ARGS
+# define COMMA_LOCKVAL_SRC_POS_ARGS
+#endif
+
+namespace util
+{
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Order classes for lock validation
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * IPRT now has a sophisticated system of run-time locking classes to validate
+ * locking order. Since the Main code is handled by simpler minds, we want
+ * compile-time constants for simplicity, and we'll look up the run-time classes
+ * in AutoLock.cpp transparently. These are passed to the constructors of the
+ * LockHandle classes.
+ */
+enum VBoxLockingClass
+{
+ LOCKCLASS_NONE = 0,
+ LOCKCLASS_WEBSERVICE = 1, // highest order: webservice locks
+ LOCKCLASS_VIRTUALBOXOBJECT = 2, // highest order within Main itself: VirtualBox object lock
+ LOCKCLASS_HOSTOBJECT = 3, // Host object lock
+ LOCKCLASS_LISTOFMACHINES = 4, // list of machines in VirtualBox object
+ LOCKCLASS_MACHINEOBJECT = 5, // Machine object lock
+ LOCKCLASS_SNAPSHOTOBJECT = 6, // snapshot object locks
+ // (the snapshots tree, including the child pointers in Snapshot,
+ // is protected by the normal Machine object lock)
+ LOCKCLASS_MEDIUMQUERY = 7, // lock used to protect Machine::queryInfo
+ LOCKCLASS_LISTOFMEDIA = 8, // list of media (hard disks, DVDs, floppies) in VirtualBox object
+ LOCKCLASS_LISTOFOTHEROBJECTS = 9, // any other list of objects
+ LOCKCLASS_OTHEROBJECT = 10, // any regular object member variable lock
+ LOCKCLASS_PROGRESSLIST = 11, // list of progress objects in VirtualBox; no other object lock
+ // may be held after this!
+ LOCKCLASS_OBJECTSTATE = 12 // object state lock (handled by AutoCaller classes)
+};
+
+void InitAutoLockSystem();
+
+/**
+ * Check whether the current thread holds any locks in the given class
+ *
+ * @return true if any such locks are held, false otherwise. If the lock
+ * validator is not compiled in, always returns false.
+ * @param lockClass Which lock class to check.
+ */
+bool AutoLockHoldsLocksInClass(VBoxLockingClass lockClass);
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// LockHandle and friends
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Abstract base class for semaphore handles (RWLockHandle and WriteLockHandle).
+ * Don't use this directly, but this implements lock validation for them.
+ */
+class LockHandle
+{
+public:
+ LockHandle()
+ {}
+
+ virtual ~LockHandle()
+ {}
+
+ /**
+ * Returns @c true if the current thread holds a write lock on this
+ * read/write semaphore. Intended for debugging only.
+ */
+ virtual bool isWriteLockOnCurrentThread() const = 0;
+
+ /**
+ * Returns the current write lock level of this semaphore. The lock level
+ * determines the number of nested #lock() calls on the given semaphore
+ * handle.
+ *
+ * Note that this call is valid only when the current thread owns a write
+ * lock on the given semaphore handle and will assert otherwise.
+ */
+ virtual uint32_t writeLockLevel() const = 0;
+
+ virtual void lockWrite(LOCKVAL_SRC_POS_DECL) = 0;
+ virtual void unlockWrite() = 0;
+ virtual void lockRead(LOCKVAL_SRC_POS_DECL) = 0;
+ virtual void unlockRead() = 0;
+
+#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION
+ virtual const char* describe() const = 0;
+#endif
+
+private:
+ // prohibit copy + assignment
+ LockHandle(const LockHandle&);
+ LockHandle& operator=(const LockHandle&);
+};
+
+/**
+ * Full-featured read/write semaphore handle implementation.
+ *
+ * This is an auxiliary base class for classes that need full-featured
+ * read/write locking as described in the AutoWriteLock class documentation.
+ * Instances of classes inherited from this class can be passed as arguments to
+ * the AutoWriteLock and AutoReadLock constructors.
+ */
+class RWLockHandle : public LockHandle
+{
+public:
+ RWLockHandle(VBoxLockingClass lockClass);
+ virtual ~RWLockHandle();
+
+ virtual bool isWriteLockOnCurrentThread() const;
+
+ virtual void lockWrite(LOCKVAL_SRC_POS_DECL);
+ virtual void unlockWrite();
+ virtual void lockRead(LOCKVAL_SRC_POS_DECL);
+ virtual void unlockRead();
+
+ virtual uint32_t writeLockLevel() const;
+
+#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION
+ virtual const char* describe() const;
+#endif
+
+private:
+ struct Data;
+ Data *m;
+};
+
+/**
+ * Write-only semaphore handle implementation.
+ *
+ * This is an auxiliary base class for classes that need write-only (exclusive)
+ * locking and do not need read (shared) locking. This implementation uses a
+ * cheap and fast critical section for both lockWrite() and lockRead() methods
+ * which makes a lockRead() call fully equivalent to the lockWrite() call and
+ * therefore makes it pointless to use instahces of this class with
+ * AutoReadLock instances -- shared locking will not be possible anyway and
+ * any call to lock() will block if there are lock owners on other threads.
+ *
+ * Use with care only when absolutely sure that shared locks are not necessary.
+ */
+class WriteLockHandle : public LockHandle
+{
+public:
+ WriteLockHandle(VBoxLockingClass lockClass);
+ virtual ~WriteLockHandle();
+ virtual bool isWriteLockOnCurrentThread() const;
+
+ virtual void lockWrite(LOCKVAL_SRC_POS_DECL);
+ virtual void unlockWrite();
+ virtual void lockRead(LOCKVAL_SRC_POS_DECL);
+ virtual void unlockRead();
+ virtual uint32_t writeLockLevel() const;
+
+#ifdef VBOX_WITH_MAIN_LOCK_VALIDATION
+ virtual const char* describe() const;
+#endif
+
+private:
+ struct Data;
+ Data *m;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Lockable
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Lockable interface.
+ *
+ * This is an abstract base for classes that need read/write locking. Unlike
+ * RWLockHandle and other classes that makes the read/write semaphore a part of
+ * class data, this class allows subclasses to decide which semaphore handle to
+ * use.
+ */
+class Lockable
+{
+public:
+
+ /**
+ * Returns a pointer to a LockHandle used by AutoWriteLock/AutoReadLock
+ * for locking. Subclasses are allowed to return @c NULL -- in this case,
+ * the AutoWriteLock/AutoReadLock object constructed using an instance of
+ * such subclass will simply turn into no-op.
+ */
+ virtual LockHandle *lockHandle() const = 0;
+
+ /**
+ * Equivalent to <tt>#lockHandle()->isWriteLockOnCurrentThread()</tt>.
+ * Returns @c false if lockHandle() returns @c NULL.
+ */
+ bool isWriteLockOnCurrentThread()
+ {
+ LockHandle *h = lockHandle();
+ return h ? h->isWriteLockOnCurrentThread() : false;
+ }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutoLockBase
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Abstract base class for all autolocks.
+ *
+ * This cannot be used directly. Use AutoReadLock or AutoWriteLock or AutoMultiWriteLock2/3
+ * which directly and indirectly derive from this.
+ *
+ * In the implementation, the instance data contains a list of lock handles.
+ * The class provides some utility functions to help locking and unlocking
+ * them.
+ */
+
+class AutoLockBase
+{
+protected:
+ AutoLockBase(uint32_t cHandles
+ COMMA_LOCKVAL_SRC_POS_DECL);
+ AutoLockBase(uint32_t cHandles,
+ LockHandle *pHandle
+ COMMA_LOCKVAL_SRC_POS_DECL);
+ virtual ~AutoLockBase();
+
+ struct Data;
+ Data *m;
+
+ virtual void callLockImpl(LockHandle &l) = 0;
+ virtual void callUnlockImpl(LockHandle &l) = 0;
+
+ void callLockOnAllHandles();
+ void callUnlockOnAllHandles();
+
+ void cleanup();
+
+public:
+ void acquire();
+ void release();
+
+private:
+ // prohibit copy + assignment
+ AutoLockBase(const AutoLockBase&);
+ AutoLockBase& operator=(const AutoLockBase&);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutoReadLock
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Automatic read lock. Use this with a RWLockHandle to request a read/write
+ * semaphore in read mode. You can also use this with a WriteLockHandle but
+ * that makes little sense since they treat read mode like write mode.
+ *
+ * If constructed with a RWLockHandle or an instance of Lockable (which in
+ * practice means any VirtualBoxBase derivative), it autoamtically requests
+ * the lock in read mode and releases the read lock in the destructor.
+ */
+class AutoReadLock : public AutoLockBase
+{
+public:
+
+ /**
+ * Constructs a null instance that does not manage any read/write
+ * semaphore.
+ *
+ * Note that all method calls on a null instance are no-ops. This allows to
+ * have the code where lock protection can be selected (or omitted) at
+ * runtime.
+ */
+ AutoReadLock(LOCKVAL_SRC_POS_DECL)
+ : AutoLockBase(1,
+ NULL
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ { }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a read lock.
+ */
+ AutoReadLock(LockHandle *aHandle
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoLockBase(1,
+ aHandle
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a read lock.
+ */
+ AutoReadLock(LockHandle &aHandle
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoLockBase(1,
+ &aHandle
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a read lock.
+ */
+ AutoReadLock(const Lockable &aLockable
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoLockBase(1,
+ aLockable.lockHandle()
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a read lock.
+ */
+ AutoReadLock(const Lockable *aLockable
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoLockBase(1,
+ aLockable ? aLockable->lockHandle() : NULL
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ virtual ~AutoReadLock();
+
+ virtual void callLockImpl(LockHandle &l);
+ virtual void callUnlockImpl(LockHandle &l);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutoWriteLockBase
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Base class for all auto write locks.
+ *
+ * This cannot be used directly. Use AutoWriteLock or AutoMultiWriteLock2/3
+ * which derive from this.
+ *
+ * It has some utility methods for subclasses.
+ */
+class AutoWriteLockBase : public AutoLockBase
+{
+protected:
+ AutoWriteLockBase(uint32_t cHandles
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoLockBase(cHandles
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ { }
+
+ AutoWriteLockBase(uint32_t cHandles,
+ LockHandle *pHandle
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoLockBase(cHandles,
+ pHandle
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ { }
+
+ virtual ~AutoWriteLockBase()
+ { }
+
+ virtual void callLockImpl(LockHandle &l);
+ virtual void callUnlockImpl(LockHandle &l);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutoWriteLock
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Automatic write lock. Use this with a RWLockHandle to request a read/write
+ * semaphore in write mode. There can only ever be one writer of a read/write
+ * semaphore: while the lock is held in write mode, no other writer or reader
+ * can request the semaphore and will block.
+ *
+ * If constructed with a RWLockHandle or an instance of Lockable (which in
+ * practice means any VirtualBoxBase derivative), it autoamtically requests
+ * the lock in write mode and releases the write lock in the destructor.
+ *
+ * When used with a WriteLockHandle, it requests the semaphore contained therein
+ * exclusively.
+ */
+class AutoWriteLock : public AutoWriteLockBase
+{
+public:
+
+ /**
+ * Constructs a null instance that does not manage any read/write
+ * semaphore.
+ *
+ * Note that all method calls on a null instance are no-ops. This allows to
+ * have the code where lock protection can be selected (or omitted) at
+ * runtime.
+ */
+ AutoWriteLock(LOCKVAL_SRC_POS_DECL)
+ : AutoWriteLockBase(1,
+ NULL
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ { }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a write lock.
+ */
+ AutoWriteLock(LockHandle *aHandle
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoWriteLockBase(1,
+ aHandle
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a write lock.
+ */
+ AutoWriteLock(LockHandle &aHandle
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoWriteLockBase(1,
+ &aHandle
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a write lock.
+ */
+ AutoWriteLock(const Lockable &aLockable
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoWriteLockBase(1,
+ aLockable.lockHandle()
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a write lock.
+ */
+ AutoWriteLock(const Lockable *aLockable
+ COMMA_LOCKVAL_SRC_POS_DECL)
+ : AutoWriteLockBase(1,
+ aLockable ? aLockable->lockHandle() : NULL
+ COMMA_LOCKVAL_SRC_POS_ARGS)
+ {
+ acquire();
+ }
+
+ /**
+ * Constructs a new instance that will start managing the given read/write
+ * semaphore by requesting a write lock.
+ */
+ AutoWriteLock(uint32_t cHandles,
+ LockHandle** pHandles
+ COMMA_LOCKVAL_SRC_POS_DECL);
+
+ /**
+ * Release all write locks acquired by this instance through the #lock()
+ * call and destroys the instance.
+ *
+ * Note that if there there are nested #lock() calls without the
+ * corresponding number of #unlock() calls when the destructor is called, it
+ * will assert. This is because having an unbalanced number of nested locks
+ * is a program logic error which must be fixed.
+ */
+ virtual ~AutoWriteLock()
+ {
+ cleanup();
+ }
+
+ void attach(LockHandle *aHandle);
+
+ /** @see attach (LockHandle *) */
+ void attach(LockHandle &aHandle)
+ {
+ attach(&aHandle);
+ }
+
+ /** @see attach (LockHandle *) */
+ void attach(const Lockable &aLockable)
+ {
+ attach(aLockable.lockHandle());
+ }
+
+ /** @see attach (LockHandle *) */
+ void attach(const Lockable *aLockable)
+ {
+ attach(aLockable ? aLockable->lockHandle() : NULL);
+ }
+
+ bool isWriteLockOnCurrentThread() const;
+ uint32_t writeLockLevel() const;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// AutoMultiWriteLock*
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A multi-write-lock containing two other write locks.
+ *
+ */
+class AutoMultiWriteLock2 : public AutoWriteLockBase
+{
+public:
+ AutoMultiWriteLock2(Lockable *pl1,
+ Lockable *pl2
+ COMMA_LOCKVAL_SRC_POS_DECL);
+ AutoMultiWriteLock2(LockHandle *pl1,
+ LockHandle *pl2
+ COMMA_LOCKVAL_SRC_POS_DECL);
+
+ virtual ~AutoMultiWriteLock2()
+ {
+ cleanup();
+ }
+};
+
+/**
+ * A multi-write-lock containing three other write locks.
+ *
+ */
+class AutoMultiWriteLock3 : public AutoWriteLockBase
+{
+public:
+ AutoMultiWriteLock3(Lockable *pl1,
+ Lockable *pl2,
+ Lockable *pl3
+ COMMA_LOCKVAL_SRC_POS_DECL);
+ AutoMultiWriteLock3(LockHandle *pl1,
+ LockHandle *pl2,
+ LockHandle *pl3
+ COMMA_LOCKVAL_SRC_POS_DECL);
+
+ virtual ~AutoMultiWriteLock3()
+ {
+ cleanup();
+ }
+};
+
+/**
+ * A multi-write-lock containing four other write locks.
+ *
+ */
+class AutoMultiWriteLock4 : public AutoWriteLockBase
+{
+public:
+ AutoMultiWriteLock4(Lockable *pl1,
+ Lockable *pl2,
+ Lockable *pl3,
+ Lockable *pl4
+ COMMA_LOCKVAL_SRC_POS_DECL);
+ AutoMultiWriteLock4(LockHandle *pl1,
+ LockHandle *pl2,
+ LockHandle *pl3,
+ LockHandle *pl4
+ COMMA_LOCKVAL_SRC_POS_DECL);
+
+ virtual ~AutoMultiWriteLock4()
+ {
+ cleanup();
+ }
+};
+
+} /* namespace util */
+
+#endif // ____H_AUTOLOCK
+
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
diff --git a/include/VBox/com/ErrorInfo.h b/include/VBox/com/ErrorInfo.h
new file mode 100644
index 00000000..1037b253
--- /dev/null
+++ b/include/VBox/com/ErrorInfo.h
@@ -0,0 +1,495 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * ErrorInfo class declaration
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_ErrorInfo_h
+#define ___VBox_com_ErrorInfo_h
+
+#include "VBox/com/ptr.h"
+#include "VBox/com/string.h"
+#include "VBox/com/Guid.h"
+#include "VBox/com/assert.h"
+
+struct IProgress;
+struct IVirtualBoxErrorInfo;
+
+namespace com
+{
+
+/**
+ * General discussion:
+ *
+ * In COM all errors are stored on a per thread basis. In general this means
+ * only _one_ active error is possible per thread. A new error will overwrite
+ * the previous one. To prevent this use MultiResult or ErrorInfoKeeper (see
+ * below). The implementations in MSCOM/XPCOM differ slightly, but the details
+ * are handled by this glue code.
+ *
+ * We have different classes which are involved in the error management. I try
+ * to describe them separately to make clear what they are there for.
+ *
+ * ErrorInfo:
+ *
+ * This class is able to retrieve the per thread error and store it into its
+ * member variables. This class can also handle non-VirtualBox errors (like
+ * standard COM errors).
+ *
+ * ProgressErrorInfo:
+ *
+ * This is just a simple wrapper class to get the ErrorInfo stored within an
+ * IProgress object. That is the error which was stored when the progress
+ * object was in use and not an error produced by IProgress itself.
+ *
+ * IVirtualBoxErrorInfo:
+ *
+ * The VirtualBox interface class for accessing error information from Main
+ * clients. This class is also used for storing the error information in the
+ * thread context.
+ *
+ * ErrorInfoKeeper:
+ *
+ * A helper class which stores the current per thread info internally. After
+ * calling methods which may produce other errors it is possible to restore
+ * the previous error and therefore restore the situation before calling the
+ * other methods.
+ *
+ * MultiResult:
+ *
+ * Creating an instance of MultiResult turns error chain saving on. All errors
+ * which follow will be saved in a chain for later access.
+ *
+ * COMErrorInfo (Qt/Gui only):
+ *
+ * The Qt GUI does some additional work for saving errors. Because we create
+ * wrappers for _every_ COM call, it is possible to automatically save the
+ * error info after the execution. This allow some additional info like saving
+ * the callee. Please note that this error info is saved on the client side
+ * and therefore locally to the object instance. See COMBaseWithEI,
+ * COMErrorInfo and the generated COMWrappers.cpp in the GUI.
+ *
+ * Errors itself are set in VirtualBoxBase::setErrorInternal. First a
+ * IVirtualBoxErrorInfo object is created and the given error is saved within.
+ * If MultiResult is active the current per thread error is fetched and
+ * attached to the new created IVirtualBoxErrorInfo object. Next this object is
+ * set as the new per thread error.
+ *
+ * Some general hints:
+ *
+ * - Always use setError, especially when you are working in an asynchronous thread
+ * to indicate an error. Otherwise the error information itself will not make
+ * it into the client.
+ *
+ */
+
+/**
+ * The ErrorInfo class provides a convenient way to retrieve error
+ * information set by the most recent interface method, that was invoked on
+ * the current thread and returned an unsuccessful result code.
+ *
+ * Once the instance of this class is created, the error information for
+ * the current thread is cleared.
+ *
+ * There is no sense to use instances of this class after the last
+ * invoked interface method returns a success.
+ *
+ * The class usage pattern is as follows:
+ * <code>
+ * IFoo *foo;
+ * ...
+ * HRESULT rc = foo->SomeMethod();
+ * if (FAILED(rc)) {
+ * ErrorInfo info(foo);
+ * if (info.isFullAvailable()) {
+ * printf("error message = %ls\n", info.getText().raw());
+ * }
+ * }
+ * </code>
+ *
+ * This class fetches error information using the IErrorInfo interface on
+ * Win32 (MS COM) or the nsIException interface on other platforms (XPCOM),
+ * or the extended IVirtualBoxErrorInfo interface when when it is available
+ * (i.e. a given IErrorInfo or nsIException instance implements it).
+ * Currently, IVirtualBoxErrorInfo is only available for VirtualBox components.
+ *
+ * ErrorInfo::isFullAvailable() and ErrorInfo::isBasicAvailable() determine
+ * what level of error information is available. If #isBasicAvailable()
+ * returns true, it means that only IErrorInfo or nsIException is available as
+ * the source of information (depending on the platform), but not
+ * IVirtualBoxErrorInfo. If #isFullAvailable() returns true, it means that all
+ * three interfaces are available. If both methods return false, no error info
+ * is available at all.
+ *
+ * Here is a table of correspondence between this class methods and
+ * and IErrorInfo/nsIException/IVirtualBoxErrorInfo attributes/methods:
+ *
+ * ErrorInfo IErrorInfo nsIException IVirtualBoxErrorInfo
+ * --------------------------------------------------------------------
+ * getResultCode -- result resultCode
+ * getIID GetGUID -- interfaceID
+ * getComponent GetSource -- component
+ * getText GetDescription message text
+ *
+ * '--' means that this interface does not provide the corresponding portion
+ * of information, therefore it is useless to query it if only
+ * #isBasicAvailable() returns true. As it can be seen, the amount of
+ * information provided at the basic level, depends on the platform
+ * (MS COM or XPCOM).
+ */
+class ErrorInfo
+{
+public:
+
+ /**
+ * Constructs a new, "interfaceless" ErrorInfo instance that takes
+ * the error information possibly set on the current thread by an
+ * interface method of some COM component or by the COM subsystem.
+ *
+ * This constructor is useful, for example, after an unsuccessful attempt
+ * to instantiate (create) a component, so there is no any valid interface
+ * pointer available.
+ */
+ explicit ErrorInfo()
+ : mIsBasicAvailable(false),
+ mIsFullAvailable(false),
+ mResultCode(S_OK),
+ m_pNext(NULL)
+ {
+ init();
+ }
+
+ ErrorInfo(IUnknown *pObj, const GUID &aIID)
+ : mIsBasicAvailable(false),
+ mIsFullAvailable(false),
+ mResultCode(S_OK),
+ m_pNext(NULL)
+ {
+ init(pObj, aIID);
+ }
+
+ /** Specialization for the IVirtualBoxErrorInfo smart pointer */
+ ErrorInfo (const ComPtr <IVirtualBoxErrorInfo> &aPtr)
+ : mIsBasicAvailable (false), mIsFullAvailable (false)
+ , mResultCode (S_OK)
+ { init (aPtr); }
+
+ /**
+ * Constructs a new ErrorInfo instance from the IVirtualBoxErrorInfo
+ * interface pointer. If this pointer is not NULL, both #isFullAvailable()
+ * and #isBasicAvailable() will return |true|.
+ *
+ * @param aInfo pointer to the IVirtualBoxErrorInfo interface that
+ * holds error info to be fetched by this instance
+ */
+ ErrorInfo (IVirtualBoxErrorInfo *aInfo)
+ : mIsBasicAvailable (false), mIsFullAvailable (false)
+ , mResultCode (S_OK)
+ { init (aInfo); }
+
+ ErrorInfo(const ErrorInfo &x)
+ {
+ copyFrom(x);
+ }
+
+ virtual ~ErrorInfo()
+ {
+ cleanup();
+ }
+
+ ErrorInfo& operator=(const ErrorInfo& x)
+ {
+ cleanup();
+ copyFrom(x);
+ return *this;
+ }
+
+ /**
+ * Returns whether basic error info is actually available for the current
+ * thread. If the instance was created from an interface pointer that
+ * supports basic error info and successfully provided it, or if it is an
+ * "interfaceless" instance and there is some error info for the current
+ * thread, the returned value will be true.
+ *
+ * See the class description for details about the basic error info level.
+ *
+ * The appropriate methods of this class provide meaningful info only when
+ * this method returns true (otherwise they simply return NULL-like values).
+ */
+ bool isBasicAvailable() const
+ {
+ return mIsBasicAvailable;
+ }
+
+ /**
+ * Returns whether full error info is actually available for the current
+ * thread. If the instance was created from an interface pointer that
+ * supports full error info and successfully provided it, or if it is an
+ * "interfaceless" instance and there is some error info for the current
+ * thread, the returned value will be true.
+ *
+ * See the class description for details about the full error info level.
+ *
+ * The appropriate methods of this class provide meaningful info only when
+ * this method returns true (otherwise they simply return NULL-like values).
+ */
+ bool isFullAvailable() const
+ {
+ return mIsFullAvailable;
+ }
+
+ /**
+ * Returns the COM result code of the failed operation.
+ */
+ HRESULT getResultCode() const
+ {
+ return mResultCode;
+ }
+
+ /**
+ * Returns the IID of the interface that defined the error.
+ */
+ const Guid& getInterfaceID() const
+ {
+ return mInterfaceID;
+ }
+
+ /**
+ * Returns the name of the component that generated the error.
+ */
+ const Bstr& getComponent() const
+ {
+ return mComponent;
+ }
+
+ /**
+ * Returns the textual description of the error.
+ */
+ const Bstr& getText() const
+ {
+ return mText;
+ }
+
+ /**
+ * Returns the next error information object or @c NULL if there is none.
+ */
+ const ErrorInfo* getNext() const
+ {
+ return m_pNext;
+ }
+
+ /**
+ * Returns the name of the interface that defined the error
+ */
+ const Bstr& getInterfaceName() const
+ {
+ return mInterfaceName;
+ }
+
+ /**
+ * Returns the IID of the interface that returned the error.
+ *
+ * This method returns a non-null IID only if the instance was created
+ * using #template <class I> ErrorInfo(I *i) or
+ * template <class I> ErrorInfo(const ComPtr<I> &i) constructor.
+ */
+ const Guid& getCalleeIID() const
+ {
+ return mCalleeIID;
+ }
+
+ /**
+ * Returns the name of the interface that returned the error
+ *
+ * This method returns a non-null name only if the instance was created
+ * using #template <class I> ErrorInfo(I *i) or
+ * template <class I> ErrorInfo(const ComPtr<I> &i) constructor.
+ */
+ const Bstr& getCalleeName() const
+ {
+ return mCalleeName;
+ }
+
+ /**
+ * Resets all collected error information. #isBasicAvailable() and
+ * #isFullAvailable will return @c true after this method is called.
+ */
+ void setNull()
+ {
+ cleanup();
+ }
+
+protected:
+
+ ErrorInfo(bool /* aDummy */)
+ : mIsBasicAvailable(false),
+ mIsFullAvailable(false),
+ mResultCode(S_OK),
+ m_pNext(NULL)
+ { }
+
+ void copyFrom(const ErrorInfo &x);
+ void cleanup();
+
+ void init(bool aKeepObj = false);
+ void init(IUnknown *aUnk, const GUID &aIID, bool aKeepObj = false);
+ void init(IVirtualBoxErrorInfo *aInfo);
+
+ bool mIsBasicAvailable : 1;
+ bool mIsFullAvailable : 1;
+
+ HRESULT mResultCode;
+ Guid mInterfaceID;
+ Bstr mComponent;
+ Bstr mText;
+
+ ErrorInfo *m_pNext;
+
+ Bstr mInterfaceName;
+ Guid mCalleeIID;
+ Bstr mCalleeName;
+
+ ComPtr<IUnknown> mErrorInfo;
+};
+
+/**
+ * A convenience subclass of ErrorInfo that, given an IProgress interface
+ * pointer, reads its errorInfo attribute and uses the returned
+ * IVirtualBoxErrorInfo instance to construct itself.
+ */
+class ProgressErrorInfo : public ErrorInfo
+{
+public:
+
+ /**
+ * Constructs a new instance by fetching error information from the
+ * IProgress interface pointer. If the progress object is not NULL,
+ * its completed attribute is true, resultCode represents a failure,
+ * and the errorInfo attribute returns a valid IVirtualBoxErrorInfo pointer,
+ * both #isFullAvailable() and #isBasicAvailable() will return true.
+ *
+ * @param progress the progress object representing a failed operation
+ */
+ ProgressErrorInfo(IProgress *progress);
+};
+
+/**
+ * A convenience subclass of ErrorInfo that allows to preserve the current
+ * error info. Instances of this class fetch an error info object set on the
+ * current thread and keep a reference to it, which allows to restore it
+ * later using the #restore() method. This is useful to preserve error
+ * information returned by some method for the duration of making another COM
+ * call that may set its own error info and overwrite the existing
+ * one. Preserving and restoring error information makes sense when some
+ * method wants to return error information set by other call as its own
+ * error information while it still needs to make another call before return.
+ *
+ * Instead of calling #restore() explicitly you may let the object destructor
+ * do it for you, if you correctly limit the object's lifetime.
+ *
+ * The usage pattern is:
+ * <code>
+ * rc = foo->method();
+ * if (FAILED(rc))
+ * {
+ * ErrorInfoKeeper eik;
+ * ...
+ * // bar may return error info as well
+ * bar->method();
+ * ...
+ * // no need to call #restore() explicitly here because the eik's
+ * // destructor will restore error info fetched after the failed
+ * // call to foo before returning to the caller
+ * return rc;
+ * }
+ * </code>
+ */
+class ErrorInfoKeeper : public ErrorInfo
+{
+public:
+
+ /**
+ * Constructs a new instance that will fetch the current error info if
+ * @a aIsNull is @c false (by default) or remain uninitialized (null)
+ * otherwise.
+ *
+ * @param aIsNull @c true to prevent fetching error info and leave
+ * the instance uninitialized.
+ */
+ ErrorInfoKeeper(bool aIsNull = false)
+ : ErrorInfo(false), mForgot(aIsNull)
+ {
+ if (!aIsNull)
+ init(true /* aKeepObj */);
+ }
+
+ /**
+ * Destroys this instance and automatically calls #restore() which will
+ * either restore error info fetched by the constructor or do nothing
+ * if #forget() was called before destruction.
+ */
+ ~ErrorInfoKeeper() { if (!mForgot) restore(); }
+
+ /**
+ * Tries to (re-)fetch error info set on the current thread. On success,
+ * the previous error information, if any, will be overwritten with the
+ * new error information. On failure, or if there is no error information
+ * available, this instance will be reset to null.
+ */
+ void fetch()
+ {
+ setNull();
+ mForgot = false;
+ init(true /* aKeepObj */);
+ }
+
+ /**
+ * Restores error info fetched by the constructor and forgets it
+ * afterwards. Does nothing if the error info was forgotten by #forget().
+ *
+ * @return COM result of the restore operation.
+ */
+ HRESULT restore();
+
+ /**
+ * Forgets error info fetched by the constructor to prevent it from
+ * being restored by #restore() or by the destructor.
+ */
+ void forget() { mForgot = true; }
+
+ /**
+ * Forgets error info fetched by the constructor to prevent it from
+ * being restored by #restore() or by the destructor, and returns the
+ * stored error info object to the caller.
+ */
+ ComPtr<IUnknown> takeError() { mForgot = true; return mErrorInfo; }
+
+private:
+
+ bool mForgot : 1;
+};
+
+} /* namespace com */
+
+#endif
+
diff --git a/include/VBox/com/EventQueue.h b/include/VBox/com/EventQueue.h
new file mode 100644
index 00000000..14f4fc84
--- /dev/null
+++ b/include/VBox/com/EventQueue.h
@@ -0,0 +1,140 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * Event and EventQueue class declaration
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_EventQueue_h
+#define ___VBox_com_EventQueue_h
+
+#ifndef VBOX_WITH_XPCOM
+# include <Windows.h>
+#else // VBOX_WITH_XPCOM
+# include <nsEventQueueUtils.h>
+#endif // VBOX_WITH_XPCOM
+
+#include <VBox/com/defs.h>
+#include <VBox/com/assert.h>
+
+namespace com
+{
+
+class EventQueue;
+
+/**
+ * Base class for all events. Intended to be subclassed to introduce new
+ * events and handlers for them.
+ *
+ * Subclasses usually reimplement virtual #handler() (that does nothing by
+ * default) and add new data members describing the event.
+ */
+class Event
+{
+public:
+
+ Event() {}
+ virtual ~Event() {};
+
+protected:
+
+ /**
+ * Event handler. Called in the context of the event queue's thread.
+ * Always reimplemented by subclasses
+ *
+ * @return reserved, should be NULL.
+ */
+ virtual void *handler() { return NULL; }
+
+ friend class EventQueue;
+};
+
+/**
+ * Simple event queue.
+ *
+ * When using XPCOM, this will map onto the default XPCOM queue for the thread.
+ * So, if a queue is created on the main thread, it automatically processes
+ * XPCOM/IPC events while waiting.
+ *
+ * When using Windows, Darwin and OS/2, this will map onto the native thread
+ * queue/runloop. So, windows messages and what not will be processed while
+ * waiting for events.
+ *
+ * @note It is intentional that there is no way to retrieve arbitrary
+ * events and controlling their processing. There is no use case which
+ * warrants introducing the complexity of platform independent events.
+ */
+class EventQueue
+{
+public:
+
+ EventQueue();
+ ~EventQueue();
+
+ BOOL postEvent(Event *event);
+ int processEventQueue(RTMSINTERVAL cMsTimeout);
+ int interruptEventQueueProcessing();
+ int getSelectFD();
+ static int init();
+ static int uninit();
+ static EventQueue *getMainEventQueue();
+
+#ifdef VBOX_WITH_XPCOM
+ already_AddRefed<nsIEventQueue> getIEventQueue()
+ {
+ return mEventQ.get();
+ }
+#else
+ static int dispatchMessageOnWindows(MSG const *pMsg, int rc);
+#endif
+
+private:
+ static EventQueue *sMainQueue;
+
+#ifndef VBOX_WITH_XPCOM
+
+ /** The thread which the queue belongs to. */
+ DWORD mThreadId;
+ /** Duplicated thread handle for MsgWaitForMultipleObjects. */
+ HANDLE mhThread;
+
+#else // VBOX_WITH_XPCOM
+
+ /** Whether it was created (and thus needs destroying) or if a queue already
+ * associated with the thread was used. */
+ bool mEQCreated;
+
+ /** Whether event processing should be interrupted. */
+ bool mInterrupted;
+
+ nsCOMPtr <nsIEventQueue> mEventQ;
+ nsCOMPtr <nsIEventQueueService> mEventQService;
+
+ static void *PR_CALLBACK plEventHandler(PLEvent *self);
+ static void PR_CALLBACK plEventDestructor(PLEvent *self);
+
+#endif // VBOX_WITH_XPCOM
+};
+
+} /* namespace com */
+
+#endif
diff --git a/include/VBox/com/Guid.h b/include/VBox/com/Guid.h
new file mode 100644
index 00000000..c55d69dc
--- /dev/null
+++ b/include/VBox/com/Guid.h
@@ -0,0 +1,353 @@
+/* $Id: Guid.h $ */
+/** @file
+ * MS COM / XPCOM Abstraction Layer - Guid class declaration.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_Guid_h
+#define ___VBox_com_Guid_h
+
+/* Make sure all the stdint.h macros are included - must come first! */
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS
+#endif
+
+#if defined(VBOX_WITH_XPCOM)
+# include <nsMemory.h>
+#endif
+
+#include "VBox/com/string.h"
+
+#include <iprt/uuid.h>
+#include <iprt/err.h>
+
+namespace com
+{
+
+/**
+ * Helper class that represents the UUID type and hides platform-specific
+ * implementation details.
+ */
+class Guid
+{
+public:
+
+ Guid()
+ {
+ ::RTUuidClear(&mUuid);
+ refresh();
+ }
+
+ Guid(const Guid &that)
+ {
+ mUuid = that.mUuid;
+ refresh();
+ }
+
+ Guid(const RTUUID &that)
+ {
+ mUuid = that;
+ refresh();
+ }
+
+ Guid(const GUID &that)
+ {
+ AssertCompileSize(GUID, sizeof(RTUUID));
+ ::memcpy(&mUuid, &that, sizeof(GUID));
+ refresh();
+ }
+
+ /**
+ * Construct a GUID from a string.
+ *
+ * Should the string be invalid, the object will be set to the null GUID
+ * (isEmpty() == true).
+ *
+ * @param that The UUID string. We feed this to RTUuidFromStr(),
+ * so check it out for the exact format.
+ */
+ Guid(const char *that)
+ {
+ int rc = ::RTUuidFromStr(&mUuid, that);
+ if (RT_FAILURE(rc))
+ ::RTUuidClear(&mUuid);
+ refresh();
+ }
+
+ /**
+ * Construct a GUID from a BSTR.
+ *
+ * Should the string be empty or invalid, the object will be set to the
+ * null GUID (isEmpty() == true).
+ *
+ * @param that The UUID BSTR. We feed this to RTUuidFromUtf16(),
+ * so check it out for the exact format.
+ */
+ Guid(const Bstr &that)
+ {
+ int rc = !that.isEmpty()
+ ? ::RTUuidFromUtf16(&mUuid, that.raw())
+ : VERR_INVALID_UUID_FORMAT;
+ if (RT_FAILURE(rc))
+ ::RTUuidClear(&mUuid);
+ refresh();
+ }
+
+ Guid& operator=(const Guid &that)
+ {
+ ::memcpy(&mUuid, &that.mUuid, sizeof (RTUUID));
+ refresh();
+ return *this;
+ }
+ Guid& operator=(const GUID &guid)
+ {
+ ::memcpy(&mUuid, &guid, sizeof (GUID));
+ refresh();
+ return *this;
+ }
+ Guid& operator=(const RTUUID &guid)
+ {
+ ::memcpy(&mUuid, &guid, sizeof (RTUUID));
+ refresh();
+ return *this;
+ }
+ Guid& operator=(const char *str)
+ {
+ int rc = ::RTUuidFromStr(&mUuid, str);
+ if (RT_FAILURE(rc))
+ ::RTUuidClear(&mUuid);
+ refresh();
+ return *this;
+ }
+
+ void create()
+ {
+ ::RTUuidCreate(&mUuid);
+ refresh();
+ }
+ void clear()
+ {
+ ::RTUuidClear(&mUuid);
+ refresh();
+ }
+
+ /**
+ * Convert the GUID to a string.
+ *
+ * @returns String object containing the formatted GUID.
+ * @throws std::bad_alloc
+ */
+ Utf8Str toString() const
+ {
+ char buf[RTUUID_STR_LENGTH];
+ ::RTUuidToStr(&mUuid, buf, RTUUID_STR_LENGTH);
+ return Utf8Str(buf);
+ }
+
+ /**
+ * Like toString, but encloses the returned string in curly brackets.
+ *
+ * @returns String object containing the formatted GUID in curly brackets.
+ * @throws std::bad_alloc
+ */
+ Utf8Str toStringCurly() const
+ {
+ char buf[RTUUID_STR_LENGTH + 2] = "{";
+ ::RTUuidToStr(&mUuid, buf + 1, RTUUID_STR_LENGTH);
+ buf[sizeof(buf) - 2] = '}';
+ buf[sizeof(buf) - 1] = '\0';
+ return Utf8Str(buf);
+ }
+
+ /**
+ * Convert the GUID to a string.
+ *
+ * @returns Bstr object containing the formatted GUID.
+ * @throws std::bad_alloc
+ */
+ Bstr toUtf16() const
+ {
+ if (isEmpty())
+ return Bstr();
+
+ RTUTF16 buf[RTUUID_STR_LENGTH];
+ ::RTUuidToUtf16(&mUuid, buf, RTUUID_STR_LENGTH);
+ return Bstr(buf);
+ }
+
+ bool isEmpty() const
+ {
+ return ::RTUuidIsNull(&mUuid);
+ }
+
+ bool isNotEmpty() const
+ {
+ return !::RTUuidIsNull(&mUuid);
+ }
+
+ bool operator==(const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) == 0; }
+ bool operator==(const GUID &guid) const { return ::RTUuidCompare(&mUuid, (PRTUUID)&guid) == 0; }
+ bool operator!=(const Guid &that) const { return !operator==(that); }
+ bool operator!=(const GUID &guid) const { return !operator==(guid); }
+ bool operator<( const Guid &that) const { return ::RTUuidCompare(&mUuid, &that.mUuid) < 0; }
+ bool operator<( const GUID &guid) const { return ::RTUuidCompare(&mUuid, (PRTUUID)&guid) < 0; }
+
+ /**
+ * To directly copy the contents to a GUID, or for passing it as an input
+ * parameter of type (const GUID *), the compiler converts. */
+ const GUID &ref() const
+ {
+ return *(const GUID *)&mUuid;
+ }
+
+ /**
+ * To pass instances to printf-like functions.
+ */
+ PCRTUUID raw() const
+ {
+ return (PCRTUUID)&mUuid;
+ }
+
+#if !defined(VBOX_WITH_XPCOM)
+
+ /** To assign instances to OUT_GUID parameters from within the interface
+ * method. */
+ const Guid &cloneTo(GUID *pguid) const
+ {
+ if (pguid)
+ ::memcpy(pguid, &mUuid, sizeof(GUID));
+ return *this;
+ }
+
+ /** To pass instances as OUT_GUID parameters to interface methods. */
+ GUID *asOutParam()
+ {
+ return (GUID *)&mUuid;
+ }
+
+#else
+
+ /** To assign instances to OUT_GUID parameters from within the
+ * interface method */
+ const Guid &cloneTo(nsID **ppGuid) const
+ {
+ if (ppGuid)
+ *ppGuid = (nsID *)nsMemory::Clone(&mUuid, sizeof(nsID));
+ return *this;
+ }
+
+ /**
+ * Internal helper class for asOutParam().
+ *
+ * This takes a GUID refrence in the constructor and copies the mUuid from
+ * the method to that instance in its destructor.
+ */
+ class GuidOutParam
+ {
+ GuidOutParam(Guid &guid)
+ : ptr(0),
+ outer(guid)
+ {
+ outer.clear();
+ }
+
+ nsID *ptr;
+ Guid &outer;
+ GuidOutParam(const GuidOutParam &that); // disabled
+ GuidOutParam &operator=(const GuidOutParam &that); // disabled
+ public:
+ operator nsID**() { return &ptr; }
+ ~GuidOutParam()
+ {
+ if (ptr && outer.isEmpty())
+ {
+ outer = *ptr;
+ outer.refresh();
+ nsMemory::Free(ptr);
+ }
+ }
+ friend class Guid;
+ };
+
+ /** to pass instances as OUT_GUID parameters to interface methods */
+ GuidOutParam asOutParam() { return GuidOutParam(*this); }
+
+#endif
+
+ /* to directly test IN_GUID interface method's parameters */
+ static bool isEmpty(const GUID &guid)
+ {
+ return ::RTUuidIsNull((PRTUUID)&guid);
+ }
+
+ /**
+ * Static immutable empty object. May be used for comparison purposes.
+ */
+ static const Guid Empty;
+
+private:
+ /**
+ * Refresh the debug-only UUID string.
+ *
+ * In debug code, refresh the UUID string representatino for debugging;
+ * must be called every time the internal uuid changes; compiles to nothing
+ * in release code.
+ */
+ inline void refresh()
+ {
+#ifdef DEBUG
+ ::RTUuidToStr(&mUuid, mszUuid, RTUUID_STR_LENGTH);
+ m_pcszUUID = mszUuid;
+#endif
+ }
+
+ /** The UUID. */
+ RTUUID mUuid;
+
+#ifdef DEBUG
+ /** String representation of mUuid for printing in the debugger. */
+ char mszUuid[RTUUID_STR_LENGTH];
+ /** Another string variant for the debugger, points to szUUID. */
+ const char *m_pcszUUID;
+#endif
+};
+
+inline Bstr asGuidStr(const Bstr& str)
+{
+ Guid guid(str);
+ return guid.isEmpty() ? Bstr() : guid.toUtf16();
+}
+
+inline bool isValidGuid(const Bstr& str)
+{
+ Guid guid(str);
+ return !guid.isEmpty();
+}
+
+} /* namespace com */
+
+#endif /* !___VBox_com_Guid_h */
+
diff --git a/include/VBox/com/Makefile.kup b/include/VBox/com/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/VBox/com/Makefile.kup
diff --git a/include/VBox/com/MultiResult.h b/include/VBox/com/MultiResult.h
new file mode 100644
index 00000000..705e1dbe
--- /dev/null
+++ b/include/VBox/com/MultiResult.h
@@ -0,0 +1,262 @@
+/* $Id: MultiResult.h $ */
+
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * MultiResult class declarations
+ */
+
+/*
+ * Copyright (C) 2008-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 ___VBox_com_MultiResult_h
+#define ___VBox_com_MultiResult_h
+
+#include "VBox/com/defs.h"
+#include "VBox/com/string.h"
+
+#include <stdarg.h>
+
+namespace com
+{
+
+/**
+ * "First worst" result type.
+ *
+ * Variables of this class are used instead of HRESULT variables when it is
+ * desirable to memorize the "first worst" result code instead of the last
+ * assigned one. In other words, an assignment operation to a variable of this
+ * class will succeed only if the result code to assign has worse severity. The
+ * following table demonstrate this (the first column lists the previous result
+ * code stored in the variable, the first row lists the new result code being
+ * assigned, 'A' means the assignment will take place, '> S_OK' means a warning
+ * result code):
+ *
+ * {{{
+ * FAILED > S_OK S_OK
+ * FAILED - - -
+ * > S_OK A - -
+ * S_OK A A -
+ *
+ * }}}
+ *
+ * In practice, you will need to use a FWResult variable when you call some COM
+ * method B after another COM method A fails and want to return the result code
+ * of A even if B also fails, but want to return the failed result code of B if
+ * A issues a warning or succeeds.
+ */
+class FWResult
+{
+
+public:
+
+ /**
+ * Constructs a new variable. Note that by default this constructor sets the
+ * result code to E_FAIL to make sure a failure is returned to the caller if
+ * the variable is never assigned another value (which is considered as the
+ * improper use of this class).
+ */
+ FWResult (HRESULT aRC = E_FAIL) : mRC (aRC) {}
+
+ FWResult &operator= (HRESULT aRC)
+ {
+ if ((FAILED (aRC) && !FAILED (mRC)) ||
+ (mRC == S_OK && aRC != S_OK))
+ mRC = aRC;
+
+ return *this;
+ }
+
+ operator HRESULT() const { return mRC; }
+
+ HRESULT *operator&() { return &mRC; }
+
+private:
+
+ HRESULT mRC;
+};
+
+/**
+ * The MultiResult class is a com::FWResult enhancement that also acts as a
+ * switch to turn on multi-error mode for VirtualBoxBase::setError() and
+ * VirtualBoxBase::setWarning() calls.
+ *
+ * When an instance of this class is created, multi-error mode is turned on
+ * for the current thread and the turn-on counter is increased by one. In
+ * multi-error mode, a call to setError() or setWarning() does not
+ * overwrite the current error or warning info object possibly set on the
+ * current thread by other method calls, but instead it stores this old
+ * object in the IVirtualBoxErrorInfo::next attribute of the new error
+ * object being set.
+ *
+ * This way, error/warning objects are stacked together and form a chain of
+ * errors where the most recent error is the first one retrieved by the
+ * calling party, the preceding error is what the
+ * IVirtualBoxErrorInfo::next attribute of the first error points to, and so
+ * on, up to the first error or warning occurred which is the last in the
+ * chain. See IVirtualBoxErrorInfo documentation for more info.
+ *
+ * When the instance of the MultiResult class goes out of scope and gets
+ * destroyed, it automatically decreases the turn-on counter by one. If
+ * the counter drops to zero, multi-error mode for the current thread is
+ * turned off and the thread switches back to single-error mode where every
+ * next error or warning object overwrites the previous one.
+ *
+ * Note that the caller of a COM method uses a non-S_OK result code to
+ * decide if the method has returned an error (negative codes) or a warning
+ * (positive non-zero codes) and will query extended error info only in
+ * these two cases. However, since multi-error mode implies that the method
+ * doesn't return control return to the caller immediately after the first
+ * error or warning but continues its execution, the functionality provided
+ * by the base com::FWResult class becomes very useful because it allows to
+ * preserve the error or the warning result code even if it is later assigned
+ * a S_OK value multiple times. See com::FWResult for details.
+ *
+ * Here is the typical usage pattern:
+ * <code>
+
+ HRESULT Bar::method()
+ {
+ // assume multi-errors are turned off here...
+
+ if (something)
+ {
+ // Turn on multi-error mode and make sure severity is preserved
+ MultiResult rc = foo->method1();
+
+ // return on fatal error, but continue on warning or on success
+ CheckComRCReturnRC (rc);
+
+ rc = foo->method2();
+ // no matter what result, stack it and continue
+
+ // ...
+
+ // return the last worst result code (it will be preserved even if
+ // foo->method2() returns S_OK.
+ return rc;
+ }
+
+ // multi-errors are turned off here again...
+
+ return S_OK;
+ }
+
+ * </code>
+ *
+ * @note This class is intended to be instantiated on the stack, therefore
+ * You cannot create them using new(). Although it is possible to copy
+ * instances of MultiResult or return them by value, please never do
+ * that as it is breaks the class semantics (and will assert);
+ */
+class MultiResult : public FWResult
+{
+public:
+
+ /**
+ * @copydoc FWResult::FWResult().
+ */
+ MultiResult (HRESULT aRC = E_FAIL) : FWResult (aRC) { incCounter(); }
+
+ MultiResult (const MultiResult &aThat) : FWResult (aThat)
+ {
+ /* We need this copy constructor only for GCC that wants to have
+ * it in case of expressions like |MultiResult rc = E_FAIL;|. But
+ * we assert since the optimizer should actually avoid the
+ * temporary and call the other constructor directly instead. */
+ AssertFailed();
+ }
+
+ ~MultiResult() { decCounter(); }
+
+ MultiResult &operator= (HRESULT aRC)
+ {
+ FWResult::operator= (aRC);
+ return *this;
+ }
+
+ MultiResult &operator= (const MultiResult & /* aThat */)
+ {
+ /* We need this copy constructor only for GCC that wants to have
+ * it in case of expressions like |MultiResult rc = E_FAIL;|. But
+ * we assert since the optimizer should actually avoid the
+ * temporary and call the other constructor directly instead. */
+ AssertFailed();
+ return *this;
+ }
+
+ /**
+ * Returns true if multi-mode is enabled for the current thread (i.e. at
+ * least one MultiResult instance exists on the stack somewhere).
+ * @return
+ */
+ static bool isMultiEnabled();
+
+private:
+
+ DECLARE_CLS_NEW_DELETE_NOOP(MultiResult)
+
+ static void incCounter();
+ static void decCounter();
+
+ static RTTLS sCounter;
+
+ friend class MultiResultRef;
+};
+
+/**
+ * The MultiResultRef class is equivalent to MultiResult except that it takes
+ * a reference to the existing HRESULT variable instead of maintaining its own
+ * one.
+ */
+class MultiResultRef
+{
+public:
+
+ MultiResultRef (HRESULT &aRC) : mRC (aRC) { MultiResult::incCounter(); }
+
+ ~MultiResultRef() { MultiResult::decCounter(); }
+
+ MultiResultRef &operator= (HRESULT aRC)
+ {
+ /* Copied from FWResult */
+ if ((FAILED (aRC) && !FAILED (mRC)) ||
+ (mRC == S_OK && aRC != S_OK))
+ mRC = aRC;
+
+ return *this;
+ }
+
+ operator HRESULT() const { return mRC; }
+
+ HRESULT *operator&() { return &mRC; }
+
+private:
+
+ DECLARE_CLS_NEW_DELETE_NOOP (MultiResultRef)
+
+ HRESULT &mRC;
+};
+
+
+} /* namespace com */
+
+#endif /* ___VBox_com_MultiResult_h */
+
diff --git a/include/VBox/com/VirtualBox.h b/include/VBox/com/VirtualBox.h
new file mode 100644
index 00000000..92fe1e84
--- /dev/null
+++ b/include/VBox/com/VirtualBox.h
@@ -0,0 +1,55 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * VirtualBox COM Library definitions.
+ *
+ * Note: This is the main header file that COM/XPCOM clients
+ * include; however, it is only a wrapper around another
+ * platform-dependent include file that contains the real
+ * COM/XPCOM interface declarations. That other include file
+ * is generated automatically at build time from
+ * /src/VBox/Main/idl/VirtualBox.xidl, which contains all
+ * the VirtualBox interfaces; the include file is called
+ * VirtualBox.h on Windows hosts and VirtualBox_XPCOM.h
+ * on Linux hosts. The build process places it in
+ * out/<platform>/bin/sdk/include, from where it gets
+ * included by the rest of the VirtualBox code.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_com_VirtualBox_h
+#define ___VBox_com_VirtualBox_h
+
+// generated VirtualBox COM library definition file
+#if !defined (VBOXCOM_NOINCLUDE)
+# if !defined (VBOX_WITH_XPCOM)
+# include <VirtualBox.h>
+# else
+# include <VirtualBox_XPCOM.h>
+# endif
+#endif // !defined (VBOXCOM_NOINCLUDE)
+
+// for convenience
+#include "VBox/com/defs.h"
+#include "VBox/com/ptr.h"
+
+#endif
diff --git a/include/VBox/com/array.h b/include/VBox/com/array.h
new file mode 100644
index 00000000..7f1796d9
--- /dev/null
+++ b/include/VBox/com/array.h
@@ -0,0 +1,1702 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * Safe array helper class declaration
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_array_h
+#define ___VBox_com_array_h
+
+/** @defgroup grp_COM_arrays COM/XPCOM Arrays
+ * @{
+ *
+ * The COM/XPCOM array support layer provides a cross-platform way to pass
+ * arrays to and from COM interface methods and consists of the com::SafeArray
+ * template and a set of ComSafeArray* macros part of which is defined in
+ * VBox/com/defs.h.
+ *
+ * This layer works with interface attributes and method parameters that have
+ * the 'safearray="yes"' attribute in the XIDL definition:
+ * @code
+
+ <interface name="ISomething" ...>
+
+ <method name="testArrays">
+ <param name="inArr" type="long" dir="in" safearray="yes"/>
+ <param name="outArr" type="long" dir="out" safearray="yes"/>
+ <param name="retArr" type="long" dir="return" safearray="yes"/>
+ </method>
+
+ </interface>
+
+ * @endcode
+ *
+ * Methods generated from this and similar definitions are implemented in
+ * component classes using the following declarations:
+ * @code
+
+ STDMETHOD(TestArrays)(ComSafeArrayIn(LONG, aIn),
+ ComSafeArrayOut(LONG, aOut),
+ ComSafeArrayOut(LONG, aRet));
+
+ * @endcode
+ *
+ * And the following function bodies:
+ * @code
+
+ STDMETHODIMP Component::TestArrays(ComSafeArrayIn(LONG, aIn),
+ ComSafeArrayOut(LONG, aOut),
+ ComSafeArrayOut(LONG, aRet))
+ {
+ if (ComSafeArrayInIsNull(aIn))
+ return E_INVALIDARG;
+ if (ComSafeArrayOutIsNull(aOut))
+ return E_POINTER;
+ if (ComSafeArrayOutIsNull(aRet))
+ return E_POINTER;
+
+ // Use SafeArray to access the input array parameter
+
+ com::SafeArray<LONG> in(ComSafeArrayInArg(aIn));
+
+ for (size_t i = 0; i < in.size(); ++ i)
+ LogFlow(("*** in[%u]=%d\n", i, in[i]));
+
+ // Use SafeArray to create the return array (the same technique is used
+ // for output array parameters)
+
+ SafeArray<LONG> ret(in.size() * 2);
+ for (size_t i = 0; i < in.size(); ++ i)
+ {
+ ret[i] = in[i];
+ ret[i + in.size()] = in[i] * 10;
+ }
+
+ ret.detachTo(ComSafeArrayOutArg(aRet));
+
+ return S_OK;
+ }
+
+ * @endcode
+ *
+ * Such methods can be called from the client code using the following pattern:
+ * @code
+
+ ComPtr<ISomething> component;
+
+ // ...
+
+ com::SafeArray<LONG> in(3);
+ in[0] = -1;
+ in[1] = -2;
+ in[2] = -3;
+
+ com::SafeArray<LONG> out;
+ com::SafeArray<LONG> ret;
+
+ HRESULT rc = component->TestArrays(ComSafeArrayAsInParam(in),
+ ComSafeArrayAsOutParam(out),
+ ComSafeArrayAsOutParam(ret));
+
+ if (SUCCEEDED(rc))
+ for (size_t i = 0; i < ret.size(); ++ i)
+ printf("*** ret[%u]=%d\n", i, ret[i]);
+
+ * @endcode
+ *
+ * For interoperability with standard C++ containers, there is a template
+ * constructor that takes such a container as argument and performs a deep copy
+ * of its contents. This can be used in method implementations like this:
+ * @code
+
+ STDMETHODIMP Component::COMGETTER(Values)(ComSafeArrayOut(int, aValues))
+ {
+ // ... assume there is a |std::list<int> mValues| data member
+
+ com::SafeArray<int> values(mValues);
+ values.detachTo(ComSafeArrayOutArg(aValues));
+
+ return S_OK;
+ }
+
+ * @endcode
+ *
+ * The current implementation of the SafeArray layer supports all types normally
+ * allowed in XIDL as array element types (including 'wstring' and 'uuid').
+ * However, 'pointer-to-...' types (e.g. 'long *', 'wstring *') are not
+ * supported and therefore cannot be used as element types.
+ *
+ * Note that for GUID arrays you should use SafeGUIDArray and
+ * SafeConstGUIDArray, customized SafeArray<> specializations.
+ *
+ * Also note that in order to pass input BSTR array parameters declared
+ * using the ComSafeArrayIn(IN_BSTR, aParam) macro to the SafeArray<>
+ * constructor using the ComSafeArrayInArg() macro, you should use IN_BSTR
+ * as the SafeArray<> template argument, not just BSTR.
+ *
+ * Arrays of interface pointers are also supported but they require to use a
+ * special SafeArray implementation, com::SafeIfacePointer, which takes the
+ * interface class name as a template argument (e.g. com::SafeIfacePointer
+ * <IUnknown>). This implementation functions identically to com::SafeArray.
+ */
+
+#ifdef VBOX_WITH_XPCOM
+# include <nsMemory.h>
+#endif
+
+#include "VBox/com/defs.h"
+#include "VBox/com/ptr.h"
+#include "VBox/com/assert.h"
+#include "iprt/cpp/list.h"
+
+#ifdef VBOX_WITH_XPCOM
+
+/**
+ * Wraps the given com::SafeArray instance to generate an expression that is
+ * suitable for passing it to functions that take input safearray parameters
+ * declared using the ComSafeArrayIn macro.
+ *
+ * @param aArray com::SafeArray instance to pass as an input parameter.
+ */
+#define ComSafeArrayAsInParam(aArray) \
+ (aArray).size(), (aArray).__asInParam_Arr((aArray).raw())
+
+/**
+ * Wraps the given com::SafeArray instance to generate an expression that is
+ * suitable for passing it to functions that take output safearray parameters
+ * declared using the ComSafeArrayOut macro.
+ *
+ * @param aArray com::SafeArray instance to pass as an output parameter.
+ */
+#define ComSafeArrayAsOutParam(aArray) \
+ (aArray).__asOutParam_Size(), (aArray).__asOutParam_Arr()
+
+#else /* !VBOX_WITH_XPCOM */
+
+#define ComSafeArrayAsInParam(aArray) (aArray).__asInParam()
+
+#define ComSafeArrayAsOutParam(aArray) (aArray).__asOutParam()
+
+#endif /* !VBOX_WITH_XPCOM */
+
+/**
+ *
+ */
+namespace com
+{
+
+#ifdef VBOX_WITH_XPCOM
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Provides various helpers for SafeArray.
+ *
+ * @param T Type of array elements.
+ */
+template<typename T>
+struct SafeArrayTraits
+{
+protected:
+
+ /** Initializes memory for aElem. */
+ static void Init(T &aElem) { aElem = 0; }
+
+ /** Initializes memory occupied by aElem. */
+ static void Uninit(T &aElem) { aElem = 0; }
+
+ /** Creates a deep copy of aFrom and stores it in aTo. */
+ static void Copy(const T &aFrom, T &aTo) { aTo = aFrom; }
+
+public:
+
+ /* Magic to workaround strict rules of par. 4.4.4 of the C++ standard (that
+ * in particular forbid casts of 'char **' to 'const char **'). Then initial
+ * reason for this magic is that XPIDL declares input strings
+ * (char/PRUnichar pointers) as const but doesn't do so for pointers to
+ * arrays. */
+ static T *__asInParam_Arr(T *aArr) { return aArr; }
+ static T *__asInParam_Arr(const T *aArr) { return const_cast<T *>(aArr); }
+};
+
+template<typename T>
+struct SafeArrayTraits<T *>
+{
+ // Arbitrary pointers are not supported
+};
+
+template<>
+struct SafeArrayTraits<PRUnichar *>
+{
+protected:
+
+ static void Init(PRUnichar * &aElem) { aElem = NULL; }
+
+ static void Uninit(PRUnichar * &aElem)
+ {
+ if (aElem)
+ {
+ ::SysFreeString(aElem);
+ aElem = NULL;
+ }
+ }
+
+ static void Copy(const PRUnichar * aFrom, PRUnichar * &aTo)
+ {
+ AssertCompile(sizeof(PRUnichar) == sizeof(OLECHAR));
+ aTo = aFrom ? ::SysAllocString((const OLECHAR *)aFrom) : NULL;
+ }
+
+public:
+
+ /* Magic to workaround strict rules of par. 4.4.4 of the C++ standard */
+ static const PRUnichar **__asInParam_Arr(PRUnichar **aArr)
+ {
+ return const_cast<const PRUnichar **>(aArr);
+ }
+ static const PRUnichar **__asInParam_Arr(const PRUnichar **aArr) { return aArr; }
+};
+
+template<>
+struct SafeArrayTraits<const PRUnichar *>
+{
+protected:
+
+ static void Init(const PRUnichar * &aElem) { aElem = NULL; }
+ static void Uninit(const PRUnichar * &aElem)
+ {
+ if (aElem)
+ {
+ ::SysFreeString(const_cast<PRUnichar *>(aElem));
+ aElem = NULL;
+ }
+ }
+
+ static void Copy(const PRUnichar * aFrom, const PRUnichar * &aTo)
+ {
+ AssertCompile(sizeof(PRUnichar) == sizeof(OLECHAR));
+ aTo = aFrom ? ::SysAllocString((const OLECHAR *)aFrom) : NULL;
+ }
+
+public:
+
+ /* Magic to workaround strict rules of par. 4.4.4 of the C++ standard */
+ static const PRUnichar **__asInParam_Arr(const PRUnichar **aArr) { return aArr; }
+};
+
+template<>
+struct SafeArrayTraits<nsID *>
+{
+protected:
+
+ static void Init(nsID * &aElem) { aElem = NULL; }
+
+ static void Uninit(nsID * &aElem)
+ {
+ if (aElem)
+ {
+ ::nsMemory::Free(aElem);
+ aElem = NULL;
+ }
+ }
+
+ static void Copy(const nsID * aFrom, nsID * &aTo)
+ {
+ if (aFrom)
+ {
+ aTo = (nsID *) ::nsMemory::Alloc(sizeof(nsID));
+ if (aTo)
+ *aTo = *aFrom;
+ }
+ else
+ aTo = NULL;
+ }
+
+ /* This specification is also reused for SafeConstGUIDArray, so provide a
+ * no-op Init() and Uninit() which are necessary for SafeArray<> but should
+ * be never called in context of SafeConstGUIDArray. */
+
+ static void Init(const nsID * &aElem) { NOREF(aElem); AssertFailed(); }
+ static void Uninit(const nsID * &aElem) { NOREF(aElem); AssertFailed(); }
+
+public:
+
+ /** Magic to workaround strict rules of par. 4.4.4 of the C++ standard. */
+ static const nsID **__asInParam_Arr(nsID **aArr)
+ {
+ return const_cast<const nsID **>(aArr);
+ }
+ static const nsID **__asInParam_Arr(const nsID **aArr) { return aArr; }
+};
+
+#else /* !VBOX_WITH_XPCOM */
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct SafeArrayTraitsBase
+{
+protected:
+
+ static SAFEARRAY *CreateSafeArray(VARTYPE aVarType, SAFEARRAYBOUND *aBound)
+ { return SafeArrayCreate(aVarType, 1, aBound); }
+};
+
+/**
+ * Provides various helpers for SafeArray.
+ *
+ * @param T Type of array elements.
+ *
+ * Specializations of this template must provide the following methods:
+ *
+ // Returns the VARTYPE of COM SafeArray elements to be used for T
+ static VARTYPE VarType();
+
+ // Returns the number of VarType() elements necessary for aSize
+ // elements of T
+ static ULONG VarCount(size_t aSize);
+
+ // Returns the number of elements of T that fit into the given number of
+ // VarType() elements (opposite to VarCount(size_t aSize)).
+ static size_t Size(ULONG aVarCount);
+
+ // Creates a deep copy of aFrom and stores it in aTo
+ static void Copy(ULONG aFrom, ULONG &aTo);
+ */
+template<typename T>
+struct SafeArrayTraits : public SafeArrayTraitsBase
+{
+protected:
+
+ // Arbitrary types are treated as passed by value and each value is
+ // represented by a number of VT_Ix type elements where VT_Ix has the
+ // biggest possible bitness necessary to represent T w/o a gap. COM enums
+ // fall into this category.
+
+ static VARTYPE VarType()
+ {
+ if (sizeof(T) % 8 == 0) return VT_I8;
+ if (sizeof(T) % 4 == 0) return VT_I4;
+ if (sizeof(T) % 2 == 0) return VT_I2;
+ return VT_I1;
+ }
+
+ static ULONG VarCount(size_t aSize)
+ {
+ if (sizeof(T) % 8 == 0) return (ULONG)((sizeof(T) / 8) * aSize);
+ if (sizeof(T) % 4 == 0) return (ULONG)((sizeof(T) / 4) * aSize);
+ if (sizeof(T) % 2 == 0) return (ULONG)((sizeof(T) / 2) * aSize);
+ return (ULONG)(sizeof(T) * aSize);
+ }
+
+ static size_t Size(ULONG aVarCount)
+ {
+ if (sizeof(T) % 8 == 0) return (size_t)(aVarCount * 8) / sizeof(T);
+ if (sizeof(T) % 4 == 0) return (size_t)(aVarCount * 4) / sizeof(T);
+ if (sizeof(T) % 2 == 0) return (size_t)(aVarCount * 2) / sizeof(T);
+ return (size_t) aVarCount / sizeof(T);
+ }
+
+ static void Copy(T aFrom, T &aTo) { aTo = aFrom; }
+};
+
+template<typename T>
+struct SafeArrayTraits<T *>
+{
+ // Arbitrary pointer types are not supported
+};
+
+/* Although the generic SafeArrayTraits template would work for all integers,
+ * we specialize it for some of them in order to use the correct VT_ type */
+
+template<>
+struct SafeArrayTraits<LONG> : public SafeArrayTraitsBase
+{
+protected:
+
+ static VARTYPE VarType() { return VT_I4; }
+ static ULONG VarCount(size_t aSize) { return (ULONG)aSize; }
+ static size_t Size(ULONG aVarCount) { return (size_t)aVarCount; }
+
+ static void Copy(LONG aFrom, LONG &aTo) { aTo = aFrom; }
+};
+
+template<>
+struct SafeArrayTraits<ULONG> : public SafeArrayTraitsBase
+{
+protected:
+
+ static VARTYPE VarType() { return VT_UI4; }
+ static ULONG VarCount(size_t aSize) { return (ULONG)aSize; }
+ static size_t Size(ULONG aVarCount) { return (size_t)aVarCount; }
+
+ static void Copy(ULONG aFrom, ULONG &aTo) { aTo = aFrom; }
+};
+
+template<>
+struct SafeArrayTraits<LONG64> : public SafeArrayTraitsBase
+{
+protected:
+
+ static VARTYPE VarType() { return VT_I8; }
+ static ULONG VarCount(size_t aSize) { return (ULONG)aSize; }
+ static size_t Size(ULONG aVarCount) { return (size_t)aVarCount; }
+
+ static void Copy(LONG64 aFrom, LONG64 &aTo) { aTo = aFrom; }
+};
+
+template<>
+struct SafeArrayTraits<ULONG64> : public SafeArrayTraitsBase
+{
+protected:
+
+ static VARTYPE VarType() { return VT_UI8; }
+ static ULONG VarCount(size_t aSize) { return (ULONG)aSize; }
+ static size_t Size(ULONG aVarCount) { return (size_t)aVarCount; }
+
+ static void Copy(ULONG64 aFrom, ULONG64 &aTo) { aTo = aFrom; }
+};
+
+template<>
+struct SafeArrayTraits<BSTR> : public SafeArrayTraitsBase
+{
+protected:
+
+ static VARTYPE VarType() { return VT_BSTR; }
+ static ULONG VarCount(size_t aSize) { return (ULONG)aSize; }
+ static size_t Size(ULONG aVarCount) { return (size_t)aVarCount; }
+
+ static void Copy(BSTR aFrom, BSTR &aTo)
+ {
+ aTo = aFrom ? ::SysAllocString((const OLECHAR *)aFrom) : NULL;
+ }
+};
+
+template<>
+struct SafeArrayTraits<GUID> : public SafeArrayTraitsBase
+{
+protected:
+
+ /* Use the 64-bit unsigned integer type for GUID */
+ static VARTYPE VarType() { return VT_UI8; }
+
+ /* GUID is 128 bit, so we need two VT_UI8 */
+ static ULONG VarCount(size_t aSize)
+ {
+ AssertCompileSize(GUID, 16);
+ return (ULONG)(aSize * 2);
+ }
+
+ static size_t Size(ULONG aVarCount) { return (size_t)aVarCount / 2; }
+
+ static void Copy(GUID aFrom, GUID &aTo) { aTo = aFrom; }
+};
+
+/**
+ * Helper for SafeArray::__asOutParam() that automatically updates m.raw after a
+ * non-NULL m.arr assignment.
+ */
+class OutSafeArrayDipper
+{
+ OutSafeArrayDipper(SAFEARRAY **aArr, void **aRaw)
+ : arr(aArr), raw(aRaw) { Assert(*aArr == NULL && *aRaw == NULL); }
+
+ SAFEARRAY **arr;
+ void **raw;
+
+ template<class, class> friend class SafeArray;
+
+public:
+
+ ~OutSafeArrayDipper()
+ {
+ if (*arr != NULL)
+ {
+ HRESULT rc = SafeArrayAccessData(*arr, raw);
+ AssertComRC(rc);
+ }
+ }
+
+ operator SAFEARRAY **() { return arr; }
+};
+
+#endif /* !VBOX_WITH_XPCOM */
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * The SafeArray class represents the safe array type used in COM to pass arrays
+ * to/from interface methods.
+ *
+ * This helper class hides all MSCOM/XPCOM specific implementation details and,
+ * together with ComSafeArrayIn, ComSafeArrayOut and ComSafeArrayRet macros,
+ * provides a platform-neutral way to handle safe arrays in the method
+ * implementation.
+ *
+ * When an instance of this class is destroyed, it automatically frees all
+ * resources occupied by individual elements of the array as well as by the
+ * array itself. However, when the value of an element is manually changed
+ * using #operator[] or by accessing array data through the #raw() pointer, it is
+ * the caller's responsibility to free resources occupied by the previous
+ * element's value.
+ *
+ * Also, objects of this class do not support copy and assignment operations and
+ * therefore cannot be returned from functions by value. In other words, this
+ * class is just a temporary storage for handling interface method calls and not
+ * intended to be used to store arrays as data members and such -- you should
+ * use normal list/vector classes for that.
+ *
+ * @note The current implementation supports only one-dimensional arrays.
+ *
+ * @note This class is not thread-safe.
+ */
+template<typename T, class Traits = SafeArrayTraits<T> >
+class SafeArray : public Traits
+{
+public:
+
+ /**
+ * Creates a null array.
+ */
+ SafeArray() {}
+
+ /**
+ * Creates a new array of the given size. All elements of the newly created
+ * array initialized with null values.
+ *
+ * @param aSize Initial number of elements in the array.
+ *
+ * @note If this object remains null after construction it means that there
+ * was not enough memory for creating an array of the requested size.
+ * The constructor will also assert in this case.
+ */
+ SafeArray(size_t aSize) { resize(aSize); }
+
+ /**
+ * Weakly attaches this instance to the existing array passed in a method
+ * parameter declared using the ComSafeArrayIn macro. When using this call,
+ * always wrap the parameter name in the ComSafeArrayInArg macro call like
+ * this:
+ * <pre>
+ * SafeArray safeArray(ComSafeArrayInArg(aArg));
+ * </pre>
+ *
+ * Note that this constructor doesn't take the ownership of the array. In
+ * particular, it means that operations that operate on the ownership (e.g.
+ * #detachTo()) are forbidden and will assert.
+ *
+ * @param aArg Input method parameter to attach to.
+ */
+ SafeArray(ComSafeArrayIn(T, aArg))
+ {
+#ifdef VBOX_WITH_XPCOM
+
+ AssertReturnVoid(aArg != NULL);
+
+ m.size = aArgSize;
+ m.arr = aArg;
+ m.isWeak = true;
+
+#else /* !VBOX_WITH_XPCOM */
+
+ AssertReturnVoid(aArg != NULL);
+ SAFEARRAY *arg = aArg;
+
+ if (arg)
+ {
+ AssertReturnVoid(arg->cDims == 1);
+
+ VARTYPE vt;
+ HRESULT rc = SafeArrayGetVartype(arg, &vt);
+ AssertComRCReturnVoid(rc);
+ AssertMsgReturnVoid(vt == VarType(),
+ ("Expected vartype %d, got %d.\n",
+ VarType(), vt));
+
+ rc = SafeArrayAccessData(arg, (void HUGEP **)&m.raw);
+ AssertComRCReturnVoid(rc);
+ }
+
+ m.arr = arg;
+ m.isWeak = true;
+
+#endif /* !VBOX_WITH_XPCOM */
+ }
+
+ /**
+ * Creates a deep copy of the given standard C++ container that stores
+ * T objects.
+ *
+ * @param aCntr Container object to copy.
+ *
+ * @param C Standard C++ container template class (normally deduced from
+ * @c aCntr).
+ */
+ template<template<typename, typename> class C, class A>
+ SafeArray(const C<T, A> & aCntr)
+ {
+ resize(aCntr.size());
+ AssertReturnVoid(!isNull());
+
+ size_t i = 0;
+ for (typename C<T, A>::const_iterator it = aCntr.begin();
+ it != aCntr.end(); ++ it, ++ i)
+#ifdef VBOX_WITH_XPCOM
+ SafeArray::Copy(*it, m.arr[i]);
+#else
+ Copy(*it, m.raw[i]);
+#endif
+ }
+
+ /**
+ * Creates a deep copy of the given standard C++ map that stores T objects
+ * as values.
+ *
+ * @param aMap Map object to copy.
+ *
+ * @param C Standard C++ map template class (normally deduced from
+ * @c aCntr).
+ * @param L Standard C++ compare class (deduced from @c aCntr).
+ * @param A Standard C++ allocator class (deduced from @c aCntr).
+ * @param K Map key class (deduced from @c aCntr).
+ */
+ template<template<typename, typename, typename, typename>
+ class C, class L, class A, class K>
+ SafeArray(const C<K, T, L, A> & aMap)
+ {
+ typedef C<K, T, L, A> Map;
+
+ resize(aMap.size());
+ AssertReturnVoid(!isNull());
+
+ int i = 0;
+ for (typename Map::const_iterator it = aMap.begin();
+ it != aMap.end(); ++ it, ++ i)
+#ifdef VBOX_WITH_XPCOM
+ Copy(it->second, m.arr[i]);
+#else
+ Copy(it->second, m.raw[i]);
+#endif
+ }
+
+ /**
+ * Destroys this instance after calling #setNull() to release allocated
+ * resources. See #setNull() for more details.
+ */
+ virtual ~SafeArray() { setNull(); }
+
+ /**
+ * Returns @c true if this instance represents a null array.
+ */
+ bool isNull() const { return m.arr == NULL; }
+
+ /**
+ * Returns @c true if this instance does not represents a null array.
+ */
+ bool isNotNull() const { return m.arr != NULL; }
+
+ /**
+ * Resets this instance to null and, if this instance is not a weak one,
+ * releases any resources occupied by the array data.
+ *
+ * @note This method destroys (cleans up) all elements of the array using
+ * the corresponding cleanup routine for the element type before the
+ * array itself is destroyed.
+ */
+ virtual void setNull() { m.uninit(); }
+
+ /**
+ * Returns @c true if this instance is weak. A weak instance doesn't own the
+ * array data and therefore operations manipulating the ownership (e.g.
+ * #detachTo()) are forbidden and will assert.
+ */
+ bool isWeak() const { return m.isWeak; }
+
+ /** Number of elements in the array. */
+ size_t size() const
+ {
+#ifdef VBOX_WITH_XPCOM
+ if (m.arr)
+ return m.size;
+ return 0;
+#else
+ if (m.arr)
+ return Size(m.arr->rgsabound[0].cElements);
+ return 0;
+#endif
+ }
+
+ /**
+ * Appends a copy of the given element at the end of the array.
+ *
+ * The array size is increased by one by this method and the additional
+ * space is allocated as needed.
+ *
+ * This method is handy in cases where you want to assign a copy of the
+ * existing value to the array element, for example:
+ * <tt>Bstr string; array.push_back(string);</tt>. If you create a string
+ * just to put it in the array, you may find #appendedRaw() more useful.
+ *
+ * @param aElement Element to append.
+ *
+ * @return @c true on success and @c false if there is not enough
+ * memory for resizing.
+ */
+ bool push_back(const T &aElement)
+ {
+ if (!ensureCapacity(size() + 1))
+ return false;
+
+#ifdef VBOX_WITH_XPCOM
+ SafeArray::Copy(aElement, m.arr[m.size]);
+ ++ m.size;
+#else
+ Copy(aElement, m.raw[size() - 1]);
+#endif
+ return true;
+ }
+
+ /**
+ * Appends an empty element at the end of the array and returns a raw
+ * pointer to it suitable for assigning a raw value (w/o constructing a
+ * copy).
+ *
+ * The array size is increased by one by this method and the additional
+ * space is allocated as needed.
+ *
+ * Note that in case of raw assignment, value ownership (for types with
+ * dynamically allocated data and for interface pointers) is transferred to
+ * the safe array object.
+ *
+ * This method is handy for operations like
+ * <tt>Bstr("foo").detachTo(array.appendedRaw());</tt>. Don't use it as
+ * an l-value (<tt>array.appendedRaw() = SysAllocString(L"tralala");</tt>)
+ * since this doesn't check for a NULL condition; use #resize() and
+ * #setRawAt() instead. If you need to assign a copy of the existing value
+ * instead of transferring the ownership, look at #push_back().
+ *
+ * @return Raw pointer to the added element or NULL if no memory.
+ */
+ T *appendedRaw()
+ {
+ if (!ensureCapacity(size() + 1))
+ return NULL;
+
+#ifdef VBOX_WITH_XPCOM
+ SafeArray::Init(m.arr[m.size]);
+ ++ m.size;
+ return &m.arr[m.size - 1];
+#else
+ /* nothing to do here, SafeArrayCreate() has performed element
+ * initialization */
+ return &m.raw[size() - 1];
+#endif
+ }
+
+ /**
+ * Resizes the array preserving its contents when possible. If the new size
+ * is larger than the old size, new elements are initialized with null
+ * values. If the new size is less than the old size, the contents of the
+ * array beyond the new size is lost.
+ *
+ * @param aNewSize New number of elements in the array.
+ * @return @c true on success and @c false if there is not enough
+ * memory for resizing.
+ */
+ bool resize(size_t aNewSize)
+ {
+ if (!ensureCapacity(aNewSize))
+ return false;
+
+#ifdef VBOX_WITH_XPCOM
+
+ if (m.size < aNewSize)
+ {
+ /* initialize the new elements */
+ for (size_t i = m.size; i < aNewSize; ++ i)
+ SafeArray::Init(m.arr[i]);
+ }
+
+ m.size = aNewSize;
+#else
+ /* nothing to do here, SafeArrayCreate() has performed element
+ * initialization */
+#endif
+ return true;
+ }
+
+ /**
+ * Reinitializes this instance by preallocating space for the given number
+ * of elements. The previous array contents is lost.
+ *
+ * @param aNewSize New number of elements in the array.
+ * @return @c true on success and @c false if there is not enough
+ * memory for resizing.
+ */
+ bool reset(size_t aNewSize)
+ {
+ m.uninit();
+ return resize(aNewSize);
+ }
+
+ /**
+ * Returns a pointer to the raw array data. Use this raw pointer with care
+ * as no type or bound checking is done for you in this case.
+ *
+ * @note This method returns @c NULL when this instance is null.
+ * @see #operator[]
+ */
+ T *raw()
+ {
+#ifdef VBOX_WITH_XPCOM
+ return m.arr;
+#else
+ return m.raw;
+#endif
+ }
+
+ /**
+ * Const version of #raw().
+ */
+ const T *raw() const
+ {
+#ifdef VBOX_WITH_XPCOM
+ return m.arr;
+#else
+ return m.raw;
+#endif
+ }
+
+ /**
+ * Array access operator that returns an array element by reference. A bit
+ * safer than #raw(): asserts and returns an invalid reference if this
+ * instance is null or if the index is out of bounds.
+ *
+ * @note For weak instances, this call will succeed but the behavior of
+ * changing the contents of an element of the weak array instance is
+ * undefined and may lead to a program crash on some platforms.
+ */
+ T &operator[] (size_t aIdx)
+ {
+ AssertReturn(m.arr != NULL, *((T *)NULL));
+ AssertReturn(aIdx < size(), *((T *)NULL));
+#ifdef VBOX_WITH_XPCOM
+ return m.arr[aIdx];
+#else
+ AssertReturn(m.raw != NULL, *((T *)NULL));
+ return m.raw[aIdx];
+#endif
+ }
+
+ /**
+ * Const version of #operator[] that returns an array element by value.
+ */
+ const T operator[] (size_t aIdx) const
+ {
+ AssertReturn(m.arr != NULL, *((T *)NULL));
+ AssertReturn(aIdx < size(), *((T *)NULL));
+#ifdef VBOX_WITH_XPCOM
+ return m.arr[aIdx];
+#else
+ AssertReturn(m.raw != NULL, *((T *)NULL));
+ return m.raw[aIdx];
+#endif
+ }
+
+ /**
+ * Creates a copy of this array and stores it in a method parameter declared
+ * using the ComSafeArrayOut macro. When using this call, always wrap the
+ * parameter name in the ComSafeArrayOutArg macro call like this:
+ * <pre>
+ * safeArray.cloneTo(ComSafeArrayOutArg(aArg));
+ * </pre>
+ *
+ * @note It is assumed that the ownership of the returned copy is
+ * transferred to the caller of the method and he is responsible to free the
+ * array data when it is no longer needed.
+ *
+ * @param aArg Output method parameter to clone to.
+ */
+ virtual const SafeArray &cloneTo(ComSafeArrayOut(T, aArg)) const
+ {
+ /// @todo Implement me!
+#ifdef VBOX_WITH_XPCOM
+ NOREF(aArgSize);
+ NOREF(aArg);
+#else
+ NOREF(aArg);
+#endif
+ AssertFailedReturn(*this);
+ }
+
+ void cloneTo(SafeArray<T>& aOther) const
+ {
+ aOther.reset(size());
+ aOther.initFrom(*this);
+ }
+
+
+ /**
+ * Transfers the ownership of this array's data to the specified location
+ * declared using the ComSafeArrayOut macro and makes this array a null
+ * array. When using this call, always wrap the parameter name in the
+ * ComSafeArrayOutArg macro call like this:
+ * <pre>
+ * safeArray.detachTo(ComSafeArrayOutArg(aArg));
+ * </pre>
+ *
+ * Detaching the null array is also possible in which case the location will
+ * receive NULL.
+ *
+ * @note Since the ownership of the array data is transferred to the
+ * caller of the method, he is responsible to free the array data when it is
+ * no longer needed.
+ *
+ * @param aArg Location to detach to.
+ */
+ virtual SafeArray &detachTo(ComSafeArrayOut(T, aArg))
+ {
+ AssertReturn(m.isWeak == false, *this);
+
+#ifdef VBOX_WITH_XPCOM
+
+ AssertReturn(aArgSize != NULL, *this);
+ AssertReturn(aArg != NULL, *this);
+
+ *aArgSize = m.size;
+ *aArg = m.arr;
+
+ m.isWeak = false;
+ m.size = 0;
+ m.arr = NULL;
+
+#else /* !VBOX_WITH_XPCOM */
+
+ AssertReturn(aArg != NULL, *this);
+ *aArg = m.arr;
+
+ if (m.raw)
+ {
+ HRESULT rc = SafeArrayUnaccessData(m.arr);
+ AssertComRCReturn(rc, *this);
+ m.raw = NULL;
+ }
+
+ m.isWeak = false;
+ m.arr = NULL;
+
+#endif /* !VBOX_WITH_XPCOM */
+
+ return *this;
+ }
+
+ /**
+ * Returns a copy of this SafeArray as RTCList<T>.
+ */
+ RTCList<T> toList()
+ {
+ RTCList<T> list(size());
+ for (size_t i = 0; i < size(); ++i)
+#ifdef VBOX_WITH_XPCOM
+ list.append(m.arr[i]);
+#else
+ list.append(m.raw[i]);
+#endif
+ return list;
+ }
+
+ inline void initFrom(const com::SafeArray<T> & aRef);
+ inline void initFrom(const T* aPtr, size_t aSize);
+
+ // Public methods for internal purposes only.
+
+#ifdef VBOX_WITH_XPCOM
+
+ /** Internal function. Never call it directly. */
+ PRUint32 *__asOutParam_Size() { setNull(); return &m.size; }
+
+ /** Internal function Never call it directly. */
+ T **__asOutParam_Arr() { Assert(isNull()); return &m.arr; }
+
+#else /* !VBOX_WITH_XPCOM */
+
+ /** Internal function Never call it directly. */
+ SAFEARRAY * __asInParam() { return m.arr; }
+
+ /** Internal function Never call it directly. */
+ OutSafeArrayDipper __asOutParam()
+ { setNull(); return OutSafeArrayDipper(&m.arr, (void **)&m.raw); }
+
+#endif /* !VBOX_WITH_XPCOM */
+
+ static const SafeArray Null;
+
+protected:
+
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(SafeArray)
+
+ /**
+ * Ensures that the array is big enough to contain aNewSize elements.
+ *
+ * If the new size is greater than the current capacity, a new array is
+ * allocated and elements from the old array are copied over. The size of
+ * the array doesn't change, only the capacity increases (which is always
+ * greater than the size). Note that the additionally allocated elements are
+ * left uninitialized by this method.
+ *
+ * If the new size is less than the current size, the existing array is
+ * truncated to the specified size and the elements outside the new array
+ * boundary are freed.
+ *
+ * If the new size is the same as the current size, nothing happens.
+ *
+ * @param aNewSize New size of the array.
+ *
+ * @return @c true on success and @c false if not enough memory.
+ */
+ bool ensureCapacity(size_t aNewSize)
+ {
+ AssertReturn(!m.isWeak, false);
+
+#ifdef VBOX_WITH_XPCOM
+
+ /* Note: we distinguish between a null array and an empty (zero
+ * elements) array. Therefore we never use zero in malloc (even if
+ * aNewSize is zero) to make sure we get a non-null pointer. */
+
+ if (m.size == aNewSize && m.arr != NULL)
+ return true;
+
+ /* Allocate in 16-byte pieces. */
+ size_t newCapacity = RT_MAX((aNewSize + 15) / 16 * 16, 16);
+
+ if (m.capacity != newCapacity)
+ {
+ T *newArr = (T *)nsMemory::Alloc(RT_MAX(newCapacity, 1) * sizeof(T));
+ AssertReturn(newArr != NULL, false);
+
+ if (m.arr != NULL)
+ {
+ if (m.size > aNewSize)
+ {
+ /* Truncation takes place, uninit exceeding elements and
+ * shrink the size. */
+ for (size_t i = aNewSize; i < m.size; ++ i)
+ SafeArray::Uninit(m.arr[i]);
+
+ m.size = aNewSize;
+ }
+
+ /* Copy the old contents. */
+ memcpy(newArr, m.arr, m.size * sizeof(T));
+ nsMemory::Free((void *)m.arr);
+ }
+
+ m.arr = newArr;
+ }
+ else
+ {
+ if (m.size > aNewSize)
+ {
+ /* Truncation takes place, uninit exceeding elements and
+ * shrink the size. */
+ for (size_t i = aNewSize; i < m.size; ++ i)
+ SafeArray::Uninit(m.arr[i]);
+
+ m.size = aNewSize;
+ }
+ }
+
+ m.capacity = newCapacity;
+
+#else
+
+ SAFEARRAYBOUND bound = { VarCount(aNewSize), 0 };
+ HRESULT rc;
+
+ if (m.arr == NULL)
+ {
+ m.arr = CreateSafeArray(VarType(), &bound);
+ AssertReturn(m.arr != NULL, false);
+ }
+ else
+ {
+ SafeArrayUnaccessData(m.arr);
+
+ rc = SafeArrayRedim(m.arr, &bound);
+ AssertComRCReturn(rc == S_OK, false);
+ }
+
+ rc = SafeArrayAccessData(m.arr, (void HUGEP **)&m.raw);
+ AssertComRCReturn(rc, false);
+
+#endif
+ return true;
+ }
+
+ struct Data
+ {
+ Data()
+ : isWeak(false)
+#ifdef VBOX_WITH_XPCOM
+ , capacity(0), size(0), arr(NULL)
+#else
+ , arr(NULL), raw(NULL)
+#endif
+ {}
+
+ ~Data() { uninit(); }
+
+ void uninit()
+ {
+#ifdef VBOX_WITH_XPCOM
+
+ if (arr)
+ {
+ if (!isWeak)
+ {
+ for (size_t i = 0; i < size; ++ i)
+ SafeArray::Uninit(arr[i]);
+
+ nsMemory::Free((void *)arr);
+ }
+ else
+ isWeak = false;
+
+ arr = NULL;
+ }
+
+ size = capacity = 0;
+
+#else /* !VBOX_WITH_XPCOM */
+
+ if (arr)
+ {
+ if (raw)
+ {
+ SafeArrayUnaccessData(arr);
+ raw = NULL;
+ }
+
+ if (!isWeak)
+ {
+ HRESULT rc = SafeArrayDestroy(arr);
+ AssertComRCReturnVoid(rc);
+ }
+ else
+ isWeak = false;
+
+ arr = NULL;
+ }
+
+#endif /* !VBOX_WITH_XPCOM */
+ }
+
+ bool isWeak : 1;
+
+#ifdef VBOX_WITH_XPCOM
+ PRUint32 capacity;
+ PRUint32 size;
+ T *arr;
+#else
+ SAFEARRAY *arr;
+ T *raw;
+#endif
+ };
+
+ Data m;
+};
+
+/* Few fast specializations for primitive array types */
+template<>
+inline void com::SafeArray<BYTE>::initFrom(const com::SafeArray<BYTE> & aRef)
+{
+ size_t sSize = aRef.size();
+ resize(sSize);
+ ::memcpy(raw(), aRef.raw(), sSize);
+}
+template<>
+inline void com::SafeArray<BYTE>::initFrom(const BYTE* aPtr, size_t aSize)
+{
+ resize(aSize);
+ ::memcpy(raw(), aPtr, aSize);
+}
+
+
+template<>
+inline void com::SafeArray<LONG>::initFrom(const com::SafeArray<LONG> & aRef)
+{
+ size_t sSize = aRef.size();
+ resize(sSize);
+ ::memcpy(raw(), aRef.raw(), sSize * sizeof(LONG));
+}
+template<>
+inline void com::SafeArray<LONG>::initFrom(const LONG* aPtr, size_t aSize)
+{
+ resize(aSize);
+ ::memcpy(raw(), aPtr, aSize * sizeof(LONG));
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef VBOX_WITH_XPCOM
+
+/**
+ * Version of com::SafeArray for arrays of GUID.
+ *
+ * In MS COM, GUID arrays store GUIDs by value and therefore input arrays are
+ * represented using |GUID *| and out arrays -- using |GUID **|. In XPCOM,
+ * GUID arrays store pointers to nsID so that input arrays are |const nsID **|
+ * and out arrays are |nsID ***|. Due to this difference, it is impossible to
+ * work with arrays of GUID on both platforms by simply using com::SafeArray
+ * <GUID>. This class is intended to provide some level of cross-platform
+ * behavior.
+ *
+ * The basic usage pattern is basically similar to com::SafeArray<> except that
+ * you use ComSafeGUIDArrayIn* and ComSafeGUIDArrayOut* macros instead of
+ * ComSafeArrayIn* and ComSafeArrayOut*. Another important nuance is that the
+ * raw() array type is different (nsID **, or GUID ** on XPCOM and GUID * on MS
+ * COM) so it is recommended to use operator[] instead which always returns a
+ * GUID by value.
+ *
+ * Note that due to const modifiers, you cannot use SafeGUIDArray for input GUID
+ * arrays. Please use SafeConstGUIDArray for this instead.
+ *
+ * Other than mentioned above, the functionality of this class is equivalent to
+ * com::SafeArray<>. See the description of that template and its methods for
+ * more information.
+ *
+ * Output GUID arrays are handled by a separate class, SafeGUIDArrayOut, since
+ * this class cannot handle them because of const modifiers.
+ */
+class SafeGUIDArray : public SafeArray<nsID *>
+{
+public:
+
+ typedef SafeArray<nsID *> Base;
+
+ class nsIDRef
+ {
+ public:
+
+ nsIDRef(nsID * &aVal) : mVal(aVal) {}
+
+ operator const nsID &() const { return mVal ? *mVal : *Empty; }
+ operator nsID() const { return mVal ? *mVal : *Empty; }
+
+ const nsID *operator&() const { return mVal ? mVal : Empty; }
+
+ nsIDRef &operator= (const nsID &aThat)
+ {
+ if (mVal == NULL)
+ Copy(&aThat, mVal);
+ else
+ *mVal = aThat;
+ return *this;
+ }
+
+ private:
+
+ nsID * &mVal;
+
+ static const nsID *Empty;
+
+ friend class SafeGUIDArray;
+ };
+
+ /** See SafeArray<>::SafeArray(). */
+ SafeGUIDArray() {}
+
+ /** See SafeArray<>::SafeArray(size_t). */
+ SafeGUIDArray(size_t aSize) : Base(aSize) {}
+
+ /**
+ * Array access operator that returns an array element by reference. As a
+ * special case, the return value of this operator on XPCOM is an nsID (GUID)
+ * reference, instead of an nsID pointer (the actual SafeArray template
+ * argument), for compatibility with the MS COM version.
+ *
+ * The rest is equivalent to SafeArray<>::operator[].
+ */
+ nsIDRef operator[] (size_t aIdx)
+ {
+ Assert(m.arr != NULL);
+ Assert(aIdx < size());
+ return nsIDRef(m.arr[aIdx]);
+ }
+
+ /**
+ * Const version of #operator[] that returns an array element by value.
+ */
+ const nsID &operator[] (size_t aIdx) const
+ {
+ Assert(m.arr != NULL);
+ Assert(aIdx < size());
+ return m.arr[aIdx] ? *m.arr[aIdx] : *nsIDRef::Empty;
+ }
+};
+
+/**
+ * Version of com::SafeArray for const arrays of GUID.
+ *
+ * This class is used to work with input GUID array parameters in method
+ * implementations. See SafeGUIDArray for more details.
+ */
+class SafeConstGUIDArray : public SafeArray<const nsID *,
+ SafeArrayTraits<nsID *> >
+{
+public:
+
+ typedef SafeArray<const nsID *, SafeArrayTraits<nsID *> > Base;
+
+ /** See SafeArray<>::SafeArray(). */
+ SafeConstGUIDArray() {}
+
+ /* See SafeArray<>::SafeArray(ComSafeArrayIn(T, aArg)). */
+ SafeConstGUIDArray(ComSafeGUIDArrayIn(aArg))
+ : Base(ComSafeGUIDArrayInArg(aArg)) {}
+
+ /**
+ * Array access operator that returns an array element by reference. As a
+ * special case, the return value of this operator on XPCOM is nsID (GUID)
+ * instead of nsID *, for compatibility with the MS COM version.
+ *
+ * The rest is equivalent to SafeArray<>::operator[].
+ */
+ const nsID &operator[] (size_t aIdx) const
+ {
+ AssertReturn(m.arr != NULL, **((const nsID * *)NULL));
+ AssertReturn(aIdx < size(), **((const nsID * *)NULL));
+ return *m.arr[aIdx];
+ }
+
+private:
+
+ /* These are disabled because of const. */
+ bool reset(size_t aNewSize) { NOREF(aNewSize); return false; }
+};
+
+#else /* !VBOX_WITH_XPCOM */
+
+typedef SafeArray<GUID> SafeGUIDArray;
+typedef SafeArray<const GUID, SafeArrayTraits<GUID> > SafeConstGUIDArray;
+
+#endif /* !VBOX_WITH_XPCOM */
+
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef VBOX_WITH_XPCOM
+
+template<class I>
+struct SafeIfaceArrayTraits
+{
+protected:
+
+ static void Init(I * &aElem) { aElem = NULL; }
+ static void Uninit(I * &aElem)
+ {
+ if (aElem)
+ {
+ aElem->Release();
+ aElem = NULL;
+ }
+ }
+
+ static void Copy(I * aFrom, I * &aTo)
+ {
+ if (aFrom != NULL)
+ {
+ aTo = aFrom;
+ aTo->AddRef();
+ }
+ else
+ aTo = NULL;
+ }
+
+public:
+
+ /* Magic to workaround strict rules of par. 4.4.4 of the C++ standard. */
+ static I **__asInParam_Arr(I **aArr) { return aArr; }
+ static I **__asInParam_Arr(const I **aArr) { return const_cast<I **>(aArr); }
+};
+
+#else /* !VBOX_WITH_XPCOM */
+
+template<class I>
+struct SafeIfaceArrayTraits
+{
+protected:
+
+ static VARTYPE VarType() { return VT_DISPATCH; }
+ static ULONG VarCount(size_t aSize) { return (ULONG)aSize; }
+ static size_t Size(ULONG aVarCount) { return (size_t)aVarCount; }
+
+ static void Copy(I * aFrom, I * &aTo)
+ {
+ if (aFrom != NULL)
+ {
+ aTo = aFrom;
+ aTo->AddRef();
+ }
+ else
+ aTo = NULL;
+ }
+
+ static SAFEARRAY *CreateSafeArray(VARTYPE aVarType, SAFEARRAYBOUND *aBound)
+ {
+ NOREF(aVarType);
+ return SafeArrayCreateEx(VT_DISPATCH, 1, aBound, (PVOID)&_ATL_IIDOF(I));
+ }
+};
+
+#endif /* !VBOX_WITH_XPCOM */
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Version of com::SafeArray for arrays of interface pointers.
+ *
+ * Except that it manages arrays of interface pointers, the usage of this class
+ * is identical to com::SafeArray.
+ *
+ * @param I Interface class (no asterisk).
+ */
+template<class I>
+class SafeIfaceArray : public SafeArray<I *, SafeIfaceArrayTraits<I> >
+{
+public:
+
+ typedef SafeArray<I *, SafeIfaceArrayTraits<I> > Base;
+
+ /**
+ * Creates a null array.
+ */
+ SafeIfaceArray() {}
+
+ /**
+ * Creates a new array of the given size. All elements of the newly created
+ * array initialized with null values.
+ *
+ * @param aSize Initial number of elements in the array. Must be greater
+ * than 0.
+ *
+ * @note If this object remains null after construction it means that there
+ * was not enough memory for creating an array of the requested size.
+ * The constructor will also assert in this case.
+ */
+ SafeIfaceArray(size_t aSize) { Base::resize(aSize); }
+
+ /**
+ * Weakly attaches this instance to the existing array passed in a method
+ * parameter declared using the ComSafeArrayIn macro. When using this call,
+ * always wrap the parameter name in the ComSafeArrayOutArg macro call like
+ * this:
+ * <pre>
+ * SafeArray safeArray(ComSafeArrayInArg(aArg));
+ * </pre>
+ *
+ * Note that this constructor doesn't take the ownership of the array. In
+ * particular, this means that operations that operate on the ownership
+ * (e.g. #detachTo()) are forbidden and will assert.
+ *
+ * @param aArg Input method parameter to attach to.
+ */
+ SafeIfaceArray(ComSafeArrayIn(I *, aArg))
+ {
+#ifdef VBOX_WITH_XPCOM
+
+ AssertReturnVoid(aArg != NULL);
+
+ Base::m.size = aArgSize;
+ Base::m.arr = aArg;
+ Base::m.isWeak = true;
+
+#else /* !VBOX_WITH_XPCOM */
+
+ AssertReturnVoid(aArg != NULL);
+ SAFEARRAY *arg = aArg;
+
+ if (arg)
+ {
+ AssertReturnVoid(arg->cDims == 1);
+
+ VARTYPE vt;
+ HRESULT rc = SafeArrayGetVartype(arg, &vt);
+ AssertComRCReturnVoid(rc);
+ AssertMsgReturnVoid(vt == VT_UNKNOWN || vt == VT_DISPATCH,
+ ("Expected vartype VT_UNKNOWN, got %d.\n",
+ VarType(), vt));
+ GUID guid;
+ rc = SafeArrayGetIID(arg, &guid);
+ AssertComRCReturnVoid(rc);
+ AssertMsgReturnVoid(InlineIsEqualGUID(_ATL_IIDOF(I), guid),
+ ("Expected IID {%RTuuid}, got {%RTuuid}.\n",
+ &_ATL_IIDOF(I), &guid));
+
+ rc = SafeArrayAccessData(arg, (void HUGEP **)&m.raw);
+ AssertComRCReturnVoid(rc);
+ }
+
+ m.arr = arg;
+ m.isWeak = true;
+
+#endif /* !VBOX_WITH_XPCOM */
+ }
+
+ /**
+ * Creates a deep copy of the given standard C++ container that stores
+ * interface pointers as objects of the ComPtr<I> class.
+ *
+ * @param aCntr Container object to copy.
+ *
+ * @param C Standard C++ container template class (normally deduced from
+ * @c aCntr).
+ * @param A Standard C++ allocator class (deduced from @c aCntr).
+ * @param OI Argument to the ComPtr template (deduced from @c aCntr).
+ */
+ template<template<typename, typename> class C, class A, class OI>
+ SafeIfaceArray(const C<ComPtr<OI>, A> & aCntr)
+ {
+ typedef C<ComPtr<OI>, A> List;
+
+ Base::resize(aCntr.size());
+ AssertReturnVoid(!Base::isNull());
+
+ int i = 0;
+ for (typename List::const_iterator it = aCntr.begin();
+ it != aCntr.end(); ++ it, ++ i)
+#ifdef VBOX_WITH_XPCOM
+ Copy(*it, Base::m.arr[i]);
+#else
+ Copy(*it, Base::m.raw[i]);
+#endif
+ }
+
+ /**
+ * Creates a deep copy of the given standard C++ container that stores
+ * interface pointers as objects of the ComObjPtr<I> class.
+ *
+ * @param aCntr Container object to copy.
+ *
+ * @param C Standard C++ container template class (normally deduced from
+ * @c aCntr).
+ * @param A Standard C++ allocator class (deduced from @c aCntr).
+ * @param OI Argument to the ComObjPtr template (deduced from @c aCntr).
+ */
+ template<template<typename, typename> class C, class A, class OI>
+ SafeIfaceArray(const C<ComObjPtr<OI>, A> & aCntr)
+ {
+ typedef C<ComObjPtr<OI>, A> List;
+
+ Base::resize(aCntr.size());
+ AssertReturnVoid(!Base::isNull());
+
+ int i = 0;
+ for (typename List::const_iterator it = aCntr.begin();
+ it != aCntr.end(); ++ it, ++ i)
+#ifdef VBOX_WITH_XPCOM
+ SafeIfaceArray::Copy(*it, Base::m.arr[i]);
+#else
+ Copy(*it, Base::m.raw[i]);
+#endif
+ }
+
+ /**
+ * Creates a deep copy of the given standard C++ map whose values are
+ * interface pointers stored as objects of the ComPtr<I> class.
+ *
+ * @param aMap Map object to copy.
+ *
+ * @param C Standard C++ map template class (normally deduced from
+ * @c aCntr).
+ * @param L Standard C++ compare class (deduced from @c aCntr).
+ * @param A Standard C++ allocator class (deduced from @c aCntr).
+ * @param K Map key class (deduced from @c aCntr).
+ * @param OI Argument to the ComPtr template (deduced from @c aCntr).
+ */
+ template<template<typename, typename, typename, typename>
+ class C, class L, class A, class K, class OI>
+ SafeIfaceArray(const C<K, ComPtr<OI>, L, A> & aMap)
+ {
+ typedef C<K, ComPtr<OI>, L, A> Map;
+
+ Base::resize(aMap.size());
+ AssertReturnVoid(!Base::isNull());
+
+ int i = 0;
+ for (typename Map::const_iterator it = aMap.begin();
+ it != aMap.end(); ++ it, ++ i)
+#ifdef VBOX_WITH_XPCOM
+ SafeIfaceArray::Copy(it->second, Base::m.arr[i]);
+#else
+ Copy(it->second, Base::m.raw[i]);
+#endif
+ }
+
+ /**
+ * Creates a deep copy of the given standard C++ map whose values are
+ * interface pointers stored as objects of the ComObjPtr<I> class.
+ *
+ * @param aMap Map object to copy.
+ *
+ * @param C Standard C++ map template class (normally deduced from
+ * @c aCntr).
+ * @param L Standard C++ compare class (deduced from @c aCntr).
+ * @param A Standard C++ allocator class (deduced from @c aCntr).
+ * @param K Map key class (deduced from @c aCntr).
+ * @param OI Argument to the ComObjPtr template (deduced from @c aCntr).
+ */
+ template<template<typename, typename, typename, typename>
+ class C, class L, class A, class K, class OI>
+ SafeIfaceArray(const C<K, ComObjPtr<OI>, L, A> & aMap)
+ {
+ typedef C<K, ComObjPtr<OI>, L, A> Map;
+
+ Base::resize(aMap.size());
+ AssertReturnVoid(!Base::isNull());
+
+ int i = 0;
+ for (typename Map::const_iterator it = aMap.begin();
+ it != aMap.end(); ++ it, ++ i)
+#ifdef VBOX_WITH_XPCOM
+ SafeIfaceArray::Copy(it->second, Base::m.arr[i]);
+#else
+ Copy(it->second, Base::m.raw[i]);
+#endif
+ }
+
+ void setElement(size_t iIdx, I* obj)
+ {
+#ifdef VBOX_WITH_XPCOM
+ SafeIfaceArray::Copy(obj, Base::m.arr[iIdx]);
+#else
+ Copy(obj, Base::m.raw[iIdx]);
+#endif
+ }
+};
+
+} /* namespace com */
+
+/** @} */
+
+#endif /* ___VBox_com_array_h */
diff --git a/include/VBox/com/assert.h b/include/VBox/com/assert.h
new file mode 100644
index 00000000..0a9b1afd
--- /dev/null
+++ b/include/VBox/com/assert.h
@@ -0,0 +1,108 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * Assertion macros for COM/XPCOM
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_com_assert_h
+#define ___VBox_com_assert_h
+
+#include <iprt/assert.h>
+
+/**
+ * Asserts that the COM result code is succeeded in strict builds.
+ * In non-strict builds the result code will be NOREF'ed to kill compiler warnings.
+ *
+ * @param rc COM result code
+ */
+#define AssertComRC(rc) \
+ do { AssertMsg (SUCCEEDED (rc), ("COM RC = %Rhrc (0x%08X)\n", rc, rc)); NOREF (rc); } while (0)
+
+/**
+ * A special version of AssertComRC that returns the given expression
+ * if the result code is failed.
+ *
+ * @param rc COM result code
+ * @param ret the expression to return
+ */
+#define AssertComRCReturn(rc, ret) \
+ AssertMsgReturn (SUCCEEDED (rc), ("COM RC = %Rhrc (0x%08X)\n", rc, rc), ret)
+
+/**
+ * A special version of AssertComRC that returns the given result code
+ * if it is failed.
+ *
+ * @param rc COM result code
+ * @param ret the expression to return
+ */
+#define AssertComRCReturnRC(rc) \
+ AssertMsgReturn (SUCCEEDED (rc), ("COM RC = %Rhrc (0x%08X)\n", rc, rc), rc)
+
+/**
+ * A special version of AssertComRC that returns if the result code is failed.
+ *
+ * @param rc COM result code
+ * @param ret the expression to return
+ */
+#define AssertComRCReturnVoid(rc) \
+ AssertMsgReturnVoid (SUCCEEDED (rc), ("COM RC = %Rhrc (0x%08X)\n", rc, rc))
+
+/**
+ * A special version of AssertComRC that evaluates the given expression and
+ * breaks if the result code is failed.
+ *
+ * @param rc COM result code
+ * @param eval the expression to evaluate
+ */
+#define AssertComRCBreak(rc, eval) \
+ if (!SUCCEEDED (rc)) { AssertComRC (rc); eval; break; } else do {} while (0)
+
+/**
+ * A special version of AssertComRC that evaluates the given expression and
+ * throws it if the result code is failed.
+ *
+ * @param rc COM result code
+ * @param eval the expression to throw
+ */
+#define AssertComRCThrow(rc, eval) \
+ if (!SUCCEEDED (rc)) { AssertComRC (rc); throw (eval); } else do {} while (0)
+
+/**
+ * A special version of AssertComRC that just breaks if the result code is
+ * failed.
+ *
+ * @param rc COM result code
+ */
+#define AssertComRCBreakRC(rc) \
+ if (!SUCCEEDED (rc)) { AssertComRC (rc); break; } else do {} while (0)
+
+/**
+ * A special version of AssertComRC that just throws @a rc if the result code is
+ * failed.
+ *
+ * @param rc COM result code
+ */
+#define AssertComRCThrowRC(rc) \
+ if (!SUCCEEDED (rc)) { AssertComRC (rc); throw rc; } else do {} while (0)
+
+#endif // !___VBox_com_assert_h
diff --git a/include/VBox/com/com.h b/include/VBox/com/com.h
new file mode 100644
index 00000000..524c89c6
--- /dev/null
+++ b/include/VBox/com/com.h
@@ -0,0 +1,111 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * COM initialization / shutdown
+ */
+
+/*
+ * Copyright (C) 2005-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 ___VBox_com_com_h
+#define ___VBox_com_com_h
+
+#include "VBox/com/defs.h"
+
+namespace com
+{
+
+/**
+ * Initializes the COM runtime.
+ * Must be called on the main thread, before any COM activity in any thread, and by any thread
+ * willing to perform COM operations.
+ *
+ * @param fMain if call is performed on the GUI thread
+ * @return COM result code
+ */
+HRESULT Initialize(bool fGui = false);
+
+/**
+ * Shuts down the COM runtime.
+ * Must be called on the main thread before termination.
+ * No COM calls may be made in any thread after this method returns.
+ */
+HRESULT Shutdown();
+
+/**
+ * Resolves a given interface ID to a string containing the interface name.
+ * If, for some reason, the given IID cannot be resolved to a name, a NULL
+ * string is returned. A non-NULL string returned by this function must be
+ * freed using SysFreeString().
+ *
+ * @param aIID ID of the interface to get a name for
+ * @param aName Resolved interface name or @c NULL on error
+ */
+void GetInterfaceNameByIID(const GUID &aIID, BSTR *aName);
+
+/**
+ * Returns the VirtualBox user home directory.
+ *
+ * On failure, this function will return a path that caused a failure (or
+ * NULL if the failure is not path-related).
+ *
+ * On success, this function will try to create the returned directory if it
+ * doesn't exist yet. This may also fail with the corresponding status code.
+ *
+ * If @a aDirLen is smaller than RTPATH_MAX then there is a great chance that
+ * this method will return VERR_BUFFER_OVERFLOW.
+ *
+ * @param aDir Buffer to store the directory string in UTF-8 encoding.
+ * @param aDirLen Length of the supplied buffer including space for the
+ * terminating null character, in bytes.
+ * @param fCreateDir Flag whether to create the returned directory on success if it
+ * doesn't exist.
+ * @return VBox status code.
+ */
+int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir = true);
+
+/**
+ * Creates a release log file, used both in VBoxSVC and in API clients.
+ *
+ * @param pcszEntity Human readable name of the program.
+ * @param pcszLogFile Name of the release log file.
+ * @param fFlags Logger instance flags.
+ * @param pcszGroupSettings Group logging settings.
+ * @param pcszEnvVarBase Base environment variable name for the logger.
+ * @param fDestFlags Logger destination flags.
+ * @param cMaxEntriesPerGroup Limit for log entries per group. UINT32_MAX for no limit.
+ * @param cHistory Number of old log files to keep.
+ * @param uHistoryFileTime Maximum amount of time to put in a log file.
+ * @param uHistoryFileSize Maximum size of a log file before rotating.
+ * @param pszError In case of creation failure: buffer for error message.
+ * @param cbError Size of error message buffer.
+ * @return VBox status code.
+ */
+int VBoxLogRelCreate(const char *pcszEntity, const char *pcszLogFile,
+ uint32_t fFlags, const char *pcszGroupSettings,
+ const char *pcszEnvVarBase, uint32_t fDestFlags,
+ uint32_t cMaxEntriesPerGroup, uint32_t cHistory,
+ uint32_t uHistoryFileTime, uint64_t uHistoryFileSize,
+ char *pszError, size_t cbError);
+
+} /* namespace com */
+
+#endif
+
diff --git a/include/VBox/com/defs.h b/include/VBox/com/defs.h
new file mode 100644
index 00000000..aa9800dd
--- /dev/null
+++ b/include/VBox/com/defs.h
@@ -0,0 +1,549 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * Common definitions
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_defs_h
+#define ___VBox_com_defs_h
+
+/* Make sure all the stdint.h macros are included - must come first! */
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS
+#endif
+
+#if defined (RT_OS_OS2)
+
+# if defined(RT_MAX) && RT_MAX != 22
+# undef RT_MAX
+# define REDEFINE_RT_MAX
+# endif
+# undef RT_MAX
+
+/* Make sure OS/2 Toolkit headers are pulled in to have BOOL/ULONG/etc. typedefs
+ * already defined in order to be able to redefine them using #define. */
+# define INCL_BASE
+# define INCL_PM
+# include <os2.h>
+
+/* OS/2 Toolkit defines TRUE and FALSE */
+# undef FALSE
+# undef TRUE
+
+/* */
+# undef RT_MAX
+# ifdef REDEFINE_RT_MAX
+# define RT_MAX(Value1, Value2) ( (Value1) >= (Value2) ? (Value1) : (Value2) )
+# endif
+
+#endif /* defined (RT_OS_OS2) */
+
+/* Include iprt/types.h (which also includes iprt/types.h) now to make sure iprt
+ * gets to stdint.h first, otherwise a system/xpcom header might beat us and
+ * we'll be without the macros that are optional in C++. */
+#include <iprt/types.h>
+
+#if !defined (VBOX_WITH_XPCOM)
+
+#if defined (RT_OS_WINDOWS)
+
+// Windows COM
+/////////////////////////////////////////////////////////////////////////////
+
+#include <objbase.h>
+#ifndef VBOX_COM_NO_ATL
+# define _ATL_FREE_THREADED
+
+# include <atlbase.h>
+#include <atlcom.h>
+#endif
+
+#define NS_DECL_ISUPPORTS
+#define NS_IMPL_ISUPPORTS1_CI(a, b)
+
+/* these are XPCOM only, one for every interface implemented */
+#define NS_DECL_ISUPPORTS
+
+/** Returns @c true if @a rc represents a warning result code */
+#define SUCCEEDED_WARNING(rc) (SUCCEEDED (rc) && (rc) != S_OK)
+
+/** Tests is a COM result code indicates that the process implementing the
+ * interface is dead.
+ *
+ * COM status codes:
+ * 0x800706ba - RPC_S_SERVER_UNAVAILABLE. Killed before call was made.
+ * 0x800706be - RPC_S_CALL_FAILED. Killed after call was made.
+ * 0x800706bf - RPC_S_CALL_FAILED_DNE. Not observed, but should be matter of timing.
+ */
+#define FAILED_DEAD_INTERFACE(rc) \
+ ( (rc) == HRESULT_FROM_WIN32(RPC_S_SERVER_UNAVAILABLE) \
+ || (rc) == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED) \
+ || (rc) == HRESULT_FROM_WIN32(RPC_S_CALL_FAILED_DNE) \
+ )
+
+/** Immutable BSTR string */
+typedef const OLECHAR *CBSTR;
+
+/** Input BSTR argument of interface method declaration. */
+#define IN_BSTR BSTR
+
+/** Input GUID argument of interface method declaration. */
+#define IN_GUID GUID
+/** Output GUID argument of interface method declaration. */
+#define OUT_GUID GUID*
+
+/** Makes the name of the getter interface function (n must be capitalized). */
+#define COMGETTER(n) get_##n
+/** Makes the name of the setter interface function (n must be capitalized). */
+#define COMSETTER(n) put_##n
+
+/**
+ * Declares an input safearray parameter in the COM method implementation. Also
+ * used to declare the COM attribute setter parameter. Corresponds to either of
+ * the following XIDL definitions:
+ * <pre>
+ * <param name="arg" ... dir="in" safearray="yes"/>
+ * ...
+ * <attribute name="arg" ... safearray="yes"/>
+ * </pre>
+ *
+ * The method implementation should use the com::SafeArray helper class to work
+ * with parameters declared using this define.
+ *
+ * @param aType Array element type.
+ * @param aArg Parameter/attribute name.
+ */
+#define ComSafeArrayIn(aType, aArg) SAFEARRAY *aArg
+
+/**
+ * Expands to @true if the given input safearray parameter is a "null pointer"
+ * which makes it impossible to use it for reading safearray data.
+ */
+#define ComSafeArrayInIsNull(aArg) ((aArg) == NULL)
+
+/**
+ * Wraps the given parameter name to generate an expression that is suitable for
+ * passing the parameter to functions that take input safearray parameters
+ * declared using the ComSafeArrayIn marco.
+ *
+ * @param aArg Parameter name to wrap. The given parameter must be declared
+ * within the calling function using the ComSafeArrayIn macro.
+ */
+#define ComSafeArrayInArg(aArg) aArg
+
+/**
+ * Declares an output safearray parameter in the COM method implementation. Also
+ * used to declare the COM attribute getter parameter. Corresponds to either of
+ * the following XIDL definitions:
+ * <pre>
+ * <param name="arg" ... dir="out" safearray="yes"/>
+ * <param name="arg" ... dir="return" safearray="yes"/>
+ * ...
+ * <attribute name="arg" ... safearray="yes"/>
+ * </pre>
+ *
+ * The method implementation should use the com::SafeArray helper class to work
+ * with parameters declared using this define.
+ *
+ * @param aType Array element type.
+ * @param aArg Parameter/attribute name.
+ */
+#define ComSafeArrayOut(aType, aArg) SAFEARRAY **aArg
+
+/**
+ * Expands to @true if the given output safearray parameter is a "null pointer"
+ * which makes it impossible to use it for returning a safearray.
+ */
+#define ComSafeArrayOutIsNull(aArg) ((aArg) == NULL)
+
+/**
+ * Wraps the given parameter name to generate an expression that is suitable for
+ * passing the parameter to functions that take output safearray parameters
+ * declared using the ComSafeArrayOut marco.
+ *
+ * @param aArg Parameter name to wrap. The given parameter must be declared
+ * within the calling function using the ComSafeArrayOut macro.
+ */
+#define ComSafeArrayOutArg(aArg) aArg
+
+/**
+ * Version of ComSafeArrayIn for GUID.
+ * @param aArg Parameter name to wrap.
+ */
+#define ComSafeGUIDArrayIn(aArg) SAFEARRAY *aArg
+
+/**
+ * Version of ComSafeArrayInIsNull for GUID.
+ * @param aArg Parameter name to wrap.
+ */
+#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg)
+
+/**
+ * Version of ComSafeArrayInArg for GUID.
+ * @param aArg Parameter name to wrap.
+ */
+#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg)
+
+/**
+ * Version of ComSafeArrayOut for GUID.
+ * @param aArg Parameter name to wrap.
+ */
+#define ComSafeGUIDArrayOut(aArg) SAFEARRAY **aArg
+
+/**
+ * Version of ComSafeArrayOutIsNull for GUID.
+ * @param aArg Parameter name to wrap.
+ */
+#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg)
+
+/**
+ * Version of ComSafeArrayOutArg for GUID.
+ * @param aArg Parameter name to wrap.
+ */
+#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg)
+
+/**
+ * Returns the const reference to the IID (i.e., |const GUID &|) of the given
+ * interface.
+ *
+ * @param i interface class
+ */
+#define COM_IIDOF(I) _ATL_IIDOF(I)
+
+/**
+ * For using interfaces before including the interface definitions. This will
+ * deal with XPCOM using 'class' and COM using 'struct' when defining
+ * interfaces.
+ *
+ * @param I interface name.
+ */
+#define COM_STRUCT_OR_CLASS(I) struct I
+
+#else /* defined (RT_OS_WINDOWS) */
+
+#error "VBOX_WITH_XPCOM must be defined on a platform other than Windows!"
+
+#endif /* defined (RT_OS_WINDOWS) */
+
+#else /* !defined (VBOX_WITH_XPCOM) */
+
+// XPCOM
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined (RT_OS_DARWIN) || (defined (QT_VERSION) && (QT_VERSION >= 0x040000))
+ /* CFBase.h defines these &
+ * qglobal.h from Qt4 defines these */
+# undef FALSE
+# undef TRUE
+#endif /* RT_OS_DARWIN || QT_VERSION */
+
+#include <nsID.h>
+
+#define ATL_NO_VTABLE
+#define DECLARE_CLASSFACTORY(a)
+#define DECLARE_CLASSFACTORY_SINGLETON(a)
+#define DECLARE_REGISTRY_RESOURCEID(a)
+#define DECLARE_NOT_AGGREGATABLE(a)
+#define DECLARE_PROTECT_FINAL_CONSTRUCT()
+#define BEGIN_COM_MAP(a)
+#define COM_INTERFACE_ENTRY(a)
+#define COM_INTERFACE_ENTRY2(a,b)
+#define END_COM_MAP() NS_DECL_ISUPPORTS
+#define COM_INTERFACE_ENTRY_AGGREGATE(a,b)
+
+#define HRESULT nsresult
+#define SUCCEEDED NS_SUCCEEDED
+#define FAILED NS_FAILED
+
+#define SUCCEEDED_WARNING(rc) (NS_SUCCEEDED (rc) && (rc) != NS_OK)
+
+#define FAILED_DEAD_INTERFACE(rc) ( (rc) == NS_ERROR_ABORT \
+ || (rc) == NS_ERROR_CALL_FAILED \
+ )
+
+#define IUnknown nsISupports
+
+#define BOOL PRBool
+#define BYTE PRUint8
+#define SHORT PRInt16
+#define USHORT PRUint16
+#define LONG PRInt32
+#define ULONG PRUint32
+#define LONG64 PRInt64
+#define ULONG64 PRUint64
+/* XPCOM has only 64bit floats */
+#define FLOAT PRFloat64
+#define DOUBLE PRFloat64
+
+#define FALSE PR_FALSE
+#define TRUE PR_TRUE
+
+#define OLECHAR wchar_t
+
+/* note: typedef to semantically match BSTR on Win32 */
+typedef PRUnichar *BSTR;
+typedef const PRUnichar *CBSTR;
+typedef BSTR *LPBSTR;
+
+/** Input BSTR argument the interface method declaration. */
+#define IN_BSTR CBSTR
+
+/**
+ * Type to define a raw GUID variable (for members use the com::Guid class
+ * instead).
+ */
+#define GUID nsID
+/** Input GUID argument the interface method declaration. */
+#define IN_GUID const nsID &
+/** Output GUID argument the interface method declaration. */
+#define OUT_GUID nsID **
+
+/** Makes the name of the getter interface function (n must be capitalized). */
+#define COMGETTER(n) Get##n
+/** Makes the name of the setter interface function (n must be capitalized). */
+#define COMSETTER(n) Set##n
+
+/* safearray input parameter macros */
+#define ComSafeArrayIn(aType, aArg) PRUint32 aArg##Size, aType *aArg
+#define ComSafeArrayInIsNull(aArg) ((aArg) == NULL)
+#define ComSafeArrayInArg(aArg) aArg##Size, aArg
+
+/* safearray output parameter macros */
+#define ComSafeArrayOut(aType, aArg) PRUint32 *aArg##Size, aType **aArg
+#define ComSafeArrayOutIsNull(aArg) ((aArg) == NULL)
+#define ComSafeArrayOutArg(aArg) aArg##Size, aArg
+
+/* safearray input parameter macros for GUID */
+#define ComSafeGUIDArrayIn(aArg) PRUint32 aArg##Size, const nsID **aArg
+#define ComSafeGUIDArrayInIsNull(aArg) ComSafeArrayInIsNull (aArg)
+#define ComSafeGUIDArrayInArg(aArg) ComSafeArrayInArg (aArg)
+
+/* safearray output parameter macros for GUID */
+#define ComSafeGUIDArrayOut(aArg) PRUint32 *aArg##Size, nsID ***aArg
+#define ComSafeGUIDArrayOutIsNull(aArg) ComSafeArrayOutIsNull (aArg)
+#define ComSafeGUIDArrayOutArg(aArg) ComSafeArrayOutArg (aArg)
+
+/* CLSID and IID for compatibility with Win32 */
+typedef nsCID CLSID;
+typedef nsIID IID;
+
+/* OLE error codes */
+#define S_OK ((nsresult) NS_OK)
+#define E_UNEXPECTED NS_ERROR_UNEXPECTED
+#define E_NOTIMPL NS_ERROR_NOT_IMPLEMENTED
+#define E_OUTOFMEMORY NS_ERROR_OUT_OF_MEMORY
+#define E_INVALIDARG NS_ERROR_INVALID_ARG
+#define E_NOINTERFACE NS_ERROR_NO_INTERFACE
+#define E_POINTER NS_ERROR_NULL_POINTER
+#define E_ABORT NS_ERROR_ABORT
+#define E_FAIL NS_ERROR_FAILURE
+/* Note: a better analog for E_ACCESSDENIED would probably be
+ * NS_ERROR_NOT_AVAILABLE, but we want binary compatibility for now. */
+#define E_ACCESSDENIED ((nsresult) 0x80070005L)
+
+#define STDMETHOD(a) NS_IMETHOD a
+#define STDMETHODIMP NS_IMETHODIMP
+
+#define COM_IIDOF(I) NS_GET_IID(I)
+
+#define COM_STRUCT_OR_CLASS(I) class I
+
+/* A few very simple ATL emulator classes to provide
+ * FinalConstruct()/FinalRelease() functionality on Linux. */
+
+class CComMultiThreadModel
+{
+};
+
+template <class Base> class CComObjectRootEx : public Base
+{
+public:
+ HRESULT FinalConstruct() { return S_OK; }
+ void FinalRelease() {}
+};
+
+template <class Base> class CComObject : public Base
+{
+public:
+ virtual ~CComObject() { this->FinalRelease(); }
+};
+
+/* helper functions */
+extern "C"
+{
+BSTR SysAllocString (const OLECHAR* sz);
+BSTR SysAllocStringByteLen (char *psz, unsigned int len);
+BSTR SysAllocStringLen (const OLECHAR *pch, unsigned int cch);
+void SysFreeString (BSTR bstr);
+int SysReAllocString (BSTR *pbstr, const OLECHAR *psz);
+int SysReAllocStringLen (BSTR *pbstr, const OLECHAR *psz, unsigned int cch);
+unsigned int SysStringByteLen (BSTR bstr);
+unsigned int SysStringLen (BSTR bstr);
+}
+
+/**
+ * 'Constructor' for the component class.
+ * This constructor, as opposed to NS_GENERIC_FACTORY_CONSTRUCTOR,
+ * assumes that the component class is derived from the CComObjectRootEx<>
+ * template, so it calls FinalConstruct() right after object creation
+ * and ensures that FinalRelease() will be called right before destruction.
+ * The result from FinalConstruct() is returned to the caller.
+ */
+#define NS_GENERIC_FACTORY_CONSTRUCTOR_WITH_RC(_InstanceClass) \
+static NS_IMETHODIMP \
+_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
+ void **aResult) \
+{ \
+ nsresult rv; \
+ \
+ *aResult = NULL; \
+ if (NULL != aOuter) { \
+ rv = NS_ERROR_NO_AGGREGATION; \
+ return rv; \
+ } \
+ \
+ CComObject <_InstanceClass> *inst = new CComObject <_InstanceClass>(); \
+ if (NULL == inst) { \
+ rv = NS_ERROR_OUT_OF_MEMORY; \
+ return rv; \
+ } \
+ \
+ NS_ADDREF(inst); /* protect FinalConstruct() */ \
+ rv = inst->FinalConstruct(); \
+ if (NS_SUCCEEDED(rv)) \
+ rv = inst->QueryInterface(aIID, aResult); \
+ NS_RELEASE(inst); \
+ \
+ return rv; \
+}
+
+/**
+ * 'Constructor' that uses an existing getter function that gets a singleton.
+ * The getter function must have the following prototype:
+ * nsresult _GetterProc (_InstanceClass **inst)
+ * This constructor, as opposed to NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR,
+ * lets the getter function return a result code that is passed back to the
+ * caller that tries to instantiate the object.
+ * NOTE: assumes that getter does an AddRef - so additional AddRef is not done.
+ */
+#define NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR_WITH_RC(_InstanceClass, _GetterProc) \
+static NS_IMETHODIMP \
+_InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
+ void **aResult) \
+{ \
+ nsresult rv; \
+ \
+ _InstanceClass * inst = NULL; /* initialized to shut up gcc */ \
+ \
+ *aResult = NULL; \
+ if (NULL != aOuter) { \
+ rv = NS_ERROR_NO_AGGREGATION; \
+ return rv; \
+ } \
+ \
+ rv = _GetterProc(&inst); \
+ if (NS_FAILED(rv)) \
+ return rv; \
+ \
+ /* sanity check */ \
+ if (NULL == inst) \
+ return NS_ERROR_OUT_OF_MEMORY; \
+ \
+ /* NS_ADDREF(inst); */ \
+ if (NS_SUCCEEDED(rv)) { \
+ rv = inst->QueryInterface(aIID, aResult); \
+ } \
+ NS_RELEASE(inst); \
+ \
+ return rv; \
+}
+
+#endif /* !defined (VBOX_WITH_XPCOM) */
+
+/**
+ * Declares a wchar_t string literal from the argument.
+ * Necessary to overcome MSC / GCC differences.
+ * @param s expression to stringify
+ */
+#if defined (_MSC_VER)
+# define WSTR_LITERAL(s) L#s
+#elif defined (__GNUC__)
+# define WSTR_LITERAL(s) L""#s
+#else
+# error "Unsupported compiler!"
+#endif
+
+namespace com
+{
+
+// use this macro to implement scriptable interfaces
+#ifdef RT_OS_WINDOWS
+#define VBOX_SCRIPTABLE_IMPL(iface) \
+ public IDispatchImpl<iface, &IID_##iface, &LIBID_VirtualBox, \
+ kTypeLibraryMajorVersion, kTypeLibraryMinorVersion>
+
+#define VBOX_SCRIPTABLE_DISPATCH_IMPL(iface) \
+ STDMETHOD(QueryInterface)(REFIID riid , void **ppObj) \
+ { \
+ if (riid == IID_##iface) \
+ { \
+ *ppObj = (iface*)this; \
+ AddRef(); \
+ return S_OK; \
+ } \
+ if (riid == IID_IUnknown) \
+ { \
+ *ppObj = (IUnknown*)this; \
+ AddRef(); \
+ return S_OK; \
+ } \
+ if (riid == IID_IDispatch) \
+ { \
+ *ppObj = (IDispatch*)this; \
+ AddRef(); \
+ return S_OK; \
+ } \
+ *ppObj = NULL; \
+ return E_NOINTERFACE; \
+ }
+
+
+#define VBOX_DEFAULT_INTERFACE_ENTRIES(iface) \
+ COM_INTERFACE_ENTRY(ISupportErrorInfo) \
+ COM_INTERFACE_ENTRY(iface) \
+ COM_INTERFACE_ENTRY2(IDispatch,iface) \
+ COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
+#else
+#define VBOX_SCRIPTABLE_IMPL(iface) \
+ public iface
+#define VBOX_SCRIPTABLE_DISPATCH_IMPL(iface)
+#define VBOX_DEFAULT_INTERFACE_ENTRIES(iface)
+#endif
+
+
+} /* namespace com */
+
+#endif /* ___VBox_com_defs_h */
diff --git a/include/VBox/com/errorprint.h b/include/VBox/com/errorprint.h
new file mode 100644
index 00000000..2ee11676
--- /dev/null
+++ b/include/VBox/com/errorprint.h
@@ -0,0 +1,261 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * Error printing macros using shared functions defined in shared glue code.
+ * Use these CHECK_* macros for efficient error checking around calling COM methods.
+ */
+
+/*
+ * Copyright (C) 2009 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 ___VBox_com_errorprint_h
+#define ___VBox_com_errorprint_h
+
+#include <VBox/com/ErrorInfo.h>
+
+namespace com
+{
+
+// shared prototypes; these are defined in shared glue code and are
+// compiled only once for all front-ends
+void GluePrintErrorInfo(const com::ErrorInfo &info);
+void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t ulLine);
+void GluePrintRCMessage(HRESULT rc);
+void GlueHandleComError(ComPtr<IUnknown> iface,
+ const char *pcszContext,
+ HRESULT rc,
+ const char *pcszSourceFile,
+ uint32_t ulLine);
+void GlueHandleComErrorProgress(ComPtr<IProgress> progress,
+ const char *pcszContext,
+ HRESULT rc,
+ const char *pcszSourceFile,
+ uint32_t ulLine);
+
+/**
+ * Calls the given method of the given interface and then checks if the return
+ * value (COM result code) indicates a failure. If so, prints the failed
+ * function/line/file, the description of the result code and attempts to
+ * query the extended error information on the current thread (using
+ * com::ErrorInfo) if the interface reports that it supports error information.
+ *
+ * Used by command line tools or for debugging and assumes the |HRESULT rc|
+ * variable is accessible for assigning in the current scope.
+ */
+#define CHECK_ERROR(iface, method) \
+ do { \
+ rc = iface->method; \
+ if (FAILED(rc)) \
+ com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
+ } while (0)
+
+/**
+ * Same as CHECK_ERROR except that it also executes the statement |stmt| on
+ * failure.
+ */
+#define CHECK_ERROR_STMT(iface, method, stmt) \
+ do { \
+ rc = iface->method; \
+ if (FAILED(rc)) \
+ { \
+ com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
+ stmt; \
+ } \
+ } while (0)
+
+/**
+ * Same as CHECK_ERROR_STMT except that it uses an internal variable |hrcCheck|
+ * for holding the result.
+ */
+#define CHECK_ERROR2_STMT(iface, method, stmt) \
+ do { \
+ HRESULT hrcCheck = iface->method; \
+ if (FAILED(hrcCheck)) \
+ { \
+ com::GlueHandleComError(iface, #method, hrcCheck, __FILE__, __LINE__); \
+ stmt; \
+ } \
+ } while (0)
+
+
+/**
+ * Does the same as CHECK_ERROR(), but executes the |break| statement on
+ * failure.
+ */
+#ifdef __GNUC__
+# define CHECK_ERROR_BREAK(iface, method) \
+ __extension__ \
+ ({ \
+ rc = iface->method; \
+ if (FAILED(rc)) \
+ { \
+ com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
+ break; \
+ } \
+ })
+#else
+# define CHECK_ERROR_BREAK(iface, method) \
+ if (1) \
+ { \
+ rc = iface->method; \
+ if (FAILED(rc)) \
+ { \
+ com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
+ break; \
+ } \
+ } \
+ else do {} while (0)
+#endif
+
+/**
+ * Does the same as CHECK_ERROR(), but executes the |return ret| statement on
+ * failure.
+ */
+#define CHECK_ERROR_RET(iface, method, ret) \
+ do { \
+ rc = iface->method; \
+ if (FAILED(rc)) \
+ { \
+ com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
+ return (ret); \
+ } \
+ } while (0)
+
+/**
+ * Does the same as CHECK_ERROR(), but returns @a ret on failure.
+ *
+ * Unlike CHECK_ERROR and CHECK_ERROR_RET, this macro does not presuppose a
+ * |rc| variable but instead employs a local variable |hrcCheck| in its own
+ * scope. This |hrcCheck| variable can be referenced by the @a rcRet
+ * parameter.
+ *
+ * @param iface The interface pointer (can be a smart pointer object).
+ * @param method The method to invoke together with the parameters.
+ * @param rcRet What to return on failure. Use |hrcCheck| to return
+ * the status code of the method call.
+ */
+#define CHECK_ERROR2_RET(iface, method, rcRet) \
+ do { \
+ HRESULT hrcCheck = iface->method; \
+ if (FAILED(hrcCheck)) \
+ { \
+ com::GlueHandleComError(iface, #method, hrcCheck, __FILE__, __LINE__); \
+ return (rcRet); \
+ } \
+ } while (0)
+
+
+/**
+ * Check the progress object for an error and if there is one print out the
+ * extended error information.
+ */
+#define CHECK_PROGRESS_ERROR(progress, msg) \
+ do { \
+ LONG iRc; \
+ rc = progress->COMGETTER(ResultCode)(&iRc); \
+ if (FAILED(iRc)) \
+ { \
+ rc = iRc; \
+ RTMsgError msg; \
+ com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
+ } \
+ } while (0)
+
+/**
+ * Does the same as CHECK_PROGRESS_ERROR(), but executes the |break| statement
+ * on failure.
+ */
+#ifdef __GNUC__
+# define CHECK_PROGRESS_ERROR_BREAK(progress, msg) \
+ __extension__ \
+ ({ \
+ LONG iRc; \
+ rc = progress->COMGETTER(ResultCode)(&iRc); \
+ if (FAILED(iRc)) \
+ { \
+ rc = iRc; \
+ RTMsgError msg; \
+ com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
+ break; \
+ } \
+ })
+#else
+# define CHECK_PROGRESS_ERROR_BREAK(progress, msg) \
+ if (1) \
+ { \
+ LONG iRc; \
+ rc = progress->COMGETTER(ResultCode)(&iRc); \
+ if (FAILED(iRc)) \
+ { \
+ rc = iRc; \
+ RTMsgError msg; \
+ com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
+ break; \
+ } \
+ } \
+ else do {} while (0)
+#endif
+
+/**
+ * Does the same as CHECK_PROGRESS_ERROR(), but executes the |return ret|
+ * statement on failure.
+ */
+#define CHECK_PROGRESS_ERROR_RET(progress, msg, ret) \
+ do { \
+ LONG iRc; \
+ progress->COMGETTER(ResultCode)(&iRc); \
+ if (FAILED(iRc)) \
+ { \
+ RTMsgError msg; \
+ com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
+ return (ret); \
+ } \
+ } while (0)
+
+/**
+ * Asserts the given expression is true. When the expression is false, prints
+ * a line containing the failed function/line/file; otherwise does nothing.
+ */
+#define ASSERT(expr) \
+ do { \
+ if (!(expr)) \
+ { \
+ RTPrintf ("[!] ASSERTION FAILED at line %d: %s\n", __LINE__, #expr); \
+ Log (("[!] ASSERTION FAILED at line %d: %s\n", __LINE__, #expr)); \
+ } \
+ } while (0)
+
+#endif
+
+/**
+ * Does the same as ASSERT(), but executes the |return ret| statement if the
+ * expression to assert is false;
+ */
+#define ASSERT_RET(expr, ret) \
+ do { ASSERT(expr); if (!(expr)) return (ret); } while (0)
+
+/**
+ * Does the same as ASSERT(), but executes the |break| statement if the
+ * expression to assert is false;
+ */
+#define ASSERT_BREAK(expr, ret) \
+ if (1) { ASSERT(expr); if (!(expr)) break; } else do {} while (0)
+
+} /* namespace com */
diff --git a/include/VBox/com/list.h b/include/VBox/com/list.h
new file mode 100644
index 00000000..11a137b5
--- /dev/null
+++ b/include/VBox/com/list.h
@@ -0,0 +1,197 @@
+/* $Id: list.h $ */
+/** @file
+ * MS COM / XPCOM Abstraction Layer - List classes declaration.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_list_h
+#define ___VBox_com_list_h
+
+#include <VBox/com/ptr.h>
+#include <VBox/com/string.h>
+#include <iprt/cpp/list.h>
+
+/**
+ * Specialized list class for using with com::ComPtr<C>
+ *
+ * @note: This is necessary cause ComPtr<IFACE> has a size of 8.
+ */
+template <typename C>
+class RTCList< ComPtr<C> >: public RTCListBase< ComPtr<C>, ComPtr<C>*, false>
+{
+ /* Traits */
+ typedef ComPtr<C> T;
+ typedef T *ITYPE;
+ static const bool MT = false;
+ typedef RTCListBase<T, ITYPE, MT> BASE;
+
+public:
+ /**
+ * Creates a new list.
+ *
+ * This preallocates @a cCapacity elements within the list.
+ *
+ * @param cCapacitiy The initial capacity the list has.
+ * @throws std::bad_alloc
+ */
+ RTCList(size_t cCapacity = BASE::DefaultCapacity)
+ : BASE(cCapacity) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * Specialized list class for using with com::ComObjPtr<C>
+ *
+ * @note: This is necessary cause ComObjPtr<IFACE> has a size of 8.
+ */
+template <typename C>
+class RTCList< ComObjPtr<C> >: public RTCListBase< ComObjPtr<C>, ComObjPtr<C>*, false>
+{
+ /* Traits */
+ typedef ComObjPtr<C> T;
+ typedef T *ITYPE;
+ static const bool MT = false;
+ typedef RTCListBase<T, ITYPE, MT> BASE;
+
+public:
+ /**
+ * Creates a new list.
+ *
+ * This preallocates @a cCapacity elements within the list.
+ *
+ * @param cCapacitiy The initial capacity the list has.
+ * @throws std::bad_alloc
+ */
+ RTCList(size_t cCapacity = BASE::DefaultCapacity)
+ : BASE(cCapacity) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * Specialized list class for using with com::Utf8Str.
+ *
+ * The class offers methods for importing com::SafeArray's of com::Bstr's.
+ */
+template <>
+class RTCList<Utf8Str>: public RTCListBase<Utf8Str, Utf8Str*, false>
+{
+ /* Traits */
+ typedef Utf8Str T;
+ typedef T *ITYPE;
+ static const bool MT = false;
+ typedef RTCListBase<T, ITYPE, MT> BASE;
+
+public:
+ /**
+ * Creates a new list.
+ *
+ * This preallocates @a cCapacity elements within the list.
+ *
+ * @param cCapacitiy The initial capacity the list has.
+ * @throws std::bad_alloc
+ */
+ RTCList(size_t cCapacity = BASE::DefaultCapacity)
+ : BASE(cCapacity) {}
+
+ /**
+ * Creates a copy of another list.
+ *
+ * The other list will be fully copied and the capacity will be the same as
+ * the size of the other list. The com::Bstr's are silently converted to
+ * com::Utf8Str's.
+ *
+ * @param other The list to copy.
+ * @throws std::bad_alloc
+ */
+ RTCList(ComSafeArrayIn(IN_BSTR, other))
+ {
+ com::SafeArray<IN_BSTR> sfaOther(ComSafeArrayInArg(other));
+ realloc(sfaOther.size());
+ m_cSize = sfaOther.size();
+ for (size_t i = 0; i < m_cSize; ++i)
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, T(sfaOther[i]));
+ }
+
+ /**
+ * Creates a copy of another list.
+ *
+ * The other list will be fully copied and the capacity will be the same as
+ * the size of the other list. The com::Bstr's are silently converted to
+ * com::Utf8Str's.
+ *
+ * @param other The list to copy.
+ * @throws std::bad_alloc
+ */
+ RTCList(const com::SafeArray<IN_BSTR> &other)
+ : BASE(other.size())
+ {
+ for (size_t i = 0; i < m_cSize; ++i)
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i]));
+ }
+
+ /**
+ * Copy the items of the other list into this list. All previous items of
+ * this list are deleted.
+ *
+ * @param other The list to copy.
+ * @return a reference to this list.
+ * @throws std::bad_alloc
+ */
+ RTCListBase<T, ITYPE, MT> &operator=(const com::SafeArray<IN_BSTR> &other)
+ {
+ m_guard.enterWrite();
+ /* Values cleanup */
+ RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
+ /* Copy */
+ if (other.size() != m_cCapacity)
+ realloc_no_elements_clean(other.size());
+ m_cSize = other.size();
+ for (size_t i = 0; i < other.size(); ++i)
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i]));
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * Implicit conversion to a RTCString list.
+ *
+ * This allows the usage of the RTCString::join method with this list type.
+ *
+ * @return a converted const reference to this list.
+ */
+ operator const RTCList<RTCString, RTCString*>&()
+ {
+ return *reinterpret_cast<RTCList<RTCString, RTCString*> *>(this);
+ }
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+#endif /* !___VBox_com_list_h */
+
diff --git a/include/VBox/com/listeners.h b/include/VBox/com/listeners.h
new file mode 100644
index 00000000..419b18fa
--- /dev/null
+++ b/include/VBox/com/listeners.h
@@ -0,0 +1,171 @@
+/* $Id: listeners.h $ */
+/** @file
+ * Listeners helpers.
+ */
+
+/*
+ * Copyright (C) 2010-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_listeners_h
+#define ___VBox_com_listeners_h
+
+#include <VBox/com/com.h>
+#include <VBox/com/VirtualBox.h>
+
+#ifdef VBOX_WITH_XPCOM
+# define NS_IMPL_QUERY_HEAD_INLINE() \
+NS_IMETHODIMP QueryInterface(REFNSIID aIID, void **aInstancePtr) \
+{ \
+ NS_ASSERTION(aInstancePtr, "QueryInterface requires a non-NULL destination!"); \
+ nsISupports *foundInterface;
+
+# define NS_INTERFACE_MAP_BEGIN_INLINE() NS_IMPL_QUERY_HEAD_INLINE()
+
+# define NS_IMPL_QUERY_INTERFACE1_INLINE(a_i1) \
+ NS_INTERFACE_MAP_BEGIN_INLINE() \
+ NS_INTERFACE_MAP_ENTRY(a_i1) \
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, a_i1) \
+ NS_INTERFACE_MAP_END
+#endif
+
+template <class T, class TParam = void *>
+class ListenerImpl :
+ public CComObjectRootEx<CComMultiThreadModel>,
+ VBOX_SCRIPTABLE_IMPL(IEventListener)
+{
+ T* mListener;
+
+#ifdef RT_OS_WINDOWS
+ /* FTM stuff */
+ CComPtr <IUnknown> m_pUnkMarshaler;
+#else
+ nsAutoRefCnt mRefCnt;
+ NS_DECL_OWNINGTHREAD
+#endif
+
+public:
+ ListenerImpl()
+ {
+ }
+
+ virtual ~ListenerImpl()
+ {
+ }
+
+ HRESULT init(T* aListener, TParam param)
+ {
+ mListener = aListener;
+ return mListener->init(param);
+ }
+
+ HRESULT init(T* aListener)
+ {
+ mListener = aListener;
+ return mListener->init();
+ }
+
+ void uninit()
+ {
+ if (mListener)
+ {
+ mListener->uninit();
+ delete mListener;
+ mListener = 0;
+ }
+ }
+
+ HRESULT FinalConstruct()
+ {
+#ifdef RT_OS_WINDOWS
+ return CoCreateFreeThreadedMarshaler(this, &m_pUnkMarshaler.p);
+#else
+ return S_OK;
+#endif
+ }
+
+ void FinalRelease()
+ {
+ uninit();
+#ifdef RT_OS_WINDOWS
+ m_pUnkMarshaler.Release();
+#endif
+ }
+
+ T* getWrapped()
+ {
+ return mListener;
+ }
+
+ DECLARE_NOT_AGGREGATABLE(ListenerImpl)
+
+ DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+#ifdef RT_OS_WINDOWS
+ BEGIN_COM_MAP(ListenerImpl)
+ COM_INTERFACE_ENTRY(IEventListener)
+ COM_INTERFACE_ENTRY2(IDispatch, IEventListener)
+ COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
+ END_COM_MAP()
+#else
+ NS_IMETHOD_(nsrefcnt) AddRef(void)
+ {
+ NS_PRECONDITION(PRInt32(mRefCnt) >= 0, "illegal refcnt");
+ nsrefcnt count;
+ count = PR_AtomicIncrement((PRInt32*)&mRefCnt);
+ NS_LOG_ADDREF(this, count, "ListenerImpl", sizeof(*this));
+ return count;
+ }
+
+ NS_IMETHOD_(nsrefcnt) Release(void)
+ {
+ nsrefcnt count;
+ NS_PRECONDITION(0 != mRefCnt, "dup release");
+ count = PR_AtomicDecrement((PRInt32 *)&mRefCnt);
+ NS_LOG_RELEASE(this, count, "ListenerImpl");
+ if (0 == count) {
+ mRefCnt = 1; /* stabilize */
+ /* enable this to find non-threadsafe destructors: */
+ /* NS_ASSERT_OWNINGTHREAD(_class); */
+ NS_DELETEXPCOM(this);
+ return 0;
+ }
+ return count;
+ }
+
+ NS_IMPL_QUERY_INTERFACE1_INLINE(IEventListener)
+#endif
+
+
+ STDMETHOD(HandleEvent)(IEvent * aEvent)
+ {
+ VBoxEventType_T aType = VBoxEventType_Invalid;
+ aEvent->COMGETTER(Type)(&aType);
+ return mListener->HandleEvent(aType, aEvent);
+ }
+};
+
+#ifdef VBOX_WITH_XPCOM
+# define VBOX_LISTENER_DECLARE(klazz) NS_DECL_CLASSINFO(klazz)
+#else
+# define VBOX_LISTENER_DECLARE(klazz)
+#endif
+
+#endif
diff --git a/include/VBox/com/mtlist.h b/include/VBox/com/mtlist.h
new file mode 100644
index 00000000..c4142c5f
--- /dev/null
+++ b/include/VBox/com/mtlist.h
@@ -0,0 +1,197 @@
+/* $Id: mtlist.h $ */
+/** @file
+ * MS COM / XPCOM Abstraction Layer - Thread-safe list classes declaration.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_mtlist_h
+#define ___VBox_com_mtlist_h
+
+#include <VBox/com/ptr.h>
+#include <VBox/com/string.h>
+#include <iprt/cpp/mtlist.h>
+
+/**
+ * Specialized thread-safe list class for using with com::ComPtr<C>
+ *
+ * @note: This is necessary cause ComPtr<IFACE> has a size of 8.
+ */
+template <typename C>
+class RTCMTList< ComPtr<C> >: public RTCListBase< ComPtr<C>, ComPtr<C>*, true>
+{
+ /* Traits */
+ typedef ComPtr<C> T;
+ typedef T *ITYPE;
+ static const bool MT = true;
+ typedef RTCListBase<T, ITYPE, MT> BASE;
+
+public:
+ /**
+ * Creates a new list.
+ *
+ * This preallocates @a cCapacity elements within the list.
+ *
+ * @param cCapacitiy The initial capacity the list has.
+ * @throws std::bad_alloc
+ */
+ RTCList(size_t cCapacity = BASE::DefaultCapacity)
+ : BASE(cCapacity) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * Specialized thread-safe list class for using with com::ComObjPtr<C>
+ *
+ * @note: This is necessary cause ComObjPtr<IFACE> has a size of 8.
+ */
+template <typename C>
+class RTCMTList< ComObjPtr<C> >: public RTCListBase< ComObjPtr<C>, ComObjPtr<C>*, true>
+{
+ /* Traits */
+ typedef ComObjPtr<C> T;
+ typedef T *ITYPE;
+ static const bool MT = true;
+ typedef RTCListBase<T, ITYPE, MT> BASE;
+
+public:
+ /**
+ * Creates a new list.
+ *
+ * This preallocates @a cCapacity elements within the list.
+ *
+ * @param cCapacitiy The initial capacity the list has.
+ * @throws std::bad_alloc
+ */
+ RTCList(size_t cCapacity = BASE::DefaultCapacity)
+ : BASE(cCapacity) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * Specialized thread-safe list class for using with com::Utf8Str.
+ *
+ * The class offers methods for importing com::SafeArray's of com::Bstr's.
+ */
+template <>
+class RTCMTList<Utf8Str>: public RTCListBase<Utf8Str, Utf8Str*, true>
+{
+ /* Traits */
+ typedef Utf8Str T;
+ typedef T *ITYPE;
+ static const bool MT = true;
+ typedef RTCListBase<T, ITYPE, MT> BASE;
+
+public:
+ /**
+ * Creates a new list.
+ *
+ * This preallocates @a cCapacity elements within the list.
+ *
+ * @param cCapacitiy The initial capacity the list has.
+ * @throws std::bad_alloc
+ */
+ RTCMTList(size_t cCapacity = BASE::DefaultCapacity)
+ : BASE(cCapacity) {}
+
+ /**
+ * Creates a copy of another list.
+ *
+ * The other list will be fully copied and the capacity will be the same as
+ * the size of the other list. The com::Bstr's are silently converted to
+ * com::Utf8Str's.
+ *
+ * @param other The list to copy.
+ * @throws std::bad_alloc
+ */
+ RTCMTList(ComSafeArrayIn(IN_BSTR, other))
+ {
+ com::SafeArray<IN_BSTR> sfaOther(ComSafeArrayInArg(other));
+ realloc(sfaOther.size());
+ m_cSize = sfaOther.size();
+ for (size_t i = 0; i < m_cSize; ++i)
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, T(sfaOther[i]));
+ }
+
+ /**
+ * Creates a copy of another list.
+ *
+ * The other list will be fully copied and the capacity will be the same as
+ * the size of the other list. The com::Bstr's are silently converted to
+ * com::Utf8Str's.
+ *
+ * @param other The list to copy.
+ * @throws std::bad_alloc
+ */
+ RTCMTList(const com::SafeArray<IN_BSTR> &other)
+ : BASE(other.size())
+ {
+ for (size_t i = 0; i < m_cSize; ++i)
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i]));
+ }
+
+ /**
+ * Copy the items of the other list into this list. All previous items of
+ * this list are deleted.
+ *
+ * @param other The list to copy.
+ * @return a reference to this list.
+ * @throws std::bad_alloc
+ */
+ RTCListBase<T, ITYPE, MT> &operator=(const com::SafeArray<IN_BSTR> &other)
+ {
+ m_guard.enterWrite();
+ /* Values cleanup */
+ RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
+ /* Copy */
+ if (other.size() != m_cCapacity)
+ realloc_no_elements_clean(other.size());
+ m_cSize = other.size();
+ for (size_t i = 0; i < other.size(); ++i)
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, T(other[i]));
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * Implicit conversion to a RTCString list.
+ *
+ * This allows the usage of the RTCString::join method with this list type.
+ *
+ * @return a converted const reference to this list.
+ */
+ operator const RTCMTList<RTCString, RTCString*>&()
+ {
+ return *reinterpret_cast<RTCMTList<RTCString, RTCString*> *>(this);
+ }
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+#endif /* !___VBox_com_mtlist_h */
+
diff --git a/include/VBox/com/ptr.h b/include/VBox/com/ptr.h
new file mode 100644
index 00000000..1942274b
--- /dev/null
+++ b/include/VBox/com/ptr.h
@@ -0,0 +1,493 @@
+/** @file
+ * MS COM / XPCOM Abstraction Layer:
+ * Smart COM pointer classes declaration
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_ptr_h
+#define ___VBox_com_ptr_h
+
+/* Make sure all the stdint.h macros are included - must come first! */
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS
+#endif
+
+#if !defined (VBOX_WITH_XPCOM)
+ #include <atlbase.h>
+ #ifndef _ATL_IIDOF
+ # define _ATL_IIDOF(c) __uuidof(c)
+ #endif
+#else
+ #include <nsISupportsUtils.h>
+
+#endif /* !defined (VBOX_WITH_XPCOM) */
+
+#include <VBox/com/defs.h>
+
+#ifdef VBOX_WITH_XPCOM
+
+namespace com
+{
+// declare a couple of XPCOM helper methods (defined in glue/com.cpp)
+// so we don't have to include a ton of XPCOM implementation headers here
+HRESULT GlueCreateObjectOnServer(const CLSID &clsid,
+ const char *serverName,
+ const nsIID &id,
+ void** ppobj);
+HRESULT GlueCreateInstance(const CLSID &clsid,
+ const nsIID &id,
+ void** ppobj);
+}
+
+#endif // VBOX_WITH_XPCOM
+
+/**
+ * COM autopointer class which takes care of all required reference counting.
+ *
+ * This automatically calls the required basic COM methods on COM pointers
+ * given to it:
+ *
+ * -- AddRef() gets called automatically whenever a new COM pointer is assigned
+ * to the ComPtr instance (either in the copy constructor or by assignment);
+ *
+ * -- Release() gets called automatically by the destructor and when an existing
+ * object gets released in assignment;
+ *
+ * -- QueryInterface() gets called automatically when COM pointers get converted
+ * from one interface to another.
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ * {
+ * ComPtr<IMachine> pMachine = findMachine("blah"); // calls AddRef()
+ * ComPtr<IUnknown> pUnknown = pMachine; // calls QueryInterface()
+ * } # ComPtr destructor of both instances calls Release()
+ *
+ * @endcode
+ */
+template <class T>
+class ComPtr
+{
+public:
+
+ /**
+ * Default constructor, sets up a NULL pointer.
+ */
+ ComPtr()
+ : m_p(NULL)
+ { }
+
+ /**
+ * Destructor. Calls Release() on the contained COM object.
+ */
+ ~ComPtr()
+ {
+ cleanup();
+ }
+
+ /**
+ * Copy constructor from another ComPtr of any interface.
+ *
+ * This calls QueryInterface(T) and can result in a NULL pointer if the input
+ * pointer p does not support the ComPtr interface T.
+ *
+ * Does not call AddRef explicitly because if QueryInterface succeeded, then
+ * the refcount will have been increased by one already .
+ */
+ template <class T2>
+ ComPtr(const ComPtr<T2> &that)
+ {
+ m_p = NULL;
+ if (!that.isNull())
+ that->QueryInterface(COM_IIDOF(T), (void**)&m_p);
+ }
+
+ /**
+ * Specialization: copy constructor from another ComPtr<T>. Calls AddRef().
+ */
+ ComPtr(const ComPtr &that)
+ {
+ copyFrom(that.m_p);
+ }
+
+ /**
+ * Copy constructor from another interface pointer of any interface.
+ *
+ * This calls QueryInterface(T) and can result in a NULL pointer if the input
+ * pointer p does not support the ComPtr interface T.
+ *
+ * Does not call AddRef explicitly because if QueryInterface succeeded, then
+ * the refcount will have been increased by one already .
+ */
+ template <class T2>
+ ComPtr(T2 *p)
+ {
+ m_p = NULL;
+ if (p)
+ p->QueryInterface(COM_IIDOF(T), (void**)&m_p);
+ }
+
+ /**
+ * Specialization: copy constructor from a plain T* pointer. Calls AddRef().
+ */
+ ComPtr(T *that_p)
+ {
+ copyFrom(that_p);
+ }
+
+ /**
+ * Assignment from another ComPtr of any interface.
+ *
+ * This calls QueryInterface(T) and can result in a NULL pointer if the input
+ * pointer p does not support the ComPtr interface T.
+ *
+ * Does not call AddRef explicitly because if QueryInterface succeeded, then
+ * the refcount will have been increased by one already .
+ */
+ template <class T2>
+ ComPtr& operator=(const ComPtr<T2> &that)
+ {
+ return operator=((T2*)that);
+ }
+
+ /**
+ * Specialization of the previous: assignment from another ComPtr<T>.
+ * Calls Release() on the previous member pointer, if any, and AddRef() on the new one.
+ */
+ ComPtr& operator=(const ComPtr &that)
+ {
+ return operator=((T*)that);
+ }
+
+ /**
+ * Assignment from another interface pointer of any interface.
+ *
+ * This calls QueryInterface(T) and can result in a NULL pointer if the input
+ * pointer p does not support the ComPtr interface T.
+ *
+ * Does not call AddRef explicitly because if QueryInterface succeeded, then
+ * the refcount will have been increased by one already .
+ */
+ template <class T2>
+ ComPtr& operator=(T2 *p)
+ {
+ cleanup();
+ if (p)
+ p->QueryInterface(COM_IIDOF(T), (void**)&m_p);
+ return *this;
+ }
+
+ /**
+ * Specialization of the previous: assignment from a plain T* pointer.
+ * Calls Release() on the previous member pointer, if any, and AddRef() on the new one.
+ */
+ ComPtr& operator=(T *p)
+ {
+ cleanup();
+ copyFrom(p);
+ return *this;
+ }
+
+ /**
+ * Resets the ComPtr to NULL. Works like a NULL assignment except it avoids the templates.
+ */
+ void setNull()
+ {
+ cleanup();
+ }
+
+ /**
+ * Returns true if the pointer is NULL.
+ */
+ bool isNull() const
+ {
+ return (m_p == NULL);
+ }
+
+ bool operator<(T* p) const
+ {
+ return m_p < p;
+ }
+
+ /**
+ * Conversion operator, most often used to pass ComPtr instances as
+ * parameters to COM method calls.
+ */
+ operator T*() const
+ {
+ return m_p;
+ }
+
+ /**
+ * Dereferences the instance (redirects the -> operator to the managed
+ * pointer).
+ */
+ T* operator->() const
+ {
+ return m_p;
+ }
+
+ /**
+ * Special method which allows using a ComPtr as an output argument of a COM method.
+ * The ComPtr will then accept the method's interface pointer without calling AddRef()
+ * itself, since by COM convention this must has been done by the method which created
+ * the object that is being accepted.
+ *
+ * The ComPtr destructor will then still invoke Release() so that the returned object
+ * can get cleaned up properly.
+ */
+ T** asOutParam()
+ {
+ cleanup();
+ return &m_p;
+ }
+
+ /**
+ * Converts the contained pointer to a different interface
+ * by calling QueryInterface() on it.
+ * @param pp
+ * @return
+ */
+ template <class T2>
+ HRESULT queryInterfaceTo(T2 **pp) const
+ {
+ if (pp)
+ {
+ if (m_p)
+ return m_p->QueryInterface(COM_IIDOF(T2), (void**)pp);
+ else
+ {
+ *pp = NULL;
+ return S_OK;
+ }
+ }
+
+ return E_INVALIDARG;
+ }
+
+ /**
+ * Equality test operator. By COM definition, two COM objects are considered
+ * equal if their IUnknown interface pointers are equal.
+ */
+ template <class T2>
+ bool operator==(T2* p)
+ {
+ IUnknown *p1 = NULL;
+ bool fNeedsRelease1 = false;
+ if (m_p)
+ fNeedsRelease1 = (SUCCEEDED(m_p->QueryInterface(COM_IIDOF(IUnknown), (void**)&p1)));
+
+ IUnknown *p2 = NULL;
+ bool fNeedsRelease2 = false;
+ if (p)
+ fNeedsRelease2 = (SUCCEEDED(p->QueryInterface(COM_IIDOF(IUnknown), (void**)&p2)));
+
+ bool f = p1 == p2;
+ if (fNeedsRelease1)
+ p1->Release();
+ if (fNeedsRelease2)
+ p2->Release();
+ return f;
+ }
+
+ /**
+ * Creates an in-process object of the given class ID and starts to
+ * manage a reference to the created object in case of success.
+ */
+ HRESULT createInprocObject(const CLSID &clsid)
+ {
+ HRESULT rc;
+ T *obj = NULL;
+#if !defined (VBOX_WITH_XPCOM)
+ rc = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, _ATL_IIDOF(T),
+ (void**)&obj);
+#else /* !defined (VBOX_WITH_XPCOM) */
+ using namespace com;
+ rc = GlueCreateInstance(clsid, NS_GET_IID(T), (void**)&obj);
+#endif /* !defined (VBOX_WITH_XPCOM) */
+ *this = obj;
+ if (SUCCEEDED(rc))
+ obj->Release();
+ return rc;
+ }
+
+ /**
+ * Creates a local (out-of-process) object of the given class ID and starts
+ * to manage a reference to the created object in case of success.
+ *
+ * Note: In XPCOM, the out-of-process functionality is currently emulated
+ * through in-process wrapper objects (that start a dedicated process and
+ * redirect all object requests to that process). For this reason, this
+ * method is fully equivalent to #createInprocObject() for now.
+ */
+ HRESULT createLocalObject(const CLSID &clsid)
+ {
+#if !defined (VBOX_WITH_XPCOM)
+ HRESULT rc;
+ T *obj = NULL;
+ rc = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, _ATL_IIDOF(T),
+ (void**)&obj);
+ *this = obj;
+ if (SUCCEEDED(rc))
+ obj->Release();
+ return rc;
+#else /* !defined (VBOX_WITH_XPCOM) */
+ return createInprocObject(clsid);
+#endif /* !defined (VBOX_WITH_XPCOM) */
+ }
+
+#ifdef VBOX_WITH_XPCOM
+ /**
+ * Creates an object of the given class ID on the specified server and
+ * starts to manage a reference to the created object in case of success.
+ *
+ * @param serverName Name of the server to create an object within.
+ */
+ HRESULT createObjectOnServer(const CLSID &clsid, const char *serverName)
+ {
+ T *obj = NULL;
+ HRESULT rc = GlueCreateObjectOnServer(clsid, serverName, NS_GET_IID(T), (void**)&obj);
+ *this = obj;
+ if (SUCCEEDED(rc))
+ obj->Release();
+ return rc;
+ }
+#endif
+
+protected:
+ void copyFrom(T* p)
+ {
+ m_p = p;
+ if (m_p)
+ m_p->AddRef();
+ }
+
+ void cleanup()
+ {
+ if (m_p)
+ {
+ m_p->Release();
+ m_p = NULL;
+ }
+ }
+
+ T *m_p;
+};
+
+/**
+ * ComObjPtr is a more specialized variant of ComPtr designed to be used for implementation
+ * objects. For example, use ComPtr<IMachine> for a client pointer that calls the interface
+ * but ComObjPtr<Machine> for a pointer to an implementation object.
+ *
+ * The methods behave the same except that ComObjPtr has the additional createObject()
+ * method which allows for instantiating a new implementation object.
+ *
+ * Note: To convert a ComObjPtr<InterfaceImpl> to a ComObj<IInterface> you have
+ * to query the interface. See the following example code for the IProgress
+ * interface:
+ *
+ * @code
+ *
+ * {
+ * ComObjPtr<Progress> pProgress; // create the server side object
+ * pProgress.createObject(); // ...
+ * pProgress->init(...); // ...
+ * ComPtr<IProgress> pProgress2; // create an interface pointer
+ * pProgress.queryInterfaceTo(pProgress2.asOutParam()); // transfer the interface
+ * }
+ *
+ * @endcode
+ */
+template <class T>
+class ComObjPtr : public ComPtr<T>
+{
+public:
+
+ ComObjPtr()
+ : ComPtr<T>()
+ {}
+
+ ComObjPtr(const ComObjPtr &that)
+ : ComPtr<T>(that)
+ {}
+
+ ComObjPtr(T *that_p)
+ : ComPtr<T>(that_p)
+ {}
+
+ ComObjPtr& operator=(const ComObjPtr &that)
+ {
+ ComPtr<T>::operator=(that);
+ return *this;
+ }
+
+ ComObjPtr& operator=(T *that_p)
+ {
+ ComPtr<T>::operator=(that_p);
+ return *this;
+ }
+
+ /**
+ * Creates a new server-side object of the given component class and
+ * immediately starts to manage a pointer to the created object (the
+ * previous pointer, if any, is of course released when appropriate).
+ *
+ * @note Win32: when VBOX_COM_OUTOFPROC_MODULE is defined, the created
+ * object doesn't increase the lock count of the server module, as it
+ * does otherwise.
+ */
+ HRESULT createObject()
+ {
+ HRESULT rc;
+#if !defined (VBOX_WITH_XPCOM)
+# ifdef VBOX_COM_OUTOFPROC_MODULE
+ CComObjectNoLock<T> *obj = new CComObjectNoLock<T>();
+ if (obj)
+ {
+ obj->InternalFinalConstructAddRef();
+ rc = obj->FinalConstruct();
+ obj->InternalFinalConstructRelease();
+ }
+ else
+ rc = E_OUTOFMEMORY;
+# else
+ CComObject<T> *obj = NULL;
+ rc = CComObject<T>::CreateInstance(&obj);
+# endif
+#else /* !defined (VBOX_WITH_XPCOM) */
+ CComObject<T> *obj = new CComObject<T>();
+ if (obj)
+ rc = obj->FinalConstruct();
+ else
+ rc = E_OUTOFMEMORY;
+#endif /* !defined (VBOX_WITH_XPCOM) */
+ *this = obj;
+ return rc;
+ }
+};
+#endif
diff --git a/include/VBox/com/string.h b/include/VBox/com/string.h
new file mode 100644
index 00000000..3462818e
--- /dev/null
+++ b/include/VBox/com/string.h
@@ -0,0 +1,810 @@
+/* $Id: string.h $ */
+/** @file
+ * MS COM / XPCOM Abstraction Layer - Smart string classes declaration.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_com_string_h
+#define ___VBox_com_string_h
+
+/* Make sure all the stdint.h macros are included - must come first! */
+#ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS
+#endif
+
+#if defined(VBOX_WITH_XPCOM)
+# include <nsMemory.h>
+#endif
+
+#include "VBox/com/defs.h"
+#include "VBox/com/assert.h"
+
+#include <iprt/mem.h>
+#include <iprt/cpp/ministring.h>
+
+namespace com
+{
+
+class Utf8Str;
+
+// global constant in glue/string.cpp that represents an empty BSTR
+extern const BSTR g_bstrEmpty;
+
+/**
+ * String class used universally in Main for COM-style Utf-16 strings.
+ *
+ * Unfortunately COM on Windows uses UTF-16 everywhere, requiring conversions
+ * back and forth since most of VirtualBox and our libraries use UTF-8.
+ *
+ * To make things more obscure, on Windows, a COM-style BSTR is not just a
+ * pointer to a null-terminated wide character array, but the four bytes (32
+ * bits) BEFORE the memory that the pointer points to are a length DWORD. One
+ * must therefore avoid pointer arithmetic and always use SysAllocString and
+ * the like to deal with BSTR pointers, which manage that DWORD correctly.
+ *
+ * For platforms other than Windows, we provide our own versions of the Sys*
+ * functions in Main/xpcom/helpers.cpp which do NOT use length prefixes though
+ * to be compatible with how XPCOM allocates string parameters to public
+ * functions.
+ *
+ * The Bstr class hides all this handling behind a std::string-like interface
+ * and also provides automatic conversions to RTCString and Utf8Str instances.
+ *
+ * The one advantage of using the SysString* routines is that this makes it
+ * possible to use it as a type of member variables of COM/XPCOM components and
+ * pass their values to callers through component methods' output parameters
+ * using the #cloneTo() operation. Also, the class can adopt (take ownership
+ * of) string buffers returned in output parameters of COM methods using the
+ * #asOutParam() operation and correctly free them afterwards.
+ *
+ * Starting with VirtualBox 3.2, like Utf8Str, Bstr no longer differentiates
+ * between NULL strings and empty strings. In other words, Bstr("") and
+ * Bstr(NULL) behave the same. In both cases, Bstr allocates no memory,
+ * reports a zero length and zero allocated bytes for both, and returns an
+ * empty C wide string from raw().
+ *
+ * @note All Bstr methods ASSUMES valid UTF-16 or UTF-8 input strings.
+ * The VirtualBox policy in this regard is to validate strings coming
+ * from external sources before passing them to Bstr or Utf8Str.
+ */
+class Bstr
+{
+public:
+
+ Bstr()
+ : m_bstr(NULL)
+ { }
+
+ Bstr(const Bstr &that)
+ {
+ copyFrom((const OLECHAR *)that.m_bstr);
+ }
+
+ Bstr(CBSTR that)
+ {
+ copyFrom((const OLECHAR *)that);
+ }
+
+#if defined(VBOX_WITH_XPCOM)
+ Bstr(const wchar_t *that)
+ {
+ AssertCompile(sizeof(wchar_t) == sizeof(OLECHAR));
+ copyFrom((const OLECHAR *)that);
+ }
+#endif
+
+ Bstr(const RTCString &that)
+ {
+ copyFrom(that.c_str());
+ }
+
+ Bstr(const char *that)
+ {
+ copyFrom(that);
+ }
+
+ Bstr(const char *a_pThat, size_t a_cchMax)
+ {
+ copyFromN(a_pThat, a_cchMax);
+ }
+
+ ~Bstr()
+ {
+ setNull();
+ }
+
+ Bstr& operator=(const Bstr &that)
+ {
+ cleanup();
+ copyFrom((const OLECHAR *)that.m_bstr);
+ return *this;
+ }
+
+ Bstr& operator=(CBSTR that)
+ {
+ cleanup();
+ copyFrom((const OLECHAR *)that);
+ return *this;
+ }
+
+#if defined(VBOX_WITH_XPCOM)
+ Bstr& operator=(const wchar_t *that)
+ {
+ cleanup();
+ copyFrom((const OLECHAR *)that);
+ return *this;
+ }
+#endif
+
+ Bstr& setNull()
+ {
+ cleanup();
+ return *this;
+ }
+
+#ifdef _MSC_VER
+# if _MSC_VER >= 1400
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+# endif
+#else
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+#endif
+
+ /** Case sensitivity selector. */
+ enum CaseSensitivity
+ {
+ CaseSensitive,
+ CaseInsensitive
+ };
+
+ /**
+ * Compares the member string to str.
+ * @param str
+ * @param cs Whether comparison should be case-sensitive.
+ * @return
+ */
+ int compare(CBSTR str, CaseSensitivity cs = CaseSensitive) const
+ {
+ if (cs == CaseSensitive)
+ return ::RTUtf16Cmp((PRTUTF16)m_bstr, (PRTUTF16)str);
+ return ::RTUtf16LocaleICmp((PRTUTF16)m_bstr, (PRTUTF16)str);
+ }
+
+ int compare(BSTR str, CaseSensitivity cs = CaseSensitive) const
+ {
+ return compare((CBSTR)str, cs);
+ }
+
+ int compare(const Bstr &that, CaseSensitivity cs = CaseSensitive) const
+ {
+ return compare(that.m_bstr, cs);
+ }
+
+ bool operator==(const Bstr &that) const { return !compare(that.m_bstr); }
+ bool operator!=(const Bstr &that) const { return !!compare(that.m_bstr); }
+ bool operator==(CBSTR that) const { return !compare(that); }
+ bool operator==(BSTR that) const { return !compare(that); }
+
+ bool operator!=(CBSTR that) const { return !!compare(that); }
+ bool operator!=(BSTR that) const { return !!compare(that); }
+ bool operator<(const Bstr &that) const { return compare(that.m_bstr) < 0; }
+ bool operator<(CBSTR that) const { return compare(that) < 0; }
+ bool operator<(BSTR that) const { return compare(that) < 0; }
+
+ /**
+ * Returns true if the member string has no length.
+ * This is true for instances created from both NULL and "" input strings.
+ *
+ * @note Always use this method to check if an instance is empty. Do not
+ * use length() because that may need to run through the entire string
+ * (Bstr does not cache string lengths).
+ */
+ bool isEmpty() const { return m_bstr == NULL || *m_bstr == 0; }
+
+ /**
+ * Returns true if the member string has a length of one or more.
+ *
+ * @returns true if not empty, false if empty (NULL or "").
+ */
+ bool isNotEmpty() const { return m_bstr != NULL && *m_bstr != 0; }
+
+ size_t length() const { return isEmpty() ? 0 : ::RTUtf16Len((PRTUTF16)m_bstr); }
+
+#if defined(VBOX_WITH_XPCOM)
+ /**
+ * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
+ * returns a pointer to a global variable containing an empty BSTR with a proper zero
+ * length prefix so that Windows is happy.
+ */
+ CBSTR raw() const
+ {
+ if (m_bstr)
+ return m_bstr;
+
+ return g_bstrEmpty;
+ }
+#else
+ /**
+ * Windows-only hack, as the automatically generated headers use BSTR.
+ * So if we don't want to cast like crazy we have to be more loose than
+ * on XPCOM.
+ *
+ * Returns a pointer to the raw member UTF-16 string. If the member string is empty,
+ * returns a pointer to a global variable containing an empty BSTR with a proper zero
+ * length prefix so that Windows is happy.
+ */
+ BSTR raw() const
+ {
+ if (m_bstr)
+ return m_bstr;
+
+ return g_bstrEmpty;
+ }
+#endif
+
+ /**
+ * Returns a non-const raw pointer that allows to modify the string directly.
+ * As opposed to raw(), this DOES return NULL if the member string is empty
+ * because we cannot return a mutable pointer to the global variable with the
+ * empty string.
+ *
+ * @warning
+ * Be sure not to modify data beyond the allocated memory! The
+ * guaranteed size of the allocated memory is at least #length()
+ * bytes after creation and after every assignment operation.
+ */
+ BSTR mutableRaw() { return m_bstr; }
+
+ /**
+ * Intended to assign copies of instances to |BSTR| out parameters from
+ * within the interface method. Transfers the ownership of the duplicated
+ * string to the caller.
+ *
+ * If the member string is empty, this allocates an empty BSTR in *pstr
+ * (i.e. makes it point to a new buffer with a null byte).
+ *
+ * @deprecated Use cloneToEx instead to avoid throwing exceptions.
+ */
+ void cloneTo(BSTR *pstr) const
+ {
+ if (pstr)
+ {
+ *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
+#ifdef RT_EXCEPTIONS_ENABLED
+ if (!*pstr)
+ throw std::bad_alloc();
+#endif
+ }
+ }
+
+ /**
+ * A version of cloneTo that does not throw any out of memory exceptions, but
+ * returns E_OUTOFMEMORY intead.
+ * @returns S_OK or E_OUTOFMEMORY.
+ */
+ HRESULT cloneToEx(BSTR *pstr) const
+ {
+ if (!pstr)
+ return S_OK;
+ *pstr = ::SysAllocString((const OLECHAR *)raw()); // raw() returns a pointer to "" if empty
+ return pstr ? S_OK : E_OUTOFMEMORY;
+ }
+
+ /**
+ * Intended to assign instances to |BSTR| out parameters from within the
+ * interface method. Transfers the ownership of the original string to the
+ * caller and resets the instance to null.
+ *
+ * As opposed to cloneTo(), this method doesn't create a copy of the
+ * string.
+ *
+ * If the member string is empty, this allocates an empty BSTR in *pstr
+ * (i.e. makes it point to a new buffer with a null byte).
+ *
+ * @param pbstrDst The BSTR variable to detach the string to.
+ *
+ * @throws std::bad_alloc if we failed to allocate a new empty string.
+ */
+ void detachTo(BSTR *pbstrDst)
+ {
+ if (m_bstr)
+ {
+ *pbstrDst = m_bstr;
+ m_bstr = NULL;
+ }
+ else
+ {
+ // allocate null BSTR
+ *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
+#ifdef RT_EXCEPTIONS_ENABLED
+ if (!*pbstrDst)
+ throw std::bad_alloc();
+#endif
+ }
+ }
+
+ /**
+ * A version of detachTo that does not throw exceptions on out-of-memory
+ * conditions, but instead returns E_OUTOFMEMORY.
+ *
+ * @param pbstrDst The BSTR variable to detach the string to.
+ * @returns S_OK or E_OUTOFMEMORY.
+ */
+ HRESULT detachToEx(BSTR *pbstrDst)
+ {
+ if (m_bstr)
+ {
+ *pbstrDst = m_bstr;
+ m_bstr = NULL;
+ }
+ else
+ {
+ // allocate null BSTR
+ *pbstrDst = ::SysAllocString((const OLECHAR *)g_bstrEmpty);
+ if (!*pbstrDst)
+ return E_OUTOFMEMORY;
+ }
+ return S_OK;
+ }
+
+ /**
+ * Intended to pass instances as |BSTR| out parameters to methods.
+ * Takes the ownership of the returned data.
+ */
+ BSTR *asOutParam()
+ {
+ cleanup();
+ return &m_bstr;
+ }
+
+ /**
+ * Static immutable empty-string object. May be used for comparison purposes.
+ */
+ static const Bstr Empty;
+
+protected:
+
+ void cleanup()
+ {
+ if (m_bstr)
+ {
+ ::SysFreeString(m_bstr);
+ m_bstr = NULL;
+ }
+ }
+
+ /**
+ * Protected internal helper to copy a string. This ignores the previous object
+ * state, so either call this from a constructor or call cleanup() first.
+ *
+ * This variant copies from a zero-terminated UTF-16 string (which need not
+ * be a BSTR, i.e. need not have a length prefix).
+ *
+ * If the source is empty, this sets the member string to NULL.
+ *
+ * @param a_bstrSrc The source string. The caller guarantees
+ * that this is valid UTF-16.
+ *
+ * @throws std::bad_alloc - the object is representing an empty string.
+ */
+ void copyFrom(const OLECHAR *a_bstrSrc)
+ {
+ if (a_bstrSrc && *a_bstrSrc)
+ {
+ m_bstr = ::SysAllocString(a_bstrSrc);
+#ifdef RT_EXCEPTIONS_ENABLED
+ if (!m_bstr)
+ throw std::bad_alloc();
+#endif
+ }
+ else
+ m_bstr = NULL;
+ }
+
+ /**
+ * Protected internal helper to copy a string. This ignores the previous object
+ * state, so either call this from a constructor or call cleanup() first.
+ *
+ * This variant copies and converts from a zero-terminated UTF-8 string.
+ *
+ * If the source is empty, this sets the member string to NULL.
+ *
+ * @param a_pszSrc The source string. The caller guarantees
+ * that this is valid UTF-8.
+ *
+ * @throws std::bad_alloc - the object is representing an empty string.
+ */
+ void copyFrom(const char *a_pszSrc)
+ {
+ copyFromN(a_pszSrc, RTSTR_MAX);
+ }
+
+ /**
+ * Variant of copyFrom for sub-string constructors.
+ *
+ * @param a_pszSrc The source string. The caller guarantees
+ * that this is valid UTF-8.
+ * @param a_cchMax The maximum number of chars (not
+ * codepoints) to copy. If you pass RTSTR_MAX
+ * it'll be exactly like copyFrom().
+ *
+ * @throws std::bad_alloc - the object is representing an empty string.
+ */
+ void copyFromN(const char *a_pszSrc, size_t a_cchSrc);
+
+ BSTR m_bstr;
+
+ friend class Utf8Str; /* to access our raw_copy() */
+};
+
+/* symmetric compare operators */
+inline bool operator==(CBSTR l, const Bstr &r) { return r.operator==(l); }
+inline bool operator!=(CBSTR l, const Bstr &r) { return r.operator!=(l); }
+inline bool operator==(BSTR l, const Bstr &r) { return r.operator==(l); }
+inline bool operator!=(BSTR l, const Bstr &r) { return r.operator!=(l); }
+
+
+
+
+/**
+ * String class used universally in Main for UTF-8 strings.
+ *
+ * This is based on RTCString, to which some functionality has been
+ * moved. Here we keep things that are specific to Main, such as conversions
+ * with UTF-16 strings (Bstr).
+ *
+ * Like RTCString, Utf8Str does not differentiate between NULL strings
+ * and empty strings. In other words, Utf8Str("") and Utf8Str(NULL) behave the
+ * same. In both cases, RTCString allocates no memory, reports
+ * a zero length and zero allocated bytes for both, and returns an empty
+ * C string from c_str().
+ *
+ * @note All Utf8Str methods ASSUMES valid UTF-8 or UTF-16 input strings.
+ * The VirtualBox policy in this regard is to validate strings coming
+ * from external sources before passing them to Utf8Str or Bstr.
+ */
+class Utf8Str : public RTCString
+{
+public:
+
+ Utf8Str() {}
+
+ Utf8Str(const RTCString &that)
+ : RTCString(that)
+ {}
+
+ Utf8Str(const char *that)
+ : RTCString(that)
+ {}
+
+ Utf8Str(const Bstr &that)
+ {
+ copyFrom(that.raw());
+ }
+
+ Utf8Str(CBSTR that)
+ {
+ copyFrom(that);
+ }
+
+ Utf8Str(const char *a_pszSrc, size_t a_cchSrc)
+ : RTCString(a_pszSrc, a_cchSrc)
+ {
+ }
+
+ /**
+ * Constructs a new string given the format string and the list of the
+ * arguments for the format string.
+ *
+ * @param a_pszFormat Pointer to the format string (UTF-8),
+ * @see pg_rt_str_format.
+ * @param a_va Argument vector containing the arguments
+ * specified by the format string.
+ * @sa RTCString::printfV
+ */
+ Utf8Str(const char *a_pszFormat, va_list a_va)
+ : RTCString(a_pszFormat, a_va)
+ {
+ }
+
+ Utf8Str& operator=(const RTCString &that)
+ {
+ RTCString::operator=(that);
+ return *this;
+ }
+
+ Utf8Str& operator=(const char *that)
+ {
+ RTCString::operator=(that);
+ return *this;
+ }
+
+ Utf8Str& operator=(const Bstr &that)
+ {
+ cleanup();
+ copyFrom(that.raw());
+ return *this;
+ }
+
+ Utf8Str& operator=(CBSTR that)
+ {
+ cleanup();
+ copyFrom(that);
+ return *this;
+ }
+
+ bool operator<(const RTCString &that) const { return RTCString::operator<(that); }
+
+ /**
+ * Extended assignment method that returns a COM status code instead of an
+ * exception on failure.
+ *
+ * @returns S_OK or E_OUTOFMEMORY.
+ * @param a_rSrcStr The source string
+ */
+ HRESULT assignEx(Utf8Str const &a_rSrcStr)
+ {
+ return copyFromExNComRC(a_rSrcStr.m_psz, a_rSrcStr.m_cch);
+ }
+
+ /**
+ * Extended assignment method that returns a COM status code instead of an
+ * exception on failure.
+ *
+ * @returns S_OK, E_OUTOFMEMORY or E_INVALIDARG.
+ * @param a_pcszSrc The source string
+ * @param a_offSrc The character (byte) offset of the substring.
+ * @param a_cchSrc The number of characters (bytes) to copy from the source
+ * string.
+ */
+ HRESULT assignEx(Utf8Str const &a_rSrcStr, size_t a_offSrc, size_t a_cchSrc)
+ {
+ if ( a_offSrc + a_cchSrc > a_rSrcStr.m_cch
+ || a_offSrc > a_rSrcStr.m_cch)
+ return E_INVALIDARG;
+ return copyFromExNComRC(a_rSrcStr.m_psz, a_rSrcStr.m_cch);
+ }
+
+ /**
+ * Extended assignment method that returns a COM status code instead of an
+ * exception on failure.
+ *
+ * @returns S_OK or E_OUTOFMEMORY.
+ * @param a_pcszSrc The source string
+ */
+ HRESULT assignEx(const char *a_pcszSrc)
+ {
+ return copyFromExNComRC(a_pcszSrc, a_pcszSrc ? strlen(a_pcszSrc) : 0);
+ }
+
+ /**
+ * Extended assignment method that returns a COM status code instead of an
+ * exception on failure.
+ *
+ * @returns S_OK or E_OUTOFMEMORY.
+ * @param a_pcszSrc The source string
+ * @param a_cchSrc The number of characters (bytes) to copy from the source
+ * string.
+ */
+ HRESULT assignEx(const char *a_pcszSrc, size_t a_cchSrc)
+ {
+ return copyFromExNComRC(a_pcszSrc, a_cchSrc);
+ }
+
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+
+#if defined(VBOX_WITH_XPCOM)
+ /**
+ * Intended to assign instances to |char *| out parameters from within the
+ * interface method. Transfers the ownership of the duplicated string to the
+ * caller.
+ *
+ * This allocates a single 0 byte in the target if the member string is empty.
+ *
+ * This uses XPCOM memory allocation and thus only works on XPCOM. MSCOM doesn't
+ * like char* strings anyway.
+ */
+ void cloneTo(char **pstr) const;
+
+ /**
+ * A version of cloneTo that does not throw allocation errors but returns
+ * E_OUTOFMEMORY instead.
+ * @returns S_OK or E_OUTOFMEMORY (COM status codes).
+ */
+ HRESULT cloneToEx(char **pstr) const;
+#endif
+
+ /**
+ * Intended to assign instances to |BSTR| out parameters from within the
+ * interface method. Transfers the ownership of the duplicated string to the
+ * caller.
+ */
+ void cloneTo(BSTR *pstr) const
+ {
+ if (pstr)
+ {
+ Bstr bstr(*this);
+ bstr.cloneTo(pstr);
+ }
+ }
+
+ /**
+ * A version of cloneTo that does not throw allocation errors but returns
+ * E_OUTOFMEMORY instead.
+ *
+ * @param pbstr Where to store a clone of the string.
+ * @returns S_OK or E_OUTOFMEMORY (COM status codes).
+ */
+ HRESULT cloneToEx(BSTR *pbstr) const
+ {
+ if (!pbstr)
+ return S_OK;
+ Bstr bstr(*this);
+ return bstr.detachToEx(pbstr);
+ }
+
+ /**
+ * Safe assignment from BSTR.
+ *
+ * @param pbstrSrc The source string.
+ * @returns S_OK or E_OUTOFMEMORY (COM status codes).
+ */
+ HRESULT cloneEx(CBSTR pbstrSrc)
+ {
+ cleanup();
+ return copyFromEx(pbstrSrc);
+ }
+
+ /**
+ * Removes a trailing slash from the member string, if present.
+ * Calls RTPathStripTrailingSlash() without having to mess with mutableRaw().
+ */
+ Utf8Str& stripTrailingSlash();
+
+ /**
+ * Removes a trailing filename from the member string, if present.
+ * Calls RTPathStripFilename() without having to mess with mutableRaw().
+ */
+ Utf8Str& stripFilename();
+
+ /**
+ * Removes the path component from the member string, if present.
+ * Calls RTPathFilename() without having to mess with mutableRaw().
+ */
+ Utf8Str& stripPath();
+
+ /**
+ * Removes a trailing file name extension from the member string, if present.
+ * Calls RTPathStripExt() without having to mess with mutableRaw().
+ */
+ Utf8Str& stripExt();
+
+ /**
+ * Static immutable empty-string object. May be used for comparison purposes.
+ */
+ static const Utf8Str Empty;
+protected:
+
+ void copyFrom(CBSTR a_pbstr);
+ HRESULT copyFromEx(CBSTR a_pbstr);
+ HRESULT copyFromExNComRC(const char *a_pcszSrc, size_t a_cchSrc);
+
+ friend class Bstr; /* to access our raw_copy() */
+};
+
+/**
+ * Class with RTCString::printf as constructor for your convenience.
+ *
+ * Constructing a Utf8Str string object from a format string and a variable
+ * number of arguments can easily be confused with the other Utf8Str
+ * constructures, thus this child class.
+ *
+ * The usage of this class is like the following:
+ * @code
+ Utf8StrFmt strName("program name = %s", argv[0]);
+ @endcode
+ */
+class Utf8StrFmt : public Utf8Str
+{
+public:
+
+ /**
+ * Constructs a new string given the format string and the list of the
+ * arguments for the format string.
+ *
+ * @param a_pszFormat Pointer to the format string (UTF-8),
+ * @see pg_rt_str_format.
+ * @param ... Ellipsis containing the arguments specified by
+ * the format string.
+ */
+ explicit Utf8StrFmt(const char *a_pszFormat, ...)
+ {
+ va_list va;
+ va_start(va, a_pszFormat);
+ printfV(a_pszFormat, va);
+ va_end(va);
+ }
+
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+
+protected:
+ Utf8StrFmt()
+ { }
+
+private:
+};
+
+/**
+ * The BstrFmt class is a shortcut to <tt>Bstr(Utf8StrFmt(...))</tt>.
+ */
+class BstrFmt : public Bstr
+{
+public:
+
+ /**
+ * Constructs a new string given the format string and the list of the
+ * arguments for the format string.
+ *
+ * @param aFormat printf-like format string (in UTF-8 encoding).
+ * @param ... List of the arguments for the format string.
+ */
+ explicit BstrFmt(const char *aFormat, ...)
+ {
+ va_list args;
+ va_start(args, aFormat);
+ copyFrom(Utf8Str(aFormat, args).c_str());
+ va_end(args);
+ }
+
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * The BstrFmtVA class is a shortcut to <tt>Bstr(Utf8Str(format,va))</tt>.
+ */
+class BstrFmtVA : public Bstr
+{
+public:
+
+ /**
+ * Constructs a new string given the format string and the list of the
+ * arguments for the format string.
+ *
+ * @param aFormat printf-like format string (in UTF-8 encoding).
+ * @param aArgs List of arguments for the format string
+ */
+ BstrFmtVA(const char *aFormat, va_list aArgs)
+ {
+ copyFrom(Utf8Str(aFormat, aArgs).c_str());
+ }
+
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+} /* namespace com */
+
+#endif /* !___VBox_com_string_h */
+
diff --git a/include/VBox/dbg.h b/include/VBox/dbg.h
new file mode 100644
index 00000000..320dac16
--- /dev/null
+++ b/include/VBox/dbg.h
@@ -0,0 +1,1209 @@
+/** @file
+ * Debugger Interfaces. (VBoxDbg)
+ *
+ * This header covers all external interfaces of the Debugger module.
+ * However, it does not cover the DBGF interface since that part of the
+ * VMM. Use dbgf.h for that.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_dbg_h
+#define ___VBox_dbg_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/vmm/dbgf.h>
+
+#include <iprt/stdarg.h>
+#ifdef IN_RING3
+# include <iprt/err.h>
+#endif
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING3 /* The debugger stuff is ring-3 only. */
+
+/** @def VBOX_WITH_DEBUGGER
+ * The build is with debugger module. Test if this is defined before registering
+ * external debugger commands. This is normally defined in Config.kmk.
+ */
+#ifdef DOXYGEN_RUNNING
+# define VBOX_WITH_DEBUGGER
+#endif
+
+
+/**
+ * DBGC variable category.
+ *
+ * Used to describe an argument to a command or function and a functions
+ * return value.
+ */
+typedef enum DBGCVARCAT
+{
+ /** Any type is fine. */
+ DBGCVAR_CAT_ANY = 0,
+ /** Any kind of pointer or number. */
+ DBGCVAR_CAT_POINTER_NUMBER,
+ /** Any kind of pointer or number, no range. */
+ DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE,
+ /** Any kind of pointer. */
+ DBGCVAR_CAT_POINTER,
+ /** Any kind of pointer with no range option. */
+ DBGCVAR_CAT_POINTER_NO_RANGE,
+ /** GC pointer. */
+ DBGCVAR_CAT_GC_POINTER,
+ /** GC pointer with no range option. */
+ DBGCVAR_CAT_GC_POINTER_NO_RANGE,
+ /** Numeric argument. */
+ DBGCVAR_CAT_NUMBER,
+ /** Numeric argument with no range option. */
+ DBGCVAR_CAT_NUMBER_NO_RANGE,
+ /** String. */
+ DBGCVAR_CAT_STRING,
+ /** Symbol. */
+ DBGCVAR_CAT_SYMBOL,
+ /** Option. */
+ DBGCVAR_CAT_OPTION,
+ /** Option + string. */
+ DBGCVAR_CAT_OPTION_STRING,
+ /** Option + number. */
+ DBGCVAR_CAT_OPTION_NUMBER
+} DBGCVARCAT;
+
+
+/**
+ * DBGC variable type.
+ */
+typedef enum DBGCVARTYPE
+{
+ /** unknown... */
+ DBGCVAR_TYPE_UNKNOWN = 0,
+ /** Flat GC pointer. */
+ DBGCVAR_TYPE_GC_FLAT,
+ /** Segmented GC pointer. */
+ DBGCVAR_TYPE_GC_FAR,
+ /** Physical GC pointer. */
+ DBGCVAR_TYPE_GC_PHYS,
+ /** Flat HC pointer. */
+ DBGCVAR_TYPE_HC_FLAT,
+ /** Physical HC pointer. */
+ DBGCVAR_TYPE_HC_PHYS,
+ /** Number. */
+ DBGCVAR_TYPE_NUMBER,
+ /** String. */
+ DBGCVAR_TYPE_STRING,
+ /** Symbol. */
+ DBGCVAR_TYPE_SYMBOL,
+ /** Special type used when querying symbols. */
+ DBGCVAR_TYPE_ANY
+} DBGCVARTYPE;
+
+/** @todo Rename to DBGCVAR_IS_xyz. */
+
+/** Checks if the specified variable type is of a pointer persuasion. */
+#define DBGCVAR_ISPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && enmType <= DBGCVAR_TYPE_HC_PHYS)
+/** Checks if the specified variable type is of a pointer persuasion. */
+#define DBGCVAR_IS_FAR_PTR(enmType) ((enmType) == DBGCVAR_TYPE_GC_FAR)
+/** Checks if the specified variable type is of a pointer persuasion and of the guest context sort. */
+#define DBGCVAR_ISGCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_GC_FLAT && (enmType) <= DBGCVAR_TYPE_GC_PHYS)
+/** Checks if the specified variable type is of a pointer persuasion and of the host context sort. */
+#define DBGCVAR_ISHCPOINTER(enmType) ((enmType) >= DBGCVAR_TYPE_HC_FLAT && (enmType) <= DBGCVAR_TYPE_HC_PHYS)
+
+
+/**
+ * DBGC variable range type.
+ */
+typedef enum DBGCVARRANGETYPE
+{
+ /** No range appliable or no range specified. */
+ DBGCVAR_RANGE_NONE = 0,
+ /** Number of elements. */
+ DBGCVAR_RANGE_ELEMENTS,
+ /** Number of bytes. */
+ DBGCVAR_RANGE_BYTES
+} DBGCVARRANGETYPE;
+
+
+/**
+ * Variable descriptor.
+ */
+typedef struct DBGCVARDESC
+{
+ /** The minimal number of times this argument may occur.
+ * Use 0 here to inidicate that the argument is optional. */
+ unsigned cTimesMin;
+ /** Maximum number of occurrences.
+ * Use ~0 here to indicate infinite. */
+ unsigned cTimesMax;
+ /** Argument category. */
+ DBGCVARCAT enmCategory;
+ /** Flags, DBGCVD_FLAGS_* */
+ unsigned fFlags;
+ /** Argument name. */
+ const char *pszName;
+ /** Argument name. */
+ const char *pszDescription;
+} DBGCVARDESC;
+/** Pointer to an argument descriptor. */
+typedef DBGCVARDESC *PDBGCVARDESC;
+/** Pointer to a const argument descriptor. */
+typedef const DBGCVARDESC *PCDBGCVARDESC;
+
+/** Variable descriptor flags.
+ * @{ */
+/** Indicates that the variable depends on the previous being present. */
+#define DBGCVD_FLAGS_DEP_PREV RT_BIT(1)
+/** @} */
+
+
+/**
+ * DBGC variable.
+ */
+typedef struct DBGCVAR
+{
+ /** Pointer to the argument descriptor. */
+ PCDBGCVARDESC pDesc;
+ /** Pointer to the next argument. */
+ struct DBGCVAR *pNext;
+
+ /** Argument type. */
+ DBGCVARTYPE enmType;
+ /** Type specific. */
+ union
+ {
+ /** Flat GC Address. (DBGCVAR_TYPE_GC_FLAT) */
+ RTGCPTR GCFlat;
+ /** Far (16:32) GC Address. (DBGCVAR_TYPE_GC_FAR) */
+ RTFAR32 GCFar;
+ /** Physical GC Address. (DBGCVAR_TYPE_GC_PHYS) */
+ RTGCPHYS GCPhys;
+ /** Flat HC Address. (DBGCVAR_TYPE_HC_FLAT) */
+ void *pvHCFlat;
+ /** Physical GC Address. (DBGCVAR_TYPE_HC_PHYS) */
+ RTHCPHYS HCPhys;
+ /** String. (DBGCVAR_TYPE_STRING)
+ * The basic idea is the the this is a pointer to the expression we're
+ * parsing, so no messing with freeing. */
+ const char *pszString;
+ /** Number. (DBGCVAR_TYPE_NUMBER) */
+ uint64_t u64Number;
+ } u;
+
+ /** Range type. */
+ DBGCVARRANGETYPE enmRangeType;
+ /** Range. The use of the content depends on the enmRangeType. */
+ uint64_t u64Range;
+} DBGCVAR;
+/** Pointer to a command argument. */
+typedef DBGCVAR *PDBGCVAR;
+/** Pointer to a const command argument. */
+typedef const DBGCVAR *PCDBGCVAR;
+
+
+/**
+ * Macro for initializing a DBGC variable with defaults.
+ * The result is an unknown variable type without any range.
+ */
+#define DBGCVAR_INIT(pVar) \
+ do { \
+ (pVar)->pDesc = NULL;\
+ (pVar)->pNext = NULL; \
+ (pVar)->enmType = DBGCVAR_TYPE_UNKNOWN; \
+ (pVar)->u.u64Number = 0; \
+ (pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
+ (pVar)->u64Range = 0; \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a HC physical address.
+ */
+#define DBGCVAR_INIT_HC_PHYS(pVar, Phys) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_HC_PHYS; \
+ (pVar)->u.HCPhys = (Phys); \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a HC flat address.
+ */
+#define DBGCVAR_INIT_HC_FLAT(pVar, Flat) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_HC_FLAT; \
+ (pVar)->u.pvHCFlat = (Flat); \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a GC physical address.
+ */
+#define DBGCVAR_INIT_GC_PHYS(pVar, Phys) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_GC_PHYS; \
+ (pVar)->u.GCPhys = (Phys); \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a GC flat address.
+ */
+#define DBGCVAR_INIT_GC_FLAT(pVar, Flat) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
+ (pVar)->u.GCFlat = (Flat); \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a GC flat address.
+ */
+#define DBGCVAR_INIT_GC_FLAT_BYTE_RANGE(pVar, Flat, cbRange) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_GC_FLAT; \
+ (pVar)->u.GCFlat = (Flat); \
+ DBGCVAR_SET_RANGE(pVar, DBGCVAR_RANGE_BYTES, cbRange); \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a GC far address.
+ */
+#define DBGCVAR_INIT_GC_FAR(pVar, _sel, _off) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_GC_FAR; \
+ (pVar)->u.GCFar.sel = (_sel); \
+ (pVar)->u.GCFar.off = (_off); \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a number.
+ */
+#define DBGCVAR_INIT_NUMBER(pVar, Value) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_NUMBER; \
+ (pVar)->u.u64Number = (Value); \
+ } while (0)
+
+/**
+ * Macro for initializing a DBGC variable with a string.
+ */
+#define DBGCVAR_INIT_STRING(pVar, a_pszString) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_STRING; \
+ (pVar)->enmRangeType = DBGCVAR_RANGE_BYTES; \
+ (pVar)->u.pszString = (a_pszString); \
+ (pVar)->u64Range = strlen(a_pszString); \
+ } while (0)
+
+
+/**
+ * Macro for initializing a DBGC variable with a symbol.
+ */
+#define DBGCVAR_INIT_SYMBOL(pVar, a_pszSymbol) \
+ do { \
+ DBGCVAR_INIT(pVar); \
+ (pVar)->enmType = DBGCVAR_TYPE_SYMBOL; \
+ (pVar)->enmRangeType = DBGCVAR_RANGE_BYTES; \
+ (pVar)->u.pszString = (a_pszSymbol); \
+ (pVar)->u64Range = strlen(a_pszSymbol); \
+ } while (0)
+
+
+/**
+ * Macro for setting the range of a DBGC variable.
+ * @param pVar The variable.
+ * @param _enmRangeType The range type.
+ * @param Value The range length value.
+ */
+#define DBGCVAR_SET_RANGE(pVar, _enmRangeType, Value) \
+ do { \
+ (pVar)->enmRangeType = (_enmRangeType); \
+ (pVar)->u64Range = (Value); \
+ } while (0)
+
+
+/**
+ * Macro for setting the range of a DBGC variable.
+ * @param a_pVar The variable.
+ * @param a_cbRange The range, in bytes.
+ */
+#define DBGCVAR_SET_BYTE_RANGE(a_pVar, a_cbRange) \
+ DBGCVAR_SET_RANGE(a_pVar, DBGCVAR_RANGE_BYTES, a_cbRange)
+
+
+/**
+ * Macro for resetting the range a DBGC variable.
+ * @param a_pVar The variable.
+ */
+#define DBGCVAR_ZAP_RANGE(a_pVar) \
+ do { \
+ (a_pVar)->enmRangeType = DBGCVAR_RANGE_NONE; \
+ (a_pVar)->u64Range = 0; \
+ } while (0)
+
+
+/**
+ * Macro for assigning one DBGC variable to another.
+ * @param a_pResult The result (target) variable.
+ * @param a_pVar The source variable.
+ */
+#define DBGCVAR_ASSIGN(a_pResult, a_pVar) \
+ do { \
+ *(a_pResult) = *(a_pVar); \
+ } while (0)
+
+
+/** Pointer to a command descriptor. */
+typedef struct DBGCCMD *PDBGCCMD;
+/** Pointer to a const command descriptor. */
+typedef const struct DBGCCMD *PCDBGCCMD;
+
+/** Pointer to a function descriptor. */
+typedef struct DBGCFUNC *PDBGCFUNC;
+/** Pointer to a const function descriptor. */
+typedef const struct DBGCFUNC *PCDBGCFUNC;
+
+/** Pointer to helper functions for commands. */
+typedef struct DBGCCMDHLP *PDBGCCMDHLP;
+
+
+/**
+ * Helper functions for commands.
+ */
+typedef struct DBGCCMDHLP
+{
+ /** Magic value (DBGCCMDHLP_MAGIC). */
+ uint32_t u32Magic;
+
+ /**
+ * Command helper for writing formatted text to the debug console.
+ *
+ * @returns VBox status.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pcb Where to store the number of bytes written.
+ * @param pszFormat The format string. This may use all IPRT extensions as
+ * well as the debugger ones.
+ * @param ... Arguments specified in the format string.
+ */
+ DECLCALLBACKMEMBER(int, pfnPrintf)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, ...);
+
+ /**
+ * Command helper for writing formatted text to the debug console.
+ *
+ * @returns VBox status.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pcb Where to store the number of bytes written.
+ * @param pszFormat The format string. This may use all IPRT extensions as
+ * well as the debugger ones.
+ * @param args Arguments specified in the format string.
+ */
+ DECLCALLBACKMEMBER(int, pfnPrintfV)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args);
+
+ /**
+ * Command helper for formatting a string with debugger format specifiers.
+ *
+ * @returns The number of bytes written.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param pszFormat The format string. This may use all IPRT extensions as
+ * well as the debugger ones.
+ * @param ... Arguments specified in the format string.
+ */
+ DECLCALLBACKMEMBER(size_t, pfnStrPrintf)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
+
+ /**
+ * Command helper for formatting a string with debugger format specifiers.
+ *
+ * @returns The number of bytes written.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param pszFormat The format string. This may use all IPRT extensions as
+ * well as the debugger ones.
+ * @param va Arguments specified in the format string.
+ */
+ DECLCALLBACKMEMBER(size_t, pfnStrPrintfV)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf,
+ const char *pszFormat, va_list va);
+
+ /**
+ * Command helper for formatting and error message for a VBox status code.
+ *
+ * @returns VBox status code appropriate to return from a command.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param rc The VBox status code.
+ * @param pszFormat Format string for additional messages. Can be NULL.
+ * @param ... Format arguments, optional.
+ */
+ DECLCALLBACKMEMBER(int, pfnVBoxError)(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...);
+
+ /**
+ * Command helper for formatting and error message for a VBox status code.
+ *
+ * @returns VBox status code appropriate to return from a command.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param rc The VBox status code.
+ * @param pcb Where to store the number of bytes written.
+ * @param pszFormat Format string for additional messages. Can be NULL.
+ * @param args Format arguments, optional.
+ */
+ DECLCALLBACKMEMBER(int, pfnVBoxErrorV)(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, va_list args);
+
+ /**
+ * Command helper for reading memory specified by a DBGC variable.
+ *
+ * @returns VBox status code appropriate to return from a command.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVM VM handle if GC or physical HC address.
+ * @param pvBuffer Where to store the read data.
+ * @param cbRead Number of bytes to read.
+ * @param pVarPointer DBGC variable specifying where to start reading.
+ * @param pcbRead Where to store the number of bytes actually read.
+ * This optional, but it's useful when read GC virtual memory where a
+ * page in the requested range might not be present.
+ * If not specified not-present failure or end of a HC physical page
+ * will cause failure.
+ */
+ DECLCALLBACKMEMBER(int, pfnMemRead)(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead);
+
+ /**
+ * Command helper for writing memory specified by a DBGC variable.
+ *
+ * @returns VBox status code appropriate to return from a command.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVM VM handle if GC or physical HC address.
+ * @param pvBuffer What to write.
+ * @param cbWrite Number of bytes to write.
+ * @param pVarPointer DBGC variable specifying where to start reading.
+ * @param pcbWritten Where to store the number of bytes written.
+ * This is optional. If NULL be aware that some of the buffer
+ * might have been written to the specified address.
+ */
+ DECLCALLBACKMEMBER(int, pfnMemWrite)(PDBGCCMDHLP pCmdHlp, PVM pVM, const void *pvBuffer, size_t cbWrite, PCDBGCVAR pVarPointer, size_t *pcbWritten);
+
+ /**
+ * Executes command an expression.
+ * (Hopefully the parser and functions are fully reentrant.)
+ *
+ * @returns VBox status code appropriate to return from a command.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pszExpr The expression. Format string with the format DBGC extensions.
+ * @param ... Format arguments.
+ */
+ DECLCALLBACKMEMBER(int, pfnExec)(PDBGCCMDHLP pCmdHlp, const char *pszExpr, ...);
+
+ /**
+ * Evaluates an expression.
+ * (Hopefully the parser and functions are fully reentrant.)
+ *
+ * @returns VBox status code appropriate to return from a command.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pResult Where to store the result.
+ * @param pszExpr The expression. Format string with the format DBGC extensions.
+ * @param va Format arguments.
+ */
+ DECLCALLBACKMEMBER(int, pfnEvalV)(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, va_list va);
+
+ /**
+ * Print an error and fail the current command.
+ *
+ * @returns VBox status code to pass upwards.
+ *
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pCmd The failing command.
+ * @param pszFormat The error message format string.
+ * @param va Format arguments.
+ */
+ DECLCALLBACKMEMBER(int, pfnFailV)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, va_list va);
+
+ /**
+ * Print an error and fail the current command.
+ *
+ * @returns VBox status code to pass upwards.
+ *
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pCmd The failing command.
+ * @param rc The status code indicating the failure. This will
+ * be appended to the message after a colon (': ').
+ * @param pszFormat The error message format string.
+ * @param va Format arguments.
+ *
+ * @see DBGCCmdHlpFailRc
+ */
+ DECLCALLBACKMEMBER(int, pfnFailRcV)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, va_list va);
+
+ /**
+ * Parser error.
+ *
+ * @returns VBox status code to pass upwards.
+ *
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pCmd The failing command, can be NULL but shouldn't.
+ * @param iArg The offending argument, -1 when lazy.
+ * @param pszExpr The expression.
+ * @param iLine The line number.
+ */
+ DECLCALLBACKMEMBER(int, pfnParserError)(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int iArg, const char *pszExpr, unsigned iLine);
+
+ /**
+ * Converts a DBGC variable to a DBGF address structure.
+ *
+ * @returns VBox status code.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVar The variable to convert.
+ * @param pAddress The target address.
+ */
+ DECLCALLBACKMEMBER(int, pfnVarToDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress);
+
+ /**
+ * Converts a DBGF address structure to a DBGC variable.
+ *
+ * @returns VBox status code.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pAddress The source address.
+ * @param pResult The result variable.
+ */
+ DECLCALLBACKMEMBER(int, pfnVarFromDbgfAddr)(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult);
+
+ /**
+ * Converts a DBGC variable to a 64-bit number.
+ *
+ * @returns VBox status code.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVar The variable to convert.
+ * @param pu64Number Where to store the number.
+ */
+ DECLCALLBACKMEMBER(int, pfnVarToNumber)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number);
+
+ /**
+ * Converts a DBGC variable to a boolean.
+ *
+ * @returns VBox status code.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVar The variable to convert.
+ * @param pf Where to store the boolean.
+ */
+ DECLCALLBACKMEMBER(int, pfnVarToBool)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf);
+
+ /**
+ * Get the range of a variable in bytes, resolving symbols if necessary.
+ *
+ * @returns VBox status code.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVar The variable to convert.
+ * @param cbElement Conversion factor for element ranges.
+ * @param cbDefault The default range.
+ * @param pcbRange The length of the range.
+ */
+ DECLCALLBACKMEMBER(int, pfnVarGetRange)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault,
+ uint64_t *pcbRange);
+
+ /**
+ * Converts a variable to one with the specified type.
+ *
+ * This preserves the range.
+ *
+ * @returns VBox status code.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVar The variable to convert.
+ * @param enmToType The target type.
+ * @param fConvSyms If @c true, then attempt to resolve symbols.
+ * @param pResult The output variable. Can be the same as @a pVar.
+ */
+ DECLCALLBACKMEMBER(int, pfnVarConvert)(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms,
+ PDBGCVAR pResult);
+
+ /**
+ * Gets a DBGF output helper that directs the output to the debugger
+ * console.
+ *
+ * @returns Pointer to the helper structure.
+ * @param pCmdHlp Pointer to the command callback structure.
+ */
+ DECLCALLBACKMEMBER(PCDBGFINFOHLP, pfnGetDbgfOutputHlp)(PDBGCCMDHLP pCmdHlp);
+
+ /**
+ * Gets the ID currently selected CPU.
+ *
+ * @returns Current CPU ID.
+ * @param pCmdHlp Pointer to the command callback structure.
+ */
+ DECLCALLBACKMEMBER(VMCPUID, pfnGetCurrentCpu)(PDBGCCMDHLP pCmdHlp);
+
+ /**
+ * Gets the mode the currently selected CPU is running in, in the current
+ * context.
+ *
+ * @returns Current CPU mode.
+ * @param pCmdHlp Pointer to the command callback structure.
+ */
+ DECLCALLBACKMEMBER(CPUMMODE, pfnGetCpuMode)(PDBGCCMDHLP pCmdHlp);
+
+ /** End marker (DBGCCMDHLP_MAGIC). */
+ uint32_t u32EndMarker;
+} DBGCCMDHLP;
+
+/** Magic value for DBGCCMDHLP::u32Magic. (Fyodor Mikhaylovich Dostoyevsky) */
+#define DBGCCMDHLP_MAGIC UINT32_C(18211111)
+
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc DBGCCMDHLP::pfnPrintf
+ */
+DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...)
+{
+ va_list va;
+ int rc;
+
+ va_start(va, pszFormat);
+ rc = pCmdHlp->pfnPrintfV(pCmdHlp, NULL, pszFormat, va);
+ va_end(va);
+
+ return rc;
+}
+
+
+/**
+ * @copydoc DBGCCMDHLP::pfnStrPrintf
+ */
+DECLINLINE(size_t) DBGCCmdHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...)
+{
+ va_list va;
+ size_t cch;
+
+ va_start(va, pszFormat);
+ cch = pCmdHlp->pfnStrPrintfV(pCmdHlp, pszBuf, cbBuf, pszFormat, va);
+ va_end(va);
+
+ return cch;
+}
+
+/**
+ * @copydoc FNDBGCHLPVBOXERROR
+ */
+DECLINLINE(int) DBGCCmdHlpVBoxError(PDBGCCMDHLP pCmdHlp, int rc, const char *pszFormat, ...)
+{
+ va_list va;
+
+ va_start(va, pszFormat);
+ rc = pCmdHlp->pfnVBoxErrorV(pCmdHlp, rc, pszFormat, va);
+ va_end(va);
+
+ return rc;
+}
+
+/**
+ * @copydoc FNDBGCHLPMEMREAD
+ */
+DECLINLINE(int) DBGCCmdHlpMemRead(PDBGCCMDHLP pCmdHlp, PVM pVM, void *pvBuffer, size_t cbRead, PCDBGCVAR pVarPointer, size_t *pcbRead)
+{
+ return pCmdHlp->pfnMemRead(pCmdHlp, pVM, pvBuffer, cbRead, pVarPointer, pcbRead);
+}
+
+/**
+ * Evaluates an expression.
+ * (Hopefully the parser and functions are fully reentrant.)
+ *
+ * @returns VBox status code appropriate to return from a command.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pResult Where to store the result.
+ * @param pszExpr The expression. Format string with the format DBGC extensions.
+ * @param ... Format arguments.
+ */
+DECLINLINE(int) DBGCCmdHlpEval(PDBGCCMDHLP pCmdHlp, PDBGCVAR pResult, const char *pszExpr, ...)
+{
+ va_list va;
+ int rc;
+
+ va_start(va, pszExpr);
+ rc = pCmdHlp->pfnEvalV(pCmdHlp, pResult, pszExpr, va);
+ va_end(va);
+
+ return rc;
+}
+
+/**
+ * Print an error and fail the current command.
+ *
+ * @returns VBox status code to pass upwards.
+ *
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pCmd The failing command.
+ * @param pszFormat The error message format string.
+ * @param ... Format arguments.
+ */
+DECLINLINE(int) DBGCCmdHlpFail(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, const char *pszFormat, ...)
+{
+ va_list va;
+ int rc;
+
+ va_start(va, pszFormat);
+ rc = pCmdHlp->pfnFailV(pCmdHlp, pCmd, pszFormat, va);
+ va_end(va);
+
+ return rc;
+}
+
+/**
+ * Print an error and fail the current command.
+ *
+ * Usage example:
+ * @code
+ int rc = VMMR3Something(pVM);
+ if (RT_FAILURE(rc))
+ return DBGCCmdHlpFailRc(pCmdHlp, pCmd, rc, "VMMR3Something");
+ return VINF_SUCCESS;
+ * @endcode
+ *
+ * @returns VBox status code to pass upwards.
+ *
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pCmd The failing command.
+ * @param rc The status code indicating the failure.
+ * @param pszFormat The error message format string.
+ * @param ... Format arguments.
+ */
+DECLINLINE(int) DBGCCmdHlpFailRc(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int rc, const char *pszFormat, ...)
+{
+ va_list va;
+
+ va_start(va, pszFormat);
+ rc = pCmdHlp->pfnFailRcV(pCmdHlp, pCmd, rc, pszFormat, va);
+ va_end(va);
+
+ return rc;
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnParserError
+ */
+DECLINLINE(int) DBGCCmdHlpParserError(PDBGCCMDHLP pCmdHlp, PCDBGCCMD pCmd, int iArg, const char *pszExpr, unsigned iLine)
+{
+ return pCmdHlp->pfnParserError(pCmdHlp, pCmd, iArg, pszExpr, iLine);
+}
+
+/** Assert+return like macro for checking parser sanity.
+ * Returns with failure if the precodition is not met. */
+#define DBGC_CMDHLP_ASSERT_PARSER_RET(pCmdHlp, pCmd, iArg, expr) \
+ do { \
+ if (!(expr)) \
+ return DBGCCmdHlpParserError(pCmdHlp, pCmd, iArg, #expr, __LINE__); \
+ } while (0)
+
+/** Assert+return like macro that the VM handle is present.
+ * Returns with failure if the VM handle is NIL. */
+#define DBGC_CMDHLP_REQ_VM_RET(pCmdHlp, pCmd, pVM) \
+ do { \
+ if (!(pVM)) \
+ return DBGCCmdHlpFail(pCmdHlp, pCmd, "No VM selected"); \
+ } while (0)
+
+/**
+ * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
+ */
+DECLINLINE(int) DBGCCmdHlpVarToDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PDBGFADDRESS pAddress)
+{
+ return pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, pAddress);
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnVarToDbgfAddr
+ */
+DECLINLINE(int) DBGCCmdHlpVarFromDbgfAddr(PDBGCCMDHLP pCmdHlp, PCDBGFADDRESS pAddress, PDBGCVAR pResult)
+{
+ return pCmdHlp->pfnVarFromDbgfAddr(pCmdHlp, pAddress, pResult);
+}
+
+/**
+ * Converts an variable to a flat address.
+ *
+ * @returns VBox status code.
+ * @param pCmdHlp Pointer to the command callback structure.
+ * @param pVar The variable to convert.
+ * @param pFlatPtr Where to store the flat address.
+ */
+DECLINLINE(int) DBGCCmdHlpVarToFlatAddr(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, PRTGCPTR pFlatPtr)
+{
+ DBGFADDRESS Addr;
+ int rc = pCmdHlp->pfnVarToDbgfAddr(pCmdHlp, pVar, &Addr);
+ if (RT_SUCCESS(rc))
+ *pFlatPtr = Addr.FlatPtr;
+ return rc;
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnVarToNumber
+ */
+DECLINLINE(int) DBGCCmdHlpVarToNumber(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t *pu64Number)
+{
+ return pCmdHlp->pfnVarToNumber(pCmdHlp, pVar, pu64Number);
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnVarToBool
+ */
+DECLINLINE(int) DBGCCmdHlpVarToBool(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, bool *pf)
+{
+ return pCmdHlp->pfnVarToBool(pCmdHlp, pVar, pf);
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnVarGetRange
+ */
+DECLINLINE(int) DBGCCmdHlpVarGetRange(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, uint64_t cbElement, uint64_t cbDefault, uint64_t *pcbRange)
+{
+ return pCmdHlp->pfnVarGetRange(pCmdHlp, pVar, cbElement, cbDefault, pcbRange);
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnVarConvert
+ */
+DECLINLINE(int) DBGCCmdHlpConvert(PDBGCCMDHLP pCmdHlp, PCDBGCVAR pVar, DBGCVARTYPE enmToType, bool fConvSyms, PDBGCVAR pResult)
+{
+ return pCmdHlp->pfnVarConvert(pCmdHlp, pVar, enmToType, fConvSyms, pResult);
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnGetDbgfOutputHlp
+ */
+DECLINLINE(PCDBGFINFOHLP) DBGCCmdHlpGetDbgfOutputHlp(PDBGCCMDHLP pCmdHlp)
+{
+ return pCmdHlp->pfnGetDbgfOutputHlp(pCmdHlp);
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnGetCurrentCpu
+ */
+DECLINLINE(VMCPUID) DBGCCmdHlpGetCurrentCpu(PDBGCCMDHLP pCmdHlp)
+{
+ return pCmdHlp->pfnGetCurrentCpu(pCmdHlp);
+}
+
+/**
+ * @copydoc DBGCCMDHLP::pfnGetCpuMode
+ */
+DECLINLINE(CPUMMODE) DBGCCmdHlpGetCpuMode(PDBGCCMDHLP pCmdHlp)
+{
+ return pCmdHlp->pfnGetCpuMode(pCmdHlp);
+}
+
+#endif /* IN_RING3 */
+
+
+
+/**
+ * Command handler.
+ *
+ * The console will call the handler for a command once it's finished
+ * parsing the user input. The command handler function is responsible
+ * for executing the command itself.
+ *
+ * @returns VBox status.
+ * @param pCmd Pointer to the command descriptor (as registered).
+ * @param pCmdHlp Pointer to command helper functions.
+ * @param pVM Pointer to the current VM (if any).
+ * @param paArgs Pointer to (readonly) array of arguments.
+ * @param cArgs Number of arguments in the array.
+ */
+typedef DECLCALLBACK(int) FNDBGCCMD(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
+/** Pointer to a FNDBGCCMD() function. */
+typedef FNDBGCCMD *PFNDBGCCMD;
+
+/**
+ * DBGC command descriptor.
+ */
+typedef struct DBGCCMD
+{
+ /** Command string. */
+ const char *pszCmd;
+ /** Minimum number of arguments. */
+ unsigned cArgsMin;
+ /** Max number of arguments. */
+ unsigned cArgsMax;
+ /** Argument descriptors (array). */
+ PCDBGCVARDESC paArgDescs;
+ /** Number of argument descriptors. */
+ unsigned cArgDescs;
+ /** flags. (reserved for now) */
+ unsigned fFlags;
+ /** Handler function. */
+ PFNDBGCCMD pfnHandler;
+ /** Command syntax. */
+ const char *pszSyntax;
+ /** Command description. */
+ const char *pszDescription;
+} DBGCCMD;
+
+/** DBGCCMD Flags.
+ * @{
+ */
+/** @} */
+
+
+/**
+ * Function handler.
+ *
+ * The console will call the handler for a command once it's finished
+ * parsing the user input. The command handler function is responsible
+ * for executing the command itself.
+ *
+ * @returns VBox status.
+ * @param pCmd Pointer to the command descriptor (as registered).
+ * @param pCmdHlp Pointer to command helper functions.
+ * @param pVM Pointer to the current VM (if any).
+ * @param paArgs Pointer to (readonly) array of arguments.
+ * @param cArgs Number of arguments in the array.
+ * @param pResult Where to return the result.
+ */
+typedef DECLCALLBACK(int) FNDBGCFUNC(PCDBGCFUNC pFunc, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs,
+ PDBGCVAR pResult);
+/** Pointer to a FNDBGCFUNC() function. */
+typedef FNDBGCFUNC *PFNDBGCFUNC;
+
+/**
+ * DBGC function descriptor.
+ */
+typedef struct DBGCFUNC
+{
+ /** Command string. */
+ const char *pszFuncNm;
+ /** Minimum number of arguments. */
+ unsigned cArgsMin;
+ /** Max number of arguments. */
+ unsigned cArgsMax;
+ /** Argument descriptors (array). */
+ PCDBGCVARDESC paArgDescs;
+ /** Number of argument descriptors. */
+ unsigned cArgDescs;
+ /** flags. (reserved for now) */
+ unsigned fFlags;
+ /** Handler function. */
+ PFNDBGCFUNC pfnHandler;
+ /** Function syntax. */
+ const char *pszSyntax;
+ /** Function description. */
+ const char *pszDescription;
+} DBGCFUNC;
+
+
+
+/** Pointer to a DBGC backend. */
+typedef struct DBGCBACK *PDBGCBACK;
+
+/**
+ * Checks if there is input.
+ *
+ * @returns true if there is input ready.
+ * @returns false if there not input ready.
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param cMillies Number of milliseconds to wait on input data.
+ */
+typedef DECLCALLBACK(bool) FNDBGCBACKINPUT(PDBGCBACK pBack, uint32_t cMillies);
+/** Pointer to a FNDBGCBACKINPUT() callback. */
+typedef FNDBGCBACKINPUT *PFNDBGCBACKINPUT;
+
+/**
+ * Read input.
+ *
+ * @returns VBox status code.
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbBuf Maximum nymber of bytes to read.
+ * @param pcbRead Where to store the number of bytes actually read.
+ * If NULL the entire buffer must be filled for a
+ * successful return.
+ */
+typedef DECLCALLBACK(int) FNDBGCBACKREAD(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
+/** Pointer to a FNDBGCBACKREAD() callback. */
+typedef FNDBGCBACKREAD *PFNDBGCBACKREAD;
+
+/**
+ * Write (output).
+ *
+ * @returns VBox status code.
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param pvBuf What to write.
+ * @param cbBuf Number of bytes to write.
+ * @param pcbWritten Where to store the number of bytes actually written.
+ * If NULL the entire buffer must be successfully written.
+ */
+typedef DECLCALLBACK(int) FNDBGCBACKWRITE(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
+/** Pointer to a FNDBGCBACKWRITE() callback. */
+typedef FNDBGCBACKWRITE *PFNDBGCBACKWRITE;
+
+/**
+ * Ready / busy notification.
+ *
+ * @param pBack Pointer to the backend structure supplied by
+ * the backend. The backend can use this to find
+ * it's instance data.
+ * @param fReady Whether it's ready (true) or busy (false).
+ */
+typedef DECLCALLBACK(void) FNDBGCBACKSETREADY(PDBGCBACK pBack, bool fReady);
+/** Pointer to a FNDBGCBACKSETREADY() callback. */
+typedef FNDBGCBACKSETREADY *PFNDBGCBACKSETREADY;
+
+
+/**
+ * The communication backend provides the console with a number of callbacks
+ * which can be used
+ */
+typedef struct DBGCBACK
+{
+ /** Check for input. */
+ PFNDBGCBACKINPUT pfnInput;
+ /** Read input. */
+ PFNDBGCBACKREAD pfnRead;
+ /** Write output. */
+ PFNDBGCBACKWRITE pfnWrite;
+ /** Ready / busy notification. */
+ PFNDBGCBACKSETREADY pfnSetReady;
+} DBGCBACK;
+
+
+/**
+ * Make a console instance.
+ *
+ * This will not return until either an 'exit' command is issued or a error code
+ * indicating connection loss is encountered.
+ *
+ * @returns VINF_SUCCESS if console termination caused by the 'exit' command.
+ * @returns The VBox status code causing the console termination.
+ *
+ * @param pVM VM Handle.
+ * @param pBack Pointer to the backend structure. This must contain
+ * a full set of function pointers to service the console.
+ * @param fFlags Reserved, must be zero.
+ * @remark A forced termination of the console is easiest done by forcing the
+ * callbacks to return fatal failures.
+ */
+DBGDECL(int) DBGCCreate(PVM pVM, PDBGCBACK pBack, unsigned fFlags);
+
+
+/**
+ * Register one or more external commands.
+ *
+ * @returns VBox status.
+ * @param paCommands Pointer to an array of command descriptors.
+ * The commands must be unique. It's not possible
+ * to register the same commands more than once.
+ * @param cCommands Number of commands.
+ */
+DBGDECL(int) DBGCRegisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
+
+
+/**
+ * Deregister one or more external commands previously registered by
+ * DBGCRegisterCommands().
+ *
+ * @returns VBox status.
+ * @param paCommands Pointer to an array of command descriptors
+ * as given to DBGCRegisterCommands().
+ * @param cCommands Number of commands.
+ */
+DBGDECL(int) DBGCDeregisterCommands(PCDBGCCMD paCommands, unsigned cCommands);
+
+
+/**
+ * Spawns a new thread with a TCP based debugging console service.
+ *
+ * @returns VBox status.
+ * @param pVM VM handle.
+ * @param ppvData Where to store the pointer to instance data.
+ */
+DBGDECL(int) DBGCTcpCreate(PVM pVM, void **ppvUser);
+
+/**
+ * Terminates any running TCP base debugger console service.
+ *
+ * @returns VBox status.
+ * @param pVM VM handle.
+ * @param pvData Instance data set by DBGCTcpCreate().
+ */
+DBGDECL(int) DBGCTcpTerminate(PVM pVM, void *pvData);
+
+
+/** @defgroup grp_dbgc_plug_in The DBGC Plug-in Interface
+ * @{
+ */
+
+/** The plug-in module name prefix. */
+#define DBGC_PLUG_IN_PREFIX "DBGCPlugIn"
+
+/** The name of the plug-in entry point (FNDBGCPLUGIN) */
+#define DBGC_PLUG_IN_ENTRYPOINT "DBGCPlugInEntry"
+
+/**
+ * DBGC plug-in operations.
+ */
+typedef enum DBGCPLUGINOP
+{
+ /** The usual invalid first value. */
+ DBGCPLUGINOP_INVALID,
+ /** Initialize the plug-in, register all the stuff.
+ * The plug-in will be unloaded on failure.
+ * uArg: The VirtualBox version (major+minor). */
+ DBGCPLUGINOP_INIT,
+ /** Terminate the plug-ing, deregister all the stuff.
+ * The plug-in will be unloaded after this call regardless of the return
+ * code. */
+ DBGCPLUGINOP_TERM,
+ /** The usual 32-bit hack. */
+ DBGCPLUGINOP_32BIT_HACK = 0x7fffffff
+} DBGCPLUGINOP;
+
+/**
+ * DBGC plug-in main entry point.
+ *
+ * @returns VBox status code.
+ *
+ * @param enmOperation The operation.
+ * @param pVM The VM handle. This may be NULL.
+ * @param uArg Extra argument.
+ */
+typedef DECLCALLBACK(int) FNDBGCPLUGIN(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
+/** Pointer to a FNDBGCPLUGIN. */
+typedef FNDBGCPLUGIN *PFNDBGCPLUGIN;
+
+/** @copydoc FNDBGCPLUGIN */
+DECLEXPORT(int) DBGCPlugInEntry(DBGCPLUGINOP enmOperation, PVM pVM, uintptr_t uArg);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/dbggui.h b/include/VBox/dbggui.h
new file mode 100644
index 00000000..59a48dc5
--- /dev/null
+++ b/include/VBox/dbggui.h
@@ -0,0 +1,173 @@
+/** @file
+ * DBGGUI - The VirtualBox Debugger GUI. (VBoxDbg)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_dbggui_h
+#define ___VBox_dbggui_h
+
+#include <VBox/types.h>
+#if defined(RT_OS_WINDOWS)
+# include <VirtualBox.h>
+#else
+# include <VirtualBox_XPCOM.h>
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_dbggui VirtualBox Debugger GUI
+ * @{
+ */
+
+/** Pointer to the debugger GUI instance structure. */
+typedef struct DBGGUI *PDBGGUI;
+
+/** Virtual method table for the debugger GUI. */
+typedef struct DBGGUIVT
+{
+ /** The version. (DBGGUIVT_VERSION) */
+ uint32_t u32Version;
+ /** @copydoc DBGGuiDestroy */
+ DECLCALLBACKMEMBER(int, pfnDestroy)(PDBGGUI pGui);
+ /** @copydoc DBGGuiAdjustRelativePos */
+ DECLCALLBACKMEMBER(void, pfnAdjustRelativePos)(PDBGGUI pGui, int x, int y, unsigned cx, unsigned cy);
+ /** @copydoc DBGGuiShowStatistics */
+ DECLCALLBACKMEMBER(int, pfnShowStatistics)(PDBGGUI pGui);
+ /** @copydoc DBGGuiShowCommandLine */
+ DECLCALLBACKMEMBER(int, pfnShowCommandLine)(PDBGGUI pGui);
+ /** @copydoc DBGGuiSetParent */
+ DECLCALLBACKMEMBER(void, pfnSetParent)(PDBGGUI pGui, void *pvParent);
+ /** @copydoc DBGGuiSetMenu */
+ DECLCALLBACKMEMBER(void, pfnSetMenu)(PDBGGUI pGui, void *pvMenu);
+ /** The end version. (DBGGUIVT_VERSION) */
+ uint32_t u32EndVersion;
+} DBGGUIVT;
+/** Pointer to the virtual method table for the debugger GUI. */
+typedef DBGGUIVT const *PCDBGGUIVT;
+/** The u32Version value.
+ * The first byte is the minor version, the 2nd byte is major version number.
+ * The high 16-bit word is a magic. */
+#define DBGGUIVT_VERSION UINT32_C(0xbead0100)
+/** Macro for determining whether two versions are compatible or not.
+ * @returns boolean result.
+ * @param uVer1 The first version number.
+ * @param uVer2 The second version number.
+ */
+#define DBGGUIVT_ARE_VERSIONS_COMPATIBLE(uVer1, uVer2) \
+ ( ((uVer1) & UINT32_C(0xffffff00)) == ((uVer2) & UINT32_C(0xffffff00)) )
+
+
+/**
+ * Creates the debugger GUI.
+ *
+ * @returns VBox status code.
+ * @param pSession The VirtualBox session.
+ * @param ppGui Where to store the pointer to the debugger instance.
+ * @param ppGuiVT Where to store the virtual method table pointer.
+ * Optional.
+ */
+DBGDECL(int) DBGGuiCreate(ISession *pSession, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT);
+/** @copydoc DBGGuiCreate. */
+typedef DECLCALLBACK(int) FNDBGGUICREATE(ISession *pSession, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT);
+/** Pointer to DBGGuiCreate. */
+typedef FNDBGGUICREATE *PFNDBGGUICREATE;
+
+/**
+ * Creates the debugger GUI given a VM handle.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param ppGui Where to store the pointer to the debugger instance.
+ * @param ppGuiVT Where to store the virtual method table pointer.
+ * Optional.
+ */
+DBGDECL(int) DBGGuiCreateForVM(PVM pVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT);
+/** @copydoc DBGGuiCreateForVM. */
+typedef DECLCALLBACK(int) FNDBGGUICREATEFORVM(PVM pVM, PDBGGUI *ppGui, PCDBGGUIVT *ppGuiVT);
+/** Pointer to DBGGuiCreateForVM. */
+typedef FNDBGGUICREATEFORVM *PFNDBGGUICREATEFORVM;
+
+/**
+ * Destroys the debugger GUI.
+ *
+ * @returns VBox status code.
+ * @param pGui The instance returned by DBGGuiCreate().
+ */
+DBGDECL(int) DBGGuiDestroy(PDBGGUI pGui);
+
+/**
+ * Notifies the debugger GUI that the console window (or whatever) has changed
+ * size or position.
+ *
+ * @param pGui The instance returned by DBGGuiCreate().
+ * @param x The x-coordinate of the window the debugger is relative to.
+ * @param y The y-coordinate of the window the debugger is relative to.
+ * @param cx The width of the window the debugger is relative to.
+ * @param cy The height of the window the debugger is relative to.
+ */
+DBGDECL(void) DBGGuiAdjustRelativePos(PDBGGUI pGui, int x, int y, unsigned cx, unsigned cy);
+
+/**
+ * Shows the default statistics window.
+ *
+ * @returns VBox status code.
+ * @param pGui The instance returned by DBGGuiCreate().
+ */
+DBGDECL(int) DBGGuiShowStatistics(PDBGGUI pGui);
+
+/**
+ * Shows the default command line window.
+ *
+ * @returns VBox status code.
+ * @param pGui The instance returned by DBGGuiCreate().
+ */
+DBGDECL(int) DBGGuiShowCommandLine(PDBGGUI pGui);
+
+/**
+ * Sets the parent windows.
+ *
+ * @param pGui The instance returned by DBGGuiCreate().
+ * @param pvParent Pointer to a QWidget object.
+ *
+ * @remarks This will no affect any existing windows, so call it right after
+ * creating the thing.
+ */
+DBGDECL(void) DBGGuiSetParent(PDBGGUI pGui, void *pvParent);
+
+/**
+ * Sets the debug menu object.
+ *
+ * @param pGui The instance returned by DBGGuiCreate().
+ * @param pvMenu Pointer to a QMenu object.
+ *
+ * @remarks Call right after creation or risk losing menu item.
+ */
+DBGDECL(void) DBGGuiSetMenu(PDBGGUI pGui, void *pvMenu);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/dbus-calls.h b/include/VBox/dbus-calls.h
new file mode 100644
index 00000000..16d2be3d
--- /dev/null
+++ b/include/VBox/dbus-calls.h
@@ -0,0 +1,146 @@
+/** @file
+ * Stubs for dynamically loading libdbus-1 and the symbols which are needed by
+ * VirtualBox.
+ */
+
+/*
+ * Copyright (C) 2008 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.
+ */
+
+/** The file name of the DBus library */
+#define RT_RUNTIME_LOADER_LIB_NAME "libdbus-1.so.3"
+
+/** The name of the loader function */
+#define RT_RUNTIME_LOADER_FUNCTION RTDBusLoadLib
+
+/** The following are the symbols which we need from the DBus library. */
+#define RT_RUNTIME_LOADER_INSERT_SYMBOLS \
+ RT_PROXY_STUB(dbus_error_init, void, (DBusError *error), \
+ (error)) \
+ RT_PROXY_STUB(dbus_error_is_set, dbus_bool_t, (const DBusError *error), \
+ (error)) \
+ RT_PROXY_STUB(dbus_bus_get, DBusConnection *, \
+ (DBusBusType type, DBusError *error), (type, error)) \
+ RT_PROXY_STUB(dbus_bus_get_private, DBusConnection *, \
+ (DBusBusType type, DBusError *error), (type, error)) \
+ RT_PROXY_STUB(dbus_error_free, void, (DBusError *error), \
+ (error)) \
+ RT_PROXY_STUB(dbus_connection_unref, void, (DBusConnection *connection), \
+ (connection)) \
+ RT_PROXY_STUB(dbus_connection_close, void, (DBusConnection *connection), \
+ (connection)) \
+ RT_PROXY_STUB(dbus_connection_send, dbus_bool_t, \
+ (DBusConnection *connection, DBusMessage *message, dbus_uint32_t *serial), \
+ (connection, message, serial)) \
+ RT_PROXY_STUB(dbus_connection_flush, void, (DBusConnection *connection), \
+ (connection)) \
+ RT_PROXY_STUB(dbus_connection_set_exit_on_disconnect, void, \
+ (DBusConnection *connection, dbus_bool_t boolean), \
+ (connection, boolean)) \
+ RT_PROXY_STUB(dbus_bus_name_has_owner, dbus_bool_t, \
+ (DBusConnection *connection, const char *string, DBusError *error), \
+ (connection, string, error)) \
+ RT_PROXY_STUB(dbus_bus_add_match, void, \
+ (DBusConnection *connection, const char *string, \
+ DBusError *error), \
+ (connection, string, error)) \
+ RT_PROXY_STUB(dbus_bus_remove_match, void, \
+ (DBusConnection *connection, const char *string, \
+ DBusError *error), \
+ (connection, string, error)) \
+ RT_PROXY_STUB(dbus_message_append_args_valist, dbus_bool_t, \
+ (DBusMessage *message, int first_arg_type, va_list var_args), \
+ (message, first_arg_type, var_args)) \
+ RT_PROXY_STUB(dbus_message_iter_open_container, dbus_bool_t, \
+ (DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub), \
+ (iter, type, contained_signature, sub)) \
+ RT_PROXY_STUB(dbus_message_iter_close_container, dbus_bool_t, \
+ (DBusMessageIter *iter, DBusMessageIter *sub), \
+ (iter, sub)) \
+ RT_PROXY_STUB(dbus_message_iter_append_fixed_array, dbus_bool_t, \
+ (DBusMessageIter *iter, int element_type, const void *value, int n_elements), \
+ (iter, element_type, value, n_elements)) \
+ RT_PROXY_STUB(dbus_message_unref, void, (DBusMessage *message), \
+ (message)) \
+ RT_PROXY_STUB(dbus_message_new_method_call, DBusMessage*, \
+ (const char *string1, const char *string2, const char *string3, \
+ const char *string4), \
+ (string1, string2, string3, string4)) \
+ RT_PROXY_STUB(dbus_message_iter_init_append, void, \
+ (DBusMessage *message, DBusMessageIter *iter), \
+ (message, iter)) \
+ RT_PROXY_STUB(dbus_message_iter_append_basic, dbus_bool_t, \
+ (DBusMessageIter *iter, int val, const void *string), \
+ (iter, val, string)) \
+ RT_PROXY_STUB(dbus_connection_send_with_reply_and_block, DBusMessage *, \
+ (DBusConnection *connection, DBusMessage *message, int val, \
+ DBusError *error), \
+ (connection, message, val, error)) \
+ RT_PROXY_STUB(dbus_message_iter_init, dbus_bool_t, \
+ (DBusMessage *message, DBusMessageIter *iter), \
+ (message, iter)) \
+ RT_PROXY_STUB(dbus_message_iter_get_arg_type, int, (DBusMessageIter *iter), \
+ (iter)) \
+ RT_PROXY_STUB(dbus_message_iter_get_element_type, int, \
+ (DBusMessageIter *iter), (iter)) \
+ RT_PROXY_STUB(dbus_message_iter_recurse, void, \
+ (DBusMessageIter *iter1, DBusMessageIter *iter2), \
+ (iter1, iter2)) \
+ RT_PROXY_STUB(dbus_message_iter_get_basic, void, \
+ (DBusMessageIter *iter, void *pvoid), (iter, pvoid)) \
+ RT_PROXY_STUB(dbus_message_iter_next, dbus_bool_t, (DBusMessageIter *iter), \
+ (iter)) \
+ RT_PROXY_STUB(dbus_connection_add_filter, dbus_bool_t, \
+ (DBusConnection *connection, \
+ DBusHandleMessageFunction function1, void *pvoid, \
+ DBusFreeFunction function2), \
+ (connection, function1, pvoid, function2)) \
+ RT_PROXY_STUB(dbus_connection_remove_filter, void, \
+ (DBusConnection *connection, \
+ DBusHandleMessageFunction function, void *pvoid), \
+ (connection, function, pvoid)) \
+ RT_PROXY_STUB(dbus_connection_read_write_dispatch, dbus_bool_t, \
+ (DBusConnection *connection, int val), (connection, val)) \
+ RT_PROXY_STUB(dbus_message_is_signal, dbus_bool_t, \
+ (DBusMessage *message, const char *string1, \
+ const char *string2), \
+ (message, string1, string2)) \
+ RT_PROXY_STUB(dbus_connection_pop_message, DBusMessage *, \
+ (DBusConnection *connection), (connection))
+
+#ifdef VBOX_DBUS_GENERATE_HEADER
+# define RT_RUNTIME_LOADER_GENERATE_HEADER
+# define RT_RUNTIME_LOADER_GENERATE_DECLS
+# include <iprt/runtime-loader.h>
+# undef RT_RUNTIME_LOADER_GENERATE_HEADER
+# undef RT_RUNTIME_LOADER_GENERATE_DECLS
+
+#elif defined(VBOX_DBUS_GENERATE_BODY)
+# define RT_RUNTIME_LOADER_GENERATE_BODY_STUBS
+# include <iprt/runtime-loader.h>
+# undef RT_RUNTIME_LOADER_GENERATE_BODY_STUBS
+
+#else
+# error This file should only be included to generate stubs for loading the DBus library at runtime
+#endif
+
+#undef RT_RUNTIME_LOADER_LIB_NAME
+#undef RT_RUNTIME_LOADER_INSERT_SYMBOLS
+
diff --git a/include/VBox/dbus.h b/include/VBox/dbus.h
new file mode 100644
index 00000000..316628f4
--- /dev/null
+++ b/include/VBox/dbus.h
@@ -0,0 +1,116 @@
+/** @file
+ * Module to dynamically load libdbus and load all symbols which are needed by
+ * VirtualBox.
+ */
+
+/*
+ * Copyright (C) 2008 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 ___VBox_dbus_h
+#define ___VBox_dbus_h
+
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+#ifndef __cplusplus
+# error "This header requires C++ to avoid name clashes."
+#endif
+
+/** Types and defines from the dbus header files which we need. These are
+ * taken more or less verbatim from the DBus public interface header files. */
+struct DBusError
+{
+ const char *name;
+ const char *message;
+ unsigned int dummy1 : 1;
+ unsigned int dummy2 : 1;
+ unsigned int dummy3 : 1;
+ unsigned int dummy4 : 1;
+ unsigned int dummy5 : 1;
+ void *padding1;
+};
+typedef struct DBusError DBusError;
+
+struct DBusConnection;
+typedef struct DBusConnection DBusConnection;
+
+typedef uint32_t dbus_bool_t;
+typedef uint32_t dbus_uint32_t;
+typedef enum { DBUS_BUS_SESSON, DBUS_BUS_SYSTEM, DBUS_BUS_STARTER } DBusBusType;
+
+struct DBusMessage;
+typedef struct DBusMessage DBusMessage;
+
+struct DBusMessageIter
+{
+ void *dummy1;
+ void *dummy2;
+ dbus_uint32_t dummy3;
+ int dummy4;
+ int dummy5;
+ int dummy6;
+ int dummy7;
+ int dummy8;
+ int dummy9;
+ int dummy10;
+ int dummy11;
+ int pad1;
+ int pad2;
+ void *pad3;
+};
+typedef struct DBusMessageIter DBusMessageIter;
+
+#define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory"
+
+/* Primitive types */
+#define DBUS_TYPE_INVALID ((int) '\0')
+#define DBUS_TYPE_INT32 ((int) 'i')
+#define DBUS_TYPE_UINT32 ((int) 'u')
+#define DBUS_TYPE_STRING ((int) 's')
+#define DBUS_TYPE_STRING_AS_STRING "s"
+
+/* Compound types */
+#define DBUS_TYPE_ARRAY ((int) 'a')
+#define DBUS_TYPE_ARRAY_AS_STRING "a"
+#define DBUS_TYPE_DICT_ENTRY ((int) 'e')
+#define DBUS_TYPE_DICT_ENTRY_AS_STRING "e"
+
+typedef enum
+{
+ DBUS_HANDLER_RESULT_HANDLED,
+ DBUS_HANDLER_RESULT_NOT_YET_HANDLED,
+ DBUS_HANDLER_RESULT_NEED_MEMORY
+} DBusHandlerResult;
+
+typedef DBusHandlerResult (* DBusHandleMessageFunction)(DBusConnection *,
+ DBusMessage *, void *);
+typedef void (* DBusFreeFunction) (void *);
+
+/* Declarations of the functions that we need from libdbus-1 */
+#define VBOX_DBUS_GENERATE_HEADER
+
+#include <VBox/dbus-calls.h>
+
+#undef VBOX_DBUS_GENERATE_HEADER
+
+#endif /* ___VBox_DBus_h not defined */
+/* vi: set tabstop=4 shiftwidth=4 expandtab: */
+
diff --git a/include/VBox/dis.h b/include/VBox/dis.h
new file mode 100644
index 00000000..09d8a6ea
--- /dev/null
+++ b/include/VBox/dis.h
@@ -0,0 +1,807 @@
+/** @file
+ * DIS - The VirtualBox Disassembler.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_dis_h
+#define ___VBox_dis_h
+
+#include <VBox/types.h>
+#include <VBox/disopcode.h>
+#include <iprt/assert.h>
+
+
+RT_C_DECLS_BEGIN
+
+
+/** @name Prefix byte flags (DISSTATE::fPrefix).
+ * @{
+ */
+#define DISPREFIX_NONE UINT8_C(0x00)
+/** non-default address size. */
+#define DISPREFIX_ADDRSIZE UINT8_C(0x01)
+/** non-default operand size. */
+#define DISPREFIX_OPSIZE UINT8_C(0x02)
+/** lock prefix. */
+#define DISPREFIX_LOCK UINT8_C(0x04)
+/** segment prefix. */
+#define DISPREFIX_SEG UINT8_C(0x08)
+/** rep(e) prefix (not a prefix, but we'll treat is as one). */
+#define DISPREFIX_REP UINT8_C(0x10)
+/** rep(e) prefix (not a prefix, but we'll treat is as one). */
+#define DISPREFIX_REPNE UINT8_C(0x20)
+/** REX prefix (64 bits) */
+#define DISPREFIX_REX UINT8_C(0x40)
+/** @} */
+
+/** @name 64 bits prefix byte flags (DISSTATE::fRexPrefix).
+ * Requires VBox/disopcode.h.
+ * @{
+ */
+#define DISPREFIX_REX_OP_2_FLAGS(a) (a - OP_PARM_REX_START)
+#define DISPREFIX_REX_FLAGS DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX)
+#define DISPREFIX_REX_FLAGS_B DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_B)
+#define DISPREFIX_REX_FLAGS_X DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_X)
+#define DISPREFIX_REX_FLAGS_XB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_XB)
+#define DISPREFIX_REX_FLAGS_R DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_R)
+#define DISPREFIX_REX_FLAGS_RB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_RB)
+#define DISPREFIX_REX_FLAGS_RX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_RX)
+#define DISPREFIX_REX_FLAGS_RXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_RXB)
+#define DISPREFIX_REX_FLAGS_W DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_W)
+#define DISPREFIX_REX_FLAGS_WB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WB)
+#define DISPREFIX_REX_FLAGS_WX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WX)
+#define DISPREFIX_REX_FLAGS_WXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WXB)
+#define DISPREFIX_REX_FLAGS_WR DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WR)
+#define DISPREFIX_REX_FLAGS_WRB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRB)
+#define DISPREFIX_REX_FLAGS_WRX DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRX)
+#define DISPREFIX_REX_FLAGS_WRXB DISPREFIX_REX_OP_2_FLAGS(OP_PARM_REX_WRXB)
+/** @} */
+
+/** @name Operand type (DISOPCODE::fOpType).
+ * @{
+ */
+#define DISOPTYPE_INVALID RT_BIT_32(0)
+#define DISOPTYPE_HARMLESS RT_BIT_32(1)
+#define DISOPTYPE_CONTROLFLOW RT_BIT_32(2)
+#define DISOPTYPE_POTENTIALLY_DANGEROUS RT_BIT_32(3)
+#define DISOPTYPE_DANGEROUS RT_BIT_32(4)
+#define DISOPTYPE_PORTIO RT_BIT_32(5)
+#define DISOPTYPE_PRIVILEGED RT_BIT_32(6)
+#define DISOPTYPE_PRIVILEGED_NOTRAP RT_BIT_32(7)
+#define DISOPTYPE_UNCOND_CONTROLFLOW RT_BIT_32(8)
+#define DISOPTYPE_RELATIVE_CONTROLFLOW RT_BIT_32(9)
+#define DISOPTYPE_COND_CONTROLFLOW RT_BIT_32(10)
+#define DISOPTYPE_INTERRUPT RT_BIT_32(11)
+#define DISOPTYPE_ILLEGAL RT_BIT_32(12)
+#define DISOPTYPE_RRM_DANGEROUS RT_BIT_32(14) /**< Some additional dangerous ones when recompiling raw r0. */
+#define DISOPTYPE_RRM_DANGEROUS_16 RT_BIT_32(15) /**< Some additional dangerous ones when recompiling 16-bit raw r0. */
+#define DISOPTYPE_RRM_MASK (DISOPTYPE_RRM_DANGEROUS | DISOPTYPE_RRM_DANGEROUS_16)
+#define DISOPTYPE_INHIBIT_IRQS RT_BIT_32(16) /**< Will or can inhibit irqs (sti, pop ss, mov ss) */
+#define DISOPTYPE_PORTIO_READ RT_BIT_32(17)
+#define DISOPTYPE_PORTIO_WRITE RT_BIT_32(18)
+#define DISOPTYPE_INVALID_64 RT_BIT_32(19) /**< Invalid in 64 bits mode */
+#define DISOPTYPE_ONLY_64 RT_BIT_32(20) /**< Only valid in 64 bits mode */
+#define DISOPTYPE_DEFAULT_64_OP_SIZE RT_BIT_32(21) /**< Default 64 bits operand size */
+#define DISOPTYPE_FORCED_64_OP_SIZE RT_BIT_32(22) /**< Forced 64 bits operand size; regardless of prefix bytes */
+#define DISOPTYPE_REXB_EXTENDS_OPREG RT_BIT_32(23) /**< REX.B extends the register field in the opcode byte */
+#define DISOPTYPE_MOD_FIXED_11 RT_BIT_32(24) /**< modrm.mod is always 11b */
+#define DISOPTYPE_FORCED_32_OP_SIZE_X86 RT_BIT_32(25) /**< Forced 32 bits operand size; regardless of prefix bytes (only in 16 & 32 bits mode!) */
+#define DISOPTYPE_ALL UINT32_C(0xffffffff)
+/** @} */
+
+/** @name Parameter usage flags.
+ * @{
+ */
+#define DISUSE_BASE RT_BIT_64(0)
+#define DISUSE_INDEX RT_BIT_64(1)
+#define DISUSE_SCALE RT_BIT_64(2)
+#define DISUSE_REG_GEN8 RT_BIT_64(3)
+#define DISUSE_REG_GEN16 RT_BIT_64(4)
+#define DISUSE_REG_GEN32 RT_BIT_64(5)
+#define DISUSE_REG_GEN64 RT_BIT_64(6)
+#define DISUSE_REG_FP RT_BIT_64(7)
+#define DISUSE_REG_MMX RT_BIT_64(8)
+#define DISUSE_REG_XMM RT_BIT_64(9)
+#define DISUSE_REG_CR RT_BIT_64(10)
+#define DISUSE_REG_DBG RT_BIT_64(11)
+#define DISUSE_REG_SEG RT_BIT_64(12)
+#define DISUSE_REG_TEST RT_BIT_64(13)
+#define DISUSE_DISPLACEMENT8 RT_BIT_64(14)
+#define DISUSE_DISPLACEMENT16 RT_BIT_64(15)
+#define DISUSE_DISPLACEMENT32 RT_BIT_64(16)
+#define DISUSE_DISPLACEMENT64 RT_BIT_64(17)
+#define DISUSE_RIPDISPLACEMENT32 RT_BIT_64(18)
+#define DISUSE_IMMEDIATE8 RT_BIT_64(19)
+#define DISUSE_IMMEDIATE8_REL RT_BIT_64(20)
+#define DISUSE_IMMEDIATE16 RT_BIT_64(21)
+#define DISUSE_IMMEDIATE16_REL RT_BIT_64(22)
+#define DISUSE_IMMEDIATE32 RT_BIT_64(23)
+#define DISUSE_IMMEDIATE32_REL RT_BIT_64(24)
+#define DISUSE_IMMEDIATE64 RT_BIT_64(25)
+#define DISUSE_IMMEDIATE64_REL RT_BIT_64(26)
+#define DISUSE_IMMEDIATE_ADDR_0_32 RT_BIT_64(27)
+#define DISUSE_IMMEDIATE_ADDR_16_32 RT_BIT_64(28)
+#define DISUSE_IMMEDIATE_ADDR_0_16 RT_BIT_64(29)
+#define DISUSE_IMMEDIATE_ADDR_16_16 RT_BIT_64(30)
+/** DS:ESI */
+#define DISUSE_POINTER_DS_BASED RT_BIT_64(31)
+/** ES:EDI */
+#define DISUSE_POINTER_ES_BASED RT_BIT_64(32)
+#define DISUSE_IMMEDIATE16_SX8 RT_BIT_64(33)
+#define DISUSE_IMMEDIATE32_SX8 RT_BIT_64(34)
+#define DISUSE_IMMEDIATE64_SX8 RT_BIT_64(36)
+
+/** Mask of immediate use flags. */
+#define DISUSE_IMMEDIATE ( DISUSE_IMMEDIATE8 \
+ | DISUSE_IMMEDIATE16 \
+ | DISUSE_IMMEDIATE32 \
+ | DISUSE_IMMEDIATE64 \
+ | DISUSE_IMMEDIATE8_REL \
+ | DISUSE_IMMEDIATE16_REL \
+ | DISUSE_IMMEDIATE32_REL \
+ | DISUSE_IMMEDIATE64_REL \
+ | DISUSE_IMMEDIATE_ADDR_0_32 \
+ | DISUSE_IMMEDIATE_ADDR_16_32 \
+ | DISUSE_IMMEDIATE_ADDR_0_16 \
+ | DISUSE_IMMEDIATE_ADDR_16_16 \
+ | DISUSE_IMMEDIATE16_SX8 \
+ | DISUSE_IMMEDIATE32_SX8 \
+ | DISUSE_IMMEDIATE64_SX8)
+/** Check if the use flags indicates an effective address. */
+#define DISUSE_IS_EFFECTIVE_ADDR(a_fUseFlags) (!!( (a_fUseFlags) \
+ & ( DISUSE_BASE \
+ | DISUSE_INDEX \
+ | DISUSE_DISPLACEMENT32 \
+ | DISUSE_DISPLACEMENT64 \
+ | DISUSE_DISPLACEMENT16 \
+ | DISUSE_DISPLACEMENT8 \
+ | DISUSE_RIPDISPLACEMENT32) ))
+/** @} */
+
+/** @name 64-bit general register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
+ * @note Safe to assume same values as the 16-bit and 32-bit general registers.
+ * @{
+ */
+#define DISGREG_RAX UINT8_C(0)
+#define DISGREG_RCX UINT8_C(1)
+#define DISGREG_RDX UINT8_C(2)
+#define DISGREG_RBX UINT8_C(3)
+#define DISGREG_RSP UINT8_C(4)
+#define DISGREG_RBP UINT8_C(5)
+#define DISGREG_RSI UINT8_C(6)
+#define DISGREG_RDI UINT8_C(7)
+#define DISGREG_R8 UINT8_C(8)
+#define DISGREG_R9 UINT8_C(9)
+#define DISGREG_R10 UINT8_C(10)
+#define DISGREG_R11 UINT8_C(11)
+#define DISGREG_R12 UINT8_C(12)
+#define DISGREG_R13 UINT8_C(13)
+#define DISGREG_R14 UINT8_C(14)
+#define DISGREG_R15 UINT8_C(15)
+/** @} */
+
+/** @name 32-bit general register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
+ * @note Safe to assume same values as the 16-bit and 64-bit general registers.
+ * @{
+ */
+#define DISGREG_EAX UINT8_C(0)
+#define DISGREG_ECX UINT8_C(1)
+#define DISGREG_EDX UINT8_C(2)
+#define DISGREG_EBX UINT8_C(3)
+#define DISGREG_ESP UINT8_C(4)
+#define DISGREG_EBP UINT8_C(5)
+#define DISGREG_ESI UINT8_C(6)
+#define DISGREG_EDI UINT8_C(7)
+#define DISGREG_R8D UINT8_C(8)
+#define DISGREG_R9D UINT8_C(9)
+#define DISGREG_R10D UINT8_C(10)
+#define DISGREG_R11D UINT8_C(11)
+#define DISGREG_R12D UINT8_C(12)
+#define DISGREG_R13D UINT8_C(13)
+#define DISGREG_R14D UINT8_C(14)
+#define DISGREG_R15D UINT8_C(15)
+/** @} */
+
+/** @name 16-bit general register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
+ * @note Safe to assume same values as the 32-bit and 64-bit general registers.
+ * @{
+ */
+#define DISGREG_AX UINT8_C(0)
+#define DISGREG_CX UINT8_C(1)
+#define DISGREG_DX UINT8_C(2)
+#define DISGREG_BX UINT8_C(3)
+#define DISGREG_SP UINT8_C(4)
+#define DISGREG_BP UINT8_C(5)
+#define DISGREG_SI UINT8_C(6)
+#define DISGREG_DI UINT8_C(7)
+#define DISGREG_R8W UINT8_C(8)
+#define DISGREG_R9W UINT8_C(9)
+#define DISGREG_R10W UINT8_C(10)
+#define DISGREG_R11W UINT8_C(11)
+#define DISGREG_R12W UINT8_C(12)
+#define DISGREG_R13W UINT8_C(13)
+#define DISGREG_R14W UINT8_C(14)
+#define DISGREG_R15W UINT8_C(15)
+/** @} */
+
+/** @name 8-bit general register indexes.
+ * This mostly (?) matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxGenReg and DISOPPARAM::Index.idxGenReg.
+ * @{
+ */
+#define DISGREG_AL UINT8_C(0)
+#define DISGREG_CL UINT8_C(1)
+#define DISGREG_DL UINT8_C(2)
+#define DISGREG_BL UINT8_C(3)
+#define DISGREG_AH UINT8_C(4)
+#define DISGREG_CH UINT8_C(5)
+#define DISGREG_DH UINT8_C(6)
+#define DISGREG_BH UINT8_C(7)
+#define DISGREG_R8B UINT8_C(8)
+#define DISGREG_R9B UINT8_C(9)
+#define DISGREG_R10B UINT8_C(10)
+#define DISGREG_R11B UINT8_C(11)
+#define DISGREG_R12B UINT8_C(12)
+#define DISGREG_R13B UINT8_C(13)
+#define DISGREG_R14B UINT8_C(14)
+#define DISGREG_R15B UINT8_C(15)
+#define DISGREG_SPL UINT8_C(16)
+#define DISGREG_BPL UINT8_C(17)
+#define DISGREG_SIL UINT8_C(18)
+#define DISGREG_DIL UINT8_C(19)
+/** @} */
+
+/** @name Segment registerindexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxSegReg.
+ * @{
+ */
+typedef enum
+{
+ DISSELREG_ES = 0,
+ DISSELREG_CS = 1,
+ DISSELREG_SS = 2,
+ DISSELREG_DS = 3,
+ DISSELREG_FS = 4,
+ DISSELREG_GS = 5,
+ /** End of the valid register index values. */
+ DISSELREG_END,
+ /** The usual 32-bit paranoia. */
+ DIS_SEGREG_32BIT_HACK = 0x7fffffff
+} DISSELREG;
+/** @} */
+
+/** @name FPU register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxFpuReg.
+ * @{
+ */
+#define DISFPREG_ST0 UINT8_C(0)
+#define DISFPREG_ST1 UINT8_C(1)
+#define DISFPREG_ST2 UINT8_C(2)
+#define DISFPREG_ST3 UINT8_C(3)
+#define DISFPREG_ST4 UINT8_C(4)
+#define DISFPREG_ST5 UINT8_C(5)
+#define DISFPREG_ST6 UINT8_C(6)
+#define DISFPREG_ST7 UINT8_C(7)
+/** @} */
+
+/** @name Control register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxCtrlReg.
+ * @{
+ */
+#define DISCREG_CR0 UINT8_C(0)
+#define DISCREG_CR1 UINT8_C(1)
+#define DISCREG_CR2 UINT8_C(2)
+#define DISCREG_CR3 UINT8_C(3)
+#define DISCREG_CR4 UINT8_C(4)
+#define DISCREG_CR8 UINT8_C(8)
+/** @} */
+
+/** @name Debug register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxDbgReg.
+ * @{
+ */
+#define DISDREG_DR0 UINT8_C(0)
+#define DISDREG_DR1 UINT8_C(1)
+#define DISDREG_DR2 UINT8_C(2)
+#define DISDREG_DR3 UINT8_C(3)
+#define DISDREG_DR4 UINT8_C(4)
+#define DISDREG_DR5 UINT8_C(5)
+#define DISDREG_DR6 UINT8_C(6)
+#define DISDREG_DR7 UINT8_C(7)
+/** @} */
+
+/** @name MMX register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxMmxReg.
+ * @{
+ */
+#define DISMREG_MMX0 UINT8_C(0)
+#define DISMREG_MMX1 UINT8_C(1)
+#define DISMREG_MMX2 UINT8_C(2)
+#define DISMREG_MMX3 UINT8_C(3)
+#define DISMREG_MMX4 UINT8_C(4)
+#define DISMREG_MMX5 UINT8_C(5)
+#define DISMREG_MMX6 UINT8_C(6)
+#define DISMREG_MMX7 UINT8_C(7)
+/** @} */
+
+/** @name SSE register indexes.
+ * This matches the AMD64 register encoding. It is found used in
+ * DISOPPARAM::Base.idxXmmReg.
+ * @{
+ */
+#define DISXREG_XMM0 UINT8_C(0)
+#define DISXREG_XMM1 UINT8_C(1)
+#define DISXREG_XMM2 UINT8_C(2)
+#define DISXREG_XMM3 UINT8_C(3)
+#define DISXREG_XMM4 UINT8_C(4)
+#define DISXREG_XMM5 UINT8_C(5)
+#define DISXREG_XMM6 UINT8_C(6)
+#define DISXREG_XMM7 UINT8_C(7)
+/** @} */
+
+
+/**
+ * Opcode parameter (operand) details.
+ */
+typedef struct DISOPPARAM
+{
+ /** A combination of DISUSE_XXX. */
+ uint64_t fUse;
+ /** Immediate value or address, applicable if any of the flags included in
+ * DISUSE_IMMEDIATE are set in fUse. */
+ uint64_t uValue;
+ /** Disposition. */
+ union
+ {
+ /** 64-bit displacement, applicable if DISUSE_DISPLACEMENT64 is set in fUse. */
+ int64_t i64;
+ uint64_t u64;
+ /** 32-bit displacement, applicable if DISUSE_DISPLACEMENT32 or
+ * DISUSE_RIPDISPLACEMENT32 is set in fUse. */
+ int32_t i32;
+ uint32_t u32;
+ /** 16-bit displacement, applicable if DISUSE_DISPLACEMENT16 is set in fUse. */
+ int32_t i16;
+ uint32_t u16;
+ /** 8-bit displacement, applicable if DISUSE_DISPLACEMENT8 is set in fUse. */
+ int32_t i8;
+ uint32_t u8;
+ } uDisp;
+ /** The base register from ModR/M or SIB, applicable if DISUSE_BASE is
+ * set in fUse. */
+ union
+ {
+ /** General register index (DISGREG_XXX), applicable if DISUSE_REG_GEN8,
+ * DISUSE_REG_GEN16, DISUSE_REG_GEN32 or DISUSE_REG_GEN64 is set in fUse. */
+ uint8_t idxGenReg;
+ /** FPU stack register index (DISFPREG_XXX), applicable if DISUSE_REG_FP is
+ * set in fUse. 1:1 indexes. */
+ uint8_t idxFpuReg;
+ /** MMX register index (DISMREG_XXX), applicable if DISUSE_REG_MMX is
+ * set in fUse. 1:1 indexes. */
+ uint8_t idxMmxReg;
+ /** SSE register index (DISXREG_XXX), applicable if DISUSE_REG_XMM is
+ * set in fUse. 1:1 indexes. */
+ uint8_t idxXmmReg;
+ /** Segment register index (DISSELREG_XXX), applicable if DISUSE_REG_SEG is
+ * set in fUse. */
+ uint8_t idxSegReg;
+ /** Test register, TR0-TR7, present on early IA32 CPUs, applicable if
+ * DISUSE_REG_TEST is set in fUse. No index defines for these. */
+ uint8_t idxTestReg;
+ /** Control register index (DISCREG_XXX), applicable if DISUSE_REG_CR is
+ * set in fUse. 1:1 indexes. */
+ uint8_t idxCtrlReg;
+ /** Debug register index (DISDREG_XXX), applicable if DISUSE_REG_DBG is
+ * set in fUse. 1:1 indexes. */
+ uint8_t idxDbgReg;
+ } Base;
+ /** The SIB index register meaning, applicable if DISUSE_INDEX is
+ * set in fUse. */
+ union
+ {
+ /** General register index (DISGREG_XXX), applicable if DISUSE_REG_GEN8,
+ * DISUSE_REG_GEN16, DISUSE_REG_GEN32 or DISUSE_REG_GEN64 is set in fUse. */
+ uint8_t idxGenReg;
+ } Index;
+ /** 2, 4 or 8, if DISUSE_SCALE is set in fUse. */
+ uint8_t uScale;
+ /** Parameter size. */
+ uint8_t cb;
+ /** Copy of the corresponding DISOPCODE::fParam1 / DISOPCODE::fParam2 /
+ * DISOPCODE::fParam3. */
+ uint32_t fParam;
+} DISOPPARAM;
+AssertCompileSize(DISOPPARAM, 32);
+/** Pointer to opcode parameter. */
+typedef DISOPPARAM *PDISOPPARAM;
+/** Pointer to opcode parameter. */
+typedef const DISOPPARAM *PCDISOPPARAM;
+
+
+/**
+ * Opcode descriptor.
+ */
+typedef struct DISOPCODE
+{
+#ifndef DIS_CORE_ONLY
+ const char *pszOpcode;
+#endif
+ /** Parameter \#1 parser index. */
+ uint8_t idxParse1;
+ /** Parameter \#2 parser index. */
+ uint8_t idxParse2;
+ /** Parameter \#3 parser index. */
+ uint8_t idxParse3;
+ /** Unused padding. */
+ uint8_t uUnused;
+ /** The opcode identifier. This DIS specific, @see grp_dis_opcodes and
+ * VBox/disopcode.h. */
+ uint16_t uOpcode;
+ /** Parameter \#1 info, @see grp_dis_opparam. */
+ uint16_t fParam1;
+ /** Parameter \#2 info, @see grp_dis_opparam. */
+ uint16_t fParam2;
+ /** Parameter \#3 info, @see grp_dis_opparam. */
+ uint16_t fParam3;
+ /** Operand type flags, DISOPTYPE_XXX. */
+ uint32_t fOpType;
+} DISOPCODE;
+/** Pointer to const opcode. */
+typedef const struct DISOPCODE *PCDISOPCODE;
+
+
+/**
+ * Callback for reading instruction bytes.
+ *
+ * @returns VBox status code, bytes in DISSTATE::abInstr and byte count in
+ * DISSTATE::cbCachedInstr.
+ * @param pDis Pointer to the disassembler state. The user
+ * argument can be found in DISSTATE::pvUser if needed.
+ * @param offInstr The offset relative to the start of the instruction.
+ *
+ * To get the source address, add this to
+ * DISSTATE::uInstrAddr.
+ *
+ * To calculate the destination buffer address, use it
+ * as an index into DISSTATE::abInstr.
+ *
+ * @param cbMinRead The minimum number of bytes to read.
+ * @param cbMaxRead The maximum number of bytes that may be read.
+ */
+typedef DECLCALLBACK(int) FNDISREADBYTES(PDISSTATE pDis, uint8_t offInstr, uint8_t cbMinRead, uint8_t cbMaxRead);
+/** Pointer to a opcode byte reader. */
+typedef FNDISREADBYTES *PFNDISREADBYTES;
+
+/** Parser callback.
+ * @remark no DECLCALLBACK() here because it's considered to be internal and
+ * there is no point in enforcing CDECL. */
+typedef size_t FNDISPARSE(size_t offInstr, PCDISOPCODE pOp, PDISSTATE pDis, PDISOPPARAM pParam);
+/** Pointer to a disassembler parser function. */
+typedef FNDISPARSE *PFNDISPARSE;
+/** Pointer to a const disassembler parser function pointer. */
+typedef PFNDISPARSE const *PCPFNDISPARSE;
+
+/**
+ * The diassembler state and result.
+ */
+typedef struct DISSTATE
+{
+ /** The number of valid bytes in abInstr. */
+ uint8_t cbCachedInstr;
+ /** SIB fields. */
+ union
+ {
+ /** Bitfield view */
+ struct
+ {
+ uint8_t Base;
+ uint8_t Index;
+ uint8_t Scale;
+ } Bits;
+ } SIB;
+ /** ModRM fields. */
+ union
+ {
+ /** Bitfield view */
+ struct
+ {
+ uint8_t Rm;
+ uint8_t Reg;
+ uint8_t Mod;
+ } Bits;
+ } ModRM;
+ /** The CPU mode (DISCPUMODE). */
+ uint8_t uCpuMode;
+ /** The addressing mode (DISCPUMODE). */
+ uint8_t uAddrMode;
+ /** The operand mode (DISCPUMODE). */
+ uint8_t uOpMode;
+ /** Per instruction prefix settings. */
+ uint8_t fPrefix;
+ /** REX prefix value (64 bits only). */
+ uint8_t fRexPrefix;
+ /** Segment prefix value (DISSELREG). */
+ uint8_t idxSegPrefix;
+ /** Last prefix byte (for SSE2 extension tables). */
+ uint8_t bLastPrefix;
+ /** Last significan opcode byte of instruction. */
+ uint8_t bOpCode;
+ /** The size of the prefix bytes. */
+ uint8_t cbPrefix;
+ /** The instruction size. */
+ uint8_t cbInstr;
+ /** Unused bytes. */
+ uint8_t abUnused[3];
+ /** Internal: instruction filter */
+ uint32_t fFilter;
+ /** Internal: pointer to disassembly function table */
+ PCPFNDISPARSE pfnDisasmFnTable;
+#if ARCH_BITS == 32
+ uint32_t uPtrPadding1;
+#endif
+ /** Pointer to the current instruction. */
+ PCDISOPCODE pCurInstr;
+#if ARCH_BITS == 32
+ uint32_t uPtrPadding2;
+#endif
+ /** The instruction bytes. */
+ uint8_t abInstr[16];
+ /** SIB displacment. */
+ int32_t i32SibDisp;
+
+ /** Return code set by a worker function like the opcode bytes readers. */
+ int32_t rc;
+ /** The address of the instruction. */
+ RTUINTPTR uInstrAddr;
+ /** Optional read function */
+ PFNDISREADBYTES pfnReadBytes;
+#if ARCH_BITS == 32
+ uint32_t uPadding3;
+#endif
+ /** User data supplied as an argument to the APIs. */
+ void *pvUser;
+#if ARCH_BITS == 32
+ uint32_t uPadding4;
+#endif
+ /** Parameters. */
+ DISOPPARAM Param1;
+ DISOPPARAM Param2;
+ DISOPPARAM Param3;
+} DISSTATE;
+AssertCompileSize(DISSTATE, 0xb8);
+
+/** @deprecated Use DISSTATE and change Cpu and DisState to Dis. */
+typedef DISSTATE DISCPUSTATE;
+
+
+
+DISDECL(int) DISInstrToStr(void const *pvInstr, DISCPUMODE enmCpuMode,
+ PDISSTATE pDis, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput);
+DISDECL(int) DISInstrToStrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
+ PDISSTATE pDis, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput);
+DISDECL(int) DISInstrToStrEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode,
+ PFNDISREADBYTES pfnReadBytes, void *pvUser, uint32_t uFilter,
+ PDISSTATE pDis, uint32_t *pcbInstr, char *pszOutput, size_t cbOutput);
+
+DISDECL(int) DISInstr(void const *pvInstr, DISCPUMODE enmCpuMode, PDISSTATE pDis, uint32_t *pcbInstr);
+DISDECL(int) DISInstrWithReader(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, PFNDISREADBYTES pfnReadBytes, void *pvUser,
+ PDISSTATE pDis, uint32_t *pcbInstr);
+DISDECL(int) DISInstrEx(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, uint32_t uFilter,
+ PFNDISREADBYTES pfnReadBytes, void *pvUser,
+ PDISSTATE pDis, uint32_t *pcbInstr);
+DISDECL(int) DISInstrWithPrefetchedBytes(RTUINTPTR uInstrAddr, DISCPUMODE enmCpuMode, uint32_t fFilter,
+ void const *pvPrefetched, size_t cbPretched,
+ PFNDISREADBYTES pfnReadBytes, void *pvUser,
+ PDISSTATE pDis, uint32_t *pcbInstr);
+
+DISDECL(int) DISGetParamSize(PCDISSTATE pDis, PCDISOPPARAM pParam);
+DISDECL(DISSELREG) DISDetectSegReg(PCDISSTATE pDis, PCDISOPPARAM pParam);
+DISDECL(uint8_t) DISQuerySegPrefixByte(PCDISSTATE pDis);
+
+
+
+/** @name Flags returned by DISQueryParamVal (DISQPVPARAMVAL::flags).
+ * @{
+ */
+#define DISQPV_FLAG_8 UINT8_C(0x01)
+#define DISQPV_FLAG_16 UINT8_C(0x02)
+#define DISQPV_FLAG_32 UINT8_C(0x04)
+#define DISQPV_FLAG_64 UINT8_C(0x08)
+#define DISQPV_FLAG_FARPTR16 UINT8_C(0x10)
+#define DISQPV_FLAG_FARPTR32 UINT8_C(0x20)
+/** @} */
+
+/** @name Types returned by DISQueryParamVal (DISQPVPARAMVAL::flags).
+ * @{ */
+#define DISQPV_TYPE_REGISTER UINT8_C(1)
+#define DISQPV_TYPE_ADDRESS UINT8_C(2)
+#define DISQPV_TYPE_IMMEDIATE UINT8_C(3)
+/** @} */
+
+typedef struct
+{
+ union
+ {
+ uint8_t val8;
+ uint16_t val16;
+ uint32_t val32;
+ uint64_t val64;
+
+ struct
+ {
+ uint16_t sel;
+ uint32_t offset;
+ } farptr;
+ } val;
+
+ uint8_t type;
+ uint8_t size;
+ uint8_t flags;
+} DISQPVPARAMVAL;
+/** Pointer to opcode parameter value. */
+typedef DISQPVPARAMVAL *PDISQPVPARAMVAL;
+
+/** Indicates which parameter DISQueryParamVal should operate on. */
+typedef enum DISQPVWHICH
+{
+ DISQPVWHICH_DST = 1,
+ DISQPVWHICH_SRC,
+ DISQPVWHAT_32_BIT_HACK = 0x7fffffff
+} DISQPVWHICH;
+DISDECL(int) DISQueryParamVal(PCPUMCTXCORE pCtx, PCDISSTATE pDis, PCDISOPPARAM pParam, PDISQPVPARAMVAL pParamVal, DISQPVWHICH parmtype);
+DISDECL(int) DISQueryParamRegPtr(PCPUMCTXCORE pCtx, PCDISSTATE pDis, PCDISOPPARAM pParam, void **ppReg, size_t *pcbSize);
+
+DISDECL(int) DISFetchReg8(PCCPUMCTXCORE pCtx, unsigned reg8, uint8_t *pVal);
+DISDECL(int) DISFetchReg16(PCCPUMCTXCORE pCtx, unsigned reg16, uint16_t *pVal);
+DISDECL(int) DISFetchReg32(PCCPUMCTXCORE pCtx, unsigned reg32, uint32_t *pVal);
+DISDECL(int) DISFetchReg64(PCCPUMCTXCORE pCtx, unsigned reg64, uint64_t *pVal);
+DISDECL(int) DISFetchRegSeg(PCCPUMCTXCORE pCtx, DISSELREG sel, RTSEL *pVal);
+DISDECL(int) DISFetchRegSegEx(PCPUMCTXCORE pCtx, DISSELREG sel, PCPUMSELREG *ppSelReg);
+DISDECL(int) DISWriteReg8(PCPUMCTXCORE pRegFrame, unsigned reg8, uint8_t val8);
+DISDECL(int) DISWriteReg16(PCPUMCTXCORE pRegFrame, unsigned reg32, uint16_t val16);
+DISDECL(int) DISWriteReg32(PCPUMCTXCORE pRegFrame, unsigned reg32, uint32_t val32);
+DISDECL(int) DISWriteReg64(PCPUMCTXCORE pRegFrame, unsigned reg64, uint64_t val64);
+DISDECL(int) DISWriteRegSeg(PCPUMCTXCORE pCtx, DISSELREG sel, RTSEL val);
+DISDECL(int) DISPtrReg8(PCPUMCTXCORE pCtx, unsigned reg8, uint8_t **ppReg);
+DISDECL(int) DISPtrReg16(PCPUMCTXCORE pCtx, unsigned reg16, uint16_t **ppReg);
+DISDECL(int) DISPtrReg32(PCPUMCTXCORE pCtx, unsigned reg32, uint32_t **ppReg);
+DISDECL(int) DISPtrReg64(PCPUMCTXCORE pCtx, unsigned reg64, uint64_t **ppReg);
+
+
+/**
+ * Try resolve an address into a symbol name.
+ *
+ * For use with DISFormatYasmEx(), DISFormatMasmEx() and DISFormatGasEx().
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS on success, pszBuf contains the full symbol name.
+ * @retval VINF_BUFFER_OVERFLOW if pszBuf is too small the symbol name. The
+ * content of pszBuf is truncated and zero terminated.
+ * @retval VERR_SYMBOL_NOT_FOUND if no matching symbol was found for the address.
+ *
+ * @param pDis Pointer to the disassembler CPU state.
+ * @param u32Sel The selector value. Use DIS_FMT_SEL_IS_REG, DIS_FMT_SEL_GET_VALUE,
+ * DIS_FMT_SEL_GET_REG to access this.
+ * @param uAddress The segment address.
+ * @param pszBuf Where to store the symbol name
+ * @param cchBuf The size of the buffer.
+ * @param poff If not a perfect match, then this is where the offset from the return
+ * symbol to the specified address is returned.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(int) FNDISGETSYMBOL(PCDISSTATE pDis, uint32_t u32Sel, RTUINTPTR uAddress, char *pszBuf, size_t cchBuf, RTINTPTR *poff, void *pvUser);
+/** Pointer to a FNDISGETSYMBOL(). */
+typedef FNDISGETSYMBOL *PFNDISGETSYMBOL;
+
+/**
+ * Checks if the FNDISGETSYMBOL argument u32Sel is a register or not.
+ */
+#define DIS_FMT_SEL_IS_REG(u32Sel) ( !!((u32Sel) & RT_BIT(31)) )
+
+/**
+ * Extracts the selector value from the FNDISGETSYMBOL argument u32Sel.
+ * @returns Selector value.
+ */
+#define DIS_FMT_SEL_GET_VALUE(u32Sel) ( (RTSEL)(u32Sel) )
+
+/**
+ * Extracts the register number from the FNDISGETSYMBOL argument u32Sel.
+ * @returns USE_REG_CS, USE_REG_SS, USE_REG_DS, USE_REG_ES, USE_REG_FS or USE_REG_FS.
+ */
+#define DIS_FMT_SEL_GET_REG(u32Sel) ( ((u32Sel) >> 16) & 0xf )
+
+/** @internal */
+#define DIS_FMT_SEL_FROM_REG(uReg) ( ((uReg) << 16) | RT_BIT(31) | 0xffff )
+/** @internal */
+#define DIS_FMT_SEL_FROM_VALUE(Sel) ( (Sel) & 0xffff )
+
+
+/** @name Flags for use with DISFormatYasmEx(), DISFormatMasmEx() and DISFormatGasEx().
+ * @{
+ */
+/** Put the address to the right. */
+#define DIS_FMT_FLAGS_ADDR_RIGHT RT_BIT_32(0)
+/** Put the address to the left. */
+#define DIS_FMT_FLAGS_ADDR_LEFT RT_BIT_32(1)
+/** Put the address in comments.
+ * For some assemblers this implies placing it to the right. */
+#define DIS_FMT_FLAGS_ADDR_COMMENT RT_BIT_32(2)
+/** Put the instruction bytes to the right of the disassembly. */
+#define DIS_FMT_FLAGS_BYTES_RIGHT RT_BIT_32(3)
+/** Put the instruction bytes to the left of the disassembly. */
+#define DIS_FMT_FLAGS_BYTES_LEFT RT_BIT_32(4)
+/** Put the instruction bytes in comments.
+ * For some assemblers this implies placing the bytes to the right. */
+#define DIS_FMT_FLAGS_BYTES_COMMENT RT_BIT_32(5)
+/** Put the bytes in square brackets. */
+#define DIS_FMT_FLAGS_BYTES_BRACKETS RT_BIT_32(6)
+/** Put spaces between the bytes. */
+#define DIS_FMT_FLAGS_BYTES_SPACED RT_BIT_32(7)
+/** Display the relative +/- offset of branch instructions that uses relative addresses,
+ * and put the target address in parenthesis. */
+#define DIS_FMT_FLAGS_RELATIVE_BRANCH RT_BIT_32(8)
+/** Strict assembly. The assembly should, when ever possible, make the
+ * assembler reproduce the exact same binary. (Refers to the yasm
+ * strict keyword.) */
+#define DIS_FMT_FLAGS_STRICT RT_BIT_32(9)
+/** Checks if the given flags are a valid combination. */
+#define DIS_FMT_FLAGS_IS_VALID(fFlags) \
+ ( !((fFlags) & ~UINT32_C(0x000003ff)) \
+ && ((fFlags) & (DIS_FMT_FLAGS_ADDR_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT)) != (DIS_FMT_FLAGS_ADDR_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT) \
+ && ( !((fFlags) & DIS_FMT_FLAGS_ADDR_COMMENT) \
+ || (fFlags & (DIS_FMT_FLAGS_ADDR_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT)) ) \
+ && ((fFlags) & (DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_LEFT)) != (DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_LEFT) \
+ && ( !((fFlags) & (DIS_FMT_FLAGS_BYTES_COMMENT | DIS_FMT_FLAGS_BYTES_BRACKETS)) \
+ || (fFlags & (DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_BYTES_LEFT)) ) \
+ )
+/** @} */
+
+DISDECL(size_t) DISFormatYasm( PCDISSTATE pDis, char *pszBuf, size_t cchBuf);
+DISDECL(size_t) DISFormatYasmEx(PCDISSTATE pDis, char *pszBuf, size_t cchBuf, uint32_t fFlags, PFNDISGETSYMBOL pfnGetSymbol, void *pvUser);
+DISDECL(size_t) DISFormatMasm( PCDISSTATE pDis, char *pszBuf, size_t cchBuf);
+DISDECL(size_t) DISFormatMasmEx(PCDISSTATE pDis, char *pszBuf, size_t cchBuf, uint32_t fFlags, PFNDISGETSYMBOL pfnGetSymbol, void *pvUser);
+DISDECL(size_t) DISFormatGas( PCDISSTATE pDis, char *pszBuf, size_t cchBuf);
+DISDECL(size_t) DISFormatGasEx( PCDISSTATE pDis, char *pszBuf, size_t cchBuf, uint32_t fFlags, PFNDISGETSYMBOL pfnGetSymbol, void *pvUser);
+
+/** @todo DISAnnotate(PCDISSTATE pDis, char *pszBuf, size_t cchBuf, register
+ * reader, memory reader); */
+
+DISDECL(bool) DISFormatYasmIsOddEncoding(PDISSTATE pDis);
+
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/disopcode.h b/include/VBox/disopcode.h
new file mode 100644
index 00000000..c83f5052
--- /dev/null
+++ b/include/VBox/disopcode.h
@@ -0,0 +1,849 @@
+/** @file
+ * Disassembler - opcode.h.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_opcode_h
+#define ___VBox_opcode_h
+
+#define MODRM_MOD(a) (a>>6)
+#define MODRM_REG(a) ((a>>3)&0x7)
+#define MODRM_RM(a) (a&0x7)
+#define MAKE_MODRM(mod, reg, rm) (((mod&3) << 6) | ((reg&7) << 3) | (rm&7))
+
+#define SIB_SCALE(a) (a>>6)
+#define SIB_INDEX(a) ((a>>3)&0x7)
+#define SIB_BASE(a) (a&0x7)
+
+
+/** @defgroup grp_dis_opcodes Opcodes (DISOPCODE::uOpCode)
+ * @ingroup grp_dis
+ * @{
+ */
+
+/** @name Full Intel X86 opcode list
+ * @{ */
+#define OP_INVALID 0
+#define OP_OPSIZE 1
+#define OP_ADDRSIZE 2
+#define OP_SEG 3
+#define OP_REPNE 4
+#define OP_REPE 5
+#define OP_REX 6
+#define OP_LOCK 7
+#define OP_LAST_PREFIX OP_LOCK /* disassembler assumes this is the last prefix byte value!!!! */
+#define OP_AND 8
+#define OP_OR 9
+#define OP_DAA 10
+#define OP_SUB 11
+#define OP_DAS 12
+#define OP_XOR 13
+#define OP_AAA 14
+#define OP_CMP 15
+#define OP_IMM_GRP1 16
+#define OP_AAS 17
+#define OP_INC 18
+#define OP_DEC 19
+#define OP_PUSHA 20
+#define OP_POPA 21
+#define OP_BOUND 22
+#define OP_ARPL 23
+#define OP_PUSH 24
+#define OP_POP 25
+#define OP_IMUL 26
+#define OP_INSB 27
+#define OP_INSWD 28
+#define OP_OUTSB 29
+#define OP_OUTSWD 30
+#define OP_JO 31
+#define OP_JNO 32
+#define OP_JC 33
+#define OP_JNC 34
+#define OP_JE 35
+#define OP_JNE 36
+#define OP_JBE 37
+#define OP_JNBE 38
+#define OP_JS 39
+#define OP_JNS 40
+#define OP_JP 41
+#define OP_JNP 42
+#define OP_JL 43
+#define OP_JNL 44
+#define OP_JLE 45
+#define OP_JNLE 46
+#define OP_ADD 47
+#define OP_TEST 48
+#define OP_XCHG 49
+#define OP_MOV 50
+#define OP_LEA 51
+#define OP_NOP 52
+#define OP_CBW 53
+#define OP_CWD 54
+#define OP_CALL 55
+#define OP_WAIT 56
+#define OP_PUSHF 57
+#define OP_POPF 58
+#define OP_SAHF 59
+#define OP_LAHF 60
+#define OP_MOVSB 61
+#define OP_MOVSWD 62
+#define OP_CMPSB 63
+#define OP_CMPWD 64
+#define OP_STOSB 65
+#define OP_STOSWD 66
+#define OP_LODSB 67
+#define OP_LODSWD 68
+#define OP_SCASB 69
+#define OP_SCASWD 70
+#define OP_SHIFT_GRP2 71
+#define OP_RETN 72
+#define OP_LES 73
+#define OP_LDS 74
+#define OP_ENTER 75
+#define OP_LEAVE 76
+#define OP_RETF 77
+#define OP_INT3 78
+#define OP_INT 79
+#define OP_INTO 80
+#define OP_IRET 81
+#define OP_AAM 82
+#define OP_AAD 83
+#define OP_XLAT 84
+#define OP_ESCF0 85
+#define OP_ESCF1 86
+#define OP_ESCF2 87
+#define OP_ESCF3 88
+#define OP_ESCF4 89
+#define OP_ESCF5 90
+#define OP_ESCF6 91
+#define OP_ESCF7 92
+#define OP_LOOPNE 93
+#define OP_LOOPE 94
+#define OP_LOOP 95
+#define OP_JECXZ 96
+#define OP_IN 97
+#define OP_OUT 98
+#define OP_JMP 99
+#define OP_2B_ESC 100
+#define OP_ADC 101
+#define OP_SBB 102
+#define OP_HLT 103
+#define OP_CMC 104
+#define OP_UNARY_GRP3 105
+#define OP_CLC 106
+#define OP_STC 107
+#define OP_CLI 108
+#define OP_STI 109
+#define OP_CLD 110
+#define OP_STD 111
+#define OP_INC_GRP4 112
+#define OP_IND_GRP5 113
+#define OP_GRP6 114
+#define OP_GRP7 115
+#define OP_LAR 116
+#define OP_LSL 117
+#define OP_SYSCALL 118
+#define OP_CLTS 119
+#define OP_SYSRET 120
+#define OP_INVD 121
+#define OP_WBINVD 122
+#define OP_ILLUD2 123
+#define OP_FEMMS 124
+#define OP_3DNOW 125
+#define OP_MOVUPS 126
+#define OP_MOVLPS 127
+#define OP_UNPCKLPS 128
+#define OP_MOVHPS 129
+#define OP_UNPCKHPS 130
+#define OP_PREFETCH_GRP16 131
+#define OP_MOV_CR 132
+#define OP_MOVAPS 133
+#define OP_CVTPI2PS 134
+#define OP_MOVNTPS 135
+#define OP_CVTTPS2PI 136
+#define OP_CVTPS2PI 137
+#define OP_UCOMISS 138
+#define OP_COMISS 139
+#define OP_WRMSR 140
+#define OP_RDTSC 141
+#define OP_RDMSR 142
+#define OP_RDPMC 143
+#define OP_SYSENTER 144
+#define OP_SYSEXIT 145
+#define OP_PAUSE 146
+#define OP_CMOVO 147
+#define OP_CMOVNO 148
+#define OP_CMOVC 149
+#define OP_CMOVNC 150
+#define OP_CMOVZ 151
+#define OP_CMOVNZ 152
+#define OP_CMOVBE 153
+#define OP_CMOVNBE 154
+#define OP_CMOVS 155
+#define OP_CMOVNS 156
+#define OP_CMOVP 157
+#define OP_CMOVNP 158
+#define OP_CMOVL 159
+#define OP_CMOVNL 160
+#define OP_CMOVLE 161
+#define OP_CMOVNLE 162
+#define OP_MOVMSKPS 163
+#define OP_SQRTPS 164
+#define OP_RSQRTPS 165
+#define OP_RCPPS 166
+#define OP_ANDPS 167
+#define OP_ANDNPS 168
+#define OP_ORPS 169
+#define OP_XORPS 170
+#define OP_ADDPS 171
+#define OP_MULPS 172
+#define OP_CVTPS2PD 173
+#define OP_CVTDQ2PS 174
+#define OP_SUBPS 175
+#define OP_MINPS 176
+#define OP_DIVPS 177
+#define OP_MAXPS 178
+#define OP_PUNPCKLBW 179
+#define OP_PUNPCKLWD 180
+#define OP_PUNPCKLDQ 181
+#define OP_PACKSSWB 182
+#define OP_PCMPGTB 183
+#define OP_PCMPGTW 184
+#define OP_PCMPGTD 185
+#define OP_PACKUSWB 186
+#define OP_PUNPCKHBW 187
+#define OP_PUNPCKHWD 188
+#define OP_PUNPCKHDQ 189
+#define OP_PACKSSDW 190
+#define OP_MOVD 191
+#define OP_MOVQ 192
+#define OP_PSHUFW 193
+#define OP_3B_ESC4 194
+#define OP_3B_ESC5 195
+
+#define OP_PCMPEQB 196
+#define OP_PCMPEQW 197
+#define OP_PCMPEQD 198
+#define OP_SETO 199
+#define OP_SETNO 200
+#define OP_SETC 201
+#define OP_SETNC 202
+#define OP_SETE 203
+#define OP_SETNE 204
+#define OP_SETBE 205
+#define OP_SETNBE 206
+#define OP_SETS 207
+#define OP_SETNS 208
+#define OP_SETP 209
+#define OP_SETNP 210
+#define OP_SETL 211
+#define OP_SETNL 212
+#define OP_SETLE 213
+#define OP_SETNLE 214
+#define OP_CPUID 215
+#define OP_BT 216
+#define OP_SHLD 217
+#define OP_RSM 218
+#define OP_BTS 219
+#define OP_SHRD 220
+#define OP_GRP15 221
+#define OP_CMPXCHG 222
+#define OP_LSS 223
+#define OP_BTR 224
+#define OP_LFS 225
+#define OP_LGS 226
+#define OP_MOVZX 227
+#define OP_GRP10_INV 228
+#define OP_GRP8 229
+#define OP_BTC 230
+#define OP_BSF 231
+#define OP_BSR 232
+#define OP_MOVSX 233
+#define OP_XADD 234
+#define OP_CMPPS 235
+#define OP_MOVNTI 236
+#define OP_PINSRW 237
+#define OP_PEXTRW 238
+#define OP_SHUFPS 239
+#define OP_GRP9 240
+#define OP_BSWAP 241
+#define OP_PSRLW 242
+#define OP_PSRLD 243
+#define OP_PSRLQ 244
+#define OP_PADDQ 245
+#define OP_PMULLW 246
+#define OP_PMOVSKB 247
+#define OP_PSUBUSB 248
+#define OP_PSUBUSW 249
+#define OP_PMINUB 250
+#define OP_PAND 251
+#define OP_PADDUSB 252
+#define OP_PADDUSW 253
+#define OP_PMAXUB 254
+#define OP_PANDN 255
+#define OP_PAVGN 256
+#define OP_PSRAW 257
+#define OP_PSRAD 258
+#define OP_PAVGW 259
+#define OP_PMULHUW 260
+#define OP_PMULHW 261
+#define OP_MOVNTQ 262
+#define OP_PSUBSB 263
+#define OP_PSUBSW 264
+#define OP_PMINSW 265
+#define OP_POR 266
+#define OP_PADDSB 267
+#define OP_PADDSW 268
+#define OP_PMAXSW 269
+#define OP_PXOR 270
+#define OP_PSLLW 271
+#define OP_PSLLD 272
+#define OP_PSSQ 273
+#define OP_PMULUDQ 274
+#define OP_PADDWD 275
+#define OP_PADBW 276
+#define OP_PMASKMOVQ 277
+#define OP_PSUBB 278
+#define OP_PSUBW 279
+
+#define OP_PSUBD 281
+#define OP_PADDB 282
+#define OP_PADDW 283
+#define OP_PADDD 284
+#define OP_MOVUPD 285
+#define OP_MOVLPD 286
+#define OP_UNPCKLPD 287
+#define OP_UNPCKHPD 288
+#define OP_MOVHPD 289
+
+#define OP_MOVAPD 291
+#define OP_CVTPI2PD 292
+#define OP_MOVNTPD 293
+#define OP_CVTTPD2PI 294
+#define OP_CVTPD2PI 295
+#define OP_UCOMISD 296
+#define OP_COMISD 297
+#define OP_MOVMSKPD 298
+#define OP_SQRTPD 299
+#define OP_ANDPD 301
+#define OP_ANDNPD 302
+#define OP_ORPD 303
+#define OP_XORPD 304
+#define OP_ADDPD 305
+#define OP_MULPD 306
+#define OP_CVTPD2PS 307
+#define OP_CVTPS2DQ 308
+#define OP_SUBPD 309
+#define OP_MINPD 310
+#define OP_DIVPD 311
+#define OP_MAXPD 312
+
+#define OP_GRP12 313
+#define OP_GRP13 314
+#define OP_GRP14 315
+#define OP_EMMS 316
+#define OP_MMX_UD78 317
+#define OP_MMX_UD79 318
+#define OP_MMX_UD7A 319
+#define OP_MMX_UD7B 320
+#define OP_MMX_UD7C 321
+#define OP_MMX_UD7D 322
+
+
+#define OP_PUNPCKLQDQ 325
+#define OP_PUNPCKHQD 326
+
+#define OP_MOVDQA 328
+#define OP_PSHUFD 329
+
+
+
+#define OP_CMPPD 334
+#define OP_SHUFPD 337
+
+
+#define OP_CVTTPD2DQ 353
+#define OP_MOVNTDQ 354
+
+#define OP_PSHUFB 355
+#define OP_PHADDW 356
+#define OP_PHADDD 357
+#define OP_PHADDSW 358
+#define OP_PMADDUBSW 359
+#define OP_PHSUBW 360
+#define OP_PHSUBD 361
+#define OP_PHSUBSW 362
+#define OP_PSIGNB 363
+#define OP_PSIGNW 364
+#define OP_PSIGND 365
+#define OP_PMULHRSW 366
+#define OP_PBLENDVB 367
+#define OP_BLENDVPS 368
+#define OP_BLENDVPD 369
+#define OP_PTEST 370
+#define OP_PABSB 371
+#define OP_PABSW 372
+#define OP_PABSD 373
+
+#define OP_PMASKMOVDQU 376
+#define OP_MOVSD 377
+#define OP_CVTSI2SD 378
+#define OP_CVTTSD2SI 379
+#define OP_CVTSD2SI 380
+#define OP_SQRTSD 381
+#define OP_ADDSD 382
+#define OP_MULSD 383
+#define OP_CVTSD2SS 384
+#define OP_SUBSD 385
+#define OP_MINSD 386
+#define OP_DIVSD 387
+#define OP_MAXSD 388
+#define OP_PSHUFLW 389
+#define OP_CMPSD 390
+#define OP_MOVDQ2Q 391
+#define OP_CVTPD2DQ 392
+#define OP_MOVSS 393
+#define OP_CVTSI2SS 394
+#define OP_CVTTSS2SI 395
+#define OP_CVTSS2SI 396
+#define OP_SQRTSS 397
+#define OP_RSQRTSS 398
+#define OP_ADDSS 399
+#define OP_MULSS 401
+#define OP_CVTTPS2DQ 403
+#define OP_SUBSS 404
+#define OP_MINSS 405
+#define OP_DIVSS 406
+#define OP_MAXSS 407
+#define OP_MOVDQU 408
+#define OP_PSHUFHW 409
+#define OP_CMPSS 410
+#define OP_MOVQ2DQ 411
+#define OP_CVTDQ2PD 412
+/** @} */
+
+/** @name Floating point ops
+ * @{
+ */
+#define OP_FADD 413
+#define OP_FMUL 414
+#define OP_FCOM 415
+#define OP_FCOMP 416
+#define OP_FSUB 417
+#define OP_FSUBR 418
+#define OP_FDIV 419
+#define OP_FDIVR 420
+#define OP_FLD 421
+#define OP_FST 422
+#define OP_FSTP 423
+#define OP_FLDENV 424
+
+#define OP_FSTENV 426
+#define OP_FSTCW 427
+#define OP_FXCH 428
+#define OP_FNOP 429
+#define OP_FCHS 430
+#define OP_FABS 431
+
+#define OP_FLD1 433
+#define OP_FLDL2T 434
+#define OP_FLDL2E 435
+#define OP_FLDPI 436
+#define OP_FLDLG2 437
+#define OP_FLDLN2 438
+#define OP_FLDZ 439
+#define OP_F2XM1 440
+#define OP_FYL2X 441
+#define OP_FPTAN 442
+#define OP_FPATAN 443
+#define OP_FXTRACT 444
+#define OP_FREM1 445
+#define OP_FDECSTP 446
+#define OP_FINCSTP 447
+#define OP_FPREM 448
+#define OP_FYL2XP1 449
+#define OP_FSQRT 450
+#define OP_FSINCOS 451
+#define OP_FRNDINT 452
+#define OP_FSCALE 453
+#define OP_FSIN 454
+#define OP_FCOS 455
+#define OP_FIADD 456
+#define OP_FIMUL 457
+#define OP_FISUB 460
+#define OP_FISUBR 461
+#define OP_FIDIV 462
+#define OP_FIDIVR 463
+#define OP_FCMOVB 464
+#define OP_FCMOVE 465
+#define OP_FCMOVBE 466
+#define OP_FCMOVU 467
+#define OP_FUCOMPP 468
+#define OP_FILD 469
+#define OP_FIST 470
+#define OP_FISTP 471
+#define OP_FCMOVNB 474
+#define OP_FCMOVNE 475
+#define OP_FCMOVNBE 476
+#define OP_FCMOVNU 477
+#define OP_FCLEX 478
+#define OP_FINIT 479
+#define OP_FUCOMI 480
+#define OP_FCOMI 481
+#define OP_FRSTOR 482
+#define OP_FSAVE 483
+#define OP_FNSTSW 484
+#define OP_FFREE 485
+#define OP_FUCOM 486
+#define OP_FUCOMP 487
+#define OP_FICOM 490
+#define OP_FICOMP 491
+#define OP_FADDP 496
+#define OP_FMULP 497
+#define OP_FCOMPP 498
+#define OP_FSUBRP 499
+#define OP_FSUBP 500
+#define OP_FDIVRP 501
+#define OP_FDIVP 502
+#define OP_FBLD 503
+#define OP_FBSTP 504
+#define OP_FCOMIP 506
+#define OP_FUCOMIP 507
+/** @} */
+
+/** @name 3DNow!
+ * @{
+ */
+#define OP_PI2FW 508
+#define OP_PI2FD 509
+#define OP_PF2IW 510
+#define OP_PF2ID 511
+#define OP_PFPNACC 512
+#define OP_PFCMPGE 513
+#define OP_PFMIN 514
+#define OP_PFRCP 515
+#define OP_PFRSQRT 516
+#define OP_PFSUB 517
+#define OP_PFADD 518
+#define OP_PFCMPGT 519
+#define OP_PFMAX 520
+#define OP_PFRCPIT1 521
+#define OP_PFRSQRTIT1 522
+#define OP_PFSUBR 523
+#define OP_PFACC 524
+#define OP_PFCMPEQ 525
+#define OP_PFMUL 526
+#define OP_PFRCPIT2 527
+#define OP_PFMULHRW 528
+#define OP_PFSWAPD 529
+#define OP_PAVGUSB 530
+#define OP_PFNACC 531
+#define OP_ROL 532
+#define OP_ROR 533
+#define OP_RCL 534
+#define OP_RCR 535
+#define OP_SHL 536
+#define OP_SHR 537
+#define OP_SAR 538
+#define OP_NOT 539
+#define OP_NEG 540
+#define OP_MUL 541
+#define OP_DIV 542
+#define OP_IDIV 543
+#define OP_SLDT 544
+#define OP_STR 545
+#define OP_LLDT 546
+#define OP_LTR 547
+#define OP_VERR 548
+#define OP_VERW 549
+#define OP_SGDT 550
+#define OP_LGDT 551
+#define OP_SIDT 552
+#define OP_LIDT 553
+#define OP_SMSW 554
+#define OP_LMSW 555
+#define OP_INVLPG 556
+#define OP_CMPXCHG8B 557
+#define OP_PSLLQ 558
+#define OP_PSRLDQ 559
+#define OP_PSLLDQ 560
+#define OP_FXSAVE 561
+#define OP_FXRSTOR 562
+#define OP_LDMXCSR 563
+#define OP_STMXCSR 564
+#define OP_LFENCE 565
+#define OP_MFENCE 566
+#define OP_SFENCE 567
+#define OP_PREFETCH 568
+#define OP_MONITOR 569
+#define OP_MWAIT 570
+#define OP_CLFLUSH 571
+
+#define OP_MOV_DR 600
+#define OP_MOV_TR 601
+
+#define OP_SWAPGS 610
+
+/** @name VT-x instructions
+ * @{ */
+#define OP_VMREAD 650
+#define OP_VMWRITE 651
+#define OP_VMCALL 652
+#define OP_VMXON 653
+#define OP_VMXOFF 654
+#define OP_VMCLEAR 655
+#define OP_VMLAUNCH 656
+#define OP_VMRESUME 657
+#define OP_VMPTRLD 658
+#define OP_VMPTRST 659
+#define OP_INVEPT 660
+#define OP_INVVPID 661
+/** @} */
+
+/** @name 64 bits instruction
+ * @{ */
+#define OP_MOVSXD 700
+/** @} */
+
+/** @} */
+
+
+/** @defgroup grp_dis_opparam Opcode parameters (DISOPCODE::fParam1,
+ * DISOPCODE::fParam2, DISOPCODE::fParam3)
+ * @ingroup grp_dis
+ * @{
+ */
+
+/* NOTE: Register order is important for translations!! */
+#define OP_PARM_NONE 0
+#define OP_PARM_REG_EAX 1
+#define OP_PARM_REG_GEN32_START OP_PARM_REG_EAX
+#define OP_PARM_REG_ECX 2
+#define OP_PARM_REG_EDX 3
+#define OP_PARM_REG_EBX 4
+#define OP_PARM_REG_ESP 5
+#define OP_PARM_REG_EBP 6
+#define OP_PARM_REG_ESI 7
+#define OP_PARM_REG_EDI 8
+#define OP_PARM_REG_GEN32_END OP_PARM_REG_EDI
+
+#define OP_PARM_REG_ES 9
+#define OP_PARM_REG_SEG_START OP_PARM_REG_ES
+#define OP_PARM_REG_CS 10
+#define OP_PARM_REG_SS 11
+#define OP_PARM_REG_DS 12
+#define OP_PARM_REG_FS 13
+#define OP_PARM_REG_GS 14
+#define OP_PARM_REG_SEG_END OP_PARM_REG_GS
+
+#define OP_PARM_REG_AX 15
+#define OP_PARM_REG_GEN16_START OP_PARM_REG_AX
+#define OP_PARM_REG_CX 16
+#define OP_PARM_REG_DX 17
+#define OP_PARM_REG_BX 18
+#define OP_PARM_REG_SP 19
+#define OP_PARM_REG_BP 20
+#define OP_PARM_REG_SI 21
+#define OP_PARM_REG_DI 22
+#define OP_PARM_REG_GEN16_END OP_PARM_REG_DI
+
+#define OP_PARM_REG_AL 23
+#define OP_PARM_REG_GEN8_START OP_PARM_REG_AL
+#define OP_PARM_REG_CL 24
+#define OP_PARM_REG_DL 25
+#define OP_PARM_REG_BL 26
+#define OP_PARM_REG_AH 27
+#define OP_PARM_REG_CH 28
+#define OP_PARM_REG_DH 29
+#define OP_PARM_REG_BH 30
+#define OP_PARM_REG_GEN8_END OP_PARM_REG_BH
+
+#define OP_PARM_REGFP_0 31
+#define OP_PARM_REG_FP_START OP_PARM_REGFP_0
+#define OP_PARM_REGFP_1 32
+#define OP_PARM_REGFP_2 33
+#define OP_PARM_REGFP_3 34
+#define OP_PARM_REGFP_4 35
+#define OP_PARM_REGFP_5 36
+#define OP_PARM_REGFP_6 37
+#define OP_PARM_REGFP_7 38
+#define OP_PARM_REG_FP_END OP_PARM_REGFP_7
+
+#define OP_PARM_NTA 39
+#define OP_PARM_T0 40
+#define OP_PARM_T1 41
+#define OP_PARM_T2 42
+
+#define OP_PARM_1 43
+
+#define OP_PARM_REX 50
+#define OP_PARM_REX_START OP_PARM_REX
+#define OP_PARM_REX_B 51
+#define OP_PARM_REX_X 52
+#define OP_PARM_REX_XB 53
+#define OP_PARM_REX_R 54
+#define OP_PARM_REX_RB 55
+#define OP_PARM_REX_RX 56
+#define OP_PARM_REX_RXB 57
+#define OP_PARM_REX_W 58
+#define OP_PARM_REX_WB 59
+#define OP_PARM_REX_WX 60
+#define OP_PARM_REX_WXB 61
+#define OP_PARM_REX_WR 62
+#define OP_PARM_REX_WRB 63
+#define OP_PARM_REX_WRX 64
+#define OP_PARM_REX_WRXB 65
+
+#define OP_PARM_REG_RAX 100
+#define OP_PARM_REG_GEN64_START OP_PARM_REG_RAX
+#define OP_PARM_REG_RCX 101
+#define OP_PARM_REG_RDX 102
+#define OP_PARM_REG_RBX 103
+#define OP_PARM_REG_RSP 104
+#define OP_PARM_REG_RBP 105
+#define OP_PARM_REG_RSI 106
+#define OP_PARM_REG_RDI 107
+#define OP_PARM_REG_R8 108
+#define OP_PARM_REG_R9 109
+#define OP_PARM_REG_R10 110
+#define OP_PARM_REG_R11 111
+#define OP_PARM_REG_R12 112
+#define OP_PARM_REG_R13 113
+#define OP_PARM_REG_R14 114
+#define OP_PARM_REG_R15 115
+#define OP_PARM_REG_GEN64_END OP_PARM_REG_R15
+
+
+#define OP_PARM_VTYPE(a) ((unsigned)a & 0xFE0)
+#define OP_PARM_VSUBTYPE(a) ((unsigned)a & 0x01F)
+
+#define OP_PARM_A 0x100
+#define OP_PARM_VARIABLE OP_PARM_A
+#define OP_PARM_E 0x120
+#define OP_PARM_F 0x140
+#define OP_PARM_G 0x160
+#define OP_PARM_I 0x180
+#define OP_PARM_J 0x1A0
+#define OP_PARM_M 0x1C0
+#define OP_PARM_O 0x1E0
+#define OP_PARM_R 0x200
+#define OP_PARM_X 0x220
+#define OP_PARM_Y 0x240
+
+/* Grouped rare parameters for optimization purposes */
+#define IS_OP_PARM_RARE(a) ((a & 0xF00) == 0x300)
+#define OP_PARM_C 0x300 /* control register */
+#define OP_PARM_D 0x320 /* debug register */
+#define OP_PARM_S 0x340 /* segment register */
+#define OP_PARM_T 0x360 /* test register */
+#define OP_PARM_Q 0x380
+#define OP_PARM_P 0x3A0 /* mmx register */
+#define OP_PARM_W 0x3C0 /* xmm register */
+#define OP_PARM_V 0x3E0
+
+#define OP_PARM_NONE 0
+#define OP_PARM_a 0x1
+#define OP_PARM_b 0x2
+#define OP_PARM_d 0x3
+#define OP_PARM_dq 0x4
+#define OP_PARM_p 0x5
+#define OP_PARM_pd 0x6
+#define OP_PARM_pi 0x7
+#define OP_PARM_ps 0x8
+#define OP_PARM_pq 0x9
+#define OP_PARM_q 0xA
+#define OP_PARM_s 0xB
+#define OP_PARM_sd 0xC
+#define OP_PARM_ss 0xD
+#define OP_PARM_v 0xE
+#define OP_PARM_w 0xF
+#define OP_PARM_z 0x10
+
+
+#define OP_PARM_Ap (OP_PARM_A+OP_PARM_p)
+#define OP_PARM_Cd (OP_PARM_C+OP_PARM_d)
+#define OP_PARM_Dd (OP_PARM_D+OP_PARM_d)
+#define OP_PARM_Eb (OP_PARM_E+OP_PARM_b)
+#define OP_PARM_Ed (OP_PARM_E+OP_PARM_d)
+#define OP_PARM_Ep (OP_PARM_E+OP_PARM_p)
+#define OP_PARM_Ev (OP_PARM_E+OP_PARM_v)
+#define OP_PARM_Ew (OP_PARM_E+OP_PARM_w)
+#define OP_PARM_Fv (OP_PARM_F+OP_PARM_v)
+#define OP_PARM_Gb (OP_PARM_G+OP_PARM_b)
+#define OP_PARM_Gd (OP_PARM_G+OP_PARM_d)
+#define OP_PARM_Gv (OP_PARM_G+OP_PARM_v)
+#define OP_PARM_Gw (OP_PARM_G+OP_PARM_w)
+#define OP_PARM_Ib (OP_PARM_I+OP_PARM_b)
+#define OP_PARM_Id (OP_PARM_I+OP_PARM_d)
+#define OP_PARM_Iq (OP_PARM_I+OP_PARM_q)
+#define OP_PARM_Iw (OP_PARM_I+OP_PARM_w)
+#define OP_PARM_Iv (OP_PARM_I+OP_PARM_v)
+#define OP_PARM_Iz (OP_PARM_I+OP_PARM_z)
+#define OP_PARM_Jb (OP_PARM_J+OP_PARM_b)
+#define OP_PARM_Jv (OP_PARM_J+OP_PARM_v)
+#define OP_PARM_Ma (OP_PARM_M+OP_PARM_a)
+#define OP_PARM_Mb (OP_PARM_M+OP_PARM_b)
+#define OP_PARM_Mw (OP_PARM_M+OP_PARM_w)
+#define OP_PARM_Md (OP_PARM_M+OP_PARM_d)
+#define OP_PARM_Mp (OP_PARM_M+OP_PARM_p)
+#define OP_PARM_Mq (OP_PARM_M+OP_PARM_q)
+#define OP_PARM_Mdq (OP_PARM_M+OP_PARM_dq)
+#define OP_PARM_Ms (OP_PARM_M+OP_PARM_s)
+#define OP_PARM_Ob (OP_PARM_O+OP_PARM_b)
+#define OP_PARM_Ov (OP_PARM_O+OP_PARM_v)
+#define OP_PARM_Pq (OP_PARM_P+OP_PARM_q)
+#define OP_PARM_Pd (OP_PARM_P+OP_PARM_d)
+#define OP_PARM_Qd (OP_PARM_Q+OP_PARM_d)
+#define OP_PARM_Qq (OP_PARM_Q+OP_PARM_q)
+#define OP_PARM_Rd (OP_PARM_R+OP_PARM_d)
+#define OP_PARM_Rw (OP_PARM_R+OP_PARM_w)
+#define OP_PARM_Sw (OP_PARM_S+OP_PARM_w)
+#define OP_PARM_Td (OP_PARM_T+OP_PARM_d)
+#define OP_PARM_Vq (OP_PARM_V+OP_PARM_q)
+#define OP_PARM_Wq (OP_PARM_W+OP_PARM_q)
+#define OP_PARM_Ws (OP_PARM_W+OP_PARM_s)
+#define OP_PARM_Xb (OP_PARM_X+OP_PARM_b)
+#define OP_PARM_Xv (OP_PARM_X+OP_PARM_v)
+#define OP_PARM_Yb (OP_PARM_Y+OP_PARM_b)
+#define OP_PARM_Yv (OP_PARM_Y+OP_PARM_v)
+
+#define OP_PARM_Vps (OP_PARM_V+OP_PARM_ps)
+#define OP_PARM_Vss (OP_PARM_V+OP_PARM_ss)
+#define OP_PARM_Vpd (OP_PARM_V+OP_PARM_pd)
+#define OP_PARM_Vdq (OP_PARM_V+OP_PARM_dq)
+#define OP_PARM_Wps (OP_PARM_W+OP_PARM_ps)
+#define OP_PARM_Wpd (OP_PARM_W+OP_PARM_pd)
+#define OP_PARM_Wss (OP_PARM_W+OP_PARM_ss)
+#define OP_PARM_Wdq (OP_PARM_W+OP_PARM_dq)
+#define OP_PARM_Ppi (OP_PARM_P+OP_PARM_pi)
+#define OP_PARM_Qpi (OP_PARM_Q+OP_PARM_pi)
+#define OP_PARM_Qdq (OP_PARM_Q+OP_PARM_dq)
+#define OP_PARM_Vsd (OP_PARM_V+OP_PARM_sd)
+#define OP_PARM_Wsd (OP_PARM_W+OP_PARM_sd)
+#define OP_PARM_Vpq (OP_PARM_V+OP_PARM_pq)
+#define OP_PARM_Pdq (OP_PARM_P+OP_PARM_dq)
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/err.h b/include/VBox/err.h
new file mode 100644
index 00000000..3fae9bc9
--- /dev/null
+++ b/include/VBox/err.h
@@ -0,0 +1,2233 @@
+/** @file
+ * VirtualBox Status Codes.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_err_h
+#define ___VBox_err_h
+
+#include <VBox/cdefs.h>
+#include <iprt/err.h>
+
+
+/** @defgroup grp_err Error Codes
+ * @{
+ */
+
+/* SED-START */
+
+/** @name Misc. Status Codes
+ * @{
+ */
+/** Failed to allocate VM memory. */
+#define VERR_NO_VM_MEMORY (-1000)
+/** RC is toasted and the VMM should be terminated at once, but no need to
+ * panic about it :-) */
+#define VERR_DONT_PANIC (-1001)
+/** Unsupported CPU. */
+#define VERR_UNSUPPORTED_CPU (-1002)
+/** Unsupported CPU mode. */
+#define VERR_UNSUPPORTED_CPU_MODE (-1003)
+/** Page not present. */
+#define VERR_PAGE_NOT_PRESENT (-1004)
+/** Invalid/Corrupted configuration file. */
+#define VERR_CFG_INVALID_FORMAT (-1005)
+/** No configuration value exists. */
+#define VERR_CFG_NO_VALUE (-1006)
+/** Selector not present. */
+#define VERR_SELECTOR_NOT_PRESENT (-1007)
+/** Not code selector. */
+#define VERR_NOT_CODE_SELECTOR (-1008)
+/** Not data selector. */
+#define VERR_NOT_DATA_SELECTOR (-1009)
+/** Out of selector bounds. */
+#define VERR_OUT_OF_SELECTOR_BOUNDS (-1010)
+/** Invalid selector. Usually beyond table limits. */
+#define VERR_INVALID_SELECTOR (-1011)
+/** Invalid requested privilegde level. */
+#define VERR_INVALID_RPL (-1012)
+/** PML4 entry not present. */
+#define VERR_PAGE_MAP_LEVEL4_NOT_PRESENT (-1013)
+/** Page directory pointer not present. */
+#define VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT (-1014)
+/** Raw mode doesn't support SMP. */
+#define VERR_RAW_MODE_INVALID_SMP (-1015)
+/** Invalid VM handle. */
+#define VERR_INVALID_VM_HANDLE (-1016)
+/** Invalid VM handle. */
+#define VERR_INVALID_VMCPU_HANDLE (-1017)
+/** Invalid Virtual CPU ID. */
+#define VERR_INVALID_CPU_ID (-1018)
+/** Too many VCPUs. */
+#define VERR_TOO_MANY_CPUS (-1019)
+/** The service was disabled on the host.
+ * Returned by pfnInit in VBoxService to indicated a non-fatal error that
+ * should results in the particular service being disabled. */
+#define VERR_SERVICE_DISABLED (-1020)
+/** @} */
+
+
+/** @name Execution Monitor/Manager (EM) Status Codes
+ *
+ * The order of the status codes between VINF_EM_FIRST and VINF_EM_LAST
+ * are of vital importance. The lower the number the higher importance
+ * as a scheduling instruction.
+ * @{
+ */
+/** First scheduling related status code. */
+#define VINF_EM_FIRST 1100
+/** Indicating that the VM is being terminated and that the the execution
+ * shall stop. */
+#define VINF_EM_TERMINATE 1100
+/** Hypervisor code was stepped.
+ * EM will first send this to the debugger, and if the issue isn't
+ * resolved there it will enter guru meditation. */
+#define VINF_EM_DBG_HYPER_STEPPED 1101
+/** Hit a breakpoint in the hypervisor code,
+ * EM will first send this to the debugger, and if the issue isn't
+ * resolved there it will enter guru meditation. */
+#define VINF_EM_DBG_HYPER_BREAKPOINT 1102
+/** Hit a possible assertion in the hypervisor code,
+ * EM will first send this to the debugger, and if the issue isn't
+ * resolved there it will enter guru meditation. */
+#define VINF_EM_DBG_HYPER_ASSERTION 1103
+/** Indicating that the VM should be suspended for debugging because
+ * the developer wants to inspect the VM state. */
+#define VINF_EM_DBG_STOP 1105
+/** Indicating success single stepping and that EM should report that
+ * event to the debugger. */
+#define VINF_EM_DBG_STEPPED 1106
+/** Indicating that a breakpoint was hit and that EM should notify the debugger
+ * and in the event there is no debugger fail fatally. */
+#define VINF_EM_DBG_BREAKPOINT 1107
+/** Indicating that EM should single step an instruction.
+ * The instruction is stepped in the current execution mode (RAW/REM). */
+#define VINF_EM_DBG_STEP 1108
+/** Indicating that the VM is being turned off and that the EM should
+ * exit to the VM awaiting the destruction request. */
+#define VINF_EM_OFF 1109
+/** Indicating that the VM has been suspended and that the the thread
+ * should wait for request telling it what to do next. */
+#define VINF_EM_SUSPEND 1110
+/** Indicating that the VM has been reset and that scheduling goes
+ * back to startup defaults. */
+#define VINF_EM_RESET 1111
+/** Indicating that the VM has executed a halt instruction and that
+ * the emulation thread should wait for an interrupt before resuming
+ * execution. */
+#define VINF_EM_HALT 1112
+/** Indicating that the VM has been resumed and that the thread should
+ * start executing. */
+#define VINF_EM_RESUME 1113
+/** Indicating that we've got an out-of-memory condition and that we need
+ * to take the appropriate actions to deal with this.
+ * @remarks It might seem odd at first that this has lower priority than VINF_EM_HALT,
+ * VINF_EM_SUSPEND, and VINF_EM_RESUME. The reason is that these events are
+ * vital to correctly operating the VM. Also, they can't normally occur together
+ * with an out-of-memory condition, and even if that should happen the condition
+ * will be rediscovered before executing any more code. */
+#define VINF_EM_NO_MEMORY 1114
+/** The fatal variant of VINF_EM_NO_MEMORY. */
+#define VERR_EM_NO_MEMORY (-1114)
+/** Indicating that a rescheduling to recompiled execution.
+ * Typically caused by raw-mode executing code which is difficult/slow
+ * to virtualize rawly.
+ * @remarks Important to have a higher priority (lower number) than the other rescheduling status codes. */
+#define VINF_EM_RESCHEDULE_REM 1115
+/** Indicating that a rescheduling to vmx-mode execution.
+ * Typically caused by REM detecting that hardware-accelerated raw-mode execution is possible. */
+#define VINF_EM_RESCHEDULE_HWACC 1116
+/** Indicating that a rescheduling to raw-mode execution.
+ * Typically caused by REM detecting that raw-mode execution is possible.
+ * @remarks Important to have a higher priority (lower number) than VINF_EM_RESCHEDULE. */
+#define VINF_EM_RESCHEDULE_RAW 1117
+/** Indicating that a rescheduling now is required. Typically caused by
+ * interrupts having changed the EIP. */
+#define VINF_EM_RESCHEDULE 1118
+/** PARAV call */
+#define VINF_EM_RESCHEDULE_PARAV 1119
+/** Go back into wait for SIPI mode */
+#define VINF_EM_WAIT_SIPI 1120
+/** Last scheduling related status code. (inclusive) */
+#define VINF_EM_LAST 1120
+
+/** Reason for leaving RC: Guest trap which couldn't be handled in RC.
+ * The trap is generally forwarded to the REM and executed there. */
+#define VINF_EM_RAW_GUEST_TRAP 1121
+/** Reason for leaving RC: Interrupted by external interrupt.
+ * The interrupt needed to be handled by the host OS. */
+#define VINF_EM_RAW_INTERRUPT 1122
+/** Reason for leaving RC: Interrupted by external interrupt while in hypervisor
+ * code. The interrupt needed to be handled by the host OS and hypervisor
+ * execution must be resumed. VM state is not complete at this point. */
+#define VINF_EM_RAW_INTERRUPT_HYPER 1123
+/** Reason for leaving RC: A Ring switch was attempted.
+ * Normal cause of action is to execute this in REM. */
+#define VINF_EM_RAW_RING_SWITCH 1124
+/** Reason for leaving RC: A Ring switch was attempted using software interrupt.
+ * Normal cause of action is to execute this in REM. */
+#define VINF_EM_RAW_RING_SWITCH_INT 1125
+/** Reason for leaving RC: A privileged instruction was attempted executed.
+ * Normal cause of action is to execute this in REM. */
+#define VINF_EM_RAW_EXCEPTION_PRIVILEGED 1126
+
+/** Reason for leaving RZ: Emulate instruction. */
+#define VINF_EM_RAW_EMULATE_INSTR 1127
+/** Reason for leaving RC: Unhandled TSS write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT 1128
+/** Reason for leaving RC: Unhandled LDT write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT 1129
+/** Reason for leaving RC: Unhandled IDT write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT 1130
+/** Reason for leaving RC: Unhandled GDT write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT 1131
+/** Reason for leaving RC: Unhandled Page Directory write.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_PD_FAULT 1132
+/** Reason for leaving RC: jump inside generated patch jump.
+ * Fatal error. */
+#define VERR_EM_RAW_PATCH_CONFLICT (-1133)
+/** Reason for leaving RC: Hlt instruction.
+ * Recompiler gets control. */
+#define VINF_EM_RAW_EMULATE_INSTR_HLT 1134
+/** Reason for leaving RZ: Ring-3 operation pending. */
+#define VINF_EM_RAW_TO_R3 1135
+/** Reason for leaving RZ: Timer pending. */
+#define VINF_EM_RAW_TIMER_PENDING 1136
+/** Reason for leaving RC: Interrupt pending (guest). */
+#define VINF_EM_RAW_INTERRUPT_PENDING 1137
+/** Reason for leaving RC: Encountered a stale selector. */
+#define VINF_EM_RAW_STALE_SELECTOR 1138
+/** Reason for leaving RC: The IRET resuming guest code trapped. */
+#define VINF_EM_RAW_IRET_TRAP 1139
+/** Reason for leaving RC: Emulate (MM)IO intensive code in the recompiler. */
+#define VINF_EM_RAW_EMULATE_IO_BLOCK 1140
+/** The interpreter was unable to deal with the instruction at hand. */
+#define VERR_EM_INTERPRETER (-1148)
+/** Internal EM error caused by an unknown warning or informational status code. */
+#define VERR_EM_INTERNAL_ERROR (-1149)
+/** Pending VM request packet. */
+#define VINF_EM_PENDING_REQUEST 1150
+/** Start instruction stepping (debug only). */
+#define VINF_EM_RAW_EMULATE_DBG_STEP 1151
+/** Patch TPR access instruction. */
+#define VINF_EM_HWACCM_PATCH_TPR_INSTR 1152
+/** The EMInterpretDisasOne / EMInterpretDisasOneEx methods failed to
+ * disassemble the instruction. */
+#define VERR_EM_INTERNAL_DISAS_ERROR (-1153)
+/** Unexpected guest mapping conflict detected. */
+#define VERR_EM_UNEXPECTED_MAPPING_CONFLICT (-1154)
+/** @} */
+
+
+/** @name Debugging Facility (DBGF) DBGF Status Codes
+ * @{
+ */
+/** The function called requires the caller to be attached as a
+ * debugger to the VM. */
+#define VERR_DBGF_NOT_ATTACHED (-1200)
+/** Someone (including the caller) was already attached as
+ * debugger to the VM. */
+#define VERR_DBGF_ALREADY_ATTACHED (-1201)
+/** Tried to hald a debugger which was already halted.
+ * (This is a warning and not an error.) */
+#define VWRN_DBGF_ALREADY_HALTED 1202
+/** The DBGF has no more free breakpoint slots. */
+#define VERR_DBGF_NO_MORE_BP_SLOTS (-1203)
+/** The DBGF couldn't find the specified breakpoint. */
+#define VERR_DBGF_BP_NOT_FOUND (-1204)
+/** Attempted to enabled a breakpoint which was already enabled. */
+#define VINF_DBGF_BP_ALREADY_ENABLED 1205
+/** Attempted to disabled a breakpoint which was already disabled. */
+#define VINF_DBGF_BP_ALREADY_DISABLED 1206
+/** The breakpoint already exists. */
+#define VINF_DBGF_BP_ALREADY_EXIST 1207
+/** The byte string was not found. */
+#define VERR_DBGF_MEM_NOT_FOUND (-1208)
+/** The OS was not detected. */
+#define VERR_DBGF_OS_NOT_DETCTED (-1209)
+/** The OS was not detected. */
+#define VINF_DBGF_OS_NOT_DETCTED 1209
+/** The specified register was not found. */
+#define VERR_DBGF_REGISTER_NOT_FOUND (-1210)
+/** The value was truncated to fit.
+ * For queries this means that the register is wider than the queried value.
+ * For setters this means that the value is wider than the register. */
+#define VINF_DBGF_TRUNCATED_REGISTER 1211
+/** The value was zero extended to fit.
+ * For queries this means that the register is narrower than the queried value.
+ * For setters this means that the value is narrower than the register. */
+#define VINF_DBGF_ZERO_EXTENDED_REGISTER 1212
+/** The requested type conversion was not supported. */
+#define VERR_DBGF_UNSUPPORTED_CAST (-1213)
+/** The register is read-only and cannot be modified. */
+#define VERR_DBGF_READ_ONLY_REGISTER (-1214)
+/** Internal processing error \#1 in the DBGF register code. */
+#define VERR_DBGF_REG_IPE_1 (-1215)
+/** Internal processing error \#2 in the DBGF register code. */
+#define VERR_DBGF_REG_IPE_2 (-1216)
+/** Unhandled \#DB in hypervisor code. */
+#define VERR_DBGF_HYPER_DB_XCPT (-1217)
+/** Internal processing error \#1 in the DBGF stack code. */
+#define VERR_DBGF_STACK_IPE_1 (-1218)
+/** Internal processing error \#2 in the DBGF stack code. */
+#define VERR_DBGF_STACK_IPE_2 (-1219)
+/** No trace buffer available, please change the VM config. */
+#define VERR_DBGF_NO_TRACE_BUFFER (-1220)
+/** @} */
+
+
+/** @name Patch Manager (PATM) Status Codes
+ * @{
+ */
+/** Non fatal Patch Manager analysis phase warning */
+#define VWRN_CONTINUE_ANALYSIS 1400
+/** Non fatal Patch Manager recompile phase warning (mapped to VWRN_CONTINUE_ANALYSIS). */
+#define VWRN_CONTINUE_RECOMPILE VWRN_CONTINUE_ANALYSIS
+/** Continue search (mapped to VWRN_CONTINUE_ANALYSIS). */
+#define VWRN_PATM_CONTINUE_SEARCH VWRN_CONTINUE_ANALYSIS
+/** Patch installation refused (patch too complex or unsupported instructions ) */
+#define VERR_PATCHING_REFUSED (-1401)
+/** Unable to find patch */
+#define VERR_PATCH_NOT_FOUND (-1402)
+/** Patch disabled */
+#define VERR_PATCH_DISABLED (-1403)
+/** Patch enabled */
+#define VWRN_PATCH_ENABLED 1404
+/** Patch was already disabled */
+#define VERR_PATCH_ALREADY_DISABLED (-1405)
+/** Patch was already enabled */
+#define VERR_PATCH_ALREADY_ENABLED (-1406)
+/** Patch was removed. */
+#define VWRN_PATCH_REMOVED 1407
+
+/** Reason for leaving RC: \#GP with EIP pointing to patch code. */
+#define VINF_PATM_PATCH_TRAP_GP 1408
+/** First leave RC code. */
+#define VINF_PATM_LEAVE_RC_FIRST VINF_PATM_PATCH_TRAP_GP
+/** Reason for leaving RC: \#PF with EIP pointing to patch code. */
+#define VINF_PATM_PATCH_TRAP_PF 1409
+/** Reason for leaving RC: int3 with EIP pointing to patch code. */
+#define VINF_PATM_PATCH_INT3 1410
+/** Reason for leaving RC: \#PF for monitored patch page. */
+#define VINF_PATM_CHECK_PATCH_PAGE 1411
+/** Reason for leaving RC: duplicate instruction called at current eip. */
+#define VINF_PATM_DUPLICATE_FUNCTION 1412
+/** Execute one instruction with the recompiler */
+#define VINF_PATCH_EMULATE_INSTR 1413
+/** Reason for leaving RC: attempt to patch MMIO write. */
+#define VINF_PATM_HC_MMIO_PATCH_WRITE 1414
+/** Reason for leaving RC: attempt to patch MMIO read. */
+#define VINF_PATM_HC_MMIO_PATCH_READ 1415
+/** Reason for leaving RC: pending irq after iret that sets IF. */
+#define VINF_PATM_PENDING_IRQ_AFTER_IRET 1416
+/** Last leave RC code. */
+#define VINF_PATM_LEAVE_RC_LAST VINF_PATM_PENDING_IRQ_AFTER_IRET
+
+/** No conflicts to resolve */
+#define VERR_PATCH_NO_CONFLICT (-1425)
+/** Detected unsafe code for patching */
+#define VERR_PATM_UNSAFE_CODE (-1426)
+/** Terminate search branch */
+#define VWRN_PATCH_END_BRANCH 1427
+/** Already patched */
+#define VERR_PATM_ALREADY_PATCHED (-1428)
+/** Spinlock detection failed. */
+#define VINF_PATM_SPINLOCK_FAILED (1429)
+/** Continue execution after patch trap. */
+#define VINF_PATCH_CONTINUE (1430)
+
+/** @} */
+
+
+/** @name Code Scanning and Analysis Manager (CSAM) Status Codes
+ * @{
+ */
+/** Trap not handled */
+#define VWRN_CSAM_TRAP_NOT_HANDLED 1500
+/** Patch installed */
+#define VWRN_CSAM_INSTRUCTION_PATCHED 1501
+/** Page record not found */
+#define VWRN_CSAM_PAGE_NOT_FOUND 1502
+/** Reason for leaving RC: CSAM wants perform a task in ring-3. */
+#define VINF_CSAM_PENDING_ACTION 1503
+/** @} */
+
+
+/** @name Page Monitor/Manager (PGM) Status Codes
+ * @{
+ */
+/** Attempt to create a GC mapping which conflicts with an existing mapping. */
+#define VERR_PGM_MAPPING_CONFLICT (-1600)
+/** The physical handler range has no corresponding RAM range.
+ * If this is MMIO, see todo above the return. If not MMIO, then it's
+ * someone else's fault... */
+#define VERR_PGM_HANDLER_PHYSICAL_NO_RAM_RANGE (-1601)
+/** Attempt to register an access handler for a virtual range of which a part
+ * was already handled. */
+#define VERR_PGM_HANDLER_VIRTUAL_CONFLICT (-1602)
+/** Attempt to register an access handler for a physical range of which a part
+ * was already handled. */
+#define VERR_PGM_HANDLER_PHYSICAL_CONFLICT (-1603)
+/** Invalid page directory specified to PGM. */
+#define VERR_PGM_INVALID_PAGE_DIRECTORY (-1604)
+/** Invalid GC physical address. */
+#define VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS (-1605)
+/** Invalid GC physical range. Usually used when a specified range crosses
+ * a RAM region boundary. */
+#define VERR_PGM_INVALID_GC_PHYSICAL_RANGE (-1606)
+/** Specified access handler was not found. */
+#define VERR_PGM_HANDLER_NOT_FOUND (-1607)
+/** Attempt to register a RAM range of which parts are already
+ * covered by existing RAM ranges. */
+#define VERR_PGM_RAM_CONFLICT (-1608)
+/** Failed to add new mappings because the current mappings are fixed
+ * in guest os memory. */
+#define VERR_PGM_MAPPINGS_FIXED (-1609)
+/** Failed to fix mappings because of a conflict with the intermediate code. */
+#define VERR_PGM_MAPPINGS_FIX_CONFLICT (-1610)
+/** Failed to fix mappings because a mapping rejected the address. */
+#define VERR_PGM_MAPPINGS_FIX_REJECTED (-1611)
+/** Failed to fix mappings because the proposed memory area was to small. */
+#define VERR_PGM_MAPPINGS_FIX_TOO_SMALL (-1612)
+/** Reason for leaving RZ: The urge to syncing CR3. */
+#define VINF_PGM_SYNC_CR3 1613
+/** Page not marked for dirty bit tracking */
+#define VINF_PGM_NO_DIRTY_BIT_TRACKING 1614
+/** Page fault caused by dirty bit tracking; corrected */
+#define VINF_PGM_HANDLED_DIRTY_BIT_FAULT 1615
+/** Go ahead with the default Read/Write operation.
+ * This is returned by a R3 physical or virtual handler when it wants the
+ * PGMPhys[Read|Write] routine do the reading/writing. */
+#define VINF_PGM_HANDLER_DO_DEFAULT 1616
+/** The paging mode of the host is not supported yet. */
+#define VERR_PGM_UNSUPPORTED_HOST_PAGING_MODE (-1617)
+/** The physical guest page is a reserved/MMIO page and does not have any HC
+ * address. */
+#define VERR_PGM_PHYS_PAGE_RESERVED (-1618)
+/** No page directory available for the hypervisor. */
+#define VERR_PGM_NO_HYPERVISOR_ADDRESS (-1619)
+/** The shadow page pool was flushed.
+ * This means that a global CR3 sync was flagged. Anyone receiving this kind of status
+ * will have to get down to a SyncCR3 ASAP. See also VINF_PGM_SYNC_CR3. */
+#define VERR_PGM_POOL_FLUSHED (-1620)
+/** The shadow page pool was cleared.
+ * This is a error code internal to the shadow page pool, it will be
+ * converted to a VERR_PGM_POOL_FLUSHED before leaving the pool code. */
+#define VERR_PGM_POOL_CLEARED (-1621)
+/** The returned shadow page is cached. */
+#define VINF_PGM_CACHED_PAGE 1622
+/** Returned by handler registration, modification and deregistration
+ * when the shadow PTs could be updated because the guest page
+ * aliased or/and mapped by multiple PTs. */
+#define VINF_PGM_GCPHYS_ALIASED 1623
+/** Reason for leaving RC: Paging mode changed.
+ * PGMChangeMode() uses this to force a switch to R3 so it can safely deal with
+ * a mode switch. */
+#define VINF_PGM_CHANGE_MODE 1624
+/** SyncPage modified the PDE.
+ * This is an internal status code used to communicate back to the \#PF handler
+ * that the PDE was (probably) marked not-present and it should restart the instruction. */
+#define VINF_PGM_SYNCPAGE_MODIFIED_PDE 1625
+/** Physical range crosses dynamic ram chunk boundary; translation to HC ptr not safe. */
+#define VERR_PGM_GCPHYS_RANGE_CROSSES_BOUNDARY (-1626)
+/** Conflict between the core memory and the intermediate paging context, try again.
+ * There are some very special conditions applying to the intermediate paging context
+ * (used during the world switches), and some times we continuously run into these
+ * when asking the host kernel for memory during VM init. Let us know if you run into
+ * this and we'll adjust the code so it tries harder to avoid it.
+ */
+#define VERR_PGM_INTERMEDIATE_PAGING_CONFLICT (-1627)
+/** The shadow paging mode is not supported yet. */
+#define VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE (-1628)
+/** The dynamic mapping cache for physical memory failed. */
+#define VERR_PGM_DYNMAP_FAILED (-1629)
+/** The auto usage cache for the dynamic mapping set is full. */
+#define VERR_PGM_DYNMAP_FULL_SET (-1630)
+/** The initialization of the dynamic mapping cache failed. */
+#define VERR_PGM_DYNMAP_SETUP_ERROR (-1631)
+/** The expanding of the dynamic mapping cache failed. */
+#define VERR_PGM_DYNMAP_EXPAND_ERROR (-1632)
+/** The page is unassigned (akin to VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS). */
+#define VERR_PGM_PHYS_TLB_UNASSIGNED (-1633)
+/** Catch any access and route it thru PGM. */
+#define VERR_PGM_PHYS_TLB_CATCH_ALL (-1634)
+/** Catch write access and route it thru PGM. */
+#define VINF_PGM_PHYS_TLB_CATCH_WRITE 1635
+/** Catch write access and route it thru PGM. */
+#define VERR_PGM_PHYS_TLB_CATCH_WRITE (-1635)
+/** No CR3 root shadow page table.. */
+#define VERR_PGM_NO_CR3_SHADOW_ROOT (-1636)
+/** Trying to free a page with an invalid Page ID. */
+#define VERR_PGM_PHYS_INVALID_PAGE_ID (-1637)
+/** PGMPhysWrite/Read hit a handler in Ring-0 or raw-mode context. */
+#define VERR_PGM_PHYS_WR_HIT_HANDLER (-1638)
+/** Trying to free a page that isn't RAM. */
+#define VERR_PGM_PHYS_NOT_RAM (-1639)
+/** Not ROM page. */
+#define VERR_PGM_PHYS_NOT_ROM (-1640)
+/** Not MMIO page. */
+#define VERR_PGM_PHYS_NOT_MMIO (-1641)
+/** Not MMIO2 page. */
+#define VERR_PGM_PHYS_NOT_MMIO2 (-1642)
+/** Already aliased to a different page. */
+#define VERR_PGM_HANDLER_ALREADY_ALIASED (-1643)
+/** Already aliased to the same page. */
+#define VINF_PGM_HANDLER_ALREADY_ALIASED (1643)
+/** PGM pool flush pending - return to ring 3. */
+#define VINF_PGM_POOL_FLUSH_PENDING (1644)
+/** Unable to use the range for a large page. */
+#define VERR_PGM_INVALID_LARGE_PAGE_RANGE (-1645)
+/** Don't mess around with ballooned pages. */
+#define VERR_PGM_PHYS_PAGE_BALLOONED (-1646)
+
+
+/** pgmPhysPageMapCommon encountered PGMPAGETYPE_MMIO2_ALIAS_MMIO. */
+#define VERR_PGM_MAP_MMIO2_ALIAS_MMIO (-1651)
+/** Guest mappings are disabled. */
+#define VERR_PGM_MAPPINGS_DISABLED (-1652)
+/** No guest mappings when SMP is enabled. */
+#define VERR_PGM_MAPPINGS_SMP (-1653)
+/** Invalid saved page state. */
+#define VERR_PGM_INVALID_SAVED_PAGE_STATE (-1654)
+/** Encountered an unexpected page type in the saved state. */
+#define VERR_PGM_LOAD_UNEXPECTED_PAGE_TYPE (-1655)
+/** Encountered an unexpected page state in the saved state. */
+#define VERR_PGM_UNEXPECTED_PAGE_STATE (-1656)
+/** Couldn't find MMIO2 range from saved state. */
+#define VERR_PGM_SAVED_MMIO2_RANGE_NOT_FOUND (-1657)
+/** Couldn't find MMIO2 page from saved state. */
+#define VERR_PGM_SAVED_MMIO2_PAGE_NOT_FOUND (-1658)
+/** Couldn't find ROM range from saved state. */
+#define VERR_PGM_SAVED_ROM_RANGE_NOT_FOUND (-1659)
+/** Couldn't find ROM page from saved state. */
+#define VERR_PGM_SAVED_ROM_PAGE_NOT_FOUND (-1660)
+/** ROM page mismatch between saved state and the VM. */
+#define VERR_PGM_SAVED_ROM_PAGE_PROT (-1661)
+/** Unknown saved state record. */
+#define VERR_PGM_SAVED_REC_TYPE (-1662)
+/** Internal processing error in the PGM dynmap (r0/rc). */
+#define VERR_PGM_DYNMAP_IPE (-1663)
+/** Internal processing error in the PGM handy page allocator. */
+#define VERR_PGM_HANDY_PAGE_IPE (-1664)
+/** Failed to map the guest PML4. */
+#define VERR_PGM_PML4_MAPPING (-1665)
+/** Failed to obtain a pool page. */
+#define VERR_PGM_POOL_GET_PAGE_FAILED (-1666)
+/** A PGM function was called in a mode where it isn't supposed to be used. */
+#define VERR_PGM_NOT_USED_IN_MODE (-1667)
+/** The CR3 address specified memory we don't know about. */
+#define VERR_PGM_INVALID_CR3_ADDR (-1668)
+/** One or the PDPEs specified memory we don't know about. */
+#define VERR_PGM_INVALID_PDPE_ADDR (-1669)
+/** Internal processing error in the PGM physical handler code. */
+#define VERR_PGM_PHYS_HANDLER_IPE (-1670)
+/** Internal processing error \#1 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_1 (-1671)
+/** Internal processing error \#2 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_2 (-1672)
+/** Internal processing error \#3 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_3 (-1673)
+/** Internal processing error \#4 in the PGM physial page mapping code. */
+#define VERR_PGM_PHYS_PAGE_MAP_IPE_4 (-1674)
+/** Too many loops looking for a page to reuse. */
+#define VERR_PGM_POOL_TOO_MANY_LOOPS (-1675)
+/** Internal procesing error related to guest mappings. */
+#define VERR_PGM_MAPPING_IPE (-1676)
+/** An attempt was made to grow an already maxed out page pool. */
+#define VERR_PGM_POOL_MAXED_OUT_ALREADY (-1677)
+/** Internal processing error in the page pool code. */
+#define VERR_PGM_POOL_IPE (-1678)
+/** The write monitor is already engaged. */
+#define VERR_PGM_WRITE_MONITOR_ENGAGED (-1679)
+/** Failed to get a guest page which is expected to be present. */
+#define VERR_PGM_PHYS_PAGE_GET_IPE (-1680)
+/** We were given a NULL pPage parameter. */
+#define VERR_PGM_PHYS_NULL_PAGE_PARAM (-1681)
+/** PCI passthru is not supported by this build. */
+#define VERR_PGM_PCI_PASSTHRU_MISCONFIG (-1682)
+/** @} */
+
+
+/** @name Memory Monitor (MM) Status Codes
+ * @{
+ */
+/** Attempt to register a RAM range of which parts are already
+ * covered by existing RAM ranges. */
+#define VERR_MM_RAM_CONFLICT (-1700)
+/** Hypervisor memory allocation failed. */
+#define VERR_MM_HYPER_NO_MEMORY (-1701)
+/** A bad trap type ended up in mmGCRamTrap0eHandler. */
+#define VERR_MM_BAD_TRAP_TYPE_IPE (-1702)
+/** @} */
+
+
+/** @name CPU Monitor (CPUM) Status Codes
+ * @{
+ */
+/** The caller shall raise an \#GP(0) exception. */
+#define VERR_CPUM_RAISE_GP_0 (-1750)
+/** Incompatible CPUM configuration. */
+#define VERR_CPUM_INCOMPATIBLE_CONFIG (-1751)
+/** CPUMR3DisasmInstrCPU unexpectedly failed to determin the hidden
+ * parts of the CS register. */
+#define VERR_CPUM_HIDDEN_CS_LOAD_ERROR (-1752)
+/** @} */
+
+
+/** @name Save State Manager (SSM) Status Codes
+ * @{
+ */
+/** The specified data unit already exist. */
+#define VERR_SSM_UNIT_EXISTS (-1800)
+/** The specified data unit wasn't found. */
+#define VERR_SSM_UNIT_NOT_FOUND (-1801)
+/** The specified data unit wasn't owned by caller. */
+#define VERR_SSM_UNIT_NOT_OWNER (-1802)
+
+/** General saved state file integrity error. */
+#define VERR_SSM_INTEGRITY (-1810)
+/** The saved state file magic was not recognized. */
+#define VERR_SSM_INTEGRITY_MAGIC (-1811)
+/** The saved state file version is not supported. */
+#define VERR_SSM_INTEGRITY_VERSION (-1812)
+/** The saved state file size didn't match the one in the header. */
+#define VERR_SSM_INTEGRITY_SIZE (-1813)
+/** The CRC of the saved state file did not match. */
+#define VERR_SSM_INTEGRITY_CRC (-1814)
+/** The machine uuid field wasn't null. */
+#define VERR_SMM_INTEGRITY_MACHINE (-1815)
+/** Saved state header integrity error. */
+#define VERR_SSM_INTEGRITY_HEADER (-1816)
+/** Unit header integrity error. */
+#define VERR_SSM_INTEGRITY_UNIT (-1817)
+/** Invalid unit magic (internal data tag). */
+#define VERR_SSM_INTEGRITY_UNIT_MAGIC (-1818)
+/** The file contained a data unit which no-one wants. */
+#define VERR_SSM_INTEGRITY_UNIT_NOT_FOUND (-1819)
+/** Incorrect version numbers in the header. */
+#define VERR_SSM_INTEGRITY_VBOX_VERSION (-1820)
+/** Footer integrity error. */
+#define VERR_SSM_INTEGRITY_FOOTER (-1821)
+/** Record header integrity error. */
+#define VERR_SSM_INTEGRITY_REC_HDR (-1822)
+/** Termination record integrity error. */
+#define VERR_SSM_INTEGRITY_REC_TERM (-1823)
+/** Termination record CRC mismatch. */
+#define VERR_SSM_INTEGRITY_REC_TERM_CRC (-1824)
+/** Decompression interity error. */
+#define VERR_SSM_INTEGRITY_DECOMPRESSION (-1825)
+/** Saved state directory iintegrity error. */
+#define VERR_SSM_INTEGRITY_DIR (-1826)
+/** The saved state directory magic is wrong. */
+#define VERR_SSM_INTEGRITY_DIR_MAGIC (-1827)
+
+/** A data unit in the saved state file was defined but didn't any
+ * routine for processing it. */
+#define VERR_SSM_NO_LOAD_EXEC (-1830)
+/** A restore routine attempted to load more data then the unit contained. */
+#define VERR_SSM_LOADED_TOO_MUCH (-1831)
+/** Not in the correct state for the attempted operation. */
+#define VERR_SSM_INVALID_STATE (-1832)
+/** Not in the correct state for the attempted operation. */
+#define VERR_SSM_LOADED_TOO_LITTLE (-1833)
+
+/** Unsupported data unit version.
+ * A SSM user returns this if it doesn't know the u32Version. */
+#define VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION (-1840)
+/** The format of a data unit has changed.
+ * A SSM user returns this if it's not able to read the format for
+ * other reasons than u32Version. */
+#define VERR_SSM_DATA_UNIT_FORMAT_CHANGED (-1841)
+/** The CPUID instruction returns different information when loading than when saved.
+ * Normally caused by hardware changes on the host, but could also be caused by
+ * changes in the BIOS setup. */
+#define VERR_SSM_LOAD_CPUID_MISMATCH (-1842)
+/** The RAM size differes between the saved state and the VM config. */
+#define VERR_SSM_LOAD_MEMORY_SIZE_MISMATCH (-1843)
+/** The state doesn't match the VM configuration in one or another way.
+ * (There are certain PCI reconfiguration which the OS could potentially
+ * do which can cause this problem. Check this out when it happens.) */
+#define VERR_SSM_LOAD_CONFIG_MISMATCH (-1844)
+/** The virtual clock frequency differs too much.
+ * The clock source for the virtual time isn't reliable or the code have changed. */
+#define VERR_SSM_VIRTUAL_CLOCK_HZ (-1845)
+/** A timeout occurred while waiting for async IDE operations to finish. */
+#define VERR_SSM_IDE_ASYNC_TIMEOUT (-1846)
+/** One of the structure magics was wrong. */
+#define VERR_SSM_STRUCTURE_MAGIC (-1847)
+/** The data in the saved state doesn't conform to expectations. */
+#define VERR_SSM_UNEXPECTED_DATA (-1848)
+/** Trying to read a 64-bit guest physical address into a 32-bit variable. */
+#define VERR_SSM_GCPHYS_OVERFLOW (-1849)
+/** Trying to read a 64-bit guest virtual address into a 32-bit variable. */
+#define VERR_SSM_GCPTR_OVERFLOW (-1850)
+/** Vote for another pass. */
+#define VINF_SSM_VOTE_FOR_ANOTHER_PASS 1851
+/** Vote for done tell SSM not to call again until the final pass. */
+#define VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN 1852
+/** Vote for giving up. */
+#define VERR_SSM_VOTE_FOR_GIVING_UP (-1853)
+/** Don't call again until the final pass. */
+#define VINF_SSM_DONT_CALL_AGAIN 1854
+/** Giving up a live snapshot/teleportation attempt because of too many
+ * passes. */
+#define VERR_SSM_TOO_MANY_PASSES (-1855)
+/** Giving up a live snapshot/teleportation attempt because the state grew to
+ * big. */
+#define VERR_SSM_STATE_GREW_TOO_BIG (-1856)
+/** Giving up a live snapshot attempt because we're low on disk space. */
+#define VERR_SSM_LOW_ON_DISK_SPACE (-1857)
+/** The operation was cancelled. */
+#define VERR_SSM_CANCELLED (-1858)
+/** Nothing that can be cancelled. */
+#define VERR_SSM_NO_PENDING_OPERATION (-1859)
+/** The operation has already been cancelled. */
+#define VERR_SSM_ALREADY_CANCELLED (-1860)
+/** The machine was powered off while saving. */
+#define VERR_SSM_LIVE_POWERED_OFF (-1861)
+/** The live snapshot/teleportation operation was aborted because of a guru
+ * meditation. */
+#define VERR_SSM_LIVE_GURU_MEDITATION (-1862)
+/** The live snapshot/teleportation operation was aborted because of a fatal
+ * runtime error. */
+#define VERR_SSM_LIVE_FATAL_ERROR (-1863)
+/** The VM was suspended before or while saving, don't resume execution. */
+#define VINF_SSM_LIVE_SUSPENDED 1864
+/** Complex SSM field fed to SSMR3PutStruct or SSMR3GetStruct. Use the
+ * extended API. */
+#define VERR_SSM_FIELD_COMPLEX (-1864)
+/** Invalid size of a SSM field with the specified transformation. */
+#define VERR_SSM_FIELD_INVALID_SIZE (-1865)
+/** The specified field is outside the structure. */
+#define VERR_SSM_FIELD_OUT_OF_BOUNDS (-1866)
+/** The field does not follow immediately the previous one. */
+#define VERR_SSM_FIELD_NOT_CONSECUTIVE (-1867)
+/** The field contains an invalid callback or transformation index. */
+#define VERR_SSM_FIELD_INVALID_CALLBACK (-1868)
+/** The field contains an invalid padding size. */
+#define VERR_SSM_FIELD_INVALID_PADDING_SIZE (-1869)
+/** The field contains a value that is out of range. */
+#define VERR_SSM_FIELD_INVALID_VALUE (-1870)
+/** Generic stream error. */
+#define VERR_SSM_STREAM_ERROR (-1871)
+/** SSM did a callback for a pass we didn't expect. */
+#define VERR_SSM_UNEXPECTED_PASS (-1872)
+/** Someone is trying to skip backwards in the stream... */
+#define VERR_SSM_SKIP_BACKWARDS (-1873)
+/** Someone is trying to write a memory block which is too big to encode. */
+#define VERR_SSM_MEM_TOO_BIG (-1874)
+/** Encountered an bad (/unknown) record type. */
+#define VERR_SSM_BAD_REC_TYPE (-1875)
+/** Internal processing error \#1 in SSM code. */
+#define VERR_SSM_IPE_1 (-1876)
+/** Internal processing error \#2 in SSM code. */
+#define VERR_SSM_IPE_2 (-1877)
+/** Internal processing error \#3 in SSM code. */
+#define VERR_SSM_IPE_3 (-1878)
+/** A field contained an transformation that should only be used when loading
+ * old states. */
+#define VERR_SSM_FIELD_LOAD_ONLY_TRANSFORMATION (-1879)
+/** @} */
+
+
+/** @name Virtual Machine (VM) Status Codes
+ * @{
+ */
+/** The specified at reset handler wasn't found. */
+#define VERR_VM_ATRESET_NOT_FOUND (-1900)
+/** Invalid VM request type.
+ * For the VMR3ReqAlloc() case, the caller just specified an illegal enmType. For
+ * all the other occurrences it means indicates corruption, broken logic, or stupid
+ * interface user. */
+#define VERR_VM_REQUEST_INVALID_TYPE (-1901)
+/** Invalid VM request state.
+ * The state of the request packet was not the expected and accepted one(s). Either
+ * the interface user screwed up, or we've got corruption/broken logic. */
+#define VERR_VM_REQUEST_STATE (-1902)
+/** Invalid VM request packet.
+ * One or more of the the VM controlled packet members didn't contain the correct
+ * values. Some thing's broken. */
+#define VERR_VM_REQUEST_INVALID_PACKAGE (-1903)
+/** The status field has not been updated yet as the request is still
+ * pending completion. Someone queried the iStatus field before the request
+ * has been fully processed. */
+#define VERR_VM_REQUEST_STATUS_STILL_PENDING (-1904)
+/** The request has been freed, don't read the status now.
+ * Someone is reading the iStatus field of a freed request packet. */
+#define VERR_VM_REQUEST_STATUS_FREED (-1905)
+/** A VM api requiring EMT was called from another thread.
+ * Use the VMR3ReqCall() apis to call it! */
+#define VERR_VM_THREAD_NOT_EMT (-1906)
+/** The VM state was invalid for the requested operation.
+ * Go check the 'VM Statechart Diagram.gif'. */
+#define VERR_VM_INVALID_VM_STATE (-1907)
+/** The support driver is not installed.
+ * On linux, open returned ENOENT. */
+#define VERR_VM_DRIVER_NOT_INSTALLED (-1908)
+/** The support driver is not accessible.
+ * On linux, open returned EPERM. */
+#define VERR_VM_DRIVER_NOT_ACCESSIBLE (-1909)
+/** Was not able to load the support driver.
+ * On linux, open returned ENODEV. */
+#define VERR_VM_DRIVER_LOAD_ERROR (-1910)
+/** Was not able to open the support driver.
+ * Generic open error used when none of the other ones fit. */
+#define VERR_VM_DRIVER_OPEN_ERROR (-1911)
+/** The installed support driver doesn't match the version of the user. */
+#define VERR_VM_DRIVER_VERSION_MISMATCH (-1912)
+/** Saving the VM state is temporarily not allowed. Try again later. */
+#define VERR_VM_SAVE_STATE_NOT_ALLOWED (-1913)
+/** An EMT called an API which cannot be called on such a thread. */
+#define VERR_VM_THREAD_IS_EMT (-1914)
+/** Encountered an unexpected VM state. */
+#define VERR_VM_UNEXPECTED_VM_STATE (-1915)
+/** Unexpected unstable VM state. */
+#define VERR_VM_UNEXPECTED_UNSTABLE_STATE (-1916)
+/** Too many arguments passed to a VM request / request corruption. */
+#define VERR_VM_REQUEST_TOO_MANY_ARGS_IPE (-1917)
+/** Fatal EMT wait error. */
+#define VERR_VM_FATAL_WAIT_ERROR (-1918)
+/** The VM request was killed at VM termination. */
+#define VERR_VM_REQUEST_KILLED (-1919)
+/** @} */
+
+
+/** @name VBox Remote Desktop Protocol (VRDP) Status Codes
+ * @{
+ */
+/** Successful completion of operation (mapped to generic iprt status code). */
+#define VINF_VRDP_SUCCESS VINF_SUCCESS
+/** VRDP transport operation timed out (mapped to generic iprt status code). */
+#define VERR_VRDP_TIMEOUT VERR_TIMEOUT
+
+/** Unsupported ISO protocol feature */
+#define VERR_VRDP_ISO_UNSUPPORTED (-2000)
+/** Security (en/decryption) engine error */
+#define VERR_VRDP_SEC_ENGINE_FAIL (-2001)
+/** VRDP protocol violation */
+#define VERR_VRDP_PROTOCOL_ERROR (-2002)
+/** Unsupported VRDP protocol feature */
+#define VERR_VRDP_NOT_SUPPORTED (-2003)
+/** VRDP protocol violation, client sends less data than expected */
+#define VERR_VRDP_INSUFFICIENT_DATA (-2004)
+/** Internal error, VRDP packet is in wrong operation mode */
+#define VERR_VRDP_INVALID_MODE (-2005)
+/** Memory allocation failed */
+#define VERR_VRDP_NO_MEMORY (-2006)
+/** Client has been rejected */
+#define VERR_VRDP_ACCESS_DENIED (-2007)
+/** VRPD receives a packet that is not supported */
+#define VWRN_VRDP_PDU_NOT_SUPPORTED 2008
+/** VRDP script allowed the packet to be processed further */
+#define VINF_VRDP_PROCESS_PDU 2009
+/** VRDP script has completed its task */
+#define VINF_VRDP_OPERATION_COMPLETED 2010
+/** VRDP thread has started OK and will run */
+#define VINF_VRDP_THREAD_STARTED 2011
+/** Framebuffer is resized, terminate send bitmap procedure */
+#define VINF_VRDP_RESIZE_REQUESTED 2012
+/** Output can be enabled for the client. */
+#define VINF_VRDP_OUTPUT_ENABLE 2013
+/** @} */
+
+
+/** @name Configuration Manager (CFGM) Status Codes
+ * @{
+ */
+/** The integer value was too big for the requested representation. */
+#define VERR_CFGM_INTEGER_TOO_BIG (-2100)
+/** Child node was not found. */
+#define VERR_CFGM_CHILD_NOT_FOUND (-2101)
+/** Path to child node was invalid (i.e. empty). */
+#define VERR_CFGM_INVALID_CHILD_PATH (-2102)
+/** Value not found. */
+#define VERR_CFGM_VALUE_NOT_FOUND (-2103)
+/** No parent node specified. */
+#define VERR_CFGM_NO_PARENT (-2104)
+/** No node was specified. */
+#define VERR_CFGM_NO_NODE (-2105)
+/** The value is not an integer. */
+#define VERR_CFGM_NOT_INTEGER (-2106)
+/** The value is not a zero terminated character string. */
+#define VERR_CFGM_NOT_STRING (-2107)
+/** The value is not a byte string. */
+#define VERR_CFGM_NOT_BYTES (-2108)
+/** The specified string / bytes buffer was to small. Specify a larger one and retry. */
+#define VERR_CFGM_NOT_ENOUGH_SPACE (-2109)
+/** The path of a new node contained slashs or was empty. */
+#define VERR_CFGM_INVALID_NODE_PATH (-2160)
+/** A new node couldn't be inserted because one with the same name exists. */
+#define VERR_CFGM_NODE_EXISTS (-2161)
+/** A new leaf couldn't be inserted because one with the same name exists. */
+#define VERR_CFGM_LEAF_EXISTS (-2162)
+/** An unknown config value was encountered. */
+#define VERR_CFGM_CONFIG_UNKNOWN_VALUE (-2163)
+/** An unknown config node (key) was encountered. */
+#define VERR_CFGM_CONFIG_UNKNOWN_NODE (-2164)
+/** Internal processing error \#1 in CFGM. */
+#define VERR_CFGM_IPE_1 (-2165)
+/** @} */
+
+
+/** @name Time Manager (TM) Status Codes
+ * @{
+ */
+/** The loaded timer state was incorrect. */
+#define VERR_TM_LOAD_STATE (-2200)
+/** The timer was not in the correct state for the request operation. */
+#define VERR_TM_INVALID_STATE (-2201)
+/** The timer was in a unknown state. Corruption or stupid coding error. */
+#define VERR_TM_UNKNOWN_STATE (-2202)
+/** The timer was stuck in an unstable state until we grew impatient and returned. */
+#define VERR_TM_UNSTABLE_STATE (-2203)
+/** TM requires GIP. */
+#define VERR_TM_GIP_REQUIRED (-2204)
+/** TM does not support the GIP version. */
+#define VERR_TM_GIP_VERSION (-2205)
+/** The GIP update interval is too large. */
+#define VERR_TM_GIP_UPDATE_INTERVAL_TOO_BIG (-2206)
+/** The timer has a bad clock enum value, probably corruption. */
+#define VERR_TM_TIMER_BAD_CLOCK (-2207)
+/** The timer failed to reach a stable state. */
+#define VERR_TM_TIMER_UNSTABLE_STATE (-2208)
+/** Attempt to resume a running TSC. */
+#define VERR_TM_TSC_ALREADY_TICKING (-2209)
+/** Attempt to pause a paused TSC. */
+#define VERR_TM_TSC_ALREADY_PAUSED (-2210)
+/** Invalid value for cVirtualTicking. */
+#define VERR_TM_VIRTUAL_TICKING_IPE (-2211)
+/** @} */
+
+
+/** @name Recompiled Execution Manager (REM) Status Codes
+ * @{
+ */
+/** Fatal error in virtual hardware. */
+#define VERR_REM_VIRTUAL_HARDWARE_ERROR (-2300)
+/** Fatal error in the recompiler cpu. */
+#define VERR_REM_VIRTUAL_CPU_ERROR (-2301)
+/** Recompiler execution was interrupted by forced action. */
+#define VINF_REM_INTERRUPED_FF 2302
+/** Too many similar traps. This is a very useful debug only
+ * check (we don't do double/triple faults in REM). */
+#define VERR_REM_TOO_MANY_TRAPS (-2304)
+/** The REM is out of breakpoint slots. */
+#define VERR_REM_NO_MORE_BP_SLOTS (-2305)
+/** The REM could not find any breakpoint on the specified address. */
+#define VERR_REM_BP_NOT_FOUND (-2306)
+/** @} */
+
+
+/** @name Trap Manager / Monitor (TRPM) Status Codes
+ * @{
+ */
+/** No active trap. Cannot query or reset a non-existing trap. */
+#define VERR_TRPM_NO_ACTIVE_TRAP (-2400)
+/** Active trap. Cannot assert a new trap when when one is already active. */
+#define VERR_TRPM_ACTIVE_TRAP (-2401)
+/** Reason for leaving RC: Guest tried to write to our IDT - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the idtr register. */
+#define VERR_TRPM_SHADOW_IDT_WRITE (-2402)
+/** Reason for leaving RC: Fatal trap in hypervisor. */
+#define VERR_TRPM_DONT_PANIC (-2403)
+/** Reason for leaving RC: Double Fault. */
+#define VERR_TRPM_PANIC (-2404)
+/** The exception was dispatched for raw-mode execution. */
+#define VINF_TRPM_XCPT_DISPATCHED 2405
+/** Bad TRPM_TRAP_IN_OP. */
+#define VERR_TRPM_BAD_TRAP_IN_OP (-2406)
+/** Internal processing error \#1 in TRPM. */
+#define VERR_TRPM_IPE_1 (-2407)
+/** Internal processing error \#2 in TRPM. */
+#define VERR_TRPM_IPE_2 (-2408)
+/** Internal processing error \#3 in TRPM. */
+#define VERR_TRPM_IPE_3 (-2409)
+/** @} */
+
+
+/** @name Selector Manager / Monitor (SELM) Status Code
+ * @{
+ */
+/** Reason for leaving RC: Guest tried to write to our GDT - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the gdtr register. */
+#define VERR_SELM_SHADOW_GDT_WRITE (-2500)
+/** Reason for leaving RC: Guest tried to write to our LDT - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the ldtr register. */
+#define VERR_SELM_SHADOW_LDT_WRITE (-2501)
+/** Reason for leaving RC: Guest tried to write to our TSS - fatal.
+ * The VM will be terminated assuming the worst, i.e. that the
+ * guest has read the ltr register. */
+#define VERR_SELM_SHADOW_TSS_WRITE (-2502)
+/** Reason for leaving RC: Sync the GDT table to solve a conflict. */
+#define VINF_SELM_SYNC_GDT 2503
+/** No valid TSS present. */
+#define VERR_SELM_NO_TSS (-2504)
+/** Invalid guest LDT selector. */
+#define VERR_SELM_INVALID_LDT (-2505)
+/** The guest LDT selector is out of bounds. */
+#define VERR_SELM_LDT_OUT_OF_BOUNDS (-2506)
+/** Unknown error while reading the guest GDT during shadow table updating. */
+#define VERR_SELM_GDT_READ_ERROR (-2507)
+/** The guest GDT so full that we cannot find free space for our own
+ * selectors. */
+#define VERR_SELM_GDT_TOO_FULL (-2508)
+/** @} */
+
+
+/** @name I/O Manager / Monitor (IOM) Status Code
+ * @{
+ */
+/** The specified I/O port range was invalid.
+ * It was either empty or it was out of bounds. */
+#define VERR_IOM_INVALID_IOPORT_RANGE (-2600)
+/** The specified R0 or RC I/O port range didn't have a corresponding R3 range.
+ * IOMR3IOPortRegisterR3() must be called first. */
+#define VERR_IOM_NO_R3_IOPORT_RANGE (-2601)
+/** The specified I/O port range intruded on an existing range. There is
+ * a I/O port conflict between two device, or a device tried to register
+ * the same range twice. */
+#define VERR_IOM_IOPORT_RANGE_CONFLICT (-2602)
+/** The I/O port range specified for removal wasn't found or it wasn't contiguous. */
+#define VERR_IOM_IOPORT_RANGE_NOT_FOUND (-2603)
+/** The specified I/O port range was owned by some other device(s). Both registration
+ * and deregistration, but in the first case only RC and R0 ranges. */
+#define VERR_IOM_NOT_IOPORT_RANGE_OWNER (-2604)
+
+/** The specified MMIO range was invalid.
+ * It was either empty or it was out of bounds. */
+#define VERR_IOM_INVALID_MMIO_RANGE (-2605)
+/** The specified R0 or RC MMIO range didn't have a corresponding R3 range.
+ * IOMR3MMIORegisterR3() must be called first. */
+#define VERR_IOM_NO_R3_MMIO_RANGE (-2606)
+/** The specified MMIO range was owned by some other device(s). Both registration
+ * and deregistration, but in the first case only RC and R0 ranges. */
+#define VERR_IOM_NOT_MMIO_RANGE_OWNER (-2607)
+/** The specified MMIO range intruded on an existing range. There is
+ * a MMIO conflict between two device, or a device tried to register
+ * the same range twice. */
+#define VERR_IOM_MMIO_RANGE_CONFLICT (-2608)
+/** The MMIO range specified for removal was not found. */
+#define VERR_IOM_MMIO_RANGE_NOT_FOUND (-2609)
+/** The MMIO range specified for removal was invalid. The range didn't match
+ * quite match a set of existing ranges. It's not possible to remove parts of
+ * a MMIO range, only one or more full ranges. */
+#define VERR_IOM_INCOMPLETE_MMIO_RANGE (-2610)
+/** An invalid I/O port size was specified for a read or write operation. */
+#define VERR_IOM_INVALID_IOPORT_SIZE (-2611)
+/** The MMIO handler was called for a bogus address! Internal error! */
+#define VERR_IOM_MMIO_HANDLER_BOGUS_CALL (-2612)
+/** The MMIO handler experienced a problem with the disassembler. */
+#define VERR_IOM_MMIO_HANDLER_DISASM_ERROR (-2613)
+/** The port being read was not present(/unused) and IOM shall return ~0 according to size. */
+#define VERR_IOM_IOPORT_UNUSED (-2614)
+/** Unused MMIO register read, fill with 00. */
+#define VINF_IOM_MMIO_UNUSED_00 2615
+/** Unused MMIO register read, fill with FF. */
+#define VINF_IOM_MMIO_UNUSED_FF 2616
+
+/** Reason for leaving RZ: I/O port read. */
+#define VINF_IOM_R3_IOPORT_READ 2620
+/** Reason for leaving RZ: I/O port write. */
+#define VINF_IOM_R3_IOPORT_WRITE 2621
+/** Reason for leaving RZ: MMIO write. */
+#define VINF_IOM_R3_MMIO_READ 2623
+/** Reason for leaving RZ: MMIO read. */
+#define VINF_IOM_R3_MMIO_WRITE 2624
+/** Reason for leaving RZ: MMIO read/write. */
+#define VINF_IOM_R3_MMIO_READ_WRITE 2625
+
+/** IOMGCIOPortHandler was given an unexpected opcode. */
+#define VERR_IOM_IOPORT_UNKNOWN_OPCODE (-2630)
+/** Internal processing error \#1 in the I/O port code. */
+#define VERR_IOM_IOPORT_IPE_1 (-2631)
+/** Internal processing error \#2 in the I/O port code. */
+#define VERR_IOM_IOPORT_IPE_2 (-2632)
+/** Internal processing error \#3 in the I/O port code. */
+#define VERR_IOM_IOPORT_IPE_3 (-2633)
+/** Internal processing error \#1 in the MMIO code. */
+#define VERR_IOM_MMIO_IPE_1 (-2634)
+/** Internal processing error \#2 in the MMIO code. */
+#define VERR_IOM_MMIO_IPE_2 (-2635)
+/** Internal processing error \#3 in the MMIO code. */
+#define VERR_IOM_MMIO_IPE_3 (-2636)
+/** @} */
+
+
+/** @name Virtual Machine Monitor (VMM) Status Codes
+ * @{
+ */
+/** Reason for leaving RZ: Calling host function. */
+#define VINF_VMM_CALL_HOST 2700
+/** Reason for leaving R0: Hit a ring-0 assertion on EMT. */
+#define VERR_VMM_RING0_ASSERTION (-2701)
+/** The hyper CR3 differs between PGM and CPUM. */
+#define VERR_VMM_HYPER_CR3_MISMATCH (-2702)
+/** Reason for leaving RZ: Illegal call to ring-3. */
+#define VERR_VMM_RING3_CALL_DISABLED (-2703)
+/** The VMMR0.r0 module version does not match VBoxVMM.dll/so/dylib.
+ * If you just upgraded VirtualBox, please terminate all VMs and make sure
+ * VBoxNetDHCP is not running. Then try again. If this error persists, try
+ * re-installing VirtualBox. */
+#define VERR_VMM_R0_VERSION_MISMATCH (-2704)
+/** The VMMRC.rc module version does not match VBoxVMM.dll/so/dylib.
+ * Re-install if you are a user. Developers should make sure the build is
+ * complete or try with a clean build. */
+#define VERR_VMM_RC_VERSION_MISMATCH (-2705)
+/** VMM set jump error. */
+#define VERR_VMM_SET_JMP_ERROR (-2706)
+/** VMM set jump stack overflow error. */
+#define VERR_VMM_SET_JMP_STACK_OVERFLOW (-2707)
+/** VMM set jump resume error. */
+#define VERR_VMM_SET_JMP_ABORTED_RESUME (-2708)
+/** VMM long jump error. */
+#define VERR_VMM_LONG_JMP_ERROR (-2709)
+/** Unknown ring-3 call attempted. */
+#define VERR_VMM_UNKNOWN_RING3_CALL (-2710)
+/** The ring-3 call didn't set an RC. */
+#define VERR_VMM_RING3_CALL_NO_RC (-2711)
+/** Reason for leaving RC: Caller the tracer in ring-0. */
+#define VINF_VMM_CALL_TRACER (2712)
+/** Internal processing error \#1 in the switcher code. */
+#define VERR_VMM_SWITCHER_IPE_1 (-2713)
+/** @} */
+
+
+/** @name Pluggable Device and Driver Manager (PDM) Status Codes
+ * @{
+ */
+/** An invalid LUN specification was given. */
+#define VERR_PDM_NO_SUCH_LUN (-2800)
+/** A device encountered an unknown configuration value.
+ * This means that the device is potentially misconfigured and the device
+ * construction or unit attachment failed because of this. */
+#define VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES (-2801)
+/** The above driver doesn't export a interface required by a driver being
+ * attached to it. Typical misconfiguration problem. */
+#define VERR_PDM_MISSING_INTERFACE_ABOVE (-2802)
+/** The below driver doesn't export a interface required by the drive
+ * having attached it. Typical misconfiguration problem. */
+#define VERR_PDM_MISSING_INTERFACE_BELOW (-2803)
+/** A device didn't find a required interface with an attached driver.
+ * Typical misconfiguration problem. */
+#define VERR_PDM_MISSING_INTERFACE (-2804)
+/** A driver encountered an unknown configuration value.
+ * This means that the driver is potentially misconfigured and the driver
+ * construction failed because of this. */
+#define VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES (-2805)
+/** The PCI bus assigned to a device didn't have room for it.
+ * Either too many devices are configured on the same PCI bus, or there are
+ * some internal problem where PDM/PCI doesn't free up slots when unplugging devices. */
+#define VERR_PDM_TOO_PCI_MANY_DEVICES (-2806)
+/** A queue is out of free items, the queueing operation failed. */
+#define VERR_PDM_NO_QUEUE_ITEMS (-2807)
+/** Not possible to attach further drivers to the driver.
+ * A driver which doesn't support attachments (below of course) will
+ * return this status code if it found that further drivers were configured
+ * to be attached to it. */
+#define VERR_PDM_DRVINS_NO_ATTACH (-2808)
+/** Not possible to attach drivers to the device.
+ * A device which doesn't support attachments (below of course) will
+ * return this status code if it found that drivers were configured
+ * to be attached to it. */
+#define VERR_PDM_DEVINS_NO_ATTACH (-2809)
+/** No attached driver.
+ * The PDMDRVHLP::pfnAttach and PDMDEVHLP::pfnDriverAttach will return
+ * this error when no driver was configured to be attached. */
+#define VERR_PDM_NO_ATTACHED_DRIVER (-2810)
+/** The media geometry hasn't been set yet, so it cannot be obtained.
+ * The caller should then calculate the geometry from the media size. */
+#define VERR_PDM_GEOMETRY_NOT_SET (-2811)
+/** The media translation hasn't been set yet, so it cannot be obtained.
+ * The caller should then guess the translation. */
+#define VERR_PDM_TRANSLATION_NOT_SET (-2812)
+/** The media is not mounted, operation requires a mounted media. */
+#define VERR_PDM_MEDIA_NOT_MOUNTED (-2813)
+/** Mount failed because a media was already mounted. Unmount the media
+ * and retry the mount. */
+#define VERR_PDM_MEDIA_MOUNTED (-2814)
+/** The media is locked and cannot be unmounted. */
+#define VERR_PDM_MEDIA_LOCKED (-2815)
+/** No 'Type' attribute in the DrvBlock configuration.
+ * Misconfiguration. */
+#define VERR_PDM_BLOCK_NO_TYPE (-2816)
+/** The 'Type' attribute in the DrvBlock configuration had an unknown value.
+ * Misconfiguration. */
+#define VERR_PDM_BLOCK_UNKNOWN_TYPE (-2817)
+/** The 'Translation' attribute in the DrvBlock configuration had an unknown value.
+ * Misconfiguration. */
+#define VERR_PDM_BLOCK_UNKNOWN_TRANSLATION (-2818)
+/** The block driver type wasn't supported.
+ * Misconfiguration of the kind you get when attaching a floppy to an IDE controller. */
+#define VERR_PDM_UNSUPPORTED_BLOCK_TYPE (-2819)
+/** A attach or prepare mount call failed because the driver already
+ * had a driver attached. */
+#define VERR_PDM_DRIVER_ALREADY_ATTACHED (-2820)
+/** An attempt on deattaching a driver without anyone actually being attached, or
+ * performing any other operation on an attached driver. */
+#define VERR_PDM_NO_DRIVER_ATTACHED (-2821)
+/** The attached driver configuration is missing the 'Driver' attribute. */
+#define VERR_PDM_CFG_MISSING_DRIVER_NAME (-2822)
+/** The configured driver wasn't found.
+ * Either the necessary driver modules wasn't loaded, the name was
+ * misspelled, or it was a misconfiguration. */
+#define VERR_PDM_DRIVER_NOT_FOUND (-2823)
+/** The Ring-3 module was already loaded. */
+#define VINF_PDM_ALREADY_LOADED (2824)
+/** The name of the module clashed with an existing module. */
+#define VERR_PDM_MODULE_NAME_CLASH (-2825)
+/** Couldn't find any export for registration of drivers/devices. */
+#define VERR_PDM_NO_REGISTRATION_EXPORT (-2826)
+/** A module name is too long. */
+#define VERR_PDM_MODULE_NAME_TOO_LONG (-2827)
+/** Driver name clash. Another driver with the same name as the
+ * one begin registred exists. */
+#define VERR_PDM_DRIVER_NAME_CLASH (-2828)
+/** The version of the driver registration structure is unknown
+ * to this VBox version. Either mixing incompatible versions or
+ * the structure isn't correctly initialized. */
+#define VERR_PDM_UNKNOWN_DRVREG_VERSION (-2829)
+/** Invalid entry in the driver registration structure. */
+#define VERR_PDM_INVALID_DRIVER_REGISTRATION (-2830)
+/** Invalid host bit mask. */
+#define VERR_PDM_INVALID_DRIVER_HOST_BITS (-2831)
+/** Not possible to detach a driver because the above driver/device
+ * doesn't support it. The above entity doesn't implement the pfnDetach call. */
+#define VERR_PDM_DRIVER_DETACH_NOT_POSSIBLE (-2832)
+/** No PCI Bus is available to register the device with. This is usually a
+ * misconfiguration or in rare cases a buggy pci device. */
+#define VERR_PDM_NO_PCI_BUS (-2833)
+/** PCI physical read with bus mastering disabled. */
+#define VINF_PDM_PCI_PHYS_READ_BM_DISABLED (2833)
+/** The device is not a registered PCI device and thus cannot
+ * perform any PCI operations. The device forgot to register it self. */
+#define VERR_PDM_NOT_PCI_DEVICE (-2834)
+/** PCI physical write with bus mastering disabled. */
+#define VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED (2834)
+
+/** The version of the device registration structure is unknown
+ * to this VBox version. Either mixing incompatible versions or
+ * the structure isn't correctly initialized. */
+#define VERR_PDM_UNKNOWN_DEVREG_VERSION (-2835)
+/** Invalid entry in the device registration structure. */
+#define VERR_PDM_INVALID_DEVICE_REGISTRATION (-2836)
+/** Invalid host bit mask. */
+#define VERR_PDM_INVALID_DEVICE_GUEST_BITS (-2837)
+/** The guest bit mask didn't match the guest being loaded. */
+#define VERR_PDM_INVALID_DEVICE_HOST_BITS (-2838)
+/** Device name clash. Another device with the same name as the
+ * one begin registred exists. */
+#define VERR_PDM_DEVICE_NAME_CLASH (-2839)
+/** The device wasn't found. There was no registered device
+ * by that name. */
+#define VERR_PDM_DEVICE_NOT_FOUND (-2840)
+/** The device instance was not found. */
+#define VERR_PDM_DEVICE_INSTANCE_NOT_FOUND (-2841)
+/** The device instance have no base interface. */
+#define VERR_PDM_DEVICE_INSTANCE_NO_IBASE (-2842)
+/** The device instance have no such logical unit. */
+#define VERR_PDM_DEVICE_INSTANCE_LUN_NOT_FOUND (-2843)
+/** The driver instance could not be found. */
+#define VERR_PDM_DRIVER_INSTANCE_NOT_FOUND (-2844)
+/** Logical Unit was not found. */
+#define VERR_PDM_LUN_NOT_FOUND (-2845)
+/** The Logical Unit was found, but it had no driver attached to it. */
+#define VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN (-2846)
+/** The Logical Unit was found, but it had no driver attached to it. */
+#define VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN 2846
+/** No PIC device instance is registered with the current VM and thus
+ * the PIC operation cannot be performed. */
+#define VERR_PDM_NO_PIC_INSTANCE (-2847)
+/** No APIC device instance is registered with the current VM and thus
+ * the APIC operation cannot be performed. */
+#define VERR_PDM_NO_APIC_INSTANCE (-2848)
+/** No DMAC device instance is registered with the current VM and thus
+ * the DMA operation cannot be performed. */
+#define VERR_PDM_NO_DMAC_INSTANCE (-2849)
+/** No RTC device instance is registered with the current VM and thus
+ * the RTC or CMOS operation cannot be performed. */
+#define VERR_PDM_NO_RTC_INSTANCE (-2850)
+/** Unable to open the host interface due to a sharing violation . */
+#define VERR_PDM_HIF_SHARING_VIOLATION (-2851)
+/** Unable to open the host interface. */
+#define VERR_PDM_HIF_OPEN_FAILED (-2852)
+/** The device doesn't support runtime driver attaching.
+ * The PDMDEVREG::pfnAttach callback function is NULL. */
+#define VERR_PDM_DEVICE_NO_RT_ATTACH (-2853)
+/** The driver doesn't support runtime driver attaching.
+ * The PDMDRVREG::pfnAttach callback function is NULL. */
+#define VERR_PDM_DRIVER_NO_RT_ATTACH (-2854)
+/** Invalid host interface version. */
+#define VERR_PDM_HIF_INVALID_VERSION (-2855)
+
+/** The version of the USB device registration structure is unknown
+ * to this VBox version. Either mixing incompatible versions or
+ * the structure isn't correctly initialized. */
+#define VERR_PDM_UNKNOWN_USBREG_VERSION (-2856)
+/** Invalid entry in the device registration structure. */
+#define VERR_PDM_INVALID_USB_REGISTRATION (-2857)
+/** Driver name clash. Another driver with the same name as the
+ * one begin registred exists. */
+#define VERR_PDM_USB_NAME_CLASH (-2858)
+/** The USB hub is already registered. */
+#define VERR_PDM_USB_HUB_EXISTS (-2859)
+/** Couldn't find any USB hubs to attach the device to. */
+#define VERR_PDM_NO_USB_HUBS (-2860)
+/** Couldn't find any free USB ports to attach the device to. */
+#define VERR_PDM_NO_USB_PORTS (-2861)
+/** Couldn't find the USB Proxy device. Using OSE? */
+#define VERR_PDM_NO_USBPROXY (-2862)
+/** The async completion template is still used. */
+#define VERR_PDM_ASYNC_TEMPLATE_BUSY (-2863)
+/** The async completion task is already suspended. */
+#define VERR_PDM_ASYNC_COMPLETION_ALREADY_SUSPENDED (-2864)
+/** The async completion task is not suspended. */
+#define VERR_PDM_ASYNC_COMPLETION_NOT_SUSPENDED (-2865)
+/** The driver properties were invalid, and as a consequence construction
+ * failed. Caused my unusable media or similar problems. */
+#define VERR_PDM_DRIVER_INVALID_PROPERTIES (-2866)
+/** Too many instances of a device. */
+#define VERR_PDM_TOO_MANY_DEVICE_INSTANCES (-2867)
+/** Too many instances of a driver. */
+#define VERR_PDM_TOO_MANY_DRIVER_INSTANCES (-2868)
+/** Too many instances of a usb device. */
+#define VERR_PDM_TOO_MANY_USB_DEVICE_INSTANCES (-2869)
+/** The device instance structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DEVINS_VERSION_MISMATCH (-2870)
+/** The device helper structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DEVHLPR3_VERSION_MISMATCH (-2871)
+/** The USB device instance structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_USBINS_VERSION_MISMATCH (-2872)
+/** The USB device helper structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_USBHLPR3_VERSION_MISMATCH (-2873)
+/** The driver instance structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DRVINS_VERSION_MISMATCH (-2874)
+/** The driver helper structure version has changed.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DRVHLPR3_VERSION_MISMATCH (-2875)
+/** Generic device structure version mismatch.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DEVICE_VERSION_MISMATCH (-2876)
+/** Generic USB device structure version mismatch.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_USBDEV_VERSION_MISMATCH (-2877)
+/** Generic driver structure version mismatch.
+ *
+ * If you have upgraded VirtualBox recently, please make sure you have
+ * terminated all VMs and upgraded any extension packs. If this error
+ * persists, try re-installing VirtualBox. */
+#define VERR_PDM_DRIVER_VERSION_MISMATCH (-2878)
+/** PDMVMMDevHeapR3ToGCPhys failure. */
+#define VERR_PDM_DEV_HEAP_R3_TO_GCPHYS (-2879)
+/** A legacy device isn't implementing the HPET notification interface. */
+#define VERR_PDM_HPET_LEGACY_NOTIFY_MISSING (-2880)
+/** Internal processing error in the critical section code. */
+#define VERR_PDM_CRITSECT_IPE (-2881)
+/** The critical section being deleted was not found. */
+#define VERR_PDM_CRITSECT_NOT_FOUND (-2882)
+/** A PDMThread API was called by the wrong thread. */
+#define VERR_PDM_THREAD_INVALID_CALLER (-2883)
+/** Internal processing error \#1 in the PDM Thread code. */
+#define VERR_PDM_THREAD_IPE_1 (-2884)
+/** Internal processing error \#2 in the PDM Thread code. */
+#define VERR_PDM_THREAD_IPE_2 (-2885)
+/** Only one PCI function is supported per PDM device. */
+#define VERR_PDM_ONE_PCI_FUNCTION_PER_DEVICE (-2886)
+/** Bad PCI configuration. */
+#define VERR_PDM_BAD_PCI_CONFIG (-2887)
+/** Internal processing error # in the PDM device code. */
+#define VERR_PDM_DEV_IPE_1 (-2888)
+/** Misconfigured driver chain transformation. */
+#define VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION (-2889)
+/** The driver is already removed, not more transformations possible (at
+ * present). */
+#define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER (-2890)
+/** @} */
+
+
+/** @name Host-Guest Communication Manager (HGCM) Status Codes
+ * @{
+ */
+/** Requested service does not exist. */
+#define VERR_HGCM_SERVICE_NOT_FOUND (-2900)
+/** Service rejected client connection */
+#define VINF_HGCM_CLIENT_REJECTED 2901
+/** Command address is invalid. */
+#define VERR_HGCM_INVALID_CMD_ADDRESS (-2902)
+/** Service will execute the command in background. */
+#define VINF_HGCM_ASYNC_EXECUTE 2903
+/** HGCM could not perform requested operation because of an internal error. */
+#define VERR_HGCM_INTERNAL (-2904)
+/** Invalid HGCM client id. */
+#define VERR_HGCM_INVALID_CLIENT_ID (-2905)
+/** The HGCM is saving state. */
+#define VINF_HGCM_SAVE_STATE (2906)
+/** Requested service already exists. */
+#define VERR_HGCM_SERVICE_EXISTS (-2907)
+
+/** @} */
+
+
+/** @name Network Address Translation Driver (DrvNAT) Status Codes
+ * @{
+ */
+/** Failed to find the DNS configured for this machine. */
+#define VINF_NAT_DNS 3000
+/** Failed to convert the specified Guest IP to a binary IP address.
+ * Malformed input. */
+#define VERR_NAT_REDIR_GUEST_IP (-3001)
+/** Failed while setting up a redirector rule.
+ * There probably is a conflict between the rule and some existing
+ * service on the computer. */
+#define VERR_NAT_REDIR_SETUP (-3002)
+/** @} */
+
+
+/** @name HostIF Driver (DrvTUN) Status Codes
+ * @{
+ */
+/** The Host Interface Networking init program failed. */
+#define VERR_HOSTIF_INIT_FAILED (-3100)
+/** The Host Interface Networking device name is too long. */
+#define VERR_HOSTIF_DEVICE_NAME_TOO_LONG (-3101)
+/** The Host Interface Networking name config IOCTL call failed. */
+#define VERR_HOSTIF_IOCTL (-3102)
+/** Failed to make the Host Interface Networking handle non-blocking. */
+#define VERR_HOSTIF_BLOCKING (-3103)
+/** If a Host Interface Networking filehandle was specified it's not allowed to
+ * have any init or term programs. */
+#define VERR_HOSTIF_FD_AND_INIT_TERM (-3104)
+/** The Host Interface Networking terminate program failed. */
+#define VERR_HOSTIF_TERM_FAILED (-3105)
+/** @} */
+
+
+/** @name VBox HDD Container (VD) Status Codes
+ * @{
+ */
+/** Invalid image type. */
+#define VERR_VD_INVALID_TYPE (-3200)
+/** Operation can't be done in current HDD container state. */
+#define VERR_VD_INVALID_STATE (-3201)
+/** Configuration value not found. */
+#define VERR_VD_VALUE_NOT_FOUND (-3202)
+/** Virtual HDD is not opened. */
+#define VERR_VD_NOT_OPENED (-3203)
+/** Requested image is not opened. */
+#define VERR_VD_IMAGE_NOT_FOUND (-3204)
+/** Image is read-only. */
+#define VERR_VD_IMAGE_READ_ONLY (-3205)
+/** Geometry hasn't been set. */
+#define VERR_VD_GEOMETRY_NOT_SET (-3206)
+/** No data for this block in image. */
+#define VERR_VD_BLOCK_FREE (-3207)
+/** Differencing and parent images can't be used together due to UUID. */
+#define VERR_VD_UUID_MISMATCH (-3208)
+/** Asynchronous I/O request finished. */
+#define VINF_VD_ASYNC_IO_FINISHED 3209
+/** Asynchronous I/O is not finished yet. */
+#define VERR_VD_ASYNC_IO_IN_PROGRESS (-3210)
+/** The image is too small or too large for this format. */
+#define VERR_VD_INVALID_SIZE (-3211)
+/** Generic: Invalid image file header. Use this for plugins. */
+#define VERR_VD_GEN_INVALID_HEADER (-3220)
+/** VDI: Invalid image file header. */
+#define VERR_VD_VDI_INVALID_HEADER (-3230)
+/** VDI: Invalid image file header: invalid signature. */
+#define VERR_VD_VDI_INVALID_SIGNATURE (-3231)
+/** VDI: Invalid image file header: invalid version. */
+#define VERR_VD_VDI_UNSUPPORTED_VERSION (-3232)
+/** Comment string is too long. */
+#define VERR_VD_VDI_COMMENT_TOO_LONG (-3233)
+/** VMDK: Invalid image file header. */
+#define VERR_VD_VMDK_INVALID_HEADER (-3240)
+/** VMDK: Invalid image file header: invalid version. */
+#define VERR_VD_VMDK_UNSUPPORTED_VERSION (-3241)
+/** VMDK: Image property not found. */
+#define VERR_VD_VMDK_VALUE_NOT_FOUND (-3242)
+/** VMDK: Operation can't be done in current image state. */
+#define VERR_VD_VMDK_INVALID_STATE (-3243)
+/** VMDK: Format is invalid/inconsistent. */
+#define VERR_VD_VMDK_INVALID_FORMAT (-3244)
+/** VMDK: Invalid write position. */
+#define VERR_VD_VMDK_INVALID_WRITE (-3245)
+/** iSCSI: Invalid header, i.e. dummy for validity check. */
+#define VERR_VD_ISCSI_INVALID_HEADER (-3250)
+/** iSCSI: Configuration value is unknown. This indicates misconfiguration. */
+#define VERR_VD_ISCSI_UNKNOWN_CFG_VALUES (-3251)
+/** iSCSI: Interface is unknown. This indicates misconfiguration. */
+#define VERR_VD_ISCSI_UNKNOWN_INTERFACE (-3252)
+/** iSCSI: Operation can't be done in current image state. */
+#define VERR_VD_ISCSI_INVALID_STATE (-3253)
+/** iSCSI: Invalid device type (not a disk). */
+#define VERR_VD_ISCSI_INVALID_TYPE (-3254)
+/** iSCSI: Initiator secret not decrypted */
+#define VERR_VD_ISCSI_SECRET_ENCRYPTED (-3255)
+/** VHD: Invalid image file header. */
+#define VERR_VD_VHD_INVALID_HEADER (-3260)
+/** Parallels HDD: Invalid image file header. */
+#define VERR_VD_PARALLELS_INVALID_HEADER (-3265)
+/** DMG: Invalid image file header. */
+#define VERR_VD_DMG_INVALID_HEADER (-3267)
+/** Raw: Invalid image file header. */
+#define VERR_VD_RAW_INVALID_HEADER (-3270)
+/** Raw: Invalid image file type. */
+#define VERR_VD_RAW_INVALID_TYPE (-3271)
+/** The backend needs more metadata before it can continue. */
+#define VERR_VD_NOT_ENOUGH_METADATA (-3272)
+/** Halt the current I/O context until further notification from the backend. */
+#define VERR_VD_IOCTX_HALT (-3273)
+/** The disk has a cache attached already. */
+#define VERR_VD_CACHE_ALREADY_EXISTS (-3274)
+/** There is no cache attached to the disk. */
+#define VERR_VD_CACHE_NOT_FOUND (-3275)
+/** The cache is not up to date with the image. */
+#define VERR_VD_CACHE_NOT_UP_TO_DATE (-3276)
+/** The given range does not meet the required alignment. */
+#define VERR_VD_DISCARD_ALIGNMENT_NOT_MET (-3277)
+/** The discard operation is not supported for this image. */
+#define VERR_VD_DISCARD_NOT_SUPPORTED (-3278)
+/** The image is the correct format but is corrupted. */
+#define VERR_VD_IMAGE_CORRUPTED (-3279)
+/** Repairing the image is not supported. */
+#define VERR_VD_IMAGE_REPAIR_NOT_SUPPORTED (-3280)
+/** Repairing the image is not possible because the corruption is to severe. */
+#define VERR_VD_IMAGE_REPAIR_IMPOSSIBLE (-3281)
+/** Reading from the image was not possible because the offset is out of the image range.
+ * This usually indicates that there is a minor corruption in the image meta data. */
+#define VERR_VD_READ_OUT_OF_RANGE (-3282)
+/** Block read was marked as free in the image and returned as a zero block. */
+#define VINF_VD_NEW_ZEROED_BLOCK 3283
+/** @} */
+
+
+/** @name VBox Guest Library (VBGL) Status Codes
+ * @{
+ */
+/** Library was not initialized. */
+#define VERR_VBGL_NOT_INITIALIZED (-3300)
+/** Virtual address was not allocated by the library. */
+#define VERR_VBGL_INVALID_ADDR (-3301)
+/** IOCtl to VBoxGuest driver failed. */
+#define VERR_VBGL_IOCTL_FAILED (-3302)
+/** @} */
+
+
+/** @name VBox USB (VUSB) Status Codes
+ * @{
+ */
+/** No available ports on the hub.
+ * This error is returned when a device is attempted created and/or attached
+ * to a hub which is out of ports. */
+#define VERR_VUSB_NO_PORTS (-3400)
+/** The requested operation cannot be performed on a detached USB device. */
+#define VERR_VUSB_DEVICE_NOT_ATTACHED (-3401)
+/** Failed to allocate memory for a URB. */
+#define VERR_VUSB_NO_URB_MEMORY (-3402)
+/** General failure during URB queuing.
+ * This will go away when the queueing gets proper status code handling. */
+#define VERR_VUSB_FAILED_TO_QUEUE_URB (-3403)
+/** Device creation failed because the USB device name was not found. */
+#define VERR_VUSB_DEVICE_NAME_NOT_FOUND (-3404)
+/** Not permitted to open the USB device.
+ * The user doesn't have access to the device in the usbfs, check the mount options. */
+#define VERR_VUSB_USBFS_PERMISSION (-3405)
+/** The requested operation cannot be performed because the device
+ * is currently being reset. */
+#define VERR_VUSB_DEVICE_IS_RESETTING (-3406)
+/** The requested operation cannot be performed because the device
+ * is currently suspended. */
+#define VERR_VUSB_DEVICE_IS_SUSPENDED (-3407)
+/** Not permitted to open the USB device.
+ * The user doesn't have access to the device node, check group memberships. */
+#define VERR_VUSB_USB_DEVICE_PERMISSION (-3408)
+/** @} */
+
+
+/** @name VBox VGA Status Codes
+ * @{
+ */
+/** One of the custom modes was incorrect.
+ * The format or bit count of the custom mode value is invalid. */
+#define VERR_VGA_INVALID_CUSTOM_MODE (-3500)
+/** The display connector is resizing. */
+#define VINF_VGA_RESIZE_IN_PROGRESS (3501)
+/** @} */
+
+
+/** @name Internal Networking Status Codes
+ * @{
+ */
+/** The networking interface to filter was not found. */
+#define VERR_INTNET_FLT_IF_NOT_FOUND (-3600)
+/** The networking interface to filter was busy (used by someone). */
+#define VERR_INTNET_FLT_IF_BUSY (-3601)
+/** Failed to create or connect to a networking interface filter. */
+#define VERR_INTNET_FLT_IF_FAILED (-3602)
+/** The network already exists with a different trunk configuration. */
+#define VERR_INTNET_INCOMPATIBLE_TRUNK (-3603)
+/** The network already exists with a different security profile (restricted / public). */
+#define VERR_INTNET_INCOMPATIBLE_FLAGS (-3604)
+/** Failed to create a virtual network interface instance. */
+#define VERR_INTNET_FLT_VNIC_CREATE_FAILED (-3605)
+/** @} */
+
+
+/** @name Support Driver Status Codes
+ * @{
+ */
+/** The component factory was not found. */
+#define VERR_SUPDRV_COMPONENT_NOT_FOUND (-3700)
+/** The component factories do not support the requested interface. */
+#define VERR_SUPDRV_INTERFACE_NOT_SUPPORTED (-3701)
+/** The service module was not found. */
+#define VERR_SUPDRV_SERVICE_NOT_FOUND (-3702)
+/** The host kernel is too old. */
+#define VERR_SUPDRV_KERNEL_TOO_OLD_FOR_VTX (-3703)
+/** Bad VTG magic value. */
+#define VERR_SUPDRV_VTG_MAGIC (-3704)
+/** Bad VTG bit count value. */
+#define VERR_SUPDRV_VTG_BITS (-3705)
+/** Bad VTG header - misc. */
+#define VERR_SUPDRV_VTG_BAD_HDR_MISC (-3706)
+/** Bad VTG header - offset. */
+#define VERR_SUPDRV_VTG_BAD_HDR_OFF (-3707)
+/** Bad VTG header - offset. */
+#define VERR_SUPDRV_VTG_BAD_HDR_PTR (-3708)
+/** Bad VTG header - to low value. */
+#define VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW (-3709)
+/** Bad VTG header - to high value. */
+#define VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH (-3710)
+/** Bad VTG header - size value is not a multiple of the structure size. */
+#define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE (-3711)
+/** Bad VTG string table offset. */
+#define VERR_SUPDRV_VTG_STRTAB_OFF (-3712)
+/** Bad VTG string. */
+#define VERR_SUPDRV_VTG_BAD_STRING (-3713)
+/** VTG string is too long. */
+#define VERR_SUPDRV_VTG_STRING_TOO_LONG (-3714)
+/** Bad VTG attribute value. */
+#define VERR_SUPDRV_VTG_BAD_ATTR (-3715)
+/** Bad VTG provider descriptor. */
+#define VERR_SUPDRV_VTG_BAD_PROVIDER (-3716)
+/** Bad VTG probe descriptor. */
+#define VERR_SUPDRV_VTG_BAD_PROBE (-3717)
+/** Bad VTG argument list descriptor. */
+#define VERR_SUPDRV_VTG_BAD_ARGLIST (-3718)
+/** Bad VTG probe enabled data. */
+#define VERR_SUPDRV_VTG_BAD_PROBE_ENABLED (-3719)
+/** Bad VTG probe location record. */
+#define VERR_SUPDRV_VTG_BAD_PROBE_LOC (-3720)
+/** The VTG object for the session or image has already been registered. */
+#define VERR_SUPDRV_VTG_ALREADY_REGISTERED (-3721)
+/** A driver may only register one VTG object per session. */
+#define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION (-3722)
+/** A tracer has already been registered. */
+#define VERR_SUPDRV_TRACER_ALREADY_REGISTERED (-3723)
+/** The session has no tracer associated with it. */
+#define VERR_SUPDRV_TRACER_NOT_REGISTERED (-3724)
+/** The tracer has already been opened in this sesssion. */
+#define VERR_SUPDRV_TRACER_ALREADY_OPENED (-3725)
+/** The tracer has not been opened. */
+#define VERR_SUPDRV_TRACER_NOT_OPENED (-3726)
+/** There is no tracer present. */
+#define VERR_SUPDRV_TRACER_NOT_PRESENT (-3727)
+/** The tracer is unloading. */
+#define VERR_SUPDRV_TRACER_UNLOADING (-3728)
+/** Another thread in the session is talking to the tracer. */
+#define VERR_SUPDRV_TRACER_SESSION_BUSY (-3729)
+/** The tracer cannot open it self in the same session. */
+#define VERR_SUPDRV_TRACER_CANNOT_OPEN_SELF (-3730)
+/** Bad argument flags. */
+#define VERR_SUPDRV_TRACER_BAD_ARG_FLAGS (-3731)
+/** The session has reached the max number of (user mode) providers. */
+#define VERR_SUPDRV_TRACER_TOO_MANY_PROVIDERS (-3732)
+/** The tracepoint provider object is too large. */
+#define VERR_SUPDRV_TRACER_TOO_LARGE (-3733)
+/** The probe location array isn't adjacent to the probe enable array. */
+#define VERR_SUPDRV_TRACER_UMOD_NOT_ADJACENT (-3734)
+/** The user mode tracepoint provider has too many probe locations and
+ * probes. */
+#define VERR_SUPDRV_TRACER_UMOD_TOO_MANY_PROBES (-3735)
+/** The user mode tracepoint provider string table is too large. */
+#define VERR_SUPDRV_TRACER_UMOD_STRTAB_TOO_BIG (-3736)
+/** The user mode tracepoint provider string table offset is bad. */
+#define VERR_SUPDRV_TRACER_UMOD_STRTAB_OFF_BAD (-3737)
+/** @} */
+
+
+/** @name Support Library Status Codes
+ * @{
+ */
+/** The specified path was not absolute (hardening). */
+#define VERR_SUPLIB_PATH_NOT_ABSOLUTE (-3750)
+/** The specified path was not clean (hardening). */
+#define VERR_SUPLIB_PATH_NOT_CLEAN (-3751)
+/** The specified path is too long (hardening). */
+#define VERR_SUPLIB_PATH_TOO_LONG (-3752)
+/** The specified path is too short (hardening). */
+#define VERR_SUPLIB_PATH_TOO_SHORT (-3753)
+/** The specified path has too many components (hardening). */
+#define VERR_SUPLIB_PATH_TOO_MANY_COMPONENTS (-3754)
+/** The specified path is a root path (hardening). */
+#define VERR_SUPLIB_PATH_IS_ROOT (-3755)
+/** Failed to enumerate directory (hardening). */
+#define VERR_SUPLIB_DIR_ENUM_FAILED (-3756)
+/** Failed to stat a file/dir during enumeration (hardening). */
+#define VERR_SUPLIB_STAT_ENUM_FAILED (-3757)
+/** Failed to stat a file/dir (hardening). */
+#define VERR_SUPLIB_STAT_FAILED (-3758)
+/** Failed to fstat a native handle (hardening). */
+#define VERR_SUPLIB_FSTAT_FAILED (-3759)
+/** Found an illegal symbolic link (hardening). */
+#define VERR_SUPLIB_SYMLINKS_ARE_NOT_PERMITTED (-3760)
+/** Found something which isn't a file nor a directory (hardening). */
+#define VERR_SUPLIB_NOT_DIR_NOT_FILE (-3761)
+/** The specified path is a directory and not a file (hardening). */
+#define VERR_SUPLIB_IS_DIRECTORY (-3762)
+/** The specified path is a file and not a directory (hardening). */
+#define VERR_SUPLIB_IS_FILE (-3763)
+/** The path is not the same object as the native handle (hardening). */
+#define VERR_SUPLIB_NOT_SAME_OBJECT (-3764)
+/** The owner is not root (hardening). */
+#define VERR_SUPLIB_OWNER_NOT_ROOT (-3765)
+/** The group is a non-system group and it has write access (hardening). */
+#define VERR_SUPLIB_WRITE_NON_SYS_GROUP (-3766)
+/** The file or directory is world writable (hardening). */
+#define VERR_SUPLIB_WORLD_WRITABLE (-3767)
+/** The argv[0] of an internal application does not match the executable image
+ * path (hardening). */
+#define VERR_SUPLIB_INVALID_ARGV0_INTERNAL (-3768)
+/** The internal application does not reside in the correct place (hardening). */
+#define VERR_SUPLIB_INVALID_INTERNAL_APP_DIR (-3769)
+/** @} */
+
+
+/** @name VBox GMM Status Codes
+ * @{
+ */
+/** The GMM is out of pages and needs to be give another chunk of user memory that
+ * it can lock down and borrow pages from. */
+#define VERR_GMM_SEED_ME (-3800)
+/** Unable to allocate more pages from the host system. */
+#define VERR_GMM_OUT_OF_MEMORY (-3801)
+/** Hit the global allocation limit.
+ * If you know there is still sufficient memory available, try raising the limit. */
+#define VERR_GMM_HIT_GLOBAL_LIMIT (-3802)
+/** Hit the a VM account limit. */
+#define VERR_GMM_HIT_VM_ACCOUNT_LIMIT (-3803)
+/** Attempt to free more memory than what was previously allocated. */
+#define VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH (-3804)
+/** Attempted to report too many pages as deflated. */
+#define VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH (-3805)
+/** The page to be freed or updated was not found. */
+#define VERR_GMM_PAGE_NOT_FOUND (-3806)
+/** The specified shared page was not actually private. */
+#define VERR_GMM_PAGE_NOT_PRIVATE (-3807)
+/** The specified shared page was not actually shared. */
+#define VERR_GMM_PAGE_NOT_SHARED (-3808)
+/** The page to be freed was already freed. */
+#define VERR_GMM_PAGE_ALREADY_FREE (-3809)
+/** The page to be updated or freed was noted owned by the caller. */
+#define VERR_GMM_NOT_PAGE_OWNER (-3810)
+/** The specified chunk was not found. */
+#define VERR_GMM_CHUNK_NOT_FOUND (-3811)
+/** The chunk has already been mapped into the process. */
+#define VERR_GMM_CHUNK_ALREADY_MAPPED (-3812)
+/** The chunk to be unmapped isn't actually mapped into the process. */
+#define VERR_GMM_CHUNK_NOT_MAPPED (-3813)
+/** The chunk has been mapped too many times already (impossible). */
+#define VERR_GMM_TOO_MANY_CHUNK_MAPPINGS (-3814)
+/** The reservation or reservation update was declined - too many VMs, too
+ * little memory, and/or too low GMM configuration. */
+#define VERR_GMM_MEMORY_RESERVATION_DECLINED (-3815)
+/** A GMM sanity check failed. */
+#define VERR_GMM_IS_NOT_SANE (-3816)
+/** Inserting a new chunk failed. */
+#define VERR_GMM_CHUNK_INSERT (-3817)
+/** Failed to obtain the GMM instance. */
+#define VERR_GMM_INSTANCE (-3818)
+/** Bad mutex semaphore flags. */
+#define VERR_GMM_MTX_FLAGS (-3819)
+/** Internal processing error in the page allocator. */
+#define VERR_GMM_ALLOC_PAGES_IPE (-3820)
+/** Invalid page count given to GMMR3FreePagesPerform. */
+#define VERR_GMM_ACTUAL_PAGES_IPE (-3821)
+/** The shared module name is too long. */
+#define VERR_GMM_MODULE_NAME_TOO_LONG (-3822)
+/** The shared module version string is too long. */
+#define VERR_GMM_MODULE_VERSION_TOO_LONG (-3823)
+/** The shared module has too many regions. */
+#define VERR_GMM_TOO_MANY_REGIONS (-3824)
+/** The guest has reported too many modules. */
+#define VERR_GMM_TOO_MANY_PER_VM_MODULES (-3825)
+/** The guest has reported too many modules. */
+#define VERR_GMM_TOO_MANY_GLOBAL_MODULES (-3826)
+/** The shared module is already registered. */
+#define VINF_GMM_SHARED_MODULE_ALREADY_REGISTERED (3827)
+/** The shared module clashed address wise with a previously registered
+ * module. */
+#define VERR_GMM_SHARED_MODULE_ADDRESS_CLASH (-3828)
+/** The shared module was not found. */
+#define VERR_GMM_SHARED_MODULE_NOT_FOUND (-3829)
+/** The size of the shared module was out of range. */
+#define VERR_GMM_BAD_SHARED_MODULE_SIZE (-3830)
+/** The size of the one or more regions in the shared module was out of
+ * range. */
+#define VERR_GMM_SHARED_MODULE_BAD_REGIONS_SIZE (-3831)
+/** @} */
+
+
+/** @name VBox GVM Status Codes
+ * @{
+ */
+/** The GVM is out of VM handle space. */
+#define VERR_GVM_TOO_MANY_VMS (-3900)
+/** The EMT was not blocked at the time of the call. */
+#define VINF_GVM_NOT_BLOCKED 3901
+/** The EMT was not busy running guest code at the time of the call. */
+#define VINF_GVM_NOT_BUSY_IN_GC 3902
+/** RTThreadYield was called during a GVMMR0SchedPoll call. */
+#define VINF_GVM_YIELDED 3903
+/** @} */
+
+
+/** @name VBox VMX Status Codes
+ * @{
+ */
+/** Invalid VMCS index or write to read-only element. */
+#define VERR_VMX_INVALID_VMCS_FIELD (-4000)
+/** Invalid VMCS pointer. */
+#define VERR_VMX_INVALID_VMCS_PTR (-4001)
+/** Invalid VMXON pointer. */
+#define VERR_VMX_INVALID_VMXON_PTR (-4002)
+/** Generic VMX failure. */
+#define VERR_VMX_GENERIC (-4003)
+/** Invalid CPU mode for VMX execution. */
+#define VERR_VMX_UNSUPPORTED_MODE (-4004)
+/** Unable to start VM execution. */
+#define VERR_VMX_UNABLE_TO_START_VM (-4005)
+/** Unable to resume VM execution. */
+#define VERR_VMX_UNABLE_TO_RESUME_VM (-4006)
+/** Unable to switch due to invalid host state. */
+#define VERR_VMX_INVALID_HOST_STATE (-4007)
+/** IA32_FEATURE_CONTROL MSR not setup correcty (turn on VMX in the host system BIOS) */
+#define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4008)
+/** VMX CPU extension not available */
+#define VERR_VMX_NO_VMX (-4009)
+/** VMXON failed; possibly because it was already run before */
+#define VERR_VMX_VMXON_FAILED (-4010)
+/** CPU was incorrectly left in VMX root mode; incompatible with VirtualBox */
+#define VERR_VMX_IN_VMX_ROOT_MODE (-4011)
+/** Somebody cleared X86_CR4_VMXE in the CR4 register. */
+#define VERR_VMX_X86_CR4_VMXE_CLEARED (-4012)
+/** VT-x features locked or unavailable in MSR. */
+#define VERR_VMX_MSR_LOCKED_OR_DISABLED (-4013)
+/** Unable to switch due to invalid guest state. */
+#define VERR_VMX_INVALID_GUEST_STATE (-4014)
+/** Unexpected VM exit code. */
+#define VERR_VMX_UNEXPECTED_EXIT_CODE (-4015)
+/** Unexpected VM exception code. */
+#define VERR_VMX_UNEXPECTED_EXCEPTION (-4016)
+/** Unexpected interruption exit code. */
+#define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE (-4017)
+/** CPU is not in VMX root mode; unexpected when leaving VMX root mode */
+#define VERR_VMX_NOT_IN_VMX_ROOT_MODE (-4018)
+/** @} */
+
+
+/** @name VBox SVM Status Codes
+ * @{
+ */
+/** Unable to start VM execution. */
+#define VERR_SVM_UNABLE_TO_START_VM (-4050)
+/** AMD-V bit not set in K6_EFER MSR */
+#define VERR_SVM_ILLEGAL_EFER_MSR (-4051)
+/** AMD-V CPU extension not available. */
+#define VERR_SVM_NO_SVM (-4052)
+/** AMD-V CPU extension disabled (by BIOS). */
+#define VERR_SVM_DISABLED (-4053)
+/** AMD-V CPU extension in-use. */
+#define VERR_SVM_IN_USE (-4054)
+/** @} */
+
+
+/** @name VBox HWACCM Status Codes
+ * @{
+ */
+/** Unable to start VM execution. */
+#define VERR_HWACCM_UNKNOWN_CPU (-4100)
+/** No CPUID support. */
+#define VERR_HWACCM_NO_CPUID (-4101)
+/** Host is about to go into suspend mode. */
+#define VERR_HWACCM_SUSPEND_PENDING (-4102)
+/** Conflicting CFGM values. */
+#define VERR_HWACCM_CONFIG_MISMATCH (-4103)
+/** Internal processing error in the HM init code. */
+#define VERR_HM_ALREADY_ENABLED_IPE (-4104)
+/** Unexpected MSR in the load / restore list. */
+#define VERR_HM_UNEXPECTED_LD_ST_MSR (-4105)
+/** No 32-bit to 64-bit switcher in place. */
+#define VERR_HM_NO_32_TO_64_SWITCHER (-4106)
+/** Invalid pVMCB. */
+#define VERR_HMSVM_INVALID_PVMCB (-4107)
+/** Unexpected SVM exit. */
+#define VERR_HMSVM_UNEXPECTED_EXIT (-4108)
+/** Unexpected SVM exception exit. */
+#define VERR_HMSVM_UNEXPECTED_XCPT_EXIT (-4109)
+/** Unexpected SVM patch type. */
+#define VERR_HMSVM_UNEXPECTED_PATCH_TYPE (-4110)
+/** HWACCMR0Leave was called on the wrong CPU. */
+#define VERR_HM_WRONG_CPU_1 (-4111)
+/** Internal processing error \#1 in the HM code. */
+#define VERR_HM_IPE_1 (-4112)
+/** Internal processing error \#2 in the HM code. */
+#define VERR_HM_IPE_2 (-4113)
+/** Wrong 32/64-bit switcher. */
+#define VERR_HM_WRONG_SWITCHER (-4114)
+/** Unknown I/O instruction. */
+#define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4115)
+/** @} */
+
+
+/** @name VBox Disassembler Status Codes
+ * @{
+ */
+/** Invalid opcode byte(s) */
+#define VERR_DIS_INVALID_OPCODE (-4200)
+/** Generic failure during disassembly. */
+#define VERR_DIS_GEN_FAILURE (-4201)
+/** No read callback. */
+#define VERR_DIS_NO_READ_CALLBACK (-4202)
+/** Invalid Mod/RM. */
+#define VERR_DIS_INVALID_MODRM (-4203)
+/** Invalid parameter index. */
+#define VERR_DIS_INVALID_PARAMETER (-4204)
+/** Reading opcode bytes failed. */
+#define VERR_DIS_MEM_READ (-4205)
+/** The instruction is too long. */
+#define VERR_DIS_TOO_LONG_INSTR (-4206)
+/** @} */
+
+
+/** @name VBox Webservice Status Codes
+ * @{
+ */
+/** Authentication failed (ISessionManager::logon()) */
+#define VERR_WEB_NOT_AUTHENTICATED (-4300)
+/** Invalid format of managed object reference */
+#define VERR_WEB_INVALID_MANAGED_OBJECT_REFERENCE (-4301)
+/** Invalid session ID in managed object reference */
+#define VERR_WEB_INVALID_SESSION_ID (-4302)
+/** Invalid object ID in managed object reference */
+#define VERR_WEB_INVALID_OBJECT_ID (-4303)
+/** Unsupported interface for managed object reference */
+#define VERR_WEB_UNSUPPORTED_INTERFACE (-4304)
+/** @} */
+
+
+/** @name VBox PARAV Status Codes
+ * @{
+ */
+/** Switch back to host */
+#define VINF_PARAV_SWITCH_TO_HOST 4400
+
+/** @} */
+
+/** @name VBox Video HW Acceleration command status
+ * @{
+ */
+/** command processing is pending, a completion handler will be called */
+#define VINF_VHWA_CMD_PENDING 4500
+
+/** @} */
+
+
+/** @name VBox COM error codes
+ *
+ * @remarks Global::vboxStatusCodeToCOM and Global::vboxStatusCodeFromCOM uses
+ * these for conversion that is lossless with respect to important COM
+ * status codes. These methods should be moved to the glue library.
+ * @{ */
+/** Unexpected turn of events. */
+#define VERR_COM_UNEXPECTED (-4600)
+/** The base of the VirtualBox COM status codes (the lower value)
+ * corresponding 1:1 to VBOX_E_XXX. This is the lowest value. */
+#define VERR_COM_VBOX_LOWEST (-4699)
+/** Object corresponding to the supplied arguments does not exist. */
+#define VERR_COM_OBJECT_NOT_FOUND (VERR_COM_VBOX_LOWEST + 1)
+/** Current virtual machine state prevents the operation. */
+#define VERR_COM_INVALID_VM_STATE (VERR_COM_VBOX_LOWEST + 2)
+/** Virtual machine error occurred attempting the operation. */
+#define VERR_COM_VM_ERROR (VERR_COM_VBOX_LOWEST + 3)
+/** File not accessible or erroneous file contents. */
+#define VERR_COM_FILE_ERROR (VERR_COM_VBOX_LOWEST + 4)
+/** IPRT error. */
+#define VERR_COM_IPRT_ERROR (VERR_COM_VBOX_LOWEST + 5)
+/** Pluggable Device Manager error. */
+#define VERR_COM_PDM_ERROR (VERR_COM_VBOX_LOWEST + 6)
+/** Current object state prohibits operation. */
+#define VERR_COM_INVALID_OBJECT_STATE (VERR_COM_VBOX_LOWEST + 7)
+/** Host operating system related error. */
+#define VERR_COM_HOST_ERROR (VERR_COM_VBOX_LOWEST + 8)
+/** Requested operation is not supported. */
+#define VERR_COM_NOT_SUPPORTED (VERR_COM_VBOX_LOWEST + 9)
+/** Invalid XML found. */
+#define VERR_COM_XML_ERROR (VERR_COM_VBOX_LOWEST + 10)
+/** Current session state prohibits operation. */
+#define VERR_COM_INVALID_SESSION_STATE (VERR_COM_VBOX_LOWEST + 11)
+/** Object being in use prohibits operation. */
+#define VERR_COM_OBJECT_IN_USE (VERR_COM_VBOX_LOWEST + 12)
+/** Returned by callback methods which does not need to be called
+ * again because the client does not actually make use of them. */
+#define VERR_COM_DONT_CALL_AGAIN (VERR_COM_VBOX_LOWEST + 13)
+/** @} */
+
+/** @name VBox CPU hotplug Status codes
+ * @{
+ */
+/** CPU hotplug events from VMMDev are not monitored by the guest. */
+#define VERR_CPU_HOTPLUG_NOT_MONITORED_BY_GUEST (-4700)
+/** @} */
+
+/** @name VBox async I/O manager Status Codes
+ * @{
+ */
+/** Async I/O task is pending, a completion handler will be called. */
+#define VINF_AIO_TASK_PENDING 4800
+/** @} */
+
+/** @name VBox Virtual SCSI Status Codes
+ * @{
+ */
+/** LUN type is not supported. */
+#define VERR_VSCSI_LUN_TYPE_NOT_SUPPORTED (-4900)
+/** LUN is already/still attached to a device. */
+#define VERR_VSCSI_LUN_ATTACHED_TO_DEVICE (-4901)
+/** The specified LUN is invalid. */
+#define VERR_VSCSI_LUN_INVALID (-4902)
+/** The LUN is not attached to the device. */
+#define VERR_VSCSI_LUN_NOT_ATTACHED (-4903)
+/** The LUN is still busy. */
+#define VERR_VSCSI_LUN_BUSY (-4904)
+/** @} */
+
+/** @name VBox FAM Status Codes
+ * @{
+ */
+/** FAM failed to open a connection. */
+#define VERR_FAM_OPEN_FAILED (-5000)
+/** FAM failed to add a file to the list to be monitored. */
+#define VERR_FAM_MONITOR_FILE_FAILED (-5001)
+/** FAM failed to add a directory to the list to be monitored. */
+#define VERR_FAM_MONITOR_DIRECTORY_FAILED (-5002)
+/** The connection to the FAM daemon was lost. */
+#define VERR_FAM_CONNECTION_LOST (-5003)
+/** @} */
+
+
+/** @name PCI Passtrhough Status Codes
+ * @{
+ */
+/** RamPreAlloc not set.
+ * RAM pre-allocation is currently a requirement for PCI passthrough. */
+#define VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC (-5100)
+/** VT-x/AMD-V not active.
+ * PCI passthrough currently works only if VT-x/AMD-V is active. */
+#define VERR_PCI_PASSTHROUGH_NO_HWACCM (-5101)
+/** Nested paging not active.
+ * PCI passthrough currently works only if nested paging is active. */
+#define VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING (-5102)
+/** @} */
+
+
+/** @name GVMM Status Codes
+ * @{
+ */
+/** Internal error obtaining the GVMM instance. */
+#define VERR_GVMM_INSTANCE (-5200)
+/** GVMM does not support the range of CPUs present/possible on the host. */
+#define VERR_GVMM_HOST_CPU_RANGE (-5201)
+/** GVMM ran into some broken IPRT code. */
+#define VERR_GVMM_BROKEN_IPRT (-5202)
+/** Internal processing error \#1 in the GVMM code. */
+#define VERR_GVMM_IPE_1 (-5203)
+/** Internal processing error \#2 in the GVMM code. */
+#define VERR_GVMM_IPE_2 (-5204)
+/** @} */
+
+
+/** @name IEM Status Codes
+ * @{ */
+/** The instruction is not yet implemented by IEM. */
+#define VERR_IEM_INSTR_NOT_IMPLEMENTED (-5300)
+/** This particular aspect of the instruction is not yet implemented by IEM. */
+#define VERR_IEM_ASPECT_NOT_IMPLEMENTED (-5391)
+/** Internal processing error \#1 in the IEM code.. */
+#define VERR_IEM_IPE_1 (-5392)
+/** Internal processing error \#2 in the IEM code.. */
+#define VERR_IEM_IPE_2 (-5393)
+/** Internal processing error \#3 in the IEM code.. */
+#define VERR_IEM_IPE_3 (-5394)
+/** Restart the current instruction. For testing only. */
+#define VERR_IEM_RESTART_INSTRUCTION (-5395)
+/** @} */
+
+
+/** @name DBGC Status Codes
+ * @{ */
+/** Status that causes DBGC to quit. */
+#define VERR_DBGC_QUIT (-5400)
+/** Async command pending. */
+#define VWRN_DBGC_CMD_PENDING 5401
+/** The command has already been registered. */
+#define VWRN_DBGC_ALREADY_REGISTERED 5402
+/** The command cannot be deregistered because has not been registered. */
+#define VERR_DBGC_COMMANDS_NOT_REGISTERED (-5403)
+/** Unknown breakpoint. */
+#define VERR_DBGC_BP_NOT_FOUND (-5404)
+/** The breakpoint already exists. */
+#define VERR_DBGC_BP_EXISTS (-5405)
+/** The breakpoint has no command. */
+#define VINF_DBGC_BP_NO_COMMAND 5406
+/** Generic debugger command failure. */
+#define VERR_DBGC_COMMAND_FAILED (-5407)
+/** Logic bug in the DBGC code.. */
+#define VERR_DBGC_IPE (-5408)
+
+/** The lowest parse status code. */
+#define VERR_DBGC_PARSE_LOWEST (-5499)
+/** Syntax error - too few arguments. */
+#define VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS (VERR_DBGC_PARSE_LOWEST + 0)
+/** Syntax error - too many arguments. */
+#define VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS (VERR_DBGC_PARSE_LOWEST + 1)
+/** Syntax error - too many arguments for static storage. */
+#define VERR_DBGC_PARSE_ARGUMENT_OVERFLOW (VERR_DBGC_PARSE_LOWEST + 2)
+/** Syntax error - expected binary operator. */
+#define VERR_DBGC_PARSE_EXPECTED_BINARY_OP (VERR_DBGC_PARSE_LOWEST + 3)
+
+/** Syntax error - the argument does not allow a range to be specified. */
+#define VERR_DBGC_PARSE_NO_RANGE_ALLOWED (VERR_DBGC_PARSE_LOWEST + 5)
+/** Syntax error - unbalanced quotes. */
+#define VERR_DBGC_PARSE_UNBALANCED_QUOTE (VERR_DBGC_PARSE_LOWEST + 6)
+/** Syntax error - unbalanced parenthesis. */
+#define VERR_DBGC_PARSE_UNBALANCED_PARENTHESIS (VERR_DBGC_PARSE_LOWEST + 7)
+/** Syntax error - an argument or subargument contains nothing useful. */
+#define VERR_DBGC_PARSE_EMPTY_ARGUMENT (VERR_DBGC_PARSE_LOWEST + 8)
+/** Syntax error - invalid operator usage. */
+#define VERR_DBGC_PARSE_UNEXPECTED_OPERATOR (VERR_DBGC_PARSE_LOWEST + 9)
+/** Syntax error - invalid numeric value. */
+#define VERR_DBGC_PARSE_INVALID_NUMBER (VERR_DBGC_PARSE_LOWEST + 10)
+/** Syntax error - numeric overflow. */
+#define VERR_DBGC_PARSE_NUMBER_TOO_BIG (VERR_DBGC_PARSE_LOWEST + 11)
+/** Syntax error - invalid operation attempted. */
+#define VERR_DBGC_PARSE_INVALID_OPERATION (VERR_DBGC_PARSE_LOWEST + 12)
+/** Syntax error - function not found. */
+#define VERR_DBGC_PARSE_FUNCTION_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 13)
+/** Syntax error - the specified function is not a function. */
+#define VERR_DBGC_PARSE_NOT_A_FUNCTION (VERR_DBGC_PARSE_LOWEST + 14)
+/** Syntax error - out of scratch memory. */
+#define VERR_DBGC_PARSE_NO_SCRATCH (VERR_DBGC_PARSE_LOWEST + 15)
+/** Syntax error - out of regular heap memory. */
+#define VERR_DBGC_PARSE_NO_MEMORY (VERR_DBGC_PARSE_LOWEST + 16)
+/** Syntax error - incorrect argument type. */
+#define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE (VERR_DBGC_PARSE_LOWEST + 17)
+/** Syntax error - an undefined variable was referenced. */
+#define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 18)
+/** Syntax error - a type conversion failed. */
+#define VERR_DBGC_PARSE_CONVERSION_FAILED (VERR_DBGC_PARSE_LOWEST + 19)
+/** Syntax error - you hit a debugger feature which isn't implemented yet.
+ * (Feel free to help implement it.) */
+#define VERR_DBGC_PARSE_NOT_IMPLEMENTED (VERR_DBGC_PARSE_LOWEST + 20)
+/** Syntax error - Couldn't staisfy a request for a sepcific result type. */
+#define VERR_DBGC_PARSE_BAD_RESULT_TYPE (VERR_DBGC_PARSE_LOWEST + 21)
+/** Syntax error - Cannot read symbol value, it is a set-only symbol. */
+#define VERR_DBGC_PARSE_WRITEONLY_SYMBOL (VERR_DBGC_PARSE_LOWEST + 22)
+/** Syntax error - Invalid command name. */
+#define VERR_DBGC_PARSE_INVALD_COMMAND_NAME (VERR_DBGC_PARSE_LOWEST + 23)
+/** Syntax error - Command not found. */
+#define VERR_DBGC_PARSE_COMMAND_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 24)
+/** Syntax error - buggy parser. */
+#define VERR_DBGC_PARSE_BUG (VERR_DBGC_PARSE_LOWEST + 25)
+
+
+/** @} */
+
+/** @name VBox Extension Pack Status Codes
+ * @{
+ */
+/** The host is not supported. Uninstall the extension pack.
+ * Returned by the VBOXEXTPACKREG::pfnInstalled. */
+#define VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL (-6000)
+/** The VirtualBox version is not supported by one of the extension packs.
+ *
+ * You have probably upgraded VirtualBox recently. Please upgrade the
+ * extension packs to versions compatible with this VirtualBox release.
+ */
+#define VERR_EXTPACK_VBOX_VERSION_MISMATCH (-6001)
+/** @} */
+
+
+/* SED-END */
+
+/** @} */
+
+
+#endif
+
diff --git a/include/VBox/err.mac b/include/VBox/err.mac
new file mode 100644
index 00000000..2470d6c0
--- /dev/null
+++ b/include/VBox/err.mac
@@ -0,0 +1,812 @@
+%define VERR_NO_VM_MEMORY (-1000)
+%define VERR_DONT_PANIC (-1001)
+%define VERR_UNSUPPORTED_CPU (-1002)
+%define VERR_UNSUPPORTED_CPU_MODE (-1003)
+%define VERR_PAGE_NOT_PRESENT (-1004)
+%define VERR_CFG_INVALID_FORMAT (-1005)
+%define VERR_CFG_NO_VALUE (-1006)
+%define VERR_SELECTOR_NOT_PRESENT (-1007)
+%define VERR_NOT_CODE_SELECTOR (-1008)
+%define VERR_NOT_DATA_SELECTOR (-1009)
+%define VERR_OUT_OF_SELECTOR_BOUNDS (-1010)
+%define VERR_INVALID_SELECTOR (-1011)
+%define VERR_INVALID_RPL (-1012)
+%define VERR_PAGE_MAP_LEVEL4_NOT_PRESENT (-1013)
+%define VERR_PAGE_DIRECTORY_PTR_NOT_PRESENT (-1014)
+%define VERR_RAW_MODE_INVALID_SMP (-1015)
+%define VERR_INVALID_VM_HANDLE (-1016)
+%define VERR_INVALID_VMCPU_HANDLE (-1017)
+%define VERR_INVALID_CPU_ID (-1018)
+%define VERR_TOO_MANY_CPUS (-1019)
+%define VERR_SERVICE_DISABLED (-1020)
+%define VINF_EM_FIRST 1100
+%define VINF_EM_TERMINATE 1100
+%define VINF_EM_DBG_HYPER_STEPPED 1101
+%define VINF_EM_DBG_HYPER_BREAKPOINT 1102
+%define VINF_EM_DBG_HYPER_ASSERTION 1103
+%define VINF_EM_DBG_STOP 1105
+%define VINF_EM_DBG_STEPPED 1106
+%define VINF_EM_DBG_BREAKPOINT 1107
+%define VINF_EM_DBG_STEP 1108
+%define VINF_EM_OFF 1109
+%define VINF_EM_SUSPEND 1110
+%define VINF_EM_RESET 1111
+%define VINF_EM_HALT 1112
+%define VINF_EM_RESUME 1113
+%define VINF_EM_NO_MEMORY 1114
+%define VERR_EM_NO_MEMORY (-1114)
+%define VINF_EM_RESCHEDULE_REM 1115
+%define VINF_EM_RESCHEDULE_HWACC 1116
+%define VINF_EM_RESCHEDULE_RAW 1117
+%define VINF_EM_RESCHEDULE 1118
+%define VINF_EM_RESCHEDULE_PARAV 1119
+%define VINF_EM_WAIT_SIPI 1120
+%define VINF_EM_LAST 1120
+%define VINF_EM_RAW_GUEST_TRAP 1121
+%define VINF_EM_RAW_INTERRUPT 1122
+%define VINF_EM_RAW_INTERRUPT_HYPER 1123
+%define VINF_EM_RAW_RING_SWITCH 1124
+%define VINF_EM_RAW_RING_SWITCH_INT 1125
+%define VINF_EM_RAW_EXCEPTION_PRIVILEGED 1126
+%define VINF_EM_RAW_EMULATE_INSTR 1127
+%define VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT 1128
+%define VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT 1129
+%define VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT 1130
+%define VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT 1131
+%define VINF_EM_RAW_EMULATE_INSTR_PD_FAULT 1132
+%define VERR_EM_RAW_PATCH_CONFLICT (-1133)
+%define VINF_EM_RAW_EMULATE_INSTR_HLT 1134
+%define VINF_EM_RAW_TO_R3 1135
+%define VINF_EM_RAW_TIMER_PENDING 1136
+%define VINF_EM_RAW_INTERRUPT_PENDING 1137
+%define VINF_EM_RAW_STALE_SELECTOR 1138
+%define VINF_EM_RAW_IRET_TRAP 1139
+%define VINF_EM_RAW_EMULATE_IO_BLOCK 1140
+%define VERR_EM_INTERPRETER (-1148)
+%define VERR_EM_INTERNAL_ERROR (-1149)
+%define VINF_EM_PENDING_REQUEST 1150
+%define VINF_EM_RAW_EMULATE_DBG_STEP 1151
+%define VINF_EM_HWACCM_PATCH_TPR_INSTR 1152
+%define VERR_EM_INTERNAL_DISAS_ERROR (-1153)
+%define VERR_EM_UNEXPECTED_MAPPING_CONFLICT (-1154)
+%define VERR_DBGF_NOT_ATTACHED (-1200)
+%define VERR_DBGF_ALREADY_ATTACHED (-1201)
+%define VWRN_DBGF_ALREADY_HALTED 1202
+%define VERR_DBGF_NO_MORE_BP_SLOTS (-1203)
+%define VERR_DBGF_BP_NOT_FOUND (-1204)
+%define VINF_DBGF_BP_ALREADY_ENABLED 1205
+%define VINF_DBGF_BP_ALREADY_DISABLED 1206
+%define VINF_DBGF_BP_ALREADY_EXIST 1207
+%define VERR_DBGF_MEM_NOT_FOUND (-1208)
+%define VERR_DBGF_OS_NOT_DETCTED (-1209)
+%define VINF_DBGF_OS_NOT_DETCTED 1209
+%define VERR_DBGF_REGISTER_NOT_FOUND (-1210)
+%define VINF_DBGF_TRUNCATED_REGISTER 1211
+%define VINF_DBGF_ZERO_EXTENDED_REGISTER 1212
+%define VERR_DBGF_UNSUPPORTED_CAST (-1213)
+%define VERR_DBGF_READ_ONLY_REGISTER (-1214)
+%define VERR_DBGF_REG_IPE_1 (-1215)
+%define VERR_DBGF_REG_IPE_2 (-1216)
+%define VERR_DBGF_HYPER_DB_XCPT (-1217)
+%define VERR_DBGF_STACK_IPE_1 (-1218)
+%define VERR_DBGF_STACK_IPE_2 (-1219)
+%define VERR_DBGF_NO_TRACE_BUFFER (-1220)
+%define VWRN_CONTINUE_ANALYSIS 1400
+%define VWRN_CONTINUE_RECOMPILE VWRN_CONTINUE_ANALYSIS
+%define VWRN_PATM_CONTINUE_SEARCH VWRN_CONTINUE_ANALYSIS
+%define VERR_PATCHING_REFUSED (-1401)
+%define VERR_PATCH_NOT_FOUND (-1402)
+%define VERR_PATCH_DISABLED (-1403)
+%define VWRN_PATCH_ENABLED 1404
+%define VERR_PATCH_ALREADY_DISABLED (-1405)
+%define VERR_PATCH_ALREADY_ENABLED (-1406)
+%define VWRN_PATCH_REMOVED 1407
+%define VINF_PATM_PATCH_TRAP_GP 1408
+%define VINF_PATM_LEAVE_RC_FIRST VINF_PATM_PATCH_TRAP_GP
+%define VINF_PATM_PATCH_TRAP_PF 1409
+%define VINF_PATM_PATCH_INT3 1410
+%define VINF_PATM_CHECK_PATCH_PAGE 1411
+%define VINF_PATM_DUPLICATE_FUNCTION 1412
+%define VINF_PATCH_EMULATE_INSTR 1413
+%define VINF_PATM_HC_MMIO_PATCH_WRITE 1414
+%define VINF_PATM_HC_MMIO_PATCH_READ 1415
+%define VINF_PATM_PENDING_IRQ_AFTER_IRET 1416
+%define VINF_PATM_LEAVE_RC_LAST VINF_PATM_PENDING_IRQ_AFTER_IRET
+%define VERR_PATCH_NO_CONFLICT (-1425)
+%define VERR_PATM_UNSAFE_CODE (-1426)
+%define VWRN_PATCH_END_BRANCH 1427
+%define VERR_PATM_ALREADY_PATCHED (-1428)
+%define VINF_PATM_SPINLOCK_FAILED (1429)
+%define VINF_PATCH_CONTINUE (1430)
+%define VWRN_CSAM_TRAP_NOT_HANDLED 1500
+%define VWRN_CSAM_INSTRUCTION_PATCHED 1501
+%define VWRN_CSAM_PAGE_NOT_FOUND 1502
+%define VINF_CSAM_PENDING_ACTION 1503
+%define VERR_PGM_MAPPING_CONFLICT (-1600)
+%define VERR_PGM_HANDLER_PHYSICAL_NO_RAM_RANGE (-1601)
+%define VERR_PGM_HANDLER_VIRTUAL_CONFLICT (-1602)
+%define VERR_PGM_HANDLER_PHYSICAL_CONFLICT (-1603)
+%define VERR_PGM_INVALID_PAGE_DIRECTORY (-1604)
+%define VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS (-1605)
+%define VERR_PGM_INVALID_GC_PHYSICAL_RANGE (-1606)
+%define VERR_PGM_HANDLER_NOT_FOUND (-1607)
+%define VERR_PGM_RAM_CONFLICT (-1608)
+%define VERR_PGM_MAPPINGS_FIXED (-1609)
+%define VERR_PGM_MAPPINGS_FIX_CONFLICT (-1610)
+%define VERR_PGM_MAPPINGS_FIX_REJECTED (-1611)
+%define VERR_PGM_MAPPINGS_FIX_TOO_SMALL (-1612)
+%define VINF_PGM_SYNC_CR3 1613
+%define VINF_PGM_NO_DIRTY_BIT_TRACKING 1614
+%define VINF_PGM_HANDLED_DIRTY_BIT_FAULT 1615
+%define VINF_PGM_HANDLER_DO_DEFAULT 1616
+%define VERR_PGM_UNSUPPORTED_HOST_PAGING_MODE (-1617)
+%define VERR_PGM_PHYS_PAGE_RESERVED (-1618)
+%define VERR_PGM_NO_HYPERVISOR_ADDRESS (-1619)
+%define VERR_PGM_POOL_FLUSHED (-1620)
+%define VERR_PGM_POOL_CLEARED (-1621)
+%define VINF_PGM_CACHED_PAGE 1622
+%define VINF_PGM_GCPHYS_ALIASED 1623
+%define VINF_PGM_CHANGE_MODE 1624
+%define VINF_PGM_SYNCPAGE_MODIFIED_PDE 1625
+%define VERR_PGM_GCPHYS_RANGE_CROSSES_BOUNDARY (-1626)
+%define VERR_PGM_INTERMEDIATE_PAGING_CONFLICT (-1627)
+%define VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE (-1628)
+%define VERR_PGM_DYNMAP_FAILED (-1629)
+%define VERR_PGM_DYNMAP_FULL_SET (-1630)
+%define VERR_PGM_DYNMAP_SETUP_ERROR (-1631)
+%define VERR_PGM_DYNMAP_EXPAND_ERROR (-1632)
+%define VERR_PGM_PHYS_TLB_UNASSIGNED (-1633)
+%define VERR_PGM_PHYS_TLB_CATCH_ALL (-1634)
+%define VINF_PGM_PHYS_TLB_CATCH_WRITE 1635
+%define VERR_PGM_PHYS_TLB_CATCH_WRITE (-1635)
+%define VERR_PGM_NO_CR3_SHADOW_ROOT (-1636)
+%define VERR_PGM_PHYS_INVALID_PAGE_ID (-1637)
+%define VERR_PGM_PHYS_WR_HIT_HANDLER (-1638)
+%define VERR_PGM_PHYS_NOT_RAM (-1639)
+%define VERR_PGM_PHYS_NOT_ROM (-1640)
+%define VERR_PGM_PHYS_NOT_MMIO (-1641)
+%define VERR_PGM_PHYS_NOT_MMIO2 (-1642)
+%define VERR_PGM_HANDLER_ALREADY_ALIASED (-1643)
+%define VINF_PGM_HANDLER_ALREADY_ALIASED (1643)
+%define VINF_PGM_POOL_FLUSH_PENDING (1644)
+%define VERR_PGM_INVALID_LARGE_PAGE_RANGE (-1645)
+%define VERR_PGM_PHYS_PAGE_BALLOONED (-1646)
+%define VERR_PGM_MAP_MMIO2_ALIAS_MMIO (-1651)
+%define VERR_PGM_MAPPINGS_DISABLED (-1652)
+%define VERR_PGM_MAPPINGS_SMP (-1653)
+%define VERR_PGM_INVALID_SAVED_PAGE_STATE (-1654)
+%define VERR_PGM_LOAD_UNEXPECTED_PAGE_TYPE (-1655)
+%define VERR_PGM_UNEXPECTED_PAGE_STATE (-1656)
+%define VERR_PGM_SAVED_MMIO2_RANGE_NOT_FOUND (-1657)
+%define VERR_PGM_SAVED_MMIO2_PAGE_NOT_FOUND (-1658)
+%define VERR_PGM_SAVED_ROM_RANGE_NOT_FOUND (-1659)
+%define VERR_PGM_SAVED_ROM_PAGE_NOT_FOUND (-1660)
+%define VERR_PGM_SAVED_ROM_PAGE_PROT (-1661)
+%define VERR_PGM_SAVED_REC_TYPE (-1662)
+%define VERR_PGM_DYNMAP_IPE (-1663)
+%define VERR_PGM_HANDY_PAGE_IPE (-1664)
+%define VERR_PGM_PML4_MAPPING (-1665)
+%define VERR_PGM_POOL_GET_PAGE_FAILED (-1666)
+%define VERR_PGM_NOT_USED_IN_MODE (-1667)
+%define VERR_PGM_INVALID_CR3_ADDR (-1668)
+%define VERR_PGM_INVALID_PDPE_ADDR (-1669)
+%define VERR_PGM_PHYS_HANDLER_IPE (-1670)
+%define VERR_PGM_PHYS_PAGE_MAP_IPE_1 (-1671)
+%define VERR_PGM_PHYS_PAGE_MAP_IPE_2 (-1672)
+%define VERR_PGM_PHYS_PAGE_MAP_IPE_3 (-1673)
+%define VERR_PGM_PHYS_PAGE_MAP_IPE_4 (-1674)
+%define VERR_PGM_POOL_TOO_MANY_LOOPS (-1675)
+%define VERR_PGM_MAPPING_IPE (-1676)
+%define VERR_PGM_POOL_MAXED_OUT_ALREADY (-1677)
+%define VERR_PGM_POOL_IPE (-1678)
+%define VERR_PGM_WRITE_MONITOR_ENGAGED (-1679)
+%define VERR_PGM_PHYS_PAGE_GET_IPE (-1680)
+%define VERR_PGM_PHYS_NULL_PAGE_PARAM (-1681)
+%define VERR_PGM_PCI_PASSTHRU_MISCONFIG (-1682)
+%define VERR_MM_RAM_CONFLICT (-1700)
+%define VERR_MM_HYPER_NO_MEMORY (-1701)
+%define VERR_MM_BAD_TRAP_TYPE_IPE (-1702)
+%define VERR_CPUM_RAISE_GP_0 (-1750)
+%define VERR_CPUM_INCOMPATIBLE_CONFIG (-1751)
+%define VERR_CPUM_HIDDEN_CS_LOAD_ERROR (-1752)
+%define VERR_SSM_UNIT_EXISTS (-1800)
+%define VERR_SSM_UNIT_NOT_FOUND (-1801)
+%define VERR_SSM_UNIT_NOT_OWNER (-1802)
+%define VERR_SSM_INTEGRITY (-1810)
+%define VERR_SSM_INTEGRITY_MAGIC (-1811)
+%define VERR_SSM_INTEGRITY_VERSION (-1812)
+%define VERR_SSM_INTEGRITY_SIZE (-1813)
+%define VERR_SSM_INTEGRITY_CRC (-1814)
+%define VERR_SMM_INTEGRITY_MACHINE (-1815)
+%define VERR_SSM_INTEGRITY_HEADER (-1816)
+%define VERR_SSM_INTEGRITY_UNIT (-1817)
+%define VERR_SSM_INTEGRITY_UNIT_MAGIC (-1818)
+%define VERR_SSM_INTEGRITY_UNIT_NOT_FOUND (-1819)
+%define VERR_SSM_INTEGRITY_VBOX_VERSION (-1820)
+%define VERR_SSM_INTEGRITY_FOOTER (-1821)
+%define VERR_SSM_INTEGRITY_REC_HDR (-1822)
+%define VERR_SSM_INTEGRITY_REC_TERM (-1823)
+%define VERR_SSM_INTEGRITY_REC_TERM_CRC (-1824)
+%define VERR_SSM_INTEGRITY_DECOMPRESSION (-1825)
+%define VERR_SSM_INTEGRITY_DIR (-1826)
+%define VERR_SSM_INTEGRITY_DIR_MAGIC (-1827)
+%define VERR_SSM_NO_LOAD_EXEC (-1830)
+%define VERR_SSM_LOADED_TOO_MUCH (-1831)
+%define VERR_SSM_INVALID_STATE (-1832)
+%define VERR_SSM_LOADED_TOO_LITTLE (-1833)
+%define VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION (-1840)
+%define VERR_SSM_DATA_UNIT_FORMAT_CHANGED (-1841)
+%define VERR_SSM_LOAD_CPUID_MISMATCH (-1842)
+%define VERR_SSM_LOAD_MEMORY_SIZE_MISMATCH (-1843)
+%define VERR_SSM_LOAD_CONFIG_MISMATCH (-1844)
+%define VERR_SSM_VIRTUAL_CLOCK_HZ (-1845)
+%define VERR_SSM_IDE_ASYNC_TIMEOUT (-1846)
+%define VERR_SSM_STRUCTURE_MAGIC (-1847)
+%define VERR_SSM_UNEXPECTED_DATA (-1848)
+%define VERR_SSM_GCPHYS_OVERFLOW (-1849)
+%define VERR_SSM_GCPTR_OVERFLOW (-1850)
+%define VINF_SSM_VOTE_FOR_ANOTHER_PASS 1851
+%define VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN 1852
+%define VERR_SSM_VOTE_FOR_GIVING_UP (-1853)
+%define VINF_SSM_DONT_CALL_AGAIN 1854
+%define VERR_SSM_TOO_MANY_PASSES (-1855)
+%define VERR_SSM_STATE_GREW_TOO_BIG (-1856)
+%define VERR_SSM_LOW_ON_DISK_SPACE (-1857)
+%define VERR_SSM_CANCELLED (-1858)
+%define VERR_SSM_NO_PENDING_OPERATION (-1859)
+%define VERR_SSM_ALREADY_CANCELLED (-1860)
+%define VERR_SSM_LIVE_POWERED_OFF (-1861)
+%define VERR_SSM_LIVE_GURU_MEDITATION (-1862)
+%define VERR_SSM_LIVE_FATAL_ERROR (-1863)
+%define VINF_SSM_LIVE_SUSPENDED 1864
+%define VERR_SSM_FIELD_COMPLEX (-1864)
+%define VERR_SSM_FIELD_INVALID_SIZE (-1865)
+%define VERR_SSM_FIELD_OUT_OF_BOUNDS (-1866)
+%define VERR_SSM_FIELD_NOT_CONSECUTIVE (-1867)
+%define VERR_SSM_FIELD_INVALID_CALLBACK (-1868)
+%define VERR_SSM_FIELD_INVALID_PADDING_SIZE (-1869)
+%define VERR_SSM_FIELD_INVALID_VALUE (-1870)
+%define VERR_SSM_STREAM_ERROR (-1871)
+%define VERR_SSM_UNEXPECTED_PASS (-1872)
+%define VERR_SSM_SKIP_BACKWARDS (-1873)
+%define VERR_SSM_MEM_TOO_BIG (-1874)
+%define VERR_SSM_BAD_REC_TYPE (-1875)
+%define VERR_SSM_IPE_1 (-1876)
+%define VERR_SSM_IPE_2 (-1877)
+%define VERR_SSM_IPE_3 (-1878)
+%define VERR_SSM_FIELD_LOAD_ONLY_TRANSFORMATION (-1879)
+%define VERR_VM_ATRESET_NOT_FOUND (-1900)
+%define VERR_VM_REQUEST_INVALID_TYPE (-1901)
+%define VERR_VM_REQUEST_STATE (-1902)
+%define VERR_VM_REQUEST_INVALID_PACKAGE (-1903)
+%define VERR_VM_REQUEST_STATUS_STILL_PENDING (-1904)
+%define VERR_VM_REQUEST_STATUS_FREED (-1905)
+%define VERR_VM_THREAD_NOT_EMT (-1906)
+%define VERR_VM_INVALID_VM_STATE (-1907)
+%define VERR_VM_DRIVER_NOT_INSTALLED (-1908)
+%define VERR_VM_DRIVER_NOT_ACCESSIBLE (-1909)
+%define VERR_VM_DRIVER_LOAD_ERROR (-1910)
+%define VERR_VM_DRIVER_OPEN_ERROR (-1911)
+%define VERR_VM_DRIVER_VERSION_MISMATCH (-1912)
+%define VERR_VM_SAVE_STATE_NOT_ALLOWED (-1913)
+%define VERR_VM_THREAD_IS_EMT (-1914)
+%define VERR_VM_UNEXPECTED_VM_STATE (-1915)
+%define VERR_VM_UNEXPECTED_UNSTABLE_STATE (-1916)
+%define VERR_VM_REQUEST_TOO_MANY_ARGS_IPE (-1917)
+%define VERR_VM_FATAL_WAIT_ERROR (-1918)
+%define VERR_VM_REQUEST_KILLED (-1919)
+%define VINF_VRDP_SUCCESS VINF_SUCCESS
+%define VERR_VRDP_TIMEOUT VERR_TIMEOUT
+%define VERR_VRDP_ISO_UNSUPPORTED (-2000)
+%define VERR_VRDP_SEC_ENGINE_FAIL (-2001)
+%define VERR_VRDP_PROTOCOL_ERROR (-2002)
+%define VERR_VRDP_NOT_SUPPORTED (-2003)
+%define VERR_VRDP_INSUFFICIENT_DATA (-2004)
+%define VERR_VRDP_INVALID_MODE (-2005)
+%define VERR_VRDP_NO_MEMORY (-2006)
+%define VERR_VRDP_ACCESS_DENIED (-2007)
+%define VWRN_VRDP_PDU_NOT_SUPPORTED 2008
+%define VINF_VRDP_PROCESS_PDU 2009
+%define VINF_VRDP_OPERATION_COMPLETED 2010
+%define VINF_VRDP_THREAD_STARTED 2011
+%define VINF_VRDP_RESIZE_REQUESTED 2012
+%define VINF_VRDP_OUTPUT_ENABLE 2013
+%define VERR_CFGM_INTEGER_TOO_BIG (-2100)
+%define VERR_CFGM_CHILD_NOT_FOUND (-2101)
+%define VERR_CFGM_INVALID_CHILD_PATH (-2102)
+%define VERR_CFGM_VALUE_NOT_FOUND (-2103)
+%define VERR_CFGM_NO_PARENT (-2104)
+%define VERR_CFGM_NO_NODE (-2105)
+%define VERR_CFGM_NOT_INTEGER (-2106)
+%define VERR_CFGM_NOT_STRING (-2107)
+%define VERR_CFGM_NOT_BYTES (-2108)
+%define VERR_CFGM_NOT_ENOUGH_SPACE (-2109)
+%define VERR_CFGM_INVALID_NODE_PATH (-2160)
+%define VERR_CFGM_NODE_EXISTS (-2161)
+%define VERR_CFGM_LEAF_EXISTS (-2162)
+%define VERR_CFGM_CONFIG_UNKNOWN_VALUE (-2163)
+%define VERR_CFGM_CONFIG_UNKNOWN_NODE (-2164)
+%define VERR_CFGM_IPE_1 (-2165)
+%define VERR_TM_LOAD_STATE (-2200)
+%define VERR_TM_INVALID_STATE (-2201)
+%define VERR_TM_UNKNOWN_STATE (-2202)
+%define VERR_TM_UNSTABLE_STATE (-2203)
+%define VERR_TM_GIP_REQUIRED (-2204)
+%define VERR_TM_GIP_VERSION (-2205)
+%define VERR_TM_GIP_UPDATE_INTERVAL_TOO_BIG (-2206)
+%define VERR_TM_TIMER_BAD_CLOCK (-2207)
+%define VERR_TM_TIMER_UNSTABLE_STATE (-2208)
+%define VERR_TM_TSC_ALREADY_TICKING (-2209)
+%define VERR_TM_TSC_ALREADY_PAUSED (-2210)
+%define VERR_TM_VIRTUAL_TICKING_IPE (-2211)
+%define VERR_REM_VIRTUAL_HARDWARE_ERROR (-2300)
+%define VERR_REM_VIRTUAL_CPU_ERROR (-2301)
+%define VINF_REM_INTERRUPED_FF 2302
+%define VERR_REM_TOO_MANY_TRAPS (-2304)
+%define VERR_REM_NO_MORE_BP_SLOTS (-2305)
+%define VERR_REM_BP_NOT_FOUND (-2306)
+%define VERR_TRPM_NO_ACTIVE_TRAP (-2400)
+%define VERR_TRPM_ACTIVE_TRAP (-2401)
+%define VERR_TRPM_SHADOW_IDT_WRITE (-2402)
+%define VERR_TRPM_DONT_PANIC (-2403)
+%define VERR_TRPM_PANIC (-2404)
+%define VINF_TRPM_XCPT_DISPATCHED 2405
+%define VERR_TRPM_BAD_TRAP_IN_OP (-2406)
+%define VERR_TRPM_IPE_1 (-2407)
+%define VERR_TRPM_IPE_2 (-2408)
+%define VERR_TRPM_IPE_3 (-2409)
+%define VERR_SELM_SHADOW_GDT_WRITE (-2500)
+%define VERR_SELM_SHADOW_LDT_WRITE (-2501)
+%define VERR_SELM_SHADOW_TSS_WRITE (-2502)
+%define VINF_SELM_SYNC_GDT 2503
+%define VERR_SELM_NO_TSS (-2504)
+%define VERR_SELM_INVALID_LDT (-2505)
+%define VERR_SELM_LDT_OUT_OF_BOUNDS (-2506)
+%define VERR_SELM_GDT_READ_ERROR (-2507)
+%define VERR_SELM_GDT_TOO_FULL (-2508)
+%define VERR_IOM_INVALID_IOPORT_RANGE (-2600)
+%define VERR_IOM_NO_R3_IOPORT_RANGE (-2601)
+%define VERR_IOM_IOPORT_RANGE_CONFLICT (-2602)
+%define VERR_IOM_IOPORT_RANGE_NOT_FOUND (-2603)
+%define VERR_IOM_NOT_IOPORT_RANGE_OWNER (-2604)
+%define VERR_IOM_INVALID_MMIO_RANGE (-2605)
+%define VERR_IOM_NO_R3_MMIO_RANGE (-2606)
+%define VERR_IOM_NOT_MMIO_RANGE_OWNER (-2607)
+%define VERR_IOM_MMIO_RANGE_CONFLICT (-2608)
+%define VERR_IOM_MMIO_RANGE_NOT_FOUND (-2609)
+%define VERR_IOM_INCOMPLETE_MMIO_RANGE (-2610)
+%define VERR_IOM_INVALID_IOPORT_SIZE (-2611)
+%define VERR_IOM_MMIO_HANDLER_BOGUS_CALL (-2612)
+%define VERR_IOM_MMIO_HANDLER_DISASM_ERROR (-2613)
+%define VERR_IOM_IOPORT_UNUSED (-2614)
+%define VINF_IOM_MMIO_UNUSED_00 2615
+%define VINF_IOM_MMIO_UNUSED_FF 2616
+%define VINF_IOM_R3_IOPORT_READ 2620
+%define VINF_IOM_R3_IOPORT_WRITE 2621
+%define VINF_IOM_R3_MMIO_READ 2623
+%define VINF_IOM_R3_MMIO_WRITE 2624
+%define VINF_IOM_R3_MMIO_READ_WRITE 2625
+%define VERR_IOM_IOPORT_UNKNOWN_OPCODE (-2630)
+%define VERR_IOM_IOPORT_IPE_1 (-2631)
+%define VERR_IOM_IOPORT_IPE_2 (-2632)
+%define VERR_IOM_IOPORT_IPE_3 (-2633)
+%define VERR_IOM_MMIO_IPE_1 (-2634)
+%define VERR_IOM_MMIO_IPE_2 (-2635)
+%define VERR_IOM_MMIO_IPE_3 (-2636)
+%define VINF_VMM_CALL_HOST 2700
+%define VERR_VMM_RING0_ASSERTION (-2701)
+%define VERR_VMM_HYPER_CR3_MISMATCH (-2702)
+%define VERR_VMM_RING3_CALL_DISABLED (-2703)
+%define VERR_VMM_R0_VERSION_MISMATCH (-2704)
+%define VERR_VMM_RC_VERSION_MISMATCH (-2705)
+%define VERR_VMM_SET_JMP_ERROR (-2706)
+%define VERR_VMM_SET_JMP_STACK_OVERFLOW (-2707)
+%define VERR_VMM_SET_JMP_ABORTED_RESUME (-2708)
+%define VERR_VMM_LONG_JMP_ERROR (-2709)
+%define VERR_VMM_UNKNOWN_RING3_CALL (-2710)
+%define VERR_VMM_RING3_CALL_NO_RC (-2711)
+%define VINF_VMM_CALL_TRACER (2712)
+%define VERR_VMM_SWITCHER_IPE_1 (-2713)
+%define VERR_PDM_NO_SUCH_LUN (-2800)
+%define VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES (-2801)
+%define VERR_PDM_MISSING_INTERFACE_ABOVE (-2802)
+%define VERR_PDM_MISSING_INTERFACE_BELOW (-2803)
+%define VERR_PDM_MISSING_INTERFACE (-2804)
+%define VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES (-2805)
+%define VERR_PDM_TOO_PCI_MANY_DEVICES (-2806)
+%define VERR_PDM_NO_QUEUE_ITEMS (-2807)
+%define VERR_PDM_DRVINS_NO_ATTACH (-2808)
+%define VERR_PDM_DEVINS_NO_ATTACH (-2809)
+%define VERR_PDM_NO_ATTACHED_DRIVER (-2810)
+%define VERR_PDM_GEOMETRY_NOT_SET (-2811)
+%define VERR_PDM_TRANSLATION_NOT_SET (-2812)
+%define VERR_PDM_MEDIA_NOT_MOUNTED (-2813)
+%define VERR_PDM_MEDIA_MOUNTED (-2814)
+%define VERR_PDM_MEDIA_LOCKED (-2815)
+%define VERR_PDM_BLOCK_NO_TYPE (-2816)
+%define VERR_PDM_BLOCK_UNKNOWN_TYPE (-2817)
+%define VERR_PDM_BLOCK_UNKNOWN_TRANSLATION (-2818)
+%define VERR_PDM_UNSUPPORTED_BLOCK_TYPE (-2819)
+%define VERR_PDM_DRIVER_ALREADY_ATTACHED (-2820)
+%define VERR_PDM_NO_DRIVER_ATTACHED (-2821)
+%define VERR_PDM_CFG_MISSING_DRIVER_NAME (-2822)
+%define VERR_PDM_DRIVER_NOT_FOUND (-2823)
+%define VINF_PDM_ALREADY_LOADED (2824)
+%define VERR_PDM_MODULE_NAME_CLASH (-2825)
+%define VERR_PDM_NO_REGISTRATION_EXPORT (-2826)
+%define VERR_PDM_MODULE_NAME_TOO_LONG (-2827)
+%define VERR_PDM_DRIVER_NAME_CLASH (-2828)
+%define VERR_PDM_UNKNOWN_DRVREG_VERSION (-2829)
+%define VERR_PDM_INVALID_DRIVER_REGISTRATION (-2830)
+%define VERR_PDM_INVALID_DRIVER_HOST_BITS (-2831)
+%define VERR_PDM_DRIVER_DETACH_NOT_POSSIBLE (-2832)
+%define VERR_PDM_NO_PCI_BUS (-2833)
+%define VINF_PDM_PCI_PHYS_READ_BM_DISABLED (2833)
+%define VERR_PDM_NOT_PCI_DEVICE (-2834)
+%define VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED (2834)
+%define VERR_PDM_UNKNOWN_DEVREG_VERSION (-2835)
+%define VERR_PDM_INVALID_DEVICE_REGISTRATION (-2836)
+%define VERR_PDM_INVALID_DEVICE_GUEST_BITS (-2837)
+%define VERR_PDM_INVALID_DEVICE_HOST_BITS (-2838)
+%define VERR_PDM_DEVICE_NAME_CLASH (-2839)
+%define VERR_PDM_DEVICE_NOT_FOUND (-2840)
+%define VERR_PDM_DEVICE_INSTANCE_NOT_FOUND (-2841)
+%define VERR_PDM_DEVICE_INSTANCE_NO_IBASE (-2842)
+%define VERR_PDM_DEVICE_INSTANCE_LUN_NOT_FOUND (-2843)
+%define VERR_PDM_DRIVER_INSTANCE_NOT_FOUND (-2844)
+%define VERR_PDM_LUN_NOT_FOUND (-2845)
+%define VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN (-2846)
+%define VINF_PDM_NO_DRIVER_ATTACHED_TO_LUN 2846
+%define VERR_PDM_NO_PIC_INSTANCE (-2847)
+%define VERR_PDM_NO_APIC_INSTANCE (-2848)
+%define VERR_PDM_NO_DMAC_INSTANCE (-2849)
+%define VERR_PDM_NO_RTC_INSTANCE (-2850)
+%define VERR_PDM_HIF_SHARING_VIOLATION (-2851)
+%define VERR_PDM_HIF_OPEN_FAILED (-2852)
+%define VERR_PDM_DEVICE_NO_RT_ATTACH (-2853)
+%define VERR_PDM_DRIVER_NO_RT_ATTACH (-2854)
+%define VERR_PDM_HIF_INVALID_VERSION (-2855)
+%define VERR_PDM_UNKNOWN_USBREG_VERSION (-2856)
+%define VERR_PDM_INVALID_USB_REGISTRATION (-2857)
+%define VERR_PDM_USB_NAME_CLASH (-2858)
+%define VERR_PDM_USB_HUB_EXISTS (-2859)
+%define VERR_PDM_NO_USB_HUBS (-2860)
+%define VERR_PDM_NO_USB_PORTS (-2861)
+%define VERR_PDM_NO_USBPROXY (-2862)
+%define VERR_PDM_ASYNC_TEMPLATE_BUSY (-2863)
+%define VERR_PDM_ASYNC_COMPLETION_ALREADY_SUSPENDED (-2864)
+%define VERR_PDM_ASYNC_COMPLETION_NOT_SUSPENDED (-2865)
+%define VERR_PDM_DRIVER_INVALID_PROPERTIES (-2866)
+%define VERR_PDM_TOO_MANY_DEVICE_INSTANCES (-2867)
+%define VERR_PDM_TOO_MANY_DRIVER_INSTANCES (-2868)
+%define VERR_PDM_TOO_MANY_USB_DEVICE_INSTANCES (-2869)
+%define VERR_PDM_DEVINS_VERSION_MISMATCH (-2870)
+%define VERR_PDM_DEVHLPR3_VERSION_MISMATCH (-2871)
+%define VERR_PDM_USBINS_VERSION_MISMATCH (-2872)
+%define VERR_PDM_USBHLPR3_VERSION_MISMATCH (-2873)
+%define VERR_PDM_DRVINS_VERSION_MISMATCH (-2874)
+%define VERR_PDM_DRVHLPR3_VERSION_MISMATCH (-2875)
+%define VERR_PDM_DEVICE_VERSION_MISMATCH (-2876)
+%define VERR_PDM_USBDEV_VERSION_MISMATCH (-2877)
+%define VERR_PDM_DRIVER_VERSION_MISMATCH (-2878)
+%define VERR_PDM_DEV_HEAP_R3_TO_GCPHYS (-2879)
+%define VERR_PDM_HPET_LEGACY_NOTIFY_MISSING (-2880)
+%define VERR_PDM_CRITSECT_IPE (-2881)
+%define VERR_PDM_CRITSECT_NOT_FOUND (-2882)
+%define VERR_PDM_THREAD_INVALID_CALLER (-2883)
+%define VERR_PDM_THREAD_IPE_1 (-2884)
+%define VERR_PDM_THREAD_IPE_2 (-2885)
+%define VERR_PDM_ONE_PCI_FUNCTION_PER_DEVICE (-2886)
+%define VERR_PDM_BAD_PCI_CONFIG (-2887)
+%define VERR_PDM_DEV_IPE_1 (-2888)
+%define VERR_PDM_MISCONFIGURED_DRV_TRANSFORMATION (-2889)
+%define VERR_PDM_CANNOT_TRANSFORM_REMOVED_DRIVER (-2890)
+%define VERR_HGCM_SERVICE_NOT_FOUND (-2900)
+%define VINF_HGCM_CLIENT_REJECTED 2901
+%define VERR_HGCM_INVALID_CMD_ADDRESS (-2902)
+%define VINF_HGCM_ASYNC_EXECUTE 2903
+%define VERR_HGCM_INTERNAL (-2904)
+%define VERR_HGCM_INVALID_CLIENT_ID (-2905)
+%define VINF_HGCM_SAVE_STATE (2906)
+%define VERR_HGCM_SERVICE_EXISTS (-2907)
+%define VINF_NAT_DNS 3000
+%define VERR_NAT_REDIR_GUEST_IP (-3001)
+%define VERR_NAT_REDIR_SETUP (-3002)
+%define VERR_HOSTIF_INIT_FAILED (-3100)
+%define VERR_HOSTIF_DEVICE_NAME_TOO_LONG (-3101)
+%define VERR_HOSTIF_IOCTL (-3102)
+%define VERR_HOSTIF_BLOCKING (-3103)
+%define VERR_HOSTIF_FD_AND_INIT_TERM (-3104)
+%define VERR_HOSTIF_TERM_FAILED (-3105)
+%define VERR_VD_INVALID_TYPE (-3200)
+%define VERR_VD_INVALID_STATE (-3201)
+%define VERR_VD_VALUE_NOT_FOUND (-3202)
+%define VERR_VD_NOT_OPENED (-3203)
+%define VERR_VD_IMAGE_NOT_FOUND (-3204)
+%define VERR_VD_IMAGE_READ_ONLY (-3205)
+%define VERR_VD_GEOMETRY_NOT_SET (-3206)
+%define VERR_VD_BLOCK_FREE (-3207)
+%define VERR_VD_UUID_MISMATCH (-3208)
+%define VINF_VD_ASYNC_IO_FINISHED 3209
+%define VERR_VD_ASYNC_IO_IN_PROGRESS (-3210)
+%define VERR_VD_INVALID_SIZE (-3211)
+%define VERR_VD_GEN_INVALID_HEADER (-3220)
+%define VERR_VD_VDI_INVALID_HEADER (-3230)
+%define VERR_VD_VDI_INVALID_SIGNATURE (-3231)
+%define VERR_VD_VDI_UNSUPPORTED_VERSION (-3232)
+%define VERR_VD_VDI_COMMENT_TOO_LONG (-3233)
+%define VERR_VD_VMDK_INVALID_HEADER (-3240)
+%define VERR_VD_VMDK_UNSUPPORTED_VERSION (-3241)
+%define VERR_VD_VMDK_VALUE_NOT_FOUND (-3242)
+%define VERR_VD_VMDK_INVALID_STATE (-3243)
+%define VERR_VD_VMDK_INVALID_FORMAT (-3244)
+%define VERR_VD_VMDK_INVALID_WRITE (-3245)
+%define VERR_VD_ISCSI_INVALID_HEADER (-3250)
+%define VERR_VD_ISCSI_UNKNOWN_CFG_VALUES (-3251)
+%define VERR_VD_ISCSI_UNKNOWN_INTERFACE (-3252)
+%define VERR_VD_ISCSI_INVALID_STATE (-3253)
+%define VERR_VD_ISCSI_INVALID_TYPE (-3254)
+%define VERR_VD_ISCSI_SECRET_ENCRYPTED (-3255)
+%define VERR_VD_VHD_INVALID_HEADER (-3260)
+%define VERR_VD_PARALLELS_INVALID_HEADER (-3265)
+%define VERR_VD_DMG_INVALID_HEADER (-3267)
+%define VERR_VD_RAW_INVALID_HEADER (-3270)
+%define VERR_VD_RAW_INVALID_TYPE (-3271)
+%define VERR_VD_NOT_ENOUGH_METADATA (-3272)
+%define VERR_VD_IOCTX_HALT (-3273)
+%define VERR_VD_CACHE_ALREADY_EXISTS (-3274)
+%define VERR_VD_CACHE_NOT_FOUND (-3275)
+%define VERR_VD_CACHE_NOT_UP_TO_DATE (-3276)
+%define VERR_VD_DISCARD_ALIGNMENT_NOT_MET (-3277)
+%define VERR_VD_DISCARD_NOT_SUPPORTED (-3278)
+%define VERR_VD_IMAGE_CORRUPTED (-3279)
+%define VERR_VD_IMAGE_REPAIR_NOT_SUPPORTED (-3280)
+%define VERR_VD_IMAGE_REPAIR_IMPOSSIBLE (-3281)
+%define VERR_VD_READ_OUT_OF_RANGE (-3282)
+%define VINF_VD_NEW_ZEROED_BLOCK 3283
+%define VERR_VBGL_NOT_INITIALIZED (-3300)
+%define VERR_VBGL_INVALID_ADDR (-3301)
+%define VERR_VBGL_IOCTL_FAILED (-3302)
+%define VERR_VUSB_NO_PORTS (-3400)
+%define VERR_VUSB_DEVICE_NOT_ATTACHED (-3401)
+%define VERR_VUSB_NO_URB_MEMORY (-3402)
+%define VERR_VUSB_FAILED_TO_QUEUE_URB (-3403)
+%define VERR_VUSB_DEVICE_NAME_NOT_FOUND (-3404)
+%define VERR_VUSB_USBFS_PERMISSION (-3405)
+%define VERR_VUSB_DEVICE_IS_RESETTING (-3406)
+%define VERR_VUSB_DEVICE_IS_SUSPENDED (-3407)
+%define VERR_VUSB_USB_DEVICE_PERMISSION (-3408)
+%define VERR_VGA_INVALID_CUSTOM_MODE (-3500)
+%define VINF_VGA_RESIZE_IN_PROGRESS (3501)
+%define VERR_INTNET_FLT_IF_NOT_FOUND (-3600)
+%define VERR_INTNET_FLT_IF_BUSY (-3601)
+%define VERR_INTNET_FLT_IF_FAILED (-3602)
+%define VERR_INTNET_INCOMPATIBLE_TRUNK (-3603)
+%define VERR_INTNET_INCOMPATIBLE_FLAGS (-3604)
+%define VERR_INTNET_FLT_VNIC_CREATE_FAILED (-3605)
+%define VERR_SUPDRV_COMPONENT_NOT_FOUND (-3700)
+%define VERR_SUPDRV_INTERFACE_NOT_SUPPORTED (-3701)
+%define VERR_SUPDRV_SERVICE_NOT_FOUND (-3702)
+%define VERR_SUPDRV_KERNEL_TOO_OLD_FOR_VTX (-3703)
+%define VERR_SUPDRV_VTG_MAGIC (-3704)
+%define VERR_SUPDRV_VTG_BITS (-3705)
+%define VERR_SUPDRV_VTG_BAD_HDR_MISC (-3706)
+%define VERR_SUPDRV_VTG_BAD_HDR_OFF (-3707)
+%define VERR_SUPDRV_VTG_BAD_HDR_PTR (-3708)
+%define VERR_SUPDRV_VTG_BAD_HDR_TOO_FEW (-3709)
+%define VERR_SUPDRV_VTG_BAD_HDR_TOO_MUCH (-3710)
+%define VERR_SUPDRV_VTG_BAD_HDR_NOT_MULTIPLE (-3711)
+%define VERR_SUPDRV_VTG_STRTAB_OFF (-3712)
+%define VERR_SUPDRV_VTG_BAD_STRING (-3713)
+%define VERR_SUPDRV_VTG_STRING_TOO_LONG (-3714)
+%define VERR_SUPDRV_VTG_BAD_ATTR (-3715)
+%define VERR_SUPDRV_VTG_BAD_PROVIDER (-3716)
+%define VERR_SUPDRV_VTG_BAD_PROBE (-3717)
+%define VERR_SUPDRV_VTG_BAD_ARGLIST (-3718)
+%define VERR_SUPDRV_VTG_BAD_PROBE_ENABLED (-3719)
+%define VERR_SUPDRV_VTG_BAD_PROBE_LOC (-3720)
+%define VERR_SUPDRV_VTG_ALREADY_REGISTERED (-3721)
+%define VERR_SUPDRV_VTG_ONLY_ONCE_PER_SESSION (-3722)
+%define VERR_SUPDRV_TRACER_ALREADY_REGISTERED (-3723)
+%define VERR_SUPDRV_TRACER_NOT_REGISTERED (-3724)
+%define VERR_SUPDRV_TRACER_ALREADY_OPENED (-3725)
+%define VERR_SUPDRV_TRACER_NOT_OPENED (-3726)
+%define VERR_SUPDRV_TRACER_NOT_PRESENT (-3727)
+%define VERR_SUPDRV_TRACER_UNLOADING (-3728)
+%define VERR_SUPDRV_TRACER_SESSION_BUSY (-3729)
+%define VERR_SUPDRV_TRACER_CANNOT_OPEN_SELF (-3730)
+%define VERR_SUPDRV_TRACER_BAD_ARG_FLAGS (-3731)
+%define VERR_SUPDRV_TRACER_TOO_MANY_PROVIDERS (-3732)
+%define VERR_SUPDRV_TRACER_TOO_LARGE (-3733)
+%define VERR_SUPDRV_TRACER_UMOD_NOT_ADJACENT (-3734)
+%define VERR_SUPDRV_TRACER_UMOD_TOO_MANY_PROBES (-3735)
+%define VERR_SUPDRV_TRACER_UMOD_STRTAB_TOO_BIG (-3736)
+%define VERR_SUPDRV_TRACER_UMOD_STRTAB_OFF_BAD (-3737)
+%define VERR_SUPLIB_PATH_NOT_ABSOLUTE (-3750)
+%define VERR_SUPLIB_PATH_NOT_CLEAN (-3751)
+%define VERR_SUPLIB_PATH_TOO_LONG (-3752)
+%define VERR_SUPLIB_PATH_TOO_SHORT (-3753)
+%define VERR_SUPLIB_PATH_TOO_MANY_COMPONENTS (-3754)
+%define VERR_SUPLIB_PATH_IS_ROOT (-3755)
+%define VERR_SUPLIB_DIR_ENUM_FAILED (-3756)
+%define VERR_SUPLIB_STAT_ENUM_FAILED (-3757)
+%define VERR_SUPLIB_STAT_FAILED (-3758)
+%define VERR_SUPLIB_FSTAT_FAILED (-3759)
+%define VERR_SUPLIB_SYMLINKS_ARE_NOT_PERMITTED (-3760)
+%define VERR_SUPLIB_NOT_DIR_NOT_FILE (-3761)
+%define VERR_SUPLIB_IS_DIRECTORY (-3762)
+%define VERR_SUPLIB_IS_FILE (-3763)
+%define VERR_SUPLIB_NOT_SAME_OBJECT (-3764)
+%define VERR_SUPLIB_OWNER_NOT_ROOT (-3765)
+%define VERR_SUPLIB_WRITE_NON_SYS_GROUP (-3766)
+%define VERR_SUPLIB_WORLD_WRITABLE (-3767)
+%define VERR_SUPLIB_INVALID_ARGV0_INTERNAL (-3768)
+%define VERR_SUPLIB_INVALID_INTERNAL_APP_DIR (-3769)
+%define VERR_GMM_SEED_ME (-3800)
+%define VERR_GMM_OUT_OF_MEMORY (-3801)
+%define VERR_GMM_HIT_GLOBAL_LIMIT (-3802)
+%define VERR_GMM_HIT_VM_ACCOUNT_LIMIT (-3803)
+%define VERR_GMM_ATTEMPT_TO_FREE_TOO_MUCH (-3804)
+%define VERR_GMM_ATTEMPT_TO_DEFLATE_TOO_MUCH (-3805)
+%define VERR_GMM_PAGE_NOT_FOUND (-3806)
+%define VERR_GMM_PAGE_NOT_PRIVATE (-3807)
+%define VERR_GMM_PAGE_NOT_SHARED (-3808)
+%define VERR_GMM_PAGE_ALREADY_FREE (-3809)
+%define VERR_GMM_NOT_PAGE_OWNER (-3810)
+%define VERR_GMM_CHUNK_NOT_FOUND (-3811)
+%define VERR_GMM_CHUNK_ALREADY_MAPPED (-3812)
+%define VERR_GMM_CHUNK_NOT_MAPPED (-3813)
+%define VERR_GMM_TOO_MANY_CHUNK_MAPPINGS (-3814)
+%define VERR_GMM_MEMORY_RESERVATION_DECLINED (-3815)
+%define VERR_GMM_IS_NOT_SANE (-3816)
+%define VERR_GMM_CHUNK_INSERT (-3817)
+%define VERR_GMM_INSTANCE (-3818)
+%define VERR_GMM_MTX_FLAGS (-3819)
+%define VERR_GMM_ALLOC_PAGES_IPE (-3820)
+%define VERR_GMM_ACTUAL_PAGES_IPE (-3821)
+%define VERR_GMM_MODULE_NAME_TOO_LONG (-3822)
+%define VERR_GMM_MODULE_VERSION_TOO_LONG (-3823)
+%define VERR_GMM_TOO_MANY_REGIONS (-3824)
+%define VERR_GMM_TOO_MANY_PER_VM_MODULES (-3825)
+%define VERR_GMM_TOO_MANY_GLOBAL_MODULES (-3826)
+%define VINF_GMM_SHARED_MODULE_ALREADY_REGISTERED (3827)
+%define VERR_GMM_SHARED_MODULE_ADDRESS_CLASH (-3828)
+%define VERR_GMM_SHARED_MODULE_NOT_FOUND (-3829)
+%define VERR_GMM_BAD_SHARED_MODULE_SIZE (-3830)
+%define VERR_GMM_SHARED_MODULE_BAD_REGIONS_SIZE (-3831)
+%define VERR_GVM_TOO_MANY_VMS (-3900)
+%define VINF_GVM_NOT_BLOCKED 3901
+%define VINF_GVM_NOT_BUSY_IN_GC 3902
+%define VINF_GVM_YIELDED 3903
+%define VERR_VMX_INVALID_VMCS_FIELD (-4000)
+%define VERR_VMX_INVALID_VMCS_PTR (-4001)
+%define VERR_VMX_INVALID_VMXON_PTR (-4002)
+%define VERR_VMX_GENERIC (-4003)
+%define VERR_VMX_UNSUPPORTED_MODE (-4004)
+%define VERR_VMX_UNABLE_TO_START_VM (-4005)
+%define VERR_VMX_UNABLE_TO_RESUME_VM (-4006)
+%define VERR_VMX_INVALID_HOST_STATE (-4007)
+%define VERR_VMX_ILLEGAL_FEATURE_CONTROL_MSR (-4008)
+%define VERR_VMX_NO_VMX (-4009)
+%define VERR_VMX_VMXON_FAILED (-4010)
+%define VERR_VMX_IN_VMX_ROOT_MODE (-4011)
+%define VERR_VMX_X86_CR4_VMXE_CLEARED (-4012)
+%define VERR_VMX_MSR_LOCKED_OR_DISABLED (-4013)
+%define VERR_VMX_INVALID_GUEST_STATE (-4014)
+%define VERR_VMX_UNEXPECTED_EXIT_CODE (-4015)
+%define VERR_VMX_UNEXPECTED_EXCEPTION (-4016)
+%define VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE (-4017)
+%define VERR_VMX_NOT_IN_VMX_ROOT_MODE (-4018)
+%define VERR_SVM_UNABLE_TO_START_VM (-4050)
+%define VERR_SVM_ILLEGAL_EFER_MSR (-4051)
+%define VERR_SVM_NO_SVM (-4052)
+%define VERR_SVM_DISABLED (-4053)
+%define VERR_SVM_IN_USE (-4054)
+%define VERR_HWACCM_UNKNOWN_CPU (-4100)
+%define VERR_HWACCM_NO_CPUID (-4101)
+%define VERR_HWACCM_SUSPEND_PENDING (-4102)
+%define VERR_HWACCM_CONFIG_MISMATCH (-4103)
+%define VERR_HM_ALREADY_ENABLED_IPE (-4104)
+%define VERR_HM_UNEXPECTED_LD_ST_MSR (-4105)
+%define VERR_HM_NO_32_TO_64_SWITCHER (-4106)
+%define VERR_HMSVM_INVALID_PVMCB (-4107)
+%define VERR_HMSVM_UNEXPECTED_EXIT (-4108)
+%define VERR_HMSVM_UNEXPECTED_XCPT_EXIT (-4109)
+%define VERR_HMSVM_UNEXPECTED_PATCH_TYPE (-4110)
+%define VERR_HM_WRONG_CPU_1 (-4111)
+%define VERR_HM_IPE_1 (-4112)
+%define VERR_HM_IPE_2 (-4113)
+%define VERR_HM_WRONG_SWITCHER (-4114)
+%define VERR_HM_UNKNOWN_IO_INSTRUCTION (-4115)
+%define VERR_DIS_INVALID_OPCODE (-4200)
+%define VERR_DIS_GEN_FAILURE (-4201)
+%define VERR_DIS_NO_READ_CALLBACK (-4202)
+%define VERR_DIS_INVALID_MODRM (-4203)
+%define VERR_DIS_INVALID_PARAMETER (-4204)
+%define VERR_DIS_MEM_READ (-4205)
+%define VERR_DIS_TOO_LONG_INSTR (-4206)
+%define VERR_WEB_NOT_AUTHENTICATED (-4300)
+%define VERR_WEB_INVALID_MANAGED_OBJECT_REFERENCE (-4301)
+%define VERR_WEB_INVALID_SESSION_ID (-4302)
+%define VERR_WEB_INVALID_OBJECT_ID (-4303)
+%define VERR_WEB_UNSUPPORTED_INTERFACE (-4304)
+%define VINF_PARAV_SWITCH_TO_HOST 4400
+%define VINF_VHWA_CMD_PENDING 4500
+%define VERR_COM_UNEXPECTED (-4600)
+%define VERR_COM_VBOX_LOWEST (-4699)
+%define VERR_COM_OBJECT_NOT_FOUND (VERR_COM_VBOX_LOWEST + 1)
+%define VERR_COM_INVALID_VM_STATE (VERR_COM_VBOX_LOWEST + 2)
+%define VERR_COM_VM_ERROR (VERR_COM_VBOX_LOWEST + 3)
+%define VERR_COM_FILE_ERROR (VERR_COM_VBOX_LOWEST + 4)
+%define VERR_COM_IPRT_ERROR (VERR_COM_VBOX_LOWEST + 5)
+%define VERR_COM_PDM_ERROR (VERR_COM_VBOX_LOWEST + 6)
+%define VERR_COM_INVALID_OBJECT_STATE (VERR_COM_VBOX_LOWEST + 7)
+%define VERR_COM_HOST_ERROR (VERR_COM_VBOX_LOWEST + 8)
+%define VERR_COM_NOT_SUPPORTED (VERR_COM_VBOX_LOWEST + 9)
+%define VERR_COM_XML_ERROR (VERR_COM_VBOX_LOWEST + 10)
+%define VERR_COM_INVALID_SESSION_STATE (VERR_COM_VBOX_LOWEST + 11)
+%define VERR_COM_OBJECT_IN_USE (VERR_COM_VBOX_LOWEST + 12)
+%define VERR_COM_DONT_CALL_AGAIN (VERR_COM_VBOX_LOWEST + 13)
+%define VERR_CPU_HOTPLUG_NOT_MONITORED_BY_GUEST (-4700)
+%define VINF_AIO_TASK_PENDING 4800
+%define VERR_VSCSI_LUN_TYPE_NOT_SUPPORTED (-4900)
+%define VERR_VSCSI_LUN_ATTACHED_TO_DEVICE (-4901)
+%define VERR_VSCSI_LUN_INVALID (-4902)
+%define VERR_VSCSI_LUN_NOT_ATTACHED (-4903)
+%define VERR_VSCSI_LUN_BUSY (-4904)
+%define VERR_FAM_OPEN_FAILED (-5000)
+%define VERR_FAM_MONITOR_FILE_FAILED (-5001)
+%define VERR_FAM_MONITOR_DIRECTORY_FAILED (-5002)
+%define VERR_FAM_CONNECTION_LOST (-5003)
+%define VERR_PCI_PASSTHROUGH_NO_RAM_PREALLOC (-5100)
+%define VERR_PCI_PASSTHROUGH_NO_HWACCM (-5101)
+%define VERR_PCI_PASSTHROUGH_NO_NESTED_PAGING (-5102)
+%define VERR_GVMM_INSTANCE (-5200)
+%define VERR_GVMM_HOST_CPU_RANGE (-5201)
+%define VERR_GVMM_BROKEN_IPRT (-5202)
+%define VERR_GVMM_IPE_1 (-5203)
+%define VERR_GVMM_IPE_2 (-5204)
+%define VERR_IEM_INSTR_NOT_IMPLEMENTED (-5300)
+%define VERR_IEM_ASPECT_NOT_IMPLEMENTED (-5391)
+%define VERR_IEM_IPE_1 (-5392)
+%define VERR_IEM_IPE_2 (-5393)
+%define VERR_IEM_IPE_3 (-5394)
+%define VERR_IEM_RESTART_INSTRUCTION (-5395)
+%define VERR_DBGC_QUIT (-5400)
+%define VWRN_DBGC_CMD_PENDING 5401
+%define VWRN_DBGC_ALREADY_REGISTERED 5402
+%define VERR_DBGC_COMMANDS_NOT_REGISTERED (-5403)
+%define VERR_DBGC_BP_NOT_FOUND (-5404)
+%define VERR_DBGC_BP_EXISTS (-5405)
+%define VINF_DBGC_BP_NO_COMMAND 5406
+%define VERR_DBGC_COMMAND_FAILED (-5407)
+%define VERR_DBGC_IPE (-5408)
+%define VERR_DBGC_PARSE_LOWEST (-5499)
+%define VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS (VERR_DBGC_PARSE_LOWEST + 0)
+%define VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS (VERR_DBGC_PARSE_LOWEST + 1)
+%define VERR_DBGC_PARSE_ARGUMENT_OVERFLOW (VERR_DBGC_PARSE_LOWEST + 2)
+%define VERR_DBGC_PARSE_EXPECTED_BINARY_OP (VERR_DBGC_PARSE_LOWEST + 3)
+%define VERR_DBGC_PARSE_NO_RANGE_ALLOWED (VERR_DBGC_PARSE_LOWEST + 5)
+%define VERR_DBGC_PARSE_UNBALANCED_QUOTE (VERR_DBGC_PARSE_LOWEST + 6)
+%define VERR_DBGC_PARSE_UNBALANCED_PARENTHESIS (VERR_DBGC_PARSE_LOWEST + 7)
+%define VERR_DBGC_PARSE_EMPTY_ARGUMENT (VERR_DBGC_PARSE_LOWEST + 8)
+%define VERR_DBGC_PARSE_UNEXPECTED_OPERATOR (VERR_DBGC_PARSE_LOWEST + 9)
+%define VERR_DBGC_PARSE_INVALID_NUMBER (VERR_DBGC_PARSE_LOWEST + 10)
+%define VERR_DBGC_PARSE_NUMBER_TOO_BIG (VERR_DBGC_PARSE_LOWEST + 11)
+%define VERR_DBGC_PARSE_INVALID_OPERATION (VERR_DBGC_PARSE_LOWEST + 12)
+%define VERR_DBGC_PARSE_FUNCTION_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 13)
+%define VERR_DBGC_PARSE_NOT_A_FUNCTION (VERR_DBGC_PARSE_LOWEST + 14)
+%define VERR_DBGC_PARSE_NO_SCRATCH (VERR_DBGC_PARSE_LOWEST + 15)
+%define VERR_DBGC_PARSE_NO_MEMORY (VERR_DBGC_PARSE_LOWEST + 16)
+%define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE (VERR_DBGC_PARSE_LOWEST + 17)
+%define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 18)
+%define VERR_DBGC_PARSE_CONVERSION_FAILED (VERR_DBGC_PARSE_LOWEST + 19)
+%define VERR_DBGC_PARSE_NOT_IMPLEMENTED (VERR_DBGC_PARSE_LOWEST + 20)
+%define VERR_DBGC_PARSE_BAD_RESULT_TYPE (VERR_DBGC_PARSE_LOWEST + 21)
+%define VERR_DBGC_PARSE_WRITEONLY_SYMBOL (VERR_DBGC_PARSE_LOWEST + 22)
+%define VERR_DBGC_PARSE_INVALD_COMMAND_NAME (VERR_DBGC_PARSE_LOWEST + 23)
+%define VERR_DBGC_PARSE_COMMAND_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 24)
+%define VERR_DBGC_PARSE_BUG (VERR_DBGC_PARSE_LOWEST + 25)
+%define VERR_EXTPACK_UNSUPPORTED_HOST_UNINSTALL (-6000)
+%define VERR_EXTPACK_VBOX_VERSION_MISMATCH (-6001)
+%include "iprt/err.mac"
diff --git a/include/VBox/err.sed b/include/VBox/err.sed
new file mode 100644
index 00000000..b9c18489
--- /dev/null
+++ b/include/VBox/err.sed
@@ -0,0 +1,45 @@
+## @file
+#
+# SED script for converting VBox/err.h to .mac.
+#
+
+# Copyright (C) 2006-2009 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.
+#
+
+# Handle text inside the markers.
+/SED-START/,/SED-END/{
+
+# if (#define) goto defines
+/^[[:space:]]*#[[:space:]]*define/b defines
+
+}
+
+# Everything else is deleted!
+d
+b end
+
+##
+# Convert the defines
+:defines
+s/^[[:space:]]*#[[:space:]]*define[[:space:]]*\([[:alnum:]_]*\)[[:space:]]*\(.*\)[[:space:]]*$/%define \1 \2/
+b end
+
+# next expression
+:end
diff --git a/include/VBox/hgcmsvc.h b/include/VBox/hgcmsvc.h
new file mode 100644
index 00000000..c3480a73
--- /dev/null
+++ b/include/VBox/hgcmsvc.h
@@ -0,0 +1,409 @@
+/** @file
+ * Host-Guest Communication Manager (HGCM) - Service library definitions.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_hgcm_h
+#define ___VBox_hgcm_h
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/err.h>
+#ifdef VBOX_TEST_HGCM_PARMS
+# include <iprt/test.h>
+#endif
+
+/** @todo proper comments. */
+
+/**
+ * Service interface version.
+ *
+ * Includes layout of both VBOXHGCMSVCFNTABLE and VBOXHGCMSVCHELPERS.
+ *
+ * A service can work with these structures if major version
+ * is equal and minor version of service is <= version of the
+ * structures.
+ *
+ * For example when a new helper is added at the end of helpers
+ * structure, then the minor version will be increased. All older
+ * services still can work because they have their old helpers
+ * unchanged.
+ *
+ * Revision history.
+ * 1.1->2.1 Because the pfnConnect now also has the pvClient parameter.
+ * 2.1->2.2 Because pfnSaveState and pfnLoadState were added
+ * 2.2->3.1 Because pfnHostCall is now synchronous, returns rc, and parameters were changed
+ * 3.1->3.2 Because pfnRegisterExtension was added
+ * 3.2->3.3 Because pfnDisconnectClient helper was added
+ * 3.3->4.1 Because the pvService entry and parameter was added
+ * 4.1->4.2 Because the VBOX_HGCM_SVC_PARM_CALLBACK parameter type was added
+ * 4.2->5.1 Removed the VBOX_HGCM_SVC_PARM_CALLBACK parameter type, as
+ * this problem is already solved by service extension callbacks
+ */
+#define VBOX_HGCM_SVC_VERSION_MAJOR (0x0005)
+#define VBOX_HGCM_SVC_VERSION_MINOR (0x0001)
+#define VBOX_HGCM_SVC_VERSION ((VBOX_HGCM_SVC_VERSION_MAJOR << 16) + VBOX_HGCM_SVC_VERSION_MINOR)
+
+
+/** Typed pointer to distinguish a call to service. */
+struct VBOXHGCMCALLHANDLE_TYPEDEF;
+typedef struct VBOXHGCMCALLHANDLE_TYPEDEF *VBOXHGCMCALLHANDLE;
+
+/** Service helpers pointers table. */
+typedef struct _VBOXHGCMSVCHELPERS
+{
+ /** The service has processed the Call request. */
+ DECLR3CALLBACKMEMBER(void, pfnCallComplete, (VBOXHGCMCALLHANDLE callHandle, int32_t rc));
+
+ void *pvInstance;
+
+ /** The service disconnects the client. */
+ DECLR3CALLBACKMEMBER(void, pfnDisconnectClient, (void *pvInstance, uint32_t u32ClientID));
+} VBOXHGCMSVCHELPERS;
+
+typedef VBOXHGCMSVCHELPERS *PVBOXHGCMSVCHELPERS;
+
+
+#define VBOX_HGCM_SVC_PARM_INVALID (0U)
+#define VBOX_HGCM_SVC_PARM_32BIT (1U)
+#define VBOX_HGCM_SVC_PARM_64BIT (2U)
+#define VBOX_HGCM_SVC_PARM_PTR (3U)
+
+typedef struct VBOXHGCMSVCPARM
+{
+ /** VBOX_HGCM_SVC_PARM_* values. */
+ uint32_t type;
+
+ union
+ {
+ uint32_t uint32;
+ uint64_t uint64;
+ struct
+ {
+ uint32_t size;
+ void *addr;
+ } pointer;
+ } u;
+#ifdef __cplusplus
+ /** Extract a uint32_t value from an HGCM parameter structure */
+ int getUInt32 (uint32_t *u32)
+ {
+ AssertPtrReturn(u32, VERR_INVALID_POINTER);
+ int rc = VINF_SUCCESS;
+ if (type != VBOX_HGCM_SVC_PARM_32BIT)
+ rc = VERR_INVALID_PARAMETER;
+ if (RT_SUCCESS(rc))
+ *u32 = u.uint32;
+ return rc;
+ }
+
+ /** Extract a uint64_t value from an HGCM parameter structure */
+ int getUInt64 (uint64_t *u64)
+ {
+ AssertPtrReturn(u64, VERR_INVALID_POINTER);
+ int rc = VINF_SUCCESS;
+ if (type != VBOX_HGCM_SVC_PARM_64BIT)
+ rc = VERR_INVALID_PARAMETER;
+ if (RT_SUCCESS(rc))
+ *u64 = u.uint64;
+ return rc;
+ }
+
+ /** Extract a pointer value from an HGCM parameter structure */
+ int getPointer (void **ppv, uint32_t *pcb)
+ {
+ AssertPtrReturn(ppv, VERR_INVALID_POINTER);
+ AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+ if (type == VBOX_HGCM_SVC_PARM_PTR)
+ {
+ *ppv = u.pointer.addr;
+ *pcb = u.pointer.size;
+ return VINF_SUCCESS;
+ }
+
+ return VERR_INVALID_PARAMETER;
+ }
+
+ /** Extract a constant pointer value from an HGCM parameter structure */
+ int getPointer (const void **ppcv, uint32_t *pcb)
+ {
+ AssertPtrReturn(ppcv, VERR_INVALID_POINTER);
+ AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+ void *pv;
+ int rc = getPointer(&pv, pcb);
+ *ppcv = pv;
+ return rc;
+ }
+
+ /** Extract a pointer value to a non-empty buffer from an HGCM parameter
+ * structure */
+ int getBuffer (void **ppv, uint32_t *pcb)
+ {
+ AssertPtrReturn(ppv, VERR_INVALID_POINTER);
+ AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+ void *pv = NULL;
+ uint32_t cb = 0;
+ int rc = getPointer(&pv, &cb);
+ if ( RT_SUCCESS(rc)
+ && VALID_PTR(pv)
+ && cb > 0)
+ {
+ *ppv = pv;
+ *pcb = cb;
+ return VINF_SUCCESS;
+ }
+
+ return VERR_INVALID_PARAMETER;
+ }
+
+ /** Extract a pointer value to a non-empty constant buffer from an HGCM
+ * parameter structure */
+ int getBuffer (const void **ppcv, uint32_t *pcb)
+ {
+ AssertPtrReturn(ppcv, VERR_INVALID_POINTER);
+ AssertPtrReturn(pcb, VERR_INVALID_POINTER);
+ void *pcv = NULL;
+ int rc = getBuffer(&pcv, pcb);
+ *ppcv = pcv;
+ return rc;
+ }
+
+ /** Extract a string value from an HGCM parameter structure */
+ int getString (char **ppch, uint32_t *pcb)
+ {
+ uint32_t cb = 0;
+ char *pch = NULL;
+ int rc = getBuffer((void **)&pch, &cb);
+ if (RT_FAILURE(rc))
+ {
+ *ppch = NULL;
+ *pcb = 0;
+ return rc;
+ }
+ rc = RTStrValidateEncodingEx(pch, cb,
+ RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED);
+ *ppch = pch;
+ *pcb = cb;
+ return rc;
+ }
+
+ /** Extract a constant string value from an HGCM parameter structure */
+ int getString (const char **ppch, uint32_t *pcb)
+ {
+ char *pch = NULL;
+ int rc = getString(&pch, pcb);
+ *ppch = pch;
+ return rc;
+ }
+
+ /** Set a uint32_t value to an HGCM parameter structure */
+ void setUInt32(uint32_t u32)
+ {
+ type = VBOX_HGCM_SVC_PARM_32BIT;
+ u.uint32 = u32;
+ }
+
+ /** Set a uint64_t value to an HGCM parameter structure */
+ void setUInt64(uint64_t u64)
+ {
+ type = VBOX_HGCM_SVC_PARM_64BIT;
+ u.uint64 = u64;
+ }
+
+ /** Set a pointer value to an HGCM parameter structure */
+ void setPointer(void *pv, uint32_t cb)
+ {
+ type = VBOX_HGCM_SVC_PARM_PTR;
+ u.pointer.addr = pv;
+ u.pointer.size = cb;
+ }
+
+ /** Set a const string value to an HGCM parameter structure */
+ void setString(const char *psz)
+ {
+ type = VBOX_HGCM_SVC_PARM_PTR;
+ u.pointer.addr = (void *)psz;
+ u.pointer.size = (uint32_t)strlen(psz) + 1;
+ }
+
+#ifdef VBOX_TEST_HGCM_PARMS
+ /** Test the getString member function. Indirectly tests the getPointer
+ * and getBuffer APIs.
+ * @param hTest an running IPRT test
+ * @param aType the type that the parameter should be set to before
+ * calling getString
+ * @param apcc the value that the parameter should be set to before
+ * calling getString, and also the address (!) which we
+ * expect getString to return. Stricter than needed of
+ * course, but I was feeling lazy.
+ * @param acb the size that the parameter should be set to before
+ * calling getString, and also the size which we expect
+ * getString to return.
+ * @param rcExp the expected return value of the call to getString.
+ */
+ void doTestGetString(RTTEST hTest, uint32_t aType, const char *apcc,
+ uint32_t acb, int rcExp)
+ {
+ /* An RTTest API like this, which would print out an additional line
+ * of context if a test failed, would be nice. This is because the
+ * line number alone doesn't help much here, given that this is a
+ * subroutine called many times. */
+ /*
+ RTTestContextF(hTest,
+ ("doTestGetString, aType=%u, apcc=%p, acp=%u, rcExp=%Rrc",
+ aType, apcc, acp, rcExp));
+ */
+ setPointer((void *)apcc, acb);
+ type = aType; /* in case we don't want VBOX_HGCM_SVC_PARM_PTR */
+ const char *pcc = NULL;
+ uint32_t cb = 0;
+ int rc = getString(&pcc, &cb);
+ RTTEST_CHECK_RC(hTest, rc, rcExp);
+ if (RT_SUCCESS(rcExp))
+ {
+ RTTEST_CHECK_MSG_RETV(hTest, (pcc == apcc),
+ (hTest, "expected %p, got %p", apcc, pcc));
+ RTTEST_CHECK_MSG_RETV(hTest, (cb == acb),
+ (hTest, "expected %u, got %u", acb, cb));
+ }
+ }
+
+ /** Run some unit tests on the getString method and indirectly test
+ * getPointer and getBuffer as well. */
+ void testGetString(RTTEST hTest)
+ {
+ RTTestSub(hTest, "HGCM string parameter handling");
+ doTestGetString(hTest, VBOX_HGCM_SVC_PARM_32BIT, "test", 3,
+ VERR_INVALID_PARAMETER);
+ doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 5,
+ VINF_SUCCESS);
+ doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 3,
+ VERR_BUFFER_OVERFLOW);
+ doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test\xf0", 6,
+ VERR_INVALID_UTF8_ENCODING);
+ doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, "test", 0,
+ VERR_INVALID_PARAMETER);
+ doTestGetString(hTest, VBOX_HGCM_SVC_PARM_PTR, (const char *)0x1, 5,
+ VERR_INVALID_PARAMETER);
+ RTTestSubDone(hTest);
+ }
+#endif
+
+ VBOXHGCMSVCPARM() : type(VBOX_HGCM_SVC_PARM_INVALID) {}
+#endif
+} VBOXHGCMSVCPARM;
+
+typedef VBOXHGCMSVCPARM *PVBOXHGCMSVCPARM;
+
+#ifdef VBOX_WITH_CRHGSMI
+typedef void * HGCMCVSHANDLE;
+
+typedef DECLCALLBACK(void) HGCMHOSTFASTCALLCB (int32_t result, uint32_t u32Function, PVBOXHGCMSVCPARM pParam, void *pvContext);
+typedef HGCMHOSTFASTCALLCB *PHGCMHOSTFASTCALLCB;
+#endif
+
+
+/** Service specific extension callback.
+ * This callback is called by the service to perform service specific operation.
+ *
+ * @param pvExtension The extension pointer.
+ * @param u32Function What the callback is supposed to do.
+ * @param pvParm The function parameters.
+ * @param cbParm The size of the function parameters.
+ */
+typedef DECLCALLBACK(int) FNHGCMSVCEXT(void *pvExtension, uint32_t u32Function, void *pvParm, uint32_t cbParms);
+typedef FNHGCMSVCEXT *PFNHGCMSVCEXT;
+
+/** The Service DLL entry points.
+ *
+ * HGCM will call the DLL "VBoxHGCMSvcLoad"
+ * function and the DLL must fill in the VBOXHGCMSVCFNTABLE
+ * with function pointers.
+ */
+
+/* The structure is used in separately compiled binaries so an explicit packing is required. */
+#pragma pack(1)
+typedef struct _VBOXHGCMSVCFNTABLE
+{
+ /** Filled by HGCM */
+
+ /** Size of the structure. */
+ uint32_t cbSize;
+
+ /** Version of the structure, including the helpers. */
+ uint32_t u32Version;
+
+ PVBOXHGCMSVCHELPERS pHelpers;
+
+ /** Filled by the service. */
+
+ /** Size of client information the service want to have. */
+ uint32_t cbClient;
+#if ARCH_BITS == 64
+ /** Ensure that the following pointers are properly aligned on 64-bit system. */
+ uint32_t u32Alignment0;
+#endif
+
+ /** Uninitialize service */
+ DECLR3CALLBACKMEMBER(int, pfnUnload, (void *pvService));
+
+ /** Inform the service about a client connection. */
+ DECLR3CALLBACKMEMBER(int, pfnConnect, (void *pvService, uint32_t u32ClientID, void *pvClient));
+
+ /** Inform the service that the client wants to disconnect. */
+ DECLR3CALLBACKMEMBER(int, pfnDisconnect, (void *pvService, uint32_t u32ClientID, void *pvClient));
+
+ /** Service entry point.
+ * Return code is passed to pfnCallComplete callback.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnCall, (void *pvService, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]));
+
+ /** Host Service entry point meant for privileged features invisible to the guest.
+ * Return code is passed to pfnCallComplete callback.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnHostCall, (void *pvService, uint32_t function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]));
+
+ /** Inform the service about a VM save operation. */
+ DECLR3CALLBACKMEMBER(int, pfnSaveState, (void *pvService, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM));
+
+ /** Inform the service about a VM load operation. */
+ DECLR3CALLBACKMEMBER(int, pfnLoadState, (void *pvService, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM));
+
+ /** Register a service extension callback. */
+ DECLR3CALLBACKMEMBER(int, pfnRegisterExtension, (void *pvService, PFNHGCMSVCEXT pfnExtension, void *pvExtension));
+
+ /** User/instance data pointer for the service. */
+ void *pvService;
+
+} VBOXHGCMSVCFNTABLE;
+#pragma pack()
+
+
+/** Service initialization entry point. */
+typedef DECLCALLBACK(int) VBOXHGCMSVCLOAD(VBOXHGCMSVCFNTABLE *ptable);
+typedef VBOXHGCMSVCLOAD *PFNVBOXHGCMSVCLOAD;
+#define VBOX_HGCM_SVCLOAD_NAME "VBoxHGCMSvcLoad"
+
+#endif
diff --git a/include/VBox/intnet.h b/include/VBox/intnet.h
new file mode 100644
index 00000000..dc439ea5
--- /dev/null
+++ b/include/VBox/intnet.h
@@ -0,0 +1,1223 @@
+/** @file
+ * INTNET - Internal Networking. (DEV,++)
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_intnet_h
+#define ___VBox_intnet_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/stam.h>
+#include <VBox/sup.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+
+RT_C_DECLS_BEGIN
+
+
+/**
+ * Generic two-sided ring buffer.
+ *
+ * The deal is that there is exactly one writer and one reader.
+ * When offRead equals offWrite the buffer is empty. In the other
+ * extreme the writer will not use the last free byte in the buffer.
+ */
+typedef struct INTNETRINGBUF
+{
+ /** The offset from this structure to the start of the buffer. */
+ uint32_t offStart;
+ /** The offset from this structure to the end of the buffer. (exclusive). */
+ uint32_t offEnd;
+ /** The current read offset. */
+ uint32_t volatile offReadX;
+ /** Alignment. */
+ uint32_t u32Align0;
+
+ /** The committed write offset. */
+ uint32_t volatile offWriteCom;
+ /** Writer internal current write offset.
+ * This is ahead of offWriteCom when buffer space is handed to a third party for
+ * data gathering. offWriteCom will be assigned this value by the writer then
+ * the frame is ready. */
+ uint32_t volatile offWriteInt;
+ /** The number of bytes written (not counting overflows). */
+ STAMCOUNTER cbStatWritten;
+ /** The number of frames written (not counting overflows). */
+ STAMCOUNTER cStatFrames;
+ /** The number of overflows. */
+ STAMCOUNTER cOverflows;
+} INTNETRINGBUF;
+AssertCompileSize(INTNETRINGBUF, 48);
+/** Pointer to a ring buffer. */
+typedef INTNETRINGBUF *PINTNETRINGBUF;
+
+/** The alignment of a ring buffer. */
+#define INTNETRINGBUF_ALIGNMENT sizeof(INTNETHDR)
+
+/**
+ * Asserts the sanity of the specified INTNETRINGBUF structure.
+ */
+#ifdef VBOX_STRICT
+# define INTNETRINGBUF_ASSERT_SANITY(pRingBuf) \
+ do \
+ { \
+ AssertPtr(pRingBuf); \
+ { \
+ uint32_t const offWriteCom = (pRingBuf)->offWriteCom; \
+ uint32_t const offRead = (pRingBuf)->offReadX; \
+ uint32_t const offWriteInt = (pRingBuf)->offWriteInt; \
+ \
+ AssertMsg(offWriteCom == RT_ALIGN_32(offWriteCom, INTNETHDR_ALIGNMENT), ("%#x\n", offWriteCom)); \
+ AssertMsg(offWriteCom >= (pRingBuf)->offStart, ("%#x %#x\n", offWriteCom, (pRingBuf)->offStart)); \
+ AssertMsg(offWriteCom < (pRingBuf)->offEnd, ("%#x %#x\n", offWriteCom, (pRingBuf)->offEnd)); \
+ \
+ AssertMsg(offRead == RT_ALIGN_32(offRead, INTNETHDR_ALIGNMENT), ("%#x\n", offRead)); \
+ AssertMsg(offRead >= (pRingBuf)->offStart, ("%#x %#x\n", offRead, (pRingBuf)->offStart)); \
+ AssertMsg(offRead < (pRingBuf)->offEnd, ("%#x %#x\n", offRead, (pRingBuf)->offEnd)); \
+ \
+ AssertMsg(offWriteInt == RT_ALIGN_32(offWriteInt, INTNETHDR_ALIGNMENT), ("%#x\n", offWriteInt)); \
+ AssertMsg(offWriteInt >= (pRingBuf)->offStart, ("%#x %#x\n", offWriteInt, (pRingBuf)->offStart)); \
+ AssertMsg(offWriteInt < (pRingBuf)->offEnd, ("%#x %#x\n", offWriteInt, (pRingBuf)->offEnd)); \
+ AssertMsg( offRead <= offWriteCom \
+ ? offWriteCom <= offWriteInt || offWriteInt < offRead \
+ : offWriteCom <= offWriteInt, \
+ ("W=%#x W'=%#x R=%#x\n", offWriteCom, offWriteInt, offRead)); \
+ } \
+ } while (0)
+#else
+# define INTNETRINGBUF_ASSERT_SANITY(pRingBuf) do { } while (0)
+#endif
+
+
+
+/**
+ * A interface buffer.
+ */
+typedef struct INTNETBUF
+{
+ /** Magic number (INTNETBUF_MAGIC). */
+ uint32_t u32Magic;
+ /** The size of the entire buffer. */
+ uint32_t cbBuf;
+ /** The size of the send area. */
+ uint32_t cbSend;
+ /** The size of the receive area. */
+ uint32_t cbRecv;
+ /** The receive buffer. */
+ INTNETRINGBUF Recv;
+ /** The send buffer. */
+ INTNETRINGBUF Send;
+ /** Number of times yields help solve an overflow. */
+ STAMCOUNTER cStatYieldsOk;
+ /** Number of times yields didn't help solve an overflow. */
+ STAMCOUNTER cStatYieldsNok;
+ /** Number of lost packets due to overflows. */
+ STAMCOUNTER cStatLost;
+ /** Number of bad frames (both rings). */
+ STAMCOUNTER cStatBadFrames;
+ /** Reserved for future use. */
+ STAMCOUNTER aStatReserved[2];
+ /** Reserved for future send profiling. */
+ STAMPROFILE StatSend1;
+ /** Reserved for future send profiling. */
+ STAMPROFILE StatSend2;
+ /** Reserved for future receive profiling. */
+ STAMPROFILE StatRecv1;
+ /** Reserved for future receive profiling. */
+ STAMPROFILE StatRecv2;
+ /** Reserved for future profiling. */
+ STAMPROFILE StatReserved;
+} INTNETBUF;
+AssertCompileSize(INTNETBUF, 320);
+AssertCompileMemberOffset(INTNETBUF, Recv, 16);
+AssertCompileMemberOffset(INTNETBUF, Send, 64);
+
+/** Pointer to an interface buffer. */
+typedef INTNETBUF *PINTNETBUF;
+/** Pointer to a const interface buffer. */
+typedef INTNETBUF const *PCINTNETBUF;
+
+/** Magic number for INTNETBUF::u32Magic (Sir William Gerald Golding). */
+#define INTNETBUF_MAGIC UINT32_C(0x19110919)
+
+/**
+ * Asserts the sanity of the specified INTNETBUF structure.
+ */
+#define INTNETBUF_ASSERT_SANITY(pBuf) \
+ do \
+ { \
+ AssertPtr(pBuf); \
+ Assert((pBuf)->u32Magic == INTNETBUF_MAGIC); \
+ { \
+ uint32_t const offRecvStart = (pBuf)->Recv.offStart + RT_OFFSETOF(INTNETBUF, Recv); \
+ uint32_t const offRecvEnd = (pBuf)->Recv.offStart + RT_OFFSETOF(INTNETBUF, Recv); \
+ uint32_t const offSendStart = (pBuf)->Send.offStart + RT_OFFSETOF(INTNETBUF, Send); \
+ uint32_t const offSendEnd = (pBuf)->Send.offStart + RT_OFFSETOF(INTNETBUF, Send); \
+ \
+ Assert(offRecvEnd > offRecvStart); \
+ Assert(offRecvEnd - offRecvStart == (pBuf)->cbRecv); \
+ Assert(offRecvStart == sizeof(INTNETBUF)); \
+ \
+ Assert(offSendEnd > offSendStart); \
+ Assert(offSendEnd - offSendStart == (pBuf)->cbSend); \
+ Assert(pffSendEnd <= (pBuf)->cbBuf); \
+ \
+ Assert(offSendStart == offRecvEnd); \
+ } \
+ } while (0)
+
+
+/** Internal networking interface handle. */
+typedef uint32_t INTNETIFHANDLE;
+/** Pointer to an internal networking interface handle. */
+typedef INTNETIFHANDLE *PINTNETIFHANDLE;
+
+/** Or mask to obscure the handle index. */
+#define INTNET_HANDLE_MAGIC 0x88880000
+/** Mask to extract the handle index. */
+#define INTNET_HANDLE_INDEX_MASK 0xffff
+/** The maximum number of handles (exclusive) */
+#define INTNET_HANDLE_MAX 0xffff
+/** Invalid handle. */
+#define INTNET_HANDLE_INVALID (0)
+
+
+/**
+ * The frame header.
+ *
+ * The header is intentionally 8 bytes long. It will always
+ * start at an 8 byte aligned address. Assuming that the buffer
+ * size is a multiple of 8 bytes, that means that we can guarantee
+ * that the entire header is contiguous in both virtual and physical
+ * memory.
+ */
+typedef struct INTNETHDR
+{
+ /** Header type. This is currently serving as a magic, it
+ * can be extended later to encode special command frames and stuff. */
+ uint16_t u16Type;
+ /** The size of the frame. */
+ uint16_t cbFrame;
+ /** The offset from the start of this header to where the actual frame starts.
+ * This is used to keep the frame it self contiguous in virtual memory and
+ * thereby both simplify access as well as the descriptor. */
+ int32_t offFrame;
+} INTNETHDR;
+AssertCompileSize(INTNETHDR, 8);
+AssertCompileSizeAlignment(INTNETBUF, sizeof(INTNETHDR));
+/** Pointer to a frame header.*/
+typedef INTNETHDR *PINTNETHDR;
+/** Pointer to a const frame header.*/
+typedef INTNETHDR const *PCINTNETHDR;
+
+/** The alignment of a frame header. */
+#define INTNETHDR_ALIGNMENT sizeof(INTNETHDR)
+AssertCompile(sizeof(INTNETHDR) == INTNETHDR_ALIGNMENT);
+AssertCompile(INTNETHDR_ALIGNMENT <= INTNETRINGBUF_ALIGNMENT);
+
+/** @name Frame types (INTNETHDR::u16Type).
+ * @{ */
+/** Normal frames. */
+#define INTNETHDR_TYPE_FRAME 0x2442
+/** Padding frames. */
+#define INTNETHDR_TYPE_PADDING 0x3553
+/** Generic segment offload frames.
+ * The frame starts with a PDMNETWORKGSO structure which is followed by the
+ * header template and data. */
+#define INTNETHDR_TYPE_GSO 0x4664
+AssertCompileSize(PDMNETWORKGSO, 8);
+/** @} */
+
+/**
+ * Asserts the sanity of the specified INTNETHDR.
+ */
+#ifdef VBOX_STRICT
+#define INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf) \
+ do \
+ { \
+ AssertPtr(pHdr); \
+ Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr); \
+ Assert( (pHdr)->u16Type == INTNETHDR_TYPE_FRAME \
+ || (pHdr)->u16Type == INTNETHDR_TYPE_GSO \
+ || (pHdr)->u16Type == INTNETHDR_TYPE_PADDING); \
+ { \
+ uintptr_t const offHdr = (uintptr_t)pHdr - (uintptr_t)pRingBuf; \
+ uintptr_t const offFrame = offHdr + (pHdr)->offFrame; \
+ \
+ Assert(offHdr >= (pRingBuf)->offStart); \
+ Assert(offHdr < (pRingBuf)->offEnd); \
+ \
+ /* could do more thorough work here... later, perhaps. */ \
+ Assert(offFrame >= (pRingBuf)->offStart); \
+ Assert(offFrame < (pRingBuf)->offEnd); \
+ } \
+ } while (0)
+#else
+# define INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf) do { } while (0)
+#endif
+
+
+/**
+ * Scatter / Gather segment (internal networking).
+ */
+typedef struct INTNETSEG
+{
+ /** The physical address. NIL_RTHCPHYS is not set. */
+ RTHCPHYS Phys;
+ /** Pointer to the segment data. */
+ void *pv;
+ /** The segment size. */
+ uint32_t cb;
+} INTNETSEG;
+/** Pointer to a internal networking frame segment. */
+typedef INTNETSEG *PINTNETSEG;
+/** Pointer to a internal networking frame segment. */
+typedef INTNETSEG const *PCINTNETSEG;
+
+
+/**
+ * Scatter / Gather list (internal networking).
+ *
+ * This is used when communicating with the trunk port.
+ */
+typedef struct INTNETSG
+{
+ /** Owner data, don't touch! */
+ void *pvOwnerData;
+ /** User data. */
+ void *pvUserData;
+ /** User data 2 in case anyone needs it. */
+ void *pvUserData2;
+ /** GSO context information, set the type to invalid if not relevant. */
+ PDMNETWORKGSO GsoCtx;
+ /** The total length of the scatter gather list. */
+ uint32_t cbTotal;
+ /** The number of users (references).
+ * This is used by the SGRelease code to decide when it can be freed. */
+ uint16_t volatile cUsers;
+ /** Flags, see INTNETSG_FLAGS_* */
+ uint16_t volatile fFlags;
+#if ARCH_BITS == 64
+ /** Alignment padding. */
+ uint16_t uPadding;
+#endif
+ /** The number of segments allocated. */
+ uint16_t cSegsAlloc;
+ /** The number of segments actually used. */
+ uint16_t cSegsUsed;
+ /** Variable sized list of segments. */
+ INTNETSEG aSegs[1];
+} INTNETSG;
+AssertCompileSizeAlignment(INTNETSG, 8);
+/** Pointer to a scatter / gather list. */
+typedef INTNETSG *PINTNETSG;
+/** Pointer to a const scatter / gather list. */
+typedef INTNETSG const *PCINTNETSG;
+
+/** @name INTNETSG::fFlags definitions.
+ * @{ */
+/** Set if the SG is free. */
+#define INTNETSG_FLAGS_FREE RT_BIT_32(1)
+/** Set if the SG is a temporary one that will become invalid upon return.
+ * Try to finish using it before returning, and if that's not possible copy
+ * to other buffers.
+ * When not set, the callee should always free the SG.
+ * Attempts to free it made by the callee will be quietly ignored. */
+#define INTNETSG_FLAGS_TEMP RT_BIT_32(2)
+/** ARP packet, IPv4 + MAC.
+ * @internal */
+#define INTNETSG_FLAGS_ARP_IPV4 RT_BIT_32(3)
+/** Copied to the temporary buffer.
+ * @internal */
+#define INTNETSG_FLAGS_PKT_CP_IN_TMP RT_BIT_32(4)
+/** @} */
+
+
+/** @name Direction (frame source or destination)
+ * @{ */
+/** To/From the wire. */
+#define INTNETTRUNKDIR_WIRE RT_BIT_32(0)
+/** To/From the host. */
+#define INTNETTRUNKDIR_HOST RT_BIT_32(1)
+/** Mask of valid bits. */
+#define INTNETTRUNKDIR_VALID_MASK UINT32_C(3)
+/** @} */
+
+/**
+ * Switch decisions returned by INTNETTRUNKSWPORT::pfnPreRecv.
+ */
+typedef enum INTNETSWDECISION
+{
+ /** The usual invalid zero value. */
+ INTNETSWDECISION_INVALID = 0,
+ /** Everywhere. */
+ INTNETSWDECISION_BROADCAST,
+ /** Only to the internal network. */
+ INTNETSWDECISION_INTNET,
+ /** Only for the trunk (host/wire). */
+ INTNETSWDECISION_TRUNK,
+ /** Used internally to indicate that the packet cannot be handled in the
+ * current context. */
+ INTNETSWDECISION_BAD_CONTEXT,
+ /** Used internally to indicate that the packet should be dropped. */
+ INTNETSWDECISION_DROP,
+ /** The usual 32-bit type expansion. */
+ INTNETSWDECISION_32BIT_HACK = 0x7fffffff
+} INTNETSWDECISION;
+
+
+/** Pointer to the switch side of a trunk port. */
+typedef struct INTNETTRUNKSWPORT *PINTNETTRUNKSWPORT;
+/**
+ * This is the port on the internal network 'switch', i.e.
+ * what the driver is connected to.
+ *
+ * This is only used for the in-kernel trunk connections.
+ */
+typedef struct INTNETTRUNKSWPORT
+{
+ /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
+ uint32_t u32Version;
+
+ /**
+ * Examine the packet and figure out where it is going.
+ *
+ * This method is for making packet switching decisions in contexts where
+ * pfnRecv cannot be called or is no longer applicable. This method can be
+ * called from any context.
+ *
+ * @returns INTNETSWDECISION_BROADCAST, INTNETSWDECISION_INTNET or
+ * INTNETSWDECISION_TRUNK. The source is excluded from broadcast &
+ * trunk, of course.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param pvHdrs Pointer to the packet headers.
+ * @param cbHdrs Size of the packet headers. This must be at least 6
+ * bytes (the destination MAC address), but should if
+ * possible also include any VLAN tag and network
+ * layer header (wireless mac address sharing).
+ * @param fSrc Where this frame comes from. Only one bit should be
+ * set!
+ *
+ * @remarks Will only grab the switch table spinlock (interrupt safe). May
+ * signal an event semaphore iff we're racing network cleanup. The
+ * caller must be busy when calling.
+ */
+ DECLR0CALLBACKMEMBER(INTNETSWDECISION, pfnPreRecv,(PINTNETTRUNKSWPORT pSwitchPort,
+ void const *pvHdrs, size_t cbHdrs, uint32_t fSrc));
+
+ /**
+ * Incoming frame.
+ *
+ * The frame may be modified when the trunk port on the switch is set to share
+ * the mac address of the host when hitting the wire. Currently frames
+ * containing ARP packets are subject to this, later other protocols like
+ * NDP/ICMPv6 may need editing as well when operating in this mode. The edited
+ * packet should be forwarded to the host/wire when @c false is returned.
+ *
+ * @returns true if we've handled it and it should be dropped.
+ * false if it should hit the wire/host.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param pvIf Pointer to the interface which received this frame
+ * if available. Can be NULL.
+ * @param pSG The (scatter /) gather structure for the frame. This
+ * will only be use during the call, so a temporary one can
+ * be used. The Phys member will not be used.
+ * @param fSrc Where this frame comes from. Exactly one bit shall be
+ * set!
+ *
+ * @remarks Will only grab the switch table spinlock (interrupt safe). Will
+ * signal event semaphores. The caller must be busy when calling.
+ *
+ * @remarks NAT and TAP will use this interface.
+ *
+ * @todo Do any of the host require notification before frame modifications?
+ * If so, we'll add a callback to INTNETTRUNKIFPORT for this
+ * (pfnSGModifying) and a SG flag.
+ */
+ DECLR0CALLBACKMEMBER(bool, pfnRecv,(PINTNETTRUNKSWPORT pSwitchPort, void *pvIf, PINTNETSG pSG, uint32_t fSrc));
+
+ /**
+ * Retain a SG.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param pSG Pointer to the (scatter /) gather structure.
+ *
+ * @remarks Will not grab any locks. The caller must be busy when calling.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnSGRetain,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
+
+ /**
+ * Release a SG.
+ *
+ * This is called by the pfnXmit code when done with a SG. This may safe
+ * be done in an asynchronous manner.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param pSG Pointer to the (scatter /) gather structure.
+ *
+ * @remarks May signal an event semaphore later on, currently code won't though.
+ * The caller is busy when making this call.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnSGRelease,(PINTNETTRUNKSWPORT pSwitchPort, PINTNETSG pSG));
+
+ /**
+ * Selects whether outgoing SGs should have their physical address set.
+ *
+ * By enabling physical addresses in the scatter / gather segments it should
+ * be possible to save some unnecessary address translation and memory locking
+ * in the network stack. (Internal networking knows the physical address for
+ * all the INTNETBUF data and that it's locked memory.) There is a negative
+ * side effects though, frames that crosses page boundaries will require
+ * multiple scather / gather segments.
+ *
+ * @returns The old setting.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param fEnable Whether to enable or disable it.
+ *
+ * @remarks Will not grab any locks. The caller must be busy when calling.
+ */
+ DECLR0CALLBACKMEMBER(bool, pfnSetSGPhys,(PINTNETTRUNKSWPORT pSwitchPort, bool fEnable));
+
+ /**
+ * Reports the MAC address of the trunk.
+ *
+ * This is supposed to be called when creating, connection or reconnecting the
+ * trunk and when the MAC address is changed by the system admin.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param pMacAddr The MAC address.
+ *
+ * @remarks May take a spinlock or two. The caller must be busy when calling.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnReportMacAddress,(PINTNETTRUNKSWPORT pSwitchPort, PCRTMAC pMacAddr));
+
+ /**
+ * Reports the promicuousness of the interface.
+ *
+ * This is supposed to be called when creating, connection or reconnecting the
+ * trunk and when the mode is changed by the system admin.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param fPromiscuous True if the host operates the interface in
+ * promiscuous mode, false if not.
+ *
+ * @remarks May take a spinlock or two. The caller must be busy when calling.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnReportPromiscuousMode,(PINTNETTRUNKSWPORT pSwitchPort, bool fPromiscuous));
+
+ /**
+ * Reports the GSO capabilities of the host, wire or both.
+ *
+ * This is supposed to be used only when creating, connecting or reconnecting
+ * the trunk. It is assumed that the GSO capabilities are kind of static the
+ * rest of the time.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param fGsoCapabilities The GSO capability bit mask. The bits
+ * corresponds to the GSO type with the same value.
+ * @param fDst The destination mask (INTNETTRUNKDIR_XXX).
+ *
+ * @remarks Does not take any locks. The caller must be busy when calling.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnReportGsoCapabilities,(PINTNETTRUNKSWPORT pSwitchPort, uint32_t fGsoCapabilities, uint32_t fDst));
+
+ /**
+ * Reports the no-preemption-xmit capabilities of the host and wire.
+ *
+ * This is supposed to be used only when creating, connecting or reconnecting
+ * the trunk. It is assumed that the GSO capabilities are kind of static the
+ * rest of the time.
+ *
+ * @param pSwitchPort Pointer to this structure.
+ * @param fNoPreemptDsts The destinations (INTNETTRUNKDIR_XXX) which it
+ * is safe to transmit to with preemption disabled.
+ * @param fDst The destination mask (INTNETTRUNKDIR_XXX).
+ *
+ * @remarks Does not take any locks. The caller must be busy when calling.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnReportNoPreemptDsts,(PINTNETTRUNKSWPORT pSwitchPort, uint32_t fNoPreemptDsts));
+
+ /** Structure version number. (INTNETTRUNKSWPORT_VERSION) */
+ uint32_t u32VersionEnd;
+} INTNETTRUNKSWPORT;
+
+/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
+#define INTNETTRUNKSWPORT_VERSION UINT32_C(0xA2CDf001)
+
+
+/**
+ * The trunk interface state used set by INTNETTRUNKIFPORT::pfnSetState.
+ */
+typedef enum INTNETTRUNKIFSTATE
+{
+ /** The invalid zero entry. */
+ INTNETTRUNKIFSTATE_INVALID = 0,
+ /** The trunk is inactive. No calls to INTNETTRUNKSWPORT::pfnRecv or
+ * INTNETTRUNKSWPORT::pfnPreRecv. Calling other methods is OK. */
+ INTNETTRUNKIFSTATE_INACTIVE,
+ /** The trunk is active, no restrictions on methods or anything. */
+ INTNETTRUNKIFSTATE_ACTIVE,
+ /** The trunk is about to be disconnected from the internal network. No
+ * calls to any INTNETRUNKSWPORT methods. */
+ INTNETTRUNKIFSTATE_DISCONNECTING,
+ /** The end of the valid states. */
+ INTNETTRUNKIFSTATE_END,
+ /** The usual 32-bit type blow up hack. */
+ INTNETTRUNKIFSTATE_32BIT_HACK = 0x7fffffff
+} INTNETTRUNKIFSTATE;
+
+/** Pointer to the interface side of a trunk port. */
+typedef struct INTNETTRUNKIFPORT *PINTNETTRUNKIFPORT;
+/**
+ * This is the port on the trunk interface, i.e. the driver side which the
+ * internal network is connected to.
+ *
+ * This is only used for the in-kernel trunk connections.
+ */
+typedef struct INTNETTRUNKIFPORT
+{
+ /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
+ uint32_t u32Version;
+
+ /**
+ * Retain the object.
+ *
+ * It will normally be called while owning the internal network semaphore.
+ *
+ * @param pIfPort Pointer to this structure.
+ *
+ * @remarks May own the big mutex, no spinlocks.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnRetain,(PINTNETTRUNKIFPORT pIfPort));
+
+ /**
+ * Releases the object.
+ *
+ * This must be called for every pfnRetain call.
+ *
+ *
+ * @param pIfPort Pointer to this structure.
+ *
+ * @remarks May own the big mutex, no spinlocks.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnRelease,(PINTNETTRUNKIFPORT pIfPort));
+
+ /**
+ * Disconnect from the switch and release the object.
+ *
+ * The is the counter action of the
+ * INTNETTRUNKNETFLTFACTORY::pfnCreateAndConnect method.
+ *
+ * @param pIfPort Pointer to this structure.
+ *
+ * @remarks Owns the big mutex.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnDisconnectAndRelease,(PINTNETTRUNKIFPORT pIfPort));
+
+ /**
+ * Changes the state of the trunk interface.
+ *
+ * The interface is created in the inactive state (INTNETTRUNKIFSTATE_INACTIVE).
+ * When the first connect VM or service is activated, the internal network
+ * activates the trunk (INTNETTRUNKIFSTATE_ACTIVE). The state may then be set
+ * back and forth between INACTIVE and ACTIVE as VMs are paused, added and
+ * removed.
+ *
+ * Eventually though, the network is destroyed as a result of there being no
+ * more VMs left in it and the state is changed to disconnecting
+ * (INTNETTRUNKIFSTATE_DISCONNECTING) and pfnWaitForIdle is called to make sure
+ * there are no active calls in either direction when pfnDisconnectAndRelease is
+ * called.
+ *
+ * A typical operation to performed by this method is to enable/disable promiscuous
+ * mode on the host network interface when entering/leaving the active state.
+ *
+ * @returns The previous state.
+ *
+ * @param pIfPort Pointer to this structure.
+ * @param enmState The new state.
+ *
+ * @remarks Owns the big mutex. No racing pfnSetState, pfnWaitForIdle,
+ * pfnDisconnectAndRelease or INTNETTRUNKFACTORY::pfnCreateAndConnect
+ * calls.
+ */
+ DECLR0CALLBACKMEMBER(INTNETTRUNKIFSTATE, pfnSetState,(PINTNETTRUNKIFPORT pIfPort, INTNETTRUNKIFSTATE enmState));
+
+ /**
+ * Notifies when the MAC address of an interface is set or changes.
+ *
+ * @param pIfPort Pointer to this structure.
+ * @param pvIfData Pointer to the trunk's interface data (see
+ * pfnConnectInterface).
+ * @param pMac Pointer to the MAC address of the connecting VM NIC.
+ *
+ * @remarks Only busy references to the trunk and the interface.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnNotifyMacAddress,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PCRTMAC pMac));
+
+ /**
+ * Called when an interface is connected to the network.
+ *
+ * @returns IPRT status code.
+ * @param pIfPort Pointer to this structure.
+ * @param pvIf Opaque pointer to the interface being connected.
+ * For use INTNETTRUNKSWPORT::pfnRecv.
+ * @param ppvIfData Pointer to a pointer variable that the trunk
+ * implementation can use to associate data with the
+ * interface. This pointer will be passed to the
+ * pfnXmit, pfnNotifyMacAddress and
+ * pfnDisconnectInterface methods.
+ *
+ * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnConnectInterface,(PINTNETTRUNKIFPORT pIfPort, void *pvIf, void **ppvIfData));
+
+ /**
+ * Called when an interface is disconnected from the network.
+ *
+ * @param pIfPort Pointer to this structure.
+ * @param pvIfData Pointer to the trunk's interface data (see
+ * pfnConnectInterface).
+ *
+ * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnDisconnectInterface,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData));
+
+ /**
+ * Waits for the interface to become idle.
+ *
+ * This method must be called before disconnecting and releasing the object in
+ * order to prevent racing incoming/outgoing frames and device
+ * enabling/disabling.
+ *
+ * @returns IPRT status code (see RTSemEventWait).
+ * @param pIfPort Pointer to this structure.
+ * @param cMillies The number of milliseconds to wait. 0 means
+ * no waiting at all. Use RT_INDEFINITE_WAIT for
+ * an indefinite wait.
+ *
+ * @remarks Owns the big mutex. No racing pfnDisconnectAndRelease.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnWaitForIdle,(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies));
+
+ /**
+ * Transmit a frame.
+ *
+ * @return VBox status code. Error generally means we'll drop the frame.
+ * @param pIfPort Pointer to this structure.
+ * @param pvIfData Pointer to the trunk's interface data (see
+ * pfnConnectInterface).
+ * @param pSG Pointer to the (scatter /) gather structure for the frame.
+ * This may or may not be a temporary buffer. If it's temporary
+ * the transmit operation(s) then it's required to make a copy
+ * of the frame unless it can be transmitted synchronously.
+ * @param fDst The destination mask. At least one bit will be set.
+ *
+ * @remarks No locks. May be called concurrently on several threads.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnXmit,(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PINTNETSG pSG, uint32_t fDst));
+
+ /** Structure version number. (INTNETTRUNKIFPORT_VERSION) */
+ uint32_t u32VersionEnd;
+} INTNETTRUNKIFPORT;
+
+/** Version number for the INTNETTRUNKIFPORT::u32Version and INTNETTRUNKIFPORT::u32VersionEnd fields. */
+#define INTNETTRUNKIFPORT_VERSION UINT32_C(0xA2CDe001)
+
+
+/**
+ * The component factory interface for create a network
+ * interface filter (like VBoxNetFlt).
+ */
+typedef struct INTNETTRUNKFACTORY
+{
+ /**
+ * Release this factory.
+ *
+ * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
+ * will retain a reference to the factory and the caller has to call this method to
+ * release it once the pfnCreateAndConnect call(s) has been done.
+ *
+ * @param pIfFactory Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnRelease,(struct INTNETTRUNKFACTORY *pIfFactory));
+
+ /**
+ * Create an instance for the specfied host interface and connects it
+ * to the internal network trunk port.
+ *
+ * The initial interface active state is false (suspended).
+ *
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS and *ppIfPort set on success.
+ * @retval VERR_INTNET_FLT_IF_NOT_FOUND if the interface was not found.
+ * @retval VERR_INTNET_FLT_IF_BUSY if the interface is already connected.
+ * @retval VERR_INTNET_FLT_IF_FAILED if it failed for some other reason.
+ *
+ * @param pIfFactory Pointer to this structure.
+ * @param pszName The interface name (OS specific).
+ * @param pSwitchPort Pointer to the port interface on the switch that
+ * this interface is being connected to.
+ * @param fFlags Creation flags, see below.
+ * @param ppIfPort Where to store the pointer to the interface port
+ * on success.
+ *
+ * @remarks Called while owning the network and the out-bound trunk semaphores.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(struct INTNETTRUNKFACTORY *pIfFactory, const char *pszName,
+ PINTNETTRUNKSWPORT pSwitchPort, uint32_t fFlags,
+ PINTNETTRUNKIFPORT *ppIfPort));
+} INTNETTRUNKFACTORY;
+/** Pointer to the trunk factory. */
+typedef INTNETTRUNKFACTORY *PINTNETTRUNKFACTORY;
+
+/** The UUID for the (current) trunk factory. (case sensitive) */
+#define INTNETTRUNKFACTORY_UUID_STR "de504d93-1d1e-4781-8b73-6ea39a0e36a2"
+
+/** @name INTNETTRUNKFACTORY::pfnCreateAndConnect flags.
+ * @{ */
+/** Don't put the filtered interface in promiscuous mode.
+ * This is used for wireless interface since these can misbehave if
+ * we try to put them in promiscuous mode. (Wireless interfaces are
+ * normally bridged on level 3 instead of level 2.) */
+#define INTNETTRUNKFACTORY_FLAG_NO_PROMISC RT_BIT_32(0)
+/** @} */
+
+
+/**
+ * The trunk connection type.
+ *
+ * Used by IntNetR0Open and associated interfaces.
+ */
+typedef enum INTNETTRUNKTYPE
+{
+ /** Invalid trunk type. */
+ kIntNetTrunkType_Invalid = 0,
+ /** No trunk connection. */
+ kIntNetTrunkType_None,
+ /** We don't care which kind of trunk connection if the network exists,
+ * if it doesn't exist create it without a connection. */
+ kIntNetTrunkType_WhateverNone,
+ /** VirtualBox host network interface filter driver.
+ * The trunk name is the name of the host network interface. */
+ kIntNetTrunkType_NetFlt,
+ /** VirtualBox adapter host driver. */
+ kIntNetTrunkType_NetAdp,
+ /** Nat service (ring-0). */
+ kIntNetTrunkType_SrvNat,
+ /** The end of valid types. */
+ kIntNetTrunkType_End,
+ /** The usual 32-bit hack. */
+ kIntNetTrunkType_32bitHack = 0x7fffffff
+} INTNETTRUNKTYPE;
+
+/** @name IntNetR0Open flags.
+ *
+ * The desired policy options must be specified explicitly, if omitted it is
+ * understood that whatever is current or default is fine with the caller.
+ *
+ * @todo Move the policies out of the flags, use three new parameters.
+ *
+ * @{ */
+/** Share the MAC address with the host when sending something to the wire via the trunk.
+ * This is typically used when the trunk is a NetFlt for a wireless interface. */
+#define INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE RT_BIT_32(0)
+/** Require that the current security and promiscuous policies of the network
+ * is exactly as the ones specified in this open network request.
+ *
+ * Use this with INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES to prevent
+ * restrictions from being lifted. If no further policy changes are desired,
+ * apply the relevant _FIXED flags. */
+#define INTNET_OPEN_FLAGS_REQUIRE_EXACT RT_BIT_32(1)
+/** Require that the security and promiscuous policies of the network is at
+ * least as restrictive as specified this request specifies and prevent them
+ * being lifted later on. */
+#define INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES RT_BIT_32(2)
+
+/** Network access policy: Fixed if set, changable if clear. */
+#define INTNET_OPEN_FLAGS_ACCESS_FIXED RT_BIT_32(3)
+/** Network access policy: Public network. */
+#define INTNET_OPEN_FLAGS_ACCESS_PUBLIC RT_BIT_32(4)
+/** Network access policy: Restricted network. */
+#define INTNET_OPEN_FLAGS_ACCESS_RESTRICTED RT_BIT_32(5)
+
+/** Promiscuous mode policy: Is it fixed or changable by new participants? */
+#define INTNET_OPEN_FLAGS_PROMISC_FIXED RT_BIT_32(6)
+/** Promiscuous mode policy: Allow the clients to request it. */
+#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS RT_BIT_32(7)
+/** Promiscuous mode policy: Deny the clients from requesting it. */
+#define INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS RT_BIT_32(8)
+/** Promiscuous mode policy: Allow the trunk-host to request it. */
+#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST RT_BIT_32(9)
+/** Promiscuous mode policy: Deny the trunk-host from requesting it. */
+#define INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST RT_BIT_32(10)
+/** Promiscuous mode policy: Allow the trunk-wire to request it. */
+#define INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE RT_BIT_32(11)
+/** Promiscuous mode policy: Deny the trunk-wire from requesting it. */
+#define INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE RT_BIT_32(12)
+
+/** Interface policies: Is it fixed or changable (by admin).
+ * @note Per interface, not network wide. */
+#define INTNET_OPEN_FLAGS_IF_FIXED RT_BIT_32(13)
+/** Interface promiscuous mode policy: Allow the interface to request it. */
+#define INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW RT_BIT_32(14)
+/** Interface promiscuous mode policy: Deny the interface from requesting it. */
+#define INTNET_OPEN_FLAGS_IF_PROMISC_DENY RT_BIT_32(15)
+/** Interface promiscuous mode policy: See unrelated trunk traffic. */
+#define INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK RT_BIT_32(16)
+/** Interface promiscuous mode policy: No unrelated trunk traffic visible. */
+#define INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK RT_BIT_32(17)
+
+/** Trunk policy: Fixed if set, changable if clear.
+ * @remarks The DISABLED options are considered more restrictive by
+ * INTNET_OPEN_FLAGS_REQUIRE_AS_RESTRICTIVE_POLICIES. */
+#define INTNET_OPEN_FLAGS_TRUNK_FIXED RT_BIT_32(18)
+/** Trunk policy: The host end should be enabled. */
+#define INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED RT_BIT_32(19)
+/** Trunk policy: The host end should be disabled. */
+#define INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED RT_BIT_32(20)
+/** Trunk policy: The host should only see packets destined for it. */
+#define INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE RT_BIT_32(21)
+/** Trunk policy: The host should see all packets. */
+#define INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE RT_BIT_32(22)
+/** Trunk policy: The wire end should be enabled. */
+#define INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED RT_BIT_32(23)
+/** Trunk policy: The wire end should be disabled. */
+#define INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED RT_BIT_32(24)
+/** Trunk policy: The wire should only see packets destined for it. */
+#define INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE RT_BIT_32(25)
+/** Trunk policy: The wire should see all packets. */
+#define INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE RT_BIT_32(26)
+
+/** Used to enable host specific workarounds.
+ *
+ * On darwin this will clear ip_tos in DHCP packets when
+ * INTNET_OPEN_FLAGS_SHARED_MAC_ON_WIRE is also set. */
+#define INTNET_OPEN_FLAGS_WORKAROUND_1 RT_BIT_32(31)
+
+
+/** The mask of valid flags. */
+#define INTNET_OPEN_FLAGS_MASK UINT32_C(0x83ffffff)
+/** The mask of all flags use to fix (lock) settings. */
+#define INTNET_OPEN_FLAGS_FIXED_MASK \
+ ( INTNET_OPEN_FLAGS_ACCESS_FIXED \
+ | INTNET_OPEN_FLAGS_PROMISC_FIXED \
+ | INTNET_OPEN_FLAGS_IF_FIXED \
+ | INTNET_OPEN_FLAGS_TRUNK_FIXED )
+
+/** The mask of all policy pairs. */
+#define INTNET_OPEN_FLAGS_PAIR_MASK \
+ ( INTNET_OPEN_FLAGS_ACCESS_PUBLIC | INTNET_OPEN_FLAGS_ACCESS_RESTRICTED \
+ | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS | INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS \
+ | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST \
+ | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE \
+ | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW | INTNET_OPEN_FLAGS_IF_PROMISC_DENY \
+ | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK | INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK \
+ | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED | INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED \
+ | INTNET_OPEN_FLAGS_TRUNK_HOST_PROMISC_MODE | INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE \
+ | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED | INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED \
+ | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE \
+ )
+/** The mask of all relaxed policy bits. */
+#define INTNET_OPEN_FLAGS_RELAXED_MASK \
+ ( INTNET_OPEN_FLAGS_ACCESS_PUBLIC \
+ | INTNET_OPEN_FLAGS_PROMISC_ALLOW_CLIENTS \
+ | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_HOST \
+ | INTNET_OPEN_FLAGS_PROMISC_ALLOW_TRUNK_WIRE \
+ | INTNET_OPEN_FLAGS_IF_PROMISC_ALLOW \
+ | INTNET_OPEN_FLAGS_IF_PROMISC_SEE_TRUNK \
+ | INTNET_OPEN_FLAGS_TRUNK_HOST_ENABLED \
+ | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE \
+ | INTNET_OPEN_FLAGS_TRUNK_WIRE_ENABLED \
+ | INTNET_OPEN_FLAGS_TRUNK_WIRE_PROMISC_MODE \
+ )
+/** The mask of all strict policy bits. */
+#define INTNET_OPEN_FLAGS_STRICT_MASK \
+ ( INTNET_OPEN_FLAGS_ACCESS_RESTRICTED \
+ | INTNET_OPEN_FLAGS_PROMISC_DENY_CLIENTS \
+ | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_HOST \
+ | INTNET_OPEN_FLAGS_PROMISC_DENY_TRUNK_WIRE \
+ | INTNET_OPEN_FLAGS_IF_PROMISC_DENY \
+ | INTNET_OPEN_FLAGS_IF_PROMISC_NO_TRUNK \
+ | INTNET_OPEN_FLAGS_TRUNK_HOST_DISABLED \
+ | INTNET_OPEN_FLAGS_TRUNK_HOST_CHASTE_MODE \
+ | INTNET_OPEN_FLAGS_TRUNK_WIRE_DISABLED \
+ | INTNET_OPEN_FLAGS_TRUNK_WIRE_CHASTE_MODE \
+ )
+/** @} */
+
+/** The maximum length of a network name. */
+#define INTNET_MAX_NETWORK_NAME 128
+
+/** The maximum length of a trunk name. */
+#define INTNET_MAX_TRUNK_NAME 64
+
+
+/**
+ * Request buffer for IntNetR0OpenReq / VMMR0_DO_INTNET_OPEN.
+ * @see IntNetR0Open.
+ */
+typedef struct INTNETOPENREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** The network name. (input) */
+ char szNetwork[INTNET_MAX_NETWORK_NAME];
+ /** What to connect to the trunk port. (input)
+ * This is specific to the trunk type below. */
+ char szTrunk[INTNET_MAX_TRUNK_NAME];
+ /** The type of trunk link (NAT, Filter, TAP, etc). (input) */
+ INTNETTRUNKTYPE enmTrunkType;
+ /** Flags, see INTNET_OPEN_FLAGS_*. (input) */
+ uint32_t fFlags;
+ /** The size of the send buffer. (input) */
+ uint32_t cbSend;
+ /** The size of the receive buffer. (input) */
+ uint32_t cbRecv;
+ /** The handle to the network interface. (output) */
+ INTNETIFHANDLE hIf;
+} INTNETOPENREQ;
+/** Pointer to an IntNetR0OpenReq / VMMR0_DO_INTNET_OPEN request buffer. */
+typedef INTNETOPENREQ *PINTNETOPENREQ;
+
+INTNETR0DECL(int) IntNetR0OpenReq(PSUPDRVSESSION pSession, PINTNETOPENREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE.
+ * @see IntNetR0IfClose.
+ */
+typedef struct INTNETIFCLOSEREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** The handle to the network interface. */
+ INTNETIFHANDLE hIf;
+} INTNETIFCLOSEREQ;
+/** Pointer to an IntNetR0IfCloseReq / VMMR0_DO_INTNET_IF_CLOSE request
+ * buffer. */
+typedef INTNETIFCLOSEREQ *PINTNETIFCLOSEREQ;
+
+INTNETR0DECL(int) IntNetR0IfCloseReq(PSUPDRVSESSION pSession, PINTNETIFCLOSEREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfGetRing3BufferReq /
+ * VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS.
+ * @see IntNetR0IfGetRing3Buffer.
+ */
+typedef struct INTNETIFGETBUFFERPTRSREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** Handle to the interface. */
+ INTNETIFHANDLE hIf;
+ /** The pointer to the ring-3 buffer. (output) */
+ R3PTRTYPE(PINTNETBUF) pRing3Buf;
+ /** The pointer to the ring-0 buffer. (output) */
+ R0PTRTYPE(PINTNETBUF) pRing0Buf;
+} INTNETIFGETBUFFERPTRSREQ;
+/** Pointer to an IntNetR0IfGetRing3BufferReq /
+ * VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS request buffer. */
+typedef INTNETIFGETBUFFERPTRSREQ *PINTNETIFGETBUFFERPTRSREQ;
+
+INTNETR0DECL(int) IntNetR0IfGetBufferPtrsReq(PSUPDRVSESSION pSession, PINTNETIFGETBUFFERPTRSREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfSetPromiscuousModeReq /
+ * VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE.
+ * @see IntNetR0IfSetPromiscuousMode.
+ */
+typedef struct INTNETIFSETPROMISCUOUSMODEREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** Handle to the interface. */
+ INTNETIFHANDLE hIf;
+ /** The new promiscuous mode. */
+ bool fPromiscuous;
+} INTNETIFSETPROMISCUOUSMODEREQ;
+/** Pointer to an IntNetR0IfSetPromiscuousModeReq /
+ * VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE request buffer. */
+typedef INTNETIFSETPROMISCUOUSMODEREQ *PINTNETIFSETPROMISCUOUSMODEREQ;
+
+INTNETR0DECL(int) IntNetR0IfSetPromiscuousModeReq(PSUPDRVSESSION pSession, PINTNETIFSETPROMISCUOUSMODEREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfSetMacAddressReq /
+ * VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS.
+ * @see IntNetR0IfSetMacAddress.
+ */
+typedef struct INTNETIFSETMACADDRESSREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** Handle to the interface. */
+ INTNETIFHANDLE hIf;
+ /** The new MAC address. */
+ RTMAC Mac;
+} INTNETIFSETMACADDRESSREQ;
+/** Pointer to an IntNetR0IfSetMacAddressReq /
+ * VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS request buffer. */
+typedef INTNETIFSETMACADDRESSREQ *PINTNETIFSETMACADDRESSREQ;
+
+INTNETR0DECL(int) IntNetR0IfSetMacAddressReq(PSUPDRVSESSION pSession, PINTNETIFSETMACADDRESSREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE.
+ * @see IntNetR0IfSetActive.
+ */
+typedef struct INTNETIFSETACTIVEREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** Handle to the interface. */
+ INTNETIFHANDLE hIf;
+ /** The new state. */
+ bool fActive;
+} INTNETIFSETACTIVEREQ;
+/** Pointer to an IntNetR0IfSetActiveReq / VMMR0_DO_INTNET_IF_SET_ACTIVE
+ * request buffer. */
+typedef INTNETIFSETACTIVEREQ *PINTNETIFSETACTIVEREQ;
+
+INTNETR0DECL(int) IntNetR0IfSetActiveReq(PSUPDRVSESSION pSession, PINTNETIFSETACTIVEREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfSendReq / VMMR0_DO_INTNET_IF_SEND.
+ * @see IntNetR0IfSend.
+ */
+typedef struct INTNETIFSENDREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** Handle to the interface. */
+ INTNETIFHANDLE hIf;
+} INTNETIFSENDREQ;
+/** Pointer to an IntNetR0IfSend() argument package. */
+typedef INTNETIFSENDREQ *PINTNETIFSENDREQ;
+
+INTNETR0DECL(int) IntNetR0IfSendReq(PSUPDRVSESSION pSession, PINTNETIFSENDREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT.
+ * @see IntNetR0IfWait.
+ */
+typedef struct INTNETIFWAITREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** Handle to the interface. */
+ INTNETIFHANDLE hIf;
+ /** The number of milliseconds to wait. */
+ uint32_t cMillies;
+} INTNETIFWAITREQ;
+/** Pointer to an IntNetR0IfWaitReq / VMMR0_DO_INTNET_IF_WAIT request buffer. */
+typedef INTNETIFWAITREQ *PINTNETIFWAITREQ;
+
+INTNETR0DECL(int) IntNetR0IfWaitReq(PSUPDRVSESSION pSession, PINTNETIFWAITREQ pReq);
+
+
+/**
+ * Request buffer for IntNetR0IfAbortWaitReq / VMMR0_DO_INTNET_IF_ABORT_WAIT.
+ * @see IntNetR0IfAbortWait.
+ */
+typedef struct INTNETIFABORTWAITREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both. */
+ PSUPDRVSESSION pSession;
+ /** Handle to the interface. */
+ INTNETIFHANDLE hIf;
+ /** Set this to fend off all future IntNetR0Wait calls. */
+ bool fNoMoreWaits;
+} INTNETIFABORTWAITREQ;
+/** Pointer to an IntNetR0IfAbortWaitReq / VMMR0_DO_INTNET_IF_ABORT_WAIT
+ * request buffer. */
+typedef INTNETIFABORTWAITREQ *PINTNETIFABORTWAITREQ;
+
+INTNETR0DECL(int) IntNetR0IfAbortWaitReq(PSUPDRVSESSION pSession, PINTNETIFABORTWAITREQ pReq);
+
+
+#if defined(IN_RING0) || defined(IN_INTNET_TESTCASE)
+/** @name
+ * @{
+ */
+
+INTNETR0DECL(int) IntNetR0Init(void);
+INTNETR0DECL(void) IntNetR0Term(void);
+INTNETR0DECL(int) IntNetR0Open(PSUPDRVSESSION pSession, const char *pszNetwork,
+ INTNETTRUNKTYPE enmTrunkType, const char *pszTrunk, uint32_t fFlags,
+ uint32_t cbSend, uint32_t cbRecv, PINTNETIFHANDLE phIf);
+INTNETR0DECL(uint32_t) IntNetR0GetNetworkCount(void);
+
+INTNETR0DECL(int) IntNetR0IfClose(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
+INTNETR0DECL(int) IntNetR0IfGetBufferPtrs(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession,
+ R3PTRTYPE(PINTNETBUF) *ppRing3Buf, R0PTRTYPE(PINTNETBUF) *ppRing0Buf);
+INTNETR0DECL(int) IntNetR0IfSetPromiscuousMode(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fPromiscuous);
+INTNETR0DECL(int) IntNetR0IfSetMacAddress(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, PCRTMAC pMac);
+INTNETR0DECL(int) IntNetR0IfSetActive(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, bool fActive);
+INTNETR0DECL(int) IntNetR0IfSend(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
+INTNETR0DECL(int) IntNetR0IfWait(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession, uint32_t cMillies);
+INTNETR0DECL(int) IntNetR0IfAbortWait(INTNETIFHANDLE hIf, PSUPDRVSESSION pSession);
+
+/** @} */
+#endif /* IN_RING0 */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/intnetinline.h b/include/VBox/intnetinline.h
new file mode 100644
index 00000000..bcc42f1a
--- /dev/null
+++ b/include/VBox/intnetinline.h
@@ -0,0 +1,822 @@
+/* $Id: intnetinline.h $ */
+/** @file
+ * INTNET - Internal Networking, Inlined Code. (DEV,++)
+ *
+ * This is all inlined because it's too tedious to create 2-3 libraries to
+ * contain it all. Large parts of this header is only accessible from C++
+ * sources because of mixed code and variables.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_intnetinline_h
+#define ___VBox_intnetinline_h
+
+#include <VBox/intnet.h>
+#include <iprt/string.h>
+#include <iprt/assert.h>
+#include <iprt/err.h>
+#include <VBox/log.h>
+
+
+
+/**
+ * Valid internal networking frame type.
+ *
+ * @returns true / false.
+ * @param u16Type The frame type to check.
+ */
+DECLINLINE(bool) IntNetIsValidFrameType(uint16_t u16Type)
+{
+ if (RT_LIKELY( u16Type == INTNETHDR_TYPE_FRAME
+ || u16Type == INTNETHDR_TYPE_GSO
+ || u16Type == INTNETHDR_TYPE_PADDING))
+ return true;
+ return false;
+}
+
+
+/**
+ * Partly initializes a scatter / gather buffer, leaving the segments to the
+ * caller.
+ *
+ * @returns Pointer to the start of the frame.
+ * @param pSG Pointer to the scatter / gather structure.
+ * @param cbTotal The total size.
+ * @param cSegs The number of segments.
+ * @param cSegsUsed The number of used segments.
+ */
+DECLINLINE(void) IntNetSgInitTempSegs(PINTNETSG pSG, uint32_t cbTotal, unsigned cSegs, unsigned cSegsUsed)
+{
+ pSG->pvOwnerData = NULL;
+ pSG->pvUserData = NULL;
+ pSG->pvUserData2 = NULL;
+ pSG->cbTotal = cbTotal;
+ pSG->cUsers = 1;
+ pSG->fFlags = INTNETSG_FLAGS_TEMP;
+ pSG->GsoCtx.u8Type = (uint8_t)PDMNETWORKGSOTYPE_INVALID;
+ pSG->GsoCtx.cbHdrsTotal = 0;
+ pSG->GsoCtx.cbHdrsSeg = 0;
+ pSG->GsoCtx.cbMaxSeg= 0;
+ pSG->GsoCtx.offHdr1 = 0;
+ pSG->GsoCtx.offHdr2 = 0;
+ pSG->GsoCtx.u8Unused= 0;
+#if ARCH_BITS == 64
+ pSG->uPadding = 0;
+#endif
+ pSG->cSegsAlloc = (uint16_t)cSegs;
+ Assert(pSG->cSegsAlloc == cSegs);
+ pSG->cSegsUsed = (uint16_t)cSegsUsed;
+ Assert(pSG->cSegsUsed == cSegsUsed);
+ Assert(cSegs >= cSegsUsed);
+}
+
+
+/**
+ * Partly initializes a scatter / gather buffer w/ GSO, leaving the segments to
+ * the caller.
+ *
+ * @returns Pointer to the start of the frame.
+ * @param pSG Pointer to the scatter / gather structure.
+ * @param cbTotal The total size.
+ * @param cSegs The number of segments.
+ * @param cSegsUsed The number of used segments.
+ * @param pGso The GSO context.
+ */
+DECLINLINE(void) IntNetSgInitTempSegsGso(PINTNETSG pSG, uint32_t cbTotal, unsigned cSegs,
+ unsigned cSegsUsed, PCPDMNETWORKGSO pGso)
+{
+ pSG->pvOwnerData = NULL;
+ pSG->pvUserData = NULL;
+ pSG->pvUserData2 = NULL;
+ pSG->cbTotal = cbTotal;
+ pSG->cUsers = 1;
+ pSG->fFlags = INTNETSG_FLAGS_TEMP;
+ pSG->GsoCtx.u8Type = pGso->u8Type;
+ pSG->GsoCtx.cbHdrsTotal = pGso->cbHdrsTotal;
+ pSG->GsoCtx.cbHdrsSeg = pGso->cbHdrsSeg;
+ pSG->GsoCtx.cbMaxSeg= pGso->cbMaxSeg;
+ pSG->GsoCtx.offHdr1 = pGso->offHdr1;
+ pSG->GsoCtx.offHdr2 = pGso->offHdr2;
+ pSG->GsoCtx.u8Unused= 0;
+#if ARCH_BITS == 64
+ pSG->uPadding = 0;
+#endif
+ pSG->cSegsAlloc = (uint16_t)cSegs;
+ Assert(pSG->cSegsAlloc == cSegs);
+ pSG->cSegsUsed = (uint16_t)cSegsUsed;
+ Assert(pSG->cSegsUsed == cSegsUsed);
+ Assert(cSegs >= cSegsUsed);
+}
+
+
+
+/**
+ * Initializes a scatter / gather buffer describing a simple linear buffer.
+ *
+ * @returns Pointer to the start of the frame.
+ * @param pSG Pointer to the scatter / gather structure.
+ * @param pvFrame Pointer to the frame
+ * @param cbFrame The size of the frame.
+ */
+DECLINLINE(void) IntNetSgInitTemp(PINTNETSG pSG, void *pvFrame, uint32_t cbFrame)
+{
+ IntNetSgInitTempSegs(pSG, cbFrame, 1, 1);
+ pSG->aSegs[0].Phys = NIL_RTHCPHYS;
+ pSG->aSegs[0].pv = pvFrame;
+ pSG->aSegs[0].cb = cbFrame;
+}
+
+/**
+ * Initializes a scatter / gather buffer describing a simple linear buffer.
+ *
+ * @returns Pointer to the start of the frame.
+ * @param pSG Pointer to the scatter / gather structure.
+ * @param pvFrame Pointer to the frame
+ * @param cbFrame The size of the frame.
+ * @param pGso The GSO context.
+ */
+DECLINLINE(void) IntNetSgInitTempGso(PINTNETSG pSG, void *pvFrame, uint32_t cbFrame, PCPDMNETWORKGSO pGso)
+{
+ IntNetSgInitTempSegsGso(pSG, cbFrame, 1, 1, pGso);
+ pSG->aSegs[0].Phys = NIL_RTHCPHYS;
+ pSG->aSegs[0].pv = pvFrame;
+ pSG->aSegs[0].cb = cbFrame;
+}
+
+
+/**
+ * Reads an entire SG into a fittingly size buffer.
+ *
+ * @param pSG The SG list to read.
+ * @param pvBuf The buffer to read into (at least pSG->cbTotal in size).
+ */
+DECLINLINE(void) IntNetSgRead(PCINTNETSG pSG, void *pvBuf)
+{
+ memcpy(pvBuf, pSG->aSegs[0].pv, pSG->aSegs[0].cb);
+ if (pSG->cSegsUsed == 1)
+ Assert(pSG->cbTotal == pSG->aSegs[0].cb);
+ else
+ {
+ uint8_t *pbDst = (uint8_t *)pvBuf + pSG->aSegs[0].cb;
+ unsigned iSeg = 0;
+ unsigned const cSegs = pSG->cSegsUsed;
+ while (++iSeg < cSegs)
+ {
+ uint32_t cbSeg = pSG->aSegs[iSeg].cb;
+ Assert((uintptr_t)pbDst - (uintptr_t)pvBuf + cbSeg <= pSG->cbTotal);
+ memcpy(pbDst, pSG->aSegs[iSeg].pv, cbSeg);
+ pbDst += cbSeg;
+ }
+ }
+}
+
+
+/**
+ * Reads a portion of an SG into a buffer.
+ *
+ * @param pSG The SG list to read.
+ * @param offSrc The offset to start start copying from.
+ * @param cbToRead The number of bytes to copy.
+ * @param pvBuf The buffer to read into, cb or more in size.
+ */
+DECLINLINE(void) IntNetSgReadEx(PCINTNETSG pSG, uint32_t offSrc, uint32_t cbToRead, void *pvBuf)
+{
+ uint8_t *pbDst = (uint8_t *)pvBuf;
+ uint32_t iSeg = 0;
+
+ /* validate assumptions */
+ Assert(cbToRead <= pSG->cbTotal);
+ Assert(offSrc <= pSG->cbTotal);
+ Assert(offSrc + cbToRead <= pSG->cbTotal);
+
+ /* Find the right segment and copy any bits from within the segment. */
+ while (offSrc)
+ {
+ uint32_t cbSeg = pSG->aSegs[iSeg].cb;
+ if (offSrc < cbSeg)
+ {
+ uint32_t cbChunk = cbSeg - offSrc;
+ if (cbChunk >= cbToRead)
+ {
+ memcpy(pbDst, (uint8_t const *)pSG->aSegs[iSeg].pv + offSrc, cbToRead);
+ return;
+ }
+
+ memcpy(pbDst, (uint8_t const *)pSG->aSegs[iSeg].pv + offSrc, cbChunk);
+ pbDst += cbChunk;
+ cbToRead -= cbChunk;
+ break;
+ }
+
+ /* advance */
+ offSrc -= cbSeg;
+ iSeg++;
+ }
+
+ /* We're not at the start of a segment, copy until we're done. */
+ for (;;)
+ {
+ uint32_t cbSeg = pSG->aSegs[iSeg].cb;
+ if (cbSeg >= cbToRead)
+ {
+ memcpy(pbDst, pSG->aSegs[iSeg].pv, cbToRead);
+ return;
+ }
+
+ memcpy(pbDst, pSG->aSegs[iSeg].pv, cbSeg);
+ pbDst += cbSeg;
+ cbToRead -= cbSeg;
+ iSeg++;
+ Assert(iSeg < pSG->cSegsUsed);
+ }
+}
+
+#ifdef __cplusplus
+
+/**
+ * Get the amount of space available for writing.
+ *
+ * @returns Number of available bytes.
+ * @param pRingBuf The ring buffer.
+ */
+DECLINLINE(uint32_t) IntNetRingGetWritable(PINTNETRINGBUF pRingBuf)
+{
+ uint32_t const offRead = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ uint32_t const offWriteInt = ASMAtomicUoReadU32(&pRingBuf->offWriteInt);
+ return offRead <= offWriteInt
+ ? pRingBuf->offEnd - offWriteInt + offRead - pRingBuf->offStart - 1
+ : offRead - offWriteInt - 1;
+}
+
+
+/**
+ * Checks if the ring has more for us to read.
+ *
+ * @returns Number of ready bytes.
+ * @param pRingBuf The ring buffer.
+ */
+DECLINLINE(bool) IntNetRingHasMoreToRead(PINTNETRINGBUF pRingBuf)
+{
+ uint32_t const offRead = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ uint32_t const offWriteCom = ASMAtomicUoReadU32(&pRingBuf->offWriteCom);
+ return offRead != offWriteCom;
+}
+
+
+/**
+ * Gets the next frame to read.
+ *
+ * @returns Pointer to the next frame. NULL if done.
+ * @param pRingBuf The ring buffer.
+ */
+DECLINLINE(PINTNETHDR) IntNetRingGetNextFrameToRead(PINTNETRINGBUF pRingBuf)
+{
+ uint32_t const offRead = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ uint32_t const offWriteCom = ASMAtomicUoReadU32(&pRingBuf->offWriteCom);
+ if (offRead == offWriteCom)
+ return NULL;
+ return (PINTNETHDR)((uint8_t *)pRingBuf + offRead);
+}
+
+
+/**
+ * Get the amount of data ready for reading.
+ *
+ * @returns Number of ready bytes.
+ * @param pRingBuf The ring buffer.
+ */
+DECLINLINE(uint32_t) IntNetRingGetReadable(PINTNETRINGBUF pRingBuf)
+{
+ uint32_t const offRead = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ uint32_t const offWriteCom = ASMAtomicUoReadU32(&pRingBuf->offWriteCom);
+ return offRead <= offWriteCom
+ ? offWriteCom - offRead
+ : pRingBuf->offEnd - offRead + offWriteCom - pRingBuf->offStart;
+}
+
+
+/**
+ * Calculates the pointer to the frame.
+ *
+ * @returns Pointer to the start of the frame.
+ * @param pHdr Pointer to the packet header
+ * @param pBuf The buffer the header is within. Only used in strict builds.
+ */
+DECLINLINE(void *) IntNetHdrGetFramePtr(PCINTNETHDR pHdr, PCINTNETBUF pBuf)
+{
+ uint8_t *pu8 = (uint8_t *)pHdr + pHdr->offFrame;
+#ifdef VBOX_STRICT
+ const uintptr_t off = (uintptr_t)pu8 - (uintptr_t)pBuf;
+ Assert(IntNetIsValidFrameType(pHdr->u16Type));
+ Assert(off < pBuf->cbBuf);
+ Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
+#endif
+ NOREF(pBuf);
+ return pu8;
+}
+
+
+/**
+ * Calculates the pointer to the GSO context.
+ *
+ * ASSUMES the frame is a GSO frame.
+ *
+ * The GSO context is immediately followed by the headers and payload. The size
+ * is INTNETBUF::cbFrame - sizeof(PDMNETWORKGSO).
+ *
+ * @returns Pointer to the GSO context.
+ * @param pHdr Pointer to the packet header
+ * @param pBuf The buffer the header is within. Only used in strict builds.
+ */
+DECLINLINE(PPDMNETWORKGSO) IntNetHdrGetGsoContext(PCINTNETHDR pHdr, PCINTNETBUF pBuf)
+{
+ PPDMNETWORKGSO pGso = (PPDMNETWORKGSO)((uint8_t *)pHdr + pHdr->offFrame);
+#ifdef VBOX_STRICT
+ const uintptr_t off = (uintptr_t)pGso - (uintptr_t)pBuf;
+ Assert(pHdr->u16Type == INTNETHDR_TYPE_GSO);
+ Assert(off < pBuf->cbBuf);
+ Assert(off + pHdr->cbFrame <= pBuf->cbBuf);
+#endif
+ NOREF(pBuf);
+ return pGso;
+}
+
+
+/**
+ * Skips to the next (read) frame in the buffer.
+ *
+ * @param pRingBuf The ring buffer in question.
+ */
+DECLINLINE(void) IntNetRingSkipFrame(PINTNETRINGBUF pRingBuf)
+{
+ uint32_t const offReadOld = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offReadOld);
+ Assert(offReadOld >= pRingBuf->offStart);
+ Assert(offReadOld < pRingBuf->offEnd);
+ Assert(RT_ALIGN_PT(pHdr, INTNETHDR_ALIGNMENT, INTNETHDR *) == pHdr);
+ Assert(IntNetIsValidFrameType(pHdr->u16Type));
+
+ /* skip the frame */
+ uint32_t offReadNew = offReadOld + pHdr->offFrame + pHdr->cbFrame;
+ offReadNew = RT_ALIGN_32(offReadNew, INTNETHDR_ALIGNMENT);
+ Assert(offReadNew <= pRingBuf->offEnd && offReadNew >= pRingBuf->offStart);
+ if (offReadNew >= pRingBuf->offEnd)
+ offReadNew = pRingBuf->offStart;
+ Log2(("IntNetRingSkipFrame: offReadX: %#x -> %#x (1)\n", offReadOld, offReadNew));
+#ifdef INTNET_POISON_READ_FRAMES
+ memset((uint8_t *)pHdr + pHdr->offFrame, 0xfe, RT_ALIGN_32(pHdr->cbFrame, INTNETHDR_ALIGNMENT));
+ memset(pHdr, 0xef, sizeof(*pHdr));
+#endif
+ ASMAtomicWriteU32(&pRingBuf->offReadX, offReadNew);
+}
+
+
+/**
+ * Allocates a frame in the specified ring.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pRingBuf The ring buffer.
+ * @param cbFrame The frame size.
+ * @param ppHdr Where to return the frame header.
+ * Don't touch this!
+ * @param ppvFrame Where to return the frame pointer.
+ */
+DECLINLINE(int) intnetRingAllocateFrameInternal(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, uint16_t u16Type,
+ PINTNETHDR *ppHdr, void **ppvFrame)
+{
+ /*
+ * Validate input and adjust the input.
+ */
+ INTNETRINGBUF_ASSERT_SANITY(pRingBuf);
+ Assert(cbFrame >= sizeof(RTMAC) * 2);
+
+ const uint32_t cb = RT_ALIGN_32(cbFrame, INTNETHDR_ALIGNMENT);
+ uint32_t offWriteInt = ASMAtomicUoReadU32(&pRingBuf->offWriteInt);
+ uint32_t offRead = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ if (offRead <= offWriteInt)
+ {
+ /*
+ * Try fit it all before the end of the buffer.
+ */
+ if (pRingBuf->offEnd - offWriteInt >= cb + sizeof(INTNETHDR))
+ {
+ uint32_t offNew = offWriteInt + cb + sizeof(INTNETHDR);
+ if (offNew >= pRingBuf->offEnd)
+ offNew = pRingBuf->offStart;
+ if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
+ return VERR_WRONG_ORDER; /* race */
+ Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (1) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
+
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
+ pHdr->u16Type = u16Type;
+ pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
+ pHdr->offFrame = sizeof(INTNETHDR);
+
+ *ppHdr = pHdr;
+ *ppvFrame = pHdr + 1;
+ return VINF_SUCCESS;
+ }
+ /*
+ * Try fit the frame at the start of the buffer.
+ * (The header fits before the end of the buffer because of alignment.)
+ */
+ AssertMsg(pRingBuf->offEnd - offWriteInt >= sizeof(INTNETHDR), ("offEnd=%x offWriteInt=%x\n", pRingBuf->offEnd, offWriteInt));
+ if (offRead - pRingBuf->offStart > cb) /* not >= ! */
+ {
+ uint32_t offNew = pRingBuf->offStart + cb;
+ if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
+ return VERR_WRONG_ORDER; /* race */
+ Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (2) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
+
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
+ pHdr->u16Type = u16Type;
+ pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
+ pHdr->offFrame = pRingBuf->offStart - offWriteInt;
+
+ *ppHdr = pHdr;
+ *ppvFrame = (uint8_t *)pRingBuf + pRingBuf->offStart;
+ return VINF_SUCCESS;
+ }
+ }
+ /*
+ * The reader is ahead of the writer, try fit it into that space.
+ */
+ else if (offRead - offWriteInt > cb + sizeof(INTNETHDR)) /* not >= ! */
+ {
+ uint32_t offNew = offWriteInt + cb + sizeof(INTNETHDR);
+ if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
+ return VERR_WRONG_ORDER; /* race */
+ Log2(("intnetRingAllocateFrameInternal: offWriteInt: %#x -> %#x (3) (R=%#x T=%#x S=%#x)\n", offWriteInt, offNew, offRead, u16Type, cbFrame));
+
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
+ pHdr->u16Type = u16Type;
+ pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
+ pHdr->offFrame = sizeof(INTNETHDR);
+
+ *ppHdr = pHdr;
+ *ppvFrame = pHdr + 1;
+ return VINF_SUCCESS;
+ }
+
+ /* (it didn't fit) */
+ *ppHdr = NULL; /* shut up gcc, */
+ *ppvFrame = NULL; /* ditto. */
+ STAM_REL_COUNTER_INC(&pRingBuf->cOverflows);
+ return VERR_BUFFER_OVERFLOW;
+}
+
+
+/**
+ * Allocates a normal frame in the specified ring.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pRingBuf The ring buffer.
+ * @param cbFrame The frame size.
+ * @param ppHdr Where to return the frame header.
+ * Don't touch this!
+ * @param ppvFrame Where to return the frame pointer.
+ */
+DECLINLINE(int) IntNetRingAllocateFrame(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, PINTNETHDR *ppHdr, void **ppvFrame)
+{
+ return intnetRingAllocateFrameInternal(pRingBuf, cbFrame, INTNETHDR_TYPE_FRAME, ppHdr, ppvFrame);
+}
+
+
+/**
+ * Allocates a GSO frame in the specified ring.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pRingBuf The ring buffer.
+ * @param cbFrame The frame size.
+ * @param pGso Pointer to the GSO context.
+ * @param ppHdr Where to return the frame header.
+ * Don't touch this!
+ * @param ppvFrame Where to return the frame pointer.
+ */
+DECLINLINE(int) IntNetRingAllocateGsoFrame(PINTNETRINGBUF pRingBuf, uint32_t cbFrame, PCPDMNETWORKGSO pGso,
+ PINTNETHDR *ppHdr, void **ppvFrame)
+{
+ void *pvFrame = NULL; /* gcc maybe used uninitialized */
+ int rc = intnetRingAllocateFrameInternal(pRingBuf, cbFrame + sizeof(*pGso), INTNETHDR_TYPE_GSO, ppHdr, &pvFrame);
+ if (RT_SUCCESS(rc))
+ {
+ PPDMNETWORKGSO pGsoCopy = (PPDMNETWORKGSO)pvFrame;
+ *pGsoCopy = *pGso;
+ *ppvFrame = pGsoCopy + 1;
+ }
+ return rc;
+}
+
+
+/**
+ * Commits a frame.
+ *
+ * Make sure to commit the frames in the order they've been allocated!
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pRingBuf The ring buffer.
+ * @param pHdr The frame header returned by
+ * IntNetRingAllocateFrame.
+ */
+DECLINLINE(void) IntNetRingCommitFrame(PINTNETRINGBUF pRingBuf, PINTNETHDR pHdr)
+{
+ /*
+ * Validate input and commit order.
+ */
+ INTNETRINGBUF_ASSERT_SANITY(pRingBuf);
+ INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf);
+ Assert(pRingBuf->offWriteCom == ((uintptr_t)pHdr - (uintptr_t)pRingBuf));
+
+ /*
+ * Figure out the offWriteCom for this packet and update the ring.
+ */
+ const uint32_t cbFrame = pHdr->cbFrame;
+ const uint32_t cb = RT_ALIGN_32(cbFrame, INTNETHDR_ALIGNMENT);
+ uint32_t offWriteCom = (uint32_t)((uintptr_t)pHdr - (uintptr_t)pRingBuf)
+ + pHdr->offFrame
+ + cb;
+ if (offWriteCom >= pRingBuf->offEnd)
+ {
+ Assert(offWriteCom == pRingBuf->offEnd);
+ offWriteCom = pRingBuf->offStart;
+ }
+ Log2(("IntNetRingCommitFrame: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, cbFrame));
+ ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom);
+ STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame);
+ STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames);
+}
+
+
+/**
+ * Commits a frame and injects a filler frame if not all of the buffer was used.
+ *
+ * Make sure to commit the frames in the order they've been allocated!
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pRingBuf The ring buffer.
+ * @param pHdr The frame header returned by
+ * IntNetRingAllocateFrame.
+ * @param cbUsed The amount of space actually used. This does
+ * not include the GSO part.
+ */
+DECLINLINE(void) IntNetRingCommitFrameEx(PINTNETRINGBUF pRingBuf, PINTNETHDR pHdr, size_t cbUsed)
+{
+ /*
+ * Validate input and commit order.
+ */
+ INTNETRINGBUF_ASSERT_SANITY(pRingBuf);
+ INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf);
+ Assert(pRingBuf->offWriteCom == ((uintptr_t)pHdr - (uintptr_t)pRingBuf));
+
+ if (pHdr->u16Type == INTNETHDR_TYPE_GSO)
+ cbUsed += sizeof(PDMNETWORKGSO);
+
+ /*
+ * Calc the new write commit offset.
+ */
+ const uint32_t cbAlignedFrame = RT_ALIGN_32(pHdr->cbFrame, INTNETHDR_ALIGNMENT);
+ const uint32_t cbAlignedUsed = RT_ALIGN_32(cbUsed, INTNETHDR_ALIGNMENT);
+ uint32_t offWriteCom = (uint32_t)((uintptr_t)pHdr - (uintptr_t)pRingBuf)
+ + pHdr->offFrame
+ + cbAlignedFrame;
+ if (offWriteCom >= pRingBuf->offEnd)
+ {
+ Assert(offWriteCom == pRingBuf->offEnd);
+ offWriteCom = pRingBuf->offStart;
+ }
+
+ /*
+ * Insert a dummy frame to pad any unused space.
+ */
+ if (cbAlignedFrame != cbAlignedUsed)
+ {
+ /** @todo Later: Try unallocate the extra memory. */
+ PINTNETHDR pHdrPadding = (PINTNETHDR)((uint8_t *)pHdr + pHdr->offFrame + cbAlignedUsed);
+ pHdrPadding->u16Type = INTNETHDR_TYPE_PADDING;
+ pHdrPadding->cbFrame = (uint16_t)(cbAlignedFrame - cbAlignedUsed - sizeof(INTNETHDR));
+ pHdrPadding->offFrame = sizeof(INTNETHDR);
+ pHdr->cbFrame = (uint16_t)cbUsed;
+ }
+
+ Log2(("IntNetRingCommitFrameEx: offWriteCom: %#x -> %#x (R=%#x T=%#x S=%#x P=%#x)\n", pRingBuf->offWriteCom, offWriteCom, pRingBuf->offReadX, pHdr->u16Type, pHdr->cbFrame, cbAlignedFrame - cbAlignedUsed));
+ ASMAtomicWriteU32(&pRingBuf->offWriteCom, offWriteCom);
+ STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbUsed);
+ STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames);
+}
+
+
+/**
+ * Writes a frame to the specified ring.
+ *
+ * Make sure you don't have any uncommitted frames when calling this function!
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pRingBuf The ring buffer.
+ * @param pvFrame The bits to write.
+ * @param cbFrame How much to write.
+ */
+DECLINLINE(int) IntNetRingWriteFrame(PINTNETRINGBUF pRingBuf, const void *pvFrame, size_t cbFrame)
+{
+ /*
+ * Validate input.
+ */
+ INTNETRINGBUF_ASSERT_SANITY(pRingBuf);
+ Assert(cbFrame >= sizeof(RTMAC) * 2);
+
+ /*
+ * Align the size and read the volatile ring buffer variables.
+ */
+ const uint32_t cb = RT_ALIGN_32(cbFrame, INTNETHDR_ALIGNMENT);
+ uint32_t offWriteInt = ASMAtomicUoReadU32(&pRingBuf->offWriteInt);
+ uint32_t offRead = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ if (offRead <= offWriteInt)
+ {
+ /*
+ * Try fit it all before the end of the buffer.
+ */
+ if (pRingBuf->offEnd - offWriteInt >= cb + sizeof(INTNETHDR))
+ {
+ uint32_t offNew = offWriteInt + cb + sizeof(INTNETHDR);
+ if (offNew >= pRingBuf->offEnd)
+ offNew = pRingBuf->offStart;
+ if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
+ return VERR_WRONG_ORDER; /* race */
+ Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (1)\n", offWriteInt, offNew));
+
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
+ pHdr->u16Type = INTNETHDR_TYPE_FRAME;
+ pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
+ pHdr->offFrame = sizeof(INTNETHDR);
+
+ memcpy(pHdr + 1, pvFrame, cbFrame);
+
+ Log2(("IntNetRingWriteFrame: offWriteCom: %#x -> %#x (1)\n", pRingBuf->offWriteCom, offNew));
+ ASMAtomicWriteU32(&pRingBuf->offWriteCom, offNew);
+ STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame);
+ STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames);
+ return VINF_SUCCESS;
+ }
+ /*
+ * Try fit the frame at the start of the buffer.
+ * (The header fits before the end of the buffer because of alignment.)
+ */
+ AssertMsg(pRingBuf->offEnd - offWriteInt >= sizeof(INTNETHDR), ("offEnd=%x offWriteInt=%x\n", pRingBuf->offEnd, offWriteInt));
+ if (offRead - pRingBuf->offStart > cb) /* not >= ! */
+ {
+ uint32_t offNew = pRingBuf->offStart + cb;
+ if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
+ return VERR_WRONG_ORDER; /* race */
+ Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (2)\n", offWriteInt, offNew));
+
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
+ pHdr->u16Type = INTNETHDR_TYPE_FRAME;
+ pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
+ pHdr->offFrame = pRingBuf->offStart - offWriteInt;
+
+ memcpy((uint8_t *)pRingBuf + pRingBuf->offStart, pvFrame, cbFrame);
+
+ Log2(("IntNetRingWriteFrame: offWriteCom: %#x -> %#x (2)\n", pRingBuf->offWriteCom, offNew));
+ ASMAtomicWriteU32(&pRingBuf->offWriteCom, offNew);
+ STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame);
+ STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames);
+ return VINF_SUCCESS;
+ }
+ }
+ /*
+ * The reader is ahead of the writer, try fit it into that space.
+ */
+ else if (offRead - offWriteInt > cb + sizeof(INTNETHDR)) /* not >= ! */
+ {
+ uint32_t offNew = offWriteInt + cb + sizeof(INTNETHDR);
+ if (RT_UNLIKELY(!ASMAtomicCmpXchgU32(&pRingBuf->offWriteInt, offNew, offWriteInt)))
+ return VERR_WRONG_ORDER; /* race */
+ Log2(("IntNetRingWriteFrame: offWriteInt: %#x -> %#x (3)\n", offWriteInt, offNew));
+
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offWriteInt);
+ pHdr->u16Type = INTNETHDR_TYPE_FRAME;
+ pHdr->cbFrame = (uint16_t)cbFrame; Assert(pHdr->cbFrame == cbFrame);
+ pHdr->offFrame = sizeof(INTNETHDR);
+
+ memcpy(pHdr + 1, pvFrame, cbFrame);
+
+ Log2(("IntNetRingWriteFrame: offWriteCom: %#x -> %#x (3)\n", pRingBuf->offWriteCom, offNew));
+ ASMAtomicWriteU32(&pRingBuf->offWriteCom, offNew);
+ STAM_REL_COUNTER_ADD(&pRingBuf->cbStatWritten, cbFrame);
+ STAM_REL_COUNTER_INC(&pRingBuf->cStatFrames);
+ return VINF_SUCCESS;
+ }
+
+ /* (it didn't fit) */
+ STAM_REL_COUNTER_INC(&pRingBuf->cOverflows);
+ return VERR_BUFFER_OVERFLOW;
+}
+
+
+/**
+ * Reads the next frame in the buffer and moves the read cursor past it.
+ *
+ * @returns Size of the frame in bytes. 0 is returned if nothing in the buffer.
+ * @param pRingBuff The ring buffer to read from.
+ * @param pvFrameDst Where to put the frame. The caller is responsible for
+ * ensuring that there is sufficient space for the frame.
+ *
+ * @deprecated Bad interface, do NOT use it! Only for tstIntNetR0.
+ */
+DECLINLINE(uint32_t) IntNetRingReadAndSkipFrame(PINTNETRINGBUF pRingBuf, void *pvFrameDst)
+{
+ INTNETRINGBUF_ASSERT_SANITY(pRingBuf);
+
+ uint32_t offRead = ASMAtomicUoReadU32(&pRingBuf->offReadX);
+ uint32_t const offWriteCom = ASMAtomicUoReadU32(&pRingBuf->offWriteCom);
+ if (offRead == offWriteCom)
+ return 0;
+
+ PINTNETHDR pHdr = (PINTNETHDR)((uint8_t *)pRingBuf + offRead);
+ INTNETHDR_ASSERT_SANITY(pHdr, pRingBuf);
+
+ uint32_t const cbFrame = pHdr->cbFrame;
+ int32_t const offFrame = pHdr->offFrame;
+ const void *pvFrameSrc = (uint8_t *)pHdr + offFrame;
+ memcpy(pvFrameDst, pvFrameSrc, cbFrame);
+#ifdef INTNET_POISON_READ_FRAMES
+ memset((void *)pvFrameSrc, 0xfe, RT_ALIGN_32(cbFrame, INTNETHDR_ALIGNMENT));
+ memset(pHdr, 0xef, sizeof(*pHdr));
+#endif
+
+ /* skip the frame */
+ offRead += offFrame + cbFrame;
+ offRead = RT_ALIGN_32(offRead, INTNETHDR_ALIGNMENT);
+ Assert(offRead <= pRingBuf->offEnd && offRead >= pRingBuf->offStart);
+ if (offRead >= pRingBuf->offEnd)
+ offRead = pRingBuf->offStart;
+ ASMAtomicWriteU32(&pRingBuf->offReadX, offRead);
+ return cbFrame;
+}
+
+
+/**
+ * Initializes a buffer structure.
+ *
+ * @param pIntBuf The internal networking interface buffer. This
+ * expected to be cleared prior to calling this
+ * function.
+ * @param cbBuf The size of the whole buffer.
+ * @param cbRecv The receive size.
+ * @param cbSend The send size.
+ */
+DECLINLINE(void) IntNetBufInit(PINTNETBUF pIntBuf, uint32_t cbBuf, uint32_t cbRecv, uint32_t cbSend)
+{
+ AssertCompileSizeAlignment(INTNETBUF, INTNETHDR_ALIGNMENT);
+ AssertCompileSizeAlignment(INTNETBUF, INTNETRINGBUF_ALIGNMENT);
+ Assert(cbBuf >= sizeof(INTNETBUF) + cbRecv + cbSend);
+ Assert(RT_ALIGN_32(cbRecv, INTNETRINGBUF_ALIGNMENT) == cbRecv);
+ Assert(RT_ALIGN_32(cbSend, INTNETRINGBUF_ALIGNMENT) == cbSend);
+ Assert(ASMMemIsAll8(pIntBuf, cbBuf, '\0') == NULL);
+
+ pIntBuf->u32Magic = INTNETBUF_MAGIC;
+ pIntBuf->cbBuf = cbBuf;
+ pIntBuf->cbRecv = cbRecv;
+ pIntBuf->cbSend = cbSend;
+
+ /* receive ring buffer. */
+ uint32_t offBuf = RT_ALIGN_32(sizeof(INTNETBUF), INTNETRINGBUF_ALIGNMENT) - RT_OFFSETOF(INTNETBUF, Recv);
+ pIntBuf->Recv.offStart = offBuf;
+ pIntBuf->Recv.offReadX = offBuf;
+ pIntBuf->Recv.offWriteInt = offBuf;
+ pIntBuf->Recv.offWriteCom = offBuf;
+ pIntBuf->Recv.offEnd = offBuf + cbRecv;
+
+ /* send ring buffer. */
+ offBuf += cbRecv + RT_OFFSETOF(INTNETBUF, Recv) - RT_OFFSETOF(INTNETBUF, Send);
+ pIntBuf->Send.offStart = offBuf;
+ pIntBuf->Send.offReadX = offBuf;
+ pIntBuf->Send.offWriteCom = offBuf;
+ pIntBuf->Send.offWriteInt = offBuf;
+ pIntBuf->Send.offEnd = offBuf + cbSend;
+ Assert(cbBuf >= offBuf + cbSend);
+}
+
+#endif /* __cplusplus */
+
+#endif
+
diff --git a/include/VBox/log.h b/include/VBox/log.h
new file mode 100644
index 00000000..05d53b7b
--- /dev/null
+++ b/include/VBox/log.h
@@ -0,0 +1,557 @@
+/** @file
+ * VirtualBox - Logging.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_log_h
+#define ___VBox_log_h
+
+/*
+ * Set the default loggroup.
+ */
+#ifndef LOG_GROUP
+# define LOG_GROUP LOG_GROUP_DEFAULT
+#endif
+
+#include <iprt/log.h>
+
+
+/** @defgroup grp_rt_vbox_log VirtualBox Logging
+ * @ingroup grp_rt_vbox
+ * @{
+ */
+
+/** PC port for debug output */
+#define RTLOG_DEBUG_PORT 0x504
+
+/**
+ * VirtualBox Logging Groups.
+ * (Remember to update LOGGROUP_NAMES!)
+ *
+ * @remark It should be pretty obvious, but just to have
+ * mentioned it, the values are sorted alphabetically (using the
+ * english alphabet) except for _DEFAULT which is always first.
+ *
+ * If anyone might be wondering what the alphabet looks like:
+ * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _
+ */
+typedef enum LOGGROUP
+{
+ /** The default VBox group. */
+ LOG_GROUP_DEFAULT = RTLOGGROUP_FIRST_USER,
+ /** Auto-logon group. */
+ LOG_GROUP_AUTOLOGON,
+ /** CFGM group. */
+ LOG_GROUP_CFGM,
+ /** CPUM group. */
+ LOG_GROUP_CPUM,
+ /** CSAM group. */
+ LOG_GROUP_CSAM,
+ /** Debug Console group. */
+ LOG_GROUP_DBGC,
+ /** DBGF group. */
+ LOG_GROUP_DBGF,
+ /** DBGF info group. */
+ LOG_GROUP_DBGF_INFO,
+ /** The debugger gui. */
+ LOG_GROUP_DBGG,
+ /** Generic Device group. */
+ LOG_GROUP_DEV,
+ /** ACPI Device group. */
+ LOG_GROUP_DEV_ACPI,
+ /** AHCI Device group. */
+ LOG_GROUP_DEV_AHCI,
+ /** APIC Device group. */
+ LOG_GROUP_DEV_APIC,
+ /** Audio Device group. */
+ LOG_GROUP_DEV_AUDIO,
+ /** BusLogic SCSI host adapter group. */
+ LOG_GROUP_DEV_BUSLOGIC,
+ /** DMA Controller group. */
+ LOG_GROUP_DEV_DMA,
+ /** Gigabit Ethernet Device group. */
+ LOG_GROUP_DEV_E1000,
+ /** Extensible Firmware Interface Device group. */
+ LOG_GROUP_DEV_EFI,
+ /** Floppy Controller Device group. */
+ LOG_GROUP_DEV_FDC,
+ /** High Precision Event Timer Device group. */
+ LOG_GROUP_DEV_HPET,
+ /** IDE Device group. */
+ LOG_GROUP_DEV_IDE,
+ /** The internal networking IP stack Device group. */
+ LOG_GROUP_DEV_INIP,
+ /** KeyBoard Controller Device group. */
+ LOG_GROUP_DEV_KBD,
+ /** Low Pin Count Device group. */
+ LOG_GROUP_DEV_LPC,
+ /** LsiLogic SCSI controller Device group. */
+ LOG_GROUP_DEV_LSILOGICSCSI,
+ /** NE2000 Device group. */
+ LOG_GROUP_DEV_NE2000,
+ /** Parallel Device group */
+ LOG_GROUP_DEV_PARALLEL,
+ /** PC Device group. */
+ LOG_GROUP_DEV_PC,
+ /** PC Architecture Device group. */
+ LOG_GROUP_DEV_PC_ARCH,
+ /** PC BIOS Device group. */
+ LOG_GROUP_DEV_PC_BIOS,
+ /** PCI Device group. */
+ LOG_GROUP_DEV_PCI,
+ /** PCI Raw Device group. */
+ LOG_GROUP_DEV_PCI_RAW,
+ /** PCNet Device group. */
+ LOG_GROUP_DEV_PCNET,
+ /** PIC Device group. */
+ LOG_GROUP_DEV_PIC,
+ /** PIT Device group. */
+ LOG_GROUP_DEV_PIT,
+ /** RTC Device group. */
+ LOG_GROUP_DEV_RTC,
+ /** Serial Device group */
+ LOG_GROUP_DEV_SERIAL,
+ /** System Management Controller Device group. */
+ LOG_GROUP_DEV_SMC,
+ /** USB Device group. */
+ LOG_GROUP_DEV_USB,
+ /** VGA Device group. */
+ LOG_GROUP_DEV_VGA,
+ /** Virtio PCI Device group. */
+ LOG_GROUP_DEV_VIRTIO,
+ /** Virtio Network Device group. */
+ LOG_GROUP_DEV_VIRTIO_NET,
+ /** VMM Device group. */
+ LOG_GROUP_DEV_VMM,
+ /** VMM Device group for backdoor logging. */
+ LOG_GROUP_DEV_VMM_BACKDOOR,
+ /** VMM Device group for logging guest backdoor logging to stderr. */
+ LOG_GROUP_DEV_VMM_STDERR,
+ /** Disassembler group. */
+ LOG_GROUP_DIS,
+ /** Generic driver group. */
+ LOG_GROUP_DRV,
+ /** ACPI driver group */
+ LOG_GROUP_DRV_ACPI,
+ /** Block driver group. */
+ LOG_GROUP_DRV_BLOCK,
+ /** Char driver group. */
+ LOG_GROUP_DRV_CHAR,
+ /** Disk integrity driver group. */
+ LOG_GROUP_DRV_DISK_INTEGRITY,
+ /** Video Display driver group. */
+ LOG_GROUP_DRV_DISPLAY,
+ /** Floppy media driver group. */
+ LOG_GROUP_DRV_FLOPPY,
+ /** Host Base block driver group. */
+ LOG_GROUP_DRV_HOST_BASE,
+ /** Host DVD block driver group. */
+ LOG_GROUP_DRV_HOST_DVD,
+ /** Host floppy block driver group. */
+ LOG_GROUP_DRV_HOST_FLOPPY,
+ /** Host Parallel Driver group */
+ LOG_GROUP_DRV_HOST_PARALLEL,
+ /** Host Serial Driver Group */
+ LOG_GROUP_DRV_HOST_SERIAL,
+ /** The internal networking transport driver group. */
+ LOG_GROUP_DRV_INTNET,
+ /** ISO (CD/DVD) media driver group. */
+ LOG_GROUP_DRV_ISO,
+ /** Keyboard Queue driver group. */
+ LOG_GROUP_DRV_KBD_QUEUE,
+ /** lwIP IP stack driver group. */
+ LOG_GROUP_DRV_LWIP,
+ /** Video Miniport driver group. */
+ LOG_GROUP_DRV_MINIPORT,
+ /** Mouse driver group. */
+ LOG_GROUP_DRV_MOUSE,
+ /** Mouse Queue driver group. */
+ LOG_GROUP_DRV_MOUSE_QUEUE,
+ /** Named Pipe stream driver group. */
+ LOG_GROUP_DRV_NAMEDPIPE,
+ /** NAT network transport driver group */
+ LOG_GROUP_DRV_NAT,
+ /** Raw image driver group */
+ LOG_GROUP_DRV_RAW_IMAGE,
+ /** SCSI driver group. */
+ LOG_GROUP_DRV_SCSI,
+ /** Host SCSI driver group. */
+ LOG_GROUP_DRV_SCSIHOST,
+ /** Async transport driver group */
+ LOG_GROUP_DRV_TRANSPORT_ASYNC,
+ /** TUN network transport driver group */
+ LOG_GROUP_DRV_TUN,
+ /** UDP tunnet network transport driver group. */
+ LOG_GROUP_DRV_UDPTUNNEL,
+ /** USB Proxy driver group. */
+ LOG_GROUP_DRV_USBPROXY,
+ /** VBoxHDD media driver group. */
+ LOG_GROUP_DRV_VBOXHDD,
+ /** VBox HDD container media driver group. */
+ LOG_GROUP_DRV_VD,
+ /** Virtual Switch transport driver group */
+ LOG_GROUP_DRV_VSWITCH,
+ /** VUSB driver group */
+ LOG_GROUP_DRV_VUSB,
+ /** EM group. */
+ LOG_GROUP_EM,
+ /** FTM group. */
+ LOG_GROUP_FTM,
+ /** GMM group. */
+ LOG_GROUP_GMM,
+ /** Guest control. */
+ LOG_GROUP_GUEST_CONTROL,
+ /** GUI group. */
+ LOG_GROUP_GUI,
+ /** GVMM group. */
+ LOG_GROUP_GVMM,
+ /** HGCM group */
+ LOG_GROUP_HGCM,
+ /** HGSMI group */
+ LOG_GROUP_HGSMI,
+ /** HWACCM group. */
+ LOG_GROUP_HWACCM,
+ /** IEM group. */
+ LOG_GROUP_IEM,
+ /** IOM group. */
+ LOG_GROUP_IOM,
+ /** XPCOM IPC group. */
+ LOG_GROUP_IPC,
+ /** Main group. */
+ LOG_GROUP_MAIN,
+ /** Misc. group intended for external use only. */
+ LOG_GROUP_MISC,
+ /** MM group. */
+ LOG_GROUP_MM,
+ /** MM group. */
+ LOG_GROUP_MM_HEAP,
+ /** MM group. */
+ LOG_GROUP_MM_HYPER,
+ /** MM Hypervisor Heap group. */
+ LOG_GROUP_MM_HYPER_HEAP,
+ /** MM Physical/Ram group. */
+ LOG_GROUP_MM_PHYS,
+ /** MM Page pool group. */
+ LOG_GROUP_MM_POOL,
+ /** The NAT service group */
+ LOG_GROUP_NAT_SERVICE,
+ /** The network adaptor driver group. */
+ LOG_GROUP_NET_ADP_DRV,
+ /** The network filter driver group. */
+ LOG_GROUP_NET_FLT_DRV,
+ /** The common network service group */
+ LOG_GROUP_NET_SERVICE,
+ /** Network traffic shaper driver group. */
+ LOG_GROUP_NET_SHAPER,
+ /** PATM group. */
+ LOG_GROUP_PATM,
+ /** PDM group. */
+ LOG_GROUP_PDM,
+ /** PDM Async completion group. */
+ LOG_GROUP_PDM_ASYNC_COMPLETION,
+ /** PDM Block cache group. */
+ LOG_GROUP_PDM_BLK_CACHE,
+ /** PDM Device group. */
+ LOG_GROUP_PDM_DEVICE,
+ /** PDM Driver group. */
+ LOG_GROUP_PDM_DRIVER,
+ /** PDM Loader group. */
+ LOG_GROUP_PDM_LDR,
+ /** PDM Loader group. */
+ LOG_GROUP_PDM_QUEUE,
+ /** PGM group. */
+ LOG_GROUP_PGM,
+ /** PGM dynamic mapping group. */
+ LOG_GROUP_PGM_DYNMAP,
+ /** PGM physical group. */
+ LOG_GROUP_PGM_PHYS,
+ /** PGM physical access group. */
+ LOG_GROUP_PGM_PHYS_ACCESS,
+ /** PGM shadow page pool group. */
+ LOG_GROUP_PGM_POOL,
+ /** PGM shared paging group. */
+ LOG_GROUP_PGM_SHARED,
+ /** REM group. */
+ LOG_GROUP_REM,
+ /** REM disassembly handler group. */
+ LOG_GROUP_REM_DISAS,
+ /** REM access handler group. */
+ LOG_GROUP_REM_HANDLER,
+ /** REM I/O port access group. */
+ LOG_GROUP_REM_IOPORT,
+ /** REM MMIO access group. */
+ LOG_GROUP_REM_MMIO,
+ /** REM Printf. */
+ LOG_GROUP_REM_PRINTF,
+ /** REM running group. */
+ LOG_GROUP_REM_RUN,
+ /** SELM group. */
+ LOG_GROUP_SELM,
+ /** Shared clipboard host service group. */
+ LOG_GROUP_SHARED_CLIPBOARD,
+ /** Chromium OpenGL host service group. */
+ LOG_GROUP_SHARED_CROPENGL,
+ /** Shared folders host service group. */
+ LOG_GROUP_SHARED_FOLDERS,
+ /** OpenGL host service group. */
+ LOG_GROUP_SHARED_OPENGL,
+ /** The internal networking service group. */
+ LOG_GROUP_SRV_INTNET,
+ /** SSM group. */
+ LOG_GROUP_SSM,
+ /** STAM group. */
+ LOG_GROUP_STAM,
+ /** SUP group. */
+ LOG_GROUP_SUP,
+ /** SUPport driver group. */
+ LOG_GROUP_SUP_DRV,
+ /** TM group. */
+ LOG_GROUP_TM,
+ /** TRPM group. */
+ LOG_GROUP_TRPM,
+ /** USB cardreader group. */
+ LOG_GROUP_USB_CARDREADER,
+ /** USB driver group. */
+ LOG_GROUP_USB_DRV,
+ /** USBFilter group. */
+ LOG_GROUP_USB_FILTER,
+ /** USB keyboard device group. */
+ LOG_GROUP_USB_KBD,
+ /** MSD USB device group. */
+ LOG_GROUP_USB_MSD,
+ /** USB webcam. */
+ LOG_GROUP_USB_WEBCAM,
+ /** Generic virtual disk layer. */
+ LOG_GROUP_VD,
+ /** DMG virtual disk backend. */
+ LOG_GROUP_VD_DMG,
+ /** iSCSI virtual disk backend. */
+ LOG_GROUP_VD_ISCSI,
+ /** Parallels HDD virtual disk backend. */
+ LOG_GROUP_VD_PARALLELS,
+ /** QCOW virtual disk backend. */
+ LOG_GROUP_VD_QCOW,
+ /** QED virtual disk backend. */
+ LOG_GROUP_VD_QED,
+ /** Raw virtual disk backend. */
+ LOG_GROUP_VD_RAW,
+ /** VDI virtual disk backend. */
+ LOG_GROUP_VD_VDI,
+ /** VHD virtual disk backend. */
+ LOG_GROUP_VD_VHD,
+ /** VMDK virtual disk backend. */
+ LOG_GROUP_VD_VMDK,
+ /** VM group. */
+ LOG_GROUP_VM,
+ /** VMM group. */
+ LOG_GROUP_VMM,
+ /** VRDE group */
+ LOG_GROUP_VRDE,
+ /** VRDP group */
+ LOG_GROUP_VRDP,
+ /** VSCSI group */
+ LOG_GROUP_VSCSI,
+ /** Webservice group. */
+ LOG_GROUP_WEBSERVICE
+ /* !!!ALPHABETICALLY!!! */
+} VBOX_LOGGROUP;
+
+
+/** @def VBOX_LOGGROUP_NAMES
+ * VirtualBox Logging group names.
+ *
+ * Must correspond 100% to LOGGROUP!
+ * Don't forget commas!
+ *
+ * @remark It should be pretty obvious, but just to have
+ * mentioned it, the values are sorted alphabetically (using the
+ * english alphabet) except for _DEFAULT which is always first.
+ *
+ * If anyone might be wondering what the alphabet looks like:
+ * a b c d e f g h i j k l m n o p q r s t u v w x y z
+ */
+#define VBOX_LOGGROUP_NAMES \
+{ \
+ RT_LOGGROUP_NAMES, \
+ "DEFAULT", \
+ "AUTOLOGON", \
+ "CFGM", \
+ "CPUM", \
+ "CSAM", \
+ "DBGC", \
+ "DBGF", \
+ "DBGF_INFO", \
+ "DBGG", \
+ "DEV", \
+ "DEV_ACPI", \
+ "DEV_AHCI", \
+ "DEV_APIC", \
+ "DEV_AUDIO", \
+ "DEV_BUSLOGIC", \
+ "DEV_DMA", \
+ "DEV_E1000", \
+ "DEV_EFI", \
+ "DEV_FDC", \
+ "DEV_HPET", \
+ "DEV_IDE", \
+ "DEV_INIP", \
+ "DEV_KBD", \
+ "DEV_LPC", \
+ "DEV_LSILOGICSCSI", \
+ "DEV_NE2000", \
+ "DEV_PARALLEL", \
+ "DEV_PC", \
+ "DEV_PC_ARCH", \
+ "DEV_PC_BIOS", \
+ "DEV_PCI", \
+ "DEV_PCI_RAW", \
+ "DEV_PCNET", \
+ "DEV_PIC", \
+ "DEV_PIT", \
+ "DEV_RTC", \
+ "DEV_SERIAL", \
+ "DEV_SMC", \
+ "DEV_USB", \
+ "DEV_VGA", \
+ "DEV_VIRTIO", \
+ "DEV_VIRTIO_NET", \
+ "DEV_VMM", \
+ "DEV_VMM_BACKDOOR", \
+ "DEV_VMM_STDERR",\
+ "DIS", \
+ "DRV", \
+ "DRV_ACPI", \
+ "DRV_BLOCK", \
+ "DRV_CHAR", \
+ "DRV_DISK_INTEGRITY", \
+ "DRV_DISPLAY", \
+ "DRV_FLOPPY", \
+ "DRV_HOST_BASE", \
+ "DRV_HOST_DVD", \
+ "DRV_HOST_FLOPPY", \
+ "DRV_HOST_PARALLEL", \
+ "DRV_HOST_SERIAL", \
+ "DRV_INTNET", \
+ "DRV_ISO", \
+ "DRV_KBD_QUEUE", \
+ "DRV_LWIP", \
+ "DRV_MINIPORT", \
+ "DRV_MOUSE", \
+ "DRV_MOUSE_QUEUE", \
+ "DRV_NAMEDPIPE", \
+ "DRV_NAT", \
+ "DRV_RAW_IMAGE", \
+ "DRV_SCSI", \
+ "DRV_SCSIHOST", \
+ "DRV_TRANSPORT_ASYNC", \
+ "DRV_TUN", \
+ "DRV_UDPTUNNEL", \
+ "DRV_USBPROXY", \
+ "DRV_VBOXHDD", \
+ "DRV_VD", \
+ "DRV_VSWITCH", \
+ "DRV_VUSB", \
+ "EM", \
+ "FTM", \
+ "GMM", \
+ "GUEST_CONTROL", \
+ "GUI", \
+ "GVMM", \
+ "HGCM", \
+ "HGSMI", \
+ "HWACCM", \
+ "IEM", \
+ "IOM", \
+ "IPC", \
+ "MAIN", \
+ "MISC", \
+ "MM", \
+ "MM_HEAP", \
+ "MM_HYPER", \
+ "MM_HYPER_HEAP",\
+ "MM_PHYS", \
+ "MM_POOL", \
+ "NAT_SERVICE", \
+ "NET_ADP_DRV", \
+ "NET_FLT_DRV", \
+ "NET_SERVICE", \
+ "NET_SHAPER", \
+ "PATM", \
+ "PDM", \
+ "PDM_ASYNC_COMPLETION", \
+ "PDM_BLK_CACHE", \
+ "PDM_DEVICE", \
+ "PDM_DRIVER", \
+ "PDM_LDR", \
+ "PDM_QUEUE", \
+ "PGM", \
+ "PGM_DYNMAP", \
+ "PGM_PHYS", \
+ "PGM_PHYS_ACCESS",\
+ "PGM_POOL", \
+ "PGM_SHARED", \
+ "REM", \
+ "REM_DISAS", \
+ "REM_HANDLER", \
+ "REM_IOPORT", \
+ "REM_MMIO", \
+ "REM_PRINTF", \
+ "REM_RUN", \
+ "SELM", \
+ "SHARED_CLIPBOARD",\
+ "SHARED_CROPENGL",\
+ "SHARED_FOLDERS",\
+ "SHARED_OPENGL",\
+ "SRV_INTNET", \
+ "SSM", \
+ "STAM", \
+ "SUP", \
+ "SUP_DRV", \
+ "TM", \
+ "TRPM", \
+ "USB_CARDREADER",\
+ "USB_DRV", \
+ "USB_FILTER", \
+ "USB_KBD", \
+ "USB_MSD", \
+ "USB_WEBCAM", \
+ "VD", \
+ "VD_DMG", \
+ "VD_ISCSI", \
+ "VD_PARALLELS", \
+ "VD_QCOW", \
+ "VD_QED", \
+ "VD_RAW", \
+ "VD_VDI", \
+ "VD_VHD", \
+ "VD_VMDK", \
+ "VM", \
+ "VMM", \
+ "VRDE", \
+ "VRDP", \
+ "VSCSI", \
+ "WEBSERVICE", \
+}
+
+/** @} */
+#endif
diff --git a/include/VBox/msi.h b/include/VBox/msi.h
new file mode 100644
index 00000000..7bfc4222
--- /dev/null
+++ b/include/VBox/msi.h
@@ -0,0 +1,121 @@
+/** @file
+ * MSI - Message signalled interrupts support.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_msi_h
+#define ___VBox_msi_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/assert.h>
+
+#include <VBox/pci.h>
+
+/* Constants for Intel APIC MSI messages */
+#define VBOX_MSI_DATA_VECTOR_SHIFT 0
+#define VBOX_MSI_DATA_VECTOR_MASK 0x000000ff
+#define VBOX_MSI_DATA_VECTOR(v) (((v) << VBOX_MSI_DATA_VECTOR_SHIFT) & \
+ VBOX_MSI_DATA_VECTOR_MASK)
+#define VBOX_MSI_DATA_DELIVERY_MODE_SHIFT 8
+#define VBOX_MSI_DATA_DELIVERY_FIXED (0 << VBOX_MSI_DATA_DELIVERY_MODE_SHIFT)
+#define VBOX_MSI_DATA_DELIVERY_LOWPRI (1 << VBOX_MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define VBOX_MSI_DATA_LEVEL_SHIFT 14
+#define VBOX_MSI_DATA_LEVEL_DEASSERT (0 << VBOX_MSI_DATA_LEVEL_SHIFT)
+#define VBOX_MSI_DATA_LEVEL_ASSERT (1 << VBOX_MSI_DATA_LEVEL_SHIFT)
+
+#define VBOX_MSI_DATA_TRIGGER_SHIFT 15
+#define VBOX_MSI_DATA_TRIGGER_EDGE (0 << VBOX_MSI_DATA_TRIGGER_SHIFT)
+#define VBOX_MSI_DATA_TRIGGER_LEVEL (1 << VBOX_MSI_DATA_TRIGGER_SHIFT)
+
+/**
+ * MSI region, actually same as LAPIC MMIO region, but listens on bus,
+ * not CPU, accesses.
+ */
+#define VBOX_MSI_ADDR_BASE 0xfee00000
+#define VBOX_MSI_ADDR_SIZE 0x100000
+
+#define VBOX_MSI_ADDR_DEST_MODE_SHIFT 2
+#define VBOX_MSI_ADDR_DEST_MODE_PHYSICAL (0 << VBOX_MSI_ADDR_DEST_MODE_SHIFT)
+#define VBOX_MSI_ADDR_DEST_MODE_LOGICAL (1 << VBOX_MSI_ADDR_DEST_MODE_SHIFT)
+
+#define VBOX_MSI_ADDR_REDIRECTION_SHIFT 3
+#define VBOX_MSI_ADDR_REDIRECTION_CPU (0 << VBOX_MSI_ADDR_REDIRECTION_SHIFT)
+ /* dedicated cpu */
+#define VBOX_MSI_ADDR_REDIRECTION_LOWPRI (1 << VBOX_MSI_ADDR_REDIRECTION_SHIFT)
+ /* lowest priority */
+
+#define VBOX_MSI_ADDR_DEST_ID_SHIFT 12
+#define VBOX_MSI_ADDR_DEST_ID_MASK 0x00ffff0
+#define VBOX_MSI_ADDR_DEST_ID(dest) (((dest) << VBOX_MSI_ADDR_DEST_ID_SHIFT) & \
+ VBOX_MSI_ADDR_DEST_ID_MASK)
+#define VBOX_MSI_ADDR_EXT_DEST_ID(dest) ((dest) & 0xffffff00)
+
+#define VBOX_MSI_ADDR_IR_EXT_INT (1 << 4)
+#define VBOX_MSI_ADDR_IR_SHV (1 << 3)
+#define VBOX_MSI_ADDR_IR_INDEX1(index) ((index & 0x8000) >> 13)
+#define VBOX_MSI_ADDR_IR_INDEX2(index) ((index & 0x7fff) << 5)
+
+/* Maximum number of vectors, per device/function */
+#define VBOX_MSI_MAX_ENTRIES 32
+
+/* Offsets in MSI PCI capability structure (VBOX_PCI_CAP_ID_MSI) */
+#define VBOX_MSI_CAP_MESSAGE_CONTROL 0x02
+#define VBOX_MSI_CAP_MESSAGE_ADDRESS_32 0x04
+#define VBOX_MSI_CAP_MESSAGE_ADDRESS_LO 0x04
+#define VBOX_MSI_CAP_MESSAGE_ADDRESS_HI 0x08
+#define VBOX_MSI_CAP_MESSAGE_DATA_32 0x08
+#define VBOX_MSI_CAP_MESSAGE_DATA_64 0x0c
+#define VBOX_MSI_CAP_MASK_BITS_32 0x0c
+#define VBOX_MSI_CAP_PENDING_BITS_32 0x10
+#define VBOX_MSI_CAP_MASK_BITS_64 0x10
+#define VBOX_MSI_CAP_PENDING_BITS_64 0x14
+
+/* We implement MSI with per-vector masking */
+#define VBOX_MSI_CAP_SIZE_32 0x14
+#define VBOX_MSI_CAP_SIZE_64 0x18
+
+/**
+ * MSI-X different from MSI by the fact that dedicated physical page
+ * (in device memory) is assigned for MSI-X table, and Pending Bit Array (PBA),
+ * which is recommended to be separated from the main table by at least 2K.
+ */
+/* Size of a MSI-X page */
+#define VBOX_MSIX_PAGE_SIZE 0x1000
+/* Pending interrupts (PBA) */
+#define VBOX_MSIX_PAGE_PENDING (VBOX_MSIX_PAGE_SIZE / 2)
+/* Maximum number of vectors, per device/function */
+#define VBOX_MSIX_MAX_ENTRIES 32
+#define VBOX_MSIX_ENTRY_SIZE 16
+/* Size of MSI-X PCI capability */
+#define VBOX_MSIX_CAP_SIZE 12
+/* Offsets in MSI-X PCI capability structure (VBOX_PCI_CAP_ID_MSIX) */
+#define VBOX_MSIX_CAP_MESSAGE_CONTROL 0x02
+#define VBOX_MSIX_TABLE_BIROFFSET 0x04
+#define VBOX_MSIX_PBA_BIROFFSET 0x08
+/* Size of single MSI-X table entry */
+#define VBOX_MSIX_ENTRY_SIZE 16
+
+
+#endif
diff --git a/include/VBox/nasm.mac b/include/VBox/nasm.mac
new file mode 100644
index 00000000..416a72f6
--- /dev/null
+++ b/include/VBox/nasm.mac
@@ -0,0 +1,34 @@
+;; @file
+; Global NASM macros
+;
+; @deprecated Use VBox/asmdefs.mac
+;
+
+;
+; Copyright (C) 2006-2007 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; 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 __VBox_nasm_mac__
+%define __VBox_nasm_mac__
+
+%include "VBox/asmdefs.mac"
+
+%endif
+
diff --git a/include/VBox/ostypes.h b/include/VBox/ostypes.h
new file mode 100644
index 00000000..cbc0b739
--- /dev/null
+++ b/include/VBox/ostypes.h
@@ -0,0 +1,150 @@
+/** @file
+ * VirtualBox - Global Guest Operating System definition.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_ostypes_h
+#define ___VBox_ostypes_h
+
+#include <iprt/cdefs.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Global list of guest operating system types.
+ *
+ * They are grouped into families. A family identifer is always has
+ * mod 0x10000 == 0. New entries can be added, however other components
+ * depend on the values (e.g. the Qt GUI and guest additions) so the
+ * existing values MUST stay the same.
+ *
+ * Note: distinguish between 32 & 64 bits guest OSes by checking bit 8 (mod 0x100)
+ */
+typedef enum VBOXOSTYPE
+{
+ VBOXOSTYPE_Unknown = 0,
+ VBOXOSTYPE_DOS = 0x10000,
+ VBOXOSTYPE_Win31 = 0x15000,
+ VBOXOSTYPE_Win9x = 0x20000,
+ VBOXOSTYPE_Win95 = 0x21000,
+ VBOXOSTYPE_Win98 = 0x22000,
+ VBOXOSTYPE_WinMe = 0x23000,
+ VBOXOSTYPE_WinNT = 0x30000,
+ VBOXOSTYPE_WinNT4 = 0x31000,
+ VBOXOSTYPE_Win2k = 0x32000,
+ VBOXOSTYPE_WinXP = 0x33000,
+ VBOXOSTYPE_WinXP_x64 = 0x33100,
+ VBOXOSTYPE_Win2k3 = 0x34000,
+ VBOXOSTYPE_Win2k3_x64 = 0x34100,
+ VBOXOSTYPE_WinVista = 0x35000,
+ VBOXOSTYPE_WinVista_x64 = 0x35100,
+ VBOXOSTYPE_Win2k8 = 0x36000,
+ VBOXOSTYPE_Win2k8_x64 = 0x36100,
+ VBOXOSTYPE_Win7 = 0x37000,
+ VBOXOSTYPE_Win7_x64 = 0x37100,
+ VBOXOSTYPE_Win8 = 0x38000,
+ VBOXOSTYPE_Win8_x64 = 0x38100,
+ VBOXOSTYPE_Win2k12_x64 = 0x39100,
+ VBOXOSTYPE_OS2 = 0x40000,
+ VBOXOSTYPE_OS2Warp3 = 0x41000,
+ VBOXOSTYPE_OS2Warp4 = 0x42000,
+ VBOXOSTYPE_OS2Warp45 = 0x43000,
+ VBOXOSTYPE_ECS = 0x44000,
+ VBOXOSTYPE_Linux = 0x50000,
+ VBOXOSTYPE_Linux_x64 = 0x50100,
+ VBOXOSTYPE_Linux22 = 0x51000,
+ VBOXOSTYPE_Linux24 = 0x52000,
+ VBOXOSTYPE_Linux24_x64 = 0x52100,
+ VBOXOSTYPE_Linux26 = 0x53000,
+ VBOXOSTYPE_Linux26_x64 = 0x53100,
+ VBOXOSTYPE_ArchLinux = 0x54000,
+ VBOXOSTYPE_ArchLinux_x64 = 0x54100,
+ VBOXOSTYPE_Debian = 0x55000,
+ VBOXOSTYPE_Debian_x64 = 0x55100,
+ VBOXOSTYPE_OpenSUSE = 0x56000,
+ VBOXOSTYPE_OpenSUSE_x64 = 0x56100,
+ VBOXOSTYPE_FedoraCore = 0x57000,
+ VBOXOSTYPE_FedoraCore_x64 = 0x57100,
+ VBOXOSTYPE_Gentoo = 0x58000,
+ VBOXOSTYPE_Gentoo_x64 = 0x58100,
+ VBOXOSTYPE_Mandriva = 0x59000,
+ VBOXOSTYPE_Mandriva_x64 = 0x59100,
+ VBOXOSTYPE_RedHat = 0x5A000,
+ VBOXOSTYPE_RedHat_x64 = 0x5A100,
+ VBOXOSTYPE_Turbolinux = 0x5B000,
+ VBOXOSTYPE_Turbolinux_x64 = 0x5B100,
+ VBOXOSTYPE_Ubuntu = 0x5C000,
+ VBOXOSTYPE_Ubuntu_x64 = 0x5C100,
+ VBOXOSTYPE_Xandros = 0x5D000,
+ VBOXOSTYPE_Xandros_x64 = 0x5D100,
+ VBOXOSTYPE_Oracle = 0x5E000,
+ VBOXOSTYPE_Oracle_x64 = 0x5E100,
+ VBOXOSTYPE_FreeBSD = 0x60000,
+ VBOXOSTYPE_FreeBSD_x64 = 0x60100,
+ VBOXOSTYPE_OpenBSD = 0x61000,
+ VBOXOSTYPE_OpenBSD_x64 = 0x61100,
+ VBOXOSTYPE_NetBSD = 0x62000,
+ VBOXOSTYPE_NetBSD_x64 = 0x62100,
+ VBOXOSTYPE_Netware = 0x70000,
+ VBOXOSTYPE_Solaris = 0x80000,
+ VBOXOSTYPE_Solaris_x64 = 0x80100,
+ VBOXOSTYPE_OpenSolaris = 0x81000,
+ VBOXOSTYPE_OpenSolaris_x64 = 0x81100,
+ VBOXOSTYPE_Solaris11_x64 = 0x82100,
+ VBOXOSTYPE_L4 = 0x90000,
+ VBOXOSTYPE_QNX = 0xA0000,
+ VBOXOSTYPE_MacOS = 0xB0000,
+ VBOXOSTYPE_MacOS_x64 = 0xB0100,
+ VBOXOSTYPE_JRockitVE = 0xC0000,
+/** The bit number which indicates 64-bit or 32-bit. */
+#define VBOXOSTYPE_x64_BIT 8
+ /** The mask which indicates 64-bit. */
+ VBOXOSTYPE_x64 = 1 << VBOXOSTYPE_x64_BIT,
+ /** The usual 32-bit hack. */
+ VBOXOSTYPE_32BIT_HACK = 0x7fffffff
+} VBOXOSTYPE;
+
+
+/**
+ * Global list of guest OS families.
+ */
+typedef enum VBOXOSFAMILY
+{
+ VBOXOSFAMILY_Unknown = 0,
+ VBOXOSFAMILY_Windows32 = 1,
+ VBOXOSFAMILY_Windows64 = 2,
+ VBOXOSFAMILY_Linux32 = 3,
+ VBOXOSFAMILY_Linux64 = 4,
+ VBOXOSFAMILY_FreeBSD32 = 5,
+ VBOXOSFAMILY_FreeBSD64 = 6,
+ VBOXOSFAMILY_Solaris32 = 7,
+ VBOXOSFAMILY_Solaris64 = 8,
+ VBOXOSFAMILY_MacOSX32 = 9,
+ VBOXOSFAMILY_MacOSX64 = 10,
+ /** The usual 32-bit hack. */
+ VBOXOSFAMILY_32BIT_HACK = 0x7fffffff
+} VBOXOSFAMILY;
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/param.h b/include/VBox/param.h
new file mode 100644
index 00000000..0f94967c
--- /dev/null
+++ b/include/VBox/param.h
@@ -0,0 +1,178 @@
+/** @file
+ * VirtualBox Parameter Definitions. (VMM,+)
+ *
+ * param.mac is generated from this file by running 'kmk incs' in the root.
+ */
+
+/*
+ * Copyright (C) 2006-2009 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 ___VBox_param_h
+#define ___VBox_param_h
+
+#include <iprt/param.h>
+#include <iprt/cdefs.h>
+
+
+/** @defgroup grp_vbox_param VBox Parameter Definition
+ * @{
+ */
+
+/** The maximum number of pages that can be allocated and mapped
+ * by various MM, PGM and SUP APIs. */
+#define VBOX_MAX_ALLOC_PAGE_COUNT (256U * _1M / PAGE_SIZE)
+
+/** @def VBOX_WITH_PAGE_SHARING
+ * Enables the page sharing code.
+ * @remarks This must match GMMR0Init; currently we only support page fusion on
+ * all 64-bit hosts except Mac OS X */
+#if ( HC_ARCH_BITS == 64 /* ASM-NOINC */ \
+ && (defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)) ) /* ASM-NOINC */ \
+ || defined(DOXYGEN_RUNNING) /* ASM-NOINC */
+# define VBOX_WITH_PAGE_SHARING /* ASM-NOINC */
+#endif /* ASM-NOINC */
+
+
+/** @defgroup grp_vbox_param_mm Memory Monitor Parameters
+ * @ingroup grp_vbox_param
+ * @{
+ */
+/** Initial address of Hypervisor Memory Area.
+ * MUST BE PAGE TABLE ALIGNED! */
+#define MM_HYPER_AREA_ADDRESS UINT32_C(0xa0000000)
+
+/** The max size of the hypervisor memory area. */
+#define MM_HYPER_AREA_MAX_SIZE (40U * _1M) /**< @todo Readjust when floating RAMRANGEs have been implemented. Used to be 20 * _1MB */
+
+/** Maximum number of bytes we can dynamically map into the hypervisor region.
+ * This must be a power of 2 number of pages!
+ */
+#define MM_HYPER_DYNAMIC_SIZE (16U * PAGE_SIZE)
+
+/** The minimum guest RAM size in bytes. */
+#define MM_RAM_MIN UINT32_C(0x00400000)
+/** The maximum guest RAM size in bytes. */
+#if HC_ARCH_BITS == 64
+# define MM_RAM_MAX UINT64_C(0x20000000000)
+#else
+# define MM_RAM_MAX UINT64_C(0x000E0000000)
+#endif
+/** The minimum guest RAM size in MBs. */
+#define MM_RAM_MIN_IN_MB UINT32_C(4)
+/** The maximum guest RAM size in MBs. */
+#if HC_ARCH_BITS == 64
+# define MM_RAM_MAX_IN_MB UINT32_C(2097152)
+#else
+# define MM_RAM_MAX_IN_MB UINT32_C(3584)
+#endif
+/** The default size of the below 4GB RAM hole. */
+#define MM_RAM_HOLE_SIZE_DEFAULT (512U * _1M)
+/** @} */
+
+
+/** @defgroup grp_vbox_param_pgm Page Manager Parameters
+ * @ingroup grp_vbox_param
+ * @{
+ */
+/** The number of handy pages.
+ * This should be a power of two. */
+#define PGM_HANDY_PAGES 128
+/** The threshold at which allocation of more handy pages is flagged. */
+#define PGM_HANDY_PAGES_SET_FF 32
+/** The threshold at which we will allocate more when in ring-3.
+ * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and
+ * PGM_HANDY_PAGES_MIN. */
+#define PGM_HANDY_PAGES_R3_ALLOC 8
+/** The threshold at which we will allocate more when in ring-0 or raw mode.
+ * The idea is that we should never go below this threshold while in ring-0 or
+ * raw mode because of PGM_HANDY_PAGES_RZ_TO_R3. However, should this happen and
+ * we are actually out of memory, we will have 8 page to get out of whatever
+ * code we're executing.
+ *
+ * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and
+ * PGM_HANDY_PAGES_MIN. */
+#define PGM_HANDY_PAGES_RZ_ALLOC 8
+/** The threshold at which we force return to R3 ASAP.
+ * The idea is that this should be large enough to get out of any code and up to
+ * the main EM loop when we are out of memory.
+ * This must be less or equal to PGM_HANDY_PAGES_MIN. */
+#define PGM_HANDY_PAGES_RZ_TO_R3 24
+/** The minimum number of handy pages (after allocation).
+ * This must be greater or equal to PGM_HANDY_PAGES_SET_FF.
+ * Another name would be PGM_HANDY_PAGES_EXTRA_RESERVATION or _PARANOIA. :-) */
+#define PGM_HANDY_PAGES_MIN 32
+/** @} */
+
+
+/** @defgroup grp_vbox_param_vmm VMM Parameters
+ * @ingroup grp_vbox_param
+ * @{
+ */
+/** VMM stack size. */
+#ifdef RT_OS_DARWIN
+# define VMM_STACK_SIZE 16384U
+#else
+# define VMM_STACK_SIZE 8192U
+#endif
+/** Min number of Virtual CPUs. */
+#define VMM_MIN_CPU_COUNT 1
+/** Max number of Virtual CPUs. */
+#define VMM_MAX_CPU_COUNT 64
+
+/** @} */
+
+
+/** @defgroup grp_vbox_pci PCI Identifiers
+ * @{ */
+/** VirtualBox PCI vendor ID. */
+#define VBOX_PCI_VENDORID (0x80ee)
+
+/** @name VirtualBox graphics card identifiers
+ * @{ */
+#define VBOX_VENDORID VBOX_PCI_VENDORID /**< @todo wonderful choice of name! Please squeeze a _VGA_ or something in there, please. */
+#define VBOX_DEVICEID (0xbeef) /**< @todo ditto. */
+#define VBOX_VESA_VENDORID VBOX_PCI_VENDORID
+#define VBOX_VESA_DEVICEID (0xbeef)
+/** @} */
+
+/** @name VMMDev PCI card identifiers
+ * @{ */
+#define VMMDEV_VENDORID VBOX_PCI_VENDORID
+#define VMMDEV_DEVICEID (0xcafe)
+/** @} */
+
+/** @} */
+
+
+/** @defgroup grp_vbox_param_misc Misc
+ * @{ */
+
+/** The maximum size of a generic segment offload (GSO) frame. This limit is
+ * imposed by the 16-bit frame size in internal networking header. */
+#define VBOX_MAX_GSO_SIZE 0xfff0
+
+/** @} */
+
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/param.mac b/include/VBox/param.mac
new file mode 100644
index 00000000..17db6f2d
--- /dev/null
+++ b/include/VBox/param.mac
@@ -0,0 +1,41 @@
+%ifndef ___VBox_param_h
+%define ___VBox_param_h
+%define VBOX_MAX_ALLOC_PAGE_COUNT (256U * _1M / PAGE_SIZE)
+%define MM_HYPER_AREA_ADDRESS 0xa0000000
+%define MM_HYPER_AREA_MAX_SIZE (40U * _1M)
+%define MM_HYPER_DYNAMIC_SIZE (16U * PAGE_SIZE)
+%define MM_RAM_MIN 0x00400000
+%if HC_ARCH_BITS == 64
+ %define MM_RAM_MAX 0x20000000000
+%else
+ %define MM_RAM_MAX 0x000E0000000
+%endif
+%define MM_RAM_MIN_IN_MB 4
+%if HC_ARCH_BITS == 64
+ %define MM_RAM_MAX_IN_MB 2097152
+%else
+ %define MM_RAM_MAX_IN_MB 3584
+%endif
+%define MM_RAM_HOLE_SIZE_DEFAULT (512U * _1M)
+%define PGM_HANDY_PAGES 128
+%define PGM_HANDY_PAGES_SET_FF 32
+%define PGM_HANDY_PAGES_R3_ALLOC 8
+%define PGM_HANDY_PAGES_RZ_ALLOC 8
+%define PGM_HANDY_PAGES_RZ_TO_R3 24
+%define PGM_HANDY_PAGES_MIN 32
+%ifdef RT_OS_DARWIN
+ %define VMM_STACK_SIZE 16384
+%else
+ %define VMM_STACK_SIZE 8192
+%endif
+%define VMM_MIN_CPU_COUNT 1
+%define VMM_MAX_CPU_COUNT 64
+%define VBOX_PCI_VENDORID (0x80ee)
+%define VBOX_VENDORID VBOX_PCI_VENDORID
+%define VBOX_DEVICEID (0xbeef)
+%define VBOX_VESA_VENDORID VBOX_PCI_VENDORID
+%define VBOX_VESA_DEVICEID (0xbeef)
+%define VMMDEV_VENDORID VBOX_PCI_VENDORID
+%define VMMDEV_DEVICEID (0xcafe)
+%define VBOX_MAX_GSO_SIZE 0xfff0
+%endif
diff --git a/include/VBox/pci.h b/include/VBox/pci.h
new file mode 100644
index 00000000..526c7298
--- /dev/null
+++ b/include/VBox/pci.h
@@ -0,0 +1,1174 @@
+/** @file
+ * PCI - The PCI Controller And Devices. (DEV)
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_pci_h
+#define ___VBox_pci_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/assert.h>
+
+/** @defgroup grp_pci PCI - The PCI Controller.
+ * @{
+ */
+
+/** Pointer to a PCI device. */
+typedef struct PCIDevice *PPCIDEVICE;
+
+
+/**
+ * PCI configuration word 4 (command) and word 6 (status).
+ */
+typedef enum PCICONFIGCOMMAND
+{
+ /** Supports/uses memory accesses. */
+ PCI_COMMAND_IOACCESS = 0x0001,
+ PCI_COMMAND_MEMACCESS = 0x0002,
+ PCI_COMMAND_BUSMASTER = 0x0004
+} PCICONFIGCOMMAND;
+
+
+/**
+ * PCI Address space specification.
+ * This is used when registering a I/O region.
+ */
+/**
+ * Defined by the PCI specification.
+ */
+typedef enum PCIADDRESSSPACE
+{
+ /** Memory. */
+ PCI_ADDRESS_SPACE_MEM = 0x00,
+ /** I/O space. */
+ PCI_ADDRESS_SPACE_IO = 0x01,
+ /** 32-bit BAR. */
+ PCI_ADDRESS_SPACE_BAR32 = 0x00,
+ /** 64-bit BAR. */
+ PCI_ADDRESS_SPACE_BAR64 = 0x04,
+ /** Prefetch memory. */
+ PCI_ADDRESS_SPACE_MEM_PREFETCH = 0x08
+} PCIADDRESSSPACE;
+
+
+/**
+ * Callback function for mapping an PCI I/O region.
+ *
+ * @return VBox status code.
+ * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
+ * @param iRegion The region number.
+ * @param GCPhysAddress Physical address of the region. If enmType is PCI_ADDRESS_SPACE_IO, this
+ * is an I/O port, otherwise it's a physical address.
+ *
+ * NIL_RTGCPHYS indicates that a MMIO2 mapping is about to be unmapped and
+ * that the device deregister access handlers for it and update its internal
+ * state to reflect this.
+ *
+ * @param enmType One of the PCI_ADDRESS_SPACE_* values.
+ *
+ */
+typedef DECLCALLBACK(int) FNPCIIOREGIONMAP(PPCIDEVICE pPciDev, /*unsigned*/ int iRegion, RTGCPHYS GCPhysAddress, uint32_t cb, PCIADDRESSSPACE enmType);
+/** Pointer to a FNPCIIOREGIONMAP() function. */
+typedef FNPCIIOREGIONMAP *PFNPCIIOREGIONMAP;
+
+
+/** @name PCI Configuration Space Registers
+ * @{ */
+/* Commented out values common for different header types */
+/* Common part of the header */
+#define VBOX_PCI_VENDOR_ID 0x00 /**< 16-bit RO */
+#define VBOX_PCI_DEVICE_ID 0x02 /**< 16-bit RO */
+#define VBOX_PCI_COMMAND 0x04 /**< 16-bit RW, some bits RO */
+#define VBOX_PCI_STATUS 0x06 /**< 16-bit RW, some bits RO */
+#define VBOX_PCI_REVISION_ID 0x08 /**< 8-bit RO - - device revision */
+#define VBOX_PCI_CLASS_PROG 0x09 /**< 8-bit RO - - register-level programming class code (device specific). */
+#define VBOX_PCI_CLASS_SUB 0x0a /**< 8-bit RO - - sub-class code. */
+#define VBOX_PCI_CLASS_DEVICE VBOX_PCI_CLASS_SUB
+#define VBOX_PCI_CLASS_BASE 0x0b /**< 8-bit RO - - base class code. */
+#define VBOX_PCI_CACHE_LINE_SIZE 0x0c /**< 8-bit RW - - system cache line size */
+#define VBOX_PCI_LATENCY_TIMER 0x0d /**< 8-bit RW - - master latency timer, hardwired to 0 for PCIe */
+#define VBOX_PCI_HEADER_TYPE 0x0e /**< 8-bit RO - - header type (0 - device, 1 - bridge, 2 - CardBus bridge) */
+#define VBOX_PCI_BIST 0x0f /**< 8-bit RW - - built-in self test control */
+#define VBOX_PCI_CAPABILITY_LIST 0x34 /**< 8-bit RO? - - linked list of new capabilities implemented by the device, 2 bottom bits reserved */
+#define VBOX_PCI_INTERRUPT_LINE 0x3c /**< 8-bit RW - - interrupt line. */
+#define VBOX_PCI_INTERRUPT_PIN 0x3d /**< 8-bit RO - - interrupt pin. */
+
+/* Type 0 header, device */
+#define VBOX_PCI_BASE_ADDRESS_0 0x10 /**< 32-bit RW */
+#define VBOX_PCI_BASE_ADDRESS_1 0x14 /**< 32-bit RW */
+#define VBOX_PCI_BASE_ADDRESS_2 0x18 /**< 32-bit RW */
+#define VBOX_PCI_BASE_ADDRESS_3 0x1c /**< 32-bit RW */
+#define VBOX_PCI_BASE_ADDRESS_4 0x20 /**< 32-bit RW */
+#define VBOX_PCI_BASE_ADDRESS_5 0x24 /**< 32-bit RW */
+#define VBOX_PCI_CARDBUS_CIS 0x28 /**< 32-bit ?? */
+#define VBOX_PCI_SUBSYSTEM_VENDOR_ID 0x2c /**< 16-bit RO */
+#define VBOX_PCI_SUBSYSTEM_ID 0x2e /**< 16-bit RO */
+#define VBOX_PCI_ROM_ADDRESS 0x30 /**< 32-bit ?? */
+/* #define VBOX_PCI_CAPABILITY_LIST 0x34 */ /**< 8-bit? ?? */
+#define VBOX_PCI_RESERVED_35 0x35 /**< 8-bit ?? - - reserved */
+#define VBOX_PCI_RESERVED_36 0x36 /**< 8-bit ?? - - reserved */
+#define VBOX_PCI_RESERVED_37 0x37 /**< 8-bit ?? - - reserved */
+#define VBOX_PCI_RESERVED_38 0x38 /**< 32-bit ?? - - reserved */
+/* #define VBOX_PCI_INTERRUPT_LINE 0x3c */ /**< 8-bit RW - - interrupt line. */
+/* #define VBOX_PCI_INTERRUPT_PIN 0x3d */ /**< 8-bit RO - - interrupt pin. */
+#define VBOX_PCI_MIN_GNT 0x3e /**< 8-bit RO - - burst period length (in 1/4 microsecond units) */
+#define VBOX_PCI_MAX_LAT 0x3f /**< 8-bit RO - - how often the device needs access to the PCI bus (in 1/4 microsecond units) */
+
+/* Type 1 header, PCI-to-PCI bridge */
+/* #define VBOX_PCI_BASE_ADDRESS_0 0x10 */ /**< 32-bit RW */
+/* #define VBOX_PCI_BASE_ADDRESS_1 0x14 */ /**< 32-bit RW */
+#define VBOX_PCI_PRIMARY_BUS 0x18 /**< 8-bit ?? - - primary bus number. */
+#define VBOX_PCI_SECONDARY_BUS 0x19 /**< 8-bit ?? - - secondary bus number. */
+#define VBOX_PCI_SUBORDINATE_BUS 0x1a /**< 8-bit ?? - - highest subordinate bus number. (behind the bridge) */
+#define VBOX_PCI_SEC_LATENCY_TIMER 0x1b /**< 8-bit ?? - - secondary latency timer. */
+#define VBOX_PCI_IO_BASE 0x1c /**< 8-bit ?? - - I/O range base. */
+#define VBOX_PCI_IO_LIMIT 0x1d /**< 8-bit ?? - - I/O range limit. */
+#define VBOX_PCI_SEC_STATUS 0x1e /**< 16-bit ?? - - secondary status register. */
+#define VBOX_PCI_MEMORY_BASE 0x20 /**< 16-bit ?? - - memory range base. */
+#define VBOX_PCI_MEMORY_LIMIT 0x22 /**< 16-bit ?? - - memory range limit. */
+#define VBOX_PCI_PREF_MEMORY_BASE 0x24 /**< 16-bit ?? - - prefetchable memory range base. */
+#define VBOX_PCI_PREF_MEMORY_LIMIT 0x26 /**< 16-bit ?? - - prefetchable memory range limit. */
+#define VBOX_PCI_PREF_BASE_UPPER32 0x28 /**< 32-bit ?? - - prefetchable memory range high base.*/
+#define VBOX_PCI_PREF_LIMIT_UPPER32 0x2c /**< 32-bit ?? - - prefetchable memory range high limit. */
+#define VBOX_PCI_IO_BASE_UPPER16 0x30 /**< 16-bit ?? - - memory range high base. */
+#define VBOX_PCI_IO_LIMIT_UPPER16 0x32 /**< 16-bit ?? - - memory range high limit. */
+/* #define VBOX_PCI_CAPABILITY_LIST 0x34 */ /**< 8-bit? ?? */
+/* #define VBOX_PCI_RESERVED_35 0x35 */ /**< 8-bit ?? - - reserved */
+/* #define VBOX_PCI_RESERVED_36 0x36 */ /**< 8-bit ?? - - reserved */
+/* #define VBOX_PCI_RESERVED_37 0x37 */ /**< 8-bit ?? - - reserved */
+#define VBOX_PCI_ROM_ADDRESS_BR 0x38 /**< 32-bit ?? - - expansion ROM base address */
+#define VBOX_PCI_BRIDGE_CONTROL 0x3e /**< 16-bit? ?? - - bridge control */
+
+/* Type 2 header, PCI-to-CardBus bridge */
+#define VBOX_PCI_CARDBUS_BASE_ADDRESS 0x10 /**< 32-bit RW - - CardBus Socket/ExCa base address */
+#define VBOX_PCI_CARDBUS_CAPLIST 0x14 /**< 8-bit RO? - - offset of capabilities list */
+#define VBOX_PCI_CARDBUS_RESERVED_15 0x15 /**< 8-bit ?? - - reserved */
+#define VBOX_PCI_CARDBUS_SEC_STATUS 0x16 /**< 16-bit ?? - - secondary status */
+#define VBOX_PCI_CARDBUS_PCIBUS_NUMBER 0x18 /**< 8-bit ?? - - PCI bus number */
+#define VBOX_PCI_CARDBUS_CARDBUS_NUMBER 0x19 /**< 8-bit ?? - - CardBus bus number */
+/* #define VBOX_PCI_SUBORDINATE_BUS 0x1a */ /**< 8-bit ?? - - highest subordinate bus number. (behind the bridge) */
+/* #define VBOX_PCI_SEC_LATENCY_TIMER 0x1b */ /**< 8-bit ?? - - secondary latency timer. */
+#define VBOX_PCI_CARDBUS_MEMORY_BASE0 0x1c /**< 32-bit RW - - memory base address 0 */
+#define VBOX_PCI_CARDBUS_MEMORY_LIMIT0 0x20 /**< 32-bit RW - - memory limit 0 */
+#define VBOX_PCI_CARDBUS_MEMORY_BASE1 0x24 /**< 32-bit RW - - memory base address 1 */
+#define VBOX_PCI_CARDBUS_MEMORY_LIMIT1 0x28 /**< 32-bit RW - - memory limit 1 */
+#define VBOX_PCI_CARDBUS_IO_BASE0 0x2c /**< 32-bit RW - - IO base address 0 */
+#define VBOX_PCI_CARDBUS_IO_LIMIT0 0x30 /**< 32-bit RW - - IO limit 0 */
+#define VBOX_PCI_CARDBUS_IO_BASE1 0x34 /**< 32-bit RW - - IO base address 1 */
+#define VBOX_PCI_CARDBUS_IO_LIMIT1 0x38 /**< 32-bit RW - - IO limit 1 */
+/* #define VBOX_PCI_INTERRUPT_LINE 0x3c */ /**< 8-bit RW - - interrupt line. */
+/* #define VBOX_PCI_INTERRUPT_PIN 0x3d */ /**< 8-bit RO - - interrupt pin. */
+/* #define VBOX_PCI_BRIDGE_CONTROL 0x3e */ /**< 16-bit? ?? - - bridge control */
+/** @} */
+
+
+/* Possible values in status bitmask */
+#define VBOX_PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
+#define VBOX_PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
+#define VBOX_PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
+#define VBOX_PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
+#define VBOX_PCI_STATUS_PARITY 0x100 /* Detected parity error */
+#define VBOX_PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
+#define VBOX_PCI_STATUS_DEVSEL_FAST 0x000
+#define VBOX_PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define VBOX_PCI_STATUS_DEVSEL_SLOW 0x400
+#define VBOX_PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
+#define VBOX_PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
+#define VBOX_PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
+#define VBOX_PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
+#define VBOX_PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
+
+
+/* Command bitmask */
+#define VBOX_PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
+#define VBOX_PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
+#define VBOX_PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
+#define VBOX_PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
+#define VBOX_PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
+#define VBOX_PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
+#define VBOX_PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
+#define VBOX_PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
+#define VBOX_PCI_COMMAND_SERR 0x100 /* Enable SERR */
+#define VBOX_PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
+#define VBOX_PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
+
+
+/* Capability list values (capability offset 0) */
+/* Next value pointer in offset 1, or 0 if none */
+#define VBOX_PCI_CAP_ID_PM 0x01 /* Power Management */
+#define VBOX_PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
+#define VBOX_PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
+#define VBOX_PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
+#define VBOX_PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
+#define VBOX_PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
+#define VBOX_PCI_CAP_ID_PCIX 0x07 /* PCI-X */
+#define VBOX_PCI_CAP_ID_HT 0x08 /* HyperTransport */
+#define VBOX_PCI_CAP_ID_VNDR 0x09 /* Vendor specific */
+#define VBOX_PCI_CAP_ID_DBG 0x0A /* Debug port */
+#define VBOX_PCI_CAP_ID_CCRC 0x0B /* CompactPCI Central Resource Control */
+#define VBOX_PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
+#define VBOX_PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */
+#define VBOX_PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */
+#define VBOX_PCI_CAP_ID_SECURE 0x0F /* Secure device (?) */
+#define VBOX_PCI_CAP_ID_EXP 0x10 /* PCI Express */
+#define VBOX_PCI_CAP_ID_MSIX 0x11 /* MSI-X */
+#define VBOX_PCI_CAP_ID_SATA 0x12 /* Serial-ATA HBA */
+#define VBOX_PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */
+
+/* Extended Capabilities (PCI-X 2.0 and Express), start at 0x100, next - bits [20..32] */
+#define VBOX_PCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error Reporting */
+#define VBOX_PCI_EXT_CAP_ID_VC 0x02 /* Virtual Channel */
+#define VBOX_PCI_EXT_CAP_ID_DSN 0x03 /* Device Serial Number */
+#define VBOX_PCI_EXT_CAP_ID_PWR 0x04 /* Power Budgeting */
+#define VBOX_PCI_EXT_CAP_ID_RCLINK 0x05 /* Root Complex Link Declaration */
+#define VBOX_PCI_EXT_CAP_ID_RCILINK 0x06 /* Root Complex Internal Link Declaration */
+#define VBOX_PCI_EXT_CAP_ID_RCECOLL 0x07 /* Root Complex Event Collector */
+#define VBOX_PCI_EXT_CAP_ID_MFVC 0x08 /* Multi-Function Virtual Channel */
+#define VBOX_PCI_EXT_CAP_ID_RBCB 0x0a /* Root Bridge Control Block */
+#define VBOX_PCI_EXT_CAP_ID_VNDR 0x0b /* Vendor specific */
+#define VBOX_PCI_EXT_CAP_ID_ACS 0x0d /* Access Controls */
+#define VBOX_PCI_EXT_CAP_ID_ARI 0x0e
+#define VBOX_PCI_EXT_CAP_ID_ATS 0x0f
+#define VBOX_PCI_EXT_CAP_ID_SRIOV 0x10
+
+
+/* MSI flags, aka Message Control (2 bytes, capability offset 2) */
+#define VBOX_PCI_MSI_FLAGS_ENABLE 0x0001 /* MSI feature enabled */
+#define VBOX_PCI_MSI_FLAGS_64BIT 0x0080 /* 64-bit addresses allowed */
+#define VBOX_PCI_MSI_FLAGS_MASKBIT 0x0100 /* Per-vector masking support */
+/* Encoding for 3-bit patterns for message queue (per chapter 6.8.1 of PCI spec),
+ someone very similar to log_2().
+ 000 1
+ 001 2
+ 010 4
+ 011 8
+ 100 16
+ 101 32
+ 110 Reserved
+ 111 Reserved */
+#define VBOX_PCI_MSI_FLAGS_QSIZE 0x0070 /* Message queue size configured (i.e. vectors per device allocated) */
+#define VBOX_PCI_MSI_FLAGS_QMASK 0x000e /* Maximum queue size available (i.e. vectors per device possible) */
+
+/* MSI-X flags (2 bytes, capability offset 2) */
+#define VBOX_PCI_MSIX_FLAGS_ENABLE 0x8000 /* MSI-X enable */
+#define VBOX_PCI_MSIX_FLAGS_FUNCMASK 0x4000 /* Function mask */
+
+/* Power management flags (2 bytes, capability offset 2) */
+#define VBOX_PCI_PM_CAP_VER_MASK 0x0007 /* Version mask */
+#define VBOX_PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
+#define VBOX_PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
+#define VBOX_PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
+#define VBOX_PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */
+#define VBOX_PCI_PM_CAP_D1 0x0200 /* D1 power state support */
+#define VBOX_PCI_PM_CAP_D2 0x0400 /* D2 power state support */
+#define VBOX_PCI_PM_CAP_PME 0x0800 /* PME pin supported */
+#define VBOX_PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
+#define VBOX_PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
+#define VBOX_PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
+#define VBOX_PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
+#define VBOX_PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
+#define VBOX_PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
+
+/* Power management control flags (2 bytes, capability offset 4) */
+#define VBOX_PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
+#define VBOX_PCI_PM_CTRL_NO_SOFT_RESET 0x0008 /* No reset for D3hot->D0 */
+#define VBOX_PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
+#define VBOX_PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
+#define VBOX_PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
+#define VBOX_PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
+
+/* PCI-X config flags (2 bytes, capability offset 2) */
+#define VBOX_PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */
+#define VBOX_PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */
+#define VBOX_PCI_X_CMD_MAX_OUTSTANDING_SPLIT_TRANS 0x0070
+#define VBOX_PCI_X_CMD_READ_512 0x0000 /* 512 byte maximum read byte count */
+#define VBOX_PCI_X_CMD_READ_1K 0x0004 /* 1Kbyte maximum read byte count */
+#define VBOX_PCI_X_CMD_READ_2K 0x0008 /* 2Kbyte maximum read byte count */
+#define VBOX_PCI_X_CMD_READ_4K 0x000c /* 4Kbyte maximum read byte count */
+#define VBOX_PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */
+
+/* PCI-X config flags (4 bytes, capability offset 4) */
+#define VBOX_PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */
+#define VBOX_PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */
+#define VBOX_PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */
+#define VBOX_PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */
+#define VBOX_PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */
+#define VBOX_PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */
+#define VBOX_PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity, 0 = simple device, 1 = bridge device */
+#define VBOX_PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count, 0 = 512 bytes, 1 = 1024, 2 = 2048, 3 = 4096 */
+#define VBOX_PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */
+#define VBOX_PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */
+#define VBOX_PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */
+#define VBOX_PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
+#define VBOX_PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
+
+/* PCI Express config flags (2 bytes, capability offset 2) */
+#define VBOX_PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
+#define VBOX_PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
+#define VBOX_PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
+#define VBOX_PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
+#define VBOX_PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
+#define VBOX_PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
+#define VBOX_PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
+#define VBOX_PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
+#define VBOX_PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIE Bridge */
+#define VBOX_PCI_EXP_TYPE_ROOT_INT_EP 0x9 /* Root Complex Integrated Endpoint */
+#define VBOX_PCI_EXP_TYPE_ROOT_EC 0xa /* Root Complex Event Collector */
+#define VBOX_PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
+#define VBOX_PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
+
+/* PCI Express device capabilities (4 bytes, capability offset 4) */
+#define VBOX_PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
+#define VBOX_PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
+#define VBOX_PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
+#define VBOX_PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
+#define VBOX_PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
+#define VBOX_PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
+#define VBOX_PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
+#define VBOX_PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
+#define VBOX_PCI_EXP_DEVCAP_RBE 0x8000 /* Role-Based Error Reporting */
+#define VBOX_PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
+#define VBOX_PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
+#define VBOX_PCI_EXP_DEVCAP_FLRESET 0x10000000 /* Function-Level Reset */
+
+/* PCI Express device control (2 bytes, capability offset 8) */
+#define VBOX_PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
+#define VBOX_PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
+#define VBOX_PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
+#define VBOX_PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
+#define VBOX_PCI_EXP_DEVCTL_RELAXED 0x0010 /* Enable Relaxed Ordering */
+#define VBOX_PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
+#define VBOX_PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
+#define VBOX_PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
+#define VBOX_PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
+#define VBOX_PCI_EXP_DEVCTL_NOSNOOP 0x0800 /* Enable No Snoop */
+#define VBOX_PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
+#define VBOX_PCI_EXP_DEVCTL_BCRE 0x8000 /* Bridge Configuration Retry Enable */
+#define VBOX_PCI_EXP_DEVCTL_FLRESET 0x8000 /* Function-Level Reset [bit shared with BCRE] */
+
+/* PCI Express device status (2 bytes, capability offset 10) */
+#define VBOX_PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
+#define VBOX_PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
+#define VBOX_PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
+#define VBOX_PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
+#define VBOX_PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
+#define VBOX_PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
+
+/* PCI Express link capabilities (4 bytes, capability offset 12) */
+#define VBOX_PCI_EXP_LNKCAP_SPEED 0x0000f /* Maximum Link Speed */
+#define VBOX_PCI_EXP_LNKCAP_WIDTH 0x003f0 /* Maximum Link Width */
+#define VBOX_PCI_EXP_LNKCAP_ASPM 0x00c00 /* Active State Power Management */
+#define VBOX_PCI_EXP_LNKCAP_L0S 0x07000 /* L0s Acceptable Latency */
+#define VBOX_PCI_EXP_LNKCAP_L1 0x38000 /* L1 Acceptable Latency */
+#define VBOX_PCI_EXP_LNKCAP_CLOCKPM 0x40000 /* Clock Power Management */
+#define VBOX_PCI_EXP_LNKCAP_SURPRISE 0x80000 /* Surprise Down Error Reporting */
+#define VBOX_PCI_EXP_LNKCAP_DLLA 0x100000 /* Data Link Layer Active Reporting */
+#define VBOX_PCI_EXP_LNKCAP_LBNC 0x200000 /* Link Bandwidth Notification Capability */
+#define VBOX_PCI_EXP_LNKCAP_PORT 0xff000000 /* Port Number */
+
+/* PCI Express link control (2 bytes, capability offset 16) */
+#define VBOX_PCI_EXP_LNKCTL_ASPM 0x0003 /* ASPM Control */
+#define VBOX_PCI_EXP_LNKCTL_RCB 0x0008 /* Read Completion Boundary */
+#define VBOX_PCI_EXP_LNKCTL_DISABLE 0x0010 /* Link Disable */
+#define VBOX_PCI_EXP_LNKCTL_RETRAIN 0x0020 /* Retrain Link */
+#define VBOX_PCI_EXP_LNKCTL_CLOCK 0x0040 /* Common Clock Configuration */
+#define VBOX_PCI_EXP_LNKCTL_XSYNCH 0x0080 /* Extended Synch */
+#define VBOX_PCI_EXP_LNKCTL_CLOCKPM 0x0100 /* Clock Power Management */
+#define VBOX_PCI_EXP_LNKCTL_HWAUTWD 0x0200 /* Hardware Autonomous Width Disable */
+#define VBOX_PCI_EXP_LNKCTL_BWMIE 0x0400 /* Bandwidth Mgmt Interrupt Enable */
+#define VBOX_PCI_EXP_LNKCTL_AUTBWIE 0x0800 /* Autonomous Bandwidth Mgmt Interrupt Enable */
+
+/* PCI Express link status (2 bytes, capability offset 18) */
+#define VBOX_PCI_EXP_LNKSTA_SPEED 0x000f /* Negotiated Link Speed */
+#define VBOX_PCI_EXP_LNKSTA_WIDTH 0x03f0 /* Negotiated Link Width */
+#define VBOX_PCI_EXP_LNKSTA_TR_ERR 0x0400 /* Training Error (obsolete) */
+#define VBOX_PCI_EXP_LNKSTA_TRAIN 0x0800 /* Link Training */
+#define VBOX_PCI_EXP_LNKSTA_SL_CLK 0x1000 /* Slot Clock Configuration */
+#define VBOX_PCI_EXP_LNKSTA_DL_ACT 0x2000 /* Data Link Layer in DL_Active State */
+#define VBOX_PCI_EXP_LNKSTA_BWMGMT 0x4000 /* Bandwidth Mgmt Status */
+#define VBOX_PCI_EXP_LNKSTA_AUTBW 0x8000 /* Autonomous Bandwidth Mgmt Status */
+
+/* PCI Express slot capabilities (4 bytes, capability offset 20) */
+#define VBOX_PCI_EXP_SLTCAP_ATNB 0x0001 /* Attention Button Present */
+#define VBOX_PCI_EXP_SLTCAP_PWRC 0x0002 /* Power Controller Present */
+#define VBOX_PCI_EXP_SLTCAP_MRL 0x0004 /* MRL Sensor Present */
+#define VBOX_PCI_EXP_SLTCAP_ATNI 0x0008 /* Attention Indicator Present */
+#define VBOX_PCI_EXP_SLTCAP_PWRI 0x0010 /* Power Indicator Present */
+#define VBOX_PCI_EXP_SLTCAP_HPS 0x0020 /* Hot-Plug Surprise */
+#define VBOX_PCI_EXP_SLTCAP_HPC 0x0040 /* Hot-Plug Capable */
+#define VBOX_PCI_EXP_SLTCAP_PWR_VAL 0x00007f80 /* Slot Power Limit Value */
+#define VBOX_PCI_EXP_SLTCAP_PWR_SCL 0x00018000 /* Slot Power Limit Scale */
+#define VBOX_PCI_EXP_SLTCAP_INTERLOCK 0x020000 /* Electromechanical Interlock Present */
+#define VBOX_PCI_EXP_SLTCAP_NOCMDCOMP 0x040000 /* No Command Completed Support */
+#define VBOX_PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */
+
+/* PCI Express slot control (2 bytes, capability offset 24) */
+#define VBOX_PCI_EXP_SLTCTL_ATNB 0x0001 /* Attention Button Pressed Enable */
+#define VBOX_PCI_EXP_SLTCTL_PWRF 0x0002 /* Power Fault Detected Enable */
+#define VBOX_PCI_EXP_SLTCTL_MRLS 0x0004 /* MRL Sensor Changed Enable */
+#define VBOX_PCI_EXP_SLTCTL_PRSD 0x0008 /* Presence Detect Changed Enable */
+#define VBOX_PCI_EXP_SLTCTL_CMDC 0x0010 /* Command Completed Interrupt Enable */
+#define VBOX_PCI_EXP_SLTCTL_HPIE 0x0020 /* Hot-Plug Interrupt Enable */
+#define VBOX_PCI_EXP_SLTCTL_ATNI 0x00c0 /* Attention Indicator Control */
+#define VBOX_PCI_EXP_SLTCTL_PWRI 0x0300 /* Power Indicator Control */
+#define VBOX_PCI_EXP_SLTCTL_PWRC 0x0400 /* Power Controller Control */
+#define VBOX_PCI_EXP_SLTCTL_INTERLOCK 0x0800 /* Electromechanical Interlock Control */
+#define VBOX_PCI_EXP_SLTCTL_LLCHG 0x1000 /* Data Link Layer State Changed Enable */
+
+/* PCI Express slot status (2 bytes, capability offset 26) */
+#define VBOX_PCI_EXP_SLTSTA_ATNB 0x0001 /* Attention Button Pressed */
+#define VBOX_PCI_EXP_SLTSTA_PWRF 0x0002 /* Power Fault Detected */
+#define VBOX_PCI_EXP_SLTSTA_MRLS 0x0004 /* MRL Sensor Changed */
+#define VBOX_PCI_EXP_SLTSTA_PRSD 0x0008 /* Presence Detect Changed */
+#define VBOX_PCI_EXP_SLTSTA_CMDC 0x0010 /* Command Completed */
+#define VBOX_PCI_EXP_SLTSTA_MRL_ST 0x0020 /* MRL Sensor State */
+#define VBOX_PCI_EXP_SLTSTA_PRES 0x0040 /* Presence Detect State */
+#define VBOX_PCI_EXP_SLTSTA_INTERLOCK 0x0080 /* Electromechanical Interlock Status */
+#define VBOX_PCI_EXP_SLTSTA_LLCHG 0x0100 /* Data Link Layer State Changed */
+
+/* PCI Express root control (2 bytes, capability offset 28) */
+#define VBOX_PCI_EXP_RTCTL_SECEE 0x0001 /* System Error on Correctable Error */
+#define VBOX_PCI_EXP_RTCTL_SENFEE 0x0002 /* System Error on Non-Fatal Error */
+#define VBOX_PCI_EXP_RTCTL_SEFEE 0x0004 /* System Error on Fatal Error */
+#define VBOX_PCI_EXP_RTCTL_PMEIE 0x0008 /* PME Interrupt Enable */
+#define VBOX_PCI_EXP_RTCTL_CRSVIS 0x0010 /* Configuration Request Retry Status Visible to SW */
+
+/* PCI Express root capabilities (2 bytes, capability offset 30) */
+#define VBOX_PCI_EXP_RTCAP_CRSVIS 0x0010 /* Configuration Request Retry Status Visible to SW */
+
+/* PCI Express root status (4 bytes, capability offset 32) */
+#define VBOX_PCI_EXP_RTSTA_PME_REQID 0x0000ffff /* PME Requester ID */
+#define VBOX_PCI_EXP_RTSTA_PME_STATUS 0x00010000 /* PME Status */
+#define VBOX_PCI_EXP_RTSTA_PME_PENDING 0x00020000 /* PME is Pending */
+
+
+/**
+ * Callback function for reading from the PCI configuration space.
+ *
+ * @returns The register value.
+ * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
+ * @param Address The configuration space register address. [0..4096]
+ * @param cb The register size. [1,2,4]
+ */
+typedef DECLCALLBACK(uint32_t) FNPCICONFIGREAD(PPCIDEVICE pPciDev, uint32_t Address, unsigned cb);
+/** Pointer to a FNPCICONFIGREAD() function. */
+typedef FNPCICONFIGREAD *PFNPCICONFIGREAD;
+/** Pointer to a PFNPCICONFIGREAD. */
+typedef PFNPCICONFIGREAD *PPFNPCICONFIGREAD;
+
+/**
+ * Callback function for writing to the PCI configuration space.
+ *
+ * @param pPciDev Pointer to PCI device. Use pPciDev->pDevIns to get the device instance.
+ * @param Address The configuration space register address. [0..4096]
+ * @param u32Value The value that's being written. The number of bits actually used from
+ * this value is determined by the cb parameter.
+ * @param cb The register size. [1,2,4]
+ */
+typedef DECLCALLBACK(void) FNPCICONFIGWRITE(PPCIDEVICE pPciDev, uint32_t Address, uint32_t u32Value, unsigned cb);
+/** Pointer to a FNPCICONFIGWRITE() function. */
+typedef FNPCICONFIGWRITE *PFNPCICONFIGWRITE;
+/** Pointer to a PFNPCICONFIGWRITE. */
+typedef PFNPCICONFIGWRITE *PPFNPCICONFIGWRITE;
+
+/** Fixed I/O region number for ROM. */
+#define PCI_ROM_SLOT 6
+#define VBOX_PCI_ROM_SLOT 6
+/** Max number of I/O regions. */
+#define PCI_NUM_REGIONS 7
+#define VBOX_PCI_NUM_REGIONS 7
+
+/*
+ * Hack to include the PCIDEVICEINT structure at the right place
+ * to avoid duplications of FNPCIIOREGIONMAP and PCI_NUM_REGIONS.
+ */
+#ifdef PCI_INCLUDE_PRIVATE
+# include "PCIInternal.h"
+#endif
+
+/**
+ * PCI Device structure.
+ */
+typedef struct PCIDevice
+{
+ /** PCI config space. */
+ uint8_t config[256];
+
+ /** Internal data. */
+ union
+ {
+#ifdef PCIDEVICEINT_DECLARED
+ PCIDEVICEINT s;
+#endif
+ char padding[328];
+ } Int;
+
+ /** Read only data.
+ * @{
+ */
+ /** PCI device number on the pci bus. */
+ int32_t devfn;
+ uint32_t Alignment0; /**< Alignment. */
+ /** Device name. */
+ R3PTRTYPE(const char *) name;
+ /** Pointer to the device instance which registered the device. */
+ PPDMDEVINSR3 pDevIns;
+ /** @} */
+} PCIDEVICE;
+
+/* @todo: handle extended space access */
+DECLINLINE(void) PCIDevSetByte(PPCIDEVICE pPciDev, uint32_t uOffset, uint8_t u8Value)
+{
+ pPciDev->config[uOffset] = u8Value;
+}
+
+DECLINLINE(uint8_t) PCIDevGetByte(PPCIDEVICE pPciDev, uint32_t uOffset)
+{
+ return pPciDev->config[uOffset];
+}
+
+DECLINLINE(void) PCIDevSetWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint16_t u16Value)
+{
+ *(uint16_t*)&pPciDev->config[uOffset] = RT_H2LE_U16(u16Value);
+}
+
+DECLINLINE(uint16_t) PCIDevGetWord(PPCIDEVICE pPciDev, uint32_t uOffset)
+{
+ uint16_t u16Value = *(uint16_t*)&pPciDev->config[uOffset];
+ return RT_H2LE_U16(u16Value);
+}
+
+DECLINLINE(void) PCIDevSetDWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint32_t u32Value)
+{
+ *(uint32_t*)&pPciDev->config[uOffset] = RT_H2LE_U32(u32Value);
+}
+
+DECLINLINE(uint32_t) PCIDevGetDWord(PPCIDEVICE pPciDev, uint32_t uOffset)
+{
+ uint32_t u32Value = *(uint32_t*)&pPciDev->config[uOffset];
+ return RT_H2LE_U32(u32Value);
+}
+
+DECLINLINE(void) PCIDevSetQWord(PPCIDEVICE pPciDev, uint32_t uOffset, uint64_t u64Value)
+{
+ *(uint64_t*)&pPciDev->config[uOffset] = RT_H2LE_U64(u64Value);
+}
+
+DECLINLINE(uint64_t) PCIDevGetQWord(PPCIDEVICE pPciDev, uint32_t uOffset)
+{
+ uint64_t u64Value = *(uint64_t*)&pPciDev->config[uOffset];
+ return RT_H2LE_U64(u64Value);
+}
+
+/**
+ * Sets the vendor id config register.
+ * @param pPciDev The PCI device.
+ * @param u16VendorId The vendor id.
+ */
+DECLINLINE(void) PCIDevSetVendorId(PPCIDEVICE pPciDev, uint16_t u16VendorId)
+{
+ PCIDevSetWord(pPciDev, VBOX_PCI_VENDOR_ID, u16VendorId);
+}
+
+/**
+ * Gets the vendor id config register.
+ * @returns the vendor id.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint16_t) PCIDevGetVendorId(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetWord(pPciDev, VBOX_PCI_VENDOR_ID);
+}
+
+
+/**
+ * Sets the device id config register.
+ * @param pPciDev The PCI device.
+ * @param u16DeviceId The device id.
+ */
+DECLINLINE(void) PCIDevSetDeviceId(PPCIDEVICE pPciDev, uint16_t u16DeviceId)
+{
+ PCIDevSetWord(pPciDev, VBOX_PCI_DEVICE_ID, u16DeviceId);
+}
+
+/**
+ * Gets the device id config register.
+ * @returns the device id.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint16_t) PCIDevGetDeviceId(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetWord(pPciDev, VBOX_PCI_DEVICE_ID);
+}
+
+/**
+ * Sets the command config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u16Command The command register value.
+ */
+DECLINLINE(void) PCIDevSetCommand(PPCIDEVICE pPciDev, uint16_t u16Command)
+{
+ PCIDevSetWord(pPciDev, VBOX_PCI_COMMAND, u16Command);
+}
+
+
+/**
+ * Gets the command config register.
+ * @returns The command register value.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint16_t) PCIDevGetCommand(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetWord(pPciDev, VBOX_PCI_COMMAND);
+}
+
+/**
+ * Checks if the given PCI device is a bus master.
+ * @returns true if the device is a bus master, false if not.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(bool) PCIDevIsBusmaster(PPCIDEVICE pPciDev)
+{
+ return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_MASTER) != 0;
+}
+
+/**
+ * Checks if INTx interrupts disabled in the command config register.
+ * @returns true if disabled.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(bool) PCIDevIsIntxDisabled(PPCIDEVICE pPciDev)
+{
+ return (PCIDevGetCommand(pPciDev) & VBOX_PCI_COMMAND_INTX_DISABLE) != 0;
+}
+
+/**
+ * Gets the status config register.
+ *
+ * @returns status config register.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint16_t) PCIDevGetStatus(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetWord(pPciDev, VBOX_PCI_STATUS);
+}
+
+/**
+ * Sets the status config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u16Status The status register value.
+ */
+DECLINLINE(void) PCIDevSetStatus(PPCIDEVICE pPciDev, uint16_t u16Status)
+{
+ PCIDevSetWord(pPciDev, VBOX_PCI_STATUS, u16Status);
+}
+
+
+/**
+ * Sets the revision id config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8RevisionId The revision id.
+ */
+DECLINLINE(void) PCIDevSetRevisionId(PPCIDEVICE pPciDev, uint8_t u8RevisionId)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_REVISION_ID, u8RevisionId);
+}
+
+
+/**
+ * Sets the register level programming class config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8ClassProg The new value.
+ */
+DECLINLINE(void) PCIDevSetClassProg(PPCIDEVICE pPciDev, uint8_t u8ClassProg)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_PROG, u8ClassProg);
+}
+
+
+/**
+ * Sets the sub-class (aka device class) config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8SubClass The sub-class.
+ */
+DECLINLINE(void) PCIDevSetClassSub(PPCIDEVICE pPciDev, uint8_t u8SubClass)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_SUB, u8SubClass);
+}
+
+
+/**
+ * Sets the base class config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8BaseClass The base class.
+ */
+DECLINLINE(void) PCIDevSetClassBase(PPCIDEVICE pPciDev, uint8_t u8BaseClass)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_CLASS_BASE, u8BaseClass);
+}
+
+/**
+ * Sets the header type config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8HdrType The header type.
+ */
+DECLINLINE(void) PCIDevSetHeaderType(PPCIDEVICE pPciDev, uint8_t u8HdrType)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_HEADER_TYPE, u8HdrType);
+}
+
+/**
+ * Gets the header type config register.
+ *
+ * @param pPciDev The PCI device.
+ * @returns u8HdrType The header type.
+ */
+DECLINLINE(uint8_t) PCIDevGetHeaderType(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetByte(pPciDev, VBOX_PCI_HEADER_TYPE);
+}
+
+/**
+ * Sets the BIST (built-in self-test) config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8Bist The BIST value.
+ */
+DECLINLINE(void) PCIDevSetBIST(PPCIDEVICE pPciDev, uint8_t u8Bist)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_BIST, u8Bist);
+}
+
+/**
+ * Gets the BIST (built-in self-test) config register.
+ *
+ * @param pPciDev The PCI device.
+ * @returns u8Bist The BIST.
+ */
+DECLINLINE(uint8_t) PCIDevGetBIST(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetByte(pPciDev, VBOX_PCI_BIST);
+}
+
+
+/**
+ * Sets a base address config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param fIOSpace Whether it's I/O (true) or memory (false) space.
+ * @param fPrefetchable Whether the memory is prefetachable. Must be false if fIOSpace == true.
+ * @param f64Bit Whether the memory can be mapped anywhere in the 64-bit address space. Otherwise restrict to 32-bit.
+ * @param u32Addr The address value.
+ */
+DECLINLINE(void) PCIDevSetBaseAddress(PPCIDEVICE pPciDev, uint8_t iReg, bool fIOSpace, bool fPrefetchable, bool f64Bit, uint32_t u32Addr)
+{
+ if (fIOSpace)
+ {
+ Assert(!(u32Addr & 0x3)); Assert(!fPrefetchable); Assert(!f64Bit);
+ u32Addr |= RT_BIT_32(0);
+ }
+ else
+ {
+ Assert(!(u32Addr & 0xf));
+ if (fPrefetchable)
+ u32Addr |= RT_BIT_32(3);
+ if (f64Bit)
+ u32Addr |= 0x2 << 1;
+ }
+ switch (iReg)
+ {
+ case 0: iReg = VBOX_PCI_BASE_ADDRESS_0; break;
+ case 1: iReg = VBOX_PCI_BASE_ADDRESS_1; break;
+ case 2: iReg = VBOX_PCI_BASE_ADDRESS_2; break;
+ case 3: iReg = VBOX_PCI_BASE_ADDRESS_3; break;
+ case 4: iReg = VBOX_PCI_BASE_ADDRESS_4; break;
+ case 5: iReg = VBOX_PCI_BASE_ADDRESS_5; break;
+ default: AssertFailedReturnVoid();
+ }
+
+ PCIDevSetDWord(pPciDev, iReg, u32Addr);
+}
+
+/**
+ * Please document me. I don't seem to be getting as much as calculating
+ * the address of some PCI region.
+ */
+DECLINLINE(uint32_t) PCIDevGetRegionReg(uint32_t iRegion)
+{
+ return iRegion == VBOX_PCI_ROM_SLOT
+ ? VBOX_PCI_ROM_ADDRESS : (VBOX_PCI_BASE_ADDRESS_0 + iRegion * 4);
+}
+
+/**
+ * Sets the sub-system vendor id config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u16SubSysVendorId The sub-system vendor id.
+ */
+DECLINLINE(void) PCIDevSetSubSystemVendorId(PPCIDEVICE pPciDev, uint16_t u16SubSysVendorId)
+{
+ PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID, u16SubSysVendorId);
+}
+
+/**
+ * Gets the sub-system vendor id config register.
+ * @returns the sub-system vendor id.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint16_t) PCIDevGetSubSystemVendorId(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_VENDOR_ID);
+}
+
+
+/**
+ * Sets the sub-system id config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u16SubSystemId The sub-system id.
+ */
+DECLINLINE(void) PCIDevSetSubSystemId(PPCIDEVICE pPciDev, uint16_t u16SubSystemId)
+{
+ PCIDevSetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID, u16SubSystemId);
+}
+
+/**
+ * Gets the sub-system id config register.
+ * @returns the sub-system id.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint16_t) PCIDevGetSubSystemId(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetWord(pPciDev, VBOX_PCI_SUBSYSTEM_ID);
+}
+
+/**
+ * Sets offset to capability list.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8Offset The offset to capability list.
+ */
+DECLINLINE(void) PCIDevSetCapabilityList(PPCIDEVICE pPciDev, uint8_t u8Offset)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST, u8Offset);
+}
+
+/**
+ * Returns offset to capability list.
+ *
+ * @returns offset to capability list.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint8_t) PCIDevGetCapabilityList(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetByte(pPciDev, VBOX_PCI_CAPABILITY_LIST);
+}
+
+/**
+ * Sets the interrupt line config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8Line The interrupt line.
+ */
+DECLINLINE(void) PCIDevSetInterruptLine(PPCIDEVICE pPciDev, uint8_t u8Line)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE, u8Line);
+}
+
+/**
+ * Gets the interrupt line config register.
+ *
+ * @returns The interrupt line.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint8_t) PCIDevGetInterruptLine(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_LINE);
+}
+
+/**
+ * Sets the interrupt pin config register.
+ *
+ * @param pPciDev The PCI device.
+ * @param u8Pin The interrupt pin.
+ */
+DECLINLINE(void) PCIDevSetInterruptPin(PPCIDEVICE pPciDev, uint8_t u8Pin)
+{
+ PCIDevSetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN, u8Pin);
+}
+
+/**
+ * Gets the interrupt pin config register.
+ *
+ * @returns The interrupt pin.
+ * @param pPciDev The PCI device.
+ */
+DECLINLINE(uint8_t) PCIDevGetInterruptPin(PPCIDEVICE pPciDev)
+{
+ return PCIDevGetByte(pPciDev, VBOX_PCI_INTERRUPT_PIN);
+}
+
+#ifdef PCIDEVICEINT_DECLARED
+DECLINLINE(void) pciDevSetRequestedDevfunc(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags |= PCIDEV_FLAG_REQUESTED_DEVFUNC;
+}
+
+DECLINLINE(void) pciDevClearRequestedDevfunc(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags &= ~PCIDEV_FLAG_REQUESTED_DEVFUNC;
+}
+
+DECLINLINE(bool) pciDevIsRequestedDevfunc(PPCIDEVICE pDev)
+{
+ return (pDev->Int.s.fFlags & PCIDEV_FLAG_REQUESTED_DEVFUNC) != 0;
+}
+
+DECLINLINE(void) pciDevSetPci2PciBridge(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_TO_PCI_BRIDGE;
+}
+
+DECLINLINE(bool) pciDevIsPci2PciBridge(PPCIDEVICE pDev)
+{
+ return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_TO_PCI_BRIDGE) != 0;
+}
+
+DECLINLINE(void) pciDevSetPciExpress(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags |= PCIDEV_FLAG_PCI_EXPRESS_DEVICE;
+}
+
+DECLINLINE(bool) pciDevIsPciExpress(PPCIDEVICE pDev)
+{
+ return (pDev->Int.s.fFlags & PCIDEV_FLAG_PCI_EXPRESS_DEVICE) != 0;
+}
+
+DECLINLINE(void) pciDevSetMsiCapable(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI_CAPABLE;
+}
+
+DECLINLINE(void) pciDevClearMsiCapable(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI_CAPABLE;
+}
+
+DECLINLINE(bool) pciDevIsMsiCapable(PPCIDEVICE pDev)
+{
+ return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI_CAPABLE) != 0;
+}
+
+DECLINLINE(void) pciDevSetMsi64Capable(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags |= PCIDEV_FLAG_MSI64_CAPABLE;
+}
+
+DECLINLINE(void) pciDevClearMsi64Capable(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSI64_CAPABLE;
+}
+
+DECLINLINE(bool) pciDevIsMsi64Capable(PPCIDEVICE pDev)
+{
+ return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSI64_CAPABLE) != 0;
+}
+
+DECLINLINE(void) pciDevSetMsixCapable(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags |= PCIDEV_FLAG_MSIX_CAPABLE;
+}
+
+DECLINLINE(void) pciDevClearMsixCapable(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags &= ~PCIDEV_FLAG_MSIX_CAPABLE;
+}
+
+DECLINLINE(bool) pciDevIsMsixCapable(PPCIDEVICE pDev)
+{
+ return (pDev->Int.s.fFlags & PCIDEV_FLAG_MSIX_CAPABLE) != 0;
+}
+
+DECLINLINE(void) pciDevSetPassthrough(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags |= PCIDEV_FLAG_PASSTHROUGH;
+}
+
+DECLINLINE(void) pciDevClearPassthrough(PPCIDEVICE pDev)
+{
+ pDev->Int.s.fFlags &= ~PCIDEV_FLAG_PASSTHROUGH;
+}
+
+DECLINLINE(bool) pciDevIsPassthrough(PPCIDEVICE pDev)
+{
+ return (pDev->Int.s.fFlags & PCIDEV_FLAG_PASSTHROUGH) != 0;
+}
+
+#endif /* PCIDEVICEINT_DECLARED */
+
+#if defined(__cplusplus) && defined(IN_RING3)
+/* For RTStrPrintf(). */
+#include <iprt/string.h>
+
+/**
+ * Class representing PCI address. PCI device consist of
+ * bus, device and function numbers. Generally device PCI
+ * address could be changed during runtime, but only by
+ * an OS PCI driver.
+ *
+ * @remarks C++ classes (structs included) are not generally accepted in
+ * VMM devices or drivers. An exception may be granted for this class
+ * if it's contained to ring-3 and that this is a one time exception
+ * which sets no precedent.
+ */
+struct PCIBusAddress
+{
+ /** @todo: think if we'll need domain, which is higher
+ * word of the address. */
+ int miBus;
+ int miDevice;
+ int miFn;
+
+ PCIBusAddress()
+ {
+ clear();
+ }
+
+ PCIBusAddress(int iBus, int iDevice, int iFn)
+ {
+ init(iBus, iDevice, iFn);
+ }
+
+ PCIBusAddress(int32_t iAddr)
+ {
+ clear();
+ fromLong(iAddr);
+ }
+
+ PCIBusAddress& clear()
+ {
+ miBus = miDevice = miFn = -1;
+ return *this;
+ }
+
+ void init(int iBus, int iDevice, int iFn)
+ {
+ miBus = iBus;
+ miDevice = iDevice;
+ miFn = iFn;
+ }
+
+ void init(const PCIBusAddress &a)
+ {
+ miBus = a.miBus;
+ miDevice = a.miDevice;
+ miFn = a.miFn;
+ }
+
+ bool operator<(const PCIBusAddress &a) const
+ {
+ if (miBus < a.miBus)
+ return true;
+
+ if (miBus > a.miBus)
+ return false;
+
+ if (miDevice < a.miDevice)
+ return true;
+
+ if (miDevice > a.miDevice)
+ return false;
+
+ if (miFn < a.miFn)
+ return true;
+
+ if (miFn > a.miFn)
+ return false;
+
+ return false;
+ }
+
+ bool operator==(const PCIBusAddress &a) const
+ {
+ return (miBus == a.miBus)
+ && (miDevice == a.miDevice)
+ && (miFn == a.miFn);
+ }
+
+ bool operator!=(const PCIBusAddress &a) const
+ {
+ return (miBus != a.miBus)
+ || (miDevice != a.miDevice)
+ || (miFn != a.miFn);
+ }
+
+ bool valid() const
+ {
+ return (miBus != -1)
+ && (miDevice != -1)
+ && (miFn != -1);
+ }
+
+ int32_t asLong() const
+ {
+ Assert(valid());
+ return (miBus << 8) | (miDevice << 3) | miFn;
+ }
+
+ PCIBusAddress& fromLong(int32_t value)
+ {
+ miBus = (value >> 8) & 0xff;
+ miDevice = (value & 0xff) >> 3;
+ miFn = (value & 7);
+ return *this;
+ }
+
+ /** Create string representation of this PCI address. */
+ bool format(char* szBuf, int32_t cBufSize)
+ {
+ if (cBufSize < (/* bus */ 2 + /* : */ 1 + /* device */ 2 + /* . */ 1 + /* function*/ 1 + /* \0 */1))
+ return false;
+
+ if (valid())
+ RTStrPrintf(szBuf, cBufSize, "%02x:%02x.%01x", miBus, miDevice, miFn);
+ else
+ RTStrPrintf(szBuf, cBufSize, "%s", "<bad>");
+
+ return true;
+ }
+
+ static const size_t cMaxAddrSize = 10;
+};
+#endif /* __cplusplus */
+
+/** @} */
+
+#endif
diff --git a/include/VBox/rawpci.h b/include/VBox/rawpci.h
new file mode 100644
index 00000000..02fdd1a8
--- /dev/null
+++ b/include/VBox/rawpci.h
@@ -0,0 +1,588 @@
+/** @file
+ * Raw PCI Devices (aka PCI pass-through). (VMM)
+ */
+
+/*
+ * Copyright (C) 2010-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_rawpci_h
+#define ___VBox_rawpci_h
+
+#include <VBox/types.h>
+#include <VBox/sup.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Handle for the raw PCI device.
+ */
+typedef uint32_t PCIRAWDEVHANDLE;
+
+/**
+ * Handle for the ISR.
+ */
+typedef uint32_t PCIRAWISRHANDLE;
+
+/**
+ * Physical memory action enumeration.
+ */
+typedef enum PCIRAWMEMINFOACTION
+{
+ /** Pages mapped. */
+ PCIRAW_MEMINFO_MAP,
+ /** Pages unmapped. */
+ PCIRAW_MEMINFO_UNMAP,
+ /** The usual 32-bit type blow up. */
+ PCIRAW_MEMINFO_32BIT_HACK = 0x7fffffff
+} PCIRAWMEMINFOACTION;
+
+/**
+ * Per-VM capability flag bits.
+ */
+typedef enum PCIRAWVMFLAGS
+{
+ /** If we can use IOMMU in this VM. */
+ PCIRAW_VMFLAGS_HAS_IOMMU = (1 << 0),
+ PCIRAW_VMFLAGS_32BIT_HACK = 0x7fffffff
+} PCIRAWVMFLAGS;
+
+/* Forward declaration. */
+struct RAWPCIPERVM;
+
+/**
+ * Callback to notify raw PCI subsystem about mapping/unmapping of
+ * host pages to the guest. Typical usecase is to register physical
+ * RAM pages with IOMMU, so that it could allow DMA for PCI devices
+ * directly from the guest RAM.
+ * Region shall be one or more contigous (both host and guest) pages
+ * of physical memory.
+ *
+ * @returns VBox status code.
+ *
+ * @param pVM VM pointer.
+ * @param HostStart Physical address of region start on the host.
+ * @param GuestStart Physical address of region start on the guest.
+ * @param cMemSize Region size in bytes.
+ * @param Action Action performed (i.e. if page was mapped or unmapped).
+ */
+typedef DECLCALLBACK(int) FNRAWPCICONTIGPHYSMEMINFO(struct RAWPCIPERVM* pVmData, RTHCPHYS HostStart, RTGCPHYS GuestStart, uint64_t cMemSize, PCIRAWMEMINFOACTION Action);
+typedef FNRAWPCICONTIGPHYSMEMINFO *PFNRAWPCICONTIGPHYSMEMINFO;
+
+/** Data being part of the VM structure. */
+typedef struct RAWPCIPERVM
+{
+ /** Shall only be interpreted by the host PCI driver. */
+ RTR0PTR pDriverData;
+ /** Callback called when mapping of host pages to the guest changes. */
+ PFNRAWPCICONTIGPHYSMEMINFO pfnContigMemInfo;
+ /** Flags describing VM capabilities (such as IOMMU presence). */
+ uint32_t fVmCaps;
+} RAWPCIPERVM;
+typedef RAWPCIPERVM *PRAWPCIPERVM;
+
+/** Parameters buffer for PCIRAWR0_DO_OPEN_DEVICE call */
+typedef struct
+{
+ /* in */
+ uint32_t PciAddress;
+ uint32_t fFlags;
+ /* out */
+ PCIRAWDEVHANDLE Device;
+ uint32_t fDevFlags;
+} PCIRAWREQOPENDEVICE;
+
+/** Parameters buffer for PCIRAWR0_DO_CLOSE_DEVICE call */
+typedef struct
+{
+ /* in */
+ uint32_t fFlags;
+} PCIRAWREQCLOSEDEVICE;
+
+/** Parameters buffer for PCIRAWR0_DO_GET_REGION_INFO call */
+typedef struct
+{
+ /* in */
+ int32_t iRegion;
+ /* out */
+ RTGCPHYS RegionStart;
+ uint64_t u64RegionSize;
+ bool fPresent;
+ uint32_t fFlags;
+} PCIRAWREQGETREGIONINFO;
+
+/** Parameters buffer for PCIRAWR0_DO_MAP_REGION call. */
+typedef struct
+{
+ /* in */
+ RTGCPHYS StartAddress;
+ uint64_t iRegionSize;
+ int32_t iRegion;
+ uint32_t fFlags;
+ /* out */
+ RTR3PTR pvAddressR3;
+ RTR0PTR pvAddressR0;
+} PCIRAWREQMAPREGION;
+
+/** Parameters buffer for PCIRAWR0_DO_UNMAP_REGION call. */
+typedef struct
+{
+ /* in */
+ RTGCPHYS StartAddress;
+ uint64_t iRegionSize;
+ RTR3PTR pvAddressR3;
+ RTR0PTR pvAddressR0;
+ int32_t iRegion;
+} PCIRAWREQUNMAPREGION;
+
+/** Parameters buffer for PCIRAWR0_DO_PIO_WRITE call. */
+typedef struct
+{
+ /* in */
+ uint16_t iPort;
+ uint16_t cb;
+ uint32_t iValue;
+} PCIRAWREQPIOWRITE;
+
+/** Parameters buffer for PCIRAWR0_DO_PIO_READ call. */
+typedef struct
+{
+ /* in */
+ uint16_t iPort;
+ uint16_t cb;
+ /* out */
+ uint32_t iValue;
+} PCIRAWREQPIOREAD;
+
+/** Memory operand. */
+typedef struct
+{
+ union
+ {
+ uint8_t u8;
+ uint16_t u16;
+ uint32_t u32;
+ uint64_t u64;
+ } u;
+ uint8_t cb;
+} PCIRAWMEMLOC;
+
+/** Parameters buffer for PCIRAWR0_DO_MMIO_WRITE call. */
+typedef struct
+{
+ /* in */
+ RTR0PTR Address;
+ PCIRAWMEMLOC Value;
+} PCIRAWREQMMIOWRITE;
+
+/** Parameters buffer for PCIRAWR0_DO_MMIO_READ call. */
+typedef struct
+{
+ /* in */
+ RTR0PTR Address;
+ /* inout (Value.cb is in) */
+ PCIRAWMEMLOC Value;
+} PCIRAWREQMMIOREAD;
+
+/* Parameters buffer for PCIRAWR0_DO_PCICFG_WRITE call. */
+typedef struct
+{
+ /* in */
+ uint32_t iOffset;
+ PCIRAWMEMLOC Value;
+} PCIRAWREQPCICFGWRITE;
+
+/** Parameters buffer for PCIRAWR0_DO_PCICFG_READ call. */
+typedef struct
+{
+ /* in */
+ uint32_t iOffset;
+ /* inout (Value.cb is in) */
+ PCIRAWMEMLOC Value;
+} PCIRAWREQPCICFGREAD;
+
+/** Parameters buffer for PCIRAWR0_DO_GET_IRQ call. */
+typedef struct PCIRAWREQGETIRQ
+{
+ /* in */
+ int64_t iTimeout;
+ /* out */
+ int32_t iIrq;
+} PCIRAWREQGETIRQ;
+
+/** Parameters buffer for PCIRAWR0_DO_POWER_STATE_CHANGE call. */
+typedef struct PCIRAWREQPOWERSTATECHANGE
+{
+ /* in */
+ uint32_t iState;
+ /* in/out */
+ uint64_t u64Param;
+} PCIRAWREQPOWERSTATECHANGE;
+
+/**
+ * Request buffer use for communication with the driver.
+ */
+typedef struct PCIRAWSENDREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Alternative to passing the taking the session from the VM handle.
+ * Either use this member or use the VM handle, don't do both.
+ */
+ PSUPDRVSESSION pSession;
+ /** Request type. */
+ int32_t iRequest;
+ /** Host device request targetted to. */
+ PCIRAWDEVHANDLE TargetDevice;
+ /** Call parameters. */
+ union
+ {
+ PCIRAWREQOPENDEVICE aOpenDevice;
+ PCIRAWREQCLOSEDEVICE aCloseDevice;
+ PCIRAWREQGETREGIONINFO aGetRegionInfo;
+ PCIRAWREQMAPREGION aMapRegion;
+ PCIRAWREQUNMAPREGION aUnmapRegion;
+ PCIRAWREQPIOWRITE aPioWrite;
+ PCIRAWREQPIOREAD aPioRead;
+ PCIRAWREQMMIOWRITE aMmioWrite;
+ PCIRAWREQMMIOREAD aMmioRead;
+ PCIRAWREQPCICFGWRITE aPciCfgWrite;
+ PCIRAWREQPCICFGREAD aPciCfgRead;
+ PCIRAWREQGETIRQ aGetIrq;
+ PCIRAWREQPOWERSTATECHANGE aPowerStateChange;
+ } u;
+} PCIRAWSENDREQ;
+typedef PCIRAWSENDREQ *PPCIRAWSENDREQ;
+
+/**
+ * Operations performed by the driver.
+ */
+typedef enum PCIRAWR0OPERATION
+{
+ /* Open device. */
+ PCIRAWR0_DO_OPEN_DEVICE,
+ /* Close device. */
+ PCIRAWR0_DO_CLOSE_DEVICE,
+ /* Get PCI region info. */
+ PCIRAWR0_DO_GET_REGION_INFO,
+ /* Map PCI region into VM address space. */
+ PCIRAWR0_DO_MAP_REGION,
+ /* Unmap PCI region from VM address space. */
+ PCIRAWR0_DO_UNMAP_REGION,
+ /* Perform PIO write. */
+ PCIRAWR0_DO_PIO_WRITE,
+ /* Perform PIO read. */
+ PCIRAWR0_DO_PIO_READ,
+ /* Perform MMIO write. */
+ PCIRAWR0_DO_MMIO_WRITE,
+ /* Perform MMIO read. */
+ PCIRAWR0_DO_MMIO_READ,
+ /* Perform PCI config write. */
+ PCIRAWR0_DO_PCICFG_WRITE,
+ /* Perform PCI config read. */
+ PCIRAWR0_DO_PCICFG_READ,
+ /* Get next IRQ for the device. */
+ PCIRAWR0_DO_GET_IRQ,
+ /* Enable getting IRQs for the device. */
+ PCIRAWR0_DO_ENABLE_IRQ,
+ /* Disable getting IRQs for the device. */
+ PCIRAWR0_DO_DISABLE_IRQ,
+ /* Notify driver about guest power state change. */
+ PCIRAWR0_DO_POWER_STATE_CHANGE,
+ /** The usual 32-bit type blow up. */
+ PCIRAWR0_DO_32BIT_HACK = 0x7fffffff
+} PCIRAWR0OPERATION;
+
+/**
+ * Power state enumeration.
+ */
+typedef enum PCIRAWPOWERSTATE
+{
+ /* Power on. */
+ PCIRAW_POWER_ON,
+ /* Power off. */
+ PCIRAW_POWER_OFF,
+ /* Suspend. */
+ PCIRAW_POWER_SUSPEND,
+ /* Resume. */
+ PCIRAW_POWER_RESUME,
+ /* Reset. */
+ PCIRAW_POWER_RESET,
+ /** The usual 32-bit type blow up. */
+ PCIRAW_POWER_32BIT_HACK = 0x7fffffff
+} PCIRAWPOWERSTATE;
+
+
+/** Forward declarations. */
+typedef struct RAWPCIFACTORY *PRAWPCIFACTORY;
+typedef struct RAWPCIDEVPORT *PRAWPCIDEVPORT;
+
+/**
+ * Interrupt service routine callback.
+ *
+ * @returns if interrupt was processed.
+ *
+ * @param pvContext Opaque user data passed to the handler.
+ * @param iIrq Interrupt number.
+ */
+typedef DECLCALLBACK(bool) FNRAWPCIISR(void *pvContext, int32_t iIrq);
+typedef FNRAWPCIISR *PFNRAWPCIISR;
+
+/**
+ * This is the port on the device interface, i.e. the driver side which the
+ * host device is connected to.
+ *
+ * This is only used for the in-kernel PCI device connections.
+ */
+typedef struct RAWPCIDEVPORT
+{
+ /** Structure version number. (RAWPCIDEVPORT_VERSION) */
+ uint32_t u32Version;
+
+ /**
+ * Init device.
+ *
+ * @param pPort Pointer to this structure.
+ * @param fFlags Initialization flags.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnInit,(PRAWPCIDEVPORT pPort,
+ uint32_t fFlags));
+
+
+ /**
+ * Deinit device.
+ *
+ * @param pPort Pointer to this structure.
+ * @param fFlags Initialization flags.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnDeinit,(PRAWPCIDEVPORT pPort,
+ uint32_t fFlags));
+
+
+ /**
+ * Destroy device.
+ *
+ * @param pPort Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnDestroy,(PRAWPCIDEVPORT pPort));
+
+ /**
+ * Get PCI region info.
+ *
+ * @param pPort Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnGetRegionInfo,(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS *pRegionStart,
+ uint64_t *pu64RegionSize,
+ bool *pfPresent,
+ uint32_t *pfFlags));
+
+
+ /**
+ * Map PCI region.
+ *
+ * @param pPort Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnMapRegion,(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ int32_t fFlags,
+ RTR0PTR *pRegionBaseR0));
+
+ /**
+ * Unmap PCI region.
+ *
+ * @param pPort Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnUnmapRegion,(PRAWPCIDEVPORT pPort,
+ int32_t iRegion,
+ RTHCPHYS RegionStart,
+ uint64_t u64RegionSize,
+ RTR0PTR RegionBase));
+
+ /**
+ * Read device PCI register.
+ *
+ * @param pPort Pointer to this structure.
+ * @param Register PCI register.
+ * @param pValue Read value (with desired read width).
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPciCfgRead,(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue));
+
+
+ /**
+ * Write device PCI register.
+ *
+ * @param pPort Pointer to this structure.
+ * @param Register PCI register.
+ * @param pValue Write value (with desired write width).
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPciCfgWrite,(PRAWPCIDEVPORT pPort,
+ uint32_t Register,
+ PCIRAWMEMLOC *pValue));
+
+ /**
+ * Request to register interrupt handler.
+ *
+ * @param pPort Pointer to this structure.
+ * @param pfnHandler Pointer to the handler.
+ * @param pIrqContext Context passed to the handler.
+ * @param phIsr Handle for the ISR, .
+ */
+ DECLR0CALLBACKMEMBER(int, pfnRegisterIrqHandler,(PRAWPCIDEVPORT pPort,
+ PFNRAWPCIISR pfnHandler,
+ void* pIrqContext,
+ PCIRAWISRHANDLE *phIsr));
+
+ /**
+ * Request to unregister interrupt handler.
+ *
+ * @param pPort Pointer to this structure.
+ * @param hIsr Handle of ISR to unregister (retured by earlier pfnRegisterIrqHandler).
+ */
+ DECLR0CALLBACKMEMBER(int, pfnUnregisterIrqHandler,(PRAWPCIDEVPORT pPort,
+ PCIRAWISRHANDLE hIsr));
+
+ /**
+ * Power state change notification.
+ *
+ * @param pPort Pointer to this structure.
+ * @param aState New power state.
+ * @param pu64Param State-specific in/out parameter.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPowerStateChange,(PRAWPCIDEVPORT pPort,
+ PCIRAWPOWERSTATE aState,
+ uint64_t *pu64Param));
+
+ /** Structure version number. (RAWPCIDEVPORT_VERSION) */
+ uint32_t u32VersionEnd;
+} RAWPCIDEVPORT;
+/** Version number for the RAWPCIDEVPORT::u32Version and RAWPCIIFPORT::u32VersionEnd fields. */
+#define RAWPCIDEVPORT_VERSION UINT32_C(0xAFBDCC02)
+
+/**
+ * The component factory interface for create a raw PCI interfaces.
+ */
+typedef struct RAWPCIFACTORY
+{
+ /**
+ * Release this factory.
+ *
+ * SUPR0ComponentQueryFactory (SUPDRVFACTORY::pfnQueryFactoryInterface to be precise)
+ * will retain a reference to the factory and the caller has to call this method to
+ * release it once the pfnCreateAndConnect call(s) has been done.
+ *
+ * @param pIfFactory Pointer to this structure.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnRelease,(PRAWPCIFACTORY pFactory));
+
+ /**
+ * Create an instance for the specfied host PCI card and connects it
+ * to the driver.
+ *
+ *
+ * @returns VBox status code.
+ *
+ * @param pIfFactory Pointer to this structure.
+ * @param u32HostAddress Address of PCI device on the host.
+ * @param fFlags Creation flags.
+ * @param pVmCtx Context of VM where device is created.
+ * @param ppDevPort Where to store the pointer to the device port
+ * on success.
+ *
+ */
+ DECLR0CALLBACKMEMBER(int, pfnCreateAndConnect,(PRAWPCIFACTORY pFactory,
+ uint32_t u32HostAddress,
+ uint32_t fFlags,
+ PRAWPCIPERVM pVmCtx,
+ PRAWPCIDEVPORT *ppDevPort,
+ uint32_t *pfDevFlags));
+
+
+ /**
+ * Initialize per-VM data related to PCI passthrough.
+ *
+ * @returns VBox status code.
+ *
+ * @param pIfFactory Pointer to this structure.
+ * @param pVM Pointer to VM structure to initialize.
+ * @param pPciData Pointer to PCI data.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnInitVm,(PRAWPCIFACTORY pFactory,
+ PVM pVM,
+ PRAWPCIPERVM pPciData));
+
+ /**
+ * Deinitialize per-VM data related to PCI passthrough.
+ *
+ * @returns VBox status code.
+ *
+ * @param pIfFactory Pointer to this structure.
+ * @param pVM Pointer to VM structure to deinitialize.
+ * @param pPciData Pointer to PCI data.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnDeinitVm,(PRAWPCIFACTORY pFactory,
+ PVM pVM,
+ PRAWPCIPERVM pPciData));
+} RAWPCIFACTORY;
+
+#define RAWPCIFACTORY_UUID_STR "ea089839-4171-476f-adfb-9e7ab1cbd0fb"
+
+/**
+ * Flags passed to pfnPciDeviceConstructStart(), to notify driver
+ * about options to be used to open device.
+ */
+typedef enum PCIRAWDRIVERFLAGS
+{
+ /** If runtime shall try to detach host driver. */
+ PCIRAWDRIVERRFLAG_DETACH_HOST_DRIVER = (1 << 0),
+ /** The usual 32-bit type blow up. */
+ PCIRAWDRIVERRFLAG_32BIT_HACK = 0x7fffffff
+} PCIRAWDRIVERFLAGS;
+
+/**
+ * Flags used to describe PCI region, matches to PCIADDRESSSPACE
+ * in pci.h.
+ */
+typedef enum PCIRAWADDRESSSPACE
+{
+ /** Memory. */
+ PCIRAW_ADDRESS_SPACE_MEM = 0x00,
+ /** I/O space. */
+ PCIRAW_ADDRESS_SPACE_IO = 0x01,
+ /** 32-bit BAR. */
+ PCIRAW_ADDRESS_SPACE_BAR32 = 0x00,
+ /** 64-bit BAR. */
+ PCIRAW_ADDRESS_SPACE_BAR64 = 0x04,
+ /** Prefetch memory. */
+ PCIRAW_ADDRESS_SPACE_MEM_PREFETCH = 0x08,
+ /** The usual 32-bit type blow up. */
+ PCIRAW_ADDRESS_SPACE_32BIT_HACK = 0x7fffffff
+} PCIRAWADDRESSSPACE;
+
+RT_C_DECLS_END
+
+/* #define VBOX_WITH_SHARED_PCI_INTERRUPTS */
+
+#endif
diff --git a/include/VBox/scsi.h b/include/VBox/scsi.h
new file mode 100644
index 00000000..20bcd5e1
--- /dev/null
+++ b/include/VBox/scsi.h
@@ -0,0 +1,277 @@
+/** @file
+ * VirtualBox - SCSI declarations. (DEV,+)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_scsi_h
+#define ___VBox_scsi_h
+
+#include <iprt/assert.h>
+
+#ifdef RT_OS_FREEBSD
+/* The cam subsystem doesn't allow more */
+# define SCSI_MAX_BUFFER_SIZE (64 * _1K)
+#else
+# define SCSI_MAX_BUFFER_SIZE (100 * _1K)
+#endif
+
+/**
+ * SCSI command opcode identifiers.
+ *
+ * SCSI-3, so far for CD/DVD Logical Units, from Table 49 of the MMC-3 draft standard.
+ */
+typedef enum SCSICMD
+{
+ SCSI_BLANK = 0xa1,
+ SCSI_CLOSE_TRACK_SESSION = 0x5b,
+ SCSI_ERASE_10 = 0x2c,
+ SCSI_FORMAT_UNIT = 0x04,
+ SCSI_GET_CONFIGURATION = 0x46,
+ SCSI_GET_EVENT_STATUS_NOTIFICATION = 0x4a,
+ SCSI_GET_PERFORMANCE = 0xac,
+ /** Inquiry command. */
+ SCSI_INQUIRY = 0x12,
+ SCSI_LOAD_UNLOAD_MEDIUM = 0xa6,
+ SCSI_MECHANISM_STATUS = 0xbd,
+ SCSI_MODE_SELECT_10 = 0x55,
+ SCSI_MODE_SENSE_10 = 0x5a,
+ SCSI_PAUSE_RESUME = 0x4b,
+ SCSI_PLAY_AUDIO_10 = 0x45,
+ SCSI_PLAY_AUDIO_12 = 0xa5,
+ SCSI_PLAY_AUDIO_MSF = 0x47,
+ SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL = 0x1e,
+ /** Read(10) command. */
+ SCSI_READ_10 = 0x28,
+ SCSI_READ_12 = 0xa8,
+ SCSI_READ_BUFFER = 0x3c,
+ SCSI_READ_BUFFER_CAPACITY = 0x5c,
+ /** Read Capacity(6) command. */
+ SCSI_READ_CAPACITY = 0x25,
+ SCSI_READ_CD = 0xbe,
+ SCSI_READ_CD_MSF = 0xb9,
+ SCSI_READ_DISC_INFORMATION = 0x51,
+ SCSI_READ_DVD_STRUCTURE = 0xad,
+ SCSI_READ_FORMAT_CAPACITIES = 0x23,
+ SCSI_READ_SUBCHANNEL = 0x42,
+ SCSI_READ_TOC_PMA_ATIP = 0x43,
+ SCSI_READ_TRACK_INFORMATION = 0x52,
+ SCSI_REPAIR_TRACK = 0x58,
+ SCSI_REPORT_KEY = 0xa4,
+ SCSI_REQUEST_SENSE = 0x03,
+ SCSI_RESERVE_TRACK = 0x53,
+ SCSI_SCAN = 0xba,
+ SCSI_SEEK_10 = 0x2b,
+ SCSI_SEND_CUE_SHEET = 0x5d,
+ SCSI_SEND_DVD_STRUCTURE = 0xbf,
+ SCSI_SEND_EVENT = 0xa2,
+ SCSI_SEND_KEY = 0xa3,
+ SCSI_SEND_OPC_INFORMATION = 0x54,
+ SCSI_SET_CD_SPEED = 0xbb,
+ SCSI_SET_READ_AHEAD = 0xa7,
+ SCSI_SET_STREAMING = 0xb6,
+ SCSI_START_STOP_UNIT = 0x1b,
+ SCSI_STOP_PLAY_SCAN = 0x4e,
+ /** Synchronize Cache command. */
+ SCSI_SYNCHRONIZE_CACHE = 0x35,
+ SCSI_TEST_UNIT_READY = 0x00,
+ SCSI_VERIFY_10 = 0x2f,
+ /** Write(10) command. */
+ SCSI_WRITE_10 = 0x2a,
+ SCSI_WRITE_12 = 0xaa,
+ SCSI_WRITE_AND_VERIFY_10 = 0x2e,
+ SCSI_WRITE_BUFFER = 0x3b,
+
+ /** Mode Sekect(6) command */
+ SCSI_MODE_SELECT_6 = 0x15,
+ /** Mode Sense(6) command */
+ SCSI_MODE_SENSE_6 = 0x1a,
+ /** Report LUNs command. */
+ SCSI_REPORT_LUNS = 0xa0,
+ SCSI_REPORT_DENSITY = 0x44,
+ /** Rezero Unit command. Obsolete for ages now, but used by cdrecord. */
+ SCSI_REZERO_UNIT = 0x01,
+ SCSI_SERVICE_ACTION_IN_16 = 0x9e,
+ SCSI_READ_16 = 0x88,
+ SCSI_WRITE_16 = 0x8a,
+ SCSI_READ_6 = 0x08,
+ SCSI_WRITE_6 = 0x0a,
+ SCSI_LOG_SENSE = 0x4d,
+ SCSI_UNMAP = 0x42
+} SCSICMD;
+
+/**
+ * Service action in opcode identifiers
+ */
+typedef enum SCSISVCACTIONIN
+{
+ SCSI_SVC_ACTION_IN_READ_CAPACITY_16 = 0x10
+} SCSISVCACTIONIN;
+
+/* Mode page codes for mode sense/select commands. */
+#define SCSI_MODEPAGE_ERROR_RECOVERY 0x01
+#define SCSI_MODEPAGE_WRITE_PARAMETER 0x05
+#define SCSI_MODEPAGE_CD_STATUS 0x2a
+
+
+/* Page control codes. */
+#define SCSI_PAGECONTROL_CURRENT 0x00
+#define SCSI_PAGECONTROL_CHANGEABLE 0x01
+#define SCSI_PAGECONTROL_DEFAULT 0x02
+#define SCSI_PAGECONTROL_SAVED 0x03
+
+
+/* Status codes */
+#define SCSI_STATUS_OK 0x00
+#define SCSI_STATUS_CHECK_CONDITION 0x02
+#define SCSI_STATUS_CONDITION_MET 0x04
+#define SCSI_STATUS_BUSY 0x08
+#define SCSI_STATUS_INTERMEDIATE 0x10
+#define SCSI_STATUS_DATA_UNDEROVER_RUN 0x12
+#define SCSI_STATUS_INTERMEDIATE_CONDITION_MET 0x14
+#define SCSI_STATUS_RESERVATION_CONFLICT 0x18
+#define SCSI_STATUS_COMMAND_TERMINATED 0x22
+#define SCSI_STATUS_QUEUE_FULL 0x28
+#define SCSI_STATUS_ACA_ACTIVE 0x30
+#define SCSI_STATUS_TASK_ABORTED 0x40
+
+/* Sense data response codes - This is the first byte in the sense data */
+#define SCSI_SENSE_RESPONSE_CODE_CURR_FIXED 0x70
+#define SCSI_SENSE_RESPONSE_CODE_DEFERRED_FIXED 0x71
+#define SCSI_SENSE_RESPONSE_CODE_CURR_DESC 0x72
+#define SCSI_SENSE_RESPONSE_CODE_DEFERRED_DESC 0x73
+
+/* Sense keys */
+#define SCSI_SENSE_NONE 0
+#define SCSI_SENSE_RECOVERED_ERROR 1
+#define SCSI_SENSE_NOT_READY 2
+#define SCSI_SENSE_MEDIUM_ERROR 3
+#define SCSI_SENSE_HARDWARE_ERROR 4
+#define SCSI_SENSE_ILLEGAL_REQUEST 5
+#define SCSI_SENSE_UNIT_ATTENTION 6
+#define SCSI_SENSE_DATA_PROTECT 7
+#define SCSI_SENSE_BLANK_CHECK 8
+#define SCSI_SENSE_VENDOR_SPECIFIC 9
+#define SCSI_SENSE_COPY_ABORTED 10
+#define SCSI_SENSE_ABORTED_COMMAND 11
+#define SCSI_SENSE_VOLUME_OVERFLOW 13
+#define SCSI_SENSE_MISCOMPARE 14
+
+
+/* additional sense keys */
+#define SCSI_ASC_NONE 0x00
+#define SCSI_ASC_WRITE_ERROR 0x0c
+#define SCSI_ASC_READ_ERROR 0x11
+#define SCSI_ASC_ILLEGAL_OPCODE 0x20
+#define SCSI_ASC_LOGICAL_BLOCK_OOR 0x21
+#define SCSI_ASC_INV_FIELD_IN_CMD_PACKET 0x24
+#define SCSI_ASC_WRITE_PROTECTED 0x27
+#define SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED 0x28
+#define SCSI_ASC_MEDIUM_NOT_PRESENT 0x3a
+#define SCSI_ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39
+#define SCSI_ASC_INVALID_MESSAGE 0x49
+#define SCSI_ASC_MEDIA_LOAD_OR_EJECT_FAILED 0x53
+#define SCSI_ASC_LOGICAL_UNIT_DOES_NOT_RESPOND_TO_SELECTION 0x00
+#define SCSI_ASC_SYSTEM_RESOURCE_FAILURE 0x55
+
+/** Additional sense code qualifiers (ASCQ). */
+#define SCSI_ASCQ_SYSTEM_BUFFER_FULL 0x01
+
+/** @name SCSI_INQUIRY
+ * @{
+ */
+#pragma pack(1)
+typedef struct SCSIINQUIRYCDB
+{
+ unsigned u8Cmd : 8;
+ unsigned fEVPD : 1;
+ unsigned u4Reserved : 4;
+ unsigned u3LUN : 3;
+ unsigned u8PageCode : 8;
+ unsigned u8Reserved : 8;
+ uint8_t cbAlloc;
+ uint8_t u8Control;
+} SCSIINQUIRYCDB;
+#pragma pack()
+AssertCompileSize(SCSIINQUIRYCDB, 6);
+typedef SCSIINQUIRYCDB *PSCSIINQUIRYCDB;
+typedef const SCSIINQUIRYCDB *PCSCSIINQUIRYCDB;
+
+#pragma pack(1)
+typedef struct SCSIINQUIRYDATA
+{
+ unsigned u5PeripheralDeviceType : 5; /**< 0x00 / 00 */
+ unsigned u3PeripheralQualifier : 3;
+ unsigned u6DeviceTypeModifier : 7; /**< 0x01 */
+ unsigned fRMB : 1;
+ unsigned u3AnsiVersion : 3; /**< 0x02 */
+ unsigned u3EcmaVersion : 3;
+ unsigned u2IsoVersion : 2;
+ unsigned u4ResponseDataFormat : 4; /**< 0x03 */
+ unsigned u2Reserved0 : 2;
+ unsigned fTrmlOP : 1;
+ unsigned fAEC : 1;
+ unsigned cbAdditional : 8; /**< 0x04 */
+ unsigned u8Reserved1 : 8; /**< 0x05 */
+ unsigned u8Reserved2 : 8; /**< 0x06 */
+ unsigned fSftRe : 1; /**< 0x07 */
+ unsigned fCmdQue : 1;
+ unsigned fReserved3 : 1;
+ unsigned fLinked : 1;
+ unsigned fSync : 1;
+ unsigned fWBus16 : 1;
+ unsigned fWBus32 : 1;
+ unsigned fRelAdr : 1;
+ int8_t achVendorId[8]; /**< 0x08 */
+ int8_t achProductId[16]; /**< 0x10 */
+ int8_t achProductLevel[4]; /**< 0x20 */
+ uint8_t abVendorSpecific[20]; /**< 0x24/36 - Optional it seems. */
+ uint8_t abReserved4[40];
+ uint8_t abVendorSpecificParameters[1]; /**< 0x60/96 - Variable size. */
+} SCSIINQUIRYDATA;
+#pragma pack()
+AssertCompileSize(SCSIINQUIRYDATA, 97);
+typedef SCSIINQUIRYDATA *PSCSIINQUIRYDATA;
+typedef const SCSIINQUIRYDATA *PCSCSIINQUIRYDATA;
+
+#define SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_CONNECTED 0x00
+#define SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_BUT_SUPPORTED 0x01
+#define SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_NOT_CONNECTED_NOT_SUPPORTED 0x03
+
+#define SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS 0x00
+#define SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_SEQUENTIAL_ACCESS 0x01
+#define SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_CD_DVD 0x05
+#define SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_UNKNOWN 0x1f
+
+/** @} */
+
+#if defined(IN_RING3) && (defined(LOG_ENABLED) || defined(RT_STRICT))
+const char * SCSICmdText(uint8_t uCmd);
+const char * SCSISenseText(uint8_t uSense);
+const char * SCSISenseExtText(uint8_t uASC, uint8_t uASCQ);
+int SCSILogModePage(char *pszBuf, size_t cchBuffer, uint8_t *pbModePage,
+ size_t cbModePage);
+int SCSILogCueSheet(char *pszBuf, size_t cchBuffer, uint8_t *pbCueSheet,
+ size_t cbCueSheet);
+#endif
+
+#endif
diff --git a/include/VBox/settings.h b/include/VBox/settings.h
new file mode 100644
index 00000000..4c69a0e2
--- /dev/null
+++ b/include/VBox/settings.h
@@ -0,0 +1,1166 @@
+/** @file
+ * Settings file data structures.
+ *
+ * These structures are created by the settings file loader and filled with values
+ * copied from the raw XML data. This was all new with VirtualBox 3.1 and allows us
+ * to finally make the XML reader version-independent and read VirtualBox XML files
+ * from earlier and even newer (future) versions without requiring complicated,
+ * tedious and error-prone XSLT conversions.
+ *
+ * It is this file that defines all structures that map VirtualBox global and
+ * machine settings to XML files. These structures are used by the rest of Main,
+ * even though this header file does not require anything else in Main.
+ *
+ * Note: Headers in Main code have been tweaked to only declare the structures
+ * defined here so that this header need only be included from code files that
+ * actually use these structures.
+ */
+
+/*
+ * Copyright (C) 2007-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_settings_h
+#define ___VBox_settings_h
+
+#include <iprt/time.h>
+
+#include "VBox/com/VirtualBox.h"
+
+#include <VBox/com/Guid.h>
+#include <VBox/com/string.h>
+
+#include <list>
+#include <map>
+
+namespace xml
+{
+ class ElementNode;
+}
+
+namespace settings
+{
+
+class ConfigFileError;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Structures shared between Machine XML and VirtualBox.xml
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * USB device filter definition. This struct is used both in MainConfigFile
+ * (for global USB filters) and MachineConfigFile (for machine filters).
+ *
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct USBDeviceFilter
+{
+ USBDeviceFilter()
+ : fActive(false),
+ action(USBDeviceFilterAction_Null),
+ ulMaskedInterfaces(0)
+ {}
+
+ bool operator==(const USBDeviceFilter&u) const;
+
+ com::Utf8Str strName;
+ bool fActive;
+ com::Utf8Str strVendorId,
+ strProductId,
+ strRevision,
+ strManufacturer,
+ strProduct,
+ strSerialNumber,
+ strPort;
+ USBDeviceFilterAction_T action; // only used with host USB filters
+ com::Utf8Str strRemote; // irrelevant for host USB objects
+ uint32_t ulMaskedInterfaces; // irrelevant for host USB objects
+};
+
+typedef std::map<com::Utf8Str, com::Utf8Str> StringsMap;
+typedef std::list<com::Utf8Str> StringsList;
+
+// ExtraDataItem (used by both VirtualBox.xml and machines XML)
+struct USBDeviceFilter;
+typedef std::list<USBDeviceFilter> USBDeviceFiltersList;
+
+struct Medium;
+typedef std::list<Medium> MediaList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct Medium
+{
+ Medium()
+ : fAutoReset(false),
+ hdType(MediumType_Normal)
+ {}
+
+ com::Guid uuid;
+ com::Utf8Str strLocation;
+ com::Utf8Str strDescription;
+
+ // the following are for hard disks only:
+ com::Utf8Str strFormat;
+ bool fAutoReset; // optional, only for diffs, default is false
+ StringsMap properties;
+ MediumType_T hdType;
+
+ MediaList llChildren; // only used with hard disks
+
+ bool operator==(const Medium &m) const;
+};
+
+/**
+ * A media registry. Starting with VirtualBox 3.3, this can appear in both the
+ * VirtualBox.xml file as well as machine XML files with settings version 1.11
+ * or higher, so these lists are now in ConfigFileBase.
+ *
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct MediaRegistry
+{
+ MediaList llHardDisks,
+ llDvdImages,
+ llFloppyImages;
+
+ bool operator==(const MediaRegistry &m) const;
+};
+
+/**
+ * Common base class for both MainConfigFile and MachineConfigFile
+ * which contains some common logic for both.
+ */
+class ConfigFileBase
+{
+public:
+ bool fileExists();
+
+ void copyBaseFrom(const ConfigFileBase &b);
+
+protected:
+ ConfigFileBase(const com::Utf8Str *pstrFilename);
+ /* Note: this copy constructor doesn't create a full copy of other, cause
+ * the file based stuff (xml doc) could not be copied. */
+ ConfigFileBase(const ConfigFileBase &other);
+
+ ~ConfigFileBase();
+
+ void parseUUID(com::Guid &guid,
+ const com::Utf8Str &strUUID) const;
+ void parseTimestamp(RTTIMESPEC &timestamp,
+ const com::Utf8Str &str) const;
+
+ com::Utf8Str makeString(const RTTIMESPEC &tm);
+
+ void readExtraData(const xml::ElementNode &elmExtraData,
+ StringsMap &map);
+ void readUSBDeviceFilters(const xml::ElementNode &elmDeviceFilters,
+ USBDeviceFiltersList &ll);
+ typedef enum {Error, HardDisk, DVDImage, FloppyImage} MediaType;
+ void readMedium(MediaType t, const xml::ElementNode &elmMedium, MediaList &llMedia);
+ void readMediaRegistry(const xml::ElementNode &elmMediaRegistry, MediaRegistry &mr);
+
+ void setVersionAttribute(xml::ElementNode &elm);
+ void createStubDocument();
+
+ void buildExtraData(xml::ElementNode &elmParent, const StringsMap &me);
+ void buildUSBDeviceFilters(xml::ElementNode &elmParent,
+ const USBDeviceFiltersList &ll,
+ bool fHostMode);
+ void buildMedium(xml::ElementNode &elmMedium,
+ DeviceType_T devType,
+ const Medium &m,
+ uint32_t level);
+ void buildMediaRegistry(xml::ElementNode &elmParent,
+ const MediaRegistry &mr);
+ void clearDocument();
+
+ struct Data;
+ Data *m;
+
+ friend class ConfigFileError;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// VirtualBox.xml structures
+//
+////////////////////////////////////////////////////////////////////////////////
+
+struct Host
+{
+ USBDeviceFiltersList llUSBDeviceFilters;
+};
+
+struct SystemProperties
+{
+ SystemProperties()
+ : ulLogHistoryCount(3)
+ {}
+
+ com::Utf8Str strDefaultMachineFolder;
+ com::Utf8Str strDefaultHardDiskFolder;
+ com::Utf8Str strDefaultHardDiskFormat;
+ com::Utf8Str strVRDEAuthLibrary;
+ com::Utf8Str strWebServiceAuthLibrary;
+ com::Utf8Str strDefaultVRDEExtPack;
+ com::Utf8Str strAutostartDatabasePath;
+ com::Utf8Str strDefaultAdditionsISO;
+ uint32_t ulLogHistoryCount;
+};
+
+struct MachineRegistryEntry
+{
+ com::Guid uuid;
+ com::Utf8Str strSettingsFile;
+};
+typedef std::list<MachineRegistryEntry> MachinesRegistry;
+
+struct DHCPServer
+{
+ DHCPServer()
+ : fEnabled(false)
+ {}
+
+ com::Utf8Str strNetworkName,
+ strIPAddress,
+ strIPNetworkMask,
+ strIPLower,
+ strIPUpper;
+ bool fEnabled;
+};
+typedef std::list<DHCPServer> DHCPServersList;
+
+class MainConfigFile : public ConfigFileBase
+{
+public:
+ MainConfigFile(const com::Utf8Str *pstrFilename);
+
+ void readMachineRegistry(const xml::ElementNode &elmMachineRegistry);
+ void readDHCPServers(const xml::ElementNode &elmDHCPServers);
+
+ void write(const com::Utf8Str strFilename);
+
+ Host host;
+ SystemProperties systemProperties;
+ MediaRegistry mediaRegistry;
+ MachinesRegistry llMachines;
+ DHCPServersList llDhcpServers;
+ StringsMap mapExtraDataItems;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Machine XML structures
+//
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct VRDESettings
+{
+ VRDESettings()
+ : fEnabled(true),
+ authType(AuthType_Null),
+ ulAuthTimeout(5000),
+ fAllowMultiConnection(false),
+ fReuseSingleConnection(false)
+ {}
+
+ bool operator==(const VRDESettings& v) const;
+
+ bool fEnabled;
+ AuthType_T authType;
+ uint32_t ulAuthTimeout;
+ com::Utf8Str strAuthLibrary;
+ bool fAllowMultiConnection,
+ fReuseSingleConnection;
+ com::Utf8Str strVrdeExtPack;
+ StringsMap mapProperties;
+};
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct BIOSSettings
+{
+ BIOSSettings()
+ : fACPIEnabled(true),
+ fIOAPICEnabled(false),
+ fLogoFadeIn(true),
+ fLogoFadeOut(true),
+ ulLogoDisplayTime(0),
+ biosBootMenuMode(BIOSBootMenuMode_MessageAndMenu),
+ fPXEDebugEnabled(false),
+ llTimeOffset(0)
+ {}
+
+ bool operator==(const BIOSSettings &d) const;
+
+ bool fACPIEnabled,
+ fIOAPICEnabled,
+ fLogoFadeIn,
+ fLogoFadeOut;
+ uint32_t ulLogoDisplayTime;
+ com::Utf8Str strLogoImagePath;
+ BIOSBootMenuMode_T biosBootMenuMode;
+ bool fPXEDebugEnabled;
+ int64_t llTimeOffset;
+};
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct USBController
+{
+ USBController()
+ : fEnabled(false),
+ fEnabledEHCI(false)
+ {}
+
+ bool operator==(const USBController &u) const;
+
+ bool fEnabled;
+ bool fEnabledEHCI;
+ USBDeviceFiltersList llDeviceFilters;
+};
+
+ struct NATRule
+ {
+ NATRule()
+ : proto(NATProtocol_TCP),
+ u16HostPort(0),
+ u16GuestPort(0)
+ {}
+
+ bool operator==(const NATRule &r) const
+ {
+ return strName == r.strName
+ && proto == r.proto
+ && u16HostPort == r.u16HostPort
+ && strHostIP == r.strHostIP
+ && u16GuestPort == r.u16GuestPort
+ && strGuestIP == r.strGuestIP;
+ }
+
+ com::Utf8Str strName;
+ NATProtocol_T proto;
+ uint16_t u16HostPort;
+ com::Utf8Str strHostIP;
+ uint16_t u16GuestPort;
+ com::Utf8Str strGuestIP;
+ };
+ typedef std::list<NATRule> NATRuleList;
+
+ struct NAT
+ {
+ NAT()
+ : u32Mtu(0),
+ u32SockRcv(0),
+ u32SockSnd(0),
+ u32TcpRcv(0),
+ u32TcpSnd(0),
+ fDNSPassDomain(true), /* historically this value is true */
+ fDNSProxy(false),
+ fDNSUseHostResolver(false),
+ fAliasLog(false),
+ fAliasProxyOnly(false),
+ fAliasUseSamePorts(false)
+ {}
+
+ bool operator==(const NAT &n) const
+ {
+ return strNetwork == n.strNetwork
+ && strBindIP == n.strBindIP
+ && u32Mtu == n.u32Mtu
+ && u32SockRcv == n.u32SockRcv
+ && u32SockSnd == n.u32SockSnd
+ && u32TcpSnd == n.u32TcpSnd
+ && u32TcpRcv == n.u32TcpRcv
+ && strTFTPPrefix == n.strTFTPPrefix
+ && strTFTPBootFile == n.strTFTPBootFile
+ && strTFTPNextServer == n.strTFTPNextServer
+ && fDNSPassDomain == n.fDNSPassDomain
+ && fDNSProxy == n.fDNSProxy
+ && fDNSUseHostResolver == n.fDNSUseHostResolver
+ && fAliasLog == n.fAliasLog
+ && fAliasProxyOnly == n.fAliasProxyOnly
+ && fAliasUseSamePorts == n.fAliasUseSamePorts
+ && llRules == n.llRules;
+ }
+
+ com::Utf8Str strNetwork;
+ com::Utf8Str strBindIP;
+ uint32_t u32Mtu;
+ uint32_t u32SockRcv;
+ uint32_t u32SockSnd;
+ uint32_t u32TcpRcv;
+ uint32_t u32TcpSnd;
+ com::Utf8Str strTFTPPrefix;
+ com::Utf8Str strTFTPBootFile;
+ com::Utf8Str strTFTPNextServer;
+ bool fDNSPassDomain;
+ bool fDNSProxy;
+ bool fDNSUseHostResolver;
+ bool fAliasLog;
+ bool fAliasProxyOnly;
+ bool fAliasUseSamePorts;
+ NATRuleList llRules;
+ };
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct NetworkAdapter
+{
+ NetworkAdapter()
+ : ulSlot(0),
+ type(NetworkAdapterType_Am79C970A),
+ fEnabled(false),
+ fCableConnected(false),
+ ulLineSpeed(0),
+ enmPromiscModePolicy(NetworkAdapterPromiscModePolicy_Deny),
+ fTraceEnabled(false),
+ mode(NetworkAttachmentType_Null),
+ ulBootPriority(0)
+ {}
+
+ bool operator==(const NetworkAdapter &n) const;
+
+ uint32_t ulSlot;
+
+ NetworkAdapterType_T type;
+ bool fEnabled;
+ com::Utf8Str strMACAddress;
+ bool fCableConnected;
+ uint32_t ulLineSpeed;
+ NetworkAdapterPromiscModePolicy_T enmPromiscModePolicy;
+ bool fTraceEnabled;
+ com::Utf8Str strTraceFile;
+
+ NetworkAttachmentType_T mode;
+ NAT nat;
+ com::Utf8Str strBridgedName;
+ com::Utf8Str strHostOnlyName;
+ com::Utf8Str strInternalNetworkName;
+ com::Utf8Str strGenericDriver;
+ StringsMap genericProperties;
+ uint32_t ulBootPriority;
+ com::Utf8Str strBandwidthGroup; // requires settings version 1.13 (VirtualBox 4.2)
+};
+typedef std::list<NetworkAdapter> NetworkAdaptersList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct SerialPort
+{
+ SerialPort()
+ : ulSlot(0),
+ fEnabled(false),
+ ulIOBase(0x3f8),
+ ulIRQ(4),
+ portMode(PortMode_Disconnected),
+ fServer(false)
+ {}
+
+ bool operator==(const SerialPort &n) const;
+
+ uint32_t ulSlot;
+
+ bool fEnabled;
+ uint32_t ulIOBase;
+ uint32_t ulIRQ;
+ PortMode_T portMode;
+ com::Utf8Str strPath;
+ bool fServer;
+};
+typedef std::list<SerialPort> SerialPortsList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct ParallelPort
+{
+ ParallelPort()
+ : ulSlot(0),
+ fEnabled(false),
+ ulIOBase(0x378),
+ ulIRQ(7)
+ {}
+
+ bool operator==(const ParallelPort &d) const;
+
+ uint32_t ulSlot;
+
+ bool fEnabled;
+ uint32_t ulIOBase;
+ uint32_t ulIRQ;
+ com::Utf8Str strPath;
+};
+typedef std::list<ParallelPort> ParallelPortsList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct AudioAdapter
+{
+ AudioAdapter()
+ : fEnabled(true),
+ controllerType(AudioControllerType_AC97),
+ driverType(AudioDriverType_Null)
+ {}
+
+ bool operator==(const AudioAdapter &a) const
+ {
+ return (this == &a)
+ || ( (fEnabled == a.fEnabled)
+ && (controllerType == a.controllerType)
+ && (driverType == a.driverType)
+ );
+ }
+
+ bool fEnabled;
+ AudioControllerType_T controllerType;
+ AudioDriverType_T driverType;
+};
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct SharedFolder
+{
+ SharedFolder()
+ : fWritable(false)
+ , fAutoMount(false)
+ {}
+
+ bool operator==(const SharedFolder &a) const;
+
+ com::Utf8Str strName,
+ strHostPath;
+ bool fWritable;
+ bool fAutoMount;
+};
+typedef std::list<SharedFolder> SharedFoldersList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct GuestProperty
+{
+ GuestProperty()
+ : timestamp(0)
+ {};
+
+ bool operator==(const GuestProperty &g) const;
+
+ com::Utf8Str strName,
+ strValue;
+ uint64_t timestamp;
+ com::Utf8Str strFlags;
+};
+typedef std::list<GuestProperty> GuestPropertiesList;
+
+typedef std::map<uint32_t, DeviceType_T> BootOrderMap;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct CpuIdLeaf
+{
+ CpuIdLeaf()
+ : ulId(UINT32_MAX),
+ ulEax(0),
+ ulEbx(0),
+ ulEcx(0),
+ ulEdx(0)
+ {}
+
+ bool operator==(const CpuIdLeaf &c) const
+ {
+ return ( (this == &c)
+ || ( (ulId == c.ulId)
+ && (ulEax == c.ulEax)
+ && (ulEbx == c.ulEbx)
+ && (ulEcx == c.ulEcx)
+ && (ulEdx == c.ulEdx)
+ )
+ );
+ }
+
+ uint32_t ulId;
+ uint32_t ulEax;
+ uint32_t ulEbx;
+ uint32_t ulEcx;
+ uint32_t ulEdx;
+};
+typedef std::list<CpuIdLeaf> CpuIdLeafsList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct Cpu
+{
+ Cpu()
+ : ulId(UINT32_MAX)
+ {}
+
+ bool operator==(const Cpu &c) const
+ {
+ return (ulId == c.ulId);
+ }
+
+ uint32_t ulId;
+};
+typedef std::list<Cpu> CpuList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct BandwidthGroup
+{
+ BandwidthGroup()
+ : cMaxBytesPerSec(0),
+ enmType(BandwidthGroupType_Null)
+ {}
+
+ bool operator==(const BandwidthGroup &i) const
+ {
+ return ( (strName == i.strName)
+ && (cMaxBytesPerSec == i.cMaxBytesPerSec)
+ && (enmType == i.enmType));
+ }
+
+ com::Utf8Str strName;
+ uint64_t cMaxBytesPerSec;
+ BandwidthGroupType_T enmType;
+};
+typedef std::list<BandwidthGroup> BandwidthGroupList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct IOSettings
+{
+ IOSettings();
+
+ bool operator==(const IOSettings &i) const
+ {
+ return ( (fIOCacheEnabled == i.fIOCacheEnabled)
+ && (ulIOCacheSize == i.ulIOCacheSize)
+ && (llBandwidthGroups == i.llBandwidthGroups));
+ }
+
+ bool fIOCacheEnabled;
+ uint32_t ulIOCacheSize;
+ BandwidthGroupList llBandwidthGroups;
+};
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct HostPCIDeviceAttachment
+{
+ HostPCIDeviceAttachment()
+ : uHostAddress(0),
+ uGuestAddress(0)
+ {}
+
+ bool operator==(const HostPCIDeviceAttachment &a) const
+ {
+ return ( (uHostAddress == a.uHostAddress)
+ && (uGuestAddress == a.uGuestAddress)
+ && (strDeviceName == a.strDeviceName)
+ );
+ }
+
+ com::Utf8Str strDeviceName;
+ uint32_t uHostAddress;
+ uint32_t uGuestAddress;
+};
+typedef std::list<HostPCIDeviceAttachment> HostPCIDeviceAttachmentList;
+
+/**
+ * Representation of Machine hardware; this is used in the MachineConfigFile.hardwareMachine
+ * field.
+ *
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct Hardware
+{
+ Hardware();
+
+ bool operator==(const Hardware&) const;
+
+ com::Utf8Str strVersion; // hardware version, optional
+ com::Guid uuid; // hardware uuid, optional (null).
+
+ bool fHardwareVirt,
+ fHardwareVirtExclusive,
+ fNestedPaging,
+ fLargePages,
+ fVPID,
+ fHardwareVirtForce,
+ fSyntheticCpu,
+ fPAE;
+ uint32_t cCPUs;
+ bool fCpuHotPlug; // requires settings version 1.10 (VirtualBox 3.2)
+ CpuList llCpus; // requires settings version 1.10 (VirtualBox 3.2)
+ bool fHPETEnabled; // requires settings version 1.10 (VirtualBox 3.2)
+ uint32_t ulCpuExecutionCap; // requires settings version 1.11 (VirtualBox 3.3)
+
+ CpuIdLeafsList llCpuIdLeafs;
+
+ uint32_t ulMemorySizeMB;
+
+ BootOrderMap mapBootOrder; // item 0 has highest priority
+
+ uint32_t ulVRAMSizeMB;
+ uint32_t cMonitors;
+ bool fAccelerate3D,
+ fAccelerate2DVideo; // requires settings version 1.8 (VirtualBox 3.1)
+ uint32_t ulVideoCaptureHorzRes;
+ uint32_t ulVideoCaptureVertRes;
+ bool fVideoCaptureEnabled;
+ com::Utf8Str strVideoCaptureFile;
+ FirmwareType_T firmwareType; // requires settings version 1.9 (VirtualBox 3.1)
+
+ PointingHIDType_T pointingHIDType; // requires settings version 1.10 (VirtualBox 3.2)
+ KeyboardHIDType_T keyboardHIDType; // requires settings version 1.10 (VirtualBox 3.2)
+
+ ChipsetType_T chipsetType; // requires settings version 1.11 (VirtualBox 4.0)
+
+ bool fEmulatedUSBCardReader; // 1.12 (VirtualBox 4.1)
+
+ VRDESettings vrdeSettings;
+
+ BIOSSettings biosSettings;
+ USBController usbController;
+ NetworkAdaptersList llNetworkAdapters;
+ SerialPortsList llSerialPorts;
+ ParallelPortsList llParallelPorts;
+ AudioAdapter audioAdapter;
+
+ // technically these two have no business in the hardware section, but for some
+ // clever reason <Hardware> is where they are in the XML....
+ SharedFoldersList llSharedFolders;
+ ClipboardMode_T clipboardMode;
+ DragAndDropMode_T dragAndDropMode;
+
+ uint32_t ulMemoryBalloonSize;
+ bool fPageFusionEnabled;
+
+ GuestPropertiesList llGuestProperties;
+ com::Utf8Str strNotificationPatterns;
+
+ IOSettings ioSettings; // requires settings version 1.10 (VirtualBox 3.2)
+ HostPCIDeviceAttachmentList pciAttachments; // requires settings version 1.12 (VirtualBox 4.1)
+};
+
+/**
+ * A device attached to a storage controller. This can either be a
+ * hard disk or a DVD drive or a floppy drive and also specifies
+ * which medium is "in" the drive; as a result, this is a combination
+ * of the Main IMedium and IMediumAttachment interfaces.
+ *
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct AttachedDevice
+{
+ AttachedDevice()
+ : deviceType(DeviceType_Null),
+ fPassThrough(false),
+ fTempEject(false),
+ fNonRotational(false),
+ lPort(0),
+ lDevice(0)
+ {}
+
+ bool operator==(const AttachedDevice &a) const;
+
+ DeviceType_T deviceType; // only HardDisk, DVD or Floppy are allowed
+
+ // DVDs can be in pass-through mode:
+ bool fPassThrough;
+
+ // Whether guest-triggered eject of DVDs will keep the medium in the
+ // VM config or not:
+ bool fTempEject;
+
+ // Whether the medium is non-rotational:
+ bool fNonRotational;
+
+ // Whether the medium supports discarding unused blocks:
+ bool fDiscard;
+
+ int32_t lPort;
+ int32_t lDevice;
+
+ // if an image file is attached to the device (ISO, RAW, or hard disk image such as VDI),
+ // this is its UUID; it depends on deviceType which media registry this then needs to
+ // be looked up in. If no image file (only permitted for DVDs and floppies), then the UUID is NULL
+ com::Guid uuid;
+
+ // for DVDs and floppies, the attachment can also be a host device:
+ com::Utf8Str strHostDriveSrc; // if != NULL, value of <HostDrive>/@src
+
+ // Bandwidth group the device is attached to.
+ com::Utf8Str strBwGroup;
+};
+typedef std::list<AttachedDevice> AttachedDevicesList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct StorageController
+{
+ StorageController()
+ : storageBus(StorageBus_IDE),
+ controllerType(StorageControllerType_PIIX3),
+ ulPortCount(2),
+ ulInstance(0),
+ fUseHostIOCache(true),
+ fBootable(true),
+ lIDE0MasterEmulationPort(0),
+ lIDE0SlaveEmulationPort(0),
+ lIDE1MasterEmulationPort(0),
+ lIDE1SlaveEmulationPort(0)
+ {}
+
+ bool operator==(const StorageController &s) const;
+
+ com::Utf8Str strName;
+ StorageBus_T storageBus; // _SATA, _SCSI, _IDE, _SAS
+ StorageControllerType_T controllerType;
+ uint32_t ulPortCount;
+ uint32_t ulInstance;
+ bool fUseHostIOCache;
+ bool fBootable;
+
+ // only for when controllerType == StorageControllerType_IntelAhci:
+ int32_t lIDE0MasterEmulationPort,
+ lIDE0SlaveEmulationPort,
+ lIDE1MasterEmulationPort,
+ lIDE1SlaveEmulationPort;
+
+ AttachedDevicesList llAttachedDevices;
+};
+typedef std::list<StorageController> StorageControllersList;
+
+/**
+ * We wrap the storage controllers list into an extra struct so we can
+ * use an undefined struct without needing std::list<> in all the headers.
+ *
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct Storage
+{
+ bool operator==(const Storage &s) const;
+
+ StorageControllersList llStorageControllers;
+};
+
+/**
+ * Settings that has to do with debugging.
+ */
+struct Debugging
+{
+ Debugging()
+ : fTracingEnabled(false),
+ fAllowTracingToAccessVM(false),
+ strTracingConfig()
+ { }
+
+ bool operator==(const Debugging &rOther) const
+ {
+ return fTracingEnabled == rOther.fTracingEnabled
+ && fAllowTracingToAccessVM == rOther.fAllowTracingToAccessVM
+ && strTracingConfig == rOther.strTracingConfig;
+ }
+
+ bool areDefaultSettings() const
+ {
+ return !fTracingEnabled
+ && !fAllowTracingToAccessVM
+ && strTracingConfig.isEmpty();
+ }
+
+ bool fTracingEnabled;
+ bool fAllowTracingToAccessVM;
+ com::Utf8Str strTracingConfig;
+};
+
+/**
+ * Settings that has to do with autostart.
+ */
+struct Autostart
+{
+ Autostart()
+ : fAutostartEnabled(false),
+ uAutostartDelay(0),
+ enmAutostopType(AutostopType_Disabled)
+ { }
+
+ bool operator==(const Autostart &rOther) const
+ {
+ return fAutostartEnabled == rOther.fAutostartEnabled
+ && uAutostartDelay == rOther.uAutostartDelay
+ && enmAutostopType == rOther.enmAutostopType;
+ }
+
+ bool areDefaultSettings() const
+ {
+ return !fAutostartEnabled
+ && !uAutostartDelay
+ && enmAutostopType == AutostopType_Disabled;
+ }
+
+ bool fAutostartEnabled;
+ uint32_t uAutostartDelay;
+ AutostopType_T enmAutostopType;
+};
+
+struct Snapshot;
+typedef std::list<Snapshot> SnapshotsList;
+
+/**
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by MachineConfigFile::operator==(), or otherwise
+ * your settings might never get saved.
+ */
+struct Snapshot
+{
+ bool operator==(const Snapshot &s) const;
+
+ com::Guid uuid;
+ com::Utf8Str strName,
+ strDescription; // optional
+ RTTIMESPEC timestamp;
+
+ com::Utf8Str strStateFile; // for online snapshots only
+
+ Hardware hardware;
+ Storage storage;
+
+ Debugging debugging;
+ Autostart autostart;
+
+ SnapshotsList llChildSnapshots;
+};
+
+struct MachineUserData
+{
+ MachineUserData()
+ : fDirectoryIncludesUUID(false),
+ fNameSync(true),
+ fTeleporterEnabled(false),
+ uTeleporterPort(0),
+ enmFaultToleranceState(FaultToleranceState_Inactive),
+ uFaultTolerancePort(0),
+ uFaultToleranceInterval(0),
+ fRTCUseUTC(false)
+ {
+ llGroups.push_back("/");
+ }
+
+ bool operator==(const MachineUserData &c) const
+ {
+ return (strName == c.strName)
+ && (fDirectoryIncludesUUID == c.fDirectoryIncludesUUID)
+ && (fNameSync == c.fNameSync)
+ && (strDescription == c.strDescription)
+ && (llGroups == c.llGroups)
+ && (strOsType == c.strOsType)
+ && (strSnapshotFolder == c.strSnapshotFolder)
+ && (fTeleporterEnabled == c.fTeleporterEnabled)
+ && (uTeleporterPort == c.uTeleporterPort)
+ && (strTeleporterAddress == c.strTeleporterAddress)
+ && (strTeleporterPassword == c.strTeleporterPassword)
+ && (enmFaultToleranceState == c.enmFaultToleranceState)
+ && (uFaultTolerancePort == c.uFaultTolerancePort)
+ && (uFaultToleranceInterval == c.uFaultToleranceInterval)
+ && (strFaultToleranceAddress == c.strFaultToleranceAddress)
+ && (strFaultTolerancePassword == c.strFaultTolerancePassword)
+ && (fRTCUseUTC == c.fRTCUseUTC);
+ }
+
+ com::Utf8Str strName;
+ bool fDirectoryIncludesUUID;
+ bool fNameSync;
+ com::Utf8Str strDescription;
+ StringsList llGroups;
+ com::Utf8Str strOsType;
+ com::Utf8Str strSnapshotFolder;
+ bool fTeleporterEnabled;
+ uint32_t uTeleporterPort;
+ com::Utf8Str strTeleporterAddress;
+ com::Utf8Str strTeleporterPassword;
+ FaultToleranceState_T enmFaultToleranceState;
+ uint32_t uFaultTolerancePort;
+ com::Utf8Str strFaultToleranceAddress;
+ com::Utf8Str strFaultTolerancePassword;
+ uint32_t uFaultToleranceInterval;
+ bool fRTCUseUTC;
+};
+
+/**
+ * MachineConfigFile represents an XML machine configuration. All the machine settings
+ * that go out to the XML (or are read from it) are in here.
+ *
+ * NOTE: If you add any fields in here, you must update a) the constructor and b)
+ * the operator== which is used by Machine::saveSettings(), or otherwise your settings
+ * might never get saved.
+ */
+class MachineConfigFile : public ConfigFileBase
+{
+public:
+ com::Guid uuid;
+
+ MachineUserData machineUserData;
+
+ com::Utf8Str strStateFile;
+ bool fCurrentStateModified; // optional, default is true
+ RTTIMESPEC timeLastStateChange; // optional, defaults to now
+ bool fAborted; // optional, default is false
+
+ com::Guid uuidCurrentSnapshot;
+
+ Hardware hardwareMachine;
+ Storage storageMachine;
+ MediaRegistry mediaRegistry;
+ Debugging debugging;
+ Autostart autostart;
+
+ StringsMap mapExtraDataItems;
+
+ SnapshotsList llFirstSnapshot; // first snapshot or empty list if there's none
+
+ MachineConfigFile(const com::Utf8Str *pstrFilename);
+
+ bool operator==(const MachineConfigFile &m) const;
+
+ bool canHaveOwnMediaRegistry() const;
+
+ void importMachineXML(const xml::ElementNode &elmMachine);
+
+ void write(const com::Utf8Str &strFilename);
+
+ enum
+ {
+ BuildMachineXML_IncludeSnapshots = 0x01,
+ BuildMachineXML_WriteVboxVersionAttribute = 0x02,
+ BuildMachineXML_SkipRemovableMedia = 0x04,
+ BuildMachineXML_MediaRegistry = 0x08,
+ BuildMachineXML_SuppressSavedState = 0x10
+ };
+ void buildMachineXML(xml::ElementNode &elmMachine,
+ uint32_t fl,
+ std::list<xml::ElementNode*> *pllElementsWithUuidAttributes);
+
+ static bool isAudioDriverAllowedOnThisHost(AudioDriverType_T drv);
+ static AudioDriverType_T getHostDefaultAudioDriver();
+
+private:
+ void readNetworkAdapters(const xml::ElementNode &elmHardware, NetworkAdaptersList &ll);
+ void readAttachedNetworkMode(const xml::ElementNode &pelmMode, bool fEnabled, NetworkAdapter &nic);
+ void readCpuIdTree(const xml::ElementNode &elmCpuid, CpuIdLeafsList &ll);
+ void readCpuTree(const xml::ElementNode &elmCpu, CpuList &ll);
+ void readSerialPorts(const xml::ElementNode &elmUART, SerialPortsList &ll);
+ void readParallelPorts(const xml::ElementNode &elmLPT, ParallelPortsList &ll);
+ void readAudioAdapter(const xml::ElementNode &elmAudioAdapter, AudioAdapter &aa);
+ void readGuestProperties(const xml::ElementNode &elmGuestProperties, Hardware &hw);
+ void readStorageControllerAttributes(const xml::ElementNode &elmStorageController, StorageController &sctl);
+ void readHardware(const xml::ElementNode &elmHardware, Hardware &hw, Storage &strg);
+ void readHardDiskAttachments_pre1_7(const xml::ElementNode &elmHardDiskAttachments, Storage &strg);
+ void readStorageControllers(const xml::ElementNode &elmStorageControllers, Storage &strg);
+ void readDVDAndFloppies_pre1_9(const xml::ElementNode &elmHardware, Storage &strg);
+ void readTeleporter(const xml::ElementNode *pElmTeleporter, MachineUserData *pUserData);
+ void readDebugging(const xml::ElementNode *pElmDbg, Debugging *pDbg);
+ void readAutostart(const xml::ElementNode *pElmAutostart, Autostart *pAutostart);
+ void readGroups(const xml::ElementNode *elmGroups, StringsList *pllGroups);
+ void readSnapshot(const xml::ElementNode &elmSnapshot, Snapshot &snap);
+ void convertOldOSType_pre1_5(com::Utf8Str &str);
+ void readMachine(const xml::ElementNode &elmMachine);
+
+ void buildHardwareXML(xml::ElementNode &elmParent, const Hardware &hw, const Storage &strg);
+ void buildNetworkXML(NetworkAttachmentType_T mode, xml::ElementNode &elmParent, bool fEnabled, const NetworkAdapter &nic);
+ void buildStorageControllersXML(xml::ElementNode &elmParent,
+ const Storage &st,
+ bool fSkipRemovableMedia,
+ std::list<xml::ElementNode*> *pllElementsWithUuidAttributes);
+ void buildDebuggingXML(xml::ElementNode *pElmParent, const Debugging *pDbg);
+ void buildAutostartXML(xml::ElementNode *pElmParent, const Autostart *pAutostart);
+ void buildGroupsXML(xml::ElementNode *pElmParent, const StringsList *pllGroups);
+ void buildSnapshotXML(xml::ElementNode &elmParent, const Snapshot &snap);
+
+ void bumpSettingsVersionIfNeeded();
+};
+
+} // namespace settings
+
+
+#endif /* ___VBox_settings_h */
diff --git a/include/VBox/shflsvc.h b/include/VBox/shflsvc.h
new file mode 100644
index 00000000..923e25a7
--- /dev/null
+++ b/include/VBox/shflsvc.h
@@ -0,0 +1,1364 @@
+/** @file
+ * Shared Folders: Common header for host service and guest clients.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_shflsvc_h
+#define ___VBox_shflsvc_h
+
+#include <VBox/types.h>
+#include <VBox/VBoxGuest2.h>
+#include <VBox/VMMDev.h>
+#include <VBox/hgcmsvc.h>
+#include <iprt/fs.h>
+
+
+/** @name Some bit flag manipulation macros.
+ * @{ */
+#ifndef BIT_FLAG
+#define BIT_FLAG(__Field,__Flag) ((__Field) & (__Flag))
+#endif
+
+#ifndef BIT_FLAG_SET
+#define BIT_FLAG_SET(__Field,__Flag) ((__Field) |= (__Flag))
+#endif
+
+#ifndef BIT_FLAG_CLEAR
+#define BIT_FLAG_CLEAR(__Field,__Flag) ((__Field) &= ~(__Flag))
+#endif
+/** @} */
+
+
+/**
+ * Structures shared between guest and the service
+ * can be relocated and use offsets to point to variable
+ * length parts.
+ */
+
+/**
+ * Shared folders protocol works with handles.
+ * Before doing any action on a file system object,
+ * one have to obtain the object handle via a SHFL_FN_CREATE
+ * request. A handle must be closed with SHFL_FN_CLOSE.
+ */
+
+/** Shared Folders service functions. (guest)
+ * @{
+ */
+
+/** Query mappings changes. */
+#define SHFL_FN_QUERY_MAPPINGS (1)
+/** Query mappings changes. */
+#define SHFL_FN_QUERY_MAP_NAME (2)
+/** Open/create object. */
+#define SHFL_FN_CREATE (3)
+/** Close object handle. */
+#define SHFL_FN_CLOSE (4)
+/** Read object content. */
+#define SHFL_FN_READ (5)
+/** Write new object content. */
+#define SHFL_FN_WRITE (6)
+/** Lock/unlock a range in the object. */
+#define SHFL_FN_LOCK (7)
+/** List object content. */
+#define SHFL_FN_LIST (8)
+/** Query/set object information. */
+#define SHFL_FN_INFORMATION (9)
+/** Remove object */
+#define SHFL_FN_REMOVE (11)
+/** Map folder (legacy) */
+#define SHFL_FN_MAP_FOLDER_OLD (12)
+/** Unmap folder */
+#define SHFL_FN_UNMAP_FOLDER (13)
+/** Rename object (possibly moving it to another directory) */
+#define SHFL_FN_RENAME (14)
+/** Flush file */
+#define SHFL_FN_FLUSH (15)
+/** @todo macl, a description, please. */
+#define SHFL_FN_SET_UTF8 (16)
+/** Map folder */
+#define SHFL_FN_MAP_FOLDER (17)
+/** Read symlink destination (as of VBox 4.0) */
+#define SHFL_FN_READLINK (18)
+/** Create symlink (as of VBox 4.0) */
+#define SHFL_FN_SYMLINK (19)
+/** Ask host to show symlinks (as of VBox 4.0) */
+#define SHFL_FN_SET_SYMLINKS (20)
+
+/** @} */
+
+/** Shared Folders service functions. (host)
+ * @{
+ */
+
+/** Add shared folder mapping. */
+#define SHFL_FN_ADD_MAPPING (1)
+/** Remove shared folder mapping. */
+#define SHFL_FN_REMOVE_MAPPING (2)
+/** Set the led status light address. */
+#define SHFL_FN_SET_STATUS_LED (3)
+/** Allow the guest to create symbolic links (as of VBox 4.0) */
+#define SHFL_FN_ALLOW_SYMLINKS_CREATE (4)
+/** @} */
+
+/** Root handle for a mapping. Root handles are unique.
+ * @note
+ * Function parameters structures consider
+ * the root handle as 32 bit value. If the typedef
+ * will be changed, then function parameters must be
+ * changed accordingly. All those parameters are marked
+ * with SHFLROOT in comments.
+ */
+typedef uint32_t SHFLROOT;
+
+#define SHFL_ROOT_NIL ((SHFLROOT)~0)
+
+
+/** A shared folders handle for an opened object. */
+typedef uint64_t SHFLHANDLE;
+
+#define SHFL_HANDLE_NIL ((SHFLHANDLE)~0LL)
+#define SHFL_HANDLE_ROOT ((SHFLHANDLE)0LL)
+
+/** Hardcoded maximum length (in chars) of a shared folder name. */
+#define SHFL_MAX_LEN (256)
+/** Hardcoded maximum number of shared folder mapping available to the guest. */
+#define SHFL_MAX_MAPPINGS (64)
+
+/** @name Shared Folders strings. They can be either UTF-8 or UTF-16.
+ * @{
+ */
+
+/**
+ * Shared folder string buffer structure.
+ */
+typedef struct _SHFLSTRING
+{
+ /** Size of the String member in bytes. */
+ uint16_t u16Size;
+
+ /** Length of string without trailing nul in bytes. */
+ uint16_t u16Length;
+
+ /** UTF-8 or UTF-16 string. Nul terminated. */
+ union
+ {
+ uint8_t utf8[1];
+ uint16_t ucs2[1];
+ } String;
+} SHFLSTRING;
+
+/** Pointer to a shared folder string buffer. */
+typedef SHFLSTRING *PSHFLSTRING;
+/** Pointer to a const shared folder string buffer. */
+typedef const SHFLSTRING *PCSHFLSTRING;
+
+/** Calculate size of the string. */
+DECLINLINE(uint32_t) ShflStringSizeOfBuffer(PCSHFLSTRING pString)
+{
+ return pString? sizeof (SHFLSTRING) - sizeof (pString->String) + pString->u16Size: 0;
+}
+
+DECLINLINE(uint32_t) ShflStringLength(PCSHFLSTRING pString)
+{
+ return pString? pString->u16Length: 0;
+}
+
+DECLINLINE(PSHFLSTRING) ShflStringInitBuffer(void *pvBuffer, uint32_t u32Size)
+{
+ PSHFLSTRING pString = NULL;
+
+ uint32_t u32HeaderSize = sizeof (SHFLSTRING) - sizeof (pString->String);
+
+ /* Check that the buffer size is big enough to hold a zero sized string
+ * and is not too big to fit into 16 bit variables.
+ */
+ if (u32Size >= u32HeaderSize && u32Size - u32HeaderSize <= 0xFFFF)
+ {
+ pString = (PSHFLSTRING)pvBuffer;
+ pString->u16Size = u32Size - u32HeaderSize;
+ pString->u16Length = 0;
+ }
+
+ return pString;
+}
+
+/**
+ * Validates a HGCM string parameter.
+ *
+ * @returns true if valid, false if not.
+ *
+ * @param pString The string buffer pointer.
+ * @param cbBuf The buffer size from the parameter.
+ */
+DECLINLINE(bool) ShflStringIsValid(PCSHFLSTRING pString, uint32_t cbBuf)
+{
+ if (RT_UNLIKELY(cbBuf <= RT_UOFFSETOF(SHFLSTRING, String)))
+ return false;
+ if (RT_UNLIKELY((uint32_t)pString->u16Size + RT_UOFFSETOF(SHFLSTRING, String) > cbBuf))
+ return false;
+ if (RT_UNLIKELY(pString->u16Length >= pString->u16Size))
+ return false;
+ return true;
+}
+
+/**
+ * Validates an optional HGCM string parameter.
+ *
+ * @returns true if valid, false if not.
+ *
+ * @param pString The string buffer pointer. Can be NULL.
+ * @param cbBuf The buffer size from the parameter.
+ */
+DECLINLINE(bool) ShflStringIsValidOrNull(PCSHFLSTRING pString, uint32_t cbBuf)
+{
+ if (pString)
+ return ShflStringIsValid(pString, cbBuf);
+ if (RT_UNLIKELY(cbBuf > 0))
+ return false;
+ return true;
+}
+
+/** @} */
+
+
+/**
+ * The available additional information in a SHFLFSOBJATTR object.
+ */
+typedef enum SHFLFSOBJATTRADD
+{
+ /** No additional information is available / requested. */
+ SHFLFSOBJATTRADD_NOTHING = 1,
+ /** The additional unix attributes (SHFLFSOBJATTR::u::Unix) are
+ * available / requested. */
+ SHFLFSOBJATTRADD_UNIX,
+ /** The additional extended attribute size (SHFLFSOBJATTR::u::EASize) is
+ * available / requested. */
+ SHFLFSOBJATTRADD_EASIZE,
+ /** The last valid item (inclusive).
+ * The valid range is SHFLFSOBJATTRADD_NOTHING thru
+ * SHFLFSOBJATTRADD_LAST. */
+ SHFLFSOBJATTRADD_LAST = SHFLFSOBJATTRADD_EASIZE,
+
+ /** The usual 32-bit hack. */
+ SHFLFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff
+} SHFLFSOBJATTRADD;
+
+
+/* Assert sizes of the IRPT types we're using below. */
+AssertCompileSize(RTFMODE, 4);
+AssertCompileSize(RTFOFF, 8);
+AssertCompileSize(RTINODE, 8);
+AssertCompileSize(RTTIMESPEC, 8);
+AssertCompileSize(RTDEV, 4);
+AssertCompileSize(RTUID, 4);
+
+/**
+ * Shared folder filesystem object attributes.
+ */
+#pragma pack(1)
+typedef struct SHFLFSOBJATTR
+{
+ /** Mode flags (st_mode). RTFS_UNIX_*, RTFS_TYPE_*, and RTFS_DOS_*.
+ * @remarks We depend on a number of RTFS_ defines to remain unchanged.
+ * Fortuntately, these are depending on windows, dos and unix
+ * standard values, so this shouldn't be much of a pain. */
+ RTFMODE fMode;
+
+ /** The additional attributes available. */
+ SHFLFSOBJATTRADD enmAdditional;
+
+ /**
+ * Additional attributes.
+ *
+ * Unless explicitly specified to an API, the API can provide additional
+ * data as it is provided by the underlying OS.
+ */
+ union SHFLFSOBJATTRUNION
+ {
+ /** Additional Unix Attributes
+ * These are available when SHFLFSOBJATTRADD is set in fUnix.
+ */
+ struct SHFLFSOBJATTRUNIX
+ {
+ /** The user owning the filesystem object (st_uid).
+ * This field is ~0U if not supported. */
+ RTUID uid;
+
+ /** The group the filesystem object is assigned (st_gid).
+ * This field is ~0U if not supported. */
+ RTGID gid;
+
+ /** Number of hard links to this filesystem object (st_nlink).
+ * This field is 1 if the filesystem doesn't support hardlinking or
+ * the information isn't available.
+ */
+ uint32_t cHardlinks;
+
+ /** The device number of the device which this filesystem object resides on (st_dev).
+ * This field is 0 if this information is not available. */
+ RTDEV INodeIdDevice;
+
+ /** The unique identifier (within the filesystem) of this filesystem object (st_ino).
+ * Together with INodeIdDevice, this field can be used as a OS wide unique id
+ * when both their values are not 0.
+ * This field is 0 if the information is not available. */
+ RTINODE INodeId;
+
+ /** User flags (st_flags).
+ * This field is 0 if this information is not available. */
+ uint32_t fFlags;
+
+ /** The current generation number (st_gen).
+ * This field is 0 if this information is not available. */
+ uint32_t GenerationId;
+
+ /** The device number of a character or block device type object (st_rdev).
+ * This field is 0 if the file isn't of a character or block device type and
+ * when the OS doesn't subscribe to the major+minor device idenfication scheme. */
+ RTDEV Device;
+ } Unix;
+
+ /**
+ * Extended attribute size.
+ */
+ struct SHFLFSOBJATTREASIZE
+ {
+ /** Size of EAs. */
+ RTFOFF cb;
+ } EASize;
+ } u;
+} SHFLFSOBJATTR;
+#pragma pack()
+AssertCompileSize(SHFLFSOBJATTR, 44);
+/** Pointer to a shared folder filesystem object attributes structure. */
+typedef SHFLFSOBJATTR *PSHFLFSOBJATTR;
+/** Pointer to a const shared folder filesystem object attributes structure. */
+typedef const SHFLFSOBJATTR *PCSHFLFSOBJATTR;
+
+
+/**
+ * Filesystem object information structure.
+ */
+#pragma pack(1)
+typedef struct SHFLFSOBJINFO
+{
+ /** Logical size (st_size).
+ * For normal files this is the size of the file.
+ * For symbolic links, this is the length of the path name contained
+ * in the symbolic link.
+ * For other objects this fields needs to be specified.
+ */
+ RTFOFF cbObject;
+
+ /** Disk allocation size (st_blocks * DEV_BSIZE). */
+ RTFOFF cbAllocated;
+
+ /** Time of last access (st_atime).
+ * @remarks Here (and other places) we depend on the IPRT timespec to
+ * remain unchanged. */
+ RTTIMESPEC AccessTime;
+
+ /** Time of last data modification (st_mtime). */
+ RTTIMESPEC ModificationTime;
+
+ /** Time of last status change (st_ctime).
+ * If not available this is set to ModificationTime.
+ */
+ RTTIMESPEC ChangeTime;
+
+ /** Time of file birth (st_birthtime).
+ * If not available this is set to ChangeTime.
+ */
+ RTTIMESPEC BirthTime;
+
+ /** Attributes. */
+ SHFLFSOBJATTR Attr;
+
+} SHFLFSOBJINFO;
+#pragma pack()
+AssertCompileSize(SHFLFSOBJINFO, 92);
+/** Pointer to a shared folder filesystem object information structure. */
+typedef SHFLFSOBJINFO *PSHFLFSOBJINFO;
+/** Pointer to a const shared folder filesystem object information
+ * structure. */
+typedef const SHFLFSOBJINFO *PCSHFLFSOBJINFO;
+
+
+/**
+ * Copy file system objinfo from IPRT to shared folder format.
+ *
+ * @param pDst The shared folder structure.
+ * @param pSrc The IPRT structure.
+ */
+DECLINLINE(void) vbfsCopyFsObjInfoFromIprt(PSHFLFSOBJINFO pDst, PCRTFSOBJINFO pSrc)
+{
+ pDst->cbObject = pSrc->cbObject;
+ pDst->cbAllocated = pSrc->cbAllocated;
+ pDst->AccessTime = pSrc->AccessTime;
+ pDst->ModificationTime = pSrc->ModificationTime;
+ pDst->ChangeTime = pSrc->ChangeTime;
+ pDst->BirthTime = pSrc->BirthTime;
+ pDst->Attr.fMode = pSrc->Attr.fMode;
+ RT_ZERO(pDst->Attr.u);
+ switch (pSrc->Attr.enmAdditional)
+ {
+ default:
+ case RTFSOBJATTRADD_NOTHING:
+ pDst->Attr.enmAdditional = SHFLFSOBJATTRADD_NOTHING;
+ break;
+
+ case RTFSOBJATTRADD_UNIX:
+ pDst->Attr.enmAdditional = SHFLFSOBJATTRADD_UNIX;
+ pDst->Attr.u.Unix.uid = pSrc->Attr.u.Unix.uid;
+ pDst->Attr.u.Unix.gid = pSrc->Attr.u.Unix.gid;
+ pDst->Attr.u.Unix.cHardlinks = pSrc->Attr.u.Unix.cHardlinks;
+ pDst->Attr.u.Unix.INodeIdDevice = pSrc->Attr.u.Unix.INodeIdDevice;
+ pDst->Attr.u.Unix.INodeId = pSrc->Attr.u.Unix.INodeId;
+ pDst->Attr.u.Unix.fFlags = pSrc->Attr.u.Unix.fFlags;
+ pDst->Attr.u.Unix.GenerationId = pSrc->Attr.u.Unix.GenerationId;
+ pDst->Attr.u.Unix.Device = pSrc->Attr.u.Unix.Device;
+ break;
+
+ case RTFSOBJATTRADD_EASIZE:
+ pDst->Attr.enmAdditional = SHFLFSOBJATTRADD_EASIZE;
+ pDst->Attr.u.EASize.cb = pSrc->Attr.u.EASize.cb;
+ break;
+ }
+}
+
+
+/** Result of an open/create request.
+ * Along with handle value the result code
+ * identifies what has happened while
+ * trying to open the object.
+ */
+typedef enum _SHFLCREATERESULT
+{
+ SHFL_NO_RESULT,
+ /** Specified path does not exist. */
+ SHFL_PATH_NOT_FOUND,
+ /** Path to file exists, but the last component does not. */
+ SHFL_FILE_NOT_FOUND,
+ /** File already exists and either has been opened or not. */
+ SHFL_FILE_EXISTS,
+ /** New file was created. */
+ SHFL_FILE_CREATED,
+ /** Existing file was replaced or overwritten. */
+ SHFL_FILE_REPLACED
+} SHFLCREATERESULT;
+
+
+/** Open/create flags.
+ * @{
+ */
+
+/** No flags. Initialization value. */
+#define SHFL_CF_NONE (0x00000000)
+
+/** Lookup only the object, do not return a handle. All other flags are ignored. */
+#define SHFL_CF_LOOKUP (0x00000001)
+
+/** Open parent directory of specified object.
+ * Useful for the corresponding Windows FSD flag
+ * and for opening paths like \\dir\\*.* to search the 'dir'.
+ * @todo possibly not needed???
+ */
+#define SHFL_CF_OPEN_TARGET_DIRECTORY (0x00000002)
+
+/** Create/open a directory. */
+#define SHFL_CF_DIRECTORY (0x00000004)
+
+/** Open/create action to do if object exists
+ * and if the object does not exists.
+ * REPLACE file means atomically DELETE and CREATE.
+ * OVERWRITE file means truncating the file to 0 and
+ * setting new size.
+ * When opening an existing directory REPLACE and OVERWRITE
+ * actions are considered invalid, and cause returning
+ * FILE_EXISTS with NIL handle.
+ */
+#define SHFL_CF_ACT_MASK_IF_EXISTS (0x000000F0)
+#define SHFL_CF_ACT_MASK_IF_NEW (0x00000F00)
+
+/** What to do if object exists. */
+#define SHFL_CF_ACT_OPEN_IF_EXISTS (0x00000000)
+#define SHFL_CF_ACT_FAIL_IF_EXISTS (0x00000010)
+#define SHFL_CF_ACT_REPLACE_IF_EXISTS (0x00000020)
+#define SHFL_CF_ACT_OVERWRITE_IF_EXISTS (0x00000030)
+
+/** What to do if object does not exist. */
+#define SHFL_CF_ACT_CREATE_IF_NEW (0x00000000)
+#define SHFL_CF_ACT_FAIL_IF_NEW (0x00000100)
+
+/** Read/write requested access for the object. */
+#define SHFL_CF_ACCESS_MASK_RW (0x00003000)
+
+/** No access requested. */
+#define SHFL_CF_ACCESS_NONE (0x00000000)
+/** Read access requested. */
+#define SHFL_CF_ACCESS_READ (0x00001000)
+/** Write access requested. */
+#define SHFL_CF_ACCESS_WRITE (0x00002000)
+/** Read/Write access requested. */
+#define SHFL_CF_ACCESS_READWRITE (SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_WRITE)
+
+/** Requested share access for the object. */
+#define SHFL_CF_ACCESS_MASK_DENY (0x0000C000)
+
+/** Allow any access. */
+#define SHFL_CF_ACCESS_DENYNONE (0x00000000)
+/** Do not allow read. */
+#define SHFL_CF_ACCESS_DENYREAD (0x00004000)
+/** Do not allow write. */
+#define SHFL_CF_ACCESS_DENYWRITE (0x00008000)
+/** Do not allow access. */
+#define SHFL_CF_ACCESS_DENYALL (SHFL_CF_ACCESS_DENYREAD | SHFL_CF_ACCESS_DENYWRITE)
+
+/** Requested access to attributes of the object. */
+#define SHFL_CF_ACCESS_MASK_ATTR (0x00030000)
+
+/** No access requested. */
+#define SHFL_CF_ACCESS_ATTR_NONE (0x00000000)
+/** Read access requested. */
+#define SHFL_CF_ACCESS_ATTR_READ (0x00010000)
+/** Write access requested. */
+#define SHFL_CF_ACCESS_ATTR_WRITE (0x00020000)
+/** Read/Write access requested. */
+#define SHFL_CF_ACCESS_ATTR_READWRITE (SHFL_CF_ACCESS_READ | SHFL_CF_ACCESS_WRITE)
+
+/** The file is opened in append mode. Ignored if SHFL_CF_ACCESS_WRITE is not set. */
+#define SHFL_CF_ACCESS_APPEND (0x00040000)
+
+/** @} */
+
+#pragma pack(1)
+typedef struct _SHFLCREATEPARMS
+{
+ /* Returned handle of opened object. */
+ SHFLHANDLE Handle;
+
+ /* Returned result of the operation */
+ SHFLCREATERESULT Result;
+
+ /* SHFL_CF_* */
+ uint32_t CreateFlags;
+
+ /* Attributes of object to create and
+ * returned actual attributes of opened/created object.
+ */
+ SHFLFSOBJINFO Info;
+
+} SHFLCREATEPARMS;
+#pragma pack()
+
+typedef SHFLCREATEPARMS *PSHFLCREATEPARMS;
+
+
+/** Shared Folders mappings.
+ * @{
+ */
+
+/** The mapping has been added since last query. */
+#define SHFL_MS_NEW (1)
+/** The mapping has been deleted since last query. */
+#define SHFL_MS_DELETED (2)
+
+typedef struct _SHFLMAPPING
+{
+ /** Mapping status. */
+ uint32_t u32Status;
+ /** Root handle. */
+ SHFLROOT root;
+} SHFLMAPPING;
+/** Pointer to a SHFLMAPPING structure. */
+typedef SHFLMAPPING *PSHFLMAPPING;
+
+/** @} */
+
+/** Shared Folder directory information
+ * @{
+ */
+
+typedef struct _SHFLDIRINFO
+{
+ /** Full information about the object. */
+ SHFLFSOBJINFO Info;
+ /** The length of the short field (number of RTUTF16 chars).
+ * It is 16-bit for reasons of alignment. */
+ uint16_t cucShortName;
+ /** The short name for 8.3 compatibility.
+ * Empty string if not available.
+ */
+ RTUTF16 uszShortName[14];
+ /** @todo malc, a description, please. */
+ SHFLSTRING name;
+} SHFLDIRINFO, *PSHFLDIRINFO;
+
+
+/**
+ * Shared folder filesystem properties.
+ */
+typedef struct SHFLFSPROPERTIES
+{
+ /** The maximum size of a filesystem object name.
+ * This does not include the '\\0'. */
+ uint32_t cbMaxComponent;
+
+ /** True if the filesystem is remote.
+ * False if the filesystem is local. */
+ bool fRemote;
+
+ /** True if the filesystem is case sensitive.
+ * False if the filesystem is case insensitive. */
+ bool fCaseSensitive;
+
+ /** True if the filesystem is mounted read only.
+ * False if the filesystem is mounted read write. */
+ bool fReadOnly;
+
+ /** True if the filesystem can encode unicode object names.
+ * False if it can't. */
+ bool fSupportsUnicode;
+
+ /** True if the filesystem is compresses.
+ * False if it isn't or we don't know. */
+ bool fCompressed;
+
+ /** True if the filesystem compresses of individual files.
+ * False if it doesn't or we don't know. */
+ bool fFileCompression;
+
+ /** @todo more? */
+} SHFLFSPROPERTIES;
+AssertCompileSize(SHFLFSPROPERTIES, 12);
+/** Pointer to a shared folder filesystem properties structure. */
+typedef SHFLFSPROPERTIES *PSHFLFSPROPERTIES;
+/** Pointer to a const shared folder filesystem properties structure. */
+typedef SHFLFSPROPERTIES const *PCSHFLFSPROPERTIES;
+
+
+/**
+ * Copy file system properties from IPRT to shared folder format.
+ *
+ * @param pDst The shared folder structure.
+ * @param pSrc The IPRT structure.
+ */
+DECLINLINE(void) vbfsCopyFsPropertiesFromIprt(PSHFLFSPROPERTIES pDst, PCRTFSPROPERTIES pSrc)
+{
+ RT_ZERO(*pDst); /* zap the implicit padding. */
+ pDst->cbMaxComponent = pSrc->cbMaxComponent;
+ pDst->fRemote = pSrc->fRemote;
+ pDst->fCaseSensitive = pSrc->fCaseSensitive;
+ pDst->fReadOnly = pSrc->fReadOnly;
+ pDst->fSupportsUnicode = pSrc->fSupportsUnicode;
+ pDst->fCompressed = pSrc->fCompressed;
+ pDst->fFileCompression = pSrc->fFileCompression;
+}
+
+
+typedef struct _SHFLVOLINFO
+{
+ RTFOFF ullTotalAllocationBytes;
+ RTFOFF ullAvailableAllocationBytes;
+ uint32_t ulBytesPerAllocationUnit;
+ uint32_t ulBytesPerSector;
+ uint32_t ulSerial;
+ SHFLFSPROPERTIES fsProperties;
+} SHFLVOLINFO, *PSHFLVOLINFO;
+
+/** @} */
+
+/** Function parameter structures.
+ * @{
+ */
+
+/**
+ * SHFL_FN_QUERY_MAPPINGS
+ */
+/** Validation mask. Needs to be adjusted
+ * whenever a new SHFL_MF_ flag is added. */
+#define SHFL_MF_MASK (0x00000011)
+/** UC2 enconded strings. */
+#define SHFL_MF_UCS2 (0x00000000)
+/** Guest uses UTF8 strings, if not set then the strings are unicode (UCS2). */
+#define SHFL_MF_UTF8 (0x00000001)
+/** Just handle the auto-mounted folders. */
+#define SHFL_MF_AUTOMOUNT (0x00000010)
+
+/** Type of guest system. For future system dependent features. */
+#define SHFL_MF_SYSTEM_MASK (0x0000FF00)
+#define SHFL_MF_SYSTEM_NONE (0x00000000)
+#define SHFL_MF_SYSTEM_WINDOWS (0x00000100)
+#define SHFL_MF_SYSTEM_LINUX (0x00000200)
+
+/** Parameters structure. */
+typedef struct _VBoxSFQueryMappings
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** 32bit, in:
+ * Flags describing various client needs.
+ */
+ HGCMFunctionParameter flags;
+
+ /** 32bit, in/out:
+ * Number of mappings the client expects.
+ * This is the number of elements in the
+ * mappings array.
+ */
+ HGCMFunctionParameter numberOfMappings;
+
+ /** pointer, in/out:
+ * Points to array of SHFLMAPPING structures.
+ */
+ HGCMFunctionParameter mappings;
+
+} VBoxSFQueryMappings;
+
+/** Number of parameters */
+#define SHFL_CPARMS_QUERY_MAPPINGS (3)
+
+
+
+/**
+ * SHFL_FN_QUERY_MAP_NAME
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFQueryMapName
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** 32bit, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in/out:
+ * Points to SHFLSTRING buffer.
+ */
+ HGCMFunctionParameter name;
+
+} VBoxSFQueryMapName;
+
+/** Number of parameters */
+#define SHFL_CPARMS_QUERY_MAP_NAME (2)
+
+/**
+ * SHFL_FN_MAP_FOLDER_OLD
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFMapFolder_Old
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in:
+ * Points to SHFLSTRING buffer.
+ */
+ HGCMFunctionParameter path;
+
+ /** pointer, out: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in: RTUTF16
+ * Path delimiter
+ */
+ HGCMFunctionParameter delimiter;
+
+} VBoxSFMapFolder_Old;
+
+/** Number of parameters */
+#define SHFL_CPARMS_MAP_FOLDER_OLD (3)
+
+/**
+ * SHFL_FN_MAP_FOLDER
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFMapFolder
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in:
+ * Points to SHFLSTRING buffer.
+ */
+ HGCMFunctionParameter path;
+
+ /** pointer, out: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in: RTUTF16
+ * Path delimiter
+ */
+ HGCMFunctionParameter delimiter;
+
+ /** pointer, in: SHFLROOT
+ * Case senstive flag
+ */
+ HGCMFunctionParameter fCaseSensitive;
+
+} VBoxSFMapFolder;
+
+/** Number of parameters */
+#define SHFL_CPARMS_MAP_FOLDER (4)
+
+/**
+ * SHFL_FN_UNMAP_FOLDER
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFUnmapFolder
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+} VBoxSFUnmapFolder;
+
+/** Number of parameters */
+#define SHFL_CPARMS_UNMAP_FOLDER (1)
+
+
+/**
+ * SHFL_FN_CREATE
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFCreate
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in:
+ * Points to SHFLSTRING buffer.
+ */
+ HGCMFunctionParameter path;
+
+ /** pointer, in/out:
+ * Points to SHFLCREATEPARMS buffer.
+ */
+ HGCMFunctionParameter parms;
+
+} VBoxSFCreate;
+
+/** Number of parameters */
+#define SHFL_CPARMS_CREATE (3)
+
+
+/**
+ * SHFL_FN_CLOSE
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFClose
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+
+ /** value64, in:
+ * SHFLHANDLE of object to close.
+ */
+ HGCMFunctionParameter handle;
+
+} VBoxSFClose;
+
+/** Number of parameters */
+#define SHFL_CPARMS_CLOSE (2)
+
+
+/**
+ * SHFL_FN_READ
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFRead
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** value64, in:
+ * SHFLHANDLE of object to read from.
+ */
+ HGCMFunctionParameter handle;
+
+ /** value64, in:
+ * Offset to read from.
+ */
+ HGCMFunctionParameter offset;
+
+ /** value64, in/out:
+ * Bytes to read/How many were read.
+ */
+ HGCMFunctionParameter cb;
+
+ /** pointer, out:
+ * Buffer to place data to.
+ */
+ HGCMFunctionParameter buffer;
+
+} VBoxSFRead;
+
+/** Number of parameters */
+#define SHFL_CPARMS_READ (5)
+
+
+
+/**
+ * SHFL_FN_WRITE
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFWrite
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** value64, in:
+ * SHFLHANDLE of object to write to.
+ */
+ HGCMFunctionParameter handle;
+
+ /** value64, in:
+ * Offset to write to.
+ */
+ HGCMFunctionParameter offset;
+
+ /** value64, in/out:
+ * Bytes to write/How many were written.
+ */
+ HGCMFunctionParameter cb;
+
+ /** pointer, in:
+ * Data to write.
+ */
+ HGCMFunctionParameter buffer;
+
+} VBoxSFWrite;
+
+/** Number of parameters */
+#define SHFL_CPARMS_WRITE (5)
+
+
+
+/**
+ * SHFL_FN_LOCK
+ */
+
+/** Lock owner is the HGCM client. */
+
+/** Lock mode bit mask. */
+#define SHFL_LOCK_MODE_MASK (0x3)
+/** Cancel lock on the given range. */
+#define SHFL_LOCK_CANCEL (0x0)
+/** Acquire read only lock. Prevent write to the range. */
+#define SHFL_LOCK_SHARED (0x1)
+/** Acquire write lock. Prevent both write and read to the range. */
+#define SHFL_LOCK_EXCLUSIVE (0x2)
+
+/** Do not wait for lock if it can not be acquired at the time. */
+#define SHFL_LOCK_NOWAIT (0x0)
+/** Wait and acquire lock. */
+#define SHFL_LOCK_WAIT (0x4)
+
+/** Lock the specified range. */
+#define SHFL_LOCK_PARTIAL (0x0)
+/** Lock entire object. */
+#define SHFL_LOCK_ENTIRE (0x8)
+
+/** Parameters structure. */
+typedef struct _VBoxSFLock
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** value64, in:
+ * SHFLHANDLE of object to be locked.
+ */
+ HGCMFunctionParameter handle;
+
+ /** value64, in:
+ * Starting offset of lock range.
+ */
+ HGCMFunctionParameter offset;
+
+ /** value64, in:
+ * Length of range.
+ */
+ HGCMFunctionParameter length;
+
+ /** value32, in:
+ * Lock flags SHFL_LOCK_*.
+ */
+ HGCMFunctionParameter flags;
+
+} VBoxSFLock;
+
+/** Number of parameters */
+#define SHFL_CPARMS_LOCK (5)
+
+
+
+/**
+ * SHFL_FN_FLUSH
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFFlush
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** value64, in:
+ * SHFLHANDLE of object to be locked.
+ */
+ HGCMFunctionParameter handle;
+
+} VBoxSFFlush;
+
+/** Number of parameters */
+#define SHFL_CPARMS_FLUSH (2)
+
+/**
+ * SHFL_FN_LIST
+ */
+
+/** Listing information includes variable length RTDIRENTRY[EX] structures. */
+
+/** @todo might be necessary for future. */
+#define SHFL_LIST_NONE 0
+#define SHFL_LIST_RETURN_ONE 1
+
+/** Parameters structure. */
+typedef struct _VBoxSFList
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** value64, in:
+ * SHFLHANDLE of object to be listed.
+ */
+ HGCMFunctionParameter handle;
+
+ /** value32, in:
+ * List flags SHFL_LIST_*.
+ */
+ HGCMFunctionParameter flags;
+
+ /** value32, in/out:
+ * Bytes to be used for listing information/How many bytes were used.
+ */
+ HGCMFunctionParameter cb;
+
+ /** pointer, in/optional
+ * Points to SHFLSTRING buffer that specifies a search path.
+ */
+ HGCMFunctionParameter path;
+
+ /** pointer, out:
+ * Buffer to place listing information to. (SHFLDIRINFO)
+ */
+ HGCMFunctionParameter buffer;
+
+ /** value32, in/out:
+ * Indicates a key where the listing must be resumed.
+ * in: 0 means start from begin of object.
+ * out: 0 means listing completed.
+ */
+ HGCMFunctionParameter resumePoint;
+
+ /** pointer, out:
+ * Number of files returned
+ */
+ HGCMFunctionParameter cFiles;
+
+} VBoxSFList;
+
+/** Number of parameters */
+#define SHFL_CPARMS_LIST (8)
+
+
+
+/**
+ * SHFL_FN_READLINK
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFReadLink
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in:
+ * Points to SHFLSTRING buffer.
+ */
+ HGCMFunctionParameter path;
+
+ /** pointer, out:
+ * Buffer to place data to.
+ */
+ HGCMFunctionParameter buffer;
+
+} VBoxSFReadLink;
+
+/** Number of parameters */
+#define SHFL_CPARMS_READLINK (3)
+
+
+
+/**
+ * SHFL_FN_INFORMATION
+ */
+
+/** Mask of Set/Get bit. */
+#define SHFL_INFO_MODE_MASK (0x1)
+/** Get information */
+#define SHFL_INFO_GET (0x0)
+/** Set information */
+#define SHFL_INFO_SET (0x1)
+
+/** Get name of the object. */
+#define SHFL_INFO_NAME (0x2)
+/** Set size of object (extend/trucate); only applies to file objects */
+#define SHFL_INFO_SIZE (0x4)
+/** Get/Set file object info. */
+#define SHFL_INFO_FILE (0x8)
+/** Get volume information. */
+#define SHFL_INFO_VOLUME (0x10)
+
+/** @todo different file info structures */
+
+
+/** Parameters structure. */
+typedef struct _VBoxSFInformation
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** value64, in:
+ * SHFLHANDLE of object to be listed.
+ */
+ HGCMFunctionParameter handle;
+
+ /** value32, in:
+ * SHFL_INFO_*
+ */
+ HGCMFunctionParameter flags;
+
+ /** value32, in/out:
+ * Bytes to be used for information/How many bytes were used.
+ */
+ HGCMFunctionParameter cb;
+
+ /** pointer, in/out:
+ * Information to be set/get (SHFLFSOBJINFO or SHFLSTRING). Do not forget
+ * to set the SHFLFSOBJINFO::Attr::enmAdditional for Get operation as well.
+ */
+ HGCMFunctionParameter info;
+
+} VBoxSFInformation;
+
+/** Number of parameters */
+#define SHFL_CPARMS_INFORMATION (5)
+
+
+/**
+ * SHFL_FN_REMOVE
+ */
+
+#define SHFL_REMOVE_FILE (0x1)
+#define SHFL_REMOVE_DIR (0x2)
+#define SHFL_REMOVE_SYMLINK (0x4)
+
+/** Parameters structure. */
+typedef struct _VBoxSFRemove
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in:
+ * Points to SHFLSTRING buffer.
+ */
+ HGCMFunctionParameter path;
+
+ /** value32, in:
+ * remove flags (file/directory)
+ */
+ HGCMFunctionParameter flags;
+
+} VBoxSFRemove;
+
+#define SHFL_CPARMS_REMOVE (3)
+
+
+/**
+ * SHFL_FN_RENAME
+ */
+
+#define SHFL_RENAME_FILE (0x1)
+#define SHFL_RENAME_DIR (0x2)
+#define SHFL_RENAME_REPLACE_IF_EXISTS (0x4)
+
+/** Parameters structure. */
+typedef struct _VBoxSFRename
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in:
+ * Points to SHFLSTRING src.
+ */
+ HGCMFunctionParameter src;
+
+ /** pointer, in:
+ * Points to SHFLSTRING dest.
+ */
+ HGCMFunctionParameter dest;
+
+ /** value32, in:
+ * rename flags (file/directory)
+ */
+ HGCMFunctionParameter flags;
+
+} VBoxSFRename;
+
+#define SHFL_CPARMS_RENAME (4)
+
+
+/**
+ * SHFL_FN_SYMLINK
+ */
+
+/** Parameters structure. */
+typedef struct _VBoxSFSymlink
+{
+ VBoxGuestHGCMCallInfo callInfo;
+
+ /** pointer, in: SHFLROOT
+ * Root handle of the mapping which name is queried.
+ */
+ HGCMFunctionParameter root;
+
+ /** pointer, in:
+ * Points to SHFLSTRING of path for the new symlink.
+ */
+ HGCMFunctionParameter newPath;
+
+ /** pointer, in:
+ * Points to SHFLSTRING of destination for symlink.
+ */
+ HGCMFunctionParameter oldPath;
+
+ /** pointer, out:
+ * Information about created symlink.
+ */
+ HGCMFunctionParameter info;
+
+} VBoxSFSymlink;
+
+#define SHFL_CPARMS_SYMLINK (4)
+
+
+
+/**
+ * SHFL_FN_ADD_MAPPING
+ * Host call, no guest structure is used.
+ */
+
+#define SHFL_ADD_MAPPING_F_WRITABLE (RT_BIT_32(0))
+#define SHFL_ADD_MAPPING_F_AUTOMOUNT (RT_BIT_32(1))
+#define SHFL_ADD_MAPPING_F_CREATE_SYMLINKS (RT_BIT_32(2))
+
+#define SHFL_CPARMS_ADD_MAPPING (3)
+
+/**
+ * SHFL_FN_REMOVE_MAPPING
+ * Host call, no guest structure is used.
+ */
+
+#define SHFL_CPARMS_REMOVE_MAPPING (1)
+
+
+/**
+ * SHFL_FN_SET_STATUS_LED
+ * Host call, no guest structure is used.
+ */
+
+#define SHFL_CPARMS_SET_STATUS_LED (1)
+
+/** @} */
+
+#endif
diff --git a/include/VBox/sup.h b/include/VBox/sup.h
new file mode 100644
index 00000000..5913ff9c
--- /dev/null
+++ b/include/VBox/sup.h
@@ -0,0 +1,1745 @@
+/** @file
+ * SUP - Support Library. (HDrv)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_sup_h
+#define ___VBox_sup_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/assert.h>
+#include <iprt/stdarg.h>
+#include <iprt/cpuset.h>
+
+RT_C_DECLS_BEGIN
+
+struct VTGOBJHDR;
+struct VTGPROBELOC;
+
+
+/** @defgroup grp_sup The Support Library API
+ * @{
+ */
+
+/**
+ * Physical page descriptor.
+ */
+#pragma pack(4) /* space is more important. */
+typedef struct SUPPAGE
+{
+ /** Physical memory address. */
+ RTHCPHYS Phys;
+ /** Reserved entry for internal use by the caller. */
+ RTHCUINTPTR uReserved;
+} SUPPAGE;
+#pragma pack()
+/** Pointer to a page descriptor. */
+typedef SUPPAGE *PSUPPAGE;
+/** Pointer to a const page descriptor. */
+typedef const SUPPAGE *PCSUPPAGE;
+
+/**
+ * The paging mode.
+ *
+ * @remarks Users are making assumptions about the order here!
+ */
+typedef enum SUPPAGINGMODE
+{
+ /** The usual invalid entry.
+ * This is returned by SUPR3GetPagingMode() */
+ SUPPAGINGMODE_INVALID = 0,
+ /** Normal 32-bit paging, no global pages */
+ SUPPAGINGMODE_32_BIT,
+ /** Normal 32-bit paging with global pages. */
+ SUPPAGINGMODE_32_BIT_GLOBAL,
+ /** PAE mode, no global pages, no NX. */
+ SUPPAGINGMODE_PAE,
+ /** PAE mode with global pages. */
+ SUPPAGINGMODE_PAE_GLOBAL,
+ /** PAE mode with NX, no global pages. */
+ SUPPAGINGMODE_PAE_NX,
+ /** PAE mode with global pages and NX. */
+ SUPPAGINGMODE_PAE_GLOBAL_NX,
+ /** AMD64 mode, no global pages. */
+ SUPPAGINGMODE_AMD64,
+ /** AMD64 mode with global pages, no NX. */
+ SUPPAGINGMODE_AMD64_GLOBAL,
+ /** AMD64 mode with NX, no global pages. */
+ SUPPAGINGMODE_AMD64_NX,
+ /** AMD64 mode with global pages and NX. */
+ SUPPAGINGMODE_AMD64_GLOBAL_NX
+} SUPPAGINGMODE;
+
+/**
+ * Usermode probe context information.
+ */
+typedef struct SUPDRVTRACERUSRCTX
+{
+ /** The probe ID from the VTG location record. */
+ uint32_t idProbe;
+ /** 32 if X86, 64 if AMD64. */
+ uint8_t cBits;
+ /** Reserved padding. */
+ uint8_t abReserved[3];
+ /** Data which format is dictated by the cBits member. */
+ union
+ {
+ /** X86 context info. */
+ struct
+ {
+ uint32_t uVtgProbeLoc; /**< Location record address. */
+ uint32_t aArgs[20]; /**< Raw arguments. */
+ uint32_t eip;
+ uint32_t eflags;
+ uint32_t eax;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t ebx;
+ uint32_t esp;
+ uint32_t ebp;
+ uint32_t esi;
+ uint32_t edi;
+ uint16_t cs;
+ uint16_t ss;
+ uint16_t ds;
+ uint16_t es;
+ uint16_t fs;
+ uint16_t gs;
+ } X86;
+
+ /** AMD64 context info. */
+ struct
+ {
+ uint64_t uVtgProbeLoc; /**< Location record address. */
+ uint64_t aArgs[10]; /**< Raw arguments. */
+ uint64_t rip;
+ uint64_t rflags;
+ uint64_t rax;
+ uint64_t rcx;
+ uint64_t rdx;
+ uint64_t rbx;
+ uint64_t rsp;
+ uint64_t rbp;
+ uint64_t rsi;
+ uint64_t rdi;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ } Amd64;
+ } u;
+} SUPDRVTRACERUSRCTX;
+/** Pointer to the usermode probe context information. */
+typedef SUPDRVTRACERUSRCTX *PSUPDRVTRACERUSRCTX;
+/** Pointer to the const usermode probe context information. */
+typedef SUPDRVTRACERUSRCTX const *PCSUPDRVTRACERUSRCTX;
+
+/**
+ * The CPU state.
+ */
+typedef enum SUPGIPCPUSTATE
+{
+ /** Invalid CPU state / unused CPU entry. */
+ SUPGIPCPUSTATE_INVALID = 0,
+ /** The CPU is not present. */
+ SUPGIPCPUSTATE_ABSENT,
+ /** The CPU is offline. */
+ SUPGIPCPUSTATE_OFFLINE,
+ /** The CPU is online. */
+ SUPGIPCPUSTATE_ONLINE,
+ /** Force 32-bit enum type. */
+ SUPGIPCPUSTATE_32_BIT_HACK = 0x7fffffff
+} SUPGIPCPUSTATE;
+
+/**
+ * Per CPU data.
+ */
+typedef struct SUPGIPCPU
+{
+ /** Update transaction number.
+ * This number is incremented at the start and end of each update. It follows
+ * thusly that odd numbers indicates update in progress, while even numbers
+ * indicate stable data. Use this to make sure that the data items you fetch
+ * are consistent. */
+ volatile uint32_t u32TransactionId;
+ /** The interval in TSC ticks between two NanoTS updates.
+ * This is the average interval over the last 2, 4 or 8 updates + a little slack.
+ * The slack makes the time go a tiny tiny bit slower and extends the interval enough
+ * to avoid ending up with too many 1ns increments. */
+ volatile uint32_t u32UpdateIntervalTSC;
+ /** Current nanosecond timestamp. */
+ volatile uint64_t u64NanoTS;
+ /** The TSC at the time of u64NanoTS. */
+ volatile uint64_t u64TSC;
+ /** Current CPU Frequency. */
+ volatile uint64_t u64CpuHz;
+ /** Number of errors during updating.
+ * Typical errors are under/overflows. */
+ volatile uint32_t cErrors;
+ /** Index of the head item in au32TSCHistory. */
+ volatile uint32_t iTSCHistoryHead;
+ /** Array of recent TSC interval deltas.
+ * The most recent item is at index iTSCHistoryHead.
+ * This history is used to calculate u32UpdateIntervalTSC.
+ */
+ volatile uint32_t au32TSCHistory[8];
+ /** The interval between the last two NanoTS updates. (experiment for now) */
+ volatile uint32_t u32PrevUpdateIntervalNS;
+
+ /** Reserved for future per processor data. */
+ volatile uint32_t au32Reserved[5+5];
+
+ /** @todo Add topology/NUMA info. */
+ /** The CPU state. */
+ SUPGIPCPUSTATE volatile enmState;
+ /** The host CPU ID of this CPU (the SUPGIPCPU is indexed by APIC ID). */
+ RTCPUID idCpu;
+ /** The CPU set index of this CPU. */
+ int16_t iCpuSet;
+ /** The APIC ID of this CPU. */
+ uint16_t idApic;
+} SUPGIPCPU;
+AssertCompileSize(RTCPUID, 4);
+AssertCompileSize(SUPGIPCPU, 128);
+AssertCompileMemberAlignment(SUPGIPCPU, u64NanoTS, 8);
+AssertCompileMemberAlignment(SUPGIPCPU, u64TSC, 8);
+
+/** Pointer to per cpu data.
+ * @remark there is no const version of this typedef, see g_pSUPGlobalInfoPage for details. */
+typedef SUPGIPCPU *PSUPGIPCPU;
+
+
+
+/**
+ * Global Information Page.
+ *
+ * This page contains useful information and can be mapped into any
+ * process or VM. It can be accessed thru the g_pSUPGlobalInfoPage
+ * pointer when a session is open.
+ */
+typedef struct SUPGLOBALINFOPAGE
+{
+ /** Magic (SUPGLOBALINFOPAGE_MAGIC). */
+ uint32_t u32Magic;
+ /** The GIP version. */
+ uint32_t u32Version;
+
+ /** The GIP update mode, see SUPGIPMODE. */
+ uint32_t u32Mode;
+ /** The number of entries in the CPU table.
+ * (This can work as RTMpGetArraySize().) */
+ uint16_t cCpus;
+ /** The size of the GIP in pages. */
+ uint16_t cPages;
+ /** The update frequency of the of the NanoTS. */
+ volatile uint32_t u32UpdateHz;
+ /** The update interval in nanoseconds. (10^9 / u32UpdateHz) */
+ volatile uint32_t u32UpdateIntervalNS;
+ /** The timestamp of the last time we update the update frequency. */
+ volatile uint64_t u64NanoTSLastUpdateHz;
+ /** The set of online CPUs. */
+ RTCPUSET OnlineCpuSet;
+ /** The set of present CPUs. */
+ RTCPUSET PresentCpuSet;
+ /** The set of possible CPUs. */
+ RTCPUSET PossibleCpuSet;
+ /** The number of CPUs that are online. */
+ volatile uint16_t cOnlineCpus;
+ /** The number of CPUs present in the system. */
+ volatile uint16_t cPresentCpus;
+ /** The highest number of CPUs possible. */
+ uint16_t cPossibleCpus;
+ /** The highest number of CPUs possible. */
+ uint16_t u16Padding0;
+ /** The max CPU ID (RTMpGetMaxCpuId). */
+ RTCPUID idCpuMax;
+
+ /** Padding / reserved space for future data. */
+ uint32_t au32Padding1[29];
+
+ /** Table indexed by the CPU APIC ID to get the CPU table index. */
+ uint16_t aiCpuFromApicId[256];
+ /** CPU set index to CPU table index. */
+ uint16_t aiCpuFromCpuSetIdx[RTCPUSET_MAX_CPUS];
+
+ /** Array of per-cpu data.
+ * This is index by ApicId via the aiCpuFromApicId table.
+ *
+ * The clock and frequency information is updated for all CPUs if u32Mode
+ * is SUPGIPMODE_ASYNC_TSC, otherwise (SUPGIPMODE_SYNC_TSC) only the first
+ * entry is updated. */
+ SUPGIPCPU aCPUs[1];
+} SUPGLOBALINFOPAGE;
+AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, u64NanoTSLastUpdateHz, 8);
+#if defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 32);
+#else
+AssertCompileMemberAlignment(SUPGLOBALINFOPAGE, aCPUs, 256);
+#endif
+
+/** Pointer to the global info page.
+ * @remark there is no const version of this typedef, see g_pSUPGlobalInfoPage for details. */
+typedef SUPGLOBALINFOPAGE *PSUPGLOBALINFOPAGE;
+
+
+/** The value of the SUPGLOBALINFOPAGE::u32Magic field. (Soryo Fuyumi) */
+#define SUPGLOBALINFOPAGE_MAGIC 0x19590106
+/** The GIP version.
+ * Upper 16 bits is the major version. Major version is only changed with
+ * incompatible changes in the GIP. */
+#define SUPGLOBALINFOPAGE_VERSION 0x00030000
+
+/**
+ * SUPGLOBALINFOPAGE::u32Mode values.
+ */
+typedef enum SUPGIPMODE
+{
+ /** The usual invalid null entry. */
+ SUPGIPMODE_INVALID = 0,
+ /** The TSC of the cores and cpus in the system is in sync. */
+ SUPGIPMODE_SYNC_TSC,
+ /** Each core has it's own TSC. */
+ SUPGIPMODE_ASYNC_TSC,
+ /** The usual 32-bit hack. */
+ SUPGIPMODE_32BIT_HACK = 0x7fffffff
+} SUPGIPMODE;
+
+/** Pointer to the Global Information Page.
+ *
+ * This pointer is valid as long as SUPLib has a open session. Anyone using
+ * the page must treat this pointer as highly volatile and not trust it beyond
+ * one transaction.
+ *
+ * @remark The GIP page is read-only to everyone but the support driver and
+ * is actually mapped read only everywhere but in ring-0. However
+ * it is not marked 'const' as this might confuse compilers into
+ * thinking that values doesn't change even if members are marked
+ * as volatile. Thus, there is no PCSUPGLOBALINFOPAGE type.
+ */
+#if defined(IN_SUP_R0) || defined(IN_SUP_R3) || defined(IN_SUP_RC)
+extern DECLEXPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage;
+
+#elif !defined(IN_RING0) || defined(RT_OS_WINDOWS) || defined(RT_OS_SOLARIS)
+extern DECLIMPORT(PSUPGLOBALINFOPAGE) g_pSUPGlobalInfoPage;
+
+#else /* IN_RING0 && !RT_OS_WINDOWS */
+# if !defined(__GNUC__) || defined(RT_OS_DARWIN) || !defined(RT_ARCH_AMD64)
+# define g_pSUPGlobalInfoPage (&g_SUPGlobalInfoPage)
+# else
+# define g_pSUPGlobalInfoPage (SUPGetGIPHlp())
+/** Workaround for ELF+GCC problem on 64-bit hosts.
+ * (GCC emits a mov with a R_X86_64_32 reloc, we need R_X86_64_64.) */
+DECLINLINE(PSUPGLOBALINFOPAGE) SUPGetGIPHlp(void)
+{
+ PSUPGLOBALINFOPAGE pGIP;
+ __asm__ __volatile__ ("movabs $g_SUPGlobalInfoPage,%0\n\t"
+ : "=a" (pGIP));
+ return pGIP;
+}
+# endif
+/** The GIP.
+ * We save a level of indirection by exporting the GIP instead of a variable
+ * pointing to it. */
+extern DECLIMPORT(SUPGLOBALINFOPAGE) g_SUPGlobalInfoPage;
+#endif
+
+/**
+ * Gets the GIP pointer.
+ *
+ * @returns Pointer to the GIP or NULL.
+ */
+SUPDECL(PSUPGLOBALINFOPAGE) SUPGetGIP(void);
+
+#ifdef ___iprt_asm_amd64_x86_h
+/**
+ * Gets the TSC frequency of the calling CPU.
+ *
+ * @returns TSC frequency, UINT64_MAX on failure.
+ * @param pGip The GIP pointer.
+ */
+DECLINLINE(uint64_t) SUPGetCpuHzFromGIP(PSUPGLOBALINFOPAGE pGip)
+{
+ unsigned iCpu;
+
+ if (RT_UNLIKELY(!pGip || pGip->u32Magic != SUPGLOBALINFOPAGE_MAGIC))
+ return UINT64_MAX;
+
+ if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC)
+ iCpu = 0;
+ else
+ {
+ iCpu = pGip->aiCpuFromApicId[ASMGetApicId()];
+ if (iCpu >= pGip->cCpus)
+ return UINT64_MAX;
+ }
+
+ return pGip->aCPUs[iCpu].u64CpuHz;
+}
+#endif
+
+/**
+ * Request for generic VMMR0Entry calls.
+ */
+typedef struct SUPVMMR0REQHDR
+{
+ /** The magic. (SUPVMMR0REQHDR_MAGIC) */
+ uint32_t u32Magic;
+ /** The size of the request. */
+ uint32_t cbReq;
+} SUPVMMR0REQHDR;
+/** Pointer to a ring-0 request header. */
+typedef SUPVMMR0REQHDR *PSUPVMMR0REQHDR;
+/** the SUPVMMR0REQHDR::u32Magic value (Ethan Iverson - The Bad Plus). */
+#define SUPVMMR0REQHDR_MAGIC UINT32_C(0x19730211)
+
+
+/** For the fast ioctl path.
+ * @{
+ */
+/** @see VMMR0_DO_RAW_RUN. */
+#define SUP_VMMR0_DO_RAW_RUN 0
+/** @see VMMR0_DO_HWACC_RUN. */
+#define SUP_VMMR0_DO_HWACC_RUN 1
+/** @see VMMR0_DO_NOP */
+#define SUP_VMMR0_DO_NOP 2
+/** @} */
+
+/** SUPR3QueryVTCaps capability flags
+ * @{
+ */
+#define SUPVTCAPS_AMD_V RT_BIT(0)
+#define SUPVTCAPS_VT_X RT_BIT(1)
+#define SUPVTCAPS_NESTED_PAGING RT_BIT(2)
+/** @} */
+
+/**
+ * Request for generic FNSUPR0SERVICEREQHANDLER calls.
+ */
+typedef struct SUPR0SERVICEREQHDR
+{
+ /** The magic. (SUPR0SERVICEREQHDR_MAGIC) */
+ uint32_t u32Magic;
+ /** The size of the request. */
+ uint32_t cbReq;
+} SUPR0SERVICEREQHDR;
+/** Pointer to a ring-0 service request header. */
+typedef SUPR0SERVICEREQHDR *PSUPR0SERVICEREQHDR;
+/** the SUPVMMR0REQHDR::u32Magic value (Esbjoern Svensson - E.S.P.). */
+#define SUPR0SERVICEREQHDR_MAGIC UINT32_C(0x19640416)
+
+
+/** Event semaphore handle. Ring-0 / ring-3. */
+typedef R0PTRTYPE(struct SUPSEMEVENTHANDLE *) SUPSEMEVENT;
+/** Pointer to an event semaphore handle. */
+typedef SUPSEMEVENT *PSUPSEMEVENT;
+/** Nil event semaphore handle. */
+#define NIL_SUPSEMEVENT ((SUPSEMEVENT)0)
+
+/**
+ * Creates a single release event semaphore.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param phEvent Where to return the handle to the event semaphore.
+ */
+SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent);
+
+/**
+ * Closes a single release event semaphore handle.
+ *
+ * @returns VBox status code.
+ * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed.
+ * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore
+ * object remained alive because of other references.
+ *
+ * @param pSession The session handle of the caller.
+ * @param hEvent The handle. Nil is quietly ignored.
+ */
+SUPDECL(int) SUPSemEventClose(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent);
+
+/**
+ * Signals a single release event semaphore.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEvent The semaphore handle.
+ */
+SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent);
+
+#ifdef IN_RING0
+/**
+ * Waits on a single release event semaphore, not interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEvent The semaphore handle.
+ * @param cMillies The number of milliseconds to wait.
+ * @remarks Not available in ring-3.
+ */
+SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies);
+#endif
+
+/**
+ * Waits on a single release event semaphore, interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEvent The semaphore handle.
+ * @param cMillies The number of milliseconds to wait.
+ */
+SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies);
+
+/**
+ * Waits on a single release event semaphore, interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEvent The semaphore handle.
+ * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock.
+ */
+SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout);
+
+/**
+ * Waits on a single release event semaphore, interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEvent The semaphore handle.
+ * @param cNsTimeout The number of nanoseconds to wait.
+ */
+SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout);
+
+/**
+ * Gets the best timeout resolution that SUPSemEventWaitNsAbsIntr and
+ * SUPSemEventWaitNsAbsIntr can do.
+ *
+ * @returns The resolution in nanoseconds.
+ * @param pSession The session handle of the caller.
+ */
+SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession);
+
+
+/** Multiple release event semaphore handle. Ring-0 / ring-3. */
+typedef R0PTRTYPE(struct SUPSEMEVENTMULTIHANDLE *) SUPSEMEVENTMULTI;
+/** Pointer to an multiple release event semaphore handle. */
+typedef SUPSEMEVENTMULTI *PSUPSEMEVENTMULTI;
+/** Nil multiple release event semaphore handle. */
+#define NIL_SUPSEMEVENTMULTI ((SUPSEMEVENTMULTI)0)
+
+/**
+ * Creates a multiple release event semaphore.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param phEventMulti Where to return the handle to the event semaphore.
+ */
+SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti);
+
+/**
+ * Closes a multiple release event semaphore handle.
+ *
+ * @returns VBox status code.
+ * @retval VINF_OBJECT_DESTROYED if the semaphore was destroyed.
+ * @retval VINF_SUCCESS if the handle was successfully closed but the semaphore
+ * object remained alive because of other references.
+ *
+ * @param pSession The session handle of the caller.
+ * @param hEventMulti The handle. Nil is quietly ignored.
+ */
+SUPDECL(int) SUPSemEventMultiClose(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti);
+
+/**
+ * Signals a multiple release event semaphore.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEventMulti The semaphore handle.
+ */
+SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti);
+
+/**
+ * Resets a multiple release event semaphore.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEventMulti The semaphore handle.
+ */
+SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti);
+
+#ifdef IN_RING0
+/**
+ * Waits on a multiple release event semaphore, not interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEventMulti The semaphore handle.
+ * @param cMillies The number of milliseconds to wait.
+ * @remarks Not available in ring-3.
+ */
+SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies);
+#endif
+
+/**
+ * Waits on a multiple release event semaphore, interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEventMulti The semaphore handle.
+ * @param cMillies The number of milliseconds to wait.
+ */
+SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies);
+
+/**
+ * Waits on a multiple release event semaphore, interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEventMulti The semaphore handle.
+ * @param uNsTimeout The deadline given on the RTTimeNanoTS() clock.
+ */
+SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout);
+
+/**
+ * Waits on a multiple release event semaphore, interruptible.
+ *
+ * @returns VBox status code.
+ * @param pSession The session handle of the caller.
+ * @param hEventMulti The semaphore handle.
+ * @param cNsTimeout The number of nanoseconds to wait.
+ */
+SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout);
+
+/**
+ * Gets the best timeout resolution that SUPSemEventMultiWaitNsAbsIntr and
+ * SUPSemEventMultiWaitNsRelIntr can do.
+ *
+ * @returns The resolution in nanoseconds.
+ * @param pSession The session handle of the caller.
+ */
+SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession);
+
+
+#ifdef IN_RING3
+
+/** @defgroup grp_sup_r3 SUP Host Context Ring-3 API
+ * @ingroup grp_sup
+ * @{
+ */
+
+/**
+ * Installs the support library.
+ *
+ * @returns VBox status code.
+ */
+SUPR3DECL(int) SUPR3Install(void);
+
+/**
+ * Uninstalls the support library.
+ *
+ * @returns VBox status code.
+ */
+SUPR3DECL(int) SUPR3Uninstall(void);
+
+/**
+ * Trusted main entry point.
+ *
+ * This is exported as "TrustedMain" by the dynamic libraries which contains the
+ * "real" application binary for which the hardened stub is built. The entry
+ * point is invoked upon successful initialization of the support library and
+ * runtime.
+ *
+ * @returns main kind of exit code.
+ * @param argc The argument count.
+ * @param argv The argument vector.
+ * @param envp The environment vector.
+ */
+typedef DECLCALLBACK(int) FNSUPTRUSTEDMAIN(int argc, char **argv, char **envp);
+/** Pointer to FNSUPTRUSTEDMAIN(). */
+typedef FNSUPTRUSTEDMAIN *PFNSUPTRUSTEDMAIN;
+
+/** Which operation failed. */
+typedef enum SUPINITOP
+{
+ /** Invalid. */
+ kSupInitOp_Invalid = 0,
+ /** Installation integrity error. */
+ kSupInitOp_Integrity,
+ /** Setuid related. */
+ kSupInitOp_RootCheck,
+ /** Driver related. */
+ kSupInitOp_Driver,
+ /** IPRT init related. */
+ kSupInitOp_IPRT,
+ /** Place holder. */
+ kSupInitOp_End
+} SUPINITOP;
+
+/**
+ * Trusted error entry point, optional.
+ *
+ * This is exported as "TrustedError" by the dynamic libraries which contains
+ * the "real" application binary for which the hardened stub is built.
+ *
+ * @param pszWhere Where the error occurred (function name).
+ * @param enmWhat Which operation went wrong.
+ * @param rc The status code.
+ * @param pszMsgFmt Error message format string.
+ * @param va The message format arguments.
+ */
+typedef DECLCALLBACK(void) FNSUPTRUSTEDERROR(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va);
+/** Pointer to FNSUPTRUSTEDERROR. */
+typedef FNSUPTRUSTEDERROR *PFNSUPTRUSTEDERROR;
+
+/**
+ * Secure main.
+ *
+ * This is used for the set-user-ID-on-execute binaries on unixy systems
+ * and when using the open-vboxdrv-via-root-service setup on Windows.
+ *
+ * This function will perform the integrity checks of the VirtualBox
+ * installation, open the support driver, open the root service (later),
+ * and load the DLL corresponding to \a pszProgName and execute its main
+ * function.
+ *
+ * @returns Return code appropriate for main().
+ *
+ * @param pszProgName The program name. This will be used to figure out which
+ * DLL/SO/DYLIB to load and execute.
+ * @param fFlags Flags.
+ * @param argc The argument count.
+ * @param argv The argument vector.
+ * @param envp The environment vector.
+ */
+DECLHIDDEN(int) SUPR3HardenedMain(const char *pszProgName, uint32_t fFlags, int argc, char **argv, char **envp);
+
+/** @name SUPR3SecureMain flags.
+ * @{ */
+/** Don't open the device. (Intended for VirtualBox without -startvm.) */
+#define SUPSECMAIN_FLAGS_DONT_OPEN_DEV RT_BIT_32(0)
+/** @} */
+
+/**
+ * Initializes the support library.
+ * Each successful call to SUPR3Init() must be countered by a
+ * call to SUPR3Term(false).
+ *
+ * @returns VBox status code.
+ * @param ppSession Where to store the session handle. Defaults to NULL.
+ */
+SUPR3DECL(int) SUPR3Init(PSUPDRVSESSION *ppSession);
+
+/**
+ * Terminates the support library.
+ *
+ * @returns VBox status code.
+ * @param fForced Forced termination. This means to ignore the
+ * init call count and just terminated.
+ */
+#ifdef __cplusplus
+SUPR3DECL(int) SUPR3Term(bool fForced = false);
+#else
+SUPR3DECL(int) SUPR3Term(int fForced);
+#endif
+
+/**
+ * Sets the ring-0 VM handle for use with fast IOCtls.
+ *
+ * @returns VBox status code.
+ * @param pVMR0 The ring-0 VM handle.
+ * NIL_RTR0PTR can be used to unset the handle when the
+ * VM is about to be destroyed.
+ */
+SUPR3DECL(int) SUPR3SetVMForFastIOCtl(PVMR0 pVMR0);
+
+/**
+ * Calls the HC R0 VMM entry point.
+ * See VMMR0Entry() for more details.
+ *
+ * @returns error code specific to uFunction.
+ * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure.
+ * @param idCpu The virtual CPU ID.
+ * @param uOperation Operation to execute.
+ * @param pvArg Argument.
+ */
+SUPR3DECL(int) SUPR3CallVMMR0(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, void *pvArg);
+
+/**
+ * Variant of SUPR3CallVMMR0, except that this takes the fast ioclt path
+ * regardsless of compile-time defaults.
+ *
+ * @returns VBox status code.
+ * @param pVMR0 The ring-0 VM handle.
+ * @param uOperation The operation; only the SUP_VMMR0_DO_* ones are valid.
+ * @param idCpu The virtual CPU ID.
+ */
+SUPR3DECL(int) SUPR3CallVMMR0Fast(PVMR0 pVMR0, unsigned uOperation, VMCPUID idCpu);
+
+/**
+ * Calls the HC R0 VMM entry point, in a safer but slower manner than
+ * SUPR3CallVMMR0. When entering using this call the R0 components can call
+ * into the host kernel (i.e. use the SUPR0 and RT APIs).
+ *
+ * See VMMR0Entry() for more details.
+ *
+ * @returns error code specific to uFunction.
+ * @param pVMR0 Pointer to the Ring-0 (Host Context) mapping of the VM structure.
+ * @param idCpu The virtual CPU ID.
+ * @param uOperation Operation to execute.
+ * @param u64Arg Constant argument.
+ * @param pReqHdr Pointer to a request header. Optional.
+ * This will be copied in and out of kernel space. There currently is a size
+ * limit on this, just below 4KB.
+ */
+SUPR3DECL(int) SUPR3CallVMMR0Ex(PVMR0 pVMR0, VMCPUID idCpu, unsigned uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr);
+
+/**
+ * Calls a ring-0 service.
+ *
+ * The operation and the request packet is specific to the service.
+ *
+ * @returns error code specific to uFunction.
+ * @param pszService The service name.
+ * @param cchService The length of the service name.
+ * @param uReq The request number.
+ * @param u64Arg Constant argument.
+ * @param pReqHdr Pointer to a request header. Optional.
+ * This will be copied in and out of kernel space. There currently is a size
+ * limit on this, just below 4KB.
+ */
+SUPR3DECL(int) SUPR3CallR0Service(const char *pszService, size_t cchService, uint32_t uOperation, uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr);
+
+/** Which logger. */
+typedef enum SUPLOGGER
+{
+ SUPLOGGER_DEBUG = 1,
+ SUPLOGGER_RELEASE
+} SUPLOGGER;
+
+/**
+ * Changes the settings of the specified ring-0 logger.
+ *
+ * @returns VBox status code.
+ * @param enmWhich Which logger.
+ * @param pszFlags The flags settings.
+ * @param pszGroups The groups settings.
+ * @param pszDest The destination specificier.
+ */
+SUPR3DECL(int) SUPR3LoggerSettings(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest);
+
+/**
+ * Creates a ring-0 logger instance.
+ *
+ * @returns VBox status code.
+ * @param enmWhich Which logger to create.
+ * @param pszFlags The flags settings.
+ * @param pszGroups The groups settings.
+ * @param pszDest The destination specificier.
+ */
+SUPR3DECL(int) SUPR3LoggerCreate(SUPLOGGER enmWhich, const char *pszFlags, const char *pszGroups, const char *pszDest);
+
+/**
+ * Destroys a ring-0 logger instance.
+ *
+ * @returns VBox status code.
+ * @param enmWhich Which logger.
+ */
+SUPR3DECL(int) SUPR3LoggerDestroy(SUPLOGGER enmWhich);
+
+/**
+ * Queries the paging mode of the host OS.
+ *
+ * @returns The paging mode.
+ */
+SUPR3DECL(SUPPAGINGMODE) SUPR3GetPagingMode(void);
+
+/**
+ * Allocate zero-filled pages.
+ *
+ * Use this to allocate a number of pages suitable for seeding / locking.
+ * Call SUPR3PageFree() to free the pages once done with them.
+ *
+ * @returns VBox status.
+ * @param cPages Number of pages to allocate.
+ * @param ppvPages Where to store the base pointer to the allocated pages.
+ */
+SUPR3DECL(int) SUPR3PageAlloc(size_t cPages, void **ppvPages);
+
+/**
+ * Frees pages allocated with SUPR3PageAlloc().
+ *
+ * @returns VBox status.
+ * @param pvPages Pointer returned by SUPR3PageAlloc().
+ * @param cPages Number of pages that was allocated.
+ */
+SUPR3DECL(int) SUPR3PageFree(void *pvPages, size_t cPages);
+
+/**
+ * Allocate non-zeroed, locked, pages with user and, optionally, kernel
+ * mappings.
+ *
+ * Use SUPR3PageFreeEx() to free memory allocated with this function.
+ *
+ * @returns VBox status code.
+ * @param cPages The number of pages to allocate.
+ * @param fFlags Flags, reserved. Must be zero.
+ * @param ppvPages Where to store the address of the user mapping.
+ * @param pR0Ptr Where to store the address of the kernel mapping.
+ * NULL if no kernel mapping is desired.
+ * @param paPages Where to store the physical addresses of each page.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3PageAllocEx(size_t cPages, uint32_t fFlags, void **ppvPages, PRTR0PTR pR0Ptr, PSUPPAGE paPages);
+
+/**
+ * Maps a portion of a ring-3 only allocation into kernel space.
+ *
+ * @returns VBox status code.
+ *
+ * @param pvR3 The address SUPR3PageAllocEx return.
+ * @param off Offset to start mapping at. Must be page aligned.
+ * @param cb Number of bytes to map. Must be page aligned.
+ * @param fFlags Flags, must be zero.
+ * @param pR0Ptr Where to store the address on success.
+ *
+ */
+SUPR3DECL(int) SUPR3PageMapKernel(void *pvR3, uint32_t off, uint32_t cb, uint32_t fFlags, PRTR0PTR pR0Ptr);
+
+/**
+ * Changes the protection of
+ *
+ * @returns VBox status code.
+ * @retval VERR_NOT_SUPPORTED if the OS doesn't allow us to change page level
+ * protection. See also RTR0MemObjProtect.
+ *
+ * @param pvR3 The ring-3 address SUPR3PageAllocEx returned.
+ * @param R0Ptr The ring-0 address SUPR3PageAllocEx returned if it
+ * is desired that the corresponding ring-0 page
+ * mappings should change protection as well. Pass
+ * NIL_RTR0PTR if the ring-0 pages should remain
+ * unaffected.
+ * @param off Offset to start at which to start chagning the page
+ * level protection. Must be page aligned.
+ * @param cb Number of bytes to change. Must be page aligned.
+ * @param fProt The new page level protection, either a combination
+ * of RTMEM_PROT_READ, RTMEM_PROT_WRITE and
+ * RTMEM_PROT_EXEC, or just RTMEM_PROT_NONE.
+ */
+SUPR3DECL(int) SUPR3PageProtect(void *pvR3, RTR0PTR R0Ptr, uint32_t off, uint32_t cb, uint32_t fProt);
+
+/**
+ * Free pages allocated by SUPR3PageAllocEx.
+ *
+ * @returns VBox status code.
+ * @param pvPages The address of the user mapping.
+ * @param cPages The number of pages.
+ */
+SUPR3DECL(int) SUPR3PageFreeEx(void *pvPages, size_t cPages);
+
+/**
+ * Allocated memory with page aligned memory with a contiguous and locked physical
+ * memory backing below 4GB.
+ *
+ * @returns Pointer to the allocated memory (virtual address).
+ * *pHCPhys is set to the physical address of the memory.
+ * If ppvR0 isn't NULL, *ppvR0 is set to the ring-0 mapping.
+ * The returned memory must be freed using SUPR3ContFree().
+ * @returns NULL on failure.
+ * @param cPages Number of pages to allocate.
+ * @param pR0Ptr Where to store the ring-0 mapping of the allocation. (optional)
+ * @param pHCPhys Where to store the physical address of the memory block.
+ *
+ * @remark This 2nd version of this API exists because we're not able to map the
+ * ring-3 mapping executable on WIN64. This is a serious problem in regard to
+ * the world switchers.
+ */
+SUPR3DECL(void *) SUPR3ContAlloc(size_t cPages, PRTR0PTR pR0Ptr, PRTHCPHYS pHCPhys);
+
+/**
+ * Frees memory allocated with SUPR3ContAlloc().
+ *
+ * @returns VBox status code.
+ * @param pv Pointer to the memory block which should be freed.
+ * @param cPages Number of pages to be freed.
+ */
+SUPR3DECL(int) SUPR3ContFree(void *pv, size_t cPages);
+
+/**
+ * Allocated non contiguous physical memory below 4GB.
+ *
+ * The memory isn't zeroed.
+ *
+ * @returns VBox status code.
+ * @returns NULL on failure.
+ * @param cPages Number of pages to allocate.
+ * @param ppvPages Where to store the pointer to the allocated memory.
+ * The pointer stored here on success must be passed to
+ * SUPR3LowFree when the memory should be released.
+ * @param ppvPagesR0 Where to store the ring-0 pointer to the allocated memory. optional.
+ * @param paPages Where to store the physical addresses of the individual pages.
+ */
+SUPR3DECL(int) SUPR3LowAlloc(size_t cPages, void **ppvPages, PRTR0PTR ppvPagesR0, PSUPPAGE paPages);
+
+/**
+ * Frees memory allocated with SUPR3LowAlloc().
+ *
+ * @returns VBox status code.
+ * @param pv Pointer to the memory block which should be freed.
+ * @param cPages Number of pages that was allocated.
+ */
+SUPR3DECL(int) SUPR3LowFree(void *pv, size_t cPages);
+
+/**
+ * Load a module into R0 HC.
+ *
+ * This will verify the file integrity in a similar manner as
+ * SUPR3HardenedVerifyFile before loading it.
+ *
+ * @returns VBox status code.
+ * @param pszFilename The path to the image file.
+ * @param pszModule The module name. Max 32 bytes.
+ * @param ppvImageBase Where to store the image address.
+ * @param pErrInfo Where to return extended error information.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3LoadModule(const char *pszFilename, const char *pszModule, void **ppvImageBase, PRTERRINFO pErrInfo);
+
+/**
+ * Load a module into R0 HC.
+ *
+ * This will verify the file integrity in a similar manner as
+ * SUPR3HardenedVerifyFile before loading it.
+ *
+ * @returns VBox status code.
+ * @param pszFilename The path to the image file.
+ * @param pszModule The module name. Max 32 bytes.
+ * @param pszSrvReqHandler The name of the service request handler entry
+ * point. See FNSUPR0SERVICEREQHANDLER.
+ * @param ppvImageBase Where to store the image address.
+ */
+SUPR3DECL(int) SUPR3LoadServiceModule(const char *pszFilename, const char *pszModule,
+ const char *pszSrvReqHandler, void **ppvImageBase);
+
+/**
+ * Frees a R0 HC module.
+ *
+ * @returns VBox status code.
+ * @param pszModule The module to free.
+ * @remark This will not actually 'free' the module, there are of course usage counting.
+ */
+SUPR3DECL(int) SUPR3FreeModule(void *pvImageBase);
+
+/**
+ * Get the address of a symbol in a ring-0 module.
+ *
+ * @returns VBox status code.
+ * @param pszModule The module name.
+ * @param pszSymbol Symbol name. If it's value is less than 64k it's treated like a
+ * ordinal value rather than a string pointer.
+ * @param ppvValue Where to store the symbol value.
+ */
+SUPR3DECL(int) SUPR3GetSymbolR0(void *pvImageBase, const char *pszSymbol, void **ppvValue);
+
+/**
+ * Load R0 HC VMM code.
+ *
+ * @returns VBox status code.
+ * @deprecated Use SUPR3LoadModule(pszFilename, "VMMR0.r0", &pvImageBase)
+ */
+SUPR3DECL(int) SUPR3LoadVMM(const char *pszFilename);
+
+/**
+ * Unloads R0 HC VMM code.
+ *
+ * @returns VBox status code.
+ * @deprecated Use SUPR3FreeModule().
+ */
+SUPR3DECL(int) SUPR3UnloadVMM(void);
+
+/**
+ * Get the physical address of the GIP.
+ *
+ * @returns VBox status code.
+ * @param pHCPhys Where to store the physical address of the GIP.
+ */
+SUPR3DECL(int) SUPR3GipGetPhys(PRTHCPHYS pHCPhys);
+
+/**
+ * Verifies the integrity of a file, and optionally opens it.
+ *
+ * The integrity check is for whether the file is suitable for loading into
+ * the hypervisor or VM process. The integrity check may include verifying
+ * the authenticode/elfsign/whatever signature of the file, which can take
+ * a little while.
+ *
+ * @returns VBox status code. On failure it will have printed a LogRel message.
+ *
+ * @param pszFilename The file.
+ * @param pszWhat For the LogRel on failure.
+ * @param phFile Where to store the handle to the opened file. This is optional, pass NULL
+ * if the file should not be opened.
+ * @deprecated Write a new one.
+ */
+SUPR3DECL(int) SUPR3HardenedVerifyFile(const char *pszFilename, const char *pszWhat, PRTFILE phFile);
+
+/**
+ * Verifies the integrity of a the current process, including the image
+ * location and that the invocation was absolute.
+ *
+ * This must currently be called after initializing the runtime. The intended
+ * audience is set-uid-to-root applications, root services and similar.
+ *
+ * @returns VBox status code. On failure
+ * message.
+ * @param pszArgv0 The first argument to main().
+ * @param fInternal Set this to @c true if this is an internal
+ * VirtualBox application. Otherwise pass @c false.
+ * @param pErrInfo Where to return extended error information.
+ */
+SUPR3DECL(int) SUPR3HardenedVerifySelf(const char *pszArgv0, bool fInternal, PRTERRINFO pErrInfo);
+
+/**
+ * Verifies the integrity of an installation directory.
+ *
+ * The integrity check verifies that the directory cannot be tampered with by
+ * normal users on the system. On Unix this translates to root ownership and
+ * no symbolic linking.
+ *
+ * @returns VBox status code. On failure a message will be stored in @a pszErr.
+ *
+ * @param pszDirPath The directory path.
+ * @param fRecursive Whether the check should be recursive or
+ * not. When set, all sub-directores will be checked,
+ * including files (@a fCheckFiles is ignored).
+ * @param fCheckFiles Whether to apply the same basic integrity check to
+ * the files in the directory as the directory itself.
+ * @param pErrInfo Where to return extended error information.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3HardenedVerifyDir(const char *pszDirPath, bool fRecursive, bool fCheckFiles, PRTERRINFO pErrInfo);
+
+/**
+ * Verifies the integrity of a plug-in module.
+ *
+ * This is similar to SUPR3HardenedLdrLoad, except it does not load the module
+ * and that the module does not have to be shipped with VirtualBox.
+ *
+ * @returns VBox status code. On failure a message will be stored in @a pszErr.
+ *
+ * @param pszFilename The filename of the plug-in module (nothing can be
+ * omitted here).
+ * @param pErrInfo Where to return extended error information.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3HardenedVerifyPlugIn(const char *pszFilename, PRTERRINFO pErrInfo);
+
+/**
+ * Same as RTLdrLoad() but will verify the files it loads (hardened builds).
+ *
+ * Will add dll suffix if missing and try load the file.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Image filename. This must have a path.
+ * @param phLdrMod Where to store the handle to the loaded module.
+ * @param fFlags See RTLDRLOAD_FLAGS_XXX.
+ * @param pErrInfo Where to return extended error information.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3HardenedLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo);
+
+/**
+ * Same as RTLdrLoadAppPriv() but it will verify the files it loads (hardened
+ * builds).
+ *
+ * Will add dll suffix to the file if missing, then look for it in the
+ * architecture dependent application directory.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Image filename.
+ * @param phLdrMod Where to store the handle to the loaded module.
+ * @param fFlags See RTLDRLOAD_FLAGS_XXX.
+ * @param pErrInfo Where to return extended error information.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3HardenedLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo);
+
+/**
+ * Same as RTLdrLoad() but will verify the files it loads (hardened builds).
+ *
+ * This differs from SUPR3HardenedLdrLoad() in that it can load modules from
+ * extension packs and anything else safely installed on the system, provided
+ * they pass the hardening tests.
+ *
+ * @returns iprt status code.
+ * @param pszFilename The full path to the module, with extension.
+ * @param phLdrMod Where to store the handle to the loaded module.
+ * @param pErrInfo Where to return extended error information.
+ * Optional.
+ */
+SUPR3DECL(int) SUPR3HardenedLdrLoadPlugIn(const char *pszFilename, PRTLDRMOD phLdrMod, PRTERRINFO pErrInfo);
+
+/**
+ * Check if the host kernel can run in VMX root mode.
+ *
+ * @returns VINF_SUCCESS if supported, error code indicating why if not.
+ */
+SUPR3DECL(int) SUPR3QueryVTxSupported(void);
+
+/**
+ * Return VT-x/AMD-V capabilities.
+ *
+ * @returns VINF_SUCCESS if supported, error code indicating why if not.
+ * @param pfCaps Pointer to capability dword (out).
+ * @todo Intended for main, which means we need to relax the privilege requires
+ * when accessing certain vboxdrv functions.
+ */
+SUPR3DECL(int) SUPR3QueryVTCaps(uint32_t *pfCaps);
+
+/**
+ * Open the tracer.
+ *
+ * @returns VBox status code.
+ * @param uCookie Cookie identifying the tracer we expect to talk to.
+ * @param uArg Tracer specific open argument.
+ */
+SUPR3DECL(int) SUPR3TracerOpen(uint32_t uCookie, uintptr_t uArg);
+
+/**
+ * Closes the tracer.
+ *
+ * @returns VBox status code.
+ */
+SUPR3DECL(int) SUPR3TracerClose(void);
+
+/**
+ * Perform an I/O request on the tracer.
+ *
+ * @returns VBox status.
+ * @param uCmd The tracer command.
+ * @param uArg The argument.
+ * @param piRetVal Where to store the tracer return value.
+ */
+SUPR3DECL(int) SUPR3TracerIoCtl(uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal);
+
+/**
+ * Registers the user module with the tracer.
+ *
+ * @returns VBox status code.
+ * @param hModNative Native module handle. Pass ~(uintptr_t)0 if not
+ * at hand.
+ * @param pszModule The module name.
+ * @param pVtgHdr The VTG header.
+ * @param uVtgHdrAddr The address to which the VTG header is loaded
+ * in the relevant execution context.
+ * @param fFlags See SUP_TRACER_UMOD_FLAGS_XXX
+ */
+SUPR3DECL(int) SUPR3TracerRegisterModule(uintptr_t hModNative, const char *pszModule, struct VTGOBJHDR *pVtgHdr,
+ RTUINTPTR uVtgHdrAddr, uint32_t fFlags);
+
+/**
+ * Deregisters the user module.
+ *
+ * @returns VBox status code.
+ * @param pVtgHdr The VTG header.
+ */
+SUPR3DECL(int) SUPR3TracerDeregisterModule(struct VTGOBJHDR *pVtgHdr);
+
+/**
+ * Fire the probe.
+ *
+ * @param pVtgProbeLoc The probe location record.
+ * @param uArg0 Raw probe argument 0.
+ * @param uArg1 Raw probe argument 1.
+ * @param uArg2 Raw probe argument 2.
+ * @param uArg3 Raw probe argument 3.
+ * @param uArg4 Raw probe argument 4.
+ */
+SUPDECL(void) SUPTracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
+ uintptr_t uArg3, uintptr_t uArg4);
+/** @} */
+#endif /* IN_RING3 */
+
+/** @name User mode module flags (SUPR3TracerRegisterModule & SUP_IOCTL_TRACER_UMOD_REG).
+ * @{ */
+/** Executable image. */
+#define SUP_TRACER_UMOD_FLAGS_EXE UINT32_C(1)
+/** Shared library (DLL, DYLIB, SO, etc). */
+#define SUP_TRACER_UMOD_FLAGS_SHARED UINT32_C(2)
+/** Image type mask. */
+#define SUP_TRACER_UMOD_FLAGS_TYPE_MASK UINT32_C(3)
+/** @} */
+
+
+#ifdef IN_RING0
+/** @defgroup grp_sup_r0 SUP Host Context Ring-0 API
+ * @ingroup grp_sup
+ * @{
+ */
+
+/**
+ * Security objectype.
+ */
+typedef enum SUPDRVOBJTYPE
+{
+ /** The usual invalid object. */
+ SUPDRVOBJTYPE_INVALID = 0,
+ /** A Virtual Machine instance. */
+ SUPDRVOBJTYPE_VM,
+ /** Internal network. */
+ SUPDRVOBJTYPE_INTERNAL_NETWORK,
+ /** Internal network interface. */
+ SUPDRVOBJTYPE_INTERNAL_NETWORK_INTERFACE,
+ /** Single release event semaphore. */
+ SUPDRVOBJTYPE_SEM_EVENT,
+ /** Multiple release event semaphore. */
+ SUPDRVOBJTYPE_SEM_EVENT_MULTI,
+ /** Raw PCI device. */
+ SUPDRVOBJTYPE_RAW_PCI_DEVICE,
+ /** The first invalid object type in this end. */
+ SUPDRVOBJTYPE_END,
+ /** The usual 32-bit type size hack. */
+ SUPDRVOBJTYPE_32_BIT_HACK = 0x7ffffff
+} SUPDRVOBJTYPE;
+
+/**
+ * Object destructor callback.
+ * This is called for reference counted objectes when the count reaches 0.
+ *
+ * @param pvObj The object pointer.
+ * @param pvUser1 The first user argument.
+ * @param pvUser2 The second user argument.
+ */
+typedef DECLCALLBACK(void) FNSUPDRVDESTRUCTOR(void *pvObj, void *pvUser1, void *pvUser2);
+/** Pointer to a FNSUPDRVDESTRUCTOR(). */
+typedef FNSUPDRVDESTRUCTOR *PFNSUPDRVDESTRUCTOR;
+
+SUPR0DECL(void *) SUPR0ObjRegister(PSUPDRVSESSION pSession, SUPDRVOBJTYPE enmType, PFNSUPDRVDESTRUCTOR pfnDestructor, void *pvUser1, void *pvUser2);
+SUPR0DECL(int) SUPR0ObjAddRef(void *pvObj, PSUPDRVSESSION pSession);
+SUPR0DECL(int) SUPR0ObjAddRefEx(void *pvObj, PSUPDRVSESSION pSession, bool fNoBlocking);
+SUPR0DECL(int) SUPR0ObjRelease(void *pvObj, PSUPDRVSESSION pSession);
+SUPR0DECL(int) SUPR0ObjVerifyAccess(void *pvObj, PSUPDRVSESSION pSession, const char *pszObjName);
+
+SUPR0DECL(int) SUPR0LockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t cPages, PRTHCPHYS paPages);
+SUPR0DECL(int) SUPR0UnlockMem(PSUPDRVSESSION pSession, RTR3PTR pvR3);
+SUPR0DECL(int) SUPR0ContAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS pHCPhys);
+SUPR0DECL(int) SUPR0ContFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);
+SUPR0DECL(int) SUPR0LowAlloc(PSUPDRVSESSION pSession, uint32_t cPages, PRTR0PTR ppvR0, PRTR3PTR ppvR3, PRTHCPHYS paPages);
+SUPR0DECL(int) SUPR0LowFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);
+SUPR0DECL(int) SUPR0MemAlloc(PSUPDRVSESSION pSession, uint32_t cb, PRTR0PTR ppvR0, PRTR3PTR ppvR3);
+SUPR0DECL(int) SUPR0MemGetPhys(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr, PSUPPAGE paPages);
+SUPR0DECL(int) SUPR0MemFree(PSUPDRVSESSION pSession, RTHCUINTPTR uPtr);
+SUPR0DECL(int) SUPR0PageAllocEx(PSUPDRVSESSION pSession, uint32_t cPages, uint32_t fFlags, PRTR3PTR ppvR3, PRTR0PTR ppvR0, PRTHCPHYS paPages);
+SUPR0DECL(int) SUPR0PageMapKernel(PSUPDRVSESSION pSession, RTR3PTR pvR3, uint32_t offSub, uint32_t cbSub, uint32_t fFlags, PRTR0PTR ppvR0);
+SUPR0DECL(int) SUPR0PageProtect(PSUPDRVSESSION pSession, RTR3PTR pvR3, RTR0PTR pvR0, uint32_t offSub, uint32_t cbSub, uint32_t fProt);
+SUPR0DECL(int) SUPR0PageFree(PSUPDRVSESSION pSession, RTR3PTR pvR3);
+SUPR0DECL(int) SUPR0GipMap(PSUPDRVSESSION pSession, PRTR3PTR ppGipR3, PRTHCPHYS pHCPhysGip);
+SUPR0DECL(int) SUPR0QueryVTCaps(PSUPDRVSESSION pSession, uint32_t *pfCaps);
+SUPR0DECL(int) SUPR0GipUnmap(PSUPDRVSESSION pSession);
+SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...);
+SUPR0DECL(SUPPAGINGMODE) SUPR0GetPagingMode(void);
+SUPR0DECL(int) SUPR0EnableVTx(bool fEnable);
+
+/** @name Absolute symbols
+ * Take the address of these, don't try call them.
+ * @{ */
+SUPR0DECL(void) SUPR0AbsIs64bit(void);
+SUPR0DECL(void) SUPR0Abs64bitKernelCS(void);
+SUPR0DECL(void) SUPR0Abs64bitKernelSS(void);
+SUPR0DECL(void) SUPR0Abs64bitKernelDS(void);
+SUPR0DECL(void) SUPR0AbsKernelCS(void);
+SUPR0DECL(void) SUPR0AbsKernelSS(void);
+SUPR0DECL(void) SUPR0AbsKernelDS(void);
+SUPR0DECL(void) SUPR0AbsKernelES(void);
+SUPR0DECL(void) SUPR0AbsKernelFS(void);
+SUPR0DECL(void) SUPR0AbsKernelGS(void);
+/** @} */
+
+/**
+ * Support driver component factory.
+ *
+ * Component factories are registered by drivers that provides services
+ * such as the host network interface filtering and access to the host
+ * TCP/IP stack.
+ *
+ * @remark Module dependencies and making sure that a component doesn't
+ * get unloaded while in use, is the sole responsibility of the
+ * driver/kext/whatever implementing the component.
+ */
+typedef struct SUPDRVFACTORY
+{
+ /** The (unique) name of the component factory. */
+ char szName[56];
+ /**
+ * Queries a factory interface.
+ *
+ * The factory interface is specific to each component and will be be
+ * found in the header(s) for the component alongside its UUID.
+ *
+ * @returns Pointer to the factory interfaces on success, NULL on failure.
+ *
+ * @param pSupDrvFactory Pointer to this structure.
+ * @param pSession The SUPDRV session making the query.
+ * @param pszInterfaceUuid The UUID of the factory interface.
+ */
+ DECLR0CALLBACKMEMBER(void *, pfnQueryFactoryInterface,(struct SUPDRVFACTORY const *pSupDrvFactory, PSUPDRVSESSION pSession, const char *pszInterfaceUuid));
+} SUPDRVFACTORY;
+/** Pointer to a support driver factory. */
+typedef SUPDRVFACTORY *PSUPDRVFACTORY;
+/** Pointer to a const support driver factory. */
+typedef SUPDRVFACTORY const *PCSUPDRVFACTORY;
+
+SUPR0DECL(int) SUPR0ComponentRegisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory);
+SUPR0DECL(int) SUPR0ComponentDeregisterFactory(PSUPDRVSESSION pSession, PCSUPDRVFACTORY pFactory);
+SUPR0DECL(int) SUPR0ComponentQueryFactory(PSUPDRVSESSION pSession, const char *pszName, const char *pszInterfaceUuid, void **ppvFactoryIf);
+
+
+/** @name Tracing
+ * @{ */
+
+/**
+ * Tracer data associated with a provider.
+ */
+typedef union SUPDRVTRACERDATA
+{
+ /** Generic */
+ uint64_t au64[2];
+
+ /** DTrace data. */
+ struct
+ {
+ /** Provider ID. */
+ uintptr_t idProvider;
+ /** The number of trace points provided. */
+ uint32_t volatile cProvidedProbes;
+ /** Whether we've invalidated this bugger. */
+ bool fZombie;
+ } DTrace;
+} SUPDRVTRACERDATA;
+/** Pointer to the tracer data associated with a provider. */
+typedef SUPDRVTRACERDATA *PSUPDRVTRACERDATA;
+
+/**
+ * Probe location info for ring-0.
+ *
+ * Since we cannot trust user tracepoint modules, we need to duplicate the probe
+ * ID and enabled flag in ring-0.
+ */
+typedef struct SUPDRVPROBELOC
+{
+ /** The probe ID. */
+ uint32_t idProbe;
+ /** Whether it's enabled or not. */
+ bool fEnabled;
+} SUPDRVPROBELOC;
+/** Pointer to a ring-0 probe location record. */
+typedef SUPDRVPROBELOC *PSUPDRVPROBELOC;
+
+/**
+ * Probe info for ring-0.
+ *
+ * Since we cannot trust user tracepoint modules, we need to duplicate the
+ * probe enable count.
+ */
+typedef struct SUPDRVPROBEINFO
+{
+ /** The number of times this probe has been enabled. */
+ uint32_t volatile cEnabled;
+} SUPDRVPROBEINFO;
+/** Pointer to a ring-0 probe info record. */
+typedef SUPDRVPROBEINFO *PSUPDRVPROBEINFO;
+
+/**
+ * Support driver tracepoint provider core.
+ */
+typedef struct SUPDRVVDTPROVIDERCORE
+{
+ /** The tracer data member. */
+ SUPDRVTRACERDATA TracerData;
+ /** Pointer to the provider name (a copy that's always available). */
+ const char *pszName;
+ /** Pointer to the module name (a copy that's always available). */
+ const char *pszModName;
+
+ /** The provider descriptor. */
+ struct VTGDESCPROVIDER *pDesc;
+ /** The VTG header. */
+ struct VTGOBJHDR *pHdr;
+
+ /** The size of the entries in the pvProbeLocsEn table. */
+ uint8_t cbProbeLocsEn;
+ /** The actual module bit count (corresponds to cbProbeLocsEn). */
+ uint8_t cBits;
+ /** Set if this is a Umod, otherwise clear.. */
+ bool fUmod;
+ /** Explicit alignment padding (paranoia). */
+ uint8_t abAlignment[ARCH_BITS == 32 ? 1 : 5];
+
+ /** The probe locations used for descriptive purposes. */
+ struct VTGPROBELOC const *paProbeLocsRO;
+ /** Pointer to the probe location array where the enable flag needs
+ * flipping. For kernel providers, this will always be SUPDRVPROBELOC,
+ * while user providers can either be 32-bit or 64-bit. Use
+ * cbProbeLocsEn to calculate the address of an entry. */
+ void *pvProbeLocsEn;
+ /** Pointer to the probe array containing the enabled counts. */
+ uint32_t *pacProbeEnabled;
+
+ /** The ring-0 probe location info for user tracepoint modules.
+ * This is NULL if fUmod is false. */
+ PSUPDRVPROBELOC paR0ProbeLocs;
+ /** The ring-0 probe info for user tracepoint modules.
+ * This is NULL if fUmod is false. */
+ PSUPDRVPROBEINFO paR0Probes;
+
+} SUPDRVVDTPROVIDERCORE;
+/** Pointer to a tracepoint provider core structure. */
+typedef SUPDRVVDTPROVIDERCORE *PSUPDRVVDTPROVIDERCORE;
+
+/** Pointer to a tracer registration record. */
+typedef struct SUPDRVTRACERREG const *PCSUPDRVTRACERREG;
+/**
+ * Support driver tracer registration record.
+ */
+typedef struct SUPDRVTRACERREG
+{
+ /** Magic value (SUPDRVTRACERREG_MAGIC). */
+ uint32_t u32Magic;
+ /** Version (SUPDRVTRACERREG_VERSION). */
+ uint32_t u32Version;
+
+ /**
+ * Fire off a kernel probe.
+ *
+ * @param pVtgProbeLoc The probe location record.
+ * @param uArg0 The first raw probe argument.
+ * @param uArg1 The second raw probe argument.
+ * @param uArg2 The third raw probe argument.
+ * @param uArg3 The fourth raw probe argument.
+ * @param uArg4 The fifth raw probe argument.
+ *
+ * @remarks SUPR0TracerFireProbe will do a tail jump thru this member, so
+ * no extra stack frames will be added.
+ * @remarks This does not take a 'this' pointer argument because it doesn't map
+ * well onto VTG or DTrace.
+ *
+ */
+ DECLR0CALLBACKMEMBER(void, pfnProbeFireKernel, (struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
+ uintptr_t uArg3, uintptr_t uArg4));
+
+ /**
+ * Fire off a user-mode probe.
+ *
+ * @param pThis Pointer to the registration record.
+ *
+ * @param pVtgProbeLoc The probe location record.
+ * @param pSession The user session.
+ * @param pCtx The usermode context info.
+ * @param pVtgHdr The VTG header (read-only).
+ * @param pProbeLocRO The read-only probe location record .
+ */
+ DECLR0CALLBACKMEMBER(void, pfnProbeFireUser, (PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, PCSUPDRVTRACERUSRCTX pCtx,
+ struct VTGOBJHDR const *pVtgHdr, struct VTGPROBELOC const *pProbeLocRO));
+
+ /**
+ * Opens up the tracer.
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to the registration record.
+ * @param pSession The session doing the opening.
+ * @param uCookie A cookie (magic) unique to the tracer, so it can
+ * fend off incompatible clients.
+ * @param uArg Tracer specific argument.
+ * @param puSessionData Pointer to the session data variable. This must be
+ * set to a non-zero value on success.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnTracerOpen, (PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uint32_t uCookie, uintptr_t uArg,
+ uintptr_t *puSessionData));
+
+ /**
+ * I/O control style tracer communication method.
+ *
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to the registration record.
+ * @param pSession The session.
+ * @param uSessionData The session data value.
+ * @param uCmd The tracer specific command.
+ * @param uArg The tracer command specific argument.
+ * @param piRetVal The tracer specific return value.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnTracerIoCtl, (PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData,
+ uintptr_t uCmd, uintptr_t uArg, int32_t *piRetVal));
+
+ /**
+ * Cleans up data the tracer has associated with a session.
+ *
+ * @param pThis Pointer to the registration record.
+ * @param pSession The session handle.
+ * @param uSessionData The data assoicated with the session.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnTracerClose, (PCSUPDRVTRACERREG pThis, PSUPDRVSESSION pSession, uintptr_t uSessionData));
+
+ /**
+ * Registers a provider.
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to the registration record.
+ * @param pCore The provider core data.
+ *
+ * @todo Kernel vs. Userland providers.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnProviderRegister, (PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore));
+
+ /**
+ * Attempts to deregisters a provider.
+ *
+ * @returns VINF_SUCCESS or VERR_TRY_AGAIN. If the latter, the provider
+ * should be made as harmless as possible before returning as the
+ * VTG object and associated code will be unloaded upon return.
+ *
+ * @param pThis Pointer to the registration record.
+ * @param pCore The provider core data.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnProviderDeregister, (PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore));
+
+ /**
+ * Make another attempt at unregister a busy provider.
+ *
+ * @returns VINF_SUCCESS or VERR_TRY_AGAIN.
+ * @param pThis Pointer to the registration record.
+ * @param pCore The provider core data.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnProviderDeregisterZombie, (PCSUPDRVTRACERREG pThis, PSUPDRVVDTPROVIDERCORE pCore));
+
+ /** End marker (SUPDRVTRACERREG_MAGIC). */
+ uintptr_t uEndMagic;
+} SUPDRVTRACERREG;
+
+/** Tracer magic (Kenny Garrett). */
+#define SUPDRVTRACERREG_MAGIC UINT32_C(0x19601009)
+/** Tracer registration structure version. */
+#define SUPDRVTRACERREG_VERSION RT_MAKE_U32(0, 1)
+
+/** Pointer to a trace helper structure. */
+typedef struct SUPDRVTRACERHLP const *PCSUPDRVTRACERHLP;
+/**
+ * Helper structure.
+ */
+typedef struct SUPDRVTRACERHLP
+{
+ /** The structure version (SUPDRVTRACERHLP_VERSION). */
+ uintptr_t uVersion;
+
+ /** @todo ... */
+
+ /** End marker (SUPDRVTRACERHLP_VERSION) */
+ uintptr_t uEndVersion;
+} SUPDRVTRACERHLP;
+/** Tracer helper structure version. */
+#define SUPDRVTRACERHLP_VERSION RT_MAKE_U32(0, 1)
+
+SUPR0DECL(int) SUPR0TracerRegisterImpl(void *hMod, PSUPDRVSESSION pSession, PCSUPDRVTRACERREG pReg, PCSUPDRVTRACERHLP *ppHlp);
+SUPR0DECL(int) SUPR0TracerDeregisterImpl(void *hMod, PSUPDRVSESSION pSession);
+SUPR0DECL(int) SUPR0TracerRegisterDrv(PSUPDRVSESSION pSession, struct VTGOBJHDR *pVtgHdr, const char *pszName);
+SUPR0DECL(void) SUPR0TracerDeregisterDrv(PSUPDRVSESSION pSession);
+SUPR0DECL(int) SUPR0TracerRegisterModule(void *hMod, struct VTGOBJHDR *pVtgHdr);
+SUPR0DECL(void) SUPR0TracerFireProbe(struct VTGPROBELOC *pVtgProbeLoc, uintptr_t uArg0, uintptr_t uArg1, uintptr_t uArg2,
+ uintptr_t uArg3, uintptr_t uArg4);
+SUPR0DECL(void) SUPR0TracerUmodProbeFire(PSUPDRVSESSION pSession, PSUPDRVTRACERUSRCTX pCtx);
+/** @} */
+
+
+/**
+ * Service request callback function.
+ *
+ * @returns VBox status code.
+ * @param pSession The caller's session.
+ * @param u64Arg 64-bit integer argument.
+ * @param pReqHdr The request header. Input / Output. Optional.
+ */
+typedef DECLCALLBACK(int) FNSUPR0SERVICEREQHANDLER(PSUPDRVSESSION pSession, uint32_t uOperation,
+ uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr);
+/** Pointer to a FNR0SERVICEREQHANDLER(). */
+typedef R0PTRTYPE(FNSUPR0SERVICEREQHANDLER *) PFNSUPR0SERVICEREQHANDLER;
+
+
+/** @defgroup grp_sup_r0_idc The IDC Interface
+ * @ingroup grp_sup_r0
+ * @{
+ */
+
+/** The current SUPDRV IDC version.
+ * This follows the usual high word / low word rules, i.e. high word is the
+ * major number and it signifies incompatible interface changes. */
+#define SUPDRV_IDC_VERSION UINT32_C(0x00010000)
+
+/**
+ * Inter-Driver Communication Handle.
+ */
+typedef union SUPDRVIDCHANDLE
+{
+ /** Padding for opaque usage.
+ * Must be greater or equal in size than the private struct. */
+ void *apvPadding[4];
+#ifdef SUPDRVIDCHANDLEPRIVATE_DECLARED
+ /** The private view. */
+ struct SUPDRVIDCHANDLEPRIVATE s;
+#endif
+} SUPDRVIDCHANDLE;
+/** Pointer to a handle. */
+typedef SUPDRVIDCHANDLE *PSUPDRVIDCHANDLE;
+
+SUPR0DECL(int) SUPR0IdcOpen(PSUPDRVIDCHANDLE pHandle, uint32_t uReqVersion, uint32_t uMinVersion,
+ uint32_t *puSessionVersion, uint32_t *puDriverVersion, uint32_t *puDriverRevision);
+SUPR0DECL(int) SUPR0IdcCall(PSUPDRVIDCHANDLE pHandle, uint32_t iReq, void *pvReq, uint32_t cbReq);
+SUPR0DECL(int) SUPR0IdcClose(PSUPDRVIDCHANDLE pHandle);
+SUPR0DECL(PSUPDRVSESSION) SUPR0IdcGetSession(PSUPDRVIDCHANDLE pHandle);
+SUPR0DECL(int) SUPR0IdcComponentRegisterFactory(PSUPDRVIDCHANDLE pHandle, PCSUPDRVFACTORY pFactory);
+SUPR0DECL(int) SUPR0IdcComponentDeregisterFactory(PSUPDRVIDCHANDLE pHandle, PCSUPDRVFACTORY pFactory);
+
+/** @} */
+
+/** @name Ring-0 module entry points.
+ *
+ * These can be exported by ring-0 modules SUP are told to load.
+ *
+ * @{ */
+DECLEXPORT(int) ModuleInit(void *hMod);
+DECLEXPORT(void) ModuleTerm(void *hMod);
+/** @} */
+
+
+/** @} */
+#endif
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/sup.mac b/include/VBox/sup.mac
new file mode 100644
index 00000000..1ca7adcb
--- /dev/null
+++ b/include/VBox/sup.mac
@@ -0,0 +1,123 @@
+; $Id: sup.mac $
+;; @file
+; SUP - Support Library, assembly definitions.
+;
+
+;
+; Copyright (C) 2006-2012 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; 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 ___VBox_sup_mac
+%define ___VBox_sup_mac
+
+struc SUPGIPCPU
+ .u32TransactionId resd 1
+ .u32UpdateIntervalTSC resd 1
+ .u64NanoTS resq 1
+ .u64TSC resq 1
+ .u64CpuHz resq 1
+ .cErrors resd 1
+ .iTSCHistoryHead resd 1
+ .au32TSCHistory resd 8
+ .u32PrevUpdateIntervalNS resd 1
+ .au32Reserved resd (5+5)
+ .enmState resd 1
+ .idCpu resd 1
+ .iCpuSet resw 1
+ .idApic resw 1
+endstruc
+
+%define SUPGLOBALINFOPAGE_MAGIC 0x19590106
+struc SUPGLOBALINFOPAGE
+ .u32Magic resd 1
+ .u32Version resd 1
+ .u32Mode resd 1
+ .cCpus resw 1
+ .cPages resw 1
+ .u32UpdateHz resd 1
+ .u32UpdateIntervalNS resd 1
+ .u64NanoTSLastUpdateHz resq 1
+ .OnlineCpuSet resq 4
+ .PresentCpuSet resq 4
+ .PossibleCpuSet resq 4
+ .cOnlineCpus resw 1
+ .cPresentCpus resw 1
+ .cPossibleCpus resw 1
+ .u16Padding0 resw 1
+ .idCpuMax resd 1
+ .au32Padding1 resd 29
+ .aiCpuFromApicId resw 256
+ .aiCpuFromCpuSetIdx resw 256
+ .aCPUs resb SUPGIPCPU_size
+endstruc
+
+struc SUPDRVTRACERUSRCTX32
+ .idProbe resd 1
+ .cBits resb 1
+ .abReserved resb 3
+ .u.X86.uVtgProbeLoc resd 1
+ .u.X86.aArgs resd 20
+ .u.X86.eip resd 1
+ .u.X86.eflags resd 1
+ .u.X86.eax resd 1
+ .u.X86.ecx resd 1
+ .u.X86.edx resd 1
+ .u.X86.ebx resd 1
+ .u.X86.esp resd 1
+ .u.X86.ebp resd 1
+ .u.X86.esi resd 1
+ .u.X86.edi resd 1
+ .u.X86.cs resw 1
+ .u.X86.ss resw 1
+ .u.X86.ds resw 1
+ .u.X86.es resw 1
+ .u.X86.fs resw 1
+ .u.X86.gs resw 1
+endstruc
+
+struc SUPDRVTRACERUSRCTX64
+ .idProbe resd 1
+ .cBits resb 1
+ .abReserved resb 3
+ .u.Amd64.uVtgProbeLoc resq 1
+ .u.Amd64.aArgs resq 10
+ .u.Amd64.rip resq 1
+ .u.Amd64.rflags resq 1
+ .u.Amd64.rax resq 1
+ .u.Amd64.rcx resq 1
+ .u.Amd64.rdx resq 1
+ .u.Amd64.rbx resq 1
+ .u.Amd64.rsp resq 1
+ .u.Amd64.rbp resq 1
+ .u.Amd64.rsi resq 1
+ .u.Amd64.rdi resq 1
+ .u.Amd64.r8 resq 1
+ .u.Amd64.r9 resq 1
+ .u.Amd64.r10 resq 1
+ .u.Amd64.r11 resq 1
+ .u.Amd64.r12 resq 1
+ .u.Amd64.r13 resq 1
+ .u.Amd64.r14 resq 1
+ .u.Amd64.r15 resq 1
+endstruc
+
+
+%endif
+
diff --git a/include/VBox/types.h b/include/VBox/types.h
new file mode 100644
index 00000000..9abf5b6b
--- /dev/null
+++ b/include/VBox/types.h
@@ -0,0 +1,1057 @@
+/** @file
+ * VirtualBox - Types.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_types_h
+#define ___VBox_types_h
+
+#include <VBox/cdefs.h>
+#include <iprt/types.h>
+
+
+/** @defgroup grp_types Basic VBox Types
+ * @{
+ */
+
+
+/** @defgroup grp_types_both Common Guest and Host Context Basic Types
+ * @ingroup grp_types
+ * @{
+ */
+
+
+/** @defgroup grp_types_hc Host Context Basic Types
+ * @ingroup grp_types_both
+ * @{
+ */
+
+/** @} */
+
+
+/** @defgroup grp_types_gc Guest Context Basic Types
+ * @ingroup grp_types_both
+ * @{
+ */
+
+/** @} */
+
+
+/** Pointer to per support driver session data.
+ * (The data is a R0 entity and private to the the R0 SUP part. All
+ * other should consider this a sort of handle.) */
+typedef R0PTRTYPE(struct SUPDRVSESSION *) PSUPDRVSESSION;
+
+/** Pointer to a VM. */
+typedef struct VM *PVM;
+/** Pointer to a VM - Ring-0 Ptr. */
+typedef R0PTRTYPE(struct VM *) PVMR0;
+/** Pointer to a VM - Ring-3 Ptr. */
+typedef R3PTRTYPE(struct VM *) PVMR3;
+/** Pointer to a VM - RC Ptr. */
+typedef RCPTRTYPE(struct VM *) PVMRC;
+
+/** Pointer to a virtual CPU structure. */
+typedef struct VMCPU * PVMCPU;
+/** Pointer to a virtual CPU structure - Ring-3 Ptr. */
+typedef R3PTRTYPE(struct VMCPU *) PVMCPUR3;
+/** Pointer to a virtual CPU structure - Ring-0 Ptr. */
+typedef R0PTRTYPE(struct VMCPU *) PVMCPUR0;
+/** Pointer to a virtual CPU structure - RC Ptr. */
+typedef RCPTRTYPE(struct VMCPU *) PVMCPURC;
+
+/** Pointer to a ring-0 (global) VM structure. */
+typedef R0PTRTYPE(struct GVM *) PGVM;
+
+/** Pointer to a ring-3 (user mode) VM structure. */
+typedef R3PTRTYPE(struct UVM *) PUVM;
+
+/** Pointer to a ring-3 (user mode) VMCPU structure. */
+typedef R3PTRTYPE(struct UVMCPU *) PUVMCPU;
+
+/** Virtual CPU ID. */
+typedef uint32_t VMCPUID;
+/** Pointer to a virtual CPU ID. */
+typedef VMCPUID *PVMCPUID;
+/** @name Special CPU ID values.
+ * Most of these are for request scheduling.
+ *
+ * @{ */
+/** All virtual CPUs. */
+#define VMCPUID_ALL UINT32_C(0xfffffff2)
+/** All virtual CPUs, descending order. */
+#define VMCPUID_ALL_REVERSE UINT32_C(0xfffffff3)
+/** Any virtual CPU.
+ * Intended for scheduling a VM request or some other task. */
+#define VMCPUID_ANY UINT32_C(0xfffffff4)
+/** Any virtual CPU; always queue for future execution.
+ * Intended for scheduling a VM request or some other task. */
+#define VMCPUID_ANY_QUEUE UINT32_C(0xfffffff5)
+/** The NIL value. */
+#define NIL_VMCPUID UINT32_C(0xfffffffd)
+/** @} */
+
+/**
+ * Virtual CPU set.
+ */
+typedef struct VMCPUSET
+{
+ /** The bitmap data. */
+ uint32_t au32Bitmap[8 /*256/32*/];
+} VMCPUSET;
+/** Pointer to a Virtual CPU set. */
+typedef VMCPUSET *PVMCPUSET;
+/** Pointer to a const Virtual CPU set. */
+typedef VMCPUSET const *PCVMCPUSET;
+
+
+/**
+ * VM State
+ */
+typedef enum VMSTATE
+{
+ /** The VM is being created. */
+ VMSTATE_CREATING = 0,
+ /** The VM is created. */
+ VMSTATE_CREATED,
+ /** The VM state is being loaded from file. */
+ VMSTATE_LOADING,
+ /** The VM is being powered on */
+ VMSTATE_POWERING_ON,
+ /** The VM is being resumed. */
+ VMSTATE_RESUMING,
+ /** The VM is runnning. */
+ VMSTATE_RUNNING,
+ /** Live save: The VM is running and the state is being saved. */
+ VMSTATE_RUNNING_LS,
+ /** Fault Tolerance: The VM is running and the state is being synced. */
+ VMSTATE_RUNNING_FT,
+ /** The VM is being reset. */
+ VMSTATE_RESETTING,
+ /** Live save: The VM is being reset and immediately suspended. */
+ VMSTATE_RESETTING_LS,
+ /** The VM is being suspended. */
+ VMSTATE_SUSPENDING,
+ /** Live save: The VM is being suspended during a live save operation, either as
+ * part of the normal flow or VMR3Reset. */
+ VMSTATE_SUSPENDING_LS,
+ /** Live save: The VM is being suspended by VMR3Suspend during live save. */
+ VMSTATE_SUSPENDING_EXT_LS,
+ /** The VM is suspended. */
+ VMSTATE_SUSPENDED,
+ /** Live save: The VM has been suspended and is waiting for the live save
+ * operation to move on. */
+ VMSTATE_SUSPENDED_LS,
+ /** Live save: The VM has been suspended by VMR3Suspend during a live save. */
+ VMSTATE_SUSPENDED_EXT_LS,
+ /** The VM is suspended and its state is being saved by EMT(0). (See SSM) */
+ VMSTATE_SAVING,
+ /** The VM is being debugged. (See DBGF.) */
+ VMSTATE_DEBUGGING,
+ /** Live save: The VM is being debugged while the live phase is going on. */
+ VMSTATE_DEBUGGING_LS,
+ /** The VM is being powered off. */
+ VMSTATE_POWERING_OFF,
+ /** Live save: The VM is being powered off and the save cancelled. */
+ VMSTATE_POWERING_OFF_LS,
+ /** The VM is switched off, awaiting destruction. */
+ VMSTATE_OFF,
+ /** Live save: Waiting for cancellation and transition to VMSTATE_OFF. */
+ VMSTATE_OFF_LS,
+ /** The VM is powered off because of a fatal error. */
+ VMSTATE_FATAL_ERROR,
+ /** Live save: Waiting for cancellation and transition to FatalError. */
+ VMSTATE_FATAL_ERROR_LS,
+ /** The VM is in guru meditation over a fatal failure. */
+ VMSTATE_GURU_MEDITATION,
+ /** Live save: Waiting for cancellation and transition to GuruMeditation. */
+ VMSTATE_GURU_MEDITATION_LS,
+ /** The VM is screwed because of a failed state loading. */
+ VMSTATE_LOAD_FAILURE,
+ /** The VM is being destroyed. */
+ VMSTATE_DESTROYING,
+ /** Terminated. */
+ VMSTATE_TERMINATED,
+ /** hack forcing the size of the enum to 32-bits. */
+ VMSTATE_MAKE_32BIT_HACK = 0x7fffffff
+} VMSTATE;
+
+/** @def VBOXSTRICTRC_STRICT_ENABLED
+ * Indicates that VBOXSTRICTRC is in strict mode.
+ */
+#if defined(__cplusplus) \
+ && ARCH_BITS == 64 /* cdecl requires classes and structs as hidden params. */ \
+ && !defined(_MSC_VER) /* trouble similar to 32-bit gcc. */ \
+ && ( defined(RT_STRICT) \
+ || defined(VBOX_STRICT) \
+ || defined(DEBUG) \
+ || defined(DOXYGEN_RUNNING) )
+# define VBOXSTRICTRC_STRICT_ENABLED 1
+# ifdef _MSC_VER
+# pragma warning(disable:4190)
+# endif
+#endif
+
+/** We need RTERR_STRICT_RC. */
+#if defined(VBOXSTRICTRC_STRICT_ENABLED) && !defined(RTERR_STRICT_RC)
+# define RTERR_STRICT_RC 1
+#endif
+
+/**
+ * Strict VirtualBox status code.
+ *
+ * This is normally an 32-bit integer and the only purpose of the type is to
+ * highlight the special handling that is required. But in strict build it is a
+ * class that causes compilation and runtime errors for some of the incorrect
+ * handling.
+ */
+#ifdef VBOXSTRICTRC_STRICT_ENABLED
+struct VBOXSTRICTRC
+{
+protected:
+ /** The status code. */
+ int32_t m_rc;
+
+public:
+ /** Default constructor setting the status to VERR_IPE_UNINITIALIZED_STATUS. */
+ VBOXSTRICTRC()
+#ifdef VERR_IPE_UNINITIALIZED_STATUS
+ : m_rc(VERR_IPE_UNINITIALIZED_STATUS)
+#else
+ : m_rc(-233 /*VERR_IPE_UNINITIALIZED_STATUS*/)
+#endif
+ {
+ }
+
+ /** Constructor for normal integer status codes. */
+ VBOXSTRICTRC(int32_t const rc)
+ : m_rc(rc)
+ {
+ }
+
+ /** Getter that VBOXSTRICTRC_VAL can use. */
+ int32_t getValue() const { return m_rc; }
+
+ /** @name Comparison operators
+ * @{ */
+ bool operator==(int32_t rc) const { return m_rc == rc; }
+ bool operator!=(int32_t rc) const { return m_rc != rc; }
+ bool operator<=(int32_t rc) const { return m_rc <= rc; }
+ bool operator>=(int32_t rc) const { return m_rc >= rc; }
+ bool operator<(int32_t rc) const { return m_rc < rc; }
+ bool operator>(int32_t rc) const { return m_rc > rc; }
+
+ bool operator==(const VBOXSTRICTRC &rRc) const { return m_rc == rRc.m_rc; }
+ bool operator!=(const VBOXSTRICTRC &rRc) const { return m_rc != rRc.m_rc; }
+ bool operator<=(const VBOXSTRICTRC &rRc) const { return m_rc <= rRc.m_rc; }
+ bool operator>=(const VBOXSTRICTRC &rRc) const { return m_rc >= rRc.m_rc; }
+ bool operator<(const VBOXSTRICTRC &rRc) const { return m_rc < rRc.m_rc; }
+ bool operator>(const VBOXSTRICTRC &rRc) const { return m_rc > rRc.m_rc; }
+ /** @} */
+
+ /** Special automatic cast for RT_SUCCESS_NP. */
+ operator RTErrStrictType2() const { return RTErrStrictType2(m_rc); }
+
+private:
+ /** @name Constructors that will prevent some of the bad types.
+ * @{ */
+ VBOXSTRICTRC(uint8_t rc) : m_rc(-999) { NOREF(rc); }
+ VBOXSTRICTRC(uint16_t rc) : m_rc(-999) { NOREF(rc); }
+ VBOXSTRICTRC(uint32_t rc) : m_rc(-999) { NOREF(rc); }
+ VBOXSTRICTRC(uint64_t rc) : m_rc(-999) { NOREF(rc); }
+
+ VBOXSTRICTRC(int8_t rc) : m_rc(-999) { NOREF(rc); }
+ VBOXSTRICTRC(int16_t rc) : m_rc(-999) { NOREF(rc); }
+ VBOXSTRICTRC(int64_t rc) : m_rc(-999) { NOREF(rc); }
+ /** @} */
+};
+#else
+typedef int32_t VBOXSTRICTRC;
+#endif
+
+/** @def VBOXSTRICTRC_VAL
+ * Explicit getter.
+ * @param rcStrict The strict VirtualBox status code.
+ */
+#ifdef VBOXSTRICTRC_STRICT_ENABLED
+# define VBOXSTRICTRC_VAL(rcStrict) ( (rcStrict).getValue() )
+#else
+# define VBOXSTRICTRC_VAL(rcStrict) (rcStrict)
+#endif
+
+/** @def VBOXSTRICTRC_TODO
+ * Returns that needs dealing with.
+ * @param rcStrict The strict VirtualBox status code.
+ */
+#define VBOXSTRICTRC_TODO(rcStrict) VBOXSTRICTRC_VAL(rcStrict)
+
+
+/** Pointer to a PDM Base Interface. */
+typedef struct PDMIBASE *PPDMIBASE;
+/** Pointer to a pointer to a PDM Base Interface. */
+typedef PPDMIBASE *PPPDMIBASE;
+
+/** Pointer to a PDM Device Instance. */
+typedef struct PDMDEVINS *PPDMDEVINS;
+/** Pointer to a pointer to a PDM Device Instance. */
+typedef PPDMDEVINS *PPPDMDEVINS;
+/** R3 pointer to a PDM Device Instance. */
+typedef R3PTRTYPE(PPDMDEVINS) PPDMDEVINSR3;
+/** R0 pointer to a PDM Device Instance. */
+typedef R0PTRTYPE(PPDMDEVINS) PPDMDEVINSR0;
+/** RC pointer to a PDM Device Instance. */
+typedef RCPTRTYPE(PPDMDEVINS) PPDMDEVINSRC;
+
+/** Pointer to a PDM USB Device Instance. */
+typedef struct PDMUSBINS *PPDMUSBINS;
+/** Pointer to a pointer to a PDM USB Device Instance. */
+typedef PPDMUSBINS *PPPDMUSBINS;
+
+/** Pointer to a PDM Driver Instance. */
+typedef struct PDMDRVINS *PPDMDRVINS;
+/** Pointer to a pointer to a PDM Driver Instance. */
+typedef PPDMDRVINS *PPPDMDRVINS;
+/** R3 pointer to a PDM Driver Instance. */
+typedef R3PTRTYPE(PPDMDRVINS) PPDMDRVINSR3;
+/** R0 pointer to a PDM Driver Instance. */
+typedef R0PTRTYPE(PPDMDRVINS) PPDMDRVINSR0;
+/** RC pointer to a PDM Driver Instance. */
+typedef RCPTRTYPE(PPDMDRVINS) PPDMDRVINSRC;
+
+/** Pointer to a PDM Service Instance. */
+typedef struct PDMSRVINS *PPDMSRVINS;
+/** Pointer to a pointer to a PDM Service Instance. */
+typedef PPDMSRVINS *PPPDMSRVINS;
+
+/** Pointer to a PDM critical section. */
+typedef union PDMCRITSECT *PPDMCRITSECT;
+/** Pointer to a const PDM critical section. */
+typedef const union PDMCRITSECT *PCPDMCRITSECT;
+
+/** R3 pointer to a timer. */
+typedef R3PTRTYPE(struct TMTIMER *) PTMTIMERR3;
+/** Pointer to a R3 pointer to a timer. */
+typedef PTMTIMERR3 *PPTMTIMERR3;
+
+/** R0 pointer to a timer. */
+typedef R0PTRTYPE(struct TMTIMER *) PTMTIMERR0;
+/** Pointer to a R3 pointer to a timer. */
+typedef PTMTIMERR0 *PPTMTIMERR0;
+
+/** RC pointer to a timer. */
+typedef RCPTRTYPE(struct TMTIMER *) PTMTIMERRC;
+/** Pointer to a RC pointer to a timer. */
+typedef PTMTIMERRC *PPTMTIMERRC;
+
+/** Pointer to a timer. */
+typedef CTX_SUFF(PTMTIMER) PTMTIMER;
+/** Pointer to a pointer to a timer. */
+typedef PTMTIMER *PPTMTIMER;
+
+/** SSM Operation handle. */
+typedef struct SSMHANDLE *PSSMHANDLE;
+/** Pointer to a const SSM stream method table. */
+typedef struct SSMSTRMOPS const *PCSSMSTRMOPS;
+
+/** Pointer to a CPUMCTX. */
+typedef struct CPUMCTX *PCPUMCTX;
+/** Pointer to a const CPUMCTX. */
+typedef const struct CPUMCTX *PCCPUMCTX;
+
+/** Pointer to a CPU context core. */
+typedef struct CPUMCTXCORE *PCPUMCTXCORE;
+/** Pointer to a const CPU context core. */
+typedef const struct CPUMCTXCORE *PCCPUMCTXCORE;
+
+/** Pointer to a selector register. */
+typedef struct CPUMSELREG *PCPUMSELREG;
+/** Pointer to a const selector register. */
+typedef const struct CPUMSELREG *PCCPUMSELREG;
+
+/** Pointer to selector hidden registers.
+ * @deprecated Replaced by PCPUMSELREG */
+typedef struct CPUMSELREG *PCPUMSELREGHID;
+/** Pointer to const selector hidden registers.
+ * @deprecated Replaced by PCCPUMSELREG */
+typedef const struct CPUMSELREG *PCCPUMSELREGHID;
+
+/** @} */
+
+
+/** @defgroup grp_types_idt Interrupt Descriptor Table Entry.
+ * @ingroup grp_types
+ * @todo This all belongs in x86.h!
+ * @{ */
+
+/** @todo VBOXIDT -> VBOXDESCIDT, skip the complex variations. We'll never use them. */
+
+/** IDT Entry, Task Gate view. */
+#pragma pack(1) /* paranoia */
+typedef struct VBOXIDTE_TASKGATE
+{
+ /** Reserved. */
+ unsigned u16Reserved1 : 16;
+ /** Task Segment Selector. */
+ unsigned u16TSS : 16;
+ /** More reserved. */
+ unsigned u8Reserved2 : 8;
+ /** Fixed value bit 0 - Set to 1. */
+ unsigned u1Fixed0 : 1;
+ /** Busy bit. */
+ unsigned u1Busy : 1;
+ /** Fixed value bit 2 - Set to 1. */
+ unsigned u1Fixed1 : 1;
+ /** Fixed value bit 3 - Set to 0. */
+ unsigned u1Fixed2 : 1;
+ /** Fixed value bit 4 - Set to 0. */
+ unsigned u1Fixed3 : 1;
+ /** Descriptor Privilege level. */
+ unsigned u2DPL : 2;
+ /** Present flag. */
+ unsigned u1Present : 1;
+ /** Reserved. */
+ unsigned u16Reserved3 : 16;
+} VBOXIDTE_TASKGATE;
+#pragma pack()
+/** Pointer to IDT Entry, Task gate view. */
+typedef VBOXIDTE_TASKGATE *PVBOXIDTE_TASKGATE;
+
+
+/** IDT Entry, Intertupt gate view. */
+#pragma pack(1) /* paranoia */
+typedef struct VBOXIDTE_INTERRUPTGATE
+{
+ /** Low offset word. */
+ unsigned u16OffsetLow : 16;
+ /** Segment Selector. */
+ unsigned u16SegSel : 16;
+ /** Reserved. */
+ unsigned u5Reserved2 : 5;
+ /** Fixed value bit 0 - Set to 0. */
+ unsigned u1Fixed0 : 1;
+ /** Fixed value bit 1 - Set to 0. */
+ unsigned u1Fixed1 : 1;
+ /** Fixed value bit 2 - Set to 0. */
+ unsigned u1Fixed2 : 1;
+ /** Fixed value bit 3 - Set to 0. */
+ unsigned u1Fixed3 : 1;
+ /** Fixed value bit 4 - Set to 1. */
+ unsigned u1Fixed4 : 1;
+ /** Fixed value bit 5 - Set to 1. */
+ unsigned u1Fixed5 : 1;
+ /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+ unsigned u132BitGate : 1;
+ /** Fixed value bit 5 - Set to 0. */
+ unsigned u1Fixed6 : 1;
+ /** Descriptor Privilege level. */
+ unsigned u2DPL : 2;
+ /** Present flag. */
+ unsigned u1Present : 1;
+ /** High offset word. */
+ unsigned u16OffsetHigh : 16;
+} VBOXIDTE_INTERRUPTGATE;
+#pragma pack()
+/** Pointer to IDT Entry, Interrupt gate view. */
+typedef VBOXIDTE_INTERRUPTGATE *PVBOXIDTE_INTERRUPTGATE;
+
+/** IDT Entry, Trap Gate view. */
+#pragma pack(1) /* paranoia */
+typedef struct VBOXIDTE_TRAPGATE
+{
+ /** Low offset word. */
+ unsigned u16OffsetLow : 16;
+ /** Segment Selector. */
+ unsigned u16SegSel : 16;
+ /** Reserved. */
+ unsigned u5Reserved2 : 5;
+ /** Fixed value bit 0 - Set to 0. */
+ unsigned u1Fixed0 : 1;
+ /** Fixed value bit 1 - Set to 0. */
+ unsigned u1Fixed1 : 1;
+ /** Fixed value bit 2 - Set to 0. */
+ unsigned u1Fixed2 : 1;
+ /** Fixed value bit 3 - Set to 1. */
+ unsigned u1Fixed3 : 1;
+ /** Fixed value bit 4 - Set to 1. */
+ unsigned u1Fixed4 : 1;
+ /** Fixed value bit 5 - Set to 1. */
+ unsigned u1Fixed5 : 1;
+ /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+ unsigned u132BitGate : 1;
+ /** Fixed value bit 5 - Set to 0. */
+ unsigned u1Fixed6 : 1;
+ /** Descriptor Privilege level. */
+ unsigned u2DPL : 2;
+ /** Present flag. */
+ unsigned u1Present : 1;
+ /** High offset word. */
+ unsigned u16OffsetHigh : 16;
+} VBOXIDTE_TRAPGATE;
+#pragma pack()
+/** Pointer to IDT Entry, Trap Gate view. */
+typedef VBOXIDTE_TRAPGATE *PVBOXIDTE_TRAPGATE;
+
+/** IDT Entry Generic view. */
+#pragma pack(1) /* paranoia */
+typedef struct VBOXIDTE_GENERIC
+{
+ /** Low offset word. */
+ unsigned u16OffsetLow : 16;
+ /** Segment Selector. */
+ unsigned u16SegSel : 16;
+ /** Reserved. */
+ unsigned u5Reserved : 5;
+ /** IDT Type part one (not used for task gate). */
+ unsigned u3Type1 : 3;
+ /** IDT Type part two. */
+ unsigned u5Type2 : 5;
+ /** Descriptor Privilege level. */
+ unsigned u2DPL : 2;
+ /** Present flag. */
+ unsigned u1Present : 1;
+ /** High offset word. */
+ unsigned u16OffsetHigh : 16;
+} VBOXIDTE_GENERIC;
+#pragma pack()
+/** Pointer to IDT Entry Generic view. */
+typedef VBOXIDTE_GENERIC *PVBOXIDTE_GENERIC;
+
+/** IDT Type1 value. (Reserved for task gate!) */
+#define VBOX_IDTE_TYPE1 0
+/** IDT Type2 value - Task gate. */
+#define VBOX_IDTE_TYPE2_TASK 0x5
+/** IDT Type2 value - 16 bit interrupt gate. */
+#define VBOX_IDTE_TYPE2_INT_16 0x6
+/** IDT Type2 value - 32 bit interrupt gate. */
+#define VBOX_IDTE_TYPE2_INT_32 0xe
+/** IDT Type2 value - 16 bit trap gate. */
+#define VBOX_IDTE_TYPE2_TRAP_16 0x7
+/** IDT Type2 value - 32 bit trap gate. */
+#define VBOX_IDTE_TYPE2_TRAP_32 0xf
+
+/** IDT Entry. */
+#pragma pack(1) /* paranoia */
+typedef union VBOXIDTE
+{
+ /** Task gate view. */
+ VBOXIDTE_TASKGATE Task;
+ /** Trap gate view. */
+ VBOXIDTE_TRAPGATE Trap;
+ /** Interrupt gate view. */
+ VBOXIDTE_INTERRUPTGATE Int;
+ /** Generic IDT view. */
+ VBOXIDTE_GENERIC Gen;
+
+ /** 8 bit unsigned integer view. */
+ uint8_t au8[8];
+ /** 16 bit unsigned integer view. */
+ uint16_t au16[4];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+ /** 64 bit unsigned integer view. */
+ uint64_t au64;
+} VBOXIDTE;
+#pragma pack()
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE *PVBOXIDTE;
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE const *PCVBOXIDTE;
+
+/** IDT Entry, 64-bit mode, Intertupt gate view. */
+#pragma pack(1) /* paranoia */
+typedef struct VBOXIDTE64_INTERRUPTGATE
+{
+ /** Low offset word. */
+ unsigned u16OffsetLow : 16;
+ /** Segment Selector. */
+ unsigned u16SegSel : 16;
+ /** Interrupt Stack Table Index. */
+ unsigned u3Ist : 3;
+ /** Fixed value bit 0 - Set to 0. */
+ unsigned u1Fixed0 : 1;
+ /** Fixed value bit 1 - Set to 0. */
+ unsigned u1Fixed1 : 1;
+ /** Fixed value bit 2 - Set to 0. */
+ unsigned u1Fixed2 : 1;
+ /** Fixed value bit 3 - Set to 0. */
+ unsigned u1Fixed3 : 1;
+ /** Fixed value bit 4 - Set to 0. */
+ unsigned u1Fixed4 : 1;
+ /** Fixed value bit 5 - Set to 0. */
+ unsigned u1Fixed5 : 1;
+ /** Fixed value bit 6 - Set to 1. */
+ unsigned u1Fixed6 : 1;
+ /** Fixed value bit 7 - Set to 1. */
+ unsigned u1Fixed7 : 1;
+ /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+ unsigned u132BitGate : 1;
+ /** Fixed value bit 5 - Set to 0. */
+ unsigned u1Fixed8 : 1;
+ /** Descriptor Privilege level. */
+ unsigned u2DPL : 2;
+ /** Present flag. */
+ unsigned u1Present : 1;
+ /** High offset word. */
+ unsigned u16OffsetHigh : 16;
+ /** Offset bits 32..63. */
+ unsigned u32OffsetHigh64;
+ /** Reserved. */
+ unsigned u32Reserved;
+} VBOXIDTE64_INTERRUPTGATE;
+#pragma pack()
+/** Pointer to IDT Entry, 64-bit mode, Interrupt gate view. */
+typedef VBOXIDTE64_INTERRUPTGATE *PVBOXIDTE64_INTERRUPTGATE;
+
+/** IDT Entry, 64-bit mode, Trap gate view. */
+#pragma pack(1) /* paranoia */
+typedef struct VBOXIDTE64_TRAPGATE
+{
+ /** Low offset word. */
+ unsigned u16OffsetLow : 16;
+ /** Segment Selector. */
+ unsigned u16SegSel : 16;
+ /** Interrupt Stack Table Index. */
+ unsigned u3Ist : 3;
+ /** Fixed value bit 0 - Set to 0. */
+ unsigned u1Fixed0 : 1;
+ /** Fixed value bit 1 - Set to 0. */
+ unsigned u1Fixed1 : 1;
+ /** Fixed value bit 2 - Set to 0. */
+ unsigned u1Fixed2 : 1;
+ /** Fixed value bit 3 - Set to 0. */
+ unsigned u1Fixed3 : 1;
+ /** Fixed value bit 4 - Set to 0. */
+ unsigned u1Fixed4 : 1;
+ /** Fixed value bit 5 - Set to 1. */
+ unsigned u1Fixed5 : 1;
+ /** Fixed value bit 6 - Set to 1. */
+ unsigned u1Fixed6 : 1;
+ /** Fixed value bit 7 - Set to 1. */
+ unsigned u1Fixed7 : 1;
+ /** Gate size, 1 = 32 bits, 0 = 16 bits. */
+ unsigned u132BitGate : 1;
+ /** Fixed value bit 5 - Set to 0. */
+ unsigned u1Fixed8 : 1;
+ /** Descriptor Privilege level. */
+ unsigned u2DPL : 2;
+ /** Present flag. */
+ unsigned u1Present : 1;
+ /** High offset word. */
+ unsigned u16OffsetHigh : 16;
+ /** Offset bits 32..63. */
+ unsigned u32OffsetHigh64;
+ /** Reserved. */
+ unsigned u32Reserved;
+} VBOXIDTE64_TRAPGATE;
+#pragma pack()
+/** Pointer to IDT Entry, 64-bit mode, Trap gate view. */
+typedef VBOXIDTE64_TRAPGATE *PVBOXIDTE64_TRAPGATE;
+
+/** IDT Entry, 64-bit mode, Generic view. */
+#pragma pack(1) /* paranoia */
+typedef struct VBOXIDTE64_GENERIC
+{
+ /** Low offset word. */
+ unsigned u16OffsetLow : 16;
+ /** Segment Selector. */
+ unsigned u16SegSel : 16;
+ /** Reserved. */
+ unsigned u3Ist : 3;
+ /** Fixed value bit 0 - Set to 0. */
+ unsigned u1Fixed0 : 1;
+ /** Fixed value bit 1 - Set to 0. */
+ unsigned u1Fixed1 : 1;
+ /** IDT Type part one (not used for task gate). */
+ unsigned u3Type1 : 3;
+ /** IDT Type part two. */
+ unsigned u5Type2 : 5;
+ /** Descriptor Privilege level. */
+ unsigned u2DPL : 2;
+ /** Present flag. */
+ unsigned u1Present : 1;
+ /** High offset word. */
+ unsigned u16OffsetHigh : 16;
+ /** Offset bits 32..63. */
+ unsigned u32OffsetHigh64;
+ /** Reserved. */
+ unsigned u32Reserved;
+} VBOXIDTE64_GENERIC;
+#pragma pack()
+/** Pointer to IDT Entry, 64-bit mode, Generic view. */
+typedef VBOXIDTE64_GENERIC *PVBOXIDTE64_GENERIC;
+
+/** IDT Entry, 64-bit mode. */
+#pragma pack(1) /* paranoia */
+typedef union VBOXIDTE64
+{
+ /** Trap gate view. */
+ VBOXIDTE64_TRAPGATE Trap;
+ /** Interrupt gate view. */
+ VBOXIDTE64_INTERRUPTGATE Int;
+ /** Generic IDT view. */
+ VBOXIDTE64_GENERIC Gen;
+
+ /** 8 bit unsigned integer view. */
+ uint8_t au8[16];
+ /** 16 bit unsigned integer view. */
+ uint16_t au16[8];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[4];
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[2];
+} VBOXIDTE64;
+#pragma pack()
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE64 *PVBOXIDTE64;
+/** Pointer to IDT Entry. */
+typedef VBOXIDTE64 const *PCVBOXIDTE64;
+
+#pragma pack(1)
+/** IDTR */
+typedef struct VBOXIDTR
+{
+ /** Size of the IDT. */
+ uint16_t cbIdt;
+ /** Address of the IDT. */
+ uint64_t pIdt;
+} VBOXIDTR, *PVBOXIDTR;
+#pragma pack()
+
+/** @} */
+
+
+/** @def VBOXIDTE_OFFSET
+ * Return the offset of an IDT entry.
+ */
+#define VBOXIDTE_OFFSET(desc) \
+ ( ((uint32_t)((desc).Gen.u16OffsetHigh) << 16) \
+ | ( (desc).Gen.u16OffsetLow ) )
+
+/** @def VBOXIDTE64_OFFSET
+ * Return the offset of an IDT entry.
+ */
+#define VBOXIDTE64_OFFSET(desc) \
+ ( ((uint64_t)((desc).Gen.u32OffsetHigh64) << 32) \
+ | ((uint32_t)((desc).Gen.u16OffsetHigh) << 16) \
+ | ( (desc).Gen.u16OffsetLow ) )
+
+#pragma pack(1)
+/** GDTR */
+typedef struct VBOXGDTR
+{
+ /** Size of the GDT. */
+ uint16_t cbGdt;
+ /** Address of the GDT. */
+ uint64_t pGdt;
+} VBOXGDTR;
+#pragma pack()
+/** Pointer to GDTR. */
+typedef VBOXGDTR *PVBOXGDTR;
+
+/** @} */
+
+
+/**
+ * 32-bit Task Segment used in raw mode.
+ * @todo Move this to SELM! Use X86TSS32 instead.
+ */
+#pragma pack(1)
+typedef struct VBOXTSS
+{
+ /** 0x00 - Back link to previous task. (static) */
+ RTSEL selPrev;
+ uint16_t padding1;
+ /** 0x04 - Ring-0 stack pointer. (static) */
+ uint32_t esp0;
+ /** 0x08 - Ring-0 stack segment. (static) */
+ RTSEL ss0;
+ uint16_t padding_ss0;
+ /** 0x0c - Ring-1 stack pointer. (static) */
+ uint32_t esp1;
+ /** 0x10 - Ring-1 stack segment. (static) */
+ RTSEL ss1;
+ uint16_t padding_ss1;
+ /** 0x14 - Ring-2 stack pointer. (static) */
+ uint32_t esp2;
+ /** 0x18 - Ring-2 stack segment. (static) */
+ RTSEL ss2;
+ uint16_t padding_ss2;
+ /** 0x1c - Page directory for the task. (static) */
+ uint32_t cr3;
+ /** 0x20 - EIP before task switch. */
+ uint32_t eip;
+ /** 0x24 - EFLAGS before task switch. */
+ uint32_t eflags;
+ /** 0x28 - EAX before task switch. */
+ uint32_t eax;
+ /** 0x2c - ECX before task switch. */
+ uint32_t ecx;
+ /** 0x30 - EDX before task switch. */
+ uint32_t edx;
+ /** 0x34 - EBX before task switch. */
+ uint32_t ebx;
+ /** 0x38 - ESP before task switch. */
+ uint32_t esp;
+ /** 0x3c - EBP before task switch. */
+ uint32_t ebp;
+ /** 0x40 - ESI before task switch. */
+ uint32_t esi;
+ /** 0x44 - EDI before task switch. */
+ uint32_t edi;
+ /** 0x48 - ES before task switch. */
+ RTSEL es;
+ uint16_t padding_es;
+ /** 0x4c - CS before task switch. */
+ RTSEL cs;
+ uint16_t padding_cs;
+ /** 0x50 - SS before task switch. */
+ RTSEL ss;
+ uint16_t padding_ss;
+ /** 0x54 - DS before task switch. */
+ RTSEL ds;
+ uint16_t padding_ds;
+ /** 0x58 - FS before task switch. */
+ RTSEL fs;
+ uint16_t padding_fs;
+ /** 0x5c - GS before task switch. */
+ RTSEL gs;
+ uint16_t padding_gs;
+ /** 0x60 - LDTR before task switch. */
+ RTSEL selLdt;
+ uint16_t padding_ldt;
+ /** 0x64 - Debug trap flag */
+ uint16_t fDebugTrap;
+ /** 0x66 - Offset relative to the TSS of the start of the I/O Bitmap
+ * and the end of the interrupt redirection bitmap. */
+ uint16_t offIoBitmap;
+ /** 0x68 - 32 bytes for the virtual interrupt redirection bitmap. (VME) */
+ uint8_t IntRedirBitmap[32];
+} VBOXTSS;
+#pragma pack()
+/** Pointer to task segment. */
+typedef VBOXTSS *PVBOXTSS;
+/** Pointer to const task segment. */
+typedef const VBOXTSS *PCVBOXTSS;
+
+
+/** Pointer to a callback method table provided by the VM API user. */
+typedef struct VMM2USERMETHODS const *PCVMM2USERMETHODS;
+
+
+/**
+ * Data transport buffer (scatter/gather)
+ */
+typedef struct PDMDATASEG
+{
+ /** Length of buffer in entry. */
+ size_t cbSeg;
+ /** Pointer to the start of the buffer. */
+ void *pvSeg;
+} PDMDATASEG;
+/** Pointer to a data transport segment. */
+typedef PDMDATASEG *PPDMDATASEG;
+/** Pointer to a const data transport segment. */
+typedef PDMDATASEG const *PCPDMDATASEG;
+
+
+/**
+ * Forms of generic segment offloading.
+ */
+typedef enum PDMNETWORKGSOTYPE
+{
+ /** Invalid zero value. */
+ PDMNETWORKGSOTYPE_INVALID = 0,
+ /** TCP/IPv4 - no CWR/ECE encoding. */
+ PDMNETWORKGSOTYPE_IPV4_TCP,
+ /** TCP/IPv6 - no CWR/ECE encoding. */
+ PDMNETWORKGSOTYPE_IPV6_TCP,
+ /** UDP/IPv4. */
+ PDMNETWORKGSOTYPE_IPV4_UDP,
+ /** UDP/IPv6. */
+ PDMNETWORKGSOTYPE_IPV6_UDP,
+ /** TCP/IPv6 over IPv4 tunneling - no CWR/ECE encoding.
+ * The header offsets and sizes relates to IPv4 and TCP, the IPv6 header is
+ * figured out as needed.
+ * @todo Needs checking against facts, this is just an outline of the idea. */
+ PDMNETWORKGSOTYPE_IPV4_IPV6_TCP,
+ /** UDP/IPv6 over IPv4 tunneling.
+ * The header offsets and sizes relates to IPv4 and UDP, the IPv6 header is
+ * figured out as needed.
+ * @todo Needs checking against facts, this is just an outline of the idea. */
+ PDMNETWORKGSOTYPE_IPV4_IPV6_UDP,
+ /** The end of valid GSO types. */
+ PDMNETWORKGSOTYPE_END
+} PDMNETWORKGSOTYPE;
+
+
+/**
+ * Generic segment offloading context.
+ *
+ * We generally follow the E1000 specs wrt to which header fields we change.
+ * However the GSO type implies where the checksum fields are and that they are
+ * always updated from scratch (no half done pseudo checksums).
+ *
+ * @remarks This is part of the internal network GSO packets. Take great care
+ * when making changes. The size is expected to be exactly 8 bytes.
+ */
+typedef struct PDMNETWORKGSO
+{
+ /** The type of segmentation offloading we're performing (PDMNETWORKGSOTYPE). */
+ uint8_t u8Type;
+ /** The total header size. */
+ uint8_t cbHdrsTotal;
+ /** The max segment size (MSS) to apply. */
+ uint16_t cbMaxSeg;
+
+ /** Offset of the first header (IPv4 / IPv6). 0 if not not needed. */
+ uint8_t offHdr1;
+ /** Offset of the second header (TCP / UDP). 0 if not not needed. */
+ uint8_t offHdr2;
+ /** The header size used for segmentation (equal to offHdr2 in UFO). */
+ uint8_t cbHdrsSeg;
+ /** Unused. */
+ uint8_t u8Unused;
+} PDMNETWORKGSO;
+/** Pointer to a GSO context. */
+typedef PDMNETWORKGSO *PPDMNETWORKGSO;
+/** Pointer to a const GSO context. */
+typedef PDMNETWORKGSO const *PCPDMNETWORKGSO;
+
+
+/**
+ * The current ROM page protection.
+ *
+ * @remarks This is part of the saved state.
+ */
+typedef enum PGMROMPROT
+{
+ /** The customary invalid value. */
+ PGMROMPROT_INVALID = 0,
+ /** Read from the virgin ROM page, ignore writes.
+ * Map the virgin page, use write access handler to ignore writes. */
+ PGMROMPROT_READ_ROM_WRITE_IGNORE,
+ /** Read from the virgin ROM page, write to the shadow RAM.
+ * Map the virgin page, use write access handler to change the shadow RAM. */
+ PGMROMPROT_READ_ROM_WRITE_RAM,
+ /** Read from the shadow ROM page, ignore writes.
+ * Map the shadow page read-only, use write access handler to ignore writes. */
+ PGMROMPROT_READ_RAM_WRITE_IGNORE,
+ /** Read from the shadow ROM page, ignore writes.
+ * Map the shadow page read-write, disabled write access handler. */
+ PGMROMPROT_READ_RAM_WRITE_RAM,
+ /** The end of valid values. */
+ PGMROMPROT_END,
+ /** The usual 32-bit type size hack. */
+ PGMROMPROT_32BIT_HACK = 0x7fffffff
+} PGMROMPROT;
+
+
+/**
+ * Page mapping lock.
+ */
+typedef struct PGMPAGEMAPLOCK
+{
+#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+ /** The locked page. */
+ void *pvPage;
+ /** Pointer to the CPU that made the mapping.
+ * In ring-0 and raw-mode context we don't intend to ever allow long term
+ * locking and this is a way of making sure we're still on the same CPU. */
+ PVMCPU pVCpu;
+#else
+ /** Pointer to the PGMPAGE and lock type.
+ * bit-0 abuse: set=write, clear=read. */
+ uintptr_t uPageAndType;
+/** Read lock type value. */
+# define PGMPAGEMAPLOCK_TYPE_READ ((uintptr_t)0)
+/** Write lock type value. */
+# define PGMPAGEMAPLOCK_TYPE_WRITE ((uintptr_t)1)
+/** Lock type mask. */
+# define PGMPAGEMAPLOCK_TYPE_MASK ((uintptr_t)1)
+ /** Pointer to the PGMCHUNKR3MAP. */
+ void *pvMap;
+#endif
+} PGMPAGEMAPLOCK;
+/** Pointer to a page mapping lock. */
+typedef PGMPAGEMAPLOCK *PPGMPAGEMAPLOCK;
+
+
+/** Pointer to a info helper callback structure. */
+typedef struct DBGFINFOHLP *PDBGFINFOHLP;
+/** Pointer to a const info helper callback structure. */
+typedef const struct DBGFINFOHLP *PCDBGFINFOHLP;
+
+/** Pointer to a const register descriptor. */
+typedef struct DBGFREGDESC const *PCDBGFREGDESC;
+
+
+/** Configuration manager tree node - A key. */
+typedef struct CFGMNODE *PCFGMNODE;
+
+/** Configuration manager tree leaf - A value. */
+typedef struct CFGMLEAF *PCFGMLEAF;
+
+
+/**
+ * CPU modes.
+ */
+typedef enum CPUMMODE
+{
+ /** The usual invalid zero entry. */
+ CPUMMODE_INVALID = 0,
+ /** Real mode. */
+ CPUMMODE_REAL,
+ /** Protected mode (32-bit). */
+ CPUMMODE_PROTECTED,
+ /** Long mode (64-bit). */
+ CPUMMODE_LONG
+} CPUMMODE;
+
+
+/**
+ * CPU mode flags (DISSTATE::mode).
+ */
+typedef enum DISCPUMODE
+{
+ DISCPUMODE_INVALID = 0,
+ DISCPUMODE_16BIT,
+ DISCPUMODE_32BIT,
+ DISCPUMODE_64BIT,
+ /** hack forcing the size of the enum to 32-bits. */
+ DISCPUMODE_MAKE_32BIT_HACK = 0x7fffffff
+} DISCPUMODE;
+
+/** Pointer to the disassembler state. */
+typedef struct DISSTATE *PDISSTATE;
+/** Pointer to a const disassembler state. */
+typedef struct DISSTATE const *PCDISSTATE;
+
+/** @deprecated PDISSTATE and change pCpu and pDisState to pDis. */
+typedef PDISSTATE PDISCPUSTATE;
+/** @deprecated PCDISSTATE and change pCpu and pDisState to pDis. */
+typedef PCDISSTATE PCDISCPUSTATE;
+
+
+/** @} */
+
+#endif
diff --git a/include/VBox/usb.h b/include/VBox/usb.h
new file mode 100644
index 00000000..db648c7a
--- /dev/null
+++ b/include/VBox/usb.h
@@ -0,0 +1,255 @@
+/** @file
+ * USB - Universal Serial Bus. (DEV,Main?)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_usb_h
+#define ___VBox_usb_h
+
+#include <VBox/types.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * The USB host device state.
+ */
+typedef enum USBDEVICESTATE
+{
+ /** The device is unsupported. */
+ USBDEVICESTATE_UNSUPPORTED = 1,
+ /** The device is in use by the host. */
+ USBDEVICESTATE_USED_BY_HOST,
+ /** The device is in use by the host but could perhaps be captured even so. */
+ USBDEVICESTATE_USED_BY_HOST_CAPTURABLE,
+ /** The device is not used by the host or any guest. */
+ USBDEVICESTATE_UNUSED,
+ /** The device is held by the proxy for later guest usage. */
+ USBDEVICESTATE_HELD_BY_PROXY,
+ /** The device in use by a guest. */
+ USBDEVICESTATE_USED_BY_GUEST,
+ /** The usual 32-bit hack. */
+ USBDEVICESTATE_32BIT_HACK = 0x7fffffff
+} USBDEVICESTATE;
+
+
+/**
+ * The USB device speed.
+ */
+typedef enum USBDEVICESPEED
+{
+ /** Unknown. */
+ USBDEVICESPEED_UNKNOWN = 0,
+ /** Low speed (1.5 Mbit/s). */
+ USBDEVICESPEED_LOW,
+ /** Full speed (12 Mbit/s). */
+ USBDEVICESPEED_FULL,
+ /** High speed (480 Mbit/s). */
+ USBDEVICESPEED_HIGH,
+ /** Variable speed - USB 2.5 / wireless. */
+ USBDEVICESPEED_VARIABLE,
+ /** The usual 32-bit hack. */
+ USBDEVICESPEED_32BIT_HACK = 0x7fffffff
+} USBDEVICESPEED;
+
+
+/**
+ * USB host device description.
+ * Used for enumeration of USB devices.
+ */
+typedef struct USBDEVICE
+{
+ /** If linked, this is the pointer to the next device in the list. */
+ struct USBDEVICE *pNext;
+ /** If linked doubly, this is the pointer to the prev device in the list. */
+ struct USBDEVICE *pPrev;
+ /** Manufacturer string. */
+ const char *pszManufacturer;
+ /** Product string. */
+ const char *pszProduct;
+ /** Serial number string. */
+ const char *pszSerialNumber;
+ /** The address of the device. */
+ const char *pszAddress;
+
+ /** Vendor ID. */
+ uint16_t idVendor;
+ /** Product ID. */
+ uint16_t idProduct;
+ /** Revision, integer part. */
+ uint16_t bcdDevice;
+ /** USB version number. */
+ uint16_t bcdUSB;
+ /** Device class. */
+ uint8_t bDeviceClass;
+ /** Device subclass. */
+ uint8_t bDeviceSubClass;
+ /** Device protocol */
+ uint8_t bDeviceProtocol;
+ /** Number of configurations. */
+ uint8_t bNumConfigurations;
+ /** The device state. */
+ USBDEVICESTATE enmState;
+ /** The device speed. */
+ USBDEVICESPEED enmSpeed;
+ /** Serial hash. */
+ uint64_t u64SerialHash;
+ /** The USB Bus number. */
+ uint8_t bBus;
+ /** The port number. */
+ uint8_t bPort;
+#if defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD)
+ /** Device number. */
+ uint8_t bDevNum;
+#endif
+#ifdef RT_OS_WINDOWS
+ /** Alternate address. Can be NULL. */
+ char *pszAltAddress;
+ /** The hub name. */
+ char *pszHubName;
+#endif
+#ifdef RT_OS_SOLARIS
+ /** The /devices path of the device. */
+ char *pszDevicePath;
+ /** Do we have a partial or full device descriptor here. */
+ bool fPartialDescriptor;
+#endif
+} USBDEVICE;
+/** Pointer to a USB device. */
+typedef USBDEVICE *PUSBDEVICE;
+/** Pointer to a const USB device. */
+typedef USBDEVICE *PCUSBDEVICE;
+
+
+#ifdef VBOX_USB_H_INCL_DESCRIPTORS /* for the time being, since this may easily conflict with system headers */
+
+/**
+ * USB device descriptor.
+ */
+#pragma pack(1)
+typedef struct USBDESCHDR
+{
+ /** The descriptor length. */
+ uint8_t bLength;
+ /** The descriptor type. */
+ uint8_t bDescriptorType;
+} USBDESCHDR;
+#pragma pack()
+/** Pointer to an USB descriptor header. */
+typedef USBDESCHDR *PUSBDESCHDR;
+
+/** @name Descriptor Type values (bDescriptorType)
+ * {@ */
+#if !defined(USB_DT_DEVICE) && !defined(USB_DT_ENDPOINT)
+# define USB_DT_DEVICE 0x01
+# define USB_DT_CONFIG 0x02
+# define USB_DT_STRING 0x03
+# define USB_DT_INTERFACE 0x04
+# define USB_DT_ENDPOINT 0x05
+
+# define USB_DT_HID 0x21
+# define USB_DT_REPORT 0x22
+# define USB_DT_PHYSICAL 0x23
+# define USB_DT_HUB 0x29
+#endif
+/** @} */
+
+
+/**
+ * USB device descriptor.
+ */
+#pragma pack(1)
+typedef struct USBDEVICEDESC
+{
+ /** The descriptor length. (Usually sizeof(USBDEVICEDESC).) */
+ uint8_t bLength;
+ /** The descriptor type. (USB_DT_DEVICE) */
+ uint8_t bDescriptorType;
+ /** USB version number. */
+ uint16_t bcdUSB;
+ /** Device class. */
+ uint8_t bDeviceClass;
+ /** Device subclass. */
+ uint8_t bDeviceSubClass;
+ /** Device protocol */
+ uint8_t bDeviceProtocol;
+ /** The max packet size of the default control pipe. */
+ uint8_t bMaxPacketSize0;
+ /** Vendor ID. */
+ uint16_t idVendor;
+ /** Product ID. */
+ uint16_t idProduct;
+ /** Revision, integer part. */
+ uint16_t bcdDevice;
+ /** Manufacturer string index. */
+ uint8_t iManufacturer;
+ /** Product string index. */
+ uint8_t iProduct;
+ /** Serial number string index. */
+ uint8_t iSerialNumber;
+ /** Number of configurations. */
+ uint8_t bNumConfigurations;
+} USBDEVICEDESC;
+#pragma pack()
+/** Pointer to an USB device descriptor. */
+typedef USBDEVICEDESC *PUSBDEVICEDESC;
+
+/** @name Class codes (bDeviceClass)
+ * @{ */
+#ifndef USB_HUB_CLASSCODE
+# define USB_HUB_CLASSCODE 0x09
+#endif
+/** @} */
+
+/**
+ * USB configuration descriptor.
+ */
+#pragma pack(1)
+typedef struct USBCONFIGDESC
+{
+ /** The descriptor length. (Usually sizeof(USBCONFIGDESC).) */
+ uint8_t bLength;
+ /** The descriptor type. (USB_DT_CONFIG) */
+ uint8_t bDescriptorType;
+ /** The length of the configuration descriptor plus all associated descriptors. */
+ uint16_t wTotalLength;
+ /** Number of interfaces. */
+ uint8_t bNumInterfaces;
+ /** Configuration number. (For SetConfiguration().) */
+ uint8_t bConfigurationValue;
+ /** Configuration description string. */
+ uint8_t iConfiguration;
+ /** Configuration characteristics. */
+ uint8_t bmAttributes;
+ /** Maximum power consumption of the USB device in this config. */
+ uint8_t MaxPower;
+} USBCONFIGDESC;
+#pragma pack()
+/** Pointer to an USB configuration descriptor. */
+typedef USBCONFIGDESC *PUSBCONFIGDESC;
+
+#endif /* VBOX_USB_H_INCL_DESCRIPTORS */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/usbfilter.h b/include/VBox/usbfilter.h
new file mode 100644
index 00000000..1ed209fd
--- /dev/null
+++ b/include/VBox/usbfilter.h
@@ -0,0 +1,257 @@
+/** @file
+ * USBFilter - USB Filter constructs shared by kernel and user mode.
+ * (DEV,HDrv,Main)
+ */
+
+/*
+ * Copyright (C) 2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_usbfilter_h
+#define ___VBox_usbfilter_h
+
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#include <VBox/cdefs.h>
+#include <VBox/usb.h>
+
+
+/** @defgroup grp_USBFilter USBFilter - USB Filter constructs shared by kernel and user mode
+ * @ingroup grp_USBLib
+ * @{
+ */
+
+/**
+ * How to match a field.
+ *
+ * @remarks This is a binary interface (drivers).
+ */
+typedef enum USBFILTERMATCH
+{
+ /** The usual invalid first zero value. */
+ USBFILTERMATCH_INVALID = 0,
+ /** Ignore this field (always matching).
+ * Device Data: No value present. */
+ USBFILTERMATCH_IGNORE,
+ /** Only require this field to be present on the device. */
+ USBFILTERMATCH_PRESENT,
+
+ /** Numeric Field: The first numeric field matching method. */
+ USBFILTERMATCH_NUM_FIRST,
+ /** Numeric Field: Exact match, required to be present. */
+ USBFILTERMATCH_NUM_EXACT = USBFILTERMATCH_NUM_FIRST,
+ /** Numeric Field: Exact match or not present. */
+ USBFILTERMATCH_NUM_EXACT_NP,
+ /** Numeric Field: Expression match, required to be present.
+ * The expression is represented as a string. */
+ USBFILTERMATCH_NUM_EXPRESSION,
+ /** Numeric Field: Expression match or not present.
+ * The expression is represented as a string. */
+ USBFILTERMATCH_NUM_EXPRESSION_NP,
+ /** Numeric Field: The last numeric field matching method (inclusive). */
+ USBFILTERMATCH_NUM_LAST = USBFILTERMATCH_NUM_EXPRESSION_NP,
+
+ /** String Field: The first string field matching method. */
+ USBFILTERMATCH_STR_FIRST,
+ /** String Field: Exact match, required to be present. */
+ USBFILTERMATCH_STR_EXACT = USBFILTERMATCH_STR_FIRST,
+ /** String Field: Exact match or not present. */
+ USBFILTERMATCH_STR_EXACT_NP,
+ /** String Field: Pattern match, required to be present.*/
+ USBFILTERMATCH_STR_PATTERN,
+ /** String Field: Pattern match or not present.*/
+ USBFILTERMATCH_STR_PATTERN_NP,
+ /** String Field: The last string field matching method (inclusive). */
+ USBFILTERMATCH_STR_LAST = USBFILTERMATCH_STR_PATTERN_NP,
+
+ /** The end of valid matching methods (exclusive). */
+ USBFILTERMATCH_END
+} USBFILTERMATCH;
+AssertCompile(USBFILTERMATCH_END == 11);
+
+
+/**
+ * A USB filter field.
+ *
+ * @remarks This is a binary interface (drivers).
+ */
+typedef struct USBFILTERFIELD
+{
+ /** The matching method. (USBFILTERMATCH) */
+ uint16_t enmMatch;
+ /** The field value or offset into the string table.
+ * The enmMatch field decides which it is. */
+ uint16_t u16Value;
+} USBFILTERFIELD;
+AssertCompileSize(USBFILTERFIELD, 4);
+/** Pointer to a USB filter field. */
+typedef USBFILTERFIELD *PUSBFILTERFIELD;
+/** Pointer to a const USBFILTERFIELD. */
+typedef const USBFILTERFIELD *PCUSBFILTERFIELD;
+
+
+/**
+ * USB filter field index.
+ *
+ * This is used as an index into the USBFILTER::aFields array.
+ *
+ * @remarks This is a binary interface (drivers).
+ */
+typedef enum USBFILTERIDX
+{
+ /** idVendor (= 0) */
+ USBFILTERIDX_VENDOR_ID = 0,
+ /** idProduct (= 1) */
+ USBFILTERIDX_PRODUCT_ID,
+ /** bcdDevice (= 2)*/
+ USBFILTERIDX_DEVICE_REV,
+ USBFILTERIDX_DEVICE = USBFILTERIDX_DEVICE_REV,
+ /** bDeviceClass (= 3) */
+ USBFILTERIDX_DEVICE_CLASS,
+ /** bDeviceSubClass (= 4) */
+ USBFILTERIDX_DEVICE_SUB_CLASS,
+ /** bDeviceProtocol (= 5) */
+ USBFILTERIDX_DEVICE_PROTOCOL,
+ /** bBus (= 6 )*/
+ USBFILTERIDX_BUS,
+ /** bPort (=7) */
+ USBFILTERIDX_PORT,
+ /** Manufacturer string. (=8) */
+ USBFILTERIDX_MANUFACTURER_STR,
+ /** Product string. (=9) */
+ USBFILTERIDX_PRODUCT_STR,
+ /** SerialNumber string. (=10) */
+ USBFILTERIDX_SERIAL_NUMBER_STR,
+ /** The end of the USB filter fields (exclusive). */
+ USBFILTERIDX_END
+} USBFILTERIDX;
+AssertCompile(USBFILTERIDX_END == 11);
+
+
+/**
+ * USB Filter types.
+ *
+ * The filters types are list in priority order, i.e. highest priority first.
+ *
+ * @remarks This is a binary interface (drivers).
+ */
+typedef enum USBFILTERTYPE
+{
+ /** The usual invalid first zero value. */
+ USBFILTERTYPE_INVALID = 0,
+ /** The first valid entry. */
+ USBFILTERTYPE_FIRST,
+ /** A one-shot ignore filter that's installed when releasing a device.
+ * This filter will be automatically removedwhen the device re-appears,
+ * or when ring-3 decides that time is up, or if ring-3 dies upon us. */
+ USBFILTERTYPE_ONESHOT_IGNORE = USBFILTERTYPE_FIRST,
+ /** A one-shot capture filter that's installed when hijacking a device that's already plugged.
+ * This filter will be automatically removed when the device re-appears,
+ * or when ring-3 decides that time is up, or if ring-3 dies upon us. */
+ USBFILTERTYPE_ONESHOT_CAPTURE,
+ /** Ignore filter.
+ * This picks out devices that shouldn't be captured. */
+ USBFILTERTYPE_IGNORE,
+ /** A normal capture filter.
+ * When a device matching the filter is attach, we'll take it. */
+ USBFILTERTYPE_CAPTURE,
+ /** The end of the valid filter types (exclusive). */
+ USBFILTERTYPE_END,
+ /** The usual 32-bit hack. */
+ USBFILTERTYPE_32BIT_HACK = 0x7fffffff
+} USBFILTERTYPE;
+AssertCompileSize(USBFILTERTYPE, 4);
+AssertCompile(USBFILTERTYPE_END == 5);
+
+
+/**
+ * USB Filter.
+ *
+ * Consider the an abstract data type, use the methods below to access it.
+ *
+ * @remarks This is a binary interface (drivers).
+ */
+typedef struct USBFILTER
+{
+ /** Magic number (USBFILTER_MAGIC). */
+ uint32_t u32Magic;
+ /** The filter type. */
+ USBFILTERTYPE enmType;
+ /** The filter fields.
+ * This array is indexed by USBFILTERIDX */
+ USBFILTERFIELD aFields[USBFILTERIDX_END];
+ /** Offset to the end of the string table (last terminator). (used to speed up things) */
+ uint32_t offCurEnd;
+ /** String table.
+ * This is used for string and numeric patterns. */
+ char achStrTab[256];
+} USBFILTER;
+AssertCompileSize(USBFILTER, 312);
+
+/** Pointer to a USBLib filter. */
+typedef USBFILTER *PUSBFILTER;
+/** Pointer to a const USBLib filter. */
+typedef const USBFILTER *PCUSBFILTER;
+
+/** USBFILTER::u32Magic (Yasuhiro Nightow). */
+#define USBFILTER_MAGIC 0x19670408
+
+
+RT_C_DECLS_BEGIN
+
+USBLIB_DECL(void) USBFilterInit(PUSBFILTER pFilter, USBFILTERTYPE enmType);
+USBLIB_DECL(void) USBFilterClone(PUSBFILTER pFilter, PCUSBFILTER pToClone);
+USBLIB_DECL(void) USBFilterDelete(PUSBFILTER pFilter);
+USBLIB_DECL(int) USBFilterValidate(PCUSBFILTER pFilter);
+USBLIB_DECL(bool) USBFilterMatch(PCUSBFILTER pFilter, PCUSBFILTER pDevice);
+USBLIB_DECL(int) USBFilterMatchRated(PCUSBFILTER pFilter, PCUSBFILTER pDevice);
+USBLIB_DECL(bool) USBFilterMatchDevice(PCUSBFILTER pFilter, PCUSBDEVICE pDevice);
+USBLIB_DECL(bool) USBFilterIsIdentical(PCUSBFILTER pFilter, PCUSBFILTER pFilter2);
+
+USBLIB_DECL(int) USBFilterSetFilterType(PUSBFILTER pFilter, USBFILTERTYPE enmType);
+USBLIB_DECL(int) USBFilterSetIgnore(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx);
+USBLIB_DECL(int) USBFilterSetPresentOnly(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx);
+USBLIB_DECL(int) USBFilterSetNumExact(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx, uint16_t u16Value, bool fMustBePresent);
+USBLIB_DECL(int) USBFilterSetNumExpression(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx, const char *pszExpression, bool fMustBePresent);
+USBLIB_DECL(int) USBFilterSetStringExact(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx, const char *pszValue, bool fMustBePresent);
+USBLIB_DECL(int) USBFilterSetStringPattern(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx, const char *pszPattern, bool fMustBePresent);
+USBLIB_DECL(int) USBFilterSetMustBePresent(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx, bool fMustBePresent);
+
+USBLIB_DECL(USBFILTERTYPE) USBFilterGetFilterType(PCUSBFILTER pFilter);
+USBLIB_DECL(USBFILTERMATCH) USBFilterGetMatchingMethod(PCUSBFILTER pFilter, USBFILTERIDX enmFieldIdx);
+USBLIB_DECL(int) USBFilterQueryNum(PCUSBFILTER pFilter, USBFILTERIDX enmFieldIdx, uint16_t *pu16Value);
+USBLIB_DECL(int) USBFilterGetNum(PCUSBFILTER pFilter, USBFILTERIDX enmFieldIdx);
+USBLIB_DECL(int) USBFilterQueryString(PUSBFILTER pFilter, USBFILTERIDX enmFieldIdx, char *pszBuf, size_t cchBuf);
+USBLIB_DECL(const char *) USBFilterGetString(PCUSBFILTER pFilter, USBFILTERIDX enmFieldIdx);
+USBLIB_DECL(ssize_t) USBFilterGetStringLen(PCUSBFILTER pFilter, USBFILTERIDX enmFieldIdx);
+
+USBLIB_DECL(bool) USBFilterHasAnySubstatialCriteria(PCUSBFILTER pFilter);
+USBLIB_DECL(bool) USBFilterIsNumericField(USBFILTERIDX enmFieldIdx);
+USBLIB_DECL(bool) USBFilterIsStringField(USBFILTERIDX enmFieldIdx);
+USBLIB_DECL(bool) USBFilterIsMethodUsingNumericValue(USBFILTERMATCH enmMatchingMethod);
+USBLIB_DECL(bool) USBFilterIsMethodUsingStringValue(USBFILTERMATCH enmMatchingMethod);
+USBLIB_DECL(bool) USBFilterIsMethodNumeric(USBFILTERMATCH enmMatchingMethod);
+USBLIB_DECL(bool) USBFilterIsMethodString(USBFILTERMATCH enmMatchingMethod);
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/VBox/usblib-darwin.h b/include/VBox/usblib-darwin.h
new file mode 100644
index 00000000..db43e743
--- /dev/null
+++ b/include/VBox/usblib-darwin.h
@@ -0,0 +1,55 @@
+/** @file
+ * USBLib - Library for wrapping up the VBoxUSB functionality, Darwin flavor.
+ * (DEV,HDrv,Main)
+ */
+
+/*
+ * Copyright (C) 2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_usblib_darwin_h
+#define ___VBox_usblib_darwin_h
+
+#include <VBox/cdefs.h>
+#include <VBox/usbfilter.h>
+
+RT_C_DECLS_BEGIN
+/** @defgroup grp_USBLib_darwin Darwin Specifics
+ * @addtogroup grp_USBLib
+ * @{ */
+
+/** @name VBoxUSB specific device properties.
+ * VBoxUSB makes use of the OWNER property for communicating between the probe and
+ * start stage.
+ * USBProxyServiceDarwin makes use of all of them to correctly determine the state
+ * of the device.
+ * @{ */
+/** Contains the pid of the current client. If 0, the kernel is the current client. */
+#define VBOXUSB_CLIENT_KEY "VBoxUSB-Client"
+/** Contains the pid of the filter owner (i.e. the VBoxSVC pid). */
+#define VBOXUSB_OWNER_KEY "VBoxUSB-Owner"
+/** Contains the ID of the matching filter. */
+#define VBOXUSB_FILTER_KEY "VBoxUSB-Filter"
+/** @} */
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/usblib-solaris.h b/include/VBox/usblib-solaris.h
new file mode 100644
index 00000000..f8c4b4c2
--- /dev/null
+++ b/include/VBox/usblib-solaris.h
@@ -0,0 +1,269 @@
+/** @file
+ * USBLib - Library for wrapping up the VBoxUSB functionality, Solaris flavor.
+ * (DEV,HDrv,Main)
+ */
+
+/*
+ * Copyright (C) 2008 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 ___VBox_usblib_solaris_h
+#define ___VBox_usblib_solaris_h
+
+#include <VBox/cdefs.h>
+#include <VBox/usbfilter.h>
+#include <VBox/vusb.h>
+#include <sys/types.h>
+#include <sys/ioccom.h>
+#include <sys/param.h>
+
+RT_C_DECLS_BEGIN
+/** @defgroup grp_USBLib_solaris Solaris Specifics
+ * @addtogroup grp_USBLib
+ * @{ */
+
+/** @name VBoxUSB specific IOCtls.
+ * VBoxUSB uses them for resetting USB devices requests from userland.
+ * USBProxyService/Device makes use of them to communicate with VBoxUSB.
+ * @{ */
+
+/** Ring-3 request wrapper for big requests.
+ *
+ * This is necessary because the ioctl number scheme on many Unixy OSes (esp. Solaris)
+ * only allows a relatively small size to be encoded into the request. So, for big
+ * request this generic form is used instead. */
+typedef struct VBOXUSBREQ
+{
+ /** Magic value (VBOXUSB(MON)_MAGIC). */
+ uint32_t u32Magic;
+ /** The size of the data buffer (In & Out). */
+ uint32_t cbData;
+ /** Result code of the request filled by driver. */
+ int32_t rc;
+ /** The user address of the data buffer. */
+ RTR3PTR pvDataR3;
+} VBOXUSBREQ;
+/** Pointer to a request wrapper for solaris. */
+typedef VBOXUSBREQ *PVBOXUSBREQ;
+/** Pointer to a const request wrapper for solaris. */
+typedef const VBOXUSBREQ *PCVBOXUSBREQ;
+
+#pragma pack(1)
+typedef struct
+{
+ /* Pointer to the Filter. */
+ USBFILTER Filter;
+ /* Where to store the added Filter (Id). */
+ uintptr_t uId;
+} VBOXUSBREQ_ADD_FILTER;
+
+typedef struct
+{
+ /* Pointer to Filter (Id) to be removed. */
+ uintptr_t uId;
+} VBOXUSBREQ_REMOVE_FILTER;
+
+typedef struct
+{
+ /** Whether to re-attach the driver. */
+ bool fReattach;
+ /* Physical path of the USB device. */
+ char szDevicePath[1];
+} VBOXUSBREQ_RESET_DEVICE;
+
+typedef struct
+{
+ /* Where to store the instance. */
+ int *pInstance;
+ /* Physical path of the USB device. */
+ char szDevicePath[1];
+} VBOXUSBREQ_DEVICE_INSTANCE;
+
+typedef struct
+{
+ /** Where to store the instance. */
+ int Instance;
+ /* Where to store the client path. */
+ char szClientPath[MAXPATHLEN];
+ /** Device identifier (VendorId:ProductId:Release:StaticPath) */
+ char szDeviceIdent[MAXPATHLEN+48];
+ /** Callback from monitor specifying client consumer (VM) credentials */
+ DECLR0CALLBACKMEMBER(int, pfnSetConsumerCredentials,(RTPROCESS Process, int Instance, void *pvReserved));
+} VBOXUSBREQ_CLIENT_INFO, *PVBOXUSBREQ_CLIENT_INFO;
+typedef VBOXUSBREQ_CLIENT_INFO VBOXUSB_CLIENT_INFO;
+typedef PVBOXUSBREQ_CLIENT_INFO PVBOXUSB_CLIENT_INFO;
+
+/** Isoc packet descriptor (Must mirror exactly Solaris USBA's usb_isoc_pkt_descr_t) */
+typedef struct
+{
+ ushort_t cbPkt; /* Size of the packet */
+ ushort_t cbActPkt; /* Size of the packet actually transferred */
+ VUSBSTATUS enmStatus; /* Per frame transfer status */
+} VUSBISOC_PKT_DESC;
+
+/** VBoxUSB IOCtls */
+typedef struct
+{
+ void *pvUrbR3; /* Pointer to userland URB (untouched by kernel driver) */
+ uint8_t bEndpoint; /* Endpoint address */
+ VUSBXFERTYPE enmType; /* Xfer type */
+ VUSBDIRECTION enmDir; /* Xfer direction */
+ VUSBSTATUS enmStatus; /* URB status */
+ size_t cbData; /* Size of the data */
+ void *pvData; /* Pointer to the data */
+ uint32_t cIsocPkts; /* Number of Isoc packets */
+ VUSBISOC_PKT_DESC aIsocPkts[8]; /* Array of Isoc packet descriptors */
+} VBOXUSBREQ_URB, *PVBOXUSBREQ_URB;
+
+typedef struct
+{
+ uint8_t bEndpoint; /* Endpoint address */
+} VBOXUSBREQ_CLEAR_EP, *PVBOXUSBREQ_CLEAR_EP;
+
+
+typedef struct
+{
+ uint8_t bConfigValue; /* Configuration value */
+} VBOXUSBREQ_SET_CONFIG, *PVBOXUSBREQ_SET_CONFIG;
+typedef VBOXUSBREQ_SET_CONFIG VBOXUSBREQ_GET_CONFIG;
+typedef PVBOXUSBREQ_SET_CONFIG PVBOXUSBREQ_GET_CONFIG;
+
+typedef struct
+{
+ uint8_t bInterface; /* Interface number */
+ uint8_t bAlternate; /* Alternate setting */
+} VBOXUSBREQ_SET_INTERFACE, *PVBOXUSBREQ_SET_INTERFACE;
+
+typedef enum
+{
+ VBOXUSB_RESET_LEVEL_NONE = 0,
+ VBOXUSB_RESET_LEVEL_REATTACH = 2,
+ VBOXUSB_RESET_LEVEL_SOFT = 4
+} VBOXUSB_RESET_LEVEL;
+
+typedef struct
+{
+ VBOXUSB_RESET_LEVEL ResetLevel; /* Reset level after closing */
+} VBOXUSBREQ_CLOSE_DEVICE, *PVBOXUSBREQ_CLOSE_DEVICE;
+
+typedef struct
+{
+ uint8_t bEndpoint; /* Endpoint address */
+} VBOXUSBREQ_ABORT_PIPE, *PVBOXUSBREQ_ABORT_PIPE;
+
+typedef struct
+{
+ uint32_t u32Major; /* Driver major number */
+ uint32_t u32Minor; /* Driver minor number */
+} VBOXUSBREQ_GET_VERSION, *PVBOXUSBREQ_GET_VERSION;
+
+#pragma pack()
+
+/** The VBOXUSBREQ::u32Magic value for VBoxUSBMon. */
+#define VBOXUSBMON_MAGIC 0xba5eba11
+/** The VBOXUSBREQ::u32Magic value for VBoxUSB.*/
+#define VBOXUSB_MAGIC 0x601fba11
+/** The USBLib entry point for userland. */
+#define VBOXUSB_DEVICE_NAME "/dev/vboxusbmon"
+
+/** The USBMonitor Major version. */
+#define VBOXUSBMON_VERSION_MAJOR 2
+/** The USBMonitor Minor version. */
+#define VBOXUSBMON_VERSION_MINOR 1
+
+/** The USB Major version. */
+#define VBOXUSB_VERSION_MAJOR 1
+/** The USB Minor version. */
+#define VBOXUSB_VERSION_MINOR 1
+
+#ifdef RT_ARCH_AMD64
+# define VBOXUSB_IOCTL_FLAG 128
+#elif defined(RT_ARCH_X86)
+# define VBOXUSB_IOCTL_FLAG 0
+#else
+# error "dunno which arch this is!"
+#endif
+
+/** USB driver name*/
+#define VBOXUSB_DRIVER_NAME "vboxusb"
+
+/* No automatic buffering, size limited to 255 bytes => use VBOXUSBREQ for everything. */
+#define VBOXUSB_IOCTL_CODE(Function, Size) _IOWRN('V', (Function) | VBOXUSB_IOCTL_FLAG, sizeof(VBOXUSBREQ))
+#define VBOXUSB_IOCTL_CODE_FAST(Function) _IO( 'V', (Function) | VBOXUSB_IOCTL_FLAG)
+#define VBOXUSB_IOCTL_STRIP_SIZE(Code) (Code)
+
+#define VBOXUSBMON_IOCTL_ADD_FILTER VBOXUSB_IOCTL_CODE(1, (sizeof(VBoxUSBAddFilterReq)))
+#define VBOXUSBMON_IOCTL_REMOVE_FILTER VBOXUSB_IOCTL_CODE(2, (sizeof(VBoxUSBRemoveFilterReq)))
+#define VBOXUSBMON_IOCTL_RESET_DEVICE VBOXUSB_IOCTL_CODE(3, (sizeof(VBOXUSBREQ_RESET_DEVICE)))
+#define VBOXUSBMON_IOCTL_DEVICE_INSTANCE VBOXUSB_IOCTL_CODE(4, (sizeof(VBOXUSBREQ_DEVICE_INSTANCE)))
+#define VBOXUSBMON_IOCTL_CLIENT_INFO VBOXUSB_IOCTL_CODE(5, (sizeof(VBOXUSBREQ_CLIENT_PATH)))
+#define VBOXUSBMON_IOCTL_GET_VERSION VBOXUSB_IOCTL_CODE(6, (sizeof(VBOXUSBREQ_GET_VERSION)))
+
+/* VBoxUSB ioctls */
+#define VBOXUSB_IOCTL_SEND_URB VBOXUSB_IOCTL_CODE(20, (sizeof(VBOXUSBREQ_URB))) /* 1072146796 */
+#define VBOXUSB_IOCTL_REAP_URB VBOXUSB_IOCTL_CODE(21, (sizeof(VBOXUSBREQ_URB))) /* 1072146795 */
+#define VBOXUSB_IOCTL_CLEAR_EP VBOXUSB_IOCTL_CODE(22, (sizeof(VBOXUSBREQ_CLEAR_EP))) /* 1072146794 */
+#define VBOXUSB_IOCTL_SET_CONFIG VBOXUSB_IOCTL_CODE(23, (sizeof(VBOXUSBREQ_SET_CONFIG))) /* 1072146793 */
+#define VBOXUSB_IOCTL_SET_INTERFACE VBOXUSB_IOCTL_CODE(24, (sizeof(VBOXUSBREQ_SET_INTERFACE))) /* 1072146792 */
+#define VBOXUSB_IOCTL_CLOSE_DEVICE VBOXUSB_IOCTL_CODE(25, (sizeof(VBOXUSBREQ_CLOSE_DEVICE))) /* 1072146791 0xc0185699 */
+#define VBOXUSB_IOCTL_ABORT_PIPE VBOXUSB_IOCTL_CODE(26, (sizeof(VBOXUSBREQ_ABORT_PIPE))) /* 1072146790 */
+#define VBOXUSB_IOCTL_GET_CONFIG VBOXUSB_IOCTL_CODE(27, (sizeof(VBOXUSBREQ_GET_CONFIG))) /* 1072146789 */
+#define VBOXUSB_IOCTL_GET_VERSION VBOXUSB_IOCTL_CODE(28, (sizeof(VBOXUSBREQ_GET_VERSION))) /* 1072146788 */
+
+/** @} */
+
+/* USBLibHelper data for resetting the device. */
+typedef struct VBOXUSBHELPERDATA_RESET
+{
+ /** Path of the USB device. */
+ const char *pszDevicePath;
+ /** Re-enumerate or not. */
+ bool fHardReset;
+} VBOXUSBHELPERDATA_RESET;
+typedef VBOXUSBHELPERDATA_RESET *PVBOXUSBHELPERDATA_RESET;
+typedef const VBOXUSBHELPERDATA_RESET *PCVBOXUSBHELPERDATA_RESET;
+
+/* USBLibHelper data for device hijacking. */
+typedef struct VBOXUSBHELPERDATA_ALIAS
+{
+ /** Vendor ID. */
+ uint16_t idVendor;
+ /** Product ID. */
+ uint16_t idProduct;
+ /** Revision, integer part. */
+ uint16_t bcdDevice;
+ /** Path of the USB device. */
+ const char *pszDevicePath;
+} VBOXUSBHELPERDATA_ALIAS;
+typedef VBOXUSBHELPERDATA_ALIAS *PVBOXUSBHELPERDATA_ALIAS;
+typedef const VBOXUSBHELPERDATA_ALIAS *PCVBOXUSBHELPERDATA_ALIAS;
+
+USBLIB_DECL(int) USBLibResetDevice(char *pszDevicePath, bool fReattach);
+USBLIB_DECL(int) USBLibDeviceInstance(char *pszDevicePath, int *pInstance);
+USBLIB_DECL(int) USBLibGetClientInfo(char *pszDeviceIdent, char **ppszClientPath, int *pInstance);
+USBLIB_DECL(int) USBLibAddDeviceAlias(PUSBDEVICE pDevice);
+USBLIB_DECL(int) USBLibRemoveDeviceAlias(PUSBDEVICE pDevice);
+/*USBLIB_DECL(int) USBLibConfigureDevice(PUSBDEVICE pDevice);*/
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/usblib-win.h b/include/VBox/usblib-win.h
new file mode 100644
index 00000000..ed8885bb
--- /dev/null
+++ b/include/VBox/usblib-win.h
@@ -0,0 +1,313 @@
+/** @file
+ * USBLib - Library for wrapping up the VBoxUSB functionality, Windows flavor.
+ * (DEV,HDrv,Main)
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_usblib_win_h
+#define ___VBox_usblib_win_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/usb.h>
+
+#ifdef RT_OS_WINDOWS
+
+#include <initguid.h>
+// {6068EB61-98E7-4c98-9E20-1F068295909A}
+DEFINE_GUID(GUID_CLASS_VBOXUSB, 0x873fdf, 0xCAFE, 0x80EE, 0xaa, 0x5e, 0x0, 0xc0, 0x4f, 0xb1, 0x72, 0xb);
+
+#define USBFLT_SERVICE_NAME "\\\\.\\VBoxUSBFlt"
+#define USBFLT_NTDEVICE_NAME_STRING L"\\Device\\VBoxUSBFlt"
+#define USBFLT_SYMBOLIC_NAME_STRING L"\\DosDevices\\VBoxUSBFlt"
+
+#define USBMON_SERVICE_NAME_W L"VBoxUSBMon"
+#define USBMON_DEVICE_NAME "\\\\.\\VBoxUSBMon"
+#define USBMON_DEVICE_NAME_NT L"\\Device\\VBoxUSBMon"
+#define USBMON_DEVICE_NAME_DOS L"\\DosDevices\\VBoxUSBMon"
+
+/*
+ * IOCtl numbers.
+ * We're using the Win32 type of numbers here, thus the macros below.
+ */
+
+#ifndef CTL_CODE
+# if defined(RT_OS_WINDOWS)
+# define CTL_CODE(DeviceType, Function, Method, Access) \
+ ( ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
+#else /* unix: */
+# define CTL_CODE(DeviceType, Function, Method_ignored, Access_ignored) \
+ ( (3 << 30) | ((DeviceType) << 8) | (Function) | (sizeof(SUPDRVIOCTLDATA) << 16) )
+# endif
+#endif
+#ifndef METHOD_BUFFERED
+# define METHOD_BUFFERED 0
+#endif
+#ifndef FILE_WRITE_ACCESS
+# define FILE_WRITE_ACCESS 0x0002
+#endif
+#ifndef FILE_DEVICE_UNKNOWN
+# define FILE_DEVICE_UNKNOWN 0x00000022
+#endif
+
+#define USBFLT_MAJOR_VERSION 1
+#define USBFLT_MINOR_VERSION 3
+
+#define USBMON_MAJOR_VERSION 5
+#define USBMON_MINOR_VERSION 0
+
+#define USBDRV_MAJOR_VERSION 4
+#define USBDRV_MINOR_VERSION 0
+
+#define SUPUSB_IOCTL_TEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x601, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_GET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x603, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_SEND_URB CTL_CODE(FILE_DEVICE_UNKNOWN, 0x607, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_USB_RESET CTL_CODE(FILE_DEVICE_UNKNOWN, 0x608, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_USB_SELECT_INTERFACE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x609, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_USB_SET_CONFIG CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60A, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_USB_CLAIM_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60B, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_USB_RELEASE_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60C, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_IS_OPERATIONAL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60D, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_USB_CLEAR_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60E, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60F, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSB_IOCTL_USB_ABORT_ENDPOINT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x610, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#define SUPUSBFLT_IOCTL_GET_NUM_DEVICES CTL_CODE(FILE_DEVICE_UNKNOWN, 0x602, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_USB_CHANGE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x604, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_DISABLE_CAPTURE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x605, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_ENABLE_CAPTURE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x606, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_IGNORE_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x60F, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_GET_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x610, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_ADD_FILTER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x611, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_REMOVE_FILTER CTL_CODE(FILE_DEVICE_UNKNOWN, 0x612, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_CAPTURE_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x613, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_RELEASE_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x614, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_RUN_FILTERS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x615, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_SET_NOTIFY_EVENT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x616, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+#define SUPUSBFLT_IOCTL_GET_DEVICE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x617, METHOD_BUFFERED, FILE_WRITE_ACCESS)
+
+#pragma pack(4)
+
+#define MAX_FILTER_NAME 128
+#define MAX_USB_SERIAL_STRING 64
+
+/* a user-mode handle that could be used for retriving device information
+ * from the monitor driver */
+typedef void* HVBOXUSBDEVUSR;
+
+typedef struct
+{
+ HVBOXUSBDEVUSR hDevice;
+ uint8_t fAttached;
+ uint8_t fHiSpeed;
+} USBSUP_GETDEV, *PUSBSUP_GETDEV;
+
+typedef struct
+{
+ USBDEVICESTATE enmState;
+} USBSUP_GETDEV_MON, *PUSBSUP_GETDEV_MON;
+
+typedef struct
+{
+ uint32_t u32Major;
+ uint32_t u32Minor;
+} USBSUP_VERSION, *PUSBSUP_VERSION;
+
+#endif /* RT_OS_WINDOWS */
+
+typedef struct USBSUP_FLTADDOUT
+{
+ uintptr_t uId; /* The ID. */
+ int rc; /* The return code. */
+} USBSUP_FLTADDOUT, *PUSBSUP_FLTADDOUT;
+
+typedef struct
+{
+ uint16_t usVendorId;
+ uint16_t usProductId;
+ uint16_t usRevision;
+} USBSUP_CAPTURE, *PUSBSUP_CAPTURE;
+
+typedef USBSUP_CAPTURE USBSUP_RELEASE;
+typedef PUSBSUP_CAPTURE PUSBSUP_RELEASE;
+
+typedef struct
+{
+ uint8_t bInterfaceNumber;
+ uint8_t fClaimed;
+} USBSUP_CLAIMDEV, *PUSBSUP_CLAIMDEV;
+
+typedef USBSUP_CLAIMDEV USBSUP_RELEASEDEV;
+typedef PUSBSUP_CLAIMDEV PUSBSUP_RELEASEDEV;
+
+typedef struct
+{
+ uint32_t cUSBDevices;
+} USBSUP_GETNUMDEV, *PUSBSUP_GETNUMDEV;
+
+typedef struct
+{
+ uint8_t fUSBChange;
+ uint32_t cUSBStateChange;
+} USBSUP_USB_CHANGE, *PUSBSUP_USB_CHANGE;
+
+typedef struct
+{
+ uint8_t bConfigurationValue;
+} USBSUP_SET_CONFIG, *PUSBSUP_SET_CONFIG;
+
+typedef struct
+{
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+} USBSUP_SELECT_INTERFACE, *PUSBSUP_SELECT_INTERFACE;
+
+typedef struct
+{
+ uint8_t bEndpoint;
+} USBSUP_CLEAR_ENDPOINT, *PUSBSUP_CLEAR_ENDPOINT;
+
+typedef enum
+{
+ USBSUP_TRANSFER_TYPE_CTRL = 0,
+ USBSUP_TRANSFER_TYPE_ISOC = 1,
+ USBSUP_TRANSFER_TYPE_BULK = 2,
+ USBSUP_TRANSFER_TYPE_INTR = 3,
+ USBSUP_TRANSFER_TYPE_MSG = 4
+} USBSUP_TRANSFER_TYPE;
+
+typedef enum
+{
+ USBSUP_DIRECTION_SETUP = 0,
+ USBSUP_DIRECTION_IN = 1,
+ USBSUP_DIRECTION_OUT = 2
+} USBSUP_DIRECTION;
+
+typedef enum
+{
+ USBSUP_FLAG_NONE = 0,
+ USBSUP_FLAG_SHORT_OK = 1
+} USBSUP_XFER_FLAG;
+
+typedef enum
+{
+ USBSUP_XFER_OK = 0,
+ USBSUP_XFER_STALL = 1,
+ USBSUP_XFER_DNR = 2,
+ USBSUP_XFER_CRC = 3,
+ USBSUP_XFER_NAC = 4,
+ USBSUP_XFER_UNDERRUN = 5,
+ USBSUP_XFER_OVERRUN = 6
+} USBSUP_ERROR;
+
+typedef struct USBSUP_ISOCPKT
+{
+ uint16_t cb; /* [in/out] packet size/size transferred */
+ uint16_t off; /* [in] offset of packet in buffer */
+ USBSUP_ERROR stat; /* [out] packet status */
+} USBSUP_ISOCPKT;
+
+typedef struct
+{
+ USBSUP_TRANSFER_TYPE type; /* [in] USBSUP_TRANSFER_TYPE_XXX */
+ uint32_t ep; /* [in] index to dev->pipe */
+ USBSUP_DIRECTION dir; /* [in] USBSUP_DIRECTION_XXX */
+ USBSUP_XFER_FLAG flags; /* [in] USBSUP_FLAG_XXX */
+ USBSUP_ERROR error; /* [out] USBSUP_XFER_XXX */
+ size_t len; /* [in/out] may change */
+ void *buf; /* [in/out] depends on dir */
+ uint32_t numIsoPkts; /* [in] number of isochronous packets (8 max) */
+ USBSUP_ISOCPKT aIsoPkts[8]; /* [in/out] isochronous packet descriptors */
+} USBSUP_URB, *PUSBSUP_URB;
+
+typedef struct
+{
+ union
+ {
+ /* in: event handle */
+ void* hEvent;
+ /* out: result */
+ int rc;
+ } u;
+} USBSUP_SET_NOTIFY_EVENT, *PUSBSUP_SET_NOTIFY_EVENT;
+
+typedef struct
+{
+ uint16_t usVendorId;
+ uint16_t usProductId;
+ uint16_t usRevision;
+ uint16_t usAlignment;
+ char DrvKeyName[512];
+} USBSUP_DEVID, *PUSBSUP_DEVID;
+
+typedef struct
+{
+ USBSUP_DEVID DevId;
+ char szName[512];
+ USBDEVICESTATE enmState;
+ bool fHiSpeed;
+} USBSUP_DEVINFO, *PUSBSUP_DEVINFO;
+
+typedef struct
+{
+ int rc;
+ uint32_t cDevices;
+ USBSUP_DEVINFO aDevices[1];
+} USBSUP_GET_DEVICES, *PUSBSUP_GET_DEVICES;
+
+#pragma pack() /* paranoia */
+
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING3
+
+/** @defgroup grp_usblib_r3 USBLIB Host Context Ring 3 API
+ * @{
+ */
+
+/**
+ * Return all attached USB devices.
+ *
+ * @returns VBox status code
+ * @param ppDevices Receives pointer to list of devices
+ * @param pcbNumDevices Number of USB devices in the list
+ */
+USBLIB_DECL(int) USBLibGetDevices(PUSBDEVICE *ppDevices, uint32_t *pcbNumDevices);
+
+USBLIB_DECL(int) USBLibWaitChange(RTMSINTERVAL cMillies);
+
+USBLIB_DECL(int) USBLibInterruptWaitChange();
+
+USBLIB_DECL(int) USBLibRunFilters();
+
+/** @} */
+#endif
+
+/** @} */
+
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/VBox/usblib.h b/include/VBox/usblib.h
new file mode 100644
index 00000000..21d46419
--- /dev/null
+++ b/include/VBox/usblib.h
@@ -0,0 +1,119 @@
+/** @file
+ * USBLib - Library for wrapping up the VBoxUSB functionality. (DEV,HDrv,Main)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_usblib_h
+#define ___VBox_usblib_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/usb.h>
+#include <VBox/usbfilter.h>
+
+#ifdef RT_OS_WINDOWS
+# include <VBox/usblib-win.h>
+#endif
+#ifdef RT_OS_SOLARIS
+# include <VBox/usblib-solaris.h>
+#endif
+#ifdef RT_OS_DARWIN
+# include <VBox/usblib-darwin.h>
+#endif
+/** @todo merge the usblib-win.h interface into the darwin and linux ports where suitable. */
+
+RT_C_DECLS_BEGIN
+/** @defgroup grp_USBLib USBLib - USB Support Library
+ * This module implements the basic low-level OS interfaces and common USB code.
+ * @{
+ */
+
+#ifdef IN_RING3
+/**
+ * Initializes the USBLib component.
+ *
+ * The USBLib keeps a per process connection to the kernel driver
+ * and all USBLib users within a process will share the same
+ * connection. USBLib does reference counting to make sure that
+ * the connection remains open until all users has called USBLibTerm().
+ *
+ * @returns VBox status code.
+ *
+ * @remark The users within the process are responsible for not calling
+ * this function at the same time (because I'm lazy).
+ */
+USBLIB_DECL(int) USBLibInit(void);
+
+/**
+ * Terminates the USBLib component.
+ *
+ * Must match successful USBLibInit calls.
+ *
+ * @returns VBox status code.
+ */
+USBLIB_DECL(int) USBLibTerm(void);
+
+/**
+ * Adds a filter.
+ *
+ * This function will validate and transfer the specified filter
+ * to the kernel driver and make it start using it. The kernel
+ * driver will return a filter id that this function passes on
+ * to its caller.
+ *
+ * The kernel driver will associate the added filter with the
+ * calling process and automatically remove all filters when
+ * the process terminates the connection to it or dies.
+ *
+ * @returns Filter id for passing to USBLibRemoveFilter on success.
+ * @returns NULL on failure.
+ *
+ * @param pFilter The filter to add.
+ */
+USBLIB_DECL(void *) USBLibAddFilter(PCUSBFILTER pFilter);
+
+/**
+ * Removes a filter.
+ *
+ * @param pvId The ID returned by USBLibAddFilter.
+ */
+USBLIB_DECL(void) USBLibRemoveFilter(void *pvId);
+
+/**
+ * Calculate the hash of the serial string.
+ *
+ * 64bit FNV1a, chosen because it is designed to hash in to a power of two
+ * space, and is much quicker and simpler than, say, a half MD4.
+ *
+ * @returns the hash.
+ * @param pszSerial The serial string.
+ */
+USBLIB_DECL(uint64_t) USBLibHashSerial(const char *pszSerial);
+
+#endif /* IN_RING3 */
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/various.sed b/include/VBox/various.sed
new file mode 100644
index 00000000..fb3507f1
--- /dev/null
+++ b/include/VBox/various.sed
@@ -0,0 +1,93 @@
+
+# Check for markers (typically in comments).
+/ASM-INC/basm-inc
+/ASM-NOINC/basm-noinc
+
+# Strip comments and trailing space.
+s/[[:space:]][[:space:]]*\/\*.*$//g
+s/[[:space:]][[:space:]]*\/\/.*$//g
+s/[[:space:]][[:space:]]*$//g
+
+# Try identify the statement.
+/#[[:space:]]*define[[:space:]]/bdefine
+/#[[:space:]]*ifdef[[:space:]]/bifdef
+/#[[:space:]]*ifndef[[:space:]]/bifndef
+/#[[:space:]]*if[[:space:]]/bif
+/#[[:space:]]*elif[[:space:]]/belif
+/#[[:space:]]*else$/belse
+/#[[:space:]]*endif$/bendif
+
+# Not recognized, drop it.
+:asm-noinc
+d
+b end
+
+#
+# Defines needs some extra massaging to work in yasm.
+# Things like trailing type indicators ('U', 'ULL' ++) does not go down well.
+#
+:define
+/\$/d
+s/#\([[:space:]]*\)define/\1%define/
+
+s/\([[:space:]]0[xX][0-9a-fA-F][0-9a-fA-F]*\)U$/\1/
+s/\([[:space:]]0[xX][0-9a-fA-F][0-9a-fA-F]*\)U\([[:space:]]*\))$/\1\2)/
+s/\([[:space:]][0-9][0-9]*\)U[[:space:]]*$/\1/
+s/\([[:space:]][0-9][0-9]*\)U\([[:space:]]*\))$/\1\2)/
+
+s/\([[:space:]]0[xX][0-9a-fA-F][0-9a-fA-F]*\)UL$/\1/
+s/\([[:space:]]0[xX][0-9a-fA-F][0-9a-fA-F]*\)UL\([[:space:]]*\))$/\1\2)/
+s/\([[:space:]][0-9][0-9]*\)UL[[:space:]]*$/\1/
+s/\([[:space:]][0-9][0-9]*\)UL\([[:space:]]*\))$/\1\2)/
+
+s/\([[:space:]]0[xX][0-9a-fA-F][0-9a-fA-F]*\)ULL$/\1/
+s/\([[:space:]]0[xX][0-9a-fA-F][0-9a-fA-F]*\)ULL\([[:space:]]*\))$/\1\2)/
+s/\([[:space:]][0-9][0-9]*\)ULL[[:space:]]*$/\1/
+s/\([[:space:]][0-9][0-9]*\)ULL\([[:space:]]*\))$/\1\2)/
+
+s/UINT64_C([[:space:]]*\(0[xX][0-9a-fA-F][0-9a-fA-F]*\)[[:space:]]*)/\1/
+s/UINT64_C([[:space:]]*\([0-9][0-9]*\)[[:space:]]*)/\1/
+s/UINT32_C([[:space:]]*\(0[xX][0-9a-fA-F][0-9a-fA-F]*\)[[:space:]]*)/\1/
+s/UINT32_C([[:space:]]*\([0-9][0-9]*\)[[:space:]]*)/\1/
+s/UINT16_C([[:space:]]*\(0[xX][0-9a-fA-F][0-9a-fA-F]*\)[[:space:]]*)/\1/
+s/UINT16_C([[:space:]]*\([0-9][0-9]*\)[[:space:]]*)/\1/
+s/UINT8_C([[:space:]]*\(0[xX][0-9a-fA-F][0-9a-fA-F]*\)[[:space:]]*)/\1/
+s/UINT8_C([[:space:]]*\([0-9][0-9]*\)[[:space:]]*)/\1/
+
+b end
+
+#
+# Conditional statements, 1:1.
+#
+:ifdef
+s/#\([[:space:]]*\)ifdef/\1%ifdef/
+b end
+
+:ifndef
+s/#\([[:space:]]*\)ifndef/\1%ifndef/
+b end
+
+:if
+s/#\([[:space:]]*\)if/\1%if/
+b end
+
+:elif
+s/#\([[:space:]]*\)elif/\1%elif/
+b end
+
+:else
+s/#\([[:space:]]*\)else.*$/\1%else/
+b end
+
+:endif
+s/#\([[:space:]]*\)endif.*$/\1%endif/
+b end
+
+#
+# Assembly statement... may need adjusting when used.
+#
+:asm-inc
+b end
+
+:end
+
diff --git a/include/VBox/vd-cache-plugin.h b/include/VBox/vd-cache-plugin.h
new file mode 100644
index 00000000..af185680
--- /dev/null
+++ b/include/VBox/vd-cache-plugin.h
@@ -0,0 +1,357 @@
+/** @file
+ * Internal hard disk format support API for VBoxHDD cache images.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 __VBoxHDD_CachePlugin_h__
+#define __VBoxHDD_CachePlugin_h__
+
+#include <VBox/vd.h>
+#include <VBox/vd-ifs-internal.h>
+
+/**
+ * Cache format backend interface used by VBox HDD Container implementation.
+ */
+typedef struct VDCACHEBACKEND
+{
+ /**
+ * The name of the backend (constant string).
+ */
+ const char *pszBackendName;
+
+ /**
+ * The size of the structure.
+ */
+ uint32_t cbSize;
+
+ /**
+ * The capabilities of the backend.
+ */
+ uint64_t uBackendCaps;
+
+ /**
+ * Pointer to a NULL-terminated array of strings, containing the supported
+ * file extensions. Note that some backends do not work on files, so this
+ * pointer may just contain NULL.
+ */
+ const char * const *papszFileExtensions;
+
+ /**
+ * Pointer to an array of structs describing each supported config key.
+ * Terminated by a NULL config key. Note that some backends do not support
+ * the configuration interface, so this pointer may just contain NULL.
+ * Mandatory if the backend sets VD_CAP_CONFIG.
+ */
+ PCVDCONFIGINFO paConfigInfo;
+
+ /**
+ * Handle of loaded plugin library, NIL_RTLDRMOD for static backends.
+ */
+ RTLDRMOD hPlugin;
+
+ /**
+ * Probes the given image.
+ *
+ * @returns VBox status code.
+ * @param pszFilename Name of the image file.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnProbe, (const char *pszFilename, PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage));
+
+ /**
+ * Open a cache image.
+ *
+ * @returns VBox status code.
+ * @param pszFilename Name of the image file to open. Guaranteed to be available and
+ * unchanged during the lifetime of this image.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param ppBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnOpen, (const char *pszFilename, unsigned uOpenFlags,
+ PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
+ void **ppBackendData));
+
+ /**
+ * Create a cache image.
+ *
+ * @returns VBox status code.
+ * @param pszFilename Name of the image file to create. Guaranteed to be available and
+ * unchanged during the lifetime of this image.
+ * @param cbSize Image size in bytes.
+ * @param uImageFlags Flags specifying special image features.
+ * @param pszComment Pointer to image comment. NULL is ok.
+ * @param pUuid New UUID of the image. Not NULL.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param uPercentStart Starting value for progress percentage.
+ * @param uPercentSpan Span for varying progress percentage.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ * @param ppBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCreate, (const char *pszFilename, uint64_t cbSize,
+ unsigned uImageFlags, const char *pszComment,
+ PCRTUUID pUuid, unsigned uOpenFlags,
+ unsigned uPercentStart, unsigned uPercentSpan,
+ PVDINTERFACE pVDIfsDisk,
+ PVDINTERFACE pVDIfsImage,
+ PVDINTERFACE pVDIfsOperation,
+ void **ppBackendData));
+
+ /**
+ * Close a cache image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param fDelete If true, delete the image from the host disk.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnClose, (void *pBackendData, bool fDelete));
+
+ /**
+ * Read data from a cache image. The area read never crosses a block
+ * boundary.
+ *
+ * @returns VBox status code.
+ * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset Offset to start reading from.
+ * @param pvBuf Where to store the read bits.
+ * @param cbRead Number of bytes to read.
+ * @param pcbActuallyRead Pointer to returned number of bytes read.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, void *pvBuf,
+ size_t cbRead, size_t *pcbActuallyRead));
+
+ /**
+ * Write data to a cache image. The area written never crosses a block
+ * boundary.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset Offset to start writing to.
+ * @param pvBuf Where to retrieve the written bits.
+ * @param cbWrite Number of bytes to write.
+ * @param pcbWriteProcess Pointer to returned number of bytes that could
+ * be processed.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset,
+ const void *pvBuf, size_t cbWrite,
+ size_t *pcbWriteProcess));
+
+ /**
+ * Flush data to disk.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData));
+
+ /**
+ * Get the version of a cache image.
+ *
+ * @returns version of cache image.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(unsigned, pfnGetVersion, (void *pBackendData));
+
+ /**
+ * Get the capacity of a cache image.
+ *
+ * @returns size of cache image in bytes.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize, (void *pBackendData));
+
+ /**
+ * Get the file size of a cache image.
+ *
+ * @returns size of cache image in bytes.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetFileSize, (void *pBackendData));
+
+ /**
+ * Get the image flags of a cache image.
+ *
+ * @returns image flags of cache image.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(unsigned, pfnGetImageFlags, (void *pBackendData));
+
+ /**
+ * Get the open flags of a cache image.
+ *
+ * @returns open flags of cache image.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(unsigned, pfnGetOpenFlags, (void *pBackendData));
+
+ /**
+ * Set the open flags of a cache image. May cause the image to be locked
+ * in a different mode or be reopened (which can fail).
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOpenFlags New open flags for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetOpenFlags, (void *pBackendData, unsigned uOpenFlags));
+
+ /**
+ * Get comment of a cache image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pszComment Where to store the comment.
+ * @param cbComment Size of the comment buffer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetComment, (void *pBackendData, char *pszComment, size_t cbComment));
+
+ /**
+ * Set comment of a cache image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pszComment Where to get the comment from. NULL resets comment.
+ * The comment is silently truncated if the image format
+ * limit is exceeded.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetComment, (void *pBackendData, const char *pszComment));
+
+ /**
+ * Get UUID of a cache image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to store the image UUID.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetUuid, (void *pBackendData, PRTUUID pUuid));
+
+ /**
+ * Set UUID of a cache image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to get the image UUID from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetUuid, (void *pBackendData, PCRTUUID pUuid));
+
+ /**
+ * Get last modification UUID of a cache image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to store the image modification UUID.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetModificationUuid, (void *pBackendData, PRTUUID pUuid));
+
+ /**
+ * Set last modification UUID of a cache image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to get the image modification UUID from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetModificationUuid, (void *pBackendData, PCRTUUID pUuid));
+
+ /**
+ * Dump information about a cache image.
+ *
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnDump, (void *pBackendData));
+
+ /**
+ * Start an asynchronous read request.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset The offset of the virtual disk to read from.
+ * @param cbRead How many bytes to read.
+ * @param pIoCtx I/O context associated with this request.
+ * @param pcbActuallyRead Pointer to returned number of bytes read.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncRead, (void *pBackendData, uint64_t uOffset, size_t cbRead,
+ PVDIOCTX pIoCtx, size_t *pcbActuallyRead));
+
+ /**
+ * Start an asynchronous write request.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset The offset of the virtual disk to write to.
+ * @param cbWrite How many bytes to write.
+ * @param pIoCtx I/O context associated with this request.
+ * @param pcbWriteProcess Pointer to returned number of bytes that could
+ * be processed. In case the function returned
+ * VERR_VD_BLOCK_FREE this is the number of bytes
+ * that could be written in a full block write,
+ * when prefixed/postfixed by the appropriate
+ * amount of (previously read) padding data.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite,
+ PVDIOCTX pIoCtx, size_t *pcbWriteProcess));
+
+ /**
+ * Flush data to disk.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pIoCtx I/O context associated with this request.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncFlush, (void *pBackendData, PVDIOCTX pIoCtx));
+
+ /** Returns a human readable hard disk location string given a
+ * set of hard disk configuration keys. The returned string is an
+ * equivalent of the full file path for image-based hard disks.
+ * Mandatory for backends with no VD_CAP_FILE and NULL otherwise. */
+ DECLR3CALLBACKMEMBER(int, pfnComposeLocation, (PVDINTERFACE pConfig, char **pszLocation));
+
+ /** Returns a human readable hard disk name string given a
+ * set of hard disk configuration keys. The returned string is an
+ * equivalent of the file name part in the full file path for
+ * image-based hard disks. Mandatory for backends with no
+ * VD_CAP_FILE and NULL otherwise. */
+ DECLR3CALLBACKMEMBER(int, pfnComposeName, (PVDINTERFACE pConfig, char **pszName));
+
+} VDCACHEBACKEND;
+
+/** Pointer to VD backend. */
+typedef VDCACHEBACKEND *PVDCACHEBACKEND;
+
+/** Constant pointer to VD backend. */
+typedef const VDCACHEBACKEND *PCVDCACHEBACKEND;
+
+/** Initialization entry point. */
+typedef DECLCALLBACK(int) FNVDCACHEFORMATLOAD(PVDCACHEBACKEND *ppBackendTable);
+typedef FNVDCACHEFORMATLOAD *PFNVDCACHEFORMATLOAD;
+#define VD_CACHEFORMAT_LOAD_NAME "VDCacheFormatLoad"
+
+/** The prefix to identify Storage Plugins. */
+#define VD_CACHEFORMAT_PLUGIN_PREFIX "VDCache"
+/** The size of the prefix excluding the '\\0' terminator. */
+#define VD_CACHEFORMAT_PLUGIN_PREFIX_LENGTH (sizeof(VD_CACHEFORMAT_PLUGIN_PREFIX)-1)
+
+#endif
diff --git a/include/VBox/vd-ifs-internal.h b/include/VBox/vd-ifs-internal.h
new file mode 100644
index 00000000..5b5ae5ad
--- /dev/null
+++ b/include/VBox/vd-ifs-internal.h
@@ -0,0 +1,569 @@
+/** @file
+ * VD Container API - internal interfaces.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VD_Interfaces_Internal_h
+#define ___VBox_VD_Interfaces_Internal_h
+
+#include <iprt/sg.h>
+#include <VBox/vd-ifs.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Interface to get the parent state.
+ *
+ * Per-operation interface. Optional, present only if there is a parent, and
+ * used only internally for compacting.
+ */
+typedef struct VDINTERFACEPARENTSTATE
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Read data callback.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
+ * @param pvUser The opaque data passed for the operation.
+ * @param uOffset Offset of first reading byte from start of disk.
+ * Must be aligned to a sector boundary.
+ * @param pvBuffer Pointer to buffer for reading data.
+ * @param cbBuffer Number of bytes to read.
+ * Must be aligned to a sector boundary.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnParentRead, (void *pvUser, uint64_t uOffset, void *pvBuffer, size_t cbBuffer));
+
+} VDINTERFACEPARENTSTATE, *PVDINTERFACEPARENTSTATE;
+
+
+/**
+ * Get parent state interface from interface list.
+ *
+ * @return Pointer to the first parent state interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACEPARENTSTATE) VDIfParentStateGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_PARENTSTATE);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_PARENTSTATE)
+ && (pIf->cbSize == sizeof(VDINTERFACEPARENTSTATE))),
+ ("Not a parent state interface"), NULL);
+
+ return (PVDINTERFACEPARENTSTATE)pIf;
+}
+
+/** Forward declaration. Only visible in the VBoxHDD module. */
+/** I/O context */
+typedef struct VDIOCTX *PVDIOCTX;
+/** Storage backend handle. */
+typedef struct VDIOSTORAGE *PVDIOSTORAGE;
+/** Pointer to a storage backend handle. */
+typedef PVDIOSTORAGE *PPVDIOSTORAGE;
+
+/**
+ * Completion callback for meta/userdata reads or writes.
+ *
+ * @return VBox status code.
+ * VINF_SUCCESS if everything was successful and the transfer can continue.
+ * VERR_VD_ASYNC_IO_IN_PROGRESS if there is another data transfer pending.
+ * @param pBackendData The opaque backend data.
+ * @param pIoCtx I/O context associated with this request.
+ * @param pvUser Opaque user data passed during a read/write request.
+ * @param rcReq Status code for the completed request.
+ */
+typedef DECLCALLBACK(int) FNVDXFERCOMPLETED(void *pBackendData, PVDIOCTX pIoCtx, void *pvUser, int rcReq);
+/** Pointer to FNVDXFERCOMPLETED() */
+typedef FNVDXFERCOMPLETED *PFNVDXFERCOMPLETED;
+
+/** Metadata transfer handle. */
+typedef struct VDMETAXFER *PVDMETAXFER;
+/** Pointer to a metadata transfer handle. */
+typedef PVDMETAXFER *PPVDMETAXFER;
+
+
+/**
+ * Internal I/O interface between the generic VD layer and the backends.
+ *
+ * Per-image. Always passed to backends.
+ */
+typedef struct VDINTERFACEIOINT
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Open callback
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pszLocation Name of the location to open.
+ * @param fOpen Flags for opening the backend.
+ * See RTFILE_O_* #defines, inventing another set
+ * of open flags is not worth the mapping effort.
+ * @param ppStorage Where to store the storage handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
+ uint32_t fOpen, PPVDIOSTORAGE ppStorage));
+
+ /**
+ * Close callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to close.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, PVDIOSTORAGE pStorage));
+
+ /**
+ * Delete callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszFilename Name of the file to delete.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));
+
+ /**
+ * Move callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszSrc The path to the source file.
+ * @param pcszDst The path to the destination file.
+ * This file will be created.
+ * @param fMove A combination of the RTFILEMOVE_* flags.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
+
+ /**
+ * Returns the free space on a disk.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszFilename Name of a file to identify the disk.
+ * @param pcbFreeSpace Where to store the free space of the disk.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
+
+ /**
+ * Returns the last modification timestamp of a file.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszFilename Name of a file to identify the disk.
+ * @param pModificationTime Where to store the timestamp of the file.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
+
+ /**
+ * Returns the size of the opened storage backend.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to get the size from.
+ * @param pcbSize Where to store the size of the storage backend.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, PVDIOSTORAGE pStorage,
+ uint64_t *pcbSize));
+
+ /**
+ * Sets the size of the opened storage backend if possible.
+ *
+ * @return VBox status code.
+ * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle.
+ * @param cbSize The new size of the image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, PVDIOSTORAGE pStorage,
+ uint64_t cbSize));
+
+ /**
+ * Synchronous write callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to use.
+ * @param uOffset The offset to start from.
+ * @param pvBuffer Pointer to the bits need to be written.
+ * @param cbBuffer How many bytes to write.
+ * @param pcbWritten Where to store how many bytes were actually written.
+ *
+ * @notes Do not use in code called from the async read/write entry points in the backends.
+ * This should be only used during open/close of images and for the support functions
+ * which are not called while a VM is running (pfnCompact).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,
+ const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
+
+ /**
+ * Synchronous read callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to use.
+ * @param uOffset The offset to start from.
+ * @param pvBuffer Where to store the read bits.
+ * @param cbBuffer How many bytes to read.
+ * @param pcbRead Where to store how many bytes were actually read.
+ *
+ * @notes See pfnWriteSync()
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, PVDIOSTORAGE pStorage, uint64_t uOffset,
+ void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
+
+ /**
+ * Flush data to the storage backend.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to flush.
+ *
+ * @notes See pfnWriteSync()
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, PVDIOSTORAGE pStorage));
+
+ /**
+ * Initiate an asynchronous read request for user data.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pStorage The storage handle.
+ * @param uOffset The offset to start reading from.
+ * @param pIoCtx I/O context passed in VDAsyncRead/Write.
+ * @param cbRead How many bytes to read.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, PVDIOCTX pIoCtx,
+ size_t cbRead));
+
+ /**
+ * Initiate an asynchronous write request for user data.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pStorage The storage handle.
+ * @param uOffset The offset to start writing to.
+ * @param pIoCtx I/O context passed in VDAsyncRead/Write
+ * @param cbWrite How many bytes to write.
+ * @param pfnCompleted Completion callback.
+ * @param pvCompleteUser Opaque user data passed in the completion callback.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteUserAsync, (void *pvUser, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, PVDIOCTX pIoCtx,
+ size_t cbWrite,
+ PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser));
+
+ /**
+ * Reads metadata asynchronously from storage.
+ * The current I/O context will be halted.
+ *
+ * @returns VBox status code.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pStorage The storage handle.
+ * @param uOffset Offset to start reading from.
+ * @param pvBuffer Where to store the data.
+ * @param cbBuffer How many bytes to read.
+ * @param pIoCtx The I/O context which triggered the read.
+ * @param ppMetaXfer Where to store the metadata transfer handle on success.
+ * @param pfnCompleted Completion callback.
+ * @param pvCompleteUser Opaque user data passed in the completion callback.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, void *pvBuffer,
+ size_t cbBuffer, PVDIOCTX pIoCtx,
+ PPVDMETAXFER ppMetaXfer,
+ PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser));
+
+ /**
+ * Writes metadata asynchronously to storage.
+ *
+ * @returns VBox status code.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pStorage The storage handle.
+ * @param uOffset Offset to start writing to.
+ * @param pvBuffer Written data.
+ * @param cbBuffer How many bytes to write.
+ * @param pIoCtx The I/O context which triggered the write.
+ * @param pfnCompleted Completion callback.
+ * @param pvCompleteUser Opaque user data passed in the completion callback.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteMetaAsync, (void *pvUser, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, void *pvBuffer,
+ size_t cbBuffer, PVDIOCTX pIoCtx,
+ PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser));
+
+ /**
+ * Releases a metadata transfer handle.
+ * The free space can be used for another transfer.
+ *
+ * @returns nothing.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pMetaXfer The metadata transfer handle to release.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnMetaXferRelease, (void *pvUser, PVDMETAXFER pMetaXfer));
+
+ /**
+ * Initiates an async flush request.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to flush.
+ * @param pIoCtx I/O context which triggered the flush.
+ * @param pfnCompleted Completion callback.
+ * @param pvCompleteUser Opaque user data passed in the completion callback.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, PVDIOSTORAGE pStorage,
+ PVDIOCTX pIoCtx,
+ PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser));
+
+ /**
+ * Copies a buffer into the I/O context.
+ *
+ * @return Number of bytes copied.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pIoCtx I/O context to copy the data to.
+ * @param pvBuffer Buffer to copy.
+ * @param cbBuffer Number of bytes to copy.
+ */
+ DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyTo, (void *pvUser, PVDIOCTX pIoCtx,
+ void *pvBuffer, size_t cbBuffer));
+
+ /**
+ * Copies data from the I/O context into a buffer.
+ *
+ * @return Number of bytes copied.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pIoCtx I/O context to copy the data from.
+ * @param pvBuffer Destination buffer.
+ * @param cbBuffer Number of bytes to copy.
+ */
+ DECLR3CALLBACKMEMBER(size_t, pfnIoCtxCopyFrom, (void *pvUser, PVDIOCTX pIoCtx,
+ void *pvBuffer, size_t cbBuffer));
+
+ /**
+ * Sets the buffer of the given context to a specific byte.
+ *
+ * @return Number of bytes set.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pIoCtx I/O context to copy the data from.
+ * @param ch The byte to set.
+ * @param cbSet Number of bytes to set.
+ */
+ DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSet, (void *pvUser, PVDIOCTX pIoCtx,
+ int ch, size_t cbSet));
+
+ /**
+ * Creates a segment array from the I/O context data buffer.
+ *
+ * @returns Number of bytes the array describes.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pIoCtx I/O context to copy the data from.
+ * @param paSeg The uninitialized segment array.
+ * If NULL pcSeg will contain the number of segments needed
+ * to describe the requested amount of data.
+ * @param pcSeg The number of segments the given array has.
+ * This will hold the actual number of entries needed upon return.
+ * @param cbData Number of bytes the new array should describe.
+ */
+ DECLR3CALLBACKMEMBER(size_t, pfnIoCtxSegArrayCreate, (void *pvUser, PVDIOCTX pIoCtx,
+ PRTSGSEG paSeg, unsigned *pcSeg,
+ size_t cbData));
+ /**
+ * Marks the given number of bytes as completed and continues the I/O context.
+ *
+ * @returns nothing.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pIoCtx The I/O context.
+ * @param rcReq Status code the request completed with.
+ * @param cbCompleted Number of bytes completed.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnIoCtxCompleted, (void *pvUser, PVDIOCTX pIoCtx,
+ int rcReq, size_t cbCompleted));
+} VDINTERFACEIOINT, *PVDINTERFACEIOINT;
+
+/**
+ * Get internal I/O interface from interface list.
+ *
+ * @return Pointer to the first internal I/O interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACEIOINT) VDIfIoIntGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_IOINT);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_IOINT)
+ && (pIf->cbSize == sizeof(VDINTERFACEIOINT))),
+ ("Not an internal I/O interface"), NULL);
+
+ return (PVDINTERFACEIOINT)pIf;
+}
+
+DECLINLINE(int) vdIfIoIntFileOpen(PVDINTERFACEIOINT pIfIoInt, const char *pszFilename,
+ uint32_t fOpen, PPVDIOSTORAGE ppStorage)
+{
+ return pIfIoInt->pfnOpen(pIfIoInt->Core.pvUser, pszFilename, fOpen, ppStorage);
+}
+
+DECLINLINE(int) vdIfIoIntFileClose(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage)
+{
+ return pIfIoInt->pfnClose(pIfIoInt->Core.pvUser, pStorage);
+}
+
+DECLINLINE(int) vdIfIoIntFileDelete(PVDINTERFACEIOINT pIfIoInt, const char *pszFilename)
+{
+ return pIfIoInt->pfnDelete(pIfIoInt->Core.pvUser, pszFilename);
+}
+
+DECLINLINE(int) vdIfIoIntFileMove(PVDINTERFACEIOINT pIfIoInt, const char *pszSrc,
+ const char *pszDst, unsigned fMove)
+{
+ return pIfIoInt->pfnMove(pIfIoInt->Core.pvUser, pszSrc, pszDst, fMove);
+}
+
+DECLINLINE(int) vdIfIoIntFileGetFreeSpace(PVDINTERFACEIOINT pIfIoInt, const char *pszFilename,
+ int64_t *pcbFree)
+{
+ return pIfIoInt->pfnGetFreeSpace(pIfIoInt->Core.pvUser, pszFilename, pcbFree);
+}
+
+DECLINLINE(int) vdIfIoIntFileGetModificationTime(PVDINTERFACEIOINT pIfIoInt, const char *pcszFilename,
+ PRTTIMESPEC pModificationTime)
+{
+ return pIfIoInt->pfnGetModificationTime(pIfIoInt->Core.pvUser, pcszFilename,
+ pModificationTime);
+}
+
+DECLINLINE(int) vdIfIoIntFileGetSize(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t *pcbSize)
+{
+ return pIfIoInt->pfnGetSize(pIfIoInt->Core.pvUser, pStorage, pcbSize);
+}
+
+DECLINLINE(int) vdIfIoIntFileSetSize(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t cbSize)
+{
+ return pIfIoInt->pfnSetSize(pIfIoInt->Core.pvUser, pStorage, cbSize);
+}
+
+DECLINLINE(int) vdIfIoIntFileWriteSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, const void *pvBuffer, size_t cbBuffer,
+ size_t *pcbWritten)
+{
+ return pIfIoInt->pfnWriteSync(pIfIoInt->Core.pvUser, pStorage, uOffset,
+ pvBuffer, cbBuffer, pcbWritten);
+}
+
+DECLINLINE(int) vdIfIoIntFileReadSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, void *pvBuffer, size_t cbBuffer,
+ size_t *pcbRead)
+{
+ return pIfIoInt->pfnReadSync(pIfIoInt->Core.pvUser, pStorage, uOffset,
+ pvBuffer, cbBuffer, pcbRead);
+}
+
+DECLINLINE(int) vdIfIoIntFileFlushSync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage)
+{
+ return pIfIoInt->pfnFlushSync(pIfIoInt->Core.pvUser, pStorage);
+}
+
+DECLINLINE(int) vdIfIoIntFileReadUserAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbRead)
+{
+ return pIfIoInt->pfnReadUserAsync(pIfIoInt->Core.pvUser, pStorage,
+ uOffset, pIoCtx, cbRead);
+}
+
+DECLINLINE(int) vdIfIoIntFileWriteUserAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, PVDIOCTX pIoCtx, size_t cbWrite,
+ PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser)
+{
+ return pIfIoInt->pfnWriteUserAsync(pIfIoInt->Core.pvUser, pStorage,
+ uOffset, pIoCtx, cbWrite, pfnComplete,
+ pvCompleteUser);
+}
+
+DECLINLINE(int) vdIfIoIntFileReadMetaAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, void *pvBuffer,
+ size_t cbBuffer, PVDIOCTX pIoCtx,
+ PPVDMETAXFER ppMetaXfer,
+ PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser)
+{
+ return pIfIoInt->pfnReadMetaAsync(pIfIoInt->Core.pvUser, pStorage,
+ uOffset, pvBuffer, cbBuffer, pIoCtx,
+ ppMetaXfer, pfnComplete, pvCompleteUser);
+}
+
+DECLINLINE(int) vdIfIoIntFileWriteMetaAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ uint64_t uOffset, void *pvBuffer,
+ size_t cbBuffer, PVDIOCTX pIoCtx,
+ PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser)
+{
+ return pIfIoInt->pfnWriteMetaAsync(pIfIoInt->Core.pvUser, pStorage,
+ uOffset, pvBuffer, cbBuffer, pIoCtx,
+ pfnComplete, pvCompleteUser);
+}
+
+DECLINLINE(void) vdIfIoIntMetaXferRelease(PVDINTERFACEIOINT pIfIoInt, PVDMETAXFER pMetaXfer)
+{
+ pIfIoInt->pfnMetaXferRelease(pIfIoInt->Core.pvUser, pMetaXfer);
+}
+
+DECLINLINE(int) vdIfIoIntFileFlushAsync(PVDINTERFACEIOINT pIfIoInt, PVDIOSTORAGE pStorage,
+ PVDIOCTX pIoCtx, PFNVDXFERCOMPLETED pfnComplete,
+ void *pvCompleteUser)
+{
+ return pIfIoInt->pfnFlushAsync(pIfIoInt->Core.pvUser, pStorage, pIoCtx, pfnComplete,
+ pvCompleteUser);
+}
+
+DECLINLINE(size_t) vdIfIoIntIoCtxSet(PVDINTERFACEIOINT pIfIoInt, PVDIOCTX pIoCtx,
+ int ch, size_t cbSet)
+{
+ return pIfIoInt->pfnIoCtxSet(pIfIoInt->Core.pvUser, pIoCtx, ch, cbSet);
+}
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/VBox/vd-ifs.h b/include/VBox/vd-ifs.h
new file mode 100644
index 00000000..d3167a41
--- /dev/null
+++ b/include/VBox/vd-ifs.h
@@ -0,0 +1,1291 @@
+/** @file
+ * VD Container API - interfaces.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VD_Interfaces_h
+#define ___VBox_VD_Interfaces_h
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/mem.h>
+#include <iprt/file.h>
+#include <iprt/net.h>
+#include <iprt/sg.h>
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/err.h>
+
+RT_C_DECLS_BEGIN
+
+/** Interface header magic. */
+#define VDINTERFACE_MAGIC UINT32_C(0x19701015)
+
+/**
+ * Supported interface types.
+ */
+typedef enum VDINTERFACETYPE
+{
+ /** First valid interface. */
+ VDINTERFACETYPE_FIRST = 0,
+ /** Interface to pass error message to upper layers. Per-disk. */
+ VDINTERFACETYPE_ERROR = VDINTERFACETYPE_FIRST,
+ /** Interface for I/O operations. Per-image. */
+ VDINTERFACETYPE_IO,
+ /** Interface for progress notification. Per-operation. */
+ VDINTERFACETYPE_PROGRESS,
+ /** Interface for configuration information. Per-image. */
+ VDINTERFACETYPE_CONFIG,
+ /** Interface for TCP network stack. Per-image. */
+ VDINTERFACETYPE_TCPNET,
+ /** Interface for getting parent image state. Per-operation. */
+ VDINTERFACETYPE_PARENTSTATE,
+ /** Interface for synchronizing accesses from several threads. Per-disk. */
+ VDINTERFACETYPE_THREADSYNC,
+ /** Interface for I/O between the generic VBoxHDD code and the backend. Per-image (internal).
+ * This interface is completely internal and must not be used elsewhere. */
+ VDINTERFACETYPE_IOINT,
+ /** Interface to query the use of block ranges on the disk. Per-operation. */
+ VDINTERFACETYPE_QUERYRANGEUSE,
+ /** invalid interface. */
+ VDINTERFACETYPE_INVALID
+} VDINTERFACETYPE;
+
+/**
+ * Common structure for all interfaces and at the beginning of all types.
+ */
+typedef struct VDINTERFACE
+{
+ uint32_t u32Magic;
+ /** Human readable interface name. */
+ const char *pszInterfaceName;
+ /** Pointer to the next common interface structure. */
+ struct VDINTERFACE *pNext;
+ /** Interface type. */
+ VDINTERFACETYPE enmInterface;
+ /** Size of the interface. */
+ size_t cbSize;
+ /** Opaque user data which is passed on every call. */
+ void *pvUser;
+} VDINTERFACE;
+/** Pointer to a VDINTERFACE. */
+typedef VDINTERFACE *PVDINTERFACE;
+/** Pointer to a const VDINTERFACE. */
+typedef const VDINTERFACE *PCVDINTERFACE;
+
+/**
+ * Helper functions to handle interface lists.
+ *
+ * @note These interface lists are used consistently to pass per-disk,
+ * per-image and/or per-operation callbacks. Those three purposes are strictly
+ * separate. See the individual interface declarations for what context they
+ * apply to. The caller is responsible for ensuring that the lifetime of the
+ * interface descriptors is appropriate for the category of interface.
+ */
+
+/**
+ * Get a specific interface from a list of interfaces specified by the type.
+ *
+ * @return Pointer to the matching interface or NULL if none was found.
+ * @param pVDIfs Pointer to the VD interface list.
+ * @param enmInterface Interface to search for.
+ */
+DECLINLINE(PVDINTERFACE) VDInterfaceGet(PVDINTERFACE pVDIfs, VDINTERFACETYPE enmInterface)
+{
+ AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
+ && enmInterface < VDINTERFACETYPE_INVALID,
+ ("enmInterface=%u", enmInterface), NULL);
+
+ while (pVDIfs)
+ {
+ AssertMsgBreak(pVDIfs->u32Magic == VDINTERFACE_MAGIC,
+ ("u32Magic=%#x\n", pVDIfs->u32Magic));
+
+ if (pVDIfs->enmInterface == enmInterface)
+ return pVDIfs;
+ pVDIfs = pVDIfs->pNext;
+ }
+
+ /* No matching interface was found. */
+ return NULL;
+}
+
+/**
+ * Add an interface to a list of interfaces.
+ *
+ * @return VBox status code.
+ * @param pInterface Pointer to an unitialized common interface structure.
+ * @param pszName Name of the interface.
+ * @param enmInterface Type of the interface.
+ * @param pvUser Opaque user data passed on every function call.
+ * @param ppVDIfs Pointer to the VD interface list.
+ */
+DECLINLINE(int) VDInterfaceAdd(PVDINTERFACE pInterface, const char *pszName,
+ VDINTERFACETYPE enmInterface, void *pvUser,
+ size_t cbInterface, PVDINTERFACE *ppVDIfs)
+{
+ /* Argument checks. */
+ AssertMsgReturn( enmInterface >= VDINTERFACETYPE_FIRST
+ && enmInterface < VDINTERFACETYPE_INVALID,
+ ("enmInterface=%u", enmInterface), VERR_INVALID_PARAMETER);
+
+ AssertMsgReturn(VALID_PTR(ppVDIfs),
+ ("pInterfaceList=%#p", ppVDIfs),
+ VERR_INVALID_PARAMETER);
+
+ /* Fill out interface descriptor. */
+ pInterface->u32Magic = VDINTERFACE_MAGIC;
+ pInterface->cbSize = cbInterface;
+ pInterface->pszInterfaceName = pszName;
+ pInterface->enmInterface = enmInterface;
+ pInterface->pvUser = pvUser;
+ pInterface->pNext = *ppVDIfs;
+
+ /* Remember the new start of the list. */
+ *ppVDIfs = pInterface;
+
+ return VINF_SUCCESS;
+}
+
+/**
+ * Removes an interface from a list of interfaces.
+ *
+ * @return VBox status code
+ * @param pInterface Pointer to an initialized common interface structure to remove.
+ * @param ppVDIfs Pointer to the VD interface list to remove from.
+ */
+DECLINLINE(int) VDInterfaceRemove(PVDINTERFACE pInterface, PVDINTERFACE *ppVDIfs)
+{
+ int rc = VERR_NOT_FOUND;
+
+ /* Argument checks. */
+ AssertMsgReturn(VALID_PTR(pInterface),
+ ("pInterface=%#p", pInterface),
+ VERR_INVALID_PARAMETER);
+
+ AssertMsgReturn(VALID_PTR(ppVDIfs),
+ ("pInterfaceList=%#p", ppVDIfs),
+ VERR_INVALID_PARAMETER);
+
+ if (*ppVDIfs)
+ {
+ PVDINTERFACE pPrev = NULL;
+ PVDINTERFACE pCurr = *ppVDIfs;
+
+ while ( pCurr
+ && (pCurr != pInterface))
+ {
+ pPrev = pCurr;
+ pCurr = pCurr->pNext;
+ }
+
+ /* First interface */
+ if (!pPrev)
+ {
+ *ppVDIfs = pCurr->pNext;
+ rc = VINF_SUCCESS;
+ }
+ else if (pCurr)
+ {
+ pPrev = pCurr->pNext;
+ rc = VINF_SUCCESS;
+ }
+ }
+
+ return rc;
+}
+
+/**
+ * Interface to deliver error messages (and also informational messages)
+ * to upper layers.
+ *
+ * Per-disk interface. Optional, but think twice if you want to miss the
+ * opportunity of reporting better human-readable error messages.
+ */
+typedef struct VDINTERFACEERROR
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Error message callback. Must be able to accept special IPRT format
+ * strings.
+ *
+ * @param pvUser The opaque data passed on container creation.
+ * @param rc The VBox error code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnError, (void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Informational message callback. May be NULL. Used e.g. in
+ * VDDumpImages(). Must be able to accept special IPRT format strings.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pszFormat Message format string.
+ * @param va Message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMessage, (void *pvUser, const char *pszFormat, va_list va));
+
+} VDINTERFACEERROR, *PVDINTERFACEERROR;
+
+/**
+ * Get error interface from interface list.
+ *
+ * @return Pointer to the first error interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACEERROR) VDIfErrorGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_ERROR);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_ERROR)
+ && (pIf->cbSize == sizeof(VDINTERFACEERROR))),
+ ("Not an error interface\n"), NULL);
+
+ return (PVDINTERFACEERROR)pIf;
+}
+
+/**
+ * Signal an error to the frontend.
+ *
+ * @returns VBox status code.
+ * @param pIfError The error interface.
+ * @param rc The status code.
+ * @param RT_SRC_POS_DECL The position in the source code.
+ * @param pszFormat The format string to pass.
+ * @param ... Arguments to the format string.
+ */
+DECLINLINE(int) vdIfError(PVDINTERFACEERROR pIfError, int rc, RT_SRC_POS_DECL,
+ const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ if (pIfError)
+ pIfError->pfnError(pIfError->Core.pvUser, rc, RT_SRC_POS_ARGS, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * Signal an informational message to the frontend.
+ *
+ * @returns VBox status code.
+ * @param pIfError The error interface.
+ * @param pszFormat The format string to pass.
+ * @param ... Arguments to the format string.
+ */
+DECLINLINE(int) vdIfErrorMessage(PVDINTERFACEERROR pIfError, const char *pszFormat, ...)
+{
+ int rc = VINF_SUCCESS;
+ va_list va;
+ va_start(va, pszFormat);
+ if (pIfError)
+ rc = pIfError->pfnMessage(pIfError->Core.pvUser, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * Completion callback which is called by the interface owner
+ * to inform the backend that a task finished.
+ *
+ * @return VBox status code.
+ * @param pvUser Opaque user data which is passed on request submission.
+ * @param rcReq Status code of the completed request.
+ */
+typedef DECLCALLBACK(int) FNVDCOMPLETED(void *pvUser, int rcReq);
+/** Pointer to FNVDCOMPLETED() */
+typedef FNVDCOMPLETED *PFNVDCOMPLETED;
+
+/**
+ * Support interface for I/O
+ *
+ * Per-image. Optional as input.
+ */
+typedef struct VDINTERFACEIO
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Open callback
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pszLocation Name of the location to open.
+ * @param fOpen Flags for opening the backend.
+ * See RTFILE_O_* #defines, inventing another set
+ * of open flags is not worth the mapping effort.
+ * @param pfnCompleted The callback which is called whenever a task
+ * completed. The backend has to pass the user data
+ * of the request initiator (ie the one who calls
+ * VDAsyncRead or VDAsyncWrite) in pvCompletion
+ * if this is NULL.
+ * @param ppStorage Where to store the opaque storage handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnOpen, (void *pvUser, const char *pszLocation,
+ uint32_t fOpen,
+ PFNVDCOMPLETED pfnCompleted,
+ void **ppStorage));
+
+ /**
+ * Close callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The opaque storage handle to close.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnClose, (void *pvUser, void *pStorage));
+
+ /**
+ * Delete callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszFilename Name of the file to delete.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDelete, (void *pvUser, const char *pcszFilename));
+
+ /**
+ * Move callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszSrc The path to the source file.
+ * @param pcszDst The path to the destination file.
+ * This file will be created.
+ * @param fMove A combination of the RTFILEMOVE_* flags.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
+
+ /**
+ * Returns the free space on a disk.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszFilename Name of a file to identify the disk.
+ * @param pcbFreeSpace Where to store the free space of the disk.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
+
+ /**
+ * Returns the last modification timestamp of a file.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pcszFilename Name of a file to identify the disk.
+ * @param pModificationTime Where to store the timestamp of the file.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
+
+ /**
+ * Returns the size of the opened storage backend.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The opaque storage handle to close.
+ * @param pcbSize Where to store the size of the storage backend.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetSize, (void *pvUser, void *pStorage, uint64_t *pcbSize));
+
+ /**
+ * Sets the size of the opened storage backend if possible.
+ *
+ * @return VBox status code.
+ * @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The opaque storage handle to close.
+ * @param cbSize The new size of the image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetSize, (void *pvUser, void *pStorage, uint64_t cbSize));
+
+ /**
+ * Synchronous write callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to use.
+ * @param uOffset The offset to start from.
+ * @param pvBuffer Pointer to the bits need to be written.
+ * @param cbBuffer How many bytes to write.
+ * @param pcbWritten Where to store how many bytes were actually written.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteSync, (void *pvUser, void *pStorage, uint64_t uOffset,
+ const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
+
+ /**
+ * Synchronous read callback.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to use.
+ * @param uOffset The offset to start from.
+ * @param pvBuffer Where to store the read bits.
+ * @param cbBuffer How many bytes to read.
+ * @param pcbRead Where to store how many bytes were actually read.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadSync, (void *pvUser, void *pStorage, uint64_t uOffset,
+ void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
+
+ /**
+ * Flush data to the storage backend.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to flush.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlushSync, (void *pvUser, void *pStorage));
+
+ /**
+ * Initiate an asynchronous read request.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque user data passed on container creation.
+ * @param pStorage The storage handle.
+ * @param uOffset The offset to start reading from.
+ * @param paSegments Scatter gather list to store the data in.
+ * @param cSegments Number of segments in the list.
+ * @param cbRead How many bytes to read.
+ * @param pvCompletion The opaque user data which is returned upon completion.
+ * @param ppTask Where to store the opaque task handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
+ PCRTSGSEG paSegments, size_t cSegments,
+ size_t cbRead, void *pvCompletion,
+ void **ppTask));
+
+ /**
+ * Initiate an asynchronous write request.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque user data passed on conatiner creation.
+ * @param pStorage The storage handle.
+ * @param uOffset The offset to start writing to.
+ * @param paSegments Scatter gather list of the data to write
+ * @param cSegments Number of segments in the list.
+ * @param cbWrite How many bytes to write.
+ * @param pvCompletion The opaque user data which is returned upon completion.
+ * @param ppTask Where to store the opaque task handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteAsync, (void *pvUser, void *pStorage, uint64_t uOffset,
+ PCRTSGSEG paSegments, size_t cSegments,
+ size_t cbWrite, void *pvCompletion,
+ void **ppTask));
+
+ /**
+ * Initiates an async flush request.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque data passed on container creation.
+ * @param pStorage The storage handle to flush.
+ * @param pvCompletion The opaque user data which is returned upon completion.
+ * @param ppTask Where to store the opaque task handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlushAsync, (void *pvUser, void *pStorage,
+ void *pvCompletion, void **ppTask));
+
+} VDINTERFACEIO, *PVDINTERFACEIO;
+
+/**
+ * Get I/O interface from interface list.
+ *
+ * @return Pointer to the first I/O interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACEIO) VDIfIoGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_IO);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_IO)
+ && (pIf->cbSize == sizeof(VDINTERFACEIO))),
+ ("Not a I/O interface"), NULL);
+
+ return (PVDINTERFACEIO)pIf;
+}
+
+DECLINLINE(int) vdIfIoFileOpen(PVDINTERFACEIO pIfIo, const char *pszFilename,
+ uint32_t fOpen, PFNVDCOMPLETED pfnCompleted,
+ void **ppStorage)
+{
+ return pIfIo->pfnOpen(pIfIo->Core.pvUser, pszFilename, fOpen, pfnCompleted, ppStorage);
+}
+
+DECLINLINE(int) vdIfIoFileClose(PVDINTERFACEIO pIfIo, void *pStorage)
+{
+ return pIfIo->pfnClose(pIfIo->Core.pvUser, pStorage);
+}
+
+DECLINLINE(int) vdIfIoFileDelete(PVDINTERFACEIO pIfIo, const char *pszFilename)
+{
+ return pIfIo->pfnDelete(pIfIo->Core.pvUser, pszFilename);
+}
+
+DECLINLINE(int) vdIfIoFileMove(PVDINTERFACEIO pIfIo, const char *pszSrc,
+ const char *pszDst, unsigned fMove)
+{
+ return pIfIo->pfnMove(pIfIo->Core.pvUser, pszSrc, pszDst, fMove);
+}
+
+DECLINLINE(int) vdIfIoFileGetFreeSpace(PVDINTERFACEIO pIfIo, const char *pszFilename,
+ int64_t *pcbFree)
+{
+ return pIfIo->pfnGetFreeSpace(pIfIo->Core.pvUser, pszFilename, pcbFree);
+}
+
+DECLINLINE(int) vdIfIoFileGetModificationTime(PVDINTERFACEIO pIfIo, const char *pcszFilename,
+ PRTTIMESPEC pModificationTime)
+{
+ return pIfIo->pfnGetModificationTime(pIfIo->Core.pvUser, pcszFilename,
+ pModificationTime);
+}
+
+DECLINLINE(int) vdIfIoFileGetSize(PVDINTERFACEIO pIfIo, void *pStorage,
+ uint64_t *pcbSize)
+{
+ return pIfIo->pfnGetSize(pIfIo->Core.pvUser, pStorage, pcbSize);
+}
+
+DECLINLINE(int) vdIfIoFileSetSize(PVDINTERFACEIO pIfIo, void *pStorage,
+ uint64_t cbSize)
+{
+ return pIfIo->pfnSetSize(pIfIo->Core.pvUser, pStorage, cbSize);
+}
+
+DECLINLINE(int) vdIfIoFileWriteSync(PVDINTERFACEIO pIfIo, void *pStorage,
+ uint64_t uOffset, const void *pvBuffer, size_t cbBuffer,
+ size_t *pcbWritten)
+{
+ return pIfIo->pfnWriteSync(pIfIo->Core.pvUser, pStorage, uOffset,
+ pvBuffer, cbBuffer, pcbWritten);
+}
+
+DECLINLINE(int) vdIfIoFileReadSync(PVDINTERFACEIO pIfIo, void *pStorage,
+ uint64_t uOffset, void *pvBuffer, size_t cbBuffer,
+ size_t *pcbRead)
+{
+ return pIfIo->pfnReadSync(pIfIo->Core.pvUser, pStorage, uOffset,
+ pvBuffer, cbBuffer, pcbRead);
+}
+
+DECLINLINE(int) vdIfIoFileFlushSync(PVDINTERFACEIO pIfIo, void *pStorage)
+{
+ return pIfIo->pfnFlushSync(pIfIo->Core.pvUser, pStorage);
+}
+
+/**
+ * Callback which provides progress information about a currently running
+ * lengthy operation.
+ *
+ * @return VBox status code.
+ * @param pvUser The opaque user data associated with this interface.
+ * @param uPercent Completion percentage.
+ */
+typedef DECLCALLBACK(int) FNVDPROGRESS(void *pvUser, unsigned uPercentage);
+/** Pointer to FNVDPROGRESS() */
+typedef FNVDPROGRESS *PFNVDPROGRESS;
+
+/**
+ * Progress notification interface
+ *
+ * Per-operation. Optional.
+ */
+typedef struct VDINTERFACEPROGRESS
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Progress notification callbacks.
+ */
+ PFNVDPROGRESS pfnProgress;
+
+} VDINTERFACEPROGRESS, *PVDINTERFACEPROGRESS;
+
+/**
+ * Get progress interface from interface list.
+ *
+ * @return Pointer to the first progress interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACEPROGRESS) VDIfProgressGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_PROGRESS);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_PROGRESS)
+ && (pIf->cbSize == sizeof(VDINTERFACEPROGRESS))),
+ ("Not a progress interface"), NULL);
+
+ return (PVDINTERFACEPROGRESS)pIf;
+}
+
+
+/**
+ * Configuration information interface
+ *
+ * Per-image. Optional for most backends, but mandatory for images which do
+ * not operate on files (including standard block or character devices).
+ */
+typedef struct VDINTERFACECONFIG
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Validates that the keys are within a set of valid names.
+ *
+ * @return true if all key names are found in pszzAllowed.
+ * @return false if not.
+ * @param pvUser The opaque user data associated with this interface.
+ * @param pszzValid List of valid key names separated by '\\0' and ending with
+ * a double '\\0'.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAreKeysValid, (void *pvUser, const char *pszzValid));
+
+ /**
+ * Retrieves the length of the string value associated with a key (including
+ * the terminator, for compatibility with CFGMR3QuerySize).
+ *
+ * @return VBox status code.
+ * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
+ * @param pvUser The opaque user data associated with this interface.
+ * @param pszName Name of the key to query.
+ * @param pcbValue Where to store the value length. Non-NULL.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQuerySize, (void *pvUser, const char *pszName, size_t *pcbValue));
+
+ /**
+ * Query the string value associated with a key.
+ *
+ * @return VBox status code.
+ * VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
+ * VERR_CFGM_NOT_ENOUGH_SPACE means that the buffer is not big enough.
+ * @param pvUser The opaque user data associated with this interface.
+ * @param pszName Name of the key to query.
+ * @param pszValue Pointer to buffer where to store value.
+ * @param cchValue Length of value buffer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQuery, (void *pvUser, const char *pszName, char *pszValue, size_t cchValue));
+
+} VDINTERFACECONFIG, *PVDINTERFACECONFIG;
+
+/**
+ * Get configuration information interface from interface list.
+ *
+ * @return Pointer to the first configuration information interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACECONFIG) VDIfConfigGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_CONFIG);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_CONFIG)
+ && (pIf->cbSize == sizeof(VDINTERFACECONFIG))),
+ ("Not a config interface"), NULL);
+
+ return (PVDINTERFACECONFIG)pIf;
+}
+
+/**
+ * Query configuration, validates that the keys are within a set of valid names.
+ *
+ * @return true if all key names are found in pszzAllowed.
+ * @return false if not.
+ * @param pCfgIf Pointer to configuration callback table.
+ * @param pszzValid List of valid names separated by '\\0' and ending with
+ * a double '\\0'.
+ */
+DECLINLINE(bool) VDCFGAreKeysValid(PVDINTERFACECONFIG pCfgIf, const char *pszzValid)
+{
+ return pCfgIf->pfnAreKeysValid(pCfgIf->Core.pvUser, pszzValid);
+}
+
+/**
+ * Query configuration, unsigned 64-bit integer value with default.
+ *
+ * @return VBox status code.
+ * @param pCfgIf Pointer to configuration callback table.
+ * @param pszName Name of an integer value
+ * @param pu64 Where to store the value. Set to default on failure.
+ * @param u64Def The default value.
+ */
+DECLINLINE(int) VDCFGQueryU64Def(PVDINTERFACECONFIG pCfgIf,
+ const char *pszName, uint64_t *pu64,
+ uint64_t u64Def)
+{
+ char aszBuf[32];
+ int rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, aszBuf, sizeof(aszBuf));
+ if (RT_SUCCESS(rc))
+ {
+ rc = RTStrToUInt64Full(aszBuf, 0, pu64);
+ }
+ else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
+ {
+ rc = VINF_SUCCESS;
+ *pu64 = u64Def;
+ }
+ return rc;
+}
+
+/**
+ * Query configuration, unsigned 32-bit integer value with default.
+ *
+ * @return VBox status code.
+ * @param pCfgIf Pointer to configuration callback table.
+ * @param pszName Name of an integer value
+ * @param pu32 Where to store the value. Set to default on failure.
+ * @param u32Def The default value.
+ */
+DECLINLINE(int) VDCFGQueryU32Def(PVDINTERFACECONFIG pCfgIf,
+ const char *pszName, uint32_t *pu32,
+ uint32_t u32Def)
+{
+ uint64_t u64;
+ int rc = VDCFGQueryU64Def(pCfgIf, pszName, &u64, u32Def);
+ if (RT_SUCCESS(rc))
+ {
+ if (!(u64 & UINT64_C(0xffffffff00000000)))
+ *pu32 = (uint32_t)u64;
+ else
+ rc = VERR_CFGM_INTEGER_TOO_BIG;
+ }
+ return rc;
+}
+
+/**
+ * Query configuration, bool value with default.
+ *
+ * @return VBox status code.
+ * @param pCfgIf Pointer to configuration callback table.
+ * @param pszName Name of an integer value
+ * @param pf Where to store the value. Set to default on failure.
+ * @param fDef The default value.
+ */
+DECLINLINE(int) VDCFGQueryBoolDef(PVDINTERFACECONFIG pCfgIf,
+ const char *pszName, bool *pf,
+ bool fDef)
+{
+ uint64_t u64;
+ int rc = VDCFGQueryU64Def(pCfgIf, pszName, &u64, fDef);
+ if (RT_SUCCESS(rc))
+ *pf = u64 ? true : false;
+ return rc;
+}
+
+/**
+ * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
+ * character value.
+ *
+ * @return VBox status code.
+ * @param pCfgIf Pointer to configuration callback table.
+ * @param pszName Name of an zero terminated character value
+ * @param ppszString Where to store the string pointer. Not set on failure.
+ * Free this using RTMemFree().
+ */
+DECLINLINE(int) VDCFGQueryStringAlloc(PVDINTERFACECONFIG pCfgIf,
+ const char *pszName, char **ppszString)
+{
+ size_t cb;
+ int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
+ if (RT_SUCCESS(rc))
+ {
+ char *pszString = (char *)RTMemAlloc(cb);
+ if (pszString)
+ {
+ rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pszString, cb);
+ if (RT_SUCCESS(rc))
+ *ppszString = pszString;
+ else
+ RTMemFree(pszString);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ return rc;
+}
+
+/**
+ * Query configuration, dynamically allocated (RTMemAlloc) zero terminated
+ * character value with default.
+ *
+ * @return VBox status code.
+ * @param pCfgIf Pointer to configuration callback table.
+ * @param pszName Name of an zero terminated character value
+ * @param ppszString Where to store the string pointer. Not set on failure.
+ * Free this using RTMemFree().
+ * @param pszDef The default value.
+ */
+DECLINLINE(int) VDCFGQueryStringAllocDef(PVDINTERFACECONFIG pCfgIf,
+ const char *pszName,
+ char **ppszString,
+ const char *pszDef)
+{
+ size_t cb;
+ int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
+ if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
+ {
+ cb = strlen(pszDef) + 1;
+ rc = VINF_SUCCESS;
+ }
+ if (RT_SUCCESS(rc))
+ {
+ char *pszString = (char *)RTMemAlloc(cb);
+ if (pszString)
+ {
+ rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pszString, cb);
+ if (rc == VERR_CFGM_VALUE_NOT_FOUND || rc == VERR_CFGM_NO_PARENT)
+ {
+ memcpy(pszString, pszDef, cb);
+ rc = VINF_SUCCESS;
+ }
+ if (RT_SUCCESS(rc))
+ *ppszString = pszString;
+ else
+ RTMemFree(pszString);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ return rc;
+}
+
+/**
+ * Query configuration, dynamically allocated (RTMemAlloc) byte string value.
+ *
+ * @return VBox status code.
+ * @param pCfgIf Pointer to configuration callback table.
+ * @param pszName Name of an zero terminated character value
+ * @param ppvData Where to store the byte string pointer. Not set on failure.
+ * Free this using RTMemFree().
+ * @param pcbData Where to store the byte string length.
+ */
+DECLINLINE(int) VDCFGQueryBytesAlloc(PVDINTERFACECONFIG pCfgIf,
+ const char *pszName, void **ppvData, size_t *pcbData)
+{
+ size_t cb;
+ int rc = pCfgIf->pfnQuerySize(pCfgIf->Core.pvUser, pszName, &cb);
+ if (RT_SUCCESS(rc))
+ {
+ char *pbData;
+ Assert(cb);
+
+ pbData = (char *)RTMemAlloc(cb);
+ if (pbData)
+ {
+ rc = pCfgIf->pfnQuery(pCfgIf->Core.pvUser, pszName, pbData, cb);
+ if (RT_SUCCESS(rc))
+ {
+ *ppvData = pbData;
+ *pcbData = cb - 1; /* Exclude terminator of the queried string. */
+ }
+ else
+ RTMemFree(pbData);
+ }
+ else
+ rc = VERR_NO_MEMORY;
+ }
+ return rc;
+}
+
+/** Forward declaration of a VD socket. */
+typedef struct VDSOCKETINT *VDSOCKET;
+/** Pointer to a VD socket. */
+typedef VDSOCKET *PVDSOCKET;
+/** Nil socket handle. */
+#define NIL_VDSOCKET ((VDSOCKET)0)
+
+/** Connect flag to indicate that the backend wants to use the extended
+ * socket I/O multiplexing call. This might not be supported on all configurations
+ * (internal networking and iSCSI)
+ * and the backend needs to take appropriate action.
+ */
+#define VD_INTERFACETCPNET_CONNECT_EXTENDED_SELECT RT_BIT_32(0)
+
+/** @name Select events
+ * @{ */
+/** Readable without blocking. */
+#define VD_INTERFACETCPNET_EVT_READ RT_BIT_32(0)
+/** Writable without blocking. */
+#define VD_INTERFACETCPNET_EVT_WRITE RT_BIT_32(1)
+/** Error condition, hangup, exception or similar. */
+#define VD_INTERFACETCPNET_EVT_ERROR RT_BIT_32(2)
+/** Hint for the select that getting interrupted while waiting is more likely.
+ * The interface implementation can optimize the waiting strategy based on this.
+ * It is assumed that it is more likely to get one of the above socket events
+ * instead of being interrupted if the flag is not set. */
+#define VD_INTERFACETCPNET_HINT_INTERRUPT RT_BIT_32(3)
+/** Mask of the valid bits. */
+#define VD_INTERFACETCPNET_EVT_VALID_MASK UINT32_C(0x0000000f)
+/** @} */
+
+/**
+ * TCP network stack interface
+ *
+ * Per-image. Mandatory for backends which have the VD_CAP_TCPNET bit set.
+ */
+typedef struct VDINTERFACETCPNET
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Creates a socket. The socket is not connected if this succeeds.
+ *
+ * @return iprt status code.
+ * @retval VERR_NOT_SUPPORTED if the combination of flags is not supported.
+ * @param fFlags Combination of the VD_INTERFACETCPNET_CONNECT_* #defines.
+ * @param pSock Where to store the handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSocketCreate, (uint32_t fFlags, PVDSOCKET pSock));
+
+ /**
+ * Destroys the socket.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSocketDestroy, (VDSOCKET Sock));
+
+ /**
+ * Connect as a client to a TCP port.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pszAddress The address to connect to.
+ * @param uPort The port to connect to.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET Sock, const char *pszAddress, uint32_t uPort));
+
+ /**
+ * Close a TCP connection.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnClientClose, (VDSOCKET Sock));
+
+ /**
+ * Returns whether the socket is currently connected to the client.
+ *
+ * @returns true if the socket is connected.
+ * false otherwise.
+ * @param Sock Socket descriptor.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnIsClientConnected, (VDSOCKET Sock));
+
+ /**
+ * Socket I/O multiplexing.
+ * Checks if the socket is ready for reading.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param cMillies Number of milliseconds to wait for the socket.
+ * Use RT_INDEFINITE_WAIT to wait for ever.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSelectOne, (VDSOCKET Sock, RTMSINTERVAL cMillies));
+
+ /**
+ * Receive data from a socket.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pvBuffer Where to put the data we read.
+ * @param cbBuffer Read buffer size.
+ * @param pcbRead Number of bytes read.
+ * If NULL the entire buffer will be filled upon successful return.
+ * If not NULL a partial read can be done successfully.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
+
+ /**
+ * Send data to a socket.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pvBuffer Buffer to write data to socket.
+ * @param cbBuffer How much to write.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer));
+
+ /**
+ * Send data from scatter/gather buffer to a socket.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pSgBuffer Scatter/gather buffer to write data to socket.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSgWrite, (VDSOCKET Sock, PCRTSGBUF pSgBuffer));
+
+ /**
+ * Receive data from a socket - not blocking.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pvBuffer Where to put the data we read.
+ * @param cbBuffer Read buffer size.
+ * @param pcbRead Number of bytes read.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadNB, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
+
+ /**
+ * Send data to a socket - not blocking.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pvBuffer Buffer to write data to socket.
+ * @param cbBuffer How much to write.
+ * @param pcbWritten Number of bytes written.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteNB, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
+
+ /**
+ * Send data from scatter/gather buffer to a socket - not blocking.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pSgBuffer Scatter/gather buffer to write data to socket.
+ * @param pcbWritten Number of bytes written.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSgWriteNB, (VDSOCKET Sock, PRTSGBUF pSgBuffer, size_t *pcbWritten));
+
+ /**
+ * Flush socket write buffers.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlush, (VDSOCKET Sock));
+
+ /**
+ * Enables or disables delaying sends to coalesce packets.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param fEnable When set to true enables coalescing.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetSendCoalescing, (VDSOCKET Sock, bool fEnable));
+
+ /**
+ * Gets the address of the local side.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pAddr Where to store the local address on success.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetLocalAddress, (VDSOCKET Sock, PRTNETADDR pAddr));
+
+ /**
+ * Gets the address of the other party.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ * @param pAddr Where to store the peer address on success.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetPeerAddress, (VDSOCKET Sock, PRTNETADDR pAddr));
+
+ /**
+ * Socket I/O multiplexing - extended version which can be woken up.
+ * Checks if the socket is ready for reading or writing.
+ *
+ * @return iprt status code.
+ * @retval VERR_INTERRUPTED if the thread was woken up by a pfnPoke call.
+ * @param Sock Socket descriptor.
+ * @param fEvents Mask of events to wait for.
+ * @param pfEvents Where to store the received events.
+ * @param cMillies Number of milliseconds to wait for the socket.
+ * Use RT_INDEFINITE_WAIT to wait for ever.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSelectOneEx, (VDSOCKET Sock, uint32_t fEvents,
+ uint32_t *pfEvents, RTMSINTERVAL cMillies));
+
+ /**
+ * Wakes up the thread waiting in pfnSelectOneEx.
+ *
+ * @return iprt status code.
+ * @param Sock Socket descriptor.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPoke, (VDSOCKET Sock));
+
+} VDINTERFACETCPNET, *PVDINTERFACETCPNET;
+
+/**
+ * Get TCP network stack interface from interface list.
+ *
+ * @return Pointer to the first TCP network stack interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACETCPNET) VDIfTcpNetGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_TCPNET);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_TCPNET)
+ && (pIf->cbSize == sizeof(VDINTERFACETCPNET))),
+ ("Not a TCP net interface"), NULL);
+
+ return (PVDINTERFACETCPNET)pIf;
+}
+
+
+/**
+ * Interface to synchronize concurrent accesses by several threads.
+ *
+ * @note The scope of this interface is to manage concurrent accesses after
+ * the HDD container has been created, and they must stop before destroying the
+ * container. Opening or closing images is covered by the synchronization, but
+ * that does not mean it is safe to close images while a thread executes
+ * <link to="VDMerge"/> or <link to="VDCopy"/> operating on these images.
+ * Making them safe would require the lock to be held during the entire
+ * operation, which prevents other concurrent acitivities.
+ *
+ * @note Right now this is kept as simple as possible, and does not even
+ * attempt to provide enough information to allow e.g. concurrent write
+ * accesses to different areas of the disk. The reason is that it is very
+ * difficult to predict which area of a disk is affected by a write,
+ * especially when different image formats are mixed. Maybe later a more
+ * sophisticated interface will be provided which has the necessary information
+ * about worst case affected areas.
+ *
+ * Per-disk interface. Optional, needed if the disk is accessed concurrently
+ * by several threads, e.g. when merging diff images while a VM is running.
+ */
+typedef struct VDINTERFACETHREADSYNC
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Start a read operation.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartRead, (void *pvUser));
+
+ /**
+ * Finish a read operation.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFinishRead, (void *pvUser));
+
+ /**
+ * Start a write operation.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartWrite, (void *pvUser));
+
+ /**
+ * Finish a write operation.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFinishWrite, (void *pvUser));
+
+} VDINTERFACETHREADSYNC, *PVDINTERFACETHREADSYNC;
+
+/**
+ * Get thread synchronization interface from interface list.
+ *
+ * @return Pointer to the first thread synchronization interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACETHREADSYNC) VDIfThreadSyncGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_THREADSYNC);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_THREADSYNC)
+ && (pIf->cbSize == sizeof(VDINTERFACETHREADSYNC))),
+ ("Not a thread synchronization interface"), NULL);
+
+ return (PVDINTERFACETHREADSYNC)pIf;
+}
+
+/**
+ * Interface to query usage of disk ranges.
+ *
+ * Per-operation interface. Optional.
+ */
+typedef struct VDINTERFACEQUERYRANGEUSE
+{
+ /**
+ * Common interface header.
+ */
+ VDINTERFACE Core;
+
+ /**
+ * Query use of a disk range.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryRangeUse, (void *pvUser, uint64_t off, uint64_t cb,
+ bool *pfUsed));
+
+} VDINTERFACEQUERYRANGEUSE, *PVDINTERFACEQUERYRANGEUSE;
+
+/**
+ * Get query range use interface from interface list.
+ *
+ * @return Pointer to the first thread synchronization interface in the list.
+ * @param pVDIfs Pointer to the interface list.
+ */
+DECLINLINE(PVDINTERFACEQUERYRANGEUSE) VDIfQueryRangeUseGet(PVDINTERFACE pVDIfs)
+{
+ PVDINTERFACE pIf = VDInterfaceGet(pVDIfs, VDINTERFACETYPE_QUERYRANGEUSE);
+
+ /* Check that the interface descriptor is a progress interface. */
+ AssertMsgReturn( !pIf
+ || ( (pIf->enmInterface == VDINTERFACETYPE_QUERYRANGEUSE)
+ && (pIf->cbSize == sizeof(VDINTERFACEQUERYRANGEUSE))),
+ ("Not a query range use interface"), NULL);
+
+ return (PVDINTERFACEQUERYRANGEUSE)pIf;
+}
+
+DECLINLINE(int) vdIfQueryRangeUse(PVDINTERFACEQUERYRANGEUSE pIfQueryRangeUse, uint64_t off, uint64_t cb,
+ bool *pfUsed)
+{
+ return pIfQueryRangeUse->pfnQueryRangeUse(pIfQueryRangeUse->Core.pvUser, off, cb, pfUsed);
+}
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/VBox/vd-plugin.h b/include/VBox/vd-plugin.h
new file mode 100644
index 00000000..46f1d9a9
--- /dev/null
+++ b/include/VBox/vd-plugin.h
@@ -0,0 +1,679 @@
+/** @file
+ * Internal hard disk format support API for VBoxHDD.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 __VBoxHDD_Plugin_h__
+#define __VBoxHDD_Plugin_h__
+
+#include <VBox/vd.h>
+#include <VBox/vd-ifs-internal.h>
+
+
+/** @name VBox HDD backend write flags
+ * @{
+ */
+/** Do not allocate a new block on this write. This is just an advisory
+ * flag. The backend may still decide in some circumstances that it wants
+ * to ignore this flag (which may cause extra dynamic image expansion). */
+#define VD_WRITE_NO_ALLOC RT_BIT(1)
+/** @}*/
+
+/** @name VBox HDD backend discard flags
+ * @{
+ */
+/** Don't discard block but mark the given range as unused
+ * (usually by writing 0's to it).
+ * This doesn't require the range to be aligned on a block boundary but
+ * the image size might not be decreased. */
+#define VD_DISCARD_MARK_UNUSED RT_BIT(0)
+/** @}*/
+
+
+/**
+ * Image format backend interface used by VBox HDD Container implementation.
+ */
+typedef struct VBOXHDDBACKEND
+{
+ /**
+ * The name of the backend (constant string).
+ */
+ const char *pszBackendName;
+
+ /**
+ * The size of the structure.
+ */
+ uint32_t cbSize;
+
+ /**
+ * The capabilities of the backend.
+ */
+ uint64_t uBackendCaps;
+
+ /**
+ * Pointer to a NULL-terminated array, containing the supported
+ * file extensions. Note that some backends do not work on files, so this
+ * pointer may just contain NULL.
+ */
+ PCVDFILEEXTENSION paFileExtensions;
+
+ /**
+ * Pointer to an array of structs describing each supported config key.
+ * Terminated by a NULL config key. Note that some backends do not support
+ * the configuration interface, so this pointer may just contain NULL.
+ * Mandatory if the backend sets VD_CAP_CONFIG.
+ */
+ PCVDCONFIGINFO paConfigInfo;
+
+ /**
+ * Handle of loaded plugin library, NIL_RTLDRMOD for static backends.
+ */
+ RTLDRMOD hPlugin;
+
+ /**
+ * Check if a file is valid for the backend.
+ *
+ * @returns VBox status code.
+ * @param pszFilename Name of the image file.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param penmType Returns the supported device type on success.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCheckIfValid, (const char *pszFilename, PVDINTERFACE pVDIfsDisk,
+ PVDINTERFACE pVDIfsImage, VDTYPE *penmType));
+
+ /**
+ * Open a disk image.
+ *
+ * @returns VBox status code.
+ * @param pszFilename Name of the image file to open. Guaranteed to be available and
+ * unchanged during the lifetime of this image.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param enmType Requested type of the image.
+ * @param ppBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnOpen, (const char *pszFilename, unsigned uOpenFlags,
+ PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
+ VDTYPE enmType, void **ppBackendData));
+
+ /**
+ * Create a disk image.
+ *
+ * @returns VBox status code.
+ * @param pszFilename Name of the image file to create. Guaranteed to be available and
+ * unchanged during the lifetime of this image.
+ * @param cbSize Image size in bytes.
+ * @param uImageFlags Flags specifying special image features.
+ * @param pszComment Pointer to image comment. NULL is ok.
+ * @param pPCHSGeometry Physical drive geometry CHS <= (16383,16,255).
+ * @param pLCHSGeometry Logical drive geometry CHS <= (1024,255,63).
+ * @param pUuid New UUID of the image. Not NULL.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param uPercentStart Starting value for progress percentage.
+ * @param uPercentSpan Span for varying progress percentage.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ * @param ppBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCreate, (const char *pszFilename, uint64_t cbSize,
+ unsigned uImageFlags, const char *pszComment,
+ PCVDGEOMETRY pPCHSGeometry,
+ PCVDGEOMETRY pLCHSGeometry,
+ PCRTUUID pUuid, unsigned uOpenFlags,
+ unsigned uPercentStart, unsigned uPercentSpan,
+ PVDINTERFACE pVDIfsDisk,
+ PVDINTERFACE pVDIfsImage,
+ PVDINTERFACE pVDIfsOperation,
+ void **ppBackendData));
+
+ /**
+ * Rename a disk image. Only needs to work as long as the operating
+ * system's rename file functionality is usable. If an attempt is made to
+ * rename an image to a location on another disk/filesystem, this function
+ * may just fail with an appropriate error code (not changing the opened
+ * image data at all). Also works only on images which actually refer to
+ * regular files. May be NULL.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pszFilename New name of the image file. Guaranteed to be available and
+ * unchanged during the lifetime of this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRename, (void *pBackendData, const char *pszFilename));
+
+ /**
+ * Close a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param fDelete If true, delete the image from the host disk.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnClose, (void *pBackendData, bool fDelete));
+
+ /**
+ * Read data from a disk image. The area read never crosses a block
+ * boundary.
+ *
+ * @returns VBox status code.
+ * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset Offset to start reading from.
+ * @param pvBuf Where to store the read bits.
+ * @param cbRead Number of bytes to read.
+ * @param pcbActuallyRead Pointer to returned number of bytes read.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead, (void *pBackendData, uint64_t uOffset, void *pvBuf,
+ size_t cbRead, size_t *pcbActuallyRead));
+
+ /**
+ * Write data to a disk image. The area written never crosses a block
+ * boundary.
+ *
+ * @returns VBox status code.
+ * @returns VERR_VD_BLOCK_FREE if this image contains no data for this block and
+ * this is not a full-block write. The write must be repeated with
+ * the correct amount of prefix/postfix data read from the images below
+ * in the image stack. This might not be the most convenient interface,
+ * but it works with arbitrary block sizes, especially when the image
+ * stack uses different block sizes.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset Offset to start writing to.
+ * @param pvBuf Where to retrieve the written bits.
+ * @param cbWrite Number of bytes to write.
+ * @param pcbWriteProcess Pointer to returned number of bytes that could
+ * be processed. In case the function returned
+ * VERR_VD_BLOCK_FREE this is the number of bytes
+ * that could be written in a full block write,
+ * when prefixed/postfixed by the appropriate
+ * amount of (previously read) padding data.
+ * @param pcbPreRead Pointer to the returned amount of data that must
+ * be prefixed to perform a full block write.
+ * @param pcbPostRead Pointer to the returned amount of data that must
+ * be postfixed to perform a full block write.
+ * @param fWrite Flags which affect write behavior. Combination
+ * of the VD_WRITE_* flags.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite, (void *pBackendData, uint64_t uOffset,
+ const void *pvBuf, size_t cbWrite,
+ size_t *pcbWriteProcess, size_t *pcbPreRead,
+ size_t *pcbPostRead, unsigned fWrite));
+
+ /**
+ * Flush data to disk.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlush, (void *pBackendData));
+
+ /**
+ * Get the version of a disk image.
+ *
+ * @returns version of disk image.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(unsigned, pfnGetVersion, (void *pBackendData));
+
+ /**
+ * Get the capacity of a disk image.
+ *
+ * @returns size of disk image in bytes.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize, (void *pBackendData));
+
+ /**
+ * Get the file size of a disk image.
+ *
+ * @returns size of disk image in bytes.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetFileSize, (void *pBackendData));
+
+ /**
+ * Get virtual disk PCHS geometry stored in a disk image.
+ *
+ * @returns VBox status code.
+ * @returns VERR_VD_GEOMETRY_NOT_SET if no geometry present in the image.
+ * @param pBackendData Opaque state data for this image.
+ * @param pPCHSGeometry Where to store the geometry. Not NULL.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetPCHSGeometry, (void *pBackendData, PVDGEOMETRY pPCHSGeometry));
+
+ /**
+ * Set virtual disk PCHS geometry stored in a disk image.
+ * Only called if geometry is different than before.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pPCHSGeometry Where to load the geometry from. Not NULL.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetPCHSGeometry, (void *pBackendData, PCVDGEOMETRY pPCHSGeometry));
+
+ /**
+ * Get virtual disk LCHS geometry stored in a disk image.
+ *
+ * @returns VBox status code.
+ * @returns VERR_VD_GEOMETRY_NOT_SET if no geometry present in the image.
+ * @param pBackendData Opaque state data for this image.
+ * @param pLCHSGeometry Where to store the geometry. Not NULL.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetLCHSGeometry, (void *pBackendData, PVDGEOMETRY pLCHSGeometry));
+
+ /**
+ * Set virtual disk LCHS geometry stored in a disk image.
+ * Only called if geometry is different than before.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pLCHSGeometry Where to load the geometry from. Not NULL.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetLCHSGeometry, (void *pBackendData, PCVDGEOMETRY pLCHSGeometry));
+
+ /**
+ * Get the image flags of a disk image.
+ *
+ * @returns image flags of disk image.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(unsigned, pfnGetImageFlags, (void *pBackendData));
+
+ /**
+ * Get the open flags of a disk image.
+ *
+ * @returns open flags of disk image.
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(unsigned, pfnGetOpenFlags, (void *pBackendData));
+
+ /**
+ * Set the open flags of a disk image. May cause the image to be locked
+ * in a different mode or be reopened (which can fail).
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOpenFlags New open flags for this image.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetOpenFlags, (void *pBackendData, unsigned uOpenFlags));
+
+ /**
+ * Get comment of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pszComment Where to store the comment.
+ * @param cbComment Size of the comment buffer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetComment, (void *pBackendData, char *pszComment, size_t cbComment));
+
+ /**
+ * Set comment of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pszComment Where to get the comment from. NULL resets comment.
+ * The comment is silently truncated if the image format
+ * limit is exceeded.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetComment, (void *pBackendData, const char *pszComment));
+
+ /**
+ * Get UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to store the image UUID.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetUuid, (void *pBackendData, PRTUUID pUuid));
+
+ /**
+ * Set UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to get the image UUID from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetUuid, (void *pBackendData, PCRTUUID pUuid));
+
+ /**
+ * Get last modification UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to store the image modification UUID.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetModificationUuid, (void *pBackendData, PRTUUID pUuid));
+
+ /**
+ * Set last modification UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to get the image modification UUID from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetModificationUuid, (void *pBackendData, PCRTUUID pUuid));
+
+ /**
+ * Get parent UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to store the parent image UUID.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetParentUuid, (void *pBackendData, PRTUUID pUuid));
+
+ /**
+ * Set parent UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to get the parent image UUID from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetParentUuid, (void *pBackendData, PCRTUUID pUuid));
+
+ /**
+ * Get parent modification UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to store the parent image modification UUID.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetParentModificationUuid, (void *pBackendData, PRTUUID pUuid));
+
+ /**
+ * Set parent modification UUID of a disk image.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pUuid Where to get the parent image modification UUID from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetParentModificationUuid, (void *pBackendData, PCRTUUID pUuid));
+
+ /**
+ * Dump information about a disk image.
+ *
+ * @param pBackendData Opaque state data for this image.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnDump, (void *pBackendData));
+
+ /**
+ * Get a time stamp of a disk image. May be NULL.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pTimeStamp Where to store the time stamp.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetTimeStamp, (void *pBackendData, PRTTIMESPEC pTimeStamp));
+
+ /**
+ * Get the parent time stamp of a disk image. May be NULL.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pTimeStamp Where to store the time stamp.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetParentTimeStamp, (void *pBackendData, PRTTIMESPEC pTimeStamp));
+
+ /**
+ * Set the parent time stamp of a disk image. May be NULL.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pTimeStamp Where to get the time stamp from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetParentTimeStamp, (void *pBackendData, PCRTTIMESPEC pTimeStamp));
+
+ /**
+ * Get the relative path to parent image. May be NULL.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pszParentFilename Where to store the path.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetParentFilename, (void *pBackendData, char **ppszParentFilename));
+
+ /**
+ * Set the relative path to parent image. May be NULL.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pszParentFilename Where to get the path from.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetParentFilename, (void *pBackendData, const char *pszParentFilename));
+
+ /**
+ * Start an asynchronous read request.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset The offset of the virtual disk to read from.
+ * @param cbRead How many bytes to read.
+ * @param pIoCtx I/O context associated with this request.
+ * @param pcbActuallyRead Pointer to returned number of bytes read.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncRead, (void *pBackendData, uint64_t uOffset, size_t cbRead,
+ PVDIOCTX pIoCtx, size_t *pcbActuallyRead));
+
+ /**
+ * Start an asynchronous write request.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset The offset of the virtual disk to write to.
+ * @param cbWrite How many bytes to write.
+ * @param pIoCtx I/O context associated with this request.
+ * @param pcbWriteProcess Pointer to returned number of bytes that could
+ * be processed. In case the function returned
+ * VERR_VD_BLOCK_FREE this is the number of bytes
+ * that could be written in a full block write,
+ * when prefixed/postfixed by the appropriate
+ * amount of (previously read) padding data.
+ * @param pcbPreRead Pointer to the returned amount of data that must
+ * be prefixed to perform a full block write.
+ * @param pcbPostRead Pointer to the returned amount of data that must
+ * be postfixed to perform a full block write.
+ * @param fWrite Flags which affect write behavior. Combination
+ * of the VD_WRITE_* flags.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncWrite, (void *pBackendData, uint64_t uOffset, size_t cbWrite,
+ PVDIOCTX pIoCtx,
+ size_t *pcbWriteProcess, size_t *pcbPreRead,
+ size_t *pcbPostRead, unsigned fWrite));
+
+ /**
+ * Flush data to disk.
+ *
+ * @returns VBox status code.
+ * @param pBackendData Opaque state data for this image.
+ * @param pIoCtx I/O context associated with this request.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncFlush, (void *pBackendData, PVDIOCTX pIoCtx));
+
+ /** Returns a human readable hard disk location string given a
+ * set of hard disk configuration keys. The returned string is an
+ * equivalent of the full file path for image-based hard disks.
+ * Mandatory for backends with no VD_CAP_FILE and NULL otherwise. */
+ DECLR3CALLBACKMEMBER(int, pfnComposeLocation, (PVDINTERFACE pConfig, char **pszLocation));
+
+ /** Returns a human readable hard disk name string given a
+ * set of hard disk configuration keys. The returned string is an
+ * equivalent of the file name part in the full file path for
+ * image-based hard disks. Mandatory for backends with no
+ * VD_CAP_FILE and NULL otherwise. */
+ DECLR3CALLBACKMEMBER(int, pfnComposeName, (PVDINTERFACE pConfig, char **pszName));
+
+ /**
+ * Compact the image. The pointer may be NULL, indicating that this
+ * isn't supported yet (for file-based images) or not necessary.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_SUPPORTED if this image cannot be compacted yet.
+ * @param pBackendData Opaque state data for this image.
+ * @param uPercentStart Starting value for progress percentage.
+ * @param uPercentSpan Span for varying progress percentage.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCompact, (void *pBackendData,
+ unsigned uPercentStart, unsigned uPercentSpan,
+ PVDINTERFACE pVDIfsDisk,
+ PVDINTERFACE pVDIfsImage,
+ PVDINTERFACE pVDIfsOperation));
+
+ /**
+ * Resize the image. The pointer may be NULL, indicating that this
+ * isn't supported yet (for file-based images) or not necessary.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_SUPPORTED if this image cannot be resized yet.
+ * @param pBackendData Opaque state data for this image.
+ * @param cbSize New size of the image.
+ * @param pPCHSGeometry Pointer to the new physical disk geometry <= (16383,16,63). Not NULL.
+ * @param pLCHSGeometry Pointer to the new logical disk geometry <= (x,255,63). Not NULL.
+ * @param uPercentStart Starting value for progress percentage.
+ * @param uPercentSpan Span for varying progress percentage.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnResize, (void *pBackendData,
+ uint64_t cbSize,
+ PCVDGEOMETRY pPCHSGeometry,
+ PCVDGEOMETRY pLCHSGeometry,
+ unsigned uPercentStart, unsigned uPercentSpan,
+ PVDINTERFACE pVDIfsDisk,
+ PVDINTERFACE pVDIfsImage,
+ PVDINTERFACE pVDIfsOperation));
+
+ /**
+ * Discards the given amount of bytes decreasing the size of the image if possible.
+ *
+ * @returns VBox status code.
+ * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment
+ * for the discard.
+ * @param pBackendData Opaque state data for this image.
+ * @param uOffset The offset of the first byte to discard.
+ * @param cbDiscard How many bytes to discard.
+ * @param pcbPreAllocated Pointer to the returned amount of bytes that must
+ * be discarded before the range to perform a full
+ * block discard.
+ * @param pcbPostAllocated Pointer to the returned amount of bytes that must
+ * be discarded after the range to perform a full
+ * block discard.
+ * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which
+ * could be actually discarded.
+ * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap
+ * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL
+ * if the allocation bitmap should be returned.
+ * @param fDiscard Flags which affect discard behavior. Combination
+ * of the VD_DISCARD_* flags.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDiscard, (void *pBackendData,
+ uint64_t uOffset, size_t cbDiscard,
+ size_t *pcbPreAllocated,
+ size_t *pcbPostAllocated,
+ size_t *pcbActuallyDiscarded,
+ void **ppbmAllocationBitmap,
+ unsigned fDiscard));
+
+ /**
+ * Discards the given amount of bytes decreasing the size of the image if possible
+ * callback version for asynchronous I/O.
+ *
+ * @returns VBox status code.
+ * @retval VERR_VD_DISCARD_ALIGNMENT_NOT_MET if the range doesn't meet the required alignment
+ * for the discard.
+ * @param pBackendData Opaque state data for this image.
+ * @param pIoCtx I/O context associated with this request.
+ * @param uOffset The offset of the first byte to discard.
+ * @param cbDiscard How many bytes to discard.
+ * @param pcbPreAllocated Pointer to the returned amount of bytes that must
+ * be discarded before the range to perform a full
+ * block discard.
+ * @param pcbPostAllocated Pointer to the returned amount of bytes that must
+ * be discarded after the range to perform a full
+ * block discard.
+ * @param pcbActuallyDiscarded Pointer to the returned amount of bytes which
+ * could be actually discarded.
+ * @param ppbmAllocationBitmap Where to store the pointer to the allocation bitmap
+ * if VERR_VD_DISCARD_ALIGNMENT_NOT_MET is returned or NULL
+ * if the allocation bitmap should be returned.
+ * @param fDiscard Flags which affect discard behavior. Combination
+ * of the VD_DISCARD_* flags.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncDiscard, (void *pBackendData, PVDIOCTX pIoCtx,
+ uint64_t uOffset, size_t cbDiscard,
+ size_t *pcbPreAllocated,
+ size_t *pcbPostAllocated,
+ size_t *pcbActuallyDiscarded,
+ void **ppbmAllocationBitmap,
+ unsigned fDiscard));
+
+ /**
+ * Try to repair the given image.
+ *
+ * @returns VBox status code.
+ * @param pszFilename Name of the image file.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param fFlags Combination of the VD_REPAIR_* flags.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRepair, (const char *pszFilename, PVDINTERFACE pVDIfsDisk,
+ PVDINTERFACE pVDIfsImage, uint32_t fFlags));
+
+} VBOXHDDBACKEND;
+
+/** Pointer to VD backend. */
+typedef VBOXHDDBACKEND *PVBOXHDDBACKEND;
+
+/** Constant pointer to VD backend. */
+typedef const VBOXHDDBACKEND *PCVBOXHDDBACKEND;
+
+/** @copydoc VBOXHDDBACKEND::pfnComposeLocation */
+DECLINLINE(int) genericFileComposeLocation(PVDINTERFACE pConfig, char **pszLocation)
+{
+ *pszLocation = NULL;
+ return VINF_SUCCESS;
+}
+/** @copydoc VBOXHDDBACKEND::pfnComposeName */
+DECLINLINE(int) genericFileComposeName(PVDINTERFACE pConfig, char **pszName)
+{
+ *pszName = NULL;
+ return VINF_SUCCESS;
+}
+
+/** Initialization entry point. */
+typedef DECLCALLBACK(int) VBOXHDDFORMATLOAD(PVBOXHDDBACKEND *ppBackendTable);
+typedef VBOXHDDFORMATLOAD *PFNVBOXHDDFORMATLOAD;
+#define VBOX_HDDFORMAT_LOAD_NAME "VBoxHDDFormatLoad"
+
+/** The prefix to identify Storage Plugins. */
+#define VBOX_HDDFORMAT_PLUGIN_PREFIX "VBoxHDD"
+/** The size of the prefix excluding the '\\0' terminator. */
+#define VBOX_HDDFORMAT_PLUGIN_PREFIX_LENGTH (sizeof(VBOX_HDDFORMAT_PLUGIN_PREFIX)-1)
+
+#endif
diff --git a/include/VBox/vd.h b/include/VBox/vd.h
new file mode 100644
index 00000000..86589bbf
--- /dev/null
+++ b/include/VBox/vd.h
@@ -0,0 +1,1251 @@
+/** @file
+ * VBox HDD Container API.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VD_h
+#define ___VBox_VD_h
+
+#include <iprt/assert.h>
+#include <iprt/string.h>
+#include <iprt/mem.h>
+#include <iprt/file.h>
+#include <iprt/net.h>
+#include <iprt/sg.h>
+#include <iprt/vfs.h>
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <VBox/vd-ifs.h>
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING0
+# error "There are no VBox HDD Container APIs available in Ring-0 Host Context!"
+#endif
+
+/** @defgroup grp_vd VBox HDD Container
+ * @{
+ */
+
+/** Current VMDK image version. */
+#define VMDK_IMAGE_VERSION (0x0001)
+
+/** Current VDI image major version. */
+#define VDI_IMAGE_VERSION_MAJOR (0x0001)
+/** Current VDI image minor version. */
+#define VDI_IMAGE_VERSION_MINOR (0x0001)
+/** Current VDI image version. */
+#define VDI_IMAGE_VERSION ((VDI_IMAGE_VERSION_MAJOR << 16) | VDI_IMAGE_VERSION_MINOR)
+
+/** Get VDI major version from combined version. */
+#define VDI_GET_VERSION_MAJOR(uVer) ((uVer) >> 16)
+/** Get VDI minor version from combined version. */
+#define VDI_GET_VERSION_MINOR(uVer) ((uVer) & 0xffff)
+
+/** Placeholder for specifying the last opened image. */
+#define VD_LAST_IMAGE 0xffffffffU
+
+/** Placeholder for VDCopyEx to indicate that the image content is unknown. */
+#define VD_IMAGE_CONTENT_UNKNOWN 0xffffffffU
+
+/** @name VBox HDD container image flags
+ * @{
+ */
+/** No flags. */
+#define VD_IMAGE_FLAGS_NONE (0)
+/** Fixed image. */
+#define VD_IMAGE_FLAGS_FIXED (0x10000)
+/** Diff image. Mutually exclusive with fixed image. */
+#define VD_IMAGE_FLAGS_DIFF (0x20000)
+/** VMDK: Split image into 2GB extents. */
+#define VD_VMDK_IMAGE_FLAGS_SPLIT_2G (0x0001)
+/** VMDK: Raw disk image (giving access to a number of host partitions). */
+#define VD_VMDK_IMAGE_FLAGS_RAWDISK (0x0002)
+/** VMDK: stream optimized image, read only. */
+#define VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED (0x0004)
+/** VMDK: ESX variant, use in addition to other flags. */
+#define VD_VMDK_IMAGE_FLAGS_ESX (0x0008)
+/** VDI: Fill new blocks with zeroes while expanding image file. Only valid
+ * for newly created images, never set for opened existing images. */
+#define VD_VDI_IMAGE_FLAGS_ZERO_EXPAND (0x0100)
+
+/** Mask of valid image flags for VMDK. */
+#define VD_VMDK_IMAGE_FLAGS_MASK ( VD_IMAGE_FLAGS_FIXED | VD_IMAGE_FLAGS_DIFF | VD_IMAGE_FLAGS_NONE \
+ | VD_VMDK_IMAGE_FLAGS_SPLIT_2G | VD_VMDK_IMAGE_FLAGS_RAWDISK \
+ | VD_VMDK_IMAGE_FLAGS_STREAM_OPTIMIZED | VD_VMDK_IMAGE_FLAGS_ESX)
+
+/** Mask of valid image flags for VDI. */
+#define VD_VDI_IMAGE_FLAGS_MASK (VD_IMAGE_FLAGS_FIXED | VD_IMAGE_FLAGS_DIFF | VD_IMAGE_FLAGS_NONE | VD_VDI_IMAGE_FLAGS_ZERO_EXPAND)
+
+/** Mask of all valid image flags for all formats. */
+#define VD_IMAGE_FLAGS_MASK (VD_VMDK_IMAGE_FLAGS_MASK | VD_VDI_IMAGE_FLAGS_MASK)
+
+/** Default image flags. */
+#define VD_IMAGE_FLAGS_DEFAULT (VD_IMAGE_FLAGS_NONE)
+/** @} */
+
+/** @name VD image repair flags
+ * @{
+ */
+/** Don't repair the image but check what needs to be done. */
+#define VD_REPAIR_DRY_RUN RT_BIT_32(0)
+
+/** Mask of all valid repair flags. */
+#define VD_REPAIR_FLAGS_MASK (VD_REPAIR_DRY_RUN)
+/** @} */
+
+/** @name VD image VFS file flags
+ * @{
+ */
+/** Destroy the VD disk container when the VFS file is released. */
+#define VD_VFSFILE_DESTROY_ON_RELEASE RT_BIT_32(0)
+
+/** Mask of all valid repair flags. */
+#define VD_VFSFILE_FLAGS_MASK (VD_VFSFILE_DESTROY_ON_RELEASE)
+/** @} */
+
+/**
+ * Auxiliary type for describing partitions on raw disks. The entries must be
+ * in ascending order (as far as uStart is concerned), and must not overlap.
+ * Note that this does not correspond 1:1 to partitions, it is describing the
+ * general meaning of contiguous areas on the disk.
+ */
+typedef struct VBOXHDDRAWPARTDESC
+{
+ /** Device to use for this partition/data area. Can be the disk device if
+ * the offset field is set appropriately. If this is NULL, then this
+ * partition will not be accessible to the guest. The size of the data area
+ * must still be set correctly. */
+ const char *pszRawDevice;
+ /** Pointer to the partitioning info. NULL means this is a regular data
+ * area on disk, non-NULL denotes data which should be copied to the
+ * partition data overlay. */
+ const void *pvPartitionData;
+ /** Offset where the data starts in this device. */
+ uint64_t uStartOffset;
+ /** Offset where the data starts in the disk. */
+ uint64_t uStart;
+ /** Size of the data area. */
+ uint64_t cbData;
+} VBOXHDDRAWPARTDESC, *PVBOXHDDRAWPARTDESC;
+
+/**
+ * Auxiliary data structure for difference between GPT and MBR
+ * disks.
+ */
+enum PARTITIONING_TYPE
+{
+ MBR,
+ GPT
+};
+
+/**
+ * Auxiliary data structure for creating raw disks.
+ */
+typedef struct VBOXHDDRAW
+{
+ /** Signature for structure. Must be 'R', 'A', 'W', '\\0'. Actually a trick
+ * to make logging of the comment string produce sensible results. */
+ char szSignature[4];
+ /** Flag whether access to full disk should be given (ignoring the
+ * partition information below). */
+ bool fRawDisk;
+ /** Filename for the raw disk. Ignored for partitioned raw disks.
+ * For Linux e.g. /dev/sda, and for Windows e.g. \\\\.\\PhysicalDisk0. */
+ const char *pszRawDisk;
+ /** Number of entries in the partition descriptor array. */
+ unsigned cPartDescs;
+ /** Pointer to the partition descriptor array. */
+ PVBOXHDDRAWPARTDESC pPartDescs;
+ /**partitioning type of the disk */
+ PARTITIONING_TYPE uPartitioningType;
+
+} VBOXHDDRAW, *PVBOXHDDRAW;
+
+
+/** @name VBox HDD container image open mode flags
+ * @{
+ */
+/** Try to open image in read/write exclusive access mode if possible, or in read-only elsewhere. */
+#define VD_OPEN_FLAGS_NORMAL 0
+/** Open image in read-only mode with sharing access with others. */
+#define VD_OPEN_FLAGS_READONLY RT_BIT(0)
+/** Honor zero block writes instead of ignoring them whenever possible.
+ * This is not supported by all formats. It is silently ignored in this case. */
+#define VD_OPEN_FLAGS_HONOR_ZEROES RT_BIT(1)
+/** Honor writes of the same data instead of ignoring whenever possible.
+ * This is handled generically, and is only meaningful for differential image
+ * formats. It is silently ignored otherwise. */
+#define VD_OPEN_FLAGS_HONOR_SAME RT_BIT(2)
+/** Do not perform the base/diff image check on open. This does NOT imply
+ * opening the image as readonly (would break e.g. adding UUIDs to VMDK files
+ * created by other products). Images opened with this flag should only be
+ * used for querying information, and nothing else. */
+#define VD_OPEN_FLAGS_INFO RT_BIT(3)
+/** Open image for asynchronous access. Only available if VD_CAP_ASYNC_IO is
+ * set. VDOpen fails with VERR_NOT_SUPPORTED if this operation is not supported for
+ * this kind of image. */
+#define VD_OPEN_FLAGS_ASYNC_IO RT_BIT(4)
+/** Allow sharing of the image for writable images. May be ignored if the
+ * format backend doesn't support this type of concurrent access. */
+#define VD_OPEN_FLAGS_SHAREABLE RT_BIT(5)
+/** Ask the backend to switch to sequential accesses if possible. Opening
+ * will not fail if it cannot do this, the flag will be simply ignored. */
+#define VD_OPEN_FLAGS_SEQUENTIAL RT_BIT(6)
+/** Allow the discard operation if supported. Only available if VD_CAP_DISCARD
+ * is set. VDOpen fails with VERR_VD_DISCARD_NOT_SUPPORTED if discarding is not
+ * supported. */
+#define VD_OPEN_FLAGS_DISCARD RT_BIT(7)
+/** Ignore all flush requests to workaround certain filesystems which are slow
+ * when writing a lot of cached data to the medium.
+ * Use with extreme care as a host crash can result in completely corrupted and
+ * unusable images.
+ */
+#define VD_OPEN_FLAGS_IGNORE_FLUSH RT_BIT(8)
+/**
+ * Return VINF_VD_NEW_ZEROED_BLOCK for reads from unallocated blocks.
+ * The caller who uses the flag has to make sure that the read doesn't cross
+ * a block boundary. Because the block size can differ between images reading one
+ * sector at a time is the safest solution.
+ */
+#define VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS RT_BIT(9)
+/** Mask of valid flags. */
+#define VD_OPEN_FLAGS_MASK (VD_OPEN_FLAGS_NORMAL | VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_HONOR_ZEROES | VD_OPEN_FLAGS_HONOR_SAME | VD_OPEN_FLAGS_INFO | VD_OPEN_FLAGS_ASYNC_IO | VD_OPEN_FLAGS_SHAREABLE | VD_OPEN_FLAGS_SEQUENTIAL | VD_OPEN_FLAGS_DISCARD | VD_OPEN_FLAGS_IGNORE_FLUSH | VD_OPEN_FLAGS_INFORM_ABOUT_ZERO_BLOCKS)
+/** @}*/
+
+/**
+ * Helper functions to handle open flags.
+ */
+
+/**
+ * Translate VD_OPEN_FLAGS_* to RTFile open flags.
+ *
+ * @return RTFile open flags.
+ * @param uOpenFlags VD_OPEN_FLAGS_* open flags.
+ * @param fCreate Flag that the file should be created.
+ */
+DECLINLINE(uint32_t) VDOpenFlagsToFileOpenFlags(unsigned uOpenFlags, bool fCreate)
+{
+ AssertMsg(!((uOpenFlags & VD_OPEN_FLAGS_READONLY) && fCreate), ("Image can't be opened readonly while being created\n"));
+
+ uint32_t fOpen = 0;
+
+ if (RT_UNLIKELY(uOpenFlags & VD_OPEN_FLAGS_READONLY))
+ fOpen |= RTFILE_O_READ | RTFILE_O_DENY_NONE;
+ else
+ {
+ fOpen |= RTFILE_O_READWRITE;
+
+ if (RT_UNLIKELY(uOpenFlags & VD_OPEN_FLAGS_SHAREABLE))
+ fOpen |= RTFILE_O_DENY_NONE;
+ else
+ fOpen |= RTFILE_O_DENY_WRITE;
+ }
+
+ if (RT_UNLIKELY(fCreate))
+ fOpen |= RTFILE_O_CREATE | RTFILE_O_NOT_CONTENT_INDEXED;
+ else
+ fOpen |= RTFILE_O_OPEN;
+
+ return fOpen;
+}
+
+
+/** @name VBox HDD container backend capability flags
+ * @{
+ */
+/** Supports UUIDs as expected by VirtualBox code. */
+#define VD_CAP_UUID RT_BIT(0)
+/** Supports creating fixed size images, allocating all space instantly. */
+#define VD_CAP_CREATE_FIXED RT_BIT(1)
+/** Supports creating dynamically growing images, allocating space on demand. */
+#define VD_CAP_CREATE_DYNAMIC RT_BIT(2)
+/** Supports creating images split in chunks of a bit less than 2GBytes. */
+#define VD_CAP_CREATE_SPLIT_2G RT_BIT(3)
+/** Supports being used as differencing image format backend. */
+#define VD_CAP_DIFF RT_BIT(4)
+/** Supports asynchronous I/O operations for at least some configurations. */
+#define VD_CAP_ASYNC RT_BIT(5)
+/** The backend operates on files. The caller needs to know to handle the
+ * location appropriately. */
+#define VD_CAP_FILE RT_BIT(6)
+/** The backend uses the config interface. The caller needs to know how to
+ * provide the mandatory configuration parts this way. */
+#define VD_CAP_CONFIG RT_BIT(7)
+/** The backend uses the network stack interface. The caller has to provide
+ * the appropriate interface. */
+#define VD_CAP_TCPNET RT_BIT(8)
+/** The backend supports VFS (virtual filesystem) functionality since it uses
+ * VDINTERFACEIO exclusively for all file operations. */
+#define VD_CAP_VFS RT_BIT(9)
+/** The backend supports the discard operation. */
+#define VD_CAP_DISCARD RT_BIT(10)
+/** @}*/
+
+/** @name VBox HDD container type.
+ * @{
+ */
+typedef enum VDTYPE
+{
+ /** Invalid. */
+ VDTYPE_INVALID = 0,
+ /** HardDisk */
+ VDTYPE_HDD,
+ /** CD/DVD */
+ VDTYPE_DVD,
+ /** Floppy. */
+ VDTYPE_FLOPPY
+} VDTYPE;
+/** @}*/
+
+
+/** @name Configuration interface key handling flags.
+ * @{
+ */
+/** Mandatory config key. Not providing a value for this key will cause
+ * the backend to fail. */
+#define VD_CFGKEY_MANDATORY RT_BIT(0)
+/** Expert config key. Not showing it by default in the GUI is is probably
+ * a good idea, as the average user won't understand it easily. */
+#define VD_CFGKEY_EXPERT RT_BIT(1)
+/** @}*/
+
+
+/**
+ * Configuration value type for configuration information interface.
+ */
+typedef enum VDCFGVALUETYPE
+{
+ /** Integer value. */
+ VDCFGVALUETYPE_INTEGER = 1,
+ /** String value. */
+ VDCFGVALUETYPE_STRING,
+ /** Bytestring value. */
+ VDCFGVALUETYPE_BYTES
+} VDCFGVALUETYPE;
+
+
+/**
+ * Structure describing configuration keys required/supported by a backend
+ * through the config interface.
+ */
+typedef struct VDCONFIGINFO
+{
+ /** Key name of the configuration. */
+ const char *pszKey;
+ /** Pointer to default value (descriptor). NULL if no useful default value
+ * can be specified. */
+ const char *pszDefaultValue;
+ /** Value type for this key. */
+ VDCFGVALUETYPE enmValueType;
+ /** Key handling flags (a combination of VD_CFGKEY_* flags). */
+ uint64_t uKeyFlags;
+} VDCONFIGINFO;
+
+/** Pointer to structure describing configuration keys. */
+typedef VDCONFIGINFO *PVDCONFIGINFO;
+
+/** Pointer to const structure describing configuration keys. */
+typedef const VDCONFIGINFO *PCVDCONFIGINFO;
+
+/**
+ * Structure describing a file extension.
+ */
+typedef struct VDFILEEXTENSION
+{
+ /** Pointer to the NULL-terminated string containing the extension. */
+ const char *pszExtension;
+ /** The device type the extension supports. */
+ VDTYPE enmType;
+} VDFILEEXTENSION;
+
+/** Pointer to a structure describing a file extension. */
+typedef VDFILEEXTENSION *PVDFILEEXTENSION;
+
+/** Pointer to a const structure describing a file extension. */
+typedef const VDFILEEXTENSION *PCVDFILEEXTENSION;
+
+/**
+ * Data structure for returning a list of backend capabilities.
+ */
+typedef struct VDBACKENDINFO
+{
+ /** Name of the backend. Must be unique even with case insensitive comparison. */
+ const char *pszBackend;
+ /** Capabilities of the backend (a combination of the VD_CAP_* flags). */
+ uint64_t uBackendCaps;
+ /** Pointer to a NULL-terminated array of strings, containing the supported
+ * file extensions. Note that some backends do not work on files, so this
+ * pointer may just contain NULL. */
+ PCVDFILEEXTENSION paFileExtensions;
+ /** Pointer to an array of structs describing each supported config key.
+ * Terminated by a NULL config key. Note that some backends do not support
+ * the configuration interface, so this pointer may just contain NULL.
+ * Mandatory if the backend sets VD_CAP_CONFIG. */
+ PCVDCONFIGINFO paConfigInfo;
+ /** Returns a human readable hard disk location string given a
+ * set of hard disk configuration keys. The returned string is an
+ * equivalent of the full file path for image-based hard disks.
+ * Mandatory for backends with no VD_CAP_FILE and NULL otherwise. */
+ DECLR3CALLBACKMEMBER(int, pfnComposeLocation, (PVDINTERFACE pConfig, char **pszLocation));
+ /** Returns a human readable hard disk name string given a
+ * set of hard disk configuration keys. The returned string is an
+ * equivalent of the file name part in the full file path for
+ * image-based hard disks. Mandatory for backends with no
+ * VD_CAP_FILE and NULL otherwise. */
+ DECLR3CALLBACKMEMBER(int, pfnComposeName, (PVDINTERFACE pConfig, char **pszName));
+} VDBACKENDINFO, *PVDBACKENDINFO;
+
+
+/**
+ * Request completion callback for the async read/write API.
+ */
+typedef void (FNVDASYNCTRANSFERCOMPLETE) (void *pvUser1, void *pvUser2, int rcReq);
+/** Pointer to a transfer compelte callback. */
+typedef FNVDASYNCTRANSFERCOMPLETE *PFNVDASYNCTRANSFERCOMPLETE;
+
+/**
+ * Disk geometry.
+ */
+typedef struct VDGEOMETRY
+{
+ /** Number of cylinders. */
+ uint32_t cCylinders;
+ /** Number of heads. */
+ uint32_t cHeads;
+ /** Number of sectors. */
+ uint32_t cSectors;
+} VDGEOMETRY;
+
+/** Pointer to disk geometry. */
+typedef VDGEOMETRY *PVDGEOMETRY;
+/** Pointer to constant disk geometry. */
+typedef const VDGEOMETRY *PCVDGEOMETRY;
+
+/**
+ * VBox HDD Container main structure.
+ */
+/* Forward declaration, VBOXHDD structure is visible only inside VBox HDD module. */
+struct VBOXHDD;
+typedef struct VBOXHDD VBOXHDD;
+typedef VBOXHDD *PVBOXHDD;
+
+/**
+ * Initializes HDD backends.
+ *
+ * @returns VBox status code.
+ */
+VBOXDDU_DECL(int) VDInit(void);
+
+/**
+ * Destroys loaded HDD backends.
+ *
+ * @returns VBox status code.
+ */
+VBOXDDU_DECL(int) VDShutdown(void);
+
+/**
+ * Lists all HDD backends and their capabilities in a caller-provided buffer.
+ *
+ * @return VBox status code.
+ * VERR_BUFFER_OVERFLOW if not enough space is passed.
+ * @param cEntriesAlloc Number of list entries available.
+ * @param pEntries Pointer to array for the entries.
+ * @param pcEntriesUsed Number of entries returned.
+ */
+VBOXDDU_DECL(int) VDBackendInfo(unsigned cEntriesAlloc, PVDBACKENDINFO pEntries,
+ unsigned *pcEntriesUsed);
+
+/**
+ * Lists the capabilities of a backend identified by its name.
+ *
+ * @return VBox status code.
+ * @param pszBackend The backend name (case insensitive).
+ * @param pEntries Pointer to an entry.
+ */
+VBOXDDU_DECL(int) VDBackendInfoOne(const char *pszBackend, PVDBACKENDINFO pEntry);
+
+/**
+ * Allocates and initializes an empty HDD container.
+ * No image files are opened.
+ *
+ * @return VBox status code.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param enmType Type of the image container.
+ * @param ppDisk Where to store the reference to HDD container.
+ */
+VBOXDDU_DECL(int) VDCreate(PVDINTERFACE pVDIfsDisk, VDTYPE enmType, PVBOXHDD *ppDisk);
+
+/**
+ * Destroys HDD container.
+ * If container has opened image files they will be closed.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ */
+VBOXDDU_DECL(int) VDDestroy(PVBOXHDD pDisk);
+
+/**
+ * Try to get the backend name which can use this image.
+ *
+ * @return VBox status code.
+ * VINF_SUCCESS if a plugin was found.
+ * ppszFormat contains the string which can be used as backend name.
+ * VERR_NOT_SUPPORTED if no backend was found.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pszFilename Name of the image file for which the backend is queried.
+ * @param ppszFormat Receives pointer of the UTF-8 string which contains the format name.
+ * The returned pointer must be freed using RTStrFree().
+ * @param penmType Where to store the type of the image.
+ */
+VBOXDDU_DECL(int) VDGetFormat(PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
+ const char *pszFilename, char **ppszFormat, VDTYPE *penmType);
+
+/**
+ * Opens an image file.
+ *
+ * The first opened image file in HDD container must have a base image type,
+ * others (next opened images) must be differencing or undo images.
+ * Linkage is checked for differencing image to be consistent with the previously opened image.
+ * When another differencing image is opened and the last image was opened in read/write access
+ * mode, then the last image is reopened in read-only with deny write sharing mode. This allows
+ * other processes to use images in read-only mode too.
+ *
+ * Note that the image is opened in read-only mode if a read/write open is not possible.
+ * Use VDIsReadOnly to check open mode.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ * @param pszBackend Name of the image file backend to use (case insensitive).
+ * @param pszFilename Name of the image file to open.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ */
+VBOXDDU_DECL(int) VDOpen(PVBOXHDD pDisk, const char *pszBackend,
+ const char *pszFilename, unsigned uOpenFlags,
+ PVDINTERFACE pVDIfsImage);
+
+/**
+ * Opens a cache image.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to the HDD container which should use the cache image.
+ * @param pszBackend Name of the cache file backend to use (case insensitive).
+ * @param pszFilename Name of the cache image to open.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param pVDIfsCache Pointer to the per-cache VD interface list.
+ */
+VBOXDDU_DECL(int) VDCacheOpen(PVBOXHDD pDisk, const char *pszBackend,
+ const char *pszFilename, unsigned uOpenFlags,
+ PVDINTERFACE pVDIfsCache);
+
+/**
+ * Creates and opens a new base image file.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ * @param pszBackend Name of the image file backend to use (case insensitive).
+ * @param pszFilename Name of the image file to create.
+ * @param cbSize Image size in bytes.
+ * @param uImageFlags Flags specifying special image features.
+ * @param pszComment Pointer to image comment. NULL is ok.
+ * @param pPCHSGeometry Pointer to physical disk geometry <= (16383,16,63). Not NULL.
+ * @param pLCHSGeometry Pointer to logical disk geometry <= (x,255,63). Not NULL.
+ * @param pUuid New UUID of the image. If NULL, a new UUID is created.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+VBOXDDU_DECL(int) VDCreateBase(PVBOXHDD pDisk, const char *pszBackend,
+ const char *pszFilename, uint64_t cbSize,
+ unsigned uImageFlags, const char *pszComment,
+ PCVDGEOMETRY pPCHSGeometry,
+ PCVDGEOMETRY pLCHSGeometry,
+ PCRTUUID pUuid, unsigned uOpenFlags,
+ PVDINTERFACE pVDIfsImage,
+ PVDINTERFACE pVDIfsOperation);
+
+/**
+ * Creates and opens a new differencing image file in HDD container.
+ * See comments for VDOpen function about differencing images.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ * @param pszBackend Name of the image file backend to use (case insensitive).
+ * @param pszFilename Name of the differencing image file to create.
+ * @param uImageFlags Flags specifying special image features.
+ * @param pszComment Pointer to image comment. NULL is ok.
+ * @param pUuid New UUID of the image. If NULL, a new UUID is created.
+ * @param pParentUuid New parent UUID of the image. If NULL, the UUID is queried automatically.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+VBOXDDU_DECL(int) VDCreateDiff(PVBOXHDD pDisk, const char *pszBackend,
+ const char *pszFilename, unsigned uImageFlags,
+ const char *pszComment, PCRTUUID pUuid,
+ PCRTUUID pParentUuid, unsigned uOpenFlags,
+ PVDINTERFACE pVDIfsImage,
+ PVDINTERFACE pVDIfsOperation);
+
+/**
+ * Creates and opens new cache image file in HDD container.
+ *
+ * @return VBox status code.
+ * @param pDisk Name of the cache file backend to use (case insensitive).
+ * @param pszFilename Name of the differencing cache file to create.
+ * @param cbSize Maximum size of the cache.
+ * @param uImageFlags Flags specifying special cache features.
+ * @param pszComment Pointer to image comment. NULL is ok.
+ * @param pUuid New UUID of the image. If NULL, a new UUID is created.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * @param pVDIfsCache Pointer to the per-cache VD interface list.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+VBOXDDU_DECL(int) VDCreateCache(PVBOXHDD pDisk, const char *pszBackend,
+ const char *pszFilename, uint64_t cbSize,
+ unsigned uImageFlags, const char *pszComment,
+ PCRTUUID pUuid, unsigned uOpenFlags,
+ PVDINTERFACE pVDIfsCache, PVDINTERFACE pVDIfsOperation);
+
+/**
+ * Merges two images (not necessarily with direct parent/child relationship).
+ * As a side effect the source image and potentially the other images which
+ * are also merged to the destination are deleted from both the disk and the
+ * images in the HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImageFrom Image number to merge from, counts from 0. 0 is always base image of container.
+ * @param nImageTo Image number to merge to, counts from 0. 0 is always base image of container.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+VBOXDDU_DECL(int) VDMerge(PVBOXHDD pDisk, unsigned nImageFrom,
+ unsigned nImageTo, PVDINTERFACE pVDIfsOperation);
+
+/**
+ * Copies an image from one HDD container to another - extended version.
+ * The copy is opened in the target HDD container.
+ * It is possible to convert between different image formats, because the
+ * backend for the destination may be different from the source.
+ * If both the source and destination reference the same HDD container,
+ * then the image is moved (by copying/deleting or renaming) to the new location.
+ * The source container is unchanged if the move operation fails, otherwise
+ * the image at the new location is opened in the same way as the old one was.
+ *
+ * @note The read/write accesses across disks are not synchronized, just the
+ * accesses to each disk. Once there is a use case which requires a defined
+ * read/write behavior in this situation this needs to be extended.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDiskFrom Pointer to source HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pDiskTo Pointer to destination HDD container.
+ * @param pszBackend Name of the image file backend to use (may be NULL to use the same as the source, case insensitive).
+ * @param pszFilename New name of the image (may be NULL to specify that the
+ * copy destination is the destination container, or
+ * if pDiskFrom == pDiskTo, i.e. when moving).
+ * @param fMoveByRename If true, attempt to perform a move by renaming (if successful the new size is ignored).
+ * @param cbSize New image size (0 means leave unchanged).
+ * @param nImageSameFrom The number of the last image in the source chain having the same content as the
+ * image in the destination chain given by nImageSameTo or
+ * VD_IMAGE_CONTENT_UNKNOWN to indicate that the content of both containers is unknown.
+ * See the notes for further information.
+ * @param nImageSameTo The number of the last image in the destination chain having the same content as the
+ * image in the source chain given by nImageSameFrom or
+ * VD_IMAGE_CONTENT_UNKNOWN to indicate that the content of both containers is unknown.
+ * See the notes for further information.
+ * @param uImageFlags Flags specifying special destination image features.
+ * @param pDstUuid New UUID of the destination image. If NULL, a new UUID is created.
+ * This parameter is used if and only if a true copy is created.
+ * In all rename/move cases or copy to existing image cases the modification UUIDs are copied over.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * Only used if the destination image is created.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ * @param pDstVDIfsImage Pointer to the per-image VD interface list, for the
+ * destination image.
+ * @param pDstVDIfsOperation Pointer to the per-operation VD interface list,
+ * for the destination operation.
+ *
+ * @note Using nImageSameFrom and nImageSameTo can lead to a significant speedup
+ * when copying an image but can also lead to a corrupted copy if used incorrectly.
+ * It is mainly useful when cloning a chain of images and it is known that
+ * the virtual disk content of the two chains is exactly the same upto a certain image.
+ * Example:
+ * Imagine the chain of images which consist of a base and one diff image.
+ * Copying the chain starts with the base image. When copying the first
+ * diff image VDCopy() will read the data from the diff of the source chain
+ * and probably from the base image again in case the diff doesn't has data
+ * for the block. However the block will be optimized away because VDCopy()
+ * reads data from the base image of the destination chain compares the to
+ * and suppresses the write because the data is unchanged.
+ * For a lot of diff images this will be a huge waste of I/O bandwidth if
+ * the diff images contain only few changes.
+ * Because it is known that the base image of the source and the destination chain
+ * have the same content it is enough to check the diff image for changed data
+ * and copy it to the destination diff image which is achieved with
+ * nImageSameFrom and nImageSameTo. Setting both to 0 can suppress a lot of I/O.
+ */
+VBOXDDU_DECL(int) VDCopyEx(PVBOXHDD pDiskFrom, unsigned nImage, PVBOXHDD pDiskTo,
+ const char *pszBackend, const char *pszFilename,
+ bool fMoveByRename, uint64_t cbSize,
+ unsigned nImageFromSame, unsigned nImageToSame,
+ unsigned uImageFlags, PCRTUUID pDstUuid,
+ unsigned uOpenFlags, PVDINTERFACE pVDIfsOperation,
+ PVDINTERFACE pDstVDIfsImage,
+ PVDINTERFACE pDstVDIfsOperation);
+
+/**
+ * Copies an image from one HDD container to another.
+ * The copy is opened in the target HDD container.
+ * It is possible to convert between different image formats, because the
+ * backend for the destination may be different from the source.
+ * If both the source and destination reference the same HDD container,
+ * then the image is moved (by copying/deleting or renaming) to the new location.
+ * The source container is unchanged if the move operation fails, otherwise
+ * the image at the new location is opened in the same way as the old one was.
+ *
+ * @note The read/write accesses across disks are not synchronized, just the
+ * accesses to each disk. Once there is a use case which requires a defined
+ * read/write behavior in this situation this needs to be extended.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDiskFrom Pointer to source HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pDiskTo Pointer to destination HDD container.
+ * @param pszBackend Name of the image file backend to use (may be NULL to use the same as the source, case insensitive).
+ * @param pszFilename New name of the image (may be NULL to specify that the
+ * copy destination is the destination container, or
+ * if pDiskFrom == pDiskTo, i.e. when moving).
+ * @param fMoveByRename If true, attempt to perform a move by renaming (if successful the new size is ignored).
+ * @param cbSize New image size (0 means leave unchanged).
+ * @param uImageFlags Flags specifying special destination image features.
+ * @param pDstUuid New UUID of the destination image. If NULL, a new UUID is created.
+ * This parameter is used if and only if a true copy is created.
+ * In all rename/move cases or copy to existing image cases the modification UUIDs are copied over.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ * Only used if the destination image is created.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ * @param pDstVDIfsImage Pointer to the per-image VD interface list, for the
+ * destination image.
+ * @param pDstVDIfsOperation Pointer to the per-operation VD interface list,
+ * for the destination operation.
+ */
+VBOXDDU_DECL(int) VDCopy(PVBOXHDD pDiskFrom, unsigned nImage, PVBOXHDD pDiskTo,
+ const char *pszBackend, const char *pszFilename,
+ bool fMoveByRename, uint64_t cbSize,
+ unsigned uImageFlags, PCRTUUID pDstUuid,
+ unsigned uOpenFlags, PVDINTERFACE pVDIfsOperation,
+ PVDINTERFACE pDstVDIfsImage,
+ PVDINTERFACE pDstVDIfsOperation);
+
+/**
+ * Optimizes the storage consumption of an image. Typically the unused blocks
+ * have to be wiped with zeroes to achieve a substantial reduced storage use.
+ * Another optimization done is reordering the image blocks, which can provide
+ * a significant performance boost, as reads and writes tend to use less random
+ * file offsets.
+ *
+ * @note Compaction is treated as a single operation with regard to thread
+ * synchronization, which means that it potentially blocks other activities for
+ * a long time. The complexity of compaction would grow even more if concurrent
+ * accesses have to be handled.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @return VERR_VD_IMAGE_READ_ONLY if image is not writable.
+ * @return VERR_NOT_SUPPORTED if this kind of image can be compacted, but
+ * this isn't supported yet.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+VBOXDDU_DECL(int) VDCompact(PVBOXHDD pDisk, unsigned nImage,
+ PVDINTERFACE pVDIfsOperation);
+
+/**
+ * Resizes the given disk image to the given size.
+ *
+ * @return VBox status
+ * @return VERR_VD_IMAGE_READ_ONLY if image is not writable.
+ * @return VERR_NOT_SUPPORTED if this kind of image can be compacted, but
+ *
+ * @param pDisk Pointer to the HDD container.
+ * @param cbSize New size of the image.
+ * @param pPCHSGeometry Pointer to the new physical disk geometry <= (16383,16,63). Not NULL.
+ * @param pLCHSGeometry Pointer to the new logical disk geometry <= (x,255,63). Not NULL.
+ * @param pVDIfsOperation Pointer to the per-operation VD interface list.
+ */
+VBOXDDU_DECL(int) VDResize(PVBOXHDD pDisk, uint64_t cbSize,
+ PCVDGEOMETRY pPCHSGeometry,
+ PCVDGEOMETRY pLCHSGeometry,
+ PVDINTERFACE pVDIfsOperation);
+
+/**
+ * Closes the last opened image file in HDD container.
+ * If previous image file was opened in read-only mode (the normal case) and
+ * the last opened image is in read-write mode then the previous image will be
+ * reopened in read/write mode.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
+ * @param pDisk Pointer to HDD container.
+ * @param fDelete If true, delete the image from the host disk.
+ */
+VBOXDDU_DECL(int) VDClose(PVBOXHDD pDisk, bool fDelete);
+
+/**
+ * Closes the currently opened cache image file in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_NOT_OPENED if no cache is opened in HDD container.
+ * @param pDisk Pointer to HDD container.
+ * @param fDelete If true, delete the image from the host disk.
+ */
+VBOXDDU_DECL(int) VDCacheClose(PVBOXHDD pDisk, bool fDelete);
+
+/**
+ * Closes all opened image files in HDD container.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ */
+VBOXDDU_DECL(int) VDCloseAll(PVBOXHDD pDisk);
+
+/**
+ * Read data from virtual HDD.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
+ * @param pDisk Pointer to HDD container.
+ * @param uOffset Offset of first reading byte from start of disk.
+ * Must be aligned to a sector boundary.
+ * @param pvBuffer Pointer to buffer for reading data.
+ * @param cbBuffer Number of bytes to read.
+ * Must be aligned to a sector boundary.
+ */
+VBOXDDU_DECL(int) VDRead(PVBOXHDD pDisk, uint64_t uOffset, void *pvBuffer, size_t cbBuffer);
+
+/**
+ * Write data to virtual HDD.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
+ * @param pDisk Pointer to HDD container.
+ * @param uOffset Offset of first writing byte from start of disk.
+ * Must be aligned to a sector boundary.
+ * @param pvBuffer Pointer to buffer for writing data.
+ * @param cbBuffer Number of bytes to write.
+ * Must be aligned to a sector boundary.
+ */
+VBOXDDU_DECL(int) VDWrite(PVBOXHDD pDisk, uint64_t uOffset, const void *pvBuffer, size_t cbBuffer);
+
+/**
+ * Make sure the on disk representation of a virtual HDD is up to date.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_NOT_OPENED if no image is opened in HDD container.
+ * @param pDisk Pointer to HDD container.
+ */
+VBOXDDU_DECL(int) VDFlush(PVBOXHDD pDisk);
+
+/**
+ * Get number of opened images in HDD container.
+ *
+ * @return Number of opened images for HDD container. 0 if no images have been opened.
+ * @param pDisk Pointer to HDD container.
+ */
+VBOXDDU_DECL(unsigned) VDGetCount(PVBOXHDD pDisk);
+
+/**
+ * Get read/write mode of HDD container.
+ *
+ * @return Virtual disk ReadOnly status.
+ * @return true if no image is opened in HDD container.
+ * @param pDisk Pointer to HDD container.
+ */
+VBOXDDU_DECL(bool) VDIsReadOnly(PVBOXHDD pDisk);
+
+/**
+ * Get total capacity of an image in HDD container.
+ *
+ * @return Virtual disk size in bytes.
+ * @return 0 if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ */
+VBOXDDU_DECL(uint64_t) VDGetSize(PVBOXHDD pDisk, unsigned nImage);
+
+/**
+ * Get total file size of an image in HDD container.
+ *
+ * @return Virtual disk size in bytes.
+ * @return 0 if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ */
+VBOXDDU_DECL(uint64_t) VDGetFileSize(PVBOXHDD pDisk, unsigned nImage);
+
+/**
+ * Get virtual disk PCHS geometry of an image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @return VERR_VD_GEOMETRY_NOT_SET if no geometry present in the HDD container.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pPCHSGeometry Where to store PCHS geometry. Not NULL.
+ */
+VBOXDDU_DECL(int) VDGetPCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
+ PVDGEOMETRY pPCHSGeometry);
+
+/**
+ * Store virtual disk PCHS geometry of an image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pPCHSGeometry Where to load PCHS geometry from. Not NULL.
+ */
+VBOXDDU_DECL(int) VDSetPCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
+ PCVDGEOMETRY pPCHSGeometry);
+
+/**
+ * Get virtual disk LCHS geometry of an image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @return VERR_VD_GEOMETRY_NOT_SET if no geometry present in the HDD container.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pLCHSGeometry Where to store LCHS geometry. Not NULL.
+ */
+VBOXDDU_DECL(int) VDGetLCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
+ PVDGEOMETRY pLCHSGeometry);
+
+/**
+ * Store virtual disk LCHS geometry of an image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pLCHSGeometry Where to load LCHS geometry from. Not NULL.
+ */
+VBOXDDU_DECL(int) VDSetLCHSGeometry(PVBOXHDD pDisk, unsigned nImage,
+ PCVDGEOMETRY pLCHSGeometry);
+
+/**
+ * Get version of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param puVersion Where to store the image version.
+ */
+VBOXDDU_DECL(int) VDGetVersion(PVBOXHDD pDisk, unsigned nImage,
+ unsigned *puVersion);
+
+/**
+ * List the capabilities of image backend in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to the HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pbackendInfo Where to store the backend information.
+ */
+VBOXDDU_DECL(int) VDBackendInfoSingle(PVBOXHDD pDisk, unsigned nImage,
+ PVDBACKENDINFO pBackendInfo);
+
+/**
+ * Get flags of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param puImageFlags Where to store the image flags.
+ */
+VBOXDDU_DECL(int) VDGetImageFlags(PVBOXHDD pDisk, unsigned nImage, unsigned *puImageFlags);
+
+/**
+ * Get open flags of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param puOpenFlags Where to store the image open flags.
+ */
+VBOXDDU_DECL(int) VDGetOpenFlags(PVBOXHDD pDisk, unsigned nImage,
+ unsigned *puOpenFlags);
+
+/**
+ * Set open flags of image in HDD container.
+ * This operation may cause file locking changes and/or files being reopened.
+ * Note that in case of unrecoverable error all images in HDD container will be closed.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param uOpenFlags Image file open mode, see VD_OPEN_FLAGS_* constants.
+ */
+VBOXDDU_DECL(int) VDSetOpenFlags(PVBOXHDD pDisk, unsigned nImage,
+ unsigned uOpenFlags);
+
+/**
+ * Get base filename of image in HDD container. Some image formats use
+ * other filenames as well, so don't use this for anything but informational
+ * purposes.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @return VERR_BUFFER_OVERFLOW if pszFilename buffer too small to hold filename.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pszFilename Where to store the image file name.
+ * @param cbFilename Size of buffer pszFilename points to.
+ */
+VBOXDDU_DECL(int) VDGetFilename(PVBOXHDD pDisk, unsigned nImage,
+ char *pszFilename, unsigned cbFilename);
+
+/**
+ * Get the comment line of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @return VERR_BUFFER_OVERFLOW if pszComment buffer too small to hold comment text.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pszComment Where to store the comment string of image. NULL is ok.
+ * @param cbComment The size of pszComment buffer. 0 is ok.
+ */
+VBOXDDU_DECL(int) VDGetComment(PVBOXHDD pDisk, unsigned nImage,
+ char *pszComment, unsigned cbComment);
+
+/**
+ * Changes the comment line of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pszComment New comment string (UTF-8). NULL is allowed to reset the comment.
+ */
+VBOXDDU_DECL(int) VDSetComment(PVBOXHDD pDisk, unsigned nImage,
+ const char *pszComment);
+
+/**
+ * Get UUID of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pUuid Where to store the image UUID.
+ */
+VBOXDDU_DECL(int) VDGetUuid(PVBOXHDD pDisk, unsigned nImage, PRTUUID pUuid);
+
+/**
+ * Set the image's UUID. Should not be used by normal applications.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pUuid New UUID of the image. If NULL, a new UUID is created.
+ */
+VBOXDDU_DECL(int) VDSetUuid(PVBOXHDD pDisk, unsigned nImage, PCRTUUID pUuid);
+
+/**
+ * Get last modification UUID of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pUuid Where to store the image modification UUID.
+ */
+VBOXDDU_DECL(int) VDGetModificationUuid(PVBOXHDD pDisk, unsigned nImage,
+ PRTUUID pUuid);
+
+/**
+ * Set the image's last modification UUID. Should not be used by normal applications.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pUuid New modification UUID of the image. If NULL, a new UUID is created.
+ */
+VBOXDDU_DECL(int) VDSetModificationUuid(PVBOXHDD pDisk, unsigned nImage,
+ PCRTUUID pUuid);
+
+/**
+ * Get parent UUID of image in HDD container.
+ *
+ * @return VBox status code.
+ * @return VERR_VD_IMAGE_NOT_FOUND if image with specified number was not opened.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of the container.
+ * @param pUuid Where to store the parent image UUID.
+ */
+VBOXDDU_DECL(int) VDGetParentUuid(PVBOXHDD pDisk, unsigned nImage,
+ PRTUUID pUuid);
+
+/**
+ * Set the image's parent UUID. Should not be used by normal applications.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ * @param nImage Image number, counts from 0. 0 is always base image of container.
+ * @param pUuid New parent UUID of the image. If NULL, a new UUID is created.
+ */
+VBOXDDU_DECL(int) VDSetParentUuid(PVBOXHDD pDisk, unsigned nImage,
+ PCRTUUID pUuid);
+
+
+/**
+ * Debug helper - dumps all opened images in HDD container into the log file.
+ *
+ * @param pDisk Pointer to HDD container.
+ */
+VBOXDDU_DECL(void) VDDumpImages(PVBOXHDD pDisk);
+
+
+/**
+ * Discards unused ranges given as a list.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ * @param paRanges The array of ranges to discard.
+ * @param cRanges Number of entries in the array.
+ *
+ * @note In contrast to VDCompact() the ranges are always discarded even if they
+ * appear to contain data. This method is mainly used to implement TRIM support.
+ */
+VBOXDDU_DECL(int) VDDiscardRanges(PVBOXHDD pDisk, PCRTRANGE paRanges, unsigned cRanges);
+
+
+/**
+ * Start an asynchronous read request.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to the HDD container.
+ * @param uOffset The offset of the virtual disk to read from.
+ * @param cbRead How many bytes to read.
+ * @param pcSgBuf Pointer to the S/G buffer to read into.
+ * @param pfnComplete Completion callback.
+ * @param pvUser User data which is passed on completion
+ */
+VBOXDDU_DECL(int) VDAsyncRead(PVBOXHDD pDisk, uint64_t uOffset, size_t cbRead,
+ PCRTSGBUF pcSgBuf,
+ PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
+ void *pvUser1, void *pvUser2);
+
+
+/**
+ * Start an asynchronous write request.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to the HDD container.
+ * @param uOffset The offset of the virtual disk to write to.
+ * @param cbWrtie How many bytes to write.
+ * @param pcSgBuf Pointer to the S/G buffer to write from.
+ * @param pfnComplete Completion callback.
+ * @param pvUser User data which is passed on completion.
+ */
+VBOXDDU_DECL(int) VDAsyncWrite(PVBOXHDD pDisk, uint64_t uOffset, size_t cbWrite,
+ PCRTSGBUF pcSgBuf,
+ PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
+ void *pvUser1, void *pvUser2);
+
+
+/**
+ * Start an asynchronous flush request.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to the HDD container.
+ * @param pfnComplete Completion callback.
+ * @param pvUser User data which is passed on completion.
+ */
+VBOXDDU_DECL(int) VDAsyncFlush(PVBOXHDD pDisk,
+ PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
+ void *pvUser1, void *pvUser2);
+
+/**
+ * Start an asynchronous discard request.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ * @param paRanges The array of ranges to discard.
+ * @param cRanges Number of entries in the array.
+ * @param pfnComplete Completion callback.
+ * @param pvUser1 User data which is passed on completion.
+ * @param pvUser2 User data which is passed on completion.
+ */
+VBOXDDU_DECL(int) VDAsyncDiscardRanges(PVBOXHDD pDisk, PCRTRANGE paRanges, unsigned cRanges,
+ PFNVDASYNCTRANSFERCOMPLETE pfnComplete,
+ void *pvUser1, void *pvUser);
+
+/**
+ * Tries to repair a corrupted image.
+ *
+ * @return VBox status code.
+ * @retval VERR_VD_IMAGE_REPAIR_NOT_SUPPORTED if the backend does not support repairing the image.
+ * @retval VERR_VD_IMAGE_REPAIR_IMPOSSIBLE if the corruption is to severe to repair the image.
+ * @param pVDIfsDisk Pointer to the per-disk VD interface list.
+ * @param pVDIfsImage Pointer to the per-image VD interface list.
+ * @param pszFilename Name of the image file to repair.
+ * @param pszFormat The backend to use.
+ * @param fFlags Combination of the VD_REPAIR_* flags.
+ */
+VBOXDDU_DECL(int) VDRepair(PVDINTERFACE pVDIfsDisk, PVDINTERFACE pVDIfsImage,
+ const char *pszFilename, const char *pszBackend,
+ uint32_t fFlags);
+
+/**
+ * Create a VFS file handle from the given HDD container.
+ *
+ * @return VBox status code.
+ * @param pDisk Pointer to HDD container.
+ * @param fFlags Combination of the VD_VFSFILE_* flags.
+ * @param phVfsFile Where to stoer the handle to the VFS file on success.
+ */
+VBOXDDU_DECL(int) VDCreateVfsFileFromDisk(PVBOXHDD pDisk, uint32_t fFlags,
+ PRTVFSFILE phVfsFile);
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/VBox/vddbg.h b/include/VBox/vddbg.h
new file mode 100644
index 00000000..b68d01ad
--- /dev/null
+++ b/include/VBox/vddbg.h
@@ -0,0 +1,265 @@
+/** @file
+ * VD Debug API.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_VDDbg_h
+#define ___VBox_VDDbg_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <VBox/vd.h> /* for VDRANGE */
+#include <iprt/sg.h>
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING0
+# error "There are no VD Debug APIs available in Ring-0 Host Context!"
+#endif
+
+/** @defgroup grp_vddbg VD Debug API
+ * @{
+ */
+
+/** I/O logger handle. */
+typedef struct VDIOLOGGERINT *VDIOLOGGER;
+/** Pointer to an I/O logger handler. */
+typedef VDIOLOGGER *PVDIOLOGGER;
+
+/** Pointer to an I/O log entry handle. */
+typedef struct VDIOLOGENTINT *VDIOLOGENT;
+/** Pointer to an I/O log entry handle. */
+typedef VDIOLOGENT *PVDIOLOGENT;
+
+/** I/O logger buffers all log entries in memory until VDDbgIoLogCommit() is called.
+ * If not given all entries are immediately logged to the file. */
+#define VDDBG_IOLOG_MEMORY_BUFFER RT_BIT_32(0)
+/** I/O logger logs the written data. */
+#define VDDBG_IOLOG_LOG_DATA_WRITTEN RT_BIT_32(1)
+/** I/O logger logs the read data. */
+#define VDDBG_IOLOG_LOG_DATA_READ RT_BIT_32(2)
+/** I/O logger logs all data. */
+#define VDDBG_IOLOG_LOG_DATA (VDDBG_IOLOG_LOG_DATA_READ | VDDBG_IOLOG_LOG_DATA_WRITTEN)
+/** Mask of valid flags. */
+#define VDDBG_IOLOG_VALID_MASK (VDDBG_IOLOG_MEMORY_BUFFER | VDDBG_IOLOG_LOG_DATA)
+
+/**
+ * I/O direction.
+ */
+typedef enum VDDBGIOLOGREQ
+{
+ /** Invalid direction. */
+ VDDBGIOLOGREQ_INVALID = 0,
+ /** Read. */
+ VDDBGIOLOGREQ_READ,
+ /** Write. */
+ VDDBGIOLOGREQ_WRITE,
+ /** Flush. */
+ VDDBGIOLOGREQ_FLUSH,
+ /** Discard. */
+ VDDBGIOLOGREQ_DISCARD,
+ /** 32bit hack. */
+ VDDBGIOLOGREQ_32BIT_HACK = 0x7fffffff
+} VDDBGIOLOGREQ;
+/** Pointer to a I/O direction. */
+typedef VDDBGIOLOGREQ *PVDDBGIOLOGREQ;
+
+/**
+ * I/O log event types.
+ */
+typedef enum VDIOLOGEVENT
+{
+ /** Invalid event. */
+ VDIOLOGEVENT_INVALID = 0,
+ /** I/O request start event. */
+ VDIOLOGEVENT_START,
+ /** I/O request complete event. */
+ VDIOLOGEVENT_COMPLETE,
+ /** No more events logged. */
+ VDIOLOGEVENT_END,
+ /** 32bit type blowup. */
+ VDIOLOGEVENT_32BIT_HACK = 0x7fffffff
+} VDIOLOGEVENT;
+/** Pointer to an I/O log event. */
+typedef VDIOLOGEVENT *PVDIOLOGEVENT;
+
+/**
+ * Creates a new I/O logger for writing to the I/O log.
+ *
+ * @returns VBox status code.
+ * @param phIoLogger Where to store the I/O logger handle on success.
+ * @param pszFilename The file to log into.
+ * @param fFlags Flags for the I/O logger.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogCreate(PVDIOLOGGER phIoLogger, const char *pszFilename, uint32_t fFlags);
+
+/**
+ * Opens an existing I/O log and creates a new I/O logger from it.
+ *
+ * @returns VBox status code.
+ * @param phIoLogger Where to store the I/O logger handle on success.
+ * @param pszFilename The I/O log to use.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogOpen(PVDIOLOGGER phIoLogger, const char *pszFilename);
+
+/**
+ * Destroys the given I/O logger handle.
+ *
+ * @returns nothing.
+ * @param hIoLogger The I/O logger handle to destroy.
+ */
+VBOXDDU_DECL(void) VDDbgIoLogDestroy(VDIOLOGGER hIoLogger);
+
+/**
+ * Commit all log entries to the log file.
+ *
+ * @returns VBox status code.
+ * @param hIoLogger The I/O logger to flush.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogCommit(VDIOLOGGER hIoLogger);
+
+/**
+ * Returns the flags of the given I/O logger.
+ *
+ * @returns Flags of the I/O logger.
+ * @param hIoLogger The I/O logger to use.
+ */
+VBOXDDU_DECL(uint32_t) VDDbgIoLogGetFlags(VDIOLOGGER hIoLogger);
+
+/**
+ * Starts logging of an I/O request.
+ *
+ * @returns VBox status code.
+ * @param hIoLogger The I/O logger to use.
+ * @param fAsync Flag whether the request is synchronous or asynchronous.
+ * @param enmTxDir The transfer direction to log.
+ * @param off The start offset of the I/O request to log.
+ * @param cbIo The number of bytes the I/O request transfered.
+ * @param pSgBuf The data the I/O request is writing if it is a write request.
+ * Can be NULL if the logger is instructed to not log the data
+ * or a flush request is logged.
+ * @param phIoLogEntry Where to store the I/O log entry handle on success.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogStart(VDIOLOGGER hIoLogger, bool fAsync, VDDBGIOLOGREQ enmTxDir, uint64_t off, size_t cbIo, PCRTSGBUF pSgBuf,
+ PVDIOLOGENT phIoLogEntry);
+
+/**
+ * Starts logging of a discard request.
+ *
+ * @returns VBox status code.
+ * @param hIoLogger The I/O logger to use.
+ * @param fAsync Flag whether the request is synchronous or asynchronous.
+ * @param paRanges The array of ranges to discard.
+ * @param cRanges Number of rnages in the array.
+ * @param phIoLogEntry Where to store the I/O log entry handle on success.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogStartDiscard(VDIOLOGGER hIoLogger, bool fAsync, PCRTRANGE paRanges, unsigned cRanges,
+ PVDIOLOGENT phIoLogEntry);
+
+/**
+ * Marks the given I/O log entry as completed.
+ *
+ * @returns VBox status code.
+ * @param hIoLogger The I/O logger to use.
+ * @param hIoLogEntry The I/O log entry to complete.
+ * @param rcReq The status code the request completed with.
+ * @param pSgBuf The data read if the request was a read and it succeeded.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogComplete(VDIOLOGGER hIoLogger, VDIOLOGENT hIoLogEntry, int rcReq, PCRTSGBUF pSgBuf);
+
+/**
+ * Gets the next event type from the I/O log.
+ *
+ * @returns VBox status code.
+ * @param hIoLogger The I/O logger to use.
+ * @param penmEvent Where to store the next event on success.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogEventTypeGetNext(VDIOLOGGER hIoLogger, VDIOLOGEVENT *penmEvent);
+
+/**
+ * Gets the next request type from the I/O log.
+ *
+ * @returns VBox status code.
+ * @param hIoLogger The I/O logger to use.
+ * @param penmEvent Where to store the next event on success.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogReqTypeGetNext(VDIOLOGGER hIoLogger, PVDDBGIOLOGREQ penmReq);
+
+/**
+ * Returns the start event from the I/O log.
+ *
+ * @returns VBox status code.
+ * @retval VERR_EOF if the end of the log is reached.
+ * @retval VERR_BUFFER_OVERFLOW if the provided data buffer can't hold the data.
+ * pcbIo will hold the required buffer size on return.
+ * @param hIoLogger The I/O logger to use.
+ * @param pidEvent The ID of the event to identify the corresponding complete event.
+ * @param pfAsync Where to store the flag whether the request is
+ * @param poff Where to store the offset of the next I/O log entry on success.
+ * @param pcbIo Where to store the transfer size of the next I/O log entry on success.
+ * @param cbBuf Size of the provided data buffer.
+ * @param pvBuf Where to store the data of the next I/O log entry on success.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogEventGetStart(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
+ uint64_t *poff, size_t *pcbIo, size_t cbBuf, void *pvBuf);
+
+/**
+ * Returns the discard start event from the I/O log.
+ *
+ * @returns VBox status code.
+ * @retval VERR_EOF if the end of the log is reached.
+ * @retval VERR_BUFFER_OVERFLOW if the provided data buffer can't hold the data.
+ * pcbIo will hold the required buffer size on return.
+ * @param hIoLogger The I/O logger to use.
+ * @param pidEvent The ID of the event to identify the corresponding complete event.
+ * @param pfAsync Where to store the flag whether the request is
+ * @param ppaRanges Where to store the pointer to the range array on success.
+ * @param pcRanges Where to store the number of entries in the array on success.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogEventGetStartDiscard(VDIOLOGGER hIoLogger, uint64_t *pidEvent, bool *pfAsync,
+ PRTRANGE *ppaRanges, unsigned *pcRanges);
+
+/**
+ * Returns the complete from the I/O log.
+ *
+ * @returns VBox status code.
+ * @retval VERR_EOF if the end of the log is reached
+ * @retval VERR_BUFFER_OVERFLOW if the provided data buffer can't hold the data.
+ * pcbIo will hold the required buffer size on return.
+ * @param hIoLogger The I/O logger to use.
+ * @param pidEvent The ID of the event to identify the corresponding start event.
+ * @param pRc Where to store the status code of the request on success.
+ * @param pmsDuration Where to store the duration of the request.
+ * @param pcbIo Where to store the transfer size of the next I/O log entry on success.
+ * @param cbBuf Size of the provided data buffer.
+ * @param pvBuf Where to store the data of the data transfered during a read request.
+ */
+VBOXDDU_DECL(int) VDDbgIoLogEventGetComplete(VDIOLOGGER hIoLogger, uint64_t *pidEvent, int *pRc,
+ uint64_t *pmsDuration, size_t *pcbIo, size_t cbBuf, void *pvBuf);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/version.h b/include/VBox/version.h
new file mode 100644
index 00000000..8a48c1f6
--- /dev/null
+++ b/include/VBox/version.h
@@ -0,0 +1,111 @@
+/** @file
+ * VBox Version Management.
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_version_h
+#define ___VBox_version_h
+
+/* Product info. */
+#include <product-generated.h>
+
+#ifndef RC_INVOKED
+# include <version-generated.h>
+
+/** Combined version number. */
+# define VBOX_VERSION (VBOX_VERSION_MAJOR << 16 | VBOX_VERSION_MINOR)
+/** Get minor version from combined version. */
+# define VBOX_GET_VERSION_MINOR(uVer) ((uVer) & 0xffff)
+/** Get major version from combined version. */
+# define VBOX_GET_VERSION_MAJOR(uVer) ((uVer) >> 16)
+
+/**
+ * Make a full version number.
+ *
+ * The returned number can be used in normal integer comparsions and will yield
+ * the expected results.
+ *
+ * @param uMajor The major version number.
+ * @param uMinor The minor version number.
+ * @param uBuild The build number.
+ * @returns Full version number.
+ */
+# define VBOX_FULL_VERSION_MAKE(uMajor, uMinor, uBuild) \
+ ( (uint32_t)((uMajor) & 0xff) << 24 \
+ | (uint32_t)((uMinor) & 0xff) << 16 \
+ | (uint32_t)((uBuild) & 0xffff) \
+ )
+
+/** Combined version number. */
+# define VBOX_FULL_VERSION \
+ VBOX_FULL_VERSION_MAKE(VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD)
+/** Get the major version number from a VBOX_FULL_VERSION style number. */
+# define VBOX_FULL_VERSION_GET_MAJOR(uFullVer) ( ((uFullVer) >> 24) & 0xffU )
+/** Get the minor version number from a VBOX_FULL_VERSION style number. */
+# define VBOX_FULL_VERSION_GET_MINOR(uFullVer) ( ((uFullVer) >> 16) & 0xffU )
+/** Get the build version number from a VBOX_FULL_VERSION style number. */
+# define VBOX_FULL_VERSION_GET_BUILD(uFullVer) ( ((uFullVer) ) & 0xffffU )
+
+/**
+ * Make a short version number for use in 16 bit version fields.
+ *
+ * The returned number can be used in normal integer comparsions and will yield
+ * the expected results.
+ *
+ * @param uMajor The major version number.
+ * @param uMinor The minor version number.
+ * @returns Short version number.
+ */
+# define VBOX_SHORT_VERSION_MAKE(uMajor, uMinor) \
+ ( (uint16_t)((uMajor) & 0xff) << 8 \
+ | (uint16_t)((uMinor) & 0xff) \
+ )
+
+/** Combined short version number. */
+# define VBOX_SHORT_VERSION \
+ VBOX_SHORT_VERSION_MAKE(VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR)
+/** Get the major version number from a VBOX_SHORT_VERSION style number. */
+# define VBOX_SHORT_VERSION_GET_MAJOR(uShortVer) ( ((uShortVer) >> 8) & 0xffU )
+/** Get the minor version number from a VBOX_SHORT_VERSION style number. */
+# define VBOX_SHORT_VERSION_GET_MINOR(uShortVer) ( (uShortVer) & 0xffU )
+
+#endif /* !RC_INVOKED */
+
+/** @name Prefined strings for Windows resource files
+ *
+ * @remarks The VBOX_VERSION_*_NR define are integer numbers while
+ * VBOX_VERSION_* are strings when using the resource compile.
+ * Kind of confusing...
+ *
+ * @{ */
+#define VBOX_RC_COMPANY_NAME VBOX_VENDOR
+#define VBOX_RC_LEGAL_COPYRIGHT "Copyright (C) 2009-" VBOX_C_YEAR " Oracle Corporation\0"
+#define VBOX_RC_PRODUCT_VERSION VBOX_VERSION_MAJOR_NR , VBOX_VERSION_MINOR_NR , 0 , 0
+#define VBOX_RC_FILE_VERSION VBOX_VERSION_MAJOR_NR , VBOX_VERSION_MINOR_NR , 0 , 0
+/** @} */
+
+/** @todo Clean up the resource compiler mess where we cannot include
+ * version-generated.h and requires two files. */
+
+#endif
+
diff --git a/include/VBox/vmm/Makefile.kup b/include/VBox/vmm/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/VBox/vmm/Makefile.kup
diff --git a/include/VBox/vmm/cfgm.h b/include/VBox/vmm/cfgm.h
new file mode 100644
index 00000000..9b4e47ab
--- /dev/null
+++ b/include/VBox/vmm/cfgm.h
@@ -0,0 +1,220 @@
+/** @file
+ * CFGM - Configuration Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_cfgm_h
+#define ___VBox_vmm_cfgm_h
+
+#include <VBox/types.h>
+#include <iprt/stdarg.h>
+
+/** @defgroup grp_cfgm The Configuration Manager API
+ * @{
+ */
+
+/**
+ * Configuration manager value type.
+ */
+typedef enum CFGMVALUETYPE
+{
+ /** Integer value. */
+ CFGMVALUETYPE_INTEGER = 1,
+ /** String value. */
+ CFGMVALUETYPE_STRING,
+ /** Bytestring value. */
+ CFGMVALUETYPE_BYTES
+} CFGMVALUETYPE;
+/** Pointer to configuration manager property type. */
+typedef CFGMVALUETYPE *PCFGMVALUETYPE;
+
+
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING3
+/** @defgroup grp_cfgm_r3 The CFGM Host Context Ring-3 API
+ * @ingroup grp_cfgm
+ * @{
+ */
+
+typedef enum CFGMCONFIGTYPE
+{
+ /** pvConfig points to nothing, use defaults. */
+ CFGMCONFIGTYPE_NONE = 0,
+ /** pvConfig points to a IMachine interface. */
+ CFGMCONFIGTYPE_IMACHINE
+} CFGMCONFIGTYPE;
+
+
+/**
+ * CFGM init callback for constructing the configuration tree.
+ *
+ * This is called from the emulation thread, and the one interfacing the VM
+ * can make any necessary per-thread initializations at this point.
+ *
+ * @returns VBox status code.
+ * @param pVM VM handle.
+ * @param pvUser The argument supplied to VMR3Create().
+ */
+typedef DECLCALLBACK(int) FNCFGMCONSTRUCTOR(PVM pVM, void *pvUser);
+/** Pointer to a FNCFGMCONSTRUCTOR(). */
+typedef FNCFGMCONSTRUCTOR *PFNCFGMCONSTRUCTOR;
+
+VMMR3DECL(int) CFGMR3Init(PVM pVM, PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUser);
+VMMR3DECL(int) CFGMR3Term(PVM pVM);
+
+
+VMMR3DECL(PCFGMNODE) CFGMR3CreateTree(PVM pVM);
+VMMR3DECL(int) CFGMR3ConstructDefaultTree(PVM pVM);
+VMMR3DECL(void) CFGMR3Dump(PCFGMNODE pRoot);
+VMMR3DECL(int) CFGMR3DuplicateSubTree(PCFGMNODE pRoot, PCFGMNODE *ppCopy);
+VMMR3DECL(int) CFGMR3ReplaceSubTree(PCFGMNODE pRoot, PCFGMNODE pNewRoot);
+VMMR3DECL(int) CFGMR3InsertSubTree(PCFGMNODE pNode, const char *pszName, PCFGMNODE pSubTree, PCFGMNODE *ppChild);
+VMMR3DECL(int) CFGMR3InsertNode(PCFGMNODE pNode, const char *pszName, PCFGMNODE *ppChild);
+VMMR3DECL(int) CFGMR3InsertNodeF(PCFGMNODE pNode, PCFGMNODE *ppChild, const char *pszNameFormat, ...);
+VMMR3DECL(int) CFGMR3InsertNodeFV(PCFGMNODE pNode, PCFGMNODE *ppChild, const char *pszNameFormat, va_list Args);
+VMMR3DECL(void) CFGMR3SetRestrictedRoot(PCFGMNODE pNode);
+VMMR3DECL(void) CFGMR3RemoveNode(PCFGMNODE pNode);
+VMMR3DECL(int) CFGMR3InsertInteger(PCFGMNODE pNode, const char *pszName, uint64_t u64Integer);
+VMMR3DECL(int) CFGMR3InsertString(PCFGMNODE pNode, const char *pszName, const char *pszString);
+VMMR3DECL(int) CFGMR3InsertStringN(PCFGMNODE pNode, const char *pszName, const char *pszString, size_t cchString);
+VMMR3DECL(int) CFGMR3InsertStringF(PCFGMNODE pNode, const char *pszName, const char *pszFormat, ...);
+VMMR3DECL(int) CFGMR3InsertStringFV(PCFGMNODE pNode, const char *pszName, const char *pszFormat, va_list va);
+VMMR3DECL(int) CFGMR3InsertStringW(PCFGMNODE pNode, const char *pszName, PCRTUTF16 pwszValue);
+VMMR3DECL(int) CFGMR3InsertBytes(PCFGMNODE pNode, const char *pszName, const void *pvBytes, size_t cbBytes);
+VMMR3DECL(int) CFGMR3InsertValue(PCFGMNODE pNode, PCFGMLEAF pValue);
+VMMR3DECL(int) CFGMR3RemoveValue(PCFGMNODE pNode, const char *pszName);
+
+/** @name CFGMR3CopyTree flags.
+ * @{ */
+/** Reserved value disposition \#0. */
+#define CFGM_COPY_FLAGS_RESERVED_VALUE_DISP_0 UINT32_C(0x00000000)
+/** Reserved value disposition \#1. */
+#define CFGM_COPY_FLAGS_RESERVED_VALUE_DISP_1 UINT32_C(0x00000001)
+/** Replace exiting values. */
+#define CFGM_COPY_FLAGS_REPLACE_VALUES UINT32_C(0x00000002)
+/** Ignore exiting values. */
+#define CFGM_COPY_FLAGS_IGNORE_EXISTING_VALUES UINT32_C(0x00000003)
+/** Value disposition mask. */
+#define CFGM_COPY_FLAGS_VALUE_DISP_MASK UINT32_C(0x00000003)
+
+/** Replace exiting keys. */
+#define CFGM_COPY_FLAGS_RESERVED_KEY_DISP UINT32_C(0x00000000)
+/** Replace exiting keys. */
+#define CFGM_COPY_FLAGS_MERGE_KEYS UINT32_C(0x00000010)
+/** Replace exiting keys. */
+#define CFGM_COPY_FLAGS_REPLACE_KEYS UINT32_C(0x00000020)
+/** Ignore existing keys. */
+#define CFGM_COPY_FLAGS_IGNORE_EXISTING_KEYS UINT32_C(0x00000030)
+/** Key disposition. */
+#define CFGM_COPY_FLAGS_KEY_DISP_MASK UINT32_C(0x00000030)
+/** @} */
+VMMR3DECL(int) CFGMR3CopyTree(PCFGMNODE pDstTree, PCFGMNODE pSrcTree, uint32_t fFlags);
+
+VMMR3DECL(int) CFGMR3QueryType( PCFGMNODE pNode, const char *pszName, PCFGMVALUETYPE penmType);
+VMMR3DECL(int) CFGMR3QuerySize( PCFGMNODE pNode, const char *pszName, size_t *pcb);
+VMMR3DECL(int) CFGMR3QueryInteger( PCFGMNODE pNode, const char *pszName, uint64_t *pu64);
+VMMR3DECL(int) CFGMR3QueryIntegerDef( PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def);
+VMMR3DECL(int) CFGMR3QueryString( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString);
+VMMR3DECL(int) CFGMR3QueryStringDef( PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString, const char *pszDef);
+VMMR3DECL(int) CFGMR3QueryBytes( PCFGMNODE pNode, const char *pszName, void *pvData, size_t cbData);
+
+
+/** @name Helpers
+ * @{
+ */
+VMMR3DECL(int) CFGMR3QueryU64( PCFGMNODE pNode, const char *pszName, uint64_t *pu64);
+VMMR3DECL(int) CFGMR3QueryU64Def( PCFGMNODE pNode, const char *pszName, uint64_t *pu64, uint64_t u64Def);
+VMMR3DECL(int) CFGMR3QueryS64( PCFGMNODE pNode, const char *pszName, int64_t *pi64);
+VMMR3DECL(int) CFGMR3QueryS64Def( PCFGMNODE pNode, const char *pszName, int64_t *pi64, int64_t i64Def);
+VMMR3DECL(int) CFGMR3QueryU32( PCFGMNODE pNode, const char *pszName, uint32_t *pu32);
+VMMR3DECL(int) CFGMR3QueryU32Def( PCFGMNODE pNode, const char *pszName, uint32_t *pu32, uint32_t u32Def);
+VMMR3DECL(int) CFGMR3QueryS32( PCFGMNODE pNode, const char *pszName, int32_t *pi32);
+VMMR3DECL(int) CFGMR3QueryS32Def( PCFGMNODE pNode, const char *pszName, int32_t *pi32, int32_t i32Def);
+VMMR3DECL(int) CFGMR3QueryU16( PCFGMNODE pNode, const char *pszName, uint16_t *pu16);
+VMMR3DECL(int) CFGMR3QueryU16Def( PCFGMNODE pNode, const char *pszName, uint16_t *pu16, uint16_t u16Def);
+VMMR3DECL(int) CFGMR3QueryS16( PCFGMNODE pNode, const char *pszName, int16_t *pi16);
+VMMR3DECL(int) CFGMR3QueryS16Def( PCFGMNODE pNode, const char *pszName, int16_t *pi16, int16_t i16Def);
+VMMR3DECL(int) CFGMR3QueryU8( PCFGMNODE pNode, const char *pszName, uint8_t *pu8);
+VMMR3DECL(int) CFGMR3QueryU8Def( PCFGMNODE pNode, const char *pszName, uint8_t *pu8, uint8_t u8Def);
+VMMR3DECL(int) CFGMR3QueryS8( PCFGMNODE pNode, const char *pszName, int8_t *pi8);
+VMMR3DECL(int) CFGMR3QueryS8Def( PCFGMNODE pNode, const char *pszName, int8_t *pi8, int8_t i8Def);
+VMMR3DECL(int) CFGMR3QueryBool( PCFGMNODE pNode, const char *pszName, bool *pf);
+VMMR3DECL(int) CFGMR3QueryBoolDef( PCFGMNODE pNode, const char *pszName, bool *pf, bool fDef);
+VMMR3DECL(int) CFGMR3QueryPort( PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort);
+VMMR3DECL(int) CFGMR3QueryPortDef( PCFGMNODE pNode, const char *pszName, PRTIOPORT pPort, RTIOPORT PortDef);
+VMMR3DECL(int) CFGMR3QueryUInt( PCFGMNODE pNode, const char *pszName, unsigned int *pu);
+VMMR3DECL(int) CFGMR3QueryUIntDef( PCFGMNODE pNode, const char *pszName, unsigned int *pu, unsigned int uDef);
+VMMR3DECL(int) CFGMR3QuerySInt( PCFGMNODE pNode, const char *pszName, signed int *pi);
+VMMR3DECL(int) CFGMR3QuerySIntDef( PCFGMNODE pNode, const char *pszName, signed int *pi, signed int iDef);
+VMMR3DECL(int) CFGMR3QueryPtr( PCFGMNODE pNode, const char *pszName, void **ppv);
+VMMR3DECL(int) CFGMR3QueryPtrDef( PCFGMNODE pNode, const char *pszName, void **ppv, void *pvDef);
+VMMR3DECL(int) CFGMR3QueryGCPtr( PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr);
+VMMR3DECL(int) CFGMR3QueryGCPtrDef( PCFGMNODE pNode, const char *pszName, PRTGCPTR pGCPtr, RTGCPTR GCPtrDef);
+VMMR3DECL(int) CFGMR3QueryGCPtrU( PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr);
+VMMR3DECL(int) CFGMR3QueryGCPtrUDef( PCFGMNODE pNode, const char *pszName, PRTGCUINTPTR pGCPtr, RTGCUINTPTR GCPtrDef);
+VMMR3DECL(int) CFGMR3QueryGCPtrS( PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr);
+VMMR3DECL(int) CFGMR3QueryGCPtrSDef( PCFGMNODE pNode, const char *pszName, PRTGCINTPTR pGCPtr, RTGCINTPTR GCPtrDef);
+VMMR3DECL(int) CFGMR3QueryStringAlloc( PCFGMNODE pNode, const char *pszName, char **ppszString);
+VMMR3DECL(int) CFGMR3QueryStringAllocDef(PCFGMNODE pNode, const char *pszName, char **ppszString, const char *pszDef);
+
+/** @} */
+
+/** @name Tree Navigation and Enumeration.
+ * @{
+ */
+VMMR3DECL(PCFGMNODE) CFGMR3GetRoot(PVM pVM);
+VMMR3DECL(PCFGMNODE) CFGMR3GetParent(PCFGMNODE pNode);
+VMMR3DECL(PCFGMNODE) CFGMR3GetParentEx(PVM pVM, PCFGMNODE pNode);
+VMMR3DECL(PCFGMNODE) CFGMR3GetChild(PCFGMNODE pNode, const char *pszPath);
+VMMR3DECL(PCFGMNODE) CFGMR3GetChildF(PCFGMNODE pNode, const char *pszPathFormat, ...);
+VMMR3DECL(PCFGMNODE) CFGMR3GetChildFV(PCFGMNODE pNode, const char *pszPathFormat, va_list Args);
+VMMR3DECL(PCFGMNODE) CFGMR3GetFirstChild(PCFGMNODE pNode);
+VMMR3DECL(PCFGMNODE) CFGMR3GetNextChild(PCFGMNODE pCur);
+VMMR3DECL(int) CFGMR3GetName(PCFGMNODE pCur, char *pszName, size_t cchName);
+VMMR3DECL(size_t) CFGMR3GetNameLen(PCFGMNODE pCur);
+VMMR3DECL(bool) CFGMR3AreChildrenValid(PCFGMNODE pNode, const char *pszzValid);
+VMMR3DECL(PCFGMLEAF) CFGMR3GetFirstValue(PCFGMNODE pCur);
+VMMR3DECL(PCFGMLEAF) CFGMR3GetNextValue(PCFGMLEAF pCur);
+VMMR3DECL(int) CFGMR3GetValueName(PCFGMLEAF pCur, char *pszName, size_t cchName);
+VMMR3DECL(size_t) CFGMR3GetValueNameLen(PCFGMLEAF pCur);
+VMMR3DECL(CFGMVALUETYPE) CFGMR3GetValueType(PCFGMLEAF pCur);
+VMMR3DECL(bool) CFGMR3AreValuesValid(PCFGMNODE pNode, const char *pszzValid);
+VMMR3DECL(int) CFGMR3ValidateConfig(PCFGMNODE pNode, const char *pszNode,
+ const char *pszValidValues, const char *pszValidNodes,
+ const char *pszWho, uint32_t uInstance);
+
+/** @} */
+
+
+/** @} */
+#endif /* IN_RING3 */
+
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/cpum.h b/include/VBox/vmm/cpum.h
new file mode 100644
index 00000000..0b4abf33
--- /dev/null
+++ b/include/VBox/vmm/cpum.h
@@ -0,0 +1,492 @@
+/** @file
+ * CPUM - CPU Monitor(/ Manager).
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_cpum_h
+#define ___VBox_vmm_cpum_h
+
+#include <iprt/x86.h>
+#include <VBox/types.h>
+#include <VBox/vmm/cpumctx.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_cpum The CPU Monitor / Manager API
+ * @{
+ */
+
+/**
+ * CPUID feature to set or clear.
+ */
+typedef enum CPUMCPUIDFEATURE
+{
+ CPUMCPUIDFEATURE_INVALID = 0,
+ /** The APIC feature bit. (Std+Ext) */
+ CPUMCPUIDFEATURE_APIC,
+ /** The sysenter/sysexit feature bit. (Std) */
+ CPUMCPUIDFEATURE_SEP,
+ /** The SYSCALL/SYSEXIT feature bit (64 bits mode only for Intel CPUs). (Ext) */
+ CPUMCPUIDFEATURE_SYSCALL,
+ /** The PAE feature bit. (Std+Ext) */
+ CPUMCPUIDFEATURE_PAE,
+ /** The NX feature bit. (Ext) */
+ CPUMCPUIDFEATURE_NX,
+ /** The LAHF/SAHF feature bit (64 bits mode only). (Ext) */
+ CPUMCPUIDFEATURE_LAHF,
+ /** The LONG MODE feature bit. (Ext) */
+ CPUMCPUIDFEATURE_LONG_MODE,
+ /** The PAT feature bit. (Std+Ext) */
+ CPUMCPUIDFEATURE_PAT,
+ /** The x2APIC feature bit. (Std) */
+ CPUMCPUIDFEATURE_X2APIC,
+ /** The RDTSCP feature bit. (Ext) */
+ CPUMCPUIDFEATURE_RDTSCP,
+ /** The Hypervisor Present bit. (Std) */
+ CPUMCPUIDFEATURE_HVP,
+ /** 32bit hackishness. */
+ CPUMCPUIDFEATURE_32BIT_HACK = 0x7fffffff
+} CPUMCPUIDFEATURE;
+
+/**
+ * CPU Vendor.
+ */
+typedef enum CPUMCPUVENDOR
+{
+ CPUMCPUVENDOR_INVALID = 0,
+ CPUMCPUVENDOR_INTEL,
+ CPUMCPUVENDOR_AMD,
+ CPUMCPUVENDOR_VIA,
+ CPUMCPUVENDOR_UNKNOWN,
+ CPUMCPUVENDOR_SYNTHETIC,
+ /** 32bit hackishness. */
+ CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff
+} CPUMCPUVENDOR;
+
+
+/** @name Guest Register Getters.
+ * @{ */
+VMMDECL(void) CPUMGetGuestGDTR(PVMCPU pVCpu, PVBOXGDTR pGDTR);
+VMMDECL(RTGCPTR) CPUMGetGuestIDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
+VMMDECL(RTSEL) CPUMGetGuestTR(PVMCPU pVCpu, PCPUMSELREGHID pHidden);
+VMMDECL(RTSEL) CPUMGetGuestLDTR(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetGuestLdtrEx(PVMCPU pVCpu, uint64_t *pGCPtrBase, uint32_t *pcbLimit);
+VMMDECL(uint64_t) CPUMGetGuestCR0(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestCR2(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestCR3(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestCR4(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestCR8(PVMCPU pVCpu);
+VMMDECL(int) CPUMGetGuestCRx(PVMCPU pVCpu, unsigned iReg, uint64_t *pValue);
+VMMDECL(uint32_t) CPUMGetGuestEFlags(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestEIP(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestRIP(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestEAX(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestEBX(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestECX(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestEDX(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestESI(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestEDI(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestESP(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestEBP(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetGuestCS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetGuestDS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetGuestES(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetGuestFS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetGuestGS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetGuestSS(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestDR0(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestDR1(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestDR2(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestDR3(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestDR6(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetGuestDR7(PVMCPU pVCpu);
+VMMDECL(int) CPUMGetGuestDRx(PVMCPU pVCpu, uint32_t iReg, uint64_t *pValue);
+VMMDECL(void) CPUMGetGuestCpuId(PVMCPU pVCpu, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
+VMMDECL(uint32_t) CPUMGetGuestCpuIdStdMax(PVM pVM);
+VMMDECL(uint32_t) CPUMGetGuestCpuIdExtMax(PVM pVM);
+VMMDECL(uint32_t) CPUMGetGuestCpuIdCentaurMax(PVM pVM);
+VMMDECL(uint64_t) CPUMGetGuestEFER(PVMCPU pVCpu);
+VMMDECL(int) CPUMQueryGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t *puValue);
+VMMDECL(int) CPUMSetGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t uValue);
+VMMDECL(CPUMCPUVENDOR) CPUMGetGuestCpuVendor(PVM pVM);
+VMMDECL(CPUMCPUVENDOR) CPUMGetHostCpuVendor(PVM pVM);
+/** @} */
+
+/** @name Guest Register Setters.
+ * @{ */
+VMMDECL(int) CPUMSetGuestGDTR(PVMCPU pVCpu, uint64_t GCPtrBase, uint16_t cbLimit);
+VMMDECL(int) CPUMSetGuestIDTR(PVMCPU pVCpu, uint64_t GCPtrBase, uint16_t cbLimit);
+VMMDECL(int) CPUMSetGuestTR(PVMCPU pVCpu, uint16_t tr);
+VMMDECL(int) CPUMSetGuestLDTR(PVMCPU pVCpu, uint16_t ldtr);
+VMMDECL(int) CPUMSetGuestCR0(PVMCPU pVCpu, uint64_t cr0);
+VMMDECL(int) CPUMSetGuestCR2(PVMCPU pVCpu, uint64_t cr2);
+VMMDECL(int) CPUMSetGuestCR3(PVMCPU pVCpu, uint64_t cr3);
+VMMDECL(int) CPUMSetGuestCR4(PVMCPU pVCpu, uint64_t cr4);
+VMMDECL(int) CPUMSetGuestDR0(PVMCPU pVCpu, uint64_t uDr0);
+VMMDECL(int) CPUMSetGuestDR1(PVMCPU pVCpu, uint64_t uDr1);
+VMMDECL(int) CPUMSetGuestDR2(PVMCPU pVCpu, uint64_t uDr2);
+VMMDECL(int) CPUMSetGuestDR3(PVMCPU pVCpu, uint64_t uDr3);
+VMMDECL(int) CPUMSetGuestDR6(PVMCPU pVCpu, uint64_t uDr6);
+VMMDECL(int) CPUMSetGuestDR7(PVMCPU pVCpu, uint64_t uDr7);
+VMMDECL(int) CPUMSetGuestDRx(PVMCPU pVCpu, uint32_t iReg, uint64_t Value);
+VMMDECL(int) CPUMSetGuestEFlags(PVMCPU pVCpu, uint32_t eflags);
+VMMDECL(int) CPUMSetGuestEIP(PVMCPU pVCpu, uint32_t eip);
+VMMDECL(int) CPUMSetGuestEAX(PVMCPU pVCpu, uint32_t eax);
+VMMDECL(int) CPUMSetGuestEBX(PVMCPU pVCpu, uint32_t ebx);
+VMMDECL(int) CPUMSetGuestECX(PVMCPU pVCpu, uint32_t ecx);
+VMMDECL(int) CPUMSetGuestEDX(PVMCPU pVCpu, uint32_t edx);
+VMMDECL(int) CPUMSetGuestESI(PVMCPU pVCpu, uint32_t esi);
+VMMDECL(int) CPUMSetGuestEDI(PVMCPU pVCpu, uint32_t edi);
+VMMDECL(int) CPUMSetGuestESP(PVMCPU pVCpu, uint32_t esp);
+VMMDECL(int) CPUMSetGuestEBP(PVMCPU pVCpu, uint32_t ebp);
+VMMDECL(int) CPUMSetGuestCS(PVMCPU pVCpu, uint16_t cs);
+VMMDECL(int) CPUMSetGuestDS(PVMCPU pVCpu, uint16_t ds);
+VMMDECL(int) CPUMSetGuestES(PVMCPU pVCpu, uint16_t es);
+VMMDECL(int) CPUMSetGuestFS(PVMCPU pVCpu, uint16_t fs);
+VMMDECL(int) CPUMSetGuestGS(PVMCPU pVCpu, uint16_t gs);
+VMMDECL(int) CPUMSetGuestSS(PVMCPU pVCpu, uint16_t ss);
+VMMDECL(void) CPUMSetGuestEFER(PVMCPU pVCpu, uint64_t val);
+VMMDECL(void) CPUMSetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
+VMMDECL(void) CPUMClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
+VMMDECL(bool) CPUMGetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
+VMMDECL(void) CPUMSetGuestCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
+VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenCsAndSs(PVMCPU pVCpu);
+VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg);
+/** @} */
+
+
+/** @name Misc Guest Predicate Functions.
+ * @{ */
+
+VMMDECL(bool) CPUMIsGuestIn16BitCode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestIn32BitCode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestIn64BitCode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestNXEnabled(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestPageSizeExtEnabled(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestPagingEnabled(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestR0WriteProtEnabled(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestInRealMode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestInRealOrV86Mode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestInProtectedMode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestInPagedProtectedMode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestInLongMode(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestInPAEMode(PVMCPU pVCpu);
+VMM_INT_DECL(bool) CPUMIsGuestInRawMode(PVMCPU pVCpu);
+
+#ifndef VBOX_WITHOUT_UNNAMED_UNIONS
+
+/**
+ * Tests if the guest is running in real mode or not.
+ *
+ * @returns true if in real mode, otherwise false.
+ * @param pCtx Current CPU context
+ */
+DECLINLINE(bool) CPUMIsGuestInRealModeEx(PCPUMCTX pCtx)
+{
+ return !(pCtx->cr0 & X86_CR0_PE);
+}
+
+/**
+ * Tests if the guest is running in real or virtual 8086 mode.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param pCtx Current CPU context
+ */
+DECLINLINE(bool) CPUMIsGuestInRealOrV86ModeEx(PCPUMCTX pCtx)
+{
+ return !(pCtx->cr0 & X86_CR0_PE)
+ || pCtx->eflags.Bits.u1VM; /** @todo verify that this cannot be set in long mode. */
+}
+
+/**
+ * Tests if the guest is running in paged protected or not.
+ *
+ * @returns true if in paged protected mode, otherwise false.
+ * @param pVM The VM handle.
+ */
+DECLINLINE(bool) CPUMIsGuestInPagedProtectedModeEx(PCPUMCTX pCtx)
+{
+ return (pCtx->cr0 & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
+}
+
+/**
+ * Tests if the guest is running in long mode or not.
+ *
+ * @returns true if in long mode, otherwise false.
+ * @param pCtx Current CPU context
+ */
+DECLINLINE(bool) CPUMIsGuestInLongModeEx(PCPUMCTX pCtx)
+{
+ return (pCtx->msrEFER & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
+}
+
+VMM_INT_DECL(bool) CPUMIsGuestIn64BitCodeSlow(PCPUMCTX pCtx);
+
+/**
+ * Tests if the guest is running in 64 bits mode or not.
+ *
+ * @returns true if in 64 bits protected mode, otherwise false.
+ * @param pVCpu The current virtual CPU.
+ * @param pCtx Current CPU context
+ */
+DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx)
+{
+ if (!(pCtx->msrEFER & MSR_K6_EFER_LMA))
+ return false;
+ if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(NULL, &pCtx->cs))
+ return CPUMIsGuestIn64BitCodeSlow(pCtx);
+ return pCtx->cs.Attr.n.u1Long;
+}
+
+/**
+ * Tests if the guest is running in PAE mode or not.
+ *
+ * @returns true if in PAE mode, otherwise false.
+ * @param pCtx Current CPU context
+ */
+DECLINLINE(bool) CPUMIsGuestInPAEModeEx(PCPUMCTX pCtx)
+{
+ return ( (pCtx->cr4 & X86_CR4_PAE)
+ && CPUMIsGuestInPagedProtectedModeEx(pCtx)
+ && !CPUMIsGuestInLongModeEx(pCtx));
+}
+
+#endif /* VBOX_WITHOUT_UNNAMED_UNIONS */
+
+/** @} */
+
+
+/** @name Hypervisor Register Getters.
+ * @{ */
+VMMDECL(RTSEL) CPUMGetHyperCS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetHyperDS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetHyperES(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetHyperFS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetHyperGS(PVMCPU pVCpu);
+VMMDECL(RTSEL) CPUMGetHyperSS(PVMCPU pVCpu);
+#if 0 /* these are not correct. */
+VMMDECL(uint32_t) CPUMGetHyperCR0(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperCR2(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperCR3(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperCR4(PVMCPU pVCpu);
+#endif
+/** This register is only saved on fatal traps. */
+VMMDECL(uint32_t) CPUMGetHyperEAX(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperEBX(PVMCPU pVCpu);
+/** This register is only saved on fatal traps. */
+VMMDECL(uint32_t) CPUMGetHyperECX(PVMCPU pVCpu);
+/** This register is only saved on fatal traps. */
+VMMDECL(uint32_t) CPUMGetHyperEDX(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperESI(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperEDI(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperEBP(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperESP(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperEFlags(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperEIP(PVMCPU pVCpu);
+VMMDECL(uint64_t) CPUMGetHyperRIP(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetHyperIDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
+VMMDECL(uint32_t) CPUMGetHyperGDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
+VMMDECL(RTSEL) CPUMGetHyperLDTR(PVMCPU pVCpu);
+VMMDECL(RTGCUINTREG) CPUMGetHyperDR0(PVMCPU pVCpu);
+VMMDECL(RTGCUINTREG) CPUMGetHyperDR1(PVMCPU pVCpu);
+VMMDECL(RTGCUINTREG) CPUMGetHyperDR2(PVMCPU pVCpu);
+VMMDECL(RTGCUINTREG) CPUMGetHyperDR3(PVMCPU pVCpu);
+VMMDECL(RTGCUINTREG) CPUMGetHyperDR6(PVMCPU pVCpu);
+VMMDECL(RTGCUINTREG) CPUMGetHyperDR7(PVMCPU pVCpu);
+VMMDECL(void) CPUMGetHyperCtx(PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMDECL(uint32_t) CPUMGetHyperCR3(PVMCPU pVCpu);
+/** @} */
+
+/** @name Hypervisor Register Setters.
+ * @{ */
+VMMDECL(void) CPUMSetHyperGDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
+VMMDECL(void) CPUMSetHyperLDTR(PVMCPU pVCpu, RTSEL SelLDTR);
+VMMDECL(void) CPUMSetHyperIDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
+VMMDECL(void) CPUMSetHyperCR3(PVMCPU pVCpu, uint32_t cr3);
+VMMDECL(void) CPUMSetHyperTR(PVMCPU pVCpu, RTSEL SelTR);
+VMMDECL(void) CPUMSetHyperCS(PVMCPU pVCpu, RTSEL SelCS);
+VMMDECL(void) CPUMSetHyperDS(PVMCPU pVCpu, RTSEL SelDS);
+VMMDECL(void) CPUMSetHyperES(PVMCPU pVCpu, RTSEL SelDS);
+VMMDECL(void) CPUMSetHyperFS(PVMCPU pVCpu, RTSEL SelDS);
+VMMDECL(void) CPUMSetHyperGS(PVMCPU pVCpu, RTSEL SelDS);
+VMMDECL(void) CPUMSetHyperSS(PVMCPU pVCpu, RTSEL SelSS);
+VMMDECL(void) CPUMSetHyperESP(PVMCPU pVCpu, uint32_t u32ESP);
+VMMDECL(int) CPUMSetHyperEFlags(PVMCPU pVCpu, uint32_t Efl);
+VMMDECL(void) CPUMSetHyperEIP(PVMCPU pVCpu, uint32_t u32EIP);
+VMM_INT_DECL(void) CPUMSetHyperState(PVMCPU pVCpu, uint32_t u32EIP, uint32_t u32ESP, uint32_t u32EAX, uint32_t u32EDX);
+VMMDECL(void) CPUMSetHyperDR0(PVMCPU pVCpu, RTGCUINTREG uDr0);
+VMMDECL(void) CPUMSetHyperDR1(PVMCPU pVCpu, RTGCUINTREG uDr1);
+VMMDECL(void) CPUMSetHyperDR2(PVMCPU pVCpu, RTGCUINTREG uDr2);
+VMMDECL(void) CPUMSetHyperDR3(PVMCPU pVCpu, RTGCUINTREG uDr3);
+VMMDECL(void) CPUMSetHyperDR6(PVMCPU pVCpu, RTGCUINTREG uDr6);
+VMMDECL(void) CPUMSetHyperDR7(PVMCPU pVCpu, RTGCUINTREG uDr7);
+VMMDECL(void) CPUMSetHyperCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
+VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu);
+/** @} */
+
+VMMDECL(void) CPUMPushHyper(PVMCPU pVCpu, uint32_t u32);
+VMMDECL(int) CPUMQueryHyperCtxPtr(PVMCPU pVCpu, PCPUMCTX *ppCtx);
+VMMDECL(PCPUMCTX) CPUMGetHyperCtxPtr(PVMCPU pVCpu);
+VMMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVMCPU pVCpu);
+VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu);
+VMMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVMCPU pVCpu);
+VMMR3DECL(int) CPUMR3RawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
+VMMR3DECL(int) CPUMR3RawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc);
+VMMDECL(uint32_t) CPUMRawGetEFlags(PVMCPU pVCpu);
+VMMDECL(void) CPUMRawSetEFlags(PVMCPU pVCpu, uint32_t fEfl);
+VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu);
+
+/** @name Changed flags.
+ * These flags are used to keep track of which important register that
+ * have been changed since last they were reset. The only one allowed
+ * to clear them is REM!
+ * @{
+ */
+#define CPUM_CHANGED_FPU_REM RT_BIT(0)
+#define CPUM_CHANGED_CR0 RT_BIT(1)
+#define CPUM_CHANGED_CR4 RT_BIT(2)
+#define CPUM_CHANGED_GLOBAL_TLB_FLUSH RT_BIT(3)
+#define CPUM_CHANGED_CR3 RT_BIT(4)
+#define CPUM_CHANGED_GDTR RT_BIT(5)
+#define CPUM_CHANGED_IDTR RT_BIT(6)
+#define CPUM_CHANGED_LDTR RT_BIT(7)
+#define CPUM_CHANGED_TR RT_BIT(8) /**@< Currently unused. */
+#define CPUM_CHANGED_SYSENTER_MSR RT_BIT(9)
+#define CPUM_CHANGED_HIDDEN_SEL_REGS RT_BIT(10) /**@< Currently unused. */
+#define CPUM_CHANGED_CPUID RT_BIT(11)
+#define CPUM_CHANGED_ALL ( CPUM_CHANGED_FPU_REM \
+ | CPUM_CHANGED_CR0 \
+ | CPUM_CHANGED_CR4 \
+ | CPUM_CHANGED_GLOBAL_TLB_FLUSH \
+ | CPUM_CHANGED_CR3 \
+ | CPUM_CHANGED_GDTR \
+ | CPUM_CHANGED_IDTR \
+ | CPUM_CHANGED_LDTR \
+ | CPUM_CHANGED_TR \
+ | CPUM_CHANGED_SYSENTER_MSR \
+ | CPUM_CHANGED_HIDDEN_SEL_REGS \
+ | CPUM_CHANGED_CPUID )
+/** @} */
+
+VMMDECL(void) CPUMSetChangedFlags(PVMCPU pVCpu, uint32_t fChangedFlags);
+VMMR3DECL(uint32_t) CPUMR3RemEnter(PVMCPU pVCpu, uint32_t *puCpl);
+VMMR3DECL(void) CPUMR3RemLeave(PVMCPU pVCpu, bool fNoOutOfSyncSels);
+VMMDECL(bool) CPUMSupportsFXSR(PVM pVM);
+VMMDECL(bool) CPUMIsHostUsingSysEnter(PVM pVM);
+VMMDECL(bool) CPUMIsHostUsingSysCall(PVM pVM);
+VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCPU);
+VMMDECL(void) CPUMDeactivateGuestFPUState(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsGuestDebugStateActive(PVMCPU pVCpu);
+VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu);
+VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu);
+VMMDECL(void) CPUMDeactivateHyperDebugState(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestCPL(PVMCPU pVCpu);
+VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu);
+VMMDECL(uint32_t) CPUMGetGuestCodeBits(PVMCPU pVCpu);
+VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu);
+
+
+#ifdef IN_RING3
+/** @defgroup grp_cpum_r3 The CPU Monitor(/Manager) API
+ * @ingroup grp_cpum
+ * @{
+ */
+
+VMMR3DECL(int) CPUMR3Init(PVM pVM);
+VMMR3DECL(void) CPUMR3Relocate(PVM pVM);
+VMMR3DECL(int) CPUMR3Term(PVM pVM);
+VMMR3DECL(void) CPUMR3Reset(PVM pVM);
+VMMR3DECL(void) CPUMR3ResetCpu(PVMCPU pVCpu);
+VMMDECL(bool) CPUMR3IsStateRestorePending(PVM pVM);
+VMMR3DECL(void) CPUMR3SetHWVirtEx(PVM pVM, bool fHWVirtExEnabled);
+VMMR3DECL(int) CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd);
+VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdStdRCPtr(PVM pVM);
+VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdExtRCPtr(PVM pVM);
+VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdCentaurRCPtr(PVM pVM);
+VMMR3DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdDefRCPtr(PVM pVM);
+
+/** @} */
+#endif /* IN_RING3 */
+
+#ifdef IN_RC
+/** @defgroup grp_cpum_gc The CPU Monitor(/Manager) API
+ * @ingroup grp_cpum
+ * @{
+ */
+
+/**
+ * Calls a guest trap/interrupt handler directly
+ *
+ * Assumes a trap stack frame has already been setup on the guest's stack!
+ * This function does not return!
+ *
+ * @param pRegFrame Original trap/interrupt context
+ * @param selCS Code selector of handler
+ * @param pHandler GC virtual address of handler
+ * @param eflags Callee's EFLAGS
+ * @param selSS Stack selector for handler
+ * @param pEsp Stack address for handler
+ */
+DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTRCPTR pHandler,
+ uint32_t eflags, uint32_t selSS, RTRCPTR pEsp);
+
+/**
+ * Call guest V86 code directly.
+ *
+ * This function does not return!
+ *
+ * @param pRegFrame Original trap/interrupt context
+ */
+DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
+
+/** @} */
+#endif /* IN_RC */
+
+#ifdef IN_RING0
+/** @defgroup grp_cpum_r0 The CPU Monitor(/Manager) API
+ * @ingroup grp_cpum
+ * @{
+ */
+VMMR0DECL(int) CPUMR0ModuleInit(void);
+VMMR0DECL(int) CPUMR0ModuleTerm(void);
+VMMR0DECL(int) CPUMR0Init(PVM pVM);
+VMMR0DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0DECL(int) CPUMR0SaveGuestFPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0DECL(int) CPUMR0SaveGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
+VMMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
+VMMR0DECL(int) CPUMR0LoadHostDebugState(PVM pVM, PVMCPU pVCpu);
+VMMR0DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu);
+VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6);
+#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
+VMMR0DECL(void) CPUMR0SetLApic(PVM pVM, RTCPUID idHostCpu);
+#endif
+
+/** @} */
+#endif /* IN_RING0 */
+
+/** @} */
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/VBox/vmm/cpum.mac b/include/VBox/vmm/cpum.mac
new file mode 100644
index 00000000..8f906d06
--- /dev/null
+++ b/include/VBox/vmm/cpum.mac
@@ -0,0 +1,207 @@
+;; @file
+; CPUM - CPU Monitor, Assembly header file.
+;
+
+;
+; Copyright (C) 2006-2010 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; 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 ___VBox_vmm_cpum_mac__
+%define ___VBox_vmm_cpum_mac__
+
+;;
+; Registers frame.
+; This is used internally in TRPM, VMMSwitcher_GuestToHost_GuestCtx
+; and other places.
+struc CPUMCTXCORE
+ .eax resq 1
+ .ecx resq 1
+ .edx resq 1
+ .ebx resq 1
+ .esp resq 1
+ .ebp resq 1
+ .esi resq 1
+ .edi resq 1
+ .r8 resq 1
+ .r9 resq 1
+ .r10 resq 1
+ .r11 resq 1
+ .r12 resq 1
+ .r13 resq 1
+ .r14 resq 1
+ .r15 resq 1
+ .es.Sel resw 1
+ .es.PaddingSel resw 1
+ .es.ValidSel resw 1
+ .es.fFlags resw 1
+ .es.u64Base resq 1
+ .es.u32Limit resd 1
+ .es.Attr resd 1
+ .cs.Sel resw 1
+ .cs.PaddingSel resw 1
+ .cs.ValidSel resw 1
+ .cs.fFlags resw 1
+ .cs.u64Base resq 1
+ .cs.u32Limit resd 1
+ .cs.Attr resd 1
+ .ss.Sel resw 1
+ .ss.PaddingSel resw 1
+ .ss.ValidSel resw 1
+ .ss.fFlags resw 1
+ .ss.u64Base resq 1
+ .ss.u32Limit resd 1
+ .ss.Attr resd 1
+ .ds.Sel resw 1
+ .ds.PaddingSel resw 1
+ .ds.ValidSel resw 1
+ .ds.fFlags resw 1
+ .ds.u64Base resq 1
+ .ds.u32Limit resd 1
+ .ds.Attr resd 1
+ .fs.Sel resw 1
+ .fs.PaddingSel resw 1
+ .fs.ValidSel resw 1
+ .fs.fFlags resw 1
+ .fs.u64Base resq 1
+ .fs.u32Limit resd 1
+ .fs.Attr resd 1
+ .gs.Sel resw 1
+ .gs.PaddingSel resw 1
+ .gs.ValidSel resw 1
+ .gs.fFlags resw 1
+ .gs.u64Base resq 1
+ .gs.u32Limit resd 1
+ .gs.Attr resd 1
+ .eip resq 1
+ .eflags resq 1
+endstruc
+
+
+struc CPUMCTX
+ .fpu resb 512
+ .eax resq 1
+ .ecx resq 1
+ .edx resq 1
+ .ebx resq 1
+ .esp resq 1
+ .ebp resq 1
+ .esi resq 1
+ .edi resq 1
+ .r8 resq 1
+ .r9 resq 1
+ .r10 resq 1
+ .r11 resq 1
+ .r12 resq 1
+ .r13 resq 1
+ .r14 resq 1
+ .r15 resq 1
+ .es.Sel resw 1
+ .es.PaddingSel resw 1
+ .es.ValidSel resw 1
+ .es.fFlags resw 1
+ .es.u64Base resq 1
+ .es.u32Limit resd 1
+ .es.Attr resd 1
+ .cs.Sel resw 1
+ .cs.PaddingSel resw 1
+ .cs.ValidSel resw 1
+ .cs.fFlags resw 1
+ .cs.u64Base resq 1
+ .cs.u32Limit resd 1
+ .cs.Attr resd 1
+ .ss.Sel resw 1
+ .ss.PaddingSel resw 1
+ .ss.ValidSel resw 1
+ .ss.fFlags resw 1
+ .ss.u64Base resq 1
+ .ss.u32Limit resd 1
+ .ss.Attr resd 1
+ .ds.Sel resw 1
+ .ds.PaddingSel resw 1
+ .ds.ValidSel resw 1
+ .ds.fFlags resw 1
+ .ds.u64Base resq 1
+ .ds.u32Limit resd 1
+ .ds.Attr resd 1
+ .fs.Sel resw 1
+ .fs.PaddingSel resw 1
+ .fs.ValidSel resw 1
+ .fs.fFlags resw 1
+ .fs.u64Base resq 1
+ .fs.u32Limit resd 1
+ .fs.Attr resd 1
+ .gs.Sel resw 1
+ .gs.PaddingSel resw 1
+ .gs.ValidSel resw 1
+ .gs.fFlags resw 1
+ .gs.u64Base resq 1
+ .gs.u32Limit resd 1
+ .gs.Attr resd 1
+ .eip resq 1
+ .eflags resq 1
+ .cr0 resq 1
+ .cr2 resq 1
+ .cr3 resq 1
+ .cr4 resq 1
+ .dr resq 8
+ .gdtrPadding resw 3
+ .gdtr resw 0
+ .gdtr.cbGdt resw 1
+ .gdtr.pGdt resq 1
+ .idtrPadding resw 3
+ .idtr resw 0
+ .idtr.cbIdt resw 1
+ .idtr.pIdt resq 1
+ .ldtr.Sel resw 1
+ .ldtr.PaddingSel resw 1
+ .ldtr.ValidSel resw 1
+ .ldtr.fFlags resw 1
+ .ldtr.u64Base resq 1
+ .ldtr.u32Limit resd 1
+ .ldtr.Attr resd 1
+ .tr.Sel resw 1
+ .tr.PaddingSel resw 1
+ .tr.ValidSel resw 1
+ .tr.fFlags resw 1
+ .tr.u64Base resq 1
+ .tr.u32Limit resd 1
+ .tr.Attr resd 1
+ .SysEnter.cs resb 8
+ .SysEnter.eip resb 8
+ .SysEnter.esp resb 8
+ .msrEFER resb 8
+ .msrSTAR resb 8
+ .msrPAT resb 8
+ .msrLSTAR resb 8
+ .msrCSTAR resb 8
+ .msrSFMASK resb 8
+ .msrKERNELGSBASE resb 8
+ .au32SizePadding resb 32
+endstruc
+
+
+;;
+; Guest MSR state.
+struc CPUMCTXMSRS
+ .au64 resq 64
+endstruc
+
+
+%endif
diff --git a/include/VBox/vmm/cpumctx-v1_6.h b/include/VBox/vmm/cpumctx-v1_6.h
new file mode 100644
index 00000000..dbc5935d
--- /dev/null
+++ b/include/VBox/vmm/cpumctx-v1_6.h
@@ -0,0 +1,249 @@
+/** @file
+ * CPUM - CPU Monitor(/ Manager), Context Structures from v1.6 (saved state).
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_cpumctx_v1_6_h
+#define ___VBox_vmm_cpumctx_v1_6_h
+
+#include <iprt/x86.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @addgroup grp_cpum_ctx_v1_6 The CPUM Context Structures from v1.6
+ * @ingroup grp_cpum
+ * @{
+ */
+
+#pragma pack(1)
+/** IDTR from version 1.6 */
+typedef struct VBOXIDTR_VER1_6
+{
+ /** Size of the IDT. */
+ uint16_t cbIdt;
+ /** Address of the IDT. */
+ uint32_t pIdt;
+} VBOXIDTR_VER1_6;
+#pragma pack()
+
+#pragma pack(1)
+/** GDTR from version 1.6 */
+typedef struct VBOXGDTR_VER1_6
+{
+ /** Size of the GDT. */
+ uint16_t cbGdt;
+ /** Address of the GDT. */
+ uint32_t pGdt;
+} VBOXGDTR_VER1_6;
+#pragma pack()
+
+
+/**
+ * Selector hidden registers, for version 1.6 saved state.
+ */
+typedef struct CPUMSELREGHID_VER1_6
+{
+ /** Base register. */
+ uint32_t u32Base;
+ /** Limit (expanded). */
+ uint32_t u32Limit;
+ /** Flags.
+ * This is the high 32-bit word of the descriptor entry.
+ * Only the flags, dpl and type are used. */
+ X86DESCATTR Attr;
+} CPUMSELREGHID_VER1_6;
+
+/**
+ * CPU context, for version 1.6 saved state.
+ * @remarks PATM uses this, which is why it has to be here.
+ */
+# pragma pack(1)
+typedef struct CPUMCTX_VER1_6
+{
+ /** FPU state. (16-byte alignment)
+ * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
+ * actual format or convert it (waste of time). */
+ X86FXSTATE fpu;
+
+ /** CPUMCTXCORE Part.
+ * @{ */
+ union
+ {
+ uint32_t edi;
+ uint64_t rdi;
+ } CPUM_UNION_NAME(rdi);
+ union
+ {
+ uint32_t esi;
+ uint64_t rsi;
+ } CPUM_UNION_NAME(rsi);
+ union
+ {
+ uint32_t ebp;
+ uint64_t rbp;
+ } CPUM_UNION_NAME(rbp);
+ union
+ {
+ uint32_t eax;
+ uint64_t rax;
+ } CPUM_UNION_NAME(rax);
+ union
+ {
+ uint32_t ebx;
+ uint64_t rbx;
+ } CPUM_UNION_NAME(rbx);
+ union
+ {
+ uint32_t edx;
+ uint64_t rdx;
+ } CPUM_UNION_NAME(rdx);
+ union
+ {
+ uint32_t ecx;
+ uint64_t rcx;
+ } CPUM_UNION_NAME(rcx);
+ /** @note We rely on the exact layout, because we use lss esp, [] in the
+ * switcher. */
+ uint32_t esp;
+ RTSEL ss;
+ RTSEL ssPadding;
+ /* Note: no overlap with esp here. */
+ uint64_t rsp_notused;
+
+ RTSEL gs;
+ RTSEL gsPadding;
+ RTSEL fs;
+ RTSEL fsPadding;
+ RTSEL es;
+ RTSEL esPadding;
+ RTSEL ds;
+ RTSEL dsPadding;
+ RTSEL cs;
+ RTSEL csPadding[3]; /**< 3 words to force 8 byte alignment for the remainder. */
+
+ union
+ {
+ X86EFLAGS eflags;
+ X86RFLAGS rflags;
+ } CPUM_UNION_NAME(rflags);
+ union
+ {
+ uint32_t eip;
+ uint64_t rip;
+ } CPUM_UNION_NAME(rip);
+
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+
+ /** Hidden selector registers.
+ * @{ */
+ CPUMSELREGHID_VER1_6 esHid;
+ CPUMSELREGHID_VER1_6 csHid;
+ CPUMSELREGHID_VER1_6 ssHid;
+ CPUMSELREGHID_VER1_6 dsHid;
+ CPUMSELREGHID_VER1_6 fsHid;
+ CPUMSELREGHID_VER1_6 gsHid;
+ /** @} */
+
+ /** @} */
+
+ /** Control registers.
+ * @{ */
+ uint64_t cr0;
+ uint64_t cr2;
+ uint64_t cr3;
+ uint64_t cr4;
+ uint64_t cr8;
+ /** @} */
+
+ /** Debug registers.
+ * @{ */
+ uint64_t dr0;
+ uint64_t dr1;
+ uint64_t dr2;
+ uint64_t dr3;
+ uint64_t dr4; /**< @todo remove dr4 and dr5. */
+ uint64_t dr5;
+ uint64_t dr6;
+ uint64_t dr7;
+ /* DR8-15 are currently not supported */
+ /** @} */
+
+ /** Global Descriptor Table register. */
+ VBOXGDTR_VER1_6 gdtr;
+ uint16_t gdtrPadding;
+ uint32_t gdtrPadding64;/** @todo fix this hack */
+ /** Interrupt Descriptor Table register. */
+ VBOXIDTR_VER1_6 idtr;
+ uint16_t idtrPadding;
+ uint32_t idtrPadding64;/** @todo fix this hack */
+ /** The task register.
+ * Only the guest context uses all the members. */
+ RTSEL ldtr;
+ RTSEL ldtrPadding;
+ /** The task register.
+ * Only the guest context uses all the members. */
+ RTSEL tr;
+ RTSEL trPadding;
+
+ /** The sysenter msr registers.
+ * This member is not used by the hypervisor context. */
+ CPUMSYSENTER SysEnter;
+
+ /** System MSRs.
+ * @{ */
+ uint64_t msrEFER;
+ uint64_t msrSTAR;
+ uint64_t msrPAT;
+ uint64_t msrLSTAR;
+ uint64_t msrCSTAR;
+ uint64_t msrSFMASK;
+ uint64_t msrFSBASE;
+ uint64_t msrGSBASE;
+ uint64_t msrKERNELGSBASE;
+ /** @} */
+
+ /** Hidden selector registers.
+ * @{ */
+ CPUMSELREGHID_VER1_6 ldtrHid;
+ CPUMSELREGHID_VER1_6 trHid;
+ /** @} */
+
+ /** padding to get 32byte aligned size. */
+ uint32_t padding[2];
+} CPUMCTX_VER1_6;
+# pragma pack()
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/cpumctx.h b/include/VBox/vmm/cpumctx.h
new file mode 100644
index 00000000..35861823
--- /dev/null
+++ b/include/VBox/vmm/cpumctx.h
@@ -0,0 +1,477 @@
+/** @file
+ * CPUM - CPU Monitor(/ Manager), Context Structures.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_cpumctx_h
+#define ___VBox_vmm_cpumctx_h
+
+#ifndef VBOX_FOR_DTRACE_LIB
+# include <iprt/x86.h>
+# include <VBox/types.h>
+#else
+# pragma D depends_on library x86.d
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @addgroup grp_cpum_ctx The CPUM Context Structures
+ * @ingroup grp_cpum
+ * @{
+ */
+
+/**
+ * Selector hidden registers.
+ */
+typedef struct CPUMSELREG
+{
+ /** The selector register. */
+ RTSEL Sel;
+ /** Padding, don't use. */
+ RTSEL PaddingSel;
+ /** The selector which info resides in u64Base, u32Limit and Attr, provided
+ * that CPUMSELREG_FLAGS_VALID is set. */
+ RTSEL ValidSel;
+ /** Flags, see CPUMSELREG_FLAGS_XXX. */
+ uint16_t fFlags;
+
+ /** Base register.
+ *
+ * Long mode remarks:
+ * - Unused in long mode for CS, DS, ES, SS
+ * - 32 bits for FS & GS; FS(GS)_BASE msr used for the base address
+ * - 64 bits for TR & LDTR
+ */
+ uint64_t u64Base;
+ /** Limit (expanded). */
+ uint32_t u32Limit;
+ /** Flags.
+ * This is the high 32-bit word of the descriptor entry.
+ * Only the flags, dpl and type are used. */
+ X86DESCATTR Attr;
+} CPUMSELREG;
+
+/** @name CPUMSELREG_FLAGS_XXX - CPUMSELREG::fFlags values.
+ * @{ */
+#define CPUMSELREG_FLAGS_VALID UINT16_C(0x0001)
+#define CPUMSELREG_FLAGS_STALE UINT16_C(0x0002)
+#define CPUMSELREG_FLAGS_VALID_MASK UINT16_C(0x0003)
+/** @} */
+
+/** Checks if the hidden parts of the selector register are valid. */
+#ifdef VBOX_WITH_RAW_MODE_NOT_R0
+# define CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSelReg) \
+ ( ((a_pSelReg)->fFlags & CPUMSELREG_FLAGS_VALID) \
+ && ( (a_pSelReg)->ValidSel == (a_pSelReg)->Sel \
+ || ( (a_pVCpu) /*!= NULL*/ \
+ && (a_pSelReg)->ValidSel == ((a_pSelReg)->Sel & X86_SEL_MASK_OFF_RPL) \
+ && ((a_pSelReg)->Sel & X86_SEL_RPL) == 1 \
+ && ((a_pSelReg)->ValidSel & X86_SEL_RPL) == 0 \
+ && CPUMIsGuestInRawMode(a_pVCpu) \
+ ) \
+ ) \
+ )
+#else
+# define CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSelReg) \
+ ( ((a_pSelReg)->fFlags & CPUMSELREG_FLAGS_VALID) \
+ && (a_pSelReg)->ValidSel == (a_pSelReg)->Sel )
+#endif
+
+/** Old type used for the hidden register part.
+ * @deprecated */
+typedef CPUMSELREG CPUMSELREGHID;
+
+/**
+ * The sysenter register set.
+ */
+typedef struct CPUMSYSENTER
+{
+ /** Ring 0 cs.
+ * This value + 8 is the Ring 0 ss.
+ * This value + 16 is the Ring 3 cs.
+ * This value + 24 is the Ring 3 ss.
+ */
+ uint64_t cs;
+ /** Ring 0 eip. */
+ uint64_t eip;
+ /** Ring 0 esp. */
+ uint64_t esp;
+} CPUMSYSENTER;
+
+/**
+ * For compilers (like DTrace) that does not grok nameless unions, we have a
+ * little hack to make them palatable.
+ */
+#ifdef VBOX_FOR_DTRACE_LIB
+# define CPUM_UNION_NAME(a_Nm) a_Nm
+#elif defined(VBOX_WITHOUT_UNNAMED_UNIONS)
+# define CPUM_UNION_NAME(a_Nm) a_Nm
+#else
+# define CPUM_UNION_NAME(a_Nm)
+#endif
+
+
+/**
+ * CPU context core.
+ *
+ * @todo eliminate this structure!
+ */
+#pragma pack(1)
+typedef struct CPUMCTXCORE
+{
+ /** @name General Register.
+ * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
+ * an array starting a rax.
+ * @{ */
+ union
+ {
+ uint8_t al;
+ uint16_t ax;
+ uint32_t eax;
+ uint64_t rax;
+ } CPUM_UNION_NAME(rax);
+ union
+ {
+ uint8_t cl;
+ uint16_t cx;
+ uint32_t ecx;
+ uint64_t rcx;
+ } CPUM_UNION_NAME(rcx);
+ union
+ {
+ uint8_t dl;
+ uint16_t dx;
+ uint32_t edx;
+ uint64_t rdx;
+ } CPUM_UNION_NAME(rdx);
+ union
+ {
+ uint8_t bl;
+ uint16_t bx;
+ uint32_t ebx;
+ uint64_t rbx;
+ } CPUM_UNION_NAME(rbx);
+ union
+ {
+ uint16_t sp;
+ uint32_t esp;
+ uint64_t rsp;
+ } CPUM_UNION_NAME(rsp);
+ union
+ {
+ uint16_t bp;
+ uint32_t ebp;
+ uint64_t rbp;
+ } CPUM_UNION_NAME(rbp);
+ union
+ {
+ uint8_t sil;
+ uint16_t si;
+ uint32_t esi;
+ uint64_t rsi;
+ } CPUM_UNION_NAME(rsi);
+ union
+ {
+ uint8_t dil;
+ uint16_t di;
+ uint32_t edi;
+ uint64_t rdi;
+ } CPUM_UNION_NAME(rdi);
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ /** @} */
+
+ /** @name Segment registers.
+ * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
+ * an array starting a es.
+ * @{ */
+ CPUMSELREG es;
+ CPUMSELREG cs;
+ CPUMSELREG ss;
+ CPUMSELREG ds;
+ CPUMSELREG fs;
+ CPUMSELREG gs;
+ /** @} */
+
+ /** The program counter. */
+ union
+ {
+ uint16_t ip;
+ uint32_t eip;
+ uint64_t rip;
+ } CPUM_UNION_NAME(rip);
+
+ /** The flags register. */
+ union
+ {
+ X86EFLAGS eflags;
+ X86RFLAGS rflags;
+ } CPUM_UNION_NAME(rflags);
+
+} CPUMCTXCORE;
+#pragma pack()
+
+
+/**
+ * CPU context.
+ */
+#pragma pack(1) /* for VBOXIDTR / VBOXGDTR. */
+typedef struct CPUMCTX
+{
+ /** FPU state. (16-byte alignment)
+ * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
+ * actual format or convert it (waste of time). */
+ X86FXSTATE fpu;
+
+ /** CPUMCTXCORE Part.
+ * @{ */
+
+ /** @name General Register.
+ * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
+ * an array starting at rax.
+ * @{ */
+ union
+ {
+ uint8_t al;
+ uint16_t ax;
+ uint32_t eax;
+ uint64_t rax;
+ } CPUM_UNION_NAME(rax);
+ union
+ {
+ uint8_t cl;
+ uint16_t cx;
+ uint32_t ecx;
+ uint64_t rcx;
+ } CPUM_UNION_NAME(rcx);
+ union
+ {
+ uint8_t dl;
+ uint16_t dx;
+ uint32_t edx;
+ uint64_t rdx;
+ } CPUM_UNION_NAME(rdx);
+ union
+ {
+ uint8_t bl;
+ uint16_t bx;
+ uint32_t ebx;
+ uint64_t rbx;
+ } CPUM_UNION_NAME(rbx);
+ union
+ {
+ uint16_t sp;
+ uint32_t esp;
+ uint64_t rsp;
+ } CPUM_UNION_NAME(rsp);
+ union
+ {
+ uint16_t bp;
+ uint32_t ebp;
+ uint64_t rbp;
+ } CPUM_UNION_NAME(rbp);
+ union
+ {
+ uint8_t sil;
+ uint16_t si;
+ uint32_t esi;
+ uint64_t rsi;
+ } CPUM_UNION_NAME(rsi);
+ union
+ {
+ uint8_t dil;
+ uint16_t di;
+ uint32_t edi;
+ uint64_t rdi;
+ } CPUM_UNION_NAME(rdi);
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ /** @} */
+
+ /** @name Segment registers.
+ * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
+ * an array starting at es.
+ * @{ */
+ CPUMSELREG es;
+ CPUMSELREG cs;
+ CPUMSELREG ss;
+ CPUMSELREG ds;
+ CPUMSELREG fs;
+ CPUMSELREG gs;
+ /** @} */
+
+ /** The program counter. */
+ union
+ {
+ uint16_t ip;
+ uint32_t eip;
+ uint64_t rip;
+ } CPUM_UNION_NAME(rip);
+
+ /** The flags register. */
+ union
+ {
+ X86EFLAGS eflags;
+ X86RFLAGS rflags;
+ } CPUM_UNION_NAME(rflags);
+
+ /** @} */ /*(CPUMCTXCORE)*/
+
+
+ /** @name Control registers.
+ * @{ */
+ uint64_t cr0;
+ uint64_t cr2;
+ uint64_t cr3;
+ uint64_t cr4;
+ /** @} */
+
+ /** Debug registers.
+ * @remarks DR4 and DR5 should not be used since they are aliases for
+ * DR6 and DR7 respectively on both AMD and Intel CPUs.
+ * @remarks DR8-15 are currently not supported by AMD or Intel, so
+ * neither do we.
+ */
+ uint64_t dr[8];
+
+ /** Padding before the structure so the 64-bit member is correctly aligned.
+ * @todo fix this structure! */
+ uint16_t gdtrPadding[3];
+ /** Global Descriptor Table register. */
+ VBOXGDTR gdtr;
+
+ /** Padding before the structure so the 64-bit member is correctly aligned.
+ * @todo fix this structure! */
+ uint16_t idtrPadding[3];
+ /** Interrupt Descriptor Table register. */
+ VBOXIDTR idtr;
+
+ /** The task register.
+ * Only the guest context uses all the members. */
+ CPUMSELREG ldtr;
+ /** The task register.
+ * Only the guest context uses all the members. */
+ CPUMSELREG tr;
+
+ /** The sysenter msr registers.
+ * This member is not used by the hypervisor context. */
+ CPUMSYSENTER SysEnter;
+
+ /** @name System MSRs.
+ * @{ */
+ uint64_t msrEFER;
+ uint64_t msrSTAR; /**< Legacy syscall eip, cs & ss. */
+ uint64_t msrPAT; /**< Page attribute table. */
+ uint64_t msrLSTAR; /**< 64 bits mode syscall rip. */
+ uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */
+ uint64_t msrSFMASK; /**< syscall flag mask. */
+ uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */
+ /** @} */
+
+ /** Size padding. */
+ uint32_t au32SizePadding[8];
+} CPUMCTX;
+#pragma pack()
+
+#ifndef VBOX_FOR_DTRACE_LIB
+
+/**
+ * Gets the CPUMCTXCORE part of a CPUMCTX.
+ */
+# define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax)
+
+/**
+ * Gets the first selector register of a CPUMCTX.
+ *
+ * Use this with X86_SREG_COUNT to loop thru the selector registers.
+ */
+# define CPUMCTX_FIRST_SREG(a_pCtx) (&(a_pCtx)->es)
+
+#endif /* !VBOX_FOR_DTRACE_LIB */
+
+/**
+ * Additional guest MSRs (i.e. not part of the CPU context structure).
+ *
+ * @remarks Never change the order here because of the saved stated! The size
+ * can in theory be changed, but keep older VBox versions in mind.
+ */
+typedef union CPUMCTXMSRS
+{
+ struct
+ {
+ uint64_t TscAux; /**< MSR_K8_TSC_AUX */
+ uint64_t MiscEnable; /**< MSR_IA32_MISC_ENABLE */
+ uint64_t MtrrDefType; /**< IA32_MTRR_DEF_TYPE */
+ uint64_t MtrrFix64K_00000; /**< IA32_MTRR_FIX16K_80000 */
+ uint64_t MtrrFix16K_80000; /**< IA32_MTRR_FIX16K_80000 */
+ uint64_t MtrrFix16K_A0000; /**< IA32_MTRR_FIX16K_A0000 */
+ uint64_t MtrrFix4K_C0000; /**< IA32_MTRR_FIX4K_C0000 */
+ uint64_t MtrrFix4K_C8000; /**< IA32_MTRR_FIX4K_C8000 */
+ uint64_t MtrrFix4K_D0000; /**< IA32_MTRR_FIX4K_D0000 */
+ uint64_t MtrrFix4K_D8000; /**< IA32_MTRR_FIX4K_D8000 */
+ uint64_t MtrrFix4K_E0000; /**< IA32_MTRR_FIX4K_E0000 */
+ uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */
+ uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */
+ uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */
+ } msr;
+ uint64_t au64[64];
+} CPUMCTXMSRS;
+/** Pointer to the guest MSR state. */
+typedef CPUMCTXMSRS *PCPUMCTXMSRS;
+/** Pointer to the const guest MSR state. */
+typedef const CPUMCTXMSRS *PCCPUMCTXMSRS;
+
+/**
+ * The register set returned by a CPUID operation.
+ */
+typedef struct CPUMCPUID
+{
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+} CPUMCPUID;
+/** Pointer to a CPUID leaf. */
+typedef CPUMCPUID *PCPUMCPUID;
+/** Pointer to a const CPUID leaf. */
+typedef const CPUMCPUID *PCCPUMCPUID;
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/cpumdis.h b/include/VBox/vmm/cpumdis.h
new file mode 100644
index 00000000..9aa509a3
--- /dev/null
+++ b/include/VBox/vmm/cpumdis.h
@@ -0,0 +1,48 @@
+/** @file
+ * CPUM - Disassembler.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_cpumdis_h
+#define ___VBox_vmm_cpumdis_h
+
+#include <VBox/vmm/cpum.h>
+#include <iprt/x86.h>
+#include <VBox/dis.h>
+
+
+RT_C_DECLS_BEGIN
+/** @addtogroup grp_cpum
+ * @{
+ */
+
+#ifdef IN_RING3
+VMMR3DECL(int) CPUMR3DisasmInstrCPU(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTGCPTR GCPtrPC, PDISCPUSTATE pCpu, const char *pszPrefix);
+#endif
+
+/** @} */
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/VBox/vmm/csam.h b/include/VBox/vmm/csam.h
new file mode 100644
index 00000000..675cac7f
--- /dev/null
+++ b/include/VBox/vmm/csam.h
@@ -0,0 +1,305 @@
+/** @file
+ * CSAM - Guest OS Code Scanning and Analyis Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_csam_h
+#define ___VBox_vmm_csam_h
+
+#include <VBox/types.h>
+
+
+/** @defgroup grp_csam The Code Scanning and Analysis API
+ * @{
+ */
+
+/**
+ * CSAM monitoring tag
+ * For use with CSAMR3MonitorPage
+ */
+typedef enum CSAMTAG
+{
+ CSAM_TAG_INVALID = 0,
+ CSAM_TAG_REM,
+ CSAM_TAG_PATM,
+ CSAM_TAG_CSAM,
+ CSAM_TAG_32BIT_HACK = 0x7fffffff
+} CSAMTAG;
+
+
+RT_C_DECLS_BEGIN
+
+
+/**
+ * Check if this page needs to be analysed by CSAM.
+ *
+ * This function should only be called for supervisor pages and
+ * only when CSAM is enabled. Leaving these selection criteria
+ * to the caller simplifies the interface (PTE passing).
+ *
+ * Note the the page has not yet been synced, so the TLB trick
+ * (which wasn't ever active anyway) cannot be applied.
+ *
+ * @returns true if the page should be marked not present because
+ * CSAM want need to scan it.
+ * @returns false if the page was already scanned.
+ * @param pVM The VM to operate on.
+ * @param GCPtr GC pointer of page table entry
+ */
+VMMDECL(bool) CSAMDoesPageNeedScanning(PVM pVM, RTRCUINTPTR GCPtr);
+
+/**
+ * Check if this page was previously scanned by CSAM
+ *
+ * @returns true -> scanned, false -> not scanned
+ * @param pVM The VM to operate on.
+ * @param pPage GC page address
+ */
+VMMDECL(bool) CSAMIsPageScanned(PVM pVM, RTRCPTR pPage);
+
+/**
+ * Mark a page as scanned/not scanned
+ *
+ * @note: we always mark it as scanned, even if we haven't completely done so
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pPage GC page address (not necessarily aligned)
+ * @param fScanned Mark as scanned or not scanned
+ *
+ */
+VMMDECL(int) CSAMMarkPage(PVM pVM, RTRCUINTPTR pPage, bool fScanned);
+
+
+/**
+ * Remember a possible code page for later inspection
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param GCPtr GC pointer of page
+ */
+VMMDECL(void) CSAMMarkPossibleCodePage(PVM pVM, RTRCPTR GCPtr);
+
+/**
+ * Query CSAM state (enabled/disabled)
+ *
+ * @returns 0 - disabled, 1 - enabled
+ * @param pVM The VM to operate on.
+ */
+#define CSAMIsEnabled(pVM) (pVM->fCSAMEnabled && EMIsRawRing0Enabled(pVM))
+
+/**
+ * Turn on code scanning
+ *
+ * @returns VBox status code. (trap handled or not)
+ * @param pVM The VM to operate on.
+ */
+VMMDECL(int) CSAMEnableScanning(PVM pVM);
+
+/**
+ * Turn off code scanning
+ *
+ * @returns VBox status code. (trap handled or not)
+ * @param pVM The VM to operate on.
+ */
+VMMDECL(int) CSAMDisableScanning(PVM pVM);
+
+
+/**
+ * Check if this page needs to be analysed by CSAM
+ *
+ * @returns 0 - disabled, 1 - enabled
+ * @param pVM The VM to operate on.
+ * @param pvFault Fault address
+ */
+VMMDECL(int) CSAMExecFault(PVM pVM, RTRCPTR pvFault);
+
+/**
+ * Check if we've scanned this instruction before. If true, then we can emulate
+ * it instead of returning to ring 3.
+ *
+ * @returns boolean
+ * @param pVM The VM to operate on.
+ * @param GCPtr GC pointer of page table entry
+ */
+VMMDECL(bool) CSAMIsKnownDangerousInstr(PVM pVM, RTRCUINTPTR GCPtr);
+
+
+#ifdef IN_RING3
+/** @defgroup grp_csam_r3 The Code Scanning and Analysis API
+ * @ingroup grp_csam
+ * @{
+ */
+
+/**
+ * Query CSAM state (enabled/disabled)
+ *
+ * @returns 0 - disabled, 1 - enabled
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(int) CSAMR3IsEnabled(PVM pVM);
+
+/**
+ * Initializes the csam.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(int) CSAMR3Init(PVM pVM);
+
+/**
+ * Applies relocations to data and code managed by this
+ * component. This function will be called at init and
+ * whenever the VMM need to relocate it self inside the GC.
+ *
+ * The csam will update the addresses used by the switcher.
+ *
+ * @param pVM The VM.
+ * @param offDelta Relocation delta.
+ */
+VMMR3DECL(void) CSAMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+
+/**
+ * Terminates the csam.
+ *
+ * Termination means cleaning up and freeing all resources,
+ * the VM it self is at this point powered off or suspended.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(int) CSAMR3Term(PVM pVM);
+
+/**
+ * CSAM reset callback.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM which is reset.
+ */
+VMMR3DECL(int) CSAMR3Reset(PVM pVM);
+
+
+/**
+ * Notify CSAM of a page flush
+ *
+ * @returns VBox status code
+ * @param pVM The VM to operate on.
+ * @param addr GC address of the page to flush
+ */
+VMMR3DECL(int) CSAMR3FlushPage(PVM pVM, RTRCPTR addr);
+
+/**
+ * Remove a CSAM monitored page. Use with care!
+ *
+ * @returns VBox status code
+ * @param pVM The VM to operate on.
+ * @param addr GC address of the page to flush
+ */
+VMMR3DECL(int) CSAMR3RemovePage(PVM pVM, RTRCPTR addr);
+
+/**
+ * Scan and analyse code
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pCtxCore CPU context
+ * @param pInstrGC Instruction pointer
+ */
+VMMR3DECL(int) CSAMR3CheckCodeEx(PVM pVM, PCPUMCTXCORE pCtxCore, RTRCPTR pInstrGC);
+
+/**
+ * Scan and analyse code
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstrGC Instruction pointer (0:32 virtual address)
+ */
+VMMR3DECL(int) CSAMR3CheckCode(PVM pVM, RTRCPTR pInstrGC);
+
+/**
+ * Mark an instruction in a page as scanned/not scanned
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstr Instruction pointer
+ * @param cbInstr Instruction size
+ * @param fScanned Mark as scanned or not
+ */
+VMMR3DECL(int) CSAMR3MarkCode(PVM pVM, RTRCPTR pInstr, uint32_t cbInstr, bool fScanned);
+
+/**
+ * Perform any pending actions
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pVCpu The VMCPU to operate on.
+ */
+VMMR3DECL(int) CSAMR3DoPendingAction(PVM pVM, PVMCPU pVCpu);
+
+/**
+ * Monitors a code page (if not already monitored)
+ *
+ * @returns VBox status code
+ * @param pVM The VM to operate on.
+ * @param pPageAddrGC The page to monitor
+ * @param enmTag Monitor tag
+ */
+VMMR3DECL(int) CSAMR3MonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag);
+
+/**
+ * Unmonitors a code page
+ *
+ * @returns VBox status code
+ * @param pVM The VM to operate on.
+ * @param pPageAddrGC The page to monitor
+ * @param enmTag Monitor tag
+ */
+VMMR3DECL(int) CSAMR3UnmonitorPage(PVM pVM, RTRCPTR pPageAddrGC, CSAMTAG enmTag);
+
+/**
+ * Analyse interrupt and trap gates
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param iGate Start gate
+ * @param cGates Number of gates to check
+ */
+VMMR3DECL(int) CSAMR3CheckGates(PVM pVM, uint32_t iGate, uint32_t cGates);
+
+/**
+ * Record previous call instruction addresses
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param GCPtrCall Call address
+ */
+VMMR3DECL(int) CSAMR3RecordCallAddress(PVM pVM, RTRCPTR GCPtrCall);
+
+/** @} */
+#endif
+
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/dbgf.h b/include/VBox/vmm/dbgf.h
new file mode 100644
index 00000000..65bb94c7
--- /dev/null
+++ b/include/VBox/vmm/dbgf.h
@@ -0,0 +1,1658 @@
+/** @file
+ * DBGF - Debugger Facility.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_dbgf_h
+#define ___VBox_vmm_dbgf_h
+
+#include <VBox/types.h>
+#include <VBox/log.h> /* LOG_ENABLED */
+#include <VBox/vmm/vmm.h>
+#include <VBox/vmm/dbgfsel.h>
+
+#include <iprt/stdarg.h>
+#include <iprt/dbg.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_dbgf The Debugger Facility API
+ * @{
+ */
+
+#if defined(IN_RC) || defined(IN_RING0)
+/** @addgroup grp_dbgf_rz The RZ DBGF API
+ * @ingroup grp_dbgf
+ * @{
+ */
+VMMRZDECL(int) DBGFRZTrap01Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCUINTREG uDr6);
+VMMRZDECL(int) DBGFRZTrap03Handler(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+/** @} */
+#endif
+
+
+
+#ifdef IN_RING3
+
+/**
+ * Mixed address.
+ */
+typedef struct DBGFADDRESS
+{
+ /** The flat address. */
+ RTGCUINTPTR FlatPtr;
+ /** The selector offset address. */
+ RTGCUINTPTR off;
+ /** The selector. DBGF_SEL_FLAT is a legal value. */
+ RTSEL Sel;
+ /** Flags describing further details about the address. */
+ uint16_t fFlags;
+} DBGFADDRESS;
+/** Pointer to a mixed address. */
+typedef DBGFADDRESS *PDBGFADDRESS;
+/** Pointer to a const mixed address. */
+typedef const DBGFADDRESS *PCDBGFADDRESS;
+
+/** @name DBGFADDRESS Flags.
+ * @{ */
+/** A 16:16 far address. */
+#define DBGFADDRESS_FLAGS_FAR16 0
+/** A 16:32 far address. */
+#define DBGFADDRESS_FLAGS_FAR32 1
+/** A 16:64 far address. */
+#define DBGFADDRESS_FLAGS_FAR64 2
+/** A flat address. */
+#define DBGFADDRESS_FLAGS_FLAT 3
+/** A physical address. */
+#define DBGFADDRESS_FLAGS_PHYS 4
+/** A physical address. */
+#define DBGFADDRESS_FLAGS_RING0 5
+/** The address type mask. */
+#define DBGFADDRESS_FLAGS_TYPE_MASK 7
+
+/** Set if the address is valid. */
+#define DBGFADDRESS_FLAGS_VALID RT_BIT(3)
+
+/** The address is within the hypervisor memoary area (HMA).
+ * If not set, the address can be assumed to be a guest address. */
+#define DBGFADDRESS_FLAGS_HMA RT_BIT(4)
+
+/** Checks if the mixed address is flat or not. */
+#define DBGFADDRESS_IS_FLAT(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FLAT )
+/** Checks if the mixed address is flat or not. */
+#define DBGFADDRESS_IS_PHYS(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_PHYS )
+/** Checks if the mixed address is far 16:16 or not. */
+#define DBGFADDRESS_IS_FAR16(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR16 )
+/** Checks if the mixed address is far 16:32 or not. */
+#define DBGFADDRESS_IS_FAR32(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR32 )
+/** Checks if the mixed address is far 16:64 or not. */
+#define DBGFADDRESS_IS_FAR64(pAddress) ( ((pAddress)->fFlags & DBGFADDRESS_FLAGS_TYPE_MASK) == DBGFADDRESS_FLAGS_FAR64 )
+/** Checks if the mixed address is valid. */
+#define DBGFADDRESS_IS_VALID(pAddress) ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_VALID) )
+/** Checks if the address is flagged as within the HMA. */
+#define DBGFADDRESS_IS_HMA(pAddress) ( !!((pAddress)->fFlags & DBGFADDRESS_FLAGS_HMA) )
+/** @} */
+
+VMMR3DECL(int) DBGFR3AddrFromSelOff(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, RTSEL Sel, RTUINTPTR off);
+VMMR3DECL(int) DBGFR3AddrFromSelInfoOff(PVM pVM, PDBGFADDRESS pAddress, PCDBGFSELINFO pSelInfo, RTUINTPTR off);
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromFlat(PVM pVM, PDBGFADDRESS pAddress, RTGCUINTPTR FlatPtr);
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrFromPhys(PVM pVM, PDBGFADDRESS pAddress, RTGCPHYS PhysAddr);
+VMMR3DECL(bool) DBGFR3AddrIsValid(PVM pVM, PCDBGFADDRESS pAddress);
+VMMR3DECL(int) DBGFR3AddrToPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTGCPHYS pGCPhys);
+VMMR3DECL(int) DBGFR3AddrToHostPhys(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, PRTHCPHYS pHCPhys);
+VMMR3DECL(int) DBGFR3AddrToVolatileR3Ptr(PVM pVM, VMCPUID idCpu, PDBGFADDRESS pAddress, bool fReadOnly, void **ppvR3Ptr);
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrAdd(PDBGFADDRESS pAddress, RTGCUINTPTR uAddend);
+VMMR3DECL(PDBGFADDRESS) DBGFR3AddrSub(PDBGFADDRESS pAddress, RTGCUINTPTR uSubtrahend);
+
+#endif /* IN_RING3 */
+
+
+
+/**
+ * VMM Debug Event Type.
+ */
+typedef enum DBGFEVENTTYPE
+{
+ /** Halt completed.
+ * This notifies that a halt command have been successfully completed.
+ */
+ DBGFEVENT_HALT_DONE = 0,
+ /** Detach completed.
+ * This notifies that the detach command have been successfully completed.
+ */
+ DBGFEVENT_DETACH_DONE,
+ /** The command from the debugger is not recognized.
+ * This means internal error or half implemented features.
+ */
+ DBGFEVENT_INVALID_COMMAND,
+
+
+ /** Fatal error.
+ * This notifies a fatal error in the VMM and that the debugger get's a
+ * chance to first hand information about the the problem.
+ */
+ DBGFEVENT_FATAL_ERROR = 100,
+ /** Breakpoint Hit.
+ * This notifies that a breakpoint installed by the debugger was hit. The
+ * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
+ */
+ DBGFEVENT_BREAKPOINT,
+ /** Breakpoint Hit in the Hypervisor.
+ * This notifies that a breakpoint installed by the debugger was hit. The
+ * identifier of the breakpoint can be found in the DBGFEVENT::u::Bp::iBp member.
+ */
+ DBGFEVENT_BREAKPOINT_HYPER,
+ /** Assertion in the Hypervisor (breakpoint instruction).
+ * This notifies that a breakpoint instruction was hit in the hypervisor context.
+ */
+ DBGFEVENT_ASSERTION_HYPER,
+ /** Single Stepped.
+ * This notifies that a single step operation was completed.
+ */
+ DBGFEVENT_STEPPED,
+ /** Single Stepped.
+ * This notifies that a hypervisor single step operation was completed.
+ */
+ DBGFEVENT_STEPPED_HYPER,
+ /** The developer have used the DBGFSTOP macro or the PDMDeviceDBGFSTOP function
+ * to bring up the debugger at a specific place.
+ */
+ DBGFEVENT_DEV_STOP,
+ /** The VM is terminating.
+ * When this notification is received, the debugger thread should detach ASAP.
+ */
+ DBGFEVENT_TERMINATING,
+
+ /** The usual 32-bit hack. */
+ DBGFEVENT_32BIT_HACK = 0x7fffffff
+} DBGFEVENTTYPE;
+
+
+/**
+ * The context of an event.
+ */
+typedef enum DBGFEVENTCTX
+{
+ /** The usual invalid entry. */
+ DBGFEVENTCTX_INVALID = 0,
+ /** Raw mode. */
+ DBGFEVENTCTX_RAW,
+ /** Recompiled mode. */
+ DBGFEVENTCTX_REM,
+ /** VMX / AVT mode. */
+ DBGFEVENTCTX_HWACCL,
+ /** Hypervisor context. */
+ DBGFEVENTCTX_HYPER,
+ /** Other mode */
+ DBGFEVENTCTX_OTHER,
+
+ /** The usual 32-bit hack */
+ DBGFEVENTCTX_32BIT_HACK = 0x7fffffff
+} DBGFEVENTCTX;
+
+/**
+ * VMM Debug Event.
+ */
+typedef struct DBGFEVENT
+{
+ /** Type. */
+ DBGFEVENTTYPE enmType;
+ /** Context */
+ DBGFEVENTCTX enmCtx;
+ /** Type specific data. */
+ union
+ {
+ /** Fatal error details. */
+ struct
+ {
+ /** The GC return code. */
+ int rc;
+ } FatalError;
+
+ /** Source location. */
+ struct
+ {
+ /** File name. */
+ R3PTRTYPE(const char *) pszFile;
+ /** Function name. */
+ R3PTRTYPE(const char *) pszFunction;
+ /** Message. */
+ R3PTRTYPE(const char *) pszMessage;
+ /** Line number. */
+ unsigned uLine;
+ } Src;
+
+ /** Assertion messages. */
+ struct
+ {
+ /** The first message. */
+ R3PTRTYPE(const char *) pszMsg1;
+ /** The second message. */
+ R3PTRTYPE(const char *) pszMsg2;
+ } Assert;
+
+ /** Breakpoint. */
+ struct DBGFEVENTBP
+ {
+ /** The identifier of the breakpoint which was hit. */
+ RTUINT iBp;
+ } Bp;
+ /** Padding for ensuring that the structure is 8 byte aligned. */
+ uint64_t au64Padding[4];
+ } u;
+} DBGFEVENT;
+/** Pointer to VMM Debug Event. */
+typedef DBGFEVENT *PDBGFEVENT;
+/** Pointer to const VMM Debug Event. */
+typedef const DBGFEVENT *PCDBGFEVENT;
+
+#ifdef IN_RING3 /* The event API only works in ring-3. */
+
+/** @def DBGFSTOP
+ * Stops the debugger raising a DBGFEVENT_DEVELOPER_STOP event.
+ *
+ * @returns VBox status code which must be propagated up to EM if not VINF_SUCCESS.
+ * @param pVM VM Handle.
+ */
+# ifdef VBOX_STRICT
+# define DBGFSTOP(pVM) DBGFR3EventSrc(pVM, DBGFEVENT_DEV_STOP, __FILE__, __LINE__, __PRETTY_FUNCTION__, NULL)
+# else
+# define DBGFSTOP(pVM) VINF_SUCCESS
+# endif
+
+VMMR3DECL(int) DBGFR3Init(PVM pVM);
+VMMR3DECL(int) DBGFR3Term(PVM pVM);
+VMMR3DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3DECL(int) DBGFR3VMMForcedAction(PVM pVM);
+VMMR3DECL(int) DBGFR3Event(PVM pVM, DBGFEVENTTYPE enmEvent);
+VMMR3DECL(int) DBGFR3EventSrc(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, ...);
+VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, va_list args);
+VMMR3DECL(int) DBGFR3EventAssertion(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszMsg1, const char *pszMsg2);
+VMMR3DECL(int) DBGFR3EventBreakpoint(PVM pVM, DBGFEVENTTYPE enmEvent);
+VMMR3DECL(int) DBGFR3Attach(PVM pVM);
+VMMR3DECL(int) DBGFR3Detach(PVM pVM);
+VMMR3DECL(int) DBGFR3EventWait(PVM pVM, RTMSINTERVAL cMillies, PCDBGFEVENT *ppEvent);
+VMMR3DECL(int) DBGFR3Halt(PVM pVM);
+VMMR3DECL(bool) DBGFR3IsHalted(PVM pVM);
+VMMR3DECL(bool) DBGFR3CanWait(PVM pVM);
+VMMR3DECL(int) DBGFR3Resume(PVM pVM);
+VMMR3DECL(int) DBGFR3Step(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(int) DBGFR3PrgStep(PVMCPU pVCpu);
+
+#endif /* IN_RING3 */
+
+
+
+/** Breakpoint type. */
+typedef enum DBGFBPTYPE
+{
+ /** Free breakpoint entry. */
+ DBGFBPTYPE_FREE = 0,
+ /** Debug register. */
+ DBGFBPTYPE_REG,
+ /** INT 3 instruction. */
+ DBGFBPTYPE_INT3,
+ /** Recompiler. */
+ DBGFBPTYPE_REM,
+ /** ensure 32-bit size. */
+ DBGFBPTYPE_32BIT_HACK = 0x7fffffff
+} DBGFBPTYPE;
+
+
+/**
+ * A Breakpoint.
+ */
+typedef struct DBGFBP
+{
+ /** The number of breakpoint hits. */
+ uint64_t cHits;
+ /** The hit number which starts to trigger the breakpoint. */
+ uint64_t iHitTrigger;
+ /** The hit number which stops triggering the breakpoint (disables it).
+ * Use ~(uint64_t)0 if it should never stop. */
+ uint64_t iHitDisable;
+ /** The Flat GC address of the breakpoint.
+ * (PC register value if REM type?) */
+ RTGCUINTPTR GCPtr;
+ /** The breakpoint id. */
+ uint32_t iBp;
+ /** The breakpoint status - enabled or disabled. */
+ bool fEnabled;
+
+ /** The breakpoint type. */
+ DBGFBPTYPE enmType;
+
+#if GC_ARCH_BITS == 64
+ uint32_t u32Padding;
+#endif
+
+ /** Union of type specific data. */
+ union
+ {
+ /** Debug register data. */
+ struct DBGFBPREG
+ {
+ /** The debug register number. */
+ uint8_t iReg;
+ /** The access type (one of the X86_DR7_RW_* value). */
+ uint8_t fType;
+ /** The access size. */
+ uint8_t cb;
+ } Reg;
+ /** Recompiler breakpoint data. */
+ struct DBGFBPINT3
+ {
+ /** The byte value we replaced by the INT 3 instruction. */
+ uint8_t bOrg;
+ } Int3;
+
+ /** Recompiler breakpoint data. */
+ struct DBGFBPREM
+ {
+ /** nothing yet */
+ uint8_t fDummy;
+ } Rem;
+ /** Paddind to ensure that the size is identical on win32 and linux. */
+ uint64_t u64Padding;
+ } u;
+} DBGFBP;
+
+/** Pointer to a breakpoint. */
+typedef DBGFBP *PDBGFBP;
+/** Pointer to a const breakpoint. */
+typedef const DBGFBP *PCDBGFBP;
+
+#ifdef IN_RING3 /* The breakpoint management API is only available in ring-3. */
+VMMR3DECL(int) DBGFR3BpSet(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
+VMMR3DECL(int) DBGFR3BpSetReg(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable,
+ uint8_t fType, uint8_t cb, uint32_t *piBp);
+VMMR3DECL(int) DBGFR3BpSetREM(PVM pVM, PCDBGFADDRESS pAddress, uint64_t iHitTrigger, uint64_t iHitDisable, uint32_t *piBp);
+VMMR3DECL(int) DBGFR3BpClear(PVM pVM, uint32_t iBp);
+VMMR3DECL(int) DBGFR3BpEnable(PVM pVM, uint32_t iBp);
+VMMR3DECL(int) DBGFR3BpDisable(PVM pVM, uint32_t iBp);
+
+/**
+ * Breakpoint enumeration callback function.
+ *
+ * @returns VBox status code. Any failure will stop the enumeration.
+ * @param pVM The VM handle.
+ * @param pvUser The user argument.
+ * @param pBp Pointer to the breakpoint information. (readonly)
+ */
+typedef DECLCALLBACK(int) FNDBGFBPENUM(PVM pVM, void *pvUser, PCDBGFBP pBp);
+/** Pointer to a breakpoint enumeration callback function. */
+typedef FNDBGFBPENUM *PFNDBGFBPENUM;
+
+VMMR3DECL(int) DBGFR3BpEnum(PVM pVM, PFNDBGFBPENUM pfnCallback, void *pvUser);
+#endif /* IN_RING3 */
+
+VMMDECL(RTGCUINTREG) DBGFBpGetDR7(PVM pVM);
+VMMDECL(RTGCUINTREG) DBGFBpGetDR0(PVM pVM);
+VMMDECL(RTGCUINTREG) DBGFBpGetDR1(PVM pVM);
+VMMDECL(RTGCUINTREG) DBGFBpGetDR2(PVM pVM);
+VMMDECL(RTGCUINTREG) DBGFBpGetDR3(PVM pVM);
+VMMDECL(bool) DBGFIsStepping(PVMCPU pVCpu);
+
+
+#ifdef IN_RING3 /* The CPU mode API only works in ring-3. */
+VMMR3DECL(CPUMMODE) DBGFR3CpuGetMode(PVM pVM, VMCPUID idCpu);
+#endif
+
+
+
+#ifdef IN_RING3 /* The info callbacks API only works in ring-3. */
+
+/**
+ * Info helper callback structure.
+ */
+typedef struct DBGFINFOHLP
+{
+ /**
+ * Print formatted string.
+ *
+ * @param pHlp Pointer to this structure.
+ * @param pszFormat The format string.
+ * @param ... Arguments.
+ */
+ DECLCALLBACKMEMBER(void, pfnPrintf)(PCDBGFINFOHLP pHlp, const char *pszFormat, ...);
+
+ /**
+ * Print formatted string.
+ *
+ * @param pHlp Pointer to this structure.
+ * @param pszFormat The format string.
+ * @param args Argument list.
+ */
+ DECLCALLBACKMEMBER(void, pfnPrintfV)(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list args);
+} DBGFINFOHLP;
+
+
+/**
+ * Info handler, device version.
+ *
+ * @param pDevIns The device instance which registered the info.
+ * @param pHlp Callback functions for doing output.
+ * @param pszArgs Argument string. Optional and specific to the handler.
+ */
+typedef DECLCALLBACK(void) FNDBGFHANDLERDEV(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
+/** Pointer to a FNDBGFHANDLERDEV function. */
+typedef FNDBGFHANDLERDEV *PFNDBGFHANDLERDEV;
+
+/**
+ * Info handler, USB device version.
+ *
+ * @param pUsbIns The USB device instance which registered the info.
+ * @param pHlp Callback functions for doing output.
+ * @param pszArgs Argument string. Optional and specific to the handler.
+ */
+typedef DECLCALLBACK(void) FNDBGFHANDLERUSB(PPDMUSBINS pUsbIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
+/** Pointer to a FNDBGFHANDLERUSB function. */
+typedef FNDBGFHANDLERUSB *PFNDBGFHANDLERUSB;
+
+/**
+ * Info handler, driver version.
+ *
+ * @param pDrvIns The driver instance which registered the info.
+ * @param pHlp Callback functions for doing output.
+ * @param pszArgs Argument string. Optional and specific to the handler.
+ */
+typedef DECLCALLBACK(void) FNDBGFHANDLERDRV(PPDMDRVINS pDrvIns, PCDBGFINFOHLP pHlp, const char *pszArgs);
+/** Pointer to a FNDBGFHANDLERDRV function. */
+typedef FNDBGFHANDLERDRV *PFNDBGFHANDLERDRV;
+
+/**
+ * Info handler, internal version.
+ *
+ * @param pVM The VM handle.
+ * @param pHlp Callback functions for doing output.
+ * @param pszArgs Argument string. Optional and specific to the handler.
+ */
+typedef DECLCALLBACK(void) FNDBGFHANDLERINT(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
+/** Pointer to a FNDBGFHANDLERINT function. */
+typedef FNDBGFHANDLERINT *PFNDBGFHANDLERINT;
+
+/**
+ * Info handler, external version.
+ *
+ * @param pvUser User argument.
+ * @param pHlp Callback functions for doing output.
+ * @param pszArgs Argument string. Optional and specific to the handler.
+ */
+typedef DECLCALLBACK(void) FNDBGFHANDLEREXT(void *pvUser, PCDBGFINFOHLP pHlp, const char *pszArgs);
+/** Pointer to a FNDBGFHANDLEREXT function. */
+typedef FNDBGFHANDLEREXT *PFNDBGFHANDLEREXT;
+
+
+/** @name Flags for the info registration functions.
+ * @{ */
+/** The handler must run on the EMT. */
+#define DBGFINFO_FLAGS_RUN_ON_EMT RT_BIT(0)
+/** @} */
+
+VMMR3DECL(int) DBGFR3InfoRegisterDevice(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler, PPDMDEVINS pDevIns);
+VMMR3DECL(int) DBGFR3InfoRegisterDriver(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler, PPDMDRVINS pDrvIns);
+VMMR3DECL(int) DBGFR3InfoRegisterInternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler);
+VMMR3DECL(int) DBGFR3InfoRegisterInternalEx(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLERINT pfnHandler, uint32_t fFlags);
+VMMR3DECL(int) DBGFR3InfoRegisterExternal(PVM pVM, const char *pszName, const char *pszDesc, PFNDBGFHANDLEREXT pfnHandler, void *pvUser);
+VMMR3DECL(int) DBGFR3InfoDeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName);
+VMMR3DECL(int) DBGFR3InfoDeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName);
+VMMR3DECL(int) DBGFR3InfoDeregisterInternal(PVM pVM, const char *pszName);
+VMMR3DECL(int) DBGFR3InfoDeregisterExternal(PVM pVM, const char *pszName);
+VMMR3DECL(int) DBGFR3Info(PVM pVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
+VMMR3DECL(int) DBGFR3InfoEx(PVM pVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp);
+VMMR3DECL(int) DBGFR3InfoLogRel(PVM pVM, const char *pszName, const char *pszArgs);
+VMMR3DECL(int) DBGFR3InfoStdErr(PVM pVM, const char *pszName, const char *pszArgs);
+VMMR3DECL(int) DBGFR3InfoMulti(PVM pVM, const char *pszIncludePat, const char *pszExcludePat,
+ const char *pszSepFmt, PCDBGFINFOHLP pHlp);
+
+/** @def DBGFR3InfoLog
+ * Display a piece of info writing to the log if enabled.
+ *
+ * @param pVM VM handle.
+ * @param pszName The identifier of the info to display.
+ * @param pszArgs Arguments to the info handler.
+ */
+#ifdef LOG_ENABLED
+#define DBGFR3InfoLog(pVM, pszName, pszArgs) \
+ do { \
+ if (LogIsEnabled()) \
+ DBGFR3Info(pVM, pszName, pszArgs, NULL); \
+ } while (0)
+#else
+#define DBGFR3InfoLog(pVM, pszName, pszArgs) do { } while (0)
+#endif
+
+/**
+ * Enumeration callback for use with DBGFR3InfoEnum.
+ *
+ * @returns VBox status code.
+ * A status code indicating failure will end the enumeration
+ * and DBGFR3InfoEnum will return with that status code.
+ * @param pVM VM handle.
+ * @param pszName Info identifier name.
+ * @param pszDesc The description.
+ */
+typedef DECLCALLBACK(int) FNDBGFINFOENUM(PVM pVM, const char *pszName, const char *pszDesc, void *pvUser);
+/** Pointer to a FNDBGFINFOENUM function. */
+typedef FNDBGFINFOENUM *PFNDBGFINFOENUM;
+
+VMMR3DECL(int) DBGFR3InfoEnum(PVM pVM, PFNDBGFINFOENUM pfnCallback, void *pvUser);
+VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogHlp(void);
+VMMR3DECL(PCDBGFINFOHLP) DBGFR3InfoLogRelHlp(void);
+
+#endif /* IN_RING3 */
+
+
+#ifdef IN_RING3 /* The log contrl API only works in ring-3. */
+VMMR3DECL(int) DBGFR3LogModifyGroups(PVM pVM, const char *pszGroupSettings);
+VMMR3DECL(int) DBGFR3LogModifyFlags(PVM pVM, const char *pszFlagSettings);
+VMMR3DECL(int) DBGFR3LogModifyDestinations(PVM pVM, const char *pszDestSettings);
+#endif /* IN_RING3 */
+
+#ifdef IN_RING3 /* The debug information management APIs only works in ring-3. */
+
+/** Max length (including '\\0') of a symbol name. */
+#define DBGF_SYMBOL_NAME_LENGTH 512
+
+/**
+ * Debug symbol.
+ */
+typedef struct DBGFSYMBOL
+{
+ /** Symbol value (address). */
+ RTGCUINTPTR Value;
+ /** Symbol size. */
+ uint32_t cb;
+ /** Symbol Flags. (reserved). */
+ uint32_t fFlags;
+ /** Symbol name. */
+ char szName[DBGF_SYMBOL_NAME_LENGTH];
+} DBGFSYMBOL;
+/** Pointer to debug symbol. */
+typedef DBGFSYMBOL *PDBGFSYMBOL;
+/** Pointer to const debug symbol. */
+typedef const DBGFSYMBOL *PCDBGFSYMBOL;
+
+/**
+ * Debug line number information.
+ */
+typedef struct DBGFLINE
+{
+ /** Address. */
+ RTGCUINTPTR Address;
+ /** Line number. */
+ uint32_t uLineNo;
+ /** Filename. */
+ char szFilename[260];
+} DBGFLINE;
+/** Pointer to debug line number. */
+typedef DBGFLINE *PDBGFLINE;
+/** Pointer to const debug line number. */
+typedef const DBGFLINE *PCDBGFLINE;
+
+/** @name Address spaces aliases.
+ * @{ */
+/** The guest global address space. */
+#define DBGF_AS_GLOBAL ((RTDBGAS)-1)
+/** The guest kernel address space.
+ * This is usually resolves to the same as DBGF_AS_GLOBAL. */
+#define DBGF_AS_KERNEL ((RTDBGAS)-2)
+/** The physical address space. */
+#define DBGF_AS_PHYS ((RTDBGAS)-3)
+/** Raw-mode context. */
+#define DBGF_AS_RC ((RTDBGAS)-4)
+/** Ring-0 context. */
+#define DBGF_AS_R0 ((RTDBGAS)-5)
+/** Raw-mode context and then global guest context.
+ * When used for looking up information, it works as if the call was first made
+ * with DBGF_AS_RC and then on failure with DBGF_AS_GLOBAL. When called for
+ * making address space changes, it works as if DBGF_AS_RC was used. */
+#define DBGF_AS_RC_AND_GC_GLOBAL ((RTDBGAS)-6)
+
+/** The first special one. */
+#define DBGF_AS_FIRST DBGF_AS_RC_AND_GC_GLOBAL
+/** The last special one. */
+#define DBGF_AS_LAST DBGF_AS_GLOBAL
+#endif
+/** The number of special address space handles. */
+#define DBGF_AS_COUNT (6U)
+#ifdef IN_RING3
+/** Converts an alias handle to an array index. */
+#define DBGF_AS_ALIAS_2_INDEX(hAlias) \
+ ( (uintptr_t)(hAlias) - (uintptr_t)DBGF_AS_FIRST )
+/** Predicat macro that check if the specified handle is an alias. */
+#define DBGF_AS_IS_ALIAS(hAlias) \
+ ( DBGF_AS_ALIAS_2_INDEX(hAlias) < DBGF_AS_COUNT )
+/** Predicat macro that check if the specified alias is a fixed one or not. */
+#define DBGF_AS_IS_FIXED_ALIAS(hAlias) \
+ ( DBGF_AS_ALIAS_2_INDEX(hAlias) < (uintptr_t)DBGF_AS_PHYS - (uintptr_t)DBGF_AS_FIRST + 1U )
+
+/** @} */
+
+VMMR3DECL(int) DBGFR3AsAdd(PVM pVM, RTDBGAS hDbgAs, RTPROCESS ProcId);
+VMMR3DECL(int) DBGFR3AsDelete(PVM pVM, RTDBGAS hDbgAs);
+VMMR3DECL(int) DBGFR3AsSetAlias(PVM pVM, RTDBGAS hAlias, RTDBGAS hAliasFor);
+VMMR3DECL(RTDBGAS) DBGFR3AsResolve(PVM pVM, RTDBGAS hAlias);
+VMMR3DECL(RTDBGAS) DBGFR3AsResolveAndRetain(PVM pVM, RTDBGAS hAlias);
+VMMR3DECL(RTDBGAS) DBGFR3AsQueryByName(PVM pVM, const char *pszName);
+VMMR3DECL(RTDBGAS) DBGFR3AsQueryByPid(PVM pVM, RTPROCESS ProcId);
+
+VMMR3DECL(int) DBGFR3AsLoadImage(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
+VMMR3DECL(int) DBGFR3AsLoadMap(PVM pVM, RTDBGAS hDbgAs, const char *pszFilename, const char *pszModName, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, RTGCUINTPTR uSubtrahend, uint32_t fFlags);
+VMMR3DECL(int) DBGFR3AsLinkModule(PVM pVM, RTDBGAS hDbgAs, RTDBGMOD hMod, PCDBGFADDRESS pModAddress, RTDBGSEGIDX iModSeg, uint32_t fFlags);
+
+VMMR3DECL(int) DBGFR3AsSymbolByAddr(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
+VMMR3DECL(PRTDBGSYMBOL) DBGFR3AsSymbolByAddrA(PVM pVM, RTDBGAS hDbgAs, PCDBGFADDRESS pAddress, PRTGCINTPTR poffDisp, PRTDBGMOD phMod);
+VMMR3DECL(int) DBGFR3AsSymbolByName(PVM pVM, RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
+
+/* The following are soon to be obsoleted: */
+VMMR3DECL(int) DBGFR3ModuleLoad(PVM pVM, const char *pszFilename, RTGCUINTPTR AddressDelta, const char *pszName, RTGCUINTPTR ModuleAddress, unsigned cbImage);
+VMMR3DECL(void) DBGFR3ModuleRelocate(PVM pVM, RTGCUINTPTR OldImageBase, RTGCUINTPTR NewImageBase, RTGCUINTPTR cbImage,
+ const char *pszFilename, const char *pszName);
+VMMR3DECL(int) DBGFR3SymbolAdd(PVM pVM, RTGCUINTPTR ModuleAddress, RTGCUINTPTR SymbolAddress, RTUINT cbSymbol, const char *pszSymbol);
+VMMR3DECL(int) DBGFR3SymbolByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFSYMBOL pSymbol);
+VMMR3DECL(int) DBGFR3SymbolByName(PVM pVM, const char *pszSymbol, PDBGFSYMBOL pSymbol);
+
+VMMR3DECL(int) DBGFR3LineByAddr(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement, PDBGFLINE pLine);
+VMMR3DECL(PDBGFLINE) DBGFR3LineByAddrAlloc(PVM pVM, RTGCUINTPTR Address, PRTGCINTPTR poffDisplacement);
+VMMR3DECL(void) DBGFR3LineFree(PDBGFLINE pLine);
+
+#endif /* IN_RING3 */
+
+#ifdef IN_RING3 /* The stack API only works in ring-3. */
+
+/**
+ * Return type.
+ */
+typedef enum DBGFRETRUNTYPE
+{
+ /** The usual invalid 0 value. */
+ DBGFRETURNTYPE_INVALID = 0,
+ /** Near 16-bit return. */
+ DBGFRETURNTYPE_NEAR16,
+ /** Near 32-bit return. */
+ DBGFRETURNTYPE_NEAR32,
+ /** Near 64-bit return. */
+ DBGFRETURNTYPE_NEAR64,
+ /** Far 16:16 return. */
+ DBGFRETURNTYPE_FAR16,
+ /** Far 16:32 return. */
+ DBGFRETURNTYPE_FAR32,
+ /** Far 16:64 return. */
+ DBGFRETURNTYPE_FAR64,
+ /** 16-bit iret return (e.g. real or 286 protect mode). */
+ DBGFRETURNTYPE_IRET16,
+ /** 32-bit iret return. */
+ DBGFRETURNTYPE_IRET32,
+ /** 32-bit iret return. */
+ DBGFRETURNTYPE_IRET32_PRIV,
+ /** 32-bit iret return to V86 mode. */
+ DBGFRETURNTYPE_IRET32_V86,
+ /** @todo 64-bit iret return. */
+ DBGFRETURNTYPE_IRET64,
+ /** The end of the valid return types. */
+ DBGFRETURNTYPE_END,
+ /** The usual 32-bit blowup. */
+ DBGFRETURNTYPE_32BIT_HACK = 0x7fffffff
+} DBGFRETURNTYPE;
+
+/**
+ * Figures the size of the return state on the stack.
+ *
+ * @returns number of bytes. 0 if invalid parameter.
+ * @param enmRetType The type of return.
+ */
+DECLINLINE(unsigned) DBGFReturnTypeSize(DBGFRETURNTYPE enmRetType)
+{
+ switch (enmRetType)
+ {
+ case DBGFRETURNTYPE_NEAR16: return 2;
+ case DBGFRETURNTYPE_NEAR32: return 4;
+ case DBGFRETURNTYPE_NEAR64: return 8;
+ case DBGFRETURNTYPE_FAR16: return 4;
+ case DBGFRETURNTYPE_FAR32: return 4;
+ case DBGFRETURNTYPE_FAR64: return 8;
+ case DBGFRETURNTYPE_IRET16: return 6;
+ case DBGFRETURNTYPE_IRET32: return 4*3;
+ case DBGFRETURNTYPE_IRET32_PRIV: return 4*5;
+ case DBGFRETURNTYPE_IRET32_V86: return 4*9;
+ case DBGFRETURNTYPE_IRET64:
+ default:
+ return 0;
+ }
+}
+
+
+/** Pointer to stack frame info. */
+typedef struct DBGFSTACKFRAME *PDBGFSTACKFRAME;
+/** Pointer to const stack frame info. */
+typedef struct DBGFSTACKFRAME const *PCDBGFSTACKFRAME;
+/**
+ * Info about a stack frame.
+ */
+typedef struct DBGFSTACKFRAME
+{
+ /** Frame number. */
+ uint32_t iFrame;
+ /** Frame flags. */
+ uint32_t fFlags;
+ /** The frame address.
+ * The off member is [e|r]bp and the Sel member is ss. */
+ DBGFADDRESS AddrFrame;
+ /** The stack address of the frame.
+ * The off member is [e|r]sp and the Sel member is ss. */
+ DBGFADDRESS AddrStack;
+ /** The program counter (PC) address of the frame.
+ * The off member is [e|r]ip and the Sel member is cs. */
+ DBGFADDRESS AddrPC;
+ /** Pointer to the symbol nearest the program counter (PC). NULL if not found. */
+ PRTDBGSYMBOL pSymPC;
+ /** Pointer to the linnumber nearest the program counter (PC). NULL if not found. */
+ PDBGFLINE pLinePC;
+
+ /** The return frame address.
+ * The off member is [e|r]bp and the Sel member is ss. */
+ DBGFADDRESS AddrReturnFrame;
+ /** The return stack address.
+ * The off member is [e|r]sp and the Sel member is ss. */
+ DBGFADDRESS AddrReturnStack;
+ /** The way this frame returns to the next one. */
+ DBGFRETURNTYPE enmReturnType;
+
+ /** The program counter (PC) address which the frame returns to.
+ * The off member is [e|r]ip and the Sel member is cs. */
+ DBGFADDRESS AddrReturnPC;
+ /** Pointer to the symbol nearest the return PC. NULL if not found. */
+ PRTDBGSYMBOL pSymReturnPC;
+ /** Pointer to the linnumber nearest the return PC. NULL if not found. */
+ PDBGFLINE pLineReturnPC;
+
+ /** 32-bytes of stack arguments. */
+ union
+ {
+ /** 64-bit view */
+ uint64_t au64[4];
+ /** 32-bit view */
+ uint32_t au32[8];
+ /** 16-bit view */
+ uint16_t au16[16];
+ /** 8-bit view */
+ uint8_t au8[32];
+ } Args;
+
+ /** Pointer to the next frame.
+ * Might not be used in some cases, so consider it internal. */
+ PCDBGFSTACKFRAME pNextInternal;
+ /** Pointer to the first frame.
+ * Might not be used in some cases, so consider it internal. */
+ PCDBGFSTACKFRAME pFirstInternal;
+} DBGFSTACKFRAME;
+
+/** @name DBGFSTACKFRAME Flags.
+ * @{ */
+/** Set if the content of the frame is filled in by DBGFR3StackWalk() and can be used
+ * to construct the next frame. */
+# define DBGFSTACKFRAME_FLAGS_ALL_VALID RT_BIT(0)
+/** This is the last stack frame we can read.
+ * This flag is not set if the walk stop because of max dept or recursion. */
+# define DBGFSTACKFRAME_FLAGS_LAST RT_BIT(1)
+/** This is the last record because we detected a loop. */
+# define DBGFSTACKFRAME_FLAGS_LOOP RT_BIT(2)
+/** This is the last record because we reached the maximum depth. */
+# define DBGFSTACKFRAME_FLAGS_MAX_DEPTH RT_BIT(3)
+/** 16-bit frame. */
+# define DBGFSTACKFRAME_FLAGS_16BIT RT_BIT(4)
+/** 32-bit frame. */
+# define DBGFSTACKFRAME_FLAGS_32BIT RT_BIT(5)
+/** 64-bit frame. */
+# define DBGFSTACKFRAME_FLAGS_64BIT RT_BIT(6)
+/** @} */
+
+/** @name DBGFCODETYPE
+ * @{ */
+typedef enum DBGFCODETYPE
+{
+ /** The usual invalid 0 value. */
+ DBGFCODETYPE_INVALID = 0,
+ /** Stack walk for guest code. */
+ DBGFCODETYPE_GUEST,
+ /** Stack walk for hypervisor code. */
+ DBGFCODETYPE_HYPER,
+ /** Stack walk for ring 0 code. */
+ DBGFCODETYPE_RING0,
+ /** The usual 32-bit blowup. */
+ DBGFCODETYPE_32BIT_HACK = 0x7fffffff
+} DBGFCODETYPE;
+/** @} */
+
+VMMR3DECL(int) DBGFR3StackWalkBegin(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFSTACKFRAME *ppFirstFrame);
+VMMR3DECL(int) DBGFR3StackWalkBeginEx(PVM pVM, VMCPUID idCpu, DBGFCODETYPE enmCodeType, PCDBGFADDRESS pAddrFrame,
+ PCDBGFADDRESS pAddrStack,PCDBGFADDRESS pAddrPC,
+ DBGFRETURNTYPE enmReturnType, PCDBGFSTACKFRAME *ppFirstFrame);
+VMMR3DECL(PCDBGFSTACKFRAME) DBGFR3StackWalkNext(PCDBGFSTACKFRAME pCurrent);
+VMMR3DECL(void) DBGFR3StackWalkEnd(PCDBGFSTACKFRAME pFirstFrame);
+
+#endif /* IN_RING3 */
+
+
+#ifdef IN_RING3 /* The disassembly API only works in ring-3. */
+
+/** Flags to pass to DBGFR3DisasInstrEx().
+ * @{ */
+/** Disassemble the current guest instruction, with annotations. */
+#define DBGF_DISAS_FLAGS_CURRENT_GUEST RT_BIT(0)
+/** Disassemble the current hypervisor instruction, with annotations. */
+#define DBGF_DISAS_FLAGS_CURRENT_HYPER RT_BIT(1)
+/** No annotations for current context. */
+#define DBGF_DISAS_FLAGS_NO_ANNOTATION RT_BIT(2)
+/** No symbol lookup. */
+#define DBGF_DISAS_FLAGS_NO_SYMBOLS RT_BIT(3)
+/** No instruction bytes. */
+#define DBGF_DISAS_FLAGS_NO_BYTES RT_BIT(4)
+/** No address in the output. */
+#define DBGF_DISAS_FLAGS_NO_ADDRESS RT_BIT(5)
+/** Disassemble in the default mode of the specific context. */
+#define DBGF_DISAS_FLAGS_DEFAULT_MODE UINT32_C(0x00000000)
+/** Disassemble in 16-bit mode. */
+#define DBGF_DISAS_FLAGS_16BIT_MODE UINT32_C(0x10000000)
+/** Disassemble in 16-bit mode with real mode address translation. */
+#define DBGF_DISAS_FLAGS_16BIT_REAL_MODE UINT32_C(0x20000000)
+/** Disassemble in 32-bit mode. */
+#define DBGF_DISAS_FLAGS_32BIT_MODE UINT32_C(0x30000000)
+/** Disassemble in 64-bit mode. */
+#define DBGF_DISAS_FLAGS_64BIT_MODE UINT32_C(0x40000000)
+/** The disassembly mode mask. */
+#define DBGF_DISAS_FLAGS_MODE_MASK UINT32_C(0x70000000)
+/** Mask containing the valid flags. */
+#define DBGF_DISAS_FLAGS_VALID_MASK UINT32_C(0x7000007f)
+/** @} */
+
+/** Special flat selector. */
+#define DBGF_SEL_FLAT 1
+
+VMMR3DECL(int) DBGFR3DisasInstrEx(PVM pVM, VMCPUID idCpu, RTSEL Sel, RTGCPTR GCPtr, uint32_t fFlags,
+ char *pszOutput, uint32_t cbOutput, uint32_t *pcbInstr);
+VMMR3DECL(int) DBGFR3DisasInstrCurrent(PVMCPU pVCpu, char *pszOutput, uint32_t cbOutput);
+VMMR3DECL(int) DBGFR3DisasInstrCurrentLogInternal(PVMCPU pVCpu, const char *pszPrefix);
+
+/** @def DBGFR3DisasInstrCurrentLog
+ * Disassembles the current guest context instruction and writes it to the log.
+ * All registers and data will be displayed. Addresses will be attempted resolved to symbols.
+ */
+#ifdef LOG_ENABLED
+# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) \
+ do { \
+ if (LogIsEnabled()) \
+ DBGFR3DisasInstrCurrentLogInternal(pVCpu, pszPrefix); \
+ } while (0)
+#else
+# define DBGFR3DisasInstrCurrentLog(pVCpu, pszPrefix) do { } while (0)
+#endif
+
+VMMR3DECL(int) DBGFR3DisasInstrLogInternal(PVMCPU pVCpu, RTSEL Sel, RTGCPTR GCPtr, const char *pszPrefix);
+
+/** @def DBGFR3DisasInstrLog
+ * Disassembles the specified guest context instruction and writes it to the log.
+ * Addresses will be attempted resolved to symbols.
+ * @thread Any EMT.
+ */
+# ifdef LOG_ENABLED
+# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) \
+ do { \
+ if (LogIsEnabled()) \
+ DBGFR3DisasInstrLogInternal(pVCpu, Sel, GCPtr, pszPrefix); \
+ } while (0)
+# else
+# define DBGFR3DisasInstrLog(pVCpu, Sel, GCPtr, pszPrefix) do { } while (0)
+# endif
+#endif
+
+
+#ifdef IN_RING3
+VMMR3DECL(int) DBGFR3MemScan(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, RTGCUINTPTR cbRange, RTGCUINTPTR uAlign,
+ const void *pvNeedle, size_t cbNeedle, PDBGFADDRESS pHitAddress);
+VMMR3DECL(int) DBGFR3MemRead(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void *pvBuf, size_t cbRead);
+VMMR3DECL(int) DBGFR3MemReadString(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, char *pszBuf, size_t cbBuf);
+VMMR3DECL(int) DBGFR3MemWrite(PVM pVM, VMCPUID idCpu, PCDBGFADDRESS pAddress, void const *pvBuf, size_t cbRead);
+#endif
+
+
+/** @name Flags for DBGFR3PagingDumpEx, PGMR3DumpHierarchyHCEx and
+ * PGMR3DumpHierarchyGCEx
+ * @{ */
+/** The CR3 from the current CPU state. */
+#define DBGFPGDMP_FLAGS_CURRENT_CR3 RT_BIT_32(0)
+/** The current CPU paging mode (PSE, PAE, LM, EPT, NX). */
+#define DBGFPGDMP_FLAGS_CURRENT_MODE RT_BIT_32(1)
+/** Whether PSE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
+ * Same value as X86_CR4_PSE. */
+#define DBGFPGDMP_FLAGS_PSE RT_BIT_32(4) /* */
+/** Whether PAE is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
+ * Same value as X86_CR4_PAE. */
+#define DBGFPGDMP_FLAGS_PAE RT_BIT_32(5) /* */
+/** Whether LME is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
+ * Same value as MSR_K6_EFER_LME. */
+#define DBGFPGDMP_FLAGS_LME RT_BIT_32(8)
+/** Whether nested paging is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
+#define DBGFPGDMP_FLAGS_NP RT_BIT_32(9)
+/** Whether extended nested page tables are enabled
+ * (!DBGFPGDMP_FLAGS_CURRENT_STATE). */
+#define DBGFPGDMP_FLAGS_EPT RT_BIT_32(10)
+/** Whether no-execution is enabled (!DBGFPGDMP_FLAGS_CURRENT_STATE).
+ * Same value as MSR_K6_EFER_NXE. */
+#define DBGFPGDMP_FLAGS_NXE RT_BIT_32(11)
+/** Whether to print the CR3. */
+#define DBGFPGDMP_FLAGS_PRINT_CR3 RT_BIT_32(27)
+/** Whether to print the header. */
+#define DBGFPGDMP_FLAGS_HEADER RT_BIT_32(28)
+/** Whether to dump additional page information. */
+#define DBGFPGDMP_FLAGS_PAGE_INFO RT_BIT_32(29)
+/** Dump the shadow tables if set.
+ * Cannot be used together with DBGFPGDMP_FLAGS_GUEST. */
+#define DBGFPGDMP_FLAGS_SHADOW RT_BIT_32(30)
+/** Dump the guest tables if set.
+ * Cannot be used together with DBGFPGDMP_FLAGS_SHADOW. */
+#define DBGFPGDMP_FLAGS_GUEST RT_BIT_32(31)
+/** Mask of valid bits. */
+#define DBGFPGDMP_FLAGS_VALID_MASK UINT32_C(0xf8000f33)
+/** The mask of bits controlling the paging mode. */
+#define DBGFPGDMP_FLAGS_MODE_MASK UINT32_C(0x00000f32)
+/** @} */
+VMMDECL(int) DBGFR3PagingDumpEx(PVM pVM, VMCPUID idCpu, uint32_t fFlags, uint64_t cr3, uint64_t u64FirstAddr,
+ uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
+
+
+/** @name DBGFR3SelQueryInfo flags.
+ * @{ */
+/** Get the info from the guest descriptor table. */
+#define DBGFSELQI_FLAGS_DT_GUEST UINT32_C(0)
+/** Get the info from the shadow descriptor table.
+ * Only works in raw-mode. */
+#define DBGFSELQI_FLAGS_DT_SHADOW UINT32_C(1)
+/** If currently executing in in 64-bit mode, blow up data selectors. */
+#define DBGFSELQI_FLAGS_DT_ADJ_64BIT_MODE UINT32_C(2)
+/** @} */
+VMMR3DECL(int) DBGFR3SelQueryInfo(PVM pVM, VMCPUID idCpu, RTSEL Sel, uint32_t fFlags, PDBGFSELINFO pSelInfo);
+
+
+/**
+ * Register identifiers.
+ */
+typedef enum DBGFREG
+{
+ /* General purpose registers: */
+ DBGFREG_AL = 0,
+ DBGFREG_AX = DBGFREG_AL,
+ DBGFREG_EAX = DBGFREG_AL,
+ DBGFREG_RAX = DBGFREG_AL,
+
+ DBGFREG_CL,
+ DBGFREG_CX = DBGFREG_CL,
+ DBGFREG_ECX = DBGFREG_CL,
+ DBGFREG_RCX = DBGFREG_CL,
+
+ DBGFREG_DL,
+ DBGFREG_DX = DBGFREG_DL,
+ DBGFREG_EDX = DBGFREG_DL,
+ DBGFREG_RDX = DBGFREG_DL,
+
+ DBGFREG_BL,
+ DBGFREG_BX = DBGFREG_BL,
+ DBGFREG_EBX = DBGFREG_BL,
+ DBGFREG_RBX = DBGFREG_BL,
+
+ DBGFREG_SPL,
+ DBGFREG_SP = DBGFREG_SPL,
+ DBGFREG_ESP = DBGFREG_SPL,
+ DBGFREG_RSP = DBGFREG_SPL,
+
+ DBGFREG_BPL,
+ DBGFREG_BP = DBGFREG_BPL,
+ DBGFREG_EBP = DBGFREG_BPL,
+ DBGFREG_RBP = DBGFREG_BPL,
+
+ DBGFREG_SIL,
+ DBGFREG_SI = DBGFREG_SIL,
+ DBGFREG_ESI = DBGFREG_SIL,
+ DBGFREG_RSI = DBGFREG_SIL,
+
+ DBGFREG_DIL,
+ DBGFREG_DI = DBGFREG_DIL,
+ DBGFREG_EDI = DBGFREG_DIL,
+ DBGFREG_RDI = DBGFREG_DIL,
+
+ DBGFREG_R8,
+ DBGFREG_R8B = DBGFREG_R8,
+ DBGFREG_R8W = DBGFREG_R8,
+ DBGFREG_R8D = DBGFREG_R8,
+
+ DBGFREG_R9,
+ DBGFREG_R9B = DBGFREG_R9,
+ DBGFREG_R9W = DBGFREG_R9,
+ DBGFREG_R9D = DBGFREG_R9,
+
+ DBGFREG_R10,
+ DBGFREG_R10B = DBGFREG_R10,
+ DBGFREG_R10W = DBGFREG_R10,
+ DBGFREG_R10D = DBGFREG_R10,
+
+ DBGFREG_R11,
+ DBGFREG_R11B = DBGFREG_R11,
+ DBGFREG_R11W = DBGFREG_R11,
+ DBGFREG_R11D = DBGFREG_R11,
+
+ DBGFREG_R12,
+ DBGFREG_R12B = DBGFREG_R12,
+ DBGFREG_R12W = DBGFREG_R12,
+ DBGFREG_R12D = DBGFREG_R12,
+
+ DBGFREG_R13,
+ DBGFREG_R13B = DBGFREG_R13,
+ DBGFREG_R13W = DBGFREG_R13,
+ DBGFREG_R13D = DBGFREG_R13,
+
+ DBGFREG_R14,
+ DBGFREG_R14B = DBGFREG_R14,
+ DBGFREG_R14W = DBGFREG_R14,
+ DBGFREG_R14D = DBGFREG_R14,
+
+ DBGFREG_R15,
+ DBGFREG_R15B = DBGFREG_R15,
+ DBGFREG_R15W = DBGFREG_R15,
+ DBGFREG_R15D = DBGFREG_R15,
+
+ /* Segments and other special registers: */
+ DBGFREG_CS,
+ DBGFREG_CS_ATTR,
+ DBGFREG_CS_BASE,
+ DBGFREG_CS_LIMIT,
+
+ DBGFREG_DS,
+ DBGFREG_DS_ATTR,
+ DBGFREG_DS_BASE,
+ DBGFREG_DS_LIMIT,
+
+ DBGFREG_ES,
+ DBGFREG_ES_ATTR,
+ DBGFREG_ES_BASE,
+ DBGFREG_ES_LIMIT,
+
+ DBGFREG_FS,
+ DBGFREG_FS_ATTR,
+ DBGFREG_FS_BASE,
+ DBGFREG_FS_LIMIT,
+
+ DBGFREG_GS,
+ DBGFREG_GS_ATTR,
+ DBGFREG_GS_BASE,
+ DBGFREG_GS_LIMIT,
+
+ DBGFREG_SS,
+ DBGFREG_SS_ATTR,
+ DBGFREG_SS_BASE,
+ DBGFREG_SS_LIMIT,
+
+ DBGFREG_IP,
+ DBGFREG_EIP = DBGFREG_IP,
+ DBGFREG_RIP = DBGFREG_IP,
+
+ DBGFREG_FLAGS,
+ DBGFREG_EFLAGS = DBGFREG_FLAGS,
+ DBGFREG_RFLAGS = DBGFREG_FLAGS,
+
+ /* FPU: */
+ DBGFREG_FCW,
+ DBGFREG_FSW,
+ DBGFREG_FTW,
+ DBGFREG_FOP,
+ DBGFREG_FPUIP,
+ DBGFREG_FPUCS,
+ DBGFREG_FPUDP,
+ DBGFREG_FPUDS,
+ DBGFREG_MXCSR,
+ DBGFREG_MXCSR_MASK,
+
+ DBGFREG_ST0,
+ DBGFREG_ST1,
+ DBGFREG_ST2,
+ DBGFREG_ST3,
+ DBGFREG_ST4,
+ DBGFREG_ST5,
+ DBGFREG_ST6,
+ DBGFREG_ST7,
+
+ DBGFREG_MM0,
+ DBGFREG_MM1,
+ DBGFREG_MM2,
+ DBGFREG_MM3,
+ DBGFREG_MM4,
+ DBGFREG_MM5,
+ DBGFREG_MM6,
+ DBGFREG_MM7,
+
+ /* SSE: */
+ DBGFREG_XMM0,
+ DBGFREG_XMM1,
+ DBGFREG_XMM2,
+ DBGFREG_XMM3,
+ DBGFREG_XMM4,
+ DBGFREG_XMM5,
+ DBGFREG_XMM6,
+ DBGFREG_XMM7,
+ DBGFREG_XMM8,
+ DBGFREG_XMM9,
+ DBGFREG_XMM10,
+ DBGFREG_XMM11,
+ DBGFREG_XMM12,
+ DBGFREG_XMM13,
+ DBGFREG_XMM14,
+ DBGFREG_XMM15,
+ /** @todo add XMM aliases. */
+
+ /* System registers: */
+ DBGFREG_GDTR_BASE,
+ DBGFREG_GDTR_LIMIT,
+ DBGFREG_IDTR_BASE,
+ DBGFREG_IDTR_LIMIT,
+ DBGFREG_LDTR,
+ DBGFREG_LDTR_ATTR,
+ DBGFREG_LDTR_BASE,
+ DBGFREG_LDTR_LIMIT,
+ DBGFREG_TR,
+ DBGFREG_TR_ATTR,
+ DBGFREG_TR_BASE,
+ DBGFREG_TR_LIMIT,
+
+ DBGFREG_CR0,
+ DBGFREG_CR2,
+ DBGFREG_CR3,
+ DBGFREG_CR4,
+ DBGFREG_CR8,
+
+ DBGFREG_DR0,
+ DBGFREG_DR1,
+ DBGFREG_DR2,
+ DBGFREG_DR3,
+ DBGFREG_DR6,
+ DBGFREG_DR7,
+
+ /* MSRs: */
+ DBGFREG_MSR_IA32_APICBASE,
+ DBGFREG_MSR_IA32_CR_PAT,
+ DBGFREG_MSR_IA32_PERF_STATUS,
+ DBGFREG_MSR_IA32_SYSENTER_CS,
+ DBGFREG_MSR_IA32_SYSENTER_EIP,
+ DBGFREG_MSR_IA32_SYSENTER_ESP,
+ DBGFREG_MSR_IA32_TSC,
+ DBGFREG_MSR_K6_EFER,
+ DBGFREG_MSR_K6_STAR,
+ DBGFREG_MSR_K8_CSTAR,
+ DBGFREG_MSR_K8_FS_BASE,
+ DBGFREG_MSR_K8_GS_BASE,
+ DBGFREG_MSR_K8_KERNEL_GS_BASE,
+ DBGFREG_MSR_K8_LSTAR,
+ DBGFREG_MSR_K8_SF_MASK,
+ DBGFREG_MSR_K8_TSC_AUX,
+
+ /** The number of registers to pass to DBGFR3RegQueryAll. */
+ DBGFREG_ALL_COUNT,
+
+ /* Misc aliases that doesn't need be part of the 'all' query: */
+ DBGFREG_AH = DBGFREG_ALL_COUNT,
+ DBGFREG_CH,
+ DBGFREG_DH,
+ DBGFREG_BH,
+ DBGFREG_GDTR,
+ DBGFREG_IDTR,
+
+ /** The end of the registers. */
+ DBGFREG_END,
+ /** The usual 32-bit type hack. */
+ DBGFREG_32BIT_HACK = 0x7fffffff
+} DBGFREG;
+/** Pointer to a register identifier. */
+typedef DBGFREG *PDBGFREG;
+/** Pointer to a const register identifier. */
+typedef DBGFREG const *PCDBGFREG;
+
+/**
+ * Register value type.
+ */
+typedef enum DBGFREGVALTYPE
+{
+ DBGFREGVALTYPE_INVALID = 0,
+ /** Unsigned 8-bit register value. */
+ DBGFREGVALTYPE_U8,
+ /** Unsigned 16-bit register value. */
+ DBGFREGVALTYPE_U16,
+ /** Unsigned 32-bit register value. */
+ DBGFREGVALTYPE_U32,
+ /** Unsigned 64-bit register value. */
+ DBGFREGVALTYPE_U64,
+ /** Unsigned 128-bit register value. */
+ DBGFREGVALTYPE_U128,
+ /** Long double register value. */
+ DBGFREGVALTYPE_R80,
+ /** Descriptor table register value. */
+ DBGFREGVALTYPE_DTR,
+ /** End of the valid register value types. */
+ DBGFREGVALTYPE_END,
+ /** The usual 32-bit type hack. */
+ DBGFREGVALTYPE_32BIT_HACK = 0x7fffffff
+} DBGFREGVALTYPE;
+/** Pointer to a register value type. */
+typedef DBGFREGVALTYPE *PDBGFREGVALTYPE;
+
+/**
+ * A generic register value type.
+ */
+typedef union DBGFREGVAL
+{
+ uint8_t u8; /**< The 8-bit view. */
+ uint16_t u16; /**< The 16-bit view. */
+ uint32_t u32; /**< The 32-bit view. */
+ uint64_t u64; /**< The 64-bit view. */
+ RTUINT128U u128; /**< The 128-bit view. */
+ RTFLOAT80U r80; /**< The 80-bit floating point view. */
+ RTFLOAT80U2 r80Ex; /**< The 80-bit floating point view v2. */
+ /** GDTR or LDTR (DBGFREGVALTYPE_DTR). */
+ struct
+ {
+ /** The table address. */
+ uint64_t u64Base;
+ /** The table limit (length minus 1). */
+ uint32_t u32Limit;
+ } dtr;
+
+ uint8_t au8[16]; /**< The 8-bit array view. */
+ uint16_t au16[8]; /**< The 16-bit array view. */
+ uint32_t au32[4]; /**< The 32-bit array view. */
+ uint64_t au64[2]; /**< The 64-bit array view. */
+ RTUINT128U u;
+} DBGFREGVAL;
+/** Pointer to a generic register value type. */
+typedef DBGFREGVAL *PDBGFREGVAL;
+/** Pointer to a const generic register value type. */
+typedef DBGFREGVAL const *PCDBGFREGVAL;
+
+VMMDECL(ssize_t) DBGFR3RegFormatValue(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType, bool fSpecial);
+VMMDECL(ssize_t) DBGFR3RegFormatValueEx(char *pszBuf, size_t cbBuf, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType,
+ unsigned uBase, signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Register sub-field descriptor.
+ */
+typedef struct DBGFREGSUBFIELD
+{
+ /** The name of the sub-field. NULL is used to terminate the array. */
+ const char *pszName;
+ /** The index of the first bit. Ignored if pfnGet is set. */
+ uint8_t iFirstBit;
+ /** The number of bits. Mandatory. */
+ uint8_t cBits;
+ /** The shift count. Not applied when pfnGet is set, but used to
+ * calculate the minimum type. */
+ int8_t cShift;
+ /** Sub-field flags, DBGFREGSUBFIELD_FLAGS_XXX. */
+ uint8_t fFlags;
+ /** Getter (optional). */
+ DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, PRTUINT128U puValue);
+ /** Setter (optional). */
+ DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGSUBFIELD const *pSubField, RTUINT128U uValue, RTUINT128U fMask);
+} DBGFREGSUBFIELD;
+/** Pointer to a const register sub-field descriptor. */
+typedef DBGFREGSUBFIELD const *PCDBGFREGSUBFIELD;
+
+/** @name DBGFREGSUBFIELD_FLAGS_XXX
+ * @{ */
+/** The sub-field is read-only. */
+#define DBGFREGSUBFIELD_FLAGS_READ_ONLY UINT8_C(0x01)
+/** @} */
+
+/** Macro for creating a read-write sub-field entry without getters. */
+#define DBGFREGSUBFIELD_RW(a_szName, a_iFirstBit, a_cBits, a_cShift) \
+ { a_szName, a_iFirstBit, a_cBits, a_cShift, 0 /*fFlags*/, NULL /*pfnGet*/, NULL /*pfnSet*/ }
+/** Macro for creating a read-write sub-field entry with getters. */
+#define DBGFREGSUBFIELD_RW_SG(a_szName, a_cBits, a_cShift, a_pfnGet, a_pfnSet) \
+ { a_szName, 0 /*iFirstBit*/, a_cBits, a_cShift, 0 /*fFlags*/, a_pfnGet, a_pfnSet }
+/** Macro for creating a terminator sub-field entry. */
+#define DBGFREGSUBFIELD_TERMINATOR() \
+ { NULL, 0, 0, 0, 0, NULL, NULL }
+
+/**
+ * Register alias descriptor.
+ */
+typedef struct DBGFREGALIAS
+{
+ /** The alias name. NULL is used to terminate the array. */
+ const char *pszName;
+ /** Set to a valid type if the alias has a different type. */
+ DBGFREGVALTYPE enmType;
+} DBGFREGALIAS;
+/** Pointer to a const register alias descriptor. */
+typedef DBGFREGALIAS const *PCDBGFREGALIAS;
+
+/**
+ * Register descriptor.
+ */
+typedef struct DBGFREGDESC
+{
+ /** The normal register name. */
+ const char *pszName;
+ /** The register identifier if this is a CPU register. */
+ DBGFREG enmReg;
+ /** The default register type. */
+ DBGFREGVALTYPE enmType;
+ /** Flags, see DBGFREG_FLAGS_XXX. */
+ uint32_t fFlags;
+ /** The internal register indicator.
+ * For CPU registers this is the offset into the CPUMCTX structure,
+ * thuse the 'off' prefix. */
+ uint32_t offRegister;
+ /** Getter. */
+ DECLCALLBACKMEMBER(int, pfnGet)(void *pvUser, struct DBGFREGDESC const *pDesc, PDBGFREGVAL pValue);
+ /** Setter. */
+ DECLCALLBACKMEMBER(int, pfnSet)(void *pvUser, struct DBGFREGDESC const *pDesc, PCDBGFREGVAL pValue, PCDBGFREGVAL pfMask);
+ /** Aliases (optional). */
+ PCDBGFREGALIAS paAliases;
+ /** Sub fields (optional). */
+ PCDBGFREGSUBFIELD paSubFields;
+} DBGFREGDESC;
+
+/** @name Macros for constructing DBGFREGDESC arrays.
+ * @{ */
+#define DBGFREGDESC_RW(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
+#define DBGFREGDESC_RO(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, NULL /*paAlises*/, NULL /*paSubFields*/ }
+#define DBGFREGDESC_RW_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
+#define DBGFREGDESC_RO_A(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, NULL /*paSubFields*/ }
+#define DBGFREGDESC_RW_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
+#define DBGFREGDESC_RO_S(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paSubFields) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, /*paAliases*/, a_paSubFields }
+#define DBGFREGDESC_RW_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, 0 /*fFlags*/, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
+#define DBGFREGDESC_RO_AS(a_szName, a_TypeSuff, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields) \
+ { a_szName, DBGFREG_END, DBGFREGVALTYPE_##a_TypeSuff, DBGFREG_FLAGS_READ_ONLY, a_offRegister, a_pfnGet, a_pfnSet, a_paAliases, a_paSubFields }
+#define DBGFREGDESC_TERMINATOR() \
+ { NULL, DBGFREG_END, DBGFREGVALTYPE_INVALID, 0, 0, NULL, NULL, NULL, NULL }
+/** @} */
+
+
+/** @name DBGFREG_FLAGS_XXX
+ * @{ */
+/** The register is read-only. */
+#define DBGFREG_FLAGS_READ_ONLY RT_BIT_32(0)
+/** @} */
+
+/**
+ * Entry in a batch query or set operation.
+ */
+typedef struct DBGFREGENTRY
+{
+ /** The register identifier. */
+ DBGFREG enmReg;
+ /** The size of the value in bytes. */
+ DBGFREGVALTYPE enmType;
+ /** The register value. The valid view is indicated by enmType. */
+ DBGFREGVAL Val;
+} DBGFREGENTRY;
+/** Pointer to a register entry in a batch operation. */
+typedef DBGFREGENTRY *PDBGFREGENTRY;
+/** Pointer to a const register entry in a batch operation. */
+typedef DBGFREGENTRY const *PCDBGFREGENTRY;
+
+/** Used with DBGFR3Reg* to indicate the hypervisor register set instead of the
+ * guest. */
+#define DBGFREG_HYPER_VMCPUID UINT32_C(0x01000000)
+
+VMMR3DECL(int) DBGFR3RegCpuQueryU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t *pu8);
+VMMR3DECL(int) DBGFR3RegCpuQueryU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t *pu16);
+VMMR3DECL(int) DBGFR3RegCpuQueryU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t *pu32);
+VMMR3DECL(int) DBGFR3RegCpuQueryU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64);
+VMMR3DECL(int) DBGFR3RegCpuQueryU128(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t *pu128);
+VMMR3DECL(int) DBGFR3RegCpuQueryLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double *plrd);
+VMMR3DECL(int) DBGFR3RegCpuQueryXdtr(PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t *pu64Base, uint16_t *pu16Limit);
+#if 0
+VMMR3DECL(int) DBGFR3RegCpuQueryBatch(PVM pVM,VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
+VMMR3DECL(int) DBGFR3RegCpuQueryAll( PVM pVM, VMCPUID idCpu, PDBGFREGENTRY paRegs, size_t cRegs);
+
+VMMR3DECL(int) DBGFR3RegCpuSetU8( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint8_t u8);
+VMMR3DECL(int) DBGFR3RegCpuSetU16( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint16_t u16);
+VMMR3DECL(int) DBGFR3RegCpuSetU32( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint32_t u32);
+VMMR3DECL(int) DBGFR3RegCpuSetU64( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint64_t u64);
+VMMR3DECL(int) DBGFR3RegCpuSetU128( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, uint128_t u128);
+VMMR3DECL(int) DBGFR3RegCpuSetLrd( PVM pVM, VMCPUID idCpu, DBGFREG enmReg, long double lrd);
+VMMR3DECL(int) DBGFR3RegCpuSetBatch( PVM pVM, VMCPUID idCpu, PCDBGFREGENTRY paRegs, size_t cRegs);
+#endif
+
+VMMR3DECL(const char *) DBGFR3RegCpuName(PVM pVM, DBGFREG enmReg, DBGFREGVALTYPE enmType);
+
+VMMR3_INT_DECL(int) DBGFR3RegRegisterCpu(PVM pVM, PVMCPU pVCpu, PCDBGFREGDESC paRegisters, bool fGuestRegs);
+VMMR3DECL(int) DBGFR3RegRegisterDevice(PVM pVM, PCDBGFREGDESC paRegisters, PPDMDEVINS pDevIns, const char *pszPrefix, uint32_t iInstance);
+
+/**
+ * Entry in a named batch query or set operation.
+ */
+typedef struct DBGFREGENTRYNM
+{
+ /** The register name. */
+ const char *pszName;
+ /** The size of the value in bytes. */
+ DBGFREGVALTYPE enmType;
+ /** The register value. The valid view is indicated by enmType. */
+ DBGFREGVAL Val;
+} DBGFREGENTRYNM;
+/** Pointer to a named register entry in a batch operation. */
+typedef DBGFREGENTRYNM *PDBGFREGENTRYNM;
+/** Pointer to a const named register entry in a batch operation. */
+typedef DBGFREGENTRYNM const *PCDBGFREGENTRYNM;
+
+VMMR3DECL(int) DBGFR3RegNmValidate( PVM pVM, VMCPUID idDefCpu, const char *pszReg);
+
+VMMR3DECL(int) DBGFR3RegNmQuery( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PDBGFREGVAL pValue, PDBGFREGVALTYPE penmType);
+VMMR3DECL(int) DBGFR3RegNmQueryU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t *pu8);
+VMMR3DECL(int) DBGFR3RegNmQueryU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t *pu16);
+VMMR3DECL(int) DBGFR3RegNmQueryU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t *pu32);
+VMMR3DECL(int) DBGFR3RegNmQueryU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64);
+VMMR3DECL(int) DBGFR3RegNmQueryU128(PVM pVM, VMCPUID idDefCpu, const char *pszReg, PRTUINT128U pu128);
+/*VMMR3DECL(int) DBGFR3RegNmQueryLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double *plrd);*/
+VMMR3DECL(int) DBGFR3RegNmQueryXdtr(PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t *pu64Base, uint16_t *pu16Limit);
+VMMR3DECL(int) DBGFR3RegNmQueryBatch(PVM pVM,VMCPUID idDefCpu, PDBGFREGENTRYNM paRegs, size_t cRegs);
+VMMR3DECL(int) DBGFR3RegNmQueryAllCount(PVM pVM, size_t *pcRegs);
+VMMR3DECL(int) DBGFR3RegNmQueryAll( PVM pVM, PDBGFREGENTRYNM paRegs, size_t cRegs);
+
+VMMR3DECL(int) DBGFR3RegNmSet( PVM pVM, VMCPUID idDefCpu, const char *pszReg, PCDBGFREGVAL pValue, DBGFREGVALTYPE enmType);
+VMMR3DECL(int) DBGFR3RegNmSetU8( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint8_t u8);
+VMMR3DECL(int) DBGFR3RegNmSetU16( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint16_t u16);
+VMMR3DECL(int) DBGFR3RegNmSetU32( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint32_t u32);
+VMMR3DECL(int) DBGFR3RegNmSetU64( PVM pVM, VMCPUID idDefCpu, const char *pszReg, uint64_t u64);
+VMMR3DECL(int) DBGFR3RegNmSetU128( PVM pVM, VMCPUID idDefCpu, const char *pszReg, RTUINT128U u128);
+VMMR3DECL(int) DBGFR3RegNmSetLrd( PVM pVM, VMCPUID idDefCpu, const char *pszReg, long double lrd);
+VMMR3DECL(int) DBGFR3RegNmSetBatch( PVM pVM, VMCPUID idDefCpu, PCDBGFREGENTRYNM paRegs, size_t cRegs);
+
+/** @todo add enumeration methods. */
+
+VMMR3DECL(int) DBGFR3RegPrintf( PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, ...);
+VMMR3DECL(int) DBGFR3RegPrintfV(PVM pVM, VMCPUID idDefCpu, char *pszBuf, size_t cbBuf, const char *pszFormat, va_list va);
+
+
+/**
+ * Guest OS digger interface identifier.
+ *
+ * This is for use together with PDBGFR3QueryInterface and is used to
+ * obtain access to optional interfaces.
+ */
+typedef enum DBGFOSINTERFACE
+{
+ /** The usual invalid entry. */
+ DBGFOSINTERFACE_INVALID = 0,
+ /** Process info. */
+ DBGFOSINTERFACE_PROCESS,
+ /** Thread info. */
+ DBGFOSINTERFACE_THREAD,
+ /** The end of the valid entries. */
+ DBGFOSINTERFACE_END,
+ /** The usual 32-bit type blowup. */
+ DBGFOSINTERFACE_32BIT_HACK = 0x7fffffff
+} DBGFOSINTERFACE;
+/** Pointer to a Guest OS digger interface identifier. */
+typedef DBGFOSINTERFACE *PDBGFOSINTERFACE;
+/** Pointer to a const Guest OS digger interface identifier. */
+typedef DBGFOSINTERFACE const *PCDBGFOSINTERFACE;
+
+
+/**
+ * Guest OS Digger Registration Record.
+ *
+ * This is used with the DBGFR3OSRegister() API.
+ */
+typedef struct DBGFOSREG
+{
+ /** Magic value (DBGFOSREG_MAGIC). */
+ uint32_t u32Magic;
+ /** Flags. Reserved. */
+ uint32_t fFlags;
+ /** The size of the instance data. */
+ uint32_t cbData;
+ /** Operative System name. */
+ char szName[24];
+
+ /**
+ * Constructs the instance.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ */
+ DECLCALLBACKMEMBER(int, pfnConstruct)(PVM pVM, void *pvData);
+
+ /**
+ * Destroys the instance.
+ *
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ */
+ DECLCALLBACKMEMBER(void, pfnDestruct)(PVM pVM, void *pvData);
+
+ /**
+ * Probes the guest memory for OS finger prints.
+ *
+ * No setup or so is performed, it will be followed by a call to pfnInit
+ * or pfnRefresh that should take care of that.
+ *
+ * @returns true if is an OS handled by this module, otherwise false.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ */
+ DECLCALLBACKMEMBER(bool, pfnProbe)(PVM pVM, void *pvData);
+
+ /**
+ * Initializes a fresly detected guest, loading symbols and such useful stuff.
+ *
+ * This is called after pfnProbe.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ */
+ DECLCALLBACKMEMBER(int, pfnInit)(PVM pVM, void *pvData);
+
+ /**
+ * Refreshes symbols and stuff following a redetection of the same OS.
+ *
+ * This is called after pfnProbe.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ */
+ DECLCALLBACKMEMBER(int, pfnRefresh)(PVM pVM, void *pvData);
+
+ /**
+ * Terminates an OS when a new (or none) OS has been detected,
+ * and before destruction.
+ *
+ * This is called after pfnProbe and if needed before pfnDestruct.
+ *
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ */
+ DECLCALLBACKMEMBER(void, pfnTerm)(PVM pVM, void *pvData);
+
+ /**
+ * Queries the version of the running OS.
+ *
+ * This is only called after pfnInit().
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ * @param pszVersion Where to store the version string.
+ * @param cchVersion The size of the version string buffer.
+ */
+ DECLCALLBACKMEMBER(int, pfnQueryVersion)(PVM pVM, void *pvData, char *pszVersion, size_t cchVersion);
+
+ /**
+ * Queries the pointer to a interface.
+ *
+ * This is called after pfnProbe.
+ *
+ * @returns Pointer to the interface if available, NULL if not available.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvData Pointer to the instance data.
+ * @param enmIf The interface identifier.
+ */
+ DECLCALLBACKMEMBER(void *, pfnQueryInterface)(PVM pVM, void *pvData, DBGFOSINTERFACE enmIf);
+
+ /** Trailing magic (DBGFOSREG_MAGIC). */
+ uint32_t u32EndMagic;
+} DBGFOSREG;
+/** Pointer to a Guest OS digger registration record. */
+typedef DBGFOSREG *PDBGFOSREG;
+/** Pointer to a const Guest OS digger registration record. */
+typedef DBGFOSREG const *PCDBGFOSREG;
+
+/** Magic value for DBGFOSREG::u32Magic and DBGFOSREG::u32EndMagic. (Hitomi Kanehara) */
+#define DBGFOSREG_MAGIC 0x19830808
+
+VMMR3DECL(int) DBGFR3OSRegister(PVM pVM, PCDBGFOSREG pReg);
+VMMR3DECL(int) DBGFR3OSDeregister(PVM pVM, PCDBGFOSREG pReg);
+VMMR3DECL(int) DBGFR3OSDetect(PVM pVM, char *pszName, size_t cchName);
+VMMR3DECL(int) DBGFR3OSQueryNameAndVersion(PVM pVM, char *pszName, size_t cchName, char *pszVersion, size_t cchVersion);
+VMMR3DECL(void *) DBGFR3OSQueryInterface(PVM pVM, DBGFOSINTERFACE enmIf);
+
+
+VMMR3DECL(int) DBGFR3CoreWrite(PVM pVM, const char *pszFilename, bool fReplaceFile);
+
+/** @} */
+
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/dbgfcorefmt.h b/include/VBox/vmm/dbgfcorefmt.h
new file mode 100644
index 00000000..28f6aec2
--- /dev/null
+++ b/include/VBox/vmm/dbgfcorefmt.h
@@ -0,0 +1,79 @@
+/** @file
+ * DBGF - Debugger Facility, VM Core File Format.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_dbgfcore_h
+#define ___VBox_vmm_dbgfcore_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/cpumctx.h>
+#include <iprt/assert.h>
+
+
+RT_C_DECLS_BEGIN
+
+
+/** @addgroup grp_dbgf_corefmt VM Core File Format
+ * @ingroup grp_dbgf
+ *
+ * @todo Add description of the core file format and how the structures in this
+ * file relate to it. Point to CPUMCTX in cpum.h for the CPU state.
+ * @todo Add the note names.
+ *
+ * @{
+ */
+
+/** DBGCORECOREDESCRIPTOR::u32Magic. */
+#define DBGFCORE_MAGIC UINT32_C(0xc01ac0de)
+/** DBGCORECOREDESCRIPTOR::u32FmtVersion. */
+#define DBGFCORE_FMT_VERSION UINT32_C(0x00010000)
+
+/**
+ * The DBGF Core descriptor.
+ */
+typedef struct DBGFCOREDESCRIPTOR
+{
+ /** The core file magic (DBGFCORE_MAGIC) */
+ uint32_t u32Magic;
+ /** The core file format version (DBGFCORE_FMT_VERSION). */
+ uint32_t u32FmtVersion;
+ /** Size of this structure (sizeof(DBGFCOREDESCRIPTOR)). */
+ uint32_t cbSelf;
+ /** VirtualBox version. */
+ uint32_t u32VBoxVersion;
+ /** VirtualBox revision. */
+ uint32_t u32VBoxRevision;
+ /** Number of CPUs. */
+ uint32_t cCpus;
+} DBGFCOREDESCRIPTOR;
+AssertCompileSizeAlignment(DBGFCOREDESCRIPTOR, 8);
+/** Pointer to DBGFCOREDESCRIPTOR data. */
+typedef DBGFCOREDESCRIPTOR *PDBGFCOREDESCRIPTOR;
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/dbgfsel.h b/include/VBox/vmm/dbgfsel.h
new file mode 100644
index 00000000..708666bf
--- /dev/null
+++ b/include/VBox/vmm/dbgfsel.h
@@ -0,0 +1,104 @@
+/** @file
+ * DBGF - Debugger Facility, selector interface partly shared with SELM.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_dbgfsel_h
+#define ___VBox_vmm_dbgfsel_h
+
+#include <VBox/types.h>
+#include <iprt/x86.h>
+
+
+/** @addtogroup grp_dbgf
+ * @{ */
+
+/**
+ * Selector information structure.
+ */
+typedef struct DBGFSELINFO
+{
+ /** The base address.
+ * For gate descriptors, this is the target address. */
+ RTGCPTR GCPtrBase;
+ /** The limit (-1).
+ * For gate descriptors, this is set to zero. */
+ RTGCUINTPTR cbLimit;
+ /** The raw descriptor. */
+ union
+ {
+ X86DESC Raw;
+ X86DESC64 Raw64;
+ } u;
+ /** The selector. */
+ RTSEL Sel;
+ /** The target selector for a gate.
+ * This is 0 if non-gate descriptor. */
+ RTSEL SelGate;
+ /** Flags. */
+ uint32_t fFlags;
+} DBGFSELINFO;
+/** Pointer to a SELM selector information struct. */
+typedef DBGFSELINFO *PDBGFSELINFO;
+/** Pointer to a const SELM selector information struct. */
+typedef const DBGFSELINFO *PCDBGFSELINFO;
+
+/** @name DBGFSELINFO::fFlags
+ * @{ */
+/** The CPU is in real mode. */
+#define DBGFSELINFO_FLAGS_REAL_MODE RT_BIT_32(0)
+/** The CPU is in protected mode. */
+#define DBGFSELINFO_FLAGS_PROT_MODE RT_BIT_32(1)
+/** The CPU is in long mode. */
+#define DBGFSELINFO_FLAGS_LONG_MODE RT_BIT_32(2)
+/** The selector is a hyper selector. */
+#define DBGFSELINFO_FLAGS_HYPER RT_BIT_32(3)
+/** The selector is a gate selector. */
+#define DBGFSELINFO_FLAGS_GATE RT_BIT_32(4)
+/** The selector is invalid. */
+#define DBGFSELINFO_FLAGS_INVALID RT_BIT_32(5)
+/** The selector not present. */
+#define DBGFSELINFO_FLAGS_NOT_PRESENT RT_BIT_32(6)
+/** @} */
+
+
+/**
+ * Tests whether the selector info describes an expand-down selector or now.
+ *
+ * @returns true / false.
+ * @param pSelInfo The selector info.
+ */
+DECLINLINE(bool) DBGFSelInfoIsExpandDown(PCDBGFSELINFO pSelInfo)
+{
+ return (pSelInfo)->u.Raw.Gen.u1DescType
+ && ((pSelInfo)->u.Raw.Gen.u4Type & (X86_SEL_TYPE_DOWN | X86_SEL_TYPE_CODE)) == X86_SEL_TYPE_DOWN;
+}
+
+
+VMMR3DECL(int) DBGFR3SelInfoValidateCS(PCDBGFSELINFO pSelInfo, RTSEL SelCPL);
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/dbgftrace.h b/include/VBox/vmm/dbgftrace.h
new file mode 100644
index 00000000..df9b15de
--- /dev/null
+++ b/include/VBox/vmm/dbgftrace.h
@@ -0,0 +1,143 @@
+/** @file
+ * DBGF - Debugger Facility.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_dbgftrace_h
+#define ___VBox_vmm_dbgftrace_h
+
+#include <iprt/trace.h>
+#include <VBox/types.h>
+
+RT_C_DECLS_BEGIN
+/** @addgroup grp_dbgf_trace Tracing
+ * @ingroup grp_dbgf
+ *
+ * @{
+ */
+
+#if (defined(RTTRACE_ENABLED) || DBGFTRACE_ENABLED) && !defined(DBGFTRACE_DISABLED)
+# undef DBGFTRACE_ENABLED
+# undef DBGFTRACE_DISABLED
+# define DBGFTRACE_ENABLED
+#else
+# undef DBGFTRACE_ENABLED
+# undef DBGFTRACE_DISABLED
+# define DBGFTRACE_DISABLED
+#endif
+
+VMMDECL(int) DBGFR3TraceConfig(PVM pVM, const char *pszConfig);
+
+
+/** @name VMM Internal Trace Macros
+ * @remarks The user of these macros is responsible of including VBox/vmm/vm.h.
+ * @{
+ */
+/**
+ * Records a 64-bit unsigned integer together with a tag string.
+ */
+#ifdef DBGFTRACE_ENABLED
+# define DBGFTRACE_U64_TAG(a_pVM, a_u64, a_pszTag) \
+ do { RTTraceBufAddMsgF((a_pVM)->CTX_SUFF(hTraceBuf), "%'llu %s", (a_u64), (a_pszTag)); } while (0)
+#else
+# define DBGFTRACE_U64_TAG(a_pVM, a_u64, a_pszTag) do { } while (0)
+#endif
+
+/**
+ * Records a 64-bit unsigned integer together with two tag strings.
+ */
+#ifdef DBGFTRACE_ENABLED
+# define DBGFTRACE_U64_TAG2(a_pVM, a_u64, a_pszTag1, a_pszTag2) \
+ do { RTTraceBufAddMsgF((a_pVM)->CTX_SUFF(hTraceBuf), "%'llu %s %s", (a_u64), (a_pszTag1), (a_pszTag2)); } while (0)
+#else
+# define DBGFTRACE_U64_TAG2(a_pVM, a_u64, a_pszTag1, a_pszTag2) do { } while (0)
+#endif
+
+/**
+ * Records the current source position.
+ */
+#ifdef DBGFTRACE_ENABLED
+# define DBGFTRACE_POS(a_pVM) \
+ do { RTTraceBufAddPos((a_pVM)->CTX_SUFF(hTraceBuf), RT_SRC_POS); } while (0)
+#else
+# define DBGFTRACE_POS(a_pVM) do { } while (0)
+#endif
+
+/**
+ * Records the current source position along with a 64-bit unsigned integer.
+ */
+#ifdef DBGFTRACE_ENABLED
+# define DBGFTRACE_POS_U64(a_pVM, a_u64) \
+ do { RTTraceBufAddPosMsgF((a_pVM)->CTX_SUFF(hTraceBuf), RT_SRC_POS, "%'llu", (a_u64)); } while (0)
+#else
+# define DBGFTRACE_POS_U64(a_pVM, a_u64) do { } while (0)
+#endif
+/** @} */
+
+
+/** @name Tracing Macors for PDM Devices, Drivers and USB Devices.
+ * @{
+ */
+
+/**
+ * Get the trace buffer handle.
+ * @param a_pIns The instance (pDevIns, pDrvIns or pUsbIns).
+ */
+#define DBGFTRACE_PDM_TRACEBUF(a_pIns) ( (a_pIns)->CTX_SUFF(pHlp)->pfnDBGFTraceBuf((a_pIns)) )
+
+/**
+ * Records a tagged 64-bit unsigned integer.
+ */
+#ifdef DBGFTRACE_ENABLED
+# define DBGFTRACE_PDM_U64_TAG(a_pIns, a_u64, a_pszTag) \
+ do { RTTraceBufAddMsgF(DBGFTRACE_PDM_TRACEBUF(a_pIns), "%'llu %s", (a_u64), (a_pszTag)); } while (0)
+#else
+# define DBGFTRACE_PDM_U64_TAG(a_pIns, a_u64, a_pszTag) do { } while (0)
+#endif
+
+/**
+ * Records the current source position.
+ */
+#ifdef DBGFTRACE_ENABLED
+# define DBGFTRACE_PDM_POS(a_pIns) \
+ do { RTTraceBufAddPos(DBGFTRACE_PDM_TRACEBUF(a_pIns), RT_SRC_POS); } while (0)
+#else
+# define DBGFTRACE_PDM_POS(a_pIns) do { } while (0)
+#endif
+
+/**
+ * Records the current source position along with a 64-bit unsigned integer.
+ */
+#ifdef DBGFTRACE_ENABLED
+# define DBGFTRACE_PDM_POS_U64(a_pIns, a_u64) \
+ do { RTTraceBufAddPosMsgF(DBGFTRACE_PDM_TRACEBUF(a_pIns), RT_SRC_POS, "%'llu", (a_u64)); } while (0)
+#else
+# define DBGFTRACE_PDM_POS_U64(a_pIns, a_u64) do { } while (0)
+#endif
+/** @} */
+
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/em.h b/include/VBox/vmm/em.h
new file mode 100644
index 00000000..a0efe5fc
--- /dev/null
+++ b/include/VBox/vmm/em.h
@@ -0,0 +1,276 @@
+/** @file
+ * EM - Execution Monitor.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_em_h
+#define ___VBox_vmm_em_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/trpm.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_em The Execution Monitor / Manager API
+ * @{
+ */
+
+/** Enable to allow V86 code to run in raw mode. */
+#define VBOX_RAW_V86
+
+/**
+ * The Execution Manager State.
+ *
+ * @remarks This is used in the saved state!
+ */
+typedef enum EMSTATE
+{
+ /** Not yet started. */
+ EMSTATE_NONE = 1,
+ /** Raw-mode execution. */
+ EMSTATE_RAW,
+ /** Hardware accelerated raw-mode execution. */
+ EMSTATE_HWACC,
+ /** Value reserved for future use (used to be PARAV). */
+ EMSTATE_RESERVED,
+ /** Recompiled mode execution. */
+ EMSTATE_REM,
+ /** Execution is halted. (waiting for interrupt) */
+ EMSTATE_HALTED,
+ /** Application processor execution is halted. (waiting for startup IPI (SIPI)) */
+ EMSTATE_WAIT_SIPI,
+ /** Execution is suspended. */
+ EMSTATE_SUSPENDED,
+ /** The VM is terminating. */
+ EMSTATE_TERMINATING,
+ /** Guest debug event from raw-mode is being processed. */
+ EMSTATE_DEBUG_GUEST_RAW,
+ /** Guest debug event from hardware accelerated mode is being processed. */
+ EMSTATE_DEBUG_GUEST_HWACC,
+ /** Guest debug event from recompiled-mode is being processed. */
+ EMSTATE_DEBUG_GUEST_REM,
+ /** Hypervisor debug event being processed. */
+ EMSTATE_DEBUG_HYPER,
+ /** The VM has encountered a fatal error. (And everyone is panicing....) */
+ EMSTATE_GURU_MEDITATION,
+ /** Just a hack to ensure that we get a 32-bit integer. */
+ EMSTATE_MAKE_32BIT_HACK = 0x7fffffff
+} EMSTATE;
+
+
+/**
+ * EMInterpretInstructionCPU execution modes.
+ */
+typedef enum
+{
+ /** Only supervisor code (CPL=0). */
+ EMCODETYPE_SUPERVISOR,
+ /** User-level code only. */
+ EMCODETYPE_USER,
+ /** Supervisor and user-level code (use with great care!). */
+ EMCODETYPE_ALL,
+ /** Just a hack to ensure that we get a 32-bit integer. */
+ EMCODETYPE_32BIT_HACK = 0x7fffffff
+} EMCODETYPE;
+
+VMMDECL(EMSTATE) EMGetState(PVMCPU pVCpu);
+VMMDECL(void) EMSetState(PVMCPU pVCpu, EMSTATE enmNewState);
+
+/** @name Callback handlers for instruction emulation functions.
+ * These are placed here because IOM wants to use them as well.
+ * @{
+ */
+typedef DECLCALLBACK(uint32_t) FNEMULATEPARAM2UINT32(void *pvParam1, uint64_t val2);
+typedef FNEMULATEPARAM2UINT32 *PFNEMULATEPARAM2UINT32;
+typedef DECLCALLBACK(uint32_t) FNEMULATEPARAM2(void *pvParam1, size_t val2);
+typedef FNEMULATEPARAM2 *PFNEMULATEPARAM2;
+typedef DECLCALLBACK(uint32_t) FNEMULATEPARAM3(void *pvParam1, uint64_t val2, size_t val3);
+typedef FNEMULATEPARAM3 *PFNEMULATEPARAM3;
+typedef DECLCALLBACK(int) FNEMULATELOCKPARAM2(void *pvParam1, uint64_t val2, RTGCUINTREG32 *pf);
+typedef FNEMULATELOCKPARAM2 *PFNEMULATELOCKPARAM2;
+typedef DECLCALLBACK(int) FNEMULATELOCKPARAM3(void *pvParam1, uint64_t val2, size_t cb, RTGCUINTREG32 *pf);
+typedef FNEMULATELOCKPARAM3 *PFNEMULATELOCKPARAM3;
+/** @} */
+
+
+/**
+ * Checks if raw ring-3 execute mode is enabled.
+ *
+ * @returns true if enabled.
+ * @returns false if disabled.
+ * @param pVM The VM to operate on.
+ */
+#define EMIsRawRing3Enabled(pVM) (!(pVM)->fRecompileUser)
+
+/**
+ * Checks if raw ring-0 execute mode is enabled.
+ *
+ * @returns true if enabled.
+ * @returns false if disabled.
+ * @param pVM The VM to operate on.
+ */
+#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor)
+
+/**
+ * Checks if execution with hardware assisted virtualization is enabled.
+ *
+ * @returns true if enabled.
+ * @returns false if disabled.
+ * @param pVM The VM to operate on.
+ */
+#define EMIsHwVirtExecutionEnabled(pVM) (!(pVM)->fRecompileSupervisor && !(pVM)->fRecompileUser)
+
+/**
+ * Checks if execution of supervisor code should be done in the
+ * recompiler or not.
+ *
+ * @returns true if enabled.
+ * @returns false if disabled.
+ * @param pVM The VM to operate on.
+ */
+#define EMIsSupervisorCodeRecompiled(pVM) ((pVM)->fRecompileSupervisor)
+
+VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC);
+VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu);
+VMMDECL(int) EMInterpretDisasCurrent(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pCpu, unsigned *pcbInstr);
+VMMDECL(int) EMInterpretDisasOneEx(PVM pVM, PVMCPU pVCpu, RTGCUINTPTR GCPtrInstr, PCCPUMCTXCORE pCtxCore,
+ PDISCPUSTATE pDISState, unsigned *pcbInstr);
+VMMDECL(VBOXSTRICTRC) EMInterpretInstruction(PVMCPU pVCpu, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault);
+VMMDECL(VBOXSTRICTRC) EMInterpretInstructionEx(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbWritten);
+VMMDECL(VBOXSTRICTRC) EMInterpretInstructionDisasState(PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pCoreCtx, RTGCPTR pvFault, EMCODETYPE enmCodeType);
+
+#ifdef IN_RC
+VMMDECL(int) EMInterpretIretV86ForPatm(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+#endif
+
+VMMDECL(int) EMInterpretCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMMDECL(int) EMInterpretRdtsc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMMDECL(int) EMInterpretRdpmc(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMMDECL(int) EMInterpretRdtscp(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMDECL(VBOXSTRICTRC) EMInterpretInvlpg(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pAddrGC);
+VMMDECL(VBOXSTRICTRC) EMInterpretMWait(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMMDECL(int) EMInterpretMonitor(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMMDECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen);
+VMMDECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx);
+VMMDECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen);
+VMMDECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx);
+VMMDECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data);
+VMMDECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu);
+#ifndef VBOX_WITH_IEM
+VMMDECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+VMMDECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
+#endif /* !VBOX_WITH_IEM */
+VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx);
+VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx);
+VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx);
+
+/** @name Assembly routines
+ * @{ */
+VMMDECL(uint32_t) EMEmulateCmp(uint32_t u32Param1, uint64_t u64Param2, size_t cb);
+VMMDECL(uint32_t) EMEmulateAnd(void *pvParam1, uint64_t u64Param2, size_t cb);
+VMMDECL(uint32_t) EMEmulateInc(void *pvParam1, size_t cb);
+VMMDECL(uint32_t) EMEmulateDec(void *pvParam1, size_t cb);
+VMMDECL(uint32_t) EMEmulateOr(void *pvParam1, uint64_t u64Param2, size_t cb);
+VMMDECL(int) EMEmulateLockOr(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
+VMMDECL(uint32_t) EMEmulateXor(void *pvParam1, uint64_t u64Param2, size_t cb);
+VMMDECL(int) EMEmulateLockXor(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
+VMMDECL(uint32_t) EMEmulateAdd(void *pvParam1, uint64_t u64Param2, size_t cb);
+VMMDECL(int) EMEmulateLockAnd(void *pvParam1, uint64_t u64Param2, size_t cbSize, RTGCUINTREG32 *pf);
+VMMDECL(uint32_t) EMEmulateSub(void *pvParam1, uint64_t u64Param2, size_t cb);
+VMMDECL(uint32_t) EMEmulateAdcWithCarrySet(void *pvParam1, uint64_t u64Param2, size_t cb);
+VMMDECL(uint32_t) EMEmulateBtr(void *pvParam1, uint64_t u64Param2);
+VMMDECL(int) EMEmulateLockBtr(void *pvParam1, uint64_t u64Param2, RTGCUINTREG32 *pf);
+VMMDECL(uint32_t) EMEmulateBts(void *pvParam1, uint64_t u64Param2);
+VMMDECL(uint32_t) EMEmulateBtc(void *pvParam1, uint64_t u64Param2);
+VMMDECL(uint32_t) EMEmulateCmpXchg(void *pvParam1, uint64_t *pu32Param2, uint64_t u32Param3, size_t cbSize);
+VMMDECL(uint32_t) EMEmulateLockCmpXchg(void *pvParam1, uint64_t *pu64Param2, uint64_t u64Param3, size_t cbSize);
+VMMDECL(uint32_t) EMEmulateCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
+VMMDECL(uint32_t) EMEmulateLockCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
+VMMDECL(uint32_t) EMEmulateXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
+VMMDECL(uint32_t) EMEmulateLockXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
+/** @} */
+
+/** @name REM locking routines
+ * @{ */
+VMMDECL(void) EMRemUnlock(PVM pVM);
+VMMDECL(void) EMRemLock(PVM pVM);
+VMMDECL(bool) EMRemIsLockOwner(PVM pVM);
+VMMDECL(int) EMRemTryLock(PVM pVM);
+/** @} */
+
+#ifdef IN_RING3
+/** @defgroup grp_em_r3 The EM Host Context Ring-3 API
+ * @ingroup grp_em
+ * @{
+ */
+VMMR3DECL(int) EMR3Init(PVM pVM);
+VMMR3DECL(void) EMR3Relocate(PVM pVM);
+VMMR3DECL(void) EMR3ResetCpu(PVMCPU pVCpu);
+VMMR3DECL(void) EMR3Reset(PVM pVM);
+VMMR3DECL(int) EMR3Term(PVM pVM);
+VMMR3DECL(DECLNORETURN(void)) EMR3FatalError(PVMCPU pVCpu, int rc);
+VMMR3DECL(int) EMR3ExecuteVM(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) EMR3CheckRawForcedActions(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) EMR3Interpret(PVM pVM);
+
+/**
+ * Command argument for EMR3RawSetMode().
+ *
+ * It's possible to extend this interface to change several
+ * execution modes at once should the need arise.
+ */
+typedef enum EMEXECPOLICY
+{
+ /** The customary invalid zero entry. */
+ EMEXECPOLICY_INVALID = 0,
+ /** Whether to recompile ring-0 code or execute it in raw/hm. */
+ EMEXECPOLICY_RECOMPILE_RING0,
+ /** Whether to recompile ring-3 code or execute it in raw/hm. */
+ EMEXECPOLICY_RECOMPILE_RING3,
+ /** End of valid value (not included). */
+ EMEXECPOLICY_END,
+ /** The customary 32-bit type blowup. */
+ EMEXECPOLICY_32BIT_HACK = 0x7fffffff
+} EMEXECPOLICY;
+
+VMMR3DECL(int) EMR3SetExecutionPolicy(PVM pVM, EMEXECPOLICY enmPolicy, bool fEnforce);
+/** @} */
+#endif /* IN_RING3 */
+
+
+#ifdef IN_RC
+/** @defgroup grp_em_gc The EM Guest Context API
+ * @ingroup grp_em
+ * @{
+ */
+VMMRCDECL(int) EMGCTrap(PVM pVM, unsigned uTrap, PCPUMCTXCORE pRegFrame);
+/** @} */
+#endif /* IN_RC */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/ftm.h b/include/VBox/vmm/ftm.h
new file mode 100644
index 00000000..2fc1ccfe
--- /dev/null
+++ b/include/VBox/vmm/ftm.h
@@ -0,0 +1,71 @@
+/** @file
+ * FTM - Fault Tolerance Manager.
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_ftm_h
+#define ___VBox_vmm_ftm_h
+
+#include <VBox/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_ftm The Fault Tolerance Monitor / Manager API
+ * @{
+ */
+
+/**
+ * Fault tolerance checkpoint type.
+ */
+typedef enum FTMCHECKPOINTTYPE
+{
+ FTMCHECKPOINTTYPE_NETWORK,
+ FTMCHECKPOINTTYPE_STORAGE,
+ FTMCHECKPOINTTYPE_32BIT_HACK = 0x7fffffff
+} FTMCHECKPOINTTYPE;
+
+VMMDECL(bool) FTMIsDeltaLoadSaveActive(PVM pVM);
+VMMDECL(int) FTMSetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType);
+
+#ifdef IN_RING3
+/** @defgroup grp_ftm_r3 The FTM Host Context Ring-3 API
+ * @ingroup grp_ftm
+ * @{
+ */
+VMMR3DECL(int) FTMR3PowerOn(PVM pVM, bool fMaster, unsigned uInterval, const char *pszAddress, unsigned uPort, const char *pszPassword);
+VMMR3DECL(int) FTMR3Init(PVM pVM);
+VMMR3DECL(int) FTMR3Term(PVM pVM);
+VMMR3DECL(int) FTMR3CancelStandby(PVM pVM);
+VMMR3DECL(int) FTMR3SetCheckpoint(PVM pVM, FTMCHECKPOINTTYPE enmType);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/gmm.h b/include/VBox/vmm/gmm.h
new file mode 100644
index 00000000..0f93c94a
--- /dev/null
+++ b/include/VBox/vmm/gmm.h
@@ -0,0 +1,809 @@
+/** @file
+ * GMM - The Global Memory Manager.
+ */
+
+/*
+ * Copyright (C) 2007-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_gmm_h
+#define ___VBox_vmm_gmm_h
+
+#include <VBox/vmm/gvmm.h>
+#include <VBox/sup.h>
+#include <VBox/param.h>
+#include <VBox/ostypes.h>
+#include <VBox/VMMDev.h>
+#include <iprt/avl.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_gmm GMM - The Global Memory Manager
+ * @{
+ */
+
+/** @def IN_GMM_R0
+ * Used to indicate whether we're inside the same link module as the ring 0
+ * part of the Global Memory Manager or not.
+ */
+#ifdef DOXYGEN_RUNNING
+# define IN_GMM_R0
+#endif
+/** @def GMMR0DECL
+ * Ring 0 GMM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_GMM_R0
+# define GMMR0DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define GMMR0DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def IN_GMM_R3
+ * Used to indicate whether we're inside the same link module as the ring 3
+ * part of the Global Memory Manager or not.
+ */
+#ifdef DOXYGEN_RUNNING
+# define IN_GMM_R3
+#endif
+/** @def GMMR3DECL
+ * Ring 3 GMM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_GMM_R3
+# define GMMR3DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define GMMR3DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+
+/** The chunk shift. (2^21 = 2 MB) */
+#define GMM_CHUNK_SHIFT 21
+/** The allocation chunk size. */
+#define GMM_CHUNK_SIZE (1U << GMM_CHUNK_SHIFT)
+/** The allocation chunk size in pages. */
+#define GMM_CHUNK_NUM_PAGES (1U << (GMM_CHUNK_SHIFT - PAGE_SHIFT))
+/** The shift factor for converting a page id into a chunk id. */
+#define GMM_CHUNKID_SHIFT (GMM_CHUNK_SHIFT - PAGE_SHIFT)
+/** The last valid Chunk ID value. */
+#define GMM_CHUNKID_LAST (GMM_PAGEID_LAST >> GMM_CHUNKID_SHIFT)
+/** The last valid Page ID value.
+ * The current limit is 2^28 - 1, or almost 1TB if you like.
+ * The constraints are currently dictated by PGMPAGE. */
+#define GMM_PAGEID_LAST (RT_BIT_32(28) - 1)
+/** Mask out the page index from the Page ID. */
+#define GMM_PAGEID_IDX_MASK ((1U << GMM_CHUNKID_SHIFT) - 1)
+/** The NIL Chunk ID value. */
+#define NIL_GMM_CHUNKID 0
+/** The NIL Page ID value. */
+#define NIL_GMM_PAGEID 0
+
+#if 0 /* wrong - these are guest page pfns and not page ids! */
+/** Special Page ID used by unassigned pages. */
+#define GMM_PAGEID_UNASSIGNED 0x0fffffffU
+/** Special Page ID used by unsharable pages.
+ * Like MMIO2, shadow and heap. This is for later, obviously. */
+#define GMM_PAGEID_UNSHARABLE 0x0ffffffeU
+/** The end of the valid Page IDs. This is the first special one. */
+#define GMM_PAGEID_END 0x0ffffff0U
+#endif
+
+
+/** @def GMM_GCPHYS_LAST
+ * The last of the valid guest physical address as it applies to GMM pages.
+ *
+ * This must reflect the constraints imposed by the RTGCPHYS type and
+ * the guest page frame number used internally in GMMPAGE.
+ *
+ * @note Note this corresponds to GMM_PAGE_PFN_LAST. */
+#if HC_ARCH_BITS == 64
+# define GMM_GCPHYS_LAST UINT64_C(0x00000fffffff0000) /* 2^44 (16TB) - 0x10000 */
+#else
+# define GMM_GCPHYS_LAST UINT64_C(0x0000000fffff0000) /* 2^36 (64GB) - 0x10000 */
+#endif
+
+/**
+ * Over-commitment policy.
+ */
+typedef enum GMMOCPOLICY
+{
+ /** The usual invalid 0 value. */
+ GMMOCPOLICY_INVALID = 0,
+ /** No over-commitment, fully backed.
+ * The GMM guarantees that it will be able to allocate all of the
+ * guest RAM for a VM with OC policy. */
+ GMMOCPOLICY_NO_OC,
+ /** to-be-determined. */
+ GMMOCPOLICY_TBD,
+ /** The end of the valid policy range. */
+ GMMOCPOLICY_END,
+ /** The usual 32-bit hack. */
+ GMMOCPOLICY_32BIT_HACK = 0x7fffffff
+} GMMOCPOLICY;
+
+/**
+ * VM / Memory priority.
+ */
+typedef enum GMMPRIORITY
+{
+ /** The usual invalid 0 value. */
+ GMMPRIORITY_INVALID = 0,
+ /** High.
+ * When ballooning, ask these VMs last.
+ * When running out of memory, try not to interrupt these VMs. */
+ GMMPRIORITY_HIGH,
+ /** Normal.
+ * When ballooning, don't wait to ask these.
+ * When running out of memory, pause, save and/or kill these VMs. */
+ GMMPRIORITY_NORMAL,
+ /** Low.
+ * When ballooning, maximize these first.
+ * When running out of memory, save or kill these VMs. */
+ GMMPRIORITY_LOW,
+ /** The end of the valid priority range. */
+ GMMPRIORITY_END,
+ /** The custom 32-bit type blowup. */
+ GMMPRIORITY_32BIT_HACK = 0x7fffffff
+} GMMPRIORITY;
+
+
+/**
+ * GMM Memory Accounts.
+ */
+typedef enum GMMACCOUNT
+{
+ /** The customary invalid zero entry. */
+ GMMACCOUNT_INVALID = 0,
+ /** Account with the base allocations. */
+ GMMACCOUNT_BASE,
+ /** Account with the shadow allocations. */
+ GMMACCOUNT_SHADOW,
+ /** Account with the fixed allocations. */
+ GMMACCOUNT_FIXED,
+ /** The end of the valid values. */
+ GMMACCOUNT_END,
+ /** The usual 32-bit value to finish it off. */
+ GMMACCOUNT_32BIT_HACK = 0x7fffffff
+} GMMACCOUNT;
+
+
+/**
+ * Balloon actions.
+ */
+typedef enum
+{
+ /** Invalid zero entry. */
+ GMMBALLOONACTION_INVALID = 0,
+ /** Inflate the balloon. */
+ GMMBALLOONACTION_INFLATE,
+ /** Deflate the balloon. */
+ GMMBALLOONACTION_DEFLATE,
+ /** Puncture the balloon because of VM reset. */
+ GMMBALLOONACTION_RESET,
+ /** End of the valid actions. */
+ GMMBALLOONACTION_END,
+ /** hack forcing the size of the enum to 32-bits. */
+ GMMBALLOONACTION_MAKE_32BIT_HACK = 0x7fffffff
+} GMMBALLOONACTION;
+
+
+/**
+ * A page descriptor for use when freeing pages.
+ * See GMMR0FreePages, GMMR0BalloonedPages.
+ */
+typedef struct GMMFREEPAGEDESC
+{
+ /** The Page ID of the page to be freed. */
+ uint32_t idPage;
+} GMMFREEPAGEDESC;
+/** Pointer to a page descriptor for freeing pages. */
+typedef GMMFREEPAGEDESC *PGMMFREEPAGEDESC;
+
+
+/**
+ * A page descriptor for use when updating and allocating pages.
+ *
+ * This is a bit complicated because we want to do as much as possible
+ * with the same structure.
+ */
+typedef struct GMMPAGEDESC
+{
+ /** The physical address of the page.
+ *
+ * @input GMMR0AllocateHandyPages expects the guest physical address
+ * to update the GMMPAGE structure with. Pass GMM_GCPHYS_UNSHAREABLE
+ * when appropriate and NIL_RTHCPHYS when the page wasn't used
+ * for any specific guest address.
+ *
+ * GMMR0AllocatePage expects the guest physical address to put in
+ * the GMMPAGE structure for the page it allocates for this entry.
+ * Pass NIL_RTHCPHYS and GMM_GCPHYS_UNSHAREABLE as above.
+ *
+ * @output The host physical address of the allocated page.
+ * NIL_RTHCPHYS on allocation failure.
+ *
+ * ASSUMES: sizeof(RTHCPHYS) >= sizeof(RTGCPHYS).
+ */
+ RTHCPHYS HCPhysGCPhys;
+
+ /** The Page ID.
+ *
+ * @intput GMMR0AllocateHandyPages expects the Page ID of the page to
+ * update here. NIL_GMM_PAGEID means no page should be updated.
+ *
+ * GMMR0AllocatePages requires this to be initialized to
+ * NIL_GMM_PAGEID currently.
+ *
+ * @output The ID of the page, NIL_GMM_PAGEID if the allocation failed.
+ */
+ uint32_t idPage;
+
+ /** The Page ID of the shared page was replaced by this page.
+ *
+ * @input GMMR0AllocateHandyPages expects this to indicate a shared
+ * page that has been replaced by this page and should have its
+ * reference counter decremented and perhaps be freed up. Use
+ * NIL_GMM_PAGEID if no shared page was involved.
+ *
+ * All other APIs expects NIL_GMM_PAGEID here.
+ *
+ * @output All APIs sets this to NIL_GMM_PAGEID.
+ */
+ uint32_t idSharedPage;
+} GMMPAGEDESC;
+AssertCompileSize(GMMPAGEDESC, 16);
+/** Pointer to a page allocation. */
+typedef GMMPAGEDESC *PGMMPAGEDESC;
+
+/** GMMPAGEDESC::HCPhysGCPhys value that indicates that the page is unsharable.
+ * @note This corresponds to GMM_PAGE_PFN_UNSHAREABLE. */
+#if HC_ARCH_BITS == 64
+# define GMM_GCPHYS_UNSHAREABLE UINT64_C(0x00000fffffff1000)
+#else
+# define GMM_GCPHYS_UNSHAREABLE UINT64_C(0x0000000fffff1000)
+#endif
+
+
+/**
+ * The allocation sizes.
+ */
+typedef struct GMMVMSIZES
+{
+ /** The number of pages of base memory.
+ * This is the sum of RAM, ROMs and handy pages. */
+ uint64_t cBasePages;
+ /** The number of pages for the shadow pool. (Can be squeezed for memory.) */
+ uint32_t cShadowPages;
+ /** The number of pages for fixed allocations like MMIO2 and the hyper heap. */
+ uint32_t cFixedPages;
+} GMMVMSIZES;
+/** Pointer to a GMMVMSIZES. */
+typedef GMMVMSIZES *PGMMVMSIZES;
+
+
+/**
+ * GMM VM statistics.
+ */
+typedef struct GMMVMSTATS
+{
+ /** The reservations. */
+ GMMVMSIZES Reserved;
+ /** The actual allocations.
+ * This includes both private and shared page allocations. */
+ GMMVMSIZES Allocated;
+
+ /** The current number of private pages. */
+ uint64_t cPrivatePages;
+ /** The current number of shared pages. */
+ uint64_t cSharedPages;
+ /** The current number of ballooned pages. */
+ uint64_t cBalloonedPages;
+ /** The max number of pages that can be ballooned. */
+ uint64_t cMaxBalloonedPages;
+ /** The number of pages we've currently requested the guest to give us.
+ * This is 0 if no pages currently requested. */
+ uint64_t cReqBalloonedPages;
+ /** The number of pages the guest has given us in response to the request.
+ * This is not reset on request completed and may be used in later decisions. */
+ uint64_t cReqActuallyBalloonedPages;
+ /** The number of pages we've currently requested the guest to take back. */
+ uint64_t cReqDeflatePages;
+ /** The number of shareable module tracked by this VM. */
+ uint32_t cShareableModules;
+
+ /** The current over-commitment policy. */
+ GMMOCPOLICY enmPolicy;
+ /** The VM priority for arbitrating VMs in low and out of memory situation.
+ * Like which VMs to start squeezing first. */
+ GMMPRIORITY enmPriority;
+ /** Whether ballooning is enabled or not. */
+ bool fBallooningEnabled;
+ /** Whether shared paging is enabled or not. */
+ bool fSharedPagingEnabled;
+ /** Whether the VM is allowed to allocate memory or not.
+ * This is used when the reservation update request fails or when the VM has
+ * been told to suspend/save/die in an out-of-memory case. */
+ bool fMayAllocate;
+ /** Explicit alignment. */
+ bool afReserved[1];
+
+
+} GMMVMSTATS;
+
+
+/**
+ * The GMM statistics.
+ */
+typedef struct GMMSTATS
+{
+ /** The maximum number of pages we're allowed to allocate
+ * (GMM::cMaxPages). */
+ uint64_t cMaxPages;
+ /** The number of pages that has been reserved (GMM::cReservedPages). */
+ uint64_t cReservedPages;
+ /** The number of pages that we have over-committed in reservations
+ * (GMM::cOverCommittedPages). */
+ uint64_t cOverCommittedPages;
+ /** The number of actually allocated (committed if you like) pages
+ * (GMM::cAllocatedPages). */
+ uint64_t cAllocatedPages;
+ /** The number of pages that are shared. A subset of cAllocatedPages.
+ * (GMM::cSharedPages) */
+ uint64_t cSharedPages;
+ /** The number of pages that are actually shared between VMs.
+ * (GMM:cDuplicatePages) */
+ uint64_t cDuplicatePages;
+ /** The number of pages that are shared that has been left behind by
+ * VMs not doing proper cleanups (GMM::cLeftBehindSharedPages). */
+ uint64_t cLeftBehindSharedPages;
+ /** The number of current ballooned pages (GMM::cBalloonedPages). */
+ uint64_t cBalloonedPages;
+ /** The number of allocation chunks (GMM::cChunks). */
+ uint32_t cChunks;
+ /** The number of freed chunks ever (GMM::cFreedChunks). */
+ uint32_t cFreedChunks;
+ /** The number of shareable modules (GMM:cShareableModules). */
+ uint64_t cShareableModules;
+ /** Space reserved for later. */
+ uint64_t au64Reserved[2];
+
+ /** Statistics for the specified VM. (Zero filled if not requested.) */
+ GMMVMSTATS VMStats;
+} GMMSTATS;
+/** Pointer to the GMM statistics. */
+typedef GMMSTATS *PGMMSTATS;
+/** Const pointer to the GMM statistics. */
+typedef const GMMSTATS *PCGMMSTATS;
+
+
+GMMR0DECL(int) GMMR0Init(void);
+GMMR0DECL(void) GMMR0Term(void);
+GMMR0DECL(void) GMMR0InitPerVMData(PGVM pGVM);
+GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM);
+GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
+ GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority);
+GMMR0DECL(int) GMMR0UpdateReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages);
+GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesToUpdate, uint32_t cPagesToAlloc, PGMMPAGEDESC paPages);
+GMMR0DECL(int) GMMR0AllocatePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMPAGEDESC paPages, GMMACCOUNT enmAccount);
+GMMR0DECL(int) GMMR0AllocateLargePage(PVM pVM, VMCPUID idCpu, uint32_t cbPage, uint32_t *pIdPage, RTHCPHYS *pHCPhys);
+GMMR0DECL(int) GMMR0FreePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMFREEPAGEDESC paPages, GMMACCOUNT enmAccount);
+GMMR0DECL(int) GMMR0FreeLargePage(PVM pVM, VMCPUID idCpu, uint32_t idPage);
+GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmAction, uint32_t cBalloonedPages);
+GMMR0DECL(int) GMMR0MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3);
+GMMR0DECL(int) GMMR0SeedChunk(PVM pVM, VMCPUID idCpu, RTR3PTR pvR3);
+GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
+ RTGCPTR GCBaseAddr, uint32_t cbModule, uint32_t cRegions,
+ struct VMMDEVSHAREDREGIONDESC const *paRegions);
+GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule);
+GMMR0DECL(int) GMMR0UnregisterAllSharedModules(PVM pVM, VMCPUID idCpu);
+GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, PVMCPU pVCpu);
+GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu);
+GMMR0DECL(int) GMMR0CheckSharedModulesStart(PVM pVM);
+GMMR0DECL(int) GMMR0CheckSharedModulesEnd(PVM pVM);
+GMMR0DECL(int) GMMR0QueryStatistics(PGMMSTATS pStats, PSUPDRVSESSION pSession);
+GMMR0DECL(int) GMMR0ResetStatistics(PCGMMSTATS pStats, PSUPDRVSESSION pSession);
+
+/**
+ * Request buffer for GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION.
+ * @see GMMR0InitialReservation
+ */
+typedef struct GMMINITIALRESERVATIONREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ uint64_t cBasePages; /**< @see GMMR0InitialReservation */
+ uint32_t cShadowPages; /**< @see GMMR0InitialReservation */
+ uint32_t cFixedPages; /**< @see GMMR0InitialReservation */
+ GMMOCPOLICY enmPolicy; /**< @see GMMR0InitialReservation */
+ GMMPRIORITY enmPriority; /**< @see GMMR0InitialReservation */
+} GMMINITIALRESERVATIONREQ;
+/** Pointer to a GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION request buffer. */
+typedef GMMINITIALRESERVATIONREQ *PGMMINITIALRESERVATIONREQ;
+
+GMMR0DECL(int) GMMR0InitialReservationReq(PVM pVM, VMCPUID idCpu, PGMMINITIALRESERVATIONREQ pReq);
+
+
+/**
+ * Request buffer for GMMR0UpdateReservationReq / VMMR0_DO_GMM_UPDATE_RESERVATION.
+ * @see GMMR0UpdateReservation
+ */
+typedef struct GMMUPDATERESERVATIONREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ uint64_t cBasePages; /**< @see GMMR0UpdateReservation */
+ uint32_t cShadowPages; /**< @see GMMR0UpdateReservation */
+ uint32_t cFixedPages; /**< @see GMMR0UpdateReservation */
+} GMMUPDATERESERVATIONREQ;
+/** Pointer to a GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION request buffer. */
+typedef GMMUPDATERESERVATIONREQ *PGMMUPDATERESERVATIONREQ;
+
+GMMR0DECL(int) GMMR0UpdateReservationReq(PVM pVM, VMCPUID idCpu, PGMMUPDATERESERVATIONREQ pReq);
+
+
+/**
+ * Request buffer for GMMR0AllocatePagesReq / VMMR0_DO_GMM_ALLOCATE_PAGES.
+ * @see GMMR0AllocatePages.
+ */
+typedef struct GMMALLOCATEPAGESREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The account to charge the allocation to. */
+ GMMACCOUNT enmAccount;
+ /** The number of pages to allocate. */
+ uint32_t cPages;
+ /** Array of page descriptors. */
+ GMMPAGEDESC aPages[1];
+} GMMALLOCATEPAGESREQ;
+/** Pointer to a GMMR0AllocatePagesReq / VMMR0_DO_GMM_ALLOCATE_PAGES request buffer. */
+typedef GMMALLOCATEPAGESREQ *PGMMALLOCATEPAGESREQ;
+
+GMMR0DECL(int) GMMR0AllocatePagesReq(PVM pVM, VMCPUID idCpu, PGMMALLOCATEPAGESREQ pReq);
+
+
+/**
+ * Request buffer for GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES.
+ * @see GMMR0FreePages.
+ */
+typedef struct GMMFREEPAGESREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The account this relates to. */
+ GMMACCOUNT enmAccount;
+ /** The number of pages to free. */
+ uint32_t cPages;
+ /** Array of free page descriptors. */
+ GMMFREEPAGEDESC aPages[1];
+} GMMFREEPAGESREQ;
+/** Pointer to a GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES request buffer. */
+typedef GMMFREEPAGESREQ *PGMMFREEPAGESREQ;
+
+GMMR0DECL(int) GMMR0FreePagesReq(PVM pVM, VMCPUID idCpu, PGMMFREEPAGESREQ pReq);
+
+/**
+ * Request buffer for GMMR0BalloonedPagesReq / VMMR0_DO_GMM_BALLOONED_PAGES.
+ * @see GMMR0BalloonedPages.
+ */
+typedef struct GMMBALLOONEDPAGESREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The number of ballooned pages. */
+ uint32_t cBalloonedPages;
+ /** Inflate or deflate the balloon. */
+ GMMBALLOONACTION enmAction;
+} GMMBALLOONEDPAGESREQ;
+/** Pointer to a GMMR0BalloonedPagesReq / VMMR0_DO_GMM_BALLOONED_PAGES request buffer. */
+typedef GMMBALLOONEDPAGESREQ *PGMMBALLOONEDPAGESREQ;
+
+GMMR0DECL(int) GMMR0BalloonedPagesReq(PVM pVM, VMCPUID idCpu, PGMMBALLOONEDPAGESREQ pReq);
+
+
+/**
+ * Request buffer for GMMR0QueryHypervisorMemoryStatsReq / VMMR0_DO_GMM_QUERY_VMM_MEM_STATS.
+ * @see GMMR0QueryHypervisorMemoryStatsReq.
+ */
+typedef struct GMMMEMSTATSREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The number of allocated pages (out). */
+ uint64_t cAllocPages;
+ /** The number of free pages (out). */
+ uint64_t cFreePages;
+ /** The number of ballooned pages (out). */
+ uint64_t cBalloonedPages;
+ /** The number of shared pages (out). */
+ uint64_t cSharedPages;
+ /** Maximum nr of pages (out). */
+ uint64_t cMaxPages;
+} GMMMEMSTATSREQ;
+/** Pointer to a GMMR0QueryHypervisorMemoryStatsReq / VMMR0_DO_GMM_QUERY_HYPERVISOR_MEM_STATS request buffer. */
+typedef GMMMEMSTATSREQ *PGMMMEMSTATSREQ;
+
+GMMR0DECL(int) GMMR0QueryHypervisorMemoryStatsReq(PVM pVM, PGMMMEMSTATSREQ pReq);
+GMMR0DECL(int) GMMR0QueryMemoryStatsReq(PVM pVM, VMCPUID idCpu, PGMMMEMSTATSREQ pReq);
+
+/**
+ * Request buffer for GMMR0MapUnmapChunkReq / VMMR0_DO_GMM_MAP_UNMAP_CHUNK.
+ * @see GMMR0MapUnmapChunk
+ */
+typedef struct GMMMAPUNMAPCHUNKREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The chunk to map, NIL_GMM_CHUNKID if unmap only. (IN) */
+ uint32_t idChunkMap;
+ /** The chunk to unmap, NIL_GMM_CHUNKID if map only. (IN) */
+ uint32_t idChunkUnmap;
+ /** Where the mapping address is returned. (OUT) */
+ RTR3PTR pvR3;
+} GMMMAPUNMAPCHUNKREQ;
+/** Pointer to a GMMR0MapUnmapChunkReq / VMMR0_DO_GMM_MAP_UNMAP_CHUNK request buffer. */
+typedef GMMMAPUNMAPCHUNKREQ *PGMMMAPUNMAPCHUNKREQ;
+
+GMMR0DECL(int) GMMR0MapUnmapChunkReq(PVM pVM, PGMMMAPUNMAPCHUNKREQ pReq);
+
+
+/**
+ * Request buffer for GMMR0FreeLargePageReq / VMMR0_DO_GMM_FREE_LARGE_PAGE.
+ * @see GMMR0FreeLargePage.
+ */
+typedef struct GMMFREELARGEPAGEREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The Page ID. */
+ uint32_t idPage;
+} GMMFREELARGEPAGEREQ;
+/** Pointer to a GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES request buffer. */
+typedef GMMFREELARGEPAGEREQ *PGMMFREELARGEPAGEREQ;
+
+GMMR0DECL(int) GMMR0FreeLargePageReq(PVM pVM, VMCPUID idCpu, PGMMFREELARGEPAGEREQ pReq);
+
+/** Maximum length of the shared module name string, terminator included. */
+#define GMM_SHARED_MODULE_MAX_NAME_STRING 128
+/** Maximum length of the shared module version string, terminator included. */
+#define GMM_SHARED_MODULE_MAX_VERSION_STRING 16
+
+/**
+ * Request buffer for GMMR0RegisterSharedModuleReq / VMMR0_DO_GMM_REGISTER_SHARED_MODULE.
+ * @see GMMR0RegisterSharedModule.
+ */
+typedef struct GMMREGISTERSHAREDMODULEREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Shared module size. */
+ uint32_t cbModule;
+ /** Number of included region descriptors */
+ uint32_t cRegions;
+ /** Base address of the shared module. */
+ RTGCPTR64 GCBaseAddr;
+ /** Guest OS type. */
+ VBOXOSFAMILY enmGuestOS;
+ /** return code. */
+ uint32_t rc;
+ /** Module name */
+ char szName[GMM_SHARED_MODULE_MAX_NAME_STRING];
+ /** Module version */
+ char szVersion[GMM_SHARED_MODULE_MAX_VERSION_STRING];
+ /** Shared region descriptor(s). */
+ VMMDEVSHAREDREGIONDESC aRegions[1];
+} GMMREGISTERSHAREDMODULEREQ;
+/** Pointer to a GMMR0RegisterSharedModuleReq / VMMR0_DO_GMM_REGISTER_SHARED_MODULE request buffer. */
+typedef GMMREGISTERSHAREDMODULEREQ *PGMMREGISTERSHAREDMODULEREQ;
+
+GMMR0DECL(int) GMMR0RegisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMREGISTERSHAREDMODULEREQ pReq);
+
+/**
+ * Shared region descriptor
+ */
+typedef struct GMMSHAREDREGIONDESC
+{
+ /** The page offset where the region starts. */
+ uint32_t off;
+ /** Region size - adjusted by the region offset and rounded up to a
+ * page. */
+ uint32_t cb;
+ /** Pointer to physical GMM page ID array. */
+ uint32_t *paidPages;
+} GMMSHAREDREGIONDESC;
+/** Pointer to a GMMSHAREDREGIONDESC. */
+typedef GMMSHAREDREGIONDESC *PGMMSHAREDREGIONDESC;
+
+
+/**
+ * Shared module registration info (global)
+ */
+typedef struct GMMSHAREDMODULE
+{
+ /** Tree node (keyed by a hash of name & version). */
+ AVLLU32NODECORE Core;
+ /** Shared module size. */
+ uint32_t cbModule;
+ /** Number of included region descriptors */
+ uint32_t cRegions;
+ /** Number of users (VMs). */
+ uint32_t cUsers;
+ /** Guest OS family type. */
+ VBOXOSFAMILY enmGuestOS;
+ /** Module name */
+ char szName[GMM_SHARED_MODULE_MAX_NAME_STRING];
+ /** Module version */
+ char szVersion[GMM_SHARED_MODULE_MAX_VERSION_STRING];
+ /** Shared region descriptor(s). */
+ GMMSHAREDREGIONDESC aRegions[1];
+} GMMSHAREDMODULE;
+/** Pointer to a GMMSHAREDMODULE. */
+typedef GMMSHAREDMODULE *PGMMSHAREDMODULE;
+
+/**
+ * Page descriptor for GMMR0SharedModuleCheckRange
+ */
+typedef struct GMMSHAREDPAGEDESC
+{
+ /** HC Physical address (in/out) */
+ RTHCPHYS HCPhys;
+ /** GC Physical address (in) */
+ RTGCPHYS GCPhys;
+ /** GMM page id. (in/out) */
+ uint32_t idPage;
+ /** CRC32 of the page in strict builds (0 if page not available).
+ * In non-strict build this serves as structure alignment. */
+ uint32_t u32StrictChecksum;
+} GMMSHAREDPAGEDESC;
+/** Pointer to a GMMSHAREDPAGEDESC. */
+typedef GMMSHAREDPAGEDESC *PGMMSHAREDPAGEDESC;
+
+GMMR0DECL(int) GMMR0SharedModuleCheckPage(PGVM pGVM, PGMMSHAREDMODULE pModule, uint32_t idxRegion, uint32_t idxPage,
+ PGMMSHAREDPAGEDESC pPageDesc);
+
+/**
+ * Request buffer for GMMR0UnregisterSharedModuleReq / VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE.
+ * @see GMMR0UnregisterSharedModule.
+ */
+typedef struct GMMUNREGISTERSHAREDMODULEREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Shared module size. */
+ uint32_t cbModule;
+ /** Align at 8 byte boundary. */
+ uint32_t u32Alignment;
+ /** Base address of the shared module. */
+ RTGCPTR64 GCBaseAddr;
+ /** Module name */
+ char szName[GMM_SHARED_MODULE_MAX_NAME_STRING];
+ /** Module version */
+ char szVersion[GMM_SHARED_MODULE_MAX_VERSION_STRING];
+} GMMUNREGISTERSHAREDMODULEREQ;
+/** Pointer to a GMMR0UnregisterSharedModuleReq / VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE request buffer. */
+typedef GMMUNREGISTERSHAREDMODULEREQ *PGMMUNREGISTERSHAREDMODULEREQ;
+
+GMMR0DECL(int) GMMR0UnregisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMUNREGISTERSHAREDMODULEREQ pReq);
+
+#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
+/**
+ * Request buffer for GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE.
+ * @see GMMR0FindDuplicatePage.
+ */
+typedef struct GMMFINDDUPLICATEPAGEREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** Page id. */
+ uint32_t idPage;
+ /** Duplicate flag (out) */
+ bool fDuplicate;
+} GMMFINDDUPLICATEPAGEREQ;
+/** Pointer to a GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE request buffer. */
+typedef GMMFINDDUPLICATEPAGEREQ *PGMMFINDDUPLICATEPAGEREQ;
+
+GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq);
+#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */
+
+
+/**
+ * Request buffer for GMMR0QueryStatisticsReq / VMMR0_DO_GMM_QUERY_STATISTICS.
+ * @see GMMR0QueryStatistics.
+ */
+typedef struct GMMQUERYSTATISTICSSREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The support driver session. */
+ PSUPDRVSESSION pSession;
+ /** The statistics. */
+ GMMSTATS Stats;
+} GMMQUERYSTATISTICSSREQ;
+/** Pointer to a GMMR0QueryStatisticsReq / VMMR0_DO_GMM_QUERY_STATISTICS
+ * request buffer. */
+typedef GMMQUERYSTATISTICSSREQ *PGMMQUERYSTATISTICSSREQ;
+
+GMMR0DECL(int) GMMR0QueryStatisticsReq(PVM pVM, PGMMQUERYSTATISTICSSREQ pReq);
+
+
+/**
+ * Request buffer for GMMR0ResetStatisticsReq / VMMR0_DO_GMM_RESET_STATISTICS.
+ * @see GMMR0ResetStatistics.
+ */
+typedef struct GMMRESETSTATISTICSSREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The support driver session. */
+ PSUPDRVSESSION pSession;
+ /** The statistics to reset.
+ * Any non-zero entry will be reset (if permitted). */
+ GMMSTATS Stats;
+} GMMRESETSTATISTICSSREQ;
+/** Pointer to a GMMR0ResetStatisticsReq / VMMR0_DO_GMM_RESET_STATISTICS
+ * request buffer. */
+typedef GMMRESETSTATISTICSSREQ *PGMMRESETSTATISTICSSREQ;
+
+GMMR0DECL(int) GMMR0ResetStatisticsReq(PVM pVM, PGMMRESETSTATISTICSSREQ pReq);
+
+
+
+#ifdef IN_RING3
+/** @defgroup grp_gmm_r3 The Global Memory Manager Ring-3 API Wrappers
+ * @ingroup grp_gmm
+ * @{
+ */
+GMMR3DECL(int) GMMR3InitialReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
+ GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority);
+GMMR3DECL(int) GMMR3UpdateReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages);
+GMMR3DECL(int) GMMR3AllocatePagesPrepare(PVM pVM, PGMMALLOCATEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount);
+GMMR3DECL(int) GMMR3AllocatePagesPerform(PVM pVM, PGMMALLOCATEPAGESREQ pReq);
+GMMR3DECL(void) GMMR3AllocatePagesCleanup(PGMMALLOCATEPAGESREQ pReq);
+GMMR3DECL(int) GMMR3FreePagesPrepare(PVM pVM, PGMMFREEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount);
+GMMR3DECL(void) GMMR3FreePagesRePrep(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cPages, GMMACCOUNT enmAccount);
+GMMR3DECL(int) GMMR3FreePagesPerform(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cActualPages);
+GMMR3DECL(void) GMMR3FreePagesCleanup(PGMMFREEPAGESREQ pReq);
+GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq);
+GMMR3DECL(int) GMMR3AllocateLargePage(PVM pVM, uint32_t cbPage);
+GMMR3DECL(int) GMMR3FreeLargePage(PVM pVM, uint32_t idPage);
+GMMR3DECL(int) GMMR3MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3);
+GMMR3DECL(int) GMMR3SeedChunk(PVM pVM, RTR3PTR pvR3);
+GMMR3DECL(int) GMMR3QueryHypervisorMemoryStats(PVM pVM, uint64_t *pcTotalAllocPages, uint64_t *pcTotalFreePages, uint64_t *pcTotalBalloonPages, uint64_t *puTotalBalloonSize);
+GMMR3DECL(int) GMMR3QueryMemoryStats(PVM pVM, uint64_t *pcAllocPages, uint64_t *pcMaxPages, uint64_t *pcBalloonPages);
+GMMR3DECL(int) GMMR3BalloonedPages(PVM pVM, GMMBALLOONACTION enmAction, uint32_t cBalloonedPages);
+GMMR3DECL(int) GMMR3RegisterSharedModule(PVM pVM, PGMMREGISTERSHAREDMODULEREQ pReq);
+GMMR3DECL(int) GMMR3UnregisterSharedModule(PVM pVM, PGMMUNREGISTERSHAREDMODULEREQ pReq);
+GMMR3DECL(int) GMMR3CheckSharedModules(PVM pVM);
+GMMR3DECL(int) GMMR3ResetSharedModules(PVM pVM);
+
+# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
+GMMR3DECL(bool) GMMR3IsDuplicatePage(PVM pVM, uint32_t idPage);
+# endif
+
+/** @} */
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/gvm.h b/include/VBox/vmm/gvm.h
new file mode 100644
index 00000000..b0d607de
--- /dev/null
+++ b/include/VBox/vmm/gvm.h
@@ -0,0 +1,124 @@
+/* $Id: gvm.h $ */
+/** @file
+ * GVM - The Global VM Data.
+ */
+
+/*
+ * Copyright (C) 2007-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_gvm_h
+#define ___VBox_vmm_gvm_h
+
+#include <VBox/types.h>
+#include <iprt/thread.h>
+
+
+/** @defgroup grp_gvm GVMCPU - The Global VMCPU Data
+ * @{
+ */
+
+typedef struct GVMCPU
+{
+ /** VCPU id (0 - (pVM->cCpus - 1). */
+ VMCPUID idCpu;
+
+ /** Handle to the EMT thread. */
+ RTNATIVETHREAD hEMT;
+
+ /** The GVMM per vcpu data. */
+ union
+ {
+#ifdef ___GVMMR0Internal_h
+ struct GVMMPERVCPU s;
+#endif
+ uint8_t padding[64];
+ } gvmm;
+} GVMCPU;
+/** Pointer to the GVMCPU data. */
+typedef GVMCPU *PGVMCPU;
+
+/** @} */
+
+/** @defgroup grp_gvm GVM - The Global VM Data
+ * @{
+ */
+
+/**
+ * The Global VM Data.
+ *
+ * This is a ring-0 only structure where we put items we don't need to
+ * share with ring-3 or GC, like for instance various RTR0MEMOBJ handles.
+ *
+ * Unlike VM, there are no special alignment restrictions here. The
+ * paddings are checked by compile time assertions.
+ */
+typedef struct GVM
+{
+ /** Magic / eye-catcher (GVM_MAGIC). */
+ uint32_t u32Magic;
+ /** The global VM handle for this VM. */
+ uint32_t hSelf;
+ /** The ring-0 mapping of the VM structure. */
+ PVM pVM;
+ /** Number of Virtual CPUs, i.e. how many entries there are in aCpus.
+ * Same same as VM::cCpus. */
+ uint32_t cCpus;
+ uint32_t padding;
+
+ /** The GVMM per vm data. */
+ union
+ {
+#ifdef ___GVMMR0Internal_h
+ struct GVMMPERVM s;
+#endif
+ uint8_t padding[256];
+ } gvmm;
+
+ /** The GMM per vm data. */
+ union
+ {
+#ifdef ___GMMR0Internal_h
+ struct GMMPERVM s;
+#endif
+ uint8_t padding[512];
+ } gmm;
+
+ /** The RAWPCIVM per vm data. */
+ union
+ {
+#ifdef ___VBox_rawpci_h
+ struct RAWPCIPERVM s;
+#endif
+ uint8_t padding[64];
+ } rawpci;
+
+
+ /** GVMCPU array for the configured number of virtual CPUs. */
+ GVMCPU aCpus[1];
+} GVM;
+
+/** The GVM::u32Magic value (Wayne Shorter). */
+#define GVM_MAGIC 0x19330825
+
+/** @} */
+
+#endif
diff --git a/include/VBox/vmm/gvmm.h b/include/VBox/vmm/gvmm.h
new file mode 100644
index 00000000..e78d181b
--- /dev/null
+++ b/include/VBox/vmm/gvmm.h
@@ -0,0 +1,268 @@
+/* $Id: gvmm.h $ */
+/** @file
+ * GVMM - The Global VM Manager.
+ */
+
+/*
+ * Copyright (C) 2007-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_gvmm_h
+#define ___VBox_vmm_gvmm_h
+
+#include <VBox/types.h>
+#include <VBox/sup.h>
+#include <iprt/cpuset.h> /* RTCPUSET_MAX_CPUS */
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_GVMM GVMM - The Global VM Manager.
+ * @{
+ */
+
+/** @def IN_GVMM_R0
+ * Used to indicate whether we're inside the same link module as the ring 0
+ * part of the Global VM Manager or not.
+ */
+#ifdef DOXYGEN_RUNNING
+# define IN_GVMM_R0
+#endif
+/** @def GVMMR0DECL
+ * Ring 0 VM export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_GVMM_R0
+# define GVMMR0DECL(type) DECLEXPORT(type) VBOXCALL
+#else
+# define GVMMR0DECL(type) DECLIMPORT(type) VBOXCALL
+#endif
+
+/** @def NIL_GVM_HANDLE
+ * The nil GVM VM handle value (VM::hSelf).
+ */
+#define NIL_GVM_HANDLE 0
+
+
+/**
+ * The scheduler statistics
+ */
+typedef struct GVMMSTATSSCHED
+{
+ /** The number of calls to GVMMR0SchedHalt. */
+ uint64_t cHaltCalls;
+ /** The number of times we did go to sleep in GVMMR0SchedHalt. */
+ uint64_t cHaltBlocking;
+ /** The number of times we timed out in GVMMR0SchedHalt. */
+ uint64_t cHaltTimeouts;
+ /** The number of times we didn't go to sleep in GVMMR0SchedHalt. */
+ uint64_t cHaltNotBlocking;
+ /** The number of wake ups done during GVMMR0SchedHalt. */
+ uint64_t cHaltWakeUps;
+
+ /** The number of calls to GVMMR0WakeUp. */
+ uint64_t cWakeUpCalls;
+ /** The number of times the EMT thread wasn't actually halted when GVMMR0WakeUp
+ * was called. */
+ uint64_t cWakeUpNotHalted;
+ /** The number of wake ups done during GVMMR0WakeUp (not counting the explicit
+ * one). */
+ uint64_t cWakeUpWakeUps;
+
+ /** The number of calls to GVMMR0Poke. */
+ uint64_t cPokeCalls;
+ /** The number of times the EMT thread wasn't actually busy when
+ * GVMMR0Poke was called. */
+ uint64_t cPokeNotBusy;
+
+ /** The number of calls to GVMMR0SchedPoll. */
+ uint64_t cPollCalls;
+ /** The number of times the EMT has halted in a GVMMR0SchedPoll call. */
+ uint64_t cPollHalts;
+ /** The number of wake ups done during GVMMR0SchedPoll. */
+ uint64_t cPollWakeUps;
+
+ uint64_t u64Alignment; /**< padding */
+} GVMMSTATSSCHED;
+/** Pointer to the GVMM scheduler statistics. */
+typedef GVMMSTATSSCHED *PGVMMSTATSSCHED;
+
+/**
+ * Per host cpu statistics.
+ */
+typedef struct GVMMSTATSHOSTCPU
+{
+ /** The CPU ID. */
+ RTCPUID idCpu;
+ /** The CPU's set index. */
+ uint32_t idxCpuSet;
+ /** The desired PPT frequency. */
+ uint32_t uDesiredHz;
+ /** The current PPT timer frequency. */
+ uint32_t uTimerHz;
+ /** The number of times the PPT was changed. */
+ uint32_t cChanges;
+ /** The number of times the PPT was started. */
+ uint32_t cStarts;
+} GVMMSTATSHOSTCPU;
+/** Pointer to the GVMM per host CPU statistics. */
+typedef GVMMSTATSHOSTCPU *PGVMMSTATSHOSTCPU;
+
+/**
+ * The GVMM statistics.
+ */
+typedef struct GVMMSTATS
+{
+ /** The VM statistics if a VM was specified. */
+ GVMMSTATSSCHED SchedVM;
+ /** The sum statistics of all VMs accessible to the caller. */
+ GVMMSTATSSCHED SchedSum;
+ /** The number of VMs accessible to the caller. */
+ uint32_t cVMs;
+ /** The number of emulation threads in those VMs. */
+ uint32_t cEMTs;
+ /** Padding. */
+ uint32_t u32Padding;
+ /** The number of valid entries in aHostCpus. */
+ uint32_t cHostCpus;
+ /** Per host CPU statistics. */
+ GVMMSTATSHOSTCPU aHostCpus[RTCPUSET_MAX_CPUS];
+} GVMMSTATS;
+/** Pointer to the GVMM statistics. */
+typedef GVMMSTATS *PGVMMSTATS;
+/** Const pointer to the GVMM statistics. */
+typedef const GVMMSTATS *PCGVMMSTATS;
+
+
+
+GVMMR0DECL(int) GVMMR0Init(void);
+GVMMR0DECL(void) GVMMR0Term(void);
+GVMMR0DECL(int) GVMMR0SetConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t u64Value);
+GVMMR0DECL(int) GVMMR0QueryConfig(PSUPDRVSESSION pSession, const char *pszName, uint64_t *pu64Value);
+
+GVMMR0DECL(int) GVMMR0CreateVM(PSUPDRVSESSION pSession, uint32_t cCpus, PVM *ppVM);
+GVMMR0DECL(int) GVMMR0InitVM(PVM pVM);
+GVMMR0DECL(void) GVMMR0DoneInitVM(PVM pVM);
+GVMMR0DECL(bool) GVMMR0DoingTermVM(PVM pVM, PGVM pGVM);
+GVMMR0DECL(int) GVMMR0DestroyVM(PVM pVM);
+GVMMR0DECL(int) GVMMR0RegisterVCpu(PVM pVM, VMCPUID idCpu);
+GVMMR0DECL(PGVM) GVMMR0ByHandle(uint32_t hGVM);
+GVMMR0DECL(int) GVMMR0ByVM(PVM pVM, PGVM *ppGVM);
+GVMMR0DECL(int) GVMMR0ByVMAndEMT(PVM pVM, VMCPUID idCpu, PGVM *ppGVM);
+GVMMR0DECL(PVM) GVMMR0GetVMByHandle(uint32_t hGVM);
+GVMMR0DECL(PVM) GVMMR0GetVMByEMT(RTNATIVETHREAD hEMT);
+GVMMR0DECL(int) GVMMR0SchedHalt(PVM pVM, VMCPUID idCpu, uint64_t u64ExpireGipTime);
+GVMMR0DECL(int) GVMMR0SchedWakeUp(PVM pVM, VMCPUID idCpu);
+GVMMR0DECL(int) GVMMR0SchedWakeUpEx(PVM pVM, VMCPUID idCpu, bool fTakeUsedLock);
+GVMMR0DECL(int) GVMMR0SchedPoke(PVM pVM, VMCPUID idCpu);
+GVMMR0DECL(int) GVMMR0SchedPokeEx(PVM pVM, VMCPUID idCpu, bool fTakeUsedLock);
+GVMMR0DECL(int) GVMMR0SchedWakeUpAndPokeCpus(PVM pVM, PCVMCPUSET pSleepSet, PCVMCPUSET pPokeSet);
+GVMMR0DECL(int) GVMMR0SchedPoll(PVM pVM, VMCPUID idCpu, bool fYield);
+GVMMR0DECL(void) GVMMR0SchedUpdatePeriodicPreemptionTimer(PVM pVM, RTCPUID idHostCpu, uint32_t uHz);
+GVMMR0DECL(int) GVMMR0QueryStatistics(PGVMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM);
+GVMMR0DECL(int) GVMMR0ResetStatistics(PCGVMMSTATS pStats, PSUPDRVSESSION pSession, PVM pVM);
+
+
+/**
+ * Request packet for calling GVMMR0CreateVM.
+ */
+typedef struct GVMMCREATEVMREQ
+{
+ /** The request header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The support driver session. (IN) */
+ PSUPDRVSESSION pSession;
+ /** Number of virtual CPUs for the new VM. (IN) */
+ uint32_t cCpus;
+ /** Pointer to the ring-3 mapping of the shared VM structure on return. (OUT) */
+ PVMR3 pVMR3;
+ /** Pointer to the ring-0 mapping of the shared VM structure on return. (OUT) */
+ PVMR0 pVMR0;
+} GVMMCREATEVMREQ;
+/** Pointer to a GVMMR0CreateVM request packet. */
+typedef GVMMCREATEVMREQ *PGVMMCREATEVMREQ;
+
+GVMMR0DECL(int) GVMMR0CreateVMReq(PGVMMCREATEVMREQ pReq);
+
+
+/**
+ * Request buffer for GVMMR0SchedWakeUpAndPokeCpusReq / VMMR0_DO_GVMM_SCHED_WAKE_UP_AND_POKE_CPUS.
+ * @see GVMMR0SchedWakeUpAndPokeCpus.
+ */
+typedef struct GVMMSCHEDWAKEUPANDPOKECPUSREQ /* nice and unreadable... */
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The sleeper set. */
+ VMCPUSET SleepSet;
+ /** The set of virtual CPUs to poke. */
+ VMCPUSET PokeSet;
+} GVMMSCHEDWAKEUPANDPOKECPUSREQ;
+/** Pointer to a GVMMR0QueryStatisticsReq / VMMR0_DO_GVMM_QUERY_STATISTICS request buffer. */
+typedef GVMMSCHEDWAKEUPANDPOKECPUSREQ *PGVMMSCHEDWAKEUPANDPOKECPUSREQ;
+
+GVMMR0DECL(int) GVMMR0SchedWakeUpAndPokeCpusReq(PVM pVM, PGVMMSCHEDWAKEUPANDPOKECPUSREQ pReq);
+
+
+/**
+ * Request buffer for GVMMR0QueryStatisticsReq / VMMR0_DO_GVMM_QUERY_STATISTICS.
+ * @see GVMMR0QueryStatistics.
+ */
+typedef struct GVMMQUERYSTATISTICSSREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The support driver session. */
+ PSUPDRVSESSION pSession;
+ /** The statistics. */
+ GVMMSTATS Stats;
+} GVMMQUERYSTATISTICSSREQ;
+/** Pointer to a GVMMR0QueryStatisticsReq / VMMR0_DO_GVMM_QUERY_STATISTICS request buffer. */
+typedef GVMMQUERYSTATISTICSSREQ *PGVMMQUERYSTATISTICSSREQ;
+
+GVMMR0DECL(int) GVMMR0QueryStatisticsReq(PVM pVM, PGVMMQUERYSTATISTICSSREQ pReq);
+
+
+/**
+ * Request buffer for GVMMR0ResetStatisticsReq / VMMR0_DO_GVMM_RESET_STATISTICS.
+ * @see GVMMR0ResetStatistics.
+ */
+typedef struct GVMMRESETSTATISTICSSREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The support driver session. */
+ PSUPDRVSESSION pSession;
+ /** The statistics to reset.
+ * Any non-zero entry will be reset (if permitted). */
+ GVMMSTATS Stats;
+} GVMMRESETSTATISTICSSREQ;
+/** Pointer to a GVMMR0ResetStatisticsReq / VMMR0_DO_GVMM_RESET_STATISTICS request buffer. */
+typedef GVMMRESETSTATISTICSSREQ *PGVMMRESETSTATISTICSSREQ;
+
+GVMMR0DECL(int) GVMMR0ResetStatisticsReq(PVM pVM, PGVMMRESETSTATISTICSSREQ pReq);
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/hwacc_svm.h b/include/VBox/vmm/hwacc_svm.h
new file mode 100644
index 00000000..8912e378
--- /dev/null
+++ b/include/VBox/vmm/hwacc_svm.h
@@ -0,0 +1,744 @@
+/** @file
+ * HWACCM - SVM Structures and Definitions. (VMM)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_vmm_svm_h
+#define ___VBox_vmm_svm_h
+
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <iprt/assert.h>
+#include <iprt/asm.h>
+
+/** @defgroup grp_svm svm Types and Definitions
+ * @ingroup grp_hwaccm
+ * @{
+ */
+
+/** @name SVM features for cpuid 0x8000000a
+ * @{
+ */
+/** Bit 0 - NP - Nested Paging supported. */
+#define AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING RT_BIT(0)
+/** Bit 1 - LbrVirt - Support for saving five debug MSRs. */
+#define AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT RT_BIT(1)
+/** Bit 2 - SVML - SVM locking bit supported. */
+#define AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK RT_BIT(2)
+/** Bit 3 - NRIPS - Saving the next instruction pointer is supported. */
+#define AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE RT_BIT(3)
+/** Bit 4 - TscRateMsr - Support for MSR TSC ratio. */
+#define AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR RT_BIT(4)
+/** Bit 5 - VmcbClean - Support VMCB clean bits. */
+#define AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN RT_BIT(5)
+/** Bit 6 - FlushByAsid - Indicate TLB flushing for current ASID only, and that
+ * VMCB.TLB_Control is supported. */
+#define AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID RT_BIT(6)
+/** Bit 7 - DecodeAssist - Indicate decode assist is supported. */
+#define AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST RT_BIT(7)
+/** Where did we get this from? */
+#define AMD_CPUID_SVM_FEATURE_EDX_SSE_3_5_DISABLE RT_BIT(9)
+/** Bit 10 - PauseFilter - Indicates support for the PAUSE intercept filter. */
+#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER RT_BIT(10)
+/** Bit 12 - PauseFilterThreshold - Indicates support for the PAUSE
+ * intercept filter cycle count threshold. */
+#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER_THRESHOLD RT_BIT(12)
+/** @} */
+
+
+/** @name SVM Basic Exit Reasons.
+ * @{
+ */
+/** Invalid guest state in VMCB. */
+#define SVM_EXIT_INVALID -1
+/** Read from CR0-CR15. */
+#define SVM_EXIT_READ_CR0 0x0
+#define SVM_EXIT_READ_CR1 0x1
+#define SVM_EXIT_READ_CR2 0x2
+#define SVM_EXIT_READ_CR3 0x3
+#define SVM_EXIT_READ_CR4 0x4
+#define SVM_EXIT_READ_CR5 0x5
+#define SVM_EXIT_READ_CR6 0x6
+#define SVM_EXIT_READ_CR7 0x7
+#define SVM_EXIT_READ_CR8 0x8
+#define SVM_EXIT_READ_CR9 0x9
+#define SVM_EXIT_READ_CR10 0xA
+#define SVM_EXIT_READ_CR11 0xB
+#define SVM_EXIT_READ_CR12 0xC
+#define SVM_EXIT_READ_CR13 0xD
+#define SVM_EXIT_READ_CR14 0xE
+#define SVM_EXIT_READ_CR15 0xF
+/** Writes to CR0-CR15. */
+#define SVM_EXIT_WRITE_CR0 0x10
+#define SVM_EXIT_WRITE_CR1 0x11
+#define SVM_EXIT_WRITE_CR2 0x12
+#define SVM_EXIT_WRITE_CR3 0x13
+#define SVM_EXIT_WRITE_CR4 0x14
+#define SVM_EXIT_WRITE_CR5 0x15
+#define SVM_EXIT_WRITE_CR6 0x16
+#define SVM_EXIT_WRITE_CR7 0x17
+#define SVM_EXIT_WRITE_CR8 0x18
+#define SVM_EXIT_WRITE_CR9 0x19
+#define SVM_EXIT_WRITE_CR10 0x1A
+#define SVM_EXIT_WRITE_CR11 0x1B
+#define SVM_EXIT_WRITE_CR12 0x1C
+#define SVM_EXIT_WRITE_CR13 0x1D
+#define SVM_EXIT_WRITE_CR14 0x1E
+#define SVM_EXIT_WRITE_CR15 0x1F
+/** Read from DR0-DR15. */
+#define SVM_EXIT_READ_DR0 0x20
+#define SVM_EXIT_READ_DR1 0x21
+#define SVM_EXIT_READ_DR2 0x22
+#define SVM_EXIT_READ_DR3 0x23
+#define SVM_EXIT_READ_DR4 0x24
+#define SVM_EXIT_READ_DR5 0x25
+#define SVM_EXIT_READ_DR6 0x26
+#define SVM_EXIT_READ_DR7 0x27
+#define SVM_EXIT_READ_DR8 0x28
+#define SVM_EXIT_READ_DR9 0x29
+#define SVM_EXIT_READ_DR10 0x2A
+#define SVM_EXIT_READ_DR11 0x2B
+#define SVM_EXIT_READ_DR12 0x2C
+#define SVM_EXIT_READ_DR13 0x2D
+#define SVM_EXIT_READ_DR14 0x2E
+#define SVM_EXIT_READ_DR15 0x2F
+/** Writes to DR0-DR15. */
+#define SVM_EXIT_WRITE_DR0 0x30
+#define SVM_EXIT_WRITE_DR1 0x31
+#define SVM_EXIT_WRITE_DR2 0x32
+#define SVM_EXIT_WRITE_DR3 0x33
+#define SVM_EXIT_WRITE_DR4 0x34
+#define SVM_EXIT_WRITE_DR5 0x35
+#define SVM_EXIT_WRITE_DR6 0x36
+#define SVM_EXIT_WRITE_DR7 0x37
+#define SVM_EXIT_WRITE_DR8 0x38
+#define SVM_EXIT_WRITE_DR9 0x39
+#define SVM_EXIT_WRITE_DR10 0x3A
+#define SVM_EXIT_WRITE_DR11 0x3B
+#define SVM_EXIT_WRITE_DR12 0x3C
+#define SVM_EXIT_WRITE_DR13 0x3D
+#define SVM_EXIT_WRITE_DR14 0x3E
+#define SVM_EXIT_WRITE_DR15 0x3F
+/* Exception 0-31. */
+#define SVM_EXIT_EXCEPTION_0 0x40
+#define SVM_EXIT_EXCEPTION_1 0x41
+#define SVM_EXIT_EXCEPTION_2 0x42
+#define SVM_EXIT_EXCEPTION_3 0x43
+#define SVM_EXIT_EXCEPTION_4 0x44
+#define SVM_EXIT_EXCEPTION_5 0x45
+#define SVM_EXIT_EXCEPTION_6 0x46
+#define SVM_EXIT_EXCEPTION_7 0x47
+#define SVM_EXIT_EXCEPTION_8 0x48
+#define SVM_EXIT_EXCEPTION_9 0x49
+#define SVM_EXIT_EXCEPTION_A 0x4A
+#define SVM_EXIT_EXCEPTION_B 0x4B
+#define SVM_EXIT_EXCEPTION_C 0x4C
+#define SVM_EXIT_EXCEPTION_D 0x4D
+#define SVM_EXIT_EXCEPTION_E 0x4E
+#define SVM_EXIT_EXCEPTION_F 0x4F
+#define SVM_EXIT_EXCEPTION_10 0x50
+#define SVM_EXIT_EXCEPTION_11 0x51
+#define SVM_EXIT_EXCEPTION_12 0x52
+#define SVM_EXIT_EXCEPTION_13 0x53
+#define SVM_EXIT_EXCEPTION_14 0x54
+#define SVM_EXIT_EXCEPTION_15 0x55
+#define SVM_EXIT_EXCEPTION_16 0x56
+#define SVM_EXIT_EXCEPTION_17 0x57
+#define SVM_EXIT_EXCEPTION_18 0x58
+#define SVM_EXIT_EXCEPTION_19 0x59
+#define SVM_EXIT_EXCEPTION_1A 0x5A
+#define SVM_EXIT_EXCEPTION_1B 0x5B
+#define SVM_EXIT_EXCEPTION_1C 0x5C
+#define SVM_EXIT_EXCEPTION_1D 0x5D
+#define SVM_EXIT_EXCEPTION_1E 0x5E
+#define SVM_EXIT_EXCEPTION_1F 0x5F
+/** Physical maskable interrupt. */
+#define SVM_EXIT_INTR 0x60
+/** Non-maskable interrupt. */
+#define SVM_EXIT_NMI 0x61
+/** System Management interrupt. */
+#define SVM_EXIT_SMI 0x62
+/** Physical INIT signal. */
+#define SVM_EXIT_INIT 0x63
+/** Virtual interrupt. */
+#define SVM_EXIT_VINTR 0x64
+/** Write to CR0 that changed any bits other than CR0.TS or CR0.MP. */
+#define SVM_EXIT_CR0_SEL_WRITE 0x65
+/** IDTR read. */
+#define SVM_EXIT_IDTR_READ 0x66
+/** GDTR read. */
+#define SVM_EXIT_GDTR_READ 0x67
+/** LDTR read. */
+#define SVM_EXIT_LDTR_READ 0x68
+/** TR read. */
+#define SVM_EXIT_TR_READ 0x69
+/** IDTR write. */
+#define SVM_EXIT_IDTR_WRITE 0x6A
+/** GDTR write. */
+#define SVM_EXIT_GDTR_WRITE 0x6B
+/** LDTR write. */
+#define SVM_EXIT_LDTR_WRITE 0x6C
+/** TR write. */
+#define SVM_EXIT_TR_WRITE 0x6D
+/** RDTSC instruction. */
+#define SVM_EXIT_RDTSC 0x6E
+/** RDPMC instruction. */
+#define SVM_EXIT_RDPMC 0x6F
+/** PUSHF instruction. */
+#define SVM_EXIT_PUSHF 0x70
+/** POPF instruction. */
+#define SVM_EXIT_POPF 0x71
+/** CPUID instruction. */
+#define SVM_EXIT_CPUID 0x72
+/** RSM instruction. */
+#define SVM_EXIT_RSM 0x73
+/** IRET instruction. */
+#define SVM_EXIT_IRET 0x74
+/** software interrupt (INTn instructions). */
+#define SVM_EXIT_SWINT 0x75
+/** INVD instruction. */
+#define SVM_EXIT_INVD 0x76
+/** PAUSE instruction. */
+#define SVM_EXIT_PAUSE 0x77
+/** HLT instruction. */
+#define SVM_EXIT_HLT 0x78
+/** INVLPG instructions. */
+#define SVM_EXIT_INVLPG 0x79
+/** INVLPGA instruction. */
+#define SVM_EXIT_INVLPGA 0x7A
+/** IN or OUT accessing protected port (the EXITINFO1 field provides more information). */
+#define SVM_EXIT_IOIO 0x7B
+/** RDMSR or WRMSR access to protected MSR. */
+#define SVM_EXIT_MSR 0x7C
+/** task switch. */
+#define SVM_EXIT_TASK_SWITCH 0x7D
+/** FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt. */
+#define SVM_EXIT_FERR_FREEZE 0x7E
+/** Shutdown. */
+#define SVM_EXIT_SHUTDOWN 0x7F
+/** VMRUN instruction. */
+#define SVM_EXIT_VMRUN 0x80
+/** VMMCALL instruction. */
+#define SVM_EXIT_VMMCALL 0x81
+/** VMLOAD instruction. */
+#define SVM_EXIT_VMLOAD 0x82
+/** VMSAVE instruction. */
+#define SVM_EXIT_VMSAVE 0x83
+/** STGI instruction. */
+#define SVM_EXIT_STGI 0x84
+/** CLGI instruction. */
+#define SVM_EXIT_CLGI 0x85
+/** SKINIT instruction. */
+#define SVM_EXIT_SKINIT 0x86
+/** RDTSCP instruction. */
+#define SVM_EXIT_RDTSCP 0x87
+/** ICEBP instruction. */
+#define SVM_EXIT_ICEBP 0x88
+/** WBINVD instruction. */
+#define SVM_EXIT_WBINVD 0x89
+/** MONITOR instruction. */
+#define SVM_EXIT_MONITOR 0x8A
+/** MWAIT instruction uncond. */
+#define SVM_EXIT_MWAIT_UNCOND 0x8B
+/** MWAIT instruction when armed. */
+#define SVM_EXIT_MWAIT_ARMED 0x8C
+/** Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault). */
+#define SVM_EXIT_NPF 0x400
+
+/** @} */
+
+
+/** @name SVM_VMCB.u64ExitInfo2
+ * @{
+ */
+/** Set to 1 if the task switch was caused by an IRET; else cleared to 0. */
+#define SVM_EXIT2_TASK_SWITCH_IRET RT_BIT_64(36)
+/** Set to 1 if the task switch was caused by a far jump; else cleared to 0. */
+#define SVM_EXIT2_TASK_SWITCH_JMP RT_BIT_64(38)
+/** Set to 1 if the task switch has an error code; else cleared to 0. */
+#define SVM_EXIT2_TASK_SWITCH_HAS_ERROR_CODE RT_BIT_64(44)
+/** The value of EFLAGS.RF that would be saved in the outgoing TSS if the task switch were not intercepted. */
+#define SVM_EXIT2_TASK_SWITCH_EFLAGS_RF RT_BIT_64(48)
+/** @} */
+
+/** @name SVM_VMCB.ctrl.u32InterceptCtrl1
+ * @{
+ */
+/** 0 Intercept INTR (physical maskable interrupt). */
+#define SVM_CTRL1_INTERCEPT_INTR RT_BIT(0)
+/** 1 Intercept NMI. */
+#define SVM_CTRL1_INTERCEPT_NMI RT_BIT(1)
+/** 2 Intercept SMI. */
+#define SVM_CTRL1_INTERCEPT_SMI RT_BIT(2)
+/** 3 Intercept INIT. */
+#define SVM_CTRL1_INTERCEPT_INIT RT_BIT(3)
+/** 4 Intercept VINTR (virtual maskable interrupt). */
+#define SVM_CTRL1_INTERCEPT_VINTR RT_BIT(4)
+/** 5 Intercept CR0 writes that change bits other than CR0.TS or CR0.MP */
+#define SVM_CTRL1_INTERCEPT_CR0 RT_BIT(5)
+/** 6 Intercept reads of IDTR. */
+#define SVM_CTRL1_INTERCEPT_IDTR_READS RT_BIT(6)
+/** 7 Intercept reads of GDTR. */
+#define SVM_CTRL1_INTERCEPT_GDTR_READS RT_BIT(7)
+/** 8 Intercept reads of LDTR. */
+#define SVM_CTRL1_INTERCEPT_LDTR_READS RT_BIT(8)
+/** 9 Intercept reads of TR. */
+#define SVM_CTRL1_INTERCEPT_TR_READS RT_BIT(9)
+/** 10 Intercept writes of IDTR. */
+#define SVM_CTRL1_INTERCEPT_IDTR_WRITES RT_BIT(10)
+/** 11 Intercept writes of GDTR. */
+#define SVM_CTRL1_INTERCEPT_GDTR_WRITES RT_BIT(11)
+/** 12 Intercept writes of LDTR. */
+#define SVM_CTRL1_INTERCEPT_LDTR_WRITES RT_BIT(12)
+/** 13 Intercept writes of TR. */
+#define SVM_CTRL1_INTERCEPT_TR_WRITES RT_BIT(13)
+/** 14 Intercept RDTSC instruction. */
+#define SVM_CTRL1_INTERCEPT_RDTSC RT_BIT(14)
+/** 15 Intercept RDPMC instruction. */
+#define SVM_CTRL1_INTERCEPT_RDPMC RT_BIT(15)
+/** 16 Intercept PUSHF instruction. */
+#define SVM_CTRL1_INTERCEPT_PUSHF RT_BIT(16)
+/** 17 Intercept POPF instruction. */
+#define SVM_CTRL1_INTERCEPT_POPF RT_BIT(17)
+/** 18 Intercept CPUID instruction. */
+#define SVM_CTRL1_INTERCEPT_CPUID RT_BIT(18)
+/** 19 Intercept RSM instruction. */
+#define SVM_CTRL1_INTERCEPT_RSM RT_BIT(19)
+/** 20 Intercept IRET instruction. */
+#define SVM_CTRL1_INTERCEPT_IRET RT_BIT(20)
+/** 21 Intercept INTn instruction. */
+#define SVM_CTRL1_INTERCEPT_INTN RT_BIT(21)
+/** 22 Intercept INVD instruction. */
+#define SVM_CTRL1_INTERCEPT_INVD RT_BIT(22)
+/** 23 Intercept PAUSE instruction. */
+#define SVM_CTRL1_INTERCEPT_PAUSE RT_BIT(23)
+/** 24 Intercept HLT instruction. */
+#define SVM_CTRL1_INTERCEPT_HLT RT_BIT(24)
+/** 25 Intercept INVLPG instruction. */
+#define SVM_CTRL1_INTERCEPT_INVLPG RT_BIT(25)
+/** 26 Intercept INVLPGA instruction. */
+#define SVM_CTRL1_INTERCEPT_INVLPGA RT_BIT(26)
+/** 27 IOIO_PROT Intercept IN/OUT accesses to selected ports. */
+#define SVM_CTRL1_INTERCEPT_INOUT_BITMAP RT_BIT(27)
+/** 28 MSR_PROT Intercept RDMSR or WRMSR accesses to selected MSRs. */
+#define SVM_CTRL1_INTERCEPT_MSR_SHADOW RT_BIT(28)
+/** 29 Intercept task switches. */
+#define SVM_CTRL1_INTERCEPT_TASK_SWITCH RT_BIT(29)
+/** 30 FERR_FREEZE: intercept processor "freezing" during legacy FERR handling. */
+#define SVM_CTRL1_INTERCEPT_FERR_FREEZE RT_BIT(30)
+/** 31 Intercept shutdown events. */
+#define SVM_CTRL1_INTERCEPT_SHUTDOWN RT_BIT(31)
+/** @} */
+
+
+/** @name SVM_VMCB.ctrl.u32InterceptCtrl2
+ * @{
+ */
+/** 0 Intercept VMRUN instruction. */
+#define SVM_CTRL2_INTERCEPT_VMRUN RT_BIT(0)
+/** 1 Intercept VMMCALL instruction. */
+#define SVM_CTRL2_INTERCEPT_VMMCALL RT_BIT(1)
+/** 2 Intercept VMLOAD instruction. */
+#define SVM_CTRL2_INTERCEPT_VMLOAD RT_BIT(2)
+/** 3 Intercept VMSAVE instruction. */
+#define SVM_CTRL2_INTERCEPT_VMSAVE RT_BIT(3)
+/** 4 Intercept STGI instruction. */
+#define SVM_CTRL2_INTERCEPT_STGI RT_BIT(4)
+/** 5 Intercept CLGI instruction. */
+#define SVM_CTRL2_INTERCEPT_CLGI RT_BIT(5)
+/** 6 Intercept SKINIT instruction. */
+#define SVM_CTRL2_INTERCEPT_SKINIT RT_BIT(6)
+/** 7 Intercept RDTSCP instruction. */
+#define SVM_CTRL2_INTERCEPT_RDTSCP RT_BIT(7)
+/** 8 Intercept ICEBP instruction. */
+#define SVM_CTRL2_INTERCEPT_ICEBP RT_BIT(8)
+/** 9 Intercept WBINVD instruction. */
+#define SVM_CTRL2_INTERCEPT_WBINVD RT_BIT(9)
+/** 10 Intercept MONITOR instruction. */
+#define SVM_CTRL2_INTERCEPT_MONITOR RT_BIT(10)
+/** 11 Intercept MWAIT instruction unconditionally. */
+#define SVM_CTRL2_INTERCEPT_MWAIT_UNCOND RT_BIT(11)
+/** 12 Intercept MWAIT instruction when armed. */
+#define SVM_CTRL2_INTERCEPT_MWAIT_ARMED RT_BIT(12)
+/** 13 Intercept XSETBV instruction. */
+#define SVM_CTRL2_INTERCEPT_XSETBV RT_BIT(13)
+/** @} */
+
+/** @name SVM_VMCB.ctrl.u64NestedPaging
+ * @{
+ */
+#define SVM_NESTED_PAGING_ENABLE RT_BIT(0)
+/** @} */
+
+/** @name SVM_VMCB.ctrl.u64IntShadow
+ * @{
+ */
+#define SVM_INTERRUPT_SHADOW_ACTIVE RT_BIT(0)
+/** @} */
+
+
+/** @name SVM_INTCTRL.u3Type
+ * @{
+ */
+/** External or virtual interrupt. */
+#define SVM_EVENT_EXTERNAL_IRQ 0
+/** Non-maskable interrupt. */
+#define SVM_EVENT_NMI 2
+/** Exception; fault or trap. */
+#define SVM_EVENT_EXCEPTION 3
+/** Software interrupt. */
+#define SVM_EVENT_SOFTWARE_INT 4
+/** @} */
+
+
+/** @name SVM_VMCB.ctrl.TLBCtrl.n.u8TLBFlush
+ * @{
+ */
+/** Flush nothing. */
+#define SVM_TLB_FLUSH_NOTHING 0
+/** Flush entire TLB (host+guest entries) */
+#define SVM_TLB_FLUSH_ENTIRE 1
+/** Flush this guest's TLB entries (by ASID) */
+#define SVM_TLB_FLUSH_SINGLE_CONTEXT 3
+/** Flush this guest's non-global TLB entries (by ASID) */
+#define SVM_TLB_FLUSH_SINGLE_CONTEXT_RETAIN_GLOBALS 7
+/** @} */
+
+
+/**
+ * SVM Selector type; includes hidden parts.
+ */
+#pragma pack(1)
+typedef struct
+{
+ uint16_t u16Sel;
+ uint16_t u16Attr;
+ uint32_t u32Limit;
+ uint64_t u64Base; /**< Only lower 32 bits are implemented for CS, DS, ES & SS. */
+} SVMSEL;
+#pragma pack()
+
+/**
+ * SVM GDTR/IDTR type.
+ */
+#pragma pack(1)
+typedef struct
+{
+ uint16_t u16Reserved1;
+ uint16_t u16Reserved2;
+ uint32_t u32Limit; /**< Only lower 16 bits are implemented. */
+ uint64_t u64Base;
+} SVMGDTR;
+#pragma pack()
+
+typedef SVMGDTR SVMIDTR;
+
+/**
+ * SVM Event injection structure.
+ */
+#pragma pack(1)
+typedef union
+{
+ struct
+ {
+ uint32_t u8Vector : 8;
+ uint32_t u3Type : 3;
+ uint32_t u1ErrorCodeValid : 1;
+ uint32_t u19Reserved : 19;
+ uint32_t u1Valid : 1;
+ uint32_t u32ErrorCode : 32;
+ } n;
+ uint64_t au64[1];
+} SVM_EVENT;
+#pragma pack()
+
+
+/**
+ * SVM Interrupt control structure.
+ */
+#pragma pack(1)
+typedef union
+{
+ struct
+ {
+ uint32_t u8VTPR : 8;
+ uint32_t u1VIrqValid : 1;
+ uint32_t u7Reserved : 7;
+ uint32_t u4VIrqPriority : 4;
+ uint32_t u1IgnoreTPR : 1;
+ uint32_t u3Reserved : 3;
+ uint32_t u1VIrqMasking : 1;
+ uint32_t u7Reserved2 : 7;
+ uint32_t u8VIrqVector : 8;
+ uint32_t u24Reserved : 24;
+ } n;
+ uint64_t au64[1];
+} SVM_INTCTRL;
+#pragma pack()
+
+
+/**
+ * SVM TLB control structure.
+ */
+#pragma pack(1)
+typedef union
+{
+ struct
+ {
+ uint32_t u32ASID : 32;
+ uint32_t u8TLBFlush : 8;
+ uint32_t u24Reserved : 24;
+ } n;
+ uint64_t au64[1];
+} SVM_TLBCTRL;
+#pragma pack()
+
+
+/**
+ * SVM IOIO exit structure.
+ */
+#pragma pack(1)
+typedef union
+{
+ struct
+ {
+ uint32_t u1Type : 1; /**< 0 = out, 1 = in */
+ uint32_t u1Reserved : 1;
+ uint32_t u1STR : 1;
+ uint32_t u1REP : 1;
+ uint32_t u1OP8 : 1;
+ uint32_t u1OP16 : 1;
+ uint32_t u1OP32 : 1;
+ uint32_t u1ADDR16 : 1;
+ uint32_t u1ADDR32 : 1;
+ uint32_t u1ADDR64 : 1;
+ uint32_t u6Reserved : 6;
+ uint32_t u16Port : 16;
+ } n;
+ uint32_t au32[1];
+} SVM_IOIO_EXIT;
+#pragma pack()
+
+/**
+ * SVM nested paging structure.
+ */
+#pragma pack(1)
+typedef union
+{
+ struct
+ {
+ uint32_t u1NestedPaging : 1; /**< enabled/disabled */
+ } n;
+ uint64_t au64[1];
+} SVM_NPCTRL;
+#pragma pack()
+
+/**
+ * SVM VM Control Block. (VMCB)
+ */
+#pragma pack(1)
+typedef struct _SVM_VMCB
+{
+ /** Control Area. */
+ struct
+ {
+ /** Offset 0x00 - Intercept reads of CR0-15. */
+ uint16_t u16InterceptRdCRx;
+ /** Offset 0x02 - Intercept writes to CR0-15. */
+ uint16_t u16InterceptWrCRx;
+ /** Offset 0x04 - Intercept reads of DR0-15. */
+ uint16_t u16InterceptRdDRx;
+ /** Offset 0x06 - Intercept writes to DR0-15. */
+ uint16_t u16InterceptWrDRx;
+ /** Offset 0x08 - Intercept exception vectors 0-31. */
+ uint32_t u32InterceptException;
+ /** Offset 0x0C - Intercept control field 1. */
+ uint32_t u32InterceptCtrl1;
+ /** Offset 0x0C - Intercept control field 2. */
+ uint32_t u32InterceptCtrl2;
+ /** Offset 0x14-0x3F - Reserved. */
+ uint8_t u8Reserved[0x3e - 0x14];
+ /** Offset 0x3e - PAUSE intercept filter count. */
+ uint16_t u16PauseFilterCount;
+ /** Offset 0x40 - Physical address of IOPM. */
+ uint64_t u64IOPMPhysAddr;
+ /** Offset 0x48 - Physical address of MSRPM. */
+ uint64_t u64MSRPMPhysAddr;
+ /** Offset 0x50 - TSC Offset. */
+ uint64_t u64TSCOffset;
+ /** Offset 0x58 - TLB control field. */
+ SVM_TLBCTRL TLBCtrl;
+ /** Offset 0x60 - Interrupt control field. */
+ SVM_INTCTRL IntCtrl;
+ /** Offset 0x68 - Interrupt shadow. */
+ uint64_t u64IntShadow;
+ /** Offset 0x70 - Exit code. */
+ uint64_t u64ExitCode;
+ /** Offset 0x78 - Exit info 1. */
+ uint64_t u64ExitInfo1;
+ /** Offset 0x80 - Exit info 2. */
+ uint64_t u64ExitInfo2;
+ /** Offset 0x88 - Exit Interrupt info. */
+ SVM_EVENT ExitIntInfo;
+ /** Offset 0x90 - Nested Paging. */
+ SVM_NPCTRL NestedPaging;
+ /** Offset 0x98-0xA7 - Reserved. */
+ uint8_t u8Reserved2[0xA8-0x98];
+ /** Offset 0xA8 - Event injection. */
+ SVM_EVENT EventInject;
+ /** Offset 0xB0 - Host CR3 for nested paging. */
+ uint64_t u64NestedPagingCR3;
+ /** Offset 0xB8 - LBR Virtualization. */
+ uint64_t u64LBRVirt;
+ /** Offset 0xC0 - VMCB Clean Bits. */
+ uint64_t u64VMCBCleanBits;
+ /** Offset 0xC8 - Next sequential instruction pointer. */
+ uint64_t u64NextRIP;
+ /** Offset 0xD0 - Number of bytes fetched. */
+ uint8_t cbInstrFetched;
+ /** Offset 0xD1 - Number of bytes fetched. */
+ uint8_t abInstr[15];
+ } ctrl;
+
+ /** Offset 0xC0-0x3FF - Reserved. */
+ uint8_t u8Reserved3[0x400-0xE0];
+
+ /** State Save Area. Starts at offset 0x400. */
+ struct
+ {
+ /** Offset 0x400 - Guest ES register + hidden parts. */
+ SVMSEL ES;
+ /** Offset 0x410 - Guest CS register + hidden parts. */
+ SVMSEL CS;
+ /** Offset 0x420 - Guest SS register + hidden parts. */
+ SVMSEL SS;
+ /** Offset 0x430 - Guest DS register + hidden parts. */
+ SVMSEL DS;
+ /** Offset 0x440 - Guest FS register + hidden parts. */
+ SVMSEL FS;
+ /** Offset 0x450 - Guest GS register + hidden parts. */
+ SVMSEL GS;
+ /** Offset 0x460 - Guest GDTR register. */
+ SVMGDTR GDTR;
+ /** Offset 0x470 - Guest LDTR register + hidden parts. */
+ SVMSEL LDTR;
+ /** Offset 0x480 - Guest IDTR register. */
+ SVMIDTR IDTR;
+ /** Offset 0x490 - Guest TR register + hidden parts. */
+ SVMSEL TR;
+ /** Offset 0x4A0-0x4CA - Reserved. */
+ uint8_t u8Reserved4[0x4CB-0x4A0];
+ /** Offset 0x4CB - CPL. */
+ uint8_t u8CPL;
+ /** Offset 0x4CC-0x4CF - Reserved. */
+ uint8_t u8Reserved5[0x4D0-0x4CC];
+ /** Offset 0x4D0 - EFER. */
+ uint64_t u64EFER;
+ /** Offset 0x4D8-0x547 - Reserved. */
+ uint8_t u8Reserved6[0x548-0x4D8];
+ /** Offset 0x548 - CR4. */
+ uint64_t u64CR4;
+ /** Offset 0x550 - CR3. */
+ uint64_t u64CR3;
+ /** Offset 0x558 - CR0. */
+ uint64_t u64CR0;
+ /** Offset 0x560 - DR7. */
+ uint64_t u64DR7;
+ /** Offset 0x568 - DR6. */
+ uint64_t u64DR6;
+ /** Offset 0x570 - RFLAGS. */
+ uint64_t u64RFlags;
+ /** Offset 0x578 - RIP. */
+ uint64_t u64RIP;
+ /** Offset 0x580-0x5D7 - Reserved. */
+ uint8_t u8Reserved7[0x5D8-0x580];
+ /** Offset 0x5D8 - RSP. */
+ uint64_t u64RSP;
+ /** Offset 0x5E0-0x5F7 - Reserved. */
+ uint8_t u8Reserved8[0x5F8-0x5E0];
+ /** Offset 0x5F8 - RAX. */
+ uint64_t u64RAX;
+ /** Offset 0x600 - STAR. */
+ uint64_t u64STAR;
+ /** Offset 0x608 - LSTAR. */
+ uint64_t u64LSTAR;
+ /** Offset 0x610 - CSTAR. */
+ uint64_t u64CSTAR;
+ /** Offset 0x618 - SFMASK. */
+ uint64_t u64SFMASK;
+ /** Offset 0x620 - KernelGSBase. */
+ uint64_t u64KernelGSBase;
+ /** Offset 0x628 - SYSENTER_CS. */
+ uint64_t u64SysEnterCS;
+ /** Offset 0x630 - SYSENTER_ESP. */
+ uint64_t u64SysEnterESP;
+ /** Offset 0x638 - SYSENTER_EIP. */
+ uint64_t u64SysEnterEIP;
+ /** Offset 0x640 - CR2. */
+ uint64_t u64CR2;
+ /** Offset 0x648-0x667 - Reserved. */
+ uint8_t u8Reserved9[0x668-0x648];
+ /** Offset 0x668 - G_PAT. */
+ uint64_t u64GPAT;
+ /** Offset 0x670 - DBGCTL. */
+ uint64_t u64DBGCTL;
+ /** Offset 0x678 - BR_FROM. */
+ uint64_t u64BR_FROM;
+ /** Offset 0x680 - BR_TO. */
+ uint64_t u64BR_TO;
+ /** Offset 0x688 - LASTEXCPFROM. */
+ uint64_t u64LASTEXCPFROM;
+ /** Offset 0x690 - LASTEXCPTO. */
+ uint64_t u64LASTEXCPTO;
+ } guest;
+
+ /** Offset 0x698-0xFFF- Reserved. */
+ uint8_t u8Reserved10[0x1000-0x698];
+} SVM_VMCB;
+#pragma pack()
+AssertCompileSize(SVM_VMCB, 0x1000);
+AssertCompileMemberOffset(SVM_VMCB, ctrl.u16InterceptRdCRx, 0x000);
+AssertCompileMemberOffset(SVM_VMCB, ctrl.u16PauseFilterCount,0x03e);
+AssertCompileMemberOffset(SVM_VMCB, ctrl.TLBCtrl, 0x058);
+AssertCompileMemberOffset(SVM_VMCB, ctrl.ExitIntInfo, 0x088);
+AssertCompileMemberOffset(SVM_VMCB, ctrl.EventInject, 0x0A8);
+AssertCompileMemberOffset(SVM_VMCB, ctrl.abInstr, 0x0D1);
+AssertCompileMemberOffset(SVM_VMCB, guest, 0x400);
+AssertCompileMemberOffset(SVM_VMCB, guest.ES, 0x400);
+AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved4, 0x4A0);
+AssertCompileMemberOffset(SVM_VMCB, guest.u8CPL, 0x4CB);
+AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved6, 0x4D8);
+AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved7, 0x580);
+AssertCompileMemberOffset(SVM_VMCB, guest.u8Reserved9, 0x648);
+AssertCompileMemberOffset(SVM_VMCB, guest.u64GPAT, 0x668);
+AssertCompileMemberOffset(SVM_VMCB, guest.u64LASTEXCPTO, 0x690);
+AssertCompileMemberOffset(SVM_VMCB, u8Reserved10, 0x698);
+
+#ifdef IN_RING0
+VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
+#endif /* IN_RING0 */
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/hwacc_vmx.h b/include/VBox/vmm/hwacc_vmx.h
new file mode 100644
index 00000000..a96f587e
--- /dev/null
+++ b/include/VBox/vmm/hwacc_vmx.h
@@ -0,0 +1,1708 @@
+/** @file
+ * HWACCM - VMX Structures and Definitions. (VMM)
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_vmx_h
+#define ___VBox_vmm_vmx_h
+
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <iprt/x86.h>
+#include <iprt/assert.h>
+
+/** @defgroup grp_vmx vmx Types and Definitions
+ * @ingroup grp_hwaccm
+ * @{
+ */
+
+/** @name VMX EPT paging structures
+ * @{
+ */
+
+/**
+ * Number of page table entries in the EPT. (PDPTE/PDE/PTE)
+ */
+#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES
+
+/**
+ * EPT Page Directory Pointer Entry. Bit view.
+ * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC,
+ * this did cause trouble with one compiler/version).
+ */
+#pragma pack(1)
+typedef struct EPTPML4EBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** Reserved (must be 0). */
+ uint64_t u5Reserved : 5;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPML4EBITS;
+#pragma pack()
+AssertCompileSize(EPTPML4EBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK
+/** The page shift to get the PML4 index. */
+#define EPT_PML4_SHIFT X86_PML4_SHIFT
+/** The PML4 index mask (apply to a shifted page address). */
+#define EPT_PML4_MASK X86_PML4_MASK
+
+/**
+ * EPT PML4E.
+ */
+#pragma pack(1)
+typedef union EPTPML4E
+{
+ /** Normal view. */
+ EPTPML4EBITS n;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPML4E;
+#pragma pack()
+/** Pointer to a PML4 table entry. */
+typedef EPTPML4E *PEPTPML4E;
+/** Pointer to a const PML4 table entry. */
+typedef const EPTPML4E *PCEPTPML4E;
+AssertCompileSize(EPTPML4E, 8);
+
+/**
+ * EPT PML4 Table.
+ */
+#pragma pack(1)
+typedef struct EPTPML4
+{
+ EPTPML4E a[EPT_PG_ENTRIES];
+} EPTPML4;
+#pragma pack()
+/** Pointer to an EPT PML4 Table. */
+typedef EPTPML4 *PEPTPML4;
+/** Pointer to a const EPT PML4 Table. */
+typedef const EPTPML4 *PCEPTPML4;
+
+/**
+ * EPT Page Directory Pointer Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPDPTEBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** Reserved (must be 0). */
+ uint64_t u5Reserved : 5;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPDPTEBITS;
+#pragma pack()
+AssertCompileSize(EPTPDPTEBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK
+/** The page shift to get the PDPT index. */
+#define EPT_PDPT_SHIFT X86_PDPT_SHIFT
+/** The PDPT index mask (apply to a shifted page address). */
+#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64
+
+/**
+ * EPT Page Directory Pointer.
+ */
+#pragma pack(1)
+typedef union EPTPDPTE
+{
+ /** Normal view. */
+ EPTPDPTEBITS n;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPDPTE;
+#pragma pack()
+/** Pointer to an EPT Page Directory Pointer Entry. */
+typedef EPTPDPTE *PEPTPDPTE;
+/** Pointer to a const EPT Page Directory Pointer Entry. */
+typedef const EPTPDPTE *PCEPTPDPTE;
+AssertCompileSize(EPTPDPTE, 8);
+
+/**
+ * EPT Page Directory Pointer Table.
+ */
+#pragma pack(1)
+typedef struct EPTPDPT
+{
+ EPTPDPTE a[EPT_PG_ENTRIES];
+} EPTPDPT;
+#pragma pack()
+/** Pointer to an EPT Page Directory Pointer Table. */
+typedef EPTPDPT *PEPTPDPT;
+/** Pointer to a const EPT Page Directory Pointer Table. */
+typedef const EPTPDPT *PCEPTPDPT;
+
+
+/**
+ * EPT Page Directory Table Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPDEBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** Reserved (must be 0). */
+ uint64_t u4Reserved : 4;
+ /** Big page (must be 0 here). */
+ uint64_t u1Size : 1;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Physical address of page table. Restricted by maximum physical address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPDEBITS;
+#pragma pack()
+AssertCompileSize(EPTPDEBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK
+/** The page shift to get the PD index. */
+#define EPT_PD_SHIFT X86_PD_PAE_SHIFT
+/** The PD index mask (apply to a shifted page address). */
+#define EPT_PD_MASK X86_PD_PAE_MASK
+
+/**
+ * EPT 2MB Page Directory Table Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPDE2MBITS
+{
+ /** Present bit. */
+ uint64_t u1Present : 1;
+ /** Writable bit. */
+ uint64_t u1Write : 1;
+ /** Executable bit. */
+ uint64_t u1Execute : 1;
+ /** EPT Table Memory Type. MBZ for non-leaf nodes. */
+ uint64_t u3EMT : 3;
+ /** Ignore PAT memory type */
+ uint64_t u1IgnorePAT : 1;
+ /** Big page (must be 1 here). */
+ uint64_t u1Size : 1;
+ /** Available for software. */
+ uint64_t u4Available : 4;
+ /** Reserved (must be 0). */
+ uint64_t u9Reserved : 9;
+ /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */
+ uint64_t u31PhysAddr : 31;
+ /** Availabe for software. */
+ uint64_t u12Available : 12;
+} EPTPDE2MBITS;
+#pragma pack()
+AssertCompileSize(EPTPDE2MBITS, 8);
+
+/** Bits 21-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK
+
+/**
+ * EPT Page Directory Table Entry.
+ */
+#pragma pack(1)
+typedef union EPTPDE
+{
+ /** Normal view. */
+ EPTPDEBITS n;
+ /** 2MB view (big). */
+ EPTPDE2MBITS b;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPDE;
+#pragma pack()
+/** Pointer to an EPT Page Directory Table Entry. */
+typedef EPTPDE *PEPTPDE;
+/** Pointer to a const EPT Page Directory Table Entry. */
+typedef const EPTPDE *PCEPTPDE;
+AssertCompileSize(EPTPDE, 8);
+
+/**
+ * EPT Page Directory Table.
+ */
+#pragma pack(1)
+typedef struct EPTPD
+{
+ EPTPDE a[EPT_PG_ENTRIES];
+} EPTPD;
+#pragma pack()
+/** Pointer to an EPT Page Directory Table. */
+typedef EPTPD *PEPTPD;
+/** Pointer to a const EPT Page Directory Table. */
+typedef const EPTPD *PCEPTPD;
+
+
+/**
+ * EPT Page Table Entry. Bit view.
+ */
+#pragma pack(1)
+typedef struct EPTPTEBITS
+{
+ /** 0 - Present bit.
+ * @remark This is a convenience "misnomer". The bit actually indicates
+ * read access and the CPU will consider an entry with any of the
+ * first three bits set as present. Since all our valid entries
+ * will have this bit set, it can be used as a present indicator
+ * and allow some code sharing. */
+ uint64_t u1Present : 1;
+ /** 1 - Writable bit. */
+ uint64_t u1Write : 1;
+ /** 2 - Executable bit. */
+ uint64_t u1Execute : 1;
+ /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */
+ uint64_t u3EMT : 3;
+ /** 6 - Ignore PAT memory type */
+ uint64_t u1IgnorePAT : 1;
+ /** 11:7 - Available for software. */
+ uint64_t u5Available : 5;
+ /** 51:12 - Physical address of page. Restricted by maximum physical
+ * address width of the cpu. */
+ uint64_t u40PhysAddr : 40;
+ /** 63:52 - Available for software. */
+ uint64_t u12Available : 12;
+} EPTPTEBITS;
+#pragma pack()
+AssertCompileSize(EPTPTEBITS, 8);
+
+/** Bits 12-51 - - EPT - Physical Page number of the next level. */
+#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK
+/** The page shift to get the EPT PTE index. */
+#define EPT_PT_SHIFT X86_PT_PAE_SHIFT
+/** The EPT PT index mask (apply to a shifted page address). */
+#define EPT_PT_MASK X86_PT_PAE_MASK
+
+/**
+ * EPT Page Table Entry.
+ */
+#pragma pack(1)
+typedef union EPTPTE
+{
+ /** Normal view. */
+ EPTPTEBITS n;
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** 64 bit unsigned integer view. */
+ uint64_t au64[1];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[2];
+} EPTPTE;
+#pragma pack()
+/** Pointer to an EPT Page Directory Table Entry. */
+typedef EPTPTE *PEPTPTE;
+/** Pointer to a const EPT Page Directory Table Entry. */
+typedef const EPTPTE *PCEPTPTE;
+AssertCompileSize(EPTPTE, 8);
+
+/**
+ * EPT Page Table.
+ */
+#pragma pack(1)
+typedef struct EPTPT
+{
+ EPTPTE a[EPT_PG_ENTRIES];
+} EPTPT;
+#pragma pack()
+/** Pointer to an extended page table. */
+typedef EPTPT *PEPTPT;
+/** Pointer to a const extended table. */
+typedef const EPTPT *PCEPTPT;
+
+/**
+ * VPID flush types.
+ */
+typedef enum
+{
+ /** Invalidate a specific page. */
+ VMX_FLUSH_VPID_INDIV_ADDR = 0,
+ /** Invalidate one context (specific VPID). */
+ VMX_FLUSH_VPID_SINGLE_CONTEXT = 1,
+ /** Invalidate all contexts (all VPIDs). */
+ VMX_FLUSH_VPID_ALL_CONTEXTS = 2,
+ /** Invalidate a single VPID context retaining global mappings. */
+ VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3,
+ /** Unsupported by VirtualBox. */
+ VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad,
+ /** Unsupported by CPU. */
+ VMX_FLUSH_VPID_NONE = 0xb00,
+ /** 32bit hackishness. */
+ VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff
+} VMX_FLUSH_VPID;
+
+/**
+ * EPT flush types.
+ */
+typedef enum
+{
+ /** Invalidate one context (specific EPT). */
+ VMX_FLUSH_EPT_SINGLE_CONTEXT = 1,
+ /* Invalidate all contexts (all EPTs) */
+ VMX_FLUSH_EPT_ALL_CONTEXTS = 2,
+ /** Unsupported by VirtualBox. */
+ VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad,
+ /** Unsupported by CPU. */
+ VMX_FLUSH_EPT_NONE = 0xb00,
+ /** 32bit hackishness. */
+ VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff
+} VMX_FLUSH_EPT;
+/** @} */
+
+/** @name MSR load/store elements
+ * @{
+ */
+#pragma pack(1)
+typedef struct
+{
+ uint32_t u32IndexMSR;
+ uint32_t u32Reserved;
+ uint64_t u64Value;
+} VMXMSR;
+#pragma pack()
+/** Pointer to an MSR load/store element. */
+typedef VMXMSR *PVMXMSR;
+/** Pointer to a const MSR load/store element. */
+typedef const VMXMSR *PCVMXMSR;
+
+/** @} */
+
+
+/** @name VT-x capability qword
+ * @{
+ */
+#pragma pack(1)
+typedef union
+{
+ struct
+ {
+ uint32_t disallowed0;
+ uint32_t allowed1;
+ } n;
+ uint64_t u;
+} VMX_CAPABILITY;
+#pragma pack()
+/** @} */
+
+/** @name VMX Basic Exit Reasons.
+ * @{
+ */
+/** And-mask for setting reserved bits to zero */
+#define VMX_EFLAGS_RESERVED_0 (~0xffc08028)
+/** Or-mask for setting reserved bits to 1 */
+#define VMX_EFLAGS_RESERVED_1 0x00000002
+/** @} */
+
+/** @name VMX Basic Exit Reasons.
+ * @{
+ */
+/** -1 Invalid exit code */
+#define VMX_EXIT_INVALID -1
+/** 0 Exception or non-maskable interrupt (NMI). */
+#define VMX_EXIT_EXCEPTION 0
+/** 1 External interrupt. */
+#define VMX_EXIT_EXTERNAL_IRQ 1
+/** 2 Triple fault. */
+#define VMX_EXIT_TRIPLE_FAULT 2
+/** 3 INIT signal. */
+#define VMX_EXIT_INIT_SIGNAL 3
+/** 4 Start-up IPI (SIPI). */
+#define VMX_EXIT_SIPI 4
+/** 5 I/O system-management interrupt (SMI). */
+#define VMX_EXIT_IO_SMI_IRQ 5
+/** 6 Other SMI. */
+#define VMX_EXIT_SMI_IRQ 6
+/** 7 Interrupt window. */
+#define VMX_EXIT_IRQ_WINDOW 7
+/** 9 Task switch. */
+#define VMX_EXIT_TASK_SWITCH 9
+/** 10 Guest software attempted to execute CPUID. */
+#define VMX_EXIT_CPUID 10
+/** 12 Guest software attempted to execute HLT. */
+#define VMX_EXIT_HLT 12
+/** 13 Guest software attempted to execute INVD. */
+#define VMX_EXIT_INVD 13
+/** 14 Guest software attempted to execute INVLPG. */
+#define VMX_EXIT_INVLPG 14
+/** 15 Guest software attempted to execute RDPMC. */
+#define VMX_EXIT_RDPMC 15
+/** 16 Guest software attempted to execute RDTSC. */
+#define VMX_EXIT_RDTSC 16
+/** 17 Guest software attempted to execute RSM in SMM. */
+#define VMX_EXIT_RSM 17
+/** 18 Guest software executed VMCALL. */
+#define VMX_EXIT_VMCALL 18
+/** 19 Guest software executed VMCLEAR. */
+#define VMX_EXIT_VMCLEAR 19
+/** 20 Guest software executed VMLAUNCH. */
+#define VMX_EXIT_VMLAUNCH 20
+/** 21 Guest software executed VMPTRLD. */
+#define VMX_EXIT_VMPTRLD 21
+/** 22 Guest software executed VMPTRST. */
+#define VMX_EXIT_VMPTRST 22
+/** 23 Guest software executed VMREAD. */
+#define VMX_EXIT_VMREAD 23
+/** 24 Guest software executed VMRESUME. */
+#define VMX_EXIT_VMRESUME 24
+/** 25 Guest software executed VMWRITE. */
+#define VMX_EXIT_VMWRITE 25
+/** 26 Guest software executed VMXOFF. */
+#define VMX_EXIT_VMXOFF 26
+/** 27 Guest software executed VMXON. */
+#define VMX_EXIT_VMXON 27
+/** 28 Control-register accesses. */
+#define VMX_EXIT_CRX_MOVE 28
+/** 29 Debug-register accesses. */
+#define VMX_EXIT_DRX_MOVE 29
+/** 30 I/O instruction. */
+#define VMX_EXIT_PORT_IO 30
+/** 31 RDMSR. Guest software attempted to execute RDMSR. */
+#define VMX_EXIT_RDMSR 31
+/** 32 WRMSR. Guest software attempted to execute WRMSR. */
+#define VMX_EXIT_WRMSR 32
+/** 33 VM-entry failure due to invalid guest state. */
+#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33
+/** 34 VM-entry failure due to MSR loading. */
+#define VMX_EXIT_ERR_MSR_LOAD 34
+/** 36 Guest software executed MWAIT. */
+#define VMX_EXIT_MWAIT 36
+/** 37 VM exit due to monitor trap flag. */
+#define VMX_EXIT_MTF 37
+/** 39 Guest software attempted to execute MONITOR. */
+#define VMX_EXIT_MONITOR 39
+/** 40 Guest software attempted to execute PAUSE. */
+#define VMX_EXIT_PAUSE 40
+/** 41 VM-entry failure due to machine-check. */
+#define VMX_EXIT_ERR_MACHINE_CHECK 41
+/** 43 TPR below threshold. Guest software executed MOV to CR8. */
+#define VMX_EXIT_TPR 43
+/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
+#define VMX_EXIT_APIC_ACCESS 44
+/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */
+#define VMX_EXIT_XDTR_ACCESS 46
+/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */
+#define VMX_EXIT_TR_ACCESS 47
+/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */
+#define VMX_EXIT_EPT_VIOLATION 48
+/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */
+#define VMX_EXIT_EPT_MISCONFIG 49
+/** 50 INVEPT. Guest software attempted to execute INVEPT. */
+#define VMX_EXIT_INVEPT 50
+/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */
+#define VMX_EXIT_RDTSCP 51
+/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */
+#define VMX_EXIT_PREEMPTION_TIMER 52
+/** 53 INVVPID. Guest software attempted to execute INVVPID. */
+#define VMX_EXIT_INVVPID 53
+/** 54 WBINVD. Guest software attempted to execute WBINVD. */
+#define VMX_EXIT_WBINVD 54
+/** 55 XSETBV. Guest software attempted to execute XSETBV. */
+#define VMX_EXIT_XSETBV 55
+/** @} */
+
+
+/** @name VM Instruction Errors
+ * @{
+ */
+/** 1 VMCALL executed in VMX root operation. */
+#define VMX_ERROR_VMCALL 1
+/** 2 VMCLEAR with invalid physical address. */
+#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2
+/** 3 VMCLEAR with VMXON pointer. */
+#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3
+/** 4 VMLAUNCH with non-clear VMCS. */
+#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4
+/** 5 VMRESUME with non-launched VMCS. */
+#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5
+/** 6 VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */
+#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6
+/** 7 VM entry with invalid control field(s). */
+#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7
+/** 8 VM entry with invalid host-state field(s). */
+#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8
+/** 9 VMPTRLD with invalid physical address. */
+#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9
+/** 10 VMPTRLD with VMXON pointer. */
+#define VMX_ERROR_VMPTRLD_VMXON_PTR 10
+/** 11 VMPTRLD with incorrect VMCS revision identifier. */
+#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11
+/** 12 VMREAD/VMWRITE from/to unsupported VMCS component. */
+#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12
+#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT
+/** 13 VMWRITE to read-only VMCS component. */
+#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13
+/** 15 VMXON executed in VMX root operation. */
+#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15
+/** 16 VM entry with invalid executive-VMCS pointer. */
+#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16
+/** 17 VM entry with non-launched executive VMCS. */
+#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17
+/** 18 VM entry with executive-VMCS pointer not VMXON pointer. */
+#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18
+/** 19 VMCALL with non-clear VMCS. */
+#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19
+/** 20 VMCALL with invalid VM-exit control fields. */
+#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20
+/** 22 VMCALL with incorrect MSEG revision identifier. */
+#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22
+/** 23 VMXOFF under dual-monitor treatment of SMIs and SMM. */
+#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23
+/** 24 VMCALL with invalid SMM-monitor features. */
+#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24
+/** 25 VM entry with invalid VM-execution control fields in executive VMCS. */
+#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25
+/** 26 VM entry with events blocked by MOV SS. */
+#define VMX_ERROR_VMENTRY_MOV_SS 26
+/** 26 Invalid operand to INVEPT/INVVPID. */
+#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28
+
+/** @} */
+
+
+/** @name VMX MSRs - Basic VMX information.
+ * @{
+ */
+/** VMCS revision identifier used by the processor. */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) (a & 0x7FFFFFFF)
+/** Size of the VMCS. */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0xFFF)
+/** Width of physical address used for the VMCS.
+ * 0 -> limited to the available amount of physical ram
+ * 1 -> within the first 4 GB
+ */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1)
+/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1)
+/** Memory type that must be used for the VMCS. */
+#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF)
+/** @} */
+
+
+/** @name VMX MSRs - Misc VMX info.
+ * @{
+ */
+/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */
+#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f)
+/** Activity states supported by the implementation. */
+#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7)
+/** Number of CR3 target values supported by the processor. (0-256) */
+#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF)
+/** Maximum nr of MSRs in the VMCS. (N+1)*512. */
+#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512)
+/** MSEG revision identifier used by the processor. */
+#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32)
+/** @} */
+
+
+/** @name VMX MSRs - VMCS enumeration field info
+ * @{
+ */
+/** Highest field index. */
+#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF)
+
+/** @} */
+
+
+/** @name MSR_IA32_VMX_EPT_CAPS; EPT capabilities MSR
+ * @{
+ */
+#define MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY RT_BIT_64(0)
+#define MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY RT_BIT_64(1)
+#define MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY RT_BIT_64(2)
+#define MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS RT_BIT_64(3)
+#define MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS RT_BIT_64(4)
+#define MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS RT_BIT_64(5)
+#define MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS RT_BIT_64(6)
+#define MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS RT_BIT_64(7)
+#define MSR_IA32_VMX_EPT_CAPS_EMT_UC RT_BIT_64(8)
+#define MSR_IA32_VMX_EPT_CAPS_EMT_WC RT_BIT_64(9)
+#define MSR_IA32_VMX_EPT_CAPS_EMT_WT RT_BIT_64(12)
+#define MSR_IA32_VMX_EPT_CAPS_EMT_WP RT_BIT_64(13)
+#define MSR_IA32_VMX_EPT_CAPS_EMT_WB RT_BIT_64(14)
+#define MSR_IA32_VMX_EPT_CAPS_SP_21_BITS RT_BIT_64(16)
+#define MSR_IA32_VMX_EPT_CAPS_SP_30_BITS RT_BIT_64(17)
+#define MSR_IA32_VMX_EPT_CAPS_SP_39_BITS RT_BIT_64(18)
+#define MSR_IA32_VMX_EPT_CAPS_SP_48_BITS RT_BIT_64(19)
+#define MSR_IA32_VMX_EPT_CAPS_INVEPT RT_BIT_64(20)
+#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT RT_BIT_64(25)
+#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS RT_BIT_64(26)
+#define MSR_IA32_VMX_EPT_CAPS_INVVPID RT_BIT_64(32)
+#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR RT_BIT_64(40)
+#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT RT_BIT_64(41)
+#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS RT_BIT_64(42)
+#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43)
+
+/** @} */
+
+/** @name Extended Page Table Pointer (EPTP)
+ * @{
+ */
+/** Uncachable EPT paging structure memory type. */
+#define VMX_EPT_MEMTYPE_UC 0
+/** Write-back EPT paging structure memory type. */
+#define VMX_EPT_MEMTYPE_WB 6
+/** Shift value to get the EPT page walk length (bits 5-3) */
+#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3
+/** Mask value to get the EPT page walk length (bits 5-3) */
+#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7
+/** Default EPT page walk length */
+#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3
+/** @} */
+
+
+/** @name VMCS field encoding - 16 bits guest fields
+ * @{
+ */
+#define VMX_VMCS16_GUEST_FIELD_VPID 0x0
+#define VMX_VMCS16_GUEST_FIELD_ES 0x800
+#define VMX_VMCS16_GUEST_FIELD_CS 0x802
+#define VMX_VMCS16_GUEST_FIELD_SS 0x804
+#define VMX_VMCS16_GUEST_FIELD_DS 0x806
+#define VMX_VMCS16_GUEST_FIELD_FS 0x808
+#define VMX_VMCS16_GUEST_FIELD_GS 0x80A
+#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C
+#define VMX_VMCS16_GUEST_FIELD_TR 0x80E
+/** @} */
+
+/** @name VMCS field encoding - 16 bits host fields
+ * @{
+ */
+#define VMX_VMCS16_HOST_FIELD_ES 0xC00
+#define VMX_VMCS16_HOST_FIELD_CS 0xC02
+#define VMX_VMCS16_HOST_FIELD_SS 0xC04
+#define VMX_VMCS16_HOST_FIELD_DS 0xC06
+#define VMX_VMCS16_HOST_FIELD_FS 0xC08
+#define VMX_VMCS16_HOST_FIELD_GS 0xC0A
+#define VMX_VMCS16_HOST_FIELD_TR 0xC0C
+/** @} */
+
+/** @name VMCS field encoding - 64 bits host fields
+ * @{
+ */
+#define VMX_VMCS_HOST_FIELD_PAT_FULL 0x2C00
+#define VMX_VMCS_HOST_FIELD_PAT_HIGH 0x2C01
+#define VMX_VMCS_HOST_FIELD_EFER_FULL 0x2C02
+#define VMX_VMCS_HOST_FIELD_EFER_HIGH 0x2C03
+#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */
+#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */
+/** @} */
+
+
+/** @name VMCS field encoding - 64 Bits control fields
+ * @{
+ */
+#define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 0x2000
+#define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 0x2001
+#define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 0x2002
+#define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 0x2003
+
+/* Optional */
+#define VMX_VMCS_CTRL_MSR_BITMAP_FULL 0x2004
+#define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 0x2005
+
+#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 0x2006
+#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 0x2007
+#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 0x2008
+#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 0x2009
+
+#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0x200A
+#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0x200B
+
+#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0x200C
+#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0x200D
+
+#define VMX_VMCS_CTRL_TSC_OFFSET_FULL 0x2010
+#define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 0x2011
+
+/** Optional (VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW) */
+#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 0x2012
+#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 0x2013
+
+/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */
+#define VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL 0x2014
+#define VMX_VMCS_CTRL_APIC_ACCESSADDR_HIGH 0x2015
+
+/** Extended page table pointer. */
+#define VMX_VMCS_CTRL_EPTP_FULL 0x201a
+#define VMX_VMCS_CTRL_EPTP_HIGH 0x201b
+
+/** VM-exit phyiscal address. */
+#define VMX_VMCS_EXIT_PHYS_ADDR_FULL 0x2400
+#define VMX_VMCS_EXIT_PHYS_ADDR_HIGH 0x2401
+/** @} */
+
+
+/** @name VMCS field encoding - 64 Bits guest fields
+ * @{
+ */
+#define VMX_VMCS_GUEST_LINK_PTR_FULL 0x2800
+#define VMX_VMCS_GUEST_LINK_PTR_HIGH 0x2801
+#define VMX_VMCS_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */
+#define VMX_VMCS_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */
+#define VMX_VMCS_GUEST_PAT_FULL 0x2804
+#define VMX_VMCS_GUEST_PAT_HIGH 0x2805
+#define VMX_VMCS_GUEST_EFER_FULL 0x2806
+#define VMX_VMCS_GUEST_EFER_HIGH 0x2807
+#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */
+#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */
+#define VMX_VMCS_GUEST_PDPTR0_FULL 0x280A
+#define VMX_VMCS_GUEST_PDPTR0_HIGH 0x280B
+#define VMX_VMCS_GUEST_PDPTR1_FULL 0x280C
+#define VMX_VMCS_GUEST_PDPTR1_HIGH 0x280D
+#define VMX_VMCS_GUEST_PDPTR2_FULL 0x280E
+#define VMX_VMCS_GUEST_PDPTR2_HIGH 0x280F
+#define VMX_VMCS_GUEST_PDPTR3_FULL 0x2810
+#define VMX_VMCS_GUEST_PDPTR3_HIGH 0x2811
+/** @} */
+
+
+/** @name VMCS field encoding - 32 Bits control fields
+ * @{
+ */
+#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 0x4000
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 0x4002
+#define VMX_VMCS_CTRL_EXCEPTION_BITMAP 0x4004
+#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 0x4006
+#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 0x4008
+#define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0x400A
+#define VMX_VMCS_CTRL_EXIT_CONTROLS 0x400C
+#define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0x400E
+#define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 0x4010
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS 0x4012
+#define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014
+#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 0x4016
+#define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018
+#define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0x401A
+/** This field exists only on processors that support the 1-setting of the “use TPR shadow” VM-execution control. */
+#define VMX_VMCS_CTRL_TPR_THRESHOLD 0x401C
+/** This field exists only on processors that support the 1-setting of the “activate secondary controls” VM-execution control. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2 0x401E
+/** @} */
+
+
+/** @name VMX_VMCS_CTRL_PIN_EXEC_CONTROLS
+ * @{
+ */
+/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
+#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT RT_BIT(0)
+/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
+#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT RT_BIT(3)
+/** Virtual NMIs. */
+#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI RT_BIT(5)
+/** Activate VMX preemption timer. */
+#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER RT_BIT(6)
+/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */
+/** @} */
+
+/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS
+ * @{
+ */
+/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT RT_BIT(2)
+/** Use timestamp counter offset. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET RT_BIT(3)
+/** VM Exit when executing the HLT instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT RT_BIT(7)
+/** VM Exit when executing the INVLPG instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT RT_BIT(9)
+/** VM Exit when executing the MWAIT instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT RT_BIT(10)
+/** VM Exit when executing the RDPMC instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT RT_BIT(11)
+/** VM Exit when executing the RDTSC/RDTSCP instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT RT_BIT(12)
+/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT RT_BIT(15)
+/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT RT_BIT(16)
+/** VM Exit on CR8 loads. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT RT_BIT(19)
+/** VM Exit on CR8 stores. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT RT_BIT(20)
+/** Use TPR shadow. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW RT_BIT(21)
+/** VM Exit when virtual nmi blocking is disabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT RT_BIT(22)
+/** VM Exit when executing a MOV DRx instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT RT_BIT(23)
+/** VM Exit when executing IO instructions. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT RT_BIT(24)
+/** Use IO bitmaps. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS RT_BIT(25)
+/** Monitor trap flag. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG RT_BIT(27)
+/** Use MSR bitmaps. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS RT_BIT(28)
+/** VM Exit when executing the MONITOR instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT RT_BIT(29)
+/** VM Exit when executing the PAUSE instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT RT_BIT(30)
+/** Determines whether the secondary processor based VM-execution controls are used. */
+#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31)
+/** @} */
+
+/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2
+ * @{
+ */
+/** Virtualize APIC access. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0)
+/** EPT supported/enabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1)
+/** Descriptor table instructions cause VM-exits. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT RT_BIT(2)
+/** RDTSCP supported/enabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3)
+/** Virtualize x2APIC mode. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_X2APIC RT_BIT(4)
+/** VPID supported/enabled. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5)
+/** VM Exit when executing the WBINVD instruction. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6)
+/** Unrestricted guest execution. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE RT_BIT(7)
+/** A specified nr of pause loops cause a VM-exit. */
+#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10)
+/** @} */
+
+
+/** @name VMX_VMCS_CTRL_ENTRY_CONTROLS
+ * @{
+ */
+/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG RT_BIT(2)
+/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE RT_BIT(9)
+/** In SMM mode after VM-entry. */
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM RT_BIT(10)
+/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON RT_BIT(11)
+/** This control determines whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR RT_BIT(13)
+/** This control determines whether the guest IA32_PAT MSR is loaded on VM entry. */
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR RT_BIT(14)
+/** This control determines whether the guest IA32_EFER MSR is loaded on VM entry. */
+#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR RT_BIT(15)
+/** @} */
+
+
+/** @name VMX_VMCS_CTRL_EXIT_CONTROLS
+ * @{
+ */
+/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG RT_BIT(2)
+/** Return to long mode after a VM-exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9)
+/** This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_PERF_MSR RT_BIT(12)
+/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ RT_BIT(15)
+/** This control determines whether the guest IA32_PAT MSR is saved on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR RT_BIT(18)
+/** This control determines whether the host IA32_PAT MSR is loaded on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR RT_BIT(19)
+/** This control determines whether the guest IA32_EFER MSR is saved on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR RT_BIT(20)
+/** This control determines whether the host IA32_EFER MSR is loaded on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR RT_BIT(21)
+/** This control determines whether the value of the VMX preemption timer is saved on VM exit. */
+#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER RT_BIT(22)
+/** @} */
+
+/** @name VMCS field encoding - 32 Bits read-only fields
+ * @{
+ */
+#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400
+#define VMX_VMCS32_RO_EXIT_REASON 0x4402
+#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404
+#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE 0x4406
+#define VMX_VMCS32_RO_IDT_INFO 0x4408
+#define VMX_VMCS32_RO_IDT_ERRCODE 0x440A
+#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C
+#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E
+/** @} */
+
+/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO
+ * @{
+ */
+#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) (a & 0xff)
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7)
+#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11)
+#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) (a & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID)
+#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) (a & RT_BIT(12))
+#define VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT 31
+#define VMX_EXIT_INTERRUPTION_INFO_VALID(a) (a & RT_BIT(31))
+/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */
+#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) (a & ~RT_BIT(12))
+/** @} */
+
+/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE
+ * @{
+ */
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT 0
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT 3
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW 4 /**< int xx */
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_DBEXCPT 5 /**< Why are we getting this one?? */
+#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT 6
+/** @} */
+
+
+/** @name VMCS field encoding - 32 Bits guest state fields
+ * @{
+ */
+#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800
+#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802
+#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804
+#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806
+#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808
+#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A
+#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C
+#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E
+#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810
+#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812
+#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814
+#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816
+#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818
+#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A
+#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C
+#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E
+#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820
+#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822
+#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824
+#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826
+#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */
+#define VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE 0x482E
+/** @} */
+
+
+/** @name VMX_VMCS_GUEST_ACTIVITY_STATE
+ * @{
+ */
+/** The logical processor is active. */
+#define VMX_CMS_GUEST_ACTIVITY_ACTIVE 0x0
+/** The logical processor is inactive, because executed a HLT instruction. */
+#define VMX_CMS_GUEST_ACTIVITY_HLT 0x1
+/** The logical processor is inactive, because of a triple fault or other serious error. */
+#define VMX_CMS_GUEST_ACTIVITY_SHUTDOWN 0x2
+/** The logical processor is inactive, because it's waiting for a startup-IPI */
+#define VMX_CMS_GUEST_ACTIVITY_SIPI_WAIT 0x3
+/** @} */
+
+
+/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE
+ * @{
+ */
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0)
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1)
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2)
+#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3)
+/** @} */
+
+
+/** @name VMCS field encoding - 32 Bits host state fields
+ * @{
+ */
+#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00
+/** @} */
+
+/** @name Natural width control fields
+ * @{
+ */
+#define VMX_VMCS_CTRL_CR0_MASK 0x6000
+#define VMX_VMCS_CTRL_CR4_MASK 0x6002
+#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004
+#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C
+#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E
+/** @} */
+
+
+/** @name Natural width read-only data fields
+ * @{
+ */
+#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400
+#define VMX_VMCS_RO_IO_RCX 0x6402
+#define VMX_VMCS_RO_IO_RSX 0x6404
+#define VMX_VMCS_RO_IO_RDI 0x6406
+#define VMX_VMCS_RO_IO_RIP 0x6408
+#define VMX_VMCS_EXIT_GUEST_LINEAR_ADDR 0x640A
+/** @} */
+
+
+/** @name VMX_VMCS_RO_EXIT_QUALIFICATION
+ * @{
+ */
+/** 0-2: Debug register number */
+#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) (a & 7)
+/** 3: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) ((a >> 3) & 1)
+/** 4: Direction of move (0 = write, 1 = read) */
+#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) ((a >> 4) & 1)
+/** 5-7: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) ((a >> 5) & 7)
+/** 8-11: General purpose register number. */
+#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) ((a >> 8) & 0xF)
+/** Rest: reserved. */
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0
+#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1
+/** @} */
+
+
+
+/** @name CRx accesses
+ * @{
+ */
+/** 0-3: Control register number (0 for CLTS & LMSW) */
+#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) (a & 0xF)
+/** 4-5: Access type. */
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) ((a >> 4) & 3)
+/** 6: LMSW operand type */
+#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) ((a >> 6) & 1)
+/** 7: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) ((a >> 7) & 1)
+/** 8-11: General purpose register number (0 for CLTS & LMSW). */
+#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) ((a >> 8) & 0xF)
+/** 12-15: Reserved; cleared to 0. */
+#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) ((a >> 12) & 0xF)
+/** 16-31: LMSW source data (else 0). */
+#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) ((a >> 16) & 0xFFFF)
+/** Rest: reserved. */
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2
+#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) (a & 0xffff)
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) ((a >> 30)& 0x3)
+/** Task switch caused by a call instruction. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0
+/** Task switch caused by an iret instruction. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1
+/** Task switch caused by a jmp instruction. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2
+/** Task switch caused by an interrupt gate. */
+#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3
+
+/** @} */
+
+
+/** @name VMX_EXIT_EPT_VIOLATION
+ * @{
+ */
+/** Set if the violation was caused by a data read. */
+#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0)
+/** Set if the violation was caused by a data write. */
+#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1)
+/** Set if the violation was caused by an insruction fetch. */
+#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2)
+/** AND of the present bit of all EPT structures. */
+#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3)
+/** AND of the write bit of all EPT structures. */
+#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4)
+/** AND of the execute bit of all EPT structures. */
+#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5)
+/** Set if the guest linear address field contains the faulting address. */
+#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7)
+/** If bit 7 is one: (reserved otherwise)
+ * 1 - violation due to physical address access.
+ * 0 - violation caused by page walk or access/dirty bit updates
+ */
+#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8)
+/** @} */
+
+
+/** @name VMX_EXIT_PORT_IO
+ * @{
+ */
+/** 0-2: IO operation width. */
+#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) (a & 7)
+/** 3: IO operation direction. */
+#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) ((a >> 3) & 1)
+/** 4: String IO operation. */
+#define VMX_EXIT_QUALIFICATION_IO_STRING(a) ((a >> 4) & 1)
+/** 5: Repeated IO operation. */
+#define VMX_EXIT_QUALIFICATION_IO_REP(a) ((a >> 5) & 1)
+/** 6: Operand encoding. */
+#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) ((a >> 6) & 1)
+/** 16-31: IO Port (0-0xffff). */
+#define VMX_EXIT_QUALIFICATION_IO_PORT(a) ((a >> 16) & 0xffff)
+/* Rest reserved. */
+/** @} */
+
+/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0
+#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1
+/** @} */
+
+
+/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING
+ * @{
+ */
+#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0
+#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1
+/** @} */
+
+/** @name VMX_EXIT_APIC_ACCESS
+ * @{
+ */
+/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */
+#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) (a & 0xfff)
+/** 12-15: Access type. */
+#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a >> 12) & 0xf)
+/* Rest reserved. */
+/** @} */
+
+
+/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types
+ * @{
+ */
+/** Linear read access. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0
+/** Linear write access. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1
+/** Linear instruction fetch access. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2
+/** Linear read/write access during event delivery. */
+#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3
+/** Physical read/write access during event delivery. */
+#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10
+/** Physical access for an instruction fetch or during instruction execution. */
+#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15
+/** @} */
+
+/** @} */
+
+/** @name VMCS field encoding - Natural width guest state fields
+ * @{
+ */
+#define VMX_VMCS64_GUEST_CR0 0x6800
+#define VMX_VMCS64_GUEST_CR3 0x6802
+#define VMX_VMCS64_GUEST_CR4 0x6804
+#define VMX_VMCS64_GUEST_ES_BASE 0x6806
+#define VMX_VMCS64_GUEST_CS_BASE 0x6808
+#define VMX_VMCS64_GUEST_SS_BASE 0x680A
+#define VMX_VMCS64_GUEST_DS_BASE 0x680C
+#define VMX_VMCS64_GUEST_FS_BASE 0x680E
+#define VMX_VMCS64_GUEST_GS_BASE 0x6810
+#define VMX_VMCS64_GUEST_LDTR_BASE 0x6812
+#define VMX_VMCS64_GUEST_TR_BASE 0x6814
+#define VMX_VMCS64_GUEST_GDTR_BASE 0x6816
+#define VMX_VMCS64_GUEST_IDTR_BASE 0x6818
+#define VMX_VMCS64_GUEST_DR7 0x681A
+#define VMX_VMCS64_GUEST_RSP 0x681C
+#define VMX_VMCS64_GUEST_RIP 0x681E
+#define VMX_VMCS_GUEST_RFLAGS 0x6820
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 0x6822
+#define VMX_VMCS64_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */
+#define VMX_VMCS64_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */
+/** @} */
+
+
+/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS
+ * @{
+ */
+/** Hardware breakpoint 0 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0)
+/** Hardware breakpoint 1 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1)
+/** Hardware breakpoint 2 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2)
+/** Hardware breakpoint 3 was met. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3)
+/** At least one data or IO breakpoint was hit. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12)
+/** A debug exception would have been triggered by single-step execution mode. */
+#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14)
+/** Bits 4-11, 13 and 15-63 are reserved. */
+
+/** @} */
+
+/** @name VMCS field encoding - Natural width host state fields
+ * @{
+ */
+#define VMX_VMCS_HOST_CR0 0x6C00
+#define VMX_VMCS_HOST_CR3 0x6C02
+#define VMX_VMCS_HOST_CR4 0x6C04
+#define VMX_VMCS_HOST_FS_BASE 0x6C06
+#define VMX_VMCS_HOST_GS_BASE 0x6C08
+#define VMX_VMCS_HOST_TR_BASE 0x6C0A
+#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C
+#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E
+#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10
+#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12
+#define VMX_VMCS_HOST_RSP 0x6C14
+#define VMX_VMCS_HOST_RIP 0x6C16
+/** @} */
+
+/** @} */
+
+
+#if RT_INLINE_ASM_GNU_STYLE
+# define __STR(x) #x
+# define STR(x) __STR(x)
+#endif
+
+
+/** @defgroup grp_vmx_asm vmx assembly helpers
+ * @ingroup grp_vmx
+ * @{
+ */
+
+/**
+ * Executes VMXON
+ *
+ * @returns VBox status code
+ * @param pVMXOn Physical address of VMXON structure
+ */
+#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(int) VMXEnable(RTHCPHYS pVMXOn);
+#else
+DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn)
+{
+ int rc = VINF_SUCCESS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (
+ "push %3 \n\t"
+ "push %2 \n\t"
+ ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t"
+ "ja 2f \n\t"
+ "je 1f \n\t"
+ "movl $"STR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t"
+ "jmp 2f \n\t"
+ "1: \n\t"
+ "movl $"STR(VERR_VMX_GENERIC)", %0 \n\t"
+ "2: \n\t"
+ "add $8, %%esp \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */
+ "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */
+ :"memory"
+ );
+# else
+ __asm
+ {
+ push dword ptr [pVMXOn+4]
+ push dword ptr [pVMXOn]
+ _emit 0xF3
+ _emit 0x0F
+ _emit 0xC7
+ _emit 0x34
+ _emit 0x24 /* VMXON [esp] */
+ jnc vmxon_good
+ mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR
+ jmp the_end
+
+vmxon_good:
+ jnz the_end
+ mov dword ptr [rc], VERR_VMX_GENERIC
+the_end:
+ add esp, 8
+ }
+# endif
+ return rc;
+}
+#endif
+
+
+/**
+ * Executes VMXOFF
+ */
+#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(void) VMXDisable(void);
+#else
+DECLINLINE(void) VMXDisable(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (
+ ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t"
+ );
+# else
+ __asm
+ {
+ _emit 0x0F
+ _emit 0x01
+ _emit 0xC4 /* VMXOFF */
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Executes VMCLEAR
+ *
+ * @returns VBox status code
+ * @param pVMCS Physical address of VM control structure
+ */
+#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS);
+#else
+DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS)
+{
+ int rc = VINF_SUCCESS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (
+ "push %3 \n\t"
+ "push %2 \n\t"
+ ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t"
+ "jnc 1f \n\t"
+ "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "1: \n\t"
+ "add $8, %%esp \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
+ "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */
+ :"memory"
+ );
+# else
+ __asm
+ {
+ push dword ptr [pVMCS+4]
+ push dword ptr [pVMCS]
+ _emit 0x66
+ _emit 0x0F
+ _emit 0xC7
+ _emit 0x34
+ _emit 0x24 /* VMCLEAR [esp] */
+ jnc success
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+success:
+ add esp, 8
+ }
+# endif
+ return rc;
+}
+#endif
+
+
+/**
+ * Executes VMPTRLD
+ *
+ * @returns VBox status code
+ * @param pVMCS Physical address of VMCS structure
+ */
+#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS);
+#else
+DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS)
+{
+ int rc = VINF_SUCCESS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (
+ "push %3 \n\t"
+ "push %2 \n\t"
+ ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t"
+ "jnc 1f \n\t"
+ "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "1: \n\t"
+ "add $8, %%esp \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
+ "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */
+ );
+# else
+ __asm
+ {
+ push dword ptr [pVMCS+4]
+ push dword ptr [pVMCS]
+ _emit 0x0F
+ _emit 0xC7
+ _emit 0x34
+ _emit 0x24 /* VMPTRLD [esp] */
+ jnc success
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+
+success:
+ add esp, 8
+ }
+# endif
+ return rc;
+}
+#endif
+
+/**
+ * Executes VMPTRST
+ *
+ * @returns VBox status code
+ * @param pVMCS Address that will receive the current pointer
+ */
+DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS);
+
+/**
+ * Executes VMWRITE
+ *
+ * @returns VBox status code
+ * @param idxField VMCS index
+ * @param u32Val 32 bits value
+ */
+#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val);
+#else
+DECLINLINE(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val)
+{
+ int rc = VINF_SUCCESS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (
+ ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t"
+ "ja 2f \n\t"
+ "je 1f \n\t"
+ "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "jmp 2f \n\t"
+ "1: \n\t"
+ "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
+ "2: \n\t"
+ :"=rm"(rc)
+ :"0"(VINF_SUCCESS),
+ "a"(idxField),
+ "d"(u32Val)
+ );
+# else
+ __asm
+ {
+ push dword ptr [u32Val]
+ mov eax, [idxField]
+ _emit 0x0F
+ _emit 0x79
+ _emit 0x04
+ _emit 0x24 /* VMWRITE eax, [esp] */
+ jnc valid_vmcs
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+ jmp the_end
+
+valid_vmcs:
+ jnz the_end
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
+the_end:
+ add esp, 4
+ }
+# endif
+ return rc;
+}
+#endif
+
+/**
+ * Executes VMWRITE
+ *
+ * @returns VBox status code
+ * @param idxField VMCS index
+ * @param u64Val 16, 32 or 64 bits value
+ */
+#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(int) VMXWriteVMCS64(uint32_t idxField, uint64_t u64Val);
+#else
+VMMR0DECL(int) VMXWriteVMCS64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val);
+
+#define VMXWriteVMCS64(idxField, u64Val) VMXWriteVMCS64Ex(pVCpu, idxField, u64Val)
+#endif
+
+#if HC_ARCH_BITS == 64
+#define VMXWriteVMCS VMXWriteVMCS64
+#else
+#define VMXWriteVMCS VMXWriteVMCS32
+#endif /* HC_ARCH_BITS == 64 */
+
+
+/**
+ * Invalidate a page using invept
+ * @returns VBox status code
+ * @param enmFlush Type of flush
+ * @param pDescriptor Descriptor
+ */
+DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor);
+
+/**
+ * Invalidate a page using invvpid
+ * @returns VBox status code
+ * @param enmFlush Type of flush
+ * @param pDescriptor Descriptor
+ */
+DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor);
+
+/**
+ * Executes VMREAD
+ *
+ * @returns VBox status code
+ * @param idxField VMCS index
+ * @param pData Ptr to store VM field value
+ */
+#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData);
+#else
+DECLINLINE(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData)
+{
+ int rc = VINF_SUCCESS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (
+ "movl $"STR(VINF_SUCCESS)", %0 \n\t"
+ ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t"
+ "ja 2f \n\t"
+ "je 1f \n\t"
+ "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
+ "jmp 2f \n\t"
+ "1: \n\t"
+ "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
+ "2: \n\t"
+ :"=&r"(rc),
+ "=d"(*pData)
+ :"a"(idxField),
+ "d"(0)
+ );
+# else
+ __asm
+ {
+ sub esp, 4
+ mov dword ptr [esp], 0
+ mov eax, [idxField]
+ _emit 0x0F
+ _emit 0x78
+ _emit 0x04
+ _emit 0x24 /* VMREAD eax, [esp] */
+ mov edx, pData
+ pop dword ptr [edx]
+ jnc valid_vmcs
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
+ jmp the_end
+
+valid_vmcs:
+ jnz the_end
+ mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
+the_end:
+ }
+# endif
+ return rc;
+}
+#endif
+
+/**
+ * Executes VMREAD
+ *
+ * @returns VBox status code
+ * @param idxField VMCS index
+ * @param pData Ptr to store VM field value
+ */
+#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
+DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData);
+#else
+DECLINLINE(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData)
+{
+ int rc;
+
+ uint32_t val_hi, val;
+ rc = VMXReadVMCS32(idxField, &val);
+ rc |= VMXReadVMCS32(idxField + 1, &val_hi);
+ AssertRC(rc);
+ *pData = RT_MAKE_U64(val, val_hi);
+ return rc;
+}
+#endif
+
+#if HC_ARCH_BITS == 64
+# define VMXReadVMCS VMXReadVMCS64
+#else
+# define VMXReadVMCS VMXReadVMCS32
+#endif /* HC_ARCH_BITS == 64 */
+
+/**
+ * Gets the last instruction error value from the current VMCS
+ *
+ * @returns error value
+ */
+DECLINLINE(uint32_t) VMXGetLastError(void)
+{
+#if HC_ARCH_BITS == 64
+ uint64_t uLastError = 0;
+ int rc = VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
+ AssertRC(rc);
+ return (uint32_t)uLastError;
+
+#else /* 32-bit host: */
+ uint32_t uLastError = 0;
+ int rc = VMXReadVMCS32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
+ AssertRC(rc);
+ return uLastError;
+#endif
+}
+
+#ifdef IN_RING0
+VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
+VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys);
+#endif /* IN_RING0 */
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/hwacc_vmx.mac b/include/VBox/vmm/hwacc_vmx.mac
new file mode 100644
index 00000000..3fc11b43
--- /dev/null
+++ b/include/VBox/vmm/hwacc_vmx.mac
@@ -0,0 +1,154 @@
+;; @file
+; HWACCM - VMX Structures and Definitions.
+;
+
+;
+; Copyright (C) 2006-2010 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; 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.
+;
+
+%define VMX_VMCS_GUEST_FIELD_ES 0800h
+%define VMX_VMCS_GUEST_FIELD_CS 0802h
+%define VMX_VMCS_GUEST_FIELD_SS 0804h
+%define VMX_VMCS_GUEST_FIELD_DS 0806h
+%define VMX_VMCS_GUEST_FIELD_FS 0808h
+%define VMX_VMCS_GUEST_FIELD_GS 080Ah
+%define VMX_VMCS_GUEST_FIELD_LDTR 080Ch
+%define VMX_VMCS_GUEST_FIELD_TR 080Eh
+%define VMX_VMCS_HOST_FIELD_ES 0C00h
+%define VMX_VMCS_HOST_FIELD_CS 0C02h
+%define VMX_VMCS_HOST_FIELD_SS 0C04h
+%define VMX_VMCS_HOST_FIELD_DS 0C06h
+%define VMX_VMCS_HOST_FIELD_FS 0C08h
+%define VMX_VMCS_HOST_FIELD_GS 0C0Ah
+%define VMX_VMCS_HOST_FIELD_TR 0C0Ch
+%define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 02000h
+%define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 02001h
+%define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 02002h
+%define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 02003h
+%define VMX_VMCS_CTRL_MSR_BITMAP_FULL 02004h
+%define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 02005h
+%define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 02006h
+%define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 02007h
+%define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 02008h
+%define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 02009h
+%define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0200Ah
+%define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0200Bh
+%define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0200Ch
+%define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0200Dh
+%define VMX_VMCS_CTRL_TSC_OFFSET_FULL 02010h
+%define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 02011h
+%define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 02012h
+%define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 02013h
+%define VMX_VMCS_GUEST_LINK_PTR_FULL 02800h
+%define VMX_VMCS_GUEST_LINK_PTR_HIGH 02801h
+%define VMX_VMCS_GUEST_DEBUGCTL_FULL 02802h
+%define VMX_VMCS_GUEST_DEBUGCTL_HIGH 02803h
+%define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 04000h
+%define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 04002h
+%define VMX_VMCS_CTRL_EXCEPTION_BITMAP 04004h
+%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 04006h
+%define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 04008h
+%define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0400Ah
+%define VMX_VMCS_CTRL_EXIT_CONTROLS 0400Ch
+%define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0400Eh
+%define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 04010h
+%define VMX_VMCS_CTRL_ENTRY_CONTROLS 04012h
+%define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 04014h
+%define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 04016h
+%define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 04018h
+%define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0401Ah
+%define VMX_VMCS_CTRL_TRP_TRESHOLD 0401Ch
+%define VMX_VMCS_RO_VM_INSTR_ERROR 04400h
+%define VMX_VMCS_RO_EXIT_REASON 04402h
+%define VMX_VMCS_RO_EXIT_INTERRUPTION_INFO 04404h
+%define VMX_VMCS_RO_EXIT_INTERRUPTION_ERRCODE 04406h
+%define VMX_VMCS_RO_IDT_INFO 04408h
+%define VMX_VMCS_RO_IDT_ERRCODE 0440Ah
+%define VMX_VMCS_RO_EXIT_INSTR_LENGTH 0440Ch
+%define VMX_VMCS_RO_EXIT_INSTR_INFO 0440Eh
+%define VMX_VMCS_GUEST_ES_LIMIT 04800h
+%define VMX_VMCS_GUEST_CS_LIMIT 04802h
+%define VMX_VMCS_GUEST_SS_LIMIT 04804h
+%define VMX_VMCS_GUEST_DS_LIMIT 04806h
+%define VMX_VMCS_GUEST_FS_LIMIT 04808h
+%define VMX_VMCS_GUEST_GS_LIMIT 0480Ah
+%define VMX_VMCS_GUEST_LDTR_LIMIT 0480Ch
+%define VMX_VMCS_GUEST_TR_LIMIT 0480Eh
+%define VMX_VMCS_GUEST_GDTR_LIMIT 04810h
+%define VMX_VMCS_GUEST_IDTR_LIMIT 04812h
+%define VMX_VMCS_GUEST_ES_ACCESS_RIGHTS 04814h
+%define VMX_VMCS_GUEST_CS_ACCESS_RIGHTS 04816h
+%define VMX_VMCS_GUEST_SS_ACCESS_RIGHTS 04818h
+%define VMX_VMCS_GUEST_DS_ACCESS_RIGHTS 0481Ah
+%define VMX_VMCS_GUEST_FS_ACCESS_RIGHTS 0481Ch
+%define VMX_VMCS_GUEST_GS_ACCESS_RIGHTS 0481Eh
+%define VMX_VMCS_GUEST_LDTR_ACCESS_RIGHTS 04820h
+%define VMX_VMCS_GUEST_TR_ACCESS_RIGHTS 04822h
+%define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE 04824h
+%define VMX_VMCS_GUEST_ACTIVITY_STATE 04826h
+%define VMX_VMCS_GUEST_SYSENTER_CS 0482Ah
+%define VMX_VMCS_CTRL_CR0_MASK 06000h
+%define VMX_VMCS_CTRL_CR4_MASK 06002h
+%define VMX_VMCS_CTRL_CR0_READ_SHADOW 06004h
+%define VMX_VMCS_CTRL_CR4_READ_SHADOW 06006h
+%define VMX_VMCS_CTRL_CR3_TARGET_VAL0 06008h
+%define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0600Ah
+%define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0600Ch
+%define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0600Eh
+%define VMX_VMCS_RO_EXIT_QUALIFICATION 06400h
+%define VMX_VMCS_RO_IO_RCX 06402h
+%define VMX_VMCS_RO_IO_RSX 06404h
+%define VMX_VMCS_RO_IO_RDI 06406h
+%define VMX_VMCS_RO_IO_RIP 06408h
+%define VMX_VMCS_GUEST_LINEAR_ADDR 0640Ah
+%define VMX_VMCS64_GUEST_CR0 06800h
+%define VMX_VMCS64_GUEST_CR3 06802h
+%define VMX_VMCS64_GUEST_CR4 06804h
+%define VMX_VMCS64_GUEST_ES_BASE 06806h
+%define VMX_VMCS64_GUEST_CS_BASE 06808h
+%define VMX_VMCS64_GUEST_SS_BASE 0680Ah
+%define VMX_VMCS64_GUEST_DS_BASE 0680Ch
+%define VMX_VMCS64_GUEST_FS_BASE 0680Eh
+%define VMX_VMCS64_GUEST_GS_BASE 06810h
+%define VMX_VMCS64_GUEST_LDTR_BASE 06812h
+%define VMX_VMCS64_GUEST_TR_BASE 06814h
+%define VMX_VMCS64_GUEST_GDTR_BASE 06816h
+%define VMX_VMCS64_GUEST_IDTR_BASE 06818h
+%define VMX_VMCS64_GUEST_DR7 0681Ah
+%define VMX_VMCS64_GUEST_RSP 0681Ch
+%define VMX_VMCS64_GUEST_RIP 0681Eh
+%define VMX_VMCS64_GUEST_RFLAGS 06820h
+%define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 06822h
+%define VMX_VMCS64_GUEST_SYSENTER_ESP 06824h
+%define VMX_VMCS64_GUEST_SYSENTER_EIP 06826h
+%define VMX_VMCS_HOST_CR0 06C00h
+%define VMX_VMCS_HOST_CR3 06C02h
+%define VMX_VMCS_HOST_CR4 06C04h
+%define VMX_VMCS_HOST_FS_BASE 06C06h
+%define VMX_VMCS_HOST_GS_BASE 06C08h
+%define VMX_VMCS_HOST_TR_BASE 06C0Ah
+%define VMX_VMCS_HOST_GDTR_BASE 06C0Ch
+%define VMX_VMCS_HOST_IDTR_BASE 06C0Eh
+%define VMX_VMCS_HOST_SYSENTER_ESP 06C10h
+%define VMX_VMCS_HOST_SYSENTER_EIP 06C12h
+%define VMX_VMCS_HOST_RSP 06C14h
+%define VMX_VMCS_HOST_RIP 06C16h
+
+%define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9)
diff --git a/include/VBox/vmm/hwaccm.h b/include/VBox/vmm/hwaccm.h
new file mode 100644
index 00000000..98a7d02e
--- /dev/null
+++ b/include/VBox/vmm/hwaccm.h
@@ -0,0 +1,154 @@
+/** @file
+ * HWACCM - Intel/AMD VM Hardware Support Manager (VMM)
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_hwaccm_h
+#define ___VBox_vmm_hwaccm_h
+
+#include <VBox/vmm/pgm.h>
+#include <VBox/vmm/cpum.h>
+#include <iprt/mp.h>
+
+
+/** @defgroup grp_hwaccm The VM Hardware Manager API
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Query HWACCM state (enabled/disabled)
+ *
+ * @returns 0 - disabled, 1 - enabled
+ * @param pVM The VM to operate on.
+ */
+#define HWACCMIsEnabled(pVM) ((pVM)->fHWACCMEnabled)
+
+ /**
+ * Check if the current CPU state is valid for emulating IO blocks in the recompiler
+ *
+ * @returns boolean
+ * @param pCtx CPU context
+ */
+#define HWACCMCanEmulateIoBlock(pVCpu) (!CPUMIsGuestInPagedProtectedMode(pVCpu))
+#define HWACCMCanEmulateIoBlockEx(pCtx) (!CPUMIsGuestInPagedProtectedModeEx(pCtx))
+
+VMMDECL(int) HWACCMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCVirt);
+VMMDECL(bool) HWACCMHasPendingIrq(PVM pVM);
+
+#ifndef IN_RC
+VMMDECL(int) HWACCMFlushTLB(PVMCPU pVCpu);
+VMMDECL(int) HWACCMFlushTLBOnAllVCpus(PVM pVM);
+VMMDECL(int) HWACCMInvalidatePageOnAllVCpus(PVM pVM, RTGCPTR GCVirt);
+VMMDECL(int) HWACCMInvalidatePhysPage(PVM pVM, RTGCPHYS GCPhys);
+VMMDECL(bool) HWACCMIsNestedPagingActive(PVM pVM);
+VMMDECL(PGMMODE) HWACCMGetShwPagingMode(PVM pVM);
+#else
+/* Nop in GC */
+# define HWACCMFlushTLB(pVCpu) do { } while (0)
+# define HWACCMIsNestedPagingActive(pVM) false
+# define HWACCMFlushTLBOnAllVCpus(pVM) do { } while (0)
+#endif
+
+#ifdef IN_RING0
+/** @defgroup grp_hwaccm_r0 The VM Hardware Manager API
+ * @ingroup grp_hwaccm
+ * @{
+ */
+VMMR0DECL(int) HWACCMR0Init(void);
+VMMR0DECL(int) HWACCMR0Term(void);
+VMMR0DECL(int) HWACCMR0InitVM(PVM pVM);
+VMMR0DECL(int) HWACCMR0TermVM(PVM pVM);
+VMMR0DECL(int) HWACCMR0EnableAllCpus(PVM pVM);
+VMMR0DECL(int) HWACCMR0EnterSwitcher(PVM pVM, bool *pfVTxDisabled);
+VMMR0DECL(int) HWACCMR0LeaveSwitcher(PVM pVM, bool fVTxDisabled);
+
+VMMR0DECL(void) HWACCMR0SavePendingIOPortWrite(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize);
+VMMR0DECL(void) HWACCMR0SavePendingIOPortRead(PVMCPU pVCpu, RTGCPTR GCPtrRip, RTGCPTR GCPtrRipNext, unsigned uPort, unsigned uAndVal, unsigned cbSize);
+
+/** @} */
+#endif /* IN_RING0 */
+
+
+#ifdef IN_RING3
+/** @defgroup grp_hwaccm_r3 The VM Hardware Manager API
+ * @ingroup grp_hwaccm
+ * @{
+ */
+VMMR3DECL(bool) HWACCMR3IsEventPending(PVMCPU pVCpu);
+VMMR3DECL(int) HWACCMR3Init(PVM pVM);
+VMMR3_INT_DECL(int) HWACCMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
+VMMR3DECL(void) HWACCMR3Relocate(PVM pVM);
+VMMR3DECL(int) HWACCMR3Term(PVM pVM);
+VMMR3DECL(void) HWACCMR3Reset(PVM pVM);
+VMMR3DECL(void) HWACCMR3ResetCpu(PVMCPU pVCpu);
+VMMR3DECL(void) HWACCMR3CheckError(PVM pVM, int iStatusCode);
+VMMR3DECL(bool) HWACCMR3CanExecuteGuest(PVM pVM, PCPUMCTX pCtx);
+VMMR3DECL(void) HWACCMR3NotifyScheduled(PVMCPU pVCpu);
+VMMR3DECL(void) HWACCMR3NotifyEmulated(PVMCPU pVCpu);
+VMMR3DECL(bool) HWACCMR3IsActive(PVMCPU pVCpu);
+VMMR3DECL(bool) HWACCMR3IsNestedPagingActive(PVM pVM);
+VMMR3DECL(bool) HWACCMR3IsAllowed(PVM pVM);
+VMMR3DECL(void) HWACCMR3PagingModeChanged(PVM pVM, PVMCPU pVCpu, PGMMODE enmShadowMode, PGMMODE enmGuestMode);
+VMMR3DECL(bool) HWACCMR3IsVPIDActive(PVM pVM);
+VMMR3DECL(int) HWACCMR3InjectNMI(PVM pVM);
+VMMR3DECL(int) HWACCMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx);
+VMMR3DECL(VBOXSTRICTRC) HWACCMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR3DECL(int) HWACMMR3EnablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
+VMMR3DECL(int) HWACMMR3DisablePatching(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
+VMMR3DECL(int) HWACCMR3PatchTprInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR3DECL(bool) HWACCMR3IsRescheduleRequired(PVM pVM, PCPUMCTX pCtx);
+VMMR3DECL(bool) HWACCMR3IsVmxPreemptionTimerUsed(PVM pVM);
+
+/** @} */
+#endif /* IN_RING3 */
+
+#ifdef IN_RING0
+/** @addtogroup grp_hwaccm_r0
+ * @{
+ */
+VMMR0DECL(int) HWACCMR0SetupVM(PVM pVM);
+VMMR0DECL(int) HWACCMR0RunGuestCode(PVM pVM, PVMCPU pVCpu);
+VMMR0DECL(int) HWACCMR0Enter(PVM pVM, PVMCPU pVCpu);
+VMMR0DECL(int) HWACCMR0Leave(PVM pVM, PVMCPU pVCpu);
+VMMR0DECL(int) HWACCMR0InvalidatePage(PVM pVM, PVMCPU pVCpu);
+VMMR0DECL(int) HWACCMR0FlushTLB(PVM pVM);
+VMMR0DECL(bool) HWACCMR0SuspendPending(void);
+
+# if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS)
+VMMR0DECL(int) HWACCMR0SaveFPUState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0DECL(int) HWACCMR0SaveDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
+VMMR0DECL(int) HWACCMR0TestSwitcher3264(PVM pVM);
+# endif
+
+/** @} */
+#endif /* IN_RING0 */
+
+
+/** @} */
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/VBox/vmm/iem.h b/include/VBox/vmm/iem.h
new file mode 100644
index 00000000..617a05a6
--- /dev/null
+++ b/include/VBox/vmm/iem.h
@@ -0,0 +1,83 @@
+/** @file
+ * IEM - Interpreted Execution Manager.
+ */
+
+/*
+ * Copyright (C) 2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_iem_h
+#define ___VBox_vmm_iem_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/trpm.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_iem The Interpreted Execution Manager API.
+ * @{
+ */
+
+
+
+VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu);
+VMMDECL(VBOXSTRICTRC) IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
+VMMDECL(VBOXSTRICTRC) IEMExecOneWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC,
+ const void *pvOpcodeBytes, size_t cbOpcodeBytes);
+VMMDECL(VBOXSTRICTRC) IEMExecOneBypassEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
+VMMDECL(VBOXSTRICTRC) IEMExecOneBypassWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC,
+ const void *pvOpcodeBytes, size_t cbOpcodeBytes);
+VMMDECL(VBOXSTRICTRC) IEMExecLots(PVMCPU pVCpu);
+VMM_INT_DECL(VBOXSTRICTRC) IEMInjectTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType, uint16_t uErrCode, RTGCPTR uCr2);
+
+VMM_INT_DECL(int) IEMBreakpointSet(PVM pVM, RTGCPTR GCPtrBp);
+VMM_INT_DECL(int) IEMBreakpointClear(PVM pVM, RTGCPTR GCPtrBp);
+
+/** @name Given Instruction Interpreters
+ * @{ */
+
+/** @} */
+
+#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
+VMM_INT_DECL(void) IEMNotifyMMIORead(PVM pVM, RTGCPHYS GCPhys, size_t cbValue);
+VMM_INT_DECL(void) IEMNotifyMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue);
+VMM_INT_DECL(void) IEMNotifyIOPortRead(PVM pVM, RTIOPORT Port, size_t cbValue);
+VMM_INT_DECL(void) IEMNotifyIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
+VMM_INT_DECL(void) IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrDst, RTGCUINTREG cTransfers, size_t cbValue);
+VMM_INT_DECL(void) IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrSrc, RTGCUINTREG cTransfers, size_t cbValue);
+#endif
+
+
+/** @defgroup grp_em_r3 The IEM Host Context Ring-3 API.
+ * @ingroup grp_em
+ * @{
+ */
+VMMR3DECL(int) IEMR3Init(PVM pVM);
+VMMR3DECL(int) IEMR3Term(PVM pVM);
+VMMR3DECL(void) IEMR3Relocate(PVM pVM);
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/iom.h b/include/VBox/vmm/iom.h
new file mode 100644
index 00000000..a7e552c9
--- /dev/null
+++ b/include/VBox/vmm/iom.h
@@ -0,0 +1,325 @@
+/** @file
+ * IOM - Input / Output Monitor.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_iom_h
+#define ___VBox_vmm_iom_h
+
+#include <VBox/types.h>
+#include <VBox/dis.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_iom The Input / Ouput Monitor API
+ * @{
+ */
+
+/** @def IOM_NO_PDMINS_CHECKS
+ * Until all devices have been fully adjusted to PDM style, the pPdmIns
+ * parameter is not checked by IOM.
+ * @todo Check this again, now.
+ */
+#define IOM_NO_PDMINS_CHECKS
+
+/**
+ * Macro for checking if an I/O or MMIO emulation call succeeded.
+ *
+ * This macro shall only be used with the IOM APIs where it's mentioned
+ * in the return value description. And there it must be used to correctly
+ * determine if the call succeeded and things like the RIP needs updating.
+ *
+ *
+ * @returns Success indicator (true/false).
+ *
+ * @param rc The status code. This may be evaluated
+ * more than once!
+ *
+ * @remark To avoid making assumptions about the layout of the
+ * VINF_EM_FIRST...VINF_EM_LAST range we're checking
+ * explicitly for each for exach the exceptions.
+ * However, for efficieny we ASSUME that the
+ * VINF_EM_LAST is smaller than most of the relevant
+ * status codes. We also ASSUME that the
+ * VINF_EM_RESCHEDULE_REM status code is the most
+ * frequent status code we'll enounter in this range.
+ *
+ * @todo Will have to add VINF_EM_DBG_HYPER_BREAKPOINT if the
+ * I/O port and MMIO breakpoints should trigger before
+ * the I/O is done. Currently, we don't implement these
+ * kind of breakpoints.
+ */
+#define IOM_SUCCESS(rc) ( (rc) == VINF_SUCCESS \
+ || ( (rc) <= VINF_EM_LAST \
+ && (rc) != VINF_EM_RESCHEDULE_REM \
+ && (rc) >= VINF_EM_FIRST \
+ && (rc) != VINF_EM_RESCHEDULE_RAW \
+ && (rc) != VINF_EM_RESCHEDULE_HWACC \
+ ) \
+ )
+
+/** @name IOMMMIO_FLAGS_XXX
+ * @{ */
+/** Pass all reads thru unmodified. */
+#define IOMMMIO_FLAGS_READ_PASSTHRU UINT32_C(0x00000000)
+/** All read accesses are DWORD sized (32-bit). */
+#define IOMMMIO_FLAGS_READ_DWORD UINT32_C(0x00000001)
+/** All read accesses are DWORD (32-bit) or QWORD (64-bit) sized.
+ * Only accesses that are both QWORD sized and aligned are performed as QWORD.
+ * All other access will be done DWORD fashion (because it is way simpler). */
+#define IOMMMIO_FLAGS_READ_DWORD_QWORD UINT32_C(0x00000002)
+/** The read access mode mask. */
+#define IOMMMIO_FLAGS_READ_MODE UINT32_C(0x00000003)
+
+/** Pass all writes thru unmodified. */
+#define IOMMMIO_FLAGS_WRITE_PASSTHRU UINT32_C(0x00000000)
+/** All write accesses are DWORD (32-bit) sized and unspecified bytes are
+ * written as zero. */
+#define IOMMMIO_FLAGS_WRITE_DWORD_ZEROED UINT32_C(0x00000010)
+/** All write accesses are either DWORD (32-bit) or QWORD (64-bit) sized,
+ * missing bytes will be written as zero. Only accesses that are both QWORD
+ * sized and aligned are performed as QWORD, all other accesses will be done
+ * DWORD fashion (because it's way simpler). */
+#define IOMMMIO_FLAGS_WRITE_DWORD_QWORD_ZEROED UINT32_C(0x00000020)
+/** All write accesses are DWORD (32-bit) sized and unspecified bytes are
+ * read from the device first as DWORDs.
+ * @remarks This isn't how it happens on real hardware, but it allows
+ * simplifications of devices where reads doesn't change the device
+ * state in any way. */
+#define IOMMMIO_FLAGS_WRITE_DWORD_READ_MISSING UINT32_C(0x00000030)
+/** All write accesses are DWORD (32-bit) or QWORD (64-bit) sized and
+ * unspecified bytes are read from the device first as DWORDs. Only accesses
+ * that are both QWORD sized and aligned are performed as QWORD, all other
+ * accesses will be done DWORD fashion (because it's way simpler).
+ * @remarks This isn't how it happens on real hardware, but it allows
+ * simplifications of devices where reads doesn't change the device
+ * state in any way. */
+#define IOMMMIO_FLAGS_WRITE_DWORD_QWORD_READ_MISSING UINT32_C(0x00000040)
+/** The read access mode mask. */
+#define IOMMMIO_FLAGS_WRITE_MODE UINT32_C(0x00000070)
+
+/** Whether to do a DBGSTOP on complicated reads.
+ * What this includes depends on the read mode, but generally all misaligned
+ * reads as well as word and byte reads and maybe qword reads. */
+#define IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_READ UINT32_C(0x00000100)
+/** Whether to do a DBGSTOP on complicated writes.
+ * This depends on the write mode, but generally all writes where we have to
+ * supply bytes (zero them or read them). */
+#define IOMMMIO_FLAGS_DBGSTOP_ON_COMPLICATED_WRITE UINT32_C(0x00000200)
+
+/** Mask of valid flags. */
+#define IOMMMIO_FLAGS_VALID_MASK UINT32_C(0x00000373)
+/** @} */
+
+
+/**
+ * Port I/O Handler for IN operations.
+ *
+ * @returns VINF_SUCCESS or VINF_EM_*.
+ * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param uPort Port number used for the IN operation.
+ * @param pu32 Where to store the result. This is always a 32-bit
+ * variable regardless of what @a cb might say.
+ * @param cb Number of bytes read.
+ */
+typedef DECLCALLBACK(int) FNIOMIOPORTIN(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t *pu32, unsigned cb);
+/** Pointer to a FNIOMIOPORTIN(). */
+typedef FNIOMIOPORTIN *PFNIOMIOPORTIN;
+
+/**
+ * Port I/O Handler for string IN operations.
+ *
+ * @returns VINF_SUCCESS or VINF_EM_*.
+ * @returns VERR_IOM_IOPORT_UNUSED if the port is really unused and a ~0 value should be returned.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param uPort Port number used for the IN operation.
+ * @param pGCPtrDst Pointer to the destination buffer (GC, incremented appropriately).
+ * @param pcTransfers Pointer to the number of transfer units to read, on return remaining transfer units.
+ * @param cb Size of the transfer unit (1, 2 or 4 bytes).
+ */
+typedef DECLCALLBACK(int) FNIOMIOPORTINSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb);
+/** Pointer to a FNIOMIOPORTINSTRING(). */
+typedef FNIOMIOPORTINSTRING *PFNIOMIOPORTINSTRING;
+
+/**
+ * Port I/O Handler for OUT operations.
+ *
+ * @returns VINF_SUCCESS or VINF_EM_*.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param uPort Port number used for the OUT operation.
+ * @param u32 The value to output.
+ * @param cb The value size in bytes.
+ */
+typedef DECLCALLBACK(int) FNIOMIOPORTOUT(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, uint32_t u32, unsigned cb);
+/** Pointer to a FNIOMIOPORTOUT(). */
+typedef FNIOMIOPORTOUT *PFNIOMIOPORTOUT;
+
+/**
+ * Port I/O Handler for string OUT operations.
+ *
+ * @returns VINF_SUCCESS or VINF_EM_*.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param uPort Port number used for the OUT operation.
+ * @param pGCPtrSrc Pointer to the source buffer (GC, incremented appropriately).
+ * @param pcTransfers Pointer to the number of transfer units to write, on return remaining transfer units.
+ * @param cb Size of the transfer unit (1, 2 or 4 bytes).
+ */
+typedef DECLCALLBACK(int) FNIOMIOPORTOUTSTRING(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT Port, RTGCPTR *pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb);
+/** Pointer to a FNIOMIOPORTOUTSTRING(). */
+typedef FNIOMIOPORTOUTSTRING *PFNIOMIOPORTOUTSTRING;
+
+
+/**
+ * Memory mapped I/O Handler for read operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param GCPhysAddr Physical address (in GC) where the read starts.
+ * @param pv Where to store the result.
+ * @param cb Number of bytes read.
+ */
+typedef DECLCALLBACK(int) FNIOMMMIOREAD(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
+/** Pointer to a FNIOMMMIOREAD(). */
+typedef FNIOMMMIOREAD *PFNIOMMMIOREAD;
+
+/**
+ * Port I/O Handler for write operations.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param GCPhysAddr Physical address (in GC) where the read starts.
+ * @param pv Where to fetch the result.
+ * @param cb Number of bytes to write.
+ */
+typedef DECLCALLBACK(int) FNIOMMMIOWRITE(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void const *pv, unsigned cb);
+/** Pointer to a FNIOMMMIOWRITE(). */
+typedef FNIOMMMIOWRITE *PFNIOMMMIOWRITE;
+
+/**
+ * Port I/O Handler for memset operations, actually for REP STOS* instructions handling.
+ *
+ * @returns VBox status code.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param GCPhysAddr Physical address (in GC) where the write starts.
+ * @param u32Item Byte/Word/Dword data to fill.
+ * @param cbItem Size of data in u32Item parameter, restricted to 1/2/4 bytes.
+ * @param cItems Number of iterations.
+ */
+typedef DECLCALLBACK(int) FNIOMMMIOFILL(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, uint32_t u32Item, unsigned cbItem, unsigned cItems);
+/** Pointer to a FNIOMMMIOFILL(). */
+typedef FNIOMMMIOFILL *PFNIOMMMIOFILL;
+
+VMMDECL(VBOXSTRICTRC) IOMIOPortRead(PVM pVM, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMInterpretIN(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMIOPortReadString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrDst, PRTGCUINTREG pcTransfers, unsigned cb);
+VMMDECL(VBOXSTRICTRC) IOMIOPortWriteString(PVM pVM, RTIOPORT Port, PRTGCPTR pGCPtrSrc, PRTGCUINTREG pcTransfers, unsigned cb);
+VMMDECL(VBOXSTRICTRC) IOMInterpretINS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMInterpretINSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUTS(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+VMMDECL(VBOXSTRICTRC) IOMInterpretOUTSEx(PVM pVM, PCPUMCTXCORE pRegFrame, uint32_t uPort, uint32_t uPrefix, DISCPUMODE enmAddrMode, uint32_t cbTransfer);
+VMMDECL(VBOXSTRICTRC) IOMMMIORead(PVM pVM, RTGCPHYS GCPhys, uint32_t *pu32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue);
+VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault);
+VMMDECL(VBOXSTRICTRC) IOMInterpretCheckPortIOAccess(PVM pVM, PCPUMCTXCORE pCtxCore, RTIOPORT Port, unsigned cb);
+VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags);
+VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags);
+VMMDECL(int) IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys);
+VMMDECL(bool) IOMIsLockOwner(PVM pVM);
+
+#ifdef IN_RC
+/** @defgroup grp_iom_rc The IOM Raw-Mode Context API
+ * @ingroup grp_iom
+ * @{
+ */
+VMMRCDECL(VBOXSTRICTRC) IOMRCIOPortHandler(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+/** @} */
+#endif /* IN_RC */
+
+
+
+#ifdef IN_RING3
+/** @defgroup grp_iom_r3 The IOM Host Context Ring-3 API
+ * @ingroup grp_iom
+ * @{
+ */
+VMMR3_INT_DECL(int) IOMR3Init(PVM pVM);
+VMMR3_INT_DECL(void) IOMR3Reset(PVM pVM);
+VMMR3_INT_DECL(void) IOMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3_INT_DECL(int) IOMR3Term(PVM pVM);
+VMMR3_INT_DECL(int) IOMR3IOPortRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTHCPTR pvUser,
+ R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
+ R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStringCallback, R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStringCallback,
+ const char *pszDesc);
+VMMR3_INT_DECL(int) IOMR3IOPortRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTRCPTR pvUser,
+ RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
+ RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback,
+ const char *pszDesc);
+VMMR3_INT_DECL(int) IOMR3IOPortRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts, RTR0PTR pvUser,
+ R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback, R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback,
+ R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback, R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback,
+ const char *pszDesc);
+VMMR3_INT_DECL(int) IOMR3IOPortDeregister(PVM pVM, PPDMDEVINS pDevIns, RTIOPORT PortStart, RTUINT cPorts);
+
+VMMR3_INT_DECL(int) IOMR3MmioRegisterR3(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser,
+ R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
+ R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
+ R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback,
+ uint32_t fFlags, const char *pszDesc);
+VMMR3_INT_DECL(int) IOMR3MmioRegisterR0(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser,
+ R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
+ R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
+ R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallback);
+VMMR3_INT_DECL(int) IOMR3MmioRegisterRC(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTGCPTR pvUser,
+ RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback,
+ RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback,
+ RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback);
+VMMR3_INT_DECL(int) IOMR3MmioDeregister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange);
+
+/** @} */
+#endif /* IN_RING3 */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/mm.h b/include/VBox/vmm/mm.h
new file mode 100644
index 00000000..66490fce
--- /dev/null
+++ b/include/VBox/vmm/mm.h
@@ -0,0 +1,370 @@
+/** @file
+ * MM - The Memory Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_mm_h
+#define ___VBox_vmm_mm_h
+
+#include <VBox/types.h>
+#include <iprt/x86.h>
+#include <VBox/sup.h>
+#include <iprt/stdarg.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_mm The Memory Manager API
+ * @{
+ */
+
+/**
+ * Memory Allocation Tags.
+ * For use with MMHyperAlloc(), MMR3HeapAlloc(), MMR3HeapAllocEx(),
+ * MMR3HeapAllocZ() and MMR3HeapAllocZEx().
+ *
+ * @remark Don't forget to update the dump command in MMHeap.cpp!
+ */
+typedef enum MMTAG
+{
+ MM_TAG_INVALID = 0,
+
+ MM_TAG_CFGM,
+ MM_TAG_CFGM_BYTES,
+ MM_TAG_CFGM_STRING,
+ MM_TAG_CFGM_USER,
+
+ MM_TAG_CSAM,
+ MM_TAG_CSAM_PATCH,
+
+ MM_TAG_CPUM_CTX,
+
+ MM_TAG_DBGF,
+ MM_TAG_DBGF_AS,
+ MM_TAG_DBGF_CORE_WRITE,
+ MM_TAG_DBGF_INFO,
+ MM_TAG_DBGF_LINE,
+ MM_TAG_DBGF_LINE_DUP,
+ MM_TAG_DBGF_MODULE,
+ MM_TAG_DBGF_OS,
+ MM_TAG_DBGF_REG,
+ MM_TAG_DBGF_STACK,
+ MM_TAG_DBGF_SYMBOL,
+ MM_TAG_DBGF_SYMBOL_DUP,
+
+ MM_TAG_EM,
+
+ MM_TAG_IOM,
+ MM_TAG_IOM_STATS,
+
+ MM_TAG_MM,
+ MM_TAG_MM_LOOKUP_GUEST,
+ MM_TAG_MM_LOOKUP_PHYS,
+ MM_TAG_MM_LOOKUP_VIRT,
+ MM_TAG_MM_PAGE,
+
+ MM_TAG_PARAV,
+
+ MM_TAG_PATM,
+ MM_TAG_PATM_PATCH,
+
+ MM_TAG_PDM,
+ MM_TAG_PDM_ASYNC_COMPLETION,
+ MM_TAG_PDM_DEVICE,
+ MM_TAG_PDM_DEVICE_DESC,
+ MM_TAG_PDM_DEVICE_USER,
+ MM_TAG_PDM_DRIVER,
+ MM_TAG_PDM_DRIVER_DESC,
+ MM_TAG_PDM_DRIVER_USER,
+ MM_TAG_PDM_USB,
+ MM_TAG_PDM_USB_DESC,
+ MM_TAG_PDM_USB_USER,
+ MM_TAG_PDM_LUN,
+#ifdef VBOX_WITH_NETSHAPER
+ MM_TAG_PDM_NET_SHAPER,
+#endif /* VBOX_WITH_NETSHAPER */
+ MM_TAG_PDM_QUEUE,
+ MM_TAG_PDM_THREAD,
+
+ MM_TAG_PGM,
+ MM_TAG_PGM_CHUNK_MAPPING,
+ MM_TAG_PGM_HANDLERS,
+ MM_TAG_PGM_MAPPINGS,
+ MM_TAG_PGM_PHYS,
+ MM_TAG_PGM_POOL,
+
+ MM_TAG_REM,
+
+ MM_TAG_SELM,
+
+ MM_TAG_SSM,
+
+ MM_TAG_STAM,
+
+ MM_TAG_TM,
+
+ MM_TAG_TRPM,
+
+ MM_TAG_VM,
+ MM_TAG_VM_REQ,
+
+ MM_TAG_VMM,
+
+ MM_TAG_HWACCM,
+
+ MM_TAG_32BIT_HACK = 0x7fffffff
+} MMTAG;
+
+
+
+
+/** @defgroup grp_mm_hyper Hypervisor Memory Management
+ * @ingroup grp_mm
+ * @{ */
+
+VMMDECL(RTR3PTR) MMHyperR0ToR3(PVM pVM, RTR0PTR R0Ptr);
+VMMDECL(RTRCPTR) MMHyperR0ToRC(PVM pVM, RTR0PTR R0Ptr);
+#ifndef IN_RING0
+VMMDECL(void *) MMHyperR0ToCC(PVM pVM, RTR0PTR R0Ptr);
+#endif
+VMMDECL(RTR0PTR) MMHyperR3ToR0(PVM pVM, RTR3PTR R3Ptr);
+VMMDECL(RTRCPTR) MMHyperR3ToRC(PVM pVM, RTR3PTR R3Ptr);
+VMMDECL(RTR3PTR) MMHyperRCToR3(PVM pVM, RTRCPTR RCPtr);
+VMMDECL(RTR0PTR) MMHyperRCToR0(PVM pVM, RTRCPTR RCPtr);
+
+#ifndef IN_RING3
+VMMDECL(void *) MMHyperR3ToCC(PVM pVM, RTR3PTR R3Ptr);
+#else
+DECLINLINE(void *) MMHyperR3ToCC(PVM pVM, RTR3PTR R3Ptr)
+{
+ NOREF(pVM);
+ return R3Ptr;
+}
+#endif
+
+
+#ifndef IN_RC
+VMMDECL(void *) MMHyperRCToCC(PVM pVM, RTRCPTR RCPtr);
+#else
+DECLINLINE(void *) MMHyperRCToCC(PVM pVM, RTRCPTR RCPtr)
+{
+ NOREF(pVM);
+ return (void *)RCPtr;
+}
+#endif
+
+#ifndef IN_RING3
+VMMDECL(RTR3PTR) MMHyperCCToR3(PVM pVM, void *pv);
+#else
+DECLINLINE(RTR3PTR) MMHyperCCToR3(PVM pVM, void *pv)
+{
+ NOREF(pVM);
+ return pv;
+}
+#endif
+
+#ifndef IN_RING0
+VMMDECL(RTR0PTR) MMHyperCCToR0(PVM pVM, void *pv);
+#else
+DECLINLINE(RTR0PTR) MMHyperCCToR0(PVM pVM, void *pv)
+{
+ NOREF(pVM);
+ return pv;
+}
+#endif
+
+#ifndef IN_RC
+VMMDECL(RTRCPTR) MMHyperCCToRC(PVM pVM, void *pv);
+#else
+DECLINLINE(RTRCPTR) MMHyperCCToRC(PVM pVM, void *pv)
+{
+ NOREF(pVM);
+ return (RTRCPTR)pv;
+}
+#endif
+
+
+VMMDECL(int) MMHyperAlloc(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv);
+VMMDECL(int) MMHyperFree(PVM pVM, void *pv);
+VMMDECL(void) MMHyperHeapCheck(PVM pVM);
+VMMDECL(int) MMR3LockCall(PVM pVM);
+#ifdef DEBUG
+VMMDECL(void) MMHyperHeapDump(PVM pVM);
+#endif
+VMMDECL(size_t) MMHyperHeapGetFreeSize(PVM pVM);
+VMMDECL(size_t) MMHyperHeapGetSize(PVM pVM);
+VMMDECL(RTGCPTR) MMHyperGetArea(PVM pVM, size_t *pcb);
+VMMDECL(bool) MMHyperIsInsideArea(PVM pVM, RTGCPTR GCPtr);
+
+
+VMMDECL(RTHCPHYS) MMPage2Phys(PVM pVM, void *pvPage);
+VMMDECL(void *) MMPagePhys2Page(PVM pVM, RTHCPHYS HCPhysPage);
+VMMDECL(int) MMPagePhys2PageEx(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage);
+VMMDECL(int) MMPagePhys2PageTry(PVM pVM, RTHCPHYS HCPhysPage, void **ppvPage);
+
+
+/** @def MMHYPER_RC_ASSERT_RCPTR
+ * Asserts that an address is either NULL or inside the hypervisor memory area.
+ * This assertion only works while IN_RC, it's a NOP everywhere else.
+ * @thread The Emulation Thread.
+ */
+#ifdef IN_RC
+# define MMHYPER_RC_ASSERT_RCPTR(pVM, RCPtr) Assert(MMHyperIsInsideArea((pVM), (RTRCUINTPTR)(RCPtr)) || !(RCPtr))
+#else
+# define MMHYPER_RC_ASSERT_RCPTR(pVM, RCPtr) do { } while (0)
+#endif
+
+/** @} */
+
+
+#ifdef IN_RING3
+/** @defgroup grp_mm_r3 The MM Host Context Ring-3 API
+ * @ingroup grp_mm
+ * @{
+ */
+
+VMMR3DECL(int) MMR3InitUVM(PUVM pUVM);
+VMMR3DECL(int) MMR3Init(PVM pVM);
+VMMR3DECL(int) MMR3InitPaging(PVM pVM);
+VMMR3DECL(int) MMR3HyperInitFinalize(PVM pVM);
+VMMR3DECL(int) MMR3Term(PVM pVM);
+VMMR3DECL(void) MMR3TermUVM(PUVM pUVM);
+VMMR3DECL(int) MMR3ReserveHandyPages(PVM pVM, uint32_t cHandyPages);
+VMMR3DECL(int) MMR3IncreaseBaseReservation(PVM pVM, uint64_t cAddBasePages);
+VMMR3DECL(int) MMR3AdjustFixedReservation(PVM pVM, int32_t cDeltaFixedPages, const char *pszDesc);
+VMMR3DECL(int) MMR3UpdateShadowReservation(PVM pVM, uint32_t cShadowPages);
+
+VMMR3DECL(int) MMR3HCPhys2HCVirt(PVM pVM, RTHCPHYS HCPhys, void **ppv);
+
+/** @defgroup grp_mm_r3_hyper Hypervisor Memory Manager (HC R3 Portion)
+ * @ingroup grp_mm_r3
+ * @{ */
+VMMR3DECL(int) MMR3HyperAllocOnceNoRel(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv);
+VMMR3DECL(int) MMR3HyperAllocOnceNoRelEx(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, uint32_t fFlags, void **ppv);
+/** @name MMR3HyperAllocOnceNoRelEx flags
+ * @{ */
+/** Must have kernel mapping.
+ * If not specified, the R0 pointer may point to the user process mapping. */
+#define MMHYPER_AONR_FLAGS_KERNEL_MAPPING RT_BIT(0)
+/** @} */
+VMMR3DECL(int) MMR3HyperSetGuard(PVM pVM, void *pvStart, size_t cb, bool fSet);
+VMMR3DECL(int) MMR3HyperMapHCPhys(PVM pVM, void *pvR3, RTR0PTR pvR0, RTHCPHYS HCPhys, size_t cb, const char *pszDesc, PRTGCPTR pGCPtr);
+VMMR3DECL(int) MMR3HyperMapGCPhys(PVM pVM, RTGCPHYS GCPhys, size_t cb, const char *pszDesc, PRTGCPTR pGCPtr);
+VMMR3DECL(int) MMR3HyperMapMMIO2(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTRCPTR pRCPtr);
+VMMR3DECL(int) MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cPages, PCSUPPAGE paPages, const char *pszDesc, PRTGCPTR pGCPtr);
+VMMR3DECL(int) MMR3HyperReserve(PVM pVM, unsigned cb, const char *pszDesc, PRTGCPTR pGCPtr);
+VMMR3DECL(RTHCPHYS) MMR3HyperHCVirt2HCPhys(PVM pVM, void *pvHC);
+VMMR3DECL(int) MMR3HyperHCVirt2HCPhysEx(PVM pVM, void *pvHC, PRTHCPHYS pHCPhys);
+VMMR3DECL(void *) MMR3HyperHCPhys2HCVirt(PVM pVM, RTHCPHYS HCPhys);
+VMMR3DECL(int) MMR3HyperHCPhys2HCVirtEx(PVM pVM, RTHCPHYS HCPhys, void **ppv);
+VMMR3_INT_DECL(int) MMR3HyperQueryInfoFromHCPhys(PVM pVM, RTHCPHYS HCPhys, char *pszWhat, size_t cbWhat, uint32_t *pcbAlloc);
+VMMR3DECL(int) MMR3HyperReadGCVirt(PVM pVM, void *pvDst, RTGCPTR GCPtr, size_t cb);
+/** @} */
+
+
+/** @defgroup grp_mm_phys Guest Physical Memory Manager
+ * @todo retire this group, elimintating or moving MMR3PhysGetRamSize to PGMPhys.
+ * @ingroup grp_mm_r3
+ * @{ */
+VMMR3DECL(uint64_t) MMR3PhysGetRamSize(PVM pVM);
+/** @} */
+
+
+/** @defgroup grp_mm_page Physical Page Pool
+ * @ingroup grp_mm_r3
+ * @{ */
+VMMR3DECL(void *) MMR3PageAlloc(PVM pVM);
+VMMR3DECL(RTHCPHYS) MMR3PageAllocPhys(PVM pVM);
+VMMR3DECL(void) MMR3PageFree(PVM pVM, void *pvPage);
+VMMR3DECL(void *) MMR3PageAllocLow(PVM pVM);
+VMMR3DECL(void) MMR3PageFreeLow(PVM pVM, void *pvPage);
+VMMR3DECL(void) MMR3PageFreeByPhys(PVM pVM, RTHCPHYS HCPhysPage);
+VMMR3DECL(void *) MMR3PageDummyHCPtr(PVM pVM);
+VMMR3DECL(RTHCPHYS) MMR3PageDummyHCPhys(PVM pVM);
+/** @} */
+
+
+/** @defgroup grp_mm_heap Heap Manager
+ * @ingroup grp_mm_r3
+ * @{ */
+VMMR3DECL(void *) MMR3HeapAlloc(PVM pVM, MMTAG enmTag, size_t cbSize);
+VMMR3DECL(void *) MMR3HeapAllocU(PUVM pUVM, MMTAG enmTag, size_t cbSize);
+VMMR3DECL(int) MMR3HeapAllocEx(PVM pVM, MMTAG enmTag, size_t cbSize, void **ppv);
+VMMR3DECL(int) MMR3HeapAllocExU(PUVM pUVM, MMTAG enmTag, size_t cbSize, void **ppv);
+VMMR3DECL(void *) MMR3HeapAllocZ(PVM pVM, MMTAG enmTag, size_t cbSize);
+VMMR3DECL(void *) MMR3HeapAllocZU(PUVM pUVM, MMTAG enmTag, size_t cbSize);
+VMMR3DECL(int) MMR3HeapAllocZEx(PVM pVM, MMTAG enmTag, size_t cbSize, void **ppv);
+VMMR3DECL(int) MMR3HeapAllocZExU(PUVM pUVM, MMTAG enmTag, size_t cbSize, void **ppv);
+VMMR3DECL(void *) MMR3HeapRealloc(void *pv, size_t cbNewSize);
+VMMR3DECL(char *) MMR3HeapStrDup(PVM pVM, MMTAG enmTag, const char *psz);
+VMMR3DECL(char *) MMR3HeapStrDupU(PUVM pUVM, MMTAG enmTag, const char *psz);
+VMMR3DECL(char *) MMR3HeapAPrintf(PVM pVM, MMTAG enmTag, const char *pszFormat, ...);
+VMMR3DECL(char *) MMR3HeapAPrintfU(PUVM pUVM, MMTAG enmTag, const char *pszFormat, ...);
+VMMR3DECL(char *) MMR3HeapAPrintfV(PVM pVM, MMTAG enmTag, const char *pszFormat, va_list va);
+VMMR3DECL(char *) MMR3HeapAPrintfVU(PUVM pUVM, MMTAG enmTag, const char *pszFormat, va_list va);
+VMMR3DECL(void) MMR3HeapFree(void *pv);
+/** @} */
+
+/** @defgroup grp_mm_heap User-kernel Heap Manager.
+ * @ingroup grp_mm_r3
+ *
+ * The memory is safely accessible from kernel context as well as user land.
+ *
+ * @{ */
+VMMR3DECL(void *) MMR3UkHeapAlloc(PVM pVM, MMTAG enmTag, size_t cbSize, PRTR0PTR pR0Ptr);
+VMMR3DECL(int) MMR3UkHeapAllocEx(PVM pVM, MMTAG enmTag, size_t cbSize, void **ppv, PRTR0PTR pR0Ptr);
+VMMR3DECL(void *) MMR3UkHeapAllocZ(PVM pVM, MMTAG enmTag, size_t cbSize, PRTR0PTR pR0Ptr);
+VMMR3DECL(int) MMR3UkHeapAllocZEx(PVM pVM, MMTAG enmTag, size_t cbSize, void **ppv, PRTR0PTR pR0Ptr);
+VMMR3DECL(void) MMR3UkHeapFree(PVM pVM, void *pv, MMTAG enmTag);
+/** @} */
+
+/** @} */
+#endif /* IN_RING3 */
+
+
+
+#ifdef IN_RC
+/** @defgroup grp_mm_gc The MM Guest Context API
+ * @ingroup grp_mm
+ * @{
+ */
+
+VMMRCDECL(void) MMGCRamRegisterTrapHandler(PVM pVM);
+VMMRCDECL(void) MMGCRamDeregisterTrapHandler(PVM pVM);
+VMMRCDECL(int) MMGCRamReadNoTrapHandler(void *pDst, void *pSrc, size_t cb);
+/**
+ * @deprecated Don't use this as it doesn't check the page state.
+ */
+VMMRCDECL(int) MMGCRamWriteNoTrapHandler(void *pDst, void *pSrc, size_t cb);
+VMMRCDECL(int) MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb);
+VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb);
+
+/** @} */
+#endif /* IN_RC */
+
+/** @} */
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/VBox/vmm/patm.h b/include/VBox/vmm/patm.h
new file mode 100644
index 00000000..70b7fa55
--- /dev/null
+++ b/include/VBox/vmm/patm.h
@@ -0,0 +1,672 @@
+/** @file
+ * PATM - Dynamic Guest OS Patching Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_patm_h
+#define ___VBox_vmm_patm_h
+
+#include <VBox/types.h>
+#include <VBox/dis.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_patm The Patch Manager API
+ * @{
+ */
+#define MAX_PATCHES 512
+
+/**
+ * Flags for specifying the type of patch to install with PATMR3InstallPatch
+ * @{
+ */
+#define PATMFL_CODE32 RT_BIT_64(0)
+#define PATMFL_INTHANDLER RT_BIT_64(1)
+#define PATMFL_SYSENTER RT_BIT_64(2)
+#define PATMFL_GUEST_SPECIFIC RT_BIT_64(3)
+#define PATMFL_USER_MODE RT_BIT_64(4)
+#define PATMFL_IDTHANDLER RT_BIT_64(5)
+#define PATMFL_TRAPHANDLER RT_BIT_64(6)
+#define PATMFL_DUPLICATE_FUNCTION RT_BIT_64(7)
+#define PATMFL_REPLACE_FUNCTION_CALL RT_BIT_64(8)
+#define PATMFL_TRAPHANDLER_WITH_ERRORCODE RT_BIT_64(9)
+#define PATMFL_INTHANDLER_WITH_ERRORCODE (PATMFL_TRAPHANDLER_WITH_ERRORCODE)
+#define PATMFL_MMIO_ACCESS RT_BIT_64(10)
+/* no more room -> change PATMInternal.h if more is needed!! */
+
+/*
+ * Flags above 1024 are reserved for internal use!
+ */
+/** @} */
+
+/** Enable to activate sysenter emulation in GC. */
+/* #define PATM_EMULATE_SYSENTER */
+
+/**
+ * Maximum number of cached VGA writes
+ */
+#define MAX_VGA_WRITE_CACHE 64
+
+typedef struct PATMGCSTATE
+{
+ /* Virtual Flags register (IF + more later on) */
+ uint32_t uVMFlags;
+
+ /* Pending PATM actions (internal use only) */
+ uint32_t uPendingAction;
+
+ /* Records the number of times all patches are called (indicating how many exceptions we managed to avoid) */
+ uint32_t uPatchCalls;
+ /* Scratchpad dword */
+ uint32_t uScratch;
+ /* Debugging info */
+ uint32_t uIretEFlags, uIretCS, uIretEIP;
+
+ /* PATM stack pointer */
+ uint32_t Psp;
+
+ /* PATM interrupt flag */
+ uint32_t fPIF;
+ /* PATM inhibit irq address (used by sti) */
+ RTRCPTR GCPtrInhibitInterrupts;
+
+ /* Scratch room for call patch */
+ RTRCPTR GCCallPatchTargetAddr;
+ RTRCPTR GCCallReturnAddr;
+
+ /* Temporary storage for guest registers. */
+ struct
+ {
+ uint32_t uEAX;
+ uint32_t uECX;
+ uint32_t uEDI;
+ uint32_t eFlags;
+ uint32_t uFlags;
+ } Restore;
+} PATMGCSTATE, *PPATMGCSTATE;
+
+typedef struct PATMTRAPREC
+{
+ /* pointer to original guest code instruction (for emulation) */
+ RTRCPTR pNewEIP;
+ /* pointer to the next guest code instruction */
+ RTRCPTR pNextInstr;
+ /* pointer to the corresponding next instruction in the patch block */
+ RTRCPTR pNextPatchInstr;
+} PATMTRAPREC, *PPATMTRAPREC;
+
+
+/**
+ * Translation state (currently patch to GC ptr)
+ */
+typedef enum
+{
+ PATMTRANS_FAILED,
+ PATMTRANS_SAFE, /* Safe translation */
+ PATMTRANS_PATCHSTART, /* Instruction starts a patch block */
+ PATMTRANS_OVERWRITTEN, /* Instruction overwritten by patchjump */
+ PATMTRANS_INHIBITIRQ /* Instruction must be executed due to instruction fusing */
+} PATMTRANSSTATE;
+
+/**
+ * Load virtualized flags.
+ *
+ * This function is called from CPUMRawEnter(). It doesn't have to update the
+ * IF and IOPL eflags bits, the caller will enforce those to set and 0 respectively.
+ *
+ * @param pVM VM handle.
+ * @param pCtxCore The cpu context core.
+ * @see pg_raw
+ */
+VMMDECL(void) PATMRawEnter(PVM pVM, PCPUMCTXCORE pCtxCore);
+
+/**
+ * Restores virtualized flags.
+ *
+ * This function is called from CPUMRawLeave(). It will update the eflags register.
+ *
+ * @param pVM VM handle.
+ * @param pCtxCore The cpu context core.
+ * @param rawRC Raw mode return code
+ * @see @ref pg_raw
+ */
+VMMDECL(void) PATMRawLeave(PVM pVM, PCPUMCTXCORE pCtxCore, int rawRC);
+
+/**
+ * Get the EFLAGS.
+ * This is a worker for CPUMRawGetEFlags().
+ *
+ * @returns The eflags.
+ * @param pVM The VM handle.
+ * @param pCtxCore The context core.
+ */
+VMMDECL(uint32_t) PATMRawGetEFlags(PVM pVM, PCCPUMCTXCORE pCtxCore);
+
+/**
+ * Updates the EFLAGS.
+ * This is a worker for CPUMRawSetEFlags().
+ *
+ * @param pVM The VM handle.
+ * @param pCtxCore The context core.
+ * @param efl The new EFLAGS value.
+ */
+VMMDECL(void) PATMRawSetEFlags(PVM pVM, PCPUMCTXCORE pCtxCore, uint32_t efl);
+
+/**
+ * Returns the guest context pointer of the GC context structure
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ */
+VMMDECL(RCPTRTYPE(PPATMGCSTATE)) PATMQueryGCState(PVM pVM);
+
+/**
+ * Checks whether the GC address is part of our patch region
+ *
+ * @returns true -> yes, false -> no
+ * @param pVM The VM to operate on.
+ * @param pAddr Guest context address
+ */
+VMMDECL(bool) PATMIsPatchGCAddr(PVM pVM, RTRCUINTPTR pAddr);
+
+/**
+ * Check if we must use raw mode (patch code being executed or marked safe for IF=0)
+ *
+ * @param pVM VM handle.
+ * @param pAddrGC Guest context address
+ */
+VMMDECL(bool) PATMShouldUseRawMode(PVM pVM, RTRCPTR pAddrGC);
+
+/**
+ * Query PATM state (enabled/disabled)
+ *
+ * @returns 0 - disabled, 1 - enabled
+ * @param pVM The VM to operate on.
+ */
+#define PATMIsEnabled(pVM) (pVM->fPATMEnabled)
+
+/**
+ * Set parameters for pending MMIO patch operation
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance.
+ * @param GCPhys MMIO physical address
+ * @param pCachedData GC pointer to cached data
+ */
+VMMDECL(int) PATMSetMMIOPatchInfo(PVM pVM, RTGCPHYS GCPhys, RTRCPTR pCachedData);
+
+
+/**
+ * Adds branch pair to the lookup cache of the particular branch instruction
+ *
+ * @returns VBox status
+ * @param pVM The VM to operate on.
+ * @param pJumpTableGC Pointer to branch instruction lookup cache
+ * @param pBranchTarget Original branch target
+ * @param pRelBranchPatch Relative duplicated function address
+ */
+VMMDECL(int) PATMAddBranchToLookupCache(PVM pVM, RTRCPTR pJumpTableGC, RTRCPTR pBranchTarget, RTRCUINTPTR pRelBranchPatch);
+
+
+/**
+ * Checks if the int 3 was caused by a patched instruction
+ *
+ * @returns VBox status
+ *
+ * @param pVM The VM handle.
+ * @param pCtxCore The relevant core context.
+ */
+VMMRCDECL(int) PATMRCHandleInt3PatchTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
+
+/**
+ * Checks if the int 3 was caused by a patched instruction
+ *
+ * @returns VBox status
+ *
+ * @param pVM The VM handle.
+ * @param pInstrGC Instruction pointer
+ * @param pOpcode Original instruction opcode (out, optional)
+ * @param pSize Original instruction size (out, optional)
+ */
+VMMDECL(bool) PATMIsInt3Patch(PVM pVM, RTRCPTR pInstrGC, uint32_t *pOpcode, uint32_t *pSize);
+
+
+/**
+ * Checks if the interrupt flag is enabled or not.
+ *
+ * @returns true if it's enabled.
+ * @returns false if it's disabled.
+ *
+ * @param pVM The VM handle.
+ */
+VMMDECL(bool) PATMAreInterruptsEnabled(PVM pVM);
+
+/**
+ * Checks if the interrupt flag is enabled or not.
+ *
+ * @returns true if it's enabled.
+ * @returns false if it's disabled.
+ *
+ * @param pVM The VM handle.
+ * @param pCtxCore CPU context
+ */
+VMMDECL(bool) PATMAreInterruptsEnabledByCtxCore(PVM pVM, PCPUMCTXCORE pCtxCore);
+
+#ifdef PATM_EMULATE_SYSENTER
+/**
+ * Emulate sysenter, sysexit and syscall instructions
+ *
+ * @returns VBox status
+ *
+ * @param pVM The VM handle.
+ * @param pCtxCore The relevant core context.
+ * @param pCpu Disassembly context
+ */
+VMMDECL(int) PATMSysCall(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu);
+#endif
+
+#ifdef IN_RC
+/** @defgroup grp_patm_gc The Patch Manager API
+ * @ingroup grp_patm
+ * @{
+ */
+
+/**
+ * Checks if the write is located on a page with was patched before.
+ * (if so, then we are not allowed to turn on r/w)
+ *
+ * @returns VBox status
+ * @param pVM The VM to operate on.
+ * @param pRegFrame CPU context
+ * @param GCPtr GC pointer to write address
+ * @param cbWrite Nr of bytes to write
+ *
+ */
+VMMRCDECL(int) PATMGCHandleWriteToPatchPage(PVM pVM, PCPUMCTXCORE pRegFrame, RTRCPTR GCPtr, uint32_t cbWrite);
+
+/**
+ * Checks if the illegal instruction was caused by a patched instruction
+ *
+ * @returns VBox status
+ *
+ * @param pVM The VM handle.
+ * @param pCtxCore The relevant core context.
+ */
+VMMDECL(int) PATMRCHandleIllegalInstrTrap(PVM pVM, PCPUMCTXCORE pRegFrame);
+
+/** @} */
+
+#endif
+
+#ifdef IN_RING3
+/** @defgroup grp_patm_r3 The Patch Manager API
+ * @ingroup grp_patm
+ * @{
+ */
+
+/**
+ * Query PATM state (enabled/disabled)
+ *
+ * @returns 0 - disabled, 1 - enabled
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(int) PATMR3IsEnabled(PVM pVM);
+
+/**
+ * Initializes the PATM.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(int) PATMR3Init(PVM pVM);
+
+/**
+ * Finalizes HMA page attributes.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ */
+VMMR3DECL(int) PATMR3InitFinalize(PVM pVM);
+
+/**
+ * Applies relocations to data and code managed by this
+ * component. This function will be called at init and
+ * whenever the VMM need to relocate it self inside the GC.
+ *
+ * The PATM will update the addresses used by the switcher.
+ *
+ * @param pVM The VM.
+ */
+VMMR3DECL(void) PATMR3Relocate(PVM pVM);
+
+/**
+ * Terminates the PATM.
+ *
+ * Termination means cleaning up and freeing all resources,
+ * the VM it self is at this point powered off or suspended.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(int) PATMR3Term(PVM pVM);
+
+/**
+ * PATM reset callback.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM which is reset.
+ */
+VMMR3DECL(int) PATMR3Reset(PVM pVM);
+
+/**
+ * Returns the host context pointer and size of the patch memory block
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pcb Size of the patch memory block
+ */
+VMMR3DECL(void *) PATMR3QueryPatchMemHC(PVM pVM, uint32_t *pcb);
+
+/**
+ * Returns the guest context pointer and size of the patch memory block
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pcb Size of the patch memory block
+ */
+VMMR3DECL(RTRCPTR) PATMR3QueryPatchMemGC(PVM pVM, uint32_t *pcb);
+
+/**
+ * Checks whether the GC address is inside a generated patch jump
+ *
+ * @returns true -> yes, false -> no
+ * @param pVM The VM to operate on.
+ * @param pAddr Guest context address
+ * @param pPatchAddr Guest context patch address (if true)
+ */
+VMMR3DECL(bool) PATMR3IsInsidePatchJump(PVM pVM, RTRCPTR pAddr, PRTGCPTR32 pPatchAddr);
+
+
+/**
+ * Returns the GC pointer of the patch for the specified GC address
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pAddrGC Guest context address
+ */
+VMMR3DECL(RTRCPTR) PATMR3QueryPatchGCPtr(PVM pVM, RTRCPTR pAddrGC);
+
+/**
+ * Checks whether the HC address is part of our patch region
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pAddrGC Guest context address
+ */
+VMMR3DECL(bool) PATMR3IsPatchHCAddr(PVM pVM, R3PTRTYPE(uint8_t *) pAddrHC);
+
+/**
+ * Convert a GC patch block pointer to a HC patch pointer
+ *
+ * @returns HC pointer or NULL if it's not a GC patch pointer
+ * @param pVM The VM to operate on.
+ * @param pAddrGC GC pointer
+ */
+VMMR3DECL(R3PTRTYPE(void *)) PATMR3GCPtrToHCPtr(PVM pVM, RTRCPTR pAddrGC);
+
+
+/**
+ * Returns the host context pointer and size of the GC context structure
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(PPATMGCSTATE) PATMR3QueryGCStateHC(PVM pVM);
+
+/**
+ * Handle trap inside patch code
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pCtx CPU context
+ * @param pEip GC pointer of trapping instruction
+ * @param pNewEip GC pointer to new instruction
+ */
+VMMR3DECL(int) PATMR3HandleTrap(PVM pVM, PCPUMCTX pCtx, RTRCPTR pEip, RTGCPTR *ppNewEip);
+
+/**
+ * Handle page-fault in monitored page
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ */
+VMMR3DECL(int) PATMR3HandleMonitoredPage(PVM pVM);
+
+/**
+ * Notifies PATM about a (potential) write to code that has been patched.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param GCPtr GC pointer to write address
+ * @param cbWrite Nr of bytes to write
+ *
+ */
+VMMR3DECL(int) PATMR3PatchWrite(PVM pVM, RTRCPTR GCPtr, uint32_t cbWrite);
+
+/**
+ * Notify PATM of a page flush
+ *
+ * @returns VBox status code
+ * @param pVM The VM to operate on.
+ * @param addr GC address of the page to flush
+ */
+VMMR3DECL(int) PATMR3FlushPage(PVM pVM, RTRCPTR addr);
+
+/**
+ * Allows or disallow patching of privileged instructions executed by the guest OS
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param fAllowPatching Allow/disallow patching
+ */
+VMMR3DECL(int) PATMR3AllowPatching(PVM pVM, uint32_t fAllowPatching);
+
+/**
+ * Patch privileged instruction at specified location
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstr Guest context point to privileged instruction (0:32 flat address)
+ * @param flags Patch flags
+ *
+ * @note returns failure if patching is not allowed or possible
+ */
+VMMR3DECL(int) PATMR3InstallPatch(PVM pVM, RTRCPTR pInstrGC, uint64_t flags);
+
+/**
+ * Gives hint to PATM about supervisor guest instructions
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstr Guest context point to privileged instruction
+ * @param flags Patch flags
+ */
+VMMR3DECL(int) PATMR3AddHint(PVM pVM, RTRCPTR pInstrGC, uint32_t flags);
+
+/**
+ * Patch branch target function for call/jump at specified location.
+ * (in responds to a VINF_PATM_DUPLICATE_FUNCTION GC exit reason)
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pCtx Guest context
+ *
+ */
+VMMR3DECL(int) PATMR3DuplicateFunctionRequest(PVM pVM, PCPUMCTX pCtx);
+
+/**
+ * Query the corresponding GC instruction pointer from a pointer inside the patch block itself
+ *
+ * @returns original GC instruction pointer or 0 if not found
+ * @param pVM The VM to operate on.
+ * @param pPatchGC GC address in patch block
+ * @param pEnmState State of the translated address (out)
+ *
+ */
+VMMR3DECL(RTRCPTR) PATMR3PatchToGCPtr(PVM pVM, RTRCPTR pPatchGC, PATMTRANSSTATE *pEnmState);
+
+/**
+ * Converts Guest code GC ptr to Patch code GC ptr (if found)
+ *
+ * @returns corresponding GC pointer in patch block
+ * @param pVM The VM to operate on.
+ * @param pInstrGC Guest context pointer to privileged instruction
+ *
+ */
+VMMR3DECL(RTRCPTR) PATMR3GuestGCPtrToPatchGCPtr(PVM pVM, RCPTRTYPE(uint8_t*) pInstrGC);
+
+/**
+ * Query the opcode of the original code that was overwritten by the 5 bytes patch jump
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstrGC GC address of instr
+ * @param pByte opcode byte pointer (OUT)
+ * @returns VBOX error code
+ *
+ */
+VMMR3DECL(int) PATMR3QueryOpcode(PVM pVM, RTRCPTR pInstrGC, uint8_t *pByte);
+VMMR3DECL(int) PATMR3ReadOrgInstr(PVM pVM, RTGCPTR32 GCPtrInstr, uint8_t *pbDst, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Disable patch for privileged instruction at specified location
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstr Guest context point to privileged instruction
+ *
+ * @note returns failure if patching is not allowed or possible
+ *
+ */
+VMMR3DECL(int) PATMR3DisablePatch(PVM pVM, RTRCPTR pInstrGC);
+
+
+/**
+ * Enable patch for privileged instruction at specified location
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstr Guest context point to privileged instruction
+ *
+ * @note returns failure if patching is not allowed or possible
+ *
+ */
+VMMR3DECL(int) PATMR3EnablePatch(PVM pVM, RTRCPTR pInstrGC);
+
+
+/**
+ * Remove patch for privileged instruction at specified location
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on.
+ * @param pInstr Guest context point to privileged instruction
+ *
+ * @note returns failure if patching is not allowed or possible
+ *
+ */
+VMMR3DECL(int) PATMR3RemovePatch(PVM pVM, RTRCPTR pInstrGC);
+
+
+/**
+ * Detects it the specified address falls within a 5 byte jump generated for an active patch.
+ * If so, this patch is permanently disabled.
+ *
+ * @param pVM The VM to operate on.
+ * @param pInstrGC Guest context pointer to instruction
+ * @param pConflictGC Guest context pointer to check
+ */
+VMMR3DECL(int) PATMR3DetectConflict(PVM pVM, RTRCPTR pInstrGC, RTRCPTR pConflictGC);
+
+
+/**
+ * Checks if the instructions at the specified address has been patched already.
+ *
+ * @returns boolean, patched or not
+ * @param pVM The VM to operate on.
+ * @param pInstrGC Guest context pointer to instruction
+ */
+VMMR3DECL(bool) PATMR3HasBeenPatched(PVM pVM, RTRCPTR pInstrGC);
+
+
+/**
+ * Install Linux 2.6 spinlock patch
+ *
+ * @returns VBox status code.
+ * @param pVM The VM to operate on
+ * @param pCallAcquireSpinlockGC GC pointer of call instruction
+ * @param cbAcquireSpinlockCall Instruction size
+ *
+ */
+VMMR3DECL(int) PATMInstallSpinlockPatch(PVM pVM, RTRCPTR pCallAcquireSpinlockGC, uint32_t cbAcquireSpinlockCall);
+
+
+/**
+ * Check if supplied call target is the Linux 2.6 spinlock acquire function
+ *
+ * @returns boolean
+ * @param pVM The VM to operate on
+ * @param pCallAcquireSpinlockGC Call target GC address
+ *
+ */
+VMMR3DECL(bool) PATMIsSpinlockAcquire(PVM pVM, RTRCPTR pCallTargetGC);
+
+/**
+ * Check if supplied call target is the Linux 2.6 spinlock release function
+ *
+ * @returns boolean
+ * @param pVM The VM to operate on
+ * @param pCallTargetGC Call target GC address
+ *
+ */
+VMMR3DECL(bool) PATMIsSpinlockRelease(PVM pVM, RTRCPTR pCallTargetGC);
+
+/**
+ * Check if supplied call target is the Linux 2.6 spinlock release function (patched equivalent)
+ *
+ * @returns boolean
+ * @param pVM The VM to operate on
+ * @param pCallTargetGC Call target GC address
+ *
+ */
+VMMR3DECL(bool) PATMIsSpinlockReleasePatch(PVM pVM, RTRCPTR pCallTargetGC);
+
+/** @} */
+#endif
+
+
+/** @} */
+RT_C_DECLS_END
+
+
+#endif
diff --git a/include/VBox/vmm/pdm.h b/include/VBox/vmm/pdm.h
new file mode 100644
index 00000000..ff95ea82
--- /dev/null
+++ b/include/VBox/vmm/pdm.h
@@ -0,0 +1,40 @@
+/** @file
+ * PDM - Pluggable Device Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdm_h
+#define ___VBox_vmm_pdm_h
+
+#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/pdmqueue.h>
+#include <VBox/vmm/pdmcritsect.h>
+#include <VBox/vmm/pdmthread.h>
+#include <VBox/vmm/pdmifs.h>
+#include <VBox/vmm/pdmdrv.h>
+#include <VBox/vmm/pdmdev.h>
+#include <VBox/vmm/pdmusb.h>
+#include <VBox/vmm/pdmsrv.h>
+
+#endif
+
diff --git a/include/VBox/vmm/pdmapi.h b/include/VBox/vmm/pdmapi.h
new file mode 100644
index 00000000..1fb8aef6
--- /dev/null
+++ b/include/VBox/vmm/pdmapi.h
@@ -0,0 +1,210 @@
+/** @file
+ * PDM - Pluggable Device Manager, Core API.
+ *
+ * The 'Core API' has been put in a different header because everyone
+ * is currently including pdm.h. So, pdm.h is for including all of the
+ * PDM stuff, while pdmapi.h is for the core stuff.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmapi_h
+#define ___VBox_vmm_pdmapi_h
+
+#include <VBox/vmm/pdmcommon.h>
+#include <VBox/sup.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm The Pluggable Device Manager API
+ * @{
+ */
+
+VMMDECL(int) PDMGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Interrupt);
+VMMDECL(int) PDMIsaSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
+VMM_INT_DECL(int) PDMIoApicSetIrq(PVM pVM, uint8_t u8Irq, uint8_t u8Level, uint32_t uTagSrc);
+VMM_INT_DECL(int) PDMIoApicSendMsi(PVM pVM, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc);
+VMMDECL(bool) PDMHasIoApic(PVM pVM);
+VMMDECL(int) PDMApicHasPendingIrq(PVM pVM, bool *pfPending);
+VMMDECL(int) PDMApicSetBase(PVM pVM, uint64_t u64Base);
+VMMDECL(int) PDMApicGetBase(PVM pVM, uint64_t *pu64Base);
+VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR);
+VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending);
+VMMDECL(int) PDMApicWriteMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
+VMMDECL(int) PDMApicReadMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
+VMMDECL(int) PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys);
+VMMDECL(bool) PDMVMMDevHeapIsEnabled(PVM pVM);
+
+
+/** @defgroup grp_pdm_r3 The PDM Host Context Ring-3 API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+VMMR3DECL(int) PDMR3InitUVM(PUVM pUVM);
+VMMR3DECL(int) PDMR3LdrLoadVMMR0U(PUVM pUVM);
+VMMR3DECL(int) PDMR3Init(PVM pVM);
+VMMR3DECL(void) PDMR3PowerOn(PVM pVM);
+VMMR3DECL(void) PDMR3ResetCpu(PVMCPU pVCpu);
+VMMR3DECL(void) PDMR3Reset(PVM pVM);
+VMMR3DECL(void) PDMR3Suspend(PVM pVM);
+VMMR3DECL(void) PDMR3Resume(PVM pVM);
+VMMR3DECL(void) PDMR3PowerOff(PVM pVM);
+VMMR3DECL(void) PDMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3DECL(int) PDMR3Term(PVM pVM);
+VMMR3DECL(void) PDMR3TermUVM(PUVM pUVM);
+
+/**
+ * Module enumeration callback function.
+ *
+ * @returns VBox status.
+ * Failure will stop the search and return the return code.
+ * Warnings will be ignored and not returned.
+ * @param pVM VM Handle.
+ * @param pszFilename Module filename.
+ * @param pszName Module name. (short and unique)
+ * @param ImageBase Address where to executable image is loaded.
+ * @param cbImage Size of the executable image.
+ * @param fRC Set if raw-mode context, clear if host context.
+ * @param pvArg User argument.
+ */
+typedef DECLCALLBACK(int) FNPDMR3ENUM(PVM pVM, const char *pszFilename, const char *pszName,
+ RTUINTPTR ImageBase, size_t cbImage, bool fRC, void *pvArg);
+/** Pointer to a FNPDMR3ENUM() function. */
+typedef FNPDMR3ENUM *PFNPDMR3ENUM;
+VMMR3DECL(int) PDMR3LdrEnumModules(PVM pVM, PFNPDMR3ENUM pfnCallback, void *pvArg);
+VMMR3DECL(void) PDMR3LdrRelocateU(PUVM pUVM, RTGCINTPTR offDelta);
+VMMR3DECL(int) PDMR3LdrGetSymbolR3(PVM pVM, const char *pszModule, const char *pszSymbol, void **ppvValue);
+VMMR3DECL(int) PDMR3LdrGetSymbolR0(PVM pVM, const char *pszModule, const char *pszSymbol, PRTR0PTR ppvValue);
+VMMR3DECL(int) PDMR3LdrGetSymbolR0Lazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTR0PTR ppvValue);
+VMMR3DECL(int) PDMR3LdrLoadRC(PVM pVM, const char *pszFilename, const char *pszName);
+VMMR3DECL(int) PDMR3LdrGetSymbolRC(PVM pVM, const char *pszModule, const char *pszSymbol, PRTRCPTR pRCPtrValue);
+VMMR3DECL(int) PDMR3LdrGetSymbolRCLazy(PVM pVM, const char *pszModule, const char *pszSearchPath, const char *pszSymbol, PRTRCPTR pRCPtrValue);
+VMMR3DECL(int) PDMR3LdrQueryRCModFromPC(PVM pVM, RTRCPTR uPC,
+ char *pszModName, size_t cchModName, PRTRCPTR pMod,
+ char *pszNearSym1, size_t cchNearSym1, PRTRCPTR pNearSym1,
+ char *pszNearSym2, size_t cchNearSym2, PRTRCPTR pNearSym2);
+VMMR3DECL(int) PDMR3LdrQueryR0ModFromPC(PVM pVM, RTR0PTR uPC,
+ char *pszModName, size_t cchModName, PRTR0PTR pMod,
+ char *pszNearSym1, size_t cchNearSym1, PRTR0PTR pNearSym1,
+ char *pszNearSym2, size_t cchNearSym2, PRTR0PTR pNearSym2);
+VMMR3DECL(int) PDMR3LdrGetInterfaceSymbols(PVM pVM,
+ void *pvInterface, size_t cbInterface,
+ const char *pszModule, const char *pszSearchPath,
+ const char *pszSymPrefix, const char *pszSymList,
+ bool fRing0OrRC);
+
+VMMR3DECL(int) PDMR3QueryDevice(PVM pVM, const char *pszDevice, unsigned iInstance, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3QueryDeviceLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3QueryLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3QueryDriverOnLun(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, const char *pszDriver,
+ PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3DeviceAttach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags, PPDMIBASE *ppBase);
+VMMR3DECL(int) PDMR3DeviceDetach(PVM pVM, const char *pszDevice, unsigned iInstance, unsigned iLun, uint32_t fFlags);
+VMMR3_INT_DECL(PPDMCRITSECT) PDMR3DevGetCritSect(PVM pVM, PPDMDEVINS pDevIns);
+VMMR3DECL(int) PDMR3DriverAttach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun, uint32_t fFlags, PPPDMIBASE ppBase);
+VMMR3DECL(int) PDMR3DriverDetach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
+ const char *pszDriver, unsigned iOccurance, uint32_t fFlags);
+VMMR3DECL(int) PDMR3DriverReattach(PVM pVM, const char *pszDevice, unsigned iDevIns, unsigned iLun,
+ const char *pszDriver, unsigned iOccurance, uint32_t fFlags, PCFGMNODE pCfg, PPPDMIBASE ppBase);
+VMMR3DECL(void) PDMR3DmaRun(PVM pVM);
+VMMR3DECL(int) PDMR3LockCall(PVM pVM);
+VMMR3DECL(int) PDMR3RegisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize);
+VMMR3DECL(int) PDMR3VMMDevHeapAlloc(PVM pVM, unsigned cbSize, RTR3PTR *ppv);
+VMMR3DECL(int) PDMR3VMMDevHeapFree(PVM pVM, RTR3PTR pv);
+VMMR3DECL(int) PDMR3UnregisterVMMDevHeap(PVM pVM, RTGCPHYS GCPhys);
+VMMR3_INT_DECL(int) PDMR3TracingConfig(PVM pVM, const char *pszName, size_t cchName, bool fEnable, bool fApply);
+VMMR3_INT_DECL(bool) PDMR3TracingAreAll(PVM pVM, bool fEnabled);
+VMMR3_INT_DECL(int) PDMR3TracingQueryConfig(PVM pVM, char *pszConfig, size_t cbConfig);
+/** @} */
+
+
+
+/** @defgroup grp_pdm_rc The PDM Raw-Mode Context API
+ * @ingroup grp_pdm
+ * @{
+ */
+/** @} */
+
+
+
+/** @defgroup grp_pdm_r0 The PDM Ring-0 Context API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/**
+ * Request buffer for PDMR0DriverCallReqHandler / VMMR0_DO_PDM_DRIVER_CALL_REQ_HANDLER.
+ * @see PDMR0DriverCallReqHandler.
+ */
+typedef struct PDMDRIVERCALLREQHANDLERREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The driver instance. */
+ PPDMDRVINSR0 pDrvInsR0;
+ /** The operation. */
+ uint32_t uOperation;
+ /** Explicit alignment padding. */
+ uint32_t u32Alignment;
+ /** Optional 64-bit integer argument. */
+ uint64_t u64Arg;
+} PDMDRIVERCALLREQHANDLERREQ;
+/** Pointer to a PDMR0DriverCallReqHandler / VMMR0_DO_PDM_DRIVER_CALL_REQ_HANDLER
+ * request buffer. */
+typedef PDMDRIVERCALLREQHANDLERREQ *PPDMDRIVERCALLREQHANDLERREQ;
+
+VMMR0_INT_DECL(int) PDMR0DriverCallReqHandler(PVM pVM, PPDMDRIVERCALLREQHANDLERREQ pReq);
+
+/**
+ * Request buffer for PDMR0DeviceCallReqHandler / VMMR0_DO_PDM_DEVICE_CALL_REQ_HANDLER.
+ * @see PDMR0DeviceCallReqHandler.
+ */
+typedef struct PDMDEVICECALLREQHANDLERREQ
+{
+ /** The header. */
+ SUPVMMR0REQHDR Hdr;
+ /** The device instance. */
+ PPDMDEVINSR0 pDevInsR0;
+ /** The request handler for the device. */
+ PFNPDMDEVREQHANDLERR0 pfnReqHandlerR0;
+ /** The operation. */
+ uint32_t uOperation;
+ /** Explicit alignment padding. */
+ uint32_t u32Alignment;
+ /** Optional 64-bit integer argument. */
+ uint64_t u64Arg;
+} PDMDEVICECALLREQHANDLERREQ;
+/** Pointer to a PDMR0DeviceCallReqHandler /
+ * VMMR0_DO_PDM_DEVICE_CALL_REQ_HANDLER request buffer. */
+typedef PDMDEVICECALLREQHANDLERREQ *PPDMDEVICECALLREQHANDLERREQ;
+
+VMMR0_INT_DECL(int) PDMR0DeviceCallReqHandler(PVM pVM, PPDMDEVICECALLREQHANDLERREQ pReq);
+
+/** @} */
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/VBox/vmm/pdmasynccompletion.h b/include/VBox/vmm/pdmasynccompletion.h
new file mode 100644
index 00000000..1d1af265
--- /dev/null
+++ b/include/VBox/vmm/pdmasynccompletion.h
@@ -0,0 +1,368 @@
+/** @file
+ * PDM - Pluggable Device Manager, Async I/O Completion.
+ */
+
+/*
+ * Copyright (C) 2007-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmasynccompletion_h
+#define ___VBox_vmm_pdmasynccompletion_h
+
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <iprt/assert.h>
+#include <iprt/sg.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_async_completion The PDM Async I/O Completion API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/** Pointer to a PDM async completion template handle. */
+typedef struct PDMASYNCCOMPLETIONTEMPLATE *PPDMASYNCCOMPLETIONTEMPLATE;
+/** Pointer to a PDM async completion template handle pointer. */
+typedef PPDMASYNCCOMPLETIONTEMPLATE *PPPDMASYNCCOMPLETIONTEMPLATE;
+
+/** Pointer to a PDM async completion task handle. */
+typedef struct PDMASYNCCOMPLETIONTASK *PPDMASYNCCOMPLETIONTASK;
+/** Pointer to a PDM async completion task handle pointer. */
+typedef PPDMASYNCCOMPLETIONTASK *PPPDMASYNCCOMPLETIONTASK;
+
+/** Pointer to a PDM async completion endpoint handle. */
+typedef struct PDMASYNCCOMPLETIONENDPOINT *PPDMASYNCCOMPLETIONENDPOINT;
+/** Pointer to a PDM async completion endpoint handle pointer. */
+typedef PPDMASYNCCOMPLETIONENDPOINT *PPPDMASYNCCOMPLETIONENDPOINT;
+
+
+/**
+ * Completion callback for devices.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDEV(PPDMDEVINS pDevIns, void *pvUser, int rc);
+/** Pointer to a FNPDMASYNCCOMPLETEDEV(). */
+typedef FNPDMASYNCCOMPLETEDEV *PFNPDMASYNCCOMPLETEDEV;
+
+
+/**
+ * Completion callback for drivers.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pvTemplateUser User argument given when creating the template.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEDRV(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser, int rc);
+/** Pointer to a FNPDMASYNCCOMPLETEDRV(). */
+typedef FNPDMASYNCCOMPLETEDRV *PFNPDMASYNCCOMPLETEDRV;
+
+
+/**
+ * Completion callback for USB devices.
+ *
+ * @param pUsbIns The USB device instance.
+ * @param pvUser User argument.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEUSB(PPDMUSBINS pUsbIns, void *pvUser, int rc);
+/** Pointer to a FNPDMASYNCCOMPLETEUSB(). */
+typedef FNPDMASYNCCOMPLETEUSB *PFNPDMASYNCCOMPLETEUSB;
+
+
+/**
+ * Completion callback for internal.
+ *
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvUser User argument for the task.
+ * @param pvUser2 User argument for the template.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMASYNCCOMPLETEINT(PVM pVM, void *pvUser, void *pvUser2, int rc);
+/** Pointer to a FNPDMASYNCCOMPLETEINT(). */
+typedef FNPDMASYNCCOMPLETEINT *PFNPDMASYNCCOMPLETEINT;
+
+
+/**
+ * Creates an async completion template for a device instance.
+ *
+ * The template is used when creating new completion tasks.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDevIns The device instance.
+ * @param ppTemplate Where to store the template pointer on success.
+ * @param pfnCompleted The completion callback routine.
+ * @param pszDesc Description.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDEV pfnCompleted, const char *pszDesc);
+
+/**
+ * Creates an async completion template for a driver instance.
+ *
+ * The template is used when creating new completion tasks.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDrvIns The driver instance.
+ * @param ppTemplate Where to store the template pointer on success.
+ * @param pfnCompleted The completion callback routine.
+ * @param pvTemplateUser Template user argument.
+ * @param pszDesc Description.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc);
+
+/**
+ * Creates an async completion template for a USB device instance.
+ *
+ * The template is used when creating new completion tasks.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pUsbIns The USB device instance.
+ * @param ppTemplate Where to store the template pointer on success.
+ * @param pfnCompleted The completion callback routine.
+ * @param pszDesc Description.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEUSB pfnCompleted, const char *pszDesc);
+
+/**
+ * Creates an async completion template for internally by the VMM.
+ *
+ * The template is used when creating new completion tasks.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param ppTemplate Where to store the template pointer on success.
+ * @param pfnCompleted The completion callback routine.
+ * @param pvUser2 The 2nd user argument for the callback.
+ * @param pszDesc Description.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateCreateInternal(PVM pVM, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate, PFNPDMASYNCCOMPLETEINT pfnCompleted, void *pvUser2, const char *pszDesc);
+
+/**
+ * Destroys the specified async completion template.
+ *
+ * @returns VBox status codes:
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if the template is still in use.
+ *
+ * @param pTemplate The template in question.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroy(PPDMASYNCCOMPLETIONTEMPLATE pTemplate);
+
+/**
+ * Destroys all the specified async completion templates for the given device instance.
+ *
+ * @returns VBox status codes:
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
+ *
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDevIns The device instance.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
+
+/**
+ * Destroys all the specified async completion templates for the given driver instance.
+ *
+ * @returns VBox status codes:
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
+ *
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDrvIns The driver instance.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
+
+/**
+ * Destroys all the specified async completion templates for the given USB device instance.
+ *
+ * @returns VBox status codes:
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_PDM_ASYNC_TEMPLATE_BUSY if one or more of the templates are still in use.
+ *
+ * @param pVM Pointer to the shared VM structure.
+ * @param pUsbIns The USB device instance.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTemplateDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
+
+
+/**
+ * Opens a file as an async completion endpoint.
+ *
+ * @returns VBox status code.
+ * @param ppEndpoint Where to store the opaque endpoint handle on success.
+ * @param pszFilename Path to the file which is to be opened. (UTF-8)
+ * @param fFlags Open flags, see grp_pdmacep_file_flags.
+ * @param pTemplate Handle to the completion callback template to use
+ * for this end point.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionEpCreateForFile(PPPDMASYNCCOMPLETIONENDPOINT ppEndpoint,
+ const char *pszFilename, uint32_t fFlags,
+ PPDMASYNCCOMPLETIONTEMPLATE pTemplate);
+
+/** @defgroup grp_pdmacep_file_flags Flags for PDMR3AsyncCompletionEpCreateForFile
+ * @{ */
+/** Open the file in read-only mode. */
+#define PDMACEP_FILE_FLAGS_READ_ONLY RT_BIT_32(0)
+/** Whether the file should not be write protected.
+ * The default is to protect the file against writes by other processes
+ * when opened in read/write mode to prevent data corruption by
+ * concurrent access which can occur if the local writeback cache is enabled.
+ */
+#define PDMACEP_FILE_FLAGS_DONT_LOCK RT_BIT_32(2)
+/** Open the endpoint with the host cache enabled. */
+#define PDMACEP_FILE_FLAGS_HOST_CACHE_ENABLED RT_BIT_32(3)
+/** @} */
+
+/**
+ * Closes a endpoint waiting for any pending tasks to finish.
+ *
+ * @returns nothing.
+ * @param pEndpoint Handle of the endpoint.
+ */
+VMMR3DECL(void) PDMR3AsyncCompletionEpClose(PPDMASYNCCOMPLETIONENDPOINT pEndpoint);
+
+/**
+ * Creates a read task on the given endpoint.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The file endpoint to read from.
+ * @param off Where to start reading from.
+ * @param paSegments Scatter gather list to store the data in.
+ * @param cSegments Number of segments in the list.
+ * @param cbRead The overall number of bytes to read.
+ * @param pvUser Opaque user data returned in the completion callback
+ * upon completion of the task.
+ * @param ppTask Where to store the task handle on success.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionEpRead(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
+ PCRTSGSEG paSegments, unsigned cSegments,
+ size_t cbRead, void *pvUser,
+ PPPDMASYNCCOMPLETIONTASK ppTask);
+
+/**
+ * Creates a write task on the given endpoint.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The file endpoint to write to.
+ * @param off Where to start writing at.
+ * @param paSegments Scatter gather list of the data to write.
+ * @param cSegments Number of segments in the list.
+ * @param cbWrite The overall number of bytes to write.
+ * @param pvUser Opaque user data returned in the completion callback
+ * upon completion of the task.
+ * @param ppTask Where to store the task handle on success.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionEpWrite(PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
+ PCRTSGSEG paSegments, unsigned cSegments,
+ size_t cbWrite, void *pvUser,
+ PPPDMASYNCCOMPLETIONTASK ppTask);
+
+/**
+ * Creates a flush task on the given endpoint.
+ *
+ * Every read and write task initiated before the flush task is
+ * finished upon completion of this task.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The file endpoint to flush.
+ * @param pvUser Opaque user data returned in the completion callback
+ * upon completion of the task.
+ * @param ppTask Where to store the task handle on success.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionEpFlush(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
+ void *pvUser,
+ PPPDMASYNCCOMPLETIONTASK ppTask);
+
+/**
+ * Queries the size of an endpoint.
+ * Not that some endpoints may not support this and will return an error
+ * (sockets for example).
+ *
+ * @returns VBox status code.
+ * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation.
+ * @param pEndpoint The file endpoint.
+ * @param pcbSize Where to store the size of the endpoint.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionEpGetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
+ uint64_t *pcbSize);
+
+/**
+ * Sets the size of an endpoint.
+ * Not that some endpoints may not support this and will return an error
+ * (sockets for example).
+ *
+ * @returns VBox status code.
+ * @retval VERR_NOT_SUPPORTED if the endpoint does not support this operation.
+ * @param pEndpoint The file endpoint.
+ * @param cbSize The size to set.
+ *
+ * @note PDMR3AsyncCompletionEpFlush should be called before this operation is executed.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionEpSetSize(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
+ uint64_t cbSize);
+
+/**
+ * Assigns or removes a bandwidth control manager to/from the endpoint.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The endpoint.
+ * @param pcszBwMgr The identifer of the new bandwidth manager to assign
+ * or NULL to remove the current one.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionEpSetBwMgr(PPDMASYNCCOMPLETIONENDPOINT pEndpoint,
+ const char *pcszBwMgr);
+
+/**
+ * Cancels an async completion task.
+ *
+ * If you want to use this method, you have to take great create to make sure
+ * you will never attempt cancel a task which has been completed. Since there is
+ * no reference counting or anything on the task it self, you have to serialize
+ * the cancelation and completion paths such that the aren't racing one another.
+ *
+ * @returns VBox status code
+ * @param pTask The Task to cancel.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionTaskCancel(PPDMASYNCCOMPLETIONTASK pTask);
+
+/**
+ * Changes the limit of a bandwidth manager for file endpoints to the given value.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pcszBwMgr The identifer of the bandwidth manager to change.
+ * @param cbMaxNew The new maximum for the bandwidth manager in bytes/sec.
+ */
+VMMR3DECL(int) PDMR3AsyncCompletionBwMgrSetMaxForFile(PVM pVM, const char *pcszBwMgr, uint32_t cbMaxNew);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmasynctask.h b/include/VBox/vmm/pdmasynctask.h
new file mode 100644
index 00000000..65fdd245
--- /dev/null
+++ b/include/VBox/vmm/pdmasynctask.h
@@ -0,0 +1,61 @@
+/** @file
+ * PDM - Pluggable Device Manager, Async Task.
+ */
+
+/*
+ * Copyright (C) 2007-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmasynctask_h
+#define ___VBox_vmm_pdmasynctask_h
+
+#include <VBox/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_async_task The PDM Async Task API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/** Pointer to a PDM async task template handle. */
+typedef struct PDMASYNCTASKTEMPLATE *PPDMASYNCTASKTEMPLATE;
+/** Pointer to a PDM async task template handle pointer. */
+typedef PPDMASYNCTASKTEMPLATE *PPPDMASYNCTASKTEMPLATE;
+
+/** Pointer to a PDM async task handle. */
+typedef struct PDMASYNCTASK *PPDMASYNCTASK;
+/** Pointer to a PDM async task handle pointer. */
+typedef PPDMASYNCTASK *PPPDMASYNCTASK;
+
+/* This should be similar to VMReq, only difference there will be a pool
+ of worker threads instead of EMT. The actual implementation should be
+ made in IPRT so we can reuse it for other stuff later. The reason why
+ it should be put in PDM is because we need to manage it wrt to VM
+ state changes (need exception - add a flag for this). */
+
+/** @} */
+
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmblkcache.h b/include/VBox/vmm/pdmblkcache.h
new file mode 100644
index 00000000..fc92bc4f
--- /dev/null
+++ b/include/VBox/vmm/pdmblkcache.h
@@ -0,0 +1,422 @@
+/** @file
+ * PDM - Pluggable Device Manager, Block cache.
+ */
+
+/*
+ * Copyright (C) 2007-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmblkcache_h
+#define ___VBox_vmm_pdmblkcache_h
+
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <iprt/assert.h>
+#include <iprt/sg.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_blk_cache The PDM Block Cache API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/** Pointer to a PDM block cache. */
+typedef struct PDMBLKCACHE *PPDMBLKCACHE;
+/** Pointer to a PDM block cache pointer. */
+typedef PPDMBLKCACHE *PPPDMBLKCACHE;
+
+/** I/O transfer handle. */
+typedef struct PDMBLKCACHEIOXFER *PPDMBLKCACHEIOXFER;
+
+/**
+ * Block cache I/O request transfer direction.
+ */
+typedef enum PDMBLKCACHEXFERDIR
+{
+ /** Read */
+ PDMBLKCACHEXFERDIR_READ = 0,
+ /** Write */
+ PDMBLKCACHEXFERDIR_WRITE,
+ /** Flush */
+ PDMBLKCACHEXFERDIR_FLUSH,
+ /** Discard */
+ PDMBLKCACHEXFERDIR_DISCARD
+} PDMBLKCACHEXFERDIR;
+
+/**
+ * Completion callback for drivers.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMBLKCACHEXFERCOMPLETEDRV(PPDMDRVINS pDrvIns, void *pvUser, int rc);
+/** Pointer to a FNPDMBLKCACHEXFERCOMPLETEDRV(). */
+typedef FNPDMBLKCACHEXFERCOMPLETEDRV *PFNPDMBLKCACHEXFERCOMPLETEDRV;
+
+/**
+ * I/O enqueue callback for drivers.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEDRV(PPDMDRVINS pDrvIns,
+ PDMBLKCACHEXFERDIR enmXferDir,
+ uint64_t off, size_t cbXfer,
+ PCRTSGBUF pcSgBuf, PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEDRV(). */
+typedef FNPDMBLKCACHEXFERENQUEUEDRV *PFNPDMBLKCACHEXFERENQUEUEDRV;
+
+/**
+ * Discard enqueue callback for drivers.
+ *
+ * @param pDrvIns The driver instance.
+ * @param paRanges Ranges to discard.
+ * @param cRanges Number of range entries.
+ * @param hIoXfer I/O handle to return on completion.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEDISCARDDRV(PPDMDRVINS pDrvIns,
+ PCRTRANGE paRanges, unsigned cRanges,
+ PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEDISCARDDRV(). */
+typedef FNPDMBLKCACHEXFERENQUEUEDISCARDDRV *PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV;
+
+/**
+ * Completion callback for devices.
+ *
+ * @param pDrvIns The device instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMBLKCACHEXFERCOMPLETEDEV(PPDMDEVINS pDevIns, void *pvUser, int rc);
+/** Pointer to a FNPDMBLKCACHEXFERCOMPLETEDEV(). */
+typedef FNPDMBLKCACHEXFERCOMPLETEDEV *PFNPDMBLKCACHEXFERCOMPLETEDEV;
+
+/**
+ * I/O enqueue callback for devices.
+ *
+ * @param pDevIns The device instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEDEV(PPDMDEVINS pDevIns,
+ PDMBLKCACHEXFERDIR enmXferDir,
+ uint64_t off, size_t cbXfer,
+ PCRTSGBUF pcSgBuf, PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEDEV(). */
+typedef FNPDMBLKCACHEXFERENQUEUEDEV *PFNPDMBLKCACHEXFERENQUEUEDEV;
+
+/**
+ * Discard enqueue callback for devices.
+ *
+ * @param pDrvIns The driver instance.
+ * @param paRanges Ranges to discard.
+ * @param cRanges Number of range entries.
+ * @param hIoXfer I/O handle to return on completion.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEDISCARDDEV(PPDMDEVINS pDevIns,
+ PCRTRANGE paRanges, unsigned cRanges,
+ PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEDISCARDDEV(). */
+typedef FNPDMBLKCACHEXFERENQUEUEDISCARDDEV *PFNPDMBLKCACHEXFERENQUEUEDISCARDDEV;
+
+/**
+ * Completion callback for drivers.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMBLKCACHEXFERCOMPLETEINT(void *pvUserInt, void *pvUser, int rc);
+/** Pointer to a FNPDMBLKCACHEXFERCOMPLETEINT(). */
+typedef FNPDMBLKCACHEXFERCOMPLETEINT *PFNPDMBLKCACHEXFERCOMPLETEINT;
+
+/**
+ * I/O enqueue callback for drivers.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEINT(void *pvUser,
+ PDMBLKCACHEXFERDIR enmXferDir,
+ uint64_t off, size_t cbXfer,
+ PCRTSGBUF pcSgBuf, PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEINT(). */
+typedef FNPDMBLKCACHEXFERENQUEUEINT *PFNPDMBLKCACHEXFERENQUEUEINT;
+
+/**
+ * Discard enqueue callback for VMM internal users.
+ *
+ * @param pDrvIns The driver instance.
+ * @param paRanges Ranges to discard.
+ * @param cRanges Number of range entries.
+ * @param hIoXfer I/O handle to return on completion.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEDISCARDINT(void *pvUser,
+ PCRTRANGE paRanges, unsigned cRanges,
+ PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEDISCARDINT(). */
+typedef FNPDMBLKCACHEXFERENQUEUEDISCARDINT *PFNPDMBLKCACHEXFERENQUEUEDISCARDINT;
+
+/**
+ * Completion callback for USB.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(void) FNPDMBLKCACHEXFERCOMPLETEUSB(PPDMUSBINS pUsbIns, void *pvUser, int rc);
+/** Pointer to a FNPDMBLKCACHEXFERCOMPLETEUSB(). */
+typedef FNPDMBLKCACHEXFERCOMPLETEUSB *PFNPDMBLKCACHEXFERCOMPLETEUSB;
+
+/**
+ * I/O enqueue callback for drivers.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pvUser User argument given during request initiation.
+ * @param rc The status code of the completed request.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEUSB(PPDMUSBINS pUsbIns,
+ PDMBLKCACHEXFERDIR enmXferDir,
+ uint64_t off, size_t cbXfer,
+ PCRTSGBUF pcSgBuf, PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEUSB(). */
+typedef FNPDMBLKCACHEXFERENQUEUEUSB *PFNPDMBLKCACHEXFERENQUEUEUSB;
+
+/**
+ * Discard enqueue callback for USB devices.
+ *
+ * @param pUsbIns The USB device instance.
+ * @param paRanges Ranges to discard.
+ * @param cRanges Number of range entries.
+ * @param hIoXfer I/O handle to return on completion.
+ */
+typedef DECLCALLBACK(int) FNPDMBLKCACHEXFERENQUEUEDISCARDUSB(PPDMUSBINS pUsbIns,
+ PCRTRANGE paRanges, unsigned cRanges,
+ PPDMBLKCACHEIOXFER hIoXfer);
+/** Pointer to a FNPDMBLKCACHEXFERENQUEUEDISCARDUSB(). */
+typedef FNPDMBLKCACHEXFERENQUEUEDISCARDUSB *PFNPDMBLKCACHEXFERENQUEUEDISCARDUSB;
+
+/**
+ * Create a block cache user for a driver instance.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDrvIns The driver instance.
+ * @param ppBlkCache Where to store the handle to the block cache.
+ * @param pfnXferComplete The I/O transfer complete callback.
+ * @param pfnXferEnqueue The I/O request enqueue callback.
+ * @param pfnXferEnqueueDiscard The discard request enqueue callback.
+ * @param pcszId Unique ID used to identify the user.
+ */
+VMMR3DECL(int) PDMR3BlkCacheRetainDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMBLKCACHE ppBlkCache,
+ PFNPDMBLKCACHEXFERCOMPLETEDRV pfnXferComplete,
+ PFNPDMBLKCACHEXFERENQUEUEDRV pfnXferEnqueue,
+ PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV pfnXferEnqueueDiscard,
+ const char *pcszId);
+
+/**
+ * Create a block cache user for a device instance.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDevIns The device instance.
+ * @param ppBlkCache Where to store the handle to the block cache.
+ * @param pfnXferComplete The I/O transfer complete callback.
+ * @param pfnXferEnqueue The I/O request enqueue callback.
+ * @param pfnXferEnqueueDiscard The discard request enqueue callback.
+ * @param pcszId Unique ID used to identify the user.
+ */
+VMMR3DECL(int) PDMR3BlkCacheRetainDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMBLKCACHE ppBlkCache,
+ PFNPDMBLKCACHEXFERCOMPLETEDEV pfnXferComplete,
+ PFNPDMBLKCACHEXFERENQUEUEDEV pfnXferEnqueue,
+ PFNPDMBLKCACHEXFERENQUEUEDISCARDDEV pfnXferEnqueueDiscard,
+ const char *pcszId);
+
+/**
+ * Create a block cache user for a USB instance.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pUsbIns The USB device instance.
+ * @param ppBlkCache Where to store the handle to the block cache.
+ * @param pfnXferComplete The I/O transfer complete callback.
+ * @param pfnXferEnqueue The I/O request enqueue callback.
+ * @param pfnXferEnqueueDiscard The discard request enqueue callback.
+ * @param pcszId Unique ID used to identify the user.
+ */
+VMMR3DECL(int) PDMR3BlkCacheRetainUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMBLKCACHE ppBlkCache,
+ PFNPDMBLKCACHEXFERCOMPLETEUSB pfnXferComplete,
+ PFNPDMBLKCACHEXFERENQUEUEUSB pfnXferEnqueue,
+ PFNPDMBLKCACHEXFERENQUEUEDISCARDUSB pfnXferEnqueueDiscard,
+ const char *pcszId);
+
+/**
+ * Create a block cache user for internal use by VMM.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvUser Opaque user data.
+ * @param ppBlkCache Where to store the handle to the block cache.
+ * @param pfnXferComplete The I/O transfer complete callback.
+ * @param pfnXferEnqueue The I/O request enqueue callback.
+ * @param pfnXferEnqueueDiscard The discard request enqueue callback.
+ * @param pcszId Unique ID used to identify the user.
+ */
+VMMR3DECL(int) PDMR3BlkCacheRetainInt(PVM pVM, void *pvUser, PPPDMBLKCACHE ppBlkCache,
+ PFNPDMBLKCACHEXFERCOMPLETEINT pfnXferComplete,
+ PFNPDMBLKCACHEXFERENQUEUEINT pfnXferEnqueue,
+ PFNPDMBLKCACHEXFERENQUEUEDISCARDINT pfnXferEnqueueDiscard,
+ const char *pcszId);
+
+/**
+ * Releases a block cache handle.
+ *
+ * @returns nothing.
+ * @param pBlkCache Block cache handle.
+ */
+VMMR3DECL(void) PDMR3BlkCacheRelease(PPDMBLKCACHE pBlkCache);
+
+/**
+ * Releases all block cache handles for a device instance.
+ *
+ * @returns nothing.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDevIns The device instance.
+ */
+VMMR3DECL(void) PDMR3BlkCacheReleaseDevice(PVM pVM, PPDMDEVINS pDevIns);
+
+/**
+ * Releases all block cache handles for a driver instance.
+ *
+ * @returns nothing.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pDrvIns The driver instance.
+ */
+VMMR3DECL(void) PDMR3BlkCacheReleaseDriver(PVM pVM, PPDMDRVINS pDrvIns);
+
+/**
+ * Releases all block cache handles for a USB device instance.
+ *
+ * @returns nothing.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pUsbIns The USB device instance.
+ */
+VMMR3DECL(void) PDMR3BlkCacheReleaseUsb(PVM pVM, PPDMUSBINS pUsbIns);
+
+/**
+ * Creates a read task on the given endpoint.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The file endpoint to read from.
+ * @param off Where to start reading from.
+ * @param paSegments Scatter gather list to store the data in.
+ * @param cSegments Number of segments in the list.
+ * @param cbRead The overall number of bytes to read.
+ * @param pvUser Opaque user data returned in the completion callback
+ * upon completion of the read.
+ */
+VMMR3DECL(int) PDMR3BlkCacheRead(PPDMBLKCACHE pBlkCache, uint64_t off,
+ PCRTSGBUF pcSgBuf, size_t cbRead, void *pvUser);
+
+/**
+ * Creates a write task on the given endpoint.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The file endpoint to write to.
+ * @param off Where to start writing at.
+ * @param paSegments Scatter gather list of the data to write.
+ * @param cSegments Number of segments in the list.
+ * @param cbWrite The overall number of bytes to write.
+ * @param pvUser Opaque user data returned in the completion callback
+ * upon completion of the task.
+ */
+VMMR3DECL(int) PDMR3BlkCacheWrite(PPDMBLKCACHE pBlkCache, uint64_t off,
+ PCRTSGBUF pcSgBuf, size_t cbWrite, void *pvUser);
+
+/**
+ * Creates a flush task on the given endpoint.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The file endpoint to flush.
+ * @param pvUser Opaque user data returned in the completion callback
+ * upon completion of the task.
+ */
+VMMR3DECL(int) PDMR3BlkCacheFlush(PPDMBLKCACHE pBlkCache, void *pvUser);
+
+/**
+ * Discards the given ranges from the cache.
+ *
+ * @returns VBox status code.
+ * @param pEndpoint The file endpoint to flush.
+ * @param paRanges Array of ranges to discard.
+ * @param cRanges Number of ranges in the array.
+ * @param pvUser Opaque user data returned in the completion callback
+ * upon completion of the task.
+ */
+VMMR3DECL(int) PDMR3BlkCacheDiscard(PPDMBLKCACHE pBlkCache, PCRTRANGE paRanges, unsigned cRanges, void *pvUser);
+
+/**
+ * Notify the cache of a complete I/O transfer.
+ *
+ * @returns nothing.
+ * @param pBlkCache The cache instance.
+ * @param hIoXfer The I/O transfer handle which completed.
+ * @param rcIoXfer The status code of the completed request.
+ */
+VMMR3DECL(void) PDMR3BlkCacheIoXferComplete(PPDMBLKCACHE pBlkCache, PPDMBLKCACHEIOXFER hIoXfer, int rcIoXfer);
+
+/**
+ * Suspends the block cache. The cache waits until all I/O transfers completed
+ * and stops to enqueue new requests after the call returned but will not accept
+ * reads, write or flushes either.
+ *
+ * @returns VBox status code.
+ * @param pBlkCache The cache instance.
+ */
+VMMR3DECL(int) PDMR3BlkCacheSuspend(PPDMBLKCACHE pBlkCache);
+
+/**
+ * Resumes operation of the block cache.
+ *
+ * @returns VBox status code.
+ * @param pBlkCache The cache instance.
+ */
+VMMR3DECL(int) PDMR3BlkCacheResume(PPDMBLKCACHE pBlkCache);
+
+/**
+ * Clears the block cache and removes all entries. The cache waits until all
+ * I/O transfers completed.
+ *
+ * @returns VBox status code.
+ * @param pBlkCache The cache instance.
+ */
+VMMR3DECL(int) PDMR3BlkCacheClear(PPDMBLKCACHE pBlkCache);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmcardreaderinfs.h b/include/VBox/vmm/pdmcardreaderinfs.h
new file mode 100644
index 00000000..e1ad5a2d
--- /dev/null
+++ b/include/VBox/vmm/pdmcardreaderinfs.h
@@ -0,0 +1,116 @@
+/* $Id: pdmcardreaderinfs.h $ */
+
+/** @file
+ * cardreaderinfs - interface between Usb Card Reader device and its driver.
+ */
+
+/*
+ * Copyright (C) 2011-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 ___VBox_vmm_pdmcardreaderinfs_h
+# define ___VBox_vmm_pdmcardreaderinfs_h
+
+#include <VBox/types.h>
+
+#define PDMICARDREADERDOWN_IID "78d65378-889c-4418-8bc2-7a89a5af2817"
+
+typedef struct PDMICARDREADER_IO_REQUEST
+{
+ uint32_t u32Protocol; /* Protocol identifier */
+ uint32_t cbPciLength; /* Protocol Control Information Length */
+ /* 'cbPciLength - 8' bytes of control info may follow. */
+} PDMICARDREADER_IO_REQUEST;
+
+typedef struct PDMICARDREADER_READERSTATE
+{
+ char *pszReaderName;
+ uint32_t u32CurrentState; /* Current state of reader at time of call. */
+ uint32_t u32EventState; /* State of reader after state change */
+ uint32_t cbAtr; /* Number of bytes in the returned ATR. */
+ uint8_t au8Atr[36]; /* Atr of inserted card, (extra alignment bytes) */
+} PDMICARDREADER_READERSTATE;
+
+
+typedef struct PDMICARDREADERDOWN PDMICARDREADERDOWN;
+typedef PDMICARDREADERDOWN *PPDMICARDREADERDOWN;
+struct PDMICARDREADERDOWN
+{
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEstablishContext,(PPDMICARDREADERDOWN pInterface));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownConnect,(PPDMICARDREADERDOWN pInterface, void *pvUser, const char *pszCardReaderName,
+ uint32_t u32ShareMode, uint32_t u32PreferredProtocols));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownDisconnect,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32Disposition));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownStatus,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t cchReaderName, uint32_t cbAtrLen));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownReleaseContext,(PPDMICARDREADERDOWN pInterface, void *pvUser));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetStatusChange,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32Timeout, PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownBeginTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownEndTransaction,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32Disposition));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownTransmit,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ const PDMICARDREADER_IO_REQUEST *pioSendRequest,
+ const uint8_t *pu8SendBuffer, uint32_t cbSendBuffer, uint32_t cbRecvBuffer));
+ /**
+ * Up level provides pvInBuffer of cbInBuffer bytes to call SCardControl, also it specify bytes it expects to receive
+ * @note: device/driver implementation should copy buffers before execution in async mode, and both layers shouldn't
+ * expect permanent storage for the buffer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownControl,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32ControlCode, const void *pvInBuffer, uint32_t cbInBuffer, uint32_t cbOutBuffer));
+ /**
+ * This function ask driver to provide attribute (dwAttribId) and provide limit (cbAttrib) of buffer size for attribute value,
+ * Callback UpGetAttrib returns buffer containing the value and altered size of the buffer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownGetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32AttribId, uint32_t cbAttrib));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderDownSetAttr,(PPDMICARDREADERDOWN pInterface, void *pvUser,
+ uint32_t u32AttribId, const void *pvAttrib, uint32_t cbAttrib));
+};
+
+#define PDMICARDREADERUP_IID "c0d7498e-0635-48ca-aab1-b11b6a55cf7d"
+typedef struct PDMICARDREADERUP PDMICARDREADERUP;
+typedef PDMICARDREADERUP *PPDMICARDREADERUP;
+struct PDMICARDREADERUP
+{
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEstablishContext,(PPDMICARDREADERUP pInterface, int32_t lSCardRc));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpStatus,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ char *pszReaderName, uint32_t cchReaderName, uint32_t u32CardState,
+ uint32_t u32Protocol, uint8_t *pu8Atr, uint32_t cbAtr));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpConnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ uint32_t u32ActiveProtocol));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpDisconnect,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetStatusChange,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ PDMICARDREADER_READERSTATE *paReaderStats, uint32_t cReaderStats));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpBeginTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpEndTransaction,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc));
+ /* Note: pioRecvPci stack variable */
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpTransmit,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ const PDMICARDREADER_IO_REQUEST *pioRecvPci, uint8_t *pu8RecvBuffer, uint32_t cbRecvBuffer));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpControl,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ uint32_t u32ControlCode, void *pvOutBuffer, uint32_t cbOutBuffer));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpGetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ uint32_t u32AttribId, void *pvAttrib, uint32_t cbAttrib));
+ DECLR3CALLBACKMEMBER(int, pfnCardReaderUpSetAttrib,(PPDMICARDREADERUP pInterface, void *pvUser, int32_t lSCardRc,
+ uint32_t u32AttribId));
+};
+
+#endif
diff --git a/include/VBox/vmm/pdmcommon.h b/include/VBox/vmm/pdmcommon.h
new file mode 100644
index 00000000..c4e1be26
--- /dev/null
+++ b/include/VBox/vmm/pdmcommon.h
@@ -0,0 +1,164 @@
+/** @file
+ * PDM - Pluggable Device Manager, Common Definitions & Types.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmcommon_h
+#define ___VBox_vmm_pdmcommon_h
+
+#include <VBox/types.h>
+
+
+/** @defgroup grp_pdm_common Common Definitions & Types
+ * @ingroup grp_pdm
+ *
+ * Not all the types here are "common", they are here to work around header
+ * ordering issues.
+ *
+ * @{
+ */
+
+/** Makes a PDM structure version out of an unique magic value and major &
+ * minor version numbers.
+ *
+ * @returns 32-bit structure version number.
+ *
+ * @param uMagic 16-bit magic value. This must be unique.
+ * @param uMajor 12-bit major version number. Structures with different
+ * major numbers are not compatible.
+ * @param uMinor 4-bit minor version number. When only the minor version
+ * differs, the structures will be 100% backwards
+ * compatible.
+ */
+#define PDM_VERSION_MAKE(uMagic, uMajor, uMinor) \
+ ( ((uint32_t)(uMagic) << 16) | ((uint32_t)((uMajor) & 0xff) << 4) | ((uint32_t)((uMinor) & 0xf) << 0) )
+
+/** Checks if @a uVerMagic1 is compatible with @a uVerMagic2.
+ *
+ * @returns true / false.
+ * @param uVerMagic1 Typically the runtime version of the struct. This must
+ * have the same magic and major version as @a uVerMagic2
+ * and the minor version must be greater or equal to that
+ * of @a uVerMagic2.
+ * @param uVerMagic2 Typically the version the code was compiled against.
+ *
+ * @remarks The parameters will be referenced more than once.
+ */
+#define PDM_VERSION_ARE_COMPATIBLE(uVerMagic1, uVerMagic2) \
+ ( (uVerMagic1) == (uVerMagic2) \
+ || ( (uVerMagic1) >= (uVerMagic2) \
+ && ((uVerMagic1) & UINT32_C(0xfffffff0)) == ((uVerMagic2) & UINT32_C(0xfffffff0)) ) \
+ )
+
+
+/** PDM Attach/Detach Callback Flags.
+ * Used by PDMDeviceAttach, PDMDeviceDetach, PDMDriverAttach, PDMDriverDetach,
+ * FNPDMDEVATTACH, FNPDMDEVDETACH, FNPDMDRVATTACH, FNPDMDRVDETACH and
+ * FNPDMDRVCONSTRUCT.
+ @{ */
+/** The attach/detach command is not a hotplug event. */
+#define PDM_TACH_FLAGS_NOT_HOT_PLUG RT_BIT_32(0)
+/** Indicates that no attach or detach callbacks should be made.
+ * This is mostly for internal use. */
+#define PDM_TACH_FLAGS_NO_CALLBACKS RT_BIT_32(1)
+/* @} */
+
+
+/**
+ * Is asynchronous handling of suspend or power off notification completed?
+ *
+ * This is called to check whether the USB device has quiesced. Don't deadlock.
+ * Avoid blocking. Do NOT wait for anything.
+ *
+ * @returns true if done, false if more work to be done.
+ *
+ * @param pUsbIns The USB device instance.
+ *
+ * @thread EMT(0)
+ */
+typedef DECLCALLBACK(bool) FNPDMUSBASYNCNOTIFY(PPDMUSBINS pUsbIns);
+/** Pointer to a FNPDMUSBASYNCNOTIFY. */
+typedef FNPDMUSBASYNCNOTIFY *PFNPDMUSBASYNCNOTIFY;
+
+/**
+ * Is asynchronous handling of suspend or power off notification completed?
+ *
+ * This is called to check whether the device has quiesced. Don't deadlock.
+ * Avoid blocking. Do NOT wait for anything.
+ *
+ * @returns true if done, false if more work to be done.
+ *
+ * @param pDevIns The device instance.
+ *
+ * @thread EMT(0)
+ */
+typedef DECLCALLBACK(bool) FNPDMDEVASYNCNOTIFY(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVASYNCNOTIFY. */
+typedef FNPDMDEVASYNCNOTIFY *PFNPDMDEVASYNCNOTIFY;
+
+/**
+ * Is asynchronous handling of suspend or power off notification completed?
+ *
+ * This is called to check whether the driver has quiesced. Don't deadlock.
+ * Avoid blocking. Do NOT wait for anything.
+ *
+ * @returns true if done, false if more work to be done.
+ *
+ * @param pDrvIns The driver instance.
+ *
+ * @thread EMT(0)
+ */
+typedef DECLCALLBACK(bool) FNPDMDRVASYNCNOTIFY(PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMDRVASYNCNOTIFY. */
+typedef FNPDMDRVASYNCNOTIFY *PFNPDMDRVASYNCNOTIFY;
+
+
+/**
+ * The ring-0 driver request handler.
+ *
+ * @returns VBox status code. PDMDevHlpCallR0 will return this.
+ * @param pDevIns The device instance (the ring-0 mapping).
+ * @param uOperation The operation.
+ * @param u64Arg Optional integer argument for the operation.
+ */
+typedef DECLCALLBACK(int) FNPDMDEVREQHANDLERR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg);
+/** Ring-0 pointer to a FNPDMDEVREQHANDLERR0. */
+typedef R0PTRTYPE(FNPDMDEVREQHANDLERR0 *) PFNPDMDEVREQHANDLERR0;
+
+/**
+ * The ring-0 driver request handler.
+ *
+ * @returns VBox status code. PDMDrvHlpCallR0 will return this.
+ * @param pDrvIns The driver instance (the ring-0 mapping).
+ * @param uOperation The operation.
+ * @param u64Arg Optional integer argument for the operation.
+ */
+typedef DECLCALLBACK(int) FNPDMDRVREQHANDLERR0(PPDMDRVINS pDrvIns, uint32_t uOperation, uint64_t u64Arg);
+/** Ring-0 pointer to a FNPDMDRVREQHANDLERR0. */
+typedef R0PTRTYPE(FNPDMDRVREQHANDLERR0 *) PFNPDMDRVREQHANDLERR0;
+
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/pdmcritsect.h b/include/VBox/vmm/pdmcritsect.h
new file mode 100644
index 00000000..02d7924d
--- /dev/null
+++ b/include/VBox/vmm/pdmcritsect.h
@@ -0,0 +1,95 @@
+/** @file
+ * PDM - Pluggable Device Manager, Critical Sections.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmcritsect_h
+#define ___VBox_vmm_pdmcritsect_h
+
+#include <VBox/types.h>
+#include <iprt/critsect.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_critsect The PDM Critical Section API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/**
+ * A PDM critical section.
+ * Initialize using PDMDRVHLP::pfnCritSectInit().
+ */
+typedef union PDMCRITSECT
+{
+ /** Padding. */
+ uint8_t padding[HC_ARCH_BITS == 32 ? 0x80 : 0xc0];
+#ifdef PDMCRITSECTINT_DECLARED
+ /** The internal structure (not normally visible). */
+ struct PDMCRITSECTINT s;
+#endif
+} PDMCRITSECT;
+
+VMMR3DECL(int) PDMR3CritSectInit(PVM pVM, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...);
+VMMDECL(int) PDMCritSectEnter(PPDMCRITSECT pCritSect, int rcBusy);
+VMMDECL(int) PDMCritSectEnterDebug(PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+VMMDECL(int) PDMCritSectTryEnter(PPDMCRITSECT pCritSect);
+VMMDECL(int) PDMCritSectTryEnterDebug(PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+VMMR3DECL(int) PDMR3CritSectEnterEx(PPDMCRITSECT pCritSect, bool fCallRing3);
+VMMDECL(int) PDMCritSectLeave(PPDMCRITSECT pCritSect);
+VMMDECL(bool) PDMCritSectIsOwner(PCPDMCRITSECT pCritSect);
+VMMDECL(bool) PDMCritSectIsOwnerEx(PCPDMCRITSECT pCritSect, PVMCPU pVCpu);
+VMMDECL(bool) PDMCritSectIsInitialized(PCPDMCRITSECT pCritSect);
+VMMDECL(bool) PDMCritSectHasWaiters(PCPDMCRITSECT pCritSect);
+VMMDECL(uint32_t) PDMCritSectGetRecursion(PCPDMCRITSECT pCritSect);
+VMMR3DECL(bool) PDMR3CritSectYield(PPDMCRITSECT pCritSect);
+VMMR3DECL(const char *) PDMR3CritSectName(PCPDMCRITSECT pCritSect);
+VMMR3DECL(int) PDMR3CritSectScheduleExitEvent(PPDMCRITSECT pCritSect, RTSEMEVENT EventToSignal);
+VMMR3DECL(int) PDMR3CritSectDelete(PPDMCRITSECT pCritSect);
+VMMDECL(int) PDMR3CritSectTerm(PVM pVM);
+VMMDECL(void) PDMCritSectFF(PVMCPU pVCpu);
+VMMR3DECL(uint32_t) PDMR3CritSectCountOwned(PVM pVM, char *pszNames, size_t cbNames);
+VMMR3DECL(void) PDMR3CritSectLeaveAll(PVM pVM);
+
+VMMR3DECL(PPDMCRITSECT) PDMR3CritSectGetNop(PVM pVM);
+VMMR3DECL(R0PTRTYPE(PPDMCRITSECT)) PDMR3CritSectGetNopR0(PVM pVM);
+VMMR3DECL(RCPTRTYPE(PPDMCRITSECT)) PDMR3CritSectGetNopRC(PVM pVM);
+
+/* Strict build: Remap the two enter calls to the debug versions. */
+#ifdef VBOX_STRICT
+# ifdef ___iprt_asm_h
+# define PDMCritSectEnter(pCritSect, rcBusy) PDMCritSectEnterDebug((pCritSect), (rcBusy), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define PDMCritSectTryEnter(pCritSect) PDMCritSectTryEnterDebug((pCritSect), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+# define PDMCritSectEnter(pCritSect, rcBusy) PDMCritSectEnterDebug((pCritSect), (rcBusy), 0, RT_SRC_POS)
+# define PDMCritSectTryEnter(pCritSect) PDMCritSectTryEnterDebug((pCritSect), 0, RT_SRC_POS)
+# endif
+#endif
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmdev.h b/include/VBox/vmm/pdmdev.h
new file mode 100644
index 00000000..892ed590
--- /dev/null
+++ b/include/VBox/vmm/pdmdev.h
@@ -0,0 +1,5173 @@
+/** @file
+ * PDM - Pluggable Device Manager, Devices.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmdev_h
+#define ___VBox_vmm_pdmdev_h
+
+#include <VBox/vmm/pdmqueue.h>
+#include <VBox/vmm/pdmcritsect.h>
+#include <VBox/vmm/pdmthread.h>
+#include <VBox/vmm/pdmifs.h>
+#include <VBox/vmm/pdmins.h>
+#include <VBox/vmm/pdmcommon.h>
+#include <VBox/vmm/iom.h>
+#include <VBox/vmm/tm.h>
+#include <VBox/vmm/ssm.h>
+#include <VBox/vmm/cfgm.h>
+#include <VBox/vmm/dbgf.h>
+#include <VBox/err.h>
+#include <VBox/pci.h>
+#include <iprt/stdarg.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_device The PDM Devices API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/**
+ * Construct a device instance for a VM.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data. If the registration structure
+ * is needed, it can be accessed thru pDevIns->pReg.
+ * @param iInstance Instance number. Use this to figure out which registers
+ * and such to use. The instance number is also found in
+ * pDevIns->iInstance, but since it's likely to be
+ * frequently used PDM passes it as parameter.
+ * @param pCfg Configuration node handle for the driver. This is
+ * expected to be in high demand in the constructor and is
+ * therefore passed as an argument. When using it at other
+ * times, it can be found in pDrvIns->pCfg.
+ */
+typedef DECLCALLBACK(int) FNPDMDEVCONSTRUCT(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg);
+/** Pointer to a FNPDMDEVCONSTRUCT() function. */
+typedef FNPDMDEVCONSTRUCT *PFNPDMDEVCONSTRUCT;
+
+/**
+ * Destruct a device instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data.
+ *
+ * @remarks The device critical section is not entered. The routine may delete
+ * the critical section, so the caller cannot exit it.
+ */
+typedef DECLCALLBACK(int) FNPDMDEVDESTRUCT(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVDESTRUCT() function. */
+typedef FNPDMDEVDESTRUCT *PFNPDMDEVDESTRUCT;
+
+/**
+ * Device relocation callback.
+ *
+ * This is called when the instance data has been relocated in raw-mode context
+ * (RC). It is also called when the RC hypervisor selects changes. The device
+ * must fixup all necessary pointers and re-query all interfaces to other RC
+ * devices and drivers.
+ *
+ * Before the RC code is executed the first time, this function will be called
+ * with a 0 delta so RC pointer calculations can be one in one place.
+ *
+ * @param pDevIns Pointer to the device instance.
+ * @param offDelta The relocation delta relative to the old location.
+ *
+ * @remarks A relocation CANNOT fail.
+ *
+ * @remarks The device critical section is not entered. The relocations should
+ * not normally require any locking.
+ */
+typedef DECLCALLBACK(void) FNPDMDEVRELOCATE(PPDMDEVINS pDevIns, RTGCINTPTR offDelta);
+/** Pointer to a FNPDMDEVRELOCATE() function. */
+typedef FNPDMDEVRELOCATE *PFNPDMDEVRELOCATE;
+
+/**
+ * Device I/O Control interface.
+ *
+ * This is used by external components, such as the COM interface, to
+ * communicate with devices using a class wide interface or a device
+ * specific interface.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Pointer to the device instance.
+ * @param uFunction Function to perform.
+ * @param pvIn Pointer to input data.
+ * @param cbIn Size of input data.
+ * @param pvOut Pointer to output data.
+ * @param cbOut Size of output data.
+ * @param pcbOut Where to store the actual size of the output data.
+ *
+ * @remarks Not used.
+ */
+typedef DECLCALLBACK(int) FNPDMDEVIOCTL(PPDMDEVINS pDevIns, uint32_t uFunction,
+ void *pvIn, uint32_t cbIn,
+ void *pvOut, uint32_t cbOut, PRTUINT pcbOut);
+/** Pointer to a FNPDMDEVIOCTL() function. */
+typedef FNPDMDEVIOCTL *PFNPDMDEVIOCTL;
+
+/**
+ * Power On notification.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data.
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(void) FNPDMDEVPOWERON(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVPOWERON() function. */
+typedef FNPDMDEVPOWERON *PFNPDMDEVPOWERON;
+
+/**
+ * Reset notification.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data.
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(void) FNPDMDEVRESET(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVRESET() function. */
+typedef FNPDMDEVRESET *PFNPDMDEVRESET;
+
+/**
+ * Suspend notification.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data.
+ * @thread EMT(0)
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(void) FNPDMDEVSUSPEND(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVSUSPEND() function. */
+typedef FNPDMDEVSUSPEND *PFNPDMDEVSUSPEND;
+
+/**
+ * Resume notification.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance data.
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(void) FNPDMDEVRESUME(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVRESUME() function. */
+typedef FNPDMDEVRESUME *PFNPDMDEVRESUME;
+
+/**
+ * Power Off notification.
+ *
+ * This is only called when the VMR3PowerOff call is made on a running VM. This
+ * means that there is no notification if the VM was suspended before being
+ * powered of. There will also be no callback when hot plugging devices.
+ *
+ * @param pDevIns The device instance data.
+ * @thread EMT(0)
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(void) FNPDMDEVPOWEROFF(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVPOWEROFF() function. */
+typedef FNPDMDEVPOWEROFF *PFNPDMDEVPOWEROFF;
+
+/**
+ * Attach command.
+ *
+ * This is called to let the device attach to a driver for a specified LUN
+ * at runtime. This is not called during VM construction, the device
+ * constructor have to attach to all the available drivers.
+ *
+ * This is like plugging in the keyboard or mouse after turning on the PC.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iLUN The logical unit which is being detached.
+ * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(int) FNPDMDEVATTACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
+/** Pointer to a FNPDMDEVATTACH() function. */
+typedef FNPDMDEVATTACH *PFNPDMDEVATTACH;
+
+/**
+ * Detach notification.
+ *
+ * This is called when a driver is detaching itself from a LUN of the device.
+ * The device should adjust it's state to reflect this.
+ *
+ * This is like unplugging the network cable to use it for the laptop or
+ * something while the PC is still running.
+ *
+ * @param pDevIns The device instance.
+ * @param iLUN The logical unit which is being detached.
+ * @param fFlags Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(void) FNPDMDEVDETACH(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags);
+/** Pointer to a FNPDMDEVDETACH() function. */
+typedef FNPDMDEVDETACH *PFNPDMDEVDETACH;
+
+/**
+ * Query the base interface of a logical unit.
+ *
+ * @returns VBOX status code.
+ * @param pDevIns The device instance.
+ * @param iLUN The logicial unit to query.
+ * @param ppBase Where to store the pointer to the base interface of the LUN.
+ *
+ * @remarks The device critical section is not entered.
+ */
+typedef DECLCALLBACK(int) FNPDMDEVQUERYINTERFACE(PPDMDEVINS pDevIns, unsigned iLUN, PPDMIBASE *ppBase);
+/** Pointer to a FNPDMDEVQUERYINTERFACE() function. */
+typedef FNPDMDEVQUERYINTERFACE *PFNPDMDEVQUERYINTERFACE;
+
+/**
+ * Init complete notification.
+ * This can be done to do communication with other devices and other
+ * initialization which requires everything to be in place.
+ *
+ * @returns VBOX status code.
+ * @param pDevIns The device instance.
+ *
+ * @remarks Caller enters the device critical section.
+ */
+typedef DECLCALLBACK(int) FNPDMDEVINITCOMPLETE(PPDMDEVINS pDevIns);
+/** Pointer to a FNPDMDEVINITCOMPLETE() function. */
+typedef FNPDMDEVINITCOMPLETE *PFNPDMDEVINITCOMPLETE;
+
+
+
+/**
+ * PDM Device Registration Structure.
+ *
+ * This structure is used when registering a device from VBoxInitDevices() in HC
+ * Ring-3. PDM will continue use till the VM is terminated.
+ */
+typedef struct PDMDEVREG
+{
+ /** Structure version. PDM_DEVREG_VERSION defines the current version. */
+ uint32_t u32Version;
+ /** Device name. */
+ char szName[32];
+ /** Name of the raw-mode context module (no path).
+ * Only evalutated if PDM_DEVREG_FLAGS_RC is set. */
+ char szRCMod[32];
+ /** Name of the ring-0 module (no path).
+ * Only evalutated if PDM_DEVREG_FLAGS_R0 is set. */
+ char szR0Mod[32];
+ /** The description of the device. The UTF-8 string pointed to shall, like this structure,
+ * remain unchanged from registration till VM destruction. */
+ const char *pszDescription;
+
+ /** Flags, combination of the PDM_DEVREG_FLAGS_* \#defines. */
+ uint32_t fFlags;
+ /** Device class(es), combination of the PDM_DEVREG_CLASS_* \#defines. */
+ uint32_t fClass;
+ /** Maximum number of instances (per VM). */
+ uint32_t cMaxInstances;
+ /** Size of the instance data. */
+ uint32_t cbInstance;
+
+ /** Construct instance - required. */
+ PFNPDMDEVCONSTRUCT pfnConstruct;
+ /** Destruct instance - optional.
+ * Critical section NOT entered (will be destroyed). */
+ PFNPDMDEVDESTRUCT pfnDestruct;
+ /** Relocation command - optional.
+ * Critical section NOT entered. */
+ PFNPDMDEVRELOCATE pfnRelocate;
+ /** I/O Control interface - optional.
+ * Not used. */
+ PFNPDMDEVIOCTL pfnIOCtl;
+ /** Power on notification - optional.
+ * Critical section is entered. */
+ PFNPDMDEVPOWERON pfnPowerOn;
+ /** Reset notification - optional.
+ * Critical section is entered. */
+ PFNPDMDEVRESET pfnReset;
+ /** Suspend notification - optional.
+ * Critical section is entered. */
+ PFNPDMDEVSUSPEND pfnSuspend;
+ /** Resume notification - optional.
+ * Critical section is entered. */
+ PFNPDMDEVRESUME pfnResume;
+ /** Attach command - optional.
+ * Critical section is entered. */
+ PFNPDMDEVATTACH pfnAttach;
+ /** Detach notification - optional.
+ * Critical section is entered. */
+ PFNPDMDEVDETACH pfnDetach;
+ /** Query a LUN base interface - optional.
+ * Critical section is NOT entered. */
+ PFNPDMDEVQUERYINTERFACE pfnQueryInterface;
+ /** Init complete notification - optional.
+ * Critical section is entered. */
+ PFNPDMDEVINITCOMPLETE pfnInitComplete;
+ /** Power off notification - optional.
+ * Critical section is entered. */
+ PFNPDMDEVPOWEROFF pfnPowerOff;
+ /** @todo */
+ PFNRT pfnSoftReset;
+ /** Initialization safty marker. */
+ uint32_t u32VersionEnd;
+} PDMDEVREG;
+/** Pointer to a PDM Device Structure. */
+typedef PDMDEVREG *PPDMDEVREG;
+/** Const pointer to a PDM Device Structure. */
+typedef PDMDEVREG const *PCPDMDEVREG;
+
+/** Current DEVREG version number. */
+#define PDM_DEVREG_VERSION PDM_VERSION_MAKE(0xffff, 1, 0)
+
+/** PDM Device Flags.
+ * @{ */
+/** This flag is used to indicate that the device has a RC component. */
+#define PDM_DEVREG_FLAGS_RC 0x00000001
+/** This flag is used to indicate that the device has a R0 component. */
+#define PDM_DEVREG_FLAGS_R0 0x00000002
+
+/** @def PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT
+ * The bit count for the current host. */
+#if HC_ARCH_BITS == 32
+# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT 0x00000010
+#elif HC_ARCH_BITS == 64
+# define PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT 0x00000020
+#else
+# error Unsupported HC_ARCH_BITS value.
+#endif
+/** The host bit count mask. */
+#define PDM_DEVREG_FLAGS_HOST_BITS_MASK 0x00000030
+
+/** The device support only 32-bit guests. */
+#define PDM_DEVREG_FLAGS_GUEST_BITS_32 0x00000100
+/** The device support only 64-bit guests. */
+#define PDM_DEVREG_FLAGS_GUEST_BITS_64 0x00000200
+/** The device support both 32-bit & 64-bit guests. */
+#define PDM_DEVREG_FLAGS_GUEST_BITS_32_64 0x00000300
+/** @def PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT
+ * The guest bit count for the current compilation. */
+#if GC_ARCH_BITS == 32
+# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32
+#elif GC_ARCH_BITS == 64
+# define PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT PDM_DEVREG_FLAGS_GUEST_BITS_32_64
+#else
+# error Unsupported GC_ARCH_BITS value.
+#endif
+/** The guest bit count mask. */
+#define PDM_DEVREG_FLAGS_GUEST_BITS_MASK 0x00000300
+
+/** A convenience. */
+#define PDM_DEVREG_FLAGS_DEFAULT_BITS (PDM_DEVREG_FLAGS_GUEST_BITS_DEFAULT | PDM_DEVREG_FLAGS_HOST_BITS_DEFAULT)
+
+/** Indicates that the devices support PAE36 on a 32-bit guest. */
+#define PDM_DEVREG_FLAGS_PAE36 0x00001000
+
+/** Indicates that the device needs to be notified before the drivers when suspending. */
+#define PDM_DEVREG_FLAGS_FIRST_SUSPEND_NOTIFICATION 0x00002000
+
+/** Indicates that the device needs to be notified before the drivers when powering off. */
+#define PDM_DEVREG_FLAGS_FIRST_POWEROFF_NOTIFICATION 0x00004000
+
+/** Indicates that the device needs to be notified before the drivers when resetting. */
+#define PDM_DEVREG_FLAGS_FIRST_RESET_NOTIFICATION 0x00008000
+/** @} */
+
+
+/** PDM Device Classes.
+ * The order is important, lower bit earlier instantiation.
+ * @{ */
+/** Architecture device. */
+#define PDM_DEVREG_CLASS_ARCH RT_BIT(0)
+/** Architecture BIOS device. */
+#define PDM_DEVREG_CLASS_ARCH_BIOS RT_BIT(1)
+/** PCI bus brigde. */
+#define PDM_DEVREG_CLASS_BUS_PCI RT_BIT(2)
+/** ISA bus brigde. */
+#define PDM_DEVREG_CLASS_BUS_ISA RT_BIT(3)
+/** Input device (mouse, keyboard, joystick, HID, ...). */
+#define PDM_DEVREG_CLASS_INPUT RT_BIT(4)
+/** Interrupt controller (PIC). */
+#define PDM_DEVREG_CLASS_PIC RT_BIT(5)
+/** Interval controoler (PIT). */
+#define PDM_DEVREG_CLASS_PIT RT_BIT(6)
+/** RTC/CMOS. */
+#define PDM_DEVREG_CLASS_RTC RT_BIT(7)
+/** DMA controller. */
+#define PDM_DEVREG_CLASS_DMA RT_BIT(8)
+/** VMM Device. */
+#define PDM_DEVREG_CLASS_VMM_DEV RT_BIT(9)
+/** Graphics device, like VGA. */
+#define PDM_DEVREG_CLASS_GRAPHICS RT_BIT(10)
+/** Storage controller device. */
+#define PDM_DEVREG_CLASS_STORAGE RT_BIT(11)
+/** Network interface controller. */
+#define PDM_DEVREG_CLASS_NETWORK RT_BIT(12)
+/** Audio. */
+#define PDM_DEVREG_CLASS_AUDIO RT_BIT(13)
+/** USB HIC. */
+#define PDM_DEVREG_CLASS_BUS_USB RT_BIT(14)
+/** ACPI. */
+#define PDM_DEVREG_CLASS_ACPI RT_BIT(15)
+/** Serial controller device. */
+#define PDM_DEVREG_CLASS_SERIAL RT_BIT(16)
+/** Parallel controller device */
+#define PDM_DEVREG_CLASS_PARALLEL RT_BIT(17)
+/** Host PCI pass-through device */
+#define PDM_DEVREG_CLASS_HOST_DEV RT_BIT(18)
+/** Misc devices (always last). */
+#define PDM_DEVREG_CLASS_MISC RT_BIT(31)
+/** @} */
+
+
+/** @name IRQ Level for use with the *SetIrq APIs.
+ * @{
+ */
+/** Assert the IRQ (can assume value 1). */
+#define PDM_IRQ_LEVEL_HIGH RT_BIT(0)
+/** Deassert the IRQ (can assume value 0). */
+#define PDM_IRQ_LEVEL_LOW 0
+/** flip-flop - deassert and then assert the IRQ again immediately. */
+#define PDM_IRQ_LEVEL_FLIP_FLOP (RT_BIT(1) | PDM_IRQ_LEVEL_HIGH)
+/** @} */
+
+/**
+ * Registration record for MSI.
+ */
+typedef struct PDMMSIREG
+{
+ /** Number of MSI interrupt vectors, 0 if MSI not supported */
+ uint16_t cMsiVectors;
+ /** Offset of MSI capability */
+ uint8_t iMsiCapOffset;
+ /** Offset of next capability to MSI */
+ uint8_t iMsiNextOffset;
+ /** If we support 64-bit MSI addressing */
+ bool fMsi64bit;
+
+ /** Number of MSI-X interrupt vectors, 0 if MSI-X not supported */
+ uint16_t cMsixVectors;
+ /** Offset of MSI-X capability */
+ uint8_t iMsixCapOffset;
+ /** Offset of next capability to MSI-X */
+ uint8_t iMsixNextOffset;
+ /** Value of PCI BAR (base addresss register) assigned by device for MSI-X page access */
+ uint8_t iMsixBar;
+} PDMMSIREG;
+typedef PDMMSIREG *PPDMMSIREG;
+
+/**
+ * PCI Bus registration structure.
+ * All the callbacks, except the PCIBIOS hack, are working on PCI devices.
+ */
+typedef struct PDMPCIBUSREG
+{
+ /** Structure version number. PDM_PCIBUSREG_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Registers the device with the default PCI bus.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the PCI Bus.
+ * @param pPciDev The PCI device structure.
+ * Any PCI enabled device must keep this in it's instance data!
+ * Fill in the PCI data config before registration, please.
+ * @param pszName Pointer to device name (permanent, readonly). For debugging, not unique.
+ * @param iDev The device number ((dev << 3) | function) the device should have on the bus.
+ * If negative, the pci bus device will assign one.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, const char *pszName, int iDev));
+
+ /**
+ * Initialize MSI support in a PCI device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the PCI Bus.
+ * @param pPciDev The PCI device structure.
+ * @param pMsiReg MSI registration structure
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRegisterMsiR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PPDMMSIREG pMsiReg));
+
+ /**
+ * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the PCI Bus.
+ * @param pPciDev The PCI device structure.
+ * @param iRegion The region number.
+ * @param cbRegion Size of the region.
+ * @param iType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
+ * @param pfnCallback Callback for doing the mapping.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnIORegionRegisterR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
+
+ /**
+ * Register PCI configuration space read/write callbacks.
+ *
+ * @param pDevIns Device instance of the PCI Bus.
+ * @param pPciDev The PCI device structure.
+ * @param pfnRead Pointer to the user defined PCI config read function.
+ * @param ppfnReadOld Pointer to function pointer which will receive the old (default)
+ * PCI config read function. This way, user can decide when (and if)
+ * to call default PCI config read function. Can be NULL.
+ * @param pfnWrite Pointer to the user defined PCI config write function.
+ * @param pfnWriteOld Pointer to function pointer which will receive the old (default)
+ * PCI config write function. This way, user can decide when (and if)
+ * to call default PCI config write function. Can be NULL.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
+ PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
+
+ /**
+ * Set the IRQ for a PCI device.
+ *
+ * @param pDevIns Device instance of the PCI Bus.
+ * @param pPciDev The PCI device structure.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Saves a state of the PCI device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the PCI Bus.
+ * @param pPciDev Pointer to PCI device.
+ * @param pSSMHandle The handle to save the state to.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSaveExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
+
+ /**
+ * Loads a saved PCI device state.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the PCI Bus.
+ * @param pPciDev Pointer to PCI device.
+ * @param pSSMHandle The handle to the saved state.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLoadExecR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PSSMHANDLE pSSMHandle));
+
+ /**
+ * Called to perform the job of the bios.
+ * This is only called for the first PCI Bus - it is expected to
+ * service all the PCI buses.
+ *
+ * @returns VBox status.
+ * @param pDevIns Device instance of the first bus.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFakePCIBIOSR3,(PPDMDEVINS pDevIns));
+
+ /** The name of the SetIrq RC entry point. */
+ const char *pszSetIrqRC;
+
+ /** The name of the SetIrq R0 entry point. */
+ const char *pszSetIrqR0;
+
+} PDMPCIBUSREG;
+/** Pointer to a PCI bus registration structure. */
+typedef PDMPCIBUSREG *PPDMPCIBUSREG;
+
+/** Current PDMPCIBUSREG version number. */
+#define PDM_PCIBUSREG_VERSION PDM_VERSION_MAKE(0xfffe, 3, 0)
+
+/**
+ * PCI Bus RC helpers.
+ */
+typedef struct PDMPCIHLPRC
+{
+ /** Structure version. PDM_PCIHLPRC_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set an ISA IRQ.
+ *
+ * @param pDevIns PCI device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ * @thread EMT only.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Set an I/O-APIC IRQ.
+ *
+ * @param pDevIns PCI device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ * @thread EMT only.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Send an MSI.
+ *
+ * @param pDevIns PCI device instance.
+ * @param GCPhys Physical address MSI request was written.
+ * @param uValue Value written.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ * @thread EMT only.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
+
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The PCI device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The PCI device instance.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPCIHLPRC;
+/** Pointer to PCI helpers. */
+typedef RCPTRTYPE(PDMPCIHLPRC *) PPDMPCIHLPRC;
+/** Pointer to const PCI helpers. */
+typedef RCPTRTYPE(const PDMPCIHLPRC *) PCPDMPCIHLPRC;
+
+/** Current PDMPCIHLPRC version number. */
+#define PDM_PCIHLPRC_VERSION PDM_VERSION_MAKE(0xfffd, 3, 0)
+
+
+/**
+ * PCI Bus R0 helpers.
+ */
+typedef struct PDMPCIHLPR0
+{
+ /** Structure version. PDM_PCIHLPR0_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set an ISA IRQ.
+ *
+ * @param pDevIns PCI device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ * @thread EMT only.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Set an I/O-APIC IRQ.
+ *
+ * @param pDevIns PCI device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ * @thread EMT only.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Send an MSI.
+ *
+ * @param pDevIns PCI device instance.
+ * @param GCPhys Physical address MSI request was written.
+ * @param uValue Value written.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ * @thread EMT only.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
+
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The PCI device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The PCI device instance.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPCIHLPR0;
+/** Pointer to PCI helpers. */
+typedef R0PTRTYPE(PDMPCIHLPR0 *) PPDMPCIHLPR0;
+/** Pointer to const PCI helpers. */
+typedef R0PTRTYPE(const PDMPCIHLPR0 *) PCPDMPCIHLPR0;
+
+/** Current PDMPCIHLPR0 version number. */
+#define PDM_PCIHLPR0_VERSION PDM_VERSION_MAKE(0xfffc, 3, 0)
+
+/**
+ * PCI device helpers.
+ */
+typedef struct PDMPCIHLPR3
+{
+ /** Structure version. PDM_PCIHLPR3_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set an ISA IRQ.
+ *
+ * @param pDevIns The PCI device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnIsaSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Set an I/O-APIC IRQ.
+ *
+ * @param pDevIns The PCI device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnIoApicSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Send an MSI.
+ *
+ * @param pDevIns PCI device instance.
+ * @param GCPhys Physical address MSI request was written.
+ * @param uValue Value written.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnIoApicSendMsi,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
+
+ /**
+ * Checks if the given address is an MMIO2 base address or not.
+ *
+ * @returns true/false accordingly.
+ * @param pDevIns The PCI device instance.
+ * @param pOwner The owner of the memory, optional.
+ * @param GCPhys The address to check.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnIsMMIO2Base,(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys));
+
+ /**
+ * Gets the address of the RC PCI Bus helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the RC helpers.
+ *
+ * @returns RC pointer to the PCI Bus helpers.
+ * @param pDevIns Device instance of the PCI Bus.
+ * @thread EMT only.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMPCIHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the R0 PCI Bus helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the R0 helpers.
+ *
+ * @returns R0 pointer to the PCI Bus helpers.
+ * @param pDevIns Device instance of the PCI Bus.
+ * @thread EMT only.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMPCIHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns Fatal error on failure.
+ * @param pDevIns The PCI device instance.
+ * @param rc Dummy for making the interface identical to the RC and R0 versions.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The PCI device instance.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPCIHLPR3;
+/** Pointer to PCI helpers. */
+typedef R3PTRTYPE(PDMPCIHLPR3 *) PPDMPCIHLPR3;
+/** Pointer to const PCI helpers. */
+typedef R3PTRTYPE(const PDMPCIHLPR3 *) PCPDMPCIHLPR3;
+
+/** Current PDMPCIHLPR3 version number. */
+#define PDM_PCIHLPR3_VERSION PDM_VERSION_MAKE(0xfffb, 3, 0)
+
+
+/**
+ * Programmable Interrupt Controller registration structure.
+ */
+typedef struct PDMPICREG
+{
+ /** Structure version number. PDM_PICREG_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the an IRQ.
+ *
+ * @param pDevIns Device instance of the PIC.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /**
+ * Get a pending interrupt.
+ *
+ * @returns Pending interrupt number.
+ * @param pDevIns Device instance of the PIC.
+ * @param puTagSrc Where to return the IRQ tag and source.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
+
+ /** The name of the RC SetIrq entry point. */
+ const char *pszSetIrqRC;
+ /** The name of the RC GetInterrupt entry point. */
+ const char *pszGetInterruptRC;
+
+ /** The name of the R0 SetIrq entry point. */
+ const char *pszSetIrqR0;
+ /** The name of the R0 GetInterrupt entry point. */
+ const char *pszGetInterruptR0;
+} PDMPICREG;
+/** Pointer to a PIC registration structure. */
+typedef PDMPICREG *PPDMPICREG;
+
+/** Current PDMPICREG version number. */
+#define PDM_PICREG_VERSION PDM_VERSION_MAKE(0xfffa, 2, 0)
+
+/**
+ * PIC RC helpers.
+ */
+typedef struct PDMPICHLPRC
+{
+ /** Structure version. PDM_PICHLPRC_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
+
+ /**
+ * Clear the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The PIC device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The PIC device instance.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPICHLPRC;
+
+/** Pointer to PIC RC helpers. */
+typedef RCPTRTYPE(PDMPICHLPRC *) PPDMPICHLPRC;
+/** Pointer to const PIC RC helpers. */
+typedef RCPTRTYPE(const PDMPICHLPRC *) PCPDMPICHLPRC;
+
+/** Current PDMPICHLPRC version number. */
+#define PDM_PICHLPRC_VERSION PDM_VERSION_MAKE(0xfff9, 2, 0)
+
+
+/**
+ * PIC R0 helpers.
+ */
+typedef struct PDMPICHLPR0
+{
+ /** Structure version. PDM_PICHLPR0_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
+
+ /**
+ * Clear the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The PIC device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The PCI device instance.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPICHLPR0;
+
+/** Pointer to PIC R0 helpers. */
+typedef R0PTRTYPE(PDMPICHLPR0 *) PPDMPICHLPR0;
+/** Pointer to const PIC R0 helpers. */
+typedef R0PTRTYPE(const PDMPICHLPR0 *) PCPDMPICHLPR0;
+
+/** Current PDMPICHLPR0 version number. */
+#define PDM_PICHLPR0_VERSION PDM_VERSION_MAKE(0xfff8, 1, 0)
+
+/**
+ * PIC R3 helpers.
+ */
+typedef struct PDMPICHLPR3
+{
+ /** Structure version. PDM_PICHLP_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns));
+
+ /**
+ * Clear the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns Fatal error on failure.
+ * @param pDevIns The PIC device instance.
+ * @param rc Dummy for making the interface identical to the RC and R0 versions.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The PIC device instance.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the RC PIC helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the RC helpers.
+ *
+ * @returns RC pointer to the PIC helpers.
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the R0 PIC helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the R0 helpers.
+ *
+ * @returns R0 pointer to the PIC helpers.
+ * @param pDevIns Device instance of the PIC.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPICHLPR3;
+
+/** Pointer to PIC R3 helpers. */
+typedef R3PTRTYPE(PDMPICHLPR3 *) PPDMPICHLPR3;
+/** Pointer to const PIC R3 helpers. */
+typedef R3PTRTYPE(const PDMPICHLPR3 *) PCPDMPICHLPR3;
+
+/** Current PDMPICHLPR3 version number. */
+#define PDM_PICHLPR3_VERSION PDM_VERSION_MAKE(0xfff7, 1, 0)
+
+
+
+/**
+ * Advanced Programmable Interrupt Controller registration structure.
+ */
+typedef struct PDMAPICREG
+{
+ /** Structure version number. PDM_APICREG_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Get a pending interrupt.
+ *
+ * @returns Pending interrupt number.
+ * @param pDevIns Device instance of the APIC.
+ * @param puTagSrc Where to return the tag source.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetInterruptR3,(PPDMDEVINS pDevIns, uint32_t *puTagSrc));
+
+ /**
+ * Check if the APIC has a pending interrupt/if a TPR change would active one
+ *
+ * @returns Pending interrupt yes/no
+ * @param pDevIns Device instance of the APIC.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnHasPendingIrqR3,(PPDMDEVINS pDevIns));
+
+ /**
+ * Set the APIC base.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param u64Base The new base.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetBaseR3,(PPDMDEVINS pDevIns, uint64_t u64Base));
+
+ /**
+ * Get the APIC base.
+ *
+ * @returns Current base.
+ * @param pDevIns Device instance of the APIC.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetBaseR3,(PPDMDEVINS pDevIns));
+
+ /**
+ * Set the TPR (task priority register).
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param idCpu VCPU id
+ * @param u8TPR The new TPR.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint8_t u8TPR));
+
+ /**
+ * Get the TPR (task priority register).
+ *
+ * @returns The current TPR.
+ * @param pDevIns Device instance of the APIC.
+ * @param idCpu VCPU id
+ */
+ DECLR3CALLBACKMEMBER(uint8_t, pfnGetTPRR3,(PPDMDEVINS pDevIns, VMCPUID idCpu));
+
+ /**
+ * Write to a MSR in APIC range.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the APIC.
+ * @param idCpu Target CPU.
+ * @param u32Reg The MSR begin written to.
+ * @param u64Value The value to write.
+ *
+ * @remarks Unlike the other callbacks, the PDM lock is not taken before
+ * calling this method.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value));
+
+ /**
+ * Read from a MSR in APIC range.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the APIC.
+ * @param idCpu Target CPU.
+ * @param u32Reg MSR to read.
+ * @param pu64Value Where to return the read value.
+ *
+ * @remarks Unlike the other callbacks, the PDM lock is not taken before
+ * calling this method.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
+
+ /**
+ * Private interface between the IOAPIC and APIC.
+ *
+ * This is a low-level, APIC/IOAPIC implementation specific interface which
+ * is registered with PDM only because it makes life so much simpler right
+ * now (GC bits). This is a bad bad hack! The correct way of doing this
+ * would involve some way of querying GC interfaces and relocating them.
+ * Perhaps doing some kind of device init in GC...
+ *
+ * @returns status code.
+ * @param pDevIns Device instance of the APIC.
+ * @param u8Dest See APIC implementation.
+ * @param u8DestMode See APIC implementation.
+ * @param u8DeliveryMode See APIC implementation.
+ * @param iVector See APIC implementation.
+ * @param u8Polarity See APIC implementation.
+ * @param u8TriggerMode See APIC implementation.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+ uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
+
+ /**
+ * Deliver a signal to CPU's local interrupt pins (LINT0/LINT1).
+ *
+ * Used for virtual wire mode when interrupts from the PIC are passed through
+ * LAPIC.
+ *
+ * @returns status code.
+ * @param pDevIns Device instance of the APIC.
+ * @param u8Pin Local pin number (0 or 1 for current CPUs).
+ * @param u8Level The level.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, uint8_t u8Pin, uint8_t u8Level));
+
+ /** The name of the RC GetInterrupt entry point. */
+ const char *pszGetInterruptRC;
+ /** The name of the RC HasPendingIrq entry point. */
+ const char *pszHasPendingIrqRC;
+ /** The name of the RC SetBase entry point. */
+ const char *pszSetBaseRC;
+ /** The name of the RC GetBase entry point. */
+ const char *pszGetBaseRC;
+ /** The name of the RC SetTPR entry point. */
+ const char *pszSetTPRRC;
+ /** The name of the RC GetTPR entry point. */
+ const char *pszGetTPRRC;
+ /** The name of the RC WriteMSR entry point. */
+ const char *pszWriteMSRRC;
+ /** The name of the RC ReadMSR entry point. */
+ const char *pszReadMSRRC;
+ /** The name of the RC BusDeliver entry point. */
+ const char *pszBusDeliverRC;
+ /** The name of the RC LocalInterrupt entry point. */
+ const char *pszLocalInterruptRC;
+
+ /** The name of the R0 GetInterrupt entry point. */
+ const char *pszGetInterruptR0;
+ /** The name of the R0 HasPendingIrq entry point. */
+ const char *pszHasPendingIrqR0;
+ /** The name of the R0 SetBase entry point. */
+ const char *pszSetBaseR0;
+ /** The name of the R0 GetBase entry point. */
+ const char *pszGetBaseR0;
+ /** The name of the R0 SetTPR entry point. */
+ const char *pszSetTPRR0;
+ /** The name of the R0 GetTPR entry point. */
+ const char *pszGetTPRR0;
+ /** The name of the R0 WriteMSR entry point. */
+ const char *pszWriteMSRR0;
+ /** The name of the R0 ReadMSR entry point. */
+ const char *pszReadMSRR0;
+ /** The name of the R0 BusDeliver entry point. */
+ const char *pszBusDeliverR0;
+ /** The name of the R0 LocalInterrupt entry point. */
+ const char *pszLocalInterruptR0;
+
+} PDMAPICREG;
+/** Pointer to an APIC registration structure. */
+typedef PDMAPICREG *PPDMAPICREG;
+
+/** Current PDMAPICREG version number. */
+#define PDM_APICREG_VERSION PDM_VERSION_MAKE(0xfff6, 2, 0)
+
+
+/**
+ * APIC version argument for pfnChangeFeature.
+ */
+typedef enum PDMAPICVERSION
+{
+ /** Invalid 0 entry. */
+ PDMAPICVERSION_INVALID = 0,
+ /** No APIC. */
+ PDMAPICVERSION_NONE,
+ /** Standard APIC (X86_CPUID_FEATURE_EDX_APIC). */
+ PDMAPICVERSION_APIC,
+ /** Intel X2APIC (X86_CPUID_FEATURE_ECX_X2APIC). */
+ PDMAPICVERSION_X2APIC,
+ /** The usual 32-bit paranoia. */
+ PDMAPICVERSION_32BIT_HACK = 0x7fffffff
+} PDMAPICVERSION;
+
+/**
+ * APIC irq argument for SetInterruptFF.
+ */
+typedef enum PDMAPICIRQ
+{
+ /** Invalid 0 entry. */
+ PDMAPICIRQ_INVALID = 0,
+ /** Normal hardware interrupt. */
+ PDMAPICIRQ_HARDWARE,
+ /** NMI. */
+ PDMAPICIRQ_NMI,
+ /** SMI. */
+ PDMAPICIRQ_SMI,
+ /** ExtINT (HW interrupt via PIC). */
+ PDMAPICIRQ_EXTINT,
+ /** The usual 32-bit paranoia. */
+ PDMAPICIRQ_32BIT_HACK = 0x7fffffff
+} PDMAPICIRQ;
+
+
+/**
+ * APIC RC helpers.
+ */
+typedef struct PDMAPICHLPRC
+{
+ /** Structure version. PDM_APICHLPRC_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmType IRQ type.
+ * @param idCpu Virtual CPU to set flag upon.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
+
+ /**
+ * Clear the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmType IRQ type.
+ * @param idCpu Virtual CPU to clear flag upon.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
+
+ /**
+ * Calculates an IRQ tag for a timer, IPI or similar event.
+ *
+ * @returns The IRQ tag.
+ * @param pDevIns Device instance of the APIC.
+ * @param u8Level PDM_IRQ_LEVEL_HIGH or PDM_IRQ_LEVEL_FLIP_FLOP.
+ */
+ DECLRCCALLBACKMEMBER(uint32_t, pfnCalcIrqTag,(PPDMDEVINS pDevIns, uint8_t u8Level));
+
+ /**
+ * Modifies APIC-related bits in the CPUID feature mask.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmVersion Supported APIC version.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The APIC device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The APIC device instance.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the virtual CPU id corresponding to the current EMT.
+ *
+ * @param pDevIns The APIC device instance.
+ */
+ DECLRCCALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMAPICHLPRC;
+/** Pointer to APIC GC helpers. */
+typedef RCPTRTYPE(PDMAPICHLPRC *) PPDMAPICHLPRC;
+/** Pointer to const APIC helpers. */
+typedef RCPTRTYPE(const PDMAPICHLPRC *) PCPDMAPICHLPRC;
+
+/** Current PDMAPICHLPRC version number. */
+#define PDM_APICHLPRC_VERSION PDM_VERSION_MAKE(0xfff5, 2, 0)
+
+
+/**
+ * APIC R0 helpers.
+ */
+typedef struct PDMAPICHLPR0
+{
+ /** Structure version. PDM_APICHLPR0_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmType IRQ type.
+ * @param idCpu Virtual CPU to set flag upon.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
+
+ /**
+ * Clear the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmType IRQ type.
+ * @param idCpu Virtual CPU to clear flag upon.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
+
+ /**
+ * Calculates an IRQ tag for a timer, IPI or similar event.
+ *
+ * @returns The IRQ tag.
+ * @param pDevIns Device instance of the APIC.
+ * @param u8Level PDM_IRQ_LEVEL_HIGH or PDM_IRQ_LEVEL_FLIP_FLOP.
+ */
+ DECLR0CALLBACKMEMBER(uint32_t, pfnCalcIrqTag,(PPDMDEVINS pDevIns, uint8_t u8Level));
+
+ /**
+ * Modifies APIC-related bits in the CPUID feature mask.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmVersion Supported APIC version.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The APIC device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The APIC device instance.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the virtual CPU id corresponding to the current EMT.
+ *
+ * @param pDevIns The APIC device instance.
+ */
+ DECLR0CALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMAPICHLPR0;
+/** Pointer to APIC GC helpers. */
+typedef RCPTRTYPE(PDMAPICHLPR0 *) PPDMAPICHLPR0;
+/** Pointer to const APIC helpers. */
+typedef R0PTRTYPE(const PDMAPICHLPR0 *) PCPDMAPICHLPR0;
+
+/** Current PDMAPICHLPR0 version number. */
+#define PDM_APICHLPR0_VERSION PDM_VERSION_MAKE(0xfff4, 2, 0)
+
+/**
+ * APIC R3 helpers.
+ */
+typedef struct PDMAPICHLPR3
+{
+ /** Structure version. PDM_APICHLPR3_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmType IRQ type.
+ * @param idCpu Virtual CPU to set flag upon.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
+
+ /**
+ * Clear the interrupt force action flag.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmType IRQ type.
+ * @param idCpu Virtual CPU to clear flag upon.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnClearInterruptFF,(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu));
+
+ /**
+ * Calculates an IRQ tag for a timer, IPI or similar event.
+ *
+ * @returns The IRQ tag.
+ * @param pDevIns Device instance of the APIC.
+ * @param u8Level PDM_IRQ_LEVEL_HIGH or PDM_IRQ_LEVEL_FLIP_FLOP.
+ */
+ DECLR3CALLBACKMEMBER(uint32_t, pfnCalcIrqTag,(PPDMDEVINS pDevIns, uint8_t u8Level));
+
+ /**
+ * Modifies APIC-related bits in the CPUID feature mask.
+ *
+ * @param pDevIns Device instance of the APIC.
+ * @param enmVersion Supported APIC version.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnChangeFeature,(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion));
+
+ /**
+ * Get the virtual CPU id corresponding to the current EMT.
+ *
+ * @param pDevIns The APIC device instance.
+ */
+ DECLR3CALLBACKMEMBER(VMCPUID, pfnGetCpuId,(PPDMDEVINS pDevIns));
+
+ /**
+ * Sends SIPI to given virtual CPU.
+ *
+ * @param pDevIns The APIC device instance.
+ * @param idCpu Virtual CPU to perform SIPI on
+ * @param iVector SIPI vector
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSendSipi,(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector));
+
+ /**
+ * Sends init IPI to given virtual CPU, should result in reset and
+ * halting till SIPI.
+ *
+ * @param pDevIns The APIC device instance.
+ * @param idCpu Virtual CPU to perform SIPI on
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSendInitIpi,(PPDMDEVINS pDevIns, VMCPUID idCpu));
+
+ /**
+ * Gets the address of the RC APIC helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the RC helpers.
+ *
+ * @returns GC pointer to the APIC helpers.
+ * @param pDevIns Device instance of the APIC.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMAPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the R0 APIC helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the R0 helpers.
+ *
+ * @returns R0 pointer to the APIC helpers.
+ * @param pDevIns Device instance of the APIC.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the critical section used to synchronize the PICs, PCI and stuff.
+ *
+ * @returns Ring-3 pointer to the critical section.
+ * @param pDevIns The APIC device instance.
+ */
+ DECLR3CALLBACKMEMBER(R3PTRTYPE(PPDMCRITSECT), pfnGetR3CritSect,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the critical section used to synchronize the PICs, PCI and stuff.
+ *
+ * @returns Raw-mode context pointer to the critical section.
+ * @param pDevIns The APIC device instance.
+ */
+ DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnGetRCCritSect,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the critical section used to synchronize the PICs, PCI and stuff.
+ *
+ * @returns Ring-0 pointer to the critical section.
+ * @param pDevIns The APIC device instance.
+ */
+ DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnGetR0CritSect,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMAPICHLPR3;
+/** Pointer to APIC helpers. */
+typedef R3PTRTYPE(PDMAPICHLPR3 *) PPDMAPICHLPR3;
+/** Pointer to const APIC helpers. */
+typedef R3PTRTYPE(const PDMAPICHLPR3 *) PCPDMAPICHLPR3;
+
+/** Current PDMAPICHLP version number. */
+#define PDM_APICHLPR3_VERSION PDM_VERSION_MAKE(0xfff3, 2, 0)
+
+
+/**
+ * I/O APIC registration structure.
+ */
+typedef struct PDMIOAPICREG
+{
+ /** Struct version+magic number (PDM_IOAPICREG_VERSION). */
+ uint32_t u32Version;
+
+ /**
+ * Set the an IRQ.
+ *
+ * @param pDevIns Device instance of the I/O APIC.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetIrqR3,(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc));
+
+ /** The name of the RC SetIrq entry point. */
+ const char *pszSetIrqRC;
+
+ /** The name of the R0 SetIrq entry point. */
+ const char *pszSetIrqR0;
+
+ /**
+ * Send a MSI.
+ *
+ * @param pDevIns Device instance of the I/O APIC.
+ * @param GCPhys Request address.
+ * @param uValue Request value.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSendMsiR3,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc));
+
+ /** The name of the RC SendMsi entry point. */
+ const char *pszSendMsiRC;
+
+ /** The name of the R0 SendMsi entry point. */
+ const char *pszSendMsiR0;
+} PDMIOAPICREG;
+/** Pointer to an APIC registration structure. */
+typedef PDMIOAPICREG *PPDMIOAPICREG;
+
+/** Current PDMAPICREG version number. */
+#define PDM_IOAPICREG_VERSION PDM_VERSION_MAKE(0xfff2, 3, 0)
+
+
+/**
+ * IOAPIC RC helpers.
+ */
+typedef struct PDMIOAPICHLPRC
+{
+ /** Structure version. PDM_IOAPICHLPRC_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Private interface between the IOAPIC and APIC.
+ *
+ * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
+ *
+ * @returns status code.
+ * @param pDevIns Device instance of the IOAPIC.
+ * @param u8Dest See APIC implementation.
+ * @param u8DestMode See APIC implementation.
+ * @param u8DeliveryMode See APIC implementation.
+ * @param iVector See APIC implementation.
+ * @param u8Polarity See APIC implementation.
+ * @param u8TriggerMode See APIC implementation.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLRCCALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+ uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The IOAPIC device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The IOAPIC device instance.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMIOAPICHLPRC;
+/** Pointer to IOAPIC RC helpers. */
+typedef RCPTRTYPE(PDMIOAPICHLPRC *) PPDMIOAPICHLPRC;
+/** Pointer to const IOAPIC helpers. */
+typedef RCPTRTYPE(const PDMIOAPICHLPRC *) PCPDMIOAPICHLPRC;
+
+/** Current PDMIOAPICHLPRC version number. */
+#define PDM_IOAPICHLPRC_VERSION PDM_VERSION_MAKE(0xfff1, 2, 0)
+
+
+/**
+ * IOAPIC R0 helpers.
+ */
+typedef struct PDMIOAPICHLPR0
+{
+ /** Structure version. PDM_IOAPICHLPR0_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Private interface between the IOAPIC and APIC.
+ *
+ * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
+ *
+ * @returns status code.
+ * @param pDevIns Device instance of the IOAPIC.
+ * @param u8Dest See APIC implementation.
+ * @param u8DestMode See APIC implementation.
+ * @param u8DeliveryMode See APIC implementation.
+ * @param iVector See APIC implementation.
+ * @param u8Polarity See APIC implementation.
+ * @param u8TriggerMode See APIC implementation.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR0CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+ uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to acquire the lock.
+ * @param pDevIns The IOAPIC device instance.
+ * @param rc What to return if we fail to acquire the lock.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The IOAPIC device instance.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMIOAPICHLPR0;
+/** Pointer to IOAPIC R0 helpers. */
+typedef R0PTRTYPE(PDMIOAPICHLPR0 *) PPDMIOAPICHLPR0;
+/** Pointer to const IOAPIC helpers. */
+typedef R0PTRTYPE(const PDMIOAPICHLPR0 *) PCPDMIOAPICHLPR0;
+
+/** Current PDMIOAPICHLPR0 version number. */
+#define PDM_IOAPICHLPR0_VERSION PDM_VERSION_MAKE(0xfff0, 2, 0)
+
+/**
+ * IOAPIC R3 helpers.
+ */
+typedef struct PDMIOAPICHLPR3
+{
+ /** Structure version. PDM_IOAPICHLPR3_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Private interface between the IOAPIC and APIC.
+ *
+ * See comments about this hack on PDMAPICREG::pfnBusDeliverR3.
+ *
+ * @returns status code
+ * @param pDevIns Device instance of the IOAPIC.
+ * @param u8Dest See APIC implementation.
+ * @param u8DestMode See APIC implementation.
+ * @param u8DeliveryMode See APIC implementation.
+ * @param iVector See APIC implementation.
+ * @param u8Polarity See APIC implementation.
+ * @param u8TriggerMode See APIC implementation.
+ * @param uTagSrc The IRQ tag and source (for tracing).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnApicBusDeliver,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
+ uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc));
+
+ /**
+ * Acquires the PDM lock.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns Fatal error on failure.
+ * @param pDevIns The IOAPIC device instance.
+ * @param rc Dummy for making the interface identical to the GC and R0 versions.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMDEVINS pDevIns, int rc));
+
+ /**
+ * Releases the PDM lock.
+ *
+ * @param pDevIns The IOAPIC device instance.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUnlock,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the RC IOAPIC helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the RC helpers.
+ *
+ * @returns RC pointer to the IOAPIC helpers.
+ * @param pDevIns Device instance of the IOAPIC.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the R0 IOAPIC helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the R0 helpers.
+ *
+ * @returns R0 pointer to the IOAPIC helpers.
+ * @param pDevIns Device instance of the IOAPIC.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMIOAPICHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMIOAPICHLPR3;
+/** Pointer to IOAPIC R3 helpers. */
+typedef R3PTRTYPE(PDMIOAPICHLPR3 *) PPDMIOAPICHLPR3;
+/** Pointer to const IOAPIC helpers. */
+typedef R3PTRTYPE(const PDMIOAPICHLPR3 *) PCPDMIOAPICHLPR3;
+
+/** Current PDMIOAPICHLPR3 version number. */
+#define PDM_IOAPICHLPR3_VERSION PDM_VERSION_MAKE(0xffef, 2, 0)
+
+
+/**
+ * HPET registration structure.
+ */
+typedef struct PDMHPETREG
+{
+ /** Struct version+magic number (PDM_HPETREG_VERSION). */
+ uint32_t u32Version;
+
+} PDMHPETREG;
+/** Pointer to an HPET registration structure. */
+typedef PDMHPETREG *PPDMHPETREG;
+
+/** Current PDMHPETREG version number. */
+#define PDM_HPETREG_VERSION PDM_VERSION_MAKE(0xffe2, 1, 0)
+
+/**
+ * HPET RC helpers.
+ *
+ * @remarks Keep this around in case HPET will need PDM interaction in again RC
+ * at some later point.
+ */
+typedef struct PDMHPETHLPRC
+{
+ /** Structure version. PDM_HPETHLPRC_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMHPETHLPRC;
+
+/** Pointer to HPET RC helpers. */
+typedef RCPTRTYPE(PDMHPETHLPRC *) PPDMHPETHLPRC;
+/** Pointer to const HPET RC helpers. */
+typedef RCPTRTYPE(const PDMHPETHLPRC *) PCPDMHPETHLPRC;
+
+/** Current PDMHPETHLPRC version number. */
+#define PDM_HPETHLPRC_VERSION PDM_VERSION_MAKE(0xffee, 2, 0)
+
+
+/**
+ * HPET R0 helpers.
+ *
+ * @remarks Keep this around in case HPET will need PDM interaction in again R0
+ * at some later point.
+ */
+typedef struct PDMHPETHLPR0
+{
+ /** Structure version. PDM_HPETHLPR0_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMHPETHLPR0;
+
+/** Pointer to HPET R0 helpers. */
+typedef R0PTRTYPE(PDMHPETHLPR0 *) PPDMHPETHLPR0;
+/** Pointer to const HPET R0 helpers. */
+typedef R0PTRTYPE(const PDMHPETHLPR0 *) PCPDMHPETHLPR0;
+
+/** Current PDMHPETHLPR0 version number. */
+#define PDM_HPETHLPR0_VERSION PDM_VERSION_MAKE(0xffed, 2, 0)
+
+/**
+ * HPET R3 helpers.
+ */
+typedef struct PDMHPETHLPR3
+{
+ /** Structure version. PDM_HPETHLP_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Gets the address of the RC HPET helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the RC helpers.
+ *
+ * @returns RC pointer to the HPET helpers.
+ * @param pDevIns Device instance of the HPET.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMHPETHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the R0 HPET helpers.
+ *
+ * This should be called at both construction and relocation time
+ * to obtain the correct address of the R0 helpers.
+ *
+ * @returns R0 pointer to the HPET helpers.
+ * @param pDevIns Device instance of the HPET.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMHPETHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Set legacy mode on PIT and RTC.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to set legacy mode.
+ * @param pDevIns Device instance of the HPET.
+ * @param fActivated Whether legacy mode is activated or deactivated.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetLegacyMode,(PPDMDEVINS pDevIns, bool fActivated));
+
+
+ /**
+ * Set IRQ, bypassing ISA bus override rules.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns rc if we failed to set legacy mode.
+ * @param pDevIns Device instance of the HPET.
+ * @param fActivate Activate or deactivate legacy mode.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMHPETHLPR3;
+
+/** Pointer to HPET R3 helpers. */
+typedef R3PTRTYPE(PDMHPETHLPR3 *) PPDMHPETHLPR3;
+/** Pointer to const HPET R3 helpers. */
+typedef R3PTRTYPE(const PDMHPETHLPR3 *) PCPDMHPETHLPR3;
+
+/** Current PDMHPETHLPR3 version number. */
+#define PDM_HPETHLPR3_VERSION PDM_VERSION_MAKE(0xffec, 2, 0)
+
+
+/**
+ * Raw PCI device registration structure.
+ */
+typedef struct PDMPCIRAWREG
+{
+ /** Struct version+magic number (PDM_PCIRAWREG_VERSION). */
+ uint32_t u32Version;
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPCIRAWREG;
+/** Pointer to a raw PCI registration structure. */
+typedef PDMPCIRAWREG *PPDMPCIRAWREG;
+
+/** Current PDMPCIRAWREG version number. */
+#define PDM_PCIRAWREG_VERSION PDM_VERSION_MAKE(0xffe1, 1, 0)
+
+/**
+ * Raw PCI device raw-mode context helpers.
+ */
+typedef struct PDMPCIRAWHLPRC
+{
+ /** Structure version and magic number (PDM_PCIRAWHLPRC_VERSION). */
+ uint32_t u32Version;
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPCIRAWHLPRC;
+/** Pointer to a raw PCI deviec raw-mode context helper structure. */
+typedef RCPTRTYPE(PDMPCIRAWHLPRC *) PPDMPCIRAWHLPRC;
+/** Pointer to a const raw PCI deviec raw-mode context helper structure. */
+typedef RCPTRTYPE(const PDMPCIRAWHLPRC *) PCPDMPCIRAWHLPRC;
+
+/** Current PDMPCIRAWHLPRC version number. */
+#define PDM_PCIRAWHLPRC_VERSION PDM_VERSION_MAKE(0xffe0, 1, 0)
+
+/**
+ * Raw PCI device ring-0 context helpers.
+ */
+typedef struct PDMPCIRAWHLPR0
+{
+ /** Structure version and magic number (PDM_PCIRAWHLPR0_VERSION). */
+ uint32_t u32Version;
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPCIRAWHLPR0;
+/** Pointer to a raw PCI deviec ring-0 context helper structure. */
+typedef R0PTRTYPE(PDMPCIRAWHLPR0 *) PPDMPCIRAWHLPR0;
+/** Pointer to a const raw PCI deviec ring-0 context helper structure. */
+typedef R0PTRTYPE(const PDMPCIRAWHLPR0 *) PCPDMPCIRAWHLPR0;
+
+/** Current PDMPCIRAWHLPR0 version number. */
+#define PDM_PCIRAWHLPR0_VERSION PDM_VERSION_MAKE(0xffdf, 1, 0)
+
+
+/**
+ * Raw PCI device ring-3 context helpers.
+ */
+typedef struct PDMPCIRAWHLPR3
+{
+ /** Undefined structure version and magic number. */
+ uint32_t u32Version;
+
+ /**
+ * Gets the address of the RC raw PCI device helpers.
+ *
+ * This should be called at both construction and relocation time to obtain
+ * the correct address of the RC helpers.
+ *
+ * @returns RC pointer to the raw PCI device helpers.
+ * @param pDevIns Device instance of the raw PCI device.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPRC, pfnGetRCHelpers,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the address of the R0 raw PCI device helpers.
+ *
+ * This should be called at both construction and relocation time to obtain
+ * the correct address of the R0 helpers.
+ *
+ * @returns R0 pointer to the raw PCI device helpers.
+ * @param pDevIns Device instance of the raw PCI device.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMPCIRAWHLPR0, pfnGetR0Helpers,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMPCIRAWHLPR3;
+/** Pointer to raw PCI R3 helpers. */
+typedef R3PTRTYPE(PDMPCIRAWHLPR3 *) PPDMPCIRAWHLPR3;
+/** Pointer to const raw PCI R3 helpers. */
+typedef R3PTRTYPE(const PDMPCIRAWHLPR3 *) PCPDMPCIRAWHLPR3;
+
+/** Current PDMPCIRAWHLPR3 version number. */
+#define PDM_PCIRAWHLPR3_VERSION PDM_VERSION_MAKE(0xffde, 1, 0)
+
+
+#ifdef IN_RING3
+
+/**
+ * DMA Transfer Handler.
+ *
+ * @returns Number of bytes transferred.
+ * @param pDevIns Device instance of the DMA.
+ * @param pvUser User pointer.
+ * @param uChannel Channel number.
+ * @param off DMA position.
+ * @param cb Block size.
+ */
+typedef DECLCALLBACK(uint32_t) FNDMATRANSFERHANDLER(PPDMDEVINS pDevIns, void *pvUser, unsigned uChannel, uint32_t off, uint32_t cb);
+/** Pointer to a FNDMATRANSFERHANDLER(). */
+typedef FNDMATRANSFERHANDLER *PFNDMATRANSFERHANDLER;
+
+/**
+ * DMA Controller registration structure.
+ */
+typedef struct PDMDMAREG
+{
+ /** Structure version number. PDM_DMACREG_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Execute pending transfers.
+ *
+ * @returns A more work indiciator. I.e. 'true' if there is more to be done, and 'false' if all is done.
+ * @param pDevIns Device instance of the DMAC.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnRun,(PPDMDEVINS pDevIns));
+
+ /**
+ * Register transfer function for DMA channel.
+ *
+ * @param pDevIns Device instance of the DMAC.
+ * @param uChannel Channel number.
+ * @param pfnTransferHandler Device specific transfer function.
+ * @param pvUSer User pointer to be passed to the callback.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnRegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
+
+ /**
+ * Read memory
+ *
+ * @returns Number of bytes read.
+ * @param pDevIns Device instance of the DMAC.
+ * @param pvBuffer Pointer to target buffer.
+ * @param off DMA position.
+ * @param cbBlock Block size.
+ */
+ DECLR3CALLBACKMEMBER(uint32_t, pfnReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock));
+
+ /**
+ * Write memory
+ *
+ * @returns Number of bytes written.
+ * @param pDevIns Device instance of the DMAC.
+ * @param pvBuffer Memory to write.
+ * @param off DMA position.
+ * @param cbBlock Block size.
+ */
+ DECLR3CALLBACKMEMBER(uint32_t, pfnWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock));
+
+ /**
+ * Set the DREQ line.
+ *
+ * @param pDevIns Device instance of the DMAC.
+ * @param uChannel Channel number.
+ * @param uLevel Level of the line.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
+
+ /**
+ * Get channel mode
+ *
+ * @returns Channel mode.
+ * @param pDevIns Device instance of the DMAC.
+ * @param uChannel Channel number.
+ */
+ DECLR3CALLBACKMEMBER(uint8_t, pfnGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
+
+} PDMDMACREG;
+/** Pointer to a DMAC registration structure. */
+typedef PDMDMACREG *PPDMDMACREG;
+
+/** Current PDMDMACREG version number. */
+#define PDM_DMACREG_VERSION PDM_VERSION_MAKE(0xffeb, 1, 0)
+
+
+/**
+ * DMA Controller device helpers.
+ */
+typedef struct PDMDMACHLP
+{
+ /** Structure version. PDM_DMACHLP_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /* to-be-defined */
+
+} PDMDMACHLP;
+/** Pointer to DMAC helpers. */
+typedef PDMDMACHLP *PPDMDMACHLP;
+/** Pointer to const DMAC helpers. */
+typedef const PDMDMACHLP *PCPDMDMACHLP;
+
+/** Current PDMDMACHLP version number. */
+#define PDM_DMACHLP_VERSION PDM_VERSION_MAKE(0xffea, 1, 0)
+
+#endif /* IN_RING3 */
+
+
+
+/**
+ * RTC registration structure.
+ */
+typedef struct PDMRTCREG
+{
+ /** Structure version number. PDM_RTCREG_VERSION defines the current version. */
+ uint32_t u32Version;
+ uint32_t u32Alignment; /**< structure size alignment. */
+
+ /**
+ * Write to a CMOS register and update the checksum if necessary.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the RTC.
+ * @param iReg The CMOS register index.
+ * @param u8Value The CMOS register value.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
+
+ /**
+ * Read a CMOS register.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the RTC.
+ * @param iReg The CMOS register index.
+ * @param pu8Value Where to store the CMOS register value.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
+
+} PDMRTCREG;
+/** Pointer to a RTC registration structure. */
+typedef PDMRTCREG *PPDMRTCREG;
+/** Pointer to a const RTC registration structure. */
+typedef const PDMRTCREG *PCPDMRTCREG;
+
+/** Current PDMRTCREG version number. */
+#define PDM_RTCREG_VERSION PDM_VERSION_MAKE(0xffe9, 1, 0)
+
+
+/**
+ * RTC device helpers.
+ */
+typedef struct PDMRTCHLP
+{
+ /** Structure version. PDM_RTCHLP_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /* to-be-defined */
+
+} PDMRTCHLP;
+/** Pointer to RTC helpers. */
+typedef PDMRTCHLP *PPDMRTCHLP;
+/** Pointer to const RTC helpers. */
+typedef const PDMRTCHLP *PCPDMRTCHLP;
+
+/** Current PDMRTCHLP version number. */
+#define PDM_RTCHLP_VERSION PDM_VERSION_MAKE(0xffe8, 1, 0)
+
+
+
+#ifdef IN_RING3
+
+/**
+ * PDM Device API.
+ */
+typedef struct PDMDEVHLPR3
+{
+ /** Structure version. PDM_DEVHLPR3_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Register a number of I/O ports with a device.
+ *
+ * These callbacks are of course for the host context (HC).
+ * Register HC handlers before guest context (GC) handlers! There must be a
+ * HC handler for every GC handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the ports with.
+ * @param Port First port number in the range.
+ * @param cPorts Number of ports to register.
+ * @param pvUser User argument.
+ * @param pfnOut Pointer to function which is gonna handle OUT operations.
+ * @param pfnIn Pointer to function which is gonna handle IN operations.
+ * @param pfnOutStr Pointer to function which is gonna handle string OUT operations.
+ * @param pfnInStr Pointer to function which is gonna handle string IN operations.
+ * @param pszDesc Pointer to description string. This must not be freed.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnIOPortRegister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser,
+ PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+ PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc));
+
+ /**
+ * Register a number of I/O ports with a device for RC.
+ *
+ * These callbacks are for the raw-mode context (RC). Register ring-3 context
+ * (R3) handlers before raw-mode context handlers! There must be a R3 handler
+ * for every RC handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the ports with
+ * and which RC module to resolve the names
+ * against.
+ * @param Port First port number in the range.
+ * @param cPorts Number of ports to register.
+ * @param pvUser User argument.
+ * @param pszOut Name of the RC function which is gonna handle OUT operations.
+ * @param pszIn Name of the RC function which is gonna handle IN operations.
+ * @param pszOutStr Name of the RC function which is gonna handle string OUT operations.
+ * @param pszInStr Name of the RC function which is gonna handle string IN operations.
+ * @param pszDesc Pointer to description string. This must not be freed.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterRC,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
+ const char *pszOut, const char *pszIn,
+ const char *pszOutStr, const char *pszInStr, const char *pszDesc));
+
+ /**
+ * Register a number of I/O ports with a device.
+ *
+ * These callbacks are of course for the ring-0 host context (R0).
+ * Register R3 (HC) handlers before R0 (R0) handlers! There must be a R3 (HC) handler for every R0 handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the ports with.
+ * @param Port First port number in the range.
+ * @param cPorts Number of ports to register.
+ * @param pvUser User argument. (if pointer, then it must be in locked memory!)
+ * @param pszOut Name of the R0 function which is gonna handle OUT operations.
+ * @param pszIn Name of the R0 function which is gonna handle IN operations.
+ * @param pszOutStr Name of the R0 function which is gonna handle string OUT operations.
+ * @param pszInStr Name of the R0 function which is gonna handle string IN operations.
+ * @param pszDesc Pointer to description string. This must not be freed.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnIOPortRegisterR0,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
+ const char *pszOut, const char *pszIn,
+ const char *pszOutStr, const char *pszInStr, const char *pszDesc));
+
+ /**
+ * Deregister I/O ports.
+ *
+ * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance owning the ports.
+ * @param Port First port number in the range.
+ * @param cPorts Number of ports to deregister.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnIOPortDeregister,(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts));
+
+ /**
+ * Register a Memory Mapped I/O (MMIO) region.
+ *
+ * These callbacks are of course for the ring-3 context (R3). Register HC
+ * handlers before raw-mode context (RC) and ring-0 context (R0) handlers! There
+ * must be a R3 handler for every RC and R0 handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the MMIO with.
+ * @param GCPhysStart First physical address in the range.
+ * @param cbRange The size of the range (in bytes).
+ * @param pvUser User argument.
+ * @param pfnWrite Pointer to function which is gonna handle Write operations.
+ * @param pfnRead Pointer to function which is gonna handle Read operations.
+ * @param pfnFill Pointer to function which is gonna handle Fill/memset operations. (optional)
+ * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
+ * @param pszDesc Pointer to description string. This must not be freed.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIORegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser,
+ PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, PFNIOMMMIOFILL pfnFill,
+ uint32_t fFlags, const char *pszDesc));
+
+ /**
+ * Register a Memory Mapped I/O (MMIO) region for GC.
+ *
+ * These callbacks are for the raw-mode context (RC). Register ring-3 context
+ * (R3) handlers before guest context handlers! There must be a R3 handler for
+ * every RC handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the MMIO with.
+ * @param GCPhysStart First physical address in the range.
+ * @param cbRange The size of the range (in bytes).
+ * @param pvUser User argument.
+ * @param pszWrite Name of the RC function which is gonna handle Write operations.
+ * @param pszRead Name of the RC function which is gonna handle Read operations.
+ * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIORegisterRC,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser,
+ const char *pszWrite, const char *pszRead, const char *pszFill));
+
+ /**
+ * Register a Memory Mapped I/O (MMIO) region for R0.
+ *
+ * These callbacks are for the ring-0 host context (R0). Register ring-3
+ * constext (R3) handlers before R0 handlers! There must be a R3 handler for
+ * every R0 handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the MMIO with.
+ * @param GCPhysStart First physical address in the range.
+ * @param cbRange The size of the range (in bytes).
+ * @param pvUser User argument. (if pointer, then it must be in locked memory!)
+ * @param pszWrite Name of the RC function which is gonna handle Write operations.
+ * @param pszRead Name of the RC function which is gonna handle Read operations.
+ * @param pszFill Name of the RC function which is gonna handle Fill/memset operations. (optional)
+ * @param pszDesc Obsolete. NULL is fine.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIORegisterR0,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser,
+ const char *pszWrite, const char *pszRead, const char *pszFill));
+
+ /**
+ * Deregister a Memory Mapped I/O (MMIO) region.
+ *
+ * This naturally affects both guest context (GC), ring-0 (R0) and ring-3 (R3/HC) handlers.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance owning the MMIO region(s).
+ * @param GCPhysStart First physical address in the range.
+ * @param cbRange The size of the range (in bytes).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIODeregister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange));
+
+ /**
+ * Allocate and register a MMIO2 region.
+ *
+ * As mentioned elsewhere, MMIO2 is just RAM spelled differently. It's
+ * RAM associated with a device. It is also non-shared memory with a
+ * permanent ring-3 mapping and page backing (presently).
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance.
+ * @param iRegion The region number. Use the PCI region number as
+ * this must be known to the PCI bus device too. If
+ * it's not associated with the PCI device, then
+ * any number up to UINT8_MAX is fine.
+ * @param cb The size (in bytes) of the region.
+ * @param fFlags Reserved for future use, must be zero.
+ * @param ppv Where to store the address of the ring-3 mapping
+ * of the memory.
+ * @param pszDesc Pointer to description string. This must not be
+ * freed.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIO2Register,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc));
+
+ /**
+ * Deregisters and frees a MMIO2 region.
+ *
+ * Any physical (and virtual) access handlers registered for the region must
+ * be deregistered before calling this function.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iRegion The region number used during registration.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIO2Deregister,(PPDMDEVINS pDevIns, uint32_t iRegion));
+
+ /**
+ * Maps a MMIO2 region into the physical memory space.
+ *
+ * A MMIO2 range may overlap with base memory if a lot of RAM
+ * is configured for the VM, in which case we'll drop the base
+ * memory pages. Presently we will make no attempt to preserve
+ * anything that happens to be present in the base memory that
+ * is replaced, this is of course incorrectly but it's too much
+ * effort.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iRegion The region number used during registration.
+ * @param GCPhys The physical address to map it at.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIO2Map,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
+
+ /**
+ * Unmaps a MMIO2 region previously mapped using pfnMMIO2Map.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iRegion The region number used during registration.
+ * @param GCPhys The physical address it's currently mapped at.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIO2Unmap,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys));
+
+ /**
+ * Maps a portion of an MMIO2 region into the hypervisor region.
+ *
+ * Callers of this API must never deregister the MMIO2 region before the
+ * VM is powered off.
+ *
+ * @return VBox status code.
+ * @param pDevIns The device owning the MMIO2 memory.
+ * @param iRegion The region.
+ * @param off The offset into the region. Will be rounded down
+ * to closest page boundary.
+ * @param cb The number of bytes to map. Will be rounded up
+ * to the closest page boundary.
+ * @param pszDesc Mapping description.
+ * @param pRCPtr Where to store the RC address.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMHyperMapMMIO2,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
+ const char *pszDesc, PRTRCPTR pRCPtr));
+
+ /**
+ * Maps a portion of an MMIO2 region into kernel space (host).
+ *
+ * The kernel mapping will become invalid when the MMIO2 memory is deregistered
+ * or the VM is terminated.
+ *
+ * @return VBox status code.
+ * @param pDevIns The device owning the MMIO2 memory.
+ * @param iRegion The region.
+ * @param off The offset into the region. Must be page
+ * aligned.
+ * @param cb The number of bytes to map. Must be page
+ * aligned.
+ * @param pszDesc Mapping description.
+ * @param pR0Ptr Where to store the R0 address.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMMIO2MapKernel,(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
+ const char *pszDesc, PRTR0PTR pR0Ptr));
+
+ /**
+ * Register a ROM (BIOS) region.
+ *
+ * It goes without saying that this is read-only memory. The memory region must be
+ * in unassigned memory. I.e. from the top of the address space or on the PC in
+ * the 0xa0000-0xfffff range.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance owning the ROM region.
+ * @param GCPhysStart First physical address in the range.
+ * Must be page aligned!
+ * @param cbRange The size of the range (in bytes).
+ * Must be page aligned!
+ * @param pvBinary Pointer to the binary data backing the ROM image.
+ * @param cbBinary The size of the binary pointer. This must
+ * be equal or smaller than @a cbRange.
+ * @param fFlags Shadow ROM flags, PGMPHYS_ROM_FLAGS_* in pgm.h.
+ * @param pszDesc Pointer to description string. This must not be freed.
+ *
+ * @remark There is no way to remove the rom, automatically on device cleanup or
+ * manually from the device yet. At present I doubt we need such features...
+ */
+ DECLR3CALLBACKMEMBER(int, pfnROMRegister,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
+ const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc));
+
+ /**
+ * Changes the protection of shadowed ROM mapping.
+ *
+ * This is intented for use by the system BIOS, chipset or device in question to
+ * change the protection of shadowed ROM code after init and on reset.
+ *
+ * @param pDevIns The device instance.
+ * @param GCPhysStart Where the mapping starts.
+ * @param cbRange The size of the mapping.
+ * @param enmProt The new protection type.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnROMProtectShadow,(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt));
+
+ /**
+ * Register a save state data unit.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance.
+ * @param pszName Data unit name.
+ * @param uInstance The instance identifier of the data unit.
+ * This must together with the name be unique.
+ * @param uVersion Data layout version number.
+ * @param cbGuess The approximate amount of data in the unit.
+ * Only for progress indicators.
+ * @param pszBefore Name of data unit which we should be put in
+ * front of. Optional (NULL).
+ *
+ * @param pfnLivePrep Prepare live save callback, optional.
+ * @param pfnLiveExec Execute live save callback, optional.
+ * @param pfnLiveVote Vote live save callback, optional.
+ *
+ * @param pfnSavePrep Prepare save callback, optional.
+ * @param pfnSaveExec Execute save callback, optional.
+ * @param pfnSaveDone Done save callback, optional.
+ *
+ * @param pfnLoadPrep Prepare load callback, optional.
+ * @param pfnLoadExec Execute load callback, optional.
+ * @param pfnLoadDone Done load callback, optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
+ PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
+ PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
+ PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone));
+
+ /**
+ * Creates a timer.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance.
+ * @param enmClock The clock to use on this timer.
+ * @param pfnCallback Callback function.
+ * @param pvUser User argument for the callback.
+ * @param fFlags Flags, see TMTIMER_FLAGS_*.
+ * @param pszDesc Pointer to description string which must stay around
+ * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
+ * @param ppTimer Where to store the timer on success.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
+
+ /**
+ * Get the real world UTC time adjusted for VM lag, user offset and warpdrive.
+ *
+ * @returns pTime.
+ * @param pDevIns The device instance.
+ * @param pTime Where to store the time.
+ */
+ DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnTMUtcNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
+
+ /**
+ * Read physical memory.
+ *
+ * @returns VINF_SUCCESS (for now).
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address start reading from.
+ * @param pvBuf Where to put the read bits.
+ * @param cbRead How many bytes to read.
+ * @thread Any thread, but the call may involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+ /**
+ * Write to physical memory.
+ *
+ * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
+ * @param pDevIns The device instance.
+ * @param GCPhys Physical address to write to.
+ * @param pvBuf What to write.
+ * @param cbWrite How many bytes to write.
+ * @thread Any thread, but the call may involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Requests the mapping of a guest page into ring-3.
+ *
+ * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
+ * release it.
+ *
+ * This API will assume your intention is to write to the page, and will
+ * therefore replace shared and zero pages. If you do not intend to modify the
+ * page, use the pfnPhysGCPhys2CCPtrReadOnly() API.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
+ * backing or if the page has any active access handlers. The caller
+ * must fall back on using PGMR3PhysWriteExternal.
+ * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
+ *
+ * @param pVM The VM handle.
+ * @param GCPhys The guest physical address of the page that
+ * should be mapped.
+ * @param fFlags Flags reserved for future use, MBZ.
+ * @param ppv Where to store the address corresponding to
+ * GCPhys.
+ * @param pLock Where to store the lock information that
+ * pfnPhysReleasePageMappingLock needs.
+ *
+ * @remark Avoid calling this API from within critical sections (other than the
+ * PGM one) because of the deadlock risk when we have to delegating the
+ * task to an EMT.
+ * @thread Any.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtr,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock));
+
+ /**
+ * Requests the mapping of a guest page into ring-3, external threads.
+ *
+ * When you're done with the page, call pfnPhysReleasePageMappingLock() ASAP to
+ * release it.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical
+ * backing or if the page as an active ALL access handler. The caller
+ * must fall back on using PGMPhysRead.
+ * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address.
+ *
+ * @param pDevIns The device instance.
+ * @param GCPhys The guest physical address of the page that
+ * should be mapped.
+ * @param fFlags Flags reserved for future use, MBZ.
+ * @param ppv Where to store the address corresponding to
+ * GCPhys.
+ * @param pLock Where to store the lock information that
+ * pfnPhysReleasePageMappingLock needs.
+ *
+ * @remark Avoid calling this API from within critical sections.
+ * @thread Any.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPhysGCPhys2CCPtrReadOnly,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock));
+
+ /**
+ * Release the mapping of a guest page.
+ *
+ * This is the counter part of pfnPhysGCPhys2CCPtr and
+ * pfnPhysGCPhys2CCPtrReadOnly.
+ *
+ * @param pDevIns The device instance.
+ * @param pLock The lock structure initialized by the mapping
+ * function.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnPhysReleasePageMappingLock,(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock));
+
+ /**
+ * Read guest physical memory by virtual address.
+ *
+ * @param pDevIns The device instance.
+ * @param pvDst Where to put the read bits.
+ * @param GCVirtSrc Guest virtual address to start reading from.
+ * @param cb How many bytes to read.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPhysReadGCVirt,(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb));
+
+ /**
+ * Write to guest physical memory by virtual address.
+ *
+ * @param pDevIns The device instance.
+ * @param GCVirtDst Guest virtual address to write to.
+ * @param pvSrc What to write.
+ * @param cb How many bytes to write.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPhysWriteGCVirt,(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb));
+
+ /**
+ * Convert a guest virtual address to a guest physical address.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param GCPtr Guest virtual address.
+ * @param pGCPhys Where to store the GC physical address
+ * corresponding to GCPtr.
+ * @thread The emulation thread.
+ * @remark Careful with page boundaries.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPhysGCPtr2GCPhys, (PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys));
+
+ /**
+ * Allocate memory which is associated with current VM instance
+ * and automatically freed on it's destruction.
+ *
+ * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
+ * @param pDevIns The device instance.
+ * @param cb Number of bytes to allocate.
+ */
+ DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMDEVINS pDevIns, size_t cb));
+
+ /**
+ * Allocate memory which is associated with current VM instance
+ * and automatically freed on it's destruction. The memory is ZEROed.
+ *
+ * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
+ * @param pDevIns The device instance.
+ * @param cb Number of bytes to allocate.
+ */
+ DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMDEVINS pDevIns, size_t cb));
+
+ /**
+ * Free memory allocated with pfnMMHeapAlloc() and pfnMMHeapAllocZ().
+ *
+ * @param pDevIns The device instance.
+ * @param pv Pointer to the memory to free.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnMMHeapFree,(PPDMDEVINS pDevIns, void *pv));
+
+ /**
+ * Gets the VM state.
+ *
+ * @returns VM state.
+ * @param pDevIns The device instance.
+ * @thread Any thread (just keep in mind that it's volatile info).
+ */
+ DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
+
+ /**
+ * Checks if the VM was teleported and hasn't been fully resumed yet.
+ *
+ * @returns true / false.
+ * @param pDevIns The device instance.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDEVINS pDevIns));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDevIns The device instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDevIns The device instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
+
+ /**
+ * Stops the VM and enters the debugger to look at the guest state.
+ *
+ * Use the PDMDeviceDBGFStop() inline function with the RT_SRC_POS macro instead of
+ * invoking this function directly.
+ *
+ * @returns VBox status code which must be passed up to the VMM.
+ * @param pDevIns The device instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine The linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ * @param pszFormat Message. (optional)
+ * @param args Message parameters.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list args));
+
+ /**
+ * Register a info handler with DBGF,
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pszName The identifier of the info.
+ * @param pszDesc The description of the info and any arguments
+ * the handler may take.
+ * @param pfnHandler The handler function to be called to display the
+ * info.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler));
+
+ /**
+ * Gets the trace buffer handle.
+ *
+ * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
+ * really inteded for direct usage, thus no inline wrapper function.
+ *
+ * @returns Trace buffer handle or NIL_RTTRACEBUF.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
+
+ /**
+ * Registers a statistics sample if statistics are enabled.
+ *
+ * @param pDevIns Device instance of the DMA.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is
+ * pointing at.
+ * @param pszName Sample name. The name is on this form
+ * "/<component>/<sample>". Further nesting is
+ * possible.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc));
+
+ /**
+ * Same as pfnSTAMRegister except that the name is specified in a
+ * RTStrPrintf like fashion.
+ *
+ * @returns VBox status.
+ * @param pDevIns Device instance of the DMA.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is
+ * pointing at.
+ * @param enmVisibility Visibility type specifying whether unused
+ * statistics should be visible or not.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ * @param pszName The sample name format string.
+ * @param ... Arguments to the format string.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
+ STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...));
+
+ /**
+ * Same as pfnSTAMRegister except that the name is specified in a
+ * RTStrPrintfV like fashion.
+ *
+ * @returns VBox status.
+ * @param pDevIns Device instance of the DMA.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is
+ * pointing at.
+ * @param enmVisibility Visibility type specifying whether unused
+ * statistics should be visible or not.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ * @param pszName The sample name format string.
+ * @param args Arguments to the format string.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
+ STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
+
+ /**
+ * Reads data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+ /**
+ * Writes data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Registers the device with the default PCI bus.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pPciDev The PCI device structure.
+ * Any PCI enabled device must keep this in it's instance data!
+ * Fill in the PCI data config before registration, please.
+ * @remark This is the simple interface, a Ex interface will be created if
+ * more features are needed later.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIRegister,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev));
+
+ /**
+ * Initialize MSI support in a PCI device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pMsiReg MSI registartion structure.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIRegisterMsi,(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg));
+
+ /**
+ * Registers a I/O region (memory mapped or I/O ports) for a PCI device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iRegion The region number.
+ * @param cbRegion Size of the region.
+ * @param enmType PCI_ADDRESS_SPACE_MEM, PCI_ADDRESS_SPACE_IO or PCI_ADDRESS_SPACE_MEM_PREFETCH.
+ * @param pfnCallback Callback for doing the mapping.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIIORegionRegister,(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback));
+
+ /**
+ * Register PCI configuration space read/write callbacks.
+ *
+ * @param pDevIns The device instance.
+ * @param pPciDev The PCI device structure.
+ * If NULL the default PCI device for this device instance is used.
+ * @param pfnRead Pointer to the user defined PCI config read function.
+ * @param ppfnReadOld Pointer to function pointer which will receive the old (default)
+ * PCI config read function. This way, user can decide when (and if)
+ * to call default PCI config read function. Can be NULL.
+ * @param pfnWrite Pointer to the user defined PCI config write function.
+ * @param pfnWriteOld Pointer to function pointer which will receive the old (default)
+ * PCI config write function. This way, user can decide when (and if)
+ * to call default PCI config write function. Can be NULL.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(void, pfnPCISetConfigCallbacks,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
+ PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld));
+
+ /**
+ * Set the IRQ for a PCI device.
+ *
+ * @param pDevIns The device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Set the IRQ for a PCI device, but don't wait for EMT to process
+ * the request when not called from EMT.
+ *
+ * @param pDevIns The device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnPCISetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Set ISA IRQ for a device.
+ *
+ * @param pDevIns The device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Set the ISA IRQ for a device, but don't wait for EMT to process
+ * the request when not called from EMT.
+ *
+ * @param pDevIns The device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnISASetIrqNoWait,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Attaches a driver (chain) to the device.
+ *
+ * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
+ * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryDeviceLun().
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iLun The logical unit to attach.
+ * @param pBaseInterface Pointer to the base interface for that LUN. (device side / down)
+ * @param ppBaseInterface Where to store the pointer to the base interface. (driver side / up)
+ * @param pszDesc Pointer to a string describing the LUN. This string must remain valid
+ * for the live of the device instance.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc));
+
+ /**
+ * Create a queue.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param cbItem The size of a queue item.
+ * @param cItems The number of items in the queue.
+ * @param cMilliesInterval The number of milliseconds between polling the queue.
+ * If 0 then the emulation thread will be notified whenever an item arrives.
+ * @param pfnCallback The consumer function.
+ * @param fRZEnabled Set if the queue should work in RC and R0.
+ * @param pszName The queue base name. The instance number will be
+ * appended automatically.
+ * @param ppQueue Where to store the queue handle on success.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue));
+
+ /**
+ * Initializes a PDM critical section.
+ *
+ * The PDM critical sections are derived from the IPRT critical sections, but
+ * works in RC and R0 as well.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pCritSect Pointer to the critical section.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszNameFmt Format string for naming the critical section.
+ * For statistics and lock validation.
+ * @param va Arguments for the format string.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL,
+ const char *pszNameFmt, va_list va));
+
+ /**
+ * Gets the NOP critical section.
+ *
+ * @returns The ring-3 address of the NOP critical section.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(PPDMCRITSECT, pfnCritSectGetNop,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the NOP critical section.
+ *
+ * @returns The ring-0 address of the NOP critical section.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMCRITSECT), pfnCritSectGetNopR0,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the NOP critical section.
+ *
+ * @returns The raw-mode context address of the NOP critical section.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMCRITSECT), pfnCritSectGetNopRC,(PPDMDEVINS pDevIns));
+
+ /**
+ * Changes the device level critical section from the automatically created
+ * default to one desired by the device constructor.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pCritSect The critical section to use. NULL is not
+ * valid, instead use the NOP critical
+ * section.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetDeviceCritSect,(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect));
+
+ /**
+ * Creates a PDM thread.
+ *
+ * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
+ * resuming, and destroying the thread as the VM state changes.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param ppThread Where to store the thread 'handle'.
+ * @param pvUser The user argument to the thread function.
+ * @param pfnThread The thread function.
+ * @param pfnWakeup The wakup callback. This is called on the EMT
+ * thread when a state change is pending.
+ * @param cbStack See RTThreadCreate.
+ * @param enmType See RTThreadCreate.
+ * @param pszName See RTThreadCreate.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
+ PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
+
+ /**
+ * Set up asynchronous handling of a suspend, reset or power off notification.
+ *
+ * This shall only be called when getting the notification. It must be called
+ * for each one.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pfnAsyncNotify The callback.
+ * @thread EMT(0)
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify));
+
+ /**
+ * Notify EMT(0) that the device has completed the asynchronous notification
+ * handling.
+ *
+ * This can be called at any time, spurious calls will simply be ignored.
+ *
+ * @param pDevIns The device instance.
+ * @thread Any
+ */
+ DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDEVINS pDevIns));
+
+ /**
+ * Register the RTC device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pRtcReg Pointer to a RTC registration structure.
+ * @param ppRtcHlp Where to store the pointer to the helper
+ * functions.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRTCRegister,(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp));
+
+ /**
+ * Register the PCI Bus.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pPciBusReg Pointer to PCI bus registration structure.
+ * @param ppPciHlpR3 Where to store the pointer to the PCI Bus
+ * helpers.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPCIBusRegister,(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3));
+
+ /**
+ * Register the PIC device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pPicReg Pointer to a PIC registration structure.
+ * @param ppPicHlpR3 Where to store the pointer to the PIC HC
+ * helpers.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPICRegister,(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3));
+
+ /**
+ * Register the APIC device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pApicReg Pointer to a APIC registration structure.
+ * @param ppApicHlpR3 Where to store the pointer to the APIC helpers.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAPICRegister,(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3));
+
+ /**
+ * Register the I/O APIC device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pIoApicReg Pointer to a I/O APIC registration structure.
+ * @param ppIoApicHlpR3 Where to store the pointer to the IOAPIC
+ * helpers.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnIOAPICRegister,(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3));
+
+ /**
+ * Register the HPET device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pHpetReg Pointer to a HPET registration structure.
+ * @param ppHpetHlpR3 Where to store the pointer to the HPET
+ * helpers.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnHPETRegister,(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3));
+
+ /**
+ * Register a raw PCI device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pHpetReg Pointer to a raw PCI registration structure.
+ * @param ppPciRawHlpR3 Where to store the pointer to the raw PCI
+ * device helpers.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPciRawRegister,(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3));
+
+ /**
+ * Register the DMA device.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pDmacReg Pointer to a DMAC registration structure.
+ * @param ppDmacHlp Where to store the pointer to the DMA helpers.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDMACRegister,(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp));
+
+ /**
+ * Register transfer function for DMA channel.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param uChannel Channel number.
+ * @param pfnTransferHandler Device specific transfer callback function.
+ * @param pvUser User pointer to pass to the callback.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDMARegister,(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser));
+
+ /**
+ * Read memory.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param uChannel Channel number.
+ * @param pvBuffer Pointer to target buffer.
+ * @param off DMA position.
+ * @param cbBlock Block size.
+ * @param pcbRead Where to store the number of bytes which was
+ * read. optional.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDMAReadMemory,(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead));
+
+ /**
+ * Write memory.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param uChannel Channel number.
+ * @param pvBuffer Memory to write.
+ * @param off DMA position.
+ * @param cbBlock Block size.
+ * @param pcbWritten Where to store the number of bytes which was
+ * written. optional.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDMAWriteMemory,(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten));
+
+ /**
+ * Set the DREQ line.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance.
+ * @param uChannel Channel number.
+ * @param uLevel Level of the line.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDMASetDREQ,(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel));
+
+ /**
+ * Get channel mode.
+ *
+ * @returns Channel mode. See specs.
+ * @param pDevIns The device instance.
+ * @param uChannel Channel number.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(uint8_t, pfnDMAGetChannelMode,(PPDMDEVINS pDevIns, unsigned uChannel));
+
+ /**
+ * Schedule DMA execution.
+ *
+ * @param pDevIns The device instance.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnDMASchedule,(PPDMDEVINS pDevIns));
+
+ /**
+ * Write CMOS value and update the checksum(s).
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iReg The CMOS register index.
+ * @param u8Value The CMOS register value.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCMOSWrite,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value));
+
+ /**
+ * Read CMOS value.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param iReg The CMOS register index.
+ * @param pu8Value Where to store the CMOS register value.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCMOSRead,(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value));
+
+ /**
+ * Assert that the current thread is the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDevIns The device instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine The linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Assert that the current thread is NOT the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDevIns The device instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine The linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDEVINS pDevIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Resolves the symbol for a raw-mode context interface.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pvInterface The interface structure.
+ * @param cbInterface The size of the interface structure.
+ * @param pszSymPrefix What to prefix the symbols in the list with
+ * before resolving them. This must start with
+ * 'dev' and contain the driver name.
+ * @param pszSymList List of symbols corresponding to the interface.
+ * There is generally a there is generally a define
+ * holding this list associated with the interface
+ * definition (INTERFACE_SYM_LIST). For more
+ * details see PDMR3LdrGetInterfaceSymbols.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
+ const char *pszSymPrefix, const char *pszSymList));
+
+ /**
+ * Resolves the symbol for a ring-0 context interface.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pvInterface The interface structure.
+ * @param cbInterface The size of the interface structure.
+ * @param pszSymPrefix What to prefix the symbols in the list with
+ * before resolving them. This must start with
+ * 'dev' and contain the driver name.
+ * @param pszSymList List of symbols corresponding to the interface.
+ * There is generally a there is generally a define
+ * holding this list associated with the interface
+ * definition (INTERFACE_SYM_LIST). For more
+ * details see PDMR3LdrGetInterfaceSymbols.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDEVINS pDevIns, void *pvInterface, size_t cbInterface,
+ const char *pszSymPrefix, const char *pszSymList));
+
+ /**
+ * Call the ring-0 request handler routine of the device.
+ *
+ * For this to work, the device must be ring-0 enabled and export a request
+ * handler function. The name of the function must be the device name in
+ * the PDMDRVREG struct prefixed with 'drvR0' and suffixed with
+ * 'ReqHandler'. The device name will be captialized. It shall take the
+ * exact same arguments as this function and be declared using
+ * PDMBOTHCBDECL. See FNPDMDEVREQHANDLERR0.
+ *
+ * Unlike PDMDrvHlpCallR0, this is current unsuitable for more than a call
+ * or two as the handler address will be resolved on each invocation. This
+ * is the reason for the EMT only restriction as well.
+ *
+ * @returns VBox status code.
+ * @retval VERR_SYMBOL_NOT_FOUND if the device doesn't export the required
+ * handler function.
+ * @retval VERR_ACCESS_DENIED if the device isn't ring-0 capable.
+ *
+ * @param pDevIns The device instance.
+ * @param uOperation The operation to perform.
+ * @param u64Arg 64-bit integer argument.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg));
+
+ /** Space reserved for future members.
+ * @{ */
+ DECLR3CALLBACKMEMBER(void, pfnReserved1,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved2,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved3,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved4,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved5,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved6,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved7,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved8,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved9,(void));
+ DECLR3CALLBACKMEMBER(void, pfnReserved10,(void));
+ /** @} */
+
+
+ /** API available to trusted devices only.
+ *
+ * These APIs are providing unrestricted access to the guest and the VM,
+ * or they are interacting intimately with PDM.
+ *
+ * @{
+ */
+ /**
+ * Gets the VM handle. Restricted API.
+ *
+ * @returns VM Handle.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the VMCPU handle. Restricted API.
+ *
+ * @returns VMCPU Handle.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
+
+ /**
+ * Registers the VMM device heap
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param GCPhys The physical address.
+ * @param pvHeap Ring 3 heap pointer.
+ * @param cbSize Size of the heap.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRegisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize));
+
+ /**
+ * Unregisters the VMM device heap
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param GCPhys The physical address.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUnregisterVMMDevHeap,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys));
+
+ /**
+ * Resets the VM.
+ *
+ * @returns The appropriate VBox status code to pass around on reset.
+ * @param pDevIns The device instance.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMReset,(PPDMDEVINS pDevIns));
+
+ /**
+ * Suspends the VM.
+ *
+ * @returns The appropriate VBox status code to pass around on suspend.
+ * @param pDevIns The device instance.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSuspend,(PPDMDEVINS pDevIns));
+
+ /**
+ * Suspends, saves and powers off the VM.
+ *
+ * @returns The appropriate VBox status code to pass around.
+ * @param pDevIns The device instance.
+ * @thread An emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSuspendSaveAndPowerOff,(PPDMDEVINS pDevIns));
+
+ /**
+ * Power off the VM.
+ *
+ * @returns The appropriate VBox status code to pass around on power off.
+ * @param pDevIns The device instance.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMPowerOff,(PPDMDEVINS pDevIns));
+
+ /**
+ * Checks if the Gate A20 is enabled or not.
+ *
+ * @returns true if A20 is enabled.
+ * @returns false if A20 is disabled.
+ * @param pDevIns The device instance.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
+
+ /**
+ * Enables or disables the Gate A20.
+ *
+ * @param pDevIns The device instance.
+ * @param fEnable Set this flag to enable the Gate A20; clear it
+ * to disable.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnA20Set,(PPDMDEVINS pDevIns, bool fEnable));
+
+ /**
+ * Get the specified CPUID leaf for the virtual CPU associated with the calling
+ * thread.
+ *
+ * @param pDevIns The device instance.
+ * @param iLeaf The CPUID leaf to get.
+ * @param pEax Where to store the EAX value.
+ * @param pEbx Where to store the EBX value.
+ * @param pEcx Where to store the ECX value.
+ * @param pEdx Where to store the EDX value.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnGetCpuId,(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx));
+
+ /**
+ * Get the current virtual clock time in a VM. The clock frequency must be
+ * queried separately.
+ *
+ * @returns Current clock time.
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the frequency of the virtual clock.
+ *
+ * @returns The clock frequency (not variable at run-time).
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the current virtual clock time in a VM, in nanoseconds.
+ *
+ * @returns Current clock time (in ns).
+ * @param pDevIns The device instance.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
+
+ /** @} */
+
+ /** Just a safety precaution. (PDM_DEVHLPR3_VERSION) */
+ uint32_t u32TheEnd;
+} PDMDEVHLPR3;
+#endif /* !IN_RING3 */
+/** Pointer to the R3 PDM Device API. */
+typedef R3PTRTYPE(struct PDMDEVHLPR3 *) PPDMDEVHLPR3;
+/** Pointer to the R3 PDM Device API, const variant. */
+typedef R3PTRTYPE(const struct PDMDEVHLPR3 *) PCPDMDEVHLPR3;
+
+/** Current PDMDEVHLPR3 version number. */
+#define PDM_DEVHLPR3_VERSION PDM_VERSION_MAKE(0xffe7, 9, 0)
+
+
+/**
+ * PDM Device API - RC Variant.
+ */
+typedef struct PDMDEVHLPRC
+{
+ /** Structure version. PDM_DEVHLPRC_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Reads data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+ /**
+ * Writes data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnPCIDevPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Set the IRQ for a PCI device.
+ *
+ * @param pDevIns Device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Set ISA IRQ for a device.
+ *
+ * @param pDevIns Device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLRCCALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Read physical memory.
+ *
+ * @returns VINF_SUCCESS (for now).
+ * @param pDevIns Device instance.
+ * @param GCPhys Physical address start reading from.
+ * @param pvBuf Where to put the read bits.
+ * @param cbRead How many bytes to read.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+ /**
+ * Write to physical memory.
+ *
+ * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
+ * @param pDevIns Device instance.
+ * @param GCPhys Physical address to write to.
+ * @param pvBuf What to write.
+ * @param cbWrite How many bytes to write.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Checks if the Gate A20 is enabled or not.
+ *
+ * @returns true if A20 is enabled.
+ * @returns false if A20 is disabled.
+ * @param pDevIns Device instance.
+ * @thread The emulation thread.
+ */
+ DECLRCCALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the VM state.
+ *
+ * @returns VM state.
+ * @param pDevIns The device instance.
+ * @thread Any thread (just keep in mind that it's volatile info).
+ */
+ DECLRCCALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
+
+ /**
+ * Set parameters for pending MMIO patch operation
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance.
+ * @param GCPhys MMIO physical address
+ * @param pCachedData GC pointer to cached data
+ */
+ DECLRCCALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
+
+ /**
+ * Gets the VM handle. Restricted API.
+ *
+ * @returns VM Handle.
+ * @param pDevIns Device instance.
+ */
+ DECLRCCALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the VMCPU handle. Restricted API.
+ *
+ * @returns VMCPU Handle.
+ * @param pDevIns The device instance.
+ */
+ DECLRCCALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the current virtual clock time in a VM. The clock frequency must be
+ * queried separately.
+ *
+ * @returns Current clock time.
+ * @param pDevIns The device instance.
+ */
+ DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the frequency of the virtual clock.
+ *
+ * @returns The clock frequency (not variable at run-time).
+ * @param pDevIns The device instance.
+ */
+ DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the current virtual clock time in a VM, in nanoseconds.
+ *
+ * @returns Current clock time (in ns).
+ * @param pDevIns The device instance.
+ */
+ DECLRCCALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the trace buffer handle.
+ *
+ * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
+ * really inteded for direct usage, thus no inline wrapper function.
+ *
+ * @returns Trace buffer handle or NIL_RTTRACEBUF.
+ * @param pDevIns The device instance.
+ */
+ DECLRCCALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMDEVHLPRC;
+/** Pointer PDM Device RC API. */
+typedef RCPTRTYPE(struct PDMDEVHLPRC *) PPDMDEVHLPRC;
+/** Pointer PDM Device RC API. */
+typedef RCPTRTYPE(const struct PDMDEVHLPRC *) PCPDMDEVHLPRC;
+
+/** Current PDMDEVHLP version number. */
+#define PDM_DEVHLPRC_VERSION PDM_VERSION_MAKE(0xffe6, 3, 0)
+
+
+/**
+ * PDM Device API - R0 Variant.
+ */
+typedef struct PDMDEVHLPR0
+{
+ /** Structure version. PDM_DEVHLPR0_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Reads data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPCIPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+ /**
+ * Writes data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPCIPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Set the IRQ for a PCI device.
+ *
+ * @param pDevIns Device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnPCISetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Set ISA IRQ for a device.
+ *
+ * @param pDevIns Device instance.
+ * @param iIrq IRQ number to set.
+ * @param iLevel IRQ level. See the PDM_IRQ_LEVEL_* \#defines.
+ * @thread Any thread, but will involve the emulation thread.
+ */
+ DECLR0CALLBACKMEMBER(void, pfnISASetIrq,(PPDMDEVINS pDevIns, int iIrq, int iLevel));
+
+ /**
+ * Read physical memory.
+ *
+ * @returns VINF_SUCCESS (for now).
+ * @param pDevIns Device instance.
+ * @param GCPhys Physical address start reading from.
+ * @param pvBuf Where to put the read bits.
+ * @param cbRead How many bytes to read.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPhysRead,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead));
+
+ /**
+ * Write to physical memory.
+ *
+ * @returns VINF_SUCCESS for now, and later maybe VERR_EM_MEMORY.
+ * @param pDevIns Device instance.
+ * @param GCPhys Physical address to write to.
+ * @param pvBuf What to write.
+ * @param cbWrite How many bytes to write.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPhysWrite,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Checks if the Gate A20 is enabled or not.
+ *
+ * @returns true if A20 is enabled.
+ * @returns false if A20 is disabled.
+ * @param pDevIns Device instance.
+ * @thread The emulation thread.
+ */
+ DECLR0CALLBACKMEMBER(bool, pfnA20IsEnabled,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the VM state.
+ *
+ * @returns VM state.
+ * @param pDevIns The device instance.
+ * @thread Any thread (just keep in mind that it's volatile info).
+ */
+ DECLR0CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDEVINS pDevIns));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
+
+ /**
+ * Set parameters for pending MMIO patch operation
+ *
+ * @returns rc.
+ * @param pDevIns Device instance.
+ * @param GCPhys MMIO physical address
+ * @param pCachedData GC pointer to cached data
+ */
+ DECLR0CALLBACKMEMBER(int, pfnPATMSetMMIOPatchInfo,(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData));
+
+ /**
+ * Gets the VM handle. Restricted API.
+ *
+ * @returns VM Handle.
+ * @param pDevIns Device instance.
+ */
+ DECLR0CALLBACKMEMBER(PVM, pfnGetVM,(PPDMDEVINS pDevIns));
+
+ /**
+ * Checks if our current CPU state allows for IO block emulation fallback to the recompiler
+ *
+ * @returns true = yes, false = no
+ * @param pDevIns Device instance.
+ */
+ DECLR0CALLBACKMEMBER(bool, pfnCanEmulateIoBlock,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the VMCPU handle. Restricted API.
+ *
+ * @returns VMCPU Handle.
+ * @param pDevIns The device instance.
+ */
+ DECLR0CALLBACKMEMBER(PVMCPU, pfnGetVMCPU,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the current virtual clock time in a VM. The clock frequency must be
+ * queried separately.
+ *
+ * @returns Current clock time.
+ * @param pDevIns The device instance.
+ */
+ DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGet,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the frequency of the virtual clock.
+ *
+ * @returns The clock frequency (not variable at run-time).
+ * @param pDevIns The device instance.
+ */
+ DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetFreq,(PPDMDEVINS pDevIns));
+
+ /**
+ * Get the current virtual clock time in a VM, in nanoseconds.
+ *
+ * @returns Current clock time (in ns).
+ * @param pDevIns The device instance.
+ */
+ DECLR0CALLBACKMEMBER(uint64_t, pfnTMTimeVirtGetNano,(PPDMDEVINS pDevIns));
+
+ /**
+ * Gets the trace buffer handle.
+ *
+ * This is used by the macros found in VBox/vmm/dbgftrace.h and is not
+ * really inteded for direct usage, thus no inline wrapper function.
+ *
+ * @returns Trace buffer handle or NIL_RTTRACEBUF.
+ * @param pDevIns The device instance.
+ */
+ DECLR0CALLBACKMEMBER(RTTRACEBUF, pfnDBGFTraceBuf,(PPDMDEVINS pDevIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMDEVHLPR0;
+/** Pointer PDM Device R0 API. */
+typedef R0PTRTYPE(struct PDMDEVHLPR0 *) PPDMDEVHLPR0;
+/** Pointer PDM Device GC API. */
+typedef R0PTRTYPE(const struct PDMDEVHLPR0 *) PCPDMDEVHLPR0;
+
+/** Current PDMDEVHLP version number. */
+#define PDM_DEVHLPR0_VERSION PDM_VERSION_MAKE(0xffe5, 3, 0)
+
+
+
+/**
+ * PDM Device Instance.
+ */
+typedef struct PDMDEVINS
+{
+ /** Structure version. PDM_DEVINS_VERSION defines the current version. */
+ uint32_t u32Version;
+ /** Device instance number. */
+ uint32_t iInstance;
+
+ /** Pointer the GC PDM Device API. */
+ PCPDMDEVHLPRC pHlpRC;
+ /** Pointer to device instance data. */
+ RTRCPTR pvInstanceDataRC;
+ /** The critical section for the device, see pCritSectXR3. */
+ RCPTRTYPE(PPDMCRITSECT) pCritSectRoRC;
+ /** Alignment padding. */
+ RTRCPTR pAlignmentRC;
+
+ /** Pointer the R0 PDM Device API. */
+ PCPDMDEVHLPR0 pHlpR0;
+ /** Pointer to device instance data (R0). */
+ RTR0PTR pvInstanceDataR0;
+ /** The critical section for the device, see pCritSectXR3. */
+ R0PTRTYPE(PPDMCRITSECT) pCritSectRoR0;
+
+ /** Pointer the HC PDM Device API. */
+ PCPDMDEVHLPR3 pHlpR3;
+ /** Pointer to device instance data. */
+ RTR3PTR pvInstanceDataR3;
+ /** The critical section for the device.
+ *
+ * TM and IOM will enter this critical section before calling into the device
+ * code. PDM will when doing power on, power off, reset, suspend and resume
+ * notifications. SSM will currently not, but this will be changed later on.
+ *
+ * The device gets a critical section automatically assigned to it before
+ * the constructor is called. If the constructor wishes to use a different
+ * critical section, it calls PDMDevHlpSetDeviceCritSect() to change it
+ * very early on.
+ */
+ R3PTRTYPE(PPDMCRITSECT) pCritSectRoR3;
+
+ /** Pointer to device registration structure. */
+ R3PTRTYPE(PCPDMDEVREG) pReg;
+ /** Configuration handle. */
+ R3PTRTYPE(PCFGMNODE) pCfg;
+
+ /** The base interface of the device.
+ *
+ * The device constructor initializes this if it has any
+ * device level interfaces to export. To obtain this interface
+ * call PDMR3QueryDevice(). */
+ PDMIBASE IBase;
+
+ /** Tracing indicator. */
+ uint32_t fTracing;
+ /** The tracing ID of this device. */
+ uint32_t idTracing;
+#if HC_ARCH_BITS == 32
+ /** Align the internal data more naturally. */
+ uint32_t au32Padding[HC_ARCH_BITS == 32 ? 13 : 0];
+#endif
+
+ /** Internal data. */
+ union
+ {
+#ifdef PDMDEVINSINT_DECLARED
+ PDMDEVINSINT s;
+#endif
+ uint8_t padding[HC_ARCH_BITS == 32 ? 72 : 112 + 0x28];
+ } Internal;
+
+ /** Device instance data. The size of this area is defined
+ * in the PDMDEVREG::cbInstanceData field. */
+ char achInstanceData[8];
+} PDMDEVINS;
+
+/** Current PDMDEVINS version number. */
+#define PDM_DEVINS_VERSION PDM_VERSION_MAKE(0xffe4, 3, 0)
+
+/** Converts a pointer to the PDMDEVINS::IBase to a pointer to PDMDEVINS. */
+#define PDMIBASE_2_PDMDEV(pInterface) ( (PPDMDEVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDEVINS, IBase)) )
+
+/**
+ * Checks the structure versions of the device instance and device helpers,
+ * returning if they are incompatible.
+ *
+ * This is for use in the constructor.
+ *
+ * @param pDevIns The device instance pointer.
+ */
+#define PDMDEV_CHECK_VERSIONS_RETURN(pDevIns) \
+ do \
+ { \
+ PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
+ AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION), \
+ ("DevIns=%#x mine=%#x\n", (pDevIns)->u32Version, PDM_DEVINS_VERSION), \
+ VERR_PDM_DEVINS_VERSION_MISMATCH); \
+ AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
+ ("DevHlp=%#x mine=%#x\n", (pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION), \
+ VERR_PDM_DEVHLPR3_VERSION_MISMATCH); \
+ } while (0)
+
+/**
+ * Quietly checks the structure versions of the device instance and device
+ * helpers, returning if they are incompatible.
+ *
+ * This is for use in the destructor.
+ *
+ * @param pDevIns The device instance pointer.
+ */
+#define PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns) \
+ do \
+ { \
+ PPDMDEVINS pDevInsTypeCheck = (pDevIns); NOREF(pDevInsTypeCheck); \
+ if (RT_UNLIKELY(!PDM_VERSION_ARE_COMPATIBLE((pDevIns)->u32Version, PDM_DEVINS_VERSION) )) \
+ return VERR_PDM_DEVINS_VERSION_MISMATCH; \
+ if (RT_UNLIKELY(!PDM_VERSION_ARE_COMPATIBLE((pDevIns)->pHlpR3->u32Version, PDM_DEVHLPR3_VERSION) )) \
+ return VERR_PDM_DEVHLPR3_VERSION_MISMATCH; \
+ } while (0)
+
+/**
+ * Wrapper around CFGMR3ValidateConfig for the root config for use in the
+ * constructor - returns on failure.
+ *
+ * This should be invoked after having initialized the instance data
+ * sufficiently for the correct operation of the destructor. The destructor is
+ * always called!
+ *
+ * @param pDevIns Pointer to the PDM device instance.
+ * @param pszValidValues Patterns describing the valid value names. See
+ * RTStrSimplePatternMultiMatch for details on the
+ * pattern syntax.
+ * @param pszValidNodes Patterns describing the valid node (key) names.
+ * Pass empty string if no valid nodes.
+ */
+#define PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, pszValidValues, pszValidNodes) \
+ do \
+ { \
+ int rcValCfg = CFGMR3ValidateConfig((pDevIns)->pCfg, "/", pszValidValues, pszValidNodes, \
+ (pDevIns)->pReg->szName, (pDevIns)->iInstance); \
+ if (RT_FAILURE(rcValCfg)) \
+ return rcValCfg; \
+ } while (0)
+
+/** @def PDMDEV_ASSERT_EMT
+ * Assert that the current thread is the emulation thread.
+ */
+#ifdef VBOX_STRICT
+# define PDMDEV_ASSERT_EMT(pDevIns) pDevIns->pHlpR3->pfnAssertEMT(pDevIns, __FILE__, __LINE__, __FUNCTION__)
+#else
+# define PDMDEV_ASSERT_EMT(pDevIns) do { } while (0)
+#endif
+
+/** @def PDMDEV_ASSERT_OTHER
+ * Assert that the current thread is NOT the emulation thread.
+ */
+#ifdef VBOX_STRICT
+# define PDMDEV_ASSERT_OTHER(pDevIns) pDevIns->pHlpR3->pfnAssertOther(pDevIns, __FILE__, __LINE__, __FUNCTION__)
+#else
+# define PDMDEV_ASSERT_OTHER(pDevIns) do { } while (0)
+#endif
+
+/** @def PDMDEV_ASSERT_VMLOCK_OWNER
+ * Assert that the current thread is owner of the VM lock.
+ */
+#ifdef VBOX_STRICT
+# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) pDevIns->pHlpR3->pfnAssertVMLock(pDevIns, __FILE__, __LINE__, __FUNCTION__)
+#else
+# define PDMDEV_ASSERT_VMLOCK_OWNER(pDevIns) do { } while (0)
+#endif
+
+/** @def PDMDEV_SET_ERROR
+ * Set the VM error. See PDMDevHlpVMSetError() for printf like message formatting.
+ */
+#define PDMDEV_SET_ERROR(pDevIns, rc, pszError) \
+ PDMDevHlpVMSetError(pDevIns, rc, RT_SRC_POS, "%s", pszError)
+
+/** @def PDMDEV_SET_RUNTIME_ERROR
+ * Set the VM runtime error. See PDMDevHlpVMSetRuntimeError() for printf like message formatting.
+ */
+#define PDMDEV_SET_RUNTIME_ERROR(pDevIns, fFlags, pszErrorId, pszError) \
+ PDMDevHlpVMSetRuntimeError(pDevIns, fFlags, pszErrorId, "%s", pszError)
+
+/** @def PDMDEVINS_2_RCPTR
+ * Converts a PDM Device instance pointer a RC PDM Device instance pointer.
+ */
+#define PDMDEVINS_2_RCPTR(pDevIns) ( (RCPTRTYPE(PPDMDEVINS))((RTGCUINTPTR)(pDevIns)->pvInstanceDataRC - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
+
+/** @def PDMDEVINS_2_R3PTR
+ * Converts a PDM Device instance pointer a R3 PDM Device instance pointer.
+ */
+#define PDMDEVINS_2_R3PTR(pDevIns) ( (R3PTRTYPE(PPDMDEVINS))((RTHCUINTPTR)(pDevIns)->pvInstanceDataR3 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
+
+/** @def PDMDEVINS_2_R0PTR
+ * Converts a PDM Device instance pointer a R0 PDM Device instance pointer.
+ */
+#define PDMDEVINS_2_R0PTR(pDevIns) ( (R0PTRTYPE(PPDMDEVINS))((RTR0UINTPTR)(pDevIns)->pvInstanceDataR0 - RT_OFFSETOF(PDMDEVINS, achInstanceData)) )
+
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIOPortRegister
+ */
+DECLINLINE(int) PDMDevHlpIOPortRegister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTHCPTR pvUser,
+ PFNIOMIOPORTOUT pfnOut, PFNIOMIOPORTIN pfnIn,
+ PFNIOMIOPORTOUTSTRING pfnOutStr, PFNIOMIOPORTINSTRING pfnInStr, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnIOPortRegister(pDevIns, Port, cPorts, pvUser, pfnOut, pfnIn, pfnOutStr, pfnInStr, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIOPortRegisterRC
+ */
+DECLINLINE(int) PDMDevHlpIOPortRegisterRC(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTRCPTR pvUser,
+ const char *pszOut, const char *pszIn, const char *pszOutStr,
+ const char *pszInStr, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnIOPortRegisterRC(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIOPortRegisterR0
+ */
+DECLINLINE(int) PDMDevHlpIOPortRegisterR0(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts, RTR0PTR pvUser,
+ const char *pszOut, const char *pszIn, const char *pszOutStr,
+ const char *pszInStr, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnIOPortRegisterR0(pDevIns, Port, cPorts, pvUser, pszOut, pszIn, pszOutStr, pszInStr, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnIOPortDeregister
+ */
+DECLINLINE(int) PDMDevHlpIOPortDeregister(PPDMDEVINS pDevIns, RTIOPORT Port, RTIOPORT cPorts)
+{
+ return pDevIns->pHlpR3->pfnIOPortDeregister(pDevIns, Port, cPorts);
+}
+
+/**
+ * Register a Memory Mapped I/O (MMIO) region.
+ *
+ * These callbacks are of course for the ring-3 context (R3). Register HC
+ * handlers before raw-mode context (RC) and ring-0 context (R0) handlers! There
+ * must be a R3 handler for every RC and R0 handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the MMIO with.
+ * @param GCPhysStart First physical address in the range.
+ * @param cbRange The size of the range (in bytes).
+ * @param pvUser User argument.
+ * @param fFlags Flags, IOMMMIO_FLAGS_XXX.
+ * @param pfnWrite Pointer to function which is gonna handle Write operations.
+ * @param pfnRead Pointer to function which is gonna handle Read operations.
+ * @param pszDesc Pointer to description string. This must not be freed.
+ */
+DECLINLINE(int) PDMDevHlpMMIORegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser,
+ uint32_t fFlags, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, NULL /*pfnFill*/,
+ fFlags, pszDesc);
+}
+
+/**
+ * Register a Memory Mapped I/O (MMIO) region for GC.
+ *
+ * These callbacks are for the raw-mode context (RC). Register ring-3 context
+ * (R3) handlers before guest context handlers! There must be a R3 handler for
+ * every RC handler!
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance to register the MMIO with.
+ * @param GCPhysStart First physical address in the range.
+ * @param cbRange The size of the range (in bytes).
+ * @param pvUser User argument.
+ * @param pszWrite Name of the RC function which is gonna handle Write operations.
+ * @param pszRead Name of the RC function which is gonna handle Read operations.
+ */
+DECLINLINE(int) PDMDevHlpMMIORegisterRC(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser,
+ const char *pszWrite, const char *pszRead)
+{
+ return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, NULL /*pszFill*/);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIORegisterR0
+ */
+DECLINLINE(int) PDMDevHlpMMIORegisterR0(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser,
+ const char *pszWrite, const char *pszRead)
+{
+ return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, NULL /*pszFill*/);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIORegister
+ */
+DECLINLINE(int) PDMDevHlpMMIORegisterEx(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTHCPTR pvUser,
+ uint32_t fFlags, PFNIOMMMIOWRITE pfnWrite, PFNIOMMMIOREAD pfnRead,
+ PFNIOMMMIOFILL pfnFill, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnMMIORegister(pDevIns, GCPhysStart, cbRange, pvUser, pfnWrite, pfnRead, pfnFill,
+ fFlags, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIORegisterRC
+ */
+DECLINLINE(int) PDMDevHlpMMIORegisterRCEx(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTRCPTR pvUser,
+ const char *pszWrite, const char *pszRead, const char *pszFill)
+{
+ return pDevIns->pHlpR3->pfnMMIORegisterRC(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIORegisterR0
+ */
+DECLINLINE(int) PDMDevHlpMMIORegisterR0Ex(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, RTR0PTR pvUser,
+ const char *pszWrite, const char *pszRead, const char *pszFill)
+{
+ return pDevIns->pHlpR3->pfnMMIORegisterR0(pDevIns, GCPhysStart, cbRange, pvUser, pszWrite, pszRead, pszFill);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIODeregister
+ */
+DECLINLINE(int) PDMDevHlpMMIODeregister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange)
+{
+ return pDevIns->pHlpR3->pfnMMIODeregister(pDevIns, GCPhysStart, cbRange);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIO2Register
+ */
+DECLINLINE(int) PDMDevHlpMMIO2Register(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnMMIO2Register(pDevIns, iRegion, cb, fFlags, ppv, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIO2Deregister
+ */
+DECLINLINE(int) PDMDevHlpMMIO2Deregister(PPDMDEVINS pDevIns, uint32_t iRegion)
+{
+ return pDevIns->pHlpR3->pfnMMIO2Deregister(pDevIns, iRegion);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIO2Map
+ */
+DECLINLINE(int) PDMDevHlpMMIO2Map(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
+{
+ return pDevIns->pHlpR3->pfnMMIO2Map(pDevIns, iRegion, GCPhys);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIO2Unmap
+ */
+DECLINLINE(int) PDMDevHlpMMIO2Unmap(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys)
+{
+ return pDevIns->pHlpR3->pfnMMIO2Unmap(pDevIns, iRegion, GCPhys);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMHyperMapMMIO2
+ */
+DECLINLINE(int) PDMDevHlpMMHyperMapMMIO2(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
+ const char *pszDesc, PRTRCPTR pRCPtr)
+{
+ return pDevIns->pHlpR3->pfnMMHyperMapMMIO2(pDevIns, iRegion, off, cb, pszDesc, pRCPtr);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMIO2MapKernel
+ */
+DECLINLINE(int) PDMDevHlpMMIO2MapKernel(PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb,
+ const char *pszDesc, PRTR0PTR pR0Ptr)
+{
+ return pDevIns->pHlpR3->pfnMMIO2MapKernel(pDevIns, iRegion, off, cb, pszDesc, pR0Ptr);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnROMRegister
+ */
+DECLINLINE(int) PDMDevHlpROMRegister(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange,
+ const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnROMRegister(pDevIns, GCPhysStart, cbRange, pvBinary, cbBinary, fFlags, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnROMProtectShadow
+ */
+DECLINLINE(int) PDMDevHlpROMProtectShadow(PPDMDEVINS pDevIns, RTGCPHYS GCPhysStart, uint32_t cbRange, PGMROMPROT enmProt)
+{
+ return pDevIns->pHlpR3->pfnROMProtectShadow(pDevIns, GCPhysStart, cbRange, enmProt);
+}
+
+/**
+ * Register a save state data unit.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance.
+ * @param uVersion Data layout version number.
+ * @param cbGuess The approximate amount of data in the unit.
+ * Only for progress indicators.
+ * @param pfnSaveExec Execute save callback, optional.
+ * @param pfnLoadExec Execute load callback, optional.
+ */
+DECLINLINE(int) PDMDevHlpSSMRegister(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
+ PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
+{
+ return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
+ NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveDone*/,
+ NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
+ NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
+}
+
+/**
+ * Register a save state data unit with a live save callback as well.
+ *
+ * @returns VBox status.
+ * @param pDevIns The device instance.
+ * @param uVersion Data layout version number.
+ * @param cbGuess The approximate amount of data in the unit.
+ * Only for progress indicators.
+ * @param pfnLiveExec Execute live callback, optional.
+ * @param pfnSaveExec Execute save callback, optional.
+ * @param pfnLoadExec Execute load callback, optional.
+ */
+DECLINLINE(int) PDMDevHlpSSMRegister3(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess,
+ FNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVLOADEXEC pfnLoadExec)
+{
+ return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, NULL /*pszBefore*/,
+ NULL /*pfnLivePrep*/, pfnLiveExec, NULL /*pfnLiveDone*/,
+ NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
+ NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnSSMRegister
+ */
+DECLINLINE(int) PDMDevHlpSSMRegisterEx(PPDMDEVINS pDevIns, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
+ PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
+ PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
+ PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone)
+{
+ return pDevIns->pHlpR3->pfnSSMRegister(pDevIns, uVersion, cbGuess, pszBefore,
+ pfnLivePrep, pfnLiveExec, pfnLiveVote,
+ pfnSavePrep, pfnSaveExec, pfnSaveDone,
+ pfnLoadPrep, pfnLoadExec, pfnLoadDone);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTMTimerCreate
+ */
+DECLINLINE(int) PDMDevHlpTMTimerCreate(PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags,
+ const char *pszDesc, PPTMTIMERR3 ppTimer)
+{
+ return pDevIns->pHlpR3->pfnTMTimerCreate(pDevIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTMUtcNow
+ */
+DECLINLINE(PRTTIMESPEC) PDMDevHlpTMUtcNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)
+{
+ return pDevIns->pHlpR3->pfnTMUtcNow(pDevIns, pTime);
+}
+
+#endif /* IN_RING3 */
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysRead
+ */
+DECLINLINE(int) PDMDevHlpPhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysWrite
+ */
+DECLINLINE(int) PDMDevHlpPhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite);
+}
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtr
+ */
+DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtr(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void **ppv, PPGMPAGEMAPLOCK pLock)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtr(pDevIns, GCPhys, fFlags, ppv, pLock);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysGCPhys2CCPtrReadOnly
+ */
+DECLINLINE(int) PDMDevHlpPhysGCPhys2CCPtrReadOnly(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t fFlags, void const **ppv, PPGMPAGEMAPLOCK pLock)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhys, fFlags, ppv, pLock);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysReleasePageMappingLock
+ */
+DECLINLINE(void) PDMDevHlpPhysReleasePageMappingLock(PPDMDEVINS pDevIns, PPGMPAGEMAPLOCK pLock)
+{
+ pDevIns->CTX_SUFF(pHlp)->pfnPhysReleasePageMappingLock(pDevIns, pLock);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysReadGCVirt
+ */
+DECLINLINE(int) PDMDevHlpPhysReadGCVirt(PPDMDEVINS pDevIns, void *pvDst, RTGCPTR GCVirtSrc, size_t cb)
+{
+ return pDevIns->pHlpR3->pfnPhysReadGCVirt(pDevIns, pvDst, GCVirtSrc, cb);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysWriteGCVirt
+ */
+DECLINLINE(int) PDMDevHlpPhysWriteGCVirt(PPDMDEVINS pDevIns, RTGCPTR GCVirtDst, const void *pvSrc, size_t cb)
+{
+ return pDevIns->pHlpR3->pfnPhysWriteGCVirt(pDevIns, GCVirtDst, pvSrc, cb);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPhysGCPtr2GCPhys
+ */
+DECLINLINE(int) PDMDevHlpPhysGCPtr2GCPhys(PPDMDEVINS pDevIns, RTGCPTR GCPtr, PRTGCPHYS pGCPhys)
+{
+ return pDevIns->pHlpR3->pfnPhysGCPtr2GCPhys(pDevIns, GCPtr, pGCPhys);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMHeapAlloc
+ */
+DECLINLINE(void *) PDMDevHlpMMHeapAlloc(PPDMDEVINS pDevIns, size_t cb)
+{
+ return pDevIns->pHlpR3->pfnMMHeapAlloc(pDevIns, cb);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMHeapAllocZ
+ */
+DECLINLINE(void *) PDMDevHlpMMHeapAllocZ(PPDMDEVINS pDevIns, size_t cb)
+{
+ return pDevIns->pHlpR3->pfnMMHeapAllocZ(pDevIns, cb);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnMMHeapFree
+ */
+DECLINLINE(void) PDMDevHlpMMHeapFree(PPDMDEVINS pDevIns, void *pv)
+{
+ pDevIns->pHlpR3->pfnMMHeapFree(pDevIns, pv);
+}
+#endif /* IN_RING3 */
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMState
+ */
+DECLINLINE(VMSTATE) PDMDevHlpVMState(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnVMState(pDevIns);
+}
+
+#ifdef IN_RING3
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMTeleportedAndNotFullyResumedYet
+ */
+DECLINLINE(bool) PDMDevHlpVMTeleportedAndNotFullyResumedYet(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDevIns);
+}
+#endif /* IN_RING3 */
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMSetError
+ */
+DECLINLINE(int) PDMDevHlpVMSetError(PPDMDEVINS pDevIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ pDevIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDevIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMSetRuntimeError
+ */
+DECLINLINE(int) PDMDevHlpVMSetRuntimeError(PPDMDEVINS pDevIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
+{
+ va_list va;
+ int rc;
+ va_start(va, pszFormat);
+ rc = pDevIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDevIns, fFlags, pszErrorId, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * VBOX_STRICT wrapper for pHlp->pfnDBGFStopV.
+ *
+ * @returns VBox status code which must be passed up to the VMM. This will be
+ * VINF_SUCCESS in non-strict builds.
+ * @param pDevIns The device instance.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Message. (optional)
+ * @param ... Message parameters.
+ */
+DECLINLINE(int) PDMDevHlpDBGFStop(PPDMDEVINS pDevIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
+{
+#ifdef VBOX_STRICT
+# ifdef IN_RING3
+ int rc;
+ va_list args;
+ va_start(args, pszFormat);
+ rc = pDevIns->pHlpR3->pfnDBGFStopV(pDevIns, RT_SRC_POS_ARGS, pszFormat, args);
+ va_end(args);
+ return rc;
+# else
+ NOREF(pDevIns);
+ NOREF(pszFile);
+ NOREF(iLine);
+ NOREF(pszFunction);
+ NOREF(pszFormat);
+ return VINF_EM_DBG_STOP;
+# endif
+#else
+ NOREF(pDevIns);
+ NOREF(pszFile);
+ NOREF(iLine);
+ NOREF(pszFunction);
+ NOREF(pszFormat);
+ return VINF_SUCCESS;
+#endif
+}
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDBGFInfoRegister
+ */
+DECLINLINE(int) PDMDevHlpDBGFInfoRegister(PPDMDEVINS pDevIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDEV pfnHandler)
+{
+ return pDevIns->pHlpR3->pfnDBGFInfoRegister(pDevIns, pszName, pszDesc, pfnHandler);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnSTAMRegister
+ */
+DECLINLINE(void) PDMDevHlpSTAMRegister(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
+{
+ pDevIns->pHlpR3->pfnSTAMRegister(pDevIns, pvSample, enmType, pszName, enmUnit, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnSTAMRegisterF
+ */
+DECLINLINE(void) PDMDevHlpSTAMRegisterF(PPDMDEVINS pDevIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ const char *pszDesc, const char *pszName, ...)
+{
+ va_list va;
+ va_start(va, pszName);
+ pDevIns->pHlpR3->pfnSTAMRegisterV(pDevIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
+ va_end(va);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPCIRegister
+ */
+DECLINLINE(int) PDMDevHlpPCIRegister(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev)
+{
+ return pDevIns->pHlpR3->pfnPCIRegister(pDevIns, pPciDev);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPCIIORegionRegister
+ */
+DECLINLINE(int) PDMDevHlpPCIIORegionRegister(PPDMDEVINS pDevIns, int iRegion, uint32_t cbRegion, PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)
+{
+ return pDevIns->pHlpR3->pfnPCIIORegionRegister(pDevIns, iRegion, cbRegion, enmType, pfnCallback);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPCIRegisterMsi
+ */
+DECLINLINE(int) PDMDevHlpPCIRegisterMsi(PPDMDEVINS pDevIns, PPDMMSIREG pMsiReg)
+{
+ return pDevIns->pHlpR3->pfnPCIRegisterMsi(pDevIns, pMsiReg);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPCISetConfigCallbacks
+ */
+DECLINLINE(void) PDMDevHlpPCISetConfigCallbacks(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, PPFNPCICONFIGREAD ppfnReadOld,
+ PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)
+{
+ pDevIns->pHlpR3->pfnPCISetConfigCallbacks(pDevIns, pPciDev, pfnRead, ppfnReadOld, pfnWrite, ppfnWriteOld);
+}
+
+/**
+ * Reads data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_READ_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+DECLINLINE(int) PDMDevHlpPCIDevPhysRead(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
+{
+ AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+ AssertReturn(cbRead, VERR_INVALID_PARAMETER);
+
+ if (!PCIDevIsBusmaster(pPciDev))
+ {
+#ifdef DEBUG
+ Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping read %p (%z)\n", __FUNCTION__,
+ PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbRead));
+#endif
+ return VINF_PDM_PCI_PHYS_READ_BM_DISABLED;
+ }
+
+ return PDMDevHlpPhysRead(pPciDev->pDevIns, GCPhys, pvBuf, cbRead);
+}
+
+/**
+ * Writes data via bus mastering, if enabled. If no bus mastering is available,
+ * this function does nothing and returns VINF_PGM_PCI_PHYS_WRITE_BM_DISABLED.
+ *
+ * @return IPRT status code.
+ */
+DECLINLINE(int) PDMDevHlpPCIDevPhysWrite(PPCIDEVICE pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
+{
+ AssertPtrReturn(pPciDev, VERR_INVALID_POINTER);
+ AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
+ AssertReturn(cbWrite, VERR_INVALID_PARAMETER);
+
+ if (!PCIDevIsBusmaster(pPciDev))
+ {
+#ifdef DEBUG
+ Log2(("%s: %RU16:%RU16: No bus master (anymore), skipping write %p (%z)\n", __FUNCTION__,
+ PCIDevGetVendorId(pPciDev), PCIDevGetDeviceId(pPciDev), pvBuf, cbWrite));
+#endif
+ return VINF_PDM_PCI_PHYS_WRITE_BM_DISABLED;
+ }
+
+ return PDMDevHlpPhysWrite(pPciDev->pDevIns, GCPhys, pvBuf, cbWrite);
+}
+
+#endif /* IN_RING3 */
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPCISetIrq
+ */
+DECLINLINE(void) PDMDevHlpPCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+ pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPCISetIrqNoWait
+ */
+DECLINLINE(void) PDMDevHlpPCISetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+ pDevIns->CTX_SUFF(pHlp)->pfnPCISetIrq(pDevIns, iIrq, iLevel);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnISASetIrq
+ */
+DECLINLINE(void) PDMDevHlpISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+ pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnISASetIrqNoWait
+ */
+DECLINLINE(void) PDMDevHlpISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
+{
+ pDevIns->CTX_SUFF(pHlp)->pfnISASetIrq(pDevIns, iIrq, iLevel);
+}
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDriverAttach
+ */
+DECLINLINE(int) PDMDevHlpDriverAttach(PPDMDEVINS pDevIns, uint32_t iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
+{
+ return pDevIns->pHlpR3->pfnDriverAttach(pDevIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnQueueCreate
+ */
+DECLINLINE(int) PDMDevHlpQueueCreate(PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue)
+{
+ return pDevIns->pHlpR3->pfnQueueCreate(pDevIns, cbItem, cItems, cMilliesInterval, pfnCallback, fRZEnabled, pszName, ppQueue);
+}
+
+/**
+ * Initializes a PDM critical section.
+ *
+ * The PDM critical sections are derived from the IPRT critical sections, but
+ * works in RC and R0 as well.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pCritSect Pointer to the critical section.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszNameFmt Format string for naming the critical section.
+ * For statistics and lock validation.
+ * @param ... Arguments for the format string.
+ */
+DECLINLINE(int) PDMDevHlpCritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...)
+{
+ int rc;
+ va_list va;
+ va_start(va, pszNameFmt);
+ rc = pDevIns->pHlpR3->pfnCritSectInit(pDevIns, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnCritSectGetNop
+ */
+DECLINLINE(PPDMCRITSECT) PDMDevHlpCritSectGetNop(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnCritSectGetNop(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnCritSectGetNopR0
+ */
+DECLINLINE(R0PTRTYPE(PPDMCRITSECT)) PDMDevHlpCritSectGetNopR0(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnCritSectGetNopR0(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnCritSectGetNopRC
+ */
+DECLINLINE(RCPTRTYPE(PPDMCRITSECT)) PDMDevHlpCritSectGetNopRC(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnCritSectGetNopRC(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnSetDeviceCritSect
+ */
+DECLINLINE(int) PDMDevHlpSetDeviceCritSect(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect)
+{
+ return pDevIns->pHlpR3->pfnSetDeviceCritSect(pDevIns, pCritSect);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnThreadCreate
+ */
+DECLINLINE(int) PDMDevHlpThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
+ PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
+{
+ return pDevIns->pHlpR3->pfnThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnSetAsyncNotification
+ */
+DECLINLINE(int) PDMDevHlpSetAsyncNotification(PPDMDEVINS pDevIns, PFNPDMDEVASYNCNOTIFY pfnAsyncNotify)
+{
+ return pDevIns->pHlpR3->pfnSetAsyncNotification(pDevIns, pfnAsyncNotify);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnAsyncNotificationCompleted
+ */
+DECLINLINE(void) PDMDevHlpAsyncNotificationCompleted(PPDMDEVINS pDevIns)
+{
+ pDevIns->pHlpR3->pfnAsyncNotificationCompleted(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnA20Set
+ */
+DECLINLINE(void) PDMDevHlpA20Set(PPDMDEVINS pDevIns, bool fEnable)
+{
+ pDevIns->pHlpR3->pfnA20Set(pDevIns, fEnable);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnRTCRegister
+ */
+DECLINLINE(int) PDMDevHlpRTCRegister(PPDMDEVINS pDevIns, PCPDMRTCREG pRtcReg, PCPDMRTCHLP *ppRtcHlp)
+{
+ return pDevIns->pHlpR3->pfnRTCRegister(pDevIns, pRtcReg, ppRtcHlp);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPCIBusRegister
+ */
+DECLINLINE(int) PDMDevHlpPCIBusRegister(PPDMDEVINS pDevIns, PPDMPCIBUSREG pPciBusReg, PCPDMPCIHLPR3 *ppPciHlpR3)
+{
+ return pDevIns->pHlpR3->pfnPCIBusRegister(pDevIns, pPciBusReg, ppPciHlpR3);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPICRegister
+ */
+DECLINLINE(int) PDMDevHlpPICRegister(PPDMDEVINS pDevIns, PPDMPICREG pPicReg, PCPDMPICHLPR3 *ppPicHlpR3)
+{
+ return pDevIns->pHlpR3->pfnPICRegister(pDevIns, pPicReg, ppPicHlpR3);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnAPICRegister
+ */
+DECLINLINE(int) PDMDevHlpAPICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg, PCPDMAPICHLPR3 *ppApicHlpR3)
+{
+ return pDevIns->pHlpR3->pfnAPICRegister(pDevIns, pApicReg, ppApicHlpR3);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfn
+ */
+DECLINLINE(int) PDMDevHlpIOAPICRegister(PPDMDEVINS pDevIns, PPDMIOAPICREG pIoApicReg, PCPDMIOAPICHLPR3 *ppIoApicHlpR3)
+{
+ return pDevIns->pHlpR3->pfnIOAPICRegister(pDevIns, pIoApicReg, ppIoApicHlpR3);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnHPETRegister
+ */
+DECLINLINE(int) PDMDevHlpHPETRegister(PPDMDEVINS pDevIns, PPDMHPETREG pHpetReg, PCPDMHPETHLPR3 *ppHpetHlpR3)
+{
+ return pDevIns->pHlpR3->pfnHPETRegister(pDevIns, pHpetReg, ppHpetHlpR3);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnPciRawRegister
+ */
+DECLINLINE(int) PDMDevHlpPciRawRegister(PPDMDEVINS pDevIns, PPDMPCIRAWREG pPciRawReg, PCPDMPCIRAWHLPR3 *ppPciRawHlpR3)
+{
+ return pDevIns->pHlpR3->pfnPciRawRegister(pDevIns, pPciRawReg, ppPciRawHlpR3);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDMACRegister
+ */
+DECLINLINE(int) PDMDevHlpDMACRegister(PPDMDEVINS pDevIns, PPDMDMACREG pDmacReg, PCPDMDMACHLP *ppDmacHlp)
+{
+ return pDevIns->pHlpR3->pfnDMACRegister(pDevIns, pDmacReg, ppDmacHlp);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDMARegister
+ */
+DECLINLINE(int) PDMDevHlpDMARegister(PPDMDEVINS pDevIns, unsigned uChannel, PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
+{
+ return pDevIns->pHlpR3->pfnDMARegister(pDevIns, uChannel, pfnTransferHandler, pvUser);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDMAReadMemory
+ */
+DECLINLINE(int) PDMDevHlpDMAReadMemory(PPDMDEVINS pDevIns, unsigned uChannel, void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbRead)
+{
+ return pDevIns->pHlpR3->pfnDMAReadMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbRead);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDMAWriteMemory
+ */
+DECLINLINE(int) PDMDevHlpDMAWriteMemory(PPDMDEVINS pDevIns, unsigned uChannel, const void *pvBuffer, uint32_t off, uint32_t cbBlock, uint32_t *pcbWritten)
+{
+ return pDevIns->pHlpR3->pfnDMAWriteMemory(pDevIns, uChannel, pvBuffer, off, cbBlock, pcbWritten);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDMASetDREQ
+ */
+DECLINLINE(int) PDMDevHlpDMASetDREQ(PPDMDEVINS pDevIns, unsigned uChannel, unsigned uLevel)
+{
+ return pDevIns->pHlpR3->pfnDMASetDREQ(pDevIns, uChannel, uLevel);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDMAGetChannelMode
+ */
+DECLINLINE(uint8_t) PDMDevHlpDMAGetChannelMode(PPDMDEVINS pDevIns, unsigned uChannel)
+{
+ return pDevIns->pHlpR3->pfnDMAGetChannelMode(pDevIns, uChannel);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnDMASchedule
+ */
+DECLINLINE(void) PDMDevHlpDMASchedule(PPDMDEVINS pDevIns)
+{
+ pDevIns->pHlpR3->pfnDMASchedule(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnCMOSWrite
+ */
+DECLINLINE(int) PDMDevHlpCMOSWrite(PPDMDEVINS pDevIns, unsigned iReg, uint8_t u8Value)
+{
+ return pDevIns->pHlpR3->pfnCMOSWrite(pDevIns, iReg, u8Value);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnCMOSRead
+ */
+DECLINLINE(int) PDMDevHlpCMOSRead(PPDMDEVINS pDevIns, unsigned iReg, uint8_t *pu8Value)
+{
+ return pDevIns->pHlpR3->pfnCMOSRead(pDevIns, iReg, pu8Value);
+}
+
+/**
+ * @copydoc PDMDEVHLP::pfnCallR0
+ */
+DECLINLINE(int) PDMDevHlpCallR0(PPDMDEVINS pDevIns, uint32_t uOperation, uint64_t u64Arg)
+{
+ return pDevIns->pHlpR3->pfnCallR0(pDevIns, uOperation, u64Arg);
+}
+
+#endif /* IN_RING3 */
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnGetVM
+ */
+DECLINLINE(PVM) PDMDevHlpGetVM(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnGetVM(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnGetVMCPU
+ */
+DECLINLINE(PVMCPU) PDMDevHlpGetVMCPU(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnGetVMCPU(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGet
+ */
+DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGet(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGet(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
+ */
+DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetFreq(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetFreq(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnTMTimeVirtGetFreq
+ */
+DECLINLINE(uint64_t) PDMDevHlpTMTimeVirtGetNano(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnTMTimeVirtGetNano(pDevIns);
+}
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnRegisterVMMDevHeap
+ */
+DECLINLINE(int) PDMDevHlpRegisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTR3PTR pvHeap, unsigned cbSize)
+{
+ return pDevIns->pHlpR3->pfnRegisterVMMDevHeap(pDevIns, GCPhys, pvHeap, cbSize);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnUnregisterVMMDevHeap
+ */
+DECLINLINE(int) PDMDevHlpUnregisterVMMDevHeap(PPDMDEVINS pDevIns, RTGCPHYS GCPhys)
+{
+ return pDevIns->pHlpR3->pfnUnregisterVMMDevHeap(pDevIns, GCPhys);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMReset
+ */
+DECLINLINE(int) PDMDevHlpVMReset(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnVMReset(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMSuspend
+ */
+DECLINLINE(int) PDMDevHlpVMSuspend(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnVMSuspend(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMSuspendSaveAndPowerOff
+ */
+DECLINLINE(int) PDMDevHlpVMSuspendSaveAndPowerOff(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnVMSuspendSaveAndPowerOff(pDevIns);
+}
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnVMPowerOff
+ */
+DECLINLINE(int) PDMDevHlpVMPowerOff(PPDMDEVINS pDevIns)
+{
+ return pDevIns->pHlpR3->pfnVMPowerOff(pDevIns);
+}
+
+#endif /* IN_RING3 */
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnA20IsEnabled
+ */
+DECLINLINE(bool) PDMDevHlpA20IsEnabled(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnA20IsEnabled(pDevIns);
+}
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDEVHLPR3::pfnGetCpuId
+ */
+DECLINLINE(void) PDMDevHlpGetCpuId(PPDMDEVINS pDevIns, uint32_t iLeaf, uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx)
+{
+ pDevIns->pHlpR3->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
+}
+
+#endif /* IN_RING3 */
+#ifdef IN_RING0
+
+/**
+ * @copydoc PDMDEVHLPR0::pfnCanEmulateIoBlock
+ */
+DECLINLINE(bool) PDMDevHlpCanEmulateIoBlock(PPDMDEVINS pDevIns)
+{
+ return pDevIns->CTX_SUFF(pHlp)->pfnCanEmulateIoBlock(pDevIns);
+}
+
+#endif /* IN_RING0 */
+
+
+
+
+/** Pointer to callbacks provided to the VBoxDeviceRegister() call. */
+typedef struct PDMDEVREGCB *PPDMDEVREGCB;
+
+/**
+ * Callbacks for VBoxDeviceRegister().
+ */
+typedef struct PDMDEVREGCB
+{
+ /** Interface version.
+ * This is set to PDM_DEVREG_CB_VERSION. */
+ uint32_t u32Version;
+
+ /**
+ * Registers a device with the current VM instance.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param pReg Pointer to the device registration record.
+ * This data must be permanent and readonly.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMDEVREGCB pCallbacks, PCPDMDEVREG pReg));
+} PDMDEVREGCB;
+
+/** Current version of the PDMDEVREGCB structure. */
+#define PDM_DEVREG_CB_VERSION PDM_VERSION_MAKE(0xffe3, 1, 0)
+
+
+/**
+ * The VBoxDevicesRegister callback function.
+ *
+ * PDM will invoke this function after loading a device module and letting
+ * the module decide which devices to register and how to handle conflicts.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param u32Version VBox version number.
+ */
+typedef DECLCALLBACK(int) FNPDMVBOXDEVICESREGISTER(PPDMDEVREGCB pCallbacks, uint32_t u32Version);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/pdmdrv.h b/include/VBox/vmm/pdmdrv.h
new file mode 100644
index 00000000..d830ea69
--- /dev/null
+++ b/include/VBox/vmm/pdmdrv.h
@@ -0,0 +1,1829 @@
+/** @file
+ * PDM - Pluggable Device Manager, Drivers.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmdrv_h
+#define ___VBox_vmm_pdmdrv_h
+
+#include <VBox/vmm/pdmqueue.h>
+#include <VBox/vmm/pdmcritsect.h>
+#include <VBox/vmm/pdmthread.h>
+#include <VBox/vmm/pdmifs.h>
+#include <VBox/vmm/pdmins.h>
+#include <VBox/vmm/pdmcommon.h>
+#include <VBox/vmm/pdmasynccompletion.h>
+#ifdef VBOX_WITH_NETSHAPER
+#include <VBox/vmm/pdmnetshaper.h>
+#endif /* VBOX_WITH_NETSHAPER */
+#include <VBox/vmm/pdmblkcache.h>
+#include <VBox/vmm/tm.h>
+#include <VBox/vmm/ssm.h>
+#include <VBox/vmm/cfgm.h>
+#include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/mm.h>
+#include <VBox/vmm/ftm.h>
+#include <VBox/err.h>
+#include <iprt/stdarg.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_driver The PDM Drivers API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/** Pointer const PDM Driver API, ring-3. */
+typedef R3PTRTYPE(struct PDMDRVHLPR3 const *) PCPDMDRVHLPR3;
+/** Pointer const PDM Driver API, ring-0. */
+typedef R0PTRTYPE(struct PDMDRVHLPR0 const *) PCPDMDRVHLPR0;
+/** Pointer const PDM Driver API, raw-mode context. */
+typedef RCPTRTYPE(struct PDMDRVHLPRC const *) PCPDMDRVHLPRC;
+
+
+/**
+ * Construct a driver instance for a VM.
+ *
+ * @returns VBox status.
+ * @param pDrvIns The driver instance data. If the registration structure
+ * is needed, it can be accessed thru pDrvIns->pReg.
+ * @param pCfg Configuration node handle for the driver. This is
+ * expected to be in high demand in the constructor and is
+ * therefore passed as an argument. When using it at other
+ * times, it can be accessed via pDrvIns->pCfg.
+ * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
+ */
+typedef DECLCALLBACK(int) FNPDMDRVCONSTRUCT(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags);
+/** Pointer to a FNPDMDRVCONSTRUCT() function. */
+typedef FNPDMDRVCONSTRUCT *PFNPDMDRVCONSTRUCT;
+
+/**
+ * Destruct a driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that
+ * any non-VM resources can be freed correctly.
+ *
+ * @param pDrvIns The driver instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVDESTRUCT(PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMDRVDESTRUCT() function. */
+typedef FNPDMDRVDESTRUCT *PFNPDMDRVDESTRUCT;
+
+/**
+ * Driver relocation callback.
+ *
+ * This is called when the instance data has been relocated in raw-mode context
+ * (RC). It is also called when the RC hypervisor selects changes. The driver
+ * must fixup all necessary pointers and re-query all interfaces to other RC
+ * devices and drivers.
+ *
+ * Before the RC code is executed the first time, this function will be called
+ * with a 0 delta so RC pointer calculations can be one in one place.
+ *
+ * @param pDrvIns Pointer to the driver instance.
+ * @param offDelta The relocation delta relative to the old location.
+ *
+ * @remark A relocation CANNOT fail.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVRELOCATE(PPDMDRVINS pDrvIns, RTGCINTPTR offDelta);
+/** Pointer to a FNPDMDRVRELOCATE() function. */
+typedef FNPDMDRVRELOCATE *PFNPDMDRVRELOCATE;
+
+/**
+ * Driver I/O Control interface.
+ *
+ * This is used by external components, such as the COM interface, to
+ * communicate with a driver using a driver specific interface. Generally,
+ * the driver interfaces are used for this task.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Pointer to the driver instance.
+ * @param uFunction Function to perform.
+ * @param pvIn Pointer to input data.
+ * @param cbIn Size of input data.
+ * @param pvOut Pointer to output data.
+ * @param cbOut Size of output data.
+ * @param pcbOut Where to store the actual size of the output data.
+ */
+typedef DECLCALLBACK(int) FNPDMDRVIOCTL(PPDMDRVINS pDrvIns, uint32_t uFunction,
+ void *pvIn, uint32_t cbIn,
+ void *pvOut, uint32_t cbOut, uint32_t *pcbOut);
+/** Pointer to a FNPDMDRVIOCTL() function. */
+typedef FNPDMDRVIOCTL *PFNPDMDRVIOCTL;
+
+/**
+ * Power On notification.
+ *
+ * @param pDrvIns The driver instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVPOWERON(PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMDRVPOWERON() function. */
+typedef FNPDMDRVPOWERON *PFNPDMDRVPOWERON;
+
+/**
+ * Reset notification.
+ *
+ * @returns VBox status.
+ * @param pDrvIns The driver instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVRESET(PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMDRVRESET() function. */
+typedef FNPDMDRVRESET *PFNPDMDRVRESET;
+
+/**
+ * Suspend notification.
+ *
+ * @returns VBox status.
+ * @param pDrvIns The driver instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVSUSPEND(PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMDRVSUSPEND() function. */
+typedef FNPDMDRVSUSPEND *PFNPDMDRVSUSPEND;
+
+/**
+ * Resume notification.
+ *
+ * @returns VBox status.
+ * @param pDrvIns The driver instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVRESUME(PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMDRVRESUME() function. */
+typedef FNPDMDRVRESUME *PFNPDMDRVRESUME;
+
+/**
+ * Power Off notification.
+ *
+ * This is only called when the VMR3PowerOff call is made on a running VM. This
+ * means that there is no notification if the VM was suspended before being
+ * powered of. There will also be no callback when hot plugging devices or when
+ * replumbing the driver stack.
+ *
+ * @param pDrvIns The driver instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVPOWEROFF(PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMDRVPOWEROFF() function. */
+typedef FNPDMDRVPOWEROFF *PFNPDMDRVPOWEROFF;
+
+/**
+ * Attach command.
+ *
+ * This is called to let the drive attach to a driver at runtime. This is not
+ * called during VM construction, the driver constructor have to do this by
+ * calling PDMDrvHlpAttach.
+ *
+ * This is like plugging in the keyboard or mouse after turning on the PC.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param fFlags Flags, combination of the PDM_TACH_FLAGS_* \#defines.
+ */
+typedef DECLCALLBACK(int) FNPDMDRVATTACH(PPDMDRVINS pDrvIns, uint32_t fFlags);
+/** Pointer to a FNPDMDRVATTACH() function. */
+typedef FNPDMDRVATTACH *PFNPDMDRVATTACH;
+
+/**
+ * Detach notification.
+ *
+ * This is called when a driver below it in the chain is detaching itself
+ * from it. The driver should adjust it's state to reflect this.
+ *
+ * This is like ejecting a cdrom or floppy.
+ *
+ * @param pDrvIns The driver instance.
+ * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
+ */
+typedef DECLCALLBACK(void) FNPDMDRVDETACH(PPDMDRVINS pDrvIns, uint32_t fFlags);
+/** Pointer to a FNPDMDRVDETACH() function. */
+typedef FNPDMDRVDETACH *PFNPDMDRVDETACH;
+
+
+
+/**
+ * PDM Driver Registration Structure.
+ *
+ * This structure is used when registering a driver from VBoxInitDrivers() (in
+ * host ring-3 context). PDM will continue use till the VM is terminated.
+ */
+typedef struct PDMDRVREG
+{
+ /** Structure version. PDM_DRVREG_VERSION defines the current version. */
+ uint32_t u32Version;
+ /** Driver name. */
+ char szName[32];
+ /** Name of the raw-mode context module (no path).
+ * Only evalutated if PDM_DRVREG_FLAGS_RC is set. */
+ char szRCMod[32];
+ /** Name of the ring-0 module (no path).
+ * Only evalutated if PDM_DRVREG_FLAGS_R0 is set. */
+ char szR0Mod[32];
+ /** The description of the driver. The UTF-8 string pointed to shall, like this structure,
+ * remain unchanged from registration till VM destruction. */
+ const char *pszDescription;
+
+ /** Flags, combination of the PDM_DRVREG_FLAGS_* \#defines. */
+ uint32_t fFlags;
+ /** Driver class(es), combination of the PDM_DRVREG_CLASS_* \#defines. */
+ uint32_t fClass;
+ /** Maximum number of instances (per VM). */
+ uint32_t cMaxInstances;
+ /** Size of the instance data. */
+ uint32_t cbInstance;
+
+ /** Construct instance - required. */
+ PFNPDMDRVCONSTRUCT pfnConstruct;
+ /** Destruct instance - optional. */
+ PFNPDMDRVDESTRUCT pfnDestruct;
+ /** Relocation command - optional. */
+ PFNPDMDRVRELOCATE pfnRelocate;
+ /** I/O control - optional. */
+ PFNPDMDRVIOCTL pfnIOCtl;
+ /** Power on notification - optional. */
+ PFNPDMDRVPOWERON pfnPowerOn;
+ /** Reset notification - optional. */
+ PFNPDMDRVRESET pfnReset;
+ /** Suspend notification - optional. */
+ PFNPDMDRVSUSPEND pfnSuspend;
+ /** Resume notification - optional. */
+ PFNPDMDRVRESUME pfnResume;
+ /** Attach command - optional. */
+ PFNPDMDRVATTACH pfnAttach;
+ /** Detach notification - optional. */
+ PFNPDMDRVDETACH pfnDetach;
+ /** Power off notification - optional. */
+ PFNPDMDRVPOWEROFF pfnPowerOff;
+ /** @todo */
+ PFNRT pfnSoftReset;
+ /** Initialization safty marker. */
+ uint32_t u32VersionEnd;
+} PDMDRVREG;
+/** Pointer to a PDM Driver Structure. */
+typedef PDMDRVREG *PPDMDRVREG;
+/** Const pointer to a PDM Driver Structure. */
+typedef PDMDRVREG const *PCPDMDRVREG;
+
+/** Current DRVREG version number. */
+#define PDM_DRVREG_VERSION PDM_VERSION_MAKE(0xf0ff, 1, 0)
+
+/** PDM Driver Flags.
+ * @{ */
+/** @def PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT
+ * The bit count for the current host. */
+#if HC_ARCH_BITS == 32
+# define PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000001)
+#elif HC_ARCH_BITS == 64
+# define PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT UINT32_C(0x00000002)
+#else
+# error Unsupported HC_ARCH_BITS value.
+#endif
+/** The host bit count mask. */
+#define PDM_DRVREG_FLAGS_HOST_BITS_MASK UINT32_C(0x00000003)
+/** This flag is used to indicate that the driver has a RC component. */
+#define PDM_DRVREG_FLAGS_RC UINT32_C(0x00000010)
+/** This flag is used to indicate that the driver has a R0 component. */
+#define PDM_DRVREG_FLAGS_R0 UINT32_C(0x00000020)
+
+/** @} */
+
+
+/** PDM Driver Classes.
+ * @{ */
+/** Mouse input driver. */
+#define PDM_DRVREG_CLASS_MOUSE RT_BIT(0)
+/** Keyboard input driver. */
+#define PDM_DRVREG_CLASS_KEYBOARD RT_BIT(1)
+/** Display driver. */
+#define PDM_DRVREG_CLASS_DISPLAY RT_BIT(2)
+/** Network transport driver. */
+#define PDM_DRVREG_CLASS_NETWORK RT_BIT(3)
+/** Block driver. */
+#define PDM_DRVREG_CLASS_BLOCK RT_BIT(4)
+/** Media driver. */
+#define PDM_DRVREG_CLASS_MEDIA RT_BIT(5)
+/** Mountable driver. */
+#define PDM_DRVREG_CLASS_MOUNTABLE RT_BIT(6)
+/** Audio driver. */
+#define PDM_DRVREG_CLASS_AUDIO RT_BIT(7)
+/** VMMDev driver. */
+#define PDM_DRVREG_CLASS_VMMDEV RT_BIT(8)
+/** Status driver. */
+#define PDM_DRVREG_CLASS_STATUS RT_BIT(9)
+/** ACPI driver. */
+#define PDM_DRVREG_CLASS_ACPI RT_BIT(10)
+/** USB related driver. */
+#define PDM_DRVREG_CLASS_USB RT_BIT(11)
+/** ISCSI Transport related driver. */
+#define PDM_DRVREG_CLASS_ISCSITRANSPORT RT_BIT(12)
+/** Char driver. */
+#define PDM_DRVREG_CLASS_CHAR RT_BIT(13)
+/** Stream driver. */
+#define PDM_DRVREG_CLASS_STREAM RT_BIT(14)
+/** SCSI driver. */
+#define PDM_DRVREG_CLASS_SCSI RT_BIT(15)
+/** Generic raw PCI device driver. */
+#define PDM_DRVREG_CLASS_PCIRAW RT_BIT(16)
+/** @} */
+
+
+/**
+ * PDM Driver Instance.
+ *
+ * @implements PDMIBASE
+ */
+typedef struct PDMDRVINS
+{
+ /** Structure version. PDM_DRVINS_VERSION defines the current version. */
+ uint32_t u32Version;
+ /** Driver instance number. */
+ uint32_t iInstance;
+
+ /** Pointer the PDM Driver API. */
+ RCPTRTYPE(PCPDMDRVHLPRC) pHlpRC;
+ /** Pointer to driver instance data. */
+ RCPTRTYPE(void *) pvInstanceDataRC;
+
+ /** Pointer the PDM Driver API. */
+ R0PTRTYPE(PCPDMDRVHLPR0) pHlpR0;
+ /** Pointer to driver instance data. */
+ R0PTRTYPE(void *) pvInstanceDataR0;
+
+ /** Pointer the PDM Driver API. */
+ R3PTRTYPE(PCPDMDRVHLPR3) pHlpR3;
+ /** Pointer to driver instance data. */
+ R3PTRTYPE(void *) pvInstanceDataR3;
+
+ /** Pointer to driver registration structure. */
+ R3PTRTYPE(PCPDMDRVREG) pReg;
+ /** Configuration handle. */
+ R3PTRTYPE(PCFGMNODE) pCfg;
+
+ /** Pointer to the base interface of the device/driver instance above. */
+ R3PTRTYPE(PPDMIBASE) pUpBase;
+ /** Pointer to the base interface of the driver instance below. */
+ R3PTRTYPE(PPDMIBASE) pDownBase;
+
+ /** The base interface of the driver.
+ * The driver constructor initializes this. */
+ PDMIBASE IBase;
+
+ /** Tracing indicator. */
+ uint32_t fTracing;
+ /** The tracing ID of this device. */
+ uint32_t idTracing;
+#if HC_ARCH_BITS == 32
+ /** Align the internal data more naturally. */
+ uint32_t au32Padding[HC_ARCH_BITS == 32 ? 7 : 0];
+#endif
+
+ /** Internal data. */
+ union
+ {
+#ifdef PDMDRVINSINT_DECLARED
+ PDMDRVINSINT s;
+#endif
+ uint8_t padding[HC_ARCH_BITS == 32 ? 40 + 32 : 72 + 24];
+ } Internal;
+
+ /** Driver instance data. The size of this area is defined
+ * in the PDMDRVREG::cbInstanceData field. */
+ char achInstanceData[4];
+} PDMDRVINS;
+
+/** Current DRVREG version number. */
+#define PDM_DRVINS_VERSION PDM_VERSION_MAKE(0xf0fe, 2, 0)
+
+/** Converts a pointer to the PDMDRVINS::IBase to a pointer to PDMDRVINS. */
+#define PDMIBASE_2_PDMDRV(pInterface) ( (PPDMDRVINS)((char *)(pInterface) - RT_OFFSETOF(PDMDRVINS, IBase)) )
+
+/** @def PDMDRVINS_2_RCPTR
+ * Converts a PDM Driver instance pointer a RC PDM Driver instance pointer.
+ */
+#define PDMDRVINS_2_RCPTR(pDrvIns) ( (RCPTRTYPE(PPDMDRVINS))((RTGCUINTPTR)(pDrvIns)->pvInstanceDataRC - RT_OFFSETOF(PDMDRVINS, achInstanceData)) )
+
+/** @def PDMDRVINS_2_R3PTR
+ * Converts a PDM Driver instance pointer a R3 PDM Driver instance pointer.
+ */
+#define PDMDRVINS_2_R3PTR(pDrvIns) ( (R3PTRTYPE(PPDMDRVINS))((RTHCUINTPTR)(pDrvIns)->pvInstanceDataR3 - RT_OFFSETOF(PDMDRVINS, achInstanceData)) )
+
+/** @def PDMDRVINS_2_R0PTR
+ * Converts a PDM Driver instance pointer a R0 PDM Driver instance pointer.
+ */
+#define PDMDRVINS_2_R0PTR(pDrvIns) ( (R0PTRTYPE(PPDMDRVINS))((RTR0UINTPTR)(pDrvIns)->pvInstanceDataR0 - RT_OFFSETOF(PDMDRVINS, achInstanceData)) )
+
+
+
+/**
+ * Checks the structure versions of the drive instance and driver helpers,
+ * returning if they are incompatible.
+ *
+ * Intended for the constructor.
+ *
+ * @param pDrvIns Pointer to the PDM driver instance.
+ */
+#define PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns) \
+ do \
+ { \
+ PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
+ AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
+ ("DrvIns=%#x mine=%#x\n", (pDrvIns)->u32Version, PDM_DRVINS_VERSION), \
+ VERR_PDM_DRVINS_VERSION_MISMATCH); \
+ AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
+ ("DrvHlp=%#x mine=%#x\n", (pDrvIns)->pHlpR3->u32Version, PDM_DRVHLPR3_VERSION), \
+ VERR_PDM_DRVHLPR3_VERSION_MISMATCH); \
+ } while (0)
+
+/**
+ * Quietly checks the structure versions of the drive instance and driver
+ * helpers, returning if they are incompatible.
+ *
+ * Intended for the destructor.
+ *
+ * @param pDrvIns Pointer to the PDM driver instance.
+ */
+#define PDMDRV_CHECK_VERSIONS_RETURN_VOID(pDrvIns) \
+ do \
+ { \
+ PPDMDRVINS pDrvInsTypeCheck = (pDrvIns); NOREF(pDrvInsTypeCheck); \
+ if (RT_UNLIKELY( !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->u32Version, PDM_DRVINS_VERSION) \
+ || !PDM_VERSION_ARE_COMPATIBLE((pDrvIns)->pHlpR3->u32Version, PDM_DRVHLPR3_VERSION)) ) \
+ return; \
+ } while (0)
+
+/**
+ * Wrapper around CFGMR3ValidateConfig for the root config for use in the
+ * constructor - returns on failure.
+ *
+ * This should be invoked after having initialized the instance data
+ * sufficiently for the correct operation of the destructor. The destructor is
+ * always called!
+ *
+ * @param pDrvIns Pointer to the PDM driver instance.
+ * @param pszValidValues Patterns describing the valid value names. See
+ * RTStrSimplePatternMultiMatch for details on the
+ * pattern syntax.
+ * @param pszValidNodes Patterns describing the valid node (key) names.
+ * Pass empty string if no valid nodess.
+ */
+#define PDMDRV_VALIDATE_CONFIG_RETURN(pDrvIns, pszValidValues, pszValidNodes) \
+ do \
+ { \
+ int rcValCfg = CFGMR3ValidateConfig((pDrvIns)->pCfg, "/", pszValidValues, pszValidNodes, \
+ (pDrvIns)->pReg->szName, (pDrvIns)->iInstance); \
+ if (RT_FAILURE(rcValCfg)) \
+ return rcValCfg; \
+ } while (0)
+
+
+
+/**
+ * USB hub registration structure.
+ */
+typedef struct PDMUSBHUBREG
+{
+ /** Structure version number. PDM_USBHUBREG_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Request the hub to attach of the specified device.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The hub instance.
+ * @param pUsbIns The device to attach.
+ * @param piPort Where to store the port number the device was attached to.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAttachDevice,(PPDMDRVINS pDrvIns, PPDMUSBINS pUsbIns, uint32_t *piPort));
+
+ /**
+ * Request the hub to detach of the specified device.
+ *
+ * The device has previously been attached to the hub with the
+ * pfnAttachDevice call. This call is not currently expected to
+ * fail.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The hub instance.
+ * @param pUsbIns The device to detach.
+ * @param iPort The port number returned by the attach call.
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDetachDevice,(PPDMDRVINS pDrvIns, PPDMUSBINS pUsbIns, uint32_t iPort));
+
+ /** Counterpart to u32Version, same value. */
+ uint32_t u32TheEnd;
+} PDMUSBHUBREG;
+/** Pointer to a const USB hub registration structure. */
+typedef const PDMUSBHUBREG *PCPDMUSBHUBREG;
+
+/** Current PDMUSBHUBREG version number. */
+#define PDM_USBHUBREG_VERSION PDM_VERSION_MAKE(0xf0fd, 1, 0)
+
+
+/**
+ * USB hub helpers.
+ * This is currently just a place holder.
+ */
+typedef struct PDMUSBHUBHLP
+{
+ /** Structure version. PDM_USBHUBHLP_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMUSBHUBHLP;
+/** Pointer to PCI helpers. */
+typedef PDMUSBHUBHLP *PPDMUSBHUBHLP;
+/** Pointer to const PCI helpers. */
+typedef const PDMUSBHUBHLP *PCPDMUSBHUBHLP;
+/** Pointer to const PCI helpers pointer. */
+typedef PCPDMUSBHUBHLP *PPCPDMUSBHUBHLP;
+
+/** Current PDMUSBHUBHLP version number. */
+#define PDM_USBHUBHLP_VERSION PDM_VERSION_MAKE(0xf0fc, 1, 0)
+
+
+/**
+ * PDM Driver API - raw-mode context variant.
+ */
+typedef struct PDMDRVHLPRC
+{
+ /** Structure version. PDM_DRVHLPRC_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetError,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLRCCALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
+
+ /**
+ * Assert that the current thread is the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDrvIns Driver instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLRCCALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Assert that the current thread is NOT the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDrvIns Driver instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLRCCALLBACKMEMBER(bool, pfnAssertOther,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Notify FTM about a checkpoint occurrence
+ *
+ * @param pDrvIns The driver instance.
+ * @param enmType Checkpoint type
+ * @thread Any
+ */
+ DECLRCCALLBACKMEMBER(int, pfnFTSetCheckpoint,(PPDMDRVINS pDrvIns, FTMCHECKPOINTTYPE enmType));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMDRVHLPRC;
+/** Current PDMDRVHLPRC version number. */
+#define PDM_DRVHLPRC_VERSION PDM_VERSION_MAKE(0xf0f9, 2, 0)
+
+
+/**
+ * PDM Driver API, ring-0 context.
+ */
+typedef struct PDMDRVHLPR0
+{
+ /** Structure version. PDM_DRVHLPR0_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetError,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR0CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
+
+ /**
+ * Assert that the current thread is the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDrvIns Driver instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR0CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Assert that the current thread is NOT the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDrvIns Driver instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR0CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Notify FTM about a checkpoint occurrence
+ *
+ * @param pDrvIns The driver instance.
+ * @param enmType Checkpoint type
+ * @thread Any
+ */
+ DECLR0CALLBACKMEMBER(int, pfnFTSetCheckpoint,(PPDMDRVINS pDrvIns, FTMCHECKPOINTTYPE enmType));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMDRVHLPR0;
+/** Current DRVHLP version number. */
+#define PDM_DRVHLPR0_VERSION PDM_VERSION_MAKE(0xf0f8, 2, 0)
+
+
+#ifdef IN_RING3
+
+/**
+ * PDM Driver API.
+ */
+typedef struct PDMDRVHLPR3
+{
+ /** Structure version. PDM_DRVHLPR3_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Attaches a driver (chain) to the driver.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
+ * @param ppBaseInterface Where to store the pointer to the base interface.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAttach,(PPDMDRVINS pDrvIns, uint32_t fFlags, PPDMIBASE *ppBaseInterface));
+
+ /**
+ * Detach the driver the drivers below us.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDetach,(PPDMDRVINS pDrvIns, uint32_t fFlags));
+
+ /**
+ * Detach the driver from the driver above it and destroy this
+ * driver and all drivers below it.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags PDM_TACH_FLAGS_NOT_HOT_PLUG or 0.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDetachSelf,(PPDMDRVINS pDrvIns, uint32_t fFlags));
+
+ /**
+ * Prepare a media mount.
+ *
+ * The driver must not have anything attached to itself
+ * when calling this function as the purpose is to set up the configuration
+ * of an future attachment.
+ *
+ * @returns VBox status code
+ * @param pDrvIns Driver instance.
+ * @param pszFilename Pointer to filename. If this is NULL it assumed that the caller have
+ * constructed a configuration which can be attached to the bottom driver.
+ * @param pszCoreDriver Core driver name. NULL will cause autodetection. Ignored if pszFilanem is NULL.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMountPrepare,(PPDMDRVINS pDrvIns, const char *pszFilename, const char *pszCoreDriver));
+
+ /**
+ * Assert that the current thread is the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDrvIns Driver instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Assert that the current thread is NOT the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pDrvIns Driver instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMDRVINS pDrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetError,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pDrvIns Driver instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMDRVINS pDrvIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeError,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
+
+ /**
+ * Gets the VM state.
+ *
+ * @returns VM state.
+ * @param pDrvIns The driver instance.
+ * @thread Any thread (just keep in mind that it's volatile info).
+ */
+ DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMDRVINS pDrvIns));
+
+ /**
+ * Checks if the VM was teleported and hasn't been fully resumed yet.
+ *
+ * @returns true / false.
+ * @param pDrvIns The driver instance.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnVMTeleportedAndNotFullyResumedYet,(PPDMDRVINS pDrvIns));
+
+ /**
+ * Gets the support driver session.
+ *
+ * This is intended for working using the semaphore API.
+ *
+ * @returns Support driver session handle.
+ * @param pDrvIns The driver instance.
+ */
+ DECLR3CALLBACKMEMBER(PSUPDRVSESSION, pfnGetSupDrvSession,(PPDMDRVINS pDrvIns));
+
+ /**
+ * Create a queue.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param cbItem Size a queue item.
+ * @param cItems Number of items in the queue.
+ * @param cMilliesInterval Number of milliseconds between polling the queue.
+ * If 0 then the emulation thread will be notified whenever an item arrives.
+ * @param pfnCallback The consumer function.
+ * @param pszName The queue base name. The instance number will be
+ * appended automatically.
+ * @param ppQueue Where to store the queue handle on success.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueueCreate,(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue));
+
+ /**
+ * Query the virtual timer frequency.
+ *
+ * @returns Frequency in Hz.
+ * @param pDrvIns Driver instance.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnTMGetVirtualFreq,(PPDMDRVINS pDrvIns));
+
+ /**
+ * Query the virtual time.
+ *
+ * @returns The current virtual time.
+ * @param pDrvIns Driver instance.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnTMGetVirtualTime,(PPDMDRVINS pDrvIns));
+
+ /**
+ * Creates a timer.
+ *
+ * @returns VBox status.
+ * @param pDrvIns Driver instance.
+ * @param enmClock The clock to use on this timer.
+ * @param pfnCallback Callback function.
+ * @param pvUser The user argument to the callback.
+ * @param fFlags Timer creation flags, see grp_tm_timer_flags.
+ * @param pszDesc Pointer to description string which must stay around
+ * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
+ * @param ppTimer Where to store the timer on success.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
+
+ /**
+ * Register a save state data unit.
+ *
+ * @returns VBox status.
+ * @param pDrvIns Driver instance.
+ * @param uVersion Data layout version number.
+ * @param cbGuess The approximate amount of data in the unit.
+ * Only for progress indicators.
+ *
+ * @param pfnLivePrep Prepare live save callback, optional.
+ * @param pfnLiveExec Execute live save callback, optional.
+ * @param pfnLiveVote Vote live save callback, optional.
+ *
+ * @param pfnSavePrep Prepare save callback, optional.
+ * @param pfnSaveExec Execute save callback, optional.
+ * @param pfnSaveDone Done save callback, optional.
+ *
+ * @param pfnLoadPrep Prepare load callback, optional.
+ * @param pfnLoadExec Execute load callback, optional.
+ * @param pfnLoadDone Done load callback, optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
+ PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
+ PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
+ PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone));
+
+ /**
+ * Deregister a save state data unit.
+ *
+ * @returns VBox status.
+ * @param pDrvIns Driver instance.
+ * @param pszName Data unit name.
+ * @param uInstance The instance identifier of the data unit.
+ * This must together with the name be unique.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSSMDeregister,(PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance));
+
+ /**
+ * Register an info handler with DBGF.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param pszName Data unit name.
+ * @param pszDesc The description of the info and any arguments
+ * the handler may take.
+ * @param pfnHandler The handler function to be called to display the
+ * info.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMDRVINS pDrvIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler));
+
+ /**
+ * Deregister an info handler from DBGF.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance.
+ * @param pszName Data unit name.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDBGFInfoDeregister,(PPDMDRVINS pDrvIns, const char *pszName));
+
+ /**
+ * Registers a statistics sample if statistics are enabled.
+ *
+ * @param pDrvIns Driver instance.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param pszName Sample name. The name is on this form "/<component>/<sample>".
+ * Further nesting is possible.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSTAMRegister,(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, const char *pszName,
+ STAMUNIT enmUnit, const char *pszDesc));
+
+ /**
+ * Same as pfnSTAMRegister except that the name is specified in a
+ * RTStrPrintf like fashion.
+ *
+ * @param pDrvIns Driver instance.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ * @param pszName The sample name format string.
+ * @param ... Arguments to the format string.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterF,(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
+ STAMUNIT enmUnit, const char *pszDesc, const char *pszName, ...));
+
+ /**
+ * Same as pfnSTAMRegister except that the name is specified in a
+ * RTStrPrintfV like fashion.
+ *
+ * @param pDrvIns Driver instance.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ * @param pszName The sample name format string.
+ * @param args Arguments to the format string.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
+ STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list args));
+
+ /**
+ * Deregister a statistic item previously registered with pfnSTAMRegister,
+ * pfnSTAMRegisterF or pfnSTAMRegisterV
+ *
+ * @returns VBox status.
+ * @param pDrvIns Driver instance.
+ * @param pvSample Pointer to the sample.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSTAMDeregister,(PPDMDRVINS pDrvIns, void *pvSample));
+
+ /**
+ * Calls the HC R0 VMM entry point, in a safer but slower manner than
+ * SUPR3CallVMMR0.
+ *
+ * When entering using this call the R0 components can call into the host kernel
+ * (i.e. use the SUPR0 and RT APIs).
+ *
+ * See VMMR0Entry() for more details.
+ *
+ * @returns error code specific to uFunction.
+ * @param pDrvIns The driver instance.
+ * @param uOperation Operation to execute.
+ * This is limited to services.
+ * @param pvArg Pointer to argument structure or if cbArg is 0 just an value.
+ * @param cbArg The size of the argument. This is used to copy whatever the argument
+ * points at into a kernel buffer to avoid problems like the user page
+ * being invalidated while we're executing the call.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSUPCallVMMR0Ex,(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg));
+
+ /**
+ * Registers a USB HUB.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param fVersions Indicates the kinds of USB devices that can be attached to this HUB.
+ * @param cPorts The number of ports.
+ * @param pUsbHubReg The hub callback structure that PDMUsb uses to interact with it.
+ * @param ppUsbHubHlp The helper callback structure that the hub uses to talk to PDMUsb.
+ *
+ * @thread EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUSBRegisterHub,(PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp));
+
+ /**
+ * Set up asynchronous handling of a suspend, reset or power off notification.
+ *
+ * This shall only be called when getting the notification. It must be called
+ * for each one.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pfnAsyncNotify The callback.
+ * @thread EMT(0)
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMDRVINS pDrvIns, PFNPDMDRVASYNCNOTIFY pfnAsyncNotify));
+
+ /**
+ * Notify EMT(0) that the driver has completed the asynchronous notification
+ * handling.
+ *
+ * This can be called at any time, spurious calls will simply be ignored.
+ *
+ * @param pDrvIns The driver instance.
+ * @thread Any
+ */
+ DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMDRVINS pDrvIns));
+
+ /**
+ * Creates a PDM thread.
+ *
+ * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
+ * resuming, and destroying the thread as the VM state changes.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param ppThread Where to store the thread 'handle'.
+ * @param pvUser The user argument to the thread function.
+ * @param pfnThread The thread function.
+ * @param pfnWakeup The wakup callback. This is called on the EMT thread when
+ * a state change is pending.
+ * @param cbStack See RTThreadCreate.
+ * @param enmType See RTThreadCreate.
+ * @param pszName See RTThreadCreate.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
+ PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
+
+ /**
+ * Creates an async completion template for a driver instance.
+ *
+ * The template is used when creating new completion tasks.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param ppTemplate Where to store the template pointer on success.
+ * @param pfnCompleted The completion callback routine.
+ * @param pvTemplateUser Template user argument.
+ * @param pszDesc Description.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAsyncCompletionTemplateCreate,(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
+ PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser,
+ const char *pszDesc));
+
+#ifdef VBOX_WITH_NETSHAPER
+ /**
+ * Attaches network filter driver to a bandwidth group.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pcszBwGroup Name of the bandwidth group to attach to.
+ * @param pFilter Pointer to the filter we attach.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnNetShaperAttach,(PPDMDRVINS pDrvIns, const char *pszBwGroup,
+ PPDMNSFILTER pFilter));
+
+
+ /**
+ * Detaches network filter driver to a bandwidth group.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pFilter Pointer to the filter we attach.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnNetShaperDetach,(PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter));
+#endif /* VBOX_WITH_NETSHAPER */
+
+
+ /**
+ * Resolves the symbol for a raw-mode context interface.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pvInterface The interface structure.
+ * @param cbInterface The size of the interface structure.
+ * @param pszSymPrefix What to prefix the symbols in the list with before
+ * resolving them. This must start with 'drv' and
+ * contain the driver name.
+ * @param pszSymList List of symbols corresponding to the interface.
+ * There is generally a there is generally a define
+ * holding this list associated with the interface
+ * definition (INTERFACE_SYM_LIST). For more details
+ * see PDMR3LdrGetInterfaceSymbols.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLdrGetRCInterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
+ const char *pszSymPrefix, const char *pszSymList));
+
+ /**
+ * Resolves the symbol for a ring-0 context interface.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pvInterface The interface structure.
+ * @param cbInterface The size of the interface structure.
+ * @param pszSymPrefix What to prefix the symbols in the list with before
+ * resolving them. This must start with 'drv' and
+ * contain the driver name.
+ * @param pszSymList List of symbols corresponding to the interface.
+ * There is generally a there is generally a define
+ * holding this list associated with the interface
+ * definition (INTERFACE_SYM_LIST). For more details
+ * see PDMR3LdrGetInterfaceSymbols.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLdrGetR0InterfaceSymbols,(PPDMDRVINS pDrvIns, void *pvInterface, size_t cbInterface,
+ const char *pszSymPrefix, const char *pszSymList));
+ /**
+ * Initializes a PDM critical section.
+ *
+ * The PDM critical sections are derived from the IPRT critical sections, but
+ * works in both RC and R0 as well as R3.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pCritSect Pointer to the critical section.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszName The base name of the critical section. Will be
+ * mangeled with the instance number. For
+ * statistics and lock validation.
+ * @param va Arguments for the format string.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCritSectInit,(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect,
+ RT_SRC_POS_DECL, const char *pszName));
+
+ /**
+ * Call the ring-0 request handler routine of the driver.
+ *
+ * For this to work, the driver must be ring-0 enabled and export a request
+ * handler function. The name of the function must be the driver name in the
+ * PDMDRVREG struct prefixed with 'drvR0' and suffixed with 'ReqHandler'.
+ * The driver name will be capitalized. It shall take the exact same
+ * arguments as this function and be declared using PDMBOTHCBDECL. See
+ * FNPDMDRVREQHANDLERR0.
+ *
+ * @returns VBox status code.
+ * @retval VERR_SYMBOL_NOT_FOUND if the driver doesn't export the required
+ * handler function.
+ * @retval VERR_ACCESS_DENIED if the driver isn't ring-0 capable.
+ *
+ * @param pDrvIns The driver instance.
+ * @param uOperation The operation to perform.
+ * @param u64Arg 64-bit integer argument.
+ * @thread Any
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCallR0,(PPDMDRVINS pDrvIns, uint32_t uOperation, uint64_t u64Arg));
+
+ /**
+ * Notify FTM about a checkpoint occurrence
+ *
+ * @param pDrvIns The driver instance.
+ * @param enmType Checkpoint type
+ * @thread Any
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFTSetCheckpoint,(PPDMDRVINS pDrvIns, FTMCHECKPOINTTYPE enmType));
+
+ /**
+ * Creates a block cache for a driver driver instance.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param ppBlkCache Where to store the handle to the block cache.
+ * @param pfnXferComplete The I/O transfer complete callback.
+ * @param pfnXferEnqueue The I/O request enqueue callback.
+ * @param pcszId Unique ID used to identify the user.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnBlkCacheRetain, (PPDMDRVINS pDrvIns, PPPDMBLKCACHE ppBlkCache,
+ PFNPDMBLKCACHEXFERCOMPLETEDRV pfnXferComplete,
+ PFNPDMBLKCACHEXFERENQUEUEDRV pfnXferEnqueue,
+ PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV pfnXferEnqueueDiscard,
+ const char *pcszId));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMDRVHLPR3;
+/** Current DRVHLP version number. */
+#define PDM_DRVHLPR3_VERSION PDM_VERSION_MAKE(0xf0fb, 2, 0)
+
+#endif /* IN_RING3 */
+
+
+/**
+ * @copydoc PDMDRVHLP::pfnVMSetError
+ */
+DECLINLINE(int) PDMDrvHlpVMSetError(PPDMDRVINS pDrvIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ pDrvIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDrvIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+/** @def PDMDRV_SET_ERROR
+ * Set the VM error. See PDMDrvHlpVMSetError() for printf like message formatting.
+ */
+#define PDMDRV_SET_ERROR(pDrvIns, rc, pszError) \
+ PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, "%s", pszError)
+
+/**
+ * @copydoc PDMDRVHLP::pfnVMSetErrorV
+ */
+DECLINLINE(int) PDMDrvHlpVMSetErrorV(PPDMDRVINS pDrvIns, const int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
+{
+ return pDrvIns->CTX_SUFF(pHlp)->pfnVMSetErrorV(pDrvIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
+}
+
+
+/**
+ * @copydoc PDMDRVHLP::pfnVMSetRuntimeError
+ */
+DECLINLINE(int) PDMDrvHlpVMSetRuntimeError(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...)
+{
+ va_list va;
+ int rc;
+ va_start(va, pszFormat);
+ rc = pDrvIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDrvIns, fFlags, pszErrorId, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+/** @def PDMDRV_SET_RUNTIME_ERROR
+ * Set the VM runtime error. See PDMDrvHlpVMSetRuntimeError() for printf like message formatting.
+ */
+#define PDMDRV_SET_RUNTIME_ERROR(pDrvIns, fFlags, pszErrorId, pszError) \
+ PDMDrvHlpVMSetRuntimeError(pDrvIns, fFlags, pszErrorId, "%s", pszError)
+
+/**
+ * @copydoc PDMDRVHLP::pfnVMSetRuntimeErrorV
+ */
+DECLINLINE(int) PDMDrvHlpVMSetRuntimeErrorV(PPDMDRVINS pDrvIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va)
+{
+ return pDrvIns->CTX_SUFF(pHlp)->pfnVMSetRuntimeErrorV(pDrvIns, fFlags, pszErrorId, pszFormat, va);
+}
+
+
+
+/** @def PDMDRV_ASSERT_EMT
+ * Assert that the current thread is the emulation thread.
+ */
+#ifdef VBOX_STRICT
+# define PDMDRV_ASSERT_EMT(pDrvIns) pDrvIns->CTX_SUFF(pHlp)->pfnAssertEMT(pDrvIns, __FILE__, __LINE__, __FUNCTION__)
+#else
+# define PDMDRV_ASSERT_EMT(pDrvIns) do { } while (0)
+#endif
+
+/** @def PDMDRV_ASSERT_OTHER
+ * Assert that the current thread is NOT the emulation thread.
+ */
+#ifdef VBOX_STRICT
+# define PDMDRV_ASSERT_OTHER(pDrvIns) pDrvIns->CTX_SUFF(pHlp)->pfnAssertOther(pDrvIns, __FILE__, __LINE__, __FUNCTION__)
+#else
+# define PDMDRV_ASSERT_OTHER(pDrvIns) do { } while (0)
+#endif
+
+/**
+ * @copydoc PDMDRVHLP::pfnFTSetCheckpoint
+ */
+DECLINLINE(int) PDMDrvHlpFTSetCheckpoint(PPDMDRVINS pDrvIns, FTMCHECKPOINTTYPE enmType)
+{
+ return pDrvIns->CTX_SUFF(pHlp)->pfnFTSetCheckpoint(pDrvIns, enmType);
+}
+
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMDRVHLP::pfnAttach
+ */
+DECLINLINE(int) PDMDrvHlpAttach(PPDMDRVINS pDrvIns, uint32_t fFlags, PPDMIBASE *ppBaseInterface)
+{
+ return pDrvIns->pHlpR3->pfnAttach(pDrvIns, fFlags, ppBaseInterface);
+}
+
+/**
+ * Check that there is no driver below the us that we should attach to.
+ *
+ * @returns VERR_PDM_NO_ATTACHED_DRIVER if there is no driver.
+ * @param pDrvIns The driver instance.
+ */
+DECLINLINE(int) PDMDrvHlpNoAttach(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->pHlpR3->pfnAttach(pDrvIns, 0, NULL);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnDetach
+ */
+DECLINLINE(int) PDMDrvHlpDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
+{
+ return pDrvIns->pHlpR3->pfnDetach(pDrvIns, fFlags);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnDetachSelf
+ */
+DECLINLINE(int) PDMDrvHlpDetachSelf(PPDMDRVINS pDrvIns, uint32_t fFlags)
+{
+ return pDrvIns->pHlpR3->pfnDetachSelf(pDrvIns, fFlags);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnMountPrepare
+ */
+DECLINLINE(int) PDMDrvHlpMountPrepare(PPDMDRVINS pDrvIns, const char *pszFilename, const char *pszCoreDriver)
+{
+ return pDrvIns->pHlpR3->pfnMountPrepare(pDrvIns, pszFilename, pszCoreDriver);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnVMState
+ */
+DECLINLINE(VMSTATE) PDMDrvHlpVMState(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->CTX_SUFF(pHlp)->pfnVMState(pDrvIns);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnVMTeleportedAndNotFullyResumedYet
+ */
+DECLINLINE(bool) PDMDrvHlpVMTeleportedAndNotFullyResumedYet(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->pHlpR3->pfnVMTeleportedAndNotFullyResumedYet(pDrvIns);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnGetSupDrvSession
+ */
+DECLINLINE(PSUPDRVSESSION) PDMDrvHlpGetSupDrvSession(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->pHlpR3->pfnGetSupDrvSession(pDrvIns);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnQueueCreate
+ */
+DECLINLINE(int) PDMDrvHlpQueueCreate(PPDMDRVINS pDrvIns, uint32_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue)
+{
+ return pDrvIns->pHlpR3->pfnQueueCreate(pDrvIns, cbItem, cItems, cMilliesInterval, pfnCallback, pszName, ppQueue);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnTMGetVirtualFreq
+ */
+DECLINLINE(uint64_t) PDMDrvHlpTMGetVirtualFreq(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->pHlpR3->pfnTMGetVirtualFreq(pDrvIns);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnTMGetVirtualTime
+ */
+DECLINLINE(uint64_t) PDMDrvHlpTMGetVirtualTime(PPDMDRVINS pDrvIns)
+{
+ return pDrvIns->pHlpR3->pfnTMGetVirtualTime(pDrvIns);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnTMTimerCreate
+ */
+DECLINLINE(int) PDMDrvHlpTMTimerCreate(PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+{
+ return pDrvIns->pHlpR3->pfnTMTimerCreate(pDrvIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
+}
+
+/**
+ * Register a save state data unit.
+ *
+ * @returns VBox status.
+ * @param pDrvIns Driver instance.
+ * @param uVersion Data layout version number.
+ * @param cbGuess The approximate amount of data in the unit.
+ * Only for progress indicators.
+ * @param pfnSaveExec Execute save callback, optional.
+ * @param pfnLoadExec Execute load callback, optional.
+ */
+DECLINLINE(int) PDMDrvHlpSSMRegister(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
+ PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVLOADEXEC pfnLoadExec)
+{
+ return pDrvIns->pHlpR3->pfnSSMRegister(pDrvIns, uVersion, cbGuess,
+ NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveVote*/,
+ NULL /*pfnSavePrep*/, pfnSaveExec, NULL /*pfnSaveDone*/,
+ NULL /*pfnLoadPrep*/, pfnLoadExec, NULL /*pfnLoadDone*/);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnSSMRegister
+ */
+DECLINLINE(int) PDMDrvHlpSSMRegisterEx(PPDMDRVINS pDrvIns, uint32_t uVersion, size_t cbGuess,
+ PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
+ PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
+ PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone)
+{
+ return pDrvIns->pHlpR3->pfnSSMRegister(pDrvIns, uVersion, cbGuess,
+ pfnLivePrep, pfnLiveExec, pfnLiveVote,
+ pfnSavePrep, pfnSaveExec, pfnSaveDone,
+ pfnLoadPrep, pfnLoadExec, pfnLoadDone);
+}
+
+/**
+ * Register a load done callback.
+ *
+ * @returns VBox status.
+ * @param pDrvIns Driver instance.
+ * @param pfnLoadDone Done load callback, optional.
+ */
+DECLINLINE(int) PDMDrvHlpSSMRegisterLoadDone(PPDMDRVINS pDrvIns, PFNSSMDRVLOADDONE pfnLoadDone)
+{
+ return pDrvIns->pHlpR3->pfnSSMRegister(pDrvIns, 0 /*uVersion*/, 0 /*cbGuess*/,
+ NULL /*pfnLivePrep*/, NULL /*pfnLiveExec*/, NULL /*pfnLiveVote*/,
+ NULL /*pfnSavePrep*/, NULL /*pfnSaveExec*/, NULL /*pfnSaveDone*/,
+ NULL /*pfnLoadPrep*/, NULL /*pfnLoadExec*/, pfnLoadDone);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnDBGFInfoRegister
+ */
+DECLINLINE(int) PDMDrvHlpDBGFInfoRegister(PPDMDRVINS pDrvIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler)
+{
+ return pDrvIns->pHlpR3->pfnDBGFInfoRegister(pDrvIns, pszName, pszDesc, pfnHandler);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnDBGFInfoDeregister
+ */
+DECLINLINE(int) PDMDrvHlpDBGFInfoDeregister(PPDMDRVINS pDrvIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERDRV pfnHandler)
+{
+ return pDrvIns->pHlpR3->pfnDBGFInfoRegister(pDrvIns, pszName, pszDesc, pfnHandler);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnSTAMRegister
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegister(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
+{
+ pDrvIns->pHlpR3->pfnSTAMRegister(pDrvIns, pvSample, enmType, pszName, enmUnit, pszDesc);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnSTAMRegisterF
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegisterF(PPDMDRVINS pDrvIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ const char *pszDesc, const char *pszName, ...)
+{
+ va_list va;
+ va_start(va, pszName);
+ pDrvIns->pHlpR3->pfnSTAMRegisterV(pDrvIns, pvSample, enmType, enmVisibility, enmUnit, pszDesc, pszName, va);
+ va_end(va);
+}
+
+/**
+ * Convenience wrapper that registers counter which is always visible.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pCounter Pointer to the counter variable.
+ * @param pszName The name of the sample. This is prefixed with
+ * "/Drivers/<drivername>-<instance no>/".
+ * @param enmUnit The unit.
+ * @param pszDesc The description.
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegCounterEx(PPDMDRVINS pDrvIns, PSTAMCOUNTER pCounter, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
+{
+ pDrvIns->pHlpR3->pfnSTAMRegisterF(pDrvIns, pCounter, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, enmUnit, pszDesc,
+ "/Drivers/%s-%u/%s", pDrvIns->pReg->szName, pDrvIns->iInstance, pszName);
+}
+
+/**
+ * Convenience wrapper that registers counter which is always visible and has
+ * the STAMUNIT_COUNT unit.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pCounter Pointer to the counter variable.
+ * @param pszName The name of the sample. This is prefixed with
+ * "/Drivers/<drivername>-<instance no>/".
+ * @param pszDesc The description.
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegCounter(PPDMDRVINS pDrvIns, PSTAMCOUNTER pCounter, const char *pszName, const char *pszDesc)
+{
+ PDMDrvHlpSTAMRegCounterEx(pDrvIns, pCounter, pszName, STAMUNIT_COUNT, pszDesc);
+}
+
+/**
+ * Convenience wrapper that registers profiling sample which is always visible.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pProfile Pointer to the profiling variable.
+ * @param pszName The name of the sample. This is prefixed with
+ * "/Drivers/<drivername>-<instance no>/".
+ * @param enmUnit The unit.
+ * @param pszDesc The description.
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegProfileEx(PPDMDRVINS pDrvIns, PSTAMPROFILE pProfile, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
+{
+ pDrvIns->pHlpR3->pfnSTAMRegisterF(pDrvIns, pProfile, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, enmUnit, pszDesc,
+ "/Drivers/%s-%u/%s", pDrvIns->pReg->szName, pDrvIns->iInstance, pszName);
+}
+
+/**
+ * Convenience wrapper that registers profiling sample which is always visible
+ * hand counts ticks per call (STAMUNIT_TICKS_PER_CALL).
+ *
+ * @param pDrvIns The driver instance.
+ * @param pProfile Pointer to the profiling variable.
+ * @param pszName The name of the sample. This is prefixed with
+ * "/Drivers/<drivername>-<instance no>/".
+ * @param pszDesc The description.
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegProfile(PPDMDRVINS pDrvIns, PSTAMPROFILE pProfile, const char *pszName, const char *pszDesc)
+{
+ PDMDrvHlpSTAMRegProfileEx(pDrvIns, pProfile, pszName, STAMUNIT_TICKS_PER_CALL, pszDesc);
+}
+
+/**
+ * Convenience wrapper that registers an advanced profiling sample which is
+ * always visible.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pProfile Pointer to the profiling variable.
+ * @param enmUnit The unit.
+ * @param pszName The name of the sample. This is prefixed with
+ * "/Drivers/<drivername>-<instance no>/".
+ * @param pszDesc The description.
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegProfileAdvEx(PPDMDRVINS pDrvIns, PSTAMPROFILEADV pProfile, const char *pszName, STAMUNIT enmUnit, const char *pszDesc)
+{
+ pDrvIns->pHlpR3->pfnSTAMRegisterF(pDrvIns, pProfile, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, enmUnit, pszDesc,
+ "/Drivers/%s-%u/%s", pDrvIns->pReg->szName, pDrvIns->iInstance, pszName);
+}
+
+/**
+ * Convenience wrapper that registers an advanced profiling sample which is
+ * always visible.
+ *
+ * @param pDrvIns The driver instance.
+ * @param pProfile Pointer to the profiling variable.
+ * @param pszName The name of the sample. This is prefixed with
+ * "/Drivers/<drivername>-<instance no>/".
+ * @param pszDesc The description.
+ */
+DECLINLINE(void) PDMDrvHlpSTAMRegProfileAdv(PPDMDRVINS pDrvIns, PSTAMPROFILEADV pProfile, const char *pszName, const char *pszDesc)
+{
+ PDMDrvHlpSTAMRegProfileAdvEx(pDrvIns, pProfile, pszName, STAMUNIT_TICKS_PER_CALL, pszDesc);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnSTAMDeregister
+ */
+DECLINLINE(int) PDMDrvHlpSTAMDeregister(PPDMDRVINS pDrvIns, void *pvSample)
+{
+ return pDrvIns->pHlpR3->pfnSTAMDeregister(pDrvIns, pvSample);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnSUPCallVMMR0Ex
+ */
+DECLINLINE(int) PDMDrvHlpSUPCallVMMR0Ex(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg)
+{
+ return pDrvIns->pHlpR3->pfnSUPCallVMMR0Ex(pDrvIns, uOperation, pvArg, cbArg);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnUSBRegisterHub
+ */
+DECLINLINE(int) PDMDrvHlpUSBRegisterHub(PPDMDRVINS pDrvIns, uint32_t fVersions, uint32_t cPorts, PCPDMUSBHUBREG pUsbHubReg, PPCPDMUSBHUBHLP ppUsbHubHlp)
+{
+ return pDrvIns->pHlpR3->pfnUSBRegisterHub(pDrvIns, fVersions, cPorts, pUsbHubReg, ppUsbHubHlp);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnSetAsyncNotification
+ */
+DECLINLINE(int) PDMDrvHlpSetAsyncNotification(PPDMDRVINS pDrvIns, PFNPDMDRVASYNCNOTIFY pfnAsyncNotify)
+{
+ return pDrvIns->pHlpR3->pfnSetAsyncNotification(pDrvIns, pfnAsyncNotify);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnAsyncNotificationCompleted
+ */
+DECLINLINE(void) PDMDrvHlpAsyncNotificationCompleted(PPDMDRVINS pDrvIns)
+{
+ pDrvIns->pHlpR3->pfnAsyncNotificationCompleted(pDrvIns);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnThreadCreate
+ */
+DECLINLINE(int) PDMDrvHlpThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
+ PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
+{
+ return pDrvIns->pHlpR3->pfnThreadCreate(pDrvIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
+}
+
+# ifdef VBOX_WITH_PDM_ASYNC_COMPLETION
+/**
+ * @copydoc PDMDRVHLP::pfnAsyncCompletionTemplateCreate
+ */
+DECLINLINE(int) PDMDrvHlpAsyncCompletionTemplateCreate(PPDMDRVINS pDrvIns, PPPDMASYNCCOMPLETIONTEMPLATE ppTemplate,
+ PFNPDMASYNCCOMPLETEDRV pfnCompleted, void *pvTemplateUser, const char *pszDesc)
+{
+ return pDrvIns->pHlpR3->pfnAsyncCompletionTemplateCreate(pDrvIns, ppTemplate, pfnCompleted, pvTemplateUser, pszDesc);
+}
+# endif
+
+# ifdef VBOX_WITH_NETSHAPER
+/**
+ * @copydoc PDMDRVHLP::pfnNetShaperAttach
+ */
+DECLINLINE(int) PDMDrvHlpNetShaperAttach(PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter)
+{
+ return pDrvIns->pHlpR3->pfnNetShaperAttach(pDrvIns, pcszBwGroup, pFilter);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnNetShaperDetach
+ */
+DECLINLINE(int) PDMDrvHlpNetShaperDetach(PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter)
+{
+ return pDrvIns->pHlpR3->pfnNetShaperDetach(pDrvIns, pFilter);
+}
+# endif
+
+/**
+ * @copydoc PDMDRVHLP::pfnCritSectInit
+ */
+DECLINLINE(int) PDMDrvHlpCritSectInit(PPDMDRVINS pDrvIns, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszName)
+{
+ return pDrvIns->pHlpR3->pfnCritSectInit(pDrvIns, pCritSect, RT_SRC_POS_ARGS, pszName);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnCallR0
+ */
+DECLINLINE(int) PDMDrvHlpCallR0(PPDMDRVINS pDrvIns, uint32_t uOperation, uint64_t u64Arg)
+{
+ return pDrvIns->pHlpR3->pfnCallR0(pDrvIns, uOperation, u64Arg);
+}
+
+/**
+ * @copydoc PDMDRVHLP::pfnBlkCacheRetain
+ */
+DECLINLINE(int) PDMDrvHlpBlkCacheRetain(PPDMDRVINS pDrvIns, PPPDMBLKCACHE ppBlkCache,
+ PFNPDMBLKCACHEXFERCOMPLETEDRV pfnXferComplete,
+ PFNPDMBLKCACHEXFERENQUEUEDRV pfnXferEnqueue,
+ PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV pfnXferEnqueueDiscard,
+ const char *pcszId)
+{
+ return pDrvIns->pHlpR3->pfnBlkCacheRetain(pDrvIns, ppBlkCache, pfnXferComplete, pfnXferEnqueue, pfnXferEnqueueDiscard, pcszId);
+}
+
+/** Pointer to callbacks provided to the VBoxDriverRegister() call. */
+typedef struct PDMDRVREGCB *PPDMDRVREGCB;
+/** Pointer to const callbacks provided to the VBoxDriverRegister() call. */
+typedef const struct PDMDRVREGCB *PCPDMDRVREGCB;
+
+/**
+ * Callbacks for VBoxDriverRegister().
+ */
+typedef struct PDMDRVREGCB
+{
+ /** Interface version.
+ * This is set to PDM_DRVREG_CB_VERSION. */
+ uint32_t u32Version;
+
+ /**
+ * Registers a driver with the current VM instance.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param pReg Pointer to the driver registration record.
+ * This data must be permanent and readonly.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRegister,(PCPDMDRVREGCB pCallbacks, PCPDMDRVREG pReg));
+} PDMDRVREGCB;
+
+/** Current version of the PDMDRVREGCB structure. */
+#define PDM_DRVREG_CB_VERSION PDM_VERSION_MAKE(0xf0fa, 1, 0)
+
+
+/**
+ * The VBoxDriverRegister callback function.
+ *
+ * PDM will invoke this function after loading a driver module and letting
+ * the module decide which drivers to register and how to handle conflicts.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param u32Version VBox version number.
+ */
+typedef DECLCALLBACK(int) FNPDMVBOXDRIVERSREGISTER(PCPDMDRVREGCB pCallbacks, uint32_t u32Version);
+
+VMMR3DECL(int) PDMR3DrvStaticRegistration(PVM pVM, FNPDMVBOXDRIVERSREGISTER pfnCallback);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/pdmifs.h b/include/VBox/vmm/pdmifs.h
new file mode 100644
index 00000000..17dba105
--- /dev/null
+++ b/include/VBox/vmm/pdmifs.h
@@ -0,0 +1,2996 @@
+/** @file
+ * PDM - Pluggable Device Manager, Interfaces.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmifs_h
+#define ___VBox_vmm_pdmifs_h
+
+#include <iprt/sg.h>
+#include <VBox/types.h>
+#include <VBox/hgcmsvc.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_interfaces The PDM Interface Definitions
+ * @ingroup grp_pdm
+ *
+ * For historical reasons (the PDMINTERFACE enum) a lot of interface was stuffed
+ * together in this group instead, dragging stuff into global space that didn't
+ * need to be there and making this file huge (>2500 lines). Since we're using
+ * UUIDs as interface identifiers (IIDs) now, no only generic PDM interface will
+ * be added to this file. Component specific interface should be defined in the
+ * header file of that component.
+ *
+ * Interfaces consists of a method table (typedef'ed struct) and an interface
+ * ID. The typename of the method table should have an 'I' in it, be all
+ * capitals and according to the rules, no underscores. The interface ID is a
+ * \#define constructed by appending '_IID' to the typename. The IID value is a
+ * UUID string on the form "a2299c0d-b709-4551-aa5a-73f59ffbed74". If you stick
+ * to these rules, you can make use of the PDMIBASE_QUERY_INTERFACE and
+ * PDMIBASE_RETURN_INTERFACE when querying interface and implementing
+ * PDMIBASE::pfnQueryInterface respectively.
+ *
+ * In most interface descriptions the orientation of the interface is given as
+ * 'down' or 'up'. This refers to a model with the device on the top and the
+ * drivers stacked below it. Sometimes there is mention of 'main' or 'external'
+ * which normally means the same, i.e. the Main or VBoxBFE API. Picture the
+ * orientation of 'main' as horizontal.
+ *
+ * @{
+ */
+
+
+/** @name PDMIBASE
+ * @{
+ */
+
+/**
+ * PDM Base Interface.
+ *
+ * Everyone implements this.
+ */
+typedef struct PDMIBASE
+{
+ /**
+ * Queries an interface to the driver.
+ *
+ * @returns Pointer to interface.
+ * @returns NULL if the interface was not supported by the driver.
+ * @param pInterface Pointer to this interface structure.
+ * @param pszIID The interface ID, a UUID string.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(void *, pfnQueryInterface,(struct PDMIBASE *pInterface, const char *pszIID));
+} PDMIBASE;
+/** PDMIBASE interface ID. */
+#define PDMIBASE_IID "a2299c0d-b709-4551-aa5a-73f59ffbed74"
+
+/**
+ * Helper macro for querying an interface from PDMIBASE.
+ *
+ * @returns Correctly typed PDMIBASE::pfnQueryInterface return value.
+ *
+ * @param pIBase Pointer to the base interface.
+ * @param InterfaceType The interface type name. The interface ID is
+ * derived from this by appending _IID.
+ */
+#define PDMIBASE_QUERY_INTERFACE(pIBase, InterfaceType) \
+ ( (InterfaceType *)(pIBase)->pfnQueryInterface(pIBase, InterfaceType##_IID ) )
+
+/**
+ * Helper macro for implementing PDMIBASE::pfnQueryInterface.
+ *
+ * Return @a pInterface if @a pszIID matches the @a InterfaceType. This will
+ * perform basic type checking.
+ *
+ * @param pszIID The ID of the interface that is being queried.
+ * @param InterfaceType The interface type name. The interface ID is
+ * derived from this by appending _IID.
+ * @param pInterface The interface address expression.
+ */
+#define PDMIBASE_RETURN_INTERFACE(pszIID, InterfaceType, pInterface) \
+ do { \
+ if (RTUuidCompare2Strs((pszIID), InterfaceType##_IID) == 0) \
+ { \
+ P##InterfaceType pReturnInterfaceTypeCheck = (pInterface); \
+ return pReturnInterfaceTypeCheck; \
+ } \
+ } while (0)
+
+/** @} */
+
+
+/** @name PDMIBASERC
+ * @{
+ */
+
+/**
+ * PDM Base Interface for querying ring-mode context interfaces in
+ * ring-3.
+ *
+ * This is mandatory for drivers present in raw-mode context.
+ */
+typedef struct PDMIBASERC
+{
+ /**
+ * Queries an ring-mode context interface to the driver.
+ *
+ * @returns Pointer to interface.
+ * @returns NULL if the interface was not supported by the driver.
+ * @param pInterface Pointer to this interface structure.
+ * @param pszIID The interface ID, a UUID string.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(RTRCPTR, pfnQueryInterface,(struct PDMIBASERC *pInterface, const char *pszIID));
+} PDMIBASERC;
+/** Pointer to a PDM Base Interface for query ring-mode context interfaces. */
+typedef PDMIBASERC *PPDMIBASERC;
+/** PDMIBASERC interface ID. */
+#define PDMIBASERC_IID "f6a6c649-6cb3-493f-9737-4653f221aeca"
+
+/**
+ * Helper macro for querying an interface from PDMIBASERC.
+ *
+ * @returns PDMIBASERC::pfnQueryInterface return value.
+ *
+ * @param pIBaseRC Pointer to the base raw-mode context interface. Can
+ * be NULL.
+ * @param InterfaceType The interface type base name, no trailing RC. The
+ * interface ID is derived from this by appending _IID.
+ *
+ * @remarks Unlike PDMIBASE_QUERY_INTERFACE, this macro is not able to do any
+ * implicit type checking for you.
+ */
+#define PDMIBASERC_QUERY_INTERFACE(pIBaseRC, InterfaceType) \
+ ( (P##InterfaceType##RC)((pIBaseRC) ? (pIBaseRC)->pfnQueryInterface(pIBaseRC, InterfaceType##_IID) : NIL_RTRCPTR) )
+
+/**
+ * Helper macro for implementing PDMIBASERC::pfnQueryInterface.
+ *
+ * Return @a pInterface if @a pszIID matches the @a InterfaceType. This will
+ * perform basic type checking.
+ *
+ * @param pIns Pointer to the instance data.
+ * @param pszIID The ID of the interface that is being queried.
+ * @param InterfaceType The interface type base name, no trailing RC. The
+ * interface ID is derived from this by appending _IID.
+ * @param pInterface The interface address expression. This must resolve
+ * to some address within the instance data.
+ * @remarks Don't use with PDMIBASE.
+ */
+#define PDMIBASERC_RETURN_INTERFACE(pIns, pszIID, InterfaceType, pInterface) \
+ do { \
+ Assert((uintptr_t)pInterface - PDMINS_2_DATA(pIns, uintptr_t) < _4M); \
+ if (RTUuidCompare2Strs((pszIID), InterfaceType##_IID) == 0) \
+ { \
+ InterfaceType##RC *pReturnInterfaceTypeCheck = (pInterface); \
+ return (uintptr_t)pReturnInterfaceTypeCheck \
+ - PDMINS_2_DATA(pIns, uintptr_t) \
+ + PDMINS_2_DATA_RCPTR(pIns); \
+ } \
+ } while (0)
+
+/** @} */
+
+
+/** @name PDMIBASER0
+ * @{
+ */
+
+/**
+ * PDM Base Interface for querying ring-0 interfaces in ring-3.
+ *
+ * This is mandatory for drivers present in ring-0 context.
+ */
+typedef struct PDMIBASER0
+{
+ /**
+ * Queries an ring-0 interface to the driver.
+ *
+ * @returns Pointer to interface.
+ * @returns NULL if the interface was not supported by the driver.
+ * @param pInterface Pointer to this interface structure.
+ * @param pszIID The interface ID, a UUID string.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(RTR0PTR, pfnQueryInterface,(struct PDMIBASER0 *pInterface, const char *pszIID));
+} PDMIBASER0;
+/** Pointer to a PDM Base Interface for query ring-0 context interfaces. */
+typedef PDMIBASER0 *PPDMIBASER0;
+/** PDMIBASER0 interface ID. */
+#define PDMIBASER0_IID "9c9b99b8-7f53-4f59-a3c2-5bc9659c7944"
+
+/**
+ * Helper macro for querying an interface from PDMIBASER0.
+ *
+ * @returns PDMIBASER0::pfnQueryInterface return value.
+ *
+ * @param pIBaseR0 Pointer to the base ring-0 interface. Can be NULL.
+ * @param InterfaceType The interface type base name, no trailing R0. The
+ * interface ID is derived from this by appending _IID.
+ *
+ * @remarks Unlike PDMIBASE_QUERY_INTERFACE, this macro is not able to do any
+ * implicit type checking for you.
+ */
+#define PDMIBASER0_QUERY_INTERFACE(pIBaseR0, InterfaceType) \
+ ( (P##InterfaceType##R0)((pIBaseR0) ? (pIBaseR0)->pfnQueryInterface(pIBaseR0, InterfaceType##_IID) : NIL_RTR0PTR) )
+
+/**
+ * Helper macro for implementing PDMIBASER0::pfnQueryInterface.
+ *
+ * Return @a pInterface if @a pszIID matches the @a InterfaceType. This will
+ * perform basic type checking.
+ *
+ * @param pIns Pointer to the instance data.
+ * @param pszIID The ID of the interface that is being queried.
+ * @param InterfaceType The interface type base name, no trailing R0. The
+ * interface ID is derived from this by appending _IID.
+ * @param pInterface The interface address expression. This must resolve
+ * to some address within the instance data.
+ * @remarks Don't use with PDMIBASE.
+ */
+#define PDMIBASER0_RETURN_INTERFACE(pIns, pszIID, InterfaceType, pInterface) \
+ do { \
+ Assert((uintptr_t)pInterface - PDMINS_2_DATA(pIns, uintptr_t) < _4M); \
+ if (RTUuidCompare2Strs((pszIID), InterfaceType##_IID) == 0) \
+ { \
+ InterfaceType##R0 *pReturnInterfaceTypeCheck = (pInterface); \
+ return (uintptr_t)pReturnInterfaceTypeCheck \
+ - PDMINS_2_DATA(pIns, uintptr_t) \
+ + PDMINS_2_DATA_R0PTR(pIns); \
+ } \
+ } while (0)
+
+/** @} */
+
+
+/**
+ * Dummy interface.
+ *
+ * This is used to typedef other dummy interfaces. The purpose of a dummy
+ * interface is to validate the logical function of a driver/device and
+ * full a natural interface pair.
+ */
+typedef struct PDMIDUMMY
+{
+ RTHCPTR pvDummy;
+} PDMIDUMMY;
+
+
+/** Pointer to a mouse port interface. */
+typedef struct PDMIMOUSEPORT *PPDMIMOUSEPORT;
+/**
+ * Mouse port interface (down).
+ * Pair with PDMIMOUSECONNECTOR.
+ */
+typedef struct PDMIMOUSEPORT
+{
+ /**
+ * Puts a mouse event.
+ *
+ * This is called by the source of mouse events. The event will be passed up
+ * until the topmost driver, which then calls the registered event handler.
+ *
+ * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the
+ * event now and want it to be repeated at a later point.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param iDeltaX The X delta.
+ * @param iDeltaY The Y delta.
+ * @param iDeltaZ The Z delta.
+ * @param iDeltaW The W (horizontal scroll button) delta.
+ * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIMOUSEPORT pInterface, int32_t iDeltaX, int32_t iDeltaY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates));
+ /**
+ * Puts an absolute mouse event.
+ *
+ * This is called by the source of mouse events. The event will be passed up
+ * until the topmost driver, which then calls the registered event handler.
+ *
+ * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the
+ * event now and want it to be repeated at a later point.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param uX The X value, in the range 0 to 0xffff.
+ * @param uY The Y value, in the range 0 to 0xffff.
+ * @param iDeltaZ The Z delta.
+ * @param iDeltaW The W (horizontal scroll button) delta.
+ * @param fButtonStates The button states, see the PDMIMOUSEPORT_BUTTON_* \#defines.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPutEventAbs,(PPDMIMOUSEPORT pInterface, uint32_t uX, uint32_t uY, int32_t iDeltaZ, int32_t iDeltaW, uint32_t fButtonStates));
+} PDMIMOUSEPORT;
+/** PDMIMOUSEPORT interface ID. */
+#define PDMIMOUSEPORT_IID "442136fe-6f3c-49ec-9964-259b378ffa64"
+
+/** Mouse button defines for PDMIMOUSEPORT::pfnPutEvent.
+ * @{ */
+#define PDMIMOUSEPORT_BUTTON_LEFT RT_BIT(0)
+#define PDMIMOUSEPORT_BUTTON_RIGHT RT_BIT(1)
+#define PDMIMOUSEPORT_BUTTON_MIDDLE RT_BIT(2)
+#define PDMIMOUSEPORT_BUTTON_X1 RT_BIT(3)
+#define PDMIMOUSEPORT_BUTTON_X2 RT_BIT(4)
+/** @} */
+
+
+/** Pointer to a mouse connector interface. */
+typedef struct PDMIMOUSECONNECTOR *PPDMIMOUSECONNECTOR;
+/**
+ * Mouse connector interface (up).
+ * Pair with PDMIMOUSEPORT.
+ */
+typedef struct PDMIMOUSECONNECTOR
+{
+ /**
+ * Notifies the the downstream driver of changes to the reporting modes
+ * supported by the driver
+ *
+ * @param pInterface Pointer to the this interface.
+ * @param fRelative Whether relative mode is currently supported.
+ * @param fAbsolute Whether absolute mode is currently supported.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnReportModes,(PPDMIMOUSECONNECTOR pInterface, bool fRelative, bool fAbsolute));
+
+} PDMIMOUSECONNECTOR;
+/** PDMIMOUSECONNECTOR interface ID. */
+#define PDMIMOUSECONNECTOR_IID "ce64d7bd-fa8f-41d1-a6fb-d102a2d6bffe"
+
+
+/** Pointer to a keyboard port interface. */
+typedef struct PDMIKEYBOARDPORT *PPDMIKEYBOARDPORT;
+/**
+ * Keyboard port interface (down).
+ * Pair with PDMIKEYBOARDCONNECTOR.
+ */
+typedef struct PDMIKEYBOARDPORT
+{
+ /**
+ * Puts a keyboard event.
+ *
+ * This is called by the source of keyboard events. The event will be passed up
+ * until the topmost driver, which then calls the registered event handler.
+ *
+ * @returns VBox status code. Return VERR_TRY_AGAIN if you cannot process the
+ * event now and want it to be repeated at a later point.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param u8KeyCode The keycode to queue.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPutEvent,(PPDMIKEYBOARDPORT pInterface, uint8_t u8KeyCode));
+} PDMIKEYBOARDPORT;
+/** PDMIKEYBOARDPORT interface ID. */
+#define PDMIKEYBOARDPORT_IID "2a0844f0-410b-40ab-a6ed-6575f3aa3e29"
+
+
+/**
+ * Keyboard LEDs.
+ */
+typedef enum PDMKEYBLEDS
+{
+ /** No leds. */
+ PDMKEYBLEDS_NONE = 0x0000,
+ /** Num Lock */
+ PDMKEYBLEDS_NUMLOCK = 0x0001,
+ /** Caps Lock */
+ PDMKEYBLEDS_CAPSLOCK = 0x0002,
+ /** Scroll Lock */
+ PDMKEYBLEDS_SCROLLLOCK = 0x0004
+} PDMKEYBLEDS;
+
+/** Pointer to keyboard connector interface. */
+typedef struct PDMIKEYBOARDCONNECTOR *PPDMIKEYBOARDCONNECTOR;
+/**
+ * Keyboard connector interface (up).
+ * Pair with PDMIKEYBOARDPORT
+ */
+typedef struct PDMIKEYBOARDCONNECTOR
+{
+ /**
+ * Notifies the the downstream driver about an LED change initiated by the guest.
+ *
+ * @param pInterface Pointer to the this interface.
+ * @param enmLeds The new led mask.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnLedStatusChange,(PPDMIKEYBOARDCONNECTOR pInterface, PDMKEYBLEDS enmLeds));
+
+ /**
+ * Notifies the the downstream driver of changes in driver state.
+ *
+ * @param pInterface Pointer to the this interface.
+ * @param fActive Whether interface wishes to get "focus".
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetActive,(PPDMIKEYBOARDCONNECTOR pInterface, bool fActive));
+
+} PDMIKEYBOARDCONNECTOR;
+/** PDMIKEYBOARDCONNECTOR interface ID. */
+#define PDMIKEYBOARDCONNECTOR_IID "db3f7bd5-953e-436f-9f8e-077905a92d82"
+
+
+
+/** Pointer to a display port interface. */
+typedef struct PDMIDISPLAYPORT *PPDMIDISPLAYPORT;
+/**
+ * Display port interface (down).
+ * Pair with PDMIDISPLAYCONNECTOR.
+ */
+typedef struct PDMIDISPLAYPORT
+{
+ /**
+ * Update the display with any changed regions.
+ *
+ * Flushes any display changes to the memory pointed to by the
+ * PDMIDISPLAYCONNECTOR interface and calles PDMIDISPLAYCONNECTOR::pfnUpdateRect()
+ * while doing so.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUpdateDisplay,(PPDMIDISPLAYPORT pInterface));
+
+ /**
+ * Update the entire display.
+ *
+ * Flushes the entire display content to the memory pointed to by the
+ * PDMIDISPLAYCONNECTOR interface and calles PDMIDISPLAYCONNECTOR::pfnUpdateRect().
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUpdateDisplayAll,(PPDMIDISPLAYPORT pInterface));
+
+ /**
+ * Return the current guest color depth in bits per pixel (bpp).
+ *
+ * As the graphics card is able to provide display updates with the bpp
+ * requested by the host, this method can be used to query the actual
+ * guest color depth.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pcBits Where to store the current guest color depth.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryColorDepth,(PPDMIDISPLAYPORT pInterface, uint32_t *pcBits));
+
+ /**
+ * Sets the refresh rate and restart the timer.
+ * The rate is defined as the minimum interval between the return of
+ * one PDMIDISPLAYPORT::pfnRefresh() call to the next one.
+ *
+ * The interval timer will be restarted by this call. So at VM startup
+ * this function must be called to start the refresh cycle. The refresh
+ * rate is not saved, but have to be when resuming a loaded VM state.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param cMilliesInterval Number of millis between two refreshes.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetRefreshRate,(PPDMIDISPLAYPORT pInterface, uint32_t cMilliesInterval));
+
+ /**
+ * Create a 32-bbp screenshot of the display.
+ *
+ * This will allocate and return a 32-bbp bitmap. Size of the bitmap scanline in bytes is 4*width.
+ *
+ * The allocated bitmap buffer must be freed with pfnFreeScreenshot.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param ppu8Data Where to store the pointer to the allocated buffer.
+ * @param pcbData Where to store the actual size of the bitmap.
+ * @param pcx Where to store the width of the bitmap.
+ * @param pcy Where to store the height of the bitmap.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnTakeScreenshot,(PPDMIDISPLAYPORT pInterface, uint8_t **ppu8Data, size_t *pcbData, uint32_t *pcx, uint32_t *pcy));
+
+ /**
+ * Free screenshot buffer.
+ *
+ * This will free the memory buffer allocated by pfnTakeScreenshot.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param ppu8Data Pointer to the buffer returned by pfnTakeScreenshot.
+ * @thread Any.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnFreeScreenshot,(PPDMIDISPLAYPORT pInterface, uint8_t *pu8Data));
+
+ /**
+ * Copy bitmap to the display.
+ *
+ * This will convert and copy a 32-bbp bitmap (with dword aligned scanline length) to
+ * the memory pointed to by the PDMIDISPLAYCONNECTOR interface.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pvData Pointer to the bitmap bits.
+ * @param x The upper left corner x coordinate of the destination rectangle.
+ * @param y The upper left corner y coordinate of the destination rectangle.
+ * @param cx The width of the source and destination rectangles.
+ * @param cy The height of the source and destination rectangles.
+ * @thread The emulation thread.
+ * @remark This is just a convenience for using the bitmap conversions of the
+ * graphics device.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDisplayBlt,(PPDMIDISPLAYPORT pInterface, const void *pvData, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy));
+
+ /**
+ * Render a rectangle from guest VRAM to Framebuffer.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param x The upper left corner x coordinate of the rectangle to be updated.
+ * @param y The upper left corner y coordinate of the rectangle to be updated.
+ * @param cx The width of the rectangle to be updated.
+ * @param cy The height of the rectangle to be updated.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateDisplayRect,(PPDMIDISPLAYPORT pInterface, int32_t x, int32_t y, uint32_t cx, uint32_t cy));
+
+ /**
+ * Inform the VGA device whether the Display is directly using the guest VRAM and there is no need
+ * to render the VRAM to the framebuffer memory.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param fRender Whether the VRAM content must be rendered to the framebuffer.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetRenderVRAM,(PPDMIDISPLAYPORT pInterface, bool fRender));
+
+ /**
+ * Render a bitmap rectangle from source to target buffer.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param cx The width of the rectangle to be copied.
+ * @param cy The height of the rectangle to be copied.
+ * @param pbSrc Source frame buffer 0,0.
+ * @param xSrc The upper left corner x coordinate of the source rectangle.
+ * @param ySrc The upper left corner y coordinate of the source rectangle.
+ * @param cxSrc The width of the source frame buffer.
+ * @param cySrc The height of the source frame buffer.
+ * @param cbSrcLine The line length of the source frame buffer.
+ * @param cSrcBitsPerPixel The pixel depth of the source.
+ * @param pbDst Destination frame buffer 0,0.
+ * @param xDst The upper left corner x coordinate of the destination rectangle.
+ * @param yDst The upper left corner y coordinate of the destination rectangle.
+ * @param cxDst The width of the destination frame buffer.
+ * @param cyDst The height of the destination frame buffer.
+ * @param cbDstLine The line length of the destination frame buffer.
+ * @param cDstBitsPerPixel The pixel depth of the destination.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCopyRect,(PPDMIDISPLAYPORT pInterface, uint32_t cx, uint32_t cy,
+ const uint8_t *pbSrc, int32_t xSrc, int32_t ySrc, uint32_t cxSrc, uint32_t cySrc, uint32_t cbSrcLine, uint32_t cSrcBitsPerPixel,
+ uint8_t *pbDst, int32_t xDst, int32_t yDst, uint32_t cxDst, uint32_t cyDst, uint32_t cbDstLine, uint32_t cDstBitsPerPixel));
+
+} PDMIDISPLAYPORT;
+/** PDMIDISPLAYPORT interface ID. */
+#define PDMIDISPLAYPORT_IID "22d3d93d-3407-487a-8308-85367eae00bb"
+
+
+typedef struct VBOXVHWACMD *PVBOXVHWACMD; /**< @todo r=bird: A line what it is to make doxygen happy. */
+typedef struct VBVACMDHDR *PVBVACMDHDR;
+typedef struct VBVAINFOSCREEN *PVBVAINFOSCREEN;
+typedef struct VBVAINFOVIEW *PVBVAINFOVIEW;
+typedef struct VBVAHOSTFLAGS *PVBVAHOSTFLAGS;
+typedef struct VBOXVDMACMD_CHROMIUM_CMD *PVBOXVDMACMD_CHROMIUM_CMD; /* <- chromium [hgsmi] command */
+typedef struct VBOXVDMACMD_CHROMIUM_CTL *PVBOXVDMACMD_CHROMIUM_CTL; /* <- chromium [hgsmi] command */
+
+/** Pointer to a display connector interface. */
+typedef struct PDMIDISPLAYCONNECTOR *PPDMIDISPLAYCONNECTOR;
+/**
+ * Display connector interface (up).
+ * Pair with PDMIDISPLAYPORT.
+ */
+typedef struct PDMIDISPLAYCONNECTOR
+{
+ /**
+ * Resize the display.
+ * This is called when the resolution changes. This usually happens on
+ * request from the guest os, but may also happen as the result of a reset.
+ * If the callback returns VINF_VGA_RESIZE_IN_PROGRESS, the caller (VGA device)
+ * must not access the connector and return.
+ *
+ * @returns VINF_SUCCESS if the framebuffer resize was completed,
+ * VINF_VGA_RESIZE_IN_PROGRESS if resize takes time and not yet finished.
+ * @param pInterface Pointer to this interface.
+ * @param cBits Color depth (bits per pixel) of the new video mode.
+ * @param pvVRAM Address of the guest VRAM.
+ * @param cbLine Size in bytes of a single scan line.
+ * @param cx New display width.
+ * @param cy New display height.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnResize,(PPDMIDISPLAYCONNECTOR pInterface, uint32_t cBits, void *pvVRAM, uint32_t cbLine, uint32_t cx, uint32_t cy));
+
+ /**
+ * Update a rectangle of the display.
+ * PDMIDISPLAYPORT::pfnUpdateDisplay is the caller.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param x The upper left corner x coordinate of the rectangle.
+ * @param y The upper left corner y coordinate of the rectangle.
+ * @param cx The width of the rectangle.
+ * @param cy The height of the rectangle.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateRect,(PPDMIDISPLAYCONNECTOR pInterface, uint32_t x, uint32_t y, uint32_t cx, uint32_t cy));
+
+ /**
+ * Refresh the display.
+ *
+ * The interval between these calls is set by
+ * PDMIDISPLAYPORT::pfnSetRefreshRate(). The driver should call
+ * PDMIDISPLAYPORT::pfnUpdateDisplay() if it wishes to refresh the
+ * display. PDMIDISPLAYPORT::pfnUpdateDisplay calls pfnUpdateRect with
+ * the changed rectangles.
+ *
+ * @param pInterface Pointer to this interface.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnRefresh,(PPDMIDISPLAYCONNECTOR pInterface));
+
+ /**
+ * Reset the display.
+ *
+ * Notification message when the graphics card has been reset.
+ *
+ * @param pInterface Pointer to this interface.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnReset,(PPDMIDISPLAYCONNECTOR pInterface));
+
+ /**
+ * LFB video mode enter/exit.
+ *
+ * Notification message when LinearFrameBuffer video mode is enabled/disabled.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param fEnabled false - LFB mode was disabled,
+ * true - an LFB mode was disabled
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnLFBModeChange, (PPDMIDISPLAYCONNECTOR pInterface, bool fEnabled));
+
+ /**
+ * Process the guest graphics adapter information.
+ *
+ * Direct notification from guest to the display connector.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pvVRAM Address of the guest VRAM.
+ * @param u32VRAMSize Size of the guest VRAM.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnProcessAdapterData, (PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, uint32_t u32VRAMSize));
+
+ /**
+ * Process the guest display information.
+ *
+ * Direct notification from guest to the display connector.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pvVRAM Address of the guest VRAM.
+ * @param uScreenId The index of the guest display to be processed.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnProcessDisplayData, (PPDMIDISPLAYCONNECTOR pInterface, void *pvVRAM, unsigned uScreenId));
+
+ /**
+ * Process the guest Video HW Acceleration command.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd Video HW Acceleration Command to be processed.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVHWACommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVHWACMD pCmd));
+
+ /**
+ * Process the guest chromium command.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd Video HW Acceleration Command to be processed.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnCrHgsmiCommandProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, uint32_t cbCmd));
+
+ /**
+ * Process the guest chromium control command.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd Video HW Acceleration Command to be processed.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnCrHgsmiControlProcess, (PPDMIDISPLAYCONNECTOR pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCtl, uint32_t cbCtl));
+
+
+ /**
+ * The specified screen enters VBVA mode.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param uScreenId The screen updates are for.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVBVAEnable,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, PVBVAHOSTFLAGS pHostFlags));
+
+ /**
+ * The specified screen leaves VBVA mode.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param uScreenId The screen updates are for.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVBVADisable,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId));
+
+ /**
+ * A sequence of pfnVBVAUpdateProcess calls begins.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param uScreenId The screen updates are for.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVBVAUpdateBegin,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId));
+
+ /**
+ * Process the guest VBVA command.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd Video HW Acceleration Command to be processed.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVBVAUpdateProcess,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, const PVBVACMDHDR pCmd, size_t cbCmd));
+
+ /**
+ * A sequence of pfnVBVAUpdateProcess calls ends.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param uScreenId The screen updates are for.
+ * @param x The upper left corner x coordinate of the combined rectangle of all VBVA updates.
+ * @param y The upper left corner y coordinate of the rectangle.
+ * @param cx The width of the rectangle.
+ * @param cy The height of the rectangle.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVBVAUpdateEnd,(PPDMIDISPLAYCONNECTOR pInterface, unsigned uScreenId, int32_t x, int32_t y, uint32_t cx, uint32_t cy));
+
+ /**
+ * Resize the display.
+ * This is called when the resolution changes. This usually happens on
+ * request from the guest os, but may also happen as the result of a reset.
+ * If the callback returns VINF_VGA_RESIZE_IN_PROGRESS, the caller (VGA device)
+ * must not access the connector and return.
+ *
+ * @todo Merge with pfnResize.
+ *
+ * @returns VINF_SUCCESS if the framebuffer resize was completed,
+ * VINF_VGA_RESIZE_IN_PROGRESS if resize takes time and not yet finished.
+ * @param pInterface Pointer to this interface.
+ * @param pView The description of VRAM block for this screen.
+ * @param pScreen The data of screen being resized.
+ * @param pvVRAM Address of the guest VRAM.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVBVAResize,(PPDMIDISPLAYCONNECTOR pInterface, const PVBVAINFOVIEW pView, const PVBVAINFOSCREEN pScreen, void *pvVRAM));
+
+ /**
+ * Update the pointer shape.
+ * This is called when the mouse pointer shape changes. The new shape
+ * is passed as a caller allocated buffer that will be freed after returning
+ *
+ * @param pInterface Pointer to this interface.
+ * @param fVisible Visibility indicator (if false, the other parameters are undefined).
+ * @param fAlpha Flag whether alpha channel is being passed.
+ * @param xHot Pointer hot spot x coordinate.
+ * @param yHot Pointer hot spot y coordinate.
+ * @param x Pointer new x coordinate on screen.
+ * @param y Pointer new y coordinate on screen.
+ * @param cx Pointer width in pixels.
+ * @param cy Pointer height in pixels.
+ * @param cbScanline Size of one scanline in bytes.
+ * @param pvShape New shape buffer.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVBVAMousePointerShape,(PPDMIDISPLAYCONNECTOR pInterface, bool fVisible, bool fAlpha,
+ uint32_t xHot, uint32_t yHot,
+ uint32_t cx, uint32_t cy,
+ const void *pvShape));
+
+ /** Read-only attributes.
+ * For preformance reasons some readonly attributes are kept in the interface.
+ * We trust the interface users to respect the readonlyness of these.
+ * @{
+ */
+ /** Pointer to the display data buffer. */
+ uint8_t *pu8Data;
+ /** Size of a scanline in the data buffer. */
+ uint32_t cbScanline;
+ /** The color depth (in bits) the graphics card is supposed to provide. */
+ uint32_t cBits;
+ /** The display width. */
+ uint32_t cx;
+ /** The display height. */
+ uint32_t cy;
+ /** @} */
+} PDMIDISPLAYCONNECTOR;
+/** PDMIDISPLAYCONNECTOR interface ID. */
+#define PDMIDISPLAYCONNECTOR_IID "c7a1b36d-8dfc-421d-b71f-3a0eeaf733e6"
+
+
+/** Pointer to a block port interface. */
+typedef struct PDMIBLOCKPORT *PPDMIBLOCKPORT;
+/**
+ * Block notify interface (down).
+ * Pair with PDMIBLOCK.
+ */
+typedef struct PDMIBLOCKPORT
+{
+ /**
+ * Returns the storage controller name, instance and LUN of the attached medium.
+ *
+ * @returns VBox status.
+ * @param pInterface Pointer to this interface.
+ * @param ppcszController Where to store the name of the storage controller.
+ * @param piInstance Where to store the instance number of the controller.
+ * @param piLUN Where to store the LUN of the attached device.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryDeviceLocation, (PPDMIBLOCKPORT pInterface, const char **ppcszController,
+ uint32_t *piInstance, uint32_t *piLUN));
+
+} PDMIBLOCKPORT;
+/** PDMIBLOCKPORT interface ID. */
+#define PDMIBLOCKPORT_IID "bbbed4cf-0862-4ffd-b60c-f7a65ef8e8ff"
+
+
+/**
+ * Callback which provides progress information.
+ *
+ * @return VBox status code.
+ * @param pvUser Opaque user data.
+ * @param uPercent Completion percentage.
+ */
+typedef DECLCALLBACK(int) FNSIMPLEPROGRESS(void *pvUser, unsigned uPercentage);
+/** Pointer to FNSIMPLEPROGRESS() */
+typedef FNSIMPLEPROGRESS *PFNSIMPLEPROGRESS;
+
+
+/**
+ * Block drive type.
+ */
+typedef enum PDMBLOCKTYPE
+{
+ /** Error (for the query function). */
+ PDMBLOCKTYPE_ERROR = 1,
+ /** 360KB 5 1/4" floppy drive. */
+ PDMBLOCKTYPE_FLOPPY_360,
+ /** 720KB 3 1/2" floppy drive. */
+ PDMBLOCKTYPE_FLOPPY_720,
+ /** 1.2MB 5 1/4" floppy drive. */
+ PDMBLOCKTYPE_FLOPPY_1_20,
+ /** 1.44MB 3 1/2" floppy drive. */
+ PDMBLOCKTYPE_FLOPPY_1_44,
+ /** 2.88MB 3 1/2" floppy drive. */
+ PDMBLOCKTYPE_FLOPPY_2_88,
+ /** CDROM drive. */
+ PDMBLOCKTYPE_CDROM,
+ /** DVD drive. */
+ PDMBLOCKTYPE_DVD,
+ /** Hard disk drive. */
+ PDMBLOCKTYPE_HARD_DISK
+} PDMBLOCKTYPE;
+
+
+/**
+ * Block raw command data transfer direction.
+ */
+typedef enum PDMBLOCKTXDIR
+{
+ PDMBLOCKTXDIR_NONE = 0,
+ PDMBLOCKTXDIR_FROM_DEVICE,
+ PDMBLOCKTXDIR_TO_DEVICE
+} PDMBLOCKTXDIR;
+
+
+/** Pointer to a block interface. */
+typedef struct PDMIBLOCK *PPDMIBLOCK;
+/**
+ * Block interface (up).
+ * Pair with PDMIBLOCKPORT.
+ */
+typedef struct PDMIBLOCK
+{
+ /**
+ * Read bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start reading from. The offset must be aligned to a sector boundary.
+ * @param pvBuf Where to store the read bits.
+ * @param cbRead Number of bytes to read. Must be aligned to a sector boundary.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead));
+
+ /**
+ * Write bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start writing at. The offset must be aligned to a sector boundary.
+ * @param pvBuf Where to store the write bits.
+ * @param cbWrite Number of bytes to write. Must be aligned to a sector boundary.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMIBLOCK pInterface, uint64_t off, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Make sure that the bits written are actually on the storage medium.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlush,(PPDMIBLOCK pInterface));
+
+ /**
+ * Send a raw command to the underlying device (CDROM).
+ * This method is optional (i.e. the function pointer may be NULL).
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pbCmd Offset to start reading from.
+ * @param enmTxDir Direction of transfer.
+ * @param pvBuf Pointer tp the transfer buffer.
+ * @param cbBuf Size of the transfer buffer.
+ * @param pbSenseKey Status of the command (when return value is VERR_DEV_IO_ERROR).
+ * @param cTimeoutMillies Command timeout in milliseconds.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSendCmd,(PPDMIBLOCK pInterface, const uint8_t *pbCmd, PDMBLOCKTXDIR enmTxDir, void *pvBuf, uint32_t *pcbBuf, uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies));
+
+ /**
+ * Merge medium contents during a live snapshot deletion.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfnProgress Function pointer for progress notification.
+ * @param pvUser Opaque user data for progress notification.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMerge,(PPDMIBLOCK pInterface, PFNSIMPLEPROGRESS pfnProgress, void *pvUser));
+
+ /**
+ * Check if the media is readonly or not.
+ *
+ * @returns true if readonly.
+ * @returns false if read/write.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnIsReadOnly,(PPDMIBLOCK pInterface));
+
+ /**
+ * Gets the media size in bytes.
+ *
+ * @returns Media size in bytes.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIBLOCK pInterface));
+
+ /**
+ * Gets the block drive type.
+ *
+ * @returns block drive type.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(PDMBLOCKTYPE, pfnGetType,(PPDMIBLOCK pInterface));
+
+ /**
+ * Gets the UUID of the block drive.
+ * Don't return the media UUID if it's removable.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pUuid Where to store the UUID on success.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetUuid,(PPDMIBLOCK pInterface, PRTUUID pUuid));
+
+ /**
+ * Discards the given range.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param paRanges Array of ranges to discard.
+ * @param cRanges Number of entries in the array.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDiscard,(PPDMIBLOCK pInterface, PCRTRANGE paRanges, unsigned cRanges));
+} PDMIBLOCK;
+/** PDMIBLOCK interface ID. */
+#define PDMIBLOCK_IID "5e7123dd-8cdf-4a6e-97a5-ab0c68d7e850"
+
+
+/** Pointer to a mount interface. */
+typedef struct PDMIMOUNTNOTIFY *PPDMIMOUNTNOTIFY;
+/**
+ * Block interface (up).
+ * Pair with PDMIMOUNT.
+ */
+typedef struct PDMIMOUNTNOTIFY
+{
+ /**
+ * Called when a media is mounted.
+ *
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnMountNotify,(PPDMIMOUNTNOTIFY pInterface));
+
+ /**
+ * Called when a media is unmounted
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUnmountNotify,(PPDMIMOUNTNOTIFY pInterface));
+} PDMIMOUNTNOTIFY;
+/** PDMIMOUNTNOTIFY interface ID. */
+#define PDMIMOUNTNOTIFY_IID "fa143ac9-9fc6-498e-997f-945380a558f9"
+
+
+/** Pointer to mount interface. */
+typedef struct PDMIMOUNT *PPDMIMOUNT;
+/**
+ * Mount interface (down).
+ * Pair with PDMIMOUNTNOTIFY.
+ */
+typedef struct PDMIMOUNT
+{
+ /**
+ * Mount a media.
+ *
+ * This will not unmount any currently mounted media!
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pszFilename Pointer to filename. If this is NULL it assumed that the caller have
+ * constructed a configuration which can be attached to the bottom driver.
+ * @param pszCoreDriver Core driver name. NULL will cause autodetection. Ignored if pszFilanem is NULL.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMount,(PPDMIMOUNT pInterface, const char *pszFilename, const char *pszCoreDriver));
+
+ /**
+ * Unmount the media.
+ *
+ * The driver will validate and pass it on. On the rebounce it will decide whether or not to detach it self.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread The emulation thread.
+ * @param fForce Force the unmount, even for locked media.
+ * @param fEject Eject the medium. Only relevant for host drives.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUnmount,(PPDMIMOUNT pInterface, bool fForce, bool fEject));
+
+ /**
+ * Checks if a media is mounted.
+ *
+ * @returns true if mounted.
+ * @returns false if not mounted.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnIsMounted,(PPDMIMOUNT pInterface));
+
+ /**
+ * Locks the media, preventing any unmounting of it.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLock,(PPDMIMOUNT pInterface));
+
+ /**
+ * Unlocks the media, canceling previous calls to pfnLock().
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUnlock,(PPDMIMOUNT pInterface));
+
+ /**
+ * Checks if a media is locked.
+ *
+ * @returns true if locked.
+ * @returns false if not locked.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnIsLocked,(PPDMIMOUNT pInterface));
+} PDMIMOUNT;
+/** PDMIMOUNT interface ID. */
+#define PDMIMOUNT_IID "34fc7a4c-623a-4806-a6bf-5be1be33c99f"
+
+
+/**
+ * Media geometry structure.
+ */
+typedef struct PDMMEDIAGEOMETRY
+{
+ /** Number of cylinders. */
+ uint32_t cCylinders;
+ /** Number of heads. */
+ uint32_t cHeads;
+ /** Number of sectors. */
+ uint32_t cSectors;
+} PDMMEDIAGEOMETRY;
+
+/** Pointer to media geometry structure. */
+typedef PDMMEDIAGEOMETRY *PPDMMEDIAGEOMETRY;
+/** Pointer to constant media geometry structure. */
+typedef const PDMMEDIAGEOMETRY *PCPDMMEDIAGEOMETRY;
+
+/** Pointer to a media port interface. */
+typedef struct PDMIMEDIAPORT *PPDMIMEDIAPORT;
+/**
+ * Media port interface (down).
+ */
+typedef struct PDMIMEDIAPORT
+{
+ /**
+ * Returns the storage controller name, instance and LUN of the attached medium.
+ *
+ * @returns VBox status.
+ * @param pInterface Pointer to this interface.
+ * @param ppcszController Where to store the name of the storage controller.
+ * @param piInstance Where to store the instance number of the controller.
+ * @param piLUN Where to store the LUN of the attached device.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryDeviceLocation, (PPDMIMEDIAPORT pInterface, const char **ppcszController,
+ uint32_t *piInstance, uint32_t *piLUN));
+
+} PDMIMEDIAPORT;
+/** PDMIMEDIAPORT interface ID. */
+#define PDMIMEDIAPORT_IID "9f7e8c9e-6d35-4453-bbef-1f78033174d6"
+
+/** Pointer to a media interface. */
+typedef struct PDMIMEDIA *PPDMIMEDIA;
+/**
+ * Media interface (up).
+ * Makes up the foundation for PDMIBLOCK and PDMIBLOCKBIOS.
+ * Pairs with PDMIMEDIAPORT.
+ */
+typedef struct PDMIMEDIA
+{
+ /**
+ * Read bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start reading from. The offset must be aligned to a sector boundary.
+ * @param pvBuf Where to store the read bits.
+ * @param cbRead Number of bytes to read. Must be aligned to a sector boundary.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead));
+
+ /**
+ * Write bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start writing at. The offset must be aligned to a sector boundary.
+ * @param pvBuf Where to store the write bits.
+ * @param cbWrite Number of bytes to write. Must be aligned to a sector boundary.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Make sure that the bits written are actually on the storage medium.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlush,(PPDMIMEDIA pInterface));
+
+ /**
+ * Merge medium contents during a live snapshot deletion. All details
+ * must have been configured through CFGM or this will fail.
+ * This method is optional (i.e. the function pointer may be NULL).
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfnProgress Function pointer for progress notification.
+ * @param pvUser Opaque user data for progress notification.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMerge,(PPDMIMEDIA pInterface, PFNSIMPLEPROGRESS pfnProgress, void *pvUser));
+
+ /**
+ * Get the media size in bytes.
+ *
+ * @returns Media size in bytes.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnGetSize,(PPDMIMEDIA pInterface));
+
+ /**
+ * Check if the media is readonly or not.
+ *
+ * @returns true if readonly.
+ * @returns false if read/write.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnIsReadOnly,(PPDMIMEDIA pInterface));
+
+ /**
+ * Get stored media geometry (physical CHS, PCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @returns VERR_PDM_GEOMETRY_NOT_SET if the geometry hasn't been set using pfnBiosSetPCHSGeometry() yet.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pPCHSGeometry Pointer to PCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnBiosGetPCHSGeometry,(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry));
+
+ /**
+ * Store the media geometry (physical CHS, PCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pPCHSGeometry Pointer to PCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnBiosSetPCHSGeometry,(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry));
+
+ /**
+ * Get stored media geometry (logical CHS, LCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @returns VERR_PDM_GEOMETRY_NOT_SET if the geometry hasn't been set using pfnBiosSetLCHSGeometry() yet.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pLCHSGeometry Pointer to LCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnBiosGetLCHSGeometry,(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry));
+
+ /**
+ * Store the media geometry (logical CHS, LCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pLCHSGeometry Pointer to LCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnBiosSetLCHSGeometry,(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry));
+
+ /**
+ * Gets the UUID of the media drive.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pUuid Where to store the UUID on success.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetUuid,(PPDMIMEDIA pInterface, PRTUUID pUuid));
+
+ /**
+ * Discards the given range.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param paRanges Array of ranges to discard.
+ * @param cRanges Number of entries in the array.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDiscard,(PPDMIMEDIA pInterface, PCRTRANGE paRanges, unsigned cRanges));
+
+} PDMIMEDIA;
+/** PDMIMEDIA interface ID. */
+#define PDMIMEDIA_IID "ec385d21-7aa9-42ca-8cfb-e1388297fa52"
+
+
+/** Pointer to a block BIOS interface. */
+typedef struct PDMIBLOCKBIOS *PPDMIBLOCKBIOS;
+/**
+ * Media BIOS interface (Up / External).
+ * The interface the getting and setting properties which the BIOS/CMOS care about.
+ */
+typedef struct PDMIBLOCKBIOS
+{
+ /**
+ * Get stored media geometry (physical CHS, PCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @returns VERR_PDM_GEOMETRY_NOT_SET if the geometry hasn't been set using pfnSetPCHSGeometry() yet.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pPCHSGeometry Pointer to PCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetPCHSGeometry,(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry));
+
+ /**
+ * Store the media geometry (physical CHS, PCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pPCHSGeometry Pointer to PCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetPCHSGeometry,(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry));
+
+ /**
+ * Get stored media geometry (logical CHS, LCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @returns VERR_PDM_GEOMETRY_NOT_SET if the geometry hasn't been set using pfnSetLCHSGeometry() yet.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pLCHSGeometry Pointer to LCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetLCHSGeometry,(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry));
+
+ /**
+ * Store the media geometry (logical CHS, LCHS) - BIOS property.
+ * This is an optional feature of a media.
+ *
+ * @returns VBox status code.
+ * @returns VERR_NOT_IMPLEMENTED if the media doesn't support storing the geometry.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pLCHSGeometry Pointer to LCHS geometry (cylinders/heads/sectors).
+ * @remark This has no influence on the read/write operations.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetLCHSGeometry,(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry));
+
+ /**
+ * Checks if the device should be visible to the BIOS or not.
+ *
+ * @returns true if the device is visible to the BIOS.
+ * @returns false if the device is not visible to the BIOS.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnIsVisible,(PPDMIBLOCKBIOS pInterface));
+
+ /**
+ * Gets the block drive type.
+ *
+ * @returns block drive type.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(PDMBLOCKTYPE, pfnGetType,(PPDMIBLOCKBIOS pInterface));
+
+} PDMIBLOCKBIOS;
+/** PDMIBLOCKBIOS interface ID. */
+#define PDMIBLOCKBIOS_IID "477c3eee-a48d-48a9-82fd-2a54de16b2e9"
+
+
+/** Pointer to a static block core driver interface. */
+typedef struct PDMIMEDIASTATIC *PPDMIMEDIASTATIC;
+/**
+ * Static block core driver interface.
+ */
+typedef struct PDMIMEDIASTATIC
+{
+ /**
+ * Check if the specified file is a format which the core driver can handle.
+ *
+ * @returns true / false accordingly.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pszFilename Name of the file to probe.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnCanHandle,(PPDMIMEDIASTATIC pInterface, const char *pszFilename));
+} PDMIMEDIASTATIC;
+
+
+
+
+
+/** Pointer to an asynchronous block notify interface. */
+typedef struct PDMIBLOCKASYNCPORT *PPDMIBLOCKASYNCPORT;
+/**
+ * Asynchronous block notify interface (up).
+ * Pair with PDMIBLOCKASYNC.
+ */
+typedef struct PDMIBLOCKASYNCPORT
+{
+ /**
+ * Notify completion of an asynchronous transfer.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvUser The user argument given in pfnStartWrite/Read.
+ * @param rcReq IPRT Status code of the completed request.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnTransferCompleteNotify, (PPDMIBLOCKASYNCPORT pInterface, void *pvUser, int rcReq));
+} PDMIBLOCKASYNCPORT;
+/** PDMIBLOCKASYNCPORT interface ID. */
+#define PDMIBLOCKASYNCPORT_IID "e3bdc0cb-9d99-41dd-8eec-0dc8cf5b2a92"
+
+
+
+/** Pointer to an asynchronous block interface. */
+typedef struct PDMIBLOCKASYNC *PPDMIBLOCKASYNC;
+/**
+ * Asynchronous block interface (down).
+ * Pair with PDMIBLOCKASYNCPORT.
+ */
+typedef struct PDMIBLOCKASYNC
+{
+ /**
+ * Start reading task.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start reading from.c
+ * @param paSegs Pointer to the S/G segment array.
+ * @param cSegs Number of entries in the array.
+ * @param cbRead Number of bytes to read. Must be aligned to a sector boundary.
+ * @param pvUser User argument which is returned in completion callback.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbRead, void *pvUser));
+
+ /**
+ * Write bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start writing at. The offset must be aligned to a sector boundary.
+ * @param paSegs Pointer to the S/G segment array.
+ * @param cSegs Number of entries in the array.
+ * @param cbWrite Number of bytes to write. Must be aligned to a sector boundary.
+ * @param pvUser User argument which is returned in completion callback.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbWrite, void *pvUser));
+
+ /**
+ * Flush everything to disk.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvUser User argument which is returned in completion callback.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartFlush,(PPDMIBLOCKASYNC pInterface, void *pvUser));
+
+ /**
+ * Discards the given range.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param paRanges Array of ranges to discard.
+ * @param cRanges Number of entries in the array.
+ * @param pvUser User argument which is returned in completion callback.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartDiscard,(PPDMIBLOCKASYNC pInterface, PCRTRANGE paRanges, unsigned cRanges, void *pvUser));
+
+} PDMIBLOCKASYNC;
+/** PDMIBLOCKASYNC interface ID. */
+#define PDMIBLOCKASYNC_IID "a921dd96-1748-4ecd-941e-d5f3cd4c8fe4"
+
+
+/** Pointer to an asynchronous notification interface. */
+typedef struct PDMIMEDIAASYNCPORT *PPDMIMEDIAASYNCPORT;
+/**
+ * Asynchronous version of the media interface (up).
+ * Pair with PDMIMEDIAASYNC.
+ */
+typedef struct PDMIMEDIAASYNCPORT
+{
+ /**
+ * Notify completion of a task.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvUser The user argument given in pfnStartWrite.
+ * @param rcReq IPRT Status code of the completed request.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnTransferCompleteNotify, (PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq));
+} PDMIMEDIAASYNCPORT;
+/** PDMIMEDIAASYNCPORT interface ID. */
+#define PDMIMEDIAASYNCPORT_IID "22d38853-901f-4a71-9670-4d9da6e82317"
+
+
+/** Pointer to an asynchronous media interface. */
+typedef struct PDMIMEDIAASYNC *PPDMIMEDIAASYNC;
+/**
+ * Asynchronous version of PDMIMEDIA (down).
+ * Pair with PDMIMEDIAASYNCPORT.
+ */
+typedef struct PDMIMEDIAASYNC
+{
+ /**
+ * Start reading task.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start reading from. Must be aligned to a sector boundary.
+ * @param paSegs Pointer to the S/G segment array.
+ * @param cSegs Number of entries in the array.
+ * @param cbRead Number of bytes to read. Must be aligned to a sector boundary.
+ * @param pvUser User data.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartRead,(PPDMIMEDIAASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbRead, void *pvUser));
+
+ /**
+ * Start writing task.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param off Offset to start writing at. Must be aligned to a sector boundary.
+ * @param paSegs Pointer to the S/G segment array.
+ * @param cSegs Number of entries in the array.
+ * @param cbWrite Number of bytes to write. Must be aligned to a sector boundary.
+ * @param pvUser User data.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartWrite,(PPDMIMEDIAASYNC pInterface, uint64_t off, PCRTSGSEG paSegs, unsigned cSegs, size_t cbWrite, void *pvUser));
+
+ /**
+ * Flush everything to disk.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvUser User argument which is returned in completion callback.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartFlush,(PPDMIMEDIAASYNC pInterface, void *pvUser));
+
+ /**
+ * Discards the given range.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param paRanges Array of ranges to discard.
+ * @param cRanges Number of entries in the array.
+ * @param pvUser User argument which is returned in completion callback.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStartDiscard,(PPDMIMEDIAASYNC pInterface, PCRTRANGE paRanges, unsigned cRanges, void *pvUser));
+
+} PDMIMEDIAASYNC;
+/** PDMIMEDIAASYNC interface ID. */
+#define PDMIMEDIAASYNC_IID "4be209d3-ccb5-4297-82fe-7d8018bc6ab4"
+
+
+/** Pointer to a char port interface. */
+typedef struct PDMICHARPORT *PPDMICHARPORT;
+/**
+ * Char port interface (down).
+ * Pair with PDMICHARCONNECTOR.
+ */
+typedef struct PDMICHARPORT
+{
+ /**
+ * Deliver data read to the device/driver.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf Where the read bits are stored.
+ * @param pcbRead Number of bytes available for reading/having been read.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnNotifyRead,(PPDMICHARPORT pInterface, const void *pvBuf, size_t *pcbRead));
+
+ /**
+ * Notify the device/driver when the status lines changed.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fNewStatusLine New state of the status line pins.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnNotifyStatusLinesChanged,(PPDMICHARPORT pInterface, uint32_t fNewStatusLines));
+
+ /**
+ * Notify the device when the driver buffer is full.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fFull Buffer full.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnNotifyBufferFull,(PPDMICHARPORT pInterface, bool fFull));
+
+ /**
+ * Notify the device/driver that a break occurred.
+ *
+ * @returns VBox statsus code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnNotifyBreak,(PPDMICHARPORT pInterface));
+} PDMICHARPORT;
+/** PDMICHARPORT interface ID. */
+#define PDMICHARPORT_IID "22769834-ea8b-4a6d-ade1-213dcdbd1228"
+
+/** @name Bit mask definitions for status line type.
+ * @{ */
+#define PDMICHARPORT_STATUS_LINES_DCD RT_BIT(0)
+#define PDMICHARPORT_STATUS_LINES_RI RT_BIT(1)
+#define PDMICHARPORT_STATUS_LINES_DSR RT_BIT(2)
+#define PDMICHARPORT_STATUS_LINES_CTS RT_BIT(3)
+/** @} */
+
+
+/** Pointer to a char interface. */
+typedef struct PDMICHARCONNECTOR *PPDMICHARCONNECTOR;
+/**
+ * Char connector interface (up).
+ * Pair with PDMICHARPORT.
+ */
+typedef struct PDMICHARCONNECTOR
+{
+ /**
+ * Write bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf Where to store the write bits.
+ * @param cbWrite Number of bytes to write.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMICHARCONNECTOR pInterface, const void *pvBuf, size_t cbWrite));
+
+ /**
+ * Set device parameters.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param Bps Speed of the serial connection. (bits per second)
+ * @param chParity Parity method: 'E' - even, 'O' - odd, 'N' - none.
+ * @param cDataBits Number of data bits.
+ * @param cStopBits Number of stop bits.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetParameters,(PPDMICHARCONNECTOR pInterface, unsigned Bps, char chParity, unsigned cDataBits, unsigned cStopBits));
+
+ /**
+ * Set the state of the modem lines.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fRequestToSend Set to true to make the Request to Send line active otherwise to 0.
+ * @param fDataTerminalReady Set to true to make the Data Terminal Ready line active otherwise 0.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetModemLines,(PPDMICHARCONNECTOR pInterface, bool fRequestToSend, bool fDataTerminalReady));
+
+ /**
+ * Sets the TD line into break condition.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fBreak Set to true to let the device send a break false to put into normal operation.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetBreak,(PPDMICHARCONNECTOR pInterface, bool fBreak));
+} PDMICHARCONNECTOR;
+/** PDMICHARCONNECTOR interface ID. */
+#define PDMICHARCONNECTOR_IID "4ad5c190-b408-4cef-926f-fbffce0dc5cc"
+
+
+/** Pointer to a stream interface. */
+typedef struct PDMISTREAM *PPDMISTREAM;
+/**
+ * Stream interface (up).
+ * Makes up the foundation for PDMICHARCONNECTOR. No pair interface.
+ */
+typedef struct PDMISTREAM
+{
+ /**
+ * Read bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf Where to store the read bits.
+ * @param cbRead Number of bytes to read/bytes actually read.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMISTREAM pInterface, void *pvBuf, size_t *cbRead));
+
+ /**
+ * Write bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf Where to store the write bits.
+ * @param cbWrite Number of bytes to write/bytes actually written.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMISTREAM pInterface, const void *pvBuf, size_t *cbWrite));
+} PDMISTREAM;
+/** PDMISTREAM interface ID. */
+#define PDMISTREAM_IID "d1a5bf5e-3d2c-449a-bde9-addd7920b71f"
+
+
+/** Mode of the parallel port */
+typedef enum PDMPARALLELPORTMODE
+{
+ /** First invalid mode. */
+ PDM_PARALLEL_PORT_MODE_INVALID = 0,
+ /** SPP (Compatibility mode). */
+ PDM_PARALLEL_PORT_MODE_SPP,
+ /** EPP Data mode. */
+ PDM_PARALLEL_PORT_MODE_EPP_DATA,
+ /** EPP Address mode. */
+ PDM_PARALLEL_PORT_MODE_EPP_ADDR,
+ /** ECP mode (not implemented yet). */
+ PDM_PARALLEL_PORT_MODE_ECP,
+ /** 32bit hack. */
+ PDM_PARALLEL_PORT_MODE_32BIT_HACK = 0x7fffffff
+} PDMPARALLELPORTMODE;
+
+/** Pointer to a host parallel port interface. */
+typedef struct PDMIHOSTPARALLELPORT *PPDMIHOSTPARALLELPORT;
+/**
+ * Host parallel port interface (down).
+ * Pair with PDMIHOSTPARALLELCONNECTOR.
+ */
+typedef struct PDMIHOSTPARALLELPORT
+{
+ /**
+ * Notify device/driver that an interrupt has occurred.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnNotifyInterrupt,(PPDMIHOSTPARALLELPORT pInterface));
+} PDMIHOSTPARALLELPORT;
+/** PDMIHOSTPARALLELPORT interface ID. */
+#define PDMIHOSTPARALLELPORT_IID "f24b8668-e7f6-4eaa-a14c-4aa2a5f7048e"
+
+
+
+/** Pointer to a Host Parallel connector interface. */
+typedef struct PDMIHOSTPARALLELCONNECTOR *PPDMIHOSTPARALLELCONNECTOR;
+/**
+ * Host parallel connector interface (up).
+ * Pair with PDMIHOSTPARALLELPORT.
+ */
+typedef struct PDMIHOSTPARALLELCONNECTOR
+{
+ /**
+ * Write bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf Where to store the write bits.
+ * @param cbWrite Number of bytes to write.
+ * @param enmMode Mode to write the data.
+ * @thread Any thread.
+ * @todo r=klaus cbWrite only defines buffer length, method needs a way top return actually written amount of data.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWrite,(PPDMIHOSTPARALLELCONNECTOR pInterface, const void *pvBuf,
+ size_t cbWrite, PDMPARALLELPORTMODE enmMode));
+
+ /**
+ * Read bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf Where to store the read bits.
+ * @param cbRead Number of bytes to read.
+ * @param enmMode Mode to read the data.
+ * @thread Any thread.
+ * @todo r=klaus cbRead only defines buffer length, method needs a way top return actually read amount of data.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRead,(PPDMIHOSTPARALLELCONNECTOR pInterface, void *pvBuf,
+ size_t cbRead, PDMPARALLELPORTMODE enmMode));
+
+ /**
+ * Set data direction of the port (forward/reverse).
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fForward Flag whether to indicate whether the port is operated in forward or reverse mode.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetPortDirection,(PPDMIHOSTPARALLELCONNECTOR pInterface, bool fForward));
+
+ /**
+ * Write control register bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fReg The new control register value.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWriteControl,(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t fReg));
+
+ /**
+ * Read control register bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfReg Where to store the control register bits.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadControl,(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pfReg));
+
+ /**
+ * Read status register bits.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfReg Where to store the status register bits.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReadStatus,(PPDMIHOSTPARALLELCONNECTOR pInterface, uint8_t *pfReg));
+
+} PDMIHOSTPARALLELCONNECTOR;
+/** PDMIHOSTPARALLELCONNECTOR interface ID. */
+#define PDMIHOSTPARALLELCONNECTOR_IID "7c532602-7438-4fbc-9265-349d9f0415f9"
+
+
+/** ACPI power source identifier */
+typedef enum PDMACPIPOWERSOURCE
+{
+ PDM_ACPI_POWER_SOURCE_UNKNOWN = 0,
+ PDM_ACPI_POWER_SOURCE_OUTLET,
+ PDM_ACPI_POWER_SOURCE_BATTERY
+} PDMACPIPOWERSOURCE;
+/** Pointer to ACPI battery state. */
+typedef PDMACPIPOWERSOURCE *PPDMACPIPOWERSOURCE;
+
+/** ACPI battey capacity */
+typedef enum PDMACPIBATCAPACITY
+{
+ PDM_ACPI_BAT_CAPACITY_MIN = 0,
+ PDM_ACPI_BAT_CAPACITY_MAX = 100,
+ PDM_ACPI_BAT_CAPACITY_UNKNOWN = 255
+} PDMACPIBATCAPACITY;
+/** Pointer to ACPI battery capacity. */
+typedef PDMACPIBATCAPACITY *PPDMACPIBATCAPACITY;
+
+/** ACPI battery state. See ACPI 3.0 spec '_BST (Battery Status)' */
+typedef enum PDMACPIBATSTATE
+{
+ PDM_ACPI_BAT_STATE_CHARGED = 0x00,
+ PDM_ACPI_BAT_STATE_DISCHARGING = 0x01,
+ PDM_ACPI_BAT_STATE_CHARGING = 0x02,
+ PDM_ACPI_BAT_STATE_CRITICAL = 0x04
+} PDMACPIBATSTATE;
+/** Pointer to ACPI battery state. */
+typedef PDMACPIBATSTATE *PPDMACPIBATSTATE;
+
+/** Pointer to an ACPI port interface. */
+typedef struct PDMIACPIPORT *PPDMIACPIPORT;
+/**
+ * ACPI port interface (down). Used by both the ACPI driver and (grumble) main.
+ * Pair with PDMIACPICONNECTOR.
+ */
+typedef struct PDMIACPIPORT
+{
+ /**
+ * Send an ACPI power off event.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPowerButtonPress,(PPDMIACPIPORT pInterface));
+
+ /**
+ * Send an ACPI sleep button event.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSleepButtonPress,(PPDMIACPIPORT pInterface));
+
+ /**
+ * Check if the last power button event was handled by the guest.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfHandled Is set to true if the last power button event was handled, false otherwise.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetPowerButtonHandled,(PPDMIACPIPORT pInterface, bool *pfHandled));
+
+ /**
+ * Check if the guest entered the ACPI mode.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfEnabled Is set to true if the guest entered the ACPI mode, false otherwise.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetGuestEnteredACPIMode,(PPDMIACPIPORT pInterface, bool *pfEntered));
+
+ /**
+ * Check if the given CPU is still locked by the guest.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param uCpu The CPU to check for.
+ * @param pfLocked Is set to true if the CPU is still locked by the guest, false otherwise.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetCpuStatus,(PPDMIACPIPORT pInterface, unsigned uCpu, bool *pfLocked));
+} PDMIACPIPORT;
+/** PDMIACPIPORT interface ID. */
+#define PDMIACPIPORT_IID "30d3dc4c-6a73-40c8-80e9-34309deacbb3"
+
+
+/** Pointer to an ACPI connector interface. */
+typedef struct PDMIACPICONNECTOR *PPDMIACPICONNECTOR;
+/**
+ * ACPI connector interface (up).
+ * Pair with PDMIACPIPORT.
+ */
+typedef struct PDMIACPICONNECTOR
+{
+ /**
+ * Get the current power source of the host system.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param penmPowerSource Pointer to the power source result variable.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryPowerSource,(PPDMIACPICONNECTOR, PPDMACPIPOWERSOURCE penmPowerSource));
+
+ /**
+ * Query the current battery status of the host system.
+ *
+ * @returns VBox status code?
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfPresent Is set to true if battery is present, false otherwise.
+ * @param penmRemainingCapacity Pointer to the battery remaining capacity (0 - 100 or 255 for unknown).
+ * @param penmBatteryState Pointer to the battery status.
+ * @param pu32PresentRate Pointer to the present rate (0..1000 of the total capacity).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryBatteryStatus,(PPDMIACPICONNECTOR, bool *pfPresent, PPDMACPIBATCAPACITY penmRemainingCapacity,
+ PPDMACPIBATSTATE penmBatteryState, uint32_t *pu32PresentRate));
+} PDMIACPICONNECTOR;
+/** PDMIACPICONNECTOR interface ID. */
+#define PDMIACPICONNECTOR_IID "5f14bf8d-1edf-4e3a-a1e1-cca9fd08e359"
+
+
+/** Pointer to a VMMDevice port interface. */
+typedef struct PDMIVMMDEVPORT *PPDMIVMMDEVPORT;
+/**
+ * VMMDevice port interface (down).
+ * Pair with PDMIVMMDEVCONNECTOR.
+ */
+typedef struct PDMIVMMDEVPORT
+{
+ /**
+ * Return the current absolute mouse position in pixels
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pxAbs Pointer of result value, can be NULL
+ * @param pyAbs Pointer of result value, can be NULL
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryAbsoluteMouse,(PPDMIVMMDEVPORT pInterface, int32_t *pxAbs, int32_t *pyAbs));
+
+ /**
+ * Set the new absolute mouse position in pixels
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param xabs New absolute X position
+ * @param yAbs New absolute Y position
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetAbsoluteMouse,(PPDMIVMMDEVPORT pInterface, int32_t xAbs, int32_t yAbs));
+
+ /**
+ * Return the current mouse capability flags
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pfCapabilities Pointer of result value
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryMouseCapabilities,(PPDMIVMMDEVPORT pInterface, uint32_t *pfCapabilities));
+
+ /**
+ * Set the current mouse capability flag (host side)
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fCapsAdded Mask of capabilities to add to the flag
+ * @param fCapsRemoved Mask of capabilities to remove from the flag
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUpdateMouseCapabilities,(PPDMIVMMDEVPORT pInterface, uint32_t fCapsAdded, uint32_t fCapsRemoved));
+
+ /**
+ * Issue a display resolution change request.
+ *
+ * Note that there can only one request in the queue and that in case the guest does
+ * not process it, issuing another request will overwrite the previous.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param cx Horizontal pixel resolution (0 = do not change).
+ * @param cy Vertical pixel resolution (0 = do not change).
+ * @param cBits Bits per pixel (0 = do not change).
+ * @param idxDisplay The display index.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRequestDisplayChange,(PPDMIVMMDEVPORT pInterface, uint32_t cx, uint32_t cy, uint32_t cBits, uint32_t idxDisplay));
+
+ /**
+ * Pass credentials to guest.
+ *
+ * Note that there can only be one set of credentials and the guest may or may not
+ * query them and may do whatever it wants with them.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pszUsername User name, may be empty (UTF-8).
+ * @param pszPassword Password, may be empty (UTF-8).
+ * @param pszDomain Domain name, may be empty (UTF-8).
+ * @param fFlags VMMDEV_SETCREDENTIALS_*.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetCredentials,(PPDMIVMMDEVPORT pInterface, const char *pszUsername,
+ const char *pszPassword, const char *pszDomain,
+ uint32_t fFlags));
+
+ /**
+ * Notify the driver about a VBVA status change.
+ *
+ * @returns Nothing. Because it is informational callback.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fEnabled Current VBVA status.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVBVAChange, (PPDMIVMMDEVPORT pInterface, bool fEnabled));
+
+ /**
+ * Issue a seamless mode change request.
+ *
+ * Note that there can only one request in the queue and that in case the guest does
+ * not process it, issuing another request will overwrite the previous.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fEnabled Seamless mode enabled or not
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRequestSeamlessChange,(PPDMIVMMDEVPORT pInterface, bool fEnabled));
+
+ /**
+ * Issue a memory balloon change request.
+ *
+ * Note that there can only one request in the queue and that in case the guest does
+ * not process it, issuing another request will overwrite the previous.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param cMbBalloon Balloon size in megabytes
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetMemoryBalloon,(PPDMIVMMDEVPORT pInterface, uint32_t cMbBalloon));
+
+ /**
+ * Issue a statistcs interval change request.
+ *
+ * Note that there can only one request in the queue and that in case the guest does
+ * not process it, issuing another request will overwrite the previous.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param cSecsStatInterval Statistics query interval in seconds
+ * (0=disable).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetStatisticsInterval,(PPDMIVMMDEVPORT pInterface, uint32_t cSecsStatInterval));
+
+ /**
+ * Notify the guest about a VRDP status change.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fVRDPEnabled Current VRDP status.
+ * @param uVRDPExperienceLevel Which visual effects to be disabled in
+ * the guest.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVRDPChange, (PPDMIVMMDEVPORT pInterface, bool fVRDPEnabled, uint32_t uVRDPExperienceLevel));
+
+ /**
+ * Notify the guest of CPU hot-unplug event.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param idCpuCore The core id of the CPU to remove.
+ * @param idCpuPackage The package id of the CPU to remove.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCpuHotUnplug, (PPDMIVMMDEVPORT pInterface, uint32_t idCpuCore, uint32_t idCpuPackage));
+
+ /**
+ * Notify the guest of CPU hot-plug event.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param idCpuCore The core id of the CPU to add.
+ * @param idCpuPackage The package id of the CPU to add.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCpuHotPlug, (PPDMIVMMDEVPORT pInterface, uint32_t idCpuCore, uint32_t idCpuPackage));
+
+} PDMIVMMDEVPORT;
+/** PDMIVMMDEVPORT interface ID. */
+#define PDMIVMMDEVPORT_IID "d7e52035-3b6c-422e-9215-2a75646a945d"
+
+
+/** Pointer to a HPET legacy notification interface. */
+typedef struct PDMIHPETLEGACYNOTIFY *PPDMIHPETLEGACYNOTIFY;
+/**
+ * HPET legacy notification interface.
+ */
+typedef struct PDMIHPETLEGACYNOTIFY
+{
+ /**
+ * Notify about change of HPET legacy mode.
+ *
+ * @param pInterface Pointer to the interface structure containing the
+ * called function pointer.
+ * @param fActivated If HPET legacy mode is activated (@c true) or
+ * deactivated (@c false).
+ */
+ DECLR3CALLBACKMEMBER(void, pfnModeChanged,(PPDMIHPETLEGACYNOTIFY pInterface, bool fActivated));
+} PDMIHPETLEGACYNOTIFY;
+/** PDMIHPETLEGACYNOTIFY interface ID. */
+#define PDMIHPETLEGACYNOTIFY_IID "c9ada595-4b65-4311-8b21-b10498997774"
+
+
+/** @name Flags for PDMIVMMDEVPORT::pfnSetCredentials.
+ * @{ */
+/** The guest should perform a logon with the credentials. */
+#define VMMDEV_SETCREDENTIALS_GUESTLOGON RT_BIT(0)
+/** The guest should prevent local logons. */
+#define VMMDEV_SETCREDENTIALS_NOLOCALLOGON RT_BIT(1)
+/** The guest should verify the credentials. */
+#define VMMDEV_SETCREDENTIALS_JUDGE RT_BIT(15)
+/** @} */
+
+/** Forward declaration of the guest information structure. */
+struct VBoxGuestInfo;
+/** Forward declaration of the guest information-2 structure. */
+struct VBoxGuestInfo2;
+/** Forward declaration of the guest statistics structure */
+struct VBoxGuestStatistics;
+/** Forward declaration of the guest status structure */
+struct VBoxGuestStatus;
+
+/** Forward declaration of the video accelerator command memory. */
+struct VBVAMEMORY;
+/** Pointer to video accelerator command memory. */
+typedef struct VBVAMEMORY *PVBVAMEMORY;
+
+/** Pointer to a VMMDev connector interface. */
+typedef struct PDMIVMMDEVCONNECTOR *PPDMIVMMDEVCONNECTOR;
+/**
+ * VMMDev connector interface (up).
+ * Pair with PDMIVMMDEVPORT.
+ */
+typedef struct PDMIVMMDEVCONNECTOR
+{
+ /**
+ * Update guest facility status.
+ *
+ * Called in response to VMMDevReq_ReportGuestStatus, reset or state restore.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param uFacility The facility.
+ * @param uStatus The status.
+ * @param fFlags Flags assoicated with the update. Currently
+ * reserved and should be ignored.
+ * @param pTimeSpecTS Pointer to the timestamp of this report.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateGuestStatus,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t uFacility, uint16_t uStatus,
+ uint32_t fFlags, PCRTTIMESPEC pTimeSpecTS));
+
+ /**
+ * Reports the guest API and OS version.
+ * Called whenever the Additions issue a guest info report request.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pGuestInfo Pointer to guest information structure
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateGuestInfo,(PPDMIVMMDEVCONNECTOR pInterface, const struct VBoxGuestInfo *pGuestInfo));
+
+ /**
+ * Reports the detailed Guest Additions version.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param uFullVersion The guest additions version as a full version.
+ * Use VBOX_FULL_VERSION_GET_MAJOR,
+ * VBOX_FULL_VERSION_GET_MINOR and
+ * VBOX_FULL_VERSION_GET_BUILD to access it.
+ * (This will not be zero, so turn down the
+ * paranoia level a notch.)
+ * @param pszName Pointer to the sanitized version name. This can
+ * be empty, but will not be NULL. If not empty,
+ * it will contain a build type tag and/or a
+ * publisher tag. If both, then they are separated
+ * by an underscore (VBOX_VERSION_STRING fashion).
+ * @param uRevision The SVN revision. Can be 0.
+ * @param fFeatures Feature mask, currently none are defined.
+ *
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateGuestInfo2,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t uFullVersion,
+ const char *pszName, uint32_t uRevision, uint32_t fFeatures));
+
+ /**
+ * Update the guest additions capabilities.
+ * This is called when the guest additions capabilities change. The new capabilities
+ * are given and the connector should update its internal state.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param newCapabilities New capabilities.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateGuestCapabilities,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities));
+
+ /**
+ * Update the mouse capabilities.
+ * This is called when the mouse capabilities change. The new capabilities
+ * are given and the connector should update its internal state.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param newCapabilities New capabilities.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdateMouseCapabilities,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities));
+
+ /**
+ * Update the pointer shape.
+ * This is called when the mouse pointer shape changes. The new shape
+ * is passed as a caller allocated buffer that will be freed after returning
+ *
+ * @param pInterface Pointer to this interface.
+ * @param fVisible Visibility indicator (if false, the other parameters are undefined).
+ * @param fAlpha Flag whether alpha channel is being passed.
+ * @param xHot Pointer hot spot x coordinate.
+ * @param yHot Pointer hot spot y coordinate.
+ * @param x Pointer new x coordinate on screen.
+ * @param y Pointer new y coordinate on screen.
+ * @param cx Pointer width in pixels.
+ * @param cy Pointer height in pixels.
+ * @param cbScanline Size of one scanline in bytes.
+ * @param pvShape New shape buffer.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUpdatePointerShape,(PPDMIVMMDEVCONNECTOR pInterface, bool fVisible, bool fAlpha,
+ uint32_t xHot, uint32_t yHot,
+ uint32_t cx, uint32_t cy,
+ void *pvShape));
+
+ /**
+ * Enable or disable video acceleration on behalf of guest.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param fEnable Whether to enable acceleration.
+ * @param pVbvaMemory Video accelerator memory.
+
+ * @return VBox rc. VINF_SUCCESS if VBVA was enabled.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVideoAccelEnable,(PPDMIVMMDEVCONNECTOR pInterface, bool fEnable, PVBVAMEMORY pVbvaMemory));
+
+ /**
+ * Force video queue processing.
+ *
+ * @param pInterface Pointer to this interface.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVideoAccelFlush,(PPDMIVMMDEVCONNECTOR pInterface));
+
+ /**
+ * Return whether the given video mode is supported/wanted by the host.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to this interface.
+ * @param display The guest monitor, 0 for primary.
+ * @param cy Video mode horizontal resolution in pixels.
+ * @param cx Video mode vertical resolution in pixels.
+ * @param cBits Video mode bits per pixel.
+ * @param pfSupported Where to put the indicator for whether this mode is supported. (output)
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVideoModeSupported,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t display, uint32_t cx, uint32_t cy, uint32_t cBits, bool *pfSupported));
+
+ /**
+ * Queries by how many pixels the height should be reduced when calculating video modes
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to this interface.
+ * @param pcyReduction Pointer to the result value.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetHeightReduction,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *pcyReduction));
+
+ /**
+ * Informs about a credentials judgement result from the guest.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to this interface.
+ * @param fFlags Judgement result flags.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetCredentialsJudgementResult,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t fFlags));
+
+ /**
+ * Set the visible region of the display
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param cRect Number of rectangles in pRect
+ * @param pRect Rectangle array
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetVisibleRegion,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t cRect, PRTRECT pRect));
+
+ /**
+ * Query the visible region of the display
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pcRect Number of rectangles in pRect
+ * @param pRect Rectangle array (set to NULL to query the number of rectangles)
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryVisibleRegion,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *pcRect, PRTRECT pRect));
+
+ /**
+ * Request the statistics interval
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pulInterval Pointer to interval in seconds
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryStatisticsInterval,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *pulInterval));
+
+ /**
+ * Report new guest statistics
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pGuestStats Guest statistics
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReportStatistics,(PPDMIVMMDEVCONNECTOR pInterface, struct VBoxGuestStatistics *pGuestStats));
+
+ /**
+ * Query the current balloon size
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pcbBalloon Balloon size
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryBalloonSize,(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *pcbBalloon));
+
+ /**
+ * Query the current page fusion setting
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pfPageFusionEnabled Pointer to boolean
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnIsPageFusionEnabled,(PPDMIVMMDEVCONNECTOR pInterface, bool *pfPageFusionEnabled));
+
+} PDMIVMMDEVCONNECTOR;
+/** PDMIVMMDEVCONNECTOR interface ID. */
+#define PDMIVMMDEVCONNECTOR_IID "aff90240-a443-434e-9132-80c186ab97d4"
+
+
+/** Pointer to a network connector interface */
+typedef struct PDMIAUDIOCONNECTOR *PPDMIAUDIOCONNECTOR;
+/**
+ * Audio connector interface (up).
+ * No interface pair yet.
+ */
+typedef struct PDMIAUDIOCONNECTOR
+{
+ DECLR3CALLBACKMEMBER(void, pfnRun,(PPDMIAUDIOCONNECTOR pInterface));
+
+/* DECLR3CALLBACKMEMBER(int, pfnSetRecordSource,(PPDMIAUDIOINCONNECTOR pInterface, AUDIORECSOURCE)); */
+
+} PDMIAUDIOCONNECTOR;
+/** PDMIAUDIOCONNECTOR interface ID. */
+#define PDMIAUDIOCONNECTOR_IID "85d52af5-b3aa-4b3e-b176-4b5ebfc52f47"
+
+
+/** @todo r=bird: the two following interfaces are hacks to work around the missing audio driver
+ * interface. This should be addressed rather than making more temporary hacks. */
+
+/** Pointer to a Audio Sniffer Device port interface. */
+typedef struct PDMIAUDIOSNIFFERPORT *PPDMIAUDIOSNIFFERPORT;
+/**
+ * Audio Sniffer port interface (down).
+ * Pair with PDMIAUDIOSNIFFERCONNECTOR.
+ */
+typedef struct PDMIAUDIOSNIFFERPORT
+{
+ /**
+ * Enables or disables sniffing.
+ *
+ * If sniffing is being enabled also sets a flag whether the audio must be also
+ * left on the host.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to this interface.
+ * @param fEnable 'true' for enable sniffing, 'false' to disable.
+ * @param fKeepHostAudio Indicates whether host audio should also present
+ * 'true' means that sound should not be played
+ * by the audio device.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetup,(PPDMIAUDIOSNIFFERPORT pInterface, bool fEnable, bool fKeepHostAudio));
+
+ /**
+ * Enables or disables audio input.
+ *
+ * @returns VBox status code
+ * @param pInterface Pointer to this interface.
+ * @param fIntercept 'true' for interception of audio input,
+ * 'false' to let the host audio backend do audio input.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAudioInputIntercept,(PPDMIAUDIOSNIFFERPORT pInterface, bool fIntercept));
+
+ /**
+ * Audio input is about to start.
+ *
+ * @returns VBox status code.
+ * @param pvContext The callback context, supplied in the
+ * PDMIAUDIOSNIFFERCONNECTOR::pfnAudioInputBegin as pvContext.
+ * @param iSampleHz The sample frequency in Hz.
+ * @param cChannels Number of channels. 1 for mono, 2 for stereo.
+ * @param cBits How many bits a sample for a single channel has. Normally 8 or 16.
+ * @param fUnsigned Whether samples are unsigned values.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAudioInputEventBegin,(PPDMIAUDIOSNIFFERPORT pInterface,
+ void *pvContext,
+ int iSampleHz,
+ int cChannels,
+ int cBits,
+ bool fUnsigned));
+
+ /**
+ * Callback which delivers audio data to the audio device.
+ *
+ * @returns VBox status code.
+ * @param pvContext The callback context, supplied in the
+ * PDMIAUDIOSNIFFERCONNECTOR::pfnAudioInputBegin as pvContext.
+ * @param pvData Event specific data.
+ * @param cbData Size of the buffer pointed by pvData.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAudioInputEventData,(PPDMIAUDIOSNIFFERPORT pInterface,
+ void *pvContext,
+ const void *pvData,
+ uint32_t cbData));
+
+ /**
+ * Audio input ends.
+ *
+ * @param pvContext The callback context, supplied in the
+ * PDMIAUDIOSNIFFERCONNECTOR::pfnAudioInputBegin as pvContext.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnAudioInputEventEnd,(PPDMIAUDIOSNIFFERPORT pInterface,
+ void *pvContext));
+} PDMIAUDIOSNIFFERPORT;
+/** PDMIAUDIOSNIFFERPORT interface ID. */
+#define PDMIAUDIOSNIFFERPORT_IID "8ad25d78-46e9-479b-a363-bb0bc0fe022f"
+
+
+/** Pointer to a Audio Sniffer connector interface. */
+typedef struct PDMIAUDIOSNIFFERCONNECTOR *PPDMIAUDIOSNIFFERCONNECTOR;
+
+/**
+ * Audio Sniffer connector interface (up).
+ * Pair with PDMIAUDIOSNIFFERPORT.
+ */
+typedef struct PDMIAUDIOSNIFFERCONNECTOR
+{
+ /**
+ * AudioSniffer device calls this method when audio samples
+ * are about to be played and sniffing is enabled.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pvSamples Audio samples buffer.
+ * @param cSamples How many complete samples are in the buffer.
+ * @param iSampleHz The sample frequency in Hz.
+ * @param cChannels Number of channels. 1 for mono, 2 for stereo.
+ * @param cBits How many bits a sample for a single channel has. Normally 8 or 16.
+ * @param fUnsigned Whether samples are unsigned values.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnAudioSamplesOut,(PPDMIAUDIOSNIFFERCONNECTOR pInterface, void *pvSamples, uint32_t cSamples,
+ int iSampleHz, int cChannels, int cBits, bool fUnsigned));
+
+ /**
+ * AudioSniffer device calls this method when output volume is changed.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param u16LeftVolume 0..0xFFFF volume level for left channel.
+ * @param u16RightVolume 0..0xFFFF volume level for right channel.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnAudioVolumeOut,(PPDMIAUDIOSNIFFERCONNECTOR pInterface, uint16_t u16LeftVolume, uint16_t u16RightVolume));
+
+ /**
+ * Audio input has been requested by the virtual audio device.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param ppvUserCtx The interface context for this audio input stream,
+ * it will be used in the pfnAudioInputEnd call.
+ * @param pvContext The context pointer to be used in PDMIAUDIOSNIFFERPORT::pfnAudioInputEvent.
+ * @param cSamples How many samples in a block is preferred in
+ * PDMIAUDIOSNIFFERPORT::pfnAudioInputEvent.
+ * @param iSampleHz The sample frequency in Hz.
+ * @param cChannels Number of channels. 1 for mono, 2 for stereo.
+ * @param cBits How many bits a sample for a single channel has. Normally 8 or 16.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAudioInputBegin,(PPDMIAUDIOSNIFFERCONNECTOR pInterface,
+ void **ppvUserCtx,
+ void *pvContext,
+ uint32_t cSamples,
+ uint32_t iSampleHz,
+ uint32_t cChannels,
+ uint32_t cBits));
+
+ /**
+ * Audio input has been requested by the virtual audio device.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pvUserCtx The interface context for this audio input stream,
+ * which was returned by pfnAudioInputBegin call.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnAudioInputEnd,(PPDMIAUDIOSNIFFERCONNECTOR pInterface,
+ void *pvUserCtx));
+} PDMIAUDIOSNIFFERCONNECTOR;
+/** PDMIAUDIOSNIFFERCONNECTOR - The Audio Sniffer Driver connector interface. */
+#define PDMIAUDIOSNIFFERCONNECTOR_IID "9d37f543-27af-45f8-8002-8ef7abac71e4"
+
+
+/**
+ * Generic status LED core.
+ * Note that a unit doesn't have to support all the indicators.
+ */
+typedef union PDMLEDCORE
+{
+ /** 32-bit view. */
+ uint32_t volatile u32;
+ /** Bit view. */
+ struct
+ {
+ /** Reading/Receiving indicator. */
+ uint32_t fReading : 1;
+ /** Writing/Sending indicator. */
+ uint32_t fWriting : 1;
+ /** Busy indicator. */
+ uint32_t fBusy : 1;
+ /** Error indicator. */
+ uint32_t fError : 1;
+ } s;
+} PDMLEDCORE;
+
+/** LED bit masks for the u32 view.
+ * @{ */
+/** Reading/Receiving indicator. */
+#define PDMLED_READING RT_BIT(0)
+/** Writing/Sending indicator. */
+#define PDMLED_WRITING RT_BIT(1)
+/** Busy indicator. */
+#define PDMLED_BUSY RT_BIT(2)
+/** Error indicator. */
+#define PDMLED_ERROR RT_BIT(3)
+/** @} */
+
+
+/**
+ * Generic status LED.
+ * Note that a unit doesn't have to support all the indicators.
+ */
+typedef struct PDMLED
+{
+ /** Just a magic for sanity checking. */
+ uint32_t u32Magic;
+ uint32_t u32Alignment; /**< structure size alignment. */
+ /** The actual LED status.
+ * Only the device is allowed to change this. */
+ PDMLEDCORE Actual;
+ /** The asserted LED status which is cleared by the reader.
+ * The device will assert the bits but never clear them.
+ * The driver clears them as it sees fit. */
+ PDMLEDCORE Asserted;
+} PDMLED;
+
+/** Pointer to an LED. */
+typedef PDMLED *PPDMLED;
+/** Pointer to a const LED. */
+typedef const PDMLED *PCPDMLED;
+
+/** Magic value for PDMLED::u32Magic. */
+#define PDMLED_MAGIC UINT32_C(0x11335577)
+
+/** Pointer to an LED ports interface. */
+typedef struct PDMILEDPORTS *PPDMILEDPORTS;
+/**
+ * Interface for exporting LEDs (down).
+ * Pair with PDMILEDCONNECTORS.
+ */
+typedef struct PDMILEDPORTS
+{
+ /**
+ * Gets the pointer to the status LED of a unit.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param iLUN The unit which status LED we desire.
+ * @param ppLed Where to store the LED pointer.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryStatusLed,(PPDMILEDPORTS pInterface, unsigned iLUN, PPDMLED *ppLed));
+
+} PDMILEDPORTS;
+/** PDMILEDPORTS interface ID. */
+#define PDMILEDPORTS_IID "435e0cec-8549-4ca0-8c0d-98e52f1dc038"
+
+
+/** Pointer to an LED connectors interface. */
+typedef struct PDMILEDCONNECTORS *PPDMILEDCONNECTORS;
+/**
+ * Interface for reading LEDs (up).
+ * Pair with PDMILEDPORTS.
+ */
+typedef struct PDMILEDCONNECTORS
+{
+ /**
+ * Notification about a unit which have been changed.
+ *
+ * The driver must discard any pointers to data owned by
+ * the unit and requery it.
+ *
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param iLUN The unit number.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnUnitChanged,(PPDMILEDCONNECTORS pInterface, unsigned iLUN));
+} PDMILEDCONNECTORS;
+/** PDMILEDCONNECTORS interface ID. */
+#define PDMILEDCONNECTORS_IID "8ed63568-82a7-4193-b57b-db8085ac4495"
+
+
+/** Pointer to a Media Notification interface. */
+typedef struct PDMIMEDIANOTIFY *PPDMIMEDIANOTIFY;
+/**
+ * Interface for exporting Medium eject information (up). No interface pair.
+ */
+typedef struct PDMIMEDIANOTIFY
+{
+ /**
+ * Signals that the medium was ejected.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param iLUN The unit which had the medium ejected.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnEjected,(PPDMIMEDIANOTIFY pInterface, unsigned iLUN));
+
+} PDMIMEDIANOTIFY;
+/** PDMIMEDIANOTIFY interface ID. */
+#define PDMIMEDIANOTIFY_IID "fc22d53e-feb1-4a9c-b9fb-0a990a6ab288"
+
+
+/** The special status unit number */
+#define PDM_STATUS_LUN 999
+
+
+#ifdef VBOX_WITH_HGCM
+
+/** Abstract HGCM command structure. Used only to define a typed pointer. */
+struct VBOXHGCMCMD;
+
+/** Pointer to HGCM command structure. This pointer is unique and identifies
+ * the command being processed. The pointer is passed to HGCM connector methods,
+ * and must be passed back to HGCM port when command is completed.
+ */
+typedef struct VBOXHGCMCMD *PVBOXHGCMCMD;
+
+/** Pointer to a HGCM port interface. */
+typedef struct PDMIHGCMPORT *PPDMIHGCMPORT;
+/**
+ * Host-Guest communication manager port interface (down). Normally implemented
+ * by VMMDev.
+ * Pair with PDMIHGCMCONNECTOR.
+ */
+typedef struct PDMIHGCMPORT
+{
+ /**
+ * Notify the guest on a command completion.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param rc The return code (VBox error code).
+ * @param pCmd A pointer that identifies the completed command.
+ *
+ * @returns VBox status code
+ */
+ DECLR3CALLBACKMEMBER(void, pfnCompleted,(PPDMIHGCMPORT pInterface, int32_t rc, PVBOXHGCMCMD pCmd));
+
+} PDMIHGCMPORT;
+/** PDMIHGCMPORT interface ID. */
+# define PDMIHGCMPORT_IID "e00a0cbf-b75a-45c3-87f4-41cddbc5ae0b"
+
+
+/** Pointer to a HGCM service location structure. */
+typedef struct HGCMSERVICELOCATION *PHGCMSERVICELOCATION;
+
+/** Pointer to a HGCM connector interface. */
+typedef struct PDMIHGCMCONNECTOR *PPDMIHGCMCONNECTOR;
+/**
+ * The Host-Guest communication manager connector interface (up). Normally
+ * implemented by Main::VMMDevInterface.
+ * Pair with PDMIHGCMPORT.
+ */
+typedef struct PDMIHGCMCONNECTOR
+{
+ /**
+ * Locate a service and inform it about a client connection.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd A pointer that identifies the command.
+ * @param pServiceLocation Pointer to the service location structure.
+ * @param pu32ClientID Where to store the client id for the connection.
+ * @return VBox status code.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnConnect,(PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, PHGCMSERVICELOCATION pServiceLocation, uint32_t *pu32ClientID));
+
+ /**
+ * Disconnect from service.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd A pointer that identifies the command.
+ * @param u32ClientID The client id returned by the pfnConnect call.
+ * @return VBox status code.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDisconnect,(PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, uint32_t u32ClientID));
+
+ /**
+ * Process a guest issued command.
+ *
+ * @param pInterface Pointer to this interface.
+ * @param pCmd A pointer that identifies the command.
+ * @param u32ClientID The client id returned by the pfnConnect call.
+ * @param u32Function Function to be performed by the service.
+ * @param cParms Number of parameters in the array pointed to by paParams.
+ * @param paParms Pointer to an array of parameters.
+ * @return VBox status code.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCall,(PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, uint32_t u32ClientID, uint32_t u32Function,
+ uint32_t cParms, PVBOXHGCMSVCPARM paParms));
+
+} PDMIHGCMCONNECTOR;
+/** PDMIHGCMCONNECTOR interface ID. */
+# define PDMIHGCMCONNECTOR_IID "a1104758-c888-4437-8f2a-7bac17865b5c"
+
+#endif /* VBOX_WITH_HGCM */
+
+/**
+ * Data direction.
+ */
+typedef enum PDMSCSIREQUESTTXDIR
+{
+ PDMSCSIREQUESTTXDIR_UNKNOWN = 0x00,
+ PDMSCSIREQUESTTXDIR_FROM_DEVICE = 0x01,
+ PDMSCSIREQUESTTXDIR_TO_DEVICE = 0x02,
+ PDMSCSIREQUESTTXDIR_NONE = 0x03,
+ PDMSCSIREQUESTTXDIR_32BIT_HACK = 0x7fffffff
+} PDMSCSIREQUESTTXDIR;
+
+/**
+ * SCSI request structure.
+ */
+typedef struct PDMSCSIREQUEST
+{
+ /** The logical unit. */
+ uint32_t uLogicalUnit;
+ /** Direction of the data flow. */
+ PDMSCSIREQUESTTXDIR uDataDirection;
+ /** Size of the SCSI CDB. */
+ uint32_t cbCDB;
+ /** Pointer to the SCSI CDB. */
+ uint8_t *pbCDB;
+ /** Overall size of all scatter gather list elements
+ * for data transfer if any. */
+ uint32_t cbScatterGather;
+ /** Number of elements in the scatter gather list. */
+ uint32_t cScatterGatherEntries;
+ /** Pointer to the head of the scatter gather list. */
+ PRTSGSEG paScatterGatherHead;
+ /** Size of the sense buffer. */
+ uint32_t cbSenseBuffer;
+ /** Pointer to the sense buffer. *
+ * Current assumption that the sense buffer is not scattered. */
+ uint8_t *pbSenseBuffer;
+ /** Opaque user data for use by the device. Left untouched by everything else! */
+ void *pvUser;
+} PDMSCSIREQUEST, *PPDMSCSIREQUEST;
+/** Pointer to a const SCSI request structure. */
+typedef const PDMSCSIREQUEST *PCSCSIREQUEST;
+
+/** Pointer to a SCSI port interface. */
+typedef struct PDMISCSIPORT *PPDMISCSIPORT;
+/**
+ * SCSI command execution port interface (down).
+ * Pair with PDMISCSICONNECTOR.
+ */
+typedef struct PDMISCSIPORT
+{
+
+ /**
+ * Notify the device on request completion.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pSCSIRequest Pointer to the finished SCSI request.
+ * @param rcCompletion SCSI_STATUS_* code for the completed request.
+ * @param fRedo Flag whether the request can to be redone
+ * when it failed.
+ * @param rcReq The status code the request completed with (VERR_*)
+ * Should be only used to choose the correct error message
+ * displayed to the user if the error can be fixed by him
+ * (fRedo is true).
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSCSIRequestCompleted, (PPDMISCSIPORT pInterface, PPDMSCSIREQUEST pSCSIRequest,
+ int rcCompletion, bool fRedo, int rcReq));
+
+ /**
+ * Returns the storage controller name, instance and LUN of the attached medium.
+ *
+ * @returns VBox status.
+ * @param pInterface Pointer to this interface.
+ * @param ppcszController Where to store the name of the storage controller.
+ * @param piInstance Where to store the instance number of the controller.
+ * @param piLUN Where to store the LUN of the attached device.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryDeviceLocation, (PPDMISCSIPORT pInterface, const char **ppcszController,
+ uint32_t *piInstance, uint32_t *piLUN));
+
+} PDMISCSIPORT;
+/** PDMISCSIPORT interface ID. */
+#define PDMISCSIPORT_IID "05d9fc3b-e38c-4b30-8344-a323feebcfe5"
+
+
+/** Pointer to a SCSI connector interface. */
+typedef struct PDMISCSICONNECTOR *PPDMISCSICONNECTOR;
+/**
+ * SCSI command execution connector interface (up).
+ * Pair with PDMISCSIPORT.
+ */
+typedef struct PDMISCSICONNECTOR
+{
+
+ /**
+ * Submits a SCSI request for execution.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this interface.
+ * @param pSCSIRequest Pointer to the SCSI request to execute.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSCSIRequestSend, (PPDMISCSICONNECTOR pInterface, PPDMSCSIREQUEST pSCSIRequest));
+
+} PDMISCSICONNECTOR;
+/** PDMISCSICONNECTOR interface ID. */
+#define PDMISCSICONNECTOR_IID "94465fbd-a2f2-447e-88c9-7366421bfbfe"
+
+
+/** Pointer to a display VBVA callbacks interface. */
+typedef struct PDMIDISPLAYVBVACALLBACKS *PPDMIDISPLAYVBVACALLBACKS;
+/**
+ * Display VBVA callbacks interface (up).
+ */
+typedef struct PDMIDISPLAYVBVACALLBACKS
+{
+
+ /**
+ * Informs guest about completion of processing the given Video HW Acceleration
+ * command, does not wait for the guest to process the command.
+ *
+ * @returns ???
+ * @param pInterface Pointer to this interface.
+ * @param pCmd The Video HW Acceleration Command that was
+ * completed.
+ * @todo r=bird: if async means asynchronous; then
+ * s/pfnVHWACommandCompleteAsynch/pfnVHWACommandCompleteAsync/;
+ * fi
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVHWACommandCompleteAsynch, (PPDMIDISPLAYVBVACALLBACKS pInterface,
+ PVBOXVHWACMD pCmd));
+
+ DECLR3CALLBACKMEMBER(int, pfnCrHgsmiCommandCompleteAsync, (PPDMIDISPLAYVBVACALLBACKS pInterface,
+ PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc));
+
+ DECLR3CALLBACKMEMBER(int, pfnCrHgsmiControlCompleteAsync, (PPDMIDISPLAYVBVACALLBACKS pInterface,
+ PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc));
+} PDMIDISPLAYVBVACALLBACKS;
+/** PDMIDISPLAYVBVACALLBACKS */
+#define PDMIDISPLAYVBVACALLBACKS_IID "b78b81d2-c821-4e66-96ff-dbafa76343a5"
+
+/** Pointer to a PCI raw connector interface. */
+typedef struct PDMIPCIRAWCONNECTOR *PPDMIPCIRAWCONNECTOR;
+/**
+ * PCI raw connector interface (up).
+ */
+typedef struct PDMIPCIRAWCONNECTOR
+{
+
+ /**
+ *
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDeviceConstructComplete, (PPDMIPCIRAWCONNECTOR pInterface, const char *pcszName,
+ uint32_t uHostPciAddress, uint32_t uGuestPciAddress,
+ int rc));
+
+} PDMIPCIRAWCONNECTOR;
+/** PDMIPCIRAWCONNECTOR interface ID. */
+#define PDMIPCIRAWCONNECTOR_IID "14aa9c6c-8869-4782-9dfc-910071a6aebf"
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/pdmins.h b/include/VBox/vmm/pdmins.h
new file mode 100644
index 00000000..2375f3c4
--- /dev/null
+++ b/include/VBox/vmm/pdmins.h
@@ -0,0 +1,70 @@
+/** @file
+ * PDM - Pluggable Device Manager, Common Instance Macros.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmins_h
+#define ___VBox_vmm_pdmins_h
+
+
+/** @defgroup grp_pdm_ins Common PDM Instance Macros
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/** @def PDMBOTHCBDECL
+ * Macro for declaring a callback which is static in HC and exported in GC.
+ */
+#if defined(IN_RC) || defined(IN_RING0)
+# ifdef __cplusplus
+# define PDMBOTHCBDECL(type) extern "C" DECLEXPORT(type)
+# else
+# define PDMBOTHCBDECL(type) DECLEXPORT(type)
+# endif
+#else
+# define PDMBOTHCBDECL(type) static type
+#endif
+
+/** @def PDMINS_2_DATA
+ * Converts a PDM Device, USB Device, or Driver instance pointer to a pointer to the instance data.
+ */
+#define PDMINS_2_DATA(pIns, type) ( (type)(void *)&(pIns)->achInstanceData[0] )
+
+/** @def PDMINS_2_DATA_RCPTR
+ * Converts a PDM Device, USB Device, or Driver instance pointer to a RC pointer to the instance data.
+ */
+#define PDMINS_2_DATA_RCPTR(pIns) ( (pIns)->pvInstanceDataRC )
+
+/** @def PDMINS_2_DATA_R3PTR
+ * Converts a PDM Device, USB Device, or Driver instance pointer to a HC pointer to the instance data.
+ */
+#define PDMINS_2_DATA_R3PTR(pIns) ( (pIns)->pvInstanceDataR3 )
+
+/** @def PDMINS_2_DATA_R0PTR
+ * Converts a PDM Device, USB Device, or Driver instance pointer to a R0 pointer to the instance data.
+ */
+#define PDMINS_2_DATA_R0PTR(pIns) ( (pIns)->pvInstanceDataR0 )
+
+/** @} */
+
+#endif
diff --git a/include/VBox/vmm/pdmnetifs.h b/include/VBox/vmm/pdmnetifs.h
new file mode 100644
index 00000000..e9280440
--- /dev/null
+++ b/include/VBox/vmm/pdmnetifs.h
@@ -0,0 +1,437 @@
+/** @file
+ * PDM - Pluggable Device Manager, Network Interfaces.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmnetifs_h
+#define ___VBox_vmm_pdmnetifs_h
+
+#include <VBox/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_ifs_net PDM Network Interfaces
+ * @ingroup grp_pdm_interfaces
+ * @{
+ */
+
+
+/**
+ * PDM scatter/gather buffer.
+ *
+ * @todo Promote this to VBox/types.h, VBox/vmm/pdmcommon.h or some such place.
+ */
+typedef struct PDMSCATTERGATHER
+{
+ /** Flags. */
+ size_t fFlags;
+ /** The number of bytes used.
+ * This is cleared on alloc and set by the user. */
+ size_t cbUsed;
+ /** The number of bytes available.
+ * This is set on alloc and not changed by the user. */
+ size_t cbAvailable;
+ /** Private data member for the allocator side. */
+ void *pvAllocator;
+ /** Private data member for the user side. */
+ void *pvUser;
+ /** The number of segments
+ * This is set on alloc and not changed by the user. */
+ size_t cSegs;
+ /** Variable sized array of segments. */
+ PDMDATASEG aSegs[1];
+} PDMSCATTERGATHER;
+/** Pointer to a PDM scatter/gather buffer. */
+typedef PDMSCATTERGATHER *PPDMSCATTERGATHER;
+/** Pointer to a PDM scatter/gather buffer pointer. */
+typedef PPDMSCATTERGATHER *PPPDMSCATTERGATHER;
+
+
+/** @name PDMSCATTERGATHER::fFlags
+ * @{ */
+/** Magic value. */
+#define PDMSCATTERGATHER_FLAGS_MAGIC UINT32_C(0xb1b10000)
+/** Magic mask. */
+#define PDMSCATTERGATHER_FLAGS_MAGIC_MASK UINT32_C(0xffff0000)
+/** Owned by owner number 1. */
+#define PDMSCATTERGATHER_FLAGS_OWNER_1 UINT32_C(0x00000001)
+/** Owned by owner number 2. */
+#define PDMSCATTERGATHER_FLAGS_OWNER_2 UINT32_C(0x00000002)
+/** Owned by owner number 3. */
+#define PDMSCATTERGATHER_FLAGS_OWNER_3 UINT32_C(0x00000002)
+/** Owner mask. */
+#define PDMSCATTERGATHER_FLAGS_OWNER_MASK UINT32_C(0x00000003)
+/** Mask of flags available to general use.
+ * The parties using the SG must all agree upon how to use these of course. */
+#define PDMSCATTERGATHER_FLAGS_AVL_MASK UINT32_C(0x0000f000)
+/** Flags reserved for future use, MBZ. */
+#define PDMSCATTERGATHER_FLAGS_RVD_MASK UINT32_C(0x00000ff8)
+/** @} */
+
+
+/**
+ * Sets the owner of a scatter/gather buffer.
+ *
+ * @param pSgBuf .
+ * @param uNewOwner The new owner.
+ */
+DECLINLINE(void) PDMScatterGatherSetOwner(PPDMSCATTERGATHER pSgBuf, uint32_t uNewOwner)
+{
+ pSgBuf->fFlags = (pSgBuf->fFlags & ~PDMSCATTERGATHER_FLAGS_OWNER_MASK) | uNewOwner;
+}
+
+
+
+/** Pointer to a network port interface */
+typedef struct PDMINETWORKDOWN *PPDMINETWORKDOWN;
+/**
+ * Network port interface (down).
+ * Pair with PDMINETWORKUP.
+ */
+typedef struct PDMINETWORKDOWN
+{
+ /**
+ * Wait until there is space for receiving data. We do not care how much space is available
+ * because pfnReceive() will re-check and notify the guest if necessary.
+ *
+ * This function must be called before the pfnRecieve() method is called.
+ *
+ * @returns VBox status code. VINF_SUCCESS means there is at least one receive descriptor available.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param cMillies Number of milliseconds to wait. 0 means return immediately.
+ *
+ * @thread Non-EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnWaitReceiveAvail,(PPDMINETWORKDOWN pInterface, RTMSINTERVAL cMillies));
+
+ /**
+ * Receive data from the network.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf The available data.
+ * @param cb Number of bytes available in the buffer.
+ *
+ * @thread Non-EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReceive,(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb));
+
+ /**
+ * Receive data with segmentation context from the network.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pvBuf The available data.
+ * @param cb Number of bytes available in the buffer.
+ * @param pGso Segmentation context.
+ *
+ * @thread Non-EMT.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReceiveGso,(PPDMINETWORKDOWN pInterface, const void *pvBuf, size_t cb, PCPDMNETWORKGSO pGso));
+
+ /**
+ * Do pending transmit work on the leaf driver's XMIT thread.
+ *
+ * When a PDMINETWORKUP::pfnBeginTransmit or PDMINETWORKUP::pfnAllocBuf call
+ * fails with VERR_TRY_AGAIN, the leaf drivers XMIT thread will offer to process
+ * the upstream device/driver when the the VERR_TRY_AGAIN condition has been
+ * removed. In some cases the VERR_TRY_AGAIN condition is simply being in an
+ * inconvenient context and the XMIT thread will start working ASAP.
+ *
+ * @param pInterface Pointer to this interface.
+ * @thread Non-EMT.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnXmitPending,(PPDMINETWORKDOWN pInterface));
+
+} PDMINETWORKDOWN;
+/** PDMINETWORKDOWN interface ID. */
+#define PDMINETWORKDOWN_IID "52b8cdbb-a087-493b-baa7-81ec3b803e06"
+
+
+/**
+ * Network link state.
+ */
+typedef enum PDMNETWORKLINKSTATE
+{
+ /** Invalid state. */
+ PDMNETWORKLINKSTATE_INVALID = 0,
+ /** The link is up. */
+ PDMNETWORKLINKSTATE_UP,
+ /** The link is down. */
+ PDMNETWORKLINKSTATE_DOWN,
+ /** The link is temporarily down while resuming. */
+ PDMNETWORKLINKSTATE_DOWN_RESUME
+} PDMNETWORKLINKSTATE;
+
+
+/** Pointer to a network connector interface */
+typedef R3PTRTYPE(struct PDMINETWORKUP *) PPDMINETWORKUPR3;
+/** Pointer to a network connector interface, ring-0 context. */
+typedef R0PTRTYPE(struct PDMINETWORKUPR0 *) PPDMINETWORKUPR0;
+/** Pointer to a network connector interface, raw-mode context. */
+typedef RCPTRTYPE(struct PDMINETWORKUPRC *) PPDMINETWORKUPRC;
+/** Pointer to a current context network connector interface. */
+typedef CTX_SUFF(PPDMINETWORKUP) PPDMINETWORKUP;
+
+/**
+ * Network connector interface (up).
+ * Pair with PDMINETWORKDOWN.
+ */
+typedef struct PDMINETWORKUP
+{
+ /**
+ * Begins a transmit session.
+ *
+ * The leaf driver guarantees that there are no concurrent sessions.
+ *
+ * @retval VINF_SUCCESS on success. Must always call
+ * PDMINETWORKUP::pfnEndXmit.
+ * @retval VERR_TRY_AGAIN if there is already an open transmit session or some
+ * important resource was unavailable (like buffer space). If it's a
+ * resources issue, the driver will signal its XMIT thread and have it
+ * work the device thru the PDMINETWORKDOWN::pfnNotifyBufAvailable
+ * callback method.
+ *
+ * @param pInterface Pointer to the interface structure containing the
+ * called function pointer.
+ * @param fOnWorkerThread Set if we're being called on a work thread. Clear
+ * if an EMT.
+ *
+ * @thread Any, but normally EMT or the XMIT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnBeginXmit,(PPDMINETWORKUP pInterface, bool fOnWorkerThread));
+
+ /**
+ * Get a send buffer for passing to pfnSendBuf.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_TRY_AGAIN if temporarily out of buffer space. After this
+ * happens, the driver will call PDMINETWORKDOWN::pfnNotifyBufAvailable
+ * when this is a buffer of the required size available.
+ * @retval VERR_NO_MEMORY if really out of buffer space.
+ * @retval VERR_NET_DOWN if we cannot send anything to the network at this
+ * point in time. Drop the frame with a xmit error. This is typically
+ * only seen when pausing the VM since the device keeps the link state,
+ * but there could of course be races.
+ *
+ * @param pInterface Pointer to the interface structure containing the
+ * called function pointer.
+ * @param cbMin The minimum buffer size.
+ * @param pGso Pointer to a GSO context (only reference while in
+ * this call). NULL indicates no segmentation
+ * offloading. PDMSCATTERGATHER::pvUser is used to
+ * indicate that a network SG uses GSO, usually by
+ * pointing to a copy of @a pGso.
+ * @param ppSgBuf Where to return the buffer. The buffer will be
+ * owned by the caller, designation owner number 1.
+ *
+ * @thread Any, but normally EMT or the XMIT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAllocBuf,(PPDMINETWORKUP pInterface, size_t cbMin, PCPDMNETWORKGSO pGso,
+ PPPDMSCATTERGATHER ppSgBuf));
+
+ /**
+ * Frees an unused buffer.
+ *
+ * @retval VINF_SUCCESS on success.
+ *
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pSgBuf A buffer from PDMINETWORKUP::pfnAllocBuf or
+ * PDMINETWORKDOWN::pfnNotifyBufAvailable. The buffer
+ * ownership shall be 1.
+ *
+ * @thread Any, but normally EMT or the XMIT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFreeBuf,(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf));
+
+ /**
+ * Send data to the network.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NET_DOWN if the NIC is not connected to a network. pSgBuf will
+ * be freed.
+ * @retval VERR_NET_NO_BUFFER_SPACE if we're out of resources. pSgBuf will be
+ * freed.
+ *
+ * @param pInterface Pointer to the interface structure containing the
+ * called function pointer.
+ * @param pSgBuf The buffer containing the data to send. The buffer
+ * ownership shall be 1. The buffer will always be
+ * consumed, regardless of the status code.
+ *
+ * @param fOnWorkerThread Set if we're being called on a work thread. Clear
+ * if an EMT.
+ *
+ * @thread Any, but normally EMT or the XMIT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSendBuf,(PPDMINETWORKUP pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread));
+
+ /**
+ * Ends a transmit session.
+ *
+ * Pairs with successful PDMINETWORKUP::pfnBeginXmit calls.
+ *
+ * @param pInterface Pointer to the interface structure containing the
+ * called function pointer.
+ *
+ * @thread Any, but normally EMT or the XMIT thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnEndXmit,(PPDMINETWORKUP pInterface));
+
+ /**
+ * Set promiscuous mode.
+ *
+ * This is called when the promiscuous mode is set. This means that there doesn't have
+ * to be a mode change when it's called.
+ *
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param fPromiscuous Set if the adaptor is now in promiscuous mode. Clear if it is not.
+ * @thread EMT ??
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSetPromiscuousMode,(PPDMINETWORKUP pInterface, bool fPromiscuous));
+
+ /**
+ * Notification on link status changes.
+ *
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param enmLinkState The new link state.
+ * @thread EMT ??
+ */
+ DECLR3CALLBACKMEMBER(void, pfnNotifyLinkChanged,(PPDMINETWORKUP pInterface, PDMNETWORKLINKSTATE enmLinkState));
+
+ /** @todo Add a callback that informs the driver chain about MAC address changes if we ever implement that. */
+
+} PDMINETWORKUP;
+
+/** Ring-0 edition of PDMINETWORKUP. */
+typedef struct PDMINETWORKUPR0
+{
+ /** @copydoc PDMINETWORKUP::pfnBeginXmit */
+ DECLR0CALLBACKMEMBER(int, pfnBeginXmit,(PPDMINETWORKUPR0 pInterface, bool fOnWorkerThread));
+ /** @copydoc PDMINETWORKUP::pfnAllocBuf */
+ DECLR0CALLBACKMEMBER(int, pfnAllocBuf,(PPDMINETWORKUPR0 pInterface, size_t cbMin, PCPDMNETWORKGSO pGso,
+ PPPDMSCATTERGATHER ppSgBuf));
+ /** @copydoc PDMINETWORKUP::pfnFreeBuf */
+ DECLR0CALLBACKMEMBER(int, pfnFreeBuf,(PPDMINETWORKUPR0 pInterface, PPDMSCATTERGATHER pSgBuf));
+ /** @copydoc PDMINETWORKUP::pfnSendBuf */
+ DECLR0CALLBACKMEMBER(int, pfnSendBuf,(PPDMINETWORKUPR0 pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread));
+ /** @copydoc PDMINETWORKUP::pfnEndBuf */
+ DECLR0CALLBACKMEMBER(void, pfnEndXmit,(PPDMINETWORKUPR0 pInterface));
+ /** @copydoc PDMINETWORKUP::pfnSetPromiscuousMode */
+ DECLR0CALLBACKMEMBER(void, pfnSetPromiscuousMode,(PPDMINETWORKUPR0 pInterface, bool fPromiscuous));
+} PDMINETWORKUPR0;
+
+/** Raw-mode context edition of PDMINETWORKUP. */
+typedef struct PDMINETWORKUPRC
+{
+ /** @copydoc PDMINETWORKUP::pfnBeginXmit */
+ DECLRCCALLBACKMEMBER(int, pfnBeginXmit,(PPDMINETWORKUPRC pInterface, bool fOnWorkerThread));
+ /** @copydoc PDMINETWORKUP::pfnAllocBuf */
+ DECLRCCALLBACKMEMBER(int, pfnAllocBuf,(PPDMINETWORKUPRC pInterface, size_t cbMin, PCPDMNETWORKGSO pGso,
+ PPPDMSCATTERGATHER ppSgBuf));
+ /** @copydoc PDMINETWORKUP::pfnFreeBuf */
+ DECLRCCALLBACKMEMBER(int, pfnFreeBuf,(PPDMINETWORKUPRC pInterface, PPDMSCATTERGATHER pSgBuf));
+ /** @copydoc PDMINETWORKUP::pfnSendBuf */
+ DECLRCCALLBACKMEMBER(int, pfnSendBuf,(PPDMINETWORKUPRC pInterface, PPDMSCATTERGATHER pSgBuf, bool fOnWorkerThread));
+ /** @copydoc PDMINETWORKUP::pfnEndBuf */
+ DECLRCCALLBACKMEMBER(void, pfnEndXmit,(PPDMINETWORKUPRC pInterface));
+ /** @copydoc PDMINETWORKUP::pfnSetPromiscuousMode */
+ DECLRCCALLBACKMEMBER(void, pfnSetPromiscuousMode,(PPDMINETWORKUPRC pInterface, bool fPromiscuous));
+} PDMINETWORKUPRC;
+
+/** PDMINETWORKUP interface ID. */
+#define PDMINETWORKUP_IID "67e7e7a8-2594-4649-a1e3-7cee680c6083"
+/** PDMINETWORKUP interface method names. */
+#define PDMINETWORKUP_SYM_LIST "BeginXmit;AllocBuf;FreeBuf;SendBuf;EndXmit;SetPromiscuousMode"
+
+
+/** Pointer to a network config port interface */
+typedef struct PDMINETWORKCONFIG *PPDMINETWORKCONFIG;
+/**
+ * Network config port interface (main).
+ * No interface pair.
+ */
+typedef struct PDMINETWORKCONFIG
+{
+ /**
+ * Gets the current Media Access Control (MAC) address.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param pMac Where to store the MAC address.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnGetMac,(PPDMINETWORKCONFIG pInterface, PRTMAC pMac));
+
+ /**
+ * Gets the new link state.
+ *
+ * @returns The current link state.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(PDMNETWORKLINKSTATE, pfnGetLinkState,(PPDMINETWORKCONFIG pInterface));
+
+ /**
+ * Sets the new link state.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the interface structure containing the called function pointer.
+ * @param enmState The new link state
+ * @thread EMT
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetLinkState,(PPDMINETWORKCONFIG pInterface, PDMNETWORKLINKSTATE enmState));
+
+} PDMINETWORKCONFIG;
+/** PDMINETWORKCONFIG interface ID. */
+#define PDMINETWORKCONFIG_IID "d6d909e8-716d-415d-b109-534e4478ff4e"
+
+
+/** Pointer to a NAT configuration port. */
+typedef struct PDMINETWORKNATCONFIG *PPDMINETWORKNATCONFIG;
+/**
+ * Network config port interface (main).
+ * No interface pair.
+ */
+typedef struct PDMINETWORKNATCONFIG
+{
+ /**
+ * Inform NAT about the adding/removing redirection rule
+ *
+ * @todo D O C U M E N T M E !
+ * @todo s/u16/u/g
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRedirectRuleCommand ,(PPDMINETWORKNATCONFIG pInterface, bool fRemove,
+ bool fUdp, const char *pHostIp, uint16_t u16HostPort,
+ const char *pGuestIp, uint16_t u16GuestPort));
+
+} PDMINETWORKNATCONFIG;
+/** PDMINETWORKNATCONFIG interface ID. */
+#define PDMINETWORKNATCONFIG_IID "0f001d62-4d2f-11df-93b3-2fd0b3a36a6b"
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmnetinline.h b/include/VBox/vmm/pdmnetinline.h
new file mode 100644
index 00000000..66c3078f
--- /dev/null
+++ b/include/VBox/vmm/pdmnetinline.h
@@ -0,0 +1,664 @@
+/** @file
+ * PDM - Networking Helpers, Inlined Code. (DEV,++)
+ *
+ * This is all inlined because it's too tedious to create 2-3 libraries to
+ * contain it all (same bad excuse as for intnetinline.h).
+ */
+
+/*
+ * Copyright (C) 2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 <VBox/log.h>
+#include <VBox/types.h>
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/net.h>
+#include <iprt/string.h>
+
+
+/**
+ * Checksum type.
+ */
+typedef enum PDMNETCSUMTYPE
+{
+ /** No checksum. */
+ PDMNETCSUMTYPE_NONE = 0,
+ /** Normal TCP checksum. */
+ PDMNETCSUMTYPE_COMPLETE,
+ /** Checksum on pseudo header (used with GSO). */
+ PDMNETCSUMTYPE_PSEUDO,
+ /** The usual 32-bit hack. */
+ PDMNETCSUMTYPE_32_BIT_HACK = 0x7fffffff
+} PDMNETCSUMTYPE;
+
+
+/**
+ * Validates the GSO context.
+ *
+ * @returns true if valid, false if not (not asserted or logged).
+ * @param pGso The GSO context.
+ * @param cbGsoMax The max size of the GSO context.
+ * @param cbFrame The max size of the GSO frame (use to validate
+ * the MSS).
+ */
+DECLINLINE(bool) PDMNetGsoIsValid(PCPDMNETWORKGSO pGso, size_t cbGsoMax, size_t cbFrame)
+{
+ PDMNETWORKGSOTYPE enmType;
+
+ if (RT_UNLIKELY(cbGsoMax < sizeof(*pGso)))
+ return false;
+
+ enmType = (PDMNETWORKGSOTYPE)pGso->u8Type;
+ if (RT_UNLIKELY( enmType <= PDMNETWORKGSOTYPE_INVALID || enmType >= PDMNETWORKGSOTYPE_END ))
+ return false;
+
+ /* all types requires both headers. */
+ if (RT_UNLIKELY( pGso->offHdr1 < sizeof(RTNETETHERHDR) ))
+ return false;
+ if (RT_UNLIKELY( pGso->offHdr2 <= pGso->offHdr1 ))
+ return false;
+ if (RT_UNLIKELY( pGso->cbHdrsTotal <= pGso->offHdr2 ))
+ return false;
+
+ /* min size of the 1st header(s). */
+ switch (enmType)
+ {
+ case PDMNETWORKGSOTYPE_IPV4_TCP:
+ case PDMNETWORKGSOTYPE_IPV4_UDP:
+ if (RT_UNLIKELY( (unsigned)pGso->offHdr2 - pGso->offHdr1 < RTNETIPV4_MIN_LEN ))
+ return false;
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_TCP:
+ case PDMNETWORKGSOTYPE_IPV6_UDP:
+ if (RT_UNLIKELY( (unsigned)pGso->offHdr2 - pGso->offHdr1 < RTNETIPV6_MIN_LEN ))
+ return false;
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP:
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP:
+ if (RT_UNLIKELY( (unsigned)pGso->offHdr2 - pGso->offHdr1 < RTNETIPV4_MIN_LEN + RTNETIPV6_MIN_LEN ))
+ return false;
+ break;
+ case PDMNETWORKGSOTYPE_INVALID:
+ case PDMNETWORKGSOTYPE_END:
+ break;
+ /* no default case! want gcc warnings. */
+ }
+
+ /* min size of the 2nd header. */
+ switch (enmType)
+ {
+ case PDMNETWORKGSOTYPE_IPV4_TCP:
+ case PDMNETWORKGSOTYPE_IPV6_TCP:
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP:
+ if (RT_UNLIKELY( (unsigned)pGso->cbHdrsTotal - pGso->offHdr2 < RTNETTCP_MIN_LEN ))
+ return false;
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_UDP:
+ case PDMNETWORKGSOTYPE_IPV6_UDP:
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP:
+ if (RT_UNLIKELY( (unsigned)pGso->cbHdrsTotal - pGso->offHdr2 < RTNETUDP_MIN_LEN ))
+ return false;
+ break;
+ case PDMNETWORKGSOTYPE_INVALID:
+ case PDMNETWORKGSOTYPE_END:
+ break;
+ /* no default case! want gcc warnings. */
+ }
+
+ /* There must be at more than one segment. */
+ if (RT_UNLIKELY( cbFrame <= pGso->cbHdrsTotal ))
+ return false;
+ if (RT_UNLIKELY( cbFrame - pGso->cbHdrsTotal < pGso->cbMaxSeg ))
+ return false;
+
+ return true;
+}
+
+
+/**
+ * Returns the length of header for a particular segment/fragment.
+ *
+ * We cannot simply treat UDP header as a part of payload because we do not
+ * want to modify the payload but still need to modify the checksum field in
+ * UDP header. So we want to include UDP header when calculating the length
+ * of headers in the first segment getting it copied to a temporary buffer
+ * along with other headers.
+ *
+ * @returns Length of headers (including UDP header for the first fragment).
+ * @param pGso The GSO context.
+ * @param iSeg The segment index.
+ */
+DECLINLINE(uint8_t) pdmNetSegHdrLen(PCPDMNETWORKGSO pGso, uint32_t iSeg)
+{
+ return iSeg ? pGso->cbHdrsSeg : pGso->cbHdrsTotal;
+}
+
+/**
+ * Returns the length of payload for a particular segment/fragment.
+ *
+ * The first segment does not contain UDP header. The size of UDP header is
+ * determined as the difference between the total headers size and the size
+ * used during segmentation.
+ *
+ * @returns Length of payload (including UDP header for the first fragment).
+ * @param pGso The GSO context.
+ * @param iSeg The segment that we're carving out (0-based).
+ * @param cSegs The number of segments in the GSO frame.
+ * @param cbFrame The size of the GSO frame.
+ */
+DECLINLINE(uint32_t) pdmNetSegPayloadLen(PCPDMNETWORKGSO pGso, uint32_t iSeg, uint32_t cSegs, uint32_t cbFrame)
+{
+ if (iSeg + 1 == cSegs)
+ return cbFrame - iSeg * pGso->cbMaxSeg - pdmNetSegHdrLen(pGso, iSeg);
+ else
+ return pGso->cbMaxSeg - (iSeg ? 0 : pGso->cbHdrsTotal - pGso->cbHdrsSeg);
+}
+
+/**
+ * Calculates the number of segments a GSO frame will be segmented into.
+ *
+ * @returns Segment count.
+ * @param pGso The GSO context.
+ * @param cbFrame The GSO frame size (header proto + payload).
+ */
+DECLINLINE(uint32_t) PDMNetGsoCalcSegmentCount(PCPDMNETWORKGSO pGso, size_t cbFrame)
+{
+ size_t cbPayload;
+ Assert(PDMNetGsoIsValid(pGso, sizeof(*pGso), cbFrame));
+ cbPayload = cbFrame - pGso->cbHdrsSeg;
+ return (uint32_t)((cbPayload + pGso->cbMaxSeg - 1) / pGso->cbMaxSeg);
+}
+
+
+/**
+ * Used to find the IPv6 header when handling 4to6 tunneling.
+ *
+ * @returns Offset of the IPv6 header.
+ * @param pbSegHdrs The headers / frame start.
+ * @param offIpHdr The offset of the IPv4 header.
+ */
+DECLINLINE(uint8_t) pgmNetGsoCalcIpv6Offset(uint8_t *pbSegHdrs, uint8_t offIPv4Hdr)
+{
+ PCRTNETIPV4 pIPv4Hdr = (PCRTNETIPV4)&pbSegHdrs[offIPv4Hdr];
+ return offIPv4Hdr + pIPv4Hdr->ip_hl * 4;
+}
+
+
+/**
+ * Update an UDP header after carving out a segment
+ *
+ * @param u32PseudoSum The pseudo checksum.
+ * @param pbSegHdrs Pointer to the header bytes / frame start.
+ * @param offUdpHdr The offset into @a pbSegHdrs of the UDP header.
+ * @param pbPayload Pointer to the payload bytes.
+ * @param cbPayload The amount of payload.
+ * @param cbHdrs The size of all the headers.
+ * @param enmCsumType Whether to checksum the payload, the pseudo
+ * header or nothing.
+ * @internal
+ */
+DECLINLINE(void) pdmNetGsoUpdateUdpHdr(uint32_t u32PseudoSum, uint8_t *pbSegHdrs, uint8_t offUdpHdr,
+ uint8_t const *pbPayload, uint32_t cbPayload, uint8_t cbHdrs,
+ PDMNETCSUMTYPE enmCsumType)
+{
+ PRTNETUDP pUdpHdr = (PRTNETUDP)&pbSegHdrs[offUdpHdr];
+ pUdpHdr->uh_ulen = RT_H2N_U16(cbPayload + cbHdrs - offUdpHdr);
+ switch (enmCsumType)
+ {
+ case PDMNETCSUMTYPE_NONE:
+ pUdpHdr->uh_sum = 0;
+ break;
+ case PDMNETCSUMTYPE_COMPLETE:
+ pUdpHdr->uh_sum = RTNetUDPChecksum(u32PseudoSum, pUdpHdr);
+ break;
+ case PDMNETCSUMTYPE_PSEUDO:
+ pUdpHdr->uh_sum = ~RTNetIPv4FinalizeChecksum(u32PseudoSum);
+ break;
+ default:
+ NOREF(pbPayload);
+ AssertFailed();
+ break;
+ }
+}
+
+
+/**
+ * Update an UDP header after carving out an IP fragment
+ *
+ * @param u32PseudoSum The pseudo checksum.
+ * @param pbSegHdrs Pointer to the header bytes copy
+ * @param pbFrame Pointer to the frame start.
+ * @param offUdpHdr The offset into @a pbSegHdrs of the UDP header.
+ *
+ * @internal
+ */
+DECLINLINE(void) pdmNetGsoUpdateUdpHdrUfo(uint32_t u32PseudoSum, uint8_t *pbSegHdrs, const uint8_t *pbFrame, uint8_t offUdpHdr)
+{
+ PCRTNETUDP pcUdpHdrOrig = (PCRTNETUDP)&pbFrame[offUdpHdr];
+ PRTNETUDP pUdpHdr = (PRTNETUDP)&pbSegHdrs[offUdpHdr];
+ pUdpHdr->uh_sum = RTNetUDPChecksum(u32PseudoSum, pcUdpHdrOrig);
+}
+
+
+/**
+ * Update a TCP header after carving out a segment.
+ *
+ * @param u32PseudoSum The pseudo checksum.
+ * @param pbSegHdrs Pointer to the header bytes / frame start.
+ * @param offTcpHdr The offset into @a pbSegHdrs of the TCP header.
+ * @param pbPayload Pointer to the payload bytes.
+ * @param cbPayload The amount of payload.
+ * @param offPayload The offset into the payload that we're splitting
+ * up. We're ASSUMING that the payload follows
+ * immediately after the TCP header w/ options.
+ * @param cbHdrs The size of all the headers.
+ * @param fLastSeg Set if this is the last segment.
+ * @param enmCsumType Whether to checksum the payload, the pseudo
+ * header or nothing.
+ * @internal
+ */
+DECLINLINE(void) pdmNetGsoUpdateTcpHdr(uint32_t u32PseudoSum, uint8_t *pbSegHdrs, uint8_t offTcpHdr,
+ uint8_t const *pbPayload, uint32_t cbPayload, uint32_t offPayload, uint8_t cbHdrs,
+ bool fLastSeg, PDMNETCSUMTYPE enmCsumType)
+{
+ PRTNETTCP pTcpHdr = (PRTNETTCP)&pbSegHdrs[offTcpHdr];
+ pTcpHdr->th_seq = RT_H2N_U32(RT_N2H_U32(pTcpHdr->th_seq) + offPayload);
+ if (!fLastSeg)
+ pTcpHdr->th_flags &= ~(RTNETTCP_F_FIN | RTNETTCP_F_PSH);
+ switch (enmCsumType)
+ {
+ case PDMNETCSUMTYPE_NONE:
+ pTcpHdr->th_sum = 0;
+ break;
+ case PDMNETCSUMTYPE_COMPLETE:
+ pTcpHdr->th_sum = RTNetTCPChecksum(u32PseudoSum, pTcpHdr, pbPayload, cbPayload);
+ break;
+ case PDMNETCSUMTYPE_PSEUDO:
+ pTcpHdr->th_sum = ~RTNetIPv4FinalizeChecksum(u32PseudoSum);
+ break;
+ default:
+ NOREF(cbHdrs);
+ AssertFailed();
+ break;
+ }
+}
+
+
+/**
+ * Updates a IPv6 header after carving out a segment.
+ *
+ * @returns 32-bit intermediary checksum value for the pseudo header.
+ * @param pbSegHdrs Pointer to the header bytes.
+ * @param offIpHdr The offset into @a pbSegHdrs of the IP header.
+ * @param cbSegPayload The amount of segmented payload. Not to be
+ * confused with the IP payload.
+ * @param cbHdrs The size of all the headers.
+ * @param offPktHdr Offset of the protocol packet header. For the
+ * pseudo header checksum calulation.
+ * @param bProtocol The protocol type. For the pseudo header.
+ * @internal
+ */
+DECLINLINE(uint32_t) pdmNetGsoUpdateIPv6Hdr(uint8_t *pbSegHdrs, uint8_t offIpHdr, uint32_t cbSegPayload, uint8_t cbHdrs,
+ uint8_t offPktHdr, uint8_t bProtocol)
+{
+ PRTNETIPV6 pIpHdr = (PRTNETIPV6)&pbSegHdrs[offIpHdr];
+ uint16_t cbPayload = (uint16_t)(cbHdrs - (offIpHdr + sizeof(RTNETIPV6)) + cbSegPayload);
+ pIpHdr->ip6_plen = RT_H2N_U16(cbPayload);
+ return RTNetIPv6PseudoChecksumEx(pIpHdr, bProtocol, (uint16_t)(cbHdrs - offPktHdr + cbSegPayload));
+}
+
+
+/**
+ * Updates a IPv4 header after carving out a segment.
+ *
+ * @returns 32-bit intermediary checksum value for the pseudo header.
+ * @param pbSegHdrs Pointer to the header bytes.
+ * @param offIpHdr The offset into @a pbSegHdrs of the IP header.
+ * @param cbSegPayload The amount of segmented payload.
+ * @param iSeg The segment index.
+ * @param cbHdrs The size of all the headers.
+ * @internal
+ */
+DECLINLINE(uint32_t) pdmNetGsoUpdateIPv4Hdr(uint8_t *pbSegHdrs, uint8_t offIpHdr, uint32_t cbSegPayload,
+ uint32_t iSeg, uint8_t cbHdrs)
+{
+ PRTNETIPV4 pIpHdr = (PRTNETIPV4)&pbSegHdrs[offIpHdr];
+ pIpHdr->ip_len = RT_H2N_U16(cbHdrs - offIpHdr + cbSegPayload);
+ pIpHdr->ip_id = RT_H2N_U16(RT_N2H_U16(pIpHdr->ip_id) + iSeg);
+ pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr);
+ return RTNetIPv4PseudoChecksum(pIpHdr);
+}
+
+
+/**
+ * Updates a IPv4 header after carving out an IP fragment.
+ *
+ * @param pbSegHdrs Pointer to the header bytes.
+ * @param offIpHdr The offset into @a pbSegHdrs of the IP header.
+ * @param cbSegPayload The amount of segmented payload.
+ * @param offFragment The offset of this fragment for reassembly.
+ * @param iSeg The segment index.
+ * @param cbHdrs The size of all the headers.
+ * @param fLastFragment True if this is the last fragment of datagram.
+ * @internal
+ */
+DECLINLINE(void) pdmNetGsoUpdateIPv4HdrUfo(uint8_t *pbSegHdrs, uint8_t offIpHdr, uint32_t cbSegPayload,
+ uint32_t offFragment, uint8_t cbHdrs, bool fLastFragment)
+{
+ PRTNETIPV4 pIpHdr = (PRTNETIPV4)&pbSegHdrs[offIpHdr];
+ pIpHdr->ip_len = RT_H2N_U16(cbHdrs - offIpHdr + cbSegPayload);
+ pIpHdr->ip_off = RT_H2N_U16((offFragment / 8) | (fLastFragment ? 0 : RTNETIPV4_FLAGS_MF));
+ pIpHdr->ip_sum = RTNetIPv4HdrChecksum(pIpHdr);
+}
+
+
+/**
+ * Carves out the specified segment in a destructive manner.
+ *
+ * This is for sequentially carving out segments and pushing them along for
+ * processing or sending. To avoid allocating a temporary buffer for
+ * constructing the segment in, we trash the previous frame by putting the
+ * header at the end of it.
+ *
+ * @returns Pointer to the segment frame that we've carved out.
+ * @param pGso The GSO context data.
+ * @param pbFrame Pointer to the GSO frame.
+ * @param cbFrame The size of the GSO frame.
+ * @param pbHdrScatch Pointer to a pGso->cbHdrs sized area where we
+ * can save the original header prototypes on the
+ * first call (@a iSeg is 0) and retrieve it on
+ * susequent calls. (Just use a 256 bytes
+ * buffer to make life easy.)
+ * @param iSeg The segment that we're carving out (0-based).
+ * @param cSegs The number of segments in the GSO frame. Use
+ * PDMNetGsoCalcSegmentCount to find this.
+ * @param pcbSegFrame Where to return the size of the returned segment
+ * frame.
+ */
+DECLINLINE(void *) PDMNetGsoCarveSegmentQD(PCPDMNETWORKGSO pGso, uint8_t *pbFrame, size_t cbFrame, uint8_t *pbHdrScatch,
+ uint32_t iSeg, uint32_t cSegs, uint32_t *pcbSegFrame)
+{
+ /*
+ * Figure out where the payload is and where the header starts before we
+ * do the protocol specific carving.
+ */
+ uint8_t * const pbSegHdrs = pbFrame + pGso->cbMaxSeg * iSeg;
+ uint8_t * const pbSegPayload = pbSegHdrs + pGso->cbHdrsSeg;
+ uint32_t const cbSegPayload = pdmNetSegPayloadLen(pGso, iSeg, cSegs, (uint32_t)cbFrame);
+ uint32_t const cbSegFrame = cbSegPayload + pGso->cbHdrsSeg;
+
+ /*
+ * Check assumptions (doing it after declaring the variables because of C).
+ */
+ Assert(iSeg < cSegs);
+ Assert(cSegs == PDMNetGsoCalcSegmentCount(pGso, cbFrame));
+ Assert(PDMNetGsoIsValid(pGso, sizeof(*pGso), cbFrame));
+
+ /*
+ * Copy the header and do the protocol specific massaging of it.
+ */
+ if (iSeg != 0)
+ memcpy(pbSegHdrs, pbHdrScatch, pGso->cbHdrsSeg);
+ else
+ memcpy(pbHdrScatch, pbSegHdrs, pGso->cbHdrsSeg); /* There is no need to save UDP header */
+
+ switch ((PDMNETWORKGSOTYPE)pGso->u8Type)
+ {
+ case PDMNETWORKGSOTYPE_IPV4_TCP:
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrsSeg),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ pGso->cbHdrsSeg, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_UDP:
+ if (iSeg == 0)
+ pdmNetGsoUpdateUdpHdrUfo(RTNetIPv4PseudoChecksum((PRTNETIPV4)&pbFrame[pGso->offHdr1]),
+ pbSegHdrs, pbFrame, pGso->offHdr2);
+ pdmNetGsoUpdateIPv4HdrUfo(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ pdmNetSegHdrLen(pGso, iSeg), iSeg + 1 == cSegs);
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_TCP:
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrsSeg,
+ pGso->offHdr2, RTNETIPV4_PROT_TCP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ pGso->cbHdrsSeg, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_UDP:
+ pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, pGso->cbHdrsSeg,
+ pGso->offHdr2, RTNETIPV4_PROT_UDP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrsSeg, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP:
+ pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrsSeg);
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1),
+ cbSegPayload, pGso->cbHdrsSeg, pGso->offHdr2, RTNETIPV4_PROT_TCP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ pGso->cbHdrsSeg, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP:
+ pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, pGso->cbHdrsSeg);
+ pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1),
+ cbSegPayload, pGso->cbHdrsSeg, pGso->offHdr2, RTNETIPV4_PROT_UDP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, pGso->cbHdrsSeg, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_INVALID:
+ case PDMNETWORKGSOTYPE_END:
+ /* no default! wnat gcc warnings. */
+ break;
+ }
+
+ *pcbSegFrame = cbSegFrame;
+ return pbSegHdrs;
+}
+
+
+/**
+ * Carves out the specified segment in a non-destructive manner.
+ *
+ * The segment headers and segment payload is kept separate here. The GSO frame
+ * is still expected to be one linear chunk of data, but we don't modify any of
+ * it.
+ *
+ * @returns The offset into the GSO frame of the payload.
+ * @param pGso The GSO context data.
+ * @param pbFrame Pointer to the GSO frame. Used for retrieving
+ * the header prototype and for checksumming the
+ * payload. The buffer is not modified.
+ * @param cbFrame The size of the GSO frame.
+ * @param iSeg The segment that we're carving out (0-based).
+ * @param cSegs The number of segments in the GSO frame. Use
+ * PDMNetGsoCalcSegmentCount to find this.
+ * @param pbSegHdrs Where to return the headers for the segment
+ * that's been carved out. The buffer must be at
+ * least pGso->cbHdrs in size, using a 256 byte
+ * buffer is a recommended simplification.
+ * @param pcbSegHdrs Where to return the size of the returned
+ * segment headers.
+ * @param pcbSegPayload Where to return the size of the returned
+ * segment payload.
+ */
+DECLINLINE(uint32_t) PDMNetGsoCarveSegment(PCPDMNETWORKGSO pGso, const uint8_t *pbFrame, size_t cbFrame,
+ uint32_t iSeg, uint32_t cSegs, uint8_t *pbSegHdrs,
+ uint32_t *pcbSegHdrs, uint32_t *pcbSegPayload)
+{
+ /*
+ * Figure out where the payload is and where the header starts before we
+ * do the protocol specific carving.
+ */
+ uint32_t const cbSegHdrs = pdmNetSegHdrLen(pGso, iSeg);
+ uint8_t const * const pbSegPayload = pbFrame + cbSegHdrs + iSeg * pGso->cbMaxSeg;
+ uint32_t const cbSegPayload = pdmNetSegPayloadLen(pGso, iSeg, cSegs, (uint32_t)cbFrame);
+
+ /*
+ * Check assumptions (doing it after declaring the variables because of C).
+ */
+ Assert(iSeg < cSegs);
+ Assert(cSegs == PDMNetGsoCalcSegmentCount(pGso, cbFrame));
+ Assert(PDMNetGsoIsValid(pGso, sizeof(*pGso), cbFrame));
+
+ /*
+ * Copy the header and do the protocol specific massaging of it.
+ */
+ memcpy(pbSegHdrs, pbFrame, pGso->cbHdrsTotal); /* include UDP header */
+
+ switch ((PDMNETWORKGSOTYPE)pGso->u8Type)
+ {
+ case PDMNETWORKGSOTYPE_IPV4_TCP:
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, cbSegHdrs),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ cbSegHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_UDP:
+ if (iSeg == 0)
+ pdmNetGsoUpdateUdpHdrUfo(RTNetIPv4PseudoChecksum((PRTNETIPV4)&pbFrame[pGso->offHdr1]),
+ pbSegHdrs, pbFrame, pGso->offHdr2);
+ pdmNetGsoUpdateIPv4HdrUfo(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ cbSegHdrs, iSeg + 1 == cSegs);
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_TCP:
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, cbSegHdrs,
+ pGso->offHdr2, RTNETIPV4_PROT_TCP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ cbSegHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_UDP:
+ pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, cbSegHdrs,
+ pGso->offHdr2, RTNETIPV4_PROT_UDP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, cbSegHdrs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP:
+ pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, cbSegHdrs);
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1),
+ cbSegPayload, cbSegHdrs, pGso->offHdr2, RTNETIPV4_PROT_TCP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, iSeg * pGso->cbMaxSeg,
+ cbSegHdrs, iSeg + 1 == cSegs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP:
+ pdmNetGsoUpdateIPv4Hdr(pbSegHdrs, pGso->offHdr1, cbSegPayload, iSeg, cbSegHdrs);
+ pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbSegHdrs, pgmNetGsoCalcIpv6Offset(pbSegHdrs, pGso->offHdr1),
+ cbSegPayload, cbSegHdrs, pGso->offHdr2, RTNETIPV4_PROT_UDP),
+ pbSegHdrs, pGso->offHdr2, pbSegPayload, cbSegPayload, cbSegHdrs, PDMNETCSUMTYPE_COMPLETE);
+ break;
+ case PDMNETWORKGSOTYPE_INVALID:
+ case PDMNETWORKGSOTYPE_END:
+ /* no default! wnat gcc warnings. */
+ break;
+ }
+
+ *pcbSegHdrs = cbSegHdrs;
+ *pcbSegPayload = cbSegPayload;
+ return cbSegHdrs + iSeg * pGso->cbMaxSeg;
+}
+
+
+/**
+ * Prepares the GSO frame for direct use without any segmenting.
+ *
+ * @param pGso The GSO context.
+ * @param pvFrame The frame to prepare.
+ * @param cbFrame The frame size.
+ * @param enmCsumType Whether to checksum the payload, the pseudo
+ * header or nothing.
+ */
+DECLINLINE(void) PDMNetGsoPrepForDirectUse(PCPDMNETWORKGSO pGso, void *pvFrame, size_t cbFrame, PDMNETCSUMTYPE enmCsumType)
+{
+ /*
+ * Figure out where the payload is and where the header starts before we
+ * do the protocol bits.
+ */
+ uint8_t * const pbHdrs = (uint8_t *)pvFrame;
+ uint8_t * const pbPayload = pbHdrs + pGso->cbHdrsTotal;
+ uint32_t const cbFrame32 = (uint32_t)cbFrame;
+ uint32_t const cbPayload = cbFrame32 - pGso->cbHdrsTotal;
+
+ /*
+ * Check assumptions (doing it after declaring the variables because of C).
+ */
+ Assert(PDMNetGsoIsValid(pGso, sizeof(*pGso), cbFrame));
+
+ /*
+ * Get down to busienss.
+ */
+ switch ((PDMNETWORKGSOTYPE)pGso->u8Type)
+ {
+ case PDMNETWORKGSOTYPE_IPV4_TCP:
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbFrame32 - pGso->cbHdrsTotal, 0, pGso->cbHdrsTotal),
+ pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrsTotal, true, enmCsumType);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_UDP:
+ pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbFrame32 - pGso->cbHdrsTotal, 0, pGso->cbHdrsTotal),
+ pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrsTotal, enmCsumType);
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_TCP:
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pGso->offHdr1, cbPayload, pGso->cbHdrsTotal,
+ pGso->offHdr2, RTNETIPV4_PROT_TCP),
+ pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrsTotal, true, enmCsumType);
+ break;
+ case PDMNETWORKGSOTYPE_IPV6_UDP:
+ pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pGso->offHdr1, cbPayload, pGso->cbHdrsTotal,
+ pGso->offHdr2, RTNETIPV4_PROT_UDP),
+ pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrsTotal, enmCsumType);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP:
+ pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbPayload, 0, pGso->cbHdrsTotal);
+ pdmNetGsoUpdateTcpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pgmNetGsoCalcIpv6Offset(pbHdrs, pGso->offHdr1),
+ cbPayload, pGso->cbHdrsTotal, pGso->offHdr2, RTNETIPV4_PROT_TCP),
+ pbHdrs, pGso->offHdr2, pbPayload, cbPayload, 0, pGso->cbHdrsTotal, true, enmCsumType);
+ break;
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP:
+ pdmNetGsoUpdateIPv4Hdr(pbHdrs, pGso->offHdr1, cbPayload, 0, pGso->cbHdrsTotal);
+ pdmNetGsoUpdateUdpHdr(pdmNetGsoUpdateIPv6Hdr(pbHdrs, pgmNetGsoCalcIpv6Offset(pbHdrs, pGso->offHdr1),
+ cbPayload, pGso->cbHdrsTotal, pGso->offHdr2, RTNETIPV4_PROT_UDP),
+ pbHdrs, pGso->offHdr2, pbPayload, cbPayload, pGso->cbHdrsTotal, enmCsumType);
+ break;
+ case PDMNETWORKGSOTYPE_INVALID:
+ case PDMNETWORKGSOTYPE_END:
+ /* no default! wnat gcc warnings. */
+ break;
+ }
+}
+
+
+/**
+ * Gets the GSO type name string.
+ *
+ * @returns Pointer to read only name string.
+ * @param enmType The type.
+ */
+DECLINLINE(const char *) PDMNetGsoTypeName(PDMNETWORKGSOTYPE enmType)
+{
+ switch (enmType)
+ {
+ case PDMNETWORKGSOTYPE_IPV4_TCP: return "TCPv4";
+ case PDMNETWORKGSOTYPE_IPV6_TCP: return "TCPv6";
+ case PDMNETWORKGSOTYPE_IPV4_UDP: return "UDPv4";
+ case PDMNETWORKGSOTYPE_IPV6_UDP: return "UDPv6";
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_TCP: return "4to6TCP";
+ case PDMNETWORKGSOTYPE_IPV4_IPV6_UDP: return "4to6UDP";
+ case PDMNETWORKGSOTYPE_INVALID: return "invalid";
+ case PDMNETWORKGSOTYPE_END: return "end";
+ }
+ return "bad-gso-type";
+}
+
diff --git a/include/VBox/vmm/pdmnetshaper.h b/include/VBox/vmm/pdmnetshaper.h
new file mode 100644
index 00000000..b2aa5bab
--- /dev/null
+++ b/include/VBox/vmm/pdmnetshaper.h
@@ -0,0 +1,120 @@
+/** @file
+ * PDM - Pluggable Device Manager, Network Shaper.
+ */
+
+/*
+ * Copyright (C) 2011-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 ___VBox_vmm_pdmnetshaper_h
+#define ___VBox_vmm_pdmnetshaper_h
+
+#include <VBox/types.h>
+#include <VBox/err.h>
+#include <VBox/vmm/pdmnetifs.h>
+#include <iprt/assert.h>
+#include <iprt/sg.h>
+
+
+#define PDM_NETSHAPER_MIN_BUCKET_SIZE 65536 /* bytes */
+#define PDM_NETSHAPER_MAX_LATENCY 100 /* milliseconds */
+
+RT_C_DECLS_BEGIN
+
+typedef struct PDMNSFILTER
+{
+ /** [R3] Pointer to the next group in the list. */
+ struct PDMNSFILTER *pNext;
+ /** [R3] Pointer to the bandwidth group. */
+ struct PDMNSBWGROUP *pBwGroupR3;
+ /** [R0] Pointer to the bandwidth group. */
+ R0PTRTYPE(struct PDMNSBWGROUP *) pBwGroupR0;
+ /** Becomes true when filter fails to obtain bandwidth. */
+ bool fChoked;
+ /** [R3] The driver this filter is aggregated into. */
+ PPDMINETWORKDOWN pIDrvNet;
+} PDMNSFILTER;
+
+/** @defgroup grp_pdm_net_shaper The PDM Network Shaper API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/** Pointer to a PDM filter handle. */
+typedef struct PDMNSFILTER *PPDMNSFILTER;
+/** Pointer to a network shaper. */
+typedef struct PDMNETSHAPER *PPDMNETSHAPER;
+
+
+/**
+ * Obtain bandwidth in a bandwidth group (R0 version).
+ *
+ * @returns VBox status code.
+ * @param pFilter Pointer to the filter that allocates bandwidth.
+ * @param cbTransfer Number of bytes to allocate.
+ */
+VMMR0DECL(bool) PDMR0NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer);
+
+/**
+ * Obtain bandwidth in a bandwidth group.
+ *
+ * @returns VBox status code.
+ * @param pFilter Pointer to the filter that allocates bandwidth.
+ * @param cbTransfer Number of bytes to allocate.
+ */
+VMMR3DECL(bool) PDMR3NsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer);
+
+/**
+ * Attach network filter driver from bandwidth group.
+ *
+ * @returns VBox status code.
+ * @param pVM Handle of VM.
+ * @param pDrvIns The driver instance.
+ * @param pcszBwGroup Name of the bandwidth group to attach to.
+ * @param pFilter Pointer to the filter we attach.
+ */
+VMMR3DECL(int) PDMR3NsAttach(PVM pVM, PPDMDRVINS pDrvIns, const char *pcszBwGroup, PPDMNSFILTER pFilter);
+
+/**
+ * Detach network filter driver from bandwidth group.
+ *
+ * @returns VBox status code.
+ * @param pVM Handle of VM.
+ * @param pDrvIns The driver instance.
+ * @param pFilter Pointer to the filter we detach.
+ */
+VMMR3DECL(int) PDMR3NsDetach(PVM pVM, PPDMDRVINS pDrvIns, PPDMNSFILTER pFilter);
+
+/**
+ * Adjusts the maximum rate for the bandwidth group.
+ *
+ * @returns VBox status code.
+ * @param pVM Handle of VM.
+ * @param pcszBwGroup Name of the bandwidth group to attach to.
+ * @param cbTransferPerSecMax Maximum number of bytes per second to be transmitted.
+ */
+VMMR3DECL(int) PDMR3NsBwGroupSetLimit(PVM pVM, const char *pcszBwGroup, uint64_t cbTransferPerSecMax);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmnetshaperint.h b/include/VBox/vmm/pdmnetshaperint.h
new file mode 100644
index 00000000..3bbfcda7
--- /dev/null
+++ b/include/VBox/vmm/pdmnetshaperint.h
@@ -0,0 +1,94 @@
+/* $Id: pdmnetshaperint.h $ */
+/** @file
+ * PDM Network Shaper - Internal data structures and functions common for both
+ * R0 and R3 parts.
+ */
+
+/*
+ * Copyright (C) 2011-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.
+ */
+
+/**
+ * Bandwidth group instance data
+ */
+typedef struct PDMNSBWGROUP
+{
+ /** Pointer to the next group in the list. */
+ struct PDMNSBWGROUP *pNext;
+ /** Pointer to the shared UVM structure. */
+ struct PDMNETSHAPER *pShaper;
+ /** Critical section protecting all members below. */
+ PDMCRITSECT cs;
+ /** Pointer to the first filter attached to this group. */
+ struct PDMNSFILTER *pFiltersHead;
+ /** Bandwidth group name. */
+ char *pszName;
+ /** Maximum number of bytes filters are allowed to transfer. */
+ volatile uint64_t cbTransferPerSecMax;
+ /** Number of bytes we are allowed to transfer in one burst. */
+ volatile uint32_t cbBucketSize;
+ /** Number of bytes we were allowed to transfer at the last update. */
+ volatile uint32_t cbTokensLast;
+ /** Timestamp of the last update */
+ volatile uint64_t tsUpdatedLast;
+ /** Reference counter - How many filters are associated with this group. */
+ volatile uint32_t cRefs;
+} PDMNSBWGROUP;
+/** Pointer to a bandwidth group. */
+typedef PDMNSBWGROUP *PPDMNSBWGROUP;
+
+DECLINLINE(bool) pdmNsAllocateBandwidth(PPDMNSFILTER pFilter, size_t cbTransfer)
+{
+ AssertPtrReturn(pFilter, true);
+ if (!VALID_PTR(pFilter->CTX_SUFF(pBwGroup)))
+ return true;
+
+ PPDMNSBWGROUP pBwGroup = ASMAtomicReadPtrT(&pFilter->CTX_SUFF(pBwGroup), PPDMNSBWGROUP);
+ int rc = PDMCritSectEnter(&pBwGroup->cs, VERR_SEM_BUSY); AssertRC(rc);
+ if (RT_UNLIKELY(rc == VERR_SEM_BUSY))
+ return true;
+ bool fAllowed = true;
+ if (pBwGroup->cbTransferPerSecMax)
+ {
+ /* Re-fill the bucket first */
+ uint64_t tsNow = RTTimeSystemNanoTS();
+ uint32_t uTokensAdded = (tsNow - pBwGroup->tsUpdatedLast)*pBwGroup->cbTransferPerSecMax/(1000*1000*1000);
+ uint32_t uTokens = RT_MIN(pBwGroup->cbBucketSize, uTokensAdded + pBwGroup->cbTokensLast);
+
+ if (cbTransfer > uTokens)
+ {
+ fAllowed = false;
+ ASMAtomicWriteBool(&pFilter->fChoked, true);
+ }
+ else
+ {
+ pBwGroup->tsUpdatedLast = tsNow;
+ pBwGroup->cbTokensLast = uTokens - (uint32_t)cbTransfer;
+ }
+ Log2((LOG_FN_FMT "BwGroup=%#p{%s} cbTransfer=%u uTokens=%u uTokensAdded=%u fAllowed=%RTbool\n",
+ __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, cbTransfer, uTokens, uTokensAdded, fAllowed));
+ }
+ else
+ Log2((LOG_FN_FMT "BwGroup=%#p{%s} disabled fAllowed=%RTbool\n",
+ __PRETTY_FUNCTION__, pBwGroup, pBwGroup->pszName, fAllowed));
+
+ rc = PDMCritSectLeave(&pBwGroup->cs); AssertRC(rc);
+ return fAllowed;
+}
diff --git a/include/VBox/vmm/pdmnvram.h b/include/VBox/vmm/pdmnvram.h
new file mode 100644
index 00000000..10c1abc4
--- /dev/null
+++ b/include/VBox/vmm/pdmnvram.h
@@ -0,0 +1,70 @@
+/** @file
+ * PDM - Pluggable Device Manager, EFI NVRAM storage back-end.
+ */
+
+/*
+ * 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 ___VBox_vmm_pdmnvram_h_
+#define ___VBox_vmm_pdmnvram_h_
+
+#include <VBox/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_ifs_nvram NVRAM Interface
+ * @ingroup grp_pdm_interfaces
+ * @{
+ */
+
+typedef struct PDMINVRAM *PPDMINVRAM;
+
+typedef struct PDMINVRAM
+{
+ /**
+ * This method flushes all values in the storage.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnFlushNvramStorage, (PPDMINVRAM pInterface));
+
+ /**
+ * This method store NVRAM variable to storage
+ */
+ DECLR3CALLBACKMEMBER(int, pfnStoreNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, const char *pcszVariableName, size_t cbVariableName, uint8_t *pu8Value, size_t cbValue));
+
+ /**
+ * This method load NVRAM variable to storage
+ */
+ DECLR3CALLBACKMEMBER(int, pfnLoadNvramValue, (PPDMINVRAM pInterface, int idxVariable, RTUUID *pVendorUuid, char *pcszVariableName, size_t *pcbVariableName, uint8_t *pu8Value, size_t *pcbValue));
+
+} PDMINVRAM;
+
+
+#define PDMINVRAM_IID "11226408-CB4C-4369-9218-1EE0092FB9F8"
+
+/** @} */
+
+RT_C_DECLS_END
+
+
+#endif
+
+
diff --git a/include/VBox/vmm/pdmpci.h b/include/VBox/vmm/pdmpci.h
new file mode 100644
index 00000000..16d925f1
--- /dev/null
+++ b/include/VBox/vmm/pdmpci.h
@@ -0,0 +1,398 @@
+/** @file
+ * PDM - Pluggable Device Manager, raw PCI Devices. (VMM)
+ */
+
+/*
+ * Copyright (C) 2010-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmpci_h
+#define ___VBox_vmm_pdmpci_h
+
+#include <VBox/types.h>
+#include <VBox/rawpci.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_pcidev The raw PCI Devices API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+typedef struct PDMIPCIRAW *PPDMIPCIRAW;
+typedef struct PDMIPCIRAW
+{
+ /**
+ * Notify virtual device that interrupt has arrived.
+ * For this callback to be called, interface have to be
+ * registered with PDMIPCIRAWUP::pfnRegisterInterruptListener.
+ *
+ * @note no level parameter, as we can only support flip-flop.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param iGuestIrq Guest interrupt number, passed earlier when registering listener.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnInterruptRequest ,(PPDMIPCIRAW pInterface, int32_t iGuestIrq));
+} PDMIPCIRAW;
+
+typedef struct PDMIPCIRAWUP *PPDMIPCIRAWUP;
+typedef struct PDMIPCIRAWUP
+{
+ /**
+ * Host PCI MMIO access function.
+ */
+
+ /**
+ * Request driver info about PCI region on host PCI device.
+ *
+ * @returns true, if region is present, and out parameters are correct
+ * @param pInterface Pointer to this interface structure.
+ * @param iRegion Region number.
+ * @param pRegStart Where to store region base address (guest).
+ * @param piRegSize Where to store region size.
+ *
+ * @param fMmio If region is MMIO or IO.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnGetRegionInfo, (PPDMIPCIRAWUP pInterface,
+ int32_t iRegion,
+ RTGCPHYS *pRegStart,
+ uint64_t *piRegSize,
+ uint32_t *pfFlags
+ ));
+
+ /**
+ * Request driver to map part of host device's MMIO region to the VM process and maybe kernel.
+ * Shall only be issued within earlier obtained with pfnGetRegionInfo()
+ * host physical address ranges for the device BARs. Even if failed, device still may function
+ * using pfnMmio* and pfnPio* operations, just much slower.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param iRegion Number of the region.
+ * @param StartAddress Host physical address of start.
+ * @param iRegionSize Size of the region.
+ * @param fFlags Flags, currently lowest significant bit set if R0 mapping requested too
+ * @param ppvAddressR3 Where to store mapped region address for R3 (can be 0, if cannot map into userland)
+ * @param ppvAddressR0 Where to store mapped region address for R0 (can be 0, if cannot map into kernel)
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMapRegion, (PPDMIPCIRAWUP pInterface,
+ int32_t iRegion,
+ RTHCPHYS StartAddress,
+ uint64_t iRegionSize,
+ uint32_t fFlags,
+ RTR3PTR *ppvAddressR3,
+ RTR0PTR *ppvAddressR0
+ ));
+
+ /**
+ * Request driver to unmap part of host device's MMIO region to the VM process.
+ * Shall only be issued with pointer earlier obtained with pfnMapRegion().
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure
+ * @param iRegion Number of the region.
+ * @param StartAddress Host physical address of start.
+ * @param iRegionSize Size of the region.
+ * @param pvAddressR3 R3 address of mapped region.
+ * @param pvAddressR0 R0 address of mapped region.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUnmapRegion, (PPDMIPCIRAWUP pInterface,
+ int iRegion,
+ RTHCPHYS StartAddress,
+ uint64_t iRegionSize,
+ RTR3PTR pvAddressR3,
+ RTR0PTR pvAddressR0
+ ));
+
+ /**
+ * Request port IO write.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param iPort IO port.
+ * @param iValue Value to write.
+ * @param cb Access width.
+ *
+ * @thread EMT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPioWrite, (PPDMIPCIRAWUP pInterface,
+ uint16_t iPort,
+ uint32_t iValue,
+ unsigned cb
+ ));
+
+ /**
+ * Request port IO read.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param iPort IO port.
+ * @param piValue Place to store read value.
+ * @param cb Access width.
+ *
+ * @thread EMT thread.
+ */
+
+ DECLR3CALLBACKMEMBER(int, pfnPioRead, (PPDMIPCIRAWUP pInterface,
+ uint16_t iPort,
+ uint32_t *piValue,
+ unsigned cb
+ ));
+
+
+ /**
+ * Request MMIO write. This callback is only called if driver wants to receive MMIO via
+ * pu32Flags argument of pfnPciDeviceConstructStart().
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param Address Guest physical address.
+ * @param pValue Address of value to write.
+ * @param cb Access width.
+ *
+ * @thread EMT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnMmioWrite, (PPDMIPCIRAWUP pInterface,
+ RTR0PTR Address,
+ void const *pValue,
+ unsigned cb
+ ));
+
+ /**
+ * Request MMIO read.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param Address Guest physical address.
+ * @param pValue Place to store read value.
+ * @param cb Access width.
+ *
+ * @thread EMT thread.
+ */
+
+ DECLR3CALLBACKMEMBER(int, pfnMmioRead, (PPDMIPCIRAWUP pInterface,
+ RTR0PTR Address,
+ void *pValue,
+ unsigned cb
+ ));
+
+ /**
+ * Host PCI config space accessors.
+ */
+ /**
+ * Request driver to write value to host device's PCI config space.
+ * Host specific way (PIO or MCFG) is used to perform actual operation.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param iOffset Offset in PCI config space.
+ * @param iValue Value to write.
+ * @param cb Access width.
+ *
+ * @thread EMT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPciCfgWrite, (PPDMIPCIRAWUP pInterface,
+ uint32_t iOffset,
+ void* pValue,
+ unsigned cb
+ ));
+ /**
+ * Request driver to read value from host device's PCI config space.
+ * Host specific way (PIO or MCFG) is used to perform actual operation.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param iOffset Offset in PCI config space.
+ * @param pValue Where to store read value.
+ * @param cb Access width.
+ *
+ * @thread EMT thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPciCfgRead, (PPDMIPCIRAWUP pInterface,
+ uint32_t iOffset,
+ void *pValue,
+ unsigned cb ));
+
+ /**
+ * Request to enable interrupt notifications. Please note that this is purely
+ * R3 interface, so it's up to implementor to perform necessary machinery
+ * for communications with host OS kernel driver. Typical implementation will start
+ * userland thread waiting on shared semaphore (such as using SUPSEMEVENT),
+ * notified by the kernel interrupt handler, and then will call
+ * upper port pfnInterruptRequest() based on data provided by the driver.
+ * This apporach is taken, as calling VBox code from an asyncronous R0
+ * interrupt handler when VMM may not be even running doesn't look
+ * like a good idea.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param pListener Pointer to the listener object.
+ * @param iGuestIrq Guest IRQ to be passed to pfnInterruptRequest().
+ *
+ * @thread Any thread, pfnInterruptRequest() will be usually invoked on a dedicated thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnEnableInterruptNotifications, (PPDMIPCIRAWUP pInterface, int32_t iGuestIrq
+ ));
+
+ /**
+ * Request to disable interrupt notifications.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDisableInterruptNotifications, (PPDMIPCIRAWUP pInterface
+ ));
+
+ /**
+ * Notification APIs.
+ */
+
+ /**
+ * Notify driver when raw PCI device construction starts. Have to be the first operation
+ * as initializes internal state and opens host device driver.
+ *
+ * @returns status code
+ * @param pInterface Pointer to this interface structure.
+ * @param iHostAddress Host PCI address of device attached.
+ * @param iGuestAddress Guest PCI address of device attached.
+ * @param szDeviceName Human readable device name.
+ * @param fDeviceFlags Flags for the host device.
+ * @param pu32Flags Flags for virtual device, from the upper driver.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPciDeviceConstructStart, (PPDMIPCIRAWUP pInterface,
+ uint32_t iHostAddress,
+ uint32_t iGuestAddress,
+ const char* szDeviceName,
+ uint32_t fDeviceFlags,
+ uint32_t *pu32Flags));
+
+ /**
+ * Notify driver when raw PCI device construction completes, so that it may
+ * perform further actions depending on success or failure of this operation.
+ * Standard action is to raise global IHostPciDevicePlugEvent.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param rc Result code of the operation.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnPciDeviceConstructComplete, (PPDMIPCIRAWUP pInterface,
+ int rc));
+
+ /**
+ * Notify driver on finalization of raw PCI device.
+ *
+ * @param pInterface Pointer to this interface structure.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPciDeviceDestruct, (PPDMIPCIRAWUP pInterface,
+ uint32_t fFlags));
+
+ /**
+ * Notify driver on guest power state change.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param aState New power state.
+ * @param pu64Param State-specific in/out parameter. For now only used during power-on to provide VM caps.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPciDevicePowerStateChange, (PPDMIPCIRAWUP pInterface,
+ PCIRAWPOWERSTATE aState,
+ uint64_t *pu64Param));
+
+ /**
+ * Notify driver about runtime error.
+ *
+ * @param pInterface Pointer to this interface structure.
+ * @param fFatal If error is fatal.
+ * @param szErrorId Error ID.
+ * @param szMessage Error message.
+ *
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReportRuntimeError, (PPDMIPCIRAWUP pInterface,
+ uint8_t fFatal,
+ const char* szErrorId,
+ const char* szMessage));
+} PDMIPCIRAWUP;
+
+/**
+ * Init R0 PCI module.
+ */
+PCIRAWR0DECL(int) PciRawR0Init(void);
+/**
+ * Process request (in R0).
+ */
+PCIRAWR0DECL(int) PciRawR0ProcessReq(PSUPDRVSESSION pSession, PVM pVM, PPCIRAWSENDREQ pReq);
+/**
+ * Terminate R0 PCI module.
+ */
+PCIRAWR0DECL(void) PciRawR0Term(void);
+
+/**
+ * Per-VM R0 module init.
+ */
+PCIRAWR0DECL(int) PciRawR0InitVM(PVM pVM);
+
+/**
+ * Per-VM R0 module termination routine.
+ */
+PCIRAWR0DECL(void) PciRawR0TermVM(PVM pVM);
+
+/**
+ * Flags returned by pfnPciDeviceConstructStart(), to notify device
+ * how it shall handle device IO traffic.
+ */
+typedef enum PCIRAWDEVICEFLAGS
+{
+ /** Intercept port IO (R3 PIO always go to the driver). */
+ PCIRAWRFLAG_CAPTURE_PIO = (1 << 0),
+ /** Intercept MMIO. */
+ PCIRAWRFLAG_CAPTURE_MMIO = (1 << 1),
+ /** Allow bus mastering by physical device (requires IOMMU). */
+ PCIRAWRFLAG_ALLOW_BM = (1 << 2),
+ /** Allow R3 MMIO mapping. */
+ PCIRAWRFLAG_ALLOW_R3MAP = (1 << 3),
+
+ /** The usual 32-bit type blow up. */
+ PCIRAWRFLAG_32BIT_HACK = 0x7fffffff
+} PCIRAWDEVICEFLAGS;
+
+#define PDMIPCIRAWUP_IID "06daa17f-097b-4ebe-a626-15f467b1de12"
+#define PDMIPCIRAW_IID "68c6e4c4-4223-47e0-9134-e3c297992543"
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/pdmqueue.h b/include/VBox/vmm/pdmqueue.h
new file mode 100644
index 00000000..3445c85a
--- /dev/null
+++ b/include/VBox/vmm/pdmqueue.h
@@ -0,0 +1,147 @@
+/** @file
+ * PDM - Pluggable Device Manager, Queues.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmqueue_h
+#define ___VBox_vmm_pdmqueue_h
+
+#include <VBox/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_queue The PDM Queues API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/** Pointer to a PDM queue. Also called PDM queue handle. */
+typedef struct PDMQUEUE *PPDMQUEUE;
+
+/** Pointer to a PDM queue item core. */
+typedef struct PDMQUEUEITEMCORE *PPDMQUEUEITEMCORE;
+
+/**
+ * PDM queue item core.
+ */
+typedef struct PDMQUEUEITEMCORE
+{
+ /** Pointer to the next item in the pending list - R3 Pointer. */
+ R3PTRTYPE(PPDMQUEUEITEMCORE) pNextR3;
+ /** Pointer to the next item in the pending list - R0 Pointer. */
+ R0PTRTYPE(PPDMQUEUEITEMCORE) pNextR0;
+ /** Pointer to the next item in the pending list - RC Pointer. */
+ RCPTRTYPE(PPDMQUEUEITEMCORE) pNextRC;
+#if HC_ARCH_BITS == 64
+ RTRCPTR Alignment0;
+#endif
+} PDMQUEUEITEMCORE;
+
+
+/**
+ * Queue consumer callback for devices.
+ *
+ * @returns Success indicator.
+ * If false the item will not be removed and the flushing will stop.
+ * @param pDevIns The device instance.
+ * @param pItem The item to consume. Upon return this item will be freed.
+ */
+typedef DECLCALLBACK(bool) FNPDMQUEUEDEV(PPDMDEVINS pDevIns, PPDMQUEUEITEMCORE pItem);
+/** Pointer to a FNPDMQUEUEDEV(). */
+typedef FNPDMQUEUEDEV *PFNPDMQUEUEDEV;
+
+/**
+ * Queue consumer callback for USB devices.
+ *
+ * @returns Success indicator.
+ * If false the item will not be removed and the flushing will stop.
+ * @param pDevIns The USB device instance.
+ * @param pItem The item to consume. Upon return this item will be freed.
+ */
+typedef DECLCALLBACK(bool) FNPDMQUEUEUSB(PPDMUSBINS pUsbIns, PPDMQUEUEITEMCORE pItem);
+/** Pointer to a FNPDMQUEUEUSB(). */
+typedef FNPDMQUEUEUSB *PFNPDMQUEUEUSB;
+
+/**
+ * Queue consumer callback for drivers.
+ *
+ * @returns Success indicator.
+ * If false the item will not be removed and the flushing will stop.
+ * @param pDrvIns The driver instance.
+ * @param pItem The item to consume. Upon return this item will be freed.
+ */
+typedef DECLCALLBACK(bool) FNPDMQUEUEDRV(PPDMDRVINS pDrvIns, PPDMQUEUEITEMCORE pItem);
+/** Pointer to a FNPDMQUEUEDRV(). */
+typedef FNPDMQUEUEDRV *PFNPDMQUEUEDRV;
+
+/**
+ * Queue consumer callback for internal component.
+ *
+ * @returns Success indicator.
+ * If false the item will not be removed and the flushing will stop.
+ * @param pVM The VM handle.
+ * @param pItem The item to consume. Upon return this item will be freed.
+ */
+typedef DECLCALLBACK(bool) FNPDMQUEUEINT(PVM pVM, PPDMQUEUEITEMCORE pItem);
+/** Pointer to a FNPDMQUEUEINT(). */
+typedef FNPDMQUEUEINT *PFNPDMQUEUEINT;
+
+/**
+ * Queue consumer callback for external component.
+ *
+ * @returns Success indicator.
+ * If false the item will not be removed and the flushing will stop.
+ * @param pvUser User argument.
+ * @param pItem The item to consume. Upon return this item will be freed.
+ */
+typedef DECLCALLBACK(bool) FNPDMQUEUEEXT(void *pvUser, PPDMQUEUEITEMCORE pItem);
+/** Pointer to a FNPDMQUEUEEXT(). */
+typedef FNPDMQUEUEEXT *PFNPDMQUEUEEXT;
+
+#ifdef VBOX_IN_VMM
+VMMR3_INT_DECL(int) PDMR3QueueCreateDevice(PVM pVM, PPDMDEVINS pDevIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEDEV pfnCallback, bool fRZEnabled, const char *pszName, PPDMQUEUE *ppQueue);
+VMMR3_INT_DECL(int) PDMR3QueueCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEDRV pfnCallback, const char *pszName, PPDMQUEUE *ppQueue);
+VMMR3_INT_DECL(int) PDMR3QueueCreateInternal(PVM pVM, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEINT pfnCallback, bool fGCEnabled, const char *pszName, PPDMQUEUE *ppQueue);
+VMMR3_INT_DECL(int) PDMR3QueueCreateExternal(PVM pVM, size_t cbItem, uint32_t cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEEXT pfnCallback, void *pvUser, const char *pszName, PPDMQUEUE *ppQueue);
+VMMR3_INT_DECL(int) PDMR3QueueDestroy(PPDMQUEUE pQueue);
+VMMR3_INT_DECL(int) PDMR3QueueDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
+VMMR3_INT_DECL(int) PDMR3QueueDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
+VMMR3_INT_DECL(void) PDMR3QueueFlushAll(PVM pVM);
+#endif /* VBOX_IN_VMM */
+
+VMMDECL(PPDMQUEUEITEMCORE) PDMQueueAlloc(PPDMQUEUE pQueue);
+VMMDECL(void) PDMQueueInsert(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem);
+VMMDECL(void) PDMQueueInsertEx(PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem, uint64_t NanoMaxDelay);
+VMMDECL(RCPTRTYPE(PPDMQUEUE)) PDMQueueRCPtr(PPDMQUEUE pQueue);
+VMMDECL(R0PTRTYPE(PPDMQUEUE)) PDMQueueR0Ptr(PPDMQUEUE pQueue);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/pdmsrv.h b/include/VBox/vmm/pdmsrv.h
new file mode 100644
index 00000000..98766223
--- /dev/null
+++ b/include/VBox/vmm/pdmsrv.h
@@ -0,0 +1,335 @@
+/** @file
+ * PDM - Pluggable Device Manager, VM Services.
+ *
+ * @todo This has not been implemented, consider dropping the concept.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmsrv_h
+#define ___VBox_vmm_pdmsrv_h
+
+#include <VBox/vmm/pdmifs.h>
+#include <VBox/vmm/ssm.h>
+#include <VBox/vmm/cfgm.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_services The PDM Services API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/**
+ * Construct a service instance for a VM.
+ *
+ * @returns VBox status.
+ * @param pSrvIns The service instance data.
+ * If the registration structure is needed, pSrvIns->pReg points to it.
+ * @param pCfg Configuration node handle for the service. Use this to obtain the configuration
+ * of the driver instance. It's also found in pSrvIns->pCfg, but since it's primary
+ * usage is expected in this function it is passed as a parameter.
+ */
+typedef DECLCALLBACK(int) FNPDMSRVCONSTRUCT(PPDMSRVINS pSrvIns, PCFGMNODE pCfg);
+/** Pointer to a FNPDMSRVCONSTRUCT() function. */
+typedef FNPDMSRVCONSTRUCT *PFNPDMSRVCONSTRUCT;
+
+/**
+ * Destruct a driver instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * @param pSrvIns The service instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMSRVDESTRUCT(PPDMSRVINS pSrvIns);
+/** Pointer to a FNPDMSRVDESTRUCT() function. */
+typedef FNPDMSRVDESTRUCT *PFNPDMSRVDESTRUCT;
+
+/**
+ * Power On notification.
+ *
+ * @param pSrvIns The service instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMSRVPOWERON(PPDMSRVINS pSrvIns);
+/** Pointer to a FNPDMSRVPOWERON() function. */
+typedef FNPDMSRVPOWERON *PFNPDMSRVPOWERON;
+
+/**
+ * Reset notification.
+ *
+ * @returns VBox status.
+ * @param pSrvIns The service instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMSRVRESET(PPDMSRVINS pSrvIns);
+/** Pointer to a FNPDMSRVRESET() function. */
+typedef FNPDMSRVRESET *PFNPDMSRVRESET;
+
+/**
+ * Suspend notification.
+ *
+ * @returns VBox status.
+ * @param pSrvIns The service instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMSRVSUSPEND(PPDMSRVINS pSrvIns);
+/** Pointer to a FNPDMSRVSUSPEND() function. */
+typedef FNPDMSRVSUSPEND *PFNPDMSRVSUSPEND;
+
+/**
+ * Resume notification.
+ *
+ * @returns VBox status.
+ * @param pSrvIns The service instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMSRVRESUME(PPDMSRVINS pSrvIns);
+/** Pointer to a FNPDMSRVRESUME() function. */
+typedef FNPDMSRVRESUME *PFNPDMSRVRESUME;
+
+/**
+ * Power Off notification.
+ *
+ * @param pSrvIns The service instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMSRVPOWEROFF(PPDMSRVINS pSrvIns);
+/** Pointer to a FNPDMSRVPOWEROFF() function. */
+typedef FNPDMSRVPOWEROFF *PFNPDMSRVPOWEROFF;
+
+/**
+ * Detach notification.
+ *
+ * This is called when a driver or device is detached from the service
+ *
+ * @param pSrvIns The service instance data.
+ */
+typedef DECLCALLBACK(void) FNPDMSRVDETACH(PPDMSRVINS pSrvIns, PPDMDEVINS pDevIns, PPDMDRVINS pDrvIns);
+/** Pointer to a FNPDMSRVDETACH() function. */
+typedef FNPDMSRVDETACH *PFNPDMSRVDETACH;
+
+
+
+/** PDM Service Registration Structure,
+ * This structure is used when registering a driver from
+ * VBoxServicesRegister() (HC Ring-3). PDM will continue use till
+ * the VM is terminated.
+ */
+typedef struct PDMSRVREG
+{
+ /** Structure version. PDM_SRVREG_VERSION defines the current version. */
+ uint32_t u32Version;
+ /** Driver name. */
+ char szServiceName[32];
+ /** The description of the driver. The UTF-8 string pointed to shall, like this structure,
+ * remain unchanged from registration till VM destruction. */
+ const char *pszDescription;
+
+ /** Flags, combination of the PDM_SRVREG_FLAGS_* \#defines. */
+ RTUINT fFlags;
+ /** Size of the instance data. */
+ RTUINT cbInstance;
+
+ /** Construct instance - required. */
+ PFNPDMSRVCONSTRUCT pfnConstruct;
+ /** Destruct instance - optional. */
+ PFNPDMSRVDESTRUCT pfnDestruct;
+ /** Power on notification - optional. */
+ PFNPDMSRVPOWERON pfnPowerOn;
+ /** Reset notification - optional. */
+ PFNPDMSRVRESET pfnReset;
+ /** Suspend notification - optional. */
+ PFNPDMSRVSUSPEND pfnSuspend;
+ /** Resume notification - optional. */
+ PFNPDMSRVRESUME pfnResume;
+ /** Detach notification - optional. */
+ PFNPDMSRVDETACH pfnDetach;
+ /** Power off notification - optional. */
+ PFNPDMSRVPOWEROFF pfnPowerOff;
+
+} PDMSRVREG;
+/** Pointer to a PDM Driver Structure. */
+typedef PDMSRVREG *PPDMSRVREG;
+/** Const pointer to a PDM Driver Structure. */
+typedef PDMSRVREG const *PCPDMSRVREG;
+
+
+
+/**
+ * PDM Service API.
+ */
+typedef struct PDMSRVHLP
+{
+ /** Structure version. PDM_SRVHLP_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Assert that the current thread is the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pSrvIns Service instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMSRVINS pSrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Assert that the current thread is NOT the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pSrvIns Service instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMSRVINS pSrvIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Creates a timer.
+ *
+ * @returns VBox status.
+ * @param pVM The VM to create the timer in.
+ * @param pSrvIns Service instance.
+ * @param enmClock The clock to use on this timer.
+ * @param pfnCallback Callback function.
+ * @param pszDesc Pointer to description string which must stay around
+ * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
+ * @param ppTimer Where to store the timer on success.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMSRVINS pSrvIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, const char *pszDesc, PPTMTIMERR3 ppTimer));
+
+ /**
+ * Query the virtual timer frequency.
+ *
+ * @returns Frequency in Hz.
+ * @param pSrvIns Service instance.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnTMGetVirtualFreq,(PPDMSRVINS pSrvIns));
+
+ /**
+ * Query the virtual time.
+ *
+ * @returns The current virtual time.
+ * @param pSrvIns Service instance.
+ * @thread Any thread.
+ */
+ DECLR3CALLBACKMEMBER(uint64_t, pfnTMGetVirtualTime,(PPDMSRVINS pSrvIns));
+
+} PDMSRVHLP;
+/** Pointer PDM Service API. */
+typedef PDMSRVHLP *PPDMSRVHLP;
+/** Pointer const PDM Service API. */
+typedef const PDMSRVHLP *PCPDMSRVHLP;
+
+/** Current SRVHLP version number. */
+#define PDM_SRVHLP_VERSION PDM_VERSION_MAKE(0xdfff, 1, 0)
+
+
+/**
+ * PDM Service Instance.
+ */
+typedef struct PDMSRVINS
+{
+ /** Structure version. PDM_SRVINS_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /** Internal data. */
+ union
+ {
+#ifdef PDMSRVINSINT_DECLARED
+ PDMSRVINSINT s;
+#endif
+ uint8_t padding[HC_ARCH_BITS == 32 ? 32 : 32];
+ } Internal;
+
+ /** Pointer the PDM Service API. */
+ R3PTRTYPE(PCPDMSRVHLP) pHlp;
+ /** Pointer to driver registration structure. */
+ R3PTRTYPE(PCPDMSRVREG) pReg;
+ /** Configuration handle. */
+ R3PTRTYPE(PCFGMNODE) pCfg;
+ /** The base interface of the service.
+ * The service constructor initializes this. */
+ PDMIBASE IBase;
+ /* padding to make achInstanceData aligned at 16 byte boundary. */
+ uint32_t au32Padding[2];
+ /** Pointer to driver instance data. */
+ R3PTRTYPE(void *) pvInstanceData;
+ /** Driver instance data. The size of this area is defined
+ * in the PDMSRVREG::cbInstanceData field. */
+ char achInstanceData[4];
+} PDMSRVINS;
+
+/** Current PDMSRVREG version number. */
+#define PDM_SRVINS_VERSION PDM_VERSION_MAKE(0xdffe, 1, 0)
+
+/** Converts a pointer to the PDMSRVINS::IBase to a pointer to PDMSRVINS. */
+#define PDMIBASE_2_PDMSRV(pInterface) ( (PPDMSRVINS)((char *)(pInterface) - RT_OFFSETOF(PDMSRVINS, IBase)) )
+
+
+
+/** Pointer to callbacks provided to the VBoxServiceRegister() call. */
+typedef struct PDMSRVREGCB *PPDMSRVREGCB;
+
+/**
+ * Callbacks for VBoxServiceRegister().
+ */
+typedef struct PDMSRVREGCB
+{
+ /** Interface version.
+ * This is set to PDM_SRVREG_CB_VERSION. */
+ uint32_t u32Version;
+
+ /**
+ * Registers a service with the current VM instance.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param pSrvReg Pointer to the device registration record.
+ * This data must be permanent and readonly.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRegister,(PPDMSRVREGCB pCallbacks, PCPDMSRVREG pSrvReg));
+} PDMSRVREGCB;
+
+/** Current version of the PDMSRVREGCB structure. */
+#define PDM_SRVREG_CB_VERSION PDM_VERSION_MAKE(0xdffd, 1, 0)
+
+
+/**
+ * The VBoxServicesRegister callback function.
+ *
+ * PDM will invoke this function after loading a device module and letting
+ * the module decide which devices to register and how to handle conflicts.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param u32Version VBox version number.
+ */
+typedef DECLCALLBACK(int) FNPDMVBOXSERVICESREGISTER(PPDMSRVREGCB pCallbacks, uint32_t u32Version);
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/pdmthread.h b/include/VBox/vmm/pdmthread.h
new file mode 100644
index 00000000..044620cd
--- /dev/null
+++ b/include/VBox/vmm/pdmthread.h
@@ -0,0 +1,298 @@
+/** @file
+ * PDM - Pluggable Device Manager, Threads.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmthread_h
+#define ___VBox_vmm_pdmthread_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#ifdef IN_RING3
+# include <iprt/thread.h>
+#endif
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_thread The PDM Threads API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+/**
+ * The thread state
+ */
+typedef enum PDMTHREADSTATE
+{
+ /** The usual invalid 0 entry. */
+ PDMTHREADSTATE_INVALID = 0,
+ /** The thread is initializing.
+ * Prev state: none
+ * Next state: suspended, terminating (error) */
+ PDMTHREADSTATE_INITIALIZING,
+ /** The thread has been asked to suspend.
+ * Prev state: running
+ * Next state: suspended */
+ PDMTHREADSTATE_SUSPENDING,
+ /** The thread is supended.
+ * Prev state: suspending, initializing
+ * Next state: resuming, terminated. */
+ PDMTHREADSTATE_SUSPENDED,
+ /** The thread is active.
+ * Prev state: suspended
+ * Next state: running, terminating. */
+ PDMTHREADSTATE_RESUMING,
+ /** The thread is active.
+ * Prev state: resuming
+ * Next state: suspending, terminating. */
+ PDMTHREADSTATE_RUNNING,
+ /** The thread has been asked to terminate.
+ * Prev state: initializing, suspended, resuming, running
+ * Next state: terminated. */
+ PDMTHREADSTATE_TERMINATING,
+ /** The thread is terminating / has terminated.
+ * Prev state: terminating
+ * Next state: none */
+ PDMTHREADSTATE_TERMINATED,
+ /** The usual 32-bit hack. */
+ PDMTHREADSTATE_32BIT_HACK = 0x7fffffff
+} PDMTHREADSTATE;
+
+/** A pointer to a PDM thread. */
+typedef R3PTRTYPE(struct PDMTHREAD *) PPDMTHREAD;
+/** A pointer to a pointer to a PDM thread. */
+typedef PPDMTHREAD *PPPDMTHREAD;
+
+/**
+ * PDM thread, device variation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADDEV(). */
+typedef FNPDMTHREADDEV *PFNPDMTHREADDEV;
+
+/**
+ * PDM thread, USB device variation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADUSB(PPDMUSBINS pUsbIns, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADUSB(). */
+typedef FNPDMTHREADUSB *PFNPDMTHREADUSB;
+
+/**
+ * PDM thread, driver variation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADDRV(). */
+typedef FNPDMTHREADDRV *PFNPDMTHREADDRV;
+
+/**
+ * PDM thread, driver variation.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADINT(PVM pVM, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADINT(). */
+typedef FNPDMTHREADINT *PFNPDMTHREADINT;
+
+/**
+ * PDM thread, driver variation.
+ *
+ * @returns VBox status code.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADEXT(PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADEXT(). */
+typedef FNPDMTHREADEXT *PFNPDMTHREADEXT;
+
+
+
+/**
+ * PDM thread wakeup call, device variation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADWAKEUPDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADDEV(). */
+typedef FNPDMTHREADWAKEUPDEV *PFNPDMTHREADWAKEUPDEV;
+
+/**
+ * PDM thread wakeup call, device variation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADWAKEUPUSB(PPDMUSBINS pUsbIns, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADUSB(). */
+typedef FNPDMTHREADWAKEUPUSB *PFNPDMTHREADWAKEUPUSB;
+
+/**
+ * PDM thread wakeup call, driver variation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns The driver instance.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADWAKEUPDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADDRV(). */
+typedef FNPDMTHREADWAKEUPDRV *PFNPDMTHREADWAKEUPDRV;
+
+/**
+ * PDM thread wakeup call, internal variation.
+ *
+ * @returns VBox status code.
+ * @param pVM The VM handle.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADWAKEUPINT(PVM pVM, PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADWAKEUPINT(). */
+typedef FNPDMTHREADWAKEUPINT *PFNPDMTHREADWAKEUPINT;
+
+/**
+ * PDM thread wakeup call, external variation.
+ *
+ * @returns VBox status code.
+ * @param pThread The PDM thread data.
+ */
+typedef int FNPDMTHREADWAKEUPEXT(PPDMTHREAD pThread);
+/** Pointer to a FNPDMTHREADEXT(). */
+typedef FNPDMTHREADWAKEUPEXT *PFNPDMTHREADWAKEUPEXT;
+
+
+/**
+ * PDM Thread instance data.
+ */
+typedef struct PDMTHREAD
+{
+ /** PDMTHREAD_VERSION. */
+ uint32_t u32Version;
+ /** The thread state. */
+ PDMTHREADSTATE volatile enmState;
+ /** The thread handle. */
+ RTTHREAD Thread;
+ /** The user parameter. */
+ R3PTRTYPE(void *) pvUser;
+ /** Data specific to the kind of thread.
+ * This should really be in PDMTHREADINT, but is placed here because of the
+ * function pointer typedefs. So, don't touch these, please.
+ */
+ union
+ {
+ /** PDMTHREADTYPE_DEVICE data. */
+ struct
+ {
+ /** The device instance. */
+ PPDMDEVINSR3 pDevIns;
+ /** The thread function. */
+ R3PTRTYPE(PFNPDMTHREADDEV) pfnThread;
+ /** Thread. */
+ R3PTRTYPE(PFNPDMTHREADWAKEUPDEV) pfnWakeUp;
+ } Dev;
+
+ /** PDMTHREADTYPE_USB data. */
+ struct
+ {
+ /** The device instance. */
+ PPDMUSBINS pUsbIns;
+ /** The thread function. */
+ R3PTRTYPE(PFNPDMTHREADUSB) pfnThread;
+ /** Thread. */
+ R3PTRTYPE(PFNPDMTHREADWAKEUPUSB) pfnWakeUp;
+ } Usb;
+
+ /** PDMTHREADTYPE_DRIVER data. */
+ struct
+ {
+ /** The driver instance. */
+ R3PTRTYPE(PPDMDRVINS) pDrvIns;
+ /** The thread function. */
+ R3PTRTYPE(PFNPDMTHREADDRV) pfnThread;
+ /** Thread. */
+ R3PTRTYPE(PFNPDMTHREADWAKEUPDRV) pfnWakeUp;
+ } Drv;
+
+ /** PDMTHREADTYPE_INTERNAL data. */
+ struct
+ {
+ /** The thread function. */
+ R3PTRTYPE(PFNPDMTHREADINT) pfnThread;
+ /** Thread. */
+ R3PTRTYPE(PFNPDMTHREADWAKEUPINT) pfnWakeUp;
+ } Int;
+
+ /** PDMTHREADTYPE_EXTERNAL data. */
+ struct
+ {
+ /** The thread function. */
+ R3PTRTYPE(PFNPDMTHREADEXT) pfnThread;
+ /** Thread. */
+ R3PTRTYPE(PFNPDMTHREADWAKEUPEXT) pfnWakeUp;
+ } Ext;
+ } u;
+
+ /** Internal data. */
+ union
+ {
+#ifdef PDMTHREADINT_DECLARED
+ PDMTHREADINT s;
+#endif
+ uint8_t padding[64];
+ } Internal;
+} PDMTHREAD;
+
+/** PDMTHREAD::u32Version value. */
+#define PDMTHREAD_VERSION PDM_VERSION_MAKE(0xefff, 1, 0)
+
+#ifdef IN_RING3
+VMMR3DECL(int) PDMR3ThreadCreate(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADINT pfnThread,
+ PFNPDMTHREADWAKEUPINT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
+VMMR3DECL(int) PDMR3ThreadCreateExternal(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADEXT pfnThread,
+ PFNPDMTHREADWAKEUPEXT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
+VMMR3DECL(int) PDMR3ThreadDestroy(PPDMTHREAD pThread, int *pRcThread);
+VMMR3DECL(int) PDMR3ThreadIAmSuspending(PPDMTHREAD pThread);
+VMMR3DECL(int) PDMR3ThreadIAmRunning(PPDMTHREAD pThread);
+VMMR3DECL(int) PDMR3ThreadSleep(PPDMTHREAD pThread, RTMSINTERVAL cMillies);
+VMMR3DECL(int) PDMR3ThreadSuspend(PPDMTHREAD pThread);
+VMMR3DECL(int) PDMR3ThreadResume(PPDMTHREAD pThread);
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/pdmusb.h b/include/VBox/vmm/pdmusb.h
new file mode 100644
index 00000000..ae3f5cfb
--- /dev/null
+++ b/include/VBox/vmm/pdmusb.h
@@ -0,0 +1,1004 @@
+/** @file
+ * PDM - Pluggable Device Manager, USB Devices.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pdmusb_h
+#define ___VBox_vmm_pdmusb_h
+
+#include <VBox/vmm/pdmqueue.h>
+#include <VBox/vmm/pdmcritsect.h>
+#include <VBox/vmm/pdmthread.h>
+#include <VBox/vmm/pdmifs.h>
+#include <VBox/vmm/pdmcommon.h>
+#include <VBox/vmm/tm.h>
+#include <VBox/vmm/ssm.h>
+#include <VBox/vmm/cfgm.h>
+#include <VBox/vmm/dbgf.h>
+#include <VBox/vmm/mm.h>
+#include <VBox/err.h>
+#include <VBox/vusb.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pdm_usbdev The USB Devices API
+ * @ingroup grp_pdm
+ * @{
+ */
+
+
+/**
+ * A string entry for the USB descriptor cache.
+ */
+typedef struct PDMUSBDESCCACHESTRING
+{
+ /** The string index. */
+ uint8_t idx;
+ /** The UTF-8 representation of the string. */
+ const char *psz;
+} PDMUSBDESCCACHESTRING;
+/** Pointer to a const string entry. */
+typedef PDMUSBDESCCACHESTRING const *PCPDMUSBDESCCACHESTRING;
+
+
+/**
+ * A language entry for the USB descriptor cache.
+ */
+typedef struct PDMUSBDESCCACHELANG
+{
+ /** The language ID for the strings in this block. */
+ uint16_t idLang;
+ /** The number of strings in the array. */
+ uint16_t cStrings;
+ /** Pointer to an array of associated strings.
+ * This must be sorted in ascending order by string index as a binary lookup
+ * will be performed. */
+ PCPDMUSBDESCCACHESTRING paStrings;
+} PDMUSBDESCCACHELANG;
+/** Pointer to a const language entry. */
+typedef PDMUSBDESCCACHELANG const *PCPDMUSBDESCCACHELANG;
+
+
+/**
+ * USB descriptor cache.
+ *
+ * This structure is owned by the USB device but provided to the PDM/VUSB layer
+ * thru the PDMUSBREG::pfnGetDescriptorCache method. PDM/VUSB will use the
+ * information here to map addresses to endpoints, perform SET_CONFIGURATION
+ * requests, and optionally perform GET_DESCRIPTOR requests (see flag).
+ *
+ * Currently, only device and configuration descriptors are cached.
+ */
+typedef struct PDMUSBDESCCACHE
+{
+ /** USB device descriptor */
+ PCVUSBDESCDEVICE pDevice;
+ /** USB Descriptor arrays (pDev->bNumConfigurations) */
+ PCVUSBDESCCONFIGEX paConfigs;
+ /** Language IDs and their associated strings.
+ * This must be sorted in ascending order by language ID as a binary lookup
+ * will be used. */
+ PCPDMUSBDESCCACHELANG paLanguages;
+ /** The number of entries in the array pointed to by paLanguages. */
+ uint16_t cLanguages;
+ /** Use the cached descriptors for GET_DESCRIPTOR requests. */
+ bool fUseCachedDescriptors;
+ /** Use the cached string descriptors. */
+ bool fUseCachedStringsDescriptors;
+} PDMUSBDESCCACHE;
+/** Pointer to an USB descriptor cache. */
+typedef PDMUSBDESCCACHE *PPDMUSBDESCCACHE;
+/** Pointer to a const USB descriptor cache. */
+typedef const PDMUSBDESCCACHE *PCPDMUSBDESCCACHE;
+
+
+
+/** PDM USB Device Registration Structure,
+ *
+ * This structure is used when registering a device from VBoxUsbRegister() in HC Ring-3.
+ * The PDM will make use of this structure until the VM is destroyed.
+ */
+typedef struct PDMUSBREG
+{
+ /** Structure version. PDM_DEVREG_VERSION defines the current version. */
+ uint32_t u32Version;
+ /** Device name. */
+ char szName[32];
+ /** The description of the device. The UTF-8 string pointed to shall, like this structure,
+ * remain unchanged from registration till VM destruction. */
+ const char *pszDescription;
+
+ /** Flags, combination of the PDM_USBREG_FLAGS_* \#defines. */
+ RTUINT fFlags;
+ /** Maximum number of instances (per VM). */
+ RTUINT cMaxInstances;
+ /** Size of the instance data. */
+ RTUINT cbInstance;
+
+
+ /**
+ * Construct an USB device instance for a VM.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance data.
+ * If the registration structure is needed, it will be
+ * accessible thru pUsbDev->pReg.
+ * @param iInstance Instance number. Use this to figure out which registers
+ * and such to use. The instance number is also found in
+ * pUsbDev->iInstance, but since it's likely to be
+ * frequently used PDM passes it as parameter.
+ * @param pCfg Configuration node handle for the device. Use this to
+ * obtain the configuration of the device instance. It is
+ * also found in pUsbDev->pCfg, but since it is primary
+ * usage will in this function it is passed as a parameter.
+ * @param pCfgGlobal Handle to the global device configuration. Also found
+ * in pUsbDev->pCfgGlobal.
+ * @remarks This callback is required.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnConstruct,(PPDMUSBINS pUsbIns, int iInstance, PCFGMNODE pCfg, PCFGMNODE pCfgGlobal));
+
+ /**
+ * Destruct an USB device instance.
+ *
+ * Most VM resources are freed by the VM. This callback is provided so that any non-VM
+ * resources can be freed correctly.
+ *
+ * This method will be called regardless of the pfnConstruc result to avoid
+ * complicated failure paths.
+ *
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnDestruct,(PPDMUSBINS pUsbIns));
+
+
+ /**
+ * Init complete notification.
+ *
+ * This can be done to do communication with other devices and other
+ * initialization which requires everything to be in place.
+ *
+ * @returns VBOX status code.
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ * @remarks Not called when hotplugged.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMInitComplete,(PPDMUSBINS pUsbIns));
+
+ /**
+ * VM Power On notification.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVMPowerOn,(PPDMUSBINS pUsbIns));
+
+ /**
+ * VM Reset notification.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVMReset,(PPDMUSBINS pUsbIns));
+
+ /**
+ * VM Suspend notification.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVMSuspend,(PPDMUSBINS pUsbIns));
+
+ /**
+ * VM Resume notification.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVMResume,(PPDMUSBINS pUsbIns));
+
+ /**
+ * VM Power Off notification.
+ *
+ * This is only called when the VMR3PowerOff call is made on a running VM. This
+ * means that there is no notification if the VM was suspended before being
+ * powered of. There will also be no callback when hot plugging devices.
+ *
+ * @param pUsbIns The USB device instance data.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnVMPowerOff,(PPDMUSBINS pUsbIns));
+
+ /**
+ * Called after the constructor when attaching a device at run time.
+ *
+ * This can be used to do tasks normally assigned to pfnInitComplete and/or pfnVMPowerOn.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnHotPlugged,(PPDMUSBINS pUsbIns));
+
+ /**
+ * Called before the destructor when a device is unplugged at run time.
+ *
+ * This can be used to do tasks normally assigned to pfnVMSuspend and/or pfnVMPowerOff.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance data.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnHotUnplugged,(PPDMUSBINS pUsbIns));
+ /**
+ * Driver Attach command.
+ *
+ * This is called to let the USB device attach to a driver for a specified LUN
+ * at runtime. This is not called during VM construction, the device constructor
+ * have to attach to all the available drivers.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance data.
+ * @param iLUN The logical unit which is being detached.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMUSBINS pUsbIns, unsigned iLUN));
+
+ /**
+ * Driver Detach notification.
+ *
+ * This is called when a driver is detaching itself from a LUN of the device.
+ * The device should adjust it's state to reflect this.
+ *
+ * @param pUsbIns The USB device instance data.
+ * @param iLUN The logical unit which is being detached.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnDriverDetach,(PPDMUSBINS pUsbIns, unsigned iLUN));
+
+ /**
+ * Query the base interface of a logical unit.
+ *
+ * @returns VBOX status code.
+ * @param pUsbIns The USB device instance data.
+ * @param iLUN The logicial unit to query.
+ * @param ppBase Where to store the pointer to the base interface of the LUN.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnQueryInterface,(PPDMUSBINS pUsbIns, unsigned iLUN, PPDMIBASE *ppBase));
+
+ /**
+ * Requests the USB device to reset.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param fResetOnLinux A hint to the usb proxy.
+ * Don't use this unless you're the linux proxy device.
+ * @thread Any thread.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUsbReset,(PPDMUSBINS pUsbIns, bool fResetOnLinux));
+
+ /**
+ * Query device and configuration descriptors for the caching and servicing
+ * relevant GET_DESCRIPTOR requests.
+ *
+ * @returns Pointer to the descriptor cache (read-only).
+ * @param pUsbIns The USB device instance.
+ * @remarks Mandatory.
+ */
+ DECLR3CALLBACKMEMBER(PCPDMUSBDESCCACHE, pfnUsbGetDescriptorCache,(PPDMUSBINS pUsbIns));
+
+ /**
+ * SET_CONFIGURATION request.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param bConfigurationValue The bConfigurationValue of the new configuration.
+ * @param pvOldCfgDesc Internal - for the device proxy.
+ * @param pvOldIfState Internal - for the device proxy.
+ * @param pvNewCfgDesc Internal - for the device proxy.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUsbSetConfiguration,(PPDMUSBINS pUsbIns, uint8_t bConfigurationValue,
+ const void *pvOldCfgDesc, const void *pvOldIfState, const void *pvNewCfgDesc));
+
+ /**
+ * SET_INTERFACE request.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param bInterfaceNumber The interface number.
+ * @param bAlternateSetting The alternate setting.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUsbSetInterface,(PPDMUSBINS pUsbIns, uint8_t bInterfaceNumber, uint8_t bAlternateSetting));
+
+ /**
+ * Clears the halted state of an endpoint. (Optional)
+ *
+ * This called when VUSB sees a CLEAR_FEATURE(ENDPOINT_HALT) on request
+ * on the zero pipe.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param uEndpoint The endpoint to clear.
+ * @remarks Optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUsbClearHaltedEndpoint,(PPDMUSBINS pUsbIns, unsigned uEndpoint));
+
+ /**
+ * Allocates an URB.
+ *
+ * This can be used to make use of shared user/kernel mode buffers.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param cbData The size of the data buffer.
+ * @param cTds The number of TDs.
+ * @param enmType The type of URB.
+ * @param ppUrb Where to store the allocated URB.
+ * @remarks Optional.
+ * @remarks Not implemented yet.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUrbNew,(PPDMUSBINS pUsbIns, size_t cbData, size_t cTds, VUSBXFERTYPE enmType, PVUSBURB *ppUrb));
+
+ /**
+ * Queues an URB for processing.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_VUSB_DEVICE_NOT_ATTACHED if the device has been disconnected.
+ * @retval VERR_VUSB_FAILED_TO_QUEUE_URB as a general failure kind of thing.
+ * @retval TBD - document new stuff!
+ *
+ * @param pUsbIns The USB device instance.
+ * @param pUrb The URB to process.
+ * @remarks Mandatory.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUrbQueue,(PPDMUSBINS pUsbIns, PVUSBURB pUrb));
+
+ /**
+ * Cancels an URB.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param pUrb The URB to cancel.
+ * @remarks Mandatory.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnUrbCancel,(PPDMUSBINS pUsbIns, PVUSBURB pUrb));
+
+ /**
+ * Reaps an URB.
+ *
+ * @returns A ripe URB, NULL if none.
+ * @param pUsbIns The USB device instance.
+ * @param cMillies How log to wait for an URB to become ripe.
+ * @remarks Mandatory.
+ */
+ DECLR3CALLBACKMEMBER(PVUSBURB, pfnUrbReap,(PPDMUSBINS pUsbIns, RTMSINTERVAL cMillies));
+
+
+ /** Just some init precaution. Must be set to PDM_USBREG_VERSION. */
+ uint32_t u32TheEnd;
+} PDMUSBREG;
+/** Pointer to a PDM USB Device Structure. */
+typedef PDMUSBREG *PPDMUSBREG;
+/** Const pointer to a PDM USB Device Structure. */
+typedef PDMUSBREG const *PCPDMUSBREG;
+
+/** Current USBREG version number. */
+#define PDM_USBREG_VERSION PDM_VERSION_MAKE(0xeeff, 1, 0)
+
+/** PDM USB Device Flags.
+ * @{ */
+/* none yet */
+/** @} */
+
+
+#ifdef IN_RING3
+
+/**
+ * PDM USB Device API.
+ */
+typedef struct PDMUSBHLP
+{
+ /** Structure version. PDM_USBHLP_VERSION defines the current version. */
+ uint32_t u32Version;
+
+ /**
+ * Attaches a driver (chain) to the USB device.
+ *
+ * The first call for a LUN this will serve as a registartion of the LUN. The pBaseInterface and
+ * the pszDesc string will be registered with that LUN and kept around for PDMR3QueryUSBDeviceLun().
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param iLun The logical unit to attach.
+ * @param pBaseInterface Pointer to the base interface for that LUN. (device side / down)
+ * @param ppBaseInterface Where to store the pointer to the base interface. (driver side / up)
+ * @param pszDesc Pointer to a string describing the LUN. This string must remain valid
+ * for the live of the device instance.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDriverAttach,(PPDMUSBINS pUsbIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc));
+
+ /**
+ * Assert that the current thread is the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pUsbIns The USB device instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertEMT,(PPDMUSBINS pUsbIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Assert that the current thread is NOT the emulation thread.
+ *
+ * @returns True if correct.
+ * @returns False if wrong.
+ * @param pUsbIns The USB device instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine Linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnAssertOther,(PPDMUSBINS pUsbIns, const char *pszFile, unsigned iLine, const char *pszFunction));
+
+ /**
+ * Stops the VM and enters the debugger to look at the guest state.
+ *
+ * Use the PDMUsbDBGFStop() inline function with the RT_SRC_POS macro instead of
+ * invoking this function directly.
+ *
+ * @returns VBox status code which must be passed up to the VMM.
+ * @param pUsbIns The USB device instance.
+ * @param pszFile Filename of the assertion location.
+ * @param iLine The linenumber of the assertion location.
+ * @param pszFunction Function of the assertion location.
+ * @param pszFormat Message. (optional)
+ * @param va Message parameters.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDBGFStopV,(PPDMUSBINS pUsbIns, const char *pszFile, unsigned iLine, const char *pszFunction, const char *pszFormat, va_list va));
+
+ /**
+ * Register a info handler with DBGF,
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param pszName The identifier of the info.
+ * @param pszDesc The description of the info and any arguments the handler may take.
+ * @param pfnHandler The handler function to be called to display the info.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDBGFInfoRegister,(PPDMUSBINS pUsbIns, const char *pszName, const char *pszDesc, PFNDBGFHANDLERUSB pfnHandler));
+
+ /**
+ * Allocate memory which is associated with current VM instance
+ * and automatically freed on it's destruction.
+ *
+ * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
+ * @param pUsbIns The USB device instance.
+ * @param cb Number of bytes to allocate.
+ */
+ DECLR3CALLBACKMEMBER(void *, pfnMMHeapAlloc,(PPDMUSBINS pUsbIns, size_t cb));
+
+ /**
+ * Allocate memory which is associated with current VM instance
+ * and automatically freed on it's destruction. The memory is ZEROed.
+ *
+ * @returns Pointer to allocated memory. The memory is *NOT* zero-ed.
+ * @param pUsbIns The USB device instance.
+ * @param cb Number of bytes to allocate.
+ */
+ DECLR3CALLBACKMEMBER(void *, pfnMMHeapAllocZ,(PPDMUSBINS pUsbIns, size_t cb));
+
+ /**
+ * Create a queue.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param cbItem Size a queue item.
+ * @param cItems Number of items in the queue.
+ * @param cMilliesInterval Number of milliseconds between polling the queue.
+ * If 0 then the emulation thread will be notified whenever an item arrives.
+ * @param pfnCallback The consumer function.
+ * @param pszName The queue base name. The instance number will be
+ * appended automatically.
+ * @param ppQueue Where to store the queue handle on success.
+ * @thread The emulation thread.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPDMQueueCreate,(PPDMUSBINS pUsbIns, RTUINT cbItem, RTUINT cItems, uint32_t cMilliesInterval,
+ PFNPDMQUEUEUSB pfnCallback, const char *pszName, PPDMQUEUE *ppQueue));
+
+ /**
+ * Register a save state data unit.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance.
+ * @param uVersion Data layout version number.
+ * @param cbGuess The approximate amount of data in the unit.
+ * Only for progress indicators.
+ *
+ * @param pfnLivePrep Prepare live save callback, optional.
+ * @param pfnLiveExec Execute live save callback, optional.
+ * @param pfnLiveVote Vote live save callback, optional.
+ *
+ * @param pfnSavePrep Prepare save callback, optional.
+ * @param pfnSaveExec Execute save callback, optional.
+ * @param pfnSaveDone Done save callback, optional.
+ *
+ * @param pfnLoadPrep Prepare load callback, optional.
+ * @param pfnLoadExec Execute load callback, optional.
+ * @param pfnLoadDone Done load callback, optional.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSSMRegister,(PPDMUSBINS pUsbIns, uint32_t uVersion, size_t cbGuess,
+ PFNSSMUSBLIVEPREP pfnLivePrep, PFNSSMUSBLIVEEXEC pfnLiveExec, PFNSSMUSBLIVEVOTE pfnLiveVote,
+ PFNSSMUSBSAVEPREP pfnSavePrep, PFNSSMUSBSAVEEXEC pfnSaveExec, PFNSSMUSBSAVEDONE pfnSaveDone,
+ PFNSSMUSBLOADPREP pfnLoadPrep, PFNSSMUSBLOADEXEC pfnLoadExec, PFNSSMUSBLOADDONE pfnLoadDone));
+
+ /**
+ * Register a STAM sample.
+ *
+ * Use the PDMUsbHlpSTAMRegister wrapper.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param enmVisibility Visibility type specifying whether unused statistics should be visible or not.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ * @param pszName The sample name format string.
+ * @param va Arguments to the format string.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnSTAMRegisterV,(PPDMUSBINS pUsbIns, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
+ STAMUNIT enmUnit, const char *pszDesc, const char *pszName, va_list va));
+
+ /**
+ * Creates a timer.
+ *
+ * @returns VBox status.
+ * @param pUsbIns The USB device instance.
+ * @param enmClock The clock to use on this timer.
+ * @param pfnCallback Callback function.
+ * @param pvUser User argument for the callback.
+ * @param fFlags Flags, see TMTIMER_FLAGS_*.
+ * @param pszDesc Pointer to description string which must stay around
+ * until the timer is fully destroyed (i.e. a bit after TMTimerDestroy()).
+ * @param ppTimer Where to store the timer on success.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnTMTimerCreate,(PPDMUSBINS pUsbIns, TMCLOCK enmClock, PFNTMTIMERUSB pfnCallback, void *pvUser,
+ uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer));
+
+ /**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pUsbIns The USB device instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetErrorV,(PPDMUSBINS pUsbIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
+
+ /**
+ * Set the VM runtime error message
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance.
+ * @param fFlags The action flags. See VMSETRTERR_FLAGS_*.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVMSetRuntimeErrorV,(PPDMUSBINS pUsbIns, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va));
+
+ /**
+ * Gets the VM state.
+ *
+ * @returns VM state.
+ * @param pUsbIns The USB device instance.
+ * @thread Any thread (just keep in mind that it's volatile info).
+ */
+ DECLR3CALLBACKMEMBER(VMSTATE, pfnVMState, (PPDMUSBINS pUsbIns));
+
+ /**
+ * Creates a PDM thread.
+ *
+ * This differs from the RTThreadCreate() API in that PDM takes care of suspending,
+ * resuming, and destroying the thread as the VM state changes.
+ *
+ * @returns VBox status code.
+ * @param pDevIns The device instance.
+ * @param ppThread Where to store the thread 'handle'.
+ * @param pvUser The user argument to the thread function.
+ * @param pfnThread The thread function.
+ * @param pfnWakeup The wakup callback. This is called on the EMT
+ * thread when a state change is pending.
+ * @param cbStack See RTThreadCreate.
+ * @param enmType See RTThreadCreate.
+ * @param pszName See RTThreadCreate.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnThreadCreate,(PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
+ PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName));
+
+ /**
+ * Set up asynchronous handling of a suspend, reset or power off notification.
+ *
+ * This shall only be called when getting the notification. It must be called
+ * for each one.
+ *
+ * @returns VBox status code.
+ * @param pUSBIns The USB device instance.
+ * @param pfnAsyncNotify The callback.
+ * @thread EMT(0)
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSetAsyncNotification, (PPDMUSBINS pUSbIns, PFNPDMUSBASYNCNOTIFY pfnAsyncNotify));
+
+ /**
+ * Notify EMT(0) that the device has completed the asynchronous notification
+ * handling.
+ *
+ * This can be called at any time, spurious calls will simply be ignored.
+ *
+ * @param pUSBIns The USB device instance.
+ * @thread Any
+ */
+ DECLR3CALLBACKMEMBER(void, pfnAsyncNotificationCompleted, (PPDMUSBINS pUsbIns));
+
+ /** Just a safety precaution. */
+ uint32_t u32TheEnd;
+} PDMUSBHLP;
+/** Pointer PDM USB Device API. */
+typedef PDMUSBHLP *PPDMUSBHLP;
+/** Pointer const PDM USB Device API. */
+typedef const PDMUSBHLP *PCPDMUSBHLP;
+
+/** Current USBHLP version number. */
+#define PDM_USBHLP_VERSION PDM_VERSION_MAKE(0xeefe, 2, 0)
+
+#endif /* IN_RING3 */
+
+/**
+ * PDM USB Device Instance.
+ */
+typedef struct PDMUSBINS
+{
+ /** Structure version. PDM_USBINS_VERSION defines the current version. */
+ uint32_t u32Version;
+ /** USB device instance number. */
+ uint32_t iInstance;
+ /** The base interface of the device.
+ * The device constructor initializes this if it has any device level
+ * interfaces to export. To obtain this interface call PDMR3QueryUSBDevice(). */
+ PDMIBASE IBase;
+#if HC_ARCH_BITS == 32
+ uint32_t u32Alignment; /**< Alignment padding. */
+#endif
+
+ /** Internal data. */
+ union
+ {
+#ifdef PDMUSBINSINT_DECLARED
+ PDMUSBINSINT s;
+#endif
+ uint8_t padding[HC_ARCH_BITS == 32 ? 96 : 128];
+ } Internal;
+
+ /** Pointer the PDM USB Device API. */
+ R3PTRTYPE(PCPDMUSBHLP) pHlpR3;
+ /** Pointer to the USB device registration structure. */
+ R3PTRTYPE(PCPDMUSBREG) pReg;
+ /** Configuration handle. */
+ R3PTRTYPE(PCFGMNODE) pCfg;
+ /** The (device) global configuration handle. */
+ R3PTRTYPE(PCFGMNODE) pCfgGlobal;
+ /** Pointer to device instance data. */
+ R3PTRTYPE(void *) pvInstanceDataR3;
+ /** Pointer to the VUSB Device structure.
+ * Internal to VUSB, don't touch.
+ * @todo Moved this to PDMUSBINSINT. */
+ R3PTRTYPE(void *) pvVUsbDev2;
+ /** Device name for using when logging.
+ * The constructor sets this and the destructor frees it. */
+ R3PTRTYPE(char *) pszName;
+ /** Tracing indicator. */
+ uint32_t fTracing;
+ /** The tracing ID of this device. */
+ uint32_t idTracing;
+
+ /** Padding to make achInstanceData aligned at 32 byte boundary. */
+ uint32_t au32Padding[HC_ARCH_BITS == 32 ? 3 : 4];
+
+ /** Device instance data. The size of this area is defined
+ * in the PDMUSBREG::cbInstanceData field. */
+ char achInstanceData[8];
+} PDMUSBINS;
+
+/** Current USBINS version number. */
+#define PDM_USBINS_VERSION PDM_VERSION_MAKE(0xeefd, 2, 0)
+
+/**
+ * Checks the structure versions of the USB device instance and USB device
+ * helpers, returning if they are incompatible.
+ *
+ * This is for use in the constructor.
+ *
+ * @param pUsbIns The USB device instance pointer.
+ */
+#define PDMUSB_CHECK_VERSIONS_RETURN(pUsbIns) \
+ do \
+ { \
+ PPDMUSBINS pUsbInsTypeCheck = (pUsbIns); NOREF(pUsbInsTypeCheck); \
+ AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pUsbIns)->u32Version, PDM_USBINS_VERSION), \
+ ("DevIns=%#x mine=%#x\n", (pUsbIns)->u32Version, PDM_USBINS_VERSION), \
+ VERR_PDM_USBINS_VERSION_MISMATCH); \
+ AssertLogRelMsgReturn(PDM_VERSION_ARE_COMPATIBLE((pUsbIns)->pHlpR3->u32Version, PDM_USBHLP_VERSION), \
+ ("DevHlp=%#x mine=%#x\n", (pUsbIns)->pHlpR3->u32Version, PDM_USBHLP_VERSION), \
+ VERR_PDM_USBHLPR3_VERSION_MISMATCH); \
+ } while (0)
+
+/**
+ * Quietly checks the structure versions of the USB device instance and
+ * USB device helpers, returning if they are incompatible.
+ *
+ * This is for use in the destructor.
+ *
+ * @param pUsbIns The USB device instance pointer.
+ */
+#define PDMUSB_CHECK_VERSIONS_RETURN_QUIET(pUsbIns) \
+ do \
+ { \
+ PPDMUSBINS pUsbInsTypeCheck = (pUsbIns); NOREF(pUsbInsTypeCheck); \
+ if (RT_UNLIKELY(!PDM_VERSION_ARE_COMPATIBLE((pUsbIns)->u32Version, PDM_USBINS_VERSION) )) \
+ return VERR_PDM_USBINS_VERSION_MISMATCH; \
+ if (RT_UNLIKELY(!PDM_VERSION_ARE_COMPATIBLE((pUsbIns)->pHlpR3->u32Version, PDM_USBHLPR3_VERSION) )) \
+ return VERR_PDM_USBHLPR3_VERSION_MISMATCH; \
+ } while (0)
+
+
+/** Converts a pointer to the PDMUSBINS::IBase to a pointer to PDMUSBINS. */
+#define PDMIBASE_2_PDMUSB(pInterface) ( (PPDMUSBINS)((char *)(pInterface) - RT_OFFSETOF(PDMUSBINS, IBase)) )
+
+
+/** @def PDMUSB_ASSERT_EMT
+ * Assert that the current thread is the emulation thread.
+ */
+#ifdef VBOX_STRICT
+# define PDMUSB_ASSERT_EMT(pUsbIns) pUsbIns->pHlpR3->pfnAssertEMT(pUsbIns, __FILE__, __LINE__, __FUNCTION__)
+#else
+# define PDMUSB_ASSERT_EMT(pUsbIns) do { } while (0)
+#endif
+
+/** @def PDMUSB_ASSERT_OTHER
+ * Assert that the current thread is NOT the emulation thread.
+ */
+#ifdef VBOX_STRICT
+# define PDMUSB_ASSERT_OTHER(pUsbIns) pUsbIns->pHlpR3->pfnAssertOther(pUsbIns, __FILE__, __LINE__, __FUNCTION__)
+#else
+# define PDMUSB_ASSERT_OTHER(pUsbIns) do { } while (0)
+#endif
+
+/** @def PDMUSB_SET_ERROR
+ * Set the VM error. See PDMUsbHlpVMSetError() for printf like message
+ * formatting.
+ */
+#define PDMUSB_SET_ERROR(pUsbIns, rc, pszError) \
+ PDMUsbHlpVMSetError(pUsbIns, rc, RT_SRC_POS, "%s", pszError)
+
+/** @def PDMUSB_SET_RUNTIME_ERROR
+ * Set the VM runtime error. See PDMUsbHlpVMSetRuntimeError() for printf like
+ * message formatting.
+ */
+#define PDMUSB_SET_RUNTIME_ERROR(pUsbIns, fFlags, pszErrorId, pszError) \
+ PDMUsbHlpVMSetRuntimeError(pUsbIns, fFlags, pszErrorId, "%s", pszError)
+
+
+#ifdef IN_RING3
+
+/**
+ * @copydoc PDMUSBHLP::pfnDriverAttach
+ */
+DECLINLINE(int) PDMUsbHlpDriverAttach(PPDMUSBINS pUsbIns, RTUINT iLun, PPDMIBASE pBaseInterface, PPDMIBASE *ppBaseInterface, const char *pszDesc)
+{
+ return pUsbIns->pHlpR3->pfnDriverAttach(pUsbIns, iLun, pBaseInterface, ppBaseInterface, pszDesc);
+}
+
+/**
+ * VBOX_STRICT wrapper for pHlpR3->pfnDBGFStopV.
+ *
+ * @returns VBox status code which must be passed up to the VMM.
+ * @param pUsbIns Device instance.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Message. (optional)
+ * @param ... Message parameters.
+ */
+DECLINLINE(int) PDMUsbDBGFStop(PPDMUSBINS pUsbIns, RT_SRC_POS_DECL, const char *pszFormat, ...)
+{
+#ifdef VBOX_STRICT
+ int rc;
+ va_list va;
+ va_start(va, pszFormat);
+ rc = pUsbIns->pHlpR3->pfnDBGFStopV(pUsbIns, RT_SRC_POS_ARGS, pszFormat, va);
+ va_end(va);
+ return rc;
+#else
+ NOREF(pUsbIns);
+ NOREF(pszFile);
+ NOREF(iLine);
+ NOREF(pszFunction);
+ NOREF(pszFormat);
+ return VINF_SUCCESS;
+#endif
+}
+
+/**
+ * @copydoc PDMUSBHLP::pfnVMState
+ */
+DECLINLINE(VMSTATE) PDMUsbHlpVMState(PPDMUSBINS pUsbIns)
+{
+ return pUsbIns->pHlpR3->pfnVMState(pUsbIns);
+}
+
+/**
+ * @copydoc PDMUSBHLP::pfnThreadCreate
+ */
+DECLINLINE(int) PDMUsbHlpThreadCreate(PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
+ PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
+{
+ return pUsbIns->pHlpR3->pfnThreadCreate(pUsbIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName);
+}
+
+
+/**
+ * @copydoc PDMUSBHLP::pfnSetAsyncNotification
+ */
+DECLINLINE(int) PDMUsbHlpSetAsyncNotification(PPDMUSBINS pUsbIns, PFNPDMUSBASYNCNOTIFY pfnAsyncNotify)
+{
+ return pUsbIns->pHlpR3->pfnSetAsyncNotification(pUsbIns, pfnAsyncNotify);
+}
+
+/**
+ * @copydoc PDMUSBHLP::pfnAsyncNotificationCompleted
+ */
+DECLINLINE(void) PDMUsbHlpAsyncNotificationCompleted(PPDMUSBINS pUsbIns)
+{
+ pUsbIns->pHlpR3->pfnAsyncNotificationCompleted(pUsbIns);
+}
+
+/**
+ * Set the VM error message
+ *
+ * @returns rc.
+ * @param pUsbIns The USB device instance.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL Use RT_SRC_POS.
+ * @param pszFormat Error message format string.
+ * @param ... Error message arguments.
+ */
+DECLINLINE(int) PDMUsbHlpVMSetError(PPDMUSBINS pUsbIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
+{
+ va_list va;
+ va_start(va, pszFormat);
+ rc = pUsbIns->pHlpR3->pfnVMSetErrorV(pUsbIns, rc, RT_SRC_POS_ARGS, pszFormat, va);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * @copydoc PDMUSBHLP::pfnMMHeapAlloc
+ */
+DECLINLINE(void *) PDMUsbHlpMMHeapAlloc(PPDMUSBINS pUsbIns, size_t cb)
+{
+ return pUsbIns->pHlpR3->pfnMMHeapAlloc(pUsbIns, cb);
+}
+
+/**
+ * @copydoc PDMUSBHLP::pfnMMHeapAllocZ
+ */
+DECLINLINE(void *) PDMUsbHlpMMHeapAllocZ(PPDMUSBINS pUsbIns, size_t cb)
+{
+ return pUsbIns->pHlpR3->pfnMMHeapAllocZ(pUsbIns, cb);
+}
+
+/**
+ * Frees memory allocated by PDMUsbHlpMMHeapAlloc or PDMUsbHlpMMHeapAllocZ.
+ *
+ * @param pUsbIns The USB device instance.
+ * @param pv The memory to free. NULL is fine.
+ */
+DECLINLINE(void) PDMUsbHlpMMHeapFree(PPDMUSBINS pUsbIns, void *pv)
+{
+ NOREF(pUsbIns);
+ MMR3HeapFree(pv);
+}
+
+/**
+ * @copydoc PDMUSBHLP::pfnTMTimerCreate
+ */
+DECLINLINE(int) PDMUsbHlpTMTimerCreate(PPDMUSBINS pUsbIns, TMCLOCK enmClock, PFNTMTIMERUSB pfnCallback, void *pvUser,
+ uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer)
+{
+ return pUsbIns->pHlpR3->pfnTMTimerCreate(pUsbIns, enmClock, pfnCallback, pvUser, fFlags, pszDesc, ppTimer);
+}
+
+#endif /* IN_RING3 */
+
+
+
+/** Pointer to callbacks provided to the VBoxUsbRegister() call. */
+typedef const struct PDMUSBREGCB *PCPDMUSBREGCB;
+
+/**
+ * Callbacks for VBoxUSBDeviceRegister().
+ */
+typedef struct PDMUSBREGCB
+{
+ /** Interface version.
+ * This is set to PDM_USBREG_CB_VERSION. */
+ uint32_t u32Version;
+
+ /**
+ * Registers a device with the current VM instance.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param pReg Pointer to the USB device registration record.
+ * This data must be permanent and readonly.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnRegister,(PCPDMUSBREGCB pCallbacks, PCPDMUSBREG pReg));
+} PDMUSBREGCB;
+
+/** Current version of the PDMUSBREGCB structure. */
+#define PDM_USBREG_CB_VERSION PDM_VERSION_MAKE(0xeefc, 1, 0)
+
+
+/**
+ * The VBoxUsbRegister callback function.
+ *
+ * PDM will invoke this function after loading a USB device module and letting
+ * the module decide which devices to register and how to handle conflicts.
+ *
+ * @returns VBox status code.
+ * @param pCallbacks Pointer to the callback table.
+ * @param u32Version VBox version number.
+ */
+typedef DECLCALLBACK(int) FNPDMVBOXUSBREGISTER(PCPDMUSBREGCB pCallbacks, uint32_t u32Version);
+
+VMMR3DECL(int) PDMR3USBCreateProxyDevice(PVM pVM, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend,
+ uint32_t iUsbVersion, uint32_t fMaskedIfs);
+VMMR3DECL(int) PDMR3USBDetachDevice(PVM pVM, PCRTUUID pUuid);
+VMMR3DECL(bool) PDMR3USBHasHub(PVM pVM);
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/pgm.h b/include/VBox/vmm/pgm.h
new file mode 100644
index 00000000..5d8b5f0d
--- /dev/null
+++ b/include/VBox/vmm/pgm.h
@@ -0,0 +1,586 @@
+/** @file
+ * PGM - Page Monitor / Monitor.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_pgm_h
+#define ___VBox_vmm_pgm_h
+
+#include <VBox/types.h>
+#include <VBox/sup.h>
+#include <VBox/vmm/vmapi.h>
+#include <VBox/vmm/gmm.h> /* for PGMMREGISTERSHAREDMODULEREQ */
+#include <iprt/x86.h>
+#include <VBox/VMMDev.h> /* for VMMDEVSHAREDREGIONDESC */
+#include <VBox/param.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_pgm The Page Monitor / Manager API
+ * @{
+ */
+
+/**
+ * FNPGMRELOCATE callback mode.
+ */
+typedef enum PGMRELOCATECALL
+{
+ /** The callback is for checking if the suggested address is suitable. */
+ PGMRELOCATECALL_SUGGEST = 1,
+ /** The callback is for executing the relocation. */
+ PGMRELOCATECALL_RELOCATE
+} PGMRELOCATECALL;
+
+
+/**
+ * Callback function which will be called when PGM is trying to find
+ * a new location for the mapping.
+ *
+ * The callback is called in two modes, 1) the check mode and 2) the relocate mode.
+ * In 1) the callback should say if it objects to a suggested new location. If it
+ * accepts the new location, it is called again for doing it's relocation.
+ *
+ *
+ * @returns true if the location is ok.
+ * @returns false if another location should be found.
+ * @param GCPtrOld The old virtual address.
+ * @param GCPtrNew The new virtual address.
+ * @param enmMode Used to indicate the callback mode.
+ * @param pvUser User argument.
+ * @remark The return value is no a failure indicator, it's an acceptance
+ * indicator. Relocation can not fail!
+ */
+typedef DECLCALLBACK(bool) FNPGMRELOCATE(PVM pVM, RTGCPTR GCPtrOld, RTGCPTR GCPtrNew, PGMRELOCATECALL enmMode, void *pvUser);
+/** Pointer to a relocation callback function. */
+typedef FNPGMRELOCATE *PFNPGMRELOCATE;
+
+
+/**
+ * Physical page access handler type.
+ */
+typedef enum PGMPHYSHANDLERTYPE
+{
+ /** MMIO range. Pages are not present, all access is done in interpreter or recompiler. */
+ PGMPHYSHANDLERTYPE_MMIO = 1,
+ /** Handler all write access to a physical page range. */
+ PGMPHYSHANDLERTYPE_PHYSICAL_WRITE,
+ /** Handler all access to a physical page range. */
+ PGMPHYSHANDLERTYPE_PHYSICAL_ALL
+
+} PGMPHYSHANDLERTYPE;
+
+/**
+ * \#PF Handler callback for physical access handler ranges in RC.
+ *
+ * @returns VBox status code (appropriate for RC return).
+ * @param pVM VM Handle.
+ * @param uErrorCode CPU Error code.
+ * @param pRegFrame Trap register frame.
+ * NULL on DMA and other non CPU access.
+ * @param pvFault The fault address (cr2).
+ * @param GCPhysFault The GC physical address corresponding to pvFault.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNPGMRCPHYSHANDLER(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
+/** Pointer to PGM access callback. */
+typedef FNPGMRCPHYSHANDLER *PFNPGMRCPHYSHANDLER;
+
+/**
+ * \#PF Handler callback for physical access handler ranges in R0.
+ *
+ * @returns VBox status code (appropriate for R0 return).
+ * @param pVM VM Handle.
+ * @param uErrorCode CPU Error code.
+ * @param pRegFrame Trap register frame.
+ * NULL on DMA and other non CPU access.
+ * @param pvFault The fault address (cr2).
+ * @param GCPhysFault The GC physical address corresponding to pvFault.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNPGMR0PHYSHANDLER(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
+/** Pointer to PGM access callback. */
+typedef FNPGMR0PHYSHANDLER *PFNPGMR0PHYSHANDLER;
+
+/**
+ * Guest Access type
+ */
+typedef enum PGMACCESSTYPE
+{
+ /** Read access. */
+ PGMACCESSTYPE_READ = 1,
+ /** Write access. */
+ PGMACCESSTYPE_WRITE
+} PGMACCESSTYPE;
+
+/**
+ * \#PF Handler callback for physical access handler ranges (MMIO among others) in HC.
+ *
+ * The handler can not raise any faults, it's mainly for monitoring write access
+ * to certain pages.
+ *
+ * @returns VINF_SUCCESS if the handler have carried out the operation.
+ * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
+ * @param pVM VM Handle.
+ * @param GCPhys The physical address the guest is writing to.
+ * @param pvPhys The HC mapping of that address.
+ * @param pvBuf What the guest is reading/writing.
+ * @param cbBuf How much it's reading/writing.
+ * @param enmAccessType The access type.
+ * @param pvUser User argument.
+ *
+ * @todo Add pVCpu, possibly replacing pVM.
+ */
+typedef DECLCALLBACK(int) FNPGMR3PHYSHANDLER(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
+/** Pointer to PGM access callback. */
+typedef FNPGMR3PHYSHANDLER *PFNPGMR3PHYSHANDLER;
+
+
+/**
+ * Virtual access handler type.
+ */
+typedef enum PGMVIRTHANDLERTYPE
+{
+ /** Write access handled. */
+ PGMVIRTHANDLERTYPE_WRITE = 1,
+ /** All access handled. */
+ PGMVIRTHANDLERTYPE_ALL,
+ /** Hypervisor write access handled.
+ * This is used to catch the guest trying to write to LDT, TSS and any other
+ * system structure which the brain dead intel guys let unprivilegde code find. */
+ PGMVIRTHANDLERTYPE_HYPERVISOR
+} PGMVIRTHANDLERTYPE;
+
+/**
+ * \#PF Handler callback for virtual access handler ranges, RC.
+ *
+ * Important to realize that a physical page in a range can have aliases, and
+ * for ALL and WRITE handlers these will also trigger.
+ *
+ * @returns VBox status code (appropriate for GC return).
+ * @param pVM VM Handle.
+ * @param uErrorCode CPU Error code.
+ * @param pRegFrame Trap register frame.
+ * @param pvFault The fault address (cr2).
+ * @param pvRange The base address of the handled virtual range.
+ * @param offRange The offset of the access into this range.
+ * (If it's a EIP range this is the EIP, if not it's pvFault.)
+ * @todo Add pVCpu, possibly replacing pVM.
+ */
+typedef DECLCALLBACK(int) FNPGMRCVIRTHANDLER(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPTR pvRange, uintptr_t offRange);
+/** Pointer to PGM access callback. */
+typedef FNPGMRCVIRTHANDLER *PFNPGMRCVIRTHANDLER;
+
+/**
+ * \#PF Handler callback for virtual access handler ranges, R3.
+ *
+ * Important to realize that a physical page in a range can have aliases, and
+ * for ALL and WRITE handlers these will also trigger.
+ *
+ * @returns VINF_SUCCESS if the handler have carried out the operation.
+ * @returns VINF_PGM_HANDLER_DO_DEFAULT if the caller should carry out the access operation.
+ * @param pVM VM Handle.
+ * @param GCPtr The virtual address the guest is writing to. (not correct if it's an alias!)
+ * @param pvPtr The HC mapping of that address.
+ * @param pvBuf What the guest is reading/writing.
+ * @param cbBuf How much it's reading/writing.
+ * @param enmAccessType The access type.
+ * @param pvUser User argument.
+ * @todo Add pVCpu, possibly replacing pVM.
+ */
+typedef DECLCALLBACK(int) FNPGMR3VIRTHANDLER(PVM pVM, RTGCPTR GCPtr, void *pvPtr, void *pvBuf, size_t cbBuf, PGMACCESSTYPE enmAccessType, void *pvUser);
+/** Pointer to PGM access callback. */
+typedef FNPGMR3VIRTHANDLER *PFNPGMR3VIRTHANDLER;
+
+
+/**
+ * \#PF Handler callback for invalidation of virtual access handler ranges.
+ *
+ * @param pVM VM Handle.
+ * @param GCPtr The virtual address the guest has changed.
+ */
+typedef DECLCALLBACK(int) FNPGMR3VIRTINVALIDATE(PVM pVM, RTGCPTR GCPtr);
+/** Pointer to PGM invalidation callback. */
+typedef FNPGMR3VIRTINVALIDATE *PFNPGMR3VIRTINVALIDATE;
+
+/**
+ * PGMR3PhysEnumDirtyFTPages callback for syncing dirty physical pages
+ *
+ * @param pVM VM Handle.
+ * @param GCPhys GC physical address
+ * @param pRange HC virtual address of the page(s)
+ * @param cbRange Size of the dirty range in bytes.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNPGMENUMDIRTYFTPAGES(PVM pVM, RTGCPHYS GCPhys, uint8_t *pRange, unsigned cbRange, void *pvUser);
+/** Pointer to PGMR3PhysEnumDirtyFTPages callback. */
+typedef FNPGMENUMDIRTYFTPAGES *PFNPGMENUMDIRTYFTPAGES;
+
+/**
+ * Paging mode.
+ */
+typedef enum PGMMODE
+{
+ /** The usual invalid value. */
+ PGMMODE_INVALID = 0,
+ /** Real mode. */
+ PGMMODE_REAL,
+ /** Protected mode, no paging. */
+ PGMMODE_PROTECTED,
+ /** 32-bit paging. */
+ PGMMODE_32_BIT,
+ /** PAE paging. */
+ PGMMODE_PAE,
+ /** PAE paging with NX enabled. */
+ PGMMODE_PAE_NX,
+ /** 64-bit AMD paging (long mode). */
+ PGMMODE_AMD64,
+ /** 64-bit AMD paging (long mode) with NX enabled. */
+ PGMMODE_AMD64_NX,
+ /** Nested paging mode (shadow only; guest physical to host physical). */
+ PGMMODE_NESTED,
+ /** Extended paging (Intel) mode. */
+ PGMMODE_EPT,
+ /** The max number of modes */
+ PGMMODE_MAX,
+ /** 32bit hackishness. */
+ PGMMODE_32BIT_HACK = 0x7fffffff
+} PGMMODE;
+
+/** Macro for checking if the guest is using paging.
+ * @param enmMode PGMMODE_*.
+ * @remark ASSUMES certain order of the PGMMODE_* values.
+ */
+#define PGMMODE_WITH_PAGING(enmMode) ((enmMode) >= PGMMODE_32_BIT)
+
+/** Macro for checking if it's one of the long mode modes.
+ * @param enmMode PGMMODE_*.
+ */
+#define PGMMODE_IS_LONG_MODE(enmMode) ((enmMode) == PGMMODE_AMD64_NX || (enmMode) == PGMMODE_AMD64)
+
+/**
+ * Is the ROM mapped (true) or is the shadow RAM mapped (false).
+ *
+ * @returns boolean.
+ * @param enmProt The PGMROMPROT value, must be valid.
+ */
+#define PGMROMPROT_IS_ROM(enmProt) \
+ ( (enmProt) == PGMROMPROT_READ_ROM_WRITE_IGNORE \
+ || (enmProt) == PGMROMPROT_READ_ROM_WRITE_RAM )
+
+
+
+VMMDECL(bool) PGMIsLockOwner(PVM pVM);
+
+VMMDECL(int) PGMRegisterStringFormatTypes(void);
+VMMDECL(void) PGMDeregisterStringFormatTypes(void);
+VMMDECL(RTHCPHYS) PGMGetHyperCR3(PVMCPU pVCpu);
+VMMDECL(RTHCPHYS) PGMGetNestedCR3(PVMCPU pVCpu, PGMMODE enmShadowMode);
+VMMDECL(RTHCPHYS) PGMGetInterHCCR3(PVM pVM);
+VMMDECL(RTHCPHYS) PGMGetInterRCCR3(PVM pVM, PVMCPU pVCpu);
+VMMDECL(RTHCPHYS) PGMGetInter32BitCR3(PVM pVM);
+VMMDECL(RTHCPHYS) PGMGetInterPaeCR3(PVM pVM);
+VMMDECL(RTHCPHYS) PGMGetInterAmd64CR3(PVM pVM);
+VMMDECL(int) PGMTrap0eHandler(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault);
+VMMDECL(int) PGMPrefetchPage(PVMCPU pVCpu, RTGCPTR GCPtrPage);
+VMMDECL(int) PGMVerifyAccess(PVMCPU pVCpu, RTGCPTR Addr, uint32_t cbSize, uint32_t fAccess);
+VMMDECL(int) PGMIsValidAccess(PVMCPU pVCpu, RTGCPTR Addr, uint32_t cbSize, uint32_t fAccess);
+VMMDECL(VBOXSTRICTRC) PGMInterpretInstruction(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault);
+VMMDECL(int) PGMMap(PVM pVM, RTGCPTR GCPtr, RTHCPHYS HCPhys, uint32_t cbPages, unsigned fFlags);
+VMMDECL(int) PGMMapGetPage(PVM pVM, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys);
+VMMDECL(int) PGMMapSetPage(PVM pVM, RTGCPTR GCPtr, uint64_t cb, uint64_t fFlags);
+VMMDECL(int) PGMMapModifyPage(PVM pVM, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
+#ifndef IN_RING0
+VMMDECL(bool) PGMMapHasConflicts(PVM pVM);
+#endif
+#ifdef VBOX_STRICT
+VMMDECL(void) PGMMapCheck(PVM pVM);
+#endif
+VMMDECL(int) PGMShwGetPage(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys);
+VMMDECL(int) PGMShwMakePageReadonly(PVMCPU pVCpu, RTGCPTR GCPtr, uint32_t fFlags);
+VMMDECL(int) PGMShwMakePageWritable(PVMCPU pVCpu, RTGCPTR GCPtr, uint32_t fFlags);
+VMMDECL(int) PGMShwMakePageNotPresent(PVMCPU pVCpu, RTGCPTR GCPtr, uint32_t fFlags);
+/** @name Flags for PGMShwMakePageReadonly, PGMShwMakePageWritable and
+ * PGMShwMakePageNotPresent
+ * @{ */
+/** The call is from an access handler for dealing with the a faulting write
+ * operation. The virtual address is within the same page. */
+#define PGM_MK_PG_IS_WRITE_FAULT RT_BIT(0)
+/** The page is an MMIO2. */
+#define PGM_MK_PG_IS_MMIO2 RT_BIT(1)
+/** @}*/
+VMMDECL(int) PGMGstGetPage(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys);
+VMMDECL(bool) PGMGstIsPagePresent(PVMCPU pVCpu, RTGCPTR GCPtr);
+VMMDECL(int) PGMGstSetPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags);
+VMMDECL(int) PGMGstModifyPage(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cb, uint64_t fFlags, uint64_t fMask);
+VMM_INT_DECL(int) PGMGstGetPaePdpes(PVMCPU pVCpu, PX86PDPE paPdpes);
+VMM_INT_DECL(int) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes);
+
+VMMDECL(int) PGMInvalidatePage(PVMCPU pVCpu, RTGCPTR GCPtrPage);
+VMMDECL(int) PGMFlushTLB(PVMCPU pVCpu, uint64_t cr3, bool fGlobal);
+VMMDECL(int) PGMSyncCR3(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal);
+VMMDECL(int) PGMUpdateCR3(PVMCPU pVCpu, uint64_t cr3);
+VMMDECL(int) PGMChangeMode(PVMCPU pVCpu, uint64_t cr0, uint64_t cr4, uint64_t efer);
+VMMDECL(PGMMODE) PGMGetGuestMode(PVMCPU pVCpu);
+VMMDECL(PGMMODE) PGMGetShadowMode(PVMCPU pVCpu);
+VMMDECL(PGMMODE) PGMGetHostMode(PVM pVM);
+VMMDECL(const char *) PGMGetModeName(PGMMODE enmMode);
+VMM_INT_DECL(void) PGMNotifyNxeChanged(PVMCPU pVCpu, bool fNxe);
+VMMDECL(bool) PGMHasDirtyPages(PVM pVM);
+VMMDECL(int) PGMHandlerPhysicalRegisterEx(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
+ R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
+ R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0, RTR0PTR pvUserR0,
+ RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC, RTRCPTR pvUserRC,
+ R3PTRTYPE(const char *) pszDesc);
+VMMDECL(int) PGMHandlerPhysicalModify(PVM pVM, RTGCPHYS GCPhysCurrent, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast);
+VMMDECL(int) PGMHandlerPhysicalDeregister(PVM pVM, RTGCPHYS GCPhys);
+VMMDECL(int) PGMHandlerPhysicalChangeCallbacks(PVM pVM, RTGCPHYS GCPhys,
+ R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
+ R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0, RTR0PTR pvUserR0,
+ RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC, RTRCPTR pvUserRC,
+ R3PTRTYPE(const char *) pszDesc);
+VMMDECL(int) PGMHandlerPhysicalSplit(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysSplit);
+VMMDECL(int) PGMHandlerPhysicalJoin(PVM pVM, RTGCPHYS GCPhys1, RTGCPHYS GCPhys2);
+VMMDECL(int) PGMHandlerPhysicalPageTempOff(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage);
+VMMDECL(int) PGMHandlerPhysicalPageAlias(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage, RTGCPHYS GCPhysPageRemap);
+VMMDECL(int) PGMHandlerPhysicalPageAliasHC(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage, RTHCPHYS HCPhysPageRemap);
+VMMDECL(int) PGMHandlerPhysicalReset(PVM pVM, RTGCPHYS GCPhys);
+VMMDECL(bool) PGMHandlerPhysicalIsRegistered(PVM pVM, RTGCPHYS GCPhys);
+VMMDECL(bool) PGMHandlerVirtualIsRegistered(PVM pVM, RTGCPTR GCPtr);
+VMMDECL(bool) PGMPhysIsA20Enabled(PVMCPU pVCpu);
+VMMDECL(bool) PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys);
+VMMDECL(bool) PGMPhysIsGCPhysNormal(PVM pVM, RTGCPHYS GCPhys);
+VMMDECL(int) PGMPhysGCPtr2GCPhys(PVMCPU pVCpu, RTGCPTR GCPtr, PRTGCPHYS pGCPhys);
+VMMDECL(void) PGMPhysReleasePageMappingLock(PVM pVM, PPGMPAGEMAPLOCK pLock);
+VMMDECL(int) PGMPhysRead(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
+VMMDECL(int) PGMPhysWrite(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
+VMMDECL(int) PGMPhysSimpleReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb);
+VMMDECL(int) PGMPhysSimpleWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb);
+VMMDECL(int) PGMPhysSimpleReadGCPtr(PVMCPU pVCpu, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
+VMMDECL(int) PGMPhysSimpleWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb);
+VMMDECL(int) PGMPhysReadGCPtr(PVMCPU pVCpu, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
+VMMDECL(int) PGMPhysWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb);
+VMMDECL(int) PGMPhysSimpleDirtyWriteGCPtr(PVMCPU pVCpu, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb);
+VMMDECL(int) PGMPhysInterpretedRead(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
+VMMDECL(int) PGMPhysInterpretedReadNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCUINTPTR GCPtrSrc, size_t cb, bool fRaiseTrap);
+VMMDECL(int) PGMPhysInterpretedWriteNoHandlers(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, bool fRaiseTrap);
+VMM_INT_DECL(int) PGMPhysIemGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable, bool fByPassHandlers, void **ppv, PPGMPAGEMAPLOCK pLock);
+#ifdef VBOX_STRICT
+VMMDECL(unsigned) PGMAssertHandlerAndFlagsInSync(PVM pVM);
+VMMDECL(unsigned) PGMAssertNoMappingConflicts(PVM pVM);
+VMMDECL(unsigned) PGMAssertCR3(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4);
+#endif /* VBOX_STRICT */
+
+#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
+VMMDECL(void) PGMRZDynMapStartAutoSet(PVMCPU pVCpu);
+VMMDECL(void) PGMRZDynMapReleaseAutoSet(PVMCPU pVCpu);
+VMMDECL(void) PGMRZDynMapFlushAutoSet(PVMCPU pVCpu);
+VMMDECL(uint32_t) PGMRZDynMapPushAutoSubset(PVMCPU pVCpu);
+VMMDECL(void) PGMRZDynMapPopAutoSubset(PVMCPU pVCpu, uint32_t iPrevSubset);
+#endif
+
+VMMDECL(int) PGMSetLargePageUsage(PVM pVM, bool fUseLargePages);
+
+/**
+ * Query large page usage state
+ *
+ * @returns 0 - disabled, 1 - enabled
+ * @param pVM The VM to operate on.
+ */
+#define PGMIsUsingLargePages(pVM) ((pVM)->fUseLargePages)
+
+
+#ifdef IN_RC
+/** @defgroup grp_pgm_gc The PGM Guest Context API
+ * @ingroup grp_pgm
+ * @{
+ */
+VMMRCDECL(int) PGMRCDynMapInit(PVM pVM);
+/** @} */
+#endif /* IN_RC */
+
+
+#ifdef IN_RING0
+/** @defgroup grp_pgm_r0 The PGM Host Context Ring-0 API
+ * @ingroup grp_pgm
+ * @{
+ */
+VMMR0_INT_DECL(int) PGMR0PhysAllocateHandyPages(PVM pVM, PVMCPU pVCpu);
+VMMR0_INT_DECL(int) PGMR0PhysFlushHandyPages(PVM pVM, PVMCPU pVCpu);
+VMMR0_INT_DECL(int) PGMR0PhysAllocateLargeHandyPage(PVM pVM, PVMCPU pVCpu);
+VMMR0_INT_DECL(int) PGMR0PhysSetupIommu(PVM pVM);
+VMMR0DECL(int) PGMR0SharedModuleCheck(PVM pVM, PGVM pGVM, VMCPUID idCpu, PGMMSHAREDMODULE pModule, PCRTGCPTR64 paRegionsGCPtrs);
+VMMR0DECL(int) PGMR0Trap0eHandlerNestedPaging(PVM pVM, PVMCPU pVCpu, PGMMODE enmShwPagingMode, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPHYS pvFault);
+VMMR0DECL(VBOXSTRICTRC) PGMR0Trap0eHandlerNPMisconfig(PVM pVM, PVMCPU pVCpu, PGMMODE enmShwPagingMode, PCPUMCTXCORE pRegFrame, RTGCPHYS GCPhysFault, uint32_t uErr);
+# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
+VMMR0DECL(int) PGMR0DynMapInit(void);
+VMMR0DECL(void) PGMR0DynMapTerm(void);
+VMMR0DECL(int) PGMR0DynMapInitVM(PVM pVM);
+VMMR0DECL(void) PGMR0DynMapTermVM(PVM pVM);
+VMMR0DECL(int) PGMR0DynMapAssertIntegrity(void);
+VMMR0DECL(bool) PGMR0DynMapStartOrMigrateAutoSet(PVMCPU pVCpu);
+VMMR0DECL(void) PGMR0DynMapMigrateAutoSet(PVMCPU pVCpu);
+# endif
+/** @} */
+#endif /* IN_RING0 */
+
+
+
+#ifdef IN_RING3
+/** @defgroup grp_pgm_r3 The PGM Host Context Ring-3 API
+ * @ingroup grp_pgm
+ * @{
+ */
+VMMR3DECL(int) PGMR3Init(PVM pVM);
+VMMR3DECL(int) PGMR3InitDynMap(PVM pVM);
+VMMR3DECL(int) PGMR3InitFinalize(PVM pVM);
+VMMR3_INT_DECL(int) PGMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
+VMMR3DECL(void) PGMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3DECL(void) PGMR3ResetUnpluggedCpu(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(void) PGMR3Reset(PVM pVM);
+VMMR3DECL(int) PGMR3Term(PVM pVM);
+VMMR3DECL(int) PGMR3LockCall(PVM pVM);
+VMMR3DECL(int) PGMR3ChangeMode(PVM pVM, PVMCPU pVCpu, PGMMODE enmGuestMode);
+
+VMMR3DECL(int) PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, const char *pszDesc);
+VMMR3DECL(int) PGMR3PhysChangeMemBalloon(PVM pVM, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage);
+VMMR3DECL(int) PGMR3PhysWriteProtectRAM(PVM pVM);
+VMMR3DECL(int) PGMR3PhysEnumDirtyFTPages(PVM pVM, PFNPGMENUMDIRTYFTPAGES pfnEnum, void *pvUser);
+VMMR3DECL(uint32_t) PGMR3PhysGetRamRangeCount(PVM pVM);
+VMMR3DECL(int) PGMR3PhysGetRange(PVM pVM, uint32_t iRange, PRTGCPHYS pGCPhysStart, PRTGCPHYS pGCPhysLast,
+ const char **ppszDesc, bool *pfIsMmio);
+VMMR3DECL(int) PGMR3QueryMemoryStats(PVM pVM, uint64_t *pcbTotalMem, uint64_t *pcbPrivateMem, uint64_t *pcbSharedMem, uint64_t *pcbZeroMem);
+VMMR3DECL(int) PGMR3QueryGlobalMemoryStats(PVM pVM, uint64_t *pcbAllocMem, uint64_t *pcbFreeMem, uint64_t *pcbBallonedMem, uint64_t *pcbSharedMem);
+
+VMMR3DECL(int) PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
+ R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
+ R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnHandlerR0, RTR0PTR pvUserR0,
+ RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnHandlerRC, RTRCPTR pvUserRC,
+ R3PTRTYPE(const char *) pszDesc);
+VMMR3DECL(int) PGMR3PhysMMIODeregister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
+VMMR3DECL(int) PGMR3PhysMMIO2Register(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS cb, uint32_t fFlags, void **ppv, const char *pszDesc);
+VMMR3DECL(int) PGMR3PhysMMIO2Deregister(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion);
+VMMR3DECL(int) PGMR3PhysMMIO2Map(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
+VMMR3DECL(int) PGMR3PhysMMIO2Unmap(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS GCPhys);
+VMMR3DECL(bool) PGMR3PhysMMIO2IsBase(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys);
+VMMR3DECL(int) PGMR3PhysMMIO2GetHCPhys(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, PRTHCPHYS pHCPhys);
+VMMR3DECL(int) PGMR3PhysMMIO2MapKernel(PVM pVM, PPDMDEVINS pDevIns, uint32_t iRegion, RTGCPHYS off, RTGCPHYS cb, const char *pszDesc, PRTR0PTR pR0Ptr);
+
+/** @name PGMR3PhysRegisterRom flags.
+ * @{ */
+/** Inidicates that ROM shadowing should be enabled. */
+#define PGMPHYS_ROM_FLAGS_SHADOWED RT_BIT_32(0)
+/** Indicates that what pvBinary points to won't go away
+ * and can be used for strictness checks. */
+#define PGMPHYS_ROM_FLAGS_PERMANENT_BINARY RT_BIT_32(1)
+/** @} */
+
+VMMR3DECL(int) PGMR3PhysRomRegister(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,
+ const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc);
+VMMR3DECL(int) PGMR3PhysRomProtect(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, PGMROMPROT enmProt);
+VMMR3DECL(int) PGMR3PhysRegister(PVM pVM, void *pvRam, RTGCPHYS GCPhys, size_t cb, unsigned fFlags, const SUPPAGE *paPages, const char *pszDesc);
+VMMDECL(void) PGMR3PhysSetA20(PVMCPU pVCpu, bool fEnable);
+/** @name PGMR3MapPT flags.
+ * @{ */
+/** The mapping may be unmapped later. The default is permanent mappings. */
+#define PGMR3MAPPT_FLAGS_UNMAPPABLE RT_BIT(0)
+/** @} */
+VMMR3DECL(int) PGMR3MapPT(PVM pVM, RTGCPTR GCPtr, uint32_t cb, uint32_t fFlags, PFNPGMRELOCATE pfnRelocate, void *pvUser, const char *pszDesc);
+VMMR3DECL(int) PGMR3UnmapPT(PVM pVM, RTGCPTR GCPtr);
+VMMR3DECL(int) PGMR3FinalizeMappings(PVM pVM);
+VMMR3DECL(int) PGMR3MappingsDisable(PVM pVM);
+VMMR3DECL(int) PGMR3MappingsSize(PVM pVM, uint32_t *pcb);
+VMMR3DECL(int) PGMR3MappingsFix(PVM pVM, RTGCPTR GCPtrBase, uint32_t cb);
+VMMR3DECL(int) PGMR3MappingsUnfix(PVM pVM);
+VMMR3DECL(bool) PGMR3MappingsNeedReFixing(PVM pVM);
+VMMR3DECL(int) PGMR3MapIntermediate(PVM pVM, RTUINTPTR Addr, RTHCPHYS HCPhys, unsigned cbPages);
+VMMR3DECL(int) PGMR3MapRead(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb);
+
+VMMR3DECL(int) PGMR3HandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast,
+ PFNPGMR3PHYSHANDLER pfnHandlerR3, void *pvUserR3,
+ const char *pszModR0, const char *pszHandlerR0, RTR0PTR pvUserR0,
+ const char *pszModRC, const char *pszHandlerRC, RTRCPTR pvUserRC, const char *pszDesc);
+VMMDECL(int) PGMR3HandlerVirtualRegisterEx(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
+ R3PTRTYPE(PFNPGMR3VIRTINVALIDATE) pfnInvalidateR3,
+ R3PTRTYPE(PFNPGMR3VIRTHANDLER) pfnHandlerR3,
+ RCPTRTYPE(PFNPGMRCVIRTHANDLER) pfnHandlerRC,
+ R3PTRTYPE(const char *) pszDesc);
+VMMR3DECL(int) PGMR3HandlerVirtualRegister(PVM pVM, PGMVIRTHANDLERTYPE enmType, RTGCPTR GCPtr, RTGCPTR GCPtrLast,
+ PFNPGMR3VIRTINVALIDATE pfnInvalidateR3,
+ PFNPGMR3VIRTHANDLER pfnHandlerR3,
+ const char *pszHandlerRC, const char *pszModRC, const char *pszDesc);
+VMMDECL(int) PGMHandlerVirtualChangeInvalidateCallback(PVM pVM, RTGCPTR GCPtr, R3PTRTYPE(PFNPGMR3VIRTINVALIDATE) pfnInvalidateR3);
+VMMDECL(int) PGMHandlerVirtualDeregister(PVM pVM, RTGCPTR GCPtr);
+VMMR3DECL(int) PGMR3PoolGrow(PVM pVM);
+
+VMMR3DECL(int) PGMR3PhysTlbGCPhys2Ptr(PVM pVM, RTGCPHYS GCPhys, bool fWritable, void **ppv);
+VMMR3DECL(uint8_t) PGMR3PhysReadU8(PVM pVM, RTGCPHYS GCPhys);
+VMMR3DECL(uint16_t) PGMR3PhysReadU16(PVM pVM, RTGCPHYS GCPhys);
+VMMR3DECL(uint32_t) PGMR3PhysReadU32(PVM pVM, RTGCPHYS GCPhys);
+VMMR3DECL(uint64_t) PGMR3PhysReadU64(PVM pVM, RTGCPHYS GCPhys);
+VMMR3DECL(void) PGMR3PhysWriteU8(PVM pVM, RTGCPHYS GCPhys, uint8_t Value);
+VMMR3DECL(void) PGMR3PhysWriteU16(PVM pVM, RTGCPHYS GCPhys, uint16_t Value);
+VMMR3DECL(void) PGMR3PhysWriteU32(PVM pVM, RTGCPHYS GCPhys, uint32_t Value);
+VMMR3DECL(void) PGMR3PhysWriteU64(PVM pVM, RTGCPHYS GCPhys, uint64_t Value);
+VMMR3DECL(int) PGMR3PhysReadExternal(PVM pVM, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
+VMMR3DECL(int) PGMR3PhysWriteExternal(PVM pVM, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, const char *pszWho);
+VMMR3DECL(int) PGMR3PhysGCPhys2CCPtrExternal(PVM pVM, RTGCPHYS GCPhys, void **ppv, PPGMPAGEMAPLOCK pLock);
+VMMR3DECL(int) PGMR3PhysGCPhys2CCPtrReadOnlyExternal(PVM pVM, RTGCPHYS GCPhys, void const **ppv, PPGMPAGEMAPLOCK pLock);
+VMMR3DECL(int) PGMR3PhysChunkMap(PVM pVM, uint32_t idChunk);
+VMMR3DECL(void) PGMR3PhysChunkInvalidateTLB(PVM pVM);
+VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM);
+VMMR3DECL(int) PGMR3PhysAllocateLargeHandyPage(PVM pVM, RTGCPHYS GCPhys);
+
+VMMR3DECL(int) PGMR3CheckIntegrity(PVM pVM);
+
+VMMR3DECL(int) PGMR3DbgR3Ptr2GCPhys(PVM pVM, RTR3PTR R3Ptr, PRTGCPHYS pGCPhys);
+VMMR3DECL(int) PGMR3DbgR3Ptr2HCPhys(PVM pVM, RTR3PTR R3Ptr, PRTHCPHYS pHCPhys);
+VMMR3DECL(int) PGMR3DbgHCPhys2GCPhys(PVM pVM, RTHCPHYS HCPhys, PRTGCPHYS pGCPhys);
+VMMR3DECL(int) PGMR3DbgReadGCPhys(PVM pVM, void *pvDst, RTGCPHYS GCPhysSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
+VMMR3DECL(int) PGMR3DbgWriteGCPhys(PVM pVM, RTGCPHYS GCPhysDst, const void *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
+VMMR3DECL(int) PGMR3DbgReadGCPtr(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb, uint32_t fFlags, size_t *pcbRead);
+VMMR3DECL(int) PGMR3DbgWriteGCPtr(PVM pVM, RTGCPTR GCPtrDst, void const *pvSrc, size_t cb, uint32_t fFlags, size_t *pcbWritten);
+VMMR3DECL(int) PGMR3DbgScanPhysical(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cbRange, RTGCPHYS GCPhysAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCPHYS pGCPhysHit);
+VMMR3DECL(int) PGMR3DbgScanVirtual(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, RTGCPTR cbRange, RTGCPTR GCPtrAlign, const uint8_t *pabNeedle, size_t cbNeedle, PRTGCUINTPTR pGCPhysHit);
+VMMR3_INT_DECL(int) PGMR3DumpHierarchyShw(PVM pVM, uint64_t cr3, uint32_t fFlags, uint64_t u64FirstAddr, uint64_t u64LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
+VMMR3_INT_DECL(int) PGMR3DumpHierarchyGst(PVM pVM, uint64_t cr3, uint32_t fFlags, RTGCPTR FirstAddr, RTGCPTR LastAddr, uint32_t cMaxDepth, PCDBGFINFOHLP pHlp);
+
+
+/** @name Page sharing
+ * @{ */
+VMMR3DECL(int) PGMR3SharedModuleRegister(PVM pVM, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
+ RTGCPTR GCBaseAddr, uint32_t cbModule,
+ uint32_t cRegions, VMMDEVSHAREDREGIONDESC const *paRegions);
+VMMR3DECL(int) PGMR3SharedModuleUnregister(PVM pVM, char *pszModuleName, char *pszVersion,
+ RTGCPTR GCBaseAddr, uint32_t cbModule);
+VMMR3DECL(int) PGMR3SharedModuleCheckAll(PVM pVM);
+VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *pfPageFlags);
+/** @} */
+
+/** @} */
+#endif /* IN_RING3 */
+
+RT_C_DECLS_END
+
+/** @} */
+#endif
+
diff --git a/include/VBox/vmm/rem.h b/include/VBox/vmm/rem.h
new file mode 100644
index 00000000..79a18810
--- /dev/null
+++ b/include/VBox/vmm/rem.h
@@ -0,0 +1,106 @@
+/** @file
+ * REM - The Recompiled Execution Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_rem_h
+#define ___VBox_vmm_rem_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/pgm.h>
+#include <VBox/vmm/vmapi.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rem The Recompiled Execution Manager API
+ * @{
+ */
+
+/** No pending interrupt. */
+#define REM_NO_PENDING_IRQ (~(uint32_t)0)
+
+
+#if defined(IN_RING0) || defined(IN_RC)
+VMMDECL(void) REMNotifyInvalidatePage(PVM pVM, RTGCPTR GCPtrPage);
+VMMDECL(void) REMNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler);
+VMMDECL(void) REMNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
+VMMDECL(void) REMNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
+#endif /* IN_RING0 || IN_RC */
+#ifdef IN_RC
+VMMDECL(void) REMNotifyHandlerPhysicalFlushIfAlmostFull(PVM pVM, PVMCPU pVCpu);
+#endif
+VMMDECL(void) REMFlushTBs(PVM pVM);
+
+
+#ifdef IN_RING3
+/** @defgroup grp_rem_r3 REM Host Context Ring 3 API
+ * @ingroup grp_rem
+ * @{
+ */
+REMR3DECL(int) REMR3Init(PVM pVM);
+REMR3DECL(int) REMR3InitFinalize(PVM pVM);
+REMR3DECL(int) REMR3Term(PVM pVM);
+REMR3DECL(void) REMR3Reset(PVM pVM);
+REMR3DECL(int) REMR3Run(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(int) REMR3EmulateInstruction(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(int) REMR3Step(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(int) REMR3BreakpointSet(PVM pVM, RTGCUINTPTR Address);
+REMR3DECL(int) REMR3BreakpointClear(PVM pVM, RTGCUINTPTR Address);
+REMR3DECL(int) REMR3State(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(int) REMR3StateBack(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(void) REMR3StateUpdate(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(void) REMR3A20Set(PVM pVM, PVMCPU pVCpu, bool fEnable);
+REMR3DECL(int) REMR3DisasEnableStepping(PVM pVM, bool fEnable);
+REMR3DECL(void) REMR3ReplayHandlerNotifications(PVM pVM);
+REMR3DECL(int) REMR3NotifyCodePageChanged(PVM pVM, PVMCPU pVCpu, RTGCPTR pvCodePage);
+REMR3DECL(void) REMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, unsigned fFlags);
+/** @name Flags for REMR3NotifyPhysRamRegister.
+ * @{ */
+#define REM_NOTIFY_PHYS_RAM_FLAGS_RAM RT_BIT(16)
+#define REM_NOTIFY_PHYS_RAM_FLAGS_MMIO2 RT_BIT(17)
+/** @} */
+REMR3DECL(void) REMR3NotifyPhysRomRegister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, void *pvCopy, bool fShadow);
+REMR3DECL(void) REMR3NotifyPhysRamDeregister(PVM pVM, RTGCPHYS GCPhys, RTUINT cb);
+REMR3DECL(void) REMR3NotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler);
+REMR3DECL(void) REMR3NotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhys, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
+REMR3DECL(void) REMR3NotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERTYPE enmType, RTGCPHYS GCPhysOld, RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fHasHCHandler, bool fRestoreAsRAM);
+REMR3DECL(void) REMR3NotifyPendingInterrupt(PVM pVM, PVMCPU pVCpu, uint8_t u8Interrupt);
+REMR3DECL(uint32_t) REMR3QueryPendingInterrupt(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(void) REMR3NotifyInterruptClear(PVM pVM, PVMCPU pVCpu);
+REMR3DECL(void) REMR3NotifyTimerPending(PVM pVM, PVMCPU pVCpuDst);
+REMR3DECL(void) REMR3NotifyDmaPending(PVM pVM);
+REMR3DECL(void) REMR3NotifyQueuePending(PVM pVM);
+REMR3DECL(void) REMR3NotifyFF(PVM pVM);
+REMR3DECL(bool) REMR3IsPageAccessHandled(PVM pVM, RTGCPHYS GCPhys);
+/** @} */
+#endif /* IN_RING3 */
+
+
+/** @} */
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/VBox/vmm/selm.h b/include/VBox/vmm/selm.h
new file mode 100644
index 00000000..763d0acf
--- /dev/null
+++ b/include/VBox/vmm/selm.h
@@ -0,0 +1,123 @@
+/** @file
+ * SELM - The Selector Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_selm_h
+#define ___VBox_vmm_selm_h
+
+#include <VBox/types.h>
+#include <iprt/x86.h>
+#include <VBox/dis.h>
+#include <VBox/vmm/dbgfsel.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_selm The Selector Monitor(/Manager) API
+ * @{
+ */
+
+VMMDECL(RTSEL) SELMGetTrap8Selector(PVM pVM);
+VMMDECL(void) SELMSetTrap8EIP(PVM pVM, uint32_t u32EIP);
+VMMDECL(int) SELMGetRing1Stack(PVM pVM, uint32_t *pSS, PRTGCPTR32 pEsp);
+VMMDECL(RTGCPTR) SELMGetGuestTSS(PVM pVM);
+VMMDECL(RTSEL) SELMGetHyperCS(PVM pVM);
+VMMDECL(RTSEL) SELMGetHyperCS64(PVM pVM);
+VMMDECL(RTSEL) SELMGetHyperDS(PVM pVM);
+VMMDECL(RTSEL) SELMGetHyperTSS(PVM pVM);
+VMMDECL(RTSEL) SELMGetHyperTSSTrap08(PVM pVM);
+VMMDECL(RTRCPTR) SELMGetHyperGDT(PVM pVM);
+VMMDECL(int) SELMGetTSSInfo(PVM pVM, PVMCPU pVCpu, PRTGCUINTPTR pGCPtrTss, PRTGCUINTPTR pcbTss, bool *pfCanHaveIOBitmap);
+VMMDECL(RTGCPTR) SELMToFlat(PVM pVM, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr);
+VMMDECL(RTGCPTR) SELMToFlatBySel(PVM pVM, RTSEL Sel, RTGCPTR Addr);
+VMMDECL(void) SELMShadowCR3Changed(PVM pVM, PVMCPU pVCpu);
+
+/** Flags for SELMToFlatEx().
+ * @{ */
+/** Don't check the RPL,DPL or CPL. */
+#define SELMTOFLAT_FLAGS_NO_PL RT_BIT(8)
+/** Flags contains CPL information. */
+#define SELMTOFLAT_FLAGS_HAVE_CPL RT_BIT(9)
+/** CPL is 3. */
+#define SELMTOFLAT_FLAGS_CPL3 3
+/** CPL is 2. */
+#define SELMTOFLAT_FLAGS_CPL2 2
+/** CPL is 1. */
+#define SELMTOFLAT_FLAGS_CPL1 1
+/** CPL is 0. */
+#define SELMTOFLAT_FLAGS_CPL0 0
+/** Get the CPL from the flags. */
+#define SELMTOFLAT_FLAGS_CPL(fFlags) ((fFlags) & X86_SEL_RPL)
+/** Allow converting using Hypervisor GDT entries. */
+#define SELMTOFLAT_FLAGS_HYPER RT_BIT(10)
+/** @} */
+
+VMMDECL(int) SELMToFlatEx(PVMCPU pVCpu, DISSELREG SelReg, PCPUMCTXCORE pCtxCore, RTGCPTR Addr, uint32_t fFlags,
+ PRTGCPTR ppvGC);
+VMMDECL(int) SELMToFlatBySelEx(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, uint32_t fFlags,
+ PRTGCPTR ppvGC, uint32_t *pcb);
+VMMDECL(int) SELMValidateAndConvertCSAddr(PVMCPU pVCpu, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS,
+ PCPUMSELREG pSRegCS, RTGCPTR Addr, PRTGCPTR ppvFlat);
+#ifdef VBOX_WITH_RAW_MODE
+VMM_INT_DECL(void) SELMLoadHiddenSelectorReg(PVMCPU pVCpu, PCCPUMCTX pCtx, PCPUMSELREG pSReg);
+#endif
+
+
+#ifdef IN_RING3
+/** @defgroup grp_selm_r3 The Selector Monitor(/Manager) API
+ * @ingroup grp_selm
+ * @{
+ */
+VMMR3DECL(int) SELMR3Init(PVM pVM);
+VMMR3DECL(int) SELMR3InitFinalize(PVM pVM);
+VMMR3DECL(void) SELMR3Relocate(PVM pVM);
+VMMR3DECL(int) SELMR3Term(PVM pVM);
+VMMR3DECL(void) SELMR3Reset(PVM pVM);
+VMMR3DECL(VBOXSTRICTRC) SELMR3UpdateFromCPUM(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) SELMR3SyncTSS(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) SELMR3GetSelectorInfo(PVM pVM, PVMCPU pVCpu, RTSEL Sel, PDBGFSELINFO pSelInfo);
+VMMR3DECL(int) SELMR3GetShadowSelectorInfo(PVM pVM, RTSEL Sel, PDBGFSELINFO pSelInfo);
+VMMR3DECL(void) SELMR3DisableMonitoring(PVM pVM);
+VMMR3DECL(void) SELMR3DumpDescriptor(X86DESC Desc, RTSEL Sel, const char *pszMsg);
+VMMR3DECL(void) SELMR3DumpHyperGDT(PVM pVM);
+VMMR3DECL(void) SELMR3DumpHyperLDT(PVM pVM);
+VMMR3DECL(void) SELMR3DumpGuestGDT(PVM pVM);
+VMMR3DECL(void) SELMR3DumpGuestLDT(PVM pVM);
+VMMR3DECL(bool) SELMR3CheckTSS(PVM pVM);
+VMMR3DECL(int) SELMR3DebugCheck(PVM pVM);
+/** @def SELMR3_DEBUG_CHECK
+ * Invokes SELMR3DebugCheck in stricts builds. */
+# ifdef VBOX_STRICT
+# define SELMR3_DEBUG_CHECK(pVM) SELMR3DebugCheck(pVM)
+# else
+# define SELMR3_DEBUG_CHECK(pVM) do { } while (0)
+# endif
+/** @} */
+#endif /* IN_RING3 */
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/ssm.h b/include/VBox/vmm/ssm.h
new file mode 100644
index 00000000..427e0796
--- /dev/null
+++ b/include/VBox/vmm/ssm.h
@@ -0,0 +1,1265 @@
+/** @file
+ * SSM - The Save State Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_ssm_h
+#define ___VBox_vmm_ssm_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/tm.h>
+#include <VBox/vmm/vmapi.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_ssm The Saved State Manager API
+ * @{
+ */
+
+/**
+ * Determine the major version of the SSM version. If the major SSM version of two snapshots is
+ * different, the snapshots are incompatible.
+ */
+#define SSM_VERSION_MAJOR(ver) ((ver) & 0xffff0000)
+
+/**
+ * Determine the minor version of the SSM version. If the major SSM version of two snapshots is
+ * the same, the code must handle incompatibilies between minor version changes (e.g. use dummy
+ * values for non-existent fields).
+ */
+#define SSM_VERSION_MINOR(ver) ((ver) & 0x0000ffff)
+
+/**
+ * Determine if the major version changed between two SSM versions.
+ */
+#define SSM_VERSION_MAJOR_CHANGED(ver1,ver2) (SSM_VERSION_MAJOR(ver1) != SSM_VERSION_MAJOR(ver2))
+
+/** The special value for the final pass. */
+#define SSM_PASS_FINAL UINT32_MAX
+
+
+#ifdef IN_RING3
+/** @defgroup grp_ssm_r3 The SSM Host Context Ring-3 API
+ * @{
+ */
+
+
+/**
+ * What to do after the save/load operation.
+ */
+typedef enum SSMAFTER
+{
+ /** Invalid. */
+ SSMAFTER_INVALID = 0,
+ /** Will resume the loaded state. */
+ SSMAFTER_RESUME,
+ /** Will destroy the VM after saving. */
+ SSMAFTER_DESTROY,
+ /** Will continue execution after saving the VM. */
+ SSMAFTER_CONTINUE,
+ /** Will teleport the VM.
+ * The source VM will be destroyed (then one saving), the destination VM
+ * will continue execution. */
+ SSMAFTER_TELEPORT,
+ /** Will debug the saved state.
+ * This is used to drop some of the stricter consitentcy checks so it'll
+ * load fine in the debugger or animator. */
+ SSMAFTER_DEBUG_IT,
+ /** The file was opened using SSMR3Open() and we have no idea what the plan is. */
+ SSMAFTER_OPENED
+} SSMAFTER;
+
+
+/** Pointer to a structure field description. */
+typedef struct SSMFIELD *PSSMFIELD;
+/** Pointer to a const structure field description. */
+typedef const struct SSMFIELD *PCSSMFIELD;
+
+/**
+ * SSMFIELD Get/Put callback function.
+ *
+ * This is call for getting and putting the field it is associated with. It's
+ * up to the callback to work the saved state correctly.
+ *
+ * @returns VBox status code.
+ *
+ * @param pSSM The saved state handle.
+ * @param pField The field that is being processed.
+ * @param pvStruct Pointer to the structure.
+ * @param fFlags SSMSTRUCT_FLAGS_XXX.
+ * @param fGetOrPut True if getting, false if putting.
+ * @param pvUser The user argument specified to SSMR3GetStructEx or
+ * SSMR3PutStructEx.
+ */
+typedef DECLCALLBACK(int) FNSSMFIELDGETPUT(PSSMHANDLE pSSM, const struct SSMFIELD *pField, void *pvStruct,
+ uint32_t fFlags, bool fGetOrPut, void *pvUser);
+/** Pointer to a SSMFIELD Get/Put callback. */
+typedef FNSSMFIELDGETPUT *PFNSSMFIELDGETPUT;
+
+/**
+ * SSM field transformers.
+ *
+ * These are stored in the SSMFIELD::pfnGetPutOrTransformer and must therefore
+ * have values outside the valid pointer range.
+ */
+typedef enum SSMFIELDTRANS
+{
+ /** Invalid. */
+ SSMFIELDTRANS_INVALID = 0,
+ /** No transformation. */
+ SSMFIELDTRANS_NO_TRANSFORMATION,
+ /** Guest context (GC) physical address. */
+ SSMFIELDTRANS_GCPHYS,
+ /** Guest context (GC) virtual address. */
+ SSMFIELDTRANS_GCPTR,
+ /** Raw-mode context (RC) virtual address. */
+ SSMFIELDTRANS_RCPTR,
+ /** Array of raw-mode context (RC) virtual addresses. */
+ SSMFIELDTRANS_RCPTR_ARRAY,
+ /** Host context (HC) virtual address used as a NULL indicator. See
+ * SSMFIELD_ENTRY_HCPTR_NI. */
+ SSMFIELDTRANS_HCPTR_NI,
+ /** Array of SSMFIELDTRANS_HCPTR_NI. */
+ SSMFIELDTRANS_HCPTR_NI_ARRAY,
+ /** Host context (HC) virtual address used to hold a unsigned 32-bit value. */
+ SSMFIELDTRANS_HCPTR_HACK_U32,
+ /** Load a 32-bit unsigned filed from the state and zero extend it into a 64-bit
+ * structure member. */
+ SSMFIELDTRANS_U32_ZX_U64,
+
+ /** Ignorable field. See SSMFIELD_ENTRY_IGNORE. */
+ SSMFIELDTRANS_IGNORE,
+ /** Ignorable guest context (GC) physical address. */
+ SSMFIELDTRANS_IGN_GCPHYS,
+ /** Ignorable guest context (GC) virtual address. */
+ SSMFIELDTRANS_IGN_GCPTR,
+ /** Ignorable raw-mode context (RC) virtual address. */
+ SSMFIELDTRANS_IGN_RCPTR,
+ /** Ignorable host context (HC) virtual address. */
+ SSMFIELDTRANS_IGN_HCPTR,
+
+ /** Old field.
+ * Save as zeros and skip on restore (nowhere to restore it any longer). */
+ SSMFIELDTRANS_OLD,
+ /** Old guest context (GC) physical address. */
+ SSMFIELDTRANS_OLD_GCPHYS,
+ /** Old guest context (GC) virtual address. */
+ SSMFIELDTRANS_OLD_GCPTR,
+ /** Old raw-mode context (RC) virtual address. */
+ SSMFIELDTRANS_OLD_RCPTR,
+ /** Old host context (HC) virtual address. */
+ SSMFIELDTRANS_OLD_HCPTR,
+ /** Old host context specific padding.
+ * The lower word is the size of 32-bit hosts, the upper for 64-bit hosts. */
+ SSMFIELDTRANS_OLD_PAD_HC,
+ /** Old padding specific to the 32-bit Microsoft C Compiler. */
+ SSMFIELDTRANS_OLD_PAD_MSC32,
+
+ /** Padding that differs between 32-bit and 64-bit hosts.
+ * The first byte of SSMFIELD::cb contains the size for 32-bit hosts.
+ * The second byte of SSMFIELD::cb contains the size for 64-bit hosts.
+ * The upper word of SSMFIELD::cb contains the actual field size.
+ */
+ SSMFIELDTRANS_PAD_HC,
+ /** Padding for 32-bit hosts only.
+ * SSMFIELD::cb has the same format as for SSMFIELDTRANS_PAD_HC. */
+ SSMFIELDTRANS_PAD_HC32,
+ /** Padding for 64-bit hosts only.
+ * SSMFIELD::cb has the same format as for SSMFIELDTRANS_PAD_HC. */
+ SSMFIELDTRANS_PAD_HC64,
+ /** Automatic compiler padding that may differ between 32-bit and
+ * 64-bit hosts. SSMFIELD::cb has the same format as for
+ * SSMFIELDTRANS_PAD_HC. */
+ SSMFIELDTRANS_PAD_HC_AUTO,
+ /** Automatic compiler padding specific to the 32-bit Microsoft C
+ * compiler.
+ * SSMFIELD::cb has the same format as for SSMFIELDTRANS_PAD_HC. */
+ SSMFIELDTRANS_PAD_MSC32_AUTO
+} SSMFIELDTRANS;
+
+/** Tests if it's a padding field with the special SSMFIELD::cb format.
+ * @returns true / false.
+ * @param pfn The SSMFIELD::pfnGetPutOrTransformer value.
+ */
+#define SSMFIELDTRANS_IS_PADDING(pfn) \
+ ( (uintptr_t)(pfn) >= SSMFIELDTRANS_PAD_HC && (uintptr_t)(pfn) <= SSMFIELDTRANS_PAD_MSC32_AUTO )
+
+/** Tests if it's an entry for an old field.
+ *
+ * @returns true / false.
+ * @param pfn The SSMFIELD::pfnGetPutOrTransformer value.
+ */
+#define SSMFIELDTRANS_IS_OLD(pfn) \
+ ( (uintptr_t)(pfn) >= SSMFIELDTRANS_OLD && (uintptr_t)(pfn) <= SSMFIELDTRANS_OLD_PAD_MSC32 )
+
+/**
+ * A structure field description.
+ */
+typedef struct SSMFIELD
+{
+ /** Getter and putter callback or transformer index. */
+ PFNSSMFIELDGETPUT pfnGetPutOrTransformer;
+ /** Field offset into the structure. */
+ uint32_t off;
+ /** The size of the field. */
+ uint32_t cb;
+ /** Field name. */
+ const char *pszName;
+} SSMFIELD;
+
+/** Emit a SSMFIELD array entry.
+ * @internal */
+#define SSMFIELD_ENTRY_INT(Name, off, cb, enmTransformer) \
+ { (PFNSSMFIELDGETPUT)(uintptr_t)(enmTransformer), (off), (cb), Name }
+/** Emit a SSMFIELD array entry.
+ * @internal */
+#define SSMFIELD_ENTRY_TF_INT(Type, Field, enmTransformer) \
+ SSMFIELD_ENTRY_INT(#Type "::" #Field, RT_OFFSETOF(Type, Field), RT_SIZEOFMEMB(Type, Field), enmTransformer)
+/** Emit a SSMFIELD array entry for an old field.
+ * @internal */
+#define SSMFIELD_ENTRY_OLD_INT(Field, cb, enmTransformer) \
+ SSMFIELD_ENTRY_INT("old::" #Field, UINT32_MAX / 2, (cb), enmTransformer)
+/** Emit a SSMFIELD array entry for an alignment padding.
+ * @internal */
+#define SSMFIELD_ENTRY_PAD_INT(Type, Field, cb32, cb64, enmTransformer) \
+ SSMFIELD_ENTRY_INT(#Type "::" #Field, RT_OFFSETOF(Type, Field), \
+ (RT_SIZEOFMEMB(Type, Field) << 16) | (cb32) | ((cb64) << 8), enmTransformer)
+/** Emit a SSMFIELD array entry for an alignment padding.
+ * @internal */
+#define SSMFIELD_ENTRY_PAD_OTHER_INT(Type, Field, cb32, cb64, enmTransformer) \
+ SSMFIELD_ENTRY_INT(#Type "::" #Field, UINT32_MAX / 2, 0 | (cb32) | ((cb64) << 8), enmTransformer)
+
+/** Emit a SSMFIELD array entry. */
+#define SSMFIELD_ENTRY(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_NO_TRANSFORMATION)
+/** Emit a SSMFIELD array entry for a custom made field. This is intended
+ * for working around bitfields in old structures. */
+#define SSMFIELD_ENTRY_CUSTOM(Field, off, cb) SSMFIELD_ENTRY_INT("custom::" #Field, off, cb, SSMFIELDTRANS_NO_TRANSFORMATION)
+/** Emit a SSMFIELD array entry for a RTGCPHYS type. */
+#define SSMFIELD_ENTRY_GCPHYS(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_GCPHYS)
+/** Emit a SSMFIELD array entry for a RTGCPTR type. */
+#define SSMFIELD_ENTRY_GCPTR(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_GCPTR)
+/** Emit a SSMFIELD array entry for a raw-mode context pointer. */
+#define SSMFIELD_ENTRY_RCPTR(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_RCPTR)
+/** Emit a SSMFIELD array entry for a raw-mode context pointer. */
+#define SSMFIELD_ENTRY_RCPTR_ARRAY(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_RCPTR_ARRAY)
+/** Emit a SSMFIELD array entry for a ring-0 or ring-3 pointer type that is only
+ * of interest as a NULL indicator.
+ *
+ * This is always restored as a 0 (NULL) or 1 value. When
+ * SSMSTRUCT_FLAGS_DONT_IGNORE is set, the pointer will be saved in its
+ * entirety, when clear it will be saved as a boolean. */
+#define SSMFIELD_ENTRY_HCPTR_NI(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_HCPTR_NI)
+/** Same as SSMFIELD_ENTRY_HCPTR_NI, except it's an array of the buggers. */
+#define SSMFIELD_ENTRY_HCPTR_NI_ARRAY(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_HCPTR_NI_ARRAY)
+/** Emit a SSMFIELD array entry for a ring-0 or ring-3 pointer type that has
+ * been hacked such that it will never exceed 32-bit. No sign extending. */
+#define SSMFIELD_ENTRY_HCPTR_HACK_U32(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_HCPTR_HACK_U32)
+/** Emit a SSMFIELD array entry for loading a 32-bit field into a 64-bit
+ * structure member, zero extending the value. */
+#define SSMFIELD_ENTRY_U32_ZX_U64(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_U32_ZX_U64)
+
+/** Emit a SSMFIELD array entry for a field that can be ignored.
+ * It is stored as zeros if SSMSTRUCT_FLAGS_DONT_IGNORE is specified to
+ * SSMR3PutStructEx. The member is never touched upon restore. */
+#define SSMFIELD_ENTRY_IGNORE(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_IGNORE)
+/** Emit a SSMFIELD array entry for an ignorable RTGCPHYS type. */
+#define SSMFIELD_ENTRY_IGN_GCPHYS(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_IGN_GCPHYS)
+/** Emit a SSMFIELD array entry for an ignorable RTGCPHYS type. */
+#define SSMFIELD_ENTRY_IGN_GCPTR(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_IGN_GCPTR)
+/** Emit a SSMFIELD array entry for an ignorable raw-mode context pointer. */
+#define SSMFIELD_ENTRY_IGN_RCPTR(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_IGN_RCPTR)
+/** Emit a SSMFIELD array entry for an ignorable ring-3 or/and ring-0 pointer. */
+#define SSMFIELD_ENTRY_IGN_HCPTR(Type, Field) SSMFIELD_ENTRY_TF_INT(Type, Field, SSMFIELDTRANS_IGN_HCPTR)
+
+/** Emit a SSMFIELD array entry for an old field that should be ignored now.
+ * It is stored as zeros and skipped on load. */
+#define SSMFIELD_ENTRY_OLD(Field, cb) SSMFIELD_ENTRY_OLD_INT(Field, cb, SSMFIELDTRANS_OLD)
+/** Same as SSMFIELD_ENTRY_IGN_GCPHYS, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_GCPHYS(Field) SSMFIELD_ENTRY_OLD_INT(Field, sizeof(RTGCPHYS), SSMFIELDTRANS_OLD_GCPHYS)
+/** Same as SSMFIELD_ENTRY_IGN_GCPTR, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_GCPTR(Field) SSMFIELD_ENTRY_OLD_INT(Field, sizeof(RTGCPTR), SSMFIELDTRANS_OLD_GCPTR)
+/** Same as SSMFIELD_ENTRY_IGN_RCPTR, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_RCPTR(Field) SSMFIELD_ENTRY_OLD_INT(Field, sizeof(RTRCPTR), SSMFIELDTRANS_OLD_RCPTR)
+/** Same as SSMFIELD_ENTRY_IGN_HCPTR, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_HCPTR(Field) SSMFIELD_ENTRY_OLD_INT(Field, sizeof(RTHCPTR), SSMFIELDTRANS_OLD_HCPTR)
+/** Same as SSMFIELD_ENTRY_PAD_HC, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_PAD_HC(Field, cb32, cb64) \
+ SSMFIELD_ENTRY_OLD_INT(Field, RT_MAKE_U32((cb32), (cb64)), SSMFIELDTRANS_OLD_PAD_HC)
+/** Same as SSMFIELD_ENTRY_PAD_HC64, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_PAD_HC64(Field, cb) SSMFIELD_ENTRY_OLD_PAD_HC(Field, 0, cb)
+/** Same as SSMFIELD_ENTRY_PAD_HC32, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_PAD_HC32(Field, cb) SSMFIELD_ENTRY_OLD_PAD_HC(Field, cb, 0)
+/** Same as SSMFIELD_ENTRY_PAD_HC, except there is no structure field. */
+#define SSMFIELD_ENTRY_OLD_PAD_MSC32(Field, cb) SSMFIELD_ENTRY_OLD_INT(Field, cb, SSMFIELDTRANS_OLD_PAD_MSC32)
+
+/** Emit a SSMFIELD array entry for a padding that differs in size between
+ * 64-bit and 32-bit hosts. */
+#define SSMFIELD_ENTRY_PAD_HC(Type, Field, cb32, cb64) SSMFIELD_ENTRY_PAD_INT( Type, Field, cb32, cb64, SSMFIELDTRANS_PAD_HC)
+/** Emit a SSMFIELD array entry for a padding that is exclusive to 64-bit hosts. */
+#if HC_ARCH_BITS == 64
+# define SSMFIELD_ENTRY_PAD_HC64(Type, Field, cb) SSMFIELD_ENTRY_PAD_INT( Type, Field, 0, cb, SSMFIELDTRANS_PAD_HC64)
+#else
+# define SSMFIELD_ENTRY_PAD_HC64(Type, Field, cb) SSMFIELD_ENTRY_PAD_OTHER_INT(Type, Field, 0, cb, SSMFIELDTRANS_PAD_HC64)
+#endif
+/** Emit a SSMFIELD array entry for a 32-bit padding for on 64-bits hosts. */
+#if HC_ARCH_BITS == 32
+# define SSMFIELD_ENTRY_PAD_HC32(Type, Field, cb) SSMFIELD_ENTRY_PAD_INT( Type, Field, cb, 0, SSMFIELDTRANS_PAD_HC32)
+#else
+# define SSMFIELD_ENTRY_PAD_HC32(Type, Field, cb) SSMFIELD_ENTRY_PAD_OTHER_INT(Type, Field, cb, 0, SSMFIELDTRANS_PAD_HC32)
+#endif
+/** Emit a SSMFIELD array entry for an automatic compiler padding that may
+ * differ in size between 64-bit and 32-bit hosts. */
+#if HC_ARCH_BITS == 64
+# define SSMFIELD_ENTRY_PAD_HC_AUTO(cb32, cb64) \
+ { \
+ (PFNSSMFIELDGETPUT)(uintptr_t)(SSMFIELDTRANS_PAD_HC_AUTO), \
+ UINT32_MAX / 2, (cb64 << 16) | (cb32) | ((cb64) << 8), "<compiler-padding>" \
+ }
+#else
+# define SSMFIELD_ENTRY_PAD_HC_AUTO(cb32, cb64) \
+ { \
+ (PFNSSMFIELDGETPUT)(uintptr_t)(SSMFIELDTRANS_PAD_HC_AUTO), \
+ UINT32_MAX / 2, (cb32 << 16) | (cb32) | ((cb64) << 8), "<compiler-padding>" \
+ }
+#endif
+/** Emit a SSMFIELD array entry for an automatic compiler padding that is unique
+ * to the 32-bit microsoft compiler. This is usually used together with
+ * SSMFIELD_ENTRY_PAD_HC*. */
+#if HC_ARCH_BITS == 32 && defined(_MSC_VER)
+# define SSMFIELD_ENTRY_PAD_MSC32_AUTO(cb) \
+ { \
+ (PFNSSMFIELDGETPUT)(uintptr_t)(SSMFIELDTRANS_PAD_MSC32_AUTO), \
+ UINT32_MAX / 2, ((cb) << 16) | (cb), "<msc32-padding>" \
+ }
+#else
+# define SSMFIELD_ENTRY_PAD_MSC32_AUTO(cb) \
+ { \
+ (PFNSSMFIELDGETPUT)(uintptr_t)(SSMFIELDTRANS_PAD_MSC32_AUTO), \
+ UINT32_MAX / 2, (cb), "<msc32-padding>" \
+ }
+#endif
+
+/** Emit a SSMFIELD array entry for a field with a custom callback. */
+#define SSMFIELD_ENTRY_CALLBACK(Type, Field, pfnGetPut) \
+ { (pfnGetPut), RT_OFFSETOF(Type, Field), RT_SIZEOFMEMB(Type, Field), #Type "::" #Field }
+/** Emit the terminating entry of a SSMFIELD array. */
+#define SSMFIELD_ENTRY_TERM() { (PFNSSMFIELDGETPUT)(uintptr_t)SSMFIELDTRANS_INVALID, UINT32_MAX, UINT32_MAX, NULL }
+
+
+/** @name SSMR3GetStructEx and SSMR3PutStructEx flags.
+ * @{ */
+/** The field descriptors must exactly cover the entire struct, A to Z. */
+#define SSMSTRUCT_FLAGS_FULL_STRUCT RT_BIT_32(0)
+/** No start and end markers, just the raw bits. */
+#define SSMSTRUCT_FLAGS_NO_MARKERS RT_BIT_32(1)
+/** Do not ignore any ignorable fields. */
+#define SSMSTRUCT_FLAGS_DONT_IGNORE RT_BIT_32(2)
+/** Saved using SSMR3PutMem, don't be too strict. */
+#define SSMSTRUCT_FLAGS_SAVED_AS_MEM RT_BIT_32(3)
+/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host pointers. */
+#define SSMSTRUCT_FLAGS_MEM_BAND_AID ( SSMSTRUCT_FLAGS_DONT_IGNORE | SSMSTRUCT_FLAGS_FULL_STRUCT \
+ | SSMSTRUCT_FLAGS_NO_MARKERS | SSMSTRUCT_FLAGS_SAVED_AS_MEM)
+/** Band-aid for old SSMR3PutMem/SSMR3GetMem of structurs with host
+ * pointers, with relaxed checks. */
+#define SSMSTRUCT_FLAGS_MEM_BAND_AID_RELAXED ( SSMSTRUCT_FLAGS_DONT_IGNORE \
+ | SSMSTRUCT_FLAGS_NO_MARKERS | SSMSTRUCT_FLAGS_SAVED_AS_MEM)
+/** Mask of the valid bits. */
+#define SSMSTRUCT_FLAGS_VALID_MASK UINT32_C(0x0000000f)
+/** @} */
+
+
+/** The PDM Device callback variants.
+ * @{
+ */
+
+/**
+ * Prepare state live save operation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVLIVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDEVLIVEPREP() function. */
+typedef FNSSMDEVLIVEPREP *PFNSSMDEVLIVEPREP;
+
+/**
+ * Execute state live save operation.
+ *
+ * This will be called repeatedly until all units vote that the live phase has
+ * been concluded.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @param uPass The pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVLIVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMDEVLIVEEXEC() function. */
+typedef FNSSMDEVLIVEEXEC *PFNSSMDEVLIVEEXEC;
+
+/**
+ * Vote on whether the live part of the saving has been concluded.
+ *
+ * The vote stops once a unit has vetoed the decision, so don't rely upon this
+ * being called every time.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS if done.
+ * @retval VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ * done and there is not need calling it again before the final pass.
+ * @retval VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
+ *
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVLIVEVOTE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMDEVLIVEVOTE() function. */
+typedef FNSSMDEVLIVEVOTE *PFNSSMDEVLIVEVOTE;
+
+/**
+ * Prepare state save operation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVSAVEPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDEVSAVEPREP() function. */
+typedef FNSSMDEVSAVEPREP *PFNSSMDEVSAVEPREP;
+
+/**
+ * Execute state save operation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVSAVEEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDEVSAVEEXEC() function. */
+typedef FNSSMDEVSAVEEXEC *PFNSSMDEVSAVEEXEC;
+
+/**
+ * Done state save operation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVSAVEDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDEVSAVEDONE() function. */
+typedef FNSSMDEVSAVEDONE *PFNSSMDEVSAVEDONE;
+
+/**
+ * Prepare state load operation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVLOADPREP(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDEVLOADPREP() function. */
+typedef FNSSMDEVLOADPREP *PFNSSMDEVLOADPREP;
+
+/**
+ * Execute state load operation.
+ *
+ * @returns VBox status code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @param uVersion Data layout version.
+ * @param uPass The pass. This is always SSM_PASS_FINAL for units
+ * that doesn't specify a pfnSaveLive callback.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVLOADEXEC(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+/** Pointer to a FNSSMDEVLOADEXEC() function. */
+typedef FNSSMDEVLOADEXEC *PFNSSMDEVLOADEXEC;
+
+/**
+ * Done state load operation.
+ *
+ * @returns VBox load code.
+ * @param pDevIns Device instance of the device which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDEVLOADDONE(PPDMDEVINS pDevIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDEVLOADDONE() function. */
+typedef FNSSMDEVLOADDONE *PFNSSMDEVLOADDONE;
+
+/** @} */
+
+
+/** The PDM USB device callback variants.
+ * @{
+ */
+
+/**
+ * Prepare state live save operation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBLIVEPREP(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMUSBLIVEPREP() function. */
+typedef FNSSMUSBLIVEPREP *PFNSSMUSBLIVEPREP;
+
+/**
+ * Execute state live save operation.
+ *
+ * This will be called repeatedly until all units vote that the live phase has
+ * been concluded.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @param uPass The pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBLIVEEXEC(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMUSBLIVEEXEC() function. */
+typedef FNSSMUSBLIVEEXEC *PFNSSMUSBLIVEEXEC;
+
+/**
+ * Vote on whether the live part of the saving has been concluded.
+ *
+ * The vote stops once a unit has vetoed the decision, so don't rely upon this
+ * being called every time.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS if done.
+ * @retval VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ * done and there is not need calling it again before the final pass.
+ * @retval VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
+ *
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBLIVEVOTE(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMUSBLIVEVOTE() function. */
+typedef FNSSMUSBLIVEVOTE *PFNSSMUSBLIVEVOTE;
+
+/**
+ * Prepare state save operation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBSAVEPREP(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMUSBSAVEPREP() function. */
+typedef FNSSMUSBSAVEPREP *PFNSSMUSBSAVEPREP;
+
+/**
+ * Execute state save operation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBSAVEEXEC(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMUSBSAVEEXEC() function. */
+typedef FNSSMUSBSAVEEXEC *PFNSSMUSBSAVEEXEC;
+
+/**
+ * Done state save operation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBSAVEDONE(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMUSBSAVEDONE() function. */
+typedef FNSSMUSBSAVEDONE *PFNSSMUSBSAVEDONE;
+
+/**
+ * Prepare state load operation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBLOADPREP(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMUSBLOADPREP() function. */
+typedef FNSSMUSBLOADPREP *PFNSSMUSBLOADPREP;
+
+/**
+ * Execute state load operation.
+ *
+ * @returns VBox status code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @param uVersion Data layout version.
+ * @param uPass The pass. This is always SSM_PASS_FINAL for units
+ * that doesn't specify a pfnSaveLive callback.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBLOADEXEC(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+/** Pointer to a FNSSMUSBLOADEXEC() function. */
+typedef FNSSMUSBLOADEXEC *PFNSSMUSBLOADEXEC;
+
+/**
+ * Done state load operation.
+ *
+ * @returns VBox load code.
+ * @param pUsbIns The USB device instance of the USB device which
+ * registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMUSBLOADDONE(PPDMUSBINS pUsbIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMUSBLOADDONE() function. */
+typedef FNSSMUSBLOADDONE *PFNSSMUSBLOADDONE;
+
+/** @} */
+
+
+/** The PDM Driver callback variants.
+ * @{
+ */
+
+/**
+ * Prepare state live save operation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance of the driver which registered the
+ * data unit.
+ * @param pSSM SSM operation handle.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVLIVEPREP(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDRVLIVEPREP() function. */
+typedef FNSSMDRVLIVEPREP *PFNSSMDRVLIVEPREP;
+
+/**
+ * Execute state live save operation.
+ *
+ * This will be called repeatedly until all units vote that the live phase has
+ * been concluded.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance of the driver which registered the
+ * data unit.
+ * @param pSSM SSM operation handle.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVLIVEEXEC(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMDRVLIVEEXEC() function. */
+typedef FNSSMDRVLIVEEXEC *PFNSSMDRVLIVEEXEC;
+
+/**
+ * Vote on whether the live part of the saving has been concluded.
+ *
+ * The vote stops once a unit has vetoed the decision, so don't rely upon this
+ * being called every time.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS if done.
+ * @retval VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ * done and there is not need calling it again before the final pass.
+ * @retval VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
+ *
+ * @param pDrvIns Driver instance of the driver which registered the
+ * data unit.
+ * @param pSSM SSM operation handle.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVLIVEVOTE(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMDRVLIVEVOTE() function. */
+typedef FNSSMDRVLIVEVOTE *PFNSSMDRVLIVEVOTE;
+
+
+/**
+ * Prepare state save operation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance of the driver which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVSAVEPREP(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDRVSAVEPREP() function. */
+typedef FNSSMDRVSAVEPREP *PFNSSMDRVSAVEPREP;
+
+/**
+ * Execute state save operation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance of the driver which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVSAVEEXEC(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDRVSAVEEXEC() function. */
+typedef FNSSMDRVSAVEEXEC *PFNSSMDRVSAVEEXEC;
+
+/**
+ * Done state save operation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance of the driver which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVSAVEDONE(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDRVSAVEDONE() function. */
+typedef FNSSMDRVSAVEDONE *PFNSSMDRVSAVEDONE;
+
+/**
+ * Prepare state load operation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance of the driver which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVLOADPREP(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDRVLOADPREP() function. */
+typedef FNSSMDRVLOADPREP *PFNSSMDRVLOADPREP;
+
+/**
+ * Execute state load operation.
+ *
+ * @returns VBox status code.
+ * @param pDrvIns Driver instance of the driver which registered the data unit.
+ * @param pSSM SSM operation handle.
+ * @param uVersion Data layout version.
+ * @param uPass The pass. This is always SSM_PASS_FINAL for units
+ * that doesn't specify a pfnSaveLive callback.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVLOADEXEC(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+/** Pointer to a FNSSMDRVLOADEXEC() function. */
+typedef FNSSMDRVLOADEXEC *PFNSSMDRVLOADEXEC;
+
+/**
+ * Done state load operation.
+ *
+ * @returns VBox load code.
+ * @param pDrvIns Driver instance of the driver which registered the data unit.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMDRVLOADDONE(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMDRVLOADDONE() function. */
+typedef FNSSMDRVLOADDONE *PFNSSMDRVLOADDONE;
+
+/** @} */
+
+
+/** The internal callback variants.
+ * @{
+ */
+
+
+/**
+ * Prepare state live save operation.
+ *
+ * @returns VBox status code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMINTLIVEPREP(PVM pVM, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMINTLIVEPREP() function. */
+typedef FNSSMINTLIVEPREP *PFNSSMINTLIVEPREP;
+
+/**
+ * Execute state live save operation.
+ *
+ * This will be called repeatedly until all units vote that the live phase has
+ * been concluded.
+ *
+ * @returns VBox status code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMINTLIVEEXEC(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMINTLIVEEXEC() function. */
+typedef FNSSMINTLIVEEXEC *PFNSSMINTLIVEEXEC;
+
+/**
+ * Vote on whether the live part of the saving has been concluded.
+ *
+ * The vote stops once a unit has vetoed the decision, so don't rely upon this
+ * being called every time.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS if done.
+ * @retval VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ * done and there is not need calling it again before the final pass.
+ * @retval VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
+ *
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMINTLIVEVOTE(PVM pVM, PSSMHANDLE pSSM, uint32_t uPass);
+/** Pointer to a FNSSMINTLIVEVOTE() function. */
+typedef FNSSMINTLIVEVOTE *PFNSSMINTLIVEVOTE;
+
+/**
+ * Prepare state save operation.
+ *
+ * @returns VBox status code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMINTSAVEPREP(PVM pVM, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMINTSAVEPREP() function. */
+typedef FNSSMINTSAVEPREP *PFNSSMINTSAVEPREP;
+
+/**
+ * Execute state save operation.
+ *
+ * @returns VBox status code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMINTSAVEEXEC(PVM pVM, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMINTSAVEEXEC() function. */
+typedef FNSSMINTSAVEEXEC *PFNSSMINTSAVEEXEC;
+
+/**
+ * Done state save operation.
+ *
+ * @returns VBox status code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMINTSAVEDONE(PVM pVM, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMINTSAVEDONE() function. */
+typedef FNSSMINTSAVEDONE *PFNSSMINTSAVEDONE;
+
+/**
+ * Prepare state load operation.
+ *
+ * @returns VBox status code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMINTLOADPREP(PVM pVM, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMINTLOADPREP() function. */
+typedef FNSSMINTLOADPREP *PFNSSMINTLOADPREP;
+
+/**
+ * Execute state load operation.
+ *
+ * @returns VBox status code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ * @param uVersion Data layout version.
+ * @param uPass The pass. This is always SSM_PASS_FINAL for units
+ * that doesn't specify a pfnSaveLive callback.
+ */
+typedef DECLCALLBACK(int) FNSSMINTLOADEXEC(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass);
+/** Pointer to a FNSSMINTLOADEXEC() function. */
+typedef FNSSMINTLOADEXEC *PFNSSMINTLOADEXEC;
+
+/**
+ * Done state load operation.
+ *
+ * @returns VBox load code.
+ * @param pVM VM Handle.
+ * @param pSSM SSM operation handle.
+ */
+typedef DECLCALLBACK(int) FNSSMINTLOADDONE(PVM pVM, PSSMHANDLE pSSM);
+/** Pointer to a FNSSMINTLOADDONE() function. */
+typedef FNSSMINTLOADDONE *PFNSSMINTLOADDONE;
+
+/** @} */
+
+
+/** The External callback variants.
+ * @{
+ */
+
+/**
+ * Prepare state live save operation.
+ *
+ * @returns VBox status code.
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTLIVEPREP(PSSMHANDLE pSSM, void *pvUser);
+/** Pointer to a FNSSMEXTLIVEPREP() function. */
+typedef FNSSMEXTLIVEPREP *PFNSSMEXTLIVEPREP;
+
+/**
+ * Execute state live save operation.
+ *
+ * This will be called repeatedly until all units vote that the live phase has
+ * been concluded.
+ *
+ * @returns VBox status code.
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTLIVEEXEC(PSSMHANDLE pSSM, void *pvUser, uint32_t uPass);
+/** Pointer to a FNSSMEXTLIVEEXEC() function. */
+typedef FNSSMEXTLIVEEXEC *PFNSSMEXTLIVEEXEC;
+
+/**
+ * Vote on whether the live part of the saving has been concluded.
+ *
+ * The vote stops once a unit has vetoed the decision, so don't rely upon this
+ * being called every time.
+ *
+ * @returns VBox status code.
+ * @retval VINF_SUCCESS if done.
+ * @retval VINF_SSM_VOTE_FOR_ANOTHER_PASS if another pass is needed.
+ * @retval VINF_SSM_VOTE_DONE_DONT_CALL_AGAIN if the live saving of the unit is
+ * done and there is not need calling it again before the final pass.
+ * @retval VERR_SSM_VOTE_FOR_GIVING_UP if its time to give up.
+ *
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ * @param uPass The data pass.
+ * @thread Any.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTLIVEVOTE(PSSMHANDLE pSSM, void *pvUser, uint32_t uPass);
+/** Pointer to a FNSSMEXTLIVEVOTE() function. */
+typedef FNSSMEXTLIVEVOTE *PFNSSMEXTLIVEVOTE;
+
+/**
+ * Prepare state save operation.
+ *
+ * @returns VBox status code.
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTSAVEPREP(PSSMHANDLE pSSM, void *pvUser);
+/** Pointer to a FNSSMEXTSAVEPREP() function. */
+typedef FNSSMEXTSAVEPREP *PFNSSMEXTSAVEPREP;
+
+/**
+ * Execute state save operation.
+ *
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ * @author The lack of return code is for legacy reasons.
+ */
+typedef DECLCALLBACK(void) FNSSMEXTSAVEEXEC(PSSMHANDLE pSSM, void *pvUser);
+/** Pointer to a FNSSMEXTSAVEEXEC() function. */
+typedef FNSSMEXTSAVEEXEC *PFNSSMEXTSAVEEXEC;
+
+/**
+ * Done state save operation.
+ *
+ * @returns VBox status code.
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTSAVEDONE(PSSMHANDLE pSSM, void *pvUser);
+/** Pointer to a FNSSMEXTSAVEDONE() function. */
+typedef FNSSMEXTSAVEDONE *PFNSSMEXTSAVEDONE;
+
+/**
+ * Prepare state load operation.
+ *
+ * @returns VBox status code.
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTLOADPREP(PSSMHANDLE pSSM, void *pvUser);
+/** Pointer to a FNSSMEXTLOADPREP() function. */
+typedef FNSSMEXTLOADPREP *PFNSSMEXTLOADPREP;
+
+/**
+ * Execute state load operation.
+ *
+ * @returns VBox status code.
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ * @param uVersion Data layout version.
+ * @param uPass The pass. This is always SSM_PASS_FINAL for units
+ * that doesn't specify a pfnSaveLive callback.
+ * @remark The odd return value is for legacy reasons.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTLOADEXEC(PSSMHANDLE pSSM, void *pvUser, uint32_t uVersion, uint32_t uPass);
+/** Pointer to a FNSSMEXTLOADEXEC() function. */
+typedef FNSSMEXTLOADEXEC *PFNSSMEXTLOADEXEC;
+
+/**
+ * Done state load operation.
+ *
+ * @returns VBox load code.
+ * @param pSSM SSM operation handle.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNSSMEXTLOADDONE(PSSMHANDLE pSSM, void *pvUser);
+/** Pointer to a FNSSMEXTLOADDONE() function. */
+typedef FNSSMEXTLOADDONE *PFNSSMEXTLOADDONE;
+
+/** @} */
+
+
+/**
+ * SSM stream method table.
+ *
+ * This is used by external parties for teleporting over TCP or any other media.
+ * SSM also uses this internally for file access, thus the 2-3 file centric
+ * methods.
+ */
+typedef struct SSMSTRMOPS
+{
+ /** Struct magic + version (SSMSTRMOPS_VERSION). */
+ uint32_t u32Version;
+
+ /**
+ * Write bytes to the stream.
+ *
+ * @returns VBox status code.
+ * @param pvUser The user argument.
+ * @param offStream The stream offset we're (supposed to be) at.
+ * @param pvBuf Pointer to the data.
+ * @param cbToWrite The number of bytes to write.
+ */
+ DECLCALLBACKMEMBER(int, pfnWrite)(void *pvUser, uint64_t offStream, const void *pvBuf, size_t cbToWrite);
+
+ /**
+ * Read bytes to the stream.
+ *
+ * @returns VBox status code.
+ * @param pvUser The user argument.
+ * @param offStream The stream offset we're (supposed to be) at.
+ * @param pvBuf Where to return the bytes.
+ * @param cbToRead The number of bytes to read.
+ * @param pcbRead Where to return the number of bytes actually
+ * read. This may differ from cbToRead when the
+ * end of the stream is encountered.
+ */
+ DECLCALLBACKMEMBER(int, pfnRead)(void *pvUser, uint64_t offStream, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+ /**
+ * Seeks in the stream.
+ *
+ * @returns VBox status code.
+ * @retval VERR_NOT_SUPPORTED if the stream doesn't support this action.
+ *
+ * @param pvUser The user argument.
+ * @param offSeek The seek offset.
+ * @param uMethod RTFILE_SEEK_BEGIN, RTFILE_SEEK_END or
+ * RTFILE_SEEK_CURRENT.
+ * @param poffActual Where to store the new file position. Optional.
+ */
+ DECLCALLBACKMEMBER(int, pfnSeek)(void *pvUser, int64_t offSeek, unsigned uMethod, uint64_t *poffActual);
+
+ /**
+ * Get the current stream position.
+ *
+ * @returns The correct stream position.
+ * @param pvUser The user argument.
+ */
+ DECLCALLBACKMEMBER(uint64_t, pfnTell)(void *pvUser);
+
+ /**
+ * Get the size/length of the stream.
+ *
+ * @returns VBox status code.
+ * @retval VERR_NOT_SUPPORTED if the stream doesn't support this action.
+ *
+ * @param pvUser The user argument.
+ * @param pcb Where to return the size/length.
+ */
+ DECLCALLBACKMEMBER(int, pfnSize)(void *pvUser, uint64_t *pcb);
+
+ /**
+ * Check if the stream is OK or not (cancelled).
+ *
+ * @returns VBox status code.
+ * @param pvUser The user argument.
+ *
+ * @remarks The method is expected to do a LogRel on failure.
+ */
+ DECLCALLBACKMEMBER(int, pfnIsOk)(void *pvUser);
+
+ /**
+ * Close the stream.
+ *
+ * @returns VBox status code.
+ * @param pvUser The user argument.
+ * @param fCancelled True if the operation was cancelled.
+ */
+ DECLCALLBACKMEMBER(int, pfnClose)(void *pvUser, bool fCancelled);
+
+ /** Struct magic + version (SSMSTRMOPS_VERSION). */
+ uint32_t u32EndVersion;
+} SSMSTRMOPS;
+/** Struct magic + version (SSMSTRMOPS_VERSION). */
+#define SSMSTRMOPS_VERSION UINT32_C(0x55aa0001)
+
+
+VMMR3_INT_DECL(void) SSMR3Term(PVM pVM);
+VMMR3DECL(int) SSMR3RegisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess, const char *pszBefore,
+ PFNSSMDEVLIVEPREP pfnLivePrep, PFNSSMDEVLIVEEXEC pfnLiveExec, PFNSSMDEVLIVEVOTE pfnLiveVote,
+ PFNSSMDEVSAVEPREP pfnSavePrep, PFNSSMDEVSAVEEXEC pfnSaveExec, PFNSSMDEVSAVEDONE pfnSaveDone,
+ PFNSSMDEVLOADPREP pfnLoadPrep, PFNSSMDEVLOADEXEC pfnLoadExec, PFNSSMDEVLOADDONE pfnLoadDone);
+VMMR3DECL(int) SSMR3RegisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
+ PFNSSMDRVLIVEPREP pfnLivePrep, PFNSSMDRVLIVEEXEC pfnLiveExec, PFNSSMDRVLIVEVOTE pfnLiveVote,
+ PFNSSMDRVSAVEPREP pfnSavePrep, PFNSSMDRVSAVEEXEC pfnSaveExec, PFNSSMDRVSAVEDONE pfnSaveDone,
+ PFNSSMDRVLOADPREP pfnLoadPrep, PFNSSMDRVLOADEXEC pfnLoadExec, PFNSSMDRVLOADDONE pfnLoadDone);
+VMMR3DECL(int) SSMR3RegisterInternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
+ PFNSSMINTLIVEPREP pfnLivePrep, PFNSSMINTLIVEEXEC pfnLiveExec, PFNSSMINTLIVEVOTE pfnLiveVote,
+ PFNSSMINTSAVEPREP pfnSavePrep, PFNSSMINTSAVEEXEC pfnSaveExec, PFNSSMINTSAVEDONE pfnSaveDone,
+ PFNSSMINTLOADPREP pfnLoadPrep, PFNSSMINTLOADEXEC pfnLoadExec, PFNSSMINTLOADDONE pfnLoadDone);
+VMMR3DECL(int) SSMR3RegisterExternal(PVM pVM, const char *pszName, uint32_t uInstance, uint32_t uVersion, size_t cbGuess,
+ PFNSSMEXTLIVEPREP pfnLivePrep, PFNSSMEXTLIVEEXEC pfnLiveExec, PFNSSMEXTLIVEVOTE pfnLiveVote,
+ PFNSSMEXTSAVEPREP pfnSavePrep, PFNSSMEXTSAVEEXEC pfnSaveExec, PFNSSMEXTSAVEDONE pfnSaveDone,
+ PFNSSMEXTLOADPREP pfnLoadPrep, PFNSSMEXTLOADEXEC pfnLoadExec, PFNSSMEXTLOADDONE pfnLoadDone, void *pvUser);
+VMMR3_INT_DECL(int) SSMR3DeregisterDevice(PVM pVM, PPDMDEVINS pDevIns, const char *pszName, uint32_t uInstance);
+VMMR3_INT_DECL(int) SSMR3DeregisterDriver(PVM pVM, PPDMDRVINS pDrvIns, const char *pszName, uint32_t uInstance);
+VMMR3DECL(int) SSMR3DeregisterInternal(PVM pVM, const char *pszName);
+VMMR3DECL(int) SSMR3DeregisterExternal(PVM pVM, const char *pszName);
+VMMR3DECL(int) SSMR3Save(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvUser);
+VMMR3_INT_DECL(int) SSMR3LiveSave(PVM pVM, uint32_t cMsMaxDowntime,
+ const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOps,
+ SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser,
+ PSSMHANDLE *ppSSM);
+VMMR3_INT_DECL(int) SSMR3LiveDoStep1(PSSMHANDLE pSSM);
+VMMR3_INT_DECL(int) SSMR3LiveDoStep2(PSSMHANDLE pSSM);
+VMMR3_INT_DECL(int) SSMR3LiveDone(PSSMHANDLE pSSM);
+VMMR3DECL(int) SSMR3Load(PVM pVM, const char *pszFilename, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
+ SSMAFTER enmAfter, PFNVMPROGRESS pfnProgress, void *pvProgressUser);
+VMMR3DECL(int) SSMR3ValidateFile(const char *pszFilename, bool fChecksumIt);
+VMMR3DECL(int) SSMR3Open(const char *pszFilename, unsigned fFlags, PSSMHANDLE *ppSSM);
+VMMR3DECL(int) SSMR3Close(PSSMHANDLE pSSM);
+VMMR3DECL(int) SSMR3Seek(PSSMHANDLE pSSM, const char *pszUnit, uint32_t iInstance, uint32_t *piVersion);
+VMMR3DECL(int) SSMR3HandleGetStatus(PSSMHANDLE pSSM);
+VMMR3DECL(int) SSMR3HandleSetStatus(PSSMHANDLE pSSM, int iStatus);
+VMMR3DECL(SSMAFTER) SSMR3HandleGetAfter(PSSMHANDLE pSSM);
+VMMR3DECL(bool) SSMR3HandleIsLiveSave(PSSMHANDLE pSSM);
+VMMR3DECL(uint32_t) SSMR3HandleMaxDowntime(PSSMHANDLE pSSM);
+VMMR3DECL(uint32_t) SSMR3HandleHostBits(PSSMHANDLE pSSM);
+VMMR3DECL(uint32_t) SSMR3HandleRevision(PSSMHANDLE pSSM);
+VMMR3DECL(uint32_t) SSMR3HandleVersion(PSSMHANDLE pSSM);
+VMMR3DECL(const char *) SSMR3HandleHostOSAndArch(PSSMHANDLE pSSM);
+VMMR3_INT_DECL(int) SSMR3HandleSetGCPtrSize(PSSMHANDLE pSSM, unsigned cbGCPtr);
+VMMR3DECL(void) SSMR3HandleReportLivePercent(PSSMHANDLE pSSM, unsigned uPercent);
+VMMR3DECL(int) SSMR3Cancel(PVM pVM);
+
+
+/** Save operations.
+ * @{
+ */
+VMMR3DECL(int) SSMR3PutStruct(PSSMHANDLE pSSM, const void *pvStruct, PCSSMFIELD paFields);
+VMMR3DECL(int) SSMR3PutStructEx(PSSMHANDLE pSSM, const void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser);
+VMMR3DECL(int) SSMR3PutBool(PSSMHANDLE pSSM, bool fBool);
+VMMR3DECL(int) SSMR3PutU8(PSSMHANDLE pSSM, uint8_t u8);
+VMMR3DECL(int) SSMR3PutS8(PSSMHANDLE pSSM, int8_t i8);
+VMMR3DECL(int) SSMR3PutU16(PSSMHANDLE pSSM, uint16_t u16);
+VMMR3DECL(int) SSMR3PutS16(PSSMHANDLE pSSM, int16_t i16);
+VMMR3DECL(int) SSMR3PutU32(PSSMHANDLE pSSM, uint32_t u32);
+VMMR3DECL(int) SSMR3PutS32(PSSMHANDLE pSSM, int32_t i32);
+VMMR3DECL(int) SSMR3PutU64(PSSMHANDLE pSSM, uint64_t u64);
+VMMR3DECL(int) SSMR3PutS64(PSSMHANDLE pSSM, int64_t i64);
+VMMR3DECL(int) SSMR3PutU128(PSSMHANDLE pSSM, uint128_t u128);
+VMMR3DECL(int) SSMR3PutS128(PSSMHANDLE pSSM, int128_t i128);
+VMMR3DECL(int) SSMR3PutUInt(PSSMHANDLE pSSM, RTUINT u);
+VMMR3DECL(int) SSMR3PutSInt(PSSMHANDLE pSSM, RTINT i);
+VMMR3DECL(int) SSMR3PutGCUInt(PSSMHANDLE pSSM, RTGCUINT u);
+VMMR3DECL(int) SSMR3PutGCUIntReg(PSSMHANDLE pSSM, RTGCUINTREG u);
+VMMR3DECL(int) SSMR3PutGCPhys32(PSSMHANDLE pSSM, RTGCPHYS32 GCPhys);
+VMMR3DECL(int) SSMR3PutGCPhys64(PSSMHANDLE pSSM, RTGCPHYS64 GCPhys);
+VMMR3DECL(int) SSMR3PutGCPhys(PSSMHANDLE pSSM, RTGCPHYS GCPhys);
+VMMR3DECL(int) SSMR3PutGCPtr(PSSMHANDLE pSSM, RTGCPTR GCPtr);
+VMMR3DECL(int) SSMR3PutGCUIntPtr(PSSMHANDLE pSSM, RTGCUINTPTR GCPtr);
+VMMR3DECL(int) SSMR3PutRCPtr(PSSMHANDLE pSSM, RTRCPTR RCPtr);
+VMMR3DECL(int) SSMR3PutIOPort(PSSMHANDLE pSSM, RTIOPORT IOPort);
+VMMR3DECL(int) SSMR3PutSel(PSSMHANDLE pSSM, RTSEL Sel);
+VMMR3DECL(int) SSMR3PutMem(PSSMHANDLE pSSM, const void *pv, size_t cb);
+VMMR3DECL(int) SSMR3PutStrZ(PSSMHANDLE pSSM, const char *psz);
+/** @} */
+
+
+
+/** Load operations.
+ * @{
+ */
+VMMR3DECL(int) SSMR3GetStruct(PSSMHANDLE pSSM, void *pvStruct, PCSSMFIELD paFields);
+VMMR3DECL(int) SSMR3GetStructEx(PSSMHANDLE pSSM, void *pvStruct, size_t cbStruct, uint32_t fFlags, PCSSMFIELD paFields, void *pvUser);
+VMMR3DECL(int) SSMR3GetBool(PSSMHANDLE pSSM, bool *pfBool);
+VMMR3DECL(int) SSMR3GetU8(PSSMHANDLE pSSM, uint8_t *pu8);
+VMMR3DECL(int) SSMR3GetS8(PSSMHANDLE pSSM, int8_t *pi8);
+VMMR3DECL(int) SSMR3GetU16(PSSMHANDLE pSSM, uint16_t *pu16);
+VMMR3DECL(int) SSMR3GetS16(PSSMHANDLE pSSM, int16_t *pi16);
+VMMR3DECL(int) SSMR3GetU32(PSSMHANDLE pSSM, uint32_t *pu32);
+VMMR3DECL(int) SSMR3GetS32(PSSMHANDLE pSSM, int32_t *pi32);
+VMMR3DECL(int) SSMR3GetU64(PSSMHANDLE pSSM, uint64_t *pu64);
+VMMR3DECL(int) SSMR3GetS64(PSSMHANDLE pSSM, int64_t *pi64);
+VMMR3DECL(int) SSMR3GetU128(PSSMHANDLE pSSM, uint128_t *pu128);
+VMMR3DECL(int) SSMR3GetS128(PSSMHANDLE pSSM, int128_t *pi128);
+VMMR3DECL(int) SSMR3GetUInt(PSSMHANDLE pSSM, PRTUINT pu);
+VMMR3DECL(int) SSMR3GetSInt(PSSMHANDLE pSSM, PRTINT pi);
+VMMR3DECL(int) SSMR3GetGCUInt(PSSMHANDLE pSSM, PRTGCUINT pu);
+VMMR3DECL(int) SSMR3GetGCUIntReg(PSSMHANDLE pSSM, PRTGCUINTREG pu);
+VMMR3DECL(int) SSMR3GetGCPhys32(PSSMHANDLE pSSM, PRTGCPHYS32 pGCPhys);
+VMMR3DECL(int) SSMR3GetGCPhys64(PSSMHANDLE pSSM, PRTGCPHYS64 pGCPhys);
+VMMR3DECL(int) SSMR3GetGCPhys(PSSMHANDLE pSSM, PRTGCPHYS pGCPhys);
+VMMR3DECL(int) SSMR3GetGCPtr(PSSMHANDLE pSSM, PRTGCPTR pGCPtr);
+VMMR3DECL(int) SSMR3GetGCUIntPtr(PSSMHANDLE pSSM, PRTGCUINTPTR pGCPtr);
+VMMR3DECL(int) SSMR3GetRCPtr(PSSMHANDLE pSSM, PRTRCPTR pRCPtr);
+VMMR3DECL(int) SSMR3GetIOPort(PSSMHANDLE pSSM, PRTIOPORT pIOPort);
+VMMR3DECL(int) SSMR3GetSel(PSSMHANDLE pSSM, PRTSEL pSel);
+VMMR3DECL(int) SSMR3GetMem(PSSMHANDLE pSSM, void *pv, size_t cb);
+VMMR3DECL(int) SSMR3GetStrZ(PSSMHANDLE pSSM, char *psz, size_t cbMax);
+VMMR3DECL(int) SSMR3GetStrZEx(PSSMHANDLE pSSM, char *psz, size_t cbMax, size_t *pcbStr);
+VMMR3DECL(int) SSMR3GetTimer(PSSMHANDLE pSSM, PTMTIMER pTimer);
+VMMR3DECL(int) SSMR3Skip(PSSMHANDLE pSSM, size_t cb);
+VMMR3DECL(int) SSMR3SkipToEndOfUnit(PSSMHANDLE pSSM);
+VMMR3DECL(int) SSMR3SetLoadError(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
+VMMR3DECL(int) SSMR3SetLoadErrorV(PSSMHANDLE pSSM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
+VMMR3DECL(int) SSMR3SetCfgError(PSSMHANDLE pSSM, RT_SRC_POS_DECL, const char *pszFormat, ...);
+
+/** @} */
+
+/** @} */
+#endif /* IN_RING3 */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/stam.h b/include/VBox/vmm/stam.h
new file mode 100644
index 00000000..c25c606f
--- /dev/null
+++ b/include/VBox/vmm/stam.h
@@ -0,0 +1,1265 @@
+/** @file
+ * STAM - Statistics Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_stam_h
+#define ___VBox_vmm_stam_h
+
+#include <VBox/types.h>
+#include <iprt/stdarg.h>
+#ifdef _MSC_VER
+# if _MSC_VER >= 1400
+# include <intrin.h>
+# endif
+#endif
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_stam The Statistics Manager API
+ * @{
+ */
+
+#if defined(VBOX_WITHOUT_RELEASE_STATISTICS) && defined(VBOX_WITH_STATISTICS)
+# error "Both VBOX_WITHOUT_RELEASE_STATISTICS and VBOX_WITH_STATISTICS are defined! Make up your mind!"
+#endif
+
+
+/** @def STAM_GET_TS
+ * Gets the CPU timestamp counter.
+ *
+ * @param u64 The 64-bit variable which the timestamp shall be saved in.
+ */
+#ifdef __GNUC__
+# if defined(RT_ARCH_X86)
+ /* This produces optimal assembler code for x86 but does not work for AMD64 ('A' means 'either rax or rdx') */
+# define STAM_GET_TS(u64) __asm__ __volatile__ ("rdtsc\n\t" : "=A" (u64))
+# elif defined(RT_ARCH_AMD64)
+# define STAM_GET_TS(u64) \
+ do { uint64_t low; uint64_t high; \
+ __asm__ __volatile__ ("rdtsc\n\t" : "=a"(low), "=d"(high)); \
+ (u64) = ((high << 32) | low); \
+ } while (0)
+# endif
+#else
+# if _MSC_VER >= 1400
+# pragma intrinsic(__rdtsc)
+# define STAM_GET_TS(u64) \
+ do { (u64) = __rdtsc(); } while (0)
+# else
+# define STAM_GET_TS(u64) \
+ do { \
+ uint64_t u64Tmp; \
+ __asm { \
+ __asm rdtsc \
+ __asm mov dword ptr [u64Tmp], eax \
+ __asm mov dword ptr [u64Tmp + 4], edx \
+ } \
+ (u64) = u64Tmp; \
+ } while (0)
+# endif
+#endif
+
+
+/** @def STAM_REL_STATS
+ * Code for inclusion only when VBOX_WITH_STATISTICS is defined.
+ * @param code A code block enclosed in {}.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_STATS(code) do code while(0)
+#else
+# define STAM_REL_STATS(code) do {} while(0)
+#endif
+/** @def STAM_STATS
+ * Code for inclusion only when VBOX_WITH_STATISTICS is defined.
+ * @param code A code block enclosed in {}.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_STATS(code) STAM_REL_STATS(code)
+#else
+# define STAM_STATS(code) do {} while(0)
+#endif
+
+
+/**
+ * Sample type.
+ */
+typedef enum STAMTYPE
+{
+ /** Invalid entry. */
+ STAMTYPE_INVALID = 0,
+ /** Generic counter. */
+ STAMTYPE_COUNTER,
+ /** Profiling of an function. */
+ STAMTYPE_PROFILE,
+ /** Profiling of an operation. */
+ STAMTYPE_PROFILE_ADV,
+ /** Ratio of A to B, uint32_t types. Not reset. */
+ STAMTYPE_RATIO_U32,
+ /** Ratio of A to B, uint32_t types. Reset both to 0. */
+ STAMTYPE_RATIO_U32_RESET,
+ /** Callback. */
+ STAMTYPE_CALLBACK,
+ /** Generic unsigned 8-bit value. Not reset. */
+ STAMTYPE_U8,
+ /** Generic unsigned 8-bit value. Reset to 0. */
+ STAMTYPE_U8_RESET,
+ /** Generic hexadecimal unsigned 8-bit value. Not reset. */
+ STAMTYPE_X8,
+ /** Generic hexadecimal unsigned 8-bit value. Reset to 0. */
+ STAMTYPE_X8_RESET,
+ /** Generic unsigned 16-bit value. Not reset. */
+ STAMTYPE_U16,
+ /** Generic unsigned 16-bit value. Reset to 0. */
+ STAMTYPE_U16_RESET,
+ /** Generic hexadecimal unsigned 16-bit value. Not reset. */
+ STAMTYPE_X16,
+ /** Generic hexadecimal unsigned 16-bit value. Reset to 0. */
+ STAMTYPE_X16_RESET,
+ /** Generic unsigned 32-bit value. Not reset. */
+ STAMTYPE_U32,
+ /** Generic unsigned 32-bit value. Reset to 0. */
+ STAMTYPE_U32_RESET,
+ /** Generic hexadecimal unsigned 32-bit value. Not reset. */
+ STAMTYPE_X32,
+ /** Generic hexadecimal unsigned 32-bit value. Reset to 0. */
+ STAMTYPE_X32_RESET,
+ /** Generic unsigned 64-bit value. Not reset. */
+ STAMTYPE_U64,
+ /** Generic unsigned 64-bit value. Reset to 0. */
+ STAMTYPE_U64_RESET,
+ /** Generic hexadecimal unsigned 64-bit value. Not reset. */
+ STAMTYPE_X64,
+ /** Generic hexadecimal unsigned 64-bit value. Reset to 0. */
+ STAMTYPE_X64_RESET,
+ /** Generic boolean value. Not reset. */
+ STAMTYPE_BOOL,
+ /** Generic boolean value. Reset to false. */
+ STAMTYPE_BOOL_RESET,
+ /** The end (exclusive). */
+ STAMTYPE_END
+} STAMTYPE;
+
+/**
+ * Sample visibility type.
+ */
+typedef enum STAMVISIBILITY
+{
+ /** Invalid entry. */
+ STAMVISIBILITY_INVALID = 0,
+ /** Always visible. */
+ STAMVISIBILITY_ALWAYS,
+ /** Only visible when used (/hit). */
+ STAMVISIBILITY_USED,
+ /** Not visible in the GUI. */
+ STAMVISIBILITY_NOT_GUI,
+ /** The end (exclusive). */
+ STAMVISIBILITY_END
+} STAMVISIBILITY;
+
+/**
+ * Sample unit.
+ */
+typedef enum STAMUNIT
+{
+ /** Invalid entry .*/
+ STAMUNIT_INVALID = 0,
+ /** No unit. */
+ STAMUNIT_NONE,
+ /** Number of calls. */
+ STAMUNIT_CALLS,
+ /** Count of whatever. */
+ STAMUNIT_COUNT,
+ /** Count of bytes. */
+ STAMUNIT_BYTES,
+ /** Count of bytes. */
+ STAMUNIT_PAGES,
+ /** Error count. */
+ STAMUNIT_ERRORS,
+ /** Number of occurences. */
+ STAMUNIT_OCCURENCES,
+ /** Ticks. */
+ STAMUNIT_TICKS,
+ /** Ticks per call. */
+ STAMUNIT_TICKS_PER_CALL,
+ /** Ticks per occurence. */
+ STAMUNIT_TICKS_PER_OCCURENCE,
+ /** Ratio of good vs. bad. */
+ STAMUNIT_GOOD_BAD,
+ /** Megabytes. */
+ STAMUNIT_MEGABYTES,
+ /** Kilobytes. */
+ STAMUNIT_KILOBYTES,
+ /** Nano seconds. */
+ STAMUNIT_NS,
+ /** Nanoseconds per call. */
+ STAMUNIT_NS_PER_CALL,
+ /** Nanoseconds per call. */
+ STAMUNIT_NS_PER_OCCURENCE,
+ /** Percentage. */
+ STAMUNIT_PCT,
+ /** Hertz. */
+ STAMUNIT_HZ,
+ /** The end (exclusive). */
+ STAMUNIT_END
+} STAMUNIT;
+
+
+/** @def STAM_REL_U8_INC
+ * Increments a uint8_t sample by one.
+ *
+ * @param pCounter Pointer to the uint8_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U8_INC(pCounter) \
+ do { ++*(pCounter); } while (0)
+#else
+# define STAM_REL_U8_INC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U8_INC
+ * Increments a uint8_t sample by one.
+ *
+ * @param pCounter Pointer to the uint8_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U8_INC(pCounter) STAM_REL_U8_INC(pCounter)
+#else
+# define STAM_U8_INC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U8_DEC
+ * Decrements a uint8_t sample by one.
+ *
+ * @param pCounter Pointer to the uint8_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U8_DEC(pCounter) \
+ do { --*(pCounter); } while (0)
+#else
+# define STAM_REL_U8_DEC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U8_DEC
+ * Decrements a uint8_t sample by one.
+ *
+ * @param pCounter Pointer to the uint8_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U8_DEC(pCounter) STAM_REL_U8_DEC(pCounter)
+#else
+# define STAM_U8_DEC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U8_ADD
+ * Increments a uint8_t sample by a value.
+ *
+ * @param pCounter Pointer to the uint8_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U8_ADD(pCounter, Addend) \
+ do { *(pCounter) += (Addend); } while (0)
+#else
+# define STAM_REL_U8_ADD(pCounter, Addend) do { } while (0)
+#endif
+/** @def STAM_U8_ADD
+ * Increments a uint8_t sample by a value.
+ *
+ * @param pCounter Pointer to the uint8_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U8_ADD(pCounter, Addend) STAM_REL_U8_ADD(pCounter, Addend
+#else
+# define STAM_U8_ADD(pCounter, Addend) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U16_INC
+ * Increments a uint16_t sample by one.
+ *
+ * @param pCounter Pointer to the uint16_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U16_INC(pCounter) \
+ do { ++*(pCounter); } while (0)
+#else
+# define STAM_REL_U16_INC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U16_INC
+ * Increments a uint16_t sample by one.
+ *
+ * @param pCounter Pointer to the uint16_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U16_INC(pCounter) STAM_REL_U16_INC(pCounter)
+#else
+# define STAM_U16_INC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U16_DEC
+ * Decrements a uint16_t sample by one.
+ *
+ * @param pCounter Pointer to the uint16_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U16_DEC(pCounter) \
+ do { --*(pCounter); } while (0)
+#else
+# define STAM_REL_U16_DEC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U16_DEC
+ * Decrements a uint16_t sample by one.
+ *
+ * @param pCounter Pointer to the uint16_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U16_DEC(pCounter) STAM_REL_U16_DEC(pCounter)
+#else
+# define STAM_U16_DEC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U16_INC
+ * Increments a uint16_t sample by a value.
+ *
+ * @param pCounter Pointer to the uint16_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U16_ADD(pCounter, Addend) \
+ do { *(pCounter) += (Addend); } while (0)
+#else
+# define STAM_REL_U16_ADD(pCounter, Addend) do { } while (0)
+#endif
+/** @def STAM_U16_INC
+ * Increments a uint16_t sample by a value.
+ *
+ * @param pCounter Pointer to the uint16_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U16_ADD(pCounter, Addend) STAM_REL_U16_ADD(pCounter, Addend)
+#else
+# define STAM_U16_ADD(pCounter, Addend) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U32_INC
+ * Increments a uint32_t sample by one.
+ *
+ * @param pCounter Pointer to the uint32_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U32_INC(pCounter) \
+ do { ++*(pCounter); } while (0)
+#else
+# define STAM_REL_U32_INC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U32_INC
+ * Increments a uint32_t sample by one.
+ *
+ * @param pCounter Pointer to the uint32_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U32_INC(pCounter) STAM_REL_U32_INC(pCounter)
+#else
+# define STAM_U32_INC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U32_DEC
+ * Decrements a uint32_t sample by one.
+ *
+ * @param pCounter Pointer to the uint32_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U32_DEC(pCounter) \
+ do { --*(pCounter); } while (0)
+#else
+# define STAM_REL_U32_DEC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U32_DEC
+ * Decrements a uint32_t sample by one.
+ *
+ * @param pCounter Pointer to the uint32_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U32_DEC(pCounter) STAM_REL_U32_DEC(pCounter)
+#else
+# define STAM_U32_DEC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U32_ADD
+ * Increments a uint32_t sample by value.
+ *
+ * @param pCounter Pointer to the uint32_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U32_ADD(pCounter, Addend) \
+ do { *(pCounter) += (Addend); } while (0)
+#else
+# define STAM_REL_U32_ADD(pCounter, Addend) do { } while (0)
+#endif
+/** @def STAM_U32_ADD
+ * Increments a uint32_t sample by value.
+ *
+ * @param pCounter Pointer to the uint32_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U32_ADD(pCounter, Addend) STAM_REL_U32_ADD(pCounter, Addend)
+#else
+# define STAM_U32_ADD(pCounter, Addend) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U64_INC
+ * Increments a uint64_t sample by one.
+ *
+ * @param pCounter Pointer to the uint64_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U64_INC(pCounter) \
+ do { ++*(pCounter); } while (0)
+#else
+# define STAM_REL_U64_INC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U64_INC
+ * Increments a uint64_t sample by one.
+ *
+ * @param pCounter Pointer to the uint64_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U64_INC(pCounter) STAM_REL_U64_INC(pCounter)
+#else
+# define STAM_U64_INC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U64_DEC
+ * Decrements a uint64_t sample by one.
+ *
+ * @param pCounter Pointer to the uint64_t variable to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U64_DEC(pCounter) \
+ do { --*(pCounter); } while (0)
+#else
+# define STAM_REL_U64_DEC(pCounter) do { } while (0)
+#endif
+/** @def STAM_U64_DEC
+ * Decrements a uint64_t sample by one.
+ *
+ * @param pCounter Pointer to the uint64_t variable to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U64_DEC(pCounter) STAM_REL_U64_DEC(pCounter)
+#else
+# define STAM_U64_DEC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_U64_ADD
+ * Increments a uint64_t sample by a value.
+ *
+ * @param pCounter Pointer to the uint64_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_U64_ADD(pCounter, Addend) \
+ do { *(pCounter) += (Addend); } while (0)
+#else
+# define STAM_REL_U64_ADD(pCounter, Addend) do { } while (0)
+#endif
+/** @def STAM_U64_ADD
+ * Increments a uint64_t sample by a value.
+ *
+ * @param pCounter Pointer to the uint64_t variable to operate on.
+ * @param Addend The value to add.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_U64_ADD(pCounter, Addend) STAM_REL_U64_ADD(pCounter, Addend)
+#else
+# define STAM_U64_ADD(pCounter, Addend) do { } while (0)
+#endif
+
+
+/**
+ * Counter sample - STAMTYPE_COUNTER.
+ */
+typedef struct STAMCOUNTER
+{
+ /** The current count. */
+ volatile uint64_t c;
+} STAMCOUNTER;
+/** Pointer to a counter. */
+typedef STAMCOUNTER *PSTAMCOUNTER;
+/** Pointer to a const counter. */
+typedef const STAMCOUNTER *PCSTAMCOUNTER;
+
+
+/** @def STAM_REL_COUNTER_INC
+ * Increments a counter sample by one.
+ *
+ * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_COUNTER_INC(pCounter) \
+ do { (pCounter)->c++; } while (0)
+#else
+# define STAM_REL_COUNTER_INC(pCounter) do { } while (0)
+#endif
+/** @def STAM_COUNTER_INC
+ * Increments a counter sample by one.
+ *
+ * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_COUNTER_INC(pCounter) STAM_REL_COUNTER_INC(pCounter)
+#else
+# define STAM_COUNTER_INC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_COUNTER_DEC
+ * Decrements a counter sample by one.
+ *
+ * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_COUNTER_DEC(pCounter) \
+ do { (pCounter)->c--; } while (0)
+#else
+# define STAM_REL_COUNTER_DEC(pCounter) do { } while (0)
+#endif
+/** @def STAM_COUNTER_DEC
+ * Decrements a counter sample by one.
+ *
+ * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_COUNTER_DEC(pCounter) STAM_REL_COUNTER_DEC(pCounter)
+#else
+# define STAM_COUNTER_DEC(pCounter) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_COUNTER_ADD
+ * Increments a counter sample by a value.
+ *
+ * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
+ * @param Addend The value to add to the counter.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_COUNTER_ADD(pCounter, Addend) \
+ do { (pCounter)->c += (Addend); } while (0)
+#else
+# define STAM_REL_COUNTER_ADD(pCounter, Addend) do { } while (0)
+#endif
+/** @def STAM_COUNTER_ADD
+ * Increments a counter sample by a value.
+ *
+ * @param pCounter Pointer to the STAMCOUNTER structure to operate on.
+ * @param Addend The value to add to the counter.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_COUNTER_ADD(pCounter, Addend) STAM_REL_COUNTER_ADD(pCounter, Addend)
+#else
+# define STAM_COUNTER_ADD(pCounter, Addend) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_COUNTER_RESET
+ * Resets the statistics sample.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_COUNTER_RESET(pCounter) do { (pCounter)->c = 0; } while (0)
+#else
+# define STAM_REL_COUNTER_RESET(pCounter) do { } while (0)
+#endif
+/** @def STAM_COUNTER_RESET
+ * Resets the statistics sample.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_COUNTER_RESET(pCounter) STAM_REL_COUNTER_RESET(pCounter)
+#else
+# define STAM_COUNTER_RESET(pCounter) do { } while (0)
+#endif
+
+
+
+/**
+ * Profiling sample - STAMTYPE_PROFILE.
+ */
+typedef struct STAMPROFILE
+{
+ /** Number of periods. */
+ volatile uint64_t cPeriods;
+ /** Total count of ticks. */
+ volatile uint64_t cTicks;
+ /** Maximum tick count during a sampling. */
+ volatile uint64_t cTicksMax;
+ /** Minimum tick count during a sampling. */
+ volatile uint64_t cTicksMin;
+} STAMPROFILE;
+/** Pointer to a profile sample. */
+typedef STAMPROFILE *PSTAMPROFILE;
+/** Pointer to a const profile sample. */
+typedef const STAMPROFILE *PCSTAMPROFILE;
+
+
+/** @def STAM_REL_PROFILE_ADD_PERIOD
+ * Adds a period.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param cTicksInPeriod The number of tick (or whatever) of the preiod
+ * being added. This is only referenced once.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) \
+ do { \
+ uint64_t const StamPrefix_cTicks = (cTicksInPeriod); \
+ (pProfile)->cTicks += StamPrefix_cTicks; \
+ (pProfile)->cPeriods++; \
+ if ((pProfile)->cTicksMax < StamPrefix_cTicks) \
+ (pProfile)->cTicksMax = StamPrefix_cTicks; \
+ if ((pProfile)->cTicksMin > StamPrefix_cTicks) \
+ (pProfile)->cTicksMin = StamPrefix_cTicks; \
+ } while (0)
+#else
+# define STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADD_PERIOD
+ * Adds a period.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param cTicksInPeriod The number of tick (or whatever) of the preiod
+ * being added. This is only referenced once.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) STAM_REL_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod)
+#else
+# define STAM_PROFILE_ADD_PERIOD(pProfile, cTicksInPeriod) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_PROFILE_START
+ * Samples the start time of a profiling period.
+ *
+ * @param pProfile Pointer to the STAMPROFILE structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ *
+ * @remarks Declears a stack variable that will be used by related macros.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_START(pProfile, Prefix) \
+ uint64_t Prefix##_tsStart; \
+ STAM_GET_TS(Prefix##_tsStart)
+#else
+# define STAM_REL_PROFILE_START(pProfile, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_START
+ * Samples the start time of a profiling period.
+ *
+ * @param pProfile Pointer to the STAMPROFILE structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ *
+ * @remarks Declears a stack variable that will be used by related macros.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_START(pProfile, Prefix) STAM_REL_PROFILE_START(pProfile, Prefix)
+#else
+# define STAM_PROFILE_START(pProfile, Prefix) do { } while (0)
+#endif
+
+/** @def STAM_REL_PROFILE_STOP
+ * Samples the stop time of a profiling period and updates the sample.
+ *
+ * @param pProfile Pointer to the STAMPROFILE structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_STOP(pProfile, Prefix) \
+ do { \
+ uint64_t Prefix##_cTicks; \
+ STAM_GET_TS(Prefix##_cTicks); \
+ Prefix##_cTicks -= Prefix##_tsStart; \
+ (pProfile)->cTicks += Prefix##_cTicks; \
+ (pProfile)->cPeriods++; \
+ if ((pProfile)->cTicksMax < Prefix##_cTicks) \
+ (pProfile)->cTicksMax = Prefix##_cTicks; \
+ if ((pProfile)->cTicksMin > Prefix##_cTicks) \
+ (pProfile)->cTicksMin = Prefix##_cTicks; \
+ } while (0)
+#else
+# define STAM_REL_PROFILE_STOP(pProfile, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_STOP
+ * Samples the stop time of a profiling period and updates the sample.
+ *
+ * @param pProfile Pointer to the STAMPROFILE structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_STOP(pProfile, Prefix) STAM_REL_PROFILE_STOP(pProfile, Prefix)
+#else
+# define STAM_PROFILE_STOP(pProfile, Prefix) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_PROFILE_STOP_EX
+ * Samples the stop time of a profiling period and updates both the sample
+ * and an attribution sample.
+ *
+ * @param pProfile Pointer to the STAMPROFILE structure to operate on.
+ * @param pProfile2 Pointer to the STAMPROFILE structure which this
+ * interval should be attributed to as well. This may be NULL.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) \
+ do { \
+ uint64_t Prefix##_cTicks; \
+ STAM_GET_TS(Prefix##_cTicks); \
+ Prefix##_cTicks -= Prefix##_tsStart; \
+ (pProfile)->cTicks += Prefix##_cTicks; \
+ (pProfile)->cPeriods++; \
+ if ((pProfile)->cTicksMax < Prefix##_cTicks) \
+ (pProfile)->cTicksMax = Prefix##_cTicks; \
+ if ((pProfile)->cTicksMin > Prefix##_cTicks) \
+ (pProfile)->cTicksMin = Prefix##_cTicks; \
+ \
+ if ((pProfile2)) \
+ { \
+ (pProfile2)->cTicks += Prefix##_cTicks; \
+ (pProfile2)->cPeriods++; \
+ if ((pProfile2)->cTicksMax < Prefix##_cTicks) \
+ (pProfile2)->cTicksMax = Prefix##_cTicks; \
+ if ((pProfile2)->cTicksMin > Prefix##_cTicks) \
+ (pProfile2)->cTicksMin = Prefix##_cTicks; \
+ } \
+ } while (0)
+#else
+# define STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_STOP_EX
+ * Samples the stop time of a profiling period and updates both the sample
+ * and an attribution sample.
+ *
+ * @param pProfile Pointer to the STAMPROFILE structure to operate on.
+ * @param pProfile2 Pointer to the STAMPROFILE structure which this
+ * interval should be attributed to as well. This may be NULL.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) STAM_REL_PROFILE_STOP_EX(pProfile, pProfile2, Prefix)
+#else
+# define STAM_PROFILE_STOP_EX(pProfile, pProfile2, Prefix) do { } while (0)
+#endif
+
+
+/**
+ * Advanced profiling sample - STAMTYPE_PROFILE_ADV.
+ *
+ * Identical to a STAMPROFILE sample, but the start timestamp
+ * is stored after the STAMPROFILE structure so the sampling
+ * can start and stop in different functions.
+ */
+typedef struct STAMPROFILEADV
+{
+ /** The STAMPROFILE core. */
+ STAMPROFILE Core;
+ /** The start timestamp. */
+ volatile uint64_t tsStart;
+} STAMPROFILEADV;
+/** Pointer to a advanced profile sample. */
+typedef STAMPROFILEADV *PSTAMPROFILEADV;
+/** Pointer to a const advanced profile sample. */
+typedef const STAMPROFILEADV *PCSTAMPROFILEADV;
+
+
+/** @def STAM_REL_PROFILE_ADV_START
+ * Samples the start time of a profiling period.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) \
+ STAM_GET_TS((pProfileAdv)->tsStart)
+#else
+# define STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADV_START
+ * Samples the start time of a profiling period.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_START(pProfileAdv, Prefix)
+#else
+# define STAM_PROFILE_ADV_START(pProfileAdv, Prefix) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_PROFILE_ADV_STOP
+ * Samples the stop time of a profiling period (if running) and updates the
+ * sample.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) \
+ do { \
+ if ((pProfileAdv)->tsStart) \
+ { \
+ uint64_t Prefix##_cTicks; \
+ STAM_GET_TS(Prefix##_cTicks); \
+ Prefix##_cTicks -= (pProfileAdv)->tsStart; \
+ (pProfileAdv)->tsStart = 0; \
+ (pProfileAdv)->Core.cTicks += Prefix##_cTicks; \
+ (pProfileAdv)->Core.cPeriods++; \
+ if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \
+ (pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \
+ if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \
+ (pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \
+ } \
+ } while (0)
+#else
+# define STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADV_STOP
+ * Samples the stop time of a profiling period (if running) and updates the
+ * sample.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_STOP(pProfileAdv, Prefix)
+#else
+# define STAM_PROFILE_ADV_STOP(pProfileAdv, Prefix) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_PROFILE_ADV_STOP_START
+ * Stops one profile counter (if running) and starts another one.
+ *
+ * @param pProfileAdv1 Pointer to the STAMPROFILEADV structure to stop.
+ * @param pProfileAdv2 Pointer to the STAMPROFILEADV structure to start.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
+ do { \
+ uint64_t Prefix##_cTicks; \
+ STAM_GET_TS(Prefix##_cTicks); \
+ (pProfileAdv2)->tsStart = Prefix##_cTicks; \
+ if ((pProfileAdv1)->tsStart) \
+ { \
+ Prefix##_cTicks -= (pProfileAdv1)->tsStart; \
+ (pProfileAdv1)->tsStart = 0; \
+ (pProfileAdv1)->Core.cTicks += Prefix##_cTicks; \
+ (pProfileAdv1)->Core.cPeriods++; \
+ if ((pProfileAdv1)->Core.cTicksMax < Prefix##_cTicks) \
+ (pProfileAdv1)->Core.cTicksMax = Prefix##_cTicks; \
+ if ((pProfileAdv1)->Core.cTicksMin > Prefix##_cTicks) \
+ (pProfileAdv1)->Core.cTicksMin = Prefix##_cTicks; \
+ } \
+ } while (0)
+#else
+# define STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
+ do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADV_STOP_START
+ * Samples the stop time of a profiling period (if running) and updates the
+ * sample.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
+ STAM_REL_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix)
+#else
+# define STAM_PROFILE_ADV_STOP_START(pProfileAdv1, pProfileAdv2, Prefix) \
+ do { } while (0)
+#endif
+
+
+/** @def STAM_REL_PROFILE_ADV_SUSPEND
+ * Suspends the sampling for a while. This can be useful to exclude parts
+ * covered by other samples without screwing up the count, and average+min times.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables. The prefix
+ * must match that of the resume one since it stores the
+ * suspend time in a stack variable.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) \
+ uint64_t Prefix##_tsSuspend; \
+ STAM_GET_TS(Prefix##_tsSuspend)
+#else
+# define STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADV_SUSPEND
+ * Suspends the sampling for a while. This can be useful to exclude parts
+ * covered by other samples without screwing up the count, and average+min times.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables. The prefix
+ * must match that of the resume one since it stores the
+ * suspend time in a stack variable.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix)
+#else
+# define STAM_PROFILE_ADV_SUSPEND(pProfileAdv, Prefix) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_PROFILE_ADV_RESUME
+ * Counter to STAM_REL_PROFILE_ADV_SUSPEND.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables. This must
+ * match the one used with the SUSPEND!
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) \
+ do { \
+ uint64_t Prefix##_tsNow; \
+ STAM_GET_TS(Prefix##_tsNow); \
+ (pProfileAdv)->tsStart += Prefix##_tsNow - Prefix##_tsSuspend; \
+ } while (0)
+#else
+# define STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADV_RESUME
+ * Counter to STAM_PROFILE_ADV_SUSPEND.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param Prefix Identifier prefix used to internal variables. This must
+ * match the one used with the SUSPEND!
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) STAM_REL_PROFILE_ADV_RESUME(pProfileAdv, Prefix)
+#else
+# define STAM_PROFILE_ADV_RESUME(pProfileAdv, Prefix) do { } while (0)
+#endif
+
+
+/** @def STAM_REL_PROFILE_ADV_STOP_EX
+ * Samples the stop time of a profiling period (if running) and updates both
+ * the sample and an attribution sample.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param pProfile2 Pointer to the STAMPROFILE structure which this
+ * interval should be attributed to as well. This may be NULL.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) \
+ do { \
+ if ((pProfileAdv)->tsStart) \
+ { \
+ uint64_t Prefix##_cTicks; \
+ STAM_GET_TS(Prefix##_cTicks); \
+ Prefix##_cTicks -= (pProfileAdv)->tsStart; \
+ (pProfileAdv)->tsStart = 0; \
+ (pProfileAdv)->Core.cTicks += Prefix##_cTicks; \
+ (pProfileAdv)->Core.cPeriods++; \
+ if ((pProfileAdv)->Core.cTicksMax < Prefix##_cTicks) \
+ (pProfileAdv)->Core.cTicksMax = Prefix##_cTicks; \
+ if ((pProfileAdv)->Core.cTicksMin > Prefix##_cTicks) \
+ (pProfileAdv)->Core.cTicksMin = Prefix##_cTicks; \
+ if ((pProfile2)) \
+ { \
+ (pProfile2)->cTicks += Prefix##_cTicks; \
+ (pProfile2)->cPeriods++; \
+ if ((pProfile2)->cTicksMax < Prefix##_cTicks) \
+ (pProfile2)->cTicksMax = Prefix##_cTicks; \
+ if ((pProfile2)->cTicksMin > Prefix##_cTicks) \
+ (pProfile2)->cTicksMin = Prefix##_cTicks; \
+ } \
+ } \
+ } while (0)
+#else
+# define STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADV_STOP_EX
+ * Samples the stop time of a profiling period (if running) and updates both
+ * the sample and an attribution sample.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ * @param pProfile2 Pointer to the STAMPROFILE structure which this
+ * interval should be attributed to as well. This may be NULL.
+ * @param Prefix Identifier prefix used to internal variables.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) STAM_REL_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix)
+#else
+# define STAM_PROFILE_ADV_STOP_EX(pProfileAdv, pProfile2, Prefix) do { } while (0)
+#endif
+
+/** @def STAM_REL_PROFILE_ADV_IS_RUNNING
+ * Checks if it is running.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv) (pProfileAdv)->tsStart
+#else
+# define STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv) (false)
+#endif
+/** @def STAM_PROFILE_ADV_IS_RUNNING
+ * Checks if it is running.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_IS_RUNNING(pProfileAdv) STAM_REL_PROFILE_ADV_IS_RUNNING(pProfileAdv)
+#else
+# define STAM_PROFILE_ADV_IS_RUNNING(pProfileAdv) (false)
+#endif
+
+/** @def STAM_REL_PROFILE_ADV_SET_STOPPED
+ * Marks the profile counter as stopped.
+ *
+ * This is for avoiding screwups in twisty code.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ */
+#ifndef VBOX_WITHOUT_RELEASE_STATISTICS
+# define STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { (pProfileAdv)->tsStart = 0; } while (0)
+#else
+# define STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { } while (0)
+#endif
+/** @def STAM_PROFILE_ADV_SET_STOPPED
+ * Marks the profile counter as stopped.
+ *
+ * This is for avoiding screwups in twisty code.
+ *
+ * @param pProfileAdv Pointer to the STAMPROFILEADV structure to operate on.
+ */
+#ifdef VBOX_WITH_STATISTICS
+# define STAM_PROFILE_ADV_SET_STOPPED(pProfileAdv) STAM_REL_PROFILE_ADV_SET_STOPPED(pProfileAdv)
+#else
+# define STAM_PROFILE_ADV_SET_STOPPED(pProfileAdv) do { } while (0)
+#endif
+
+
+/**
+ * Ratio of A to B, uint32_t types.
+ * @remark Use STAM_STATS or STAM_REL_STATS for modifying A & B values.
+ */
+typedef struct STAMRATIOU32
+{
+ /** Sample A. */
+ uint32_t volatile u32A;
+ /** Sample B. */
+ uint32_t volatile u32B;
+} STAMRATIOU32;
+/** Pointer to a uint32_t ratio. */
+typedef STAMRATIOU32 *PSTAMRATIOU32;
+/** Pointer to const a uint32_t ratio. */
+typedef const STAMRATIOU32 *PCSTAMRATIOU32;
+
+
+
+
+/** @defgroup grp_stam_r3 The STAM Host Context Ring 3 API
+ * @ingroup grp_stam
+ * @{
+ */
+
+VMMR3DECL(int) STAMR3InitUVM(PUVM pUVM);
+VMMR3DECL(void) STAMR3TermUVM(PUVM pUVM);
+VMMR3DECL(int) STAMR3RegisterU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
+ const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
+VMMR3DECL(int) STAMR3Register(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility,
+ const char *pszName, STAMUNIT enmUnit, const char *pszDesc);
+
+/** @def STAM_REL_REG
+ * Registers a statistics sample.
+ *
+ * @param pVM VM Handle.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param pszName Sample name. The name is on this form "/<component>/<sample>".
+ * Further nesting is possible.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ */
+#define STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
+ STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_ALWAYS, pszName, enmUnit, pszDesc); \
+ AssertRC(rcStam); })
+/** @def STAM_REG
+ * Registers a statistics sample if statistics are enabled.
+ *
+ * @param pVM VM Handle.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param pszName Sample name. The name is on this form "/<component>/<sample>".
+ * Further nesting is possible.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ */
+#define STAM_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
+ STAM_STATS({STAM_REL_REG(pVM, pvSample, enmType, pszName, enmUnit, pszDesc);})
+
+/** @def STAM_REL_REG_USED
+ * Registers a statistics sample which only shows when used.
+ *
+ * @param pVM VM Handle.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param pszName Sample name. The name is on this form "/<component>/<sample>".
+ * Further nesting is possible.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ */
+#define STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
+ STAM_REL_STATS({ int rcStam = STAMR3Register(pVM, pvSample, enmType, STAMVISIBILITY_USED, pszName, enmUnit, pszDesc); \
+ AssertRC(rcStam);})
+/** @def STAM_REG_USED
+ * Registers a statistics sample which only shows when used, if statistics are enabled.
+ *
+ * @param pVM VM Handle.
+ * @param pvSample Pointer to the sample.
+ * @param enmType Sample type. This indicates what pvSample is pointing at.
+ * @param pszName Sample name. The name is on this form "/<component>/<sample>".
+ * Further nesting is possible.
+ * @param enmUnit Sample unit.
+ * @param pszDesc Sample description.
+ */
+#define STAM_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc) \
+ STAM_STATS({ STAM_REL_REG_USED(pVM, pvSample, enmType, pszName, enmUnit, pszDesc); })
+
+VMMR3DECL(int) STAMR3RegisterFU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ const char *pszDesc, const char *pszName, ...);
+VMMR3DECL(int) STAMR3RegisterF(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ const char *pszDesc, const char *pszName, ...);
+VMMR3DECL(int) STAMR3RegisterVU(PUVM pUVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ const char *pszDesc, const char *pszName, va_list args);
+VMMR3DECL(int) STAMR3RegisterV(PVM pVM, void *pvSample, STAMTYPE enmType, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ const char *pszDesc, const char *pszName, va_list args);
+
+/**
+ * Resets the sample.
+ * @param pVM The VM handle.
+ * @param pvSample The sample registered using STAMR3RegisterCallback.
+ */
+typedef void FNSTAMR3CALLBACKRESET(PVM pVM, void *pvSample);
+/** Pointer to a STAM sample reset callback. */
+typedef FNSTAMR3CALLBACKRESET *PFNSTAMR3CALLBACKRESET;
+
+/**
+ * Prints the sample into the buffer.
+ *
+ * @param pVM The VM handle.
+ * @param pvSample The sample registered using STAMR3RegisterCallback.
+ * @param pszBuf The buffer to print into.
+ * @param cchBuf The size of the buffer.
+ */
+typedef void FNSTAMR3CALLBACKPRINT(PVM pVM, void *pvSample, char *pszBuf, size_t cchBuf);
+/** Pointer to a STAM sample print callback. */
+typedef FNSTAMR3CALLBACKPRINT *PFNSTAMR3CALLBACKPRINT;
+
+VMMR3DECL(int) STAMR3RegisterCallback(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
+ const char *pszDesc, const char *pszName, ...);
+VMMR3DECL(int) STAMR3RegisterCallbackV(PVM pVM, void *pvSample, STAMVISIBILITY enmVisibility, STAMUNIT enmUnit,
+ PFNSTAMR3CALLBACKRESET pfnReset, PFNSTAMR3CALLBACKPRINT pfnPrint,
+ const char *pszDesc, const char *pszName, va_list args);
+VMMR3DECL(int) STAMR3DeregisterU(PUVM pUVM, void *pvSample);
+VMMR3DECL(int) STAMR3Deregister(PVM pVM, void *pvSample);
+
+/** @def STAM_REL_DEREG
+ * Deregisters a statistics sample if statistics are enabled.
+ *
+ * @param pVM VM Handle.
+ * @param pvSample Pointer to the sample.
+ */
+#define STAM_REL_DEREG(pVM, pvSample) \
+ STAM_REL_STATS({ int rcStam = STAMR3Deregister(pVM, pvSample); AssertRC(rcStam); })
+/** @def STAM_DEREG
+ * Deregisters a statistics sample if statistics are enabled.
+ *
+ * @param pVM VM Handle.
+ * @param pvSample Pointer to the sample.
+ */
+#define STAM_DEREG(pVM, pvSample) \
+ STAM_STATS({ STAM_REL_DEREG(pVM, pvSample); })
+
+VMMR3DECL(int) STAMR3ResetU(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3Reset(PVM pVM, const char *pszPat);
+VMMR3DECL(int) STAMR3SnapshotU(PUVM pUVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
+VMMR3DECL(int) STAMR3Snapshot(PVM pVM, const char *pszPat, char **ppszSnapshot, size_t *pcchSnapshot, bool fWithDesc);
+VMMR3DECL(int) STAMR3SnapshotFreeU(PUVM pUVM, char *pszSnapshot);
+VMMR3DECL(int) STAMR3SnapshotFree(PVM pVM, char *pszSnapshot);
+VMMR3DECL(int) STAMR3DumpU(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3Dump(PVM pVM, const char *pszPat);
+VMMR3DECL(int) STAMR3DumpToReleaseLogU(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3DumpToReleaseLog(PVM pVM, const char *pszPat);
+VMMR3DECL(int) STAMR3PrintU(PUVM pUVM, const char *pszPat);
+VMMR3DECL(int) STAMR3Print(PVM pVM, const char *pszPat);
+
+/**
+ * Callback function for STAMR3Enum().
+ *
+ * @returns non-zero to halt the enumeration.
+ *
+ * @param pszName The name of the sample.
+ * @param enmType The type.
+ * @param pvSample Pointer to the data. enmType indicates the format of this data.
+ * @param enmUnit The unit.
+ * @param enmVisibility The visibility.
+ * @param pszDesc The description.
+ * @param pvUser The pvUser argument given to STAMR3Enum().
+ */
+typedef DECLCALLBACK(int) FNSTAMR3ENUM(const char *pszName, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
+ STAMVISIBILITY enmVisiblity, const char *pszDesc, void *pvUser);
+/** Pointer to a FNSTAMR3ENUM(). */
+typedef FNSTAMR3ENUM *PFNSTAMR3ENUM;
+
+VMMR3DECL(int) STAMR3EnumU(PUVM pUVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
+VMMR3DECL(int) STAMR3Enum(PVM pVM, const char *pszPat, PFNSTAMR3ENUM pfnEnum, void *pvUser);
+VMMR3DECL(const char *) STAMR3GetUnit(STAMUNIT enmUnit);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/stam.mac b/include/VBox/vmm/stam.mac
new file mode 100644
index 00000000..5e0fd65b
--- /dev/null
+++ b/include/VBox/vmm/stam.mac
@@ -0,0 +1,382 @@
+;; @file
+; STAM - Statistics Manager.
+;
+
+;
+; Copyright (C) 2006-2010 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; 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 ___VBox_vmm_stam_mac__
+%define ___VBox_vmm_stam_mac__
+
+
+%ifndef VBOX_WITH_STATISTICS
+ %ifdef DEBUG
+ %define VBOX_WITH_STATISTICS
+ %endif
+%endif
+
+
+
+;;
+; Counter sample - STAMTYPE_COUNTER.
+struc STAMCOUNTER
+ .c resd 2
+endstruc
+
+;;
+; Increments a counter sample by one.
+; @param %1 Pointer to the STAMCOUNTER structure to operate on.
+%macro STAM32_COUNTER_INC 1
+%ifdef VBOX_WITH_STATISTICS
+ push ebx
+ mov ebx, %1
+ inc dword [ebx + STAMCOUNTER.c]
+ adc dword [ebx + STAMCOUNTER.c + 1], byte 0
+ pop ebx
+%endif
+%endmacro
+
+%macro STAM64_COUNTER_INC 1
+%ifdef VBOX_WITH_STATISTICS
+ push rbx
+ mov rbx, %1
+ inc qword [rbx + STAMCOUNTER.c]
+ pop rbx
+%endif
+%endmacro
+
+%macro STAM_COUNTER_INC 1
+%ifdef VBOX_WITH_STATISTICS
+ %ifdef RT_ARCH_AMD64
+ STAM64_COUNTER_INC %1
+ %else
+ STAM32_COUNTER_INC %1
+ %endif
+%endif
+%endmacro
+
+
+;;
+; Increments a counter sample by a value.
+;
+; @param %1 Pointer to the STAMCOUNTER structure to operate on.
+; @param %2 The value to add to the counter.
+%macro STAM32_COUNTER_ADD 2
+%ifdef VBOX_WITH_STATISTICS
+ push ebx
+ mov ebx, %1
+ push eax
+ mov eax, %2
+
+ add [ebx + STAMCOUNTER.c], eax
+ adc dword [ebx + STAMCOUNTER.c], byte 0
+
+ pop eax
+ pop ebx
+%endif
+%endmacro
+
+%macro STAM64_COUNTER_ADD 2
+%ifdef VBOX_WITH_STATISTICS
+ push rbx
+ mov rbx, %1
+ push rax
+ mov rax, %2
+
+ add [rbx + STAMCOUNTER.c], rax
+
+ pop rax
+ pop rbx
+%endif
+%endmacro
+
+%macro STAM_COUNTER_ADD 2
+%ifdef VBOX_WITH_STATISTICS
+ %ifdef RT_ARCH_AMD64
+ STAM64_COUNTER_ADD %1, %2
+ %else
+ STAM32_COUNTER_ADD %1, %2
+ %endif
+%endif
+%endmacro
+
+
+;;
+; Profiling sample - STAMTYPE_PROFILE.
+struc STAMPROFILE
+ .cPeriods resd 2
+ .cTicks resd 2
+ .cTicksMax resd 2
+ .cTicksMin resd 2
+endstruc
+
+
+;;
+; Samples the start time of a profiling period.
+;
+; @param %1 Pointer to somewhere one can store a 64-bit timestamp until STAM_PROFILE_STOPP
+%macro STAM32_PROFILE_START 1
+%ifdef VBOX_WITH_STATISTICS
+ push ebx
+ mov ebx, %1
+ push eax
+ push edx
+
+ rdtsc
+ mov [ebx], eax
+ mov [ebx + 4], edx
+
+ pop edx
+ pop eax
+ pop ebx
+%endif
+%endmacro
+
+%macro STAM64_PROFILE_START 1
+%ifdef VBOX_WITH_STATISTICS
+ push rbx
+ mov rbx, %1
+ push rax
+ push rdx
+
+ rdtsc
+ mov [rbx], eax
+ mov [rbx + 4], edx
+
+ pop rdx
+ pop rax
+ pop rbx
+%endif
+%endmacro
+
+%macro STAM_PROFILE_START 1
+%ifdef VBOX_WITH_STATISTICS
+ %ifdef RT_ARCH_AMD64
+ STAM64_PROFILE_START %1
+ %else
+ STAM32_PROFILE_START %1
+ %endif
+%endif
+%endmacro
+
+
+;;
+; Samples the stop time of a profiling period and updates the sample.
+;
+; @param %1 Pointer to the STAMPROFILE structure to operate on.
+; @param %2 Pointer to where the 64-bit timestamp from STAM_PROFILE_START was stored.
+%macro STAM32_PROFILE_STOP 2
+%ifdef VBOX_WITH_STATISTICS
+ push ebx
+ mov ebx, %1
+ push eax
+ push edx
+
+ ; calc cTicks
+ push ecx
+ mov ecx, %2
+ rdtsc
+ sub eax, [ecx]
+ sbb edx, [ecx + 4]
+ pop ecx
+
+ ; update STAMPROFILE.cTicks
+ add [ebx + STAMPROFILE.cTicks], eax
+ adc [ebx + STAMPROFILE.cTicks + 4], edx
+ ; update STAMPROFILE.cPeriods
+ inc dword [ebx + STAMPROFILE.cPeriods]
+ adc dword [ebx + STAMPROFILE.cPeriods + 4], byte 0
+
+ ; update max?
+ cmp edx, [ebx + STAMPROFILE.cTicksMax + 4]
+ jb short %%not_update_max
+ ja short %%update_max
+ cmp eax, [ebx + STAMPROFILE.cTicksMax]
+ jbe short %%not_update_max
+%%update_max:
+ mov [ebx + STAMPROFILE.cTicksMax], eax
+ mov [ebx + STAMPROFILE.cTicksMax + 4], edx
+%%not_update_max:
+
+ ; update min?
+ cmp edx, [ebx + STAMPROFILE.cTicksMin + 4]
+ ja short %%not_update_min
+ jb short %%update_min
+ cmp eax, [ebx + STAMPROFILE.cTicksMin]
+ jae short %%not_update_min
+%%update_min:
+ mov [ebx + STAMPROFILE.cTicksMin], eax
+ mov [ebx + STAMPROFILE.cTicksMin + 4], edx
+%%not_update_min:
+
+ pop edx
+ pop eax
+ pop ebx
+%endif
+%endmacro
+
+%macro STAM64_PROFILE_STOP 2
+%ifdef VBOX_WITH_STATISTICS
+ push rbx
+ mov rbx, %1
+ push rax
+ push rdx
+
+ ; calc cTicks
+ push rcx
+ mov rcx, %2
+ rdtsc
+ sub rax, [ecx]
+ sbb rdx, [ecx + 4]
+ pop rcx
+
+ ; update STAMPROFILE.cTicks
+ shl rdx, 32
+ or rdx, rax
+ add [rbx + STAMPROFILE.cTicks], rdx
+ ; update STAMPROFILE.cPeriods
+ inc qword [rbx + STAMPROFILE.cPeriods]
+
+ ; update max?
+ cmp rdx, [rbx + STAMPROFILE.cTicksMax]
+ jbe short %%not_update_max
+ mov [rbx + STAMPROFILE.cTicksMax], rdx
+%%not_update_max:
+
+ ; update min?
+ cmp rdx, [rbx + STAMPROFILE.cTicksMin]
+ jae short %%not_update_min
+ mov [rbx + STAMPROFILE.cTicksMin], rax
+%%not_update_min:
+
+ pop rdx
+ pop rax
+ pop rbx
+%endif
+%endmacro
+
+%macro STAM_PROFILE_STOP 2
+%ifdef VBOX_WITH_STATISTICS
+ %ifdef RT_ARCH_AMD64
+ STAM64_PROFILE_STOP %1, %2
+ %else
+ STAM32_PROFILE_STOP %1, %2
+ %endif
+%endif
+%endmacro
+
+
+
+struc STAMPROFILEADV
+ .cPeriods resd 2
+ .cTicks resd 2
+ .cTicksMax resd 2
+ .cTicksMin resd 2
+ .tsStart resd 2
+endstruc
+
+
+;;
+; Samples the start time of a profiling period.
+;
+; @param %1 Pointer to the STAMPROFILEADV structure to operate on.
+%macro STAM32_PROFILE_ADV_START 1
+%ifdef VBOX_WITH_STATISTICS
+ push ecx
+ mov ecx, %1
+ lea ecx, [ecx + STAMPROFILEADV.tsStart]
+ STAM32_PROFILE_START ecx
+ pop ecx
+%endif
+%endmacro
+
+%macro STAM64_PROFILE_ADV_START 1
+%ifdef VBOX_WITH_STATISTICS
+ push rcx
+ mov rcx, %1
+ lea rcx, [rcx + STAMPROFILEADV.tsStart]
+ STAM64_PROFILE_START rcx
+ pop rcx
+%endif
+%endmacro
+
+%macro STAM_PROFILE_ADV_START 1
+%ifdef VBOX_WITH_STATISTICS
+ %ifdef RT_ARCH_AMD64
+ STAM64_PROFILE_ADV_START %1
+ %else
+ STAM32_PROFILE_ADV_START %1
+ %endif
+%endif
+%endmacro
+
+
+;;
+; Samples the stop time of a profiling period and updates the sample.
+;
+; @param %1 Pointer to the STAMPROFILEADV structure to operate on.
+
+%macro STAM32_PROFILE_ADV_STOP 1
+%ifdef VBOX_WITH_STATISTICS
+ push ecx
+ mov ecx, %1
+ lea ecx, [ecx + STAMPROFILEADV.tsStart]
+ cmp dword [ecx], byte 0
+ jnz short %%doit
+ cmp dword [ecx + 4], byte 0
+ jz short %%dont
+%%doit:
+ STAM32_PROFILE_STOP %1, ecx
+%%dont:
+ mov dword [ecx], 0
+ mov dword [ecx + 4], 0
+ pop ecx
+%endif
+%endmacro
+
+%macro STAM64_PROFILE_ADV_STOP 1
+%ifdef VBOX_WITH_STATISTICS
+ push rcx
+ mov rcx, %1
+ lea rcx, [rcx + STAMPROFILEADV.tsStart]
+ cmp qword [rcx], byte 0
+ jz short %%dont
+%%doit:
+ STAM64_PROFILE_STOP %1, rcx
+%%dont:
+ mov qword [rcx], 0
+ pop rcx
+%endif
+%endmacro
+
+%macro STAM_PROFILE_ADV_STOP 1
+%ifdef VBOX_WITH_STATISTICS
+ %ifdef RT_ARCH_AMD64
+ STAM64_PROFILE_ADV_STOP %1
+ %else
+ STAM32_PROFILE_ADV_STOP %1
+ %endif
+%endif
+%endmacro
+
+
+
+%endif
diff --git a/include/VBox/vmm/tm.h b/include/VBox/vmm/tm.h
new file mode 100644
index 00000000..be328b1c
--- /dev/null
+++ b/include/VBox/vmm/tm.h
@@ -0,0 +1,281 @@
+/** @file
+ * TM - Time Manager.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_tm_h
+#define ___VBox_vmm_tm_h
+
+#include <VBox/types.h>
+#ifdef IN_RING3
+# include <iprt/time.h>
+#endif
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_tm The Time Manager API
+ * @{
+ */
+
+/** Enable a timer hack which improves the timer response/resolution a bit. */
+#define VBOX_HIGH_RES_TIMERS_HACK
+
+
+/**
+ * Clock type.
+ */
+typedef enum TMCLOCK
+{
+ /** Real host time.
+ * This clock ticks all the time, so use with care. */
+ TMCLOCK_REAL = 0,
+ /** Virtual guest time.
+ * This clock only ticks when the guest is running. It's implemented
+ * as an offset to monotonic real time (GIP). */
+ TMCLOCK_VIRTUAL,
+ /** Virtual guest synchronized timer time.
+ * This is a special clock and timer queue for synchronizing virtual timers
+ * and virtual time sources. This clock is trying to keep up with
+ * TMCLOCK_VIRTUAL, but will wait for timers to be executed. If it lags
+ * too far behind TMCLOCK_VIRTUAL, it will try speed up to close the
+ * distance.
+ * @remarks Do not use this unless you really *must*. */
+ TMCLOCK_VIRTUAL_SYNC,
+ /** Virtual CPU timestamp.
+ * By default this is a function of TMCLOCK_VIRTUAL_SYNC and the virtual
+ * CPU frequency. */
+ TMCLOCK_TSC,
+ /** Number of clocks. */
+ TMCLOCK_MAX
+} TMCLOCK;
+
+
+/** @defgroup grp_tm_timer_flags Timer flags.
+ * @{ */
+/** Use the default critical section for the class of timers. */
+#define TMTIMER_FLAGS_DEFAULT_CRIT_SECT 0
+/** No critical section needed or a custom one is set using
+ * TMR3TimerSetCritSect(). */
+#define TMTIMER_FLAGS_NO_CRIT_SECT RT_BIT_32(0)
+/** @} */
+
+
+VMMDECL(void) TMNotifyStartOfExecution(PVMCPU pVCpu);
+VMMDECL(void) TMNotifyEndOfExecution(PVMCPU pVCpu);
+VMM_INT_DECL(void) TMNotifyStartOfHalt(PVMCPU pVCpu);
+VMM_INT_DECL(void) TMNotifyEndOfHalt(PVMCPU pVCpu);
+#ifdef IN_RING3
+VMMR3DECL(int) TMR3NotifySuspend(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) TMR3NotifyResume(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) TMR3SetWarpDrive(PVM pVM, uint32_t u32Percent);
+#endif
+VMMDECL(uint32_t) TMGetWarpDrive(PVM pVM);
+VMM_INT_DECL(uint32_t) TMCalcHostTimerFrequency(PVM pVM, PVMCPU pVCpu);
+#ifdef IN_RING3
+VMMR3DECL(int) TMR3GetCpuLoadTimes(PVM pVM, VMCPUID idCpu, uint64_t *pcNsTotal, uint64_t *pcNsExecuting,
+ uint64_t *pcNsHalted, uint64_t *pcNsOther);
+#endif
+
+
+/** @name Real Clock Methods
+ * @{
+ */
+VMM_INT_DECL(uint64_t) TMRealGet(PVM pVM);
+VMM_INT_DECL(uint64_t) TMRealGetFreq(PVM pVM);
+/** @} */
+
+
+/** @name Virtual Clock Methods
+ * @{
+ */
+VMM_INT_DECL(uint64_t) TMVirtualGet(PVM pVM);
+VMM_INT_DECL(uint64_t) TMVirtualGetNoCheck(PVM pVM);
+VMM_INT_DECL(uint64_t) TMVirtualSyncGetLag(PVM pVM);
+VMM_INT_DECL(uint32_t) TMVirtualSyncGetCatchUpPct(PVM pVM);
+VMM_INT_DECL(uint64_t) TMVirtualGetFreq(PVM pVM);
+VMM_INT_DECL(uint64_t) TMVirtualSyncGet(PVM pVM);
+VMM_INT_DECL(uint64_t) TMVirtualSyncGetNoCheck(PVM pVM);
+VMM_INT_DECL(uint64_t) TMVirtualSyncGetEx(PVM pVM, bool fCheckTimers);
+VMM_INT_DECL(uint64_t) TMVirtualSyncGetWithDeadlineNoCheck(PVM pVM, uint64_t *pcNsToDeadline);
+VMM_INT_DECL(uint64_t) TMVirtualSyncGetNsToDeadline(PVM pVM);
+VMM_INT_DECL(uint64_t) TMVirtualToNano(PVM pVM, uint64_t u64VirtualTicks);
+VMM_INT_DECL(uint64_t) TMVirtualToMicro(PVM pVM, uint64_t u64VirtualTicks);
+VMM_INT_DECL(uint64_t) TMVirtualToMilli(PVM pVM, uint64_t u64VirtualTicks);
+VMM_INT_DECL(uint64_t) TMVirtualFromNano(PVM pVM, uint64_t u64NanoTS);
+VMM_INT_DECL(uint64_t) TMVirtualFromMicro(PVM pVM, uint64_t u64MicroTS);
+VMM_INT_DECL(uint64_t) TMVirtualFromMilli(PVM pVM, uint64_t u64MilliTS);
+/** @} */
+
+
+/** @name CPU Clock Methods
+ * @{
+ */
+VMMDECL(uint64_t) TMCpuTickGet(PVMCPU pVCpu);
+VMM_INT_DECL(uint64_t) TMCpuTickGetNoCheck(PVMCPU pVCpu);
+VMM_INT_DECL(bool) TMCpuTickCanUseRealTSC(PVMCPU pVCpu, uint64_t *poffRealTSC);
+VMM_INT_DECL(uint64_t) TMCpuTickGetDeadlineAndTscOffset(PVMCPU pVCpu, bool *pfOffsettedTsc, uint64_t *poffRealTSC);
+VMM_INT_DECL(int) TMCpuTickSet(PVM pVM, PVMCPU pVCpu, uint64_t u64Tick);
+VMM_INT_DECL(int) TMCpuTickSetLastSeen(PVMCPU pVCpu, uint64_t u64LastSeenTick);
+VMM_INT_DECL(uint64_t) TMCpuTickGetLastSeen(PVMCPU pVCpu);
+VMMDECL(uint64_t) TMCpuTicksPerSecond(PVM pVM);
+/** @} */
+
+
+/** @name Timer Methods
+ * @{
+ */
+/**
+ * Device timer callback function.
+ *
+ * @param pDevIns Device instance of the device which registered the timer.
+ * @param pTimer The timer handle.
+ * @param pvUser User argument specified upon timer creation.
+ */
+typedef DECLCALLBACK(void) FNTMTIMERDEV(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser);
+/** Pointer to a device timer callback function. */
+typedef FNTMTIMERDEV *PFNTMTIMERDEV;
+
+/**
+ * USB device timer callback function.
+ *
+ * @param pUsbIns The USB device instance the timer is associated
+ * with.
+ * @param pTimer The timer handle.
+ * @param pvUser User argument specified upon timer creation.
+ */
+typedef DECLCALLBACK(void) FNTMTIMERUSB(PPDMUSBINS pUsbIns, PTMTIMER pTimer, void *pvUser);
+/** Pointer to a timer callback for a USB device. */
+typedef FNTMTIMERUSB *PFNTMTIMERUSB;
+
+/**
+ * Driver timer callback function.
+ *
+ * @param pDrvIns Device instance of the device which registered the timer.
+ * @param pTimer The timer handle.
+ * @param pvUser User argument specified upon timer creation.
+ */
+typedef DECLCALLBACK(void) FNTMTIMERDRV(PPDMDRVINS pDrvIns, PTMTIMER pTimer, void *pvUser);
+/** Pointer to a driver timer callback function. */
+typedef FNTMTIMERDRV *PFNTMTIMERDRV;
+
+/**
+ * Service timer callback function.
+ *
+ * @param pSrvIns Service instance of the device which registered the timer.
+ * @param pTimer The timer handle.
+ */
+typedef DECLCALLBACK(void) FNTMTIMERSRV(PPDMSRVINS pSrvIns, PTMTIMER pTimer);
+/** Pointer to a service timer callback function. */
+typedef FNTMTIMERSRV *PFNTMTIMERSRV;
+
+/**
+ * Internal timer callback function.
+ *
+ * @param pVM The VM.
+ * @param pTimer The timer handle.
+ * @param pvUser User argument specified upon timer creation.
+ */
+typedef DECLCALLBACK(void) FNTMTIMERINT(PVM pVM, PTMTIMER pTimer, void *pvUser);
+/** Pointer to internal timer callback function. */
+typedef FNTMTIMERINT *PFNTMTIMERINT;
+
+/**
+ * External timer callback function.
+ *
+ * @param pvUser User argument as specified when the timer was created.
+ */
+typedef DECLCALLBACK(void) FNTMTIMEREXT(void *pvUser);
+/** Pointer to an external timer callback function. */
+typedef FNTMTIMEREXT *PFNTMTIMEREXT;
+
+VMMDECL(PTMTIMERR3) TMTimerR3Ptr(PTMTIMER pTimer);
+VMMDECL(PTMTIMERR0) TMTimerR0Ptr(PTMTIMER pTimer);
+VMMDECL(PTMTIMERRC) TMTimerRCPtr(PTMTIMER pTimer);
+VMMDECL(int) TMTimerLock(PTMTIMER pTimer, int rcBusy);
+VMMDECL(void) TMTimerUnlock(PTMTIMER pTimer);
+VMMDECL(bool) TMTimerIsLockOwner(PTMTIMER pTimer);
+VMMDECL(int) TMTimerSet(PTMTIMER pTimer, uint64_t u64Expire);
+VMMDECL(int) TMTimerSetRelative(PTMTIMER pTimer, uint64_t cTicksToNext, uint64_t *pu64Now);
+VMMDECL(int) TMTimerSetFrequencyHint(PTMTIMER pTimer, uint32_t uHz);
+VMMDECL(uint64_t) TMTimerGet(PTMTIMER pTimer);
+VMMDECL(int) TMTimerStop(PTMTIMER pTimer);
+VMMDECL(bool) TMTimerIsActive(PTMTIMER pTimer);
+
+VMMDECL(int) TMTimerSetMillies(PTMTIMER pTimer, uint32_t cMilliesToNext);
+VMMDECL(int) TMTimerSetMicro(PTMTIMER pTimer, uint64_t cMicrosToNext);
+VMMDECL(int) TMTimerSetNano(PTMTIMER pTimer, uint64_t cNanosToNext);
+VMMDECL(uint64_t) TMTimerGetNano(PTMTIMER pTimer);
+VMMDECL(uint64_t) TMTimerGetMicro(PTMTIMER pTimer);
+VMMDECL(uint64_t) TMTimerGetMilli(PTMTIMER pTimer);
+VMMDECL(uint64_t) TMTimerGetFreq(PTMTIMER pTimer);
+VMMDECL(uint64_t) TMTimerGetExpire(PTMTIMER pTimer);
+VMMDECL(uint64_t) TMTimerToNano(PTMTIMER pTimer, uint64_t cTicks);
+VMMDECL(uint64_t) TMTimerToMicro(PTMTIMER pTimer, uint64_t cTicks);
+VMMDECL(uint64_t) TMTimerToMilli(PTMTIMER pTimer, uint64_t cTicks);
+VMMDECL(uint64_t) TMTimerFromNano(PTMTIMER pTimer, uint64_t cNanoSecs);
+VMMDECL(uint64_t) TMTimerFromMicro(PTMTIMER pTimer, uint64_t cMicroSecs);
+VMMDECL(uint64_t) TMTimerFromMilli(PTMTIMER pTimer, uint64_t cMilliSecs);
+
+VMMDECL(bool) TMTimerPollBool(PVM pVM, PVMCPU pVCpu);
+VMM_INT_DECL(void) TMTimerPollVoid(PVM pVM, PVMCPU pVCpu);
+VMM_INT_DECL(uint64_t) TMTimerPollGIP(PVM pVM, PVMCPU pVCpu, uint64_t *pu64Delta);
+
+/** @} */
+
+
+#ifdef IN_RING3
+/** @defgroup grp_tm_r3 The TM Host Context Ring-3 API
+ * @ingroup grp_tm
+ * @{
+ */
+VMM_INT_DECL(int) TMR3Init(PVM pVM);
+VMM_INT_DECL(int) TMR3InitFinalize(PVM pVM);
+VMM_INT_DECL(void) TMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMM_INT_DECL(int) TMR3Term(PVM pVM);
+VMM_INT_DECL(void) TMR3Reset(PVM pVM);
+VMM_INT_DECL(int) TMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
+VMM_INT_DECL(int) TMR3TimerCreateDevice(PVM pVM, PPDMDEVINS pDevIns, TMCLOCK enmClock, PFNTMTIMERDEV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer);
+VMM_INT_DECL(int) TMR3TimerCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, TMCLOCK enmClock, PFNTMTIMERUSB pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer);
+VMM_INT_DECL(int) TMR3TimerCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, TMCLOCK enmClock, PFNTMTIMERDRV pfnCallback, void *pvUser, uint32_t fFlags, const char *pszDesc, PPTMTIMERR3 ppTimer);
+VMMR3DECL(int) TMR3TimerCreateInternal(PVM pVM, TMCLOCK enmClock, PFNTMTIMERINT pfnCallback, void *pvUser, const char *pszDesc, PPTMTIMERR3 ppTimer);
+VMMR3DECL(PTMTIMERR3) TMR3TimerCreateExternal(PVM pVM, TMCLOCK enmClock, PFNTMTIMEREXT pfnCallback, void *pvUser, const char *pszDesc);
+VMMR3DECL(int) TMR3TimerDestroy(PTMTIMER pTimer);
+VMM_INT_DECL(int) TMR3TimerDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
+VMM_INT_DECL(int) TMR3TimerDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
+VMM_INT_DECL(int) TMR3TimerDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
+VMMR3DECL(int) TMR3TimerSave(PTMTIMERR3 pTimer, PSSMHANDLE pSSM);
+VMMR3DECL(int) TMR3TimerLoad(PTMTIMERR3 pTimer, PSSMHANDLE pSSM);
+VMMR3DECL(int) TMR3TimerSetCritSect(PTMTIMERR3 pTimer, PPDMCRITSECT pCritSect);
+VMMR3DECL(void) TMR3TimerQueuesDo(PVM pVM);
+VMMR3_INT_DECL(void) TMR3VirtualSyncFF(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(PRTTIMESPEC) TMR3UtcNow(PVM pVM, PRTTIMESPEC pTime);
+/** @} */
+#endif /* IN_RING3 */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/VBox/vmm/trpm.h b/include/VBox/vmm/trpm.h
new file mode 100644
index 00000000..0cdfc153
--- /dev/null
+++ b/include/VBox/vmm/trpm.h
@@ -0,0 +1,150 @@
+/** @file
+ * TRPM - The Trap Monitor.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_trpm_h
+#define ___VBox_vmm_trpm_h
+
+#include <VBox/types.h>
+#include <iprt/x86.h>
+
+
+RT_C_DECLS_BEGIN
+/** @defgroup grp_trpm The Trap Monitor API
+ * @{
+ */
+
+/**
+ * Trap: error code present or not
+ */
+typedef enum
+{
+ TRPM_TRAP_HAS_ERRORCODE = 0,
+ TRPM_TRAP_NO_ERRORCODE,
+ /** The usual 32-bit paranoia. */
+ TRPM_TRAP_32BIT_HACK = 0x7fffffff
+} TRPMERRORCODE;
+
+/**
+ * TRPM event type
+ */
+/** Note: must match trpm.mac! */
+typedef enum
+{
+ TRPM_TRAP = 0,
+ TRPM_HARDWARE_INT = 1,
+ TRPM_SOFTWARE_INT = 2,
+ /** The usual 32-bit paranoia. */
+ TRPM_32BIT_HACK = 0x7fffffff
+} TRPMEVENT;
+/** Pointer to a TRPM event type. */
+typedef TRPMEVENT *PTRPMEVENT;
+/** Pointer to a const TRPM event type. */
+typedef TRPMEVENT const *PCTRPMEVENT;
+
+/**
+ * Invalid trap handler for trampoline calls
+ */
+#define TRPM_INVALID_HANDLER 0
+
+VMMDECL(int) TRPMQueryTrap(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType);
+VMMDECL(uint8_t) TRPMGetTrapNo(PVMCPU pVCpu);
+VMMDECL(RTGCUINT) TRPMGetErrorCode(PVMCPU pVCpu);
+VMMDECL(RTGCUINTPTR) TRPMGetFaultAddress(PVMCPU pVCpu);
+VMMDECL(int) TRPMResetTrap(PVMCPU pVCpu);
+VMMDECL(int) TRPMAssertTrap(PVMCPU pVCpu, uint8_t u8TrapNo, TRPMEVENT enmType);
+VMMDECL(void) TRPMSetErrorCode(PVMCPU pVCpu, RTGCUINT uErrorCode);
+VMMDECL(void) TRPMSetFaultAddress(PVMCPU pVCpu, RTGCUINTPTR uCR2);
+VMMDECL(bool) TRPMIsSoftwareInterrupt(PVMCPU pVCpu);
+VMMDECL(bool) TRPMHasTrap(PVMCPU pVCpu);
+VMMDECL(int) TRPMQueryTrapAll(PVMCPU pVCpu, uint8_t *pu8TrapNo, PTRPMEVENT pEnmType, PRTGCUINT puErrorCode, PRTGCUINTPTR puCR2);
+VMMDECL(void) TRPMSaveTrap(PVMCPU pVCpu);
+VMMDECL(void) TRPMRestoreTrap(PVMCPU pVCpu);
+VMMDECL(int) TRPMForwardTrap(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t cbInstr, TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap);
+VMMDECL(int) TRPMRaiseXcpt(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt);
+VMMDECL(int) TRPMRaiseXcptErr(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt, uint32_t uErr);
+VMMDECL(int) TRPMRaiseXcptErrCR2(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, X86XCPT enmXcpt, uint32_t uErr, RTGCUINTPTR uCR2);
+
+
+#ifdef IN_RING3
+/** @defgroup grp_trpm_r3 TRPM Host Context Ring 3 API
+ * @ingroup grp_trpm
+ * @{
+ */
+VMMR3DECL(int) TRPMR3Init(PVM pVM);
+VMMR3DECL(void) TRPMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3DECL(void) TRPMR3ResetCpu(PVMCPU pVCpu);
+VMMR3DECL(void) TRPMR3Reset(PVM pVM);
+VMMR3_INT_DECL(int) TRPMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
+VMMR3DECL(int) TRPMR3Term(PVM pVM);
+VMMR3DECL(int) TRPMR3EnableGuestTrapHandler(PVM pVM, unsigned iTrap);
+VMMR3DECL(int) TRPMR3SetGuestTrapHandler(PVM pVM, unsigned iTrap, RTRCPTR pHandler);
+VMMR3DECL(RTRCPTR) TRPMR3GetGuestTrapHandler(PVM pVM, unsigned iTrap);
+VMMR3DECL(void) TRPMR3DisableMonitoring(PVM pVM);
+VMMR3DECL(int) TRPMR3SyncIDT(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(bool) TRPMR3IsGateHandler(PVM pVM, RTRCPTR GCPtr);
+VMMR3DECL(uint32_t) TRPMR3QueryGateByHandler(PVM pVM, RTRCPTR GCPtr);
+VMMR3DECL(int) TRPMR3InjectEvent(PVM pVM, PVMCPU pVCpu, TRPMEVENT enmEvent);
+/** @} */
+#endif
+
+
+#ifdef IN_RC
+/** @defgroup grp_trpm_gc The TRPM Guest Context API
+ * @ingroup grp_trpm
+ * @{
+ */
+
+/**
+ * Guest Context temporary trap handler
+ *
+ * @returns VBox status code (appropriate for GC return).
+ * In this context VINF_SUCCESS means to restart the instruction.
+ * @param pVM VM handle.
+ * @param pRegFrame Trap register frame.
+ */
+typedef DECLCALLBACK(int) FNTRPMGCTRAPHANDLER(PVM pVM, PCPUMCTXCORE pRegFrame);
+/** Pointer to a TRPMGCTRAPHANDLER() function. */
+typedef FNTRPMGCTRAPHANDLER *PFNTRPMGCTRAPHANDLER;
+
+VMMRCDECL(int) TRPMGCSetTempHandler(PVM pVM, unsigned iTrap, PFNTRPMGCTRAPHANDLER pfnHandler);
+VMMRCDECL(void) TRPMGCHyperReturnToHost(PVM pVM, int rc);
+/** @} */
+#endif
+
+
+#ifdef IN_RING0
+/** @defgroup grp_trpm_r0 TRPM Host Context Ring 0 API
+ * @ingroup grp_trpm
+ * @{
+ */
+VMMR0DECL(void) TRPMR0DispatchHostInterrupt(PVM pVM);
+VMMR0DECL(void) TRPMR0SetupInterruptDispatcherFrame(PVM pVM, void *pvRet);
+/** @} */
+#endif
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vmm/trpm.mac b/include/VBox/vmm/trpm.mac
new file mode 100644
index 00000000..534039e2
--- /dev/null
+++ b/include/VBox/vmm/trpm.mac
@@ -0,0 +1,47 @@
+;; @file
+; TRPM - The Trap Monitor.
+;
+
+;
+; Copyright (C) 2006-2010 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; 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 ___VBox_vmm_trpm_mac__
+%define ___VBox_vmm_trpm_mac__
+
+
+;/**
+; * TRPM event type
+; */
+;/** Note: must match trpm.mac! */
+;typedef enum
+;{
+; TRPM_TRAP = 0,
+; TRPM_HARDWARE_INT = 1,
+; TRPM_SOFTWARE_INT = 2,
+; /** The usual 32-bit paranoia. */
+; TRPM_32BIT_HACK = 0x7fffffff
+;} TRPMEVENT;
+
+%define TRPM_TRAP 0
+%define TRPM_HARDWARE_INT 1
+%define TRPM_SOFTWARE_INT 2
+%endif
+
diff --git a/include/VBox/vmm/uvm.h b/include/VBox/vmm/uvm.h
new file mode 100644
index 00000000..10b8e49b
--- /dev/null
+++ b/include/VBox/vmm/uvm.h
@@ -0,0 +1,152 @@
+/** @file
+ * GVM - The Global VM Data.
+ */
+
+/*
+ * Copyright (C) 2007-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_uvm_h
+#define ___VBox_vmm_uvm_h
+
+#include <VBox/types.h>
+#include <iprt/assert.h>
+
+
+/**
+ * Per virtual CPU ring-3 (user mode) data.
+ */
+typedef struct UVMCPU
+{
+ /** Pointer to the UVM structure. */
+ PUVM pUVM;
+ /** Pointer to the VM structure. */
+ PVM pVM;
+ /** Pointer to the VMCPU structure. */
+ PVMCPU pVCpu;
+ /** The virtual CPU ID. */
+ RTCPUID idCpu;
+ /** Alignment padding. */
+ uint8_t abAlignment0[HC_ARCH_BITS == 32 ? 16 : 4];
+
+ /** The VM internal data. */
+ union
+ {
+#ifdef ___VMInternal_h
+ struct VMINTUSERPERVMCPU s;
+#endif
+ uint8_t padding[512];
+ } vm;
+} UVMCPU;
+AssertCompileMemberAlignment(UVMCPU, vm, 32);
+
+
+/**
+ * The ring-3 (user mode) VM structure.
+ *
+ * This structure is similar to VM and GVM except that it resides in swappable
+ * user memory. The main purpose is to assist bootstrapping, where it allows us
+ * to start EMT much earlier and gives PDMLdr somewhere to put it's VMMR0 data.
+ * It is also a nice place to put big things that are user mode only.
+ */
+typedef struct UVM
+{
+ /** Magic / eye-catcher (UVM_MAGIC). */
+ uint32_t u32Magic;
+ /** The number of virtual CPUs. */
+ uint32_t cCpus;
+ /** The ring-3 mapping of the shared VM structure. */
+ PVM pVM;
+ /** Pointer to the next VM.
+ * We keep a per process list of VM for the event that a process could
+ * contain more than one VM.
+ * @todo move this into vm.s!
+ */
+ struct UVM *pNext;
+
+ /** Pointer to the optional method table provided by the VMM user. */
+ PCVMM2USERMETHODS pVmm2UserMethods;
+
+#if HC_ARCH_BITS == 32
+ /** Align the next member on a 32 byte boundary. */
+ uint8_t abAlignment0[HC_ARCH_BITS == 32 ? 12 : 0];
+#endif
+
+ /** The VM internal data. */
+ union
+ {
+#ifdef ___VMInternal_h
+ struct VMINTUSERPERVM s;
+#endif
+ uint8_t padding[512];
+ } vm;
+
+ /** The MM data. */
+ union
+ {
+#ifdef ___MMInternal_h
+ struct MMUSERPERVM s;
+#endif
+ uint8_t padding[32];
+ } mm;
+
+ /** The PDM data. */
+ union
+ {
+#ifdef ___PDMInternal_h
+ struct PDMUSERPERVM s;
+#endif
+ uint8_t padding[128];
+ } pdm;
+
+ /** The STAM data. */
+ union
+ {
+#ifdef ___STAMInternal_h
+ struct STAMUSERPERVM s;
+#endif
+ uint8_t padding[6624];
+ } stam;
+
+ /** Per virtual CPU data. */
+ UVMCPU aCpus[1];
+} UVM;
+AssertCompileMemberAlignment(UVM, vm, 32);
+AssertCompileMemberAlignment(UVM, mm, 32);
+AssertCompileMemberAlignment(UVM, pdm, 32);
+AssertCompileMemberAlignment(UVM, stam, 32);
+AssertCompileMemberAlignment(UVM, aCpus, 32);
+
+/** The UVM::u32Magic value (Brad Mehldau). */
+#define UVM_MAGIC 0x19700823
+
+/** @def UVM_ASSERT_VALID_EXT_RETURN
+ * Asserts a user mode VM handle is valid for external access.
+ */
+#define UVM_ASSERT_VALID_EXT_RETURN(a_pUVM, a_rc) \
+ AssertMsgReturn( RT_VALID_ALIGNED_PTR(a_pUVM, PAGE_SIZE) \
+ && (a_pUVM)->u32Magic == UVM_MAGIC, \
+ ("a_pUVM=%p u32Magic=%#x\n", (a_pUVM), \
+ RT_VALID_ALIGNED_PTR(a_pUVM, PAGE_SIZE) ? (a_pUVM)->u32Magic : 0), \
+ (a_rc))
+
+#endif
+
diff --git a/include/VBox/vmm/vm.h b/include/VBox/vmm/vm.h
new file mode 100644
index 00000000..ef713127
--- /dev/null
+++ b/include/VBox/vmm/vm.h
@@ -0,0 +1,1106 @@
+/** @file
+ * VM - The Virtual Machine, data.
+ */
+
+/*
+ * Copyright (C) 2006-2012 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_vm_h
+#define ___VBox_vmm_vm_h
+
+#ifndef VBOX_FOR_DTRACE_LIB
+# include <VBox/types.h>
+# include <VBox/vmm/cpum.h>
+# include <VBox/vmm/stam.h>
+# include <VBox/vmm/vmapi.h>
+# include <VBox/vmm/vmm.h>
+# include <VBox/sup.h>
+#else
+# pragma D depends_on library vbox-types.d
+# pragma D depends_on library CPUMInternal.d
+# define ___CPUMInternal_h
+#endif
+
+
+
+/** @defgroup grp_vm The Virtual Machine
+ * @{
+ */
+
+/**
+ * The state of a Virtual CPU.
+ *
+ * The basic state indicated here is whether the CPU has been started or not. In
+ * addition, there are sub-states when started for assisting scheduling (GVMM
+ * mostly).
+ *
+ * The transition out of the STOPPED state is done by a vmR3PowerOn.
+ * The transition back to the STOPPED state is done by vmR3PowerOff.
+ *
+ * (Alternatively we could let vmR3PowerOn start CPU 0 only and let the SPIP
+ * handling switch on the other CPUs. Then vmR3Reset would stop all but CPU 0.)
+ */
+typedef enum VMCPUSTATE
+{
+ /** The customary invalid zero. */
+ VMCPUSTATE_INVALID = 0,
+
+ /** Virtual CPU has not yet been started. */
+ VMCPUSTATE_STOPPED,
+
+ /** CPU started. */
+ VMCPUSTATE_STARTED,
+ /** Executing guest code and can be poked. */
+ VMCPUSTATE_STARTED_EXEC,
+ /** Executing guest code in the recompiler. */
+ VMCPUSTATE_STARTED_EXEC_REM,
+ /** Halted. */
+ VMCPUSTATE_STARTED_HALTED,
+
+ /** The end of valid virtual CPU states. */
+ VMCPUSTATE_END,
+
+ /** Ensure 32-bit type. */
+ VMCPUSTATE_32BIT_HACK = 0x7fffffff
+} VMCPUSTATE;
+
+
+/**
+ * Per virtual CPU data.
+ */
+typedef struct VMCPU
+{
+ /** Per CPU forced action.
+ * See the VMCPU_FF_* \#defines. Updated atomically. */
+ uint32_t volatile fLocalForcedActions; /* 0 */
+ /** The CPU state. */
+ VMCPUSTATE volatile enmState; /* 4 */
+
+ /** Pointer to the ring-3 UVMCPU structure. */
+ PUVMCPU pUVCpu; /* 8 */
+ /** Ring-3 Host Context VM Pointer. */
+ PVMR3 pVMR3; /* 16 / 12 */
+ /** Ring-0 Host Context VM Pointer. */
+ PVMR0 pVMR0; /* 24 / 16 */
+ /** Raw-mode Context VM Pointer. */
+ PVMRC pVMRC; /* 32 / 20 */
+ /** The CPU ID.
+ * This is the index into the VM::aCpu array. */
+ VMCPUID idCpu; /* 36 / 24 */
+ /** The native thread handle. */
+ RTNATIVETHREAD hNativeThread; /* 40 / 28 */
+ /** The native R0 thread handle. (different from the R3 handle!) */
+ RTNATIVETHREAD hNativeThreadR0; /* 48 / 32 */
+ /** Which host CPU ID is this EMT running on.
+ * Only valid when in RC or HWACCMR0 with scheduling disabled. */
+ RTCPUID volatile idHostCpu; /* 56 / 36 */
+
+ /** Trace groups enable flags. */
+ uint32_t fTraceGroups; /* 60 / 40 */
+ /** Align the structures below bit on a 64-byte boundary and make sure it starts
+ * at the same offset in both 64-bit and 32-bit builds.
+ *
+ * @remarks The alignments of the members that are larger than 48 bytes should be
+ * 64-byte for cache line reasons. structs containing small amounts of
+ * data could be lumped together at the end with a < 64 byte padding
+ * following it (to grow into and align the struct size).
+ * */
+ uint8_t abAlignment1[HC_ARCH_BITS == 64 ? 60 : 16+64];
+ /** State data for use by ad hoc profiling. */
+ uint32_t uAdHoc;
+ /** Profiling samples for use by ad hoc profiling. */
+ STAMPROFILEADV aStatAdHoc[8]; /* size: 40*8 = 320 */
+
+ /** CPUM part. */
+ union
+ {
+#ifdef ___CPUMInternal_h
+ struct CPUMCPU s;
+#endif
+ uint8_t padding[3584]; /* multiple of 64 */
+ } cpum;
+
+ /** HWACCM part. */
+ union
+ {
+#ifdef ___HWACCMInternal_h
+ struct HWACCMCPU s;
+#endif
+ uint8_t padding[5376]; /* multiple of 64 */
+ } hwaccm;
+
+ /** EM part. */
+ union
+ {
+#ifdef ___EMInternal_h
+ struct EMCPU s;
+#endif
+ uint8_t padding[1472]; /* multiple of 64 */
+ } em;
+
+ /** IEM part. */
+ union
+ {
+#ifdef ___IEMInternal_h
+ struct IEMCPU s;
+#endif
+ uint8_t padding[3072]; /* multiple of 64 */
+ } iem;
+
+ /** TRPM part. */
+ union
+ {
+#ifdef ___TRPMInternal_h
+ struct TRPMCPU s;
+#endif
+ uint8_t padding[128]; /* multiple of 64 */
+ } trpm;
+
+ /** TM part. */
+ union
+ {
+#ifdef ___TMInternal_h
+ struct TMCPU s;
+#endif
+ uint8_t padding[384]; /* multiple of 64 */
+ } tm;
+
+ /** VMM part. */
+ union
+ {
+#ifdef ___VMMInternal_h
+ struct VMMCPU s;
+#endif
+ uint8_t padding[640]; /* multiple of 64 */
+ } vmm;
+
+ /** PDM part. */
+ union
+ {
+#ifdef ___PDMInternal_h
+ struct PDMCPU s;
+#endif
+ uint8_t padding[128]; /* multiple of 64 */
+ } pdm;
+
+ /** IOM part. */
+ union
+ {
+#ifdef ___IOMInternal_h
+ struct IOMCPU s;
+#endif
+ uint8_t padding[512]; /* multiple of 64 */
+ } iom;
+
+ /** DBGF part.
+ * @todo Combine this with other tiny structures. */
+ union
+ {
+#ifdef ___DBGFInternal_h
+ struct DBGFCPU s;
+#endif
+ uint8_t padding[64]; /* multiple of 64 */
+ } dbgf;
+
+ /** Align the following members on page boundary. */
+ uint8_t abAlignment2[1024 - 320 - 128];
+
+ /** PGM part. */
+ union
+ {
+#ifdef ___PGMInternal_h
+ struct PGMCPU s;
+#endif
+ uint8_t padding[4096]; /* multiple of 4096 */
+ } pgm;
+
+} VMCPU;
+
+
+#ifndef VBOX_FOR_DTRACE_LIB
+
+/** @name Operations on VMCPU::enmState
+ * @{ */
+/** Gets the VMCPU state. */
+#define VMCPU_GET_STATE(pVCpu) ( (pVCpu)->enmState )
+/** Sets the VMCPU state. */
+#define VMCPU_SET_STATE(pVCpu, enmNewState) \
+ ASMAtomicWriteU32((uint32_t volatile *)&(pVCpu)->enmState, (enmNewState))
+/** Cmpares and sets the VMCPU state. */
+#define VMCPU_CMPXCHG_STATE(pVCpu, enmNewState, enmOldState) \
+ ASMAtomicCmpXchgU32((uint32_t volatile *)&(pVCpu)->enmState, (enmNewState), (enmOldState))
+/** Checks the VMCPU state. */
+#ifdef VBOX_STRICT
+# define VMCPU_ASSERT_STATE(pVCpu, enmExpectedState) \
+ do { \
+ VMCPUSTATE enmState = VMCPU_GET_STATE(pVCpu); \
+ AssertMsg(enmState == (enmExpectedState), \
+ ("enmState=%d enmExpectedState=%d idCpu=%u\n", \
+ enmState, enmExpectedState, (pVCpu)->idCpu)); \
+ } while (0)
+#else
+# define VMCPU_ASSERT_STATE(pVCpu, enmExpectedState) do { } while (0)
+#endif
+/** Tests if the state means that the CPU is started. */
+#define VMCPUSTATE_IS_STARTED(enmState) ( (enmState) > VMCPUSTATE_STOPPED )
+/** Tests if the state means that the CPU is stopped. */
+#define VMCPUSTATE_IS_STOPPED(enmState) ( (enmState) == VMCPUSTATE_STOPPED )
+/** @} */
+
+
+/** The name of the Guest Context VMM Core module. */
+#define VMMGC_MAIN_MODULE_NAME "VMMGC.gc"
+/** The name of the Ring 0 Context VMM Core module. */
+#define VMMR0_MAIN_MODULE_NAME "VMMR0.r0"
+
+/** VM Forced Action Flags.
+ *
+ * Use the VM_FF_SET() and VM_FF_CLEAR() macros to change the force
+ * action mask of a VM.
+ *
+ * @{
+ */
+/** The virtual sync clock has been stopped, go to TM until it has been
+ * restarted... */
+#define VM_FF_TM_VIRTUAL_SYNC RT_BIT_32(2)
+/** PDM Queues are pending. */
+#define VM_FF_PDM_QUEUES RT_BIT_32(VM_FF_PDM_QUEUES_BIT)
+/** The bit number for VM_FF_PDM_QUEUES. */
+#define VM_FF_PDM_QUEUES_BIT 3
+/** PDM DMA transfers are pending. */
+#define VM_FF_PDM_DMA RT_BIT_32(VM_FF_PDM_DMA_BIT)
+/** The bit number for VM_FF_PDM_DMA. */
+#define VM_FF_PDM_DMA_BIT 4
+/** This action forces the VM to call DBGF so DBGF can service debugger
+ * requests in the emulation thread.
+ * This action flag stays asserted till DBGF clears it.*/
+#define VM_FF_DBGF RT_BIT_32(VM_FF_DBGF_BIT)
+/** The bit number for VM_FF_DBGF. */
+#define VM_FF_DBGF_BIT 8
+/** This action forces the VM to service pending requests from other
+ * thread or requests which must be executed in another context. */
+#define VM_FF_REQUEST RT_BIT_32(9)
+/** Check for VM state changes and take appropriate action. */
+#define VM_FF_CHECK_VM_STATE RT_BIT_32(VM_FF_CHECK_VM_STATE_BIT)
+/** The bit number for VM_FF_CHECK_VM_STATE. */
+#define VM_FF_CHECK_VM_STATE_BIT 10
+/** Reset the VM. (postponed) */
+#define VM_FF_RESET RT_BIT_32(VM_FF_RESET_BIT)
+/** The bit number for VM_FF_RESET. */
+#define VM_FF_RESET_BIT 11
+/** EMT rendezvous in VMM. */
+#define VM_FF_EMT_RENDEZVOUS RT_BIT_32(VM_FF_EMT_RENDEZVOUS_BIT)
+/** The bit number for VM_FF_EMT_RENDEZVOUS. */
+#define VM_FF_EMT_RENDEZVOUS_BIT 12
+
+/** PGM needs to allocate handy pages. */
+#define VM_FF_PGM_NEED_HANDY_PAGES RT_BIT_32(18)
+/** PGM is out of memory.
+ * Abandon all loops and code paths which can be resumed and get up to the EM
+ * loops. */
+#define VM_FF_PGM_NO_MEMORY RT_BIT_32(19)
+ /** PGM is about to perform a lightweight pool flush
+ * Guest SMP: all EMT threads should return to ring 3
+ */
+#define VM_FF_PGM_POOL_FLUSH_PENDING RT_BIT_32(20)
+/** REM needs to be informed about handler changes. */
+#define VM_FF_REM_HANDLER_NOTIFY RT_BIT_32(VM_FF_REM_HANDLER_NOTIFY_BIT)
+/** The bit number for VM_FF_REM_HANDLER_NOTIFY. */
+#define VM_FF_REM_HANDLER_NOTIFY_BIT 29
+/** Suspend the VM - debug only. */
+#define VM_FF_DEBUG_SUSPEND RT_BIT_32(31)
+
+
+/** This action forces the VM to check any pending interrups on the APIC. */
+#define VMCPU_FF_INTERRUPT_APIC RT_BIT_32(0)
+/** This action forces the VM to check any pending interrups on the PIC. */
+#define VMCPU_FF_INTERRUPT_PIC RT_BIT_32(1)
+/** This action forces the VM to schedule and run pending timer (TM).
+ * @remarks Don't move - PATM compatibility. */
+#define VMCPU_FF_TIMER RT_BIT_32(2)
+/** This action forces the VM to check any pending NMIs. */
+#define VMCPU_FF_INTERRUPT_NMI_BIT 3
+#define VMCPU_FF_INTERRUPT_NMI RT_BIT_32(VMCPU_FF_INTERRUPT_NMI_BIT)
+/** This action forces the VM to check any pending SMIs. */
+#define VMCPU_FF_INTERRUPT_SMI_BIT 4
+#define VMCPU_FF_INTERRUPT_SMI RT_BIT_32(VMCPU_FF_INTERRUPT_SMI_BIT)
+/** PDM critical section unlocking is pending, process promptly upon return to R3. */
+#define VMCPU_FF_PDM_CRITSECT RT_BIT_32(5)
+/** This action forces the VM to service pending requests from other
+ * thread or requests which must be executed in another context. */
+#define VMCPU_FF_REQUEST RT_BIT_32(9)
+/** This action forces the VM to resync the page tables before going
+ * back to execute guest code. (GLOBAL FLUSH) */
+#define VMCPU_FF_PGM_SYNC_CR3 RT_BIT_32(16)
+/** Same as VM_FF_PGM_SYNC_CR3 except that global pages can be skipped.
+ * (NON-GLOBAL FLUSH) */
+#define VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL RT_BIT_32(17)
+/** Check for pending TLB shootdown actions.
+ * Consumer: HWACCM
+ * @todo rename to VMCPU_FF_HWACCM_TLB_SHOOTDOWN */
+#define VMCPU_FF_TLB_SHOOTDOWN RT_BIT_32(18)
+/** Check for pending TLB flush action.
+ * Consumer: HWACCM
+ * @todo rename to VMCPU_FF_HWACCM_TLB_FLUSH */
+#define VMCPU_FF_TLB_FLUSH RT_BIT_32(VMCPU_FF_TLB_FLUSH_BIT)
+/** The bit number for VMCPU_FF_TLB_FLUSH. */
+#define VMCPU_FF_TLB_FLUSH_BIT 19
+/** Check the interrupt and trap gates */
+#define VMCPU_FF_TRPM_SYNC_IDT RT_BIT_32(20)
+/** Check Guest's TSS ring 0 stack */
+#define VMCPU_FF_SELM_SYNC_TSS RT_BIT_32(21)
+/** Check Guest's GDT table */
+#define VMCPU_FF_SELM_SYNC_GDT RT_BIT_32(22)
+/** Check Guest's LDT table */
+#define VMCPU_FF_SELM_SYNC_LDT RT_BIT_32(23)
+/** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */
+#define VMCPU_FF_INHIBIT_INTERRUPTS RT_BIT_32(24)
+/** CSAM needs to scan the page that's being executed */
+#define VMCPU_FF_CSAM_SCAN_PAGE RT_BIT_32(26)
+/** CSAM needs to do some homework. */
+#define VMCPU_FF_CSAM_PENDING_ACTION RT_BIT_32(27)
+/** Force return to Ring-3. */
+#define VMCPU_FF_TO_R3 RT_BIT_32(28)
+
+/** Externally VM forced actions. Used to quit the idle/wait loop. */
+#define VM_FF_EXTERNAL_SUSPENDED_MASK (VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_REQUEST | VM_FF_EMT_RENDEZVOUS)
+/** Externally VMCPU forced actions. Used to quit the idle/wait loop. */
+#define VMCPU_FF_EXTERNAL_SUSPENDED_MASK (VMCPU_FF_REQUEST)
+
+/** Externally forced VM actions. Used to quit the idle/wait loop. */
+#define VM_FF_EXTERNAL_HALTED_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_REQUEST \
+ | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_EMT_RENDEZVOUS)
+/** Externally forced VMCPU actions. Used to quit the idle/wait loop. */
+#define VMCPU_FF_EXTERNAL_HALTED_MASK (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_REQUEST | VMCPU_FF_TIMER)
+
+/** High priority VM pre-execution actions. */
+#define VM_FF_HIGH_PRIORITY_PRE_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_TM_VIRTUAL_SYNC \
+ | VM_FF_DEBUG_SUSPEND | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS)
+/** High priority VMCPU pre-execution actions. */
+#define VMCPU_FF_HIGH_PRIORITY_PRE_MASK ( VMCPU_FF_TIMER | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC | VMCPU_FF_PGM_SYNC_CR3 \
+ | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \
+ | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS)
+
+/** High priority VM pre raw-mode execution mask. */
+#define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY)
+/** High priority VMCPU pre raw-mode execution mask. */
+#define VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK ( VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT \
+ | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT | VMCPU_FF_INHIBIT_INTERRUPTS)
+
+/** High priority post-execution actions. */
+#define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PGM_NO_MEMORY)
+/** High priority post-execution actions. */
+#define VMCPU_FF_HIGH_PRIORITY_POST_MASK (VMCPU_FF_PDM_CRITSECT|VMCPU_FF_CSAM_PENDING_ACTION)
+
+/** Normal priority VM post-execution actions. */
+#define VM_FF_NORMAL_PRIORITY_POST_MASK ( VM_FF_CHECK_VM_STATE | VM_FF_DBGF | VM_FF_RESET \
+ | VM_FF_PGM_NO_MEMORY | VM_FF_EMT_RENDEZVOUS)
+/** Normal priority VMCPU post-execution actions. */
+#define VMCPU_FF_NORMAL_PRIORITY_POST_MASK (VMCPU_FF_CSAM_SCAN_PAGE)
+
+/** Normal priority VM actions. */
+#define VM_FF_NORMAL_PRIORITY_MASK (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY | VM_FF_EMT_RENDEZVOUS)
+/** Normal priority VMCPU actions. */
+#define VMCPU_FF_NORMAL_PRIORITY_MASK (VMCPU_FF_REQUEST)
+
+/** Flags to clear before resuming guest execution. */
+#define VMCPU_FF_RESUME_GUEST_MASK (VMCPU_FF_TO_R3)
+
+/** VM Flags that cause the HWACCM loops to go back to ring-3. */
+#define VM_FF_HWACCM_TO_R3_MASK (VM_FF_TM_VIRTUAL_SYNC | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY | VM_FF_PDM_QUEUES | VM_FF_EMT_RENDEZVOUS)
+/** VMCPU Flags that cause the HWACCM loops to go back to ring-3. */
+#define VMCPU_FF_HWACCM_TO_R3_MASK (VMCPU_FF_TO_R3 | VMCPU_FF_TIMER | VMCPU_FF_PDM_CRITSECT)
+
+/** All the forced VM flags. */
+#define VM_FF_ALL_MASK (~0U)
+/** All the forced VMCPU flags. */
+#define VMCPU_FF_ALL_MASK (~0U)
+
+/** All the forced VM flags except those related to raw-mode and hardware
+ * assisted execution. */
+#define VM_FF_ALL_REM_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK) | VM_FF_PGM_NO_MEMORY)
+/** All the forced VMCPU flags except those related to raw-mode and hardware
+ * assisted execution. */
+#define VMCPU_FF_ALL_REM_MASK (~(VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK | VMCPU_FF_CSAM_PENDING_ACTION | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_TLB_FLUSH | VMCPU_FF_TLB_SHOOTDOWN))
+
+/** @} */
+
+/** @def VM_FF_SET
+ * Sets a force action flag.
+ *
+ * @param pVM VM Handle.
+ * @param fFlag The flag to set.
+ */
+#if 1
+# define VM_FF_SET(pVM, fFlag) ASMAtomicOrU32(&(pVM)->fGlobalForcedActions, (fFlag))
+#else
+# define VM_FF_SET(pVM, fFlag) \
+ do { ASMAtomicOrU32(&(pVM)->fGlobalForcedActions, (fFlag)); \
+ RTLogPrintf("VM_FF_SET : %08x %s - %s(%d) %s\n", (pVM)->fGlobalForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
+ } while (0)
+#endif
+
+/** @def VMCPU_FF_SET
+ * Sets a force action flag for the given VCPU.
+ *
+ * @param pVCpu VMCPU Handle.
+ * @param fFlag The flag to set.
+ */
+#define VMCPU_FF_SET(pVCpu, fFlag) ASMAtomicOrU32(&(pVCpu)->fLocalForcedActions, (fFlag))
+
+/** @def VM_FF_CLEAR
+ * Clears a force action flag.
+ *
+ * @param pVM VM Handle.
+ * @param fFlag The flag to clear.
+ */
+#if 1
+# define VM_FF_CLEAR(pVM, fFlag) ASMAtomicAndU32(&(pVM)->fGlobalForcedActions, ~(fFlag))
+#else
+# define VM_FF_CLEAR(pVM, fFlag) \
+ do { ASMAtomicAndU32(&(pVM)->fGlobalForcedActions, ~(fFlag)); \
+ RTLogPrintf("VM_FF_CLEAR: %08x %s - %s(%d) %s\n", (pVM)->fGlobalForcedActions, #fFlag, __FILE__, __LINE__, __FUNCTION__); \
+ } while (0)
+#endif
+
+/** @def VMCPU_FF_CLEAR
+ * Clears a force action flag for the given VCPU.
+ *
+ * @param pVCpu VMCPU Handle.
+ * @param fFlag The flag to clear.
+ */
+#define VMCPU_FF_CLEAR(pVCpu, fFlag) ASMAtomicAndU32(&(pVCpu)->fLocalForcedActions, ~(fFlag))
+
+/** @def VM_FF_ISSET
+ * Checks if a force action flag is set.
+ *
+ * @param pVM VM Handle.
+ * @param fFlag The flag to check.
+ */
+#define VM_FF_IS_SET(pVM, fFlag) (((pVM)->fGlobalForcedActions & (fFlag)) == (fFlag))
+/** @deprecated */
+#define VM_FF_ISSET(pVM, fFlag) VM_FF_IS_SET(pVM, fFlag)
+
+/** @def VMCPU_FF_ISSET
+ * Checks if a force action flag is set for the given VCPU.
+ *
+ * @param pVCpu VMCPU Handle.
+ * @param fFlag The flag to check.
+ */
+#define VMCPU_FF_IS_SET(pVCpu, fFlag) (((pVCpu)->fLocalForcedActions & (fFlag)) == (fFlag))
+/** @deprecated */
+#define VMCPU_FF_ISSET(pVCpu, fFlag) VMCPU_FF_IS_SET(pVCpu, fFlag)
+
+/** @def VM_FF_ISPENDING
+ * Checks if one or more force action in the specified set is pending.
+ *
+ * @param pVM VM Handle.
+ * @param fFlags The flags to check for.
+ */
+#define VM_FF_IS_PENDING(pVM, fFlags) ((pVM)->fGlobalForcedActions & (fFlags))
+/** @deprecated */
+#define VM_FF_ISPENDING(pVM, fFlags) VM_FF_IS_PENDING(pVM, fFlags)
+
+/** @def VM_FF_TESTANDCLEAR
+ * Checks if one (!) force action in the specified set is pending and clears it atomically
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ * @param pVM VM Handle.
+ * @param iBit Bit position to check and clear
+ */
+#define VM_FF_TEST_AND_CLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT))
+/** @deprecated */
+#define VM_FF_TESTANDCLEAR(pVM, iBit) (ASMAtomicBitTestAndClear(&(pVM)->fGlobalForcedActions, iBit##_BIT))
+
+/** @def VMCPU_FF_TESTANDCLEAR
+ * Checks if one (!) force action in the specified set is pending and clears it atomically
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ * @param pVCpu VMCPU Handle.
+ * @param iBit Bit position to check and clear
+ */
+#define VMCPU_FF_TEST_AND_CLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT))
+/** @deprecated */
+#define VMCPU_FF_TESTANDCLEAR(pVCpu, iBit) (ASMAtomicBitTestAndClear(&(pVCpu)->fLocalForcedActions, iBit##_BIT))
+
+/** @def VMCPU_FF_ISPENDING
+ * Checks if one or more force action in the specified set is pending for the given VCPU.
+ *
+ * @param pVCpu VMCPU Handle.
+ * @param fFlags The flags to check for.
+ */
+#define VMCPU_FF_IS_PENDING(pVCpu, fFlags) ((pVCpu)->fLocalForcedActions & (fFlags))
+/** @deprecated */
+#define VMCPU_FF_ISPENDING(pVCpu, fFlags) VMCPU_FF_IS_PENDING(pVCpu, fFlags)
+
+/** @def VM_FF_ISPENDING
+ * Checks if one or more force action in the specified set is pending while one
+ * or more other ones are not.
+ *
+ * @param pVM VM Handle.
+ * @param fFlags The flags to check for.
+ * @param fExcpt The flags that should not be set.
+ */
+#define VM_FF_IS_PENDING_EXCEPT(pVM, fFlags, fExcpt) ( ((pVM)->fGlobalForcedActions & (fFlags)) && !((pVM)->fGlobalForcedActions & (fExcpt)) )
+
+/** @def VMCPU_FF_IS_PENDING_EXCEPT
+ * Checks if one or more force action in the specified set is pending for the given
+ * VCPU while one or more other ones are not.
+ *
+ * @param pVCpu VMCPU Handle.
+ * @param fFlags The flags to check for.
+ * @param fExcpt The flags that should not be set.
+ */
+#define VMCPU_FF_IS_PENDING_EXCEPT(pVCpu, fFlags, fExcpt) ( ((pVCpu)->fLocalForcedActions & (fFlags)) && !((pVCpu)->fLocalForcedActions & (fExcpt)) )
+
+/** @def VM_IS_EMT
+ * Checks if the current thread is the emulation thread (EMT).
+ *
+ * @remark The ring-0 variation will need attention if we expand the ring-0
+ * code to let threads other than EMT mess around with the VM.
+ */
+#ifdef IN_RC
+# define VM_IS_EMT(pVM) true
+#else
+# define VM_IS_EMT(pVM) (VMMGetCpu(pVM) != NULL)
+#endif
+
+/** @def VMCPU_IS_EMT
+ * Checks if the current thread is the emulation thread (EMT) for the specified
+ * virtual CPU.
+ */
+#ifdef IN_RC
+# define VMCPU_IS_EMT(pVCpu) true
+#else
+# define VMCPU_IS_EMT(pVCpu) ((pVCpu) && ((pVCpu) == VMMGetCpu((pVCpu)->CTX_SUFF(pVM))))
+#endif
+
+/** @def VM_ASSERT_EMT
+ * Asserts that the current thread IS the emulation thread (EMT).
+ */
+#ifdef IN_RC
+# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
+#elif defined(IN_RING0)
+# define VM_ASSERT_EMT(pVM) Assert(VM_IS_EMT(pVM))
+#else
+# define VM_ASSERT_EMT(pVM) \
+ AssertMsg(VM_IS_EMT(pVM), \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), VMR3GetVMCPUNativeThread(pVM)))
+#endif
+
+/** @def VMCPU_ASSERT_EMT
+ * Asserts that the current thread IS the emulation thread (EMT) of the
+ * specified virtual CPU.
+ */
+#ifdef IN_RC
+# define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu))
+#elif defined(IN_RING0)
+# define VMCPU_ASSERT_EMT(pVCpu) Assert(VMCPU_IS_EMT(pVCpu))
+#else
+# define VMCPU_ASSERT_EMT(pVCpu) \
+ AssertMsg(VMCPU_IS_EMT(pVCpu), \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%#x\n", \
+ RTThreadNativeSelf(), (pVCpu)->hNativeThread, (pVCpu)->idCpu))
+#endif
+
+/** @def VM_ASSERT_EMT_RETURN
+ * Asserts that the current thread IS the emulation thread (EMT) and returns if it isn't.
+ */
+#ifdef IN_RC
+# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
+#elif defined(IN_RING0)
+# define VM_ASSERT_EMT_RETURN(pVM, rc) AssertReturn(VM_IS_EMT(pVM), (rc))
+#else
+# define VM_ASSERT_EMT_RETURN(pVM, rc) \
+ AssertMsgReturn(VM_IS_EMT(pVM), \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd\n", RTThreadNativeSelf(), VMR3GetVMCPUNativeThread(pVM)), \
+ (rc))
+#endif
+
+/** @def VMCPU_ASSERT_EMT_RETURN
+ * Asserts that the current thread IS the emulation thread (EMT) and returns if it isn't.
+ */
+#ifdef IN_RC
+# define VMCPU_ASSERT_EMT_RETURN(pVCpu, rc) AssertReturn(VMCPU_IS_EMT(pVCpu), (rc))
+#elif defined(IN_RING0)
+# define VMCPU_ASSERT_EMT_RETURN(pVCpu, rc) AssertReturn(VMCPU_IS_EMT(pVCpu), (rc))
+#else
+# define VMCPU_ASSERT_EMT_RETURN(pVCpu, rc) \
+ AssertMsg(VMCPU_IS_EMT(pVCpu), \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%#x\n", \
+ RTThreadNativeSelf(), (pVCpu)->hNativeThread, (pVCpu)->idCpu), \
+ (rc))
+#endif
+
+/** @def VMCPU_ASSERT_EMT_OR_GURU
+ * Asserts that the current thread IS the emulation thread (EMT) of the
+ * specified virtual CPU.
+ */
+#if defined(IN_RC) || defined(IN_RING0)
+# define VMCPU_ASSERT_EMT_OR_GURU(pVCpu) Assert( VMCPU_IS_EMT(pVCpu) \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_GURU_MEDITATION \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_GURU_MEDITATION_LS )
+#else
+# define VMCPU_ASSERT_EMT_OR_GURU(pVCpu) \
+ AssertMsg( VMCPU_IS_EMT(pVCpu) \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_GURU_MEDITATION \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_GURU_MEDITATION_LS, \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%#x\n", \
+ RTThreadNativeSelf(), (pVCpu)->hNativeThread, (pVCpu)->idCpu))
+#endif
+
+/** @def VMCPU_ASSERT_EMT_OR_NOT_RUNNING
+ * Asserts that the current thread IS the emulation thread (EMT) of the
+ * specified virtual CPU when the VM is running.
+ */
+#if defined(IN_RC) || defined(IN_RING0)
+# define VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu) \
+ Assert( VMCPU_IS_EMT(pVCpu) \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_RUNNING \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_RUNNING_LS \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_RUNNING_FT )
+#else
+# define VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu) \
+ AssertMsg( VMCPU_IS_EMT(pVCpu) \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_RUNNING \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_RUNNING_LS \
+ || pVCpu->CTX_SUFF(pVM)->enmVMState == VMSTATE_RUNNING_FT, \
+ ("Not emulation thread! Thread=%RTnthrd ThreadEMT=%RTnthrd idCpu=%#x\n", \
+ RTThreadNativeSelf(), (pVCpu)->hNativeThread, (pVCpu)->idCpu))
+#endif
+
+/** @def VM_ASSERT_EMT0
+ * Asserts that the current thread IS emulation thread \#0 (EMT0).
+ */
+#define VM_ASSERT_EMT0(pVM) VMCPU_ASSERT_EMT(&(pVM)->aCpus[0])
+
+/** @def VM_ASSERT_EMT0_RETURN
+ * Asserts that the current thread IS emulation thread \#0 (EMT0) and returns if
+ * it isn't.
+ */
+#define VM_ASSERT_EMT0_RETURN(pVM, rc) VMCPU_ASSERT_EMT_RETURN(&(pVM)->aCpus[0], (rc))
+
+
+/**
+ * Asserts that the current thread is NOT the emulation thread.
+ */
+#define VM_ASSERT_OTHER_THREAD(pVM) \
+ AssertMsg(!VM_IS_EMT(pVM), ("Not other thread!!\n"))
+
+
+/** @def VM_ASSERT_STATE_RETURN
+ * Asserts a certain VM state.
+ */
+#define VM_ASSERT_STATE(pVM, _enmState) \
+ AssertMsg((pVM)->enmVMState == (_enmState), \
+ ("state %s, expected %s\n", VMGetStateName((pVM)->enmVMState), VMGetStateName(_enmState)))
+
+/** @def VM_ASSERT_STATE_RETURN
+ * Asserts a certain VM state and returns if it doesn't match.
+ */
+#define VM_ASSERT_STATE_RETURN(pVM, _enmState, rc) \
+ AssertMsgReturn((pVM)->enmVMState == (_enmState), \
+ ("state %s, expected %s\n", VMGetStateName((pVM)->enmVMState), VMGetStateName(_enmState)), \
+ (rc))
+
+/** @def VM_ASSERT_VALID_EXT_RETURN
+ * Asserts a the VM handle is valid for external access, i.e. not being
+ * destroy or terminated.
+ */
+#define VM_ASSERT_VALID_EXT_RETURN(pVM, rc) \
+ AssertMsgReturn( RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \
+ && ( (unsigned)(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING \
+ || ( (unsigned)(pVM)->enmVMState == (unsigned)VMSTATE_DESTROYING \
+ && VM_IS_EMT(pVM))), \
+ ("pVM=%p state %s\n", (pVM), RT_VALID_ALIGNED_PTR(pVM, PAGE_SIZE) \
+ ? VMGetStateName(pVM->enmVMState) : ""), \
+ (rc))
+
+/** @def VMCPU_ASSERT_VALID_EXT_RETURN
+ * Asserts a the VMCPU handle is valid for external access, i.e. not being
+ * destroy or terminated.
+ */
+#define VMCPU_ASSERT_VALID_EXT_RETURN(pVCpu, rc) \
+ AssertMsgReturn( RT_VALID_ALIGNED_PTR(pVCpu, 64) \
+ && RT_VALID_ALIGNED_PTR((pVCpu)->CTX_SUFF(pVM), PAGE_SIZE) \
+ && (unsigned)(pVCpu)->CTX_SUFF(pVM)->enmVMState < (unsigned)VMSTATE_DESTROYING, \
+ ("pVCpu=%p pVM=%p state %s\n", (pVCpu), RT_VALID_ALIGNED_PTR(pVCpu, 64) ? (pVCpu)->CTX_SUFF(pVM) : NULL, \
+ RT_VALID_ALIGNED_PTR(pVCpu, 64) && RT_VALID_ALIGNED_PTR((pVCpu)->CTX_SUFF(pVM), PAGE_SIZE) \
+ ? VMGetStateName((pVCpu)->pVMR3->enmVMState) : ""), \
+ (rc))
+
+#endif /* !VBOX_FOR_DTRACE_LIB */
+
+
+
+/** This is the VM structure.
+ *
+ * It contains (nearly?) all the VM data which have to be available in all
+ * contexts. Even if it contains all the data the idea is to use APIs not
+ * to modify all the members all around the place. Therefore we make use of
+ * unions to hide everything which isn't local to the current source module.
+ * This means we'll have to pay a little bit of attention when adding new
+ * members to structures in the unions and make sure to keep the padding sizes
+ * up to date.
+ *
+ * Run tstVMStructSize after update!
+ */
+typedef struct VM
+{
+ /** The state of the VM.
+ * This field is read only to everyone except the VM and EM. */
+ VMSTATE volatile enmVMState;
+ /** Forced action flags.
+ * See the VM_FF_* \#defines. Updated atomically.
+ */
+ volatile uint32_t fGlobalForcedActions;
+ /** Pointer to the array of page descriptors for the VM structure allocation. */
+ R3PTRTYPE(PSUPPAGE) paVMPagesR3;
+ /** Session handle. For use when calling SUPR0 APIs. */
+ PSUPDRVSESSION pSession;
+ /** Pointer to the ring-3 VM structure. */
+ PUVM pUVM;
+ /** Ring-3 Host Context VM Pointer. */
+ R3PTRTYPE(struct VM *) pVMR3;
+ /** Ring-0 Host Context VM Pointer. */
+ R0PTRTYPE(struct VM *) pVMR0;
+ /** Raw-mode Context VM Pointer. */
+ RCPTRTYPE(struct VM *) pVMRC;
+
+ /** The GVM VM handle. Only the GVM should modify this field. */
+ uint32_t hSelf;
+ /** Number of virtual CPUs. */
+ uint32_t cCpus;
+ /** CPU excution cap (1-100) */
+ uint32_t uCpuExecutionCap;
+
+ /** Size of the VM structure including the VMCPU array. */
+ uint32_t cbSelf;
+
+ /** Offset to the VMCPU array starting from beginning of this structure. */
+ uint32_t offVMCPU;
+
+ /**
+ * VMMSwitcher assembly entry point returning to host context.
+ *
+ * Depending on how the host handles the rc status given in @a eax, this may
+ * return and let the caller resume whatever it was doing prior to the call.
+ *
+ *
+ * @param eax The return code, register.
+ * @remark Assume interrupts disabled.
+ * @remark This method pointer lives here because TRPM needs it.
+ */
+ RTRCPTR pfnVMMRCToHostAsm/*(int32_t eax)*/;
+
+ /**
+ * VMMSwitcher assembly entry point returning to host context without saving the
+ * raw-mode context (hyper) registers.
+ *
+ * Unlike pfnVMMRC2HCAsm, this will not return to the caller. Instead it
+ * expects the caller to save a RC context in CPUM where one might return if the
+ * return code indicate that this is possible.
+ *
+ * This method pointer lives here because TRPM needs it.
+ *
+ * @param eax The return code, register.
+ * @remark Assume interrupts disabled.
+ * @remark This method pointer lives here because TRPM needs it.
+ */
+ RTRCPTR pfnVMMRCToHostAsmNoReturn/*(int32_t eax)*/;
+
+ /** @name Various items that are frequently accessed.
+ * @{ */
+ /** Whether to recompile user mode code or run it raw/hm. */
+ bool fRecompileUser;
+ /** Whether to recompile supervisor mode code or run it raw/hm. */
+ bool fRecompileSupervisor;
+ /** PATM enabled flag.
+ * This is placed here for performance reasons. */
+ bool fPATMEnabled;
+ /** CSAM enabled flag.
+ * This is placed here for performance reasons. */
+ bool fCSAMEnabled;
+ /** Hardware VM support is available and enabled.
+ * This is placed here for performance reasons. */
+ bool fHWACCMEnabled;
+ /** Hardware VM support is required and non-optional.
+ * This is initialized together with the rest of the VM structure. */
+ bool fHwVirtExtForced;
+ /** Set when this VM is the master FT node. */
+ bool fFaultTolerantMaster;
+ /** Large page enabled flag. */
+ bool fUseLargePages;
+ /** @} */
+
+ /** Alignment padding.. */
+ uint32_t uPadding1;
+
+ /** @name Debugging
+ * @{ */
+ /** Raw-mode Context VM Pointer. */
+ RCPTRTYPE(RTTRACEBUF) hTraceBufRC;
+ /** Ring-3 Host Context VM Pointer. */
+ R3PTRTYPE(RTTRACEBUF) hTraceBufR3;
+ /** Ring-0 Host Context VM Pointer. */
+ R0PTRTYPE(RTTRACEBUF) hTraceBufR0;
+ /** @} */
+
+#if HC_ARCH_BITS == 32
+ /** Alignment padding.. */
+ uint32_t uPadding2;
+#endif
+
+ /** @name Switcher statistics (remove)
+ * @{ */
+ /** Profiling the total time from Qemu to GC. */
+ STAMPROFILEADV StatTotalQemuToGC;
+ /** Profiling the total time from GC to Qemu. */
+ STAMPROFILEADV StatTotalGCToQemu;
+ /** Profiling the total time spent in GC. */
+ STAMPROFILEADV StatTotalInGC;
+ /** Profiling the total time spent not in Qemu. */
+ STAMPROFILEADV StatTotalInQemu;
+ /** Profiling the VMMSwitcher code for going to GC. */
+ STAMPROFILEADV StatSwitcherToGC;
+ /** Profiling the VMMSwitcher code for going to HC. */
+ STAMPROFILEADV StatSwitcherToHC;
+ STAMPROFILEADV StatSwitcherSaveRegs;
+ STAMPROFILEADV StatSwitcherSysEnter;
+ STAMPROFILEADV StatSwitcherDebug;
+ STAMPROFILEADV StatSwitcherCR0;
+ STAMPROFILEADV StatSwitcherCR4;
+ STAMPROFILEADV StatSwitcherJmpCR3;
+ STAMPROFILEADV StatSwitcherRstrRegs;
+ STAMPROFILEADV StatSwitcherLgdt;
+ STAMPROFILEADV StatSwitcherLidt;
+ STAMPROFILEADV StatSwitcherLldt;
+ STAMPROFILEADV StatSwitcherTSS;
+ /** @} */
+
+ /** Padding - the unions must be aligned on a 64 bytes boundary and the unions
+ * must start at the same offset on both 64-bit and 32-bit hosts. */
+ uint8_t abAlignment3[(HC_ARCH_BITS == 32 ? 24 : 0) + 40];
+
+ /** CPUM part. */
+ union
+ {
+#ifdef ___CPUMInternal_h
+ struct CPUM s;
+#endif
+ uint8_t padding[1536]; /* multiple of 64 */
+ } cpum;
+
+ /** VMM part. */
+ union
+ {
+#ifdef ___VMMInternal_h
+ struct VMM s;
+#endif
+ uint8_t padding[1600]; /* multiple of 64 */
+ } vmm;
+
+ /** PGM part. */
+ union
+ {
+#ifdef ___PGMInternal_h
+ struct PGM s;
+#endif
+ uint8_t padding[4096*2+6080]; /* multiple of 64 */
+ } pgm;
+
+ /** HWACCM part. */
+ union
+ {
+#ifdef ___HWACCMInternal_h
+ struct HWACCM s;
+#endif
+ uint8_t padding[5376]; /* multiple of 64 */
+ } hwaccm;
+
+ /** TRPM part. */
+ union
+ {
+#ifdef ___TRPMInternal_h
+ struct TRPM s;
+#endif
+ uint8_t padding[5248]; /* multiple of 64 */
+ } trpm;
+
+ /** SELM part. */
+ union
+ {
+#ifdef ___SELMInternal_h
+ struct SELM s;
+#endif
+ uint8_t padding[768]; /* multiple of 64 */
+ } selm;
+
+ /** MM part. */
+ union
+ {
+#ifdef ___MMInternal_h
+ struct MM s;
+#endif
+ uint8_t padding[192]; /* multiple of 64 */
+ } mm;
+
+ /** PDM part. */
+ union
+ {
+#ifdef ___PDMInternal_h
+ struct PDM s;
+#endif
+ uint8_t padding[1920]; /* multiple of 64 */
+ } pdm;
+
+ /** IOM part. */
+ union
+ {
+#ifdef ___IOMInternal_h
+ struct IOM s;
+#endif
+ uint8_t padding[832]; /* multiple of 64 */
+ } iom;
+
+ /** PATM part. */
+ union
+ {
+#ifdef ___PATMInternal_h
+ struct PATM s;
+#endif
+ uint8_t padding[768]; /* multiple of 64 */
+ } patm;
+
+ /** CSAM part. */
+ union
+ {
+#ifdef ___CSAMInternal_h
+ struct CSAM s;
+#endif
+ uint8_t padding[1088]; /* multiple of 64 */
+ } csam;
+
+ /** EM part. */
+ union
+ {
+#ifdef ___EMInternal_h
+ struct EM s;
+#endif
+ uint8_t padding[256]; /* multiple of 64 */
+ } em;
+
+ /** TM part. */
+ union
+ {
+#ifdef ___TMInternal_h
+ struct TM s;
+#endif
+ uint8_t padding[2432]; /* multiple of 64 */
+ } tm;
+
+ /** DBGF part. */
+ union
+ {
+#ifdef ___DBGFInternal_h
+ struct DBGF s;
+#endif
+ uint8_t padding[2368]; /* multiple of 64 */
+ } dbgf;
+
+ /** SSM part. */
+ union
+ {
+#ifdef ___SSMInternal_h
+ struct SSM s;
+#endif
+ uint8_t padding[128]; /* multiple of 64 */
+ } ssm;
+
+ /** FTM part. */
+ union
+ {
+#ifdef ___FTMInternal_h
+ struct FTM s;
+#endif
+ uint8_t padding[512]; /* multiple of 64 */
+ } ftm;
+
+ /** REM part. */
+ union
+ {
+#ifdef ___REMInternal_h
+ struct REM s;
+#endif
+ uint8_t padding[0x11100]; /* multiple of 64 */
+ } rem;
+
+ /* ---- begin small stuff ---- */
+
+ /** VM part. */
+ union
+ {
+#ifdef ___VMInternal_h
+ struct VMINT s;
+#endif
+ uint8_t padding[24]; /* multiple of 8 */
+ } vm;
+
+ /** CFGM part. */
+ union
+ {
+#ifdef ___CFGMInternal_h
+ struct CFGM s;
+#endif
+ uint8_t padding[8]; /* multiple of 8 */
+ } cfgm;
+
+
+ /** Padding for aligning the cpu array on a page boundary. */
+ uint8_t abAlignment2[542];
+
+ /* ---- end small stuff ---- */
+
+ /** VMCPU array for the configured number of virtual CPUs.
+ * Must be aligned on a page boundary for TLB hit reasons as well as
+ * alignment of VMCPU members. */
+ VMCPU aCpus[1];
+} VM;
+
+
+#ifdef IN_RC
+RT_C_DECLS_BEGIN
+
+/** The VM structure.
+ * This is imported from the VMMGCBuiltin module, i.e. it's a one
+ * of those magic globals which we should avoid using.
+ */
+extern DECLIMPORT(VM) g_VM;
+
+RT_C_DECLS_END
+#endif
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/vm.mac b/include/VBox/vmm/vm.mac
new file mode 100644
index 00000000..6d65b0c9
--- /dev/null
+++ b/include/VBox/vmm/vm.mac
@@ -0,0 +1,150 @@
+;; @file
+; VM - The Virtual Machine.
+;
+
+;
+; Copyright (C) 2006-2012 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; 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 ___VBox_vmm_vm_mac
+%define ___VBox_vmm_vm_mac
+
+%include "VBox/vmm/stam.mac"
+
+;/** This action forces the VM to service check and pending interrups on the APIC. */
+%define VMCPU_FF_INTERRUPT_APIC (1 << 0)
+;/** This action forces the VM to service check and pending interrups on the PIC. */
+%define VMCPU_FF_INTERRUPT_PIC (1 << 1)
+;/** This action forces the VM to schedule and run pending timer (TM). */
+%define VMCPU_FF_TIMER (1 << 2)
+;/** This action forces the VM to service pending requests from other
+; * thread or requests which must be executed in another context. */
+%define VMCPU_FF_REQUEST (1 << 9)
+
+;;
+; This is part of the VM structure.
+struc VM
+ .enmVMState resd 1
+ .fGlobalForcedActions resd 1
+ .paVMPagesR3 RTR3PTR_RES 1
+ .pSession RTR0PTR_RES 1
+ .pUVM RTR3PTR_RES 1
+ .pVMR3 RTR3PTR_RES 1
+ .pVMR0 RTR0PTR_RES 1
+ .pVMRC RTRCPTR_RES 1
+ .hSelf resd 1
+ .cCpus resd 1
+ .uCpuExecutionCap resd 1
+ .cbSelf resd 1
+ .offVMCPU resd 1
+ .pfnVMMRCToHostAsm resd 1
+ .pfnVMMRCToHostAsmNoReturn resd 1
+ .fRecompileUser resb 1
+ .fRecompileSupervisor resb 1
+ .fPATMEnabled resb 1
+ .fCSAMEnabled resb 1
+ .fHWACCMEnabled resb 1
+ .fHwVirtExtForced resb 1
+ .fFaultTolerantMaster resb 1
+ .fUseLargePages resb 1
+
+ .uPadding1 resd 1
+
+ .hTraceBufRC RTRCPTR_RES 1
+ .hTraceBufR3 RTR3PTR_RES 1
+ .hTraceBufR0 RTR0PTR_RES 1
+
+ alignb 8
+
+ .StatTotalQemuToGC resb STAMPROFILEADV_size
+ .StatTotalGCToQemu resb STAMPROFILEADV_size
+ .StatTotalInGC resb STAMPROFILEADV_size
+ .StatTotalInQemu resb STAMPROFILEADV_size
+ .StatSwitcherToGC resb STAMPROFILEADV_size
+ .StatSwitcherToHC resb STAMPROFILEADV_size
+ .StatSwitcherSaveRegs resb STAMPROFILEADV_size
+ .StatSwitcherSysEnter resb STAMPROFILEADV_size
+ .StatSwitcherDebug resb STAMPROFILEADV_size
+ .StatSwitcherCR0 resb STAMPROFILEADV_size
+ .StatSwitcherCR4 resb STAMPROFILEADV_size
+ .StatSwitcherJmpCR3 resb STAMPROFILEADV_size
+ .StatSwitcherRstrRegs resb STAMPROFILEADV_size
+ .StatSwitcherLgdt resb STAMPROFILEADV_size
+ .StatSwitcherLidt resb STAMPROFILEADV_size
+ .StatSwitcherLldt resb STAMPROFILEADV_size
+ .StatSwitcherTSS resb STAMPROFILEADV_size
+
+%ifndef HC_ARCH_BITS
+ %error "Missing HC_ARCH_BITS"
+%endif
+%if HC_ARCH_BITS == 32
+ .abAlignment3 resb 16
+%else
+; .abAlignment3 resb 16
+%endif
+
+ alignb 64
+ .cpum resb 1536
+ .vmm resb 1536
+
+endstruc
+
+;;
+; This is part of the VMCPU structure.
+struc VMCPU
+ .fLocalForcedActions resd 1
+ .enmState resd 1
+ .pUVCpu RTR3PTR_RES 1
+ .pVMR3 RTR3PTR_RES 1
+ .pVMR0 RTR0PTR_RES 1
+ .pVMRC RTRCPTR_RES 1
+ .idCpu resd 1
+
+ .hNativeThread RTR0PTR_RES 1
+ .hNativeThreadR0 RTR0PTR_RES 1
+ .idHostCpu resd 1
+ .fTraceGroups resd 1
+%if HC_ARCH_BITS == 32
+ .abAlignment1 resb 16+64
+%else
+ .abAlignment1 resb 60
+%endif
+ .uAdHoc resd 1
+ .aStatAdHoc resb STAMPROFILEADV_size * 8
+
+ alignb 64
+
+ .cpum resb 3584
+ .hwaccm resb 5376
+ .em resb 1472
+ .iem resb 3072
+ .trpm resb 128
+ .tm resb 384
+ .vmm resb 640
+ .pdm resb 128
+ .iom resb 512
+ .dbgf resb 64
+ alignb 4096
+ .pgm resb 4096
+endstruc
+
+
+%endif
+
diff --git a/include/VBox/vmm/vmapi.h b/include/VBox/vmm/vmapi.h
new file mode 100644
index 00000000..b15fc7f6
--- /dev/null
+++ b/include/VBox/vmm/vmapi.h
@@ -0,0 +1,441 @@
+/** @file
+ * VM - The Virtual Machine, API.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_vmapi_h
+#define ___VBox_vmm_vmapi_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/stam.h>
+#include <VBox/vmm/cfgm.h>
+
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_vmm_apis VM All Contexts API
+ * @ingroup grp_vm
+ * @{ */
+
+/** @def VM_RC_ADDR
+ * Converts a current context address of data within the VM structure to the equivalent
+ * raw-mode address.
+ *
+ * @returns raw-mode virtual address.
+ * @param pVM Pointer to the VM.
+ * @param pvInVM CC Pointer within the VM.
+ */
+#ifdef IN_RING3
+# define VM_RC_ADDR(pVM, pvInVM) ( (RTRCPTR)((RTRCUINTPTR)pVM->pVMRC + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR3)) )
+#elif defined(IN_RING0)
+# define VM_RC_ADDR(pVM, pvInVM) ( (RTRCPTR)((RTRCUINTPTR)pVM->pVMRC + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR0)) )
+#else
+# define VM_RC_ADDR(pVM, pvInVM) ( (RTRCPTR)(pvInVM) )
+#endif
+
+/** @def VM_R3_ADDR
+ * Converts a current context address of data within the VM structure to the equivalent
+ * ring-3 host address.
+ *
+ * @returns host virtual address.
+ * @param pVM Pointer to the VM.
+ * @param pvInVM CC pointer within the VM.
+ */
+#ifdef IN_RC
+# define VM_R3_ADDR(pVM, pvInVM) ( (RTR3PTR)((RTR3UINTPTR)pVM->pVMR3 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMRC)) )
+#elif defined(IN_RING0)
+# define VM_R3_ADDR(pVM, pvInVM) ( (RTR3PTR)((RTR3UINTPTR)pVM->pVMR3 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR0)) )
+#else
+# define VM_R3_ADDR(pVM, pvInVM) ( (RTR3PTR)(pvInVM) )
+#endif
+
+
+/** @def VM_R0_ADDR
+ * Converts a current context address of data within the VM structure to the equivalent
+ * ring-0 host address.
+ *
+ * @returns host virtual address.
+ * @param pVM Pointer to the VM.
+ * @param pvInVM CC pointer within the VM.
+ */
+#ifdef IN_RC
+# define VM_R0_ADDR(pVM, pvInVM) ( (RTR0PTR)((RTR0UINTPTR)pVM->pVMR0 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMRC)) )
+#elif defined(IN_RING3)
+# define VM_R0_ADDR(pVM, pvInVM) ( (RTR0PTR)((RTR0UINTPTR)pVM->pVMR0 + (uint32_t)((uintptr_t)(pvInVM) - (uintptr_t)pVM->pVMR3)) )
+#else
+# define VM_R0_ADDR(pVM, pvInVM) ( (RTR0PTR)(pvInVM) )
+#endif
+
+
+
+/**
+ * VM error callback function.
+ *
+ * @param pVM The VM handle. Can be NULL if an error occurred before
+ * successfully creating a VM.
+ * @param pvUser The user argument.
+ * @param rc VBox status code.
+ * @param RT_SRC_POS_DECL The source position arguments. See RT_SRC_POS and RT_SRC_POS_ARGS.
+ * @param pszFormat Error message format string.
+ * @param args Error message arguments.
+ */
+typedef DECLCALLBACK(void) FNVMATERROR(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszError, va_list args);
+/** Pointer to a VM error callback. */
+typedef FNVMATERROR *PFNVMATERROR;
+
+VMMDECL(int) VMSetError(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
+VMMDECL(int) VMSetErrorV(PVM pVM, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list args);
+
+/** @def VM_SET_ERROR
+ * Macro for setting a simple VM error message.
+ * Don't use '%' in the message!
+ *
+ * @returns rc. Meaning you can do:
+ * @code
+ * return VM_SET_ERROR(pVM, VERR_OF_YOUR_CHOICE, "descriptive message");
+ * @endcode
+ * @param pVM VM handle.
+ * @param rc VBox status code.
+ * @param pszMessage Error message string.
+ * @thread Any
+ */
+#define VM_SET_ERROR(pVM, rc, pszMessage) (VMSetError(pVM, rc, RT_SRC_POS, pszMessage))
+
+
+/**
+ * VM runtime error callback function.
+ *
+ * See VMSetRuntimeError for the detailed description of parameters.
+ *
+ * @param pVM The VM handle.
+ * @param pvUser The user argument.
+ * @param fFlags The error flags.
+ * @param pszErrorId Error ID string.
+ * @param pszFormat Error message format string.
+ * @param va Error message arguments.
+ */
+typedef DECLCALLBACK(void) FNVMATRUNTIMEERROR(PVM pVM, void *pvUser, uint32_t fFlags, const char *pszErrorId,
+ const char *pszFormat, va_list va);
+/** Pointer to a VM runtime error callback. */
+typedef FNVMATRUNTIMEERROR *PFNVMATRUNTIMEERROR;
+
+VMMDECL(int) VMSetRuntimeError(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, ...);
+VMMDECL(int) VMSetRuntimeErrorV(PVM pVM, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list args);
+
+/** @name VMSetRuntimeError fFlags
+ * When no flags are given the VM will continue running and it's up to the front
+ * end to take action on the error condition.
+ *
+ * @{ */
+/** The error is fatal.
+ * The VM is not in a state where it can be saved and will enter a state
+ * where it can no longer execute code. The caller <b>must</b> propagate status
+ * codes. */
+#define VMSETRTERR_FLAGS_FATAL RT_BIT_32(0)
+/** Suspend the VM after, or if possible before, raising the error on EMT. The
+ * caller <b>must</b> propagate status codes. */
+#define VMSETRTERR_FLAGS_SUSPEND RT_BIT_32(1)
+/** Don't wait for the EMT to handle the request.
+ * Only valid when on a worker thread and there is a high risk of a dead
+ * lock. Be careful not to flood the user with errors. */
+#define VMSETRTERR_FLAGS_NO_WAIT RT_BIT_32(2)
+/** @} */
+
+/**
+ * VM state callback function.
+ *
+ * You are not allowed to call any function which changes the VM state from a
+ * state callback, except VMR3Destroy().
+ *
+ * @param pVM The VM handle.
+ * @param enmState The new state.
+ * @param enmOldState The old state.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(void) FNVMATSTATE(PVM pVM, VMSTATE enmState, VMSTATE enmOldState, void *pvUser);
+/** Pointer to a VM state callback. */
+typedef FNVMATSTATE *PFNVMATSTATE;
+
+VMMDECL(const char *) VMGetStateName(VMSTATE enmState);
+
+
+/**
+ * Request type.
+ */
+typedef enum VMREQTYPE
+{
+ /** Invalid request. */
+ VMREQTYPE_INVALID = 0,
+ /** VM: Internal. */
+ VMREQTYPE_INTERNAL,
+ /** Maximum request type (exclusive). Used for validation. */
+ VMREQTYPE_MAX
+} VMREQTYPE;
+
+/**
+ * Request state.
+ */
+typedef enum VMREQSTATE
+{
+ /** The state is invalid. */
+ VMREQSTATE_INVALID = 0,
+ /** The request have been allocated and is in the process of being filed. */
+ VMREQSTATE_ALLOCATED,
+ /** The request is queued by the requester. */
+ VMREQSTATE_QUEUED,
+ /** The request is begin processed. */
+ VMREQSTATE_PROCESSING,
+ /** The request is completed, the requester is begin notified. */
+ VMREQSTATE_COMPLETED,
+ /** The request packet is in the free chain. (The requester */
+ VMREQSTATE_FREE
+} VMREQSTATE;
+
+/**
+ * Request flags.
+ */
+typedef enum VMREQFLAGS
+{
+ /** The request returns a VBox status code. */
+ VMREQFLAGS_VBOX_STATUS = 0,
+ /** The request is a void request and have no status code. */
+ VMREQFLAGS_VOID = 1,
+ /** Return type mask. */
+ VMREQFLAGS_RETURN_MASK = 1,
+ /** Caller does not wait on the packet, EMT will free it. */
+ VMREQFLAGS_NO_WAIT = 2,
+ /** Poke the destination EMT(s) if executing guest code. Use with care. */
+ VMREQFLAGS_POKE = 4,
+ /** Priority request that can safely be processed while doing async
+ * suspend and power off. */
+ VMREQFLAGS_PRIORITY = 8
+} VMREQFLAGS;
+
+
+/**
+ * VM Request packet.
+ *
+ * This is used to request an action in the EMT. Usually the requester is
+ * another thread, but EMT can also end up being the requester in which case
+ * it's carried out synchronously.
+ */
+typedef struct VMREQ
+{
+ /** Pointer to the next request in the chain. */
+ struct VMREQ * volatile pNext;
+ /** Pointer to ring-3 VM structure which this request belongs to. */
+ PUVM pUVM;
+ /** Request state. */
+ volatile VMREQSTATE enmState;
+ /** VBox status code for the completed request. */
+ volatile int32_t iStatus;
+ /** Requester event sem.
+ * The request can use this event semaphore to wait/poll for completion
+ * of the request.
+ */
+ RTSEMEVENT EventSem;
+ /** Set if the event semaphore is clear. */
+ volatile bool fEventSemClear;
+ /** Flags, VMR3REQ_FLAGS_*. */
+ unsigned fFlags;
+ /** Request type. */
+ VMREQTYPE enmType;
+ /** Request destination. */
+ VMCPUID idDstCpu;
+ /** Request specific data. */
+ union VMREQ_U
+ {
+ /** VMREQTYPE_INTERNAL. */
+ struct
+ {
+ /** Pointer to the function to be called. */
+ PFNRT pfn;
+ /** Number of arguments. */
+ unsigned cArgs;
+ /** Array of arguments. */
+ uintptr_t aArgs[64];
+ } Internal;
+ } u;
+} VMREQ;
+/** Pointer to a VM request packet. */
+typedef VMREQ *PVMREQ;
+
+/** @} */
+
+
+#ifndef IN_RC
+/** @defgroup grp_vmm_apis_hc VM Host Context API
+ * @ingroup grp_vm
+ * @{ */
+
+/** @} */
+#endif
+
+
+#ifdef IN_RING3
+/** @defgroup grp_vmm_apis_r3 VM Host Context Ring 3 API
+ * This interface is a _draft_!
+ * @ingroup grp_vm
+ * @{ */
+
+/**
+ * Completion notification codes.
+ */
+typedef enum VMINITCOMPLETED
+{
+ /** The ring-3 init is completed. */
+ VMINITCOMPLETED_RING3 = 1,
+ /** The ring-0 init is completed. */
+ VMINITCOMPLETED_RING0,
+ /** The hardware accelerated virtualization init is completed.
+ * Used to make decisision depending on whether HWACCMIsEnabled(). */
+ VMINITCOMPLETED_HWACCM,
+ /** The GC init is completed. */
+ VMINITCOMPLETED_GC
+} VMINITCOMPLETED;
+
+
+VMMR3DECL(int) VMR3Create(uint32_t cCpus, PCVMM2USERMETHODS pVm2UserCbs,
+ PFNVMATERROR pfnVMAtError, void *pvUserVM,
+ PFNCFGMCONSTRUCTOR pfnCFGMConstructor, void *pvUserCFGM,
+ PVM *ppVM);
+VMMR3DECL(int) VMR3PowerOn(PVM pVM);
+VMMR3DECL(int) VMR3Suspend(PVM pVM);
+VMMR3DECL(int) VMR3Resume(PVM pVM);
+VMMR3DECL(int) VMR3Reset(PVM pVM);
+
+/**
+ * Progress callback.
+ * This will report the completion percentage of an operation.
+ *
+ * @returns VINF_SUCCESS.
+ * @returns Error code to cancel the operation with.
+ * @param pVM The VM handle.
+ * @param uPercent Completion percentage (0-100).
+ * @param pvUser User specified argument.
+ */
+typedef DECLCALLBACK(int) FNVMPROGRESS(PVM pVM, unsigned uPercent, void *pvUser);
+/** Pointer to a FNVMPROGRESS function. */
+typedef FNVMPROGRESS *PFNVMPROGRESS;
+
+VMMR3DECL(int) VMR3Save(PVM pVM, const char *pszFilename, bool fContinueAfterwards, PFNVMPROGRESS pfnProgress, void *pvUser, bool *pfSuspended);
+VMMR3DECL(int) VMR3Teleport(PVM pVM, uint32_t cMsDowntime, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser, PFNVMPROGRESS pfnProgress, void *pvProgressUser, bool *pfSuspended);
+VMMR3DECL(int) VMR3LoadFromFile(PVM pVM, const char *pszFilename, PFNVMPROGRESS pfnProgress, void *pvUser);
+VMMR3DECL(int) VMR3LoadFromStream(PVM pVM, PCSSMSTRMOPS pStreamOps, void *pvStreamOpsUser,
+ PFNVMPROGRESS pfnProgress, void *pvProgressUser);
+VMMR3DECL(int) VMR3PowerOff(PVM pVM);
+VMMR3DECL(int) VMR3Destroy(PVM pVM);
+VMMR3DECL(void) VMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3DECL(PVM) VMR3EnumVMs(PVM pVMPrev);
+
+VMMR3DECL(PVM) VMR3GetVM(PUVM pUVM);
+VMMR3DECL(PUVM) VMR3GetUVM(PVM pVM);
+VMMR3DECL(uint32_t) VMR3RetainUVM(PUVM pUVM);
+VMMR3DECL(uint32_t) VMR3ReleaseUVM(PUVM pUVM);
+VMMR3DECL(const char *) VMR3GetName(PUVM pUVM);
+VMMR3DECL(PRTUUID) VMR3GetUuid(PUVM pUVM, PRTUUID pUuid);
+VMMR3DECL(VMSTATE) VMR3GetState(PVM pVM);
+VMMR3DECL(VMSTATE) VMR3GetStateU(PUVM pUVM);
+VMMR3DECL(const char *) VMR3GetStateName(VMSTATE enmState);
+
+/**
+ * VM destruction callback.
+ * @param pVM The VM which is about to be destroyed.
+ * @param pvUser The user parameter specified at registration.
+ */
+typedef DECLCALLBACK(void) FNVMATDTOR(PVM pVM, void *pvUser);
+/** Pointer to a VM destruction callback. */
+typedef FNVMATDTOR *PFNVMATDTOR;
+
+VMMR3DECL(int) VMR3AtDtorRegister(PFNVMATDTOR pfnAtDtor, void *pvUser);
+VMMR3DECL(int) VMR3AtDtorDeregister(PFNVMATDTOR pfnAtDtor);
+VMMR3DECL(int) VMR3AtStateRegister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser);
+VMMR3DECL(int) VMR3AtStateDeregister(PVM pVM, PFNVMATSTATE pfnAtState, void *pvUser);
+VMMR3DECL(bool) VMR3TeleportedAndNotFullyResumedYet(PVM pVM);
+VMMR3DECL(int) VMR3AtErrorRegister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
+VMMR3DECL(int) VMR3AtErrorRegisterU(PUVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
+VMMR3DECL(int) VMR3AtErrorDeregister(PVM pVM, PFNVMATERROR pfnAtError, void *pvUser);
+VMMR3DECL(void) VMR3SetErrorWorker(PVM pVM);
+VMMR3DECL(uint32_t) VMR3GetErrorCount(PVM pVM);
+VMMR3DECL(uint32_t) VMR3GetErrorCountU(PUVM pUVM);
+VMMR3DECL(int) VMR3AtRuntimeErrorRegister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
+VMMR3DECL(int) VMR3AtRuntimeErrorDeregister(PVM pVM, PFNVMATRUNTIMEERROR pfnAtRuntimeError, void *pvUser);
+VMMR3DECL(int) VMR3SetRuntimeErrorWorker(PVM pVM);
+VMMR3DECL(uint32_t) VMR3GetRuntimeErrorCount(PVM pVM);
+VMMR3DECL(int) VMR3ReqCall(PVM pVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallVU(PUVM pUVM, VMCPUID idDstCpu, PVMREQ *ppReq, RTMSINTERVAL cMillies, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
+VMMR3DECL(int) VMR3ReqCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqCallVoidNoWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqPriorityCallWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqPriorityCallVoidWait(PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...);
+VMMR3DECL(int) VMR3ReqAlloc(PVM pVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu);
+VMMR3DECL(int) VMR3ReqAllocU(PUVM pUVM, PVMREQ *ppReq, VMREQTYPE enmType, VMCPUID idDstCpu);
+VMMR3DECL(int) VMR3ReqFree(PVMREQ pReq);
+VMMR3DECL(int) VMR3ReqQueue(PVMREQ pReq, RTMSINTERVAL cMillies);
+VMMR3DECL(int) VMR3ReqWait(PVMREQ pReq, RTMSINTERVAL cMillies);
+VMMR3DECL(int) VMR3ReqProcessU(PUVM pUVM, VMCPUID idDstCpu, bool fPriorityOnly);
+VMMR3DECL(void) VMR3NotifyGlobalFFU(PUVM pUVM, uint32_t fFlags);
+VMMR3DECL(void) VMR3NotifyCpuFFU(PUVMCPU pUVMCpu, uint32_t fFlags);
+/** @name Flags for VMR3NotifyCpuFFU and VMR3NotifyGlobalFFU.
+ * @{ */
+/** Whether we've done REM or not. */
+#define VMNOTIFYFF_FLAGS_DONE_REM RT_BIT_32(0)
+/** Whether we should poke the CPU if it's executing guest code. */
+#define VMNOTIFYFF_FLAGS_POKE RT_BIT_32(1)
+/** @} */
+
+VMMR3DECL(int) VMR3WaitHalted(PVM pVM, PVMCPU pVCpu, bool fIgnoreInterrupts);
+VMMR3DECL(int) VMR3WaitU(PUVMCPU pUVMCpu);
+VMMR3_INT_DECL(int) VMR3AsyncPdmNotificationWaitU(PUVMCPU pUVCpu);
+VMMR3_INT_DECL(void) VMR3AsyncPdmNotificationWakeupU(PUVM pUVM);
+VMMR3DECL(RTCPUID) VMR3GetVMCPUId(PVM pVM);
+VMMR3DECL(RTTHREAD) VMR3GetVMCPUThread(PVM pVM);
+VMMR3DECL(RTTHREAD) VMR3GetVMCPUThreadU(PUVM pUVM);
+VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThread(PVM pVM);
+VMMR3DECL(RTNATIVETHREAD) VMR3GetVMCPUNativeThreadU(PUVM pUVM);
+VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
+VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(int) VMR3SetCpuExecutionCap(PVM pVM, uint32_t uCpuExecutionCap);
+/** @} */
+#endif /* IN_RING3 */
+
+
+#ifdef IN_RC
+/** @defgroup grp_vmm_apis_gc VM Guest Context APIs
+ * @ingroup grp_vm
+ * @{ */
+
+/** @} */
+#endif
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/VBox/vmm/vmcpuset.h b/include/VBox/vmm/vmcpuset.h
new file mode 100644
index 00000000..8d92dbb5
--- /dev/null
+++ b/include/VBox/vmm/vmcpuset.h
@@ -0,0 +1,107 @@
+/** @file
+ * VirtualBox - VMCPUSET Operation.
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_vmcpuset_h
+#define ___VBox_vmm_vmcpuset_h
+
+#include <VBox/types.h>
+#include <iprt/asm.h>
+#include <iprt/string.h>
+
+/** @defgroup grp_vmcpuset VMCPUSET Operations
+ * @ingroup grp_types_both
+ * @sa VMCPUSET
+ * @{
+ */
+
+/** Tests if a valid CPU ID is present in the set.. */
+#define VMCPUSET_IS_PRESENT(pSet, idCpu) ASMBitTest( &(pSet)->au32Bitmap[0], (idCpu))
+/** Adds a CPU to the set. */
+#define VMCPUSET_ADD(pSet, idCpu) ASMBitSet( &(pSet)->au32Bitmap[0], (idCpu))
+/** Deletes a CPU from the set. */
+#define VMCPUSET_DEL(pSet, idCpu) ASMBitClear(&(pSet)->au32Bitmap[0], (idCpu))
+/** Empties the set. */
+#define VMCPUSET_EMPTY(pSet) memset(&(pSet)->au32Bitmap[0], '\0', sizeof((pSet)->au32Bitmap))
+/** Fills the set. */
+#define VMCPUSET_FILL(pSet) memset(&(pSet)->au32Bitmap[0], 0xff, sizeof((pSet)->au32Bitmap))
+/** Checks if two sets are equal to one another. */
+#define VMCPUSET_IS_EQUAL(pSet1, pSet2) (memcmp(&(pSet1)->au32Bitmap[0], &(pSet2)->au32Bitmap[0], sizeof((pSet1)->au32Bitmap)) == 0)
+/** Checks if the set is empty. */
+#define VMCPUSET_IS_EMPTY(a_pSet) ( (a_pSet)->au32Bitmap[0] == 0 \
+ && (a_pSet)->au32Bitmap[1] == 0 \
+ && (a_pSet)->au32Bitmap[2] == 0 \
+ && (a_pSet)->au32Bitmap[3] == 0 \
+ && (a_pSet)->au32Bitmap[4] == 0 \
+ && (a_pSet)->au32Bitmap[5] == 0 \
+ && (a_pSet)->au32Bitmap[6] == 0 \
+ && (a_pSet)->au32Bitmap[7] == 0 \
+ )
+/** Finds the first CPU present in the SET.
+ * @returns CPU index if found, NIL_VMCPUID if not. */
+#define VMCPUSET_FIND_FIRST_PRESENT(a_pSet) VMCpuSetFindFirstPresentInternal(a_pSet)
+
+/** Implements VMCPUSET_FIND_FIRST_PRESENT.
+ *
+ * @returns CPU index of the first CPU present in the set, NIL_VMCPUID if none
+ * are present.
+ * @param pSet The set to scan.
+ */
+DECLINLINE(int32_t) VMCpuSetFindFirstPresentInternal(PCVMCPUSET pSet)
+{
+ int i = ASMBitFirstSet(&pSet->au32Bitmap[0], RT_ELEMENTS(pSet->au32Bitmap) * 32);
+ return i >= 0 ? (VMCPUID)i : NIL_VMCPUID;
+}
+
+/** Finds the first CPU present in the SET.
+ * @returns CPU index if found, NIL_VMCPUID if not. */
+#define VMCPUSET_FIND_LAST_PRESENT(a_pSet) VMCpuSetFindLastPresentInternal(a_pSet)
+
+/** Implements VMCPUSET_FIND_LAST_PRESENT.
+ *
+ * @returns CPU index of the last CPU present in the set, NIL_VMCPUID if none
+ * are present.
+ * @param pSet The set to scan.
+ */
+DECLINLINE(int32_t) VMCpuSetFindLastPresentInternal(PCVMCPUSET pSet)
+{
+ uint32_t i = RT_ELEMENTS(pSet->au32Bitmap);
+ while (i-- > 0)
+ {
+ uint32_t u = pSet->au32Bitmap[i];
+ if (u)
+ {
+ u = ASMBitLastSetU32(u);
+ u--;
+ u |= i << 5;
+ return u;
+ }
+ }
+ return NIL_VMCPUID;
+}
+
+/** @ */
+
+#endif
+
diff --git a/include/VBox/vmm/vmm.h b/include/VBox/vmm/vmm.h
new file mode 100644
index 00000000..e3af0c29
--- /dev/null
+++ b/include/VBox/vmm/vmm.h
@@ -0,0 +1,522 @@
+/** @file
+ * VMM - The Virtual Machine Monitor.
+ */
+
+/*
+ * Copyright (C) 2006-2010 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vmm_vmm_h
+#define ___VBox_vmm_vmm_h
+
+#include <VBox/types.h>
+#include <VBox/vmm/vmapi.h>
+#include <VBox/sup.h>
+#include <VBox/log.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_vmm The Virtual Machine Monitor API
+ * @{
+ */
+
+/**
+ * World switcher identifiers.
+ */
+typedef enum VMMSWITCHER
+{
+ /** The usual invalid 0. */
+ VMMSWITCHER_INVALID = 0,
+ /** Switcher for 32-bit host to 32-bit shadow paging. */
+ VMMSWITCHER_32_TO_32,
+ /** Switcher for 32-bit host paging to PAE shadow paging. */
+ VMMSWITCHER_32_TO_PAE,
+ /** Switcher for 32-bit host paging to AMD64 shadow paging. */
+ VMMSWITCHER_32_TO_AMD64,
+ /** Switcher for PAE host to 32-bit shadow paging. */
+ VMMSWITCHER_PAE_TO_32,
+ /** Switcher for PAE host to PAE shadow paging. */
+ VMMSWITCHER_PAE_TO_PAE,
+ /** Switcher for PAE host paging to AMD64 shadow paging. */
+ VMMSWITCHER_PAE_TO_AMD64,
+ /** Switcher for AMD64 host paging to 32-bit shadow paging. */
+ VMMSWITCHER_AMD64_TO_32,
+ /** Switcher for AMD64 host paging to PAE shadow paging. */
+ VMMSWITCHER_AMD64_TO_PAE,
+ /** Switcher for AMD64 host paging to AMD64 shadow paging. */
+ VMMSWITCHER_AMD64_TO_AMD64,
+ /** Used to make a count for array declarations and suchlike. */
+ VMMSWITCHER_MAX,
+ /** The usual 32-bit paranoia. */
+ VMMSWITCHER_32BIT_HACK = 0x7fffffff
+} VMMSWITCHER;
+
+
+/**
+ * VMMRZCallRing3 operations.
+ */
+typedef enum VMMCALLRING3
+{
+ /** Invalid operation. */
+ VMMCALLRING3_INVALID = 0,
+ /** Acquire the PDM lock. */
+ VMMCALLRING3_PDM_LOCK,
+ /** Acquire the critical section specified as argument. */
+ VMMCALLRING3_PDM_CRIT_SECT_ENTER,
+ /** Acquire the PGM lock. */
+ VMMCALLRING3_PGM_LOCK,
+ /** Grow the PGM shadow page pool. */
+ VMMCALLRING3_PGM_POOL_GROW,
+ /** Maps a chunk into ring-3. */
+ VMMCALLRING3_PGM_MAP_CHUNK,
+ /** Allocates more handy pages. */
+ VMMCALLRING3_PGM_ALLOCATE_HANDY_PAGES,
+ /** Allocates a large (2MB) page. */
+ VMMCALLRING3_PGM_ALLOCATE_LARGE_HANDY_PAGE,
+ /** Acquire the MM hypervisor heap lock. */
+ VMMCALLRING3_MMHYPER_LOCK,
+ /** Replay the REM handler notifications. */
+ VMMCALLRING3_REM_REPLAY_HANDLER_NOTIFICATIONS,
+ /** Flush the GC/R0 logger. */
+ VMMCALLRING3_VMM_LOGGER_FLUSH,
+ /** Set the VM error message. */
+ VMMCALLRING3_VM_SET_ERROR,
+ /** Set the VM runtime error message. */
+ VMMCALLRING3_VM_SET_RUNTIME_ERROR,
+ /** Signal a ring 0 assertion. */
+ VMMCALLRING3_VM_R0_ASSERTION,
+ /** Ring switch to force preemption. */
+ VMMCALLRING3_VM_R0_PREEMPT,
+ /** Sync the FTM state with the standby node. */
+ VMMCALLRING3_FTM_SET_CHECKPOINT,
+ /** The usual 32-bit hack. */
+ VMMCALLRING3_32BIT_HACK = 0x7fffffff
+} VMMCALLRING3;
+
+/**
+ * VMMR3AtomicExecuteHandler callback function.
+ *
+ * @returns VBox status code.
+ * @param pVM Pointer to the shared VM structure.
+ * @param pvUser User specified argument
+ *
+ * @todo missing prefix.
+ */
+typedef DECLCALLBACK(int) FNATOMICHANDLER(PVM pVM, void *pvUser);
+/** Pointer to a FNMMATOMICHANDLER(). */
+typedef FNATOMICHANDLER *PFNATOMICHANDLER;
+
+/**
+ * Rendezvous callback.
+ *
+ * @returns VBox strict status code - EM scheduling. Do not return
+ * informational status code other than the ones used by EM for
+ * scheduling.
+ *
+ * @param pVM The VM handle.
+ * @param pVCpu The handle of the calling virtual CPU.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(VBOXSTRICTRC) FNVMMEMTRENDEZVOUS(PVM pVM, PVMCPU pVCpu, void *pvUser);
+/** Pointer to a rendezvous callback function. */
+typedef FNVMMEMTRENDEZVOUS *PFNVMMEMTRENDEZVOUS;
+
+/**
+ * Method table that the VMM uses to call back the user of the VMM.
+ */
+typedef struct VMM2USERMETHODS
+{
+ /** Magic value (VMM2USERMETHODS_MAGIC). */
+ uint32_t u32Magic;
+ /** Structure version (VMM2USERMETHODS_VERSION). */
+ uint32_t u32Version;
+
+ /**
+ * Save the VM state.
+ *
+ * @returns VBox status code.
+ * @param pThis Pointer to the callback method table.
+ * @param pUVM The user mode VM handle.
+ *
+ * @remarks This member shall be set to NULL if the operation is not
+ * supported.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSaveState,(PCVMM2USERMETHODS pThis, PUVM pUVM));
+ /** @todo Move pfnVMAtError and pfnCFGMConstructor here? */
+
+ /**
+ * EMT initialization notification callback.
+ *
+ * This is intended for doing per-thread initialization for EMTs (like COM
+ * init).
+ *
+ * @param pThis Pointer to the callback method table.
+ * @param pUVM The user mode VM handle.
+ * @param pUVCpu The user mode virtual CPU handle.
+ *
+ * @remarks This is optional and shall be set to NULL if not wanted.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnNotifyEmtInit,(PCVMM2USERMETHODS pThis, PUVM pUVM, PUVMCPU pUVCpu));
+
+ /**
+ * EMT termination notification callback.
+ *
+ * This is intended for doing per-thread cleanups for EMTs (like COM).
+ *
+ * @param pThis Pointer to the callback method table.
+ * @param pUVM The user mode VM handle.
+ * @param pUVCpu The user mode virtual CPU handle.
+ *
+ * @remarks This is optional and shall be set to NULL if not wanted.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnNotifyEmtTerm,(PCVMM2USERMETHODS pThis, PUVM pUVM, PUVMCPU pUVCpu));
+
+ /**
+ * PDM thread initialization notification callback.
+ *
+ * This is intended for doing per-thread initialization (like COM init).
+ *
+ * @param pThis Pointer to the callback method table.
+ * @param pUVM The user mode VM handle.
+ *
+ * @remarks This is optional and shall be set to NULL if not wanted.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnNotifyPdmtInit,(PCVMM2USERMETHODS pThis, PUVM pUVM));
+
+ /**
+ * EMT termination notification callback.
+ *
+ * This is intended for doing per-thread cleanups for EMTs (like COM).
+ *
+ * @param pThis Pointer to the callback method table.
+ * @param pUVM The user mode VM handle.
+ *
+ * @remarks This is optional and shall be set to NULL if not wanted.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnNotifyPdmtTerm,(PCVMM2USERMETHODS pThis, PUVM pUVM));
+
+ /** Magic value (VMM2USERMETHODS_MAGIC) marking the end of the structure. */
+ uint32_t u32EndMagic;
+} VMM2USERMETHODS;
+
+/** Magic value of the VMM2USERMETHODS (Franz Kafka). */
+#define VMM2USERMETHODS_MAGIC UINT32_C(0x18830703)
+/** The VMM2USERMETHODS structure version. */
+#define VMM2USERMETHODS_VERSION UINT32_C(0x00020000)
+
+
+VMMDECL(RTRCPTR) VMMGetStackRC(PVMCPU pVCpu);
+VMMDECL(VMCPUID) VMMGetCpuId(PVM pVM);
+VMMDECL(PVMCPU) VMMGetCpu(PVM pVM);
+VMMDECL(PVMCPU) VMMGetCpu0(PVM pVM);
+VMMDECL(PVMCPU) VMMGetCpuById(PVM pVM, VMCPUID idCpu);
+VMMDECL(uint32_t) VMMGetSvnRev(void);
+VMMDECL(VMMSWITCHER) VMMGetSwitcher(PVM pVM);
+VMMDECL(void) VMMTrashVolatileXMMRegs(void);
+
+/** @def VMMIsHwVirtExtForced
+ * Checks if forced to use the hardware assisted virtualization extensions.
+ *
+ * This is intended for making setup decisions where we can save resources when
+ * using hardware assisted virtualization.
+ *
+ * @returns true / false.
+ * @param pVM Pointer to the shared VM structure.
+ */
+#define VMMIsHwVirtExtForced(pVM) ((pVM)->fHwVirtExtForced)
+
+
+#ifdef IN_RING3
+/** @defgroup grp_vmm_r3 The VMM Host Context Ring 3 API
+ * @ingroup grp_vmm
+ * @{
+ */
+VMMR3_INT_DECL(int) VMMR3Init(PVM pVM);
+VMMR3_INT_DECL(int) VMMR3InitR0(PVM pVM);
+VMMR3_INT_DECL(int) VMMR3InitRC(PVM pVM);
+VMMR3_INT_DECL(int) VMMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
+VMMR3_INT_DECL(int) VMMR3Term(PVM pVM);
+VMMR3_INT_DECL(void) VMMR3Relocate(PVM pVM, RTGCINTPTR offDelta);
+VMMR3_INT_DECL(int) VMMR3UpdateLoggers(PVM pVM);
+VMMR3DECL(const char *) VMMR3GetRZAssertMsg1(PVM pVM);
+VMMR3DECL(const char *) VMMR3GetRZAssertMsg2(PVM pVM);
+VMMR3_INT_DECL(int) VMMR3GetImportRC(PVM pVM, const char *pszSymbol, PRTRCPTR pRCPtrValue);
+VMMR3_INT_DECL(int) VMMR3SelectSwitcher(PVM pVM, VMMSWITCHER enmSwitcher);
+VMMR3_INT_DECL(int) VMMR3DisableSwitcher(PVM pVM);
+VMMR3_INT_DECL(RTR0PTR) VMMR3GetHostToGuestSwitcher(PVM pVM, VMMSWITCHER enmSwitcher);
+VMMR3_INT_DECL(int) VMMR3RawRunGC(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(int) VMMR3HwAccRunGC(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(int) VMMR3CallRC(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, ...);
+VMMR3DECL(int) VMMR3CallRCV(PVM pVM, RTRCPTR RCPtrEntry, unsigned cArgs, va_list args);
+VMMR3DECL(int) VMMR3CallR0(PVM pVM, uint32_t uOperation, uint64_t u64Arg, PSUPVMMR0REQHDR pReqHdr);
+VMMR3DECL(int) VMMR3ResumeHyper(PVM pVM, PVMCPU pVCpu);
+VMMR3DECL(void) VMMR3FatalDump(PVM pVM, PVMCPU pVCpu, int rcErr);
+VMMR3_INT_DECL(void) VMMR3YieldSuspend(PVM pVM);
+VMMR3_INT_DECL(void) VMMR3YieldStop(PVM pVM);
+VMMR3_INT_DECL(void) VMMR3YieldResume(PVM pVM);
+VMMR3_INT_DECL(void) VMMR3SendSipi(PVM pVM, VMCPUID idCpu, uint32_t uVector);
+VMMR3_INT_DECL(void) VMMR3SendInitIpi(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(int) VMMR3RegisterPatchMemory(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
+VMMR3DECL(int) VMMR3DeregisterPatchMemory(PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem);
+VMMR3DECL(int) VMMR3EmtRendezvous(PVM pVM, uint32_t fFlags, PFNVMMEMTRENDEZVOUS pfnRendezvous, void *pvUser);
+VMMR3_INT_DECL(bool) VMMR3EmtRendezvousSetDisabled(PVMCPU pVCpu, bool fDisabled);
+/** @defgroup grp_VMMR3EmtRendezvous_fFlags VMMR3EmtRendezvous flags
+ * @{ */
+/** Execution type mask. */
+#define VMMEMTRENDEZVOUS_FLAGS_TYPE_MASK UINT32_C(0x00000007)
+/** Invalid execution type. */
+#define VMMEMTRENDEZVOUS_FLAGS_TYPE_INVALID UINT32_C(0)
+/** Let the EMTs execute the callback one by one (in no particular order). */
+#define VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE UINT32_C(1)
+/** Let all the EMTs execute the callback at the same time. */
+#define VMMEMTRENDEZVOUS_FLAGS_TYPE_ALL_AT_ONCE UINT32_C(2)
+/** Only execute the callback on one EMT (no particular one). */
+#define VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE UINT32_C(3)
+/** Let the EMTs execute the callback one by one in ascending order. */
+#define VMMEMTRENDEZVOUS_FLAGS_TYPE_ASCENDING UINT32_C(4)
+/** Let the EMTs execute the callback one by one in descending order. */
+#define VMMEMTRENDEZVOUS_FLAGS_TYPE_DESCENDING UINT32_C(5)
+/** Stop after the first error.
+ * This is not valid for any execution type where more than one EMT is active
+ * at a time. */
+#define VMMEMTRENDEZVOUS_FLAGS_STOP_ON_ERROR UINT32_C(0x00000008)
+/** The valid flags. */
+#define VMMEMTRENDEZVOUS_FLAGS_VALID_MASK UINT32_C(0x0000000f)
+/** @} */
+VMMR3_INT_DECL(int) VMMR3EmtRendezvousFF(PVM pVM, PVMCPU pVCpu);
+VMMR3_INT_DECL(int) VMMR3ReadR0Stack(PVM pVM, VMCPUID idCpu, RTHCUINTPTR R0Addr, void *pvBuf, size_t cbRead);
+/** @} */
+#endif /* IN_RING3 */
+
+
+/** @defgroup grp_vmm_r0 The VMM Host Context Ring 0 API
+ * @ingroup grp_vmm
+ * @{
+ */
+
+/**
+ * The VMMR0Entry() codes.
+ */
+typedef enum VMMR0OPERATION
+{
+ /** Run guest context. */
+ VMMR0_DO_RAW_RUN = SUP_VMMR0_DO_RAW_RUN,
+ /** Run guest code using the available hardware acceleration technology. */
+ VMMR0_DO_HWACC_RUN = SUP_VMMR0_DO_HWACC_RUN,
+ /** Official NOP that we use for profiling. */
+ VMMR0_DO_NOP = SUP_VMMR0_DO_NOP,
+ /** Official slow iocl NOP that we use for profiling. */
+ VMMR0_DO_SLOW_NOP,
+
+ /** Ask the GVMM to create a new VM. */
+ VMMR0_DO_GVMM_CREATE_VM,
+ /** Ask the GVMM to destroy the VM. */
+ VMMR0_DO_GVMM_DESTROY_VM,
+ /** Call GVMMR0SchedHalt(). */
+ VMMR0_DO_GVMM_SCHED_HALT,
+ /** Call GVMMR0SchedWakeUp(). */
+ VMMR0_DO_GVMM_SCHED_WAKE_UP,
+ /** Call GVMMR0SchedPoke(). */
+ VMMR0_DO_GVMM_SCHED_POKE,
+ /** Call GVMMR0SchedWakeUpAndPokeCpus(). */
+ VMMR0_DO_GVMM_SCHED_WAKE_UP_AND_POKE_CPUS,
+ /** Call GVMMR0SchedPoll(). */
+ VMMR0_DO_GVMM_SCHED_POLL,
+ /** Call GVMMR0QueryStatistics(). */
+ VMMR0_DO_GVMM_QUERY_STATISTICS,
+ /** Call GVMMR0ResetStatistics(). */
+ VMMR0_DO_GVMM_RESET_STATISTICS,
+ /** Call GVMMR0RegisterVCpu(). */
+ VMMR0_DO_GVMM_REGISTER_VMCPU,
+
+ /** Call VMMR0 Per VM Init. */
+ VMMR0_DO_VMMR0_INIT,
+ /** Call VMMR0 Per VM Termination. */
+ VMMR0_DO_VMMR0_TERM,
+ /** Setup the hardware accelerated raw-mode session. */
+ VMMR0_DO_HWACC_SETUP_VM,
+ /** Attempt to enable or disable hardware accelerated raw-mode. */
+ VMMR0_DO_HWACC_ENABLE,
+ /** Calls function in the hypervisor.
+ * The caller must setup the hypervisor context so the call will be performed.
+ * The difference between VMMR0_DO_RUN_GC and this one is the handling of
+ * the return GC code. The return code will not be interpreted by this operation.
+ */
+ VMMR0_DO_CALL_HYPERVISOR,
+
+ /** Call PGMR0PhysAllocateHandyPages(). */
+ VMMR0_DO_PGM_ALLOCATE_HANDY_PAGES,
+ /** Call PGMR0PhysFlushHandyPages(). */
+ VMMR0_DO_PGM_FLUSH_HANDY_PAGES,
+ /** Call PGMR0AllocateLargePage(). */
+ VMMR0_DO_PGM_ALLOCATE_LARGE_HANDY_PAGE,
+ /** Call PGMR0PhysSetupIommu(). */
+ VMMR0_DO_PGM_PHYS_SETUP_IOMMU,
+
+ /** Call GMMR0InitialReservation(). */
+ VMMR0_DO_GMM_INITIAL_RESERVATION,
+ /** Call GMMR0UpdateReservation(). */
+ VMMR0_DO_GMM_UPDATE_RESERVATION,
+ /** Call GMMR0AllocatePages(). */
+ VMMR0_DO_GMM_ALLOCATE_PAGES,
+ /** Call GMMR0FreePages(). */
+ VMMR0_DO_GMM_FREE_PAGES,
+ /** Call GMMR0FreeLargePage(). */
+ VMMR0_DO_GMM_FREE_LARGE_PAGE,
+ /** Call GMMR0QueryHypervisorMemoryStatsReq(). */
+ VMMR0_DO_GMM_QUERY_HYPERVISOR_MEM_STATS,
+ /** Call GMMR0QueryMemoryStatsReq(). */
+ VMMR0_DO_GMM_QUERY_MEM_STATS,
+ /** Call GMMR0BalloonedPages(). */
+ VMMR0_DO_GMM_BALLOONED_PAGES,
+ /** Call GMMR0MapUnmapChunk(). */
+ VMMR0_DO_GMM_MAP_UNMAP_CHUNK,
+ /** Call GMMR0SeedChunk(). */
+ VMMR0_DO_GMM_SEED_CHUNK,
+ /** Call GMMR0RegisterSharedModule. */
+ VMMR0_DO_GMM_REGISTER_SHARED_MODULE,
+ /** Call GMMR0UnregisterSharedModule. */
+ VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE,
+ /** Call GMMR0ResetSharedModules. */
+ VMMR0_DO_GMM_RESET_SHARED_MODULES,
+ /** Call GMMR0CheckSharedModules. */
+ VMMR0_DO_GMM_CHECK_SHARED_MODULES,
+ /** Call GMMR0FindDuplicatePage. */
+ VMMR0_DO_GMM_FIND_DUPLICATE_PAGE,
+ /** Call GMMR0QueryStatistics(). */
+ VMMR0_DO_GMM_QUERY_STATISTICS,
+ /** Call GMMR0ResetStatistics(). */
+ VMMR0_DO_GMM_RESET_STATISTICS,
+
+ /** Set a GVMM or GMM configuration value. */
+ VMMR0_DO_GCFGM_SET_VALUE,
+ /** Query a GVMM or GMM configuration value. */
+ VMMR0_DO_GCFGM_QUERY_VALUE,
+
+ /** Call PDMR0DriverCallReqHandler. */
+ VMMR0_DO_PDM_DRIVER_CALL_REQ_HANDLER,
+ /** Call PDMR0DeviceCallReqHandler. */
+ VMMR0_DO_PDM_DEVICE_CALL_REQ_HANDLER,
+
+ /** The start of the R0 service operations. */
+ VMMR0_DO_SRV_START,
+ /** Call IntNetR0Open(). */
+ VMMR0_DO_INTNET_OPEN,
+ /** Call IntNetR0IfClose(). */
+ VMMR0_DO_INTNET_IF_CLOSE,
+ /** Call IntNetR0IfGetBufferPtrs(). */
+ VMMR0_DO_INTNET_IF_GET_BUFFER_PTRS,
+ /** Call IntNetR0IfSetPromiscuousMode(). */
+ VMMR0_DO_INTNET_IF_SET_PROMISCUOUS_MODE,
+ /** Call IntNetR0IfSetMacAddress(). */
+ VMMR0_DO_INTNET_IF_SET_MAC_ADDRESS,
+ /** Call IntNetR0IfSetActive(). */
+ VMMR0_DO_INTNET_IF_SET_ACTIVE,
+ /** Call IntNetR0IfSend(). */
+ VMMR0_DO_INTNET_IF_SEND,
+ /** Call IntNetR0IfWait(). */
+ VMMR0_DO_INTNET_IF_WAIT,
+ /** Call IntNetR0IfAbortWait(). */
+ VMMR0_DO_INTNET_IF_ABORT_WAIT,
+
+ /** Forward call to the PCI driver */
+ VMMR0_DO_PCIRAW_REQ,
+
+ /** The end of the R0 service operations. */
+ VMMR0_DO_SRV_END,
+
+ /** Official call we use for testing Ring-0 APIs. */
+ VMMR0_DO_TESTS,
+ /** Test the 32->64 bits switcher. */
+ VMMR0_DO_TEST_SWITCHER3264,
+
+ /** The usual 32-bit type blow up. */
+ VMMR0_DO_32BIT_HACK = 0x7fffffff
+} VMMR0OPERATION;
+
+
+/**
+ * Request buffer for VMMR0_DO_GCFGM_SET_VALUE and VMMR0_DO_GCFGM_QUERY_VALUE.
+ * @todo Move got GCFGM.h when it's implemented.
+ */
+typedef struct GCFGMVALUEREQ
+{
+ /** The request header.*/
+ SUPVMMR0REQHDR Hdr;
+ /** The support driver session handle. */
+ PSUPDRVSESSION pSession;
+ /** The value.
+ * This is input for the set request and output for the query. */
+ uint64_t u64Value;
+ /** The variable name.
+ * This is fixed sized just to make things simple for the mock-up. */
+ char szName[48];
+} GCFGMVALUEREQ;
+/** Pointer to a VMMR0_DO_GCFGM_SET_VALUE and VMMR0_DO_GCFGM_QUERY_VALUE request buffer.
+ * @todo Move got GCFGM.h when it's implemented.
+ */
+typedef GCFGMVALUEREQ *PGCFGMVALUEREQ;
+
+VMMR0DECL(int) VMMR0EntryInt(PVM pVM, VMMR0OPERATION enmOperation, void *pvArg);
+VMMR0DECL(void) VMMR0EntryFast(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation);
+VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMCPUID idCpu, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg, PSUPDRVSESSION);
+VMMR0DECL(int) VMMR0TermVM(PVM pVM, PGVM pGVM);
+
+#ifdef LOG_ENABLED
+VMMR0DECL(void) VMMR0LogFlushDisable(PVMCPU pVCpu);
+VMMR0DECL(void) VMMR0LogFlushEnable(PVMCPU pVCpu);
+#else
+#define VMMR0LogFlushDisable(pVCpu) do { } while(0)
+#define VMMR0LogFlushEnable(pVCpu) do { } while(0)
+#endif
+
+/** @} */
+
+
+#ifdef IN_RC
+/** @defgroup grp_vmm_rc The VMM Raw-Mode Context API
+ * @ingroup grp_vmm
+ * @{
+ */
+VMMRCDECL(int) VMMGCEntry(PVM pVM, unsigned uOperation, unsigned uArg, ...);
+VMMRCDECL(void) VMMGCGuestToHost(PVM pVM, int rc);
+VMMRCDECL(void) VMMGCLogFlushIfFull(PVM pVM);
+/** @} */
+#endif /* IN_RC */
+
+#if defined(IN_RC) || defined(IN_RING0)
+/** @defgroup grp_vmm_rz The VMM Raw-Mode and Ring-0 Context API
+ * @ingroup grp_vmm
+ * @{
+ */
+VMMRZDECL(int) VMMRZCallRing3(PVM pVM, PVMCPU pVCpu, VMMCALLRING3 enmOperation, uint64_t uArg);
+VMMRZDECL(int) VMMRZCallRing3NoCpu(PVM pVM, VMMCALLRING3 enmOperation, uint64_t uArg);
+VMMRZDECL(void) VMMRZCallRing3Disable(PVMCPU pVCpu);
+VMMRZDECL(void) VMMRZCallRing3Enable(PVMCPU pVCpu);
+VMMRZDECL(bool) VMMRZCallRing3IsEnabled(PVMCPU pVCpu);
+/** @} */
+#endif
+
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/vrdpusb.h b/include/VBox/vrdpusb.h
new file mode 100644
index 00000000..92491500
--- /dev/null
+++ b/include/VBox/vrdpusb.h
@@ -0,0 +1,75 @@
+/** @file
+ * VBox Remote Desktop Protocol - Remote USB backend interface. (VRDP)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_vrdpusb_h
+#define ___VBox_vrdpusb_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+
+#ifdef IN_RING0
+# error "There are no VRDP APIs available in Ring-0 Host Context!"
+#endif
+#ifdef IN_RC
+# error "There are no VRDP APIs available Guest Context!"
+#endif
+
+#define REMOTE_USB_BACKEND_PREFIX_S "REMOTEUSB"
+#define REMOTE_USB_BACKEND_PREFIX_LEN 9
+
+/* Forward declaration. */
+struct _REMOTEUSBDEVICE;
+typedef struct _REMOTEUSBDEVICE *PREMOTEUSBDEVICE;
+
+/* Forward declaration. */
+struct _REMOTEUSBQURB;
+typedef struct _REMOTEUSBQURB *PREMOTEUSBQURB;
+
+/* Forward declaration. Actually a class. */
+struct _REMOTEUSBBACKEND;
+typedef struct _REMOTEUSBBACKEND *PREMOTEUSBBACKEND;
+
+/* Pointer to this structure is passed to pfnCreateProxyDevice
+ * as the device specific pointer, when creating remote devices.
+ */
+typedef struct _REMOTEUSBCALLBACK
+{
+ PREMOTEUSBBACKEND pInstance;
+
+ DECLCALLBACKMEMBER(int, pfnOpen) (PREMOTEUSBBACKEND pInstance, const char *pszAddress, size_t cbAddress, PREMOTEUSBDEVICE *ppDevice);
+ DECLCALLBACKMEMBER(void, pfnClose) (PREMOTEUSBDEVICE pDevice);
+ DECLCALLBACKMEMBER(int, pfnReset) (PREMOTEUSBDEVICE pDevice);
+ DECLCALLBACKMEMBER(int, pfnSetConfig) (PREMOTEUSBDEVICE pDevice, uint8_t u8Cfg);
+ DECLCALLBACKMEMBER(int, pfnClaimInterface) (PREMOTEUSBDEVICE pDevice, uint8_t u8Ifnum);
+ DECLCALLBACKMEMBER(int, pfnReleaseInterface) (PREMOTEUSBDEVICE pDevice, uint8_t u8Ifnum);
+ DECLCALLBACKMEMBER(int, pfnInterfaceSetting) (PREMOTEUSBDEVICE pDevice, uint8_t u8Ifnum, uint8_t u8Setting);
+ DECLCALLBACKMEMBER(int, pfnQueueURB) (PREMOTEUSBDEVICE pDevice, uint8_t u8Type, uint8_t u8Ep, uint8_t u8Direction, uint32_t u32Len, void *pvData, void *pvURB, PREMOTEUSBQURB *ppRemoteURB);
+ DECLCALLBACKMEMBER(int, pfnReapURB) (PREMOTEUSBDEVICE pDevice, uint32_t u32Millies, void **ppvURB, uint32_t *pu32Len, uint32_t *pu32Err);
+ DECLCALLBACKMEMBER(int, pfnClearHaltedEP) (PREMOTEUSBDEVICE pDevice, uint8_t u8Ep);
+ DECLCALLBACKMEMBER(void, pfnCancelURB) (PREMOTEUSBDEVICE pDevice, PREMOTEUSBQURB pRemoteURB);
+} REMOTEUSBCALLBACK;
+
+#endif
+
diff --git a/include/VBox/vscsi.h b/include/VBox/vscsi.h
new file mode 100644
index 00000000..217ce885
--- /dev/null
+++ b/include/VBox/vscsi.h
@@ -0,0 +1,323 @@
+/* $Id: vscsi.h $ */
+/** @file
+ * VBox storage drivers: Virtual SCSI driver
+ */
+
+/*
+ * Copyright (C) 2006-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___VBox_vscsi_h
+#define ___VBox_vscsi_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+#include <iprt/sg.h>
+
+RT_C_DECLS_BEGIN
+
+#ifdef IN_RING0
+# error "There are no VBox VSCSI APIs available in Ring-0 Host Context!"
+#endif
+
+/** A virtual SCSI device handle */
+typedef struct VSCSIDEVICEINT *VSCSIDEVICE;
+/** A pointer to a virtual SCSI device handle. */
+typedef VSCSIDEVICE *PVSCSIDEVICE;
+/** A virtual SCSI LUN handle. */
+typedef struct VSCSILUNINT *VSCSILUN;
+/** A pointer to a virtual SCSI LUN handle. */
+typedef VSCSILUN *PVSCSILUN;
+/** A virtual SCSI request handle. */
+typedef struct VSCSIREQINT *VSCSIREQ;
+/** A pointer to a virtual SCSI request handle. */
+typedef VSCSIREQ *PVSCSIREQ;
+/** A SCSI I/O request handle. */
+typedef struct VSCSIIOREQINT *VSCSIIOREQ;
+/** A pointer to a SCSI I/O request handle. */
+typedef VSCSIIOREQ *PVSCSIIOREQ;
+
+/**
+ * Virtual SCSI I/O request transfer direction.
+ */
+typedef enum VSCSIIOREQTXDIR
+{
+ /** Invalid direction */
+ VSCSIIOREQTXDIR_INVALID = 0,
+ /** Read */
+ VSCSIIOREQTXDIR_READ,
+ /** Write */
+ VSCSIIOREQTXDIR_WRITE,
+ /** Flush */
+ VSCSIIOREQTXDIR_FLUSH,
+ /** Unmap */
+ VSCSIIOREQTXDIR_UNMAP,
+ /** 32bit hack */
+ VSCSIIOREQTXDIR_32BIT_HACK = 0x7fffffff
+} VSCSIIOREQTXDIR;
+/** Pointer to a SCSI LUN type */
+typedef VSCSIIOREQTXDIR *PVSCSIIOREQTXDIR;
+
+/**
+ * LUN types we support
+ */
+typedef enum VSCSILUNTYPE
+{
+ /** Invalid type */
+ VSCSILUNTYPE_INVALID = 0,
+ /** Hard disk (SBC) */
+ VSCSILUNTYPE_SBC,
+ /** CD/DVD drive (MMC) */
+ VSCSILUNTYPE_MMC,
+ /** Last value to indicate an invalid device */
+ VSCSILUNTYPE_LAST,
+ /** 32bit hack */
+ VSCSILUNTYPE_32BIT_HACK = 0x7fffffff
+} VSCSILUNTYPE;
+/** Pointer to a SCSI LUN type */
+typedef VSCSILUNTYPE *PVSCSILUNTYPE;
+
+/** The LUN can handle the UNMAP command. */
+#define VSCSI_LUN_FEATURE_UNMAP RT_BIT(0)
+/** The LUN has a non rotational medium. */
+#define VSCSI_LUN_FEATURE_NON_ROTATIONAL RT_BIT(1)
+/** The medium of the LUN is readonly. */
+#define VSCSI_LUN_FEATURE_READONLY RT_BIT(2)
+
+/**
+ * Virtual SCSI LUN I/O Callback table.
+ */
+typedef struct VSCSILUNIOCALLBACKS
+{
+ /**
+ * Retrieve the size of the underlying medium.
+ *
+ * @returns VBox status status code.
+ * @param hVScsiLun Virtual SCSI LUN handle.
+ * @param pvScsiLunUser Opaque user data which may
+ * be used to identify the medium.
+ * @param pcbSize Where to store the size of the
+ * medium.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVScsiLunMediumGetSize, (VSCSILUN hVScsiLun,
+ void *pvScsiLunUser,
+ uint64_t *pcbSize));
+
+ /**
+ * Enqueue a read or write request from the medium.
+ *
+ * @returns VBox status status code.
+ * @param hVScsiLun Virtual SCSI LUN handle.
+ * @param pvScsiLunUser Opaque user data which may
+ * be used to identify the medium.
+ * @param hVScsiIoReq Virtual SCSI I/O request handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVScsiLunReqTransferEnqueue, (VSCSILUN hVScsiLun,
+ void *pvScsiLunUser,
+ VSCSIIOREQ hVScsiIoReq));
+
+ /**
+ * Returns flags of supported features.
+ *
+ * @returns VBox status status code.
+ * @param hVScsiLun Virtual SCSI LUN handle.
+ * @param pvScsiLunUser Opaque user data which may
+ * be used to identify the medium.
+ * @param hVScsiIoReq Virtual SCSI I/O request handle.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnVScsiLunGetFeatureFlags, (VSCSILUN hVScsiLun,
+ void *pvScsiLunUser,
+ uint64_t *pfFeatures));
+
+
+} VSCSILUNIOCALLBACKS;
+/** Pointer to a virtual SCSI LUN I/O callback table. */
+typedef VSCSILUNIOCALLBACKS *PVSCSILUNIOCALLBACKS;
+
+/**
+ * The virtual SCSI request completed callback.
+ */
+typedef DECLCALLBACK(void) FNVSCSIREQCOMPLETED(VSCSIDEVICE hVScsiDevice,
+ void *pvVScsiDeviceUser,
+ void *pvVScsiReqUser,
+ int rcScsiCode,
+ bool fRedoPossible,
+ int rcReq);
+/** Pointer to a virtual SCSI request completed callback. */
+typedef FNVSCSIREQCOMPLETED *PFNVSCSIREQCOMPLETED;
+
+/**
+ * Create a new empty SCSI device instance.
+ *
+ * @returns VBox status code.
+ * @param phVScsiDevice Where to store the SCSI device handle.
+ * @param pfnVScsiReqCompleted The method call after a request completed.
+ * @param pvVScsiDeviceUser Opaque user data given in the completion callback.
+ */
+VBOXDDU_DECL(int) VSCSIDeviceCreate(PVSCSIDEVICE phVScsiDevice,
+ PFNVSCSIREQCOMPLETED pfnVScsiReqCompleted,
+ void *pvVScsiDeviceUser);
+
+/**
+ * Destroy a SCSI device instance.
+ *
+ * @returns VBox status code.
+ * @param hScsiDevice The SCSI device handle to destroy.
+ */
+VBOXDDU_DECL(int) VSCSIDeviceDestroy(VSCSIDEVICE hVScsiDevice);
+
+/**
+ * Attach a LUN to the SCSI device.
+ *
+ * @returns VBox status code.
+ * @param hScsiDevice The SCSI device handle to add the LUN to.
+ * @param hScsiLun The LUN handle to add.
+ * @param iLun The LUN number.
+ */
+VBOXDDU_DECL(int) VSCSIDeviceLunAttach(VSCSIDEVICE hVScsiDevice, VSCSILUN hVScsiLun, uint32_t iLun);
+
+/**
+ * Detach a LUN from the SCSI device.
+ *
+ * @returns VBox status code.
+ * @param hVScsiDevice The SCSI device handle to add the LUN to.
+ * @param iLun The LUN number to remove.
+ * @param phVScsiLun Where to store the detached LUN handle.
+ */
+VBOXDDU_DECL(int) VSCSIDeviceLunDetach(VSCSIDEVICE hVScsiDevice, uint32_t iLun,
+ PVSCSILUN phVScsiLun);
+
+/**
+ * Return the SCSI LUN handle.
+ *
+ * @returns VBox status code.
+ * @param hVScsiDevice The SCSI device handle.
+ * @param iLun The LUN number to get.
+ * @param phVScsiLun Where to store the LUN handle.
+ */
+VBOXDDU_DECL(int) VSCSIDeviceLunGet(VSCSIDEVICE hVScsiDevice, uint32_t iLun,
+ PVSCSILUN phVScsiLun);
+
+/**
+ * Enqueue a request to the SCSI device.
+ *
+ * @returns VBox status code.
+ * @param hVScsiDevice The SCSI device handle.
+ * @param hVScsiReq The SCSI request handle to enqueue.
+ */
+VBOXDDU_DECL(int) VSCSIDeviceReqEnqueue(VSCSIDEVICE hVScsiDevice, VSCSIREQ hVScsiReq);
+
+/**
+ * Allocate a new request handle.
+ *
+ * @returns VBox status code.
+ * @param phVScsiDevice The SCSI device handle.
+ * @param phVScsiReq Where to SCSI request handle.
+ * @param iLun The LUN the request is for.
+ * @param pbCDB The CDB for the request.
+ * @param cbCDB The size of the CDB in bytes.
+ * @param cbSGList Number of bytes the S/G list describes.
+ * @param cSGListEntries Number of S/G list entries.
+ * @param paSGList Pointer to the S/G list.
+ * @param pbSense Pointer to the sense buffer.
+ * @param cbSense Size of the sense buffer.
+ * @param pvVScsiReqUser Opqaue user data returned when the request completes.
+ */
+VBOXDDU_DECL(int) VSCSIDeviceReqCreate(VSCSIDEVICE hVScsiDevice, PVSCSIREQ phVScsiReq,
+ uint32_t iLun, uint8_t *pbCDB, size_t cbCDB,
+ size_t cbSGList, unsigned cSGListEntries,
+ PCRTSGSEG paSGList, uint8_t *pbSense,
+ size_t cbSense, void *pvVScsiReqUser);
+
+/**
+ * Create a new LUN.
+ *
+ * @returns VBox status code.
+ * @param phVScsiLun Where to store the SCSI LUN handle.
+ * @param enmLunType The Lun type.
+ * @param pVScsiLunIoCallbacks Pointer to the I/O callbacks to use for his LUN.
+ * @param pvVScsiLunUser Opaque user argument which
+ * is returned in the pvScsiLunUser parameter
+ * when the request completion callback is called.
+ */
+VBOXDDU_DECL(int) VSCSILunCreate(PVSCSILUN phVScsiLun, VSCSILUNTYPE enmLunType,
+ PVSCSILUNIOCALLBACKS pVScsiLunIoCallbacks,
+ void *pvVScsiLunUser);
+
+/**
+ * Destroy virtual SCSI LUN.
+ *
+ * @returns VBox status code.
+ * @param hVScsiLun The virtual SCSI LUN handle to destroy.
+ */
+VBOXDDU_DECL(int) VSCSILunDestroy(VSCSILUN hVScsiLun);
+
+/**
+ * Notify a that a I/O request completed.
+ *
+ * @returns VBox status code.
+ * @param hVScsiIoReq The I/O request handle that completed.
+ * This is given when a I/O callback for
+ * the LUN is called by the virtual SCSI layer.
+ * @param rcIoReq The status code the I/O request completed with.
+ * @param fRedoPossible Flag whether it is possible to redo the request.
+ * If true setting any sense code will be omitted
+ * in case of an error to not alter the device state.
+ */
+VBOXDDU_DECL(int) VSCSIIoReqCompleted(VSCSIIOREQ hVScsiIoReq, int rcIoReq, bool fRedoPossible);
+
+/**
+ * Query the transfer direction of the I/O request.
+ *
+ * @returns Transfer direction.of the given I/O request
+ * @param hVScsiIoReq The SCSI I/O request handle.
+ */
+VBOXDDU_DECL(VSCSIIOREQTXDIR) VSCSIIoReqTxDirGet(VSCSIIOREQ hVScsiIoReq);
+
+/**
+ * Query I/O parameters.
+ *
+ * @returns VBox status code.
+ * @param hVScsiIoReq The SCSI I/O request handle.
+ * @param puOffset Where to store the start offset.
+ * @param pcbTransfer Where to store the amount of bytes to transfer.
+ * @param pcSeg Where to store the number of segments in the S/G list.
+ * @param pcbSeg Where to store the number of bytes the S/G list describes.
+ * @param ppaSeg Where to store the pointer to the S/G list.
+ */
+VBOXDDU_DECL(int) VSCSIIoReqParamsGet(VSCSIIOREQ hVScsiIoReq, uint64_t *puOffset,
+ size_t *pcbTransfer, unsigned *pcSeg,
+ size_t *pcbSeg, PCRTSGSEG *ppaSeg);
+
+/**
+ * Query unmap parameters.
+ *
+ * @returns VBox status code.
+ * @param hVScsiIoReq The SCSI I/O request handle.
+ * @param ppaRanges Where to store the pointer to the range array on success.
+ * @param pcRanges Where to store the number of ranges on success.
+ */
+VBOXDDU_DECL(int) VSCSIIoReqUnmapParamsGet(VSCSIIOREQ hVScsiIoReq, PCRTRANGE *ppaRanges,
+ unsigned *pcRanges);
+
+RT_C_DECLS_END
+
+#endif /* ___VBox_vscsi_h */
+
diff --git a/include/VBox/vusb.h b/include/VBox/vusb.h
new file mode 100644
index 00000000..3a2d9b8f
--- /dev/null
+++ b/include/VBox/vusb.h
@@ -0,0 +1,1077 @@
+/** @file
+ * VUSB - VirtualBox USB. (DEV,VMM)
+ */
+
+/*
+ * Copyright (C) 2006-2007 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * 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 ___VBox_vusb_h
+#define ___VBox_vusb_h
+
+#include <VBox/cdefs.h>
+#include <VBox/types.h>
+
+struct PDMLED;
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_vusb VBox USB API
+ * @{
+ */
+
+/** @defgroup grp_vusb_std Standard Stuff
+ * @{ */
+
+/** Frequency of USB bus (from spec). */
+#define VUSB_BUS_HZ 12000000
+
+
+/** @name USB Descriptor types (from spec)
+ * @{ */
+#define VUSB_DT_DEVICE 0x01
+#define VUSB_DT_CONFIG 0x02
+#define VUSB_DT_STRING 0x03
+#define VUSB_DT_INTERFACE 0x04
+#define VUSB_DT_ENDPOINT 0x05
+#define VUSB_DT_DEVICE_QUALIFIER 0x06
+#define VUSB_DT_OTHER_SPEED_CFG 0x07
+#define VUSB_DT_INTERFACE_POWER 0x08
+/** @} */
+
+/** @name USB Descriptor minimum sizes (from spec)
+ * @{ */
+#define VUSB_DT_DEVICE_MIN_LEN 18
+#define VUSB_DT_CONFIG_MIN_LEN 9
+#define VUSB_DT_CONFIG_STRING_MIN_LEN 2
+#define VUSB_DT_INTERFACE_MIN_LEN 9
+#define VUSB_DT_ENDPOINT_MIN_LEN 7
+/** @} */
+
+
+#pragma pack(1) /* ensure byte packing of the descriptors. */
+
+/**
+ * USB language id descriptor (from specs).
+ */
+typedef struct VUSBDESCLANGID
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+} VUSBDESCLANGID;
+/** Pointer to a USB language id descriptor. */
+typedef VUSBDESCLANGID *PVUSBDESCLANGID;
+/** Pointer to a const USB language id descriptor. */
+typedef const VUSBDESCLANGID *PCVUSBDESCLANGID;
+
+
+/**
+ * USB string descriptor (from specs).
+ */
+typedef struct VUSBDESCSTRING
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+} VUSBDESCSTRING;
+/** Pointer to a USB string descriptor. */
+typedef VUSBDESCSTRING *PVUSBDESCSTRING;
+/** Pointer to a const USB string descriptor. */
+typedef const VUSBDESCSTRING *PCVUSBDESCSTRING;
+
+
+/**
+ * USB device descriptor (from spec)
+ */
+typedef struct VUSBDESCDEVICE
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} VUSBDESCDEVICE;
+/** Pointer to a USB device descriptor. */
+typedef VUSBDESCDEVICE *PVUSBDESCDEVICE;
+/** Pointer to a const USB device descriptor. */
+typedef const VUSBDESCDEVICE *PCVUSBDESCDEVICE;
+
+/**
+ * USB device qualifier (from spec 9.6.2)
+ */
+struct VUSBDEVICEQUALIFIER
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUsb;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+};
+
+typedef struct VUSBDEVICEQUALIFIER VUSBDEVICEQUALIFIER;
+typedef VUSBDEVICEQUALIFIER *PVUSBDEVICEQUALIFIER;
+
+
+/**
+ * USB configuration descriptor (from spec).
+ */
+typedef struct VUSBDESCCONFIG
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength; /**< recalculated by VUSB when involved in URB. */
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t MaxPower;
+} VUSBDESCCONFIG;
+/** Pointer to a USB configuration descriptor. */
+typedef VUSBDESCCONFIG *PVUSBDESCCONFIG;
+/** Pointer to a readonly USB configuration descriptor. */
+typedef const VUSBDESCCONFIG *PCVUSBDESCCONFIG;
+
+
+/**
+ * USB interface descriptor (from spec)
+ */
+typedef struct VUSBDESCINTERFACE
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} VUSBDESCINTERFACE;
+/** Pointer to an USB interface descriptor. */
+typedef VUSBDESCINTERFACE *PVUSBDESCINTERFACE;
+/** Pointer to a const USB interface descriptor. */
+typedef const VUSBDESCINTERFACE *PCVUSBDESCINTERFACE;
+
+
+/**
+ * USB endpoint descriptor (from spec)
+ */
+typedef struct VUSBDESCENDPOINT
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} VUSBDESCENDPOINT;
+/** Pointer to an USB endpoint descriptor. */
+typedef VUSBDESCENDPOINT *PVUSBDESCENDPOINT;
+/** Pointer to a const USB endpoint descriptor. */
+typedef const VUSBDESCENDPOINT *PCVUSBDESCENDPOINT;
+
+#pragma pack() /* end of the byte packing. */
+
+
+/**
+ * USB configuration descriptor, the parsed variant used by VUSB.
+ */
+typedef struct VUSBDESCCONFIGEX
+{
+ /** The USB descriptor data.
+ * @remark The wTotalLength member is recalculated before the data is passed to the guest. */
+ VUSBDESCCONFIG Core;
+ /** Pointer to additional descriptor bytes following what's covered by VUSBDESCCONFIG. */
+ void *pvMore;
+ /** Pointer to an array of the interfaces referenced in the configuration.
+ * Core.bNumInterfaces in size. */
+ const struct VUSBINTERFACE *paIfs;
+ /** Pointer to the original descriptor data read from the device. */
+ const void *pvOriginal;
+} VUSBDESCCONFIGEX;
+/** Pointer to a parsed USB configuration descriptor. */
+typedef VUSBDESCCONFIGEX *PVUSBDESCCONFIGEX;
+/** Pointer to a const parsed USB configuration descriptor. */
+typedef const VUSBDESCCONFIGEX *PCVUSBDESCCONFIGEX;
+
+
+/**
+ * For tracking the alternate interface settings of a configuration.
+ */
+typedef struct VUSBINTERFACE
+{
+ /** Pointer to an array of interfaces. */
+ const struct VUSBDESCINTERFACEEX *paSettings;
+ /** The number of entries in the array. */
+ uint32_t cSettings;
+} VUSBINTERFACE;
+/** Pointer to a VUSBINTERFACE. */
+typedef VUSBINTERFACE *PVUSBINTERFACE;
+/** Pointer to a const VUSBINTERFACE. */
+typedef const VUSBINTERFACE *PCVUSBINTERFACE;
+
+
+/**
+ * USB interface descriptor, the parsed variant used by VUSB.
+ */
+typedef struct VUSBDESCINTERFACEEX
+{
+ /** The USB descriptor data. */
+ VUSBDESCINTERFACE Core;
+ /** Pointer to additional descriptor bytes following what's covered by VUSBDESCINTERFACE. */
+ const void *pvMore;
+ /** Pointer to additional class- or vendor-specific interface descriptors. */
+ const void *pvClass;
+ /** Size of class- or vendor-specific descriptors. */
+ uint16_t cbClass;
+ /** Pointer to an array of the endpoints referenced by the interface.
+ * Core.bNumEndpoints in size. */
+ const struct VUSBDESCENDPOINTEX *paEndpoints;
+} VUSBDESCINTERFACEEX;
+/** Pointer to an prased USB interface descriptor. */
+typedef VUSBDESCINTERFACEEX *PVUSBDESCINTERFACEEX;
+/** Pointer to a const parsed USB interface descriptor. */
+typedef const VUSBDESCINTERFACEEX *PCVUSBDESCINTERFACEEX;
+
+
+/**
+ * USB endpoint descriptor, the parsed variant used by VUSB.
+ */
+typedef struct VUSBDESCENDPOINTEX
+{
+ /** The USB descriptor data.
+ * @remark The wMaxPacketSize member is converted to native endian. */
+ VUSBDESCENDPOINT Core;
+ /** Pointer to additional descriptor bytes following what's covered by VUSBDESCENDPOINT. */
+ const void *pvMore;
+ /** Pointer to additional class- or vendor-specific interface descriptors. */
+ const void *pvClass;
+ /** Size of class- or vendor-specific descriptors. */
+ uint16_t cbClass;
+} VUSBDESCENDPOINTEX;
+/** Pointer to a parsed USB endpoint descriptor. */
+typedef VUSBDESCENDPOINTEX *PVUSBDESCENDPOINTEX;
+/** Pointer to a const parsed USB endpoint descriptor. */
+typedef const VUSBDESCENDPOINTEX *PCVUSBDESCENDPOINTEX;
+
+
+/** @name USB Control message recipient codes (from spec)
+ * @{ */
+#define VUSB_TO_DEVICE 0x0
+#define VUSB_TO_INTERFACE 0x1
+#define VUSB_TO_ENDPOINT 0x2
+#define VUSB_TO_OTHER 0x3
+#define VUSB_RECIP_MASK 0x1f
+/** @} */
+
+/** @name USB control pipe setup packet structure (from spec)
+ * @{ */
+#define VUSB_REQ_SHIFT (5)
+#define VUSB_REQ_STANDARD (0x0 << VUSB_REQ_SHIFT)
+#define VUSB_REQ_CLASS (0x1 << VUSB_REQ_SHIFT)
+#define VUSB_REQ_VENDOR (0x2 << VUSB_REQ_SHIFT)
+#define VUSB_REQ_RESERVED (0x3 << VUSB_REQ_SHIFT)
+#define VUSB_REQ_MASK (0x3 << VUSB_REQ_SHIFT)
+/** @} */
+
+#define VUSB_DIR_TO_DEVICE 0x00
+#define VUSB_DIR_TO_HOST 0x80
+#define VUSB_DIR_MASK 0x80
+
+/**
+ * USB Setup request (from spec)
+ */
+typedef struct vusb_setup
+{
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} VUSBSETUP;
+/** Pointer to a setup request. */
+typedef VUSBSETUP *PVUSBSETUP;
+/** Pointer to a const setup request. */
+typedef const VUSBSETUP *PCVUSBSETUP;
+
+/** @name USB Standard device requests (from spec)
+ * @{ */
+#define VUSB_REQ_GET_STATUS 0x00
+#define VUSB_REQ_CLEAR_FEATURE 0x01
+#define VUSB_REQ_SET_FEATURE 0x03
+#define VUSB_REQ_SET_ADDRESS 0x05
+#define VUSB_REQ_GET_DESCRIPTOR 0x06
+#define VUSB_REQ_SET_DESCRIPTOR 0x07
+#define VUSB_REQ_GET_CONFIGURATION 0x08
+#define VUSB_REQ_SET_CONFIGURATION 0x09
+#define VUSB_REQ_GET_INTERFACE 0x0a
+#define VUSB_REQ_SET_INTERFACE 0x0b
+#define VUSB_REQ_SYNCH_FRAME 0x0c
+#define VUSB_REQ_MAX 0x0d
+/** @} */
+
+/** @} */ /* end of grp_vusb_std */
+
+
+
+/** @name USB Standard version flags.
+ * @{ */
+/** Indicates USB 1.1 support. */
+#define VUSB_STDVER_11 RT_BIT(1)
+/** Indicates USB 2.0 support. */
+#define VUSB_STDVER_20 RT_BIT(2)
+/** @} */
+
+
+/** Pointer to a VBox USB device interface. */
+typedef struct VUSBIDEVICE *PVUSBIDEVICE;
+
+/** Pointer to a VUSB RootHub port interface. */
+typedef struct VUSBIROOTHUBPORT *PVUSBIROOTHUBPORT;
+
+/** Pointer to an USB request descriptor. */
+typedef struct VUSBURB *PVUSBURB;
+
+
+
+/**
+ * VBox USB port bitmap.
+ *
+ * Bit 0 == Port 0, ... , Bit 127 == Port 127.
+ */
+typedef struct VUSBPORTBITMAP
+{
+ /** 128 bits */
+ char ach[16];
+} VUSBPORTBITMAP;
+/** Pointer to a VBox USB port bitmap. */
+typedef VUSBPORTBITMAP *PVUSBPORTBITMAP;
+
+#ifndef RDESKTOP
+
+/**
+ * The VUSB RootHub port interface provided by the HCI (down).
+ * Pair with VUSBIROOTCONNECTOR
+ */
+typedef struct VUSBIROOTHUBPORT
+{
+ /**
+ * Get the number of available ports in the hub.
+ *
+ * @returns The number of ports available.
+ * @param pInterface Pointer to this structure.
+ * @param pAvailable Bitmap indicating the available ports. Set bit == available port.
+ */
+ DECLR3CALLBACKMEMBER(unsigned, pfnGetAvailablePorts,(PVUSBIROOTHUBPORT pInterface, PVUSBPORTBITMAP pAvailable));
+
+ /**
+ * Gets the supported USB versions.
+ *
+ * @returns The mask of supported USB versions.
+ * @param pInterface Pointer to this structure.
+ */
+ DECLR3CALLBACKMEMBER(uint32_t, pfnGetUSBVersions,(PVUSBIROOTHUBPORT pInterface));
+
+ /**
+ * A device is being attached to a port in the roothub.
+ *
+ * @param pInterface Pointer to this structure.
+ * @param pDev Pointer to the device being attached.
+ * @param uPort The port number assigned to the device.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAttach,(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVICE pDev, unsigned uPort));
+
+ /**
+ * A device is being detached from a port in the roothub.
+ *
+ * @param pInterface Pointer to this structure.
+ * @param pDev Pointer to the device being detached.
+ * @param uPort The port number assigned to the device.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnDetach,(PVUSBIROOTHUBPORT pInterface, PVUSBIDEVICE pDev, unsigned uPort));
+
+ /**
+ * Reset the root hub.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this structure.
+ * @param pResetOnLinux Whether or not to do real reset on linux.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReset,(PVUSBIROOTHUBPORT pInterface, bool fResetOnLinux));
+
+ /**
+ * Transfer completion callback routine.
+ *
+ * VUSB will call this when a transfer have been completed
+ * in a one or another way.
+ *
+ * @param pInterface Pointer to this structure.
+ * @param pUrb Pointer to the URB in question.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnXferCompletion,(PVUSBIROOTHUBPORT pInterface, PVUSBURB urb));
+
+ /**
+ * Handle transfer errors.
+ *
+ * VUSB calls this when a transfer attempt failed. This function will respond
+ * indicating whether to retry or complete the URB with failure.
+ *
+ * @returns Retry indicator.
+ * @param pInterface Pointer to this structure.
+ * @param pUrb Pointer to the URB in question.
+ */
+ DECLR3CALLBACKMEMBER(bool, pfnXferError,(PVUSBIROOTHUBPORT pInterface, PVUSBURB pUrb));
+
+ /** Alignment dummy. */
+ RTR3PTR Alignment;
+
+} VUSBIROOTHUBPORT;
+/** VUSBIROOTHUBPORT interface ID. */
+#define VUSBIROOTHUBPORT_IID "e38e2978-7aa2-4860-94b6-9ef4a066d8a0"
+
+
+/** Pointer to a VUSB RootHub connector interface. */
+typedef struct VUSBIROOTHUBCONNECTOR *PVUSBIROOTHUBCONNECTOR;
+/**
+ * The VUSB RootHub connector interface provided by the VBox USB RootHub driver
+ * (up).
+ * Pair with VUSBIROOTHUBPORT.
+ */
+typedef struct VUSBIROOTHUBCONNECTOR
+{
+ /**
+ * Allocates a new URB for a transfer.
+ *
+ * Either submit using pfnSubmitUrb or free using VUSBUrbFree().
+ *
+ * @returns Pointer to a new URB.
+ * @returns NULL on failure - try again later.
+ * This will not fail if the device wasn't found. We'll fail it
+ * at submit time, since that makes the usage of this api simpler.
+ * @param pInterface Pointer to this struct.
+ * @param DstAddress The destination address of the URB.
+ * @param cbData The amount of data space required.
+ * @param cTds The amount of TD space.
+ */
+ DECLR3CALLBACKMEMBER(PVUSBURB, pfnNewUrb,(PVUSBIROOTHUBCONNECTOR pInterface, uint8_t DstAddress, uint32_t cbData, uint32_t cTds));
+
+ /**
+ * Submits a URB for transfer.
+ * The transfer will do asynchronously if possible.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this struct.
+ * @param pUrb Pointer to the URB returned by pfnNewUrb.
+ * The URB will be freed in case of failure.
+ * @param pLed Pointer to USB Status LED
+ */
+ DECLR3CALLBACKMEMBER(int, pfnSubmitUrb,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb, struct PDMLED *pLed));
+
+ /**
+ * Call to service asynchronous URB completions in a polling fashion.
+ *
+ * Reaped URBs will be finished by calling the completion callback,
+ * thus there is no return code or input or anything from this function
+ * except for potential state changes elsewhere.
+ *
+ * @returns VINF_SUCCESS if no URBs are pending upon return.
+ * @returns VERR_TIMEOUT if one or more URBs are still in flight upon returning.
+ * @returns Other VBox status code.
+ *
+ * @param pInterface Pointer to this struct.
+ * @param cMillies Number of milliseconds to poll for completion.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnReapAsyncUrbs,(PVUSBIROOTHUBCONNECTOR pInterface, RTMSINTERVAL cMillies));
+
+ /**
+ * Cancels and completes - with CRC failure - all URBs queued on an endpoint.
+ * This is done in response to guest URB cancellation.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this struct.
+ * @param pUrb Pointer to a previously submitted URB.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCancelUrbsEp,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb));
+
+ /**
+ * Cancels and completes - with CRC failure - all in-flight async URBs.
+ * This is typically done before saving a state.
+ *
+ * @param pInterface Pointer to this struct.
+ */
+ DECLR3CALLBACKMEMBER(void, pfnCancelAllUrbs,(PVUSBIROOTHUBCONNECTOR pInterface));
+
+ /**
+ * Attach the device to the root hub.
+ * The device must not be attached to any hub for this call to succeed.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this struct.
+ * @param pDevice Pointer to the device (interface) attach.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnAttachDevice,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice));
+
+ /**
+ * Detach the device from the root hub.
+ * The device must already be attached for this call to succeed.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this struct.
+ * @param pDevice Pointer to the device (interface) to detach.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDetachDevice,(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice));
+
+} VUSBIROOTHUBCONNECTOR;
+/** VUSBIROOTHUBCONNECTOR interface ID. */
+#define VUSBIROOTHUBCONNECTOR_IID "d9a90c59-e3ff-4dff-9754-844557c3f7a0"
+
+
+#ifdef IN_RING3
+/** @copydoc VUSBIROOTHUBCONNECTOR::pfnNewUrb */
+DECLINLINE(PVUSBURB) VUSBIRhNewUrb(PVUSBIROOTHUBCONNECTOR pInterface, uint32_t DstAddress, uint32_t cbData, uint32_t cTds)
+{
+ return pInterface->pfnNewUrb(pInterface, DstAddress, cbData, cTds);
+}
+
+/** @copydoc VUSBIROOTHUBCONNECTOR::pfnSubmitUrb */
+DECLINLINE(int) VUSBIRhSubmitUrb(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBURB pUrb, struct PDMLED *pLed)
+{
+ return pInterface->pfnSubmitUrb(pInterface, pUrb, pLed);
+}
+
+/** @copydoc VUSBIROOTHUBCONNECTOR::pfnReapAsyncUrbs */
+DECLINLINE(void) VUSBIRhReapAsyncUrbs(PVUSBIROOTHUBCONNECTOR pInterface, RTMSINTERVAL cMillies)
+{
+ pInterface->pfnReapAsyncUrbs(pInterface, cMillies);
+}
+
+/** @copydoc VUSBIROOTHUBCONNECTOR::pfnCancelAllUrbs */
+DECLINLINE(void) VUSBIRhCancelAllUrbs(PVUSBIROOTHUBCONNECTOR pInterface)
+{
+ pInterface->pfnCancelAllUrbs(pInterface);
+}
+
+/** @copydoc VUSBIROOTHUBCONNECTOR::pfnAttachDevice */
+DECLINLINE(int) VUSBIRhAttachDevice(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice)
+{
+ return pInterface->pfnAttachDevice(pInterface, pDevice);
+}
+
+/** @copydoc VUSBIROOTHUBCONNECTOR::pfnDetachDevice */
+DECLINLINE(int) VUSBIRhDetachDevice(PVUSBIROOTHUBCONNECTOR pInterface, PVUSBIDEVICE pDevice)
+{
+ return pInterface->pfnDetachDevice(pInterface, pDevice);
+}
+#endif /* IN_RING3 */
+
+
+
+/** Pointer to a Root Hub Configuration Interface. */
+typedef struct VUSBIRHCONFIG *PVUSBIRHCONFIG;
+/**
+ * Root Hub Configuration Interface (intended for MAIN).
+ * No interface pair.
+ */
+typedef struct VUSBIRHCONFIG
+{
+ /**
+ * Creates a USB proxy device and attaches it to the root hub.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the root hub configuration interface structure.
+ * @param pUuid Pointer to the UUID for the new device.
+ * @param fRemote Whether the device must use the VRDP backend.
+ * @param pszAddress OS specific device address.
+ * @param pvBackend An opaque pointer for the backend. Only used by
+ * the VRDP backend so far.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnCreateProxyDevice,(PVUSBIRHCONFIG pInterface, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend));
+
+ /**
+ * Removes a USB proxy device from the root hub and destroys it.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the root hub configuration interface structure.
+ * @param pUuid Pointer to the UUID for the device.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnDestroyProxyDevice,(PVUSBIRHCONFIG pInterface, PCRTUUID pUuid));
+
+} VUSBIRHCONFIG;
+/** VUSBIRHCONFIG interface ID. */
+#define VUSBIRHCONFIG_IID "c354cd97-e85f-465e-bc12-b58798465f52"
+
+
+#ifdef IN_RING3
+/** @copydoc VUSBIRHCONFIG::pfnCreateProxyDevice */
+DECLINLINE(int) VUSBIRhCreateProxyDevice(PVUSBIRHCONFIG pInterface, PCRTUUID pUuid, bool fRemote, const char *pszAddress, void *pvBackend)
+{
+ return pInterface->pfnCreateProxyDevice(pInterface, pUuid, fRemote, pszAddress, pvBackend);
+}
+
+/** @copydoc VUSBIRHCONFIG::pfnDestroyProxyDevice */
+DECLINLINE(int) VUSBIRhDestroyProxyDevice(PVUSBIRHCONFIG pInterface, PCRTUUID pUuid)
+{
+ return pInterface->pfnDestroyProxyDevice(pInterface, pUuid);
+}
+#endif /* IN_RING3 */
+
+#endif /* ! RDESKTOP */
+
+
+/**
+ * VUSB device reset completion callback function.
+ * This is called by the reset thread when the reset has been completed.
+ *
+ * @param pDev Pointer to the virtual USB device core.
+ * @param rc The VBox status code of the reset operation.
+ * @param pvUser User specific argument.
+ *
+ * @thread The reset thread or EMT.
+ */
+typedef DECLCALLBACK(void) FNVUSBRESETDONE(PVUSBIDEVICE pDevice, int rc, void *pvUser);
+/** Pointer to a device reset completion callback function (FNUSBRESETDONE). */
+typedef FNVUSBRESETDONE *PFNVUSBRESETDONE;
+
+/**
+ * The state of a VUSB Device.
+ *
+ * @remark The order of these states is vital.
+ */
+typedef enum VUSBDEVICESTATE
+{
+ VUSB_DEVICE_STATE_INVALID = 0,
+ VUSB_DEVICE_STATE_DETACHED,
+ VUSB_DEVICE_STATE_ATTACHED,
+ VUSB_DEVICE_STATE_POWERED,
+ VUSB_DEVICE_STATE_DEFAULT,
+ VUSB_DEVICE_STATE_ADDRESS,
+ VUSB_DEVICE_STATE_CONFIGURED,
+ VUSB_DEVICE_STATE_SUSPENDED,
+ /** The device is being reset. Don't mess with it.
+ * Next states: VUSB_DEVICE_STATE_DEFAULT, VUSB_DEVICE_STATE_DESTROYED
+ */
+ VUSB_DEVICE_STATE_RESET,
+ /** The device has been destroy. */
+ VUSB_DEVICE_STATE_DESTROYED,
+ /** The usual 32-bit hack. */
+ VUSB_DEVICE_STATE_32BIT_HACK = 0x7fffffff
+} VUSBDEVICESTATE;
+
+#ifndef RDESKTOP
+
+/**
+ * USB Device Interface (up).
+ * No interface pair.
+ */
+typedef struct VUSBIDEVICE
+{
+ /**
+ * Resets the device.
+ *
+ * Since a device reset shall take at least 10ms from the guest point of view,
+ * it must be performed asynchronously. We create a thread which performs this
+ * operation and ensures it will take at least 10ms.
+ *
+ * At times - like init - a synchronous reset is required, this can be done
+ * by passing NULL for pfnDone.
+ *
+ * -- internal stuff, move it --
+ * While the device is being reset it is in the VUSB_DEVICE_STATE_RESET state.
+ * On completion it will be in the VUSB_DEVICE_STATE_DEFAULT state if successful,
+ * or in the VUSB_DEVICE_STATE_DETACHED state if the rest failed.
+ * -- internal stuff, move it --
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to this structure.
+ * @param fResetOnLinux Set if we can permit a real reset and a potential logical
+ * device reconnect on linux hosts.
+ * @param pfnDone Pointer to the completion routine. If NULL a synchronous
+ * reset is preformed not respecting the 10ms.
+ * @param pvUser User argument to the completion routine.
+ * @param pVM Pointer to the VM handle if callback in EMT is required. (optional)
+ */
+ DECLR3CALLBACKMEMBER(int, pfnReset,(PVUSBIDEVICE pInterface, bool fResetOnLinux,
+ PFNVUSBRESETDONE pfnDone, void *pvUser, PVM pVM));
+
+ /**
+ * Powers on the device.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the device interface structure.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPowerOn,(PVUSBIDEVICE pInterface));
+
+ /**
+ * Powers off the device.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the device interface structure.
+ */
+ DECLR3CALLBACKMEMBER(int, pfnPowerOff,(PVUSBIDEVICE pInterface));
+
+ /**
+ * Get the state of the device.
+ *
+ * @returns Device state.
+ * @param pInterface Pointer to the device interface structure.
+ */
+ DECLR3CALLBACKMEMBER(VUSBDEVICESTATE, pfnGetState,(PVUSBIDEVICE pInterface));
+
+} VUSBIDEVICE;
+/** VUSBIDEVICE interface ID. */
+#define VUSBIDEVICE_IID "88732dd3-0ccd-4625-b040-48804ac7a217"
+
+
+#ifdef IN_RING3
+/**
+ * Resets the device.
+ *
+ * Since a device reset shall take at least 10ms from the guest point of view,
+ * it must be performed asynchronously. We create a thread which performs this
+ * operation and ensures it will take at least 10ms.
+ *
+ * At times - like init - a synchronous reset is required, this can be done
+ * by passing NULL for pfnDone.
+ *
+ * -- internal stuff, move it --
+ * While the device is being reset it is in the VUSB_DEVICE_STATE_RESET state.
+ * On completion it will be in the VUSB_DEVICE_STATE_DEFAULT state if successful,
+ * or in the VUSB_DEVICE_STATE_DETACHED state if the rest failed.
+ * -- internal stuff, move it --
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the device interface structure.
+ * @param fResetOnLinux Set if we can permit a real reset and a potential logical
+ * device reconnect on linux hosts.
+ * @param pfnDone Pointer to the completion routine. If NULL a synchronous
+ * reset is preformed not respecting the 10ms.
+ * @param pvUser User argument to the completion routine.
+ * @param pVM Pointer to the VM handle if callback in EMT is required. (optional)
+ */
+DECLINLINE(int) VUSBIDevReset(PVUSBIDEVICE pInterface, bool fResetOnLinux, PFNVUSBRESETDONE pfnDone, void *pvUser, PVM pVM)
+{
+ return pInterface->pfnReset(pInterface, fResetOnLinux, pfnDone, pvUser, pVM);
+}
+
+/**
+ * Powers on the device.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the device interface structure.
+ */
+DECLINLINE(int) VUSBIDevPowerOn(PVUSBIDEVICE pInterface)
+{
+ return pInterface->pfnPowerOn(pInterface);
+}
+
+/**
+ * Powers off the device.
+ *
+ * @returns VBox status code.
+ * @param pInterface Pointer to the device interface structure.
+ */
+DECLINLINE(int) VUSBIDevPowerOff(PVUSBIDEVICE pInterface)
+{
+ return pInterface->pfnPowerOff(pInterface);
+}
+
+/**
+ * Get the state of the device.
+ *
+ * @returns Device state.
+ * @param pInterface Pointer to the device interface structure.
+ */
+DECLINLINE(VUSBDEVICESTATE) VUSBIDevGetState(PVUSBIDEVICE pInterface)
+{
+ return pInterface->pfnGetState(pInterface);
+}
+#endif /* IN_RING3 */
+
+#endif /* ! RDESKTOP */
+
+/** @name URB
+ * @{ */
+
+/**
+ * VUSB Transfer status codes.
+ */
+typedef enum VUSBSTATUS
+{
+ /** Transer was ok. */
+ VUSBSTATUS_OK = 0,
+ /** Transfer stalled, endpoint halted. */
+ VUSBSTATUS_STALL,
+ /** Device not responding. */
+ VUSBSTATUS_DNR,
+ /** CRC error. */
+ VUSBSTATUS_CRC,
+ /** Data overrun error. */
+ VUSBSTATUS_DATA_UNDERRUN,
+ /** Data overrun error. */
+ VUSBSTATUS_DATA_OVERRUN,
+ /** The isochronous buffer hasn't been touched. */
+ VUSBSTATUS_NOT_ACCESSED,
+ /** Canceled/undone URB (VUSB internal). */
+ VUSBSTATUS_UNDO,
+ /** Invalid status. */
+ VUSBSTATUS_INVALID = 0x7f
+} VUSBSTATUS;
+
+
+/**
+ * VUSB Transfer types.
+ */
+typedef enum VUSBXFERTYPE
+{
+ /** Control message. Used to represent a single control transfer. */
+ VUSBXFERTYPE_CTRL = 0,
+ /* Isochronous transfer. */
+ VUSBXFERTYPE_ISOC,
+ /** Bulk transfer. */
+ VUSBXFERTYPE_BULK,
+ /** Interrupt transfer. */
+ VUSBXFERTYPE_INTR,
+ /** Complete control message. Used to represent an entire control message. */
+ VUSBXFERTYPE_MSG,
+ /** Invalid transfer type. */
+ VUSBXFERTYPE_INVALID = 0x7f
+} VUSBXFERTYPE;
+
+
+/**
+ * VUSB transfer direction.
+ */
+typedef enum VUSBDIRECTION
+{
+ /** Setup */
+ VUSBDIRECTION_SETUP = 0,
+#define VUSB_DIRECTION_SETUP VUSBDIRECTION_SETUP
+ /** In - Device to host. */
+ VUSBDIRECTION_IN = 1,
+#define VUSB_DIRECTION_IN VUSBDIRECTION_IN
+ /** Out - Host to device. */
+ VUSBDIRECTION_OUT = 2,
+#define VUSB_DIRECTION_OUT VUSBDIRECTION_OUT
+ /** Invalid direction */
+ VUSBDIRECTION_INVALID = 0x7f
+} VUSBDIRECTION;
+
+/**
+ * The URB states
+ */
+typedef enum VUSBURBSTATE
+{
+ /** The usual invalid state. */
+ VUSBURBSTATE_INVALID = 0,
+ /** The URB is free, i.e. not in use.
+ * Next state: ALLOCATED */
+ VUSBURBSTATE_FREE,
+ /** The URB is allocated, i.e. being prepared for submission.
+ * Next state: FREE, IN_FLIGHT */
+ VUSBURBSTATE_ALLOCATED,
+ /** The URB is in flight.
+ * Next state: REAPED, CANCELLED */
+ VUSBURBSTATE_IN_FLIGHT,
+ /** The URB has been reaped and is being completed.
+ * Next state: FREE */
+ VUSBURBSTATE_REAPED,
+ /** The URB has been cancelled and is awaiting reaping and immediate freeing.
+ * Next state: FREE */
+ VUSBURBSTATE_CANCELLED,
+ /** The end of the valid states (exclusive). */
+ VUSBURBSTATE_END,
+ /** The usual 32-bit blow up. */
+ VUSBURBSTATE_32BIT_HACK = 0x7fffffff
+} VUSBURBSTATE;
+
+
+/**
+ * Information about a isochronous packet.
+ */
+typedef struct VUSBURBISOCPKT
+{
+ /** The size of the packet.
+ * IN: The packet size. I.e. the number of bytes to the next packet or end of buffer.
+ * OUT: The actual size transferred. */
+ uint16_t cb;
+ /** The offset of the packet. (Relative to VUSBURB::abData[0].)
+ * OUT: This can be changed by the USB device if it does some kind of buffer squeezing. */
+ uint16_t off;
+ /** The status of the transfer.
+ * IN: VUSBSTATUS_INVALID
+ * OUT: VUSBSTATUS_INVALID if nothing was done, otherwise the correct status. */
+ VUSBSTATUS enmStatus;
+} VUSBURBISOCPKT;
+/** Pointer to a isochronous packet. */
+typedef VUSBURBISOCPKT *PVUSBURBISOCPTK;
+/** Pointer to a const isochronous packet. */
+typedef const VUSBURBISOCPKT *PCVUSBURBISOCPKT;
+
+/**
+ * Asynchronous USB request descriptor
+ */
+typedef struct VUSBURB
+{
+ /** URB magic value. */
+ uint32_t u32Magic;
+ /** The USR state. */
+ VUSBURBSTATE enmState;
+ /** URB description, can be null. intended for logging. */
+ char *pszDesc;
+
+#ifdef RDESKTOP
+ /** The next URB in rdesktop-vrdp's linked list */
+ PVUSBURB pNext;
+ /** The previous URB in rdesktop-vrdp's linked list */
+ PVUSBURB pPrev;
+ /** The vrdp handle for the URB */
+ uint32_t handle;
+ /** Pointer used to find the usb proxy device */
+ struct VUSBDEV *pDev;
+#endif
+
+ /** The VUSB data. */
+ struct VUSBURBVUSB
+ {
+ /** URB chain pointer. */
+ PVUSBURB pNext;
+ /** URB chain pointer. */
+ PVUSBURB *ppPrev;
+ /** Pointer to the original for control messages. */
+ PVUSBURB pCtrlUrb;
+ /** Pointer to the VUSB device.
+ * This may be NULL if the destination address is invalid. */
+ struct VUSBDEV *pDev;
+ /** Sepcific to the pfnFree function. */
+ void *pvFreeCtx;
+ /**
+ * Callback which will free the URB once it's reaped and completed.
+ * @param pUrb The URB.
+ */
+ DECLCALLBACKMEMBER(void, pfnFree)(PVUSBURB pUrb);
+ /** Submit timestamp. (logging only) */
+ uint64_t u64SubmitTS;
+ /** The allocated data length. */
+ uint32_t cbDataAllocated;
+ /** The allocated TD length. */
+ uint32_t cTdsAllocated;
+ } VUsb;
+
+ /** The host controller data. */
+ struct VUSBURBHCI
+ {
+ /** The endpoint descriptor address. */
+ RTGCPHYS32 EdAddr;
+ /** Number of Tds in the array. */
+ uint32_t cTds;
+ /** Pointer to an array of TD info items.*/
+ struct VUSBURBHCITD
+ {
+ /** Type of TD (private) */
+ uint32_t TdType;
+ /** The address of the */
+ RTGCPHYS32 TdAddr;
+ /** A copy of the TD. */
+ uint32_t TdCopy[16];
+ } *paTds;
+ /** URB chain pointer. */
+ PVUSBURB pNext;
+ /** When this URB was created.
+ * (Used for isochronous frames and for logging.) */
+ uint32_t u32FrameNo;
+ /** Flag indicating that the TDs have been unlinked. */
+ bool fUnlinked;
+ } Hci;
+
+ /** The device data. */
+ struct VUSBURBDEV
+ {
+ /** Pointer to private device specific data. */
+ void *pvPrivate;
+ /** Used by the device when linking the URB in some list of its own. */
+ PVUSBURB pNext;
+ } Dev;
+
+#ifndef RDESKTOP
+ /** The USB device instance this belongs to.
+ * This is NULL if the device address is invalid, in which case this belongs to the hub. */
+ PPDMUSBINS pUsbIns;
+#endif
+ /** The device address.
+ * This is set at allocation time. */
+ uint8_t DstAddress;
+
+ /** The endpoint.
+ * IN: Must be set before submitting the URB.
+ * @remark This does not have the high bit (direction) set! */
+ uint8_t EndPt;
+ /** The transfer type.
+ * IN: Must be set before submitting the URB. */
+ VUSBXFERTYPE enmType;
+ /** The transfer direction.
+ * IN: Must be set before submitting the URB. */
+ VUSBDIRECTION enmDir;
+ /** Indicates whether it is OK to receive/send less data than requested.
+ * IN: Must be initialized before submitting the URB. */
+ bool fShortNotOk;
+ /** The transfer status.
+ * OUT: This is set when reaping the URB. */
+ VUSBSTATUS enmStatus;
+
+ /** The number of isochronous packets describe in aIsocPkts.
+ * This is ignored when enmType isn't VUSBXFERTYPE_ISOC. */
+ uint32_t cIsocPkts;
+ /** The iso packets within abData.
+ * This is ignored when enmType isn't VUSBXFERTYPE_ISOC. */
+ VUSBURBISOCPKT aIsocPkts[8];
+
+ /** The message length.
+ * IN: The amount of data to send / receive - set at allocation time.
+ * OUT: The amount of data sent / received. */
+ uint32_t cbData;
+ /** The message data.
+ * IN: On host to device transfers, the data to send.
+ * OUT: On device to host transfers, the data to received. */
+ uint8_t abData[8*_1K];
+} VUSBURB;
+
+/** The magic value of a valid VUSBURB. (Murakami Haruki) */
+#define VUSBURB_MAGIC UINT32_C(0x19490112)
+
+/** @} */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/VBox/x86.mac b/include/VBox/x86.mac
new file mode 100644
index 00000000..ebc1a324
--- /dev/null
+++ b/include/VBox/x86.mac
@@ -0,0 +1,2 @@
+%error "Use iprt/x86.mac instead! This file is just here to ease incremental build pains."
+