summaryrefslogtreecommitdiff
path: root/include
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
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')
-rw-r--r--include/Makefile.kmk149
-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
-rw-r--r--include/iprt/Makefile.kup0
-rw-r--r--include/iprt/alloc.h33
-rw-r--r--include/iprt/alloca.h56
-rw-r--r--include/iprt/asm-amd64-x86.h2701
-rw-r--r--include/iprt/asm-math.h319
-rw-r--r--include/iprt/asm.h4643
-rw-r--r--include/iprt/asmdefs.mac774
-rw-r--r--include/iprt/assert.h2675
-rw-r--r--include/iprt/avl.h1114
-rw-r--r--include/iprt/base64.h119
-rw-r--r--include/iprt/buildconfig.h125
-rw-r--r--include/iprt/cdefs.h2500
-rw-r--r--include/iprt/cdrom.h181
-rw-r--r--include/iprt/cidr.h61
-rw-r--r--include/iprt/circbuf.h138
-rw-r--r--include/iprt/condvar.h283
-rw-r--r--include/iprt/coredumper.h94
-rw-r--r--include/iprt/cpp/Makefile.kup0
-rw-r--r--include/iprt/cpp/autores.h203
-rw-r--r--include/iprt/cpp/exception.h95
-rw-r--r--include/iprt/cpp/list.h891
-rw-r--r--include/iprt/cpp/lock.h166
-rw-r--r--include/iprt/cpp/mem.h271
-rw-r--r--include/iprt/cpp/meta.h110
-rw-r--r--include/iprt/cpp/ministring.h1023
-rw-r--r--include/iprt/cpp/mtlist.h155
-rw-r--r--include/iprt/cpp/utils.h102
-rw-r--r--include/iprt/cpp/xml.h748
-rw-r--r--include/iprt/cpuset.h286
-rw-r--r--include/iprt/crc.h160
-rw-r--r--include/iprt/critsect.h366
-rw-r--r--include/iprt/ctype.h238
-rw-r--r--include/iprt/dbg.h1273
-rw-r--r--include/iprt/dir.h473
-rw-r--r--include/iprt/dvm.h379
-rw-r--r--include/iprt/env.h254
-rw-r--r--include/iprt/err.h1733
-rw-r--r--include/iprt/err.mac455
-rw-r--r--include/iprt/err.sed45
-rw-r--r--include/iprt/errno.h318
-rw-r--r--include/iprt/file.h1339
-rw-r--r--include/iprt/filesystem.h55
-rw-r--r--include/iprt/fs.h618
-rw-r--r--include/iprt/getopt.h447
-rw-r--r--include/iprt/handle.h64
-rw-r--r--include/iprt/handletable.h243
-rw-r--r--include/iprt/heap.h356
-rw-r--r--include/iprt/initterm.h238
-rw-r--r--include/iprt/isofs.h225
-rw-r--r--include/iprt/ldr.h559
-rw-r--r--include/iprt/linux/sysfs.h262
-rw-r--r--include/iprt/list.h364
-rw-r--r--include/iprt/localipc.h274
-rw-r--r--include/iprt/lockvalidator.h1062
-rw-r--r--include/iprt/log.h1984
-rw-r--r--include/iprt/mangling.h1796
-rw-r--r--include/iprt/manifest.h523
-rw-r--r--include/iprt/md5.h126
-rw-r--r--include/iprt/mem.h924
-rw-r--r--include/iprt/memcache.h147
-rw-r--r--include/iprt/memobj.h629
-rw-r--r--include/iprt/memory0
-rw-r--r--include/iprt/mempool.h165
-rw-r--r--include/iprt/memtracker.h236
-rw-r--r--include/iprt/message.h198
-rw-r--r--include/iprt/mp.h365
-rw-r--r--include/iprt/net.h816
-rw-r--r--include/iprt/nocrt/amd64/fenv.h232
-rw-r--r--include/iprt/nocrt/amd64/math.h102
-rw-r--r--include/iprt/nocrt/compiler/compiler.h37
-rw-r--r--include/iprt/nocrt/compiler/gcc.h121
-rw-r--r--include/iprt/nocrt/compiler/msc.h45
-rw-r--r--include/iprt/nocrt/fenv.h38
-rw-r--r--include/iprt/nocrt/inttypes.h42
-rw-r--r--include/iprt/nocrt/limits.h86
-rw-r--r--include/iprt/nocrt/math.h823
-rw-r--r--include/iprt/nocrt/setjmp.h55
-rw-r--r--include/iprt/nocrt/stdarg.h27
-rw-r--r--include/iprt/nocrt/stddef.h27
-rw-r--r--include/iprt/nocrt/stdlib.h36
-rw-r--r--include/iprt/nocrt/string.h80
-rw-r--r--include/iprt/nocrt/x86/fenv.h274
-rw-r--r--include/iprt/nocrt/x86/math.h101
-rw-r--r--include/iprt/ntwrap.mac0
-rw-r--r--include/iprt/once.h162
-rw-r--r--include/iprt/param.h131
-rw-r--r--include/iprt/path.h942
-rw-r--r--include/iprt/pipe.h226
-rw-r--r--include/iprt/poll.h243
-rw-r--r--include/iprt/power.h112
-rw-r--r--include/iprt/process.h398
-rw-r--r--include/iprt/rand.h317
-rw-r--r--include/iprt/req.h598
-rw-r--r--include/iprt/runtime-loader.h179
-rw-r--r--include/iprt/runtime.h86
-rw-r--r--include/iprt/s3.h270
-rw-r--r--include/iprt/semaphore.h1441
-rw-r--r--include/iprt/sg.h278
-rw-r--r--include/iprt/sha.h302
-rw-r--r--include/iprt/socket.h399
-rw-r--r--include/iprt/solaris/kmoddeps.mac183
-rw-r--r--include/iprt/sort.h128
-rw-r--r--include/iprt/spinlock.h97
-rw-r--r--include/iprt/stdarg.h54
-rw-r--r--include/iprt/stdint.h244
-rw-r--r--include/iprt/strcache.h121
-rw-r--r--include/iprt/stream.h292
-rw-r--r--include/iprt/string.h3868
-rw-r--r--include/iprt/symlink.h176
-rw-r--r--include/iprt/system.h250
-rw-r--r--include/iprt/table.h713
-rw-r--r--include/iprt/tar.h456
-rw-r--r--include/iprt/tcp.h443
-rw-r--r--include/iprt/test.h1200
-rw-r--r--include/iprt/thread.h832
-rw-r--r--include/iprt/time.h941
-rw-r--r--include/iprt/timer.h379
-rw-r--r--include/iprt/trace.h215
-rw-r--r--include/iprt/types.h2371
-rw-r--r--include/iprt/udp.h155
-rw-r--r--include/iprt/uint128.h698
-rw-r--r--include/iprt/uni.h397
-rw-r--r--include/iprt/uri.h157
-rw-r--r--include/iprt/uuid.h185
-rw-r--r--include/iprt/vector.h375
-rw-r--r--include/iprt/vfs.h934
-rw-r--r--include/iprt/vfslowlevel.h1236
-rw-r--r--include/iprt/x86.h3194
-rw-r--r--include/iprt/x86.mac706
-rw-r--r--include/iprt/x86extra.mac103
-rw-r--r--include/iprt/zip.h263
317 files changed, 158789 insertions, 0 deletions
diff --git a/include/Makefile.kmk b/include/Makefile.kmk
new file mode 100644
index 00000000..5d5a0ae7
--- /dev/null
+++ b/include/Makefile.kmk
@@ -0,0 +1,149 @@
+# $Id: Makefile.kmk $
+## @file
+# Some hacks to allow syntax and prerequisite include checking of headers.
+# This makefile doesn't and shouldn't build successfully.
+#
+
+#
+# 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.
+#
+
+DEPTH = ..
+include $(KBUILD_PATH)/header.kmk
+
+LIBRARIES = SyntaxVBoxIncludeR3 SyntaxVBoxIncludeR0 SyntaxVBoxIncludeRC
+
+# Omit headers that are using C++ features and upsets gcc.
+cpp_features_hdrs := \
+ VBox/vmm/hwaccm.h \
+ VBox/vmm/hwacc_vmx.h \
+ VBox/HostServices/GuestControlSvc.h \
+ VBox/VBoxCrHgsmi.h \
+ VBox/VBoxUhgsmi.h
+
+# Omit headers that are C++ and ring-3.
+r3_cpp_hdrs := \
+ VBox/dbggui.h \
+ VBox/settings.h \
+ VBox/com/Guid.h \
+ VBox/HostServices/GuestPropertySvc.h \
+ $(wildcard iprt/*_cpp.h iprt/cpp/*.h VBox/com/*.h )
+
+# Ring-3 only headers.
+r3_only_hdrs := \
+ VBox/vrdpapi.h \
+ VBox/vrdpusb.h \
+ VBox/VBoxHDD.h \
+ VBox/VBoxHDD-Plugin.h \
+ VBox/VBoxCrHgsmi.h \
+ VBox/VBoxUhgsmi.h \
+ VBox/dbus.h \
+ VBox/vd.h \
+ VBox/vd-plugin.h \
+ VBox/vd-cache-plugin.h \
+ VBox/vmm/uvm.h \
+ VBox/vscsi.h \
+ $(wildcard VBox/ExtPack/*.h ) \
+ iprt/alloca.h \
+ iprt/tcp.h \
+ iprt/localipc.h \
+ iprt/linux/sysfs.h \
+ iprt/socket.h
+
+# We omit a few headers which have platform specific issues or are templates.
+hdrs := $(filter-out \
+ VBox/HostServices/glext.h \
+ VBox/HostServices/glxext.h \
+ VBox/HostServices/wglext.h \
+ VBox/VBoxGuest16.h \
+ VBox/VBoxGL2D.h \
+ VBox/WinNetConfig.h \
+ VBox/usblib-win.h \
+ VBox/usblib-solaris.h \
+ VBox/VDEPlug.h \
+ $(if-expr "$(KBUILD_TARGET)" != "win", \
+ VBox/VBoxDrvCfg-win.h \
+ VBox/VBoxNetCfg-win.h \
+ ,) \
+ \
+ VBox/dbus-calls.h \
+ VBox/VDEPlugSymDefs.h \
+ VBox/VBoxKeyboard.h \
+ iprt/runtime-loader.h \
+ iprt/mangling.h \
+ \
+ $(foreach os,$(filter-out $(KBUILD_TARGET),$(KBUILD_OSES)),iprt/$(os)/% VBox/$(os)/%) \
+ $(xforeach arch,$(KBUILD_ARCHES),iprt/nocrt/$(arch)/%) \
+ , $(wildcard VBox/*.h VBox/*/*.h iprt/*.h iprt/*/*.h))
+
+# ring-3, ring-0 and raw-mode context specific exclusions.
+hdrs.r3 := $(filter-out , $(hdrs))
+hdrs-c.r3 := $(filter-out $(cpp_features_hdrs) $(r3_cpp_hdrs), $(hdrs.r3))
+hdrs.r0 := $(filter-out $(r3_cpp_hdrs) $(r3_only_hdrs), $(hdrs))
+hdrs-c.r0 := $(filter-out $(cpp_features_hdrs), $(hdrs.r0))
+hdrs.rc := $(filter-out \
+ VBox/VBoxGuestLib.h \
+ VBox/vmm/gvm.h \
+ iprt/thread.h \
+ iprt/mem.h \
+ iprt/alloc.h \
+ $(r3_cpp_hdrs) \
+ $(r3_only_hdrs) \
+ , $(hdrs))
+hdrs-c.rc := $(filter-out $(cpp_features_hdrs), $(hdrs.rc))
+
+SyntaxVBoxIncludeR3_TEMPLATE = VBOXMAINEXE
+SyntaxVBoxIncludeR3_DEFS = VBOX_WITH_HGCM
+SyntaxVBoxIncludeR3_CDEFS = VBOX_WITHOUT_UNNAMED_UNIONS
+SyntaxVBoxIncludeR3_SOURCES := \
+ $(addprefix $(PATH_TARGET)/,$(subst .h,-c.c, $(subst /,_,$(hdrs-c.r3)))) \
+ $(addprefix $(PATH_TARGET)/,$(subst .h,-cpp.cpp, $(subst /,_,$(hdrs.r3))))
+
+SyntaxVBoxIncludeR0_TEMPLATE = VBoxR0
+SyntaxVBoxIncludeR0_DEFS = VBOX_WITH_HGCM
+SyntaxVBoxIncludeR0_CDEFS = VBOX_WITHOUT_UNNAMED_UNIONS
+SyntaxVBoxIncludeR0_SOURCES := \
+ $(addprefix $(PATH_TARGET)/,$(subst .h,-c.c, $(subst /,_,$(hdrs-c.r0)))) \
+ $(addprefix $(PATH_TARGET)/,$(subst .h,-cpp.cpp, $(subst /,_,$(hdrs.r0))))
+
+SyntaxVBoxIncludeRC_TEMPLATE = VBoxRc
+SyntaxVBoxIncludeRC_DEFS = VBOX_WITH_HGCM
+SyntaxVBoxIncludeRC_CDEFS = VBOX_WITHOUT_UNNAMED_UNIONS
+SyntaxVBoxIncludeRC_SOURCES := \
+ $(addprefix $(PATH_TARGET)/,$(subst .h,-c.c, $(subst /,_,$(hdrs-c.rc)))) \
+ $(addprefix $(PATH_TARGET)/,$(subst .h,-cpp.cpp, $(subst /,_,$(hdrs.rc))))
+
+
+# Comment out the next line to simplify header correction.
+VBOX_ROOT_INCLUDE_MAKEFILE = $(PATH_ROOT)/include/Makefile.kmk
+
+include $(FILE_KBUILD_FOOTER)
+
+
+define def_hdr
+$(eval flatname := $(subst /,_,$(basename $(hdr))))
+$$(PATH_TARGET)/$(flatname)-cpp.cpp: $(VBOX_ROOT_INCLUDE_MAKEFILE) | $$(PATH_TARGET)/
+ $(QUIET)$$(APPEND) -t -n $$@ '#include <$(hdr)>' 'int main(int argc, char **argv) {(void)argc; (void)argv; return 0;}'
+
+$$(PATH_TARGET)/$(flatname)-c.c: $(VBOX_ROOT_INCLUDE_MAKEFILE) | $$(PATH_TARGET)/
+ $(QUIET)$$(APPEND) -t -n $$@ '#include <$(hdr)>' 'int main(int argc, char **argv) {(void)argc; (void)argv; return 0;}'
+
+$(subst .h,.o,$(notdir $(hdr)))::
+if1of ($(hdr), $(r3_cpp_hdrs) $(cpp_features_hdrs))
+ $$(MAKE) -f $(MAKEFILE) $(flatname)-cpp.o
+else
+ $$(MAKE) -f $(MAKEFILE) $(flatname)-c.o $(flatname)-cpp.o
+endif
+
+endef
+
+$(foreach hdr,$(hdrs), $(eval $(def_hdr)))
+
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."
+
diff --git a/include/iprt/Makefile.kup b/include/iprt/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/iprt/Makefile.kup
diff --git a/include/iprt/alloc.h b/include/iprt/alloc.h
new file mode 100644
index 00000000..e30b7f87
--- /dev/null
+++ b/include/iprt/alloc.h
@@ -0,0 +1,33 @@
+/** @file
+ * IPRT - Memory Allocation.
+ */
+
+/*
+ * 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 ___iprt_alloc_h
+#define ___iprt_alloc_h
+
+/* Forwarding to the canonical header. */
+#include <iprt/mem.h>
+
+#endif
+
diff --git a/include/iprt/alloca.h b/include/iprt/alloca.h
new file mode 100644
index 00000000..4aa00e6a
--- /dev/null
+++ b/include/iprt/alloca.h
@@ -0,0 +1,56 @@
+/** @file
+ * IPRT - alloca().
+ */
+
+/*
+ * 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 ___iprt_alloca_h
+#define ___iprt_alloca_h
+
+#if defined(IN_RC) || defined(IN_RING0_AGNOSTIC)
+# error "No alloca() in raw-mode and agnostic ring-0 context as it may have external dependencies like libgcc."
+#endif
+
+/*
+ * If there are more difficult platforms out there, we'll do OS
+ * specific #ifdefs. But for now we'll just include the headers
+ * which normally contains the alloca() prototype.
+ * When we're in kernel territory it starts getting a bit more
+ * interesting of course...
+ */
+#if defined(IN_RING0) \
+ && (defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD))
+/* ASSUMES GNU C */
+# define alloca(cb) __builtin_alloca(cb)
+
+#else
+# include <stdlib.h>
+# if !defined(RT_OS_DARWIN) && !defined(RT_OS_FREEBSD)
+# include <malloc.h>
+# endif
+# ifdef RT_OS_SOLARIS
+# include <alloca.h>
+# endif
+#endif
+
+#endif
+
diff --git a/include/iprt/asm-amd64-x86.h b/include/iprt/asm-amd64-x86.h
new file mode 100644
index 00000000..22efb441
--- /dev/null
+++ b/include/iprt/asm-amd64-x86.h
@@ -0,0 +1,2701 @@
+/** @file
+ * IPRT - AMD64 and x86 Specific Assembly Functions.
+ */
+
+/*
+ * 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 ___iprt_asm_amd64_x86_h
+#define ___iprt_asm_amd64_x86_h
+
+#include <iprt/types.h>
+#if !defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86)
+# error "Not on AMD64 or x86"
+#endif
+
+#if defined(_MSC_VER) && RT_INLINE_ASM_USES_INTRIN
+# include <intrin.h>
+ /* Emit the intrinsics at all optimization levels. */
+# pragma intrinsic(_ReadWriteBarrier)
+# pragma intrinsic(__cpuid)
+# pragma intrinsic(_enable)
+# pragma intrinsic(_disable)
+# pragma intrinsic(__rdtsc)
+# pragma intrinsic(__readmsr)
+# pragma intrinsic(__writemsr)
+# pragma intrinsic(__outbyte)
+# pragma intrinsic(__outbytestring)
+# pragma intrinsic(__outword)
+# pragma intrinsic(__outwordstring)
+# pragma intrinsic(__outdword)
+# pragma intrinsic(__outdwordstring)
+# pragma intrinsic(__inbyte)
+# pragma intrinsic(__inbytestring)
+# pragma intrinsic(__inword)
+# pragma intrinsic(__inwordstring)
+# pragma intrinsic(__indword)
+# pragma intrinsic(__indwordstring)
+# pragma intrinsic(__invlpg)
+# pragma intrinsic(__wbinvd)
+# pragma intrinsic(__readcr0)
+# pragma intrinsic(__readcr2)
+# pragma intrinsic(__readcr3)
+# pragma intrinsic(__readcr4)
+# pragma intrinsic(__writecr0)
+# pragma intrinsic(__writecr3)
+# pragma intrinsic(__writecr4)
+# pragma intrinsic(__readdr)
+# pragma intrinsic(__writedr)
+# ifdef RT_ARCH_AMD64
+# pragma intrinsic(__readcr8)
+# pragma intrinsic(__writecr8)
+# endif
+#endif
+
+
+
+/** @defgroup grp_rt_asm_amd64_x86 AMD64 and x86 Specific ASM Routines
+ * @ingroup grp_rt_asm
+ * @{
+ */
+
+/** @todo find a more proper place for this structure? */
+#pragma pack(1)
+/** IDTR */
+typedef struct RTIDTR
+{
+ /** Size of the IDT. */
+ uint16_t cbIdt;
+ /** Address of the IDT. */
+ uintptr_t pIdt;
+} RTIDTR, *PRTIDTR;
+#pragma pack()
+
+#pragma pack(1)
+/** GDTR */
+typedef struct RTGDTR
+{
+ /** Size of the GDT. */
+ uint16_t cbGdt;
+ /** Address of the GDT. */
+ uintptr_t pGdt;
+} RTGDTR, *PRTGDTR;
+#pragma pack()
+
+
+/**
+ * Gets the content of the IDTR CPU register.
+ * @param pIdtr Where to store the IDTR contents.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMGetIDTR(PRTIDTR pIdtr);
+#else
+DECLINLINE(void) ASMGetIDTR(PRTIDTR pIdtr)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("sidt %0" : "=m" (*pIdtr));
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pIdtr]
+ sidt [rax]
+# else
+ mov eax, [pIdtr]
+ sidt [eax]
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Sets the content of the IDTR CPU register.
+ * @param pIdtr Where to load the IDTR contents from
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMSetIDTR(const RTIDTR *pIdtr);
+#else
+DECLINLINE(void) ASMSetIDTR(const RTIDTR *pIdtr)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lidt %0" : : "m" (*pIdtr));
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pIdtr]
+ lidt [rax]
+# else
+ mov eax, [pIdtr]
+ lidt [eax]
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Gets the content of the GDTR CPU register.
+ * @param pGdtr Where to store the GDTR contents.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMGetGDTR(PRTGDTR pGdtr);
+#else
+DECLINLINE(void) ASMGetGDTR(PRTGDTR pGdtr)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("sgdt %0" : "=m" (*pGdtr));
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pGdtr]
+ sgdt [rax]
+# else
+ mov eax, [pGdtr]
+ sgdt [eax]
+# endif
+ }
+# endif
+}
+#endif
+
+/**
+ * Get the cs register.
+ * @returns cs.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetCS(void);
+#else
+DECLINLINE(RTSEL) ASMGetCS(void)
+{
+ RTSEL SelCS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movw %%cs, %0\n\t" : "=r" (SelCS));
+# else
+ __asm
+ {
+ mov ax, cs
+ mov [SelCS], ax
+ }
+# endif
+ return SelCS;
+}
+#endif
+
+
+/**
+ * Get the DS register.
+ * @returns DS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetDS(void);
+#else
+DECLINLINE(RTSEL) ASMGetDS(void)
+{
+ RTSEL SelDS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movw %%ds, %0\n\t" : "=r" (SelDS));
+# else
+ __asm
+ {
+ mov ax, ds
+ mov [SelDS], ax
+ }
+# endif
+ return SelDS;
+}
+#endif
+
+
+/**
+ * Get the ES register.
+ * @returns ES.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetES(void);
+#else
+DECLINLINE(RTSEL) ASMGetES(void)
+{
+ RTSEL SelES;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movw %%es, %0\n\t" : "=r" (SelES));
+# else
+ __asm
+ {
+ mov ax, es
+ mov [SelES], ax
+ }
+# endif
+ return SelES;
+}
+#endif
+
+
+/**
+ * Get the FS register.
+ * @returns FS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetFS(void);
+#else
+DECLINLINE(RTSEL) ASMGetFS(void)
+{
+ RTSEL SelFS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movw %%fs, %0\n\t" : "=r" (SelFS));
+# else
+ __asm
+ {
+ mov ax, fs
+ mov [SelFS], ax
+ }
+# endif
+ return SelFS;
+}
+# endif
+
+
+/**
+ * Get the GS register.
+ * @returns GS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetGS(void);
+#else
+DECLINLINE(RTSEL) ASMGetGS(void)
+{
+ RTSEL SelGS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movw %%gs, %0\n\t" : "=r" (SelGS));
+# else
+ __asm
+ {
+ mov ax, gs
+ mov [SelGS], ax
+ }
+# endif
+ return SelGS;
+}
+#endif
+
+
+/**
+ * Get the SS register.
+ * @returns SS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetSS(void);
+#else
+DECLINLINE(RTSEL) ASMGetSS(void)
+{
+ RTSEL SelSS;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movw %%ss, %0\n\t" : "=r" (SelSS));
+# else
+ __asm
+ {
+ mov ax, ss
+ mov [SelSS], ax
+ }
+# endif
+ return SelSS;
+}
+#endif
+
+
+/**
+ * Get the TR register.
+ * @returns TR.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTSEL) ASMGetTR(void);
+#else
+DECLINLINE(RTSEL) ASMGetTR(void)
+{
+ RTSEL SelTR;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("str %w0\n\t" : "=r" (SelTR));
+# else
+ __asm
+ {
+ str ax
+ mov [SelTR], ax
+ }
+# endif
+ return SelTR;
+}
+#endif
+
+
+/**
+ * Get the [RE]FLAGS register.
+ * @returns [RE]FLAGS.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(RTCCUINTREG) ASMGetFlags(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetFlags(void)
+{
+ RTCCUINTREG uFlags;
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("pushfq\n\t"
+ "popq %0\n\t"
+ : "=r" (uFlags));
+# else
+ __asm__ __volatile__("pushfl\n\t"
+ "popl %0\n\t"
+ : "=r" (uFlags));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ pushfq
+ pop [uFlags]
+# else
+ pushfd
+ pop [uFlags]
+# endif
+ }
+# endif
+ return uFlags;
+}
+#endif
+
+
+/**
+ * Set the [RE]FLAGS register.
+ * @param uFlags The new [RE]FLAGS value.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMSetFlags(RTCCUINTREG uFlags);
+#else
+DECLINLINE(void) ASMSetFlags(RTCCUINTREG uFlags)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("pushq %0\n\t"
+ "popfq\n\t"
+ : : "g" (uFlags));
+# else
+ __asm__ __volatile__("pushl %0\n\t"
+ "popfl\n\t"
+ : : "g" (uFlags));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ push [uFlags]
+ popfq
+# else
+ push [uFlags]
+ popfd
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Gets the content of the CPU timestamp counter register.
+ *
+ * @returns TSC.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMReadTSC(void);
+#else
+DECLINLINE(uint64_t) ASMReadTSC(void)
+{
+ RTUINT64U u;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rdtsc\n\t" : "=a" (u.s.Lo), "=d" (u.s.Hi));
+# else
+# if RT_INLINE_ASM_USES_INTRIN
+ u.u = __rdtsc();
+# else
+ __asm
+ {
+ rdtsc
+ mov [u.s.Lo], eax
+ mov [u.s.Hi], edx
+ }
+# endif
+# endif
+ return u.u;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning all registers.
+ *
+ * @param uOperator CPUID operation (eax).
+ * @param pvEAX Where to store eax.
+ * @param pvEBX Where to store ebx.
+ * @param pvECX Where to store ecx.
+ * @param pvEDX Where to store edx.
+ * @remark We're using void pointers to ease the use of special bitfield structures and such.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
+#else
+DECLINLINE(void) ASMCpuId(uint32_t uOperator, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ RTCCUINTREG uRAX, uRBX, uRCX, uRDX;
+ __asm__ __volatile__ ("cpuid\n\t"
+ : "=a" (uRAX),
+ "=b" (uRBX),
+ "=c" (uRCX),
+ "=d" (uRDX)
+ : "0" (uOperator), "2" (0));
+ *(uint32_t *)pvEAX = (uint32_t)uRAX;
+ *(uint32_t *)pvEBX = (uint32_t)uRBX;
+ *(uint32_t *)pvECX = (uint32_t)uRCX;
+ *(uint32_t *)pvEDX = (uint32_t)uRDX;
+# else
+ __asm__ __volatile__ ("xchgl %%ebx, %1\n\t"
+ "cpuid\n\t"
+ "xchgl %%ebx, %1\n\t"
+ : "=a" (*(uint32_t *)pvEAX),
+ "=r" (*(uint32_t *)pvEBX),
+ "=c" (*(uint32_t *)pvECX),
+ "=d" (*(uint32_t *)pvEDX)
+ : "0" (uOperator), "2" (0));
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ __cpuid(aInfo, uOperator);
+ *(uint32_t *)pvEAX = aInfo[0];
+ *(uint32_t *)pvEBX = aInfo[1];
+ *(uint32_t *)pvECX = aInfo[2];
+ *(uint32_t *)pvEDX = aInfo[3];
+
+# else
+ uint32_t uEAX;
+ uint32_t uEBX;
+ uint32_t uECX;
+ uint32_t uEDX;
+ __asm
+ {
+ push ebx
+ mov eax, [uOperator]
+ cpuid
+ mov [uEAX], eax
+ mov [uEBX], ebx
+ mov [uECX], ecx
+ mov [uEDX], edx
+ pop ebx
+ }
+ *(uint32_t *)pvEAX = uEAX;
+ *(uint32_t *)pvEBX = uEBX;
+ *(uint32_t *)pvECX = uECX;
+ *(uint32_t *)pvEDX = uEDX;
+# endif
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning all registers.
+ * Some subfunctions of cpuid take ECX as additional parameter (currently known for EAX=4)
+ *
+ * @param uOperator CPUID operation (eax).
+ * @param uIdxECX ecx index
+ * @param pvEAX Where to store eax.
+ * @param pvEBX Where to store ebx.
+ * @param pvECX Where to store ecx.
+ * @param pvEDX Where to store edx.
+ * @remark We're using void pointers to ease the use of special bitfield structures and such.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX);
+#else
+DECLINLINE(void) ASMCpuId_Idx_ECX(uint32_t uOperator, uint32_t uIdxECX, void *pvEAX, void *pvEBX, void *pvECX, void *pvEDX)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ RTCCUINTREG uRAX, uRBX, uRCX, uRDX;
+ __asm__ ("cpuid\n\t"
+ : "=a" (uRAX),
+ "=b" (uRBX),
+ "=c" (uRCX),
+ "=d" (uRDX)
+ : "0" (uOperator),
+ "2" (uIdxECX));
+ *(uint32_t *)pvEAX = (uint32_t)uRAX;
+ *(uint32_t *)pvEBX = (uint32_t)uRBX;
+ *(uint32_t *)pvECX = (uint32_t)uRCX;
+ *(uint32_t *)pvEDX = (uint32_t)uRDX;
+# else
+ __asm__ ("xchgl %%ebx, %1\n\t"
+ "cpuid\n\t"
+ "xchgl %%ebx, %1\n\t"
+ : "=a" (*(uint32_t *)pvEAX),
+ "=r" (*(uint32_t *)pvEBX),
+ "=c" (*(uint32_t *)pvECX),
+ "=d" (*(uint32_t *)pvEDX)
+ : "0" (uOperator),
+ "2" (uIdxECX));
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ /* ??? another intrinsic ??? */
+ __cpuid(aInfo, uOperator);
+ *(uint32_t *)pvEAX = aInfo[0];
+ *(uint32_t *)pvEBX = aInfo[1];
+ *(uint32_t *)pvECX = aInfo[2];
+ *(uint32_t *)pvEDX = aInfo[3];
+
+# else
+ uint32_t uEAX;
+ uint32_t uEBX;
+ uint32_t uECX;
+ uint32_t uEDX;
+ __asm
+ {
+ push ebx
+ mov eax, [uOperator]
+ mov ecx, [uIdxECX]
+ cpuid
+ mov [uEAX], eax
+ mov [uEBX], ebx
+ mov [uECX], ecx
+ mov [uEDX], edx
+ pop ebx
+ }
+ *(uint32_t *)pvEAX = uEAX;
+ *(uint32_t *)pvEBX = uEBX;
+ *(uint32_t *)pvECX = uECX;
+ *(uint32_t *)pvEDX = uEDX;
+# endif
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning ecx and edx.
+ *
+ * @param uOperator CPUID operation (eax).
+ * @param pvECX Where to store ecx.
+ * @param pvEDX Where to store edx.
+ * @remark We're using void pointers to ease the use of special bitfield structures and such.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX);
+#else
+DECLINLINE(void) ASMCpuId_ECX_EDX(uint32_t uOperator, void *pvECX, void *pvEDX)
+{
+ uint32_t uEBX;
+ ASMCpuId(uOperator, &uOperator, &uEBX, pvECX, pvEDX);
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning eax.
+ *
+ * @param uOperator CPUID operation (eax).
+ * @returns EAX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_EAX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_EAX(uint32_t uOperator)
+{
+ RTCCUINTREG xAX;
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ ("cpuid"
+ : "=a" (xAX)
+ : "0" (uOperator)
+ : "rbx", "rcx", "rdx");
+# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+ __asm__ ("push %%ebx\n\t"
+ "cpuid\n\t"
+ "pop %%ebx\n\t"
+ : "=a" (xAX)
+ : "0" (uOperator)
+ : "ecx", "edx");
+# else
+ __asm__ ("cpuid"
+ : "=a" (xAX)
+ : "0" (uOperator)
+ : "edx", "ecx", "ebx");
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ __cpuid(aInfo, uOperator);
+ xAX = aInfo[0];
+
+# else
+ __asm
+ {
+ push ebx
+ mov eax, [uOperator]
+ cpuid
+ mov [xAX], eax
+ pop ebx
+ }
+# endif
+ return (uint32_t)xAX;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning ebx.
+ *
+ * @param uOperator CPUID operation (eax).
+ * @returns EBX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_EBX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_EBX(uint32_t uOperator)
+{
+ RTCCUINTREG xBX;
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ RTCCUINTREG uSpill;
+ __asm__ ("cpuid"
+ : "=a" (uSpill),
+ "=b" (xBX)
+ : "0" (uOperator)
+ : "rdx", "rcx");
+# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+ __asm__ ("push %%ebx\n\t"
+ "cpuid\n\t"
+ "mov %%ebx, %%edx\n\t"
+ "pop %%ebx\n\t"
+ : "=a" (uOperator),
+ "=d" (xBX)
+ : "0" (uOperator)
+ : "ecx");
+# else
+ __asm__ ("cpuid"
+ : "=a" (uOperator),
+ "=b" (xBX)
+ : "0" (uOperator)
+ : "edx", "ecx");
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ __cpuid(aInfo, uOperator);
+ xBX = aInfo[1];
+
+# else
+ __asm
+ {
+ push ebx
+ mov eax, [uOperator]
+ cpuid
+ mov [xBX], ebx
+ pop ebx
+ }
+# endif
+ return (uint32_t)xBX;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning ecx.
+ *
+ * @param uOperator CPUID operation (eax).
+ * @returns ECX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_ECX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_ECX(uint32_t uOperator)
+{
+ RTCCUINTREG xCX;
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ RTCCUINTREG uSpill;
+ __asm__ ("cpuid"
+ : "=a" (uSpill),
+ "=c" (xCX)
+ : "0" (uOperator)
+ : "rbx", "rdx");
+# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+ __asm__ ("push %%ebx\n\t"
+ "cpuid\n\t"
+ "pop %%ebx\n\t"
+ : "=a" (uOperator),
+ "=c" (xCX)
+ : "0" (uOperator)
+ : "edx");
+# else
+ __asm__ ("cpuid"
+ : "=a" (uOperator),
+ "=c" (xCX)
+ : "0" (uOperator)
+ : "ebx", "edx");
+
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ __cpuid(aInfo, uOperator);
+ xCX = aInfo[2];
+
+# else
+ __asm
+ {
+ push ebx
+ mov eax, [uOperator]
+ cpuid
+ mov [xCX], ecx
+ pop ebx
+ }
+# endif
+ return (uint32_t)xCX;
+}
+#endif
+
+
+/**
+ * Performs the cpuid instruction returning edx.
+ *
+ * @param uOperator CPUID operation (eax).
+ * @returns EDX after cpuid operation.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMCpuId_EDX(uint32_t uOperator);
+#else
+DECLINLINE(uint32_t) ASMCpuId_EDX(uint32_t uOperator)
+{
+ RTCCUINTREG xDX;
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ RTCCUINTREG uSpill;
+ __asm__ ("cpuid"
+ : "=a" (uSpill),
+ "=d" (xDX)
+ : "0" (uOperator)
+ : "rbx", "rcx");
+# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+ __asm__ ("push %%ebx\n\t"
+ "cpuid\n\t"
+ "pop %%ebx\n\t"
+ : "=a" (uOperator),
+ "=d" (xDX)
+ : "0" (uOperator)
+ : "ecx");
+# else
+ __asm__ ("cpuid"
+ : "=a" (uOperator),
+ "=d" (xDX)
+ : "0" (uOperator)
+ : "ebx", "ecx");
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ __cpuid(aInfo, uOperator);
+ xDX = aInfo[3];
+
+# else
+ __asm
+ {
+ push ebx
+ mov eax, [uOperator]
+ cpuid
+ mov [xDX], edx
+ pop ebx
+ }
+# endif
+ return (uint32_t)xDX;
+}
+#endif
+
+
+/**
+ * Checks if the current CPU supports CPUID.
+ *
+ * @returns true if CPUID is supported.
+ */
+DECLINLINE(bool) ASMHasCpuId(void)
+{
+#ifdef RT_ARCH_AMD64
+ return true; /* ASSUME that all amd64 compatible CPUs have cpuid. */
+#else /* !RT_ARCH_AMD64 */
+ bool fRet = false;
+# if RT_INLINE_ASM_GNU_STYLE
+ uint32_t u1;
+ uint32_t u2;
+ __asm__ ("pushf\n\t"
+ "pop %1\n\t"
+ "mov %1, %2\n\t"
+ "xorl $0x200000, %1\n\t"
+ "push %1\n\t"
+ "popf\n\t"
+ "pushf\n\t"
+ "pop %1\n\t"
+ "cmpl %1, %2\n\t"
+ "setne %0\n\t"
+ "push %2\n\t"
+ "popf\n\t"
+ : "=m" (fRet), "=r" (u1), "=r" (u2));
+# else
+ __asm
+ {
+ pushfd
+ pop eax
+ mov ebx, eax
+ xor eax, 0200000h
+ push eax
+ popfd
+ pushfd
+ pop eax
+ cmp eax, ebx
+ setne fRet
+ push ebx
+ popfd
+ }
+# endif
+ return fRet;
+#endif /* !RT_ARCH_AMD64 */
+}
+
+
+/**
+ * Gets the APIC ID of the current CPU.
+ *
+ * @returns the APIC ID.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint8_t) ASMGetApicId(void);
+#else
+DECLINLINE(uint8_t) ASMGetApicId(void)
+{
+ RTCCUINTREG xBX;
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ RTCCUINTREG uSpill;
+ __asm__ __volatile__ ("cpuid"
+ : "=a" (uSpill),
+ "=b" (xBX)
+ : "0" (1)
+ : "rcx", "rdx");
+# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+ RTCCUINTREG uSpill;
+ __asm__ __volatile__ ("mov %%ebx,%1\n\t"
+ "cpuid\n\t"
+ "xchgl %%ebx,%1\n\t"
+ : "=a" (uSpill),
+ "=rm" (xBX)
+ : "0" (1)
+ : "ecx", "edx");
+# else
+ RTCCUINTREG uSpill;
+ __asm__ __volatile__ ("cpuid"
+ : "=a" (uSpill),
+ "=b" (xBX)
+ : "0" (1)
+ : "ecx", "edx");
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ __cpuid(aInfo, 1);
+ xBX = aInfo[1];
+
+# else
+ __asm
+ {
+ push ebx
+ mov eax, 1
+ cpuid
+ mov [xBX], ebx
+ pop ebx
+ }
+# endif
+ return (uint8_t)(xBX >> 24);
+}
+#endif
+
+
+/**
+ * Tests if it a genuine Intel CPU based on the ASMCpuId(0) output.
+ *
+ * @returns true/false.
+ * @param uEBX EBX return from ASMCpuId(0)
+ * @param uECX ECX return from ASMCpuId(0)
+ * @param uEDX EDX return from ASMCpuId(0)
+ */
+DECLINLINE(bool) ASMIsIntelCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
+{
+ return uEBX == UINT32_C(0x756e6547)
+ && uECX == UINT32_C(0x6c65746e)
+ && uEDX == UINT32_C(0x49656e69);
+}
+
+
+/**
+ * Tests if this is a genuine Intel CPU.
+ *
+ * @returns true/false.
+ * @remarks ASSUMES that cpuid is supported by the CPU.
+ */
+DECLINLINE(bool) ASMIsIntelCpu(void)
+{
+ uint32_t uEAX, uEBX, uECX, uEDX;
+ ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
+ return ASMIsIntelCpuEx(uEBX, uECX, uEDX);
+}
+
+
+/**
+ * Tests if it a authentic AMD CPU based on the ASMCpuId(0) output.
+ *
+ * @returns true/false.
+ * @param uEBX EBX return from ASMCpuId(0)
+ * @param uECX ECX return from ASMCpuId(0)
+ * @param uEDX EDX return from ASMCpuId(0)
+ */
+DECLINLINE(bool) ASMIsAmdCpuEx(uint32_t uEBX, uint32_t uECX, uint32_t uEDX)
+{
+ return uEBX == UINT32_C(0x68747541)
+ && uECX == UINT32_C(0x444d4163)
+ && uEDX == UINT32_C(0x69746e65);
+}
+
+
+/**
+ * Tests if this is an authentic AMD CPU.
+ *
+ * @returns true/false.
+ * @remarks ASSUMES that cpuid is supported by the CPU.
+ */
+DECLINLINE(bool) ASMIsAmdCpu(void)
+{
+ uint32_t uEAX, uEBX, uECX, uEDX;
+ ASMCpuId(0, &uEAX, &uEBX, &uECX, &uEDX);
+ return ASMIsAmdCpuEx(uEBX, uECX, uEDX);
+}
+
+
+/**
+ * Extracts the CPU family from ASMCpuId(1) or ASMCpuId(0x80000001)
+ *
+ * @returns Family.
+ * @param uEAX EAX return from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuFamily(uint32_t uEAX)
+{
+ return ((uEAX >> 8) & 0xf) == 0xf
+ ? ((uEAX >> 20) & 0x7f) + 0xf
+ : ((uEAX >> 8) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), Intel variant.
+ *
+ * @returns Model.
+ * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuModelIntel(uint32_t uEAX)
+{
+ return ((uEAX >> 8) & 0xf) == 0xf || (((uEAX >> 8) & 0xf) == 0x6) /* family! */
+ ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
+ : ((uEAX >> 4) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001), AMD variant.
+ *
+ * @returns Model.
+ * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuModelAMD(uint32_t uEAX)
+{
+ return ((uEAX >> 8) & 0xf) == 0xf
+ ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
+ : ((uEAX >> 4) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU model from ASMCpuId(1) or ASMCpuId(0x80000001)
+ *
+ * @returns Model.
+ * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ * @param fIntel Whether it's an intel CPU. Use ASMIsIntelCpuEx() or ASMIsIntelCpu().
+ */
+DECLINLINE(uint32_t) ASMGetCpuModel(uint32_t uEAX, bool fIntel)
+{
+ return ((uEAX >> 8) & 0xf) == 0xf || (((uEAX >> 8) & 0xf) == 0x6 && fIntel) /* family! */
+ ? ((uEAX >> 4) & 0xf) | ((uEAX >> 12) & 0xf0)
+ : ((uEAX >> 4) & 0xf);
+}
+
+
+/**
+ * Extracts the CPU stepping from ASMCpuId(1) or ASMCpuId(0x80000001)
+ *
+ * @returns Model.
+ * @param uEAX EAX from ASMCpuId(1) or ASMCpuId(0x80000001).
+ */
+DECLINLINE(uint32_t) ASMGetCpuStepping(uint32_t uEAX)
+{
+ return uEAX & 0xf;
+}
+
+
+/**
+ * Get cr0.
+ * @returns cr0.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR0(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR0(void)
+{
+ RTCCUINTREG uCR0;
+# if RT_INLINE_ASM_USES_INTRIN
+ uCR0 = __readcr0();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%cr0, %0\t\n" : "=r" (uCR0));
+# else
+ __asm__ __volatile__("movl %%cr0, %0\t\n" : "=r" (uCR0));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, cr0
+ mov [uCR0], rax
+# else
+ mov eax, cr0
+ mov [uCR0], eax
+# endif
+ }
+# endif
+ return uCR0;
+}
+#endif
+
+
+/**
+ * Sets the CR0 register.
+ * @param uCR0 The new CR0 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetCR0(RTCCUINTREG uCR0);
+#else
+DECLINLINE(void) ASMSetCR0(RTCCUINTREG uCR0)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writecr0(uCR0);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%cr0\n\t" :: "r" (uCR0));
+# else
+ __asm__ __volatile__("movl %0, %%cr0\n\t" :: "r" (uCR0));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uCR0]
+ mov cr0, rax
+# else
+ mov eax, [uCR0]
+ mov cr0, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr2.
+ * @returns cr2.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR2(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR2(void)
+{
+ RTCCUINTREG uCR2;
+# if RT_INLINE_ASM_USES_INTRIN
+ uCR2 = __readcr2();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%cr2, %0\t\n" : "=r" (uCR2));
+# else
+ __asm__ __volatile__("movl %%cr2, %0\t\n" : "=r" (uCR2));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, cr2
+ mov [uCR2], rax
+# else
+ mov eax, cr2
+ mov [uCR2], eax
+# endif
+ }
+# endif
+ return uCR2;
+}
+#endif
+
+
+/**
+ * Sets the CR2 register.
+ * @param uCR2 The new CR0 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMSetCR2(RTCCUINTREG uCR2);
+#else
+DECLINLINE(void) ASMSetCR2(RTCCUINTREG uCR2)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%cr2\n\t" :: "r" (uCR2));
+# else
+ __asm__ __volatile__("movl %0, %%cr2\n\t" :: "r" (uCR2));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uCR2]
+ mov cr2, rax
+# else
+ mov eax, [uCR2]
+ mov cr2, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr3.
+ * @returns cr3.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR3(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR3(void)
+{
+ RTCCUINTREG uCR3;
+# if RT_INLINE_ASM_USES_INTRIN
+ uCR3 = __readcr3();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%cr3, %0\t\n" : "=r" (uCR3));
+# else
+ __asm__ __volatile__("movl %%cr3, %0\t\n" : "=r" (uCR3));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, cr3
+ mov [uCR3], rax
+# else
+ mov eax, cr3
+ mov [uCR3], eax
+# endif
+ }
+# endif
+ return uCR3;
+}
+#endif
+
+
+/**
+ * Sets the CR3 register.
+ *
+ * @param uCR3 New CR3 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetCR3(RTCCUINTREG uCR3);
+#else
+DECLINLINE(void) ASMSetCR3(RTCCUINTREG uCR3)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writecr3(uCR3);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%cr3\n\t" : : "r" (uCR3));
+# else
+ __asm__ __volatile__("movl %0, %%cr3\n\t" : : "r" (uCR3));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uCR3]
+ mov cr3, rax
+# else
+ mov eax, [uCR3]
+ mov cr3, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reloads the CR3 register.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMReloadCR3(void);
+#else
+DECLINLINE(void) ASMReloadCR3(void)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writecr3(__readcr3());
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG u;
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%cr3, %0\n\t"
+ "movq %0, %%cr3\n\t"
+ : "=r" (u));
+# else
+ __asm__ __volatile__("movl %%cr3, %0\n\t"
+ "movl %0, %%cr3\n\t"
+ : "=r" (u));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, cr3
+ mov cr3, rax
+# else
+ mov eax, cr3
+ mov cr3, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr4.
+ * @returns cr4.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR4(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR4(void)
+{
+ RTCCUINTREG uCR4;
+# if RT_INLINE_ASM_USES_INTRIN
+ uCR4 = __readcr4();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%cr4, %0\t\n" : "=r" (uCR4));
+# else
+ __asm__ __volatile__("movl %%cr4, %0\t\n" : "=r" (uCR4));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, cr4
+ mov [uCR4], rax
+# else
+ push eax /* just in case */
+ /*mov eax, cr4*/
+ _emit 0x0f
+ _emit 0x20
+ _emit 0xe0
+ mov [uCR4], eax
+ pop eax
+# endif
+ }
+# endif
+ return uCR4;
+}
+#endif
+
+
+/**
+ * Sets the CR4 register.
+ *
+ * @param uCR4 New CR4 value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetCR4(RTCCUINTREG uCR4);
+#else
+DECLINLINE(void) ASMSetCR4(RTCCUINTREG uCR4)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writecr4(uCR4);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%cr4\n\t" : : "r" (uCR4));
+# else
+ __asm__ __volatile__("movl %0, %%cr4\n\t" : : "r" (uCR4));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uCR4]
+ mov cr4, rax
+# else
+ mov eax, [uCR4]
+ _emit 0x0F
+ _emit 0x22
+ _emit 0xE0 /* mov cr4, eax */
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Get cr8.
+ * @returns cr8.
+ * @remark The lock prefix hack for access from non-64-bit modes is NOT used and 0 is returned.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetCR8(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetCR8(void)
+{
+# ifdef RT_ARCH_AMD64
+ RTCCUINTREG uCR8;
+# if RT_INLINE_ASM_USES_INTRIN
+ uCR8 = __readcr8();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movq %%cr8, %0\t\n" : "=r" (uCR8));
+# else
+ __asm
+ {
+ mov rax, cr8
+ mov [uCR8], rax
+ }
+# endif
+ return uCR8;
+# else /* !RT_ARCH_AMD64 */
+ return 0;
+# endif /* !RT_ARCH_AMD64 */
+}
+#endif
+
+
+/**
+ * Enables interrupts (EFLAGS.IF).
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMIntEnable(void);
+#else
+DECLINLINE(void) ASMIntEnable(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm("sti\n");
+# elif RT_INLINE_ASM_USES_INTRIN
+ _enable();
+# else
+ __asm sti
+# endif
+}
+#endif
+
+
+/**
+ * Disables interrupts (!EFLAGS.IF).
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMIntDisable(void);
+#else
+DECLINLINE(void) ASMIntDisable(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm("cli\n");
+# elif RT_INLINE_ASM_USES_INTRIN
+ _disable();
+# else
+ __asm cli
+# endif
+}
+#endif
+
+
+/**
+ * Disables interrupts and returns previous xFLAGS.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMIntDisableFlags(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMIntDisableFlags(void)
+{
+ RTCCUINTREG xFlags;
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("pushfq\n\t"
+ "cli\n\t"
+ "popq %0\n\t"
+ : "=r" (xFlags));
+# else
+ __asm__ __volatile__("pushfl\n\t"
+ "cli\n\t"
+ "popl %0\n\t"
+ : "=r" (xFlags));
+# endif
+# elif RT_INLINE_ASM_USES_INTRIN && !defined(RT_ARCH_X86)
+ xFlags = ASMGetFlags();
+ _disable();
+# else
+ __asm {
+ pushfd
+ cli
+ pop [xFlags]
+ }
+# endif
+ return xFlags;
+}
+#endif
+
+
+/**
+ * Are interrupts enabled?
+ *
+ * @returns true / false.
+ */
+DECLINLINE(RTCCUINTREG) ASMIntAreEnabled(void)
+{
+ RTCCUINTREG uFlags = ASMGetFlags();
+ return uFlags & 0x200 /* X86_EFL_IF */ ? true : false;
+}
+
+
+/**
+ * Halts the CPU until interrupted.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMHalt(void);
+#else
+DECLINLINE(void) ASMHalt(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("hlt\n\t");
+# else
+ __asm {
+ hlt
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a machine specific register.
+ *
+ * @returns Register content.
+ * @param uRegister Register to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMRdMsr(uint32_t uRegister);
+#else
+DECLINLINE(uint64_t) ASMRdMsr(uint32_t uRegister)
+{
+ RTUINT64U u;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rdmsr\n\t"
+ : "=a" (u.s.Lo),
+ "=d" (u.s.Hi)
+ : "c" (uRegister));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ u.u = __readmsr(uRegister);
+
+# else
+ __asm
+ {
+ mov ecx, [uRegister]
+ rdmsr
+ mov [u.s.Lo], eax
+ mov [u.s.Hi], edx
+ }
+# endif
+
+ return u.u;
+}
+#endif
+
+
+/**
+ * Writes a machine specific register.
+ *
+ * @returns Register content.
+ * @param uRegister Register to write to.
+ * @param u64Val Value to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val);
+#else
+DECLINLINE(void) ASMWrMsr(uint32_t uRegister, uint64_t u64Val)
+{
+ RTUINT64U u;
+
+ u.u = u64Val;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("wrmsr\n\t"
+ ::"a" (u.s.Lo),
+ "d" (u.s.Hi),
+ "c" (uRegister));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __writemsr(uRegister, u.u);
+
+# else
+ __asm
+ {
+ mov ecx, [uRegister]
+ mov edx, [u.s.Hi]
+ mov eax, [u.s.Lo]
+ wrmsr
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads low part of a machine specific register.
+ *
+ * @returns Register content.
+ * @param uRegister Register to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMRdMsr_Low(uint32_t uRegister);
+#else
+DECLINLINE(uint32_t) ASMRdMsr_Low(uint32_t uRegister)
+{
+ uint32_t u32;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rdmsr\n\t"
+ : "=a" (u32)
+ : "c" (uRegister)
+ : "edx");
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ u32 = (uint32_t)__readmsr(uRegister);
+
+#else
+ __asm
+ {
+ mov ecx, [uRegister]
+ rdmsr
+ mov [u32], eax
+ }
+# endif
+
+ return u32;
+}
+#endif
+
+
+/**
+ * Reads high part of a machine specific register.
+ *
+ * @returns Register content.
+ * @param uRegister Register to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMRdMsr_High(uint32_t uRegister);
+#else
+DECLINLINE(uint32_t) ASMRdMsr_High(uint32_t uRegister)
+{
+ uint32_t u32;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rdmsr\n\t"
+ : "=d" (u32)
+ : "c" (uRegister)
+ : "eax");
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ u32 = (uint32_t)(__readmsr(uRegister) >> 32);
+
+# else
+ __asm
+ {
+ mov ecx, [uRegister]
+ rdmsr
+ mov [u32], edx
+ }
+# endif
+
+ return u32;
+}
+#endif
+
+
+/**
+ * Gets dr0.
+ *
+ * @returns dr0.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR0(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR0(void)
+{
+ RTCCUINTREG uDR0;
+# if RT_INLINE_ASM_USES_INTRIN
+ uDR0 = __readdr(0);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%dr0, %0\n\t" : "=r" (uDR0));
+# else
+ __asm__ __volatile__("movl %%dr0, %0\n\t" : "=r" (uDR0));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, dr0
+ mov [uDR0], rax
+# else
+ mov eax, dr0
+ mov [uDR0], eax
+# endif
+ }
+# endif
+ return uDR0;
+}
+#endif
+
+
+/**
+ * Gets dr1.
+ *
+ * @returns dr1.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR1(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR1(void)
+{
+ RTCCUINTREG uDR1;
+# if RT_INLINE_ASM_USES_INTRIN
+ uDR1 = __readdr(1);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%dr1, %0\n\t" : "=r" (uDR1));
+# else
+ __asm__ __volatile__("movl %%dr1, %0\n\t" : "=r" (uDR1));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, dr1
+ mov [uDR1], rax
+# else
+ mov eax, dr1
+ mov [uDR1], eax
+# endif
+ }
+# endif
+ return uDR1;
+}
+#endif
+
+
+/**
+ * Gets dr2.
+ *
+ * @returns dr2.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR2(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR2(void)
+{
+ RTCCUINTREG uDR2;
+# if RT_INLINE_ASM_USES_INTRIN
+ uDR2 = __readdr(2);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%dr2, %0\n\t" : "=r" (uDR2));
+# else
+ __asm__ __volatile__("movl %%dr2, %0\n\t" : "=r" (uDR2));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, dr2
+ mov [uDR2], rax
+# else
+ mov eax, dr2
+ mov [uDR2], eax
+# endif
+ }
+# endif
+ return uDR2;
+}
+#endif
+
+
+/**
+ * Gets dr3.
+ *
+ * @returns dr3.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR3(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR3(void)
+{
+ RTCCUINTREG uDR3;
+# if RT_INLINE_ASM_USES_INTRIN
+ uDR3 = __readdr(3);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%dr3, %0\n\t" : "=r" (uDR3));
+# else
+ __asm__ __volatile__("movl %%dr3, %0\n\t" : "=r" (uDR3));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, dr3
+ mov [uDR3], rax
+# else
+ mov eax, dr3
+ mov [uDR3], eax
+# endif
+ }
+# endif
+ return uDR3;
+}
+#endif
+
+
+/**
+ * Gets dr6.
+ *
+ * @returns dr6.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR6(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR6(void)
+{
+ RTCCUINTREG uDR6;
+# if RT_INLINE_ASM_USES_INTRIN
+ uDR6 = __readdr(6);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%dr6, %0\n\t" : "=r" (uDR6));
+# else
+ __asm__ __volatile__("movl %%dr6, %0\n\t" : "=r" (uDR6));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, dr6
+ mov [uDR6], rax
+# else
+ mov eax, dr6
+ mov [uDR6], eax
+# endif
+ }
+# endif
+ return uDR6;
+}
+#endif
+
+
+/**
+ * Reads and clears DR6.
+ *
+ * @returns DR6.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetAndClearDR6(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetAndClearDR6(void)
+{
+ RTCCUINTREG uDR6;
+# if RT_INLINE_ASM_USES_INTRIN
+ uDR6 = __readdr(6);
+ __writedr(6, 0xffff0ff0U); /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
+# elif RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG uNewValue = 0xffff0ff0U;/* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%dr6, %0\n\t"
+ "movq %1, %%dr6\n\t"
+ : "=r" (uDR6)
+ : "r" (uNewValue));
+# else
+ __asm__ __volatile__("movl %%dr6, %0\n\t"
+ "movl %1, %%dr6\n\t"
+ : "=r" (uDR6)
+ : "r" (uNewValue));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, dr6
+ mov [uDR6], rax
+ mov rcx, rax
+ mov ecx, 0ffff0ff0h; /* 31-16 and 4-11 are 1's, 12 and 63-31 are zero. */
+ mov dr6, rcx
+# else
+ mov eax, dr6
+ mov [uDR6], eax
+ mov ecx, 0ffff0ff0h; /* 31-16 and 4-11 are 1's, 12 is zero. */
+ mov dr6, ecx
+# endif
+ }
+# endif
+ return uDR6;
+}
+#endif
+
+
+/**
+ * Gets dr7.
+ *
+ * @returns dr7.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(RTCCUINTREG) ASMGetDR7(void);
+#else
+DECLINLINE(RTCCUINTREG) ASMGetDR7(void)
+{
+ RTCCUINTREG uDR7;
+# if RT_INLINE_ASM_USES_INTRIN
+ uDR7 = __readdr(7);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %%dr7, %0\n\t" : "=r" (uDR7));
+# else
+ __asm__ __volatile__("movl %%dr7, %0\n\t" : "=r" (uDR7));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, dr7
+ mov [uDR7], rax
+# else
+ mov eax, dr7
+ mov [uDR7], eax
+# endif
+ }
+# endif
+ return uDR7;
+}
+#endif
+
+
+/**
+ * Sets dr0.
+ *
+ * @param uDRVal Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR0(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR0(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writedr(0, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%dr0\n\t" : : "r" (uDRVal));
+# else
+ __asm__ __volatile__("movl %0, %%dr0\n\t" : : "r" (uDRVal));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uDRVal]
+ mov dr0, rax
+# else
+ mov eax, [uDRVal]
+ mov dr0, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr1.
+ *
+ * @param uDRVal Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR1(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR1(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writedr(1, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%dr1\n\t" : : "r" (uDRVal));
+# else
+ __asm__ __volatile__("movl %0, %%dr1\n\t" : : "r" (uDRVal));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uDRVal]
+ mov dr1, rax
+# else
+ mov eax, [uDRVal]
+ mov dr1, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr2.
+ *
+ * @param uDRVal Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR2(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR2(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writedr(2, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%dr2\n\t" : : "r" (uDRVal));
+# else
+ __asm__ __volatile__("movl %0, %%dr2\n\t" : : "r" (uDRVal));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uDRVal]
+ mov dr2, rax
+# else
+ mov eax, [uDRVal]
+ mov dr2, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr3.
+ *
+ * @param uDRVal Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR3(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR3(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writedr(3, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%dr3\n\t" : : "r" (uDRVal));
+# else
+ __asm__ __volatile__("movl %0, %%dr3\n\t" : : "r" (uDRVal));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uDRVal]
+ mov dr3, rax
+# else
+ mov eax, [uDRVal]
+ mov dr3, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr6.
+ *
+ * @param uDRVal Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR6(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR6(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writedr(6, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%dr6\n\t" : : "r" (uDRVal));
+# else
+ __asm__ __volatile__("movl %0, %%dr6\n\t" : : "r" (uDRVal));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uDRVal]
+ mov dr6, rax
+# else
+ mov eax, [uDRVal]
+ mov dr6, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Sets dr7.
+ *
+ * @param uDRVal Debug register value to write
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSetDR7(RTCCUINTREG uDRVal);
+#else
+DECLINLINE(void) ASMSetDR7(RTCCUINTREG uDRVal)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __writedr(7, uDRVal);
+# elif RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("movq %0, %%dr7\n\t" : : "r" (uDRVal));
+# else
+ __asm__ __volatile__("movl %0, %%dr7\n\t" : : "r" (uDRVal));
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [uDRVal]
+ mov dr7, rax
+# else
+ mov eax, [uDRVal]
+ mov dr7, eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Writes a 8-bit unsigned integer to an I/O port, ordered.
+ *
+ * @param Port I/O port to write to.
+ * @param u8 8-bit integer to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutU8(RTIOPORT Port, uint8_t u8);
+#else
+DECLINLINE(void) ASMOutU8(RTIOPORT Port, uint8_t u8)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("outb %b1, %w0\n\t"
+ :: "Nd" (Port),
+ "a" (u8));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __outbyte(Port, u8);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov al, [u8]
+ out dx, al
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a 8-bit unsigned integer from an I/O port, ordered.
+ *
+ * @returns 8-bit integer.
+ * @param Port I/O port to read from.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint8_t) ASMInU8(RTIOPORT Port);
+#else
+DECLINLINE(uint8_t) ASMInU8(RTIOPORT Port)
+{
+ uint8_t u8;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("inb %w1, %b0\n\t"
+ : "=a" (u8)
+ : "Nd" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ u8 = __inbyte(Port);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ in al, dx
+ mov [u8], al
+ }
+# endif
+ return u8;
+}
+#endif
+
+
+/**
+ * Writes a 16-bit unsigned integer to an I/O port, ordered.
+ *
+ * @param Port I/O port to write to.
+ * @param u16 16-bit integer to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutU16(RTIOPORT Port, uint16_t u16);
+#else
+DECLINLINE(void) ASMOutU16(RTIOPORT Port, uint16_t u16)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("outw %w1, %w0\n\t"
+ :: "Nd" (Port),
+ "a" (u16));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __outword(Port, u16);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov ax, [u16]
+ out dx, ax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a 16-bit unsigned integer from an I/O port, ordered.
+ *
+ * @returns 16-bit integer.
+ * @param Port I/O port to read from.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint16_t) ASMInU16(RTIOPORT Port);
+#else
+DECLINLINE(uint16_t) ASMInU16(RTIOPORT Port)
+{
+ uint16_t u16;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("inw %w1, %w0\n\t"
+ : "=a" (u16)
+ : "Nd" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ u16 = __inword(Port);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ in ax, dx
+ mov [u16], ax
+ }
+# endif
+ return u16;
+}
+#endif
+
+
+/**
+ * Writes a 32-bit unsigned integer to an I/O port, ordered.
+ *
+ * @param Port I/O port to write to.
+ * @param u32 32-bit integer to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutU32(RTIOPORT Port, uint32_t u32);
+#else
+DECLINLINE(void) ASMOutU32(RTIOPORT Port, uint32_t u32)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("outl %1, %w0\n\t"
+ :: "Nd" (Port),
+ "a" (u32));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __outdword(Port, u32);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov eax, [u32]
+ out dx, eax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a 32-bit unsigned integer from an I/O port, ordered.
+ *
+ * @returns 32-bit integer.
+ * @param Port I/O port to read from.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMInU32(RTIOPORT Port);
+#else
+DECLINLINE(uint32_t) ASMInU32(RTIOPORT Port)
+{
+ uint32_t u32;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("inl %w1, %0\n\t"
+ : "=a" (u32)
+ : "Nd" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ u32 = __indword(Port);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ in eax, dx
+ mov [u32], eax
+ }
+# endif
+ return u32;
+}
+#endif
+
+
+/**
+ * Writes a string of 8-bit unsigned integer items to an I/O port, ordered.
+ *
+ * @param Port I/O port to write to.
+ * @param pau8 Pointer to the string buffer.
+ * @param c The number of items to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutStrU8(RTIOPORT Port, uint8_t const *pau8, size_t c);
+#else
+DECLINLINE(void) ASMOutStrU8(RTIOPORT Port, uint8_t const *pau8, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep; outsb\n\t"
+ : "+S" (pau8),
+ "+c" (c)
+ : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __outbytestring(Port, (unsigned char *)pau8, (unsigned long)c);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov ecx, [c]
+ mov eax, [pau8]
+ xchg esi, eax
+ rep outsb
+ xchg esi, eax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a string of 8-bit unsigned integer items from an I/O port, ordered.
+ *
+ * @param Port I/O port to read from.
+ * @param pau8 Pointer to the string buffer (output).
+ * @param c The number of items to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInStrU8(RTIOPORT Port, uint8_t *pau8, size_t c);
+#else
+DECLINLINE(void) ASMInStrU8(RTIOPORT Port, uint8_t *pau8, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep; insb\n\t"
+ : "+D" (pau8),
+ "+c" (c)
+ : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __inbytestring(Port, pau8, (unsigned long)c);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov ecx, [c]
+ mov eax, [pau8]
+ xchg edi, eax
+ rep insb
+ xchg edi, eax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Writes a string of 16-bit unsigned integer items to an I/O port, ordered.
+ *
+ * @param Port I/O port to write to.
+ * @param pau16 Pointer to the string buffer.
+ * @param c The number of items to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutStrU16(RTIOPORT Port, uint16_t const *pau16, size_t c);
+#else
+DECLINLINE(void) ASMOutStrU16(RTIOPORT Port, uint16_t const *pau16, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep; outsw\n\t"
+ : "+S" (pau16),
+ "+c" (c)
+ : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __outwordstring(Port, (unsigned short *)pau16, (unsigned long)c);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov ecx, [c]
+ mov eax, [pau16]
+ xchg esi, eax
+ rep outsw
+ xchg esi, eax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a string of 16-bit unsigned integer items from an I/O port, ordered.
+ *
+ * @param Port I/O port to read from.
+ * @param pau16 Pointer to the string buffer (output).
+ * @param c The number of items to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInStrU16(RTIOPORT Port, uint16_t *pau16, size_t c);
+#else
+DECLINLINE(void) ASMInStrU16(RTIOPORT Port, uint16_t *pau16, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep; insw\n\t"
+ : "+D" (pau16),
+ "+c" (c)
+ : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __inwordstring(Port, pau16, (unsigned long)c);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov ecx, [c]
+ mov eax, [pau16]
+ xchg edi, eax
+ rep insw
+ xchg edi, eax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Writes a string of 32-bit unsigned integer items to an I/O port, ordered.
+ *
+ * @param Port I/O port to write to.
+ * @param pau32 Pointer to the string buffer.
+ * @param c The number of items to write.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMOutStrU32(RTIOPORT Port, uint32_t const *pau32, size_t c);
+#else
+DECLINLINE(void) ASMOutStrU32(RTIOPORT Port, uint32_t const *pau32, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep; outsl\n\t"
+ : "+S" (pau32),
+ "+c" (c)
+ : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __outdwordstring(Port, (unsigned long *)pau32, (unsigned long)c);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov ecx, [c]
+ mov eax, [pau32]
+ xchg esi, eax
+ rep outsd
+ xchg esi, eax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Reads a string of 32-bit unsigned integer items from an I/O port, ordered.
+ *
+ * @param Port I/O port to read from.
+ * @param pau32 Pointer to the string buffer (output).
+ * @param c The number of items to read.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInStrU32(RTIOPORT Port, uint32_t *pau32, size_t c);
+#else
+DECLINLINE(void) ASMInStrU32(RTIOPORT Port, uint32_t *pau32, size_t c)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep; insl\n\t"
+ : "+D" (pau32),
+ "+c" (c)
+ : "d" (Port));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ __indwordstring(Port, (unsigned long *)pau32, (unsigned long)c);
+
+# else
+ __asm
+ {
+ mov dx, [Port]
+ mov ecx, [c]
+ mov eax, [pau32]
+ xchg edi, eax
+ rep insd
+ xchg edi, eax
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Invalidate page.
+ *
+ * @param pv Address of the page to invalidate.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMInvalidatePage(void *pv);
+#else
+DECLINLINE(void) ASMInvalidatePage(void *pv)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __invlpg(pv);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("invlpg %0\n\t"
+ : : "m" (*(uint8_t *)pv));
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pv]
+ invlpg [rax]
+# else
+ mov eax, [pv]
+ invlpg [eax]
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Write back the internal caches and invalidate them.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMWriteBackAndInvalidateCaches(void);
+#else
+DECLINLINE(void) ASMWriteBackAndInvalidateCaches(void)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ __wbinvd();
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("wbinvd");
+# else
+ __asm
+ {
+ wbinvd
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Invalidate internal and (perhaps) external caches without first
+ * flushing dirty cache lines. Use with extreme care.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMInvalidateInternalCaches(void);
+#else
+DECLINLINE(void) ASMInvalidateInternalCaches(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("invd");
+# else
+ __asm
+ {
+ invd
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Memory load/store fence, waits for any pending writes and reads to complete.
+ * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
+ */
+DECLINLINE(void) ASMMemoryFenceSSE2(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (".byte 0x0f,0xae,0xf0\n\t");
+#elif RT_INLINE_ASM_USES_INTRIN
+ _mm_mfence();
+#else
+ __asm
+ {
+ _emit 0x0f
+ _emit 0xae
+ _emit 0xf0
+ }
+#endif
+}
+
+
+/**
+ * Memory store fence, waits for any writes to complete.
+ * Requires the X86_CPUID_FEATURE_EDX_SSE CPUID bit set.
+ */
+DECLINLINE(void) ASMWriteFenceSSE(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (".byte 0x0f,0xae,0xf8\n\t");
+#elif RT_INLINE_ASM_USES_INTRIN
+ _mm_sfence();
+#else
+ __asm
+ {
+ _emit 0x0f
+ _emit 0xae
+ _emit 0xf8
+ }
+#endif
+}
+
+
+/**
+ * Memory load fence, waits for any pending reads to complete.
+ * Requires the X86_CPUID_FEATURE_EDX_SSE2 CPUID bit set.
+ */
+DECLINLINE(void) ASMReadFenceSSE2(void)
+{
+#if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__ (".byte 0x0f,0xae,0xe8\n\t");
+#elif RT_INLINE_ASM_USES_INTRIN
+ _mm_lfence();
+#else
+ __asm
+ {
+ _emit 0x0f
+ _emit 0xae
+ _emit 0xe8
+ }
+#endif
+}
+
+/** @} */
+#endif
+
diff --git a/include/iprt/asm-math.h b/include/iprt/asm-math.h
new file mode 100644
index 00000000..a3acdf1e
--- /dev/null
+++ b/include/iprt/asm-math.h
@@ -0,0 +1,319 @@
+/** @file
+ * IPRT - Assembly Routines for Optimizing some Integers Math Operations.
+ */
+
+/*
+ * 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 ___iprt_asm_math_h
+#define ___iprt_asm_math_h
+
+#include <iprt/types.h>
+
+
+/** @defgroup grp_rt_asm_math Interger Math Optimizations
+ * @ingroup grp_rt_asm
+ * @{ */
+
+/**
+ * Multiplies two unsigned 32-bit values returning an unsigned 64-bit result.
+ *
+ * @returns u32F1 * u32F2.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(uint64_t) ASMMult2xU32RetU64(uint32_t u32F1, uint32_t u32F2);
+#else
+DECLINLINE(uint64_t) ASMMult2xU32RetU64(uint32_t u32F1, uint32_t u32F2)
+{
+# ifdef RT_ARCH_X86
+ uint64_t u64;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("mull %%edx"
+ : "=A" (u64)
+ : "a" (u32F2), "d" (u32F1));
+# else
+ __asm
+ {
+ mov edx, [u32F1]
+ mov eax, [u32F2]
+ mul edx
+ mov dword ptr [u64], eax
+ mov dword ptr [u64 + 4], edx
+ }
+# endif
+ return u64;
+# else /* generic: */
+ return (uint64_t)u32F1 * u32F2;
+# endif
+}
+#endif
+
+
+/**
+ * Multiplies two signed 32-bit values returning a signed 64-bit result.
+ *
+ * @returns u32F1 * u32F2.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(int64_t) ASMMult2xS32RetS64(int32_t i32F1, int32_t i32F2);
+#else
+DECLINLINE(int64_t) ASMMult2xS32RetS64(int32_t i32F1, int32_t i32F2)
+{
+# ifdef RT_ARCH_X86
+ int64_t i64;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("imull %%edx"
+ : "=A" (i64)
+ : "a" (i32F2), "d" (i32F1));
+# else
+ __asm
+ {
+ mov edx, [i32F1]
+ mov eax, [i32F2]
+ imul edx
+ mov dword ptr [i64], eax
+ mov dword ptr [i64 + 4], edx
+ }
+# endif
+ return i64;
+# else /* generic: */
+ return (int64_t)i32F1 * i32F2;
+# endif
+}
+#endif
+
+
+/**
+ * Divides a 64-bit unsigned by a 32-bit unsigned returning an unsigned 32-bit result.
+ *
+ * @returns u64 / u32.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(uint32_t) ASMDivU64ByU32RetU32(uint64_t u64, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMDivU64ByU32RetU32(uint64_t u64, uint32_t u32)
+{
+# ifdef RT_ARCH_X86
+# if RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG uDummy;
+ __asm__ __volatile__("divl %3"
+ : "=a" (u32), "=d"(uDummy)
+ : "A" (u64), "r" (u32));
+# else
+ __asm
+ {
+ mov eax, dword ptr [u64]
+ mov edx, dword ptr [u64 + 4]
+ mov ecx, [u32]
+ div ecx
+ mov [u32], eax
+ }
+# endif
+ return u32;
+# else /* generic: */
+ return (uint32_t)(u64 / u32);
+# endif
+}
+#endif
+
+
+/**
+ * Divides a 64-bit signed by a 32-bit signed returning a signed 32-bit result.
+ *
+ * @returns u64 / u32.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(int32_t) ASMDivS64ByS32RetS32(int64_t i64, int32_t i32);
+#else
+DECLINLINE(int32_t) ASMDivS64ByS32RetS32(int64_t i64, int32_t i32)
+{
+# ifdef RT_ARCH_X86
+# if RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG iDummy;
+ __asm__ __volatile__("idivl %3"
+ : "=a" (i32), "=d"(iDummy)
+ : "A" (i64), "r" (i32));
+# else
+ __asm
+ {
+ mov eax, dword ptr [i64]
+ mov edx, dword ptr [i64 + 4]
+ mov ecx, [i32]
+ idiv ecx
+ mov [i32], eax
+ }
+# endif
+ return i32;
+# else /* generic: */
+ return (int32_t)(i64 / i32);
+# endif
+}
+#endif
+
+
+/**
+ * Performs 64-bit unsigned by a 32-bit unsigned division with a 32-bit unsigned result,
+ * returning the rest.
+ *
+ * @returns u64 % u32.
+ *
+ * @remarks It is important that the result is <= UINT32_MAX or we'll overflow and crash.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(uint32_t) ASMModU64ByU32RetU32(uint64_t u64, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMModU64ByU32RetU32(uint64_t u64, uint32_t u32)
+{
+# ifdef RT_ARCH_X86
+# if RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG uDummy;
+ __asm__ __volatile__("divl %3"
+ : "=a" (uDummy), "=d"(u32)
+ : "A" (u64), "r" (u32));
+# else
+ __asm
+ {
+ mov eax, dword ptr [u64]
+ mov edx, dword ptr [u64 + 4]
+ mov ecx, [u32]
+ div ecx
+ mov [u32], edx
+ }
+# endif
+ return u32;
+# else /* generic: */
+ return (uint32_t)(u64 % u32);
+# endif
+}
+#endif
+
+
+/**
+ * Performs 64-bit signed by a 32-bit signed division with a 32-bit signed result,
+ * returning the rest.
+ *
+ * @returns u64 % u32.
+ *
+ * @remarks It is important that the result is <= UINT32_MAX or we'll overflow and crash.
+ */
+#if RT_INLINE_ASM_EXTERNAL && defined(RT_ARCH_X86)
+DECLASM(int32_t) ASMModS64ByS32RetS32(int64_t i64, int32_t i32);
+#else
+DECLINLINE(int32_t) ASMModS64ByS32RetS32(int64_t i64, int32_t i32)
+{
+# ifdef RT_ARCH_X86
+# if RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG iDummy;
+ __asm__ __volatile__("idivl %3"
+ : "=a" (iDummy), "=d"(i32)
+ : "A" (i64), "r" (i32));
+# else
+ __asm
+ {
+ mov eax, dword ptr [i64]
+ mov edx, dword ptr [i64 + 4]
+ mov ecx, [i32]
+ idiv ecx
+ mov [i32], edx
+ }
+# endif
+ return i32;
+# else /* generic: */
+ return (int32_t)(i64 % i32);
+# endif
+}
+#endif
+
+
+/**
+ * Multiple a 64-bit by a 32-bit integer and divide the result by a 32-bit integer
+ * using a 96 bit intermediate result.
+ * @note Don't use 64-bit C arithmetic here since some gcc compilers generate references to
+ * __udivdi3 and __umoddi3 even if this inline function is not used.
+ *
+ * @returns (u64A * u32B) / u32C.
+ * @param u64A The 64-bit value.
+ * @param u32B The 32-bit value to multiple by A.
+ * @param u32C The 32-bit value to divide A*B by.
+ *
+ * @remarks Architecture specific.
+ */
+#if RT_INLINE_ASM_EXTERNAL || !defined(__GNUC__) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
+DECLASM(uint64_t) ASMMultU64ByU32DivByU32(uint64_t u64A, uint32_t u32B, uint32_t u32C);
+#else
+DECLINLINE(uint64_t) ASMMultU64ByU32DivByU32(uint64_t u64A, uint32_t u32B, uint32_t u32C)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+# ifdef RT_ARCH_AMD64
+ uint64_t u64Result, u64Spill;
+ __asm__ __volatile__("mulq %2\n\t"
+ "divq %3\n\t"
+ : "=a" (u64Result),
+ "=d" (u64Spill)
+ : "r" ((uint64_t)u32B),
+ "r" ((uint64_t)u32C),
+ "0" (u64A),
+ "1" (0));
+ return u64Result;
+# else
+ uint32_t u32Dummy;
+ uint64_t u64Result;
+ __asm__ __volatile__("mull %%ecx \n\t" /* eax = u64Lo.lo = (u64A.lo * u32B).lo
+ edx = u64Lo.hi = (u64A.lo * u32B).hi */
+ "xchg %%eax,%%esi \n\t" /* esi = u64Lo.lo
+ eax = u64A.hi */
+ "xchg %%edx,%%edi \n\t" /* edi = u64Low.hi
+ edx = u32C */
+ "xchg %%edx,%%ecx \n\t" /* ecx = u32C
+ edx = u32B */
+ "mull %%edx \n\t" /* eax = u64Hi.lo = (u64A.hi * u32B).lo
+ edx = u64Hi.hi = (u64A.hi * u32B).hi */
+ "addl %%edi,%%eax \n\t" /* u64Hi.lo += u64Lo.hi */
+ "adcl $0,%%edx \n\t" /* u64Hi.hi += carry */
+ "divl %%ecx \n\t" /* eax = u64Hi / u32C
+ edx = u64Hi % u32C */
+ "movl %%eax,%%edi \n\t" /* edi = u64Result.hi = u64Hi / u32C */
+ "movl %%esi,%%eax \n\t" /* eax = u64Lo.lo */
+ "divl %%ecx \n\t" /* u64Result.lo */
+ "movl %%edi,%%edx \n\t" /* u64Result.hi */
+ : "=A"(u64Result), "=c"(u32Dummy),
+ "=S"(u32Dummy), "=D"(u32Dummy)
+ : "a"((uint32_t)u64A),
+ "S"((uint32_t)(u64A >> 32)),
+ "c"(u32B),
+ "D"(u32C));
+ return u64Result;
+# endif
+# else
+ RTUINT64U u;
+ uint64_t u64Lo = (uint64_t)(u64A & 0xffffffff) * u32B;
+ uint64_t u64Hi = (uint64_t)(u64A >> 32) * u32B;
+ u64Hi += (u64Lo >> 32);
+ u.s.Hi = (uint32_t)(u64Hi / u32C);
+ u.s.Lo = (uint32_t)((((u64Hi % u32C) << 32) + (u64Lo & 0xffffffff)) / u32C);
+ return u.u;
+# endif
+}
+#endif
+
+/** @} */
+#endif
+
diff --git a/include/iprt/asm.h b/include/iprt/asm.h
new file mode 100644
index 00000000..abaef3a0
--- /dev/null
+++ b/include/iprt/asm.h
@@ -0,0 +1,4643 @@
+/** @file
+ * IPRT - Assembly Functions.
+ */
+
+/*
+ * 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 ___iprt_asm_h
+#define ___iprt_asm_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+/** @def RT_INLINE_ASM_USES_INTRIN
+ * Defined as 1 if we're using a _MSC_VER 1400.
+ * Otherwise defined as 0.
+ */
+
+/* Solaris 10 header ugliness */
+#ifdef u
+# undef u
+#endif
+
+#if defined(_MSC_VER) && RT_INLINE_ASM_USES_INTRIN
+# include <intrin.h>
+ /* Emit the intrinsics at all optimization levels. */
+# pragma intrinsic(_ReadWriteBarrier)
+# pragma intrinsic(__cpuid)
+# pragma intrinsic(__stosd)
+# pragma intrinsic(__stosw)
+# pragma intrinsic(__stosb)
+# pragma intrinsic(_BitScanForward)
+# pragma intrinsic(_BitScanReverse)
+# pragma intrinsic(_bittest)
+# pragma intrinsic(_bittestandset)
+# pragma intrinsic(_bittestandreset)
+# pragma intrinsic(_bittestandcomplement)
+# pragma intrinsic(_byteswap_ushort)
+# pragma intrinsic(_byteswap_ulong)
+# pragma intrinsic(_interlockedbittestandset)
+# pragma intrinsic(_interlockedbittestandreset)
+# pragma intrinsic(_InterlockedAnd)
+# pragma intrinsic(_InterlockedOr)
+# pragma intrinsic(_InterlockedIncrement)
+# pragma intrinsic(_InterlockedDecrement)
+# pragma intrinsic(_InterlockedExchange)
+# pragma intrinsic(_InterlockedExchangeAdd)
+# pragma intrinsic(_InterlockedCompareExchange)
+# pragma intrinsic(_InterlockedCompareExchange64)
+# ifdef RT_ARCH_AMD64
+# pragma intrinsic(__stosq)
+# pragma intrinsic(_byteswap_uint64)
+# pragma intrinsic(_InterlockedExchange64)
+# pragma intrinsic(_InterlockedExchangeAdd64)
+# pragma intrinsic(_InterlockedAnd64)
+# pragma intrinsic(_InterlockedOr64)
+# pragma intrinsic(_InterlockedIncrement64)
+# pragma intrinsic(_InterlockedDecrement64)
+# endif
+#endif
+
+
+/** @defgroup grp_rt_asm ASM - Assembly Routines
+ * @ingroup grp_rt
+ *
+ * @remarks The difference between ordered and unordered atomic operations are that
+ * the former will complete outstanding reads and writes before continuing
+ * while the latter doesn't make any promises about the order. Ordered
+ * operations doesn't, it seems, make any 100% promise wrt to whether
+ * the operation will complete before any subsequent memory access.
+ * (please, correct if wrong.)
+ *
+ * ASMAtomicSomething operations are all ordered, while ASMAtomicUoSomething
+ * are unordered (note the Uo).
+ *
+ * @remarks Some remarks about __volatile__: Without this keyword gcc is allowed to reorder
+ * or even optimize assembler instructions away. For instance, in the following code
+ * the second rdmsr instruction is optimized away because gcc treats that instruction
+ * as deterministic:
+ *
+ * @code
+ * static inline uint64_t rdmsr_low(int idx)
+ * {
+ * uint32_t low;
+ * __asm__ ("rdmsr" : "=a"(low) : "c"(idx) : "edx");
+ * }
+ * ...
+ * uint32_t msr1 = rdmsr_low(1);
+ * foo(msr1);
+ * msr1 = rdmsr_low(1);
+ * bar(msr1);
+ * @endcode
+ *
+ * The input parameter of rdmsr_low is the same for both calls and therefore gcc will
+ * use the result of the first call as input parameter for bar() as well. For rdmsr this
+ * is not acceptable as this instruction is _not_ deterministic. This applies to reading
+ * machine status information in general.
+ *
+ * @{
+ */
+
+
+/** @def RT_INLINE_ASM_GCC_4_3_X_X86
+ * Used to work around some 4.3.x register allocation issues in this version of
+ * the compiler. So far this workaround is still required for 4.4 and 4.5. */
+#ifdef __GNUC__
+# define RT_INLINE_ASM_GCC_4_3_X_X86 (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 && defined(__i386__))
+#endif
+#ifndef RT_INLINE_ASM_GCC_4_3_X_X86
+# define RT_INLINE_ASM_GCC_4_3_X_X86 0
+#endif
+
+/** @def RT_INLINE_DONT_USE_CMPXCHG8B
+ * i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5493) screws up
+ * RTSemRWRequestWrite semsemrw-lockless-generic.cpp in release builds. PIC
+ * mode, x86.
+ *
+ * Some gcc 4.3.x versions may have register allocation issues with cmpxchg8b
+ * when in PIC mode on x86.
+ */
+#ifndef RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+# define RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC \
+ ( (defined(PIC) || defined(__PIC__)) \
+ && defined(RT_ARCH_X86) \
+ && ( RT_INLINE_ASM_GCC_4_3_X_X86 \
+ || defined(RT_OS_DARWIN)) )
+#endif
+
+
+/** @def ASMReturnAddress
+ * Gets the return address of the current (or calling if you like) function or method.
+ */
+#ifdef _MSC_VER
+# ifdef __cplusplus
+extern "C"
+# endif
+void * _ReturnAddress(void);
+# pragma intrinsic(_ReturnAddress)
+# define ASMReturnAddress() _ReturnAddress()
+#elif defined(__GNUC__) || defined(DOXYGEN_RUNNING)
+# define ASMReturnAddress() __builtin_return_address(0)
+#else
+# error "Unsupported compiler."
+#endif
+
+
+/**
+ * Compiler memory barrier.
+ *
+ * Ensure that the compiler does not use any cached (register/tmp stack) memory
+ * values or any outstanding writes when returning from this function.
+ *
+ * This function must be used if non-volatile data is modified by a
+ * device or the VMM. Typical cases are port access, MMIO access,
+ * trapping instruction, etc.
+ */
+#if RT_INLINE_ASM_GNU_STYLE
+# define ASMCompilerBarrier() do { __asm__ __volatile__("" : : : "memory"); } while (0)
+#elif RT_INLINE_ASM_USES_INTRIN
+# define ASMCompilerBarrier() do { _ReadWriteBarrier(); } while (0)
+#else /* 2003 should have _ReadWriteBarrier() but I guess we're at 2002 level then... */
+DECLINLINE(void) ASMCompilerBarrier(void)
+{
+ __asm
+ {
+ }
+}
+#endif
+
+
+/** @def ASMBreakpoint
+ * Debugger Breakpoint.
+ * @deprecated Use RT_BREAKPOINT instead.
+ * @internal
+ */
+#define ASMBreakpoint() RT_BREAKPOINT()
+
+
+/**
+ * Spinloop hint for platforms that have these, empty function on the other
+ * platforms.
+ *
+ * x86 & AMD64: The PAUSE variant of NOP for helping hyperthreaded CPUs detecting
+ * spin locks.
+ */
+#if RT_INLINE_ASM_EXTERNAL && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+DECLASM(void) ASMNopPause(void);
+#else
+DECLINLINE(void) ASMNopPause(void)
+{
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__(".byte 0xf3,0x90\n\t");
+# else
+ __asm {
+ _emit 0f3h
+ _emit 090h
+ }
+# endif
+# else
+ /* dummy */
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Exchange an unsigned 8-bit value, ordered.
+ *
+ * @returns Current *pu8 value
+ * @param pu8 Pointer to the 8-bit variable to update.
+ * @param u8 The 8-bit value to assign to *pu8.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint8_t) ASMAtomicXchgU8(volatile uint8_t *pu8, uint8_t u8);
+#else
+DECLINLINE(uint8_t) ASMAtomicXchgU8(volatile uint8_t *pu8, uint8_t u8)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("xchgb %0, %1\n\t"
+ : "=m" (*pu8),
+ "=q" (u8) /* =r - busted on g++ (GCC) 3.4.4 20050721 (Red Hat 3.4.4-2) */
+ : "1" (u8),
+ "m" (*pu8));
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu8]
+ mov al, [u8]
+ xchg [rdx], al
+ mov [u8], al
+# else
+ mov edx, [pu8]
+ mov al, [u8]
+ xchg [edx], al
+ mov [u8], al
+# endif
+ }
+# endif
+ return u8;
+}
+#endif
+
+
+/**
+ * Atomically Exchange a signed 8-bit value, ordered.
+ *
+ * @returns Current *pu8 value
+ * @param pi8 Pointer to the 8-bit variable to update.
+ * @param i8 The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(int8_t) ASMAtomicXchgS8(volatile int8_t *pi8, int8_t i8)
+{
+ return (int8_t)ASMAtomicXchgU8((volatile uint8_t *)pi8, (uint8_t)i8);
+}
+
+
+/**
+ * Atomically Exchange a bool value, ordered.
+ *
+ * @returns Current *pf value
+ * @param pf Pointer to the 8-bit variable to update.
+ * @param f The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(bool) ASMAtomicXchgBool(volatile bool *pf, bool f)
+{
+#ifdef _MSC_VER
+ return !!ASMAtomicXchgU8((volatile uint8_t *)pf, (uint8_t)f);
+#else
+ return (bool)ASMAtomicXchgU8((volatile uint8_t *)pf, (uint8_t)f);
+#endif
+}
+
+
+/**
+ * Atomically Exchange an unsigned 16-bit value, ordered.
+ *
+ * @returns Current *pu16 value
+ * @param pu16 Pointer to the 16-bit variable to update.
+ * @param u16 The 16-bit value to assign to *pu16.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint16_t) ASMAtomicXchgU16(volatile uint16_t *pu16, uint16_t u16);
+#else
+DECLINLINE(uint16_t) ASMAtomicXchgU16(volatile uint16_t *pu16, uint16_t u16)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("xchgw %0, %1\n\t"
+ : "=m" (*pu16),
+ "=r" (u16)
+ : "1" (u16),
+ "m" (*pu16));
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu16]
+ mov ax, [u16]
+ xchg [rdx], ax
+ mov [u16], ax
+# else
+ mov edx, [pu16]
+ mov ax, [u16]
+ xchg [edx], ax
+ mov [u16], ax
+# endif
+ }
+# endif
+ return u16;
+}
+#endif
+
+
+/**
+ * Atomically Exchange a signed 16-bit value, ordered.
+ *
+ * @returns Current *pu16 value
+ * @param pi16 Pointer to the 16-bit variable to update.
+ * @param i16 The 16-bit value to assign to *pi16.
+ */
+DECLINLINE(int16_t) ASMAtomicXchgS16(volatile int16_t *pi16, int16_t i16)
+{
+ return (int16_t)ASMAtomicXchgU16((volatile uint16_t *)pi16, (uint16_t)i16);
+}
+
+
+/**
+ * Atomically Exchange an unsigned 32-bit value, ordered.
+ *
+ * @returns Current *pu32 value
+ * @param pu32 Pointer to the 32-bit variable to update.
+ * @param u32 The 32-bit value to assign to *pu32.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicXchgU32(volatile uint32_t *pu32, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMAtomicXchgU32(volatile uint32_t *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("xchgl %0, %1\n\t"
+ : "=m" (*pu32),
+ "=r" (u32)
+ : "1" (u32),
+ "m" (*pu32));
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ u32 = _InterlockedExchange((long *)pu32, u32);
+
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+ mov eax, u32
+ xchg [rdx], eax
+ mov [u32], eax
+# else
+ mov edx, [pu32]
+ mov eax, u32
+ xchg [edx], eax
+ mov [u32], eax
+# endif
+ }
+# endif
+ return u32;
+}
+#endif
+
+
+/**
+ * Atomically Exchange a signed 32-bit value, ordered.
+ *
+ * @returns Current *pu32 value
+ * @param pi32 Pointer to the 32-bit variable to update.
+ * @param i32 The 32-bit value to assign to *pi32.
+ */
+DECLINLINE(int32_t) ASMAtomicXchgS32(volatile int32_t *pi32, int32_t i32)
+{
+ return (int32_t)ASMAtomicXchgU32((volatile uint32_t *)pi32, (uint32_t)i32);
+}
+
+
+/**
+ * Atomically Exchange an unsigned 64-bit value, ordered.
+ *
+ * @returns Current *pu64 value
+ * @param pu64 Pointer to the 64-bit variable to update.
+ * @param u64 The 64-bit value to assign to *pu64.
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(uint64_t) ASMAtomicXchgU64(volatile uint64_t *pu64, uint64_t u64);
+#else
+DECLINLINE(uint64_t) ASMAtomicXchgU64(volatile uint64_t *pu64, uint64_t u64)
+{
+# if defined(RT_ARCH_AMD64)
+# if RT_INLINE_ASM_USES_INTRIN
+ u64 = _InterlockedExchange64((__int64 *)pu64, u64);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("xchgq %0, %1\n\t"
+ : "=m" (*pu64),
+ "=r" (u64)
+ : "1" (u64),
+ "m" (*pu64));
+# else
+ __asm
+ {
+ mov rdx, [pu64]
+ mov rax, [u64]
+ xchg [rdx], rax
+ mov [u64], rax
+ }
+# endif
+# else /* !RT_ARCH_AMD64 */
+# if RT_INLINE_ASM_GNU_STYLE
+# if defined(PIC) || defined(__PIC__)
+ uint32_t u32EBX = (uint32_t)u64;
+ __asm__ __volatile__(/*"xchgl %%esi, %5\n\t"*/
+ "xchgl %%ebx, %3\n\t"
+ "1:\n\t"
+ "lock; cmpxchg8b (%5)\n\t"
+ "jnz 1b\n\t"
+ "movl %3, %%ebx\n\t"
+ /*"xchgl %%esi, %5\n\t"*/
+ : "=A" (u64),
+ "=m" (*pu64)
+ : "0" (*pu64),
+ "m" ( u32EBX ),
+ "c" ( (uint32_t)(u64 >> 32) ),
+ "S" (pu64));
+# else /* !PIC */
+ __asm__ __volatile__("1:\n\t"
+ "lock; cmpxchg8b %1\n\t"
+ "jnz 1b\n\t"
+ : "=A" (u64),
+ "=m" (*pu64)
+ : "0" (*pu64),
+ "b" ( (uint32_t)u64 ),
+ "c" ( (uint32_t)(u64 >> 32) ));
+# endif
+# else
+ __asm
+ {
+ mov ebx, dword ptr [u64]
+ mov ecx, dword ptr [u64 + 4]
+ mov edi, pu64
+ mov eax, dword ptr [edi]
+ mov edx, dword ptr [edi + 4]
+ retry:
+ lock cmpxchg8b [edi]
+ jnz retry
+ mov dword ptr [u64], eax
+ mov dword ptr [u64 + 4], edx
+ }
+# endif
+# endif /* !RT_ARCH_AMD64 */
+ return u64;
+}
+#endif
+
+
+/**
+ * Atomically Exchange an signed 64-bit value, ordered.
+ *
+ * @returns Current *pi64 value
+ * @param pi64 Pointer to the 64-bit variable to update.
+ * @param i64 The 64-bit value to assign to *pi64.
+ */
+DECLINLINE(int64_t) ASMAtomicXchgS64(volatile int64_t *pi64, int64_t i64)
+{
+ return (int64_t)ASMAtomicXchgU64((volatile uint64_t *)pi64, (uint64_t)i64);
+}
+
+
+/**
+ * Atomically Exchange a pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param ppv Pointer to the pointer variable to update.
+ * @param pv The pointer value to assign to *ppv.
+ */
+DECLINLINE(void *) ASMAtomicXchgPtr(void * volatile *ppv, const void *pv)
+{
+#if ARCH_BITS == 32
+ return (void *)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pv);
+#elif ARCH_BITS == 64
+ return (void *)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Convenience macro for avoiding the annoying casting with ASMAtomicXchgPtr.
+ *
+ * @returns Current *pv value
+ * @param ppv Pointer to the pointer variable to update.
+ * @param pv The pointer value to assign to *ppv.
+ * @param Type The type of *ppv, sans volatile.
+ */
+#ifdef __GNUC__
+# define ASMAtomicXchgPtrT(ppv, pv, Type) \
+ __extension__ \
+ ({\
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ Type const pvTypeChecked = (pv); \
+ Type pvTypeCheckedRet = (__typeof__(*(ppv))) ASMAtomicXchgPtr((void * volatile *)ppvTypeChecked, (void *)pvTypeChecked); \
+ pvTypeCheckedRet; \
+ })
+#else
+# define ASMAtomicXchgPtrT(ppv, pv, Type) \
+ (Type)ASMAtomicXchgPtr((void * volatile *)(ppv), (void *)(pv))
+#endif
+
+
+/**
+ * Atomically Exchange a raw-mode context pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param ppvRC Pointer to the pointer variable to update.
+ * @param pvRC The pointer value to assign to *ppv.
+ */
+DECLINLINE(RTRCPTR) ASMAtomicXchgRCPtr(RTRCPTR volatile *ppvRC, RTRCPTR pvRC)
+{
+ return (RTRCPTR)ASMAtomicXchgU32((uint32_t volatile *)(void *)ppvRC, (uint32_t)pvRC);
+}
+
+
+/**
+ * Atomically Exchange a ring-0 pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param ppvR0 Pointer to the pointer variable to update.
+ * @param pvR0 The pointer value to assign to *ppv.
+ */
+DECLINLINE(RTR0PTR) ASMAtomicXchgR0Ptr(RTR0PTR volatile *ppvR0, RTR0PTR pvR0)
+{
+#if R0_ARCH_BITS == 32
+ return (RTR0PTR)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppvR0, (uint32_t)pvR0);
+#elif R0_ARCH_BITS == 64
+ return (RTR0PTR)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppvR0, (uint64_t)pvR0);
+#else
+# error "R0_ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically Exchange a ring-3 pointer value, ordered.
+ *
+ * @returns Current *ppv value
+ * @param ppvR3 Pointer to the pointer variable to update.
+ * @param pvR3 The pointer value to assign to *ppv.
+ */
+DECLINLINE(RTR3PTR) ASMAtomicXchgR3Ptr(RTR3PTR volatile *ppvR3, RTR3PTR pvR3)
+{
+#if R3_ARCH_BITS == 32
+ return (RTR3PTR)ASMAtomicXchgU32((volatile uint32_t *)(void *)ppvR3, (uint32_t)pvR3);
+#elif R3_ARCH_BITS == 64
+ return (RTR3PTR)ASMAtomicXchgU64((volatile uint64_t *)(void *)ppvR3, (uint64_t)pvR3);
+#else
+# error "R3_ARCH_BITS is bogus"
+#endif
+}
+
+
+/** @def ASMAtomicXchgHandle
+ * Atomically Exchange a typical IPRT handle value, ordered.
+ *
+ * @param ph Pointer to the value to update.
+ * @param hNew The new value to assigned to *pu.
+ * @param phRes Where to store the current *ph value.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicXchgHandle(ph, hNew, phRes) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+ AssertCompile(sizeof(*(phRes)) == sizeof(uint32_t)); \
+ *(uint32_t *)(phRes) = ASMAtomicXchgU32((uint32_t volatile *)(ph), (const uint32_t)(hNew)); \
+ } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicXchgHandle(ph, hNew, phRes) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+ AssertCompile(sizeof(*(phRes)) == sizeof(uint64_t)); \
+ *(uint64_t *)(phRes) = ASMAtomicXchgU64((uint64_t volatile *)(ph), (const uint64_t)(hNew)); \
+ } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically Exchange a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param pu Pointer to the variable to update.
+ * @param uNew The value to assign to *pu.
+ * @todo This is busted as its missing the result argument.
+ */
+#define ASMAtomicXchgSize(pu, uNew) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 1: ASMAtomicXchgU8((volatile uint8_t *)(void *)(pu), (uint8_t)(uNew)); break; \
+ case 2: ASMAtomicXchgU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+ case 4: ASMAtomicXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+ case 8: ASMAtomicXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+ default: AssertMsgFailed(("ASMAtomicXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+/**
+ * Atomically Exchange a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param pu Pointer to the variable to update.
+ * @param uNew The value to assign to *pu.
+ * @param puRes Where to store the current *pu value.
+ */
+#define ASMAtomicXchgSizeCorrect(pu, uNew, puRes) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 1: *(uint8_t *)(puRes) = ASMAtomicXchgU8((volatile uint8_t *)(void *)(pu), (uint8_t)(uNew)); break; \
+ case 2: *(uint16_t *)(puRes) = ASMAtomicXchgU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+ case 4: *(uint32_t *)(puRes) = ASMAtomicXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+ case 8: *(uint64_t *)(puRes) = ASMAtomicXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+ default: AssertMsgFailed(("ASMAtomicXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+
+
+/**
+ * Atomically Compare and Exchange an unsigned 8-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pu8 Pointer to the value to update.
+ * @param u8New The new value to assigned to *pu8.
+ * @param u8Old The old value to *pu8 compare with.
+ */
+#if RT_INLINE_ASM_EXTERNAL || !RT_INLINE_ASM_GNU_STYLE
+DECLASM(bool) ASMAtomicCmpXchgU8(volatile uint8_t *pu8, const uint8_t u8New, const uint8_t u8Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgU8(volatile uint8_t *pu8, const uint8_t u8New, uint8_t u8Old)
+{
+ uint8_t u8Ret;
+ __asm__ __volatile__("lock; cmpxchgb %3, %0\n\t"
+ "setz %1\n\t"
+ : "=m" (*pu8),
+ "=qm" (u8Ret),
+ "=a" (u8Old)
+ : "q" (u8New),
+ "2" (u8Old),
+ "m" (*pu8));
+ return (bool)u8Ret;
+}
+#endif
+
+
+/**
+ * Atomically Compare and Exchange a signed 8-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pi8 Pointer to the value to update.
+ * @param i8New The new value to assigned to *pi8.
+ * @param i8Old The old value to *pi8 compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgS8(volatile int8_t *pi8, const int8_t i8New, const int8_t i8Old)
+{
+ return ASMAtomicCmpXchgU8((volatile uint8_t *)pi8, (const uint8_t)i8New, (const uint8_t)i8Old);
+}
+
+
+/**
+ * Atomically Compare and Exchange a bool value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pf Pointer to the value to update.
+ * @param fNew The new value to assigned to *pf.
+ * @param fOld The old value to *pf compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgBool(volatile bool *pf, const bool fNew, const bool fOld)
+{
+ return ASMAtomicCmpXchgU8((volatile uint8_t *)pf, (const uint8_t)fNew, (const uint8_t)fOld);
+}
+
+
+/**
+ * Atomically Compare and Exchange an unsigned 32-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pu32 Pointer to the value to update.
+ * @param u32New The new value to assigned to *pu32.
+ * @param u32Old The old value to *pu32 compare with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicCmpXchgU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgU32(volatile uint32_t *pu32, const uint32_t u32New, uint32_t u32Old)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ uint8_t u8Ret;
+ __asm__ __volatile__("lock; cmpxchgl %3, %0\n\t"
+ "setz %1\n\t"
+ : "=m" (*pu32),
+ "=qm" (u8Ret),
+ "=a" (u32Old)
+ : "r" (u32New),
+ "2" (u32Old),
+ "m" (*pu32));
+ return (bool)u8Ret;
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ return (uint32_t)_InterlockedCompareExchange((long *)pu32, u32New, u32Old) == u32Old;
+
+# else
+ uint32_t u32Ret;
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+# else
+ mov edx, [pu32]
+# endif
+ mov eax, [u32Old]
+ mov ecx, [u32New]
+# ifdef RT_ARCH_AMD64
+ lock cmpxchg [rdx], ecx
+# else
+ lock cmpxchg [edx], ecx
+# endif
+ setz al
+ movzx eax, al
+ mov [u32Ret], eax
+ }
+ return !!u32Ret;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Compare and Exchange a signed 32-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pi32 Pointer to the value to update.
+ * @param i32New The new value to assigned to *pi32.
+ * @param i32Old The old value to *pi32 compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgS32(volatile int32_t *pi32, const int32_t i32New, const int32_t i32Old)
+{
+ return ASMAtomicCmpXchgU32((volatile uint32_t *)pi32, (uint32_t)i32New, (uint32_t)i32Old);
+}
+
+
+/**
+ * Atomically Compare and exchange an unsigned 64-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pu64 Pointer to the 64-bit variable to update.
+ * @param u64New The 64-bit value to assign to *pu64.
+ * @param u64Old The value to compare with.
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(bool) ASMAtomicCmpXchgU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgU64(volatile uint64_t *pu64, uint64_t u64New, uint64_t u64Old)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ return (uint64_t)_InterlockedCompareExchange64((__int64 *)pu64, u64New, u64Old) == u64Old;
+
+# elif defined(RT_ARCH_AMD64)
+# if RT_INLINE_ASM_GNU_STYLE
+ uint8_t u8Ret;
+ __asm__ __volatile__("lock; cmpxchgq %3, %0\n\t"
+ "setz %1\n\t"
+ : "=m" (*pu64),
+ "=qm" (u8Ret),
+ "=a" (u64Old)
+ : "r" (u64New),
+ "2" (u64Old),
+ "m" (*pu64));
+ return (bool)u8Ret;
+# else
+ bool fRet;
+ __asm
+ {
+ mov rdx, [pu32]
+ mov rax, [u64Old]
+ mov rcx, [u64New]
+ lock cmpxchg [rdx], rcx
+ setz al
+ mov [fRet], al
+ }
+ return fRet;
+# endif
+# else /* !RT_ARCH_AMD64 */
+ uint32_t u32Ret;
+# if RT_INLINE_ASM_GNU_STYLE
+# if defined(PIC) || defined(__PIC__)
+ uint32_t u32EBX = (uint32_t)u64New;
+ uint32_t u32Spill;
+ __asm__ __volatile__("xchgl %%ebx, %4\n\t"
+ "lock; cmpxchg8b (%6)\n\t"
+ "setz %%al\n\t"
+ "movl %4, %%ebx\n\t"
+ "movzbl %%al, %%eax\n\t"
+ : "=a" (u32Ret),
+ "=d" (u32Spill),
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+ "+m" (*pu64)
+# else
+ "=m" (*pu64)
+# endif
+ : "A" (u64Old),
+ "m" ( u32EBX ),
+ "c" ( (uint32_t)(u64New >> 32) ),
+ "S" (pu64));
+# else /* !PIC */
+ uint32_t u32Spill;
+ __asm__ __volatile__("lock; cmpxchg8b %2\n\t"
+ "setz %%al\n\t"
+ "movzbl %%al, %%eax\n\t"
+ : "=a" (u32Ret),
+ "=d" (u32Spill),
+ "+m" (*pu64)
+ : "A" (u64Old),
+ "b" ( (uint32_t)u64New ),
+ "c" ( (uint32_t)(u64New >> 32) ));
+# endif
+ return (bool)u32Ret;
+# else
+ __asm
+ {
+ mov ebx, dword ptr [u64New]
+ mov ecx, dword ptr [u64New + 4]
+ mov edi, [pu64]
+ mov eax, dword ptr [u64Old]
+ mov edx, dword ptr [u64Old + 4]
+ lock cmpxchg8b [edi]
+ setz al
+ movzx eax, al
+ mov dword ptr [u32Ret], eax
+ }
+ return !!u32Ret;
+# endif
+# endif /* !RT_ARCH_AMD64 */
+}
+#endif
+
+
+/**
+ * Atomically Compare and exchange a signed 64-bit value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pi64 Pointer to the 64-bit variable to update.
+ * @param i64 The 64-bit value to assign to *pu64.
+ * @param i64Old The value to compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgS64(volatile int64_t *pi64, const int64_t i64, const int64_t i64Old)
+{
+ return ASMAtomicCmpXchgU64((volatile uint64_t *)pi64, (uint64_t)i64, (uint64_t)i64Old);
+}
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param ppv Pointer to the value to update.
+ * @param pvNew The new value to assigned to *ppv.
+ * @param pvOld The old value to *ppv compare with.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgPtrVoid(void * volatile *ppv, const void *pvNew, const void *pvOld)
+{
+#if ARCH_BITS == 32
+ return ASMAtomicCmpXchgU32((volatile uint32_t *)(void *)ppv, (uint32_t)pvNew, (uint32_t)pvOld);
+#elif ARCH_BITS == 64
+ return ASMAtomicCmpXchgU64((volatile uint64_t *)(void *)ppv, (uint64_t)pvNew, (uint64_t)pvOld);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param ppv Pointer to the value to update.
+ * @param pvNew The new value to assigned to *ppv.
+ * @param pvOld The old value to *ppv compare with.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicCmpXchgPtr(ppv, pvNew, pvOld) \
+ __extension__ \
+ ({\
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ __typeof__(*(ppv)) const pvNewTypeChecked = (pvNew); \
+ __typeof__(*(ppv)) const pvOldTypeChecked = (pvOld); \
+ bool fMacroRet = ASMAtomicCmpXchgPtrVoid((void * volatile *)ppvTypeChecked, \
+ (void *)pvNewTypeChecked, (void *)pvOldTypeChecked); \
+ fMacroRet; \
+ })
+#else
+# define ASMAtomicCmpXchgPtr(ppv, pvNew, pvOld) \
+ ASMAtomicCmpXchgPtrVoid((void * volatile *)(ppv), (void *)(pvNew), (void *)(pvOld))
+#endif
+
+
+/** @def ASMAtomicCmpXchgHandle
+ * Atomically Compare and Exchange a typical IPRT handle value, ordered.
+ *
+ * @param ph Pointer to the value to update.
+ * @param hNew The new value to assigned to *pu.
+ * @param hOld The old value to *pu compare with.
+ * @param fRc Where to store the result.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicCmpXchgHandle(ph, hNew, hOld, fRc) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+ (fRc) = ASMAtomicCmpXchgU32((uint32_t volatile *)(ph), (const uint32_t)(hNew), (const uint32_t)(hOld)); \
+ } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicCmpXchgHandle(ph, hNew, hOld, fRc) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+ (fRc) = ASMAtomicCmpXchgU64((uint64_t volatile *)(ph), (const uint64_t)(hNew), (const uint64_t)(hOld)); \
+ } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/** @def ASMAtomicCmpXchgSize
+ * Atomically Compare and Exchange a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param pu Pointer to the value to update.
+ * @param uNew The new value to assigned to *pu.
+ * @param uOld The old value to *pu compare with.
+ * @param fRc Where to store the result.
+ */
+#define ASMAtomicCmpXchgSize(pu, uNew, uOld, fRc) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 4: (fRc) = ASMAtomicCmpXchgU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld)); \
+ break; \
+ case 8: (fRc) = ASMAtomicCmpXchgU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld)); \
+ break; \
+ default: AssertMsgFailed(("ASMAtomicCmpXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+ (fRc) = false; \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Atomically Compare and Exchange an unsigned 32-bit value, additionally
+ * passes back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pu32 Pointer to the value to update.
+ * @param u32New The new value to assigned to *pu32.
+ * @param u32Old The old value to *pu32 compare with.
+ * @param pu32Old Pointer store the old value at.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicCmpXchgExU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t *pu32Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgExU32(volatile uint32_t *pu32, const uint32_t u32New, const uint32_t u32Old, uint32_t *pu32Old)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ uint8_t u8Ret;
+ __asm__ __volatile__("lock; cmpxchgl %3, %0\n\t"
+ "setz %1\n\t"
+ : "=m" (*pu32),
+ "=qm" (u8Ret),
+ "=a" (*pu32Old)
+ : "r" (u32New),
+ "a" (u32Old),
+ "m" (*pu32));
+ return (bool)u8Ret;
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ return (*pu32Old =_InterlockedCompareExchange((long *)pu32, u32New, u32Old)) == u32Old;
+
+# else
+ uint32_t u32Ret;
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+# else
+ mov edx, [pu32]
+# endif
+ mov eax, [u32Old]
+ mov ecx, [u32New]
+# ifdef RT_ARCH_AMD64
+ lock cmpxchg [rdx], ecx
+ mov rdx, [pu32Old]
+ mov [rdx], eax
+# else
+ lock cmpxchg [edx], ecx
+ mov edx, [pu32Old]
+ mov [edx], eax
+# endif
+ setz al
+ movzx eax, al
+ mov [u32Ret], eax
+ }
+ return !!u32Ret;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Compare and Exchange a signed 32-bit value, additionally
+ * passes back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pi32 Pointer to the value to update.
+ * @param i32New The new value to assigned to *pi32.
+ * @param i32Old The old value to *pi32 compare with.
+ * @param pi32Old Pointer store the old value at.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgExS32(volatile int32_t *pi32, const int32_t i32New, const int32_t i32Old, int32_t *pi32Old)
+{
+ return ASMAtomicCmpXchgExU32((volatile uint32_t *)pi32, (uint32_t)i32New, (uint32_t)i32Old, (uint32_t *)pi32Old);
+}
+
+
+/**
+ * Atomically Compare and exchange an unsigned 64-bit value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pu64 Pointer to the 64-bit variable to update.
+ * @param u64New The 64-bit value to assign to *pu64.
+ * @param u64Old The value to compare with.
+ * @param pu64Old Pointer store the old value at.
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(bool) ASMAtomicCmpXchgExU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old, uint64_t *pu64Old);
+#else
+DECLINLINE(bool) ASMAtomicCmpXchgExU64(volatile uint64_t *pu64, const uint64_t u64New, const uint64_t u64Old, uint64_t *pu64Old)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ return (*pu64Old =_InterlockedCompareExchange64((__int64 *)pu64, u64New, u64Old)) == u64Old;
+
+# elif defined(RT_ARCH_AMD64)
+# if RT_INLINE_ASM_GNU_STYLE
+ uint8_t u8Ret;
+ __asm__ __volatile__("lock; cmpxchgq %3, %0\n\t"
+ "setz %1\n\t"
+ : "=m" (*pu64),
+ "=qm" (u8Ret),
+ "=a" (*pu64Old)
+ : "r" (u64New),
+ "a" (u64Old),
+ "m" (*pu64));
+ return (bool)u8Ret;
+# else
+ bool fRet;
+ __asm
+ {
+ mov rdx, [pu32]
+ mov rax, [u64Old]
+ mov rcx, [u64New]
+ lock cmpxchg [rdx], rcx
+ mov rdx, [pu64Old]
+ mov [rdx], rax
+ setz al
+ mov [fRet], al
+ }
+ return fRet;
+# endif
+# else /* !RT_ARCH_AMD64 */
+# if RT_INLINE_ASM_GNU_STYLE
+ uint64_t u64Ret;
+# if defined(PIC) || defined(__PIC__)
+ /* NB: this code uses a memory clobber description, because the clean
+ * solution with an output value for *pu64 makes gcc run out of registers.
+ * This will cause suboptimal code, and anyone with a better solution is
+ * welcome to improve this. */
+ __asm__ __volatile__("xchgl %%ebx, %1\n\t"
+ "lock; cmpxchg8b %3\n\t"
+ "xchgl %%ebx, %1\n\t"
+ : "=A" (u64Ret)
+ : "DS" ((uint32_t)u64New),
+ "c" ((uint32_t)(u64New >> 32)),
+ "m" (*pu64),
+ "0" (u64Old)
+ : "memory" );
+# else /* !PIC */
+ __asm__ __volatile__("lock; cmpxchg8b %4\n\t"
+ : "=A" (u64Ret),
+ "=m" (*pu64)
+ : "b" ((uint32_t)u64New),
+ "c" ((uint32_t)(u64New >> 32)),
+ "m" (*pu64),
+ "0" (u64Old));
+# endif
+ *pu64Old = u64Ret;
+ return u64Ret == u64Old;
+# else
+ uint32_t u32Ret;
+ __asm
+ {
+ mov ebx, dword ptr [u64New]
+ mov ecx, dword ptr [u64New + 4]
+ mov edi, [pu64]
+ mov eax, dword ptr [u64Old]
+ mov edx, dword ptr [u64Old + 4]
+ lock cmpxchg8b [edi]
+ mov ebx, [pu64Old]
+ mov [ebx], eax
+ setz al
+ movzx eax, al
+ add ebx, 4
+ mov [ebx], edx
+ mov dword ptr [u32Ret], eax
+ }
+ return !!u32Ret;
+# endif
+# endif /* !RT_ARCH_AMD64 */
+}
+#endif
+
+
+/**
+ * Atomically Compare and exchange a signed 64-bit value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param pi64 Pointer to the 64-bit variable to update.
+ * @param i64 The 64-bit value to assign to *pu64.
+ * @param i64Old The value to compare with.
+ * @param pi64Old Pointer store the old value at.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgExS64(volatile int64_t *pi64, const int64_t i64, const int64_t i64Old, int64_t *pi64Old)
+{
+ return ASMAtomicCmpXchgExU64((volatile uint64_t *)pi64, (uint64_t)i64, (uint64_t)i64Old, (uint64_t *)pi64Old);
+}
+
+/** @def ASMAtomicCmpXchgExHandle
+ * Atomically Compare and Exchange a typical IPRT handle value, ordered.
+ *
+ * @param ph Pointer to the value to update.
+ * @param hNew The new value to assigned to *pu.
+ * @param hOld The old value to *pu compare with.
+ * @param fRc Where to store the result.
+ * @param phOldVal Pointer to where to store the old value.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicCmpXchgExHandle(ph, hNew, hOld, fRc, phOldVal) \
+ do { \
+ AssertCompile(sizeof(*ph) == sizeof(uint32_t)); \
+ AssertCompile(sizeof(*phOldVal) == sizeof(uint32_t)); \
+ (fRc) = ASMAtomicCmpXchgExU32((volatile uint32_t *)(pu), (uint32_t)(uNew), (uint32_t)(uOld), (uint32_t *)(puOldVal)); \
+ } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicCmpXchgExHandle(ph, hNew, hOld, fRc, phOldVal) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+ AssertCompile(sizeof(*(phOldVal)) == sizeof(uint64_t)); \
+ (fRc) = ASMAtomicCmpXchgExU64((volatile uint64_t *)(pu), (uint64_t)(uNew), (uint64_t)(uOld), (uint64_t *)(puOldVal)); \
+ } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/** @def ASMAtomicCmpXchgExSize
+ * Atomically Compare and Exchange a value which size might differ
+ * between platforms or compilers. Additionally passes back old value.
+ *
+ * @param pu Pointer to the value to update.
+ * @param uNew The new value to assigned to *pu.
+ * @param uOld The old value to *pu compare with.
+ * @param fRc Where to store the result.
+ * @param puOldVal Pointer to where to store the old value.
+ */
+#define ASMAtomicCmpXchgExSize(pu, uNew, uOld, fRc, puOldVal) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 4: (fRc) = ASMAtomicCmpXchgExU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew), (uint32_t)(uOld), (uint32_t *)(uOldVal)); \
+ break; \
+ case 8: (fRc) = ASMAtomicCmpXchgExU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew), (uint64_t)(uOld), (uint64_t *)(uOldVal)); \
+ break; \
+ default: AssertMsgFailed(("ASMAtomicCmpXchgSize: size %d is not supported\n", sizeof(*(pu)))); \
+ (fRc) = false; \
+ (uOldVal) = 0; \
+ break; \
+ } \
+ } while (0)
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param ppv Pointer to the value to update.
+ * @param pvNew The new value to assigned to *ppv.
+ * @param pvOld The old value to *ppv compare with.
+ * @param ppvOld Pointer store the old value at.
+ */
+DECLINLINE(bool) ASMAtomicCmpXchgExPtrVoid(void * volatile *ppv, const void *pvNew, const void *pvOld, void **ppvOld)
+{
+#if ARCH_BITS == 32
+ return ASMAtomicCmpXchgExU32((volatile uint32_t *)(void *)ppv, (uint32_t)pvNew, (uint32_t)pvOld, (uint32_t *)ppvOld);
+#elif ARCH_BITS == 64
+ return ASMAtomicCmpXchgExU64((volatile uint64_t *)(void *)ppv, (uint64_t)pvNew, (uint64_t)pvOld, (uint64_t *)ppvOld);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically Compare and Exchange a pointer value, additionally
+ * passing back old value, ordered.
+ *
+ * @returns true if xchg was done.
+ * @returns false if xchg wasn't done.
+ *
+ * @param ppv Pointer to the value to update.
+ * @param pvNew The new value to assigned to *ppv.
+ * @param pvOld The old value to *ppv compare with.
+ * @param ppvOld Pointer store the old value at.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicCmpXchgExPtr(ppv, pvNew, pvOld, ppvOld) \
+ __extension__ \
+ ({\
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ __typeof__(*(ppv)) const pvNewTypeChecked = (pvNew); \
+ __typeof__(*(ppv)) const pvOldTypeChecked = (pvOld); \
+ __typeof__(*(ppv)) * const ppvOldTypeChecked = (ppvOld); \
+ bool fMacroRet = ASMAtomicCmpXchgExPtrVoid((void * volatile *)ppvTypeChecked, \
+ (void *)pvNewTypeChecked, (void *)pvOldTypeChecked, \
+ (void **)ppvOldTypeChecked); \
+ fMacroRet; \
+ })
+#else
+# define ASMAtomicCmpXchgExPtr(ppv, pvNew, pvOld, ppvOld) \
+ ASMAtomicCmpXchgExPtrVoid((void * volatile *)(ppv), (void *)(pvNew), (void *)(pvOld), (void **)(ppvOld))
+#endif
+
+
+/**
+ * Serialize Instruction.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMSerializeInstruction(void);
+#else
+DECLINLINE(void) ASMSerializeInstruction(void)
+{
+# if RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG xAX = 0;
+# ifdef RT_ARCH_AMD64
+ __asm__ ("cpuid"
+ : "=a" (xAX)
+ : "0" (xAX)
+ : "rbx", "rcx", "rdx");
+# elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
+ __asm__ ("push %%ebx\n\t"
+ "cpuid\n\t"
+ "pop %%ebx\n\t"
+ : "=a" (xAX)
+ : "0" (xAX)
+ : "ecx", "edx");
+# else
+ __asm__ ("cpuid"
+ : "=a" (xAX)
+ : "0" (xAX)
+ : "ebx", "ecx", "edx");
+# endif
+
+# elif RT_INLINE_ASM_USES_INTRIN
+ int aInfo[4];
+ __cpuid(aInfo, 0);
+
+# else
+ __asm
+ {
+ push ebx
+ xor eax, eax
+ cpuid
+ pop ebx
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Memory fence, waits for any pending writes and reads to complete.
+ */
+DECLINLINE(void) ASMMemoryFence(void)
+{
+ /** @todo use mfence? check if all cpus we care for support it. */
+ uint32_t volatile u32;
+ ASMAtomicXchgU32(&u32, 0);
+}
+
+
+/**
+ * Write fence, waits for any pending writes to complete.
+ */
+DECLINLINE(void) ASMWriteFence(void)
+{
+ /** @todo use sfence? check if all cpus we care for support it. */
+ ASMMemoryFence();
+}
+
+
+/**
+ * Read fence, waits for any pending reads to complete.
+ */
+DECLINLINE(void) ASMReadFence(void)
+{
+ /** @todo use lfence? check if all cpus we care for support it. */
+ ASMMemoryFence();
+}
+
+
+/**
+ * Atomically reads an unsigned 8-bit value, ordered.
+ *
+ * @returns Current *pu8 value
+ * @param pu8 Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(uint8_t) ASMAtomicReadU8(volatile uint8_t *pu8)
+{
+ ASMMemoryFence();
+ return *pu8; /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads an unsigned 8-bit value, unordered.
+ *
+ * @returns Current *pu8 value
+ * @param pu8 Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(uint8_t) ASMAtomicUoReadU8(volatile uint8_t *pu8)
+{
+ return *pu8; /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads a signed 8-bit value, ordered.
+ *
+ * @returns Current *pi8 value
+ * @param pi8 Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(int8_t) ASMAtomicReadS8(volatile int8_t *pi8)
+{
+ ASMMemoryFence();
+ return *pi8; /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads a signed 8-bit value, unordered.
+ *
+ * @returns Current *pi8 value
+ * @param pi8 Pointer to the 8-bit variable to read.
+ */
+DECLINLINE(int8_t) ASMAtomicUoReadS8(volatile int8_t *pi8)
+{
+ return *pi8; /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads an unsigned 16-bit value, ordered.
+ *
+ * @returns Current *pu16 value
+ * @param pu16 Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(uint16_t) ASMAtomicReadU16(volatile uint16_t *pu16)
+{
+ ASMMemoryFence();
+ Assert(!((uintptr_t)pu16 & 1));
+ return *pu16;
+}
+
+
+/**
+ * Atomically reads an unsigned 16-bit value, unordered.
+ *
+ * @returns Current *pu16 value
+ * @param pu16 Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(uint16_t) ASMAtomicUoReadU16(volatile uint16_t *pu16)
+{
+ Assert(!((uintptr_t)pu16 & 1));
+ return *pu16;
+}
+
+
+/**
+ * Atomically reads a signed 16-bit value, ordered.
+ *
+ * @returns Current *pi16 value
+ * @param pi16 Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(int16_t) ASMAtomicReadS16(volatile int16_t *pi16)
+{
+ ASMMemoryFence();
+ Assert(!((uintptr_t)pi16 & 1));
+ return *pi16;
+}
+
+
+/**
+ * Atomically reads a signed 16-bit value, unordered.
+ *
+ * @returns Current *pi16 value
+ * @param pi16 Pointer to the 16-bit variable to read.
+ */
+DECLINLINE(int16_t) ASMAtomicUoReadS16(volatile int16_t *pi16)
+{
+ Assert(!((uintptr_t)pi16 & 1));
+ return *pi16;
+}
+
+
+/**
+ * Atomically reads an unsigned 32-bit value, ordered.
+ *
+ * @returns Current *pu32 value
+ * @param pu32 Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(uint32_t) ASMAtomicReadU32(volatile uint32_t *pu32)
+{
+ ASMMemoryFence();
+ Assert(!((uintptr_t)pu32 & 3));
+ return *pu32;
+}
+
+
+/**
+ * Atomically reads an unsigned 32-bit value, unordered.
+ *
+ * @returns Current *pu32 value
+ * @param pu32 Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(uint32_t) ASMAtomicUoReadU32(volatile uint32_t *pu32)
+{
+ Assert(!((uintptr_t)pu32 & 3));
+ return *pu32;
+}
+
+
+/**
+ * Atomically reads a signed 32-bit value, ordered.
+ *
+ * @returns Current *pi32 value
+ * @param pi32 Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(int32_t) ASMAtomicReadS32(volatile int32_t *pi32)
+{
+ ASMMemoryFence();
+ Assert(!((uintptr_t)pi32 & 3));
+ return *pi32;
+}
+
+
+/**
+ * Atomically reads a signed 32-bit value, unordered.
+ *
+ * @returns Current *pi32 value
+ * @param pi32 Pointer to the 32-bit variable to read.
+ */
+DECLINLINE(int32_t) ASMAtomicUoReadS32(volatile int32_t *pi32)
+{
+ Assert(!((uintptr_t)pi32 & 3));
+ return *pi32;
+}
+
+
+/**
+ * Atomically reads an unsigned 64-bit value, ordered.
+ *
+ * @returns Current *pu64 value
+ * @param pu64 Pointer to the 64-bit variable to read.
+ * The memory pointed to must be writable.
+ * @remark This will fault if the memory is read-only!
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !defined(RT_ARCH_AMD64)) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(uint64_t) ASMAtomicReadU64(volatile uint64_t *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicReadU64(volatile uint64_t *pu64)
+{
+ uint64_t u64;
+# ifdef RT_ARCH_AMD64
+ Assert(!((uintptr_t)pu64 & 7));
+/*# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__( "mfence\n\t"
+ "movq %1, %0\n\t"
+ : "=r" (u64)
+ : "m" (*pu64));
+# else
+ __asm
+ {
+ mfence
+ mov rdx, [pu64]
+ mov rax, [rdx]
+ mov [u64], rax
+ }
+# endif*/
+ ASMMemoryFence();
+ u64 = *pu64;
+# else /* !RT_ARCH_AMD64 */
+# if RT_INLINE_ASM_GNU_STYLE
+# if defined(PIC) || defined(__PIC__)
+ uint32_t u32EBX = 0;
+ Assert(!((uintptr_t)pu64 & 7));
+ __asm__ __volatile__("xchgl %%ebx, %3\n\t"
+ "lock; cmpxchg8b (%5)\n\t"
+ "movl %3, %%ebx\n\t"
+ : "=A" (u64),
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+ "+m" (*pu64)
+# else
+ "=m" (*pu64)
+# endif
+ : "0" (0ULL),
+ "m" (u32EBX),
+ "c" (0),
+ "S" (pu64));
+# else /* !PIC */
+ __asm__ __volatile__("lock; cmpxchg8b %1\n\t"
+ : "=A" (u64),
+ "+m" (*pu64)
+ : "0" (0ULL),
+ "b" (0),
+ "c" (0));
+# endif
+# else
+ Assert(!((uintptr_t)pu64 & 7));
+ __asm
+ {
+ xor eax, eax
+ xor edx, edx
+ mov edi, pu64
+ xor ecx, ecx
+ xor ebx, ebx
+ lock cmpxchg8b [edi]
+ mov dword ptr [u64], eax
+ mov dword ptr [u64 + 4], edx
+ }
+# endif
+# endif /* !RT_ARCH_AMD64 */
+ return u64;
+}
+#endif
+
+
+/**
+ * Atomically reads an unsigned 64-bit value, unordered.
+ *
+ * @returns Current *pu64 value
+ * @param pu64 Pointer to the 64-bit variable to read.
+ * The memory pointed to must be writable.
+ * @remark This will fault if the memory is read-only!
+ */
+#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) \
+ || RT_INLINE_DONT_MIX_CMPXCHG8B_AND_PIC
+DECLASM(uint64_t) ASMAtomicUoReadU64(volatile uint64_t *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicUoReadU64(volatile uint64_t *pu64)
+{
+ uint64_t u64;
+# ifdef RT_ARCH_AMD64
+ Assert(!((uintptr_t)pu64 & 7));
+/*# if RT_INLINE_ASM_GNU_STYLE
+ Assert(!((uintptr_t)pu64 & 7));
+ __asm__ __volatile__("movq %1, %0\n\t"
+ : "=r" (u64)
+ : "m" (*pu64));
+# else
+ __asm
+ {
+ mov rdx, [pu64]
+ mov rax, [rdx]
+ mov [u64], rax
+ }
+# endif */
+ u64 = *pu64;
+# else /* !RT_ARCH_AMD64 */
+# if RT_INLINE_ASM_GNU_STYLE
+# if defined(PIC) || defined(__PIC__)
+ uint32_t u32EBX = 0;
+ uint32_t u32Spill;
+ Assert(!((uintptr_t)pu64 & 7));
+ __asm__ __volatile__("xor %%eax,%%eax\n\t"
+ "xor %%ecx,%%ecx\n\t"
+ "xor %%edx,%%edx\n\t"
+ "xchgl %%ebx, %3\n\t"
+ "lock; cmpxchg8b (%4)\n\t"
+ "movl %3, %%ebx\n\t"
+ : "=A" (u64),
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 403
+ "+m" (*pu64),
+# else
+ "=m" (*pu64),
+# endif
+ "=c" (u32Spill)
+ : "m" (u32EBX),
+ "S" (pu64));
+# else /* !PIC */
+ __asm__ __volatile__("lock; cmpxchg8b %1\n\t"
+ : "=A" (u64),
+ "+m" (*pu64)
+ : "0" (0ULL),
+ "b" (0),
+ "c" (0));
+# endif
+# else
+ Assert(!((uintptr_t)pu64 & 7));
+ __asm
+ {
+ xor eax, eax
+ xor edx, edx
+ mov edi, pu64
+ xor ecx, ecx
+ xor ebx, ebx
+ lock cmpxchg8b [edi]
+ mov dword ptr [u64], eax
+ mov dword ptr [u64 + 4], edx
+ }
+# endif
+# endif /* !RT_ARCH_AMD64 */
+ return u64;
+}
+#endif
+
+
+/**
+ * Atomically reads a signed 64-bit value, ordered.
+ *
+ * @returns Current *pi64 value
+ * @param pi64 Pointer to the 64-bit variable to read.
+ * The memory pointed to must be writable.
+ * @remark This will fault if the memory is read-only!
+ */
+DECLINLINE(int64_t) ASMAtomicReadS64(volatile int64_t *pi64)
+{
+ return (int64_t)ASMAtomicReadU64((volatile uint64_t *)pi64);
+}
+
+
+/**
+ * Atomically reads a signed 64-bit value, unordered.
+ *
+ * @returns Current *pi64 value
+ * @param pi64 Pointer to the 64-bit variable to read.
+ * The memory pointed to must be writable.
+ * @remark This will fault if the memory is read-only!
+ */
+DECLINLINE(int64_t) ASMAtomicUoReadS64(volatile int64_t *pi64)
+{
+ return (int64_t)ASMAtomicUoReadU64((volatile uint64_t *)pi64);
+}
+
+
+/**
+ * Atomically reads a size_t value, ordered.
+ *
+ * @returns Current *pcb value
+ * @param pcb Pointer to the size_t variable to read.
+ */
+DECLINLINE(size_t) ASMAtomicReadZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+ return ASMAtomicReadU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+ return ASMAtomicReadU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically reads a size_t value, unordered.
+ *
+ * @returns Current *pcb value
+ * @param pcb Pointer to the size_t variable to read.
+ */
+DECLINLINE(size_t) ASMAtomicUoReadZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+ return ASMAtomicUoReadU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+ return ASMAtomicUoReadU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically reads a pointer value, ordered.
+ *
+ * @returns Current *pv value
+ * @param ppv Pointer to the pointer variable to read.
+ *
+ * @remarks Please use ASMAtomicReadPtrT, it provides better type safety and
+ * requires less typing (no casts).
+ */
+DECLINLINE(void *) ASMAtomicReadPtr(void * volatile *ppv)
+{
+#if ARCH_BITS == 32
+ return (void *)ASMAtomicReadU32((volatile uint32_t *)(void *)ppv);
+#elif ARCH_BITS == 64
+ return (void *)ASMAtomicReadU64((volatile uint64_t *)(void *)ppv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+/**
+ * Convenience macro for avoiding the annoying casting with ASMAtomicReadPtr.
+ *
+ * @returns Current *pv value
+ * @param ppv Pointer to the pointer variable to read.
+ * @param Type The type of *ppv, sans volatile.
+ */
+#ifdef __GNUC__
+# define ASMAtomicReadPtrT(ppv, Type) \
+ __extension__ \
+ ({\
+ __typeof__(*(ppv)) volatile *ppvTypeChecked = (ppv); \
+ Type pvTypeChecked = (__typeof__(*(ppv))) ASMAtomicReadPtr((void * volatile *)ppvTypeChecked); \
+ pvTypeChecked; \
+ })
+#else
+# define ASMAtomicReadPtrT(ppv, Type) \
+ (Type)ASMAtomicReadPtr((void * volatile *)(ppv))
+#endif
+
+
+/**
+ * Atomically reads a pointer value, unordered.
+ *
+ * @returns Current *pv value
+ * @param ppv Pointer to the pointer variable to read.
+ *
+ * @remarks Please use ASMAtomicUoReadPtrT, it provides better type safety and
+ * requires less typing (no casts).
+ */
+DECLINLINE(void *) ASMAtomicUoReadPtr(void * volatile *ppv)
+{
+#if ARCH_BITS == 32
+ return (void *)ASMAtomicUoReadU32((volatile uint32_t *)(void *)ppv);
+#elif ARCH_BITS == 64
+ return (void *)ASMAtomicUoReadU64((volatile uint64_t *)(void *)ppv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Convenience macro for avoiding the annoying casting with ASMAtomicUoReadPtr.
+ *
+ * @returns Current *pv value
+ * @param ppv Pointer to the pointer variable to read.
+ * @param Type The type of *ppv, sans volatile.
+ */
+#ifdef __GNUC__
+# define ASMAtomicUoReadPtrT(ppv, Type) \
+ __extension__ \
+ ({\
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ Type pvTypeChecked = (__typeof__(*(ppv))) ASMAtomicUoReadPtr((void * volatile *)ppvTypeChecked); \
+ pvTypeChecked; \
+ })
+#else
+# define ASMAtomicUoReadPtrT(ppv, Type) \
+ (Type)ASMAtomicUoReadPtr((void * volatile *)(ppv))
+#endif
+
+
+/**
+ * Atomically reads a boolean value, ordered.
+ *
+ * @returns Current *pf value
+ * @param pf Pointer to the boolean variable to read.
+ */
+DECLINLINE(bool) ASMAtomicReadBool(volatile bool *pf)
+{
+ ASMMemoryFence();
+ return *pf; /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically reads a boolean value, unordered.
+ *
+ * @returns Current *pf value
+ * @param pf Pointer to the boolean variable to read.
+ */
+DECLINLINE(bool) ASMAtomicUoReadBool(volatile bool *pf)
+{
+ return *pf; /* byte reads are atomic on x86 */
+}
+
+
+/**
+ * Atomically read a typical IPRT handle value, ordered.
+ *
+ * @param ph Pointer to the handle variable to read.
+ * @param phRes Where to store the result.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicReadHandle(ph, phRes) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+ AssertCompile(sizeof(*(phRes)) == sizeof(uint32_t)); \
+ *(uint32_t *)(phRes) = ASMAtomicReadU32((uint32_t volatile *)(ph)); \
+ } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicReadHandle(ph, phRes) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+ AssertCompile(sizeof(*(phRes)) == sizeof(uint64_t)); \
+ *(uint64_t *)(phRes) = ASMAtomicReadU64((uint64_t volatile *)(ph)); \
+ } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically read a typical IPRT handle value, unordered.
+ *
+ * @param ph Pointer to the handle variable to read.
+ * @param phRes Where to store the result.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicUoReadHandle(ph, phRes) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+ AssertCompile(sizeof(*(phRes)) == sizeof(uint32_t)); \
+ *(uint32_t *)(phRes) = ASMAtomicUoReadU32((uint32_t volatile *)(ph)); \
+ } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicUoReadHandle(ph, phRes) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+ AssertCompile(sizeof(*(phRes)) == sizeof(uint64_t)); \
+ *(uint64_t *)(phRes) = ASMAtomicUoReadU64((uint64_t volatile *)(ph)); \
+ } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically read a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param pu Pointer to the variable to read.
+ * @param puRes Where to store the result.
+ */
+#define ASMAtomicReadSize(pu, puRes) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 1: *(uint8_t *)(puRes) = ASMAtomicReadU8( (volatile uint8_t *)(void *)(pu)); break; \
+ case 2: *(uint16_t *)(puRes) = ASMAtomicReadU16((volatile uint16_t *)(void *)(pu)); break; \
+ case 4: *(uint32_t *)(puRes) = ASMAtomicReadU32((volatile uint32_t *)(void *)(pu)); break; \
+ case 8: *(uint64_t *)(puRes) = ASMAtomicReadU64((volatile uint64_t *)(void *)(pu)); break; \
+ default: AssertMsgFailed(("ASMAtomicReadSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+
+/**
+ * Atomically read a value which size might differ
+ * between platforms or compilers, unordered.
+ *
+ * @param pu Pointer to the variable to read.
+ * @param puRes Where to store the result.
+ */
+#define ASMAtomicUoReadSize(pu, puRes) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 1: *(uint8_t *)(puRes) = ASMAtomicUoReadU8( (volatile uint8_t *)(void *)(pu)); break; \
+ case 2: *(uint16_t *)(puRes) = ASMAtomicUoReadU16((volatile uint16_t *)(void *)(pu)); break; \
+ case 4: *(uint32_t *)(puRes) = ASMAtomicUoReadU32((volatile uint32_t *)(void *)(pu)); break; \
+ case 8: *(uint64_t *)(puRes) = ASMAtomicUoReadU64((volatile uint64_t *)(void *)(pu)); break; \
+ default: AssertMsgFailed(("ASMAtomicReadSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+
+/**
+ * Atomically writes an unsigned 8-bit value, ordered.
+ *
+ * @param pu8 Pointer to the 8-bit variable.
+ * @param u8 The 8-bit value to assign to *pu8.
+ */
+DECLINLINE(void) ASMAtomicWriteU8(volatile uint8_t *pu8, uint8_t u8)
+{
+ ASMAtomicXchgU8(pu8, u8);
+}
+
+
+/**
+ * Atomically writes an unsigned 8-bit value, unordered.
+ *
+ * @param pu8 Pointer to the 8-bit variable.
+ * @param u8 The 8-bit value to assign to *pu8.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU8(volatile uint8_t *pu8, uint8_t u8)
+{
+ *pu8 = u8; /* byte writes are atomic on x86 */
+}
+
+
+/**
+ * Atomically writes a signed 8-bit value, ordered.
+ *
+ * @param pi8 Pointer to the 8-bit variable to read.
+ * @param i8 The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(void) ASMAtomicWriteS8(volatile int8_t *pi8, int8_t i8)
+{
+ ASMAtomicXchgS8(pi8, i8);
+}
+
+
+/**
+ * Atomically writes a signed 8-bit value, unordered.
+ *
+ * @param pi8 Pointer to the 8-bit variable to write.
+ * @param i8 The 8-bit value to assign to *pi8.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS8(volatile int8_t *pi8, int8_t i8)
+{
+ *pi8 = i8; /* byte writes are atomic on x86 */
+}
+
+
+/**
+ * Atomically writes an unsigned 16-bit value, ordered.
+ *
+ * @param pu16 Pointer to the 16-bit variable to write.
+ * @param u16 The 16-bit value to assign to *pu16.
+ */
+DECLINLINE(void) ASMAtomicWriteU16(volatile uint16_t *pu16, uint16_t u16)
+{
+ ASMAtomicXchgU16(pu16, u16);
+}
+
+
+/**
+ * Atomically writes an unsigned 16-bit value, unordered.
+ *
+ * @param pu16 Pointer to the 16-bit variable to write.
+ * @param u16 The 16-bit value to assign to *pu16.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU16(volatile uint16_t *pu16, uint16_t u16)
+{
+ Assert(!((uintptr_t)pu16 & 1));
+ *pu16 = u16;
+}
+
+
+/**
+ * Atomically writes a signed 16-bit value, ordered.
+ *
+ * @param pi16 Pointer to the 16-bit variable to write.
+ * @param i16 The 16-bit value to assign to *pi16.
+ */
+DECLINLINE(void) ASMAtomicWriteS16(volatile int16_t *pi16, int16_t i16)
+{
+ ASMAtomicXchgS16(pi16, i16);
+}
+
+
+/**
+ * Atomically writes a signed 16-bit value, unordered.
+ *
+ * @param pi16 Pointer to the 16-bit variable to write.
+ * @param i16 The 16-bit value to assign to *pi16.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS16(volatile int16_t *pi16, int16_t i16)
+{
+ Assert(!((uintptr_t)pi16 & 1));
+ *pi16 = i16;
+}
+
+
+/**
+ * Atomically writes an unsigned 32-bit value, ordered.
+ *
+ * @param pu32 Pointer to the 32-bit variable to write.
+ * @param u32 The 32-bit value to assign to *pu32.
+ */
+DECLINLINE(void) ASMAtomicWriteU32(volatile uint32_t *pu32, uint32_t u32)
+{
+ ASMAtomicXchgU32(pu32, u32);
+}
+
+
+/**
+ * Atomically writes an unsigned 32-bit value, unordered.
+ *
+ * @param pu32 Pointer to the 32-bit variable to write.
+ * @param u32 The 32-bit value to assign to *pu32.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU32(volatile uint32_t *pu32, uint32_t u32)
+{
+ Assert(!((uintptr_t)pu32 & 3));
+ *pu32 = u32;
+}
+
+
+/**
+ * Atomically writes a signed 32-bit value, ordered.
+ *
+ * @param pi32 Pointer to the 32-bit variable to write.
+ * @param i32 The 32-bit value to assign to *pi32.
+ */
+DECLINLINE(void) ASMAtomicWriteS32(volatile int32_t *pi32, int32_t i32)
+{
+ ASMAtomicXchgS32(pi32, i32);
+}
+
+
+/**
+ * Atomically writes a signed 32-bit value, unordered.
+ *
+ * @param pi32 Pointer to the 32-bit variable to write.
+ * @param i32 The 32-bit value to assign to *pi32.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS32(volatile int32_t *pi32, int32_t i32)
+{
+ Assert(!((uintptr_t)pi32 & 3));
+ *pi32 = i32;
+}
+
+
+/**
+ * Atomically writes an unsigned 64-bit value, ordered.
+ *
+ * @param pu64 Pointer to the 64-bit variable to write.
+ * @param u64 The 64-bit value to assign to *pu64.
+ */
+DECLINLINE(void) ASMAtomicWriteU64(volatile uint64_t *pu64, uint64_t u64)
+{
+ ASMAtomicXchgU64(pu64, u64);
+}
+
+
+/**
+ * Atomically writes an unsigned 64-bit value, unordered.
+ *
+ * @param pu64 Pointer to the 64-bit variable to write.
+ * @param u64 The 64-bit value to assign to *pu64.
+ */
+DECLINLINE(void) ASMAtomicUoWriteU64(volatile uint64_t *pu64, uint64_t u64)
+{
+ Assert(!((uintptr_t)pu64 & 7));
+#if ARCH_BITS == 64
+ *pu64 = u64;
+#else
+ ASMAtomicXchgU64(pu64, u64);
+#endif
+}
+
+
+/**
+ * Atomically writes a signed 64-bit value, ordered.
+ *
+ * @param pi64 Pointer to the 64-bit variable to write.
+ * @param i64 The 64-bit value to assign to *pi64.
+ */
+DECLINLINE(void) ASMAtomicWriteS64(volatile int64_t *pi64, int64_t i64)
+{
+ ASMAtomicXchgS64(pi64, i64);
+}
+
+
+/**
+ * Atomically writes a signed 64-bit value, unordered.
+ *
+ * @param pi64 Pointer to the 64-bit variable to write.
+ * @param i64 The 64-bit value to assign to *pi64.
+ */
+DECLINLINE(void) ASMAtomicUoWriteS64(volatile int64_t *pi64, int64_t i64)
+{
+ Assert(!((uintptr_t)pi64 & 7));
+#if ARCH_BITS == 64
+ *pi64 = i64;
+#else
+ ASMAtomicXchgS64(pi64, i64);
+#endif
+}
+
+
+/**
+ * Atomically writes a boolean value, unordered.
+ *
+ * @param pf Pointer to the boolean variable to write.
+ * @param f The boolean value to assign to *pf.
+ */
+DECLINLINE(void) ASMAtomicWriteBool(volatile bool *pf, bool f)
+{
+ ASMAtomicWriteU8((uint8_t volatile *)pf, f);
+}
+
+
+/**
+ * Atomically writes a boolean value, unordered.
+ *
+ * @param pf Pointer to the boolean variable to write.
+ * @param f The boolean value to assign to *pf.
+ */
+DECLINLINE(void) ASMAtomicUoWriteBool(volatile bool *pf, bool f)
+{
+ *pf = f; /* byte writes are atomic on x86 */
+}
+
+
+/**
+ * Atomically writes a pointer value, ordered.
+ *
+ * @param ppv Pointer to the pointer variable to write.
+ * @param pv The pointer value to assign to *ppv.
+ */
+DECLINLINE(void) ASMAtomicWritePtrVoid(void * volatile *ppv, const void *pv)
+{
+#if ARCH_BITS == 32
+ ASMAtomicWriteU32((volatile uint32_t *)(void *)ppv, (uint32_t)pv);
+#elif ARCH_BITS == 64
+ ASMAtomicWriteU64((volatile uint64_t *)(void *)ppv, (uint64_t)pv);
+#else
+# error "ARCH_BITS is bogus"
+#endif
+}
+
+
+/**
+ * Atomically writes a pointer value, ordered.
+ *
+ * @param ppv Pointer to the pointer variable to write.
+ * @param pv The pointer value to assign to *ppv. If NULL use
+ * ASMAtomicWriteNullPtr or you'll land in trouble.
+ *
+ * @remarks This is relatively type safe on GCC platforms when @a pv isn't
+ * NULL.
+ */
+#ifdef __GNUC__
+# define ASMAtomicWritePtr(ppv, pv) \
+ do \
+ { \
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ __typeof__(*(ppv)) const pvTypeChecked = (pv); \
+ \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ AssertCompile(sizeof(pv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ \
+ ASMAtomicWritePtrVoid((void * volatile *)(ppvTypeChecked), (void *)(pvTypeChecked)); \
+ } while (0)
+#else
+# define ASMAtomicWritePtr(ppv, pv) \
+ do \
+ { \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ AssertCompile(sizeof(pv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ \
+ ASMAtomicWritePtrVoid((void * volatile *)(ppv), (void *)(pv)); \
+ } while (0)
+#endif
+
+
+/**
+ * Atomically sets a pointer to NULL, ordered.
+ *
+ * @param ppv Pointer to the pointer variable that should be set to NULL.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicWriteNullPtr(ppv) \
+ do \
+ { \
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ ASMAtomicWritePtrVoid((void * volatile *)(ppvTypeChecked), NULL); \
+ } while (0)
+#else
+# define ASMAtomicWriteNullPtr(ppv) \
+ do \
+ { \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ ASMAtomicWritePtrVoid((void * volatile *)(ppv), NULL); \
+ } while (0)
+#endif
+
+
+/**
+ * Atomically writes a pointer value, unordered.
+ *
+ * @returns Current *pv value
+ * @param ppv Pointer to the pointer variable.
+ * @param pv The pointer value to assign to *ppv. If NULL use
+ * ASMAtomicUoWriteNullPtr or you'll land in trouble.
+ *
+ * @remarks This is relatively type safe on GCC platforms when @a pv isn't
+ * NULL.
+ */
+#ifdef __GNUC__
+# define ASMAtomicUoWritePtr(ppv, pv) \
+ do \
+ { \
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ __typeof__(*(ppv)) const pvTypeChecked = (pv); \
+ \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ AssertCompile(sizeof(pv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ \
+ *(ppvTypeChecked) = pvTypeChecked; \
+ } while (0)
+#else
+# define ASMAtomicUoWritePtr(ppv, pv) \
+ do \
+ { \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ AssertCompile(sizeof(pv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ *(ppv) = pv; \
+ } while (0)
+#endif
+
+
+/**
+ * Atomically sets a pointer to NULL, unordered.
+ *
+ * @param ppv Pointer to the pointer variable that should be set to NULL.
+ *
+ * @remarks This is relatively type safe on GCC platforms.
+ */
+#ifdef __GNUC__
+# define ASMAtomicUoWriteNullPtr(ppv) \
+ do \
+ { \
+ __typeof__(*(ppv)) volatile * const ppvTypeChecked = (ppv); \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ *(ppvTypeChecked) = NULL; \
+ } while (0)
+#else
+# define ASMAtomicUoWriteNullPtr(ppv) \
+ do \
+ { \
+ AssertCompile(sizeof(*ppv) == sizeof(void *)); \
+ Assert(!( (uintptr_t)ppv & ((ARCH_BITS / 8) - 1) )); \
+ *(ppv) = NULL; \
+ } while (0)
+#endif
+
+
+/**
+ * Atomically write a typical IPRT handle value, ordered.
+ *
+ * @param ph Pointer to the variable to update.
+ * @param hNew The value to assign to *ph.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicWriteHandle(ph, hNew) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+ ASMAtomicWriteU32((uint32_t volatile *)(ph), (const uint32_t)(hNew)); \
+ } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicWriteHandle(ph, hNew) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+ ASMAtomicWriteU64((uint64_t volatile *)(ph), (const uint64_t)(hNew)); \
+ } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically write a typical IPRT handle value, unordered.
+ *
+ * @param ph Pointer to the variable to update.
+ * @param hNew The value to assign to *ph.
+ *
+ * @remarks This doesn't currently work for all handles (like RTFILE).
+ */
+#if HC_ARCH_BITS == 32
+# define ASMAtomicUoWriteHandle(ph, hNew) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint32_t)); \
+ ASMAtomicUoWriteU32((uint32_t volatile *)(ph), (const uint32_t)hNew); \
+ } while (0)
+#elif HC_ARCH_BITS == 64
+# define ASMAtomicUoWriteHandle(ph, hNew) \
+ do { \
+ AssertCompile(sizeof(*(ph)) == sizeof(uint64_t)); \
+ ASMAtomicUoWriteU64((uint64_t volatile *)(ph), (const uint64_t)hNew); \
+ } while (0)
+#else
+# error HC_ARCH_BITS
+#endif
+
+
+/**
+ * Atomically write a value which size might differ
+ * between platforms or compilers, ordered.
+ *
+ * @param pu Pointer to the variable to update.
+ * @param uNew The value to assign to *pu.
+ */
+#define ASMAtomicWriteSize(pu, uNew) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 1: ASMAtomicWriteU8( (volatile uint8_t *)(void *)(pu), (uint8_t )(uNew)); break; \
+ case 2: ASMAtomicWriteU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+ case 4: ASMAtomicWriteU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+ case 8: ASMAtomicWriteU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+ default: AssertMsgFailed(("ASMAtomicWriteSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+/**
+ * Atomically write a value which size might differ
+ * between platforms or compilers, unordered.
+ *
+ * @param pu Pointer to the variable to update.
+ * @param uNew The value to assign to *pu.
+ */
+#define ASMAtomicUoWriteSize(pu, uNew) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 1: ASMAtomicUoWriteU8( (volatile uint8_t *)(void *)(pu), (uint8_t )(uNew)); break; \
+ case 2: ASMAtomicUoWriteU16((volatile uint16_t *)(void *)(pu), (uint16_t)(uNew)); break; \
+ case 4: ASMAtomicUoWriteU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+ case 8: ASMAtomicUoWriteU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+ default: AssertMsgFailed(("ASMAtomicWriteSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+
+
+/**
+ * Atomically exchanges and adds to a 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pu32 Pointer to the value.
+ * @param u32 Number to add.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicAddU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMAtomicAddU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ u32 = _InterlockedExchangeAdd((long *)pu32, u32);
+ return u32;
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; xaddl %0, %1\n\t"
+ : "=r" (u32),
+ "=m" (*pu32)
+ : "0" (u32),
+ "m" (*pu32)
+ : "memory");
+ return u32;
+# else
+ __asm
+ {
+ mov eax, [u32]
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+ lock xadd [rdx], eax
+# else
+ mov edx, [pu32]
+ lock xadd [edx], eax
+# endif
+ mov [u32], eax
+ }
+ return u32;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically exchanges and adds to a signed 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pi32 Pointer to the value.
+ * @param i32 Number to add.
+ */
+DECLINLINE(int32_t) ASMAtomicAddS32(int32_t volatile *pi32, int32_t i32)
+{
+ return (int32_t)ASMAtomicAddU32((uint32_t volatile *)pi32, (uint32_t)i32);
+}
+
+
+/**
+ * Atomically exchanges and adds to a 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pu64 Pointer to the value.
+ * @param u64 Number to add.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMAtomicAddU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(uint64_t) ASMAtomicAddU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+ u64 = _InterlockedExchangeAdd64((__int64 *)pu64, u64);
+ return u64;
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+ __asm__ __volatile__("lock; xaddq %0, %1\n\t"
+ : "=r" (u64),
+ "=m" (*pu64)
+ : "0" (u64),
+ "m" (*pu64)
+ : "memory");
+ return u64;
+# else
+ uint64_t u64Old;
+ for (;;)
+ {
+ uint64_t u64New;
+ u64Old = ASMAtomicUoReadU64(pu64);
+ u64New = u64Old + u64;
+ if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+ break;
+ ASMNopPause();
+ }
+ return u64Old;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically exchanges and adds to a signed 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pi64 Pointer to the value.
+ * @param i64 Number to add.
+ */
+DECLINLINE(int64_t) ASMAtomicAddS64(int64_t volatile *pi64, int64_t i64)
+{
+ return (int64_t)ASMAtomicAddU64((uint64_t volatile *)pi64, (uint64_t)i64);
+}
+
+
+/**
+ * Atomically exchanges and adds to a size_t value, ordered.
+ *
+ * @returns The old value.
+ * @param pcb Pointer to the size_t value.
+ * @param cb Number to add.
+ */
+DECLINLINE(size_t) ASMAtomicAddZ(size_t volatile *pcb, size_t cb)
+{
+#if ARCH_BITS == 64
+ return ASMAtomicAddU64((uint64_t volatile *)pcb, cb);
+#elif ARCH_BITS == 32
+ return ASMAtomicAddU32((uint32_t volatile *)pcb, cb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically exchanges and adds a value which size might differ between
+ * platforms or compilers, ordered.
+ *
+ * @param pu Pointer to the variable to update.
+ * @param uNew The value to add to *pu.
+ * @param puOld Where to store the old value.
+ */
+#define ASMAtomicAddSize(pu, uNew, puOld) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 4: *(uint32_t *)(puOld) = ASMAtomicAddU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+ case 8: *(uint64_t *)(puOld) = ASMAtomicAddU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+ default: AssertMsgFailed(("ASMAtomicAddSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+
+/**
+ * Atomically exchanges and subtracts to an unsigned 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pu32 Pointer to the value.
+ * @param u32 Number to subtract.
+ */
+DECLINLINE(uint32_t) ASMAtomicSubU32(uint32_t volatile *pu32, uint32_t u32)
+{
+ return ASMAtomicAddU32(pu32, (uint32_t)-(int32_t)u32);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to a signed 32-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pi32 Pointer to the value.
+ * @param i32 Number to subtract.
+ */
+DECLINLINE(int32_t) ASMAtomicSubS32(int32_t volatile *pi32, int32_t i32)
+{
+ return (int32_t)ASMAtomicAddU32((uint32_t volatile *)pi32, (uint32_t)-i32);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to an unsigned 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pu64 Pointer to the value.
+ * @param u64 Number to subtract.
+ */
+DECLINLINE(uint64_t) ASMAtomicSubU64(uint64_t volatile *pu64, uint64_t u64)
+{
+ return ASMAtomicAddU64(pu64, (uint64_t)-(int64_t)u64);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to a signed 64-bit value, ordered.
+ *
+ * @returns The old value.
+ * @param pi64 Pointer to the value.
+ * @param i64 Number to subtract.
+ */
+DECLINLINE(int64_t) ASMAtomicSubS64(int64_t volatile *pi64, int64_t i64)
+{
+ return (int64_t)ASMAtomicAddU64((uint64_t volatile *)pi64, (uint64_t)-i64);
+}
+
+
+/**
+ * Atomically exchanges and subtracts to a size_t value, ordered.
+ *
+ * @returns The old value.
+ * @param pcb Pointer to the size_t value.
+ * @param cb Number to subtract.
+ */
+DECLINLINE(size_t) ASMAtomicSubZ(size_t volatile *pcb, size_t cb)
+{
+#if ARCH_BITS == 64
+ return ASMAtomicSubU64((uint64_t volatile *)pcb, cb);
+#elif ARCH_BITS == 32
+ return ASMAtomicSubU32((uint32_t volatile *)pcb, cb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically exchanges and subtracts a value which size might differ between
+ * platforms or compilers, ordered.
+ *
+ * @param pu Pointer to the variable to update.
+ * @param uNew The value to subtract to *pu.
+ * @param puOld Where to store the old value.
+ */
+#define ASMAtomicSubSize(pu, uNew, puOld) \
+ do { \
+ switch (sizeof(*(pu))) { \
+ case 4: *(uint32_t *)(puOld) = ASMAtomicSubU32((volatile uint32_t *)(void *)(pu), (uint32_t)(uNew)); break; \
+ case 8: *(uint64_t *)(puOld) = ASMAtomicSubU64((volatile uint64_t *)(void *)(pu), (uint64_t)(uNew)); break; \
+ default: AssertMsgFailed(("ASMAtomicSubSize: size %d is not supported\n", sizeof(*(pu)))); \
+ } \
+ } while (0)
+
+
+/**
+ * Atomically increment a 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pu32 Pointer to the value to increment.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicIncU32(uint32_t volatile *pu32);
+#else
+DECLINLINE(uint32_t) ASMAtomicIncU32(uint32_t volatile *pu32)
+{
+ uint32_t u32;
+# if RT_INLINE_ASM_USES_INTRIN
+ u32 = _InterlockedIncrement((long *)pu32);
+ return u32;
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; xaddl %0, %1\n\t"
+ : "=r" (u32),
+ "=m" (*pu32)
+ : "0" (1),
+ "m" (*pu32)
+ : "memory");
+ return u32+1;
+# else
+ __asm
+ {
+ mov eax, 1
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+ lock xadd [rdx], eax
+# else
+ mov edx, [pu32]
+ lock xadd [edx], eax
+# endif
+ mov u32, eax
+ }
+ return u32+1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically increment a signed 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pi32 Pointer to the value to increment.
+ */
+DECLINLINE(int32_t) ASMAtomicIncS32(int32_t volatile *pi32)
+{
+ return (int32_t)ASMAtomicIncU32((uint32_t volatile *)pi32);
+}
+
+
+/**
+ * Atomically increment a 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pu64 Pointer to the value to increment.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMAtomicIncU64(uint64_t volatile *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicIncU64(uint64_t volatile *pu64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+ uint64_t u64;
+ u64 = _InterlockedIncrement64((__int64 *)pu64);
+ return u64;
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+ uint64_t u64;
+ __asm__ __volatile__("lock; xaddq %0, %1\n\t"
+ : "=r" (u64),
+ "=m" (*pu64)
+ : "0" (1),
+ "m" (*pu64)
+ : "memory");
+ return u64 + 1;
+# else
+ return ASMAtomicAddU64(pu64, 1) + 1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically increment a signed 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pi64 Pointer to the value to increment.
+ */
+DECLINLINE(int64_t) ASMAtomicIncS64(int64_t volatile *pi64)
+{
+ return (int64_t)ASMAtomicIncU64((uint64_t volatile *)pi64);
+}
+
+
+/**
+ * Atomically increment a size_t value, ordered.
+ *
+ * @returns The new value.
+ * @param pcb Pointer to the value to increment.
+ */
+DECLINLINE(int64_t) ASMAtomicIncZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+ return ASMAtomicIncU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+ return ASMAtomicIncU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically decrement an unsigned 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pu32 Pointer to the value to decrement.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMAtomicDecU32(uint32_t volatile *pu32);
+#else
+DECLINLINE(uint32_t) ASMAtomicDecU32(uint32_t volatile *pu32)
+{
+ uint32_t u32;
+# if RT_INLINE_ASM_USES_INTRIN
+ u32 = _InterlockedDecrement((long *)pu32);
+ return u32;
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; xaddl %0, %1\n\t"
+ : "=r" (u32),
+ "=m" (*pu32)
+ : "0" (-1),
+ "m" (*pu32)
+ : "memory");
+ return u32-1;
+# else
+ __asm
+ {
+ mov eax, -1
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+ lock xadd [rdx], eax
+# else
+ mov edx, [pu32]
+ lock xadd [edx], eax
+# endif
+ mov u32, eax
+ }
+ return u32-1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically decrement a signed 32-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pi32 Pointer to the value to decrement.
+ */
+DECLINLINE(int32_t) ASMAtomicDecS32(int32_t volatile *pi32)
+{
+ return (int32_t)ASMAtomicDecU32((uint32_t volatile *)pi32);
+}
+
+
+/**
+ * Atomically decrement an unsigned 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pu64 Pointer to the value to decrement.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint64_t) ASMAtomicDecU64(uint64_t volatile *pu64);
+#else
+DECLINLINE(uint64_t) ASMAtomicDecU64(uint64_t volatile *pu64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+ uint64_t u64 = _InterlockedDecrement64((__int64 volatile *)pu64);
+ return u64;
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+ uint64_t u64;
+ __asm__ __volatile__("lock; xaddq %q0, %1\n\t"
+ : "=r" (u64),
+ "=m" (*pu64)
+ : "0" (~(uint64_t)0),
+ "m" (*pu64)
+ : "memory");
+ return u64-1;
+# else
+ return ASMAtomicAddU64(pu64, UINT64_MAX) - 1;
+# endif
+}
+#endif
+
+
+/**
+ * Atomically decrement a signed 64-bit value, ordered.
+ *
+ * @returns The new value.
+ * @param pi64 Pointer to the value to decrement.
+ */
+DECLINLINE(int64_t) ASMAtomicDecS64(int64_t volatile *pi64)
+{
+ return (int64_t)ASMAtomicDecU64((uint64_t volatile *)pi64);
+}
+
+
+/**
+ * Atomically decrement a size_t value, ordered.
+ *
+ * @returns The new value.
+ * @param pcb Pointer to the value to decrement.
+ */
+DECLINLINE(int64_t) ASMAtomicDecZ(size_t volatile *pcb)
+{
+#if ARCH_BITS == 64
+ return ASMAtomicDecU64((uint64_t volatile *)pcb);
+#elif ARCH_BITS == 32
+ return ASMAtomicDecU32((uint32_t volatile *)pcb);
+#else
+# error "Unsupported ARCH_BITS value"
+#endif
+}
+
+
+/**
+ * Atomically Or an unsigned 32-bit value, ordered.
+ *
+ * @param pu32 Pointer to the pointer variable to OR u32 with.
+ * @param u32 The value to OR *pu32 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicOrU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(void) ASMAtomicOrU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ _InterlockedOr((long volatile *)pu32, (long)u32);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; orl %1, %0\n\t"
+ : "=m" (*pu32)
+ : "ir" (u32),
+ "m" (*pu32));
+# else
+ __asm
+ {
+ mov eax, [u32]
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+ lock or [rdx], eax
+# else
+ mov edx, [pu32]
+ lock or [edx], eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Or a signed 32-bit value, ordered.
+ *
+ * @param pi32 Pointer to the pointer variable to OR u32 with.
+ * @param i32 The value to OR *pu32 with.
+ */
+DECLINLINE(void) ASMAtomicOrS32(int32_t volatile *pi32, int32_t i32)
+{
+ ASMAtomicOrU32((uint32_t volatile *)pi32, i32);
+}
+
+
+/**
+ * Atomically Or an unsigned 64-bit value, ordered.
+ *
+ * @param pu64 Pointer to the pointer variable to OR u64 with.
+ * @param u64 The value to OR *pu64 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicOrU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(void) ASMAtomicOrU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+ _InterlockedOr64((__int64 volatile *)pu64, (__int64)u64);
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+ __asm__ __volatile__("lock; orq %1, %q0\n\t"
+ : "=m" (*pu64)
+ : "r" (u64),
+ "m" (*pu64));
+# else
+ for (;;)
+ {
+ uint64_t u64Old = ASMAtomicUoReadU64(pu64);
+ uint64_t u64New = u64Old | u64;
+ if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+ break;
+ ASMNopPause();
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically Or a signed 64-bit value, ordered.
+ *
+ * @param pi64 Pointer to the pointer variable to OR u64 with.
+ * @param i64 The value to OR *pu64 with.
+ */
+DECLINLINE(void) ASMAtomicOrS64(int64_t volatile *pi64, int64_t i64)
+{
+ ASMAtomicOrU64((uint64_t volatile *)pi64, i64);
+}
+/**
+ * Atomically And an unsigned 32-bit value, ordered.
+ *
+ * @param pu32 Pointer to the pointer variable to AND u32 with.
+ * @param u32 The value to AND *pu32 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicAndU32(uint32_t volatile *pu32, uint32_t u32);
+#else
+DECLINLINE(void) ASMAtomicAndU32(uint32_t volatile *pu32, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ _InterlockedAnd((long volatile *)pu32, u32);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; andl %1, %0\n\t"
+ : "=m" (*pu32)
+ : "ir" (u32),
+ "m" (*pu32));
+# else
+ __asm
+ {
+ mov eax, [u32]
+# ifdef RT_ARCH_AMD64
+ mov rdx, [pu32]
+ lock and [rdx], eax
+# else
+ mov edx, [pu32]
+ lock and [edx], eax
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically And a signed 32-bit value, ordered.
+ *
+ * @param pi32 Pointer to the pointer variable to AND i32 with.
+ * @param i32 The value to AND *pi32 with.
+ */
+DECLINLINE(void) ASMAtomicAndS32(int32_t volatile *pi32, int32_t i32)
+{
+ ASMAtomicAndU32((uint32_t volatile *)pi32, (uint32_t)i32);
+}
+
+
+/**
+ * Atomically And an unsigned 64-bit value, ordered.
+ *
+ * @param pu64 Pointer to the pointer variable to AND u64 with.
+ * @param u64 The value to AND *pu64 with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicAndU64(uint64_t volatile *pu64, uint64_t u64);
+#else
+DECLINLINE(void) ASMAtomicAndU64(uint64_t volatile *pu64, uint64_t u64)
+{
+# if RT_INLINE_ASM_USES_INTRIN && defined(RT_ARCH_AMD64)
+ _InterlockedAnd64((__int64 volatile *)pu64, u64);
+
+# elif RT_INLINE_ASM_GNU_STYLE && defined(RT_ARCH_AMD64)
+ __asm__ __volatile__("lock; andq %1, %0\n\t"
+ : "=m" (*pu64)
+ : "r" (u64),
+ "m" (*pu64));
+# else
+ for (;;)
+ {
+ uint64_t u64Old = ASMAtomicUoReadU64(pu64);
+ uint64_t u64New = u64Old & u64;
+ if (ASMAtomicCmpXchgU64(pu64, u64New, u64Old))
+ break;
+ ASMNopPause();
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically And a signed 64-bit value, ordered.
+ *
+ * @param pi64 Pointer to the pointer variable to AND i64 with.
+ * @param i64 The value to AND *pi64 with.
+ */
+DECLINLINE(void) ASMAtomicAndS64(int64_t volatile *pi64, int64_t i64)
+{
+ ASMAtomicAndU64((uint64_t volatile *)pi64, (uint64_t)i64);
+}
+
+
+
+/** @def RT_ASM_PAGE_SIZE
+ * We try avoid dragging in iprt/param.h here.
+ * @internal
+ */
+#if defined(RT_ARCH_SPARC64)
+# define RT_ASM_PAGE_SIZE 0x2000
+# if defined(PAGE_SIZE) && !defined(NT_INCLUDED)
+# if PAGE_SIZE != 0x2000
+# error "PAGE_SIZE is not 0x2000!"
+# endif
+# endif
+#else
+# define RT_ASM_PAGE_SIZE 0x1000
+# if defined(PAGE_SIZE) && !defined(NT_INCLUDED)
+# if PAGE_SIZE != 0x1000
+# error "PAGE_SIZE is not 0x1000!"
+# endif
+# endif
+#endif
+
+/**
+ * Zeros a 4K memory page.
+ *
+ * @param pv Pointer to the memory block. This must be page aligned.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMMemZeroPage(volatile void *pv);
+# else
+DECLINLINE(void) ASMMemZeroPage(volatile void *pv)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+# ifdef RT_ARCH_AMD64
+ __stosq((unsigned __int64 *)pv, 0, RT_ASM_PAGE_SIZE / 8);
+# else
+ __stosd((unsigned long *)pv, 0, RT_ASM_PAGE_SIZE / 4);
+# endif
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG uDummy;
+# ifdef RT_ARCH_AMD64
+ __asm__ __volatile__("rep stosq"
+ : "=D" (pv),
+ "=c" (uDummy)
+ : "0" (pv),
+ "c" (RT_ASM_PAGE_SIZE >> 3),
+ "a" (0)
+ : "memory");
+# else
+ __asm__ __volatile__("rep stosl"
+ : "=D" (pv),
+ "=c" (uDummy)
+ : "0" (pv),
+ "c" (RT_ASM_PAGE_SIZE >> 2),
+ "a" (0)
+ : "memory");
+# endif
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ xor rax, rax
+ mov ecx, 0200h
+ mov rdi, [pv]
+ rep stosq
+# else
+ xor eax, eax
+ mov ecx, 0400h
+ mov edi, [pv]
+ rep stosd
+# endif
+ }
+# endif
+}
+# endif
+
+
+/**
+ * Zeros a memory block with a 32-bit aligned size.
+ *
+ * @param pv Pointer to the memory block.
+ * @param cb Number of bytes in the block. This MUST be aligned on 32-bit!
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMMemZero32(volatile void *pv, size_t cb);
+#else
+DECLINLINE(void) ASMMemZero32(volatile void *pv, size_t cb)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+# ifdef RT_ARCH_AMD64
+ if (!(cb & 7))
+ __stosq((unsigned __int64 *)pv, 0, cb / 8);
+ else
+# endif
+ __stosd((unsigned long *)pv, 0, cb / 4);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep stosl"
+ : "=D" (pv),
+ "=c" (cb)
+ : "0" (pv),
+ "1" (cb >> 2),
+ "a" (0)
+ : "memory");
+# else
+ __asm
+ {
+ xor eax, eax
+# ifdef RT_ARCH_AMD64
+ mov rcx, [cb]
+ shr rcx, 2
+ mov rdi, [pv]
+# else
+ mov ecx, [cb]
+ shr ecx, 2
+ mov edi, [pv]
+# endif
+ rep stosd
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Fills a memory block with a 32-bit aligned size.
+ *
+ * @param pv Pointer to the memory block.
+ * @param cb Number of bytes in the block. This MUST be aligned on 32-bit!
+ * @param u32 The value to fill with.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMMemFill32(volatile void *pv, size_t cb, uint32_t u32);
+#else
+DECLINLINE(void) ASMMemFill32(volatile void *pv, size_t cb, uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+# ifdef RT_ARCH_AMD64
+ if (!(cb & 7))
+ __stosq((unsigned __int64 *)pv, RT_MAKE_U64(u32, u32), cb / 8);
+ else
+# endif
+ __stosd((unsigned long *)pv, u32, cb / 4);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("rep stosl"
+ : "=D" (pv),
+ "=c" (cb)
+ : "0" (pv),
+ "1" (cb >> 2),
+ "a" (u32)
+ : "memory");
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rcx, [cb]
+ shr rcx, 2
+ mov rdi, [pv]
+# else
+ mov ecx, [cb]
+ shr ecx, 2
+ mov edi, [pv]
+# endif
+ mov eax, [u32]
+ rep stosd
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Checks if a memory page is all zeros.
+ *
+ * @returns true / false.
+ *
+ * @param pvPage Pointer to the page. Must be aligned on 16 byte
+ * boundary
+ */
+DECLINLINE(bool) ASMMemIsZeroPage(void const *pvPage)
+{
+# if 0 /*RT_INLINE_ASM_GNU_STYLE - this is actually slower... */
+ union { RTCCUINTREG r; bool f; } uAX;
+ RTCCUINTREG xCX, xDI;
+ Assert(!((uintptr_t)pvPage & 15));
+ __asm__ __volatile__("repe; "
+# ifdef RT_ARCH_AMD64
+ "scasq\n\t"
+# else
+ "scasl\n\t"
+# endif
+ "setnc %%al\n\t"
+ : "=&c" (xCX),
+ "=&D" (xDI),
+ "=&a" (uAX.r)
+ : "mr" (pvPage),
+# ifdef RT_ARCH_AMD64
+ "0" (RT_ASM_PAGE_SIZE/8),
+# else
+ "0" (RT_ASM_PAGE_SIZE/4),
+# endif
+ "1" (pvPage),
+ "2" (0));
+ return uAX.f;
+# else
+ uintptr_t const *puPtr = (uintptr_t const *)pvPage;
+ int cLeft = RT_ASM_PAGE_SIZE / sizeof(uintptr_t) / 8;
+ Assert(!((uintptr_t)pvPage & 15));
+ for (;;)
+ {
+ if (puPtr[0]) return false;
+ if (puPtr[4]) return false;
+
+ if (puPtr[2]) return false;
+ if (puPtr[6]) return false;
+
+ if (puPtr[1]) return false;
+ if (puPtr[5]) return false;
+
+ if (puPtr[3]) return false;
+ if (puPtr[7]) return false;
+
+ if (!--cLeft)
+ return true;
+ puPtr += 8;
+ }
+ return true;
+# endif
+}
+
+
+/**
+ * Checks if a memory block is filled with the specified byte.
+ *
+ * This is a sort of inverted memchr.
+ *
+ * @returns Pointer to the byte which doesn't equal u8.
+ * @returns NULL if all equal to u8.
+ *
+ * @param pv Pointer to the memory block.
+ * @param cb Number of bytes in the block. This MUST be aligned on 32-bit!
+ * @param u8 The value it's supposed to be filled with.
+ *
+ * @todo Fix name, it is a predicate function but it's not returning boolean!
+ */
+DECLINLINE(void *) ASMMemIsAll8(void const *pv, size_t cb, uint8_t u8)
+{
+/** @todo rewrite this in inline assembly? */
+ uint8_t const *pb = (uint8_t const *)pv;
+ for (; cb; cb--, pb++)
+ if (RT_UNLIKELY(*pb != u8))
+ return (void *)pb;
+ return NULL;
+}
+
+
+/**
+ * Checks if a memory block is filled with the specified 32-bit value.
+ *
+ * This is a sort of inverted memchr.
+ *
+ * @returns Pointer to the first value which doesn't equal u32.
+ * @returns NULL if all equal to u32.
+ *
+ * @param pv Pointer to the memory block.
+ * @param cb Number of bytes in the block. This MUST be aligned on 32-bit!
+ * @param u32 The value it's supposed to be filled with.
+ *
+ * @todo Fix name, it is a predicate function but it's not returning boolean!
+ */
+DECLINLINE(uint32_t *) ASMMemIsAllU32(void const *pv, size_t cb, uint32_t u32)
+{
+/** @todo rewrite this in inline assembly? */
+ uint32_t const *pu32 = (uint32_t const *)pv;
+ for (; cb; cb -= 4, pu32++)
+ if (RT_UNLIKELY(*pu32 != u32))
+ return (uint32_t *)pu32;
+ return NULL;
+}
+
+
+/**
+ * Probes a byte pointer for read access.
+ *
+ * While the function will not fault if the byte is not read accessible,
+ * the idea is to do this in a safe place like before acquiring locks
+ * and such like.
+ *
+ * Also, this functions guarantees that an eager compiler is not going
+ * to optimize the probing away.
+ *
+ * @param pvByte Pointer to the byte.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(uint8_t) ASMProbeReadByte(const void *pvByte);
+#else
+DECLINLINE(uint8_t) ASMProbeReadByte(const void *pvByte)
+{
+ /** @todo verify that the compiler actually doesn't optimize this away. (intel & gcc) */
+ uint8_t u8;
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("movb (%1), %0\n\t"
+ : "=r" (u8)
+ : "r" (pvByte));
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvByte]
+ mov al, [rax]
+# else
+ mov eax, [pvByte]
+ mov al, [eax]
+# endif
+ mov [u8], al
+ }
+# endif
+ return u8;
+}
+#endif
+
+/**
+ * Probes a buffer for read access page by page.
+ *
+ * While the function will fault if the buffer is not fully read
+ * accessible, the idea is to do this in a safe place like before
+ * acquiring locks and such like.
+ *
+ * Also, this functions guarantees that an eager compiler is not going
+ * to optimize the probing away.
+ *
+ * @param pvBuf Pointer to the buffer.
+ * @param cbBuf The size of the buffer in bytes. Must be >= 1.
+ */
+DECLINLINE(void) ASMProbeReadBuffer(const void *pvBuf, size_t cbBuf)
+{
+ /** @todo verify that the compiler actually doesn't optimize this away. (intel & gcc) */
+ /* the first byte */
+ const uint8_t *pu8 = (const uint8_t *)pvBuf;
+ ASMProbeReadByte(pu8);
+
+ /* the pages in between pages. */
+ while (cbBuf > RT_ASM_PAGE_SIZE)
+ {
+ ASMProbeReadByte(pu8);
+ cbBuf -= RT_ASM_PAGE_SIZE;
+ pu8 += RT_ASM_PAGE_SIZE;
+ }
+
+ /* the last byte */
+ ASMProbeReadByte(pu8 + cbBuf - 1);
+}
+
+
+
+/** @defgroup grp_inline_bits Bit Operations
+ * @{
+ */
+
+
+/**
+ * Sets a bit in a bitmap.
+ *
+ * @param pvBitmap Pointer to the bitmap. This should be 32-bit aligned.
+ * @param iBit The bit to set.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ * However, doing so will yield better performance as well as avoiding
+ * traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMBitSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMBitSet(volatile void *pvBitmap, int32_t iBit)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ _bittestandset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("btsl %1, %0"
+ : "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ mov edx, [iBit]
+ bts [rax], edx
+# else
+ mov eax, [pvBitmap]
+ mov edx, [iBit]
+ bts [eax], edx
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically sets a bit in a bitmap, ordered.
+ *
+ * @param pvBitmap Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ * the memory access isn't atomic!
+ * @param iBit The bit to set.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMAtomicBitSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMAtomicBitSet(volatile void *pvBitmap, int32_t iBit)
+{
+ AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_USES_INTRIN
+ _interlockedbittestandset((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; btsl %1, %0"
+ : "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ mov edx, [iBit]
+ lock bts [rax], edx
+# else
+ mov eax, [pvBitmap]
+ mov edx, [iBit]
+ lock bts [eax], edx
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Clears a bit in a bitmap.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBit The bit to clear.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ * However, doing so will yield better performance as well as avoiding
+ * traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMBitClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMBitClear(volatile void *pvBitmap, int32_t iBit)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ _bittestandreset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("btrl %1, %0"
+ : "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ mov edx, [iBit]
+ btr [rax], edx
+# else
+ mov eax, [pvBitmap]
+ mov edx, [iBit]
+ btr [eax], edx
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically clears a bit in a bitmap, ordered.
+ *
+ * @param pvBitmap Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ * the memory access isn't atomic!
+ * @param iBit The bit to toggle set.
+ * @remarks No memory barrier, take care on smp.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicBitClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMAtomicBitClear(volatile void *pvBitmap, int32_t iBit)
+{
+ AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; btrl %1, %0"
+ : "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ mov edx, [iBit]
+ lock btr [rax], edx
+# else
+ mov eax, [pvBitmap]
+ mov edx, [iBit]
+ lock btr [eax], edx
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Toggles a bit in a bitmap.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBit The bit to toggle.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ * However, doing so will yield better performance as well as avoiding
+ * traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(void) ASMBitToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMBitToggle(volatile void *pvBitmap, int32_t iBit)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ _bittestandcomplement((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("btcl %1, %0"
+ : "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ mov edx, [iBit]
+ btc [rax], edx
+# else
+ mov eax, [pvBitmap]
+ mov edx, [iBit]
+ btc [eax], edx
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Atomically toggles a bit in a bitmap, ordered.
+ *
+ * @param pvBitmap Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ * the memory access isn't atomic!
+ * @param iBit The bit to test and set.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(void) ASMAtomicBitToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(void) ASMAtomicBitToggle(volatile void *pvBitmap, int32_t iBit)
+{
+ AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; btcl %1, %0"
+ : "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ mov edx, [iBit]
+ lock btc [rax], edx
+# else
+ mov eax, [pvBitmap]
+ mov edx, [iBit]
+ lock btc [eax], edx
+# endif
+ }
+# endif
+}
+#endif
+
+
+/**
+ * Tests and sets a bit in a bitmap.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBit The bit to test and set.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ * However, doing so will yield better performance as well as avoiding
+ * traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTestAndSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTestAndSet(volatile void *pvBitmap, int32_t iBit)
+{
+ union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+ rc.u8 = _bittestandset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("btsl %2, %1\n\t"
+ "setc %b0\n\t"
+ "andl $1, %0\n\t"
+ : "=q" (rc.u32),
+ "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+ mov edx, [iBit]
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ bts [rax], edx
+# else
+ mov eax, [pvBitmap]
+ bts [eax], edx
+# endif
+ setc al
+ and eax, 1
+ mov [rc.u32], eax
+ }
+# endif
+ return rc.f;
+}
+#endif
+
+
+/**
+ * Atomically tests and sets a bit in a bitmap, ordered.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param pvBitmap Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ * the memory access isn't atomic!
+ * @param iBit The bit to set.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicBitTestAndSet(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMAtomicBitTestAndSet(volatile void *pvBitmap, int32_t iBit)
+{
+ union { bool f; uint32_t u32; uint8_t u8; } rc;
+ AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_USES_INTRIN
+ rc.u8 = _interlockedbittestandset((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; btsl %2, %1\n\t"
+ "setc %b0\n\t"
+ "andl $1, %0\n\t"
+ : "=q" (rc.u32),
+ "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+ mov edx, [iBit]
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ lock bts [rax], edx
+# else
+ mov eax, [pvBitmap]
+ lock bts [eax], edx
+# endif
+ setc al
+ and eax, 1
+ mov [rc.u32], eax
+ }
+# endif
+ return rc.f;
+}
+#endif
+
+
+/**
+ * Tests and clears a bit in a bitmap.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBit The bit to test and clear.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ * However, doing so will yield better performance as well as avoiding
+ * traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTestAndClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTestAndClear(volatile void *pvBitmap, int32_t iBit)
+{
+ union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+ rc.u8 = _bittestandreset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("btrl %2, %1\n\t"
+ "setc %b0\n\t"
+ "andl $1, %0\n\t"
+ : "=q" (rc.u32),
+ "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+ mov edx, [iBit]
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ btr [rax], edx
+# else
+ mov eax, [pvBitmap]
+ btr [eax], edx
+# endif
+ setc al
+ and eax, 1
+ mov [rc.u32], eax
+ }
+# endif
+ return rc.f;
+}
+#endif
+
+
+/**
+ * Atomically tests and clears a bit in a bitmap, ordered.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param pvBitmap Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ * the memory access isn't atomic!
+ * @param iBit The bit to test and clear.
+ *
+ * @remarks No memory barrier, take care on smp.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMAtomicBitTestAndClear(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMAtomicBitTestAndClear(volatile void *pvBitmap, int32_t iBit)
+{
+ union { bool f; uint32_t u32; uint8_t u8; } rc;
+ AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_USES_INTRIN
+ rc.u8 = _interlockedbittestandreset((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; btrl %2, %1\n\t"
+ "setc %b0\n\t"
+ "andl $1, %0\n\t"
+ : "=q" (rc.u32),
+ "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+ mov edx, [iBit]
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ lock btr [rax], edx
+# else
+ mov eax, [pvBitmap]
+ lock btr [eax], edx
+# endif
+ setc al
+ and eax, 1
+ mov [rc.u32], eax
+ }
+# endif
+ return rc.f;
+}
+#endif
+
+
+/**
+ * Tests and toggles a bit in a bitmap.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBit The bit to test and toggle.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ * However, doing so will yield better performance as well as avoiding
+ * traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTestAndToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTestAndToggle(volatile void *pvBitmap, int32_t iBit)
+{
+ union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+ rc.u8 = _bittestandcomplement((long *)pvBitmap, iBit);
+
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("btcl %2, %1\n\t"
+ "setc %b0\n\t"
+ "andl $1, %0\n\t"
+ : "=q" (rc.u32),
+ "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+ mov edx, [iBit]
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ btc [rax], edx
+# else
+ mov eax, [pvBitmap]
+ btc [eax], edx
+# endif
+ setc al
+ and eax, 1
+ mov [rc.u32], eax
+ }
+# endif
+ return rc.f;
+}
+#endif
+
+
+/**
+ * Atomically tests and toggles a bit in a bitmap, ordered.
+ *
+ * @returns true if the bit was set.
+ * @returns false if the bit was clear.
+ *
+ * @param pvBitmap Pointer to the bitmap. Must be 32-bit aligned, otherwise
+ * the memory access isn't atomic!
+ * @param iBit The bit to test and toggle.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(bool) ASMAtomicBitTestAndToggle(volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMAtomicBitTestAndToggle(volatile void *pvBitmap, int32_t iBit)
+{
+ union { bool f; uint32_t u32; uint8_t u8; } rc;
+ AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("lock; btcl %2, %1\n\t"
+ "setc %b0\n\t"
+ "andl $1, %0\n\t"
+ : "=q" (rc.u32),
+ "=m" (*(volatile long *)pvBitmap)
+ : "Ir" (iBit),
+ "m" (*(volatile long *)pvBitmap)
+ : "memory");
+# else
+ __asm
+ {
+ mov edx, [iBit]
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ lock btc [rax], edx
+# else
+ mov eax, [pvBitmap]
+ lock btc [eax], edx
+# endif
+ setc al
+ and eax, 1
+ mov [rc.u32], eax
+ }
+# endif
+ return rc.f;
+}
+#endif
+
+
+/**
+ * Tests if a bit in a bitmap is set.
+ *
+ * @returns true if the bit is set.
+ * @returns false if the bit is clear.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBit The bit to test.
+ *
+ * @remarks The 32-bit aligning of pvBitmap is not a strict requirement.
+ * However, doing so will yield better performance as well as avoiding
+ * traps accessing the last bits in the bitmap.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(bool) ASMBitTest(const volatile void *pvBitmap, int32_t iBit);
+#else
+DECLINLINE(bool) ASMBitTest(const volatile void *pvBitmap, int32_t iBit)
+{
+ union { bool f; uint32_t u32; uint8_t u8; } rc;
+# if RT_INLINE_ASM_USES_INTRIN
+ rc.u32 = _bittest((long *)pvBitmap, iBit);
+# elif RT_INLINE_ASM_GNU_STYLE
+
+ __asm__ __volatile__("btl %2, %1\n\t"
+ "setc %b0\n\t"
+ "andl $1, %0\n\t"
+ : "=q" (rc.u32)
+ : "m" (*(const volatile long *)pvBitmap),
+ "Ir" (iBit)
+ : "memory");
+# else
+ __asm
+ {
+ mov edx, [iBit]
+# ifdef RT_ARCH_AMD64
+ mov rax, [pvBitmap]
+ bt [rax], edx
+# else
+ mov eax, [pvBitmap]
+ bt [eax], edx
+# endif
+ setc al
+ and eax, 1
+ mov [rc.u32], eax
+ }
+# endif
+ return rc.f;
+}
+#endif
+
+
+/**
+ * Clears a bit range within a bitmap.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBitStart The First bit to clear.
+ * @param iBitEnd The first bit not to clear.
+ */
+DECLINLINE(void) ASMBitClearRange(volatile void *pvBitmap, int32_t iBitStart, int32_t iBitEnd)
+{
+ if (iBitStart < iBitEnd)
+ {
+ volatile uint32_t *pu32 = (volatile uint32_t *)pvBitmap + (iBitStart >> 5);
+ int iStart = iBitStart & ~31;
+ int iEnd = iBitEnd & ~31;
+ if (iStart == iEnd)
+ *pu32 &= ((1 << (iBitStart & 31)) - 1) | ~((1 << (iBitEnd & 31)) - 1);
+ else
+ {
+ /* bits in first dword. */
+ if (iBitStart & 31)
+ {
+ *pu32 &= (1 << (iBitStart & 31)) - 1;
+ pu32++;
+ iBitStart = iStart + 32;
+ }
+
+ /* whole dword. */
+ if (iBitStart != iEnd)
+ ASMMemZero32(pu32, (iEnd - iBitStart) >> 3);
+
+ /* bits in last dword. */
+ if (iBitEnd & 31)
+ {
+ pu32 = (volatile uint32_t *)pvBitmap + (iBitEnd >> 5);
+ *pu32 &= ~((1 << (iBitEnd & 31)) - 1);
+ }
+ }
+ }
+}
+
+
+/**
+ * Sets a bit range within a bitmap.
+ *
+ * @param pvBitmap Pointer to the bitmap.
+ * @param iBitStart The First bit to set.
+ * @param iBitEnd The first bit not to set.
+ */
+DECLINLINE(void) ASMBitSetRange(volatile void *pvBitmap, int32_t iBitStart, int32_t iBitEnd)
+{
+ if (iBitStart < iBitEnd)
+ {
+ volatile uint32_t *pu32 = (volatile uint32_t *)pvBitmap + (iBitStart >> 5);
+ int iStart = iBitStart & ~31;
+ int iEnd = iBitEnd & ~31;
+ if (iStart == iEnd)
+ *pu32 |= ((1 << (iBitEnd - iBitStart)) - 1) << iBitStart;
+ else
+ {
+ /* bits in first dword. */
+ if (iBitStart & 31)
+ {
+ *pu32 |= ~((1 << (iBitStart & 31)) - 1);
+ pu32++;
+ iBitStart = iStart + 32;
+ }
+
+ /* whole dword. */
+ if (iBitStart != iEnd)
+ ASMMemFill32(pu32, (iEnd - iBitStart) >> 3, ~UINT32_C(0));
+
+ /* bits in last dword. */
+ if (iBitEnd & 31)
+ {
+ pu32 = (volatile uint32_t *)pvBitmap + (iBitEnd >> 5);
+ *pu32 |= (1 << (iBitEnd & 31)) - 1;
+ }
+ }
+ }
+}
+
+
+/**
+ * Finds the first clear bit in a bitmap.
+ *
+ * @returns Index of the first zero bit.
+ * @returns -1 if no clear bit was found.
+ * @param pvBitmap Pointer to the bitmap.
+ * @param cBits The number of bits in the bitmap. Multiple of 32.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(int) ASMBitFirstClear(const volatile void *pvBitmap, uint32_t cBits);
+#else
+DECLINLINE(int) ASMBitFirstClear(const volatile void *pvBitmap, uint32_t cBits)
+{
+ if (cBits)
+ {
+ int32_t iBit;
+# if RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG uEAX, uECX, uEDI;
+ cBits = RT_ALIGN_32(cBits, 32);
+ __asm__ __volatile__("repe; scasl\n\t"
+ "je 1f\n\t"
+# ifdef RT_ARCH_AMD64
+ "lea -4(%%rdi), %%rdi\n\t"
+ "xorl (%%rdi), %%eax\n\t"
+ "subq %5, %%rdi\n\t"
+# else
+ "lea -4(%%edi), %%edi\n\t"
+ "xorl (%%edi), %%eax\n\t"
+ "subl %5, %%edi\n\t"
+# endif
+ "shll $3, %%edi\n\t"
+ "bsfl %%eax, %%edx\n\t"
+ "addl %%edi, %%edx\n\t"
+ "1:\t\n"
+ : "=d" (iBit),
+ "=&c" (uECX),
+ "=&D" (uEDI),
+ "=&a" (uEAX)
+ : "0" (0xffffffff),
+ "mr" (pvBitmap),
+ "1" (cBits >> 5),
+ "2" (pvBitmap),
+ "3" (0xffffffff));
+# else
+ cBits = RT_ALIGN_32(cBits, 32);
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rdi, [pvBitmap]
+ mov rbx, rdi
+# else
+ mov edi, [pvBitmap]
+ mov ebx, edi
+# endif
+ mov edx, 0ffffffffh
+ mov eax, edx
+ mov ecx, [cBits]
+ shr ecx, 5
+ repe scasd
+ je done
+
+# ifdef RT_ARCH_AMD64
+ lea rdi, [rdi - 4]
+ xor eax, [rdi]
+ sub rdi, rbx
+# else
+ lea edi, [edi - 4]
+ xor eax, [edi]
+ sub edi, ebx
+# endif
+ shl edi, 3
+ bsf edx, eax
+ add edx, edi
+ done:
+ mov [iBit], edx
+ }
+# endif
+ return iBit;
+ }
+ return -1;
+}
+#endif
+
+
+/**
+ * Finds the next clear bit in a bitmap.
+ *
+ * @returns Index of the first zero bit.
+ * @returns -1 if no clear bit was found.
+ * @param pvBitmap Pointer to the bitmap.
+ * @param cBits The number of bits in the bitmap. Multiple of 32.
+ * @param iBitPrev The bit returned from the last search.
+ * The search will start at iBitPrev + 1.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(int) ASMBitNextClear(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev);
+#else
+DECLINLINE(int) ASMBitNextClear(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev)
+{
+ const volatile uint32_t *pau32Bitmap = (const volatile uint32_t *)pvBitmap;
+ int iBit = ++iBitPrev & 31;
+ if (iBit)
+ {
+ /*
+ * Inspect the 32-bit word containing the unaligned bit.
+ */
+ uint32_t u32 = ~pau32Bitmap[iBitPrev / 32] >> iBit;
+
+# if RT_INLINE_ASM_USES_INTRIN
+ unsigned long ulBit = 0;
+ if (_BitScanForward(&ulBit, u32))
+ return ulBit + iBitPrev;
+# else
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("bsf %1, %0\n\t"
+ "jnz 1f\n\t"
+ "movl $-1, %0\n\t"
+ "1:\n\t"
+ : "=r" (iBit)
+ : "r" (u32));
+# else
+ __asm
+ {
+ mov edx, [u32]
+ bsf eax, edx
+ jnz done
+ mov eax, 0ffffffffh
+ done:
+ mov [iBit], eax
+ }
+# endif
+ if (iBit >= 0)
+ return iBit + iBitPrev;
+# endif
+
+ /*
+ * Skip ahead and see if there is anything left to search.
+ */
+ iBitPrev |= 31;
+ iBitPrev++;
+ if (cBits <= (uint32_t)iBitPrev)
+ return -1;
+ }
+
+ /*
+ * 32-bit aligned search, let ASMBitFirstClear do the dirty work.
+ */
+ iBit = ASMBitFirstClear(&pau32Bitmap[iBitPrev / 32], cBits - iBitPrev);
+ if (iBit >= 0)
+ iBit += iBitPrev;
+ return iBit;
+}
+#endif
+
+
+/**
+ * Finds the first set bit in a bitmap.
+ *
+ * @returns Index of the first set bit.
+ * @returns -1 if no clear bit was found.
+ * @param pvBitmap Pointer to the bitmap.
+ * @param cBits The number of bits in the bitmap. Multiple of 32.
+ */
+#if RT_INLINE_ASM_EXTERNAL
+DECLASM(int) ASMBitFirstSet(const volatile void *pvBitmap, uint32_t cBits);
+#else
+DECLINLINE(int) ASMBitFirstSet(const volatile void *pvBitmap, uint32_t cBits)
+{
+ if (cBits)
+ {
+ int32_t iBit;
+# if RT_INLINE_ASM_GNU_STYLE
+ RTCCUINTREG uEAX, uECX, uEDI;
+ cBits = RT_ALIGN_32(cBits, 32);
+ __asm__ __volatile__("repe; scasl\n\t"
+ "je 1f\n\t"
+# ifdef RT_ARCH_AMD64
+ "lea -4(%%rdi), %%rdi\n\t"
+ "movl (%%rdi), %%eax\n\t"
+ "subq %5, %%rdi\n\t"
+# else
+ "lea -4(%%edi), %%edi\n\t"
+ "movl (%%edi), %%eax\n\t"
+ "subl %5, %%edi\n\t"
+# endif
+ "shll $3, %%edi\n\t"
+ "bsfl %%eax, %%edx\n\t"
+ "addl %%edi, %%edx\n\t"
+ "1:\t\n"
+ : "=d" (iBit),
+ "=&c" (uECX),
+ "=&D" (uEDI),
+ "=&a" (uEAX)
+ : "0" (0xffffffff),
+ "mr" (pvBitmap),
+ "1" (cBits >> 5),
+ "2" (pvBitmap),
+ "3" (0));
+# else
+ cBits = RT_ALIGN_32(cBits, 32);
+ __asm
+ {
+# ifdef RT_ARCH_AMD64
+ mov rdi, [pvBitmap]
+ mov rbx, rdi
+# else
+ mov edi, [pvBitmap]
+ mov ebx, edi
+# endif
+ mov edx, 0ffffffffh
+ xor eax, eax
+ mov ecx, [cBits]
+ shr ecx, 5
+ repe scasd
+ je done
+# ifdef RT_ARCH_AMD64
+ lea rdi, [rdi - 4]
+ mov eax, [rdi]
+ sub rdi, rbx
+# else
+ lea edi, [edi - 4]
+ mov eax, [edi]
+ sub edi, ebx
+# endif
+ shl edi, 3
+ bsf edx, eax
+ add edx, edi
+ done:
+ mov [iBit], edx
+ }
+# endif
+ return iBit;
+ }
+ return -1;
+}
+#endif
+
+
+/**
+ * Finds the next set bit in a bitmap.
+ *
+ * @returns Index of the next set bit.
+ * @returns -1 if no set bit was found.
+ * @param pvBitmap Pointer to the bitmap.
+ * @param cBits The number of bits in the bitmap. Multiple of 32.
+ * @param iBitPrev The bit returned from the last search.
+ * The search will start at iBitPrev + 1.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(int) ASMBitNextSet(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev);
+#else
+DECLINLINE(int) ASMBitNextSet(const volatile void *pvBitmap, uint32_t cBits, uint32_t iBitPrev)
+{
+ const volatile uint32_t *pau32Bitmap = (const volatile uint32_t *)pvBitmap;
+ int iBit = ++iBitPrev & 31;
+ if (iBit)
+ {
+ /*
+ * Inspect the 32-bit word containing the unaligned bit.
+ */
+ uint32_t u32 = pau32Bitmap[iBitPrev / 32] >> iBit;
+
+# if RT_INLINE_ASM_USES_INTRIN
+ unsigned long ulBit = 0;
+ if (_BitScanForward(&ulBit, u32))
+ return ulBit + iBitPrev;
+# else
+# if RT_INLINE_ASM_GNU_STYLE
+ __asm__ __volatile__("bsf %1, %0\n\t"
+ "jnz 1f\n\t"
+ "movl $-1, %0\n\t"
+ "1:\n\t"
+ : "=r" (iBit)
+ : "r" (u32));
+# else
+ __asm
+ {
+ mov edx, [u32]
+ bsf eax, edx
+ jnz done
+ mov eax, 0ffffffffh
+ done:
+ mov [iBit], eax
+ }
+# endif
+ if (iBit >= 0)
+ return iBit + iBitPrev;
+# endif
+
+ /*
+ * Skip ahead and see if there is anything left to search.
+ */
+ iBitPrev |= 31;
+ iBitPrev++;
+ if (cBits <= (uint32_t)iBitPrev)
+ return -1;
+ }
+
+ /*
+ * 32-bit aligned search, let ASMBitFirstClear do the dirty work.
+ */
+ iBit = ASMBitFirstSet(&pau32Bitmap[iBitPrev / 32], cBits - iBitPrev);
+ if (iBit >= 0)
+ iBit += iBitPrev;
+ return iBit;
+}
+#endif
+
+
+/**
+ * Finds the first bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the first set bit.
+ * @returns 0 if all bits are cleared.
+ * @param u32 Integer to search for set bits.
+ * @remark Similar to ffs() in BSD.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(unsigned) ASMBitFirstSetU32(uint32_t u32);
+#else
+DECLINLINE(unsigned) ASMBitFirstSetU32(uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ unsigned long iBit;
+ if (_BitScanForward(&iBit, u32))
+ iBit++;
+ else
+ iBit = 0;
+# elif RT_INLINE_ASM_GNU_STYLE
+ uint32_t iBit;
+ __asm__ __volatile__("bsf %1, %0\n\t"
+ "jnz 1f\n\t"
+ "xorl %0, %0\n\t"
+ "jmp 2f\n"
+ "1:\n\t"
+ "incl %0\n"
+ "2:\n\t"
+ : "=r" (iBit)
+ : "rm" (u32));
+# else
+ uint32_t iBit;
+ _asm
+ {
+ bsf eax, [u32]
+ jnz found
+ xor eax, eax
+ jmp done
+ found:
+ inc eax
+ done:
+ mov [iBit], eax
+ }
+# endif
+ return iBit;
+}
+#endif
+
+
+/**
+ * Finds the first bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the first set bit.
+ * @returns 0 if all bits are cleared.
+ * @param i32 Integer to search for set bits.
+ * @remark Similar to ffs() in BSD.
+ */
+DECLINLINE(unsigned) ASMBitFirstSetS32(int32_t i32)
+{
+ return ASMBitFirstSetU32((uint32_t)i32);
+}
+
+
+/**
+ * Finds the last bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the last set bit.
+ * @returns 0 if all bits are cleared.
+ * @param u32 Integer to search for set bits.
+ * @remark Similar to fls() in BSD.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(unsigned) ASMBitLastSetU32(uint32_t u32);
+#else
+DECLINLINE(unsigned) ASMBitLastSetU32(uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ unsigned long iBit;
+ if (_BitScanReverse(&iBit, u32))
+ iBit++;
+ else
+ iBit = 0;
+# elif RT_INLINE_ASM_GNU_STYLE
+ uint32_t iBit;
+ __asm__ __volatile__("bsrl %1, %0\n\t"
+ "jnz 1f\n\t"
+ "xorl %0, %0\n\t"
+ "jmp 2f\n"
+ "1:\n\t"
+ "incl %0\n"
+ "2:\n\t"
+ : "=r" (iBit)
+ : "rm" (u32));
+# else
+ uint32_t iBit;
+ _asm
+ {
+ bsr eax, [u32]
+ jnz found
+ xor eax, eax
+ jmp done
+ found:
+ inc eax
+ done:
+ mov [iBit], eax
+ }
+# endif
+ return iBit;
+}
+#endif
+
+
+/**
+ * Finds the last bit which is set in the given 32-bit integer.
+ * Bits are numbered from 1 (least significant) to 32.
+ *
+ * @returns index [1..32] of the last set bit.
+ * @returns 0 if all bits are cleared.
+ * @param i32 Integer to search for set bits.
+ * @remark Similar to fls() in BSD.
+ */
+DECLINLINE(unsigned) ASMBitLastSetS32(int32_t i32)
+{
+ return ASMBitLastSetU32((uint32_t)i32);
+}
+
+/**
+ * Reverse the byte order of the given 16-bit integer.
+ *
+ * @returns Revert
+ * @param u16 16-bit integer value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint16_t) ASMByteSwapU16(uint16_t u16);
+#else
+DECLINLINE(uint16_t) ASMByteSwapU16(uint16_t u16)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ u16 = _byteswap_ushort(u16);
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ ("rorw $8, %0" : "=r" (u16) : "0" (u16));
+# else
+ _asm
+ {
+ mov ax, [u16]
+ ror ax, 8
+ mov [u16], ax
+ }
+# endif
+ return u16;
+}
+#endif
+
+
+/**
+ * Reverse the byte order of the given 32-bit integer.
+ *
+ * @returns Revert
+ * @param u32 32-bit integer value.
+ */
+#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
+DECLASM(uint32_t) ASMByteSwapU32(uint32_t u32);
+#else
+DECLINLINE(uint32_t) ASMByteSwapU32(uint32_t u32)
+{
+# if RT_INLINE_ASM_USES_INTRIN
+ u32 = _byteswap_ulong(u32);
+# elif RT_INLINE_ASM_GNU_STYLE
+ __asm__ ("bswapl %0" : "=r" (u32) : "0" (u32));
+# else
+ _asm
+ {
+ mov eax, [u32]
+ bswap eax
+ mov [u32], eax
+ }
+# endif
+ return u32;
+}
+#endif
+
+
+/**
+ * Reverse the byte order of the given 64-bit integer.
+ *
+ * @returns Revert
+ * @param u64 64-bit integer value.
+ */
+DECLINLINE(uint64_t) ASMByteSwapU64(uint64_t u64)
+{
+#if defined(RT_ARCH_AMD64) && RT_INLINE_ASM_USES_INTRIN
+ u64 = _byteswap_uint64(u64);
+#else
+ u64 = (uint64_t)ASMByteSwapU32((uint32_t)u64) << 32
+ | (uint64_t)ASMByteSwapU32((uint32_t)(u64 >> 32));
+#endif
+ return u64;
+}
+
+
+/** @} */
+
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/asmdefs.mac b/include/iprt/asmdefs.mac
new file mode 100644
index 00000000..665c674b
--- /dev/null
+++ b/include/iprt/asmdefs.mac
@@ -0,0 +1,774 @@
+;; @file
+; IPRT - Global YASM/NASM macros
+;
+
+;
+; 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 ___iprt_asmdefs_mac
+%define ___iprt_asmdefs_mac
+
+
+;; @defgroup grp_rt_cdefs_size Size Constants
+; (Of course, these are binary computer terms, not SI.)
+; @{
+;; 1 K (Kilo) (1 024).
+%define _1K 000000400h
+;; 4 K (Kilo) (4 096).
+%define _4K 000001000h
+;; 32 K (Kilo) (32 678).
+%define _32K 000008000h
+;; 64 K (Kilo) (65 536).
+%define _64K 000010000h
+;; 128 K (Kilo) (131 072).
+%define _128K 000020000h
+;; 256 K (Kilo) (262 144).
+%define _256K 000040000h
+;; 512 K (Kilo) (524 288).
+%define _512K 000080000h
+;; 1 M (Mega) (1 048 576).
+%define _1M 000100000h
+;; 2 M (Mega) (2 097 152).
+%define _2M 000200000h
+;; 4 M (Mega) (4 194 304).
+%define _4M 000400000h
+;; 1 G (Giga) (1 073 741 824).
+%define _1G 040000000h
+;; 2 G (Giga) (2 147 483 648).
+%define _2G 00000000080000000h
+;; 4 G (Giga) (4 294 967 296).
+%define _4G 00000000100000000h
+;; 1 T (Tera) (1 099 511 627 776).
+%define _1T 00000010000000000h
+;; 1 P (Peta) (1 125 899 906 842 624).
+%define _1P 00004000000000000h
+;; 1 E (Exa) (1 152 921 504 606 846 976).
+%define _1E 01000000000000000h
+;; 2 E (Exa) (2 305 843 009 213 693 952).
+%define _2E 02000000000000000h
+;; @}
+
+
+;;
+; Make the mask for the given bit.
+%define RT_BIT(bit) (1 << bit)
+
+;;
+; Align code, pad with INT3.
+%define ALIGNCODE(alignment) align alignment, db 0cch
+
+;;
+; Align data, pad with ZEROs.
+%define ALIGNDATA(alignment) align alignment, db 0
+
+;;
+; Align BSS, pad with ZEROs.
+%define ALIGNBSS(alignment) align alignment, resb 1
+
+;;
+; NAME_OVERLOAD can be defined by a .asm module to modify all the
+; names created using the name macros in this files.
+; This is handy when you've got some kind of template code.
+%ifndef NAME_OVERLOAD
+ %define NAME_OVERLOAD(name) name
+%endif
+
+;;
+; Mangles the given name so it can be referenced using DECLASM() in the
+; C/C++ world.
+%ifdef RT_ARCH_X86
+ %ifdef RT_OS_OS2
+ %define NAME(name) _ %+ NAME_OVERLOAD(name)
+ %endif
+ %ifdef RT_OS_WINDOWS
+ %define NAME(name) _ %+ NAME_OVERLOAD(name)
+ %endif
+%endif
+%ifdef RT_OS_DARWIN
+ %define NAME(name) _ %+ NAME_OVERLOAD(name)
+%endif
+%ifndef NAME
+ %define NAME(name) NAME_OVERLOAD(name)
+%endif
+
+;;
+; Mangles the given C name so it will _import_ the right symbol.
+%ifdef ASM_FORMAT_PE
+%define IMPNAME(name) __imp_ %+ NAME(name)
+%else
+%define IMPNAME(name) NAME(name)
+%endif
+
+;;
+; Gets the pointer to an imported object.
+%ifdef ASM_FORMAT_PE
+ %ifdef RT_ARCH_AMD64
+ %define IMP(name) qword [IMPNAME(name) wrt rip]
+ %else
+ %define IMP(name) dword [IMPNAME(name)]
+ %endif
+%else
+ %define IMP(name) IMPNAME(name)
+%endif
+
+;;
+; Gets the pointer to an imported object, version 2.
+%ifdef ASM_FORMAT_PE
+ %ifdef RT_ARCH_AMD64
+ %define IMP2(name) qword [IMPNAME(name) wrt rip]
+ %else
+ %define IMP2(name) dword [IMPNAME(name)]
+ %endif
+%else
+ %ifdef RT_ARCH_AMD64
+ %define IMP2(name) IMPNAME(name) wrt rip
+ %else
+ %define IMP2(name) IMPNAME(name)
+ %endif
+%endif
+
+
+
+;;
+; Global marker which is DECLASM() compatible.
+%macro GLOBALNAME 1,
+%ifndef ASM_FORMAT_BIN
+global NAME(%1)
+%endif
+NAME(%1):
+%endmacro
+
+;;
+; Global exported marker which is DECLASM() compatible.
+%macro EXPORTEDNAME 1,
+ %ifdef ASM_FORMAT_PE
+ export %1=NAME(%1)
+ %endif
+ %ifdef __NASM__
+ %ifdef ASM_FORMAT_OMF
+ export NAME(%1) NAME(%1)
+ %endif
+%endif
+GLOBALNAME %1
+%endmacro
+
+;;
+; Global marker which is DECLASM() compatible.
+%macro GLOBALNAME_EX 2,
+%ifndef ASM_FORMAT_BIN
+ %ifdef ASM_FORMAT_ELF
+global NAME(%1):%2
+ %else
+global NAME(%1)
+ %endif
+%endif
+NAME(%1):
+%endmacro
+
+;;
+; Global exported marker which is DECLASM() compatible.
+%macro EXPORTEDNAME_EX 2,
+ %ifdef ASM_FORMAT_PE
+ export %1=NAME(%1)
+ %endif
+ %ifdef __NASM__
+ %ifdef ASM_FORMAT_OMF
+ export NAME(%1) NAME(%1)
+ %endif
+%endif
+GLOBALNAME_EX %1, %2
+%endmacro
+
+;;
+; Begins a C callable procedure.
+%macro BEGINPROC 1
+GLOBALNAME_EX %1, function hidden
+%endmacro
+
+;;
+; Begins a C callable exported procedure.
+%macro BEGINPROC_EXPORTED 1
+EXPORTEDNAME_EX %1, function
+%endmacro
+
+;;
+; Ends a C callable procedure.
+%macro ENDPROC 1
+GLOBALNAME_EX %1 %+ _EndProc, function hidden
+%ifdef ASM_FORMAT_ELF
+size NAME(%1) NAME(%1 %+ _EndProc) - NAME(%1)
+size NAME(%1 %+ _EndProc) 0
+%endif
+ db 0xCC, 0xCC, 0xCC, 0xCC
+%endmacro
+
+
+;
+; Do OMF and Mach-O/Yasm segment definitions
+;
+; Both format requires this to get the segment order right, in the Mach-O/Yasm case
+; it's only to make sure the .bss section ends up last (it's not declared here).
+;
+%ifdef ASM_FORMAT_OMF
+
+ ; 16-bit segments first (OMF / OS/2 specific).
+ %ifdef RT_INCL_16BIT_SEGMENTS
+ segment DATA16 public CLASS=FAR_DATA align=16 use16
+ segment DATA16_INIT public CLASS=FAR_DATA align=16 use16
+ group DGROUP16 DATA16 DATA16_INIT
+
+ ;;
+ ; Begins 16-bit data
+ %macro BEGINDATA16 0
+ segment DATA16
+ %endmacro
+
+ ;;
+ ; Begins 16-bit init data
+ %macro BEGINDATA16INIT 0
+ segment DATA16_INIT
+ %endmacro
+
+ segment CODE16 public CLASS=FAR_CODE align=16 use16
+ segment CODE16_INIT public CLASS=FAR_CODE align=16 use16
+ group CGROUP16 CODE16 CODE16_INIT
+
+ ;;
+ ; Begins 16-bit code
+ %macro BEGINCODE16 0
+ segment CODE16
+ %endmacro
+
+ ;;
+ ; Begins 16-bit init code
+ %macro BEGINCODE16INIT 0
+ segment CODE16_INIT
+ %endmacro
+
+ %endif
+
+ ; 32-bit segments.
+ segment TEXT32 public CLASS=CODE align=16 use32 flat
+ segment DATA32 public CLASS=DATA align=16 use32 flat
+ segment BSS32 public CLASS=BSS align=16 use32 flat
+
+ ; Make the TEXT32 segment default.
+ segment TEXT32
+%endif
+
+%ifdef ASM_FORMAT_MACHO
+ %ifdef __YASM__
+ [section .text]
+ [section .data]
+ %endif
+%endif
+
+
+;;
+; Begins code
+%ifdef ASM_FORMAT_OMF
+ %macro BEGINCODE 0
+ segment TEXT32
+ %endmacro
+%else
+%macro BEGINCODE 0
+[section .text]
+%endmacro
+%endif
+
+;;
+; Begins constant (read-only) data
+;
+; @remarks This is mapped to the CODE section/segment when there isn't
+; any dedicated const section/segment. (There is code that
+; assumes this, so don't try change it.)
+%ifdef ASM_FORMAT_OMF
+ %macro BEGINCONST 0
+ segment TEXT32
+ %endmacro
+%else
+ %macro BEGINCONST 0
+ %ifdef ASM_FORMAT_MACHO ;; @todo check the other guys too.
+ [section .rodata]
+ %else
+ [section .text]
+ %endif
+ %endmacro
+%endif
+
+;;
+; Begins initialized data
+%ifdef ASM_FORMAT_OMF
+ %macro BEGINDATA 0
+ segment DATA32
+ %endmacro
+%else
+%macro BEGINDATA 0
+[section .data]
+%endmacro
+%endif
+
+;;
+; Begins uninitialized data
+%ifdef ASM_FORMAT_OMF
+ %macro BEGINBSS 0
+ segment BSS32
+ %endmacro
+%else
+%macro BEGINBSS 0
+[section .bss]
+%endmacro
+%endif
+
+
+
+;; @def ARCH_BITS
+; Defines the bit count of the current context.
+%ifndef ARCH_BITS
+ %ifdef RT_ARCH_AMD64
+ %define ARCH_BITS 64
+ %else
+ %define ARCH_BITS 32
+ %endif
+%endif
+
+;; @def HC_ARCH_BITS
+; Defines the host architechture bit count.
+%ifndef HC_ARCH_BITS
+ %ifndef IN_RC
+ %define HC_ARCH_BITS ARCH_BITS
+ %else
+ %define HC_ARCH_BITS 32
+ %endif
+%endif
+
+;; @def R3_ARCH_BITS
+; Defines the host ring-3 architechture bit count.
+%ifndef R3_ARCH_BITS
+ %ifdef IN_RING3
+ %define R3_ARCH_BITS ARCH_BITS
+ %else
+ %define R3_ARCH_BITS HC_ARCH_BITS
+ %endif
+%endif
+
+;; @def R0_ARCH_BITS
+; Defines the host ring-0 architechture bit count.
+%ifndef R0_ARCH_BITS
+ %ifdef IN_RING0
+ %define R0_ARCH_BITS ARCH_BITS
+ %else
+ %define R0_ARCH_BITS HC_ARCH_BITS
+ %endif
+%endif
+
+;; @def GC_ARCH_BITS
+; Defines the guest architechture bit count.
+%ifndef GC_ARCH_BITS
+ %ifdef IN_RC
+ %define GC_ARCH_BITS ARCH_BITS
+ %else
+ %define GC_ARCH_BITS 32
+ %endif
+%endif
+
+
+
+;; @def RTHCPTR_DEF
+; The pesudo-instruction used to declare an initialized pointer variable in the host context.
+%if HC_ARCH_BITS == 64
+ %define RTHCPTR_DEF dq
+%else
+ %define RTHCPTR_DEF dd
+%endif
+
+;; @def RTHCPTR_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
+; variable of the host context.
+%if HC_ARCH_BITS == 64
+ %define RTHCPTR_RES resq
+%else
+ %define RTHCPTR_RES resd
+%endif
+
+;; @def RTHCPTR_PRE
+; The memory operand prefix used for a pointer in the host context.
+%if HC_ARCH_BITS == 64
+ %define RTHCPTR_PRE qword
+%else
+ %define RTHCPTR_PRE dword
+%endif
+
+;; @def RTHCPTR_CB
+; The size in bytes of a pointer in the host context.
+%if HC_ARCH_BITS == 64
+ %define RTHCPTR_CB 8
+%else
+ %define RTHCPTR_CB 4
+%endif
+
+
+
+;; @def RTR0PTR_DEF
+; The pesudo-instruction used to declare an initialized pointer variable in the ring-0 host context.
+%if R0_ARCH_BITS == 64
+ %define RTR0PTR_DEF dq
+%else
+ %define RTR0PTR_DEF dd
+%endif
+
+;; @def RTR0PTR_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
+; variable of the ring-0 host context.
+%if R0_ARCH_BITS == 64
+ %define RTR0PTR_RES resq
+%else
+ %define RTR0PTR_RES resd
+%endif
+
+;; @def RTR0PTR_PRE
+; The memory operand prefix used for a pointer in the ring-0 host context.
+%if R0_ARCH_BITS == 64
+ %define RTR0PTR_PRE qword
+%else
+ %define RTR0PTR_PRE dword
+%endif
+
+;; @def RTR0PTR_CB
+; The size in bytes of a pointer in the ring-0 host context.
+%if R0_ARCH_BITS == 64
+ %define RTR0PTR_CB 8
+%else
+ %define RTR0PTR_CB 4
+%endif
+
+
+
+;; @def RTR3PTR_DEF
+; The pesudo-instruction used to declare an initialized pointer variable in the ring-3 host context.
+%if R3_ARCH_BITS == 64
+ %define RTR3PTR_DEF dq
+%else
+ %define RTR3PTR_DEF dd
+%endif
+
+;; @def RTR3PTR_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
+; variable of the ring-3 host context.
+%if R3_ARCH_BITS == 64
+ %define RTR3PTR_RES resq
+%else
+ %define RTR3PTR_RES resd
+%endif
+
+;; @def RTR3PTR_PRE
+; The memory operand prefix used for a pointer in the ring-3 host context.
+%if R3_ARCH_BITS == 64
+ %define RTR3PTR_PRE qword
+%else
+ %define RTR3PTR_PRE dword
+%endif
+
+;; @def RTR3PTR_CB
+; The size in bytes of a pointer in the ring-3 host context.
+%if R3_ARCH_BITS == 64
+ %define RTR3PTR_CB 8
+%else
+ %define RTR3PTR_CB 4
+%endif
+
+
+
+;; @def RTGCPTR_DEF
+; The pesudo-instruction used to declare an initialized pointer variable in the guest context.
+%if GC_ARCH_BITS == 64
+ %define RTGCPTR_DEF dq
+%else
+ %define RTGCPTR_DEF dd
+%endif
+
+;; @def RTGCPTR_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
+; variable of the guest context.
+%if GC_ARCH_BITS == 64
+ %define RTGCPTR_RES resq
+%else
+ %define RTGCPTR_RES resd
+%endif
+
+%define RTGCPTR32_RES resd
+%define RTGCPTR64_RES resq
+
+;; @def RTGCPTR_PRE
+; The memory operand prefix used for a pointer in the guest context.
+%if GC_ARCH_BITS == 64
+ %define RTGCPTR_PRE qword
+%else
+ %define RTGCPTR_PRE dword
+%endif
+
+;; @def RTGCPTR_CB
+; The size in bytes of a pointer in the guest context.
+%if GC_ARCH_BITS == 64
+ %define RTGCPTR_CB 8
+%else
+ %define RTGCPTR_CB 4
+%endif
+
+
+;; @def RTRCPTR_DEF
+; The pesudo-instruction used to declare an initialized pointer variable in the raw mode context.
+%define RTRCPTR_DEF dd
+
+;; @def RTRCPTR_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
+; variable of the raw mode context.
+%define RTRCPTR_RES resd
+
+;; @def RTRCPTR_PRE
+; The memory operand prefix used for a pointer in the raw mode context.
+%define RTRCPTR_PRE dword
+
+;; @def RTRCPTR_CB
+; The size in bytes of a pointer in the raw mode context.
+%define RTRCPTR_CB 4
+
+
+;; @def RT_CCPTR_DEF
+; The pesudo-instruction used to declare an initialized pointer variable in the current context.
+
+;; @def RT_CCPTR_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized pointer
+; variable of the current context.
+
+;; @def RT_CCPTR_PRE
+; The memory operand prefix used for a pointer in the current context.
+
+;; @def RT_CCPTR_CB
+; The size in bytes of a pointer in the current context.
+
+%ifdef IN_RC
+ %define RTCCPTR_DEF RTRCPTR_DEF
+ %define RTCCPTR_RES RTRCPTR_RES
+ %define RTCCPTR_PRE RTRCPTR_PRE
+ %define RTCCPTR_CB RTRCPTR_CB
+%else
+ %ifdef IN_RING0
+ %define RTCCPTR_DEF RTR0PTR_DEF
+ %define RTCCPTR_RES RTR0PTR_RES
+ %define RTCCPTR_PRE RTR0PTR_PRE
+ %define RTCCPTR_CB RTR0PTR_CB
+ %else
+ %define RTCCPTR_DEF RTR3PTR_DEF
+ %define RTCCPTR_RES RTR3PTR_RES
+ %define RTCCPTR_PRE RTR3PTR_PRE
+ %define RTCCPTR_CB RTR3PTR_CB
+ %endif
+%endif
+
+
+
+;; @def RTHCPHYS_DEF
+; The pesudo-instruction used to declare an initialized host physical address.
+%define RTHCPHYS_DEF dq
+
+;; @def RTHCPTR_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized
+; host physical address variable
+%define RTHCPHYS_RES resq
+
+;; @def RTHCPTR_PRE
+; The memory operand prefix used for a host physical address.
+%define RTHCPHYS_PRE qword
+
+;; @def RTHCPHYS_CB
+; The size in bytes of a host physical address.
+%define RTHCPHYS_CB 8
+
+
+
+;; @def RTGCPHYS_DEF
+; The pesudo-instruction used to declare an initialized guest physical address.
+%define RTGCPHYS_DEF dq
+
+;; @def RTGCPHYS_RES
+; The pesudo-instruction used to declare (=reserve space for) an uninitialized
+; guest physical address variable
+%define RTGCPHYS_RES resq
+
+;; @def RTGCPTR_PRE
+; The memory operand prefix used for a guest physical address.
+%define RTGCPHYS_PRE qword
+
+;; @def RTGCPHYS_CB
+; The size in bytes of a guest physical address.
+%define RTGCPHYS_CB 8
+
+
+
+;;
+; The size of the long double C/C++ type.
+; On 32-bit Darwin this is 16 bytes, on L4, Linux, OS/2 and Windows
+; it's 12 bytes.
+; @todo figure out what 64-bit Windows does (I don't recall right now).
+%ifdef RT_ARCH_X86
+ %ifdef RT_OS_DARWIN
+ %define RTLRD_CB 16
+ %else
+ %define RTLRD_CB 12
+ %endif
+%else
+ %define RTLRD_CB 16
+%endif
+
+
+
+;; @def ASM_CALL64_GCC
+; Indicates that we're using the GCC 64-bit calling convention.
+; @see @ref sec_vboxrem_amd64_compare (in VBoxREMWrapper.cpp) for an ABI description.
+
+;; @def ASM_CALL64_MSC
+; Indicates that we're using the Microsoft 64-bit calling convention (fastcall on steroids).
+; @see @ref sec_vboxrem_amd64_compare (in VBoxREMWrapper.cpp) for an ABI description.
+
+; Note: On X86 we're using cdecl unconditionally. There is not yet any common
+; calling convention on AMD64, that's why we need to support two different ones.)
+
+%ifdef RT_ARCH_AMD64
+ %ifndef ASM_CALL64_GCC
+ %ifndef ASM_CALL64_MSC
+ ; define it based on the object format.
+ %ifdef ASM_FORMAT_PE
+ %define ASM_CALL64_MSC
+ %else
+ %define ASM_CALL64_GCC
+ %endif
+ %endif
+ %else
+ ; sanity check.
+ %ifdef ASM_CALL64_MSC
+ %error "Only one of the ASM_CALL64_* defines should be defined!"
+ %endif
+ %endif
+%endif
+
+
+;; @def RT_NOCRT
+; Symbol name wrapper for the No-CRT bits.
+;
+; In order to coexist in the same process as other CRTs, we need to
+; decorate the symbols such that they don't conflict the ones in the
+; other CRTs. The result of such conflicts / duplicate symbols can
+; confuse the dynamic loader on unix like systems.
+;
+; @remark Always feed the name to this macro first and then pass the result
+; on to the next *NAME* macro.
+;
+%ifndef RT_WITHOUT_NOCRT_WRAPPERS
+ %define RT_NOCRT(name) nocrt_ %+ name
+%else
+ %define RT_NOCRT(name) name
+%endif
+
+;; @def RT_NOCRT_BEGINPROC
+; Starts a NOCRT procedure, taking care of name wrapping and aliasing.
+;
+; Aliasing (weak ones, if supported) will be created when RT_WITH_NOCRT_ALIASES
+; is defined and RT_WITHOUT_NOCRT_WRAPPERS isn't.
+;
+%macro RT_NOCRT_BEGINPROC 1
+%ifdef RT_WITH_NOCRT_ALIASES
+BEGINPROC RT_NOCRT(%1)
+%ifdef ASM_FORMAT_ELF
+global NAME(%1)
+weak NAME(%1)
+NAME(%1):
+%else
+GLOBALNAME %1
+%endif
+%else ; !RT_WITH_NOCRT_ALIASES
+BEGINPROC RT_NOCRT(%1)
+%endif ; !RT_WITH_NOCRT_ALIASES
+%endmacro ; RT_NOCRT_BEGINPROC
+
+%ifdef RT_WITH_NOCRT_ALIASES
+ %ifdef RT_WITHOUT_NOCRT_WRAPPERS
+ %error "RT_WITH_NOCRT_ALIASES and RT_WITHOUT_NOCRT_WRAPPERS doesn't mix."
+ %endif
+%endif
+
+
+
+;; @def xS
+; The stack unit size / The register unit size.
+
+;; @def xSP
+; The stack pointer register (RSP or ESP).
+
+;; @def xBP
+; The base pointer register (RBP or ESP).
+
+;; @def xAX
+; RAX or EAX depending on context.
+
+;; @def xBX
+; RBX or EBX depending on context.
+
+;; @def xCX
+; RCX or ECX depending on context.
+
+;; @def xDX
+; RDX or EDX depending on context.
+
+;; @def xDI
+; RDI or EDI depending on context.
+
+;; @def xSI
+; RSI or ESI depending on context.
+
+;; @def xWrtRIP
+; 'wrt rip' for AMD64 targets, nothing for x86 ones.
+
+%ifdef RT_ARCH_AMD64
+ %define xS 8
+ %define xSP rsp
+ %define xBP rbp
+ %define xAX rax
+ %define xBX rbx
+ %define xCX rcx
+ %define xDX rdx
+ %define xDI rdi
+ %define xSI rsi
+ %define xWrtRIP wrt rip
+%else
+ %define xS 4
+ %define xSP esp
+ %define xBP ebp
+ %define xAX eax
+ %define xBX ebx
+ %define xCX ecx
+ %define xDX edx
+ %define xDI edi
+ %define xSI esi
+ %define xWrtRIP
+%endif
+
+%endif
diff --git a/include/iprt/assert.h b/include/iprt/assert.h
new file mode 100644
index 00000000..ec1631d1
--- /dev/null
+++ b/include/iprt/assert.h
@@ -0,0 +1,2675 @@
+/** @file
+ * IPRT - Assertions.
+ */
+
+/*
+ * 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 ___iprt_assert_h
+#define ___iprt_assert_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+/** @defgroup grp_rt_assert Assert - Assertions
+ * @ingroup grp_rt
+ *
+ * Assertions are generally used to check preconditions and other
+ * assumptions. Sometimes it is also used to catch odd errors or errors
+ * that one would like to inspect in the debugger. They should not be
+ * used for errors that happen frequently.
+ *
+ * IPRT provides a host of assertion macros, so many that it can be a bit
+ * overwhelming at first. Don't despair, there is a system (surprise).
+ *
+ * First there are four families of assertions:
+ * - Assert - The normal strict build only assertions.
+ * - AssertLogRel - Calls LogRel() in non-strict builds, otherwise like Assert.
+ * - AssertRelease - Triggers in all builds.
+ * - AssertFatal - Triggers in all builds and cannot be continued.
+ *
+ * Then there are variations wrt to argument list and behavior on failure:
+ * - Msg - Custom RTStrPrintf-like message with the assertion message.
+ * - Return - Return the specific rc on failure.
+ * - ReturnVoid - Return (void) on failure.
+ * - Break - Break (out of switch/loop) on failure.
+ * - Stmt - Execute the specified statement(s) on failure.
+ * - RC - Assert RT_SUCCESS.
+ * - RCSuccess - Assert VINF_SUCCESS.
+ *
+ * In addition there is a very special family AssertCompile that can be
+ * used for some limited compile-time checking, like structure sizes and member
+ * alignment. This family doesn't have the same variations.
+ *
+ *
+ * @remarks As you might have noticed, the macros don't follow the
+ * coding guidelines wrt to macros supposedly being all uppercase
+ * and underscored. For various reasons they don't, and nobody
+ * has complained yet. Wonder why... :-)
+ *
+ * @remarks Each project has its own specific guidelines on how to use
+ * assertions, so the above is just trying to give you the general idea
+ * from the IPRT point of view.
+ *
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/**
+ * The 1st part of an assert message.
+ *
+ * @param pszExpr Expression. Can be NULL.
+ * @param uLine Location line number.
+ * @param pszFile Location file name.
+ * @param pszFunction Location function name.
+ */
+RTDECL(void) RTAssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
+/**
+ * Weak version of RTAssertMsg1 that can be overridden locally in a module to
+ * modify, redirect or otherwise mess with the assertion output.
+ *
+ * @copydoc RTAssertMsg1
+ */
+RTDECL(void) RTAssertMsg1Weak(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction);
+
+/**
+ * The 2nd (optional) part of an assert message.
+ *
+ * @param pszFormat Printf like format string.
+ * @param ... Arguments to that string.
+ */
+RTDECL(void) RTAssertMsg2(const char *pszFormat, ...);
+/**
+ * Weak version of RTAssertMsg2 that forwards to RTAssertMsg2WeakV.
+ *
+ * There is not need to override this, check out RTAssertMsg2WeakV instead!
+ *
+ * @copydoc RTAssertMsg2
+ */
+RTDECL(void) RTAssertMsg2Weak(const char *pszFormat, ...);
+
+/**
+ * The 2nd (optional) part of an assert message.
+ *
+ * @param pszFormat Printf like format string.
+ * @param va Arguments to that string.
+ */
+RTDECL(void) RTAssertMsg2V(const char *pszFormat, va_list va);
+/**
+ * Weak version of RTAssertMsg2V that can be overridden locally in a module to
+ * modify, redirect or otherwise mess with the assertion output.
+ *
+ * @copydoc RTAssertMsg2V
+ */
+RTDECL(void) RTAssertMsg2WeakV(const char *pszFormat, va_list va);
+
+/**
+ * Additional information which should be appended to the 2nd part of an
+ * assertion message.
+ *
+ * @param pszFormat Printf like format string.
+ * @param ... Arguments to that string.
+ */
+RTDECL(void) RTAssertMsg2Add(const char *pszFormat, ...);
+/**
+ * Weak version of RTAssertMsg2Add that forwards to RTAssertMsg2AddWeakV.
+ *
+ * There is not need to override this, check out RTAssertMsg2AddWeakV instead!
+ *
+ * @copydoc RTAssertMsg2Add
+ */
+RTDECL(void) RTAssertMsg2AddWeak(const char *pszFormat, ...);
+
+/**
+ * Additional information which should be appended to the 2nd part of an
+ * assertion message.
+ *
+ * @param pszFormat Printf like format string.
+ * @param va Arguments to that string.
+ */
+RTDECL(void) RTAssertMsg2AddV(const char *pszFormat, va_list va);
+/**
+ * Weak version of RTAssertMsg2AddV that can be overridden locally in a module
+ * to modify, redirect or otherwise mess with the assertion output.
+ *
+ * @copydoc RTAssertMsg2AddV
+ */
+RTDECL(void) RTAssertMsg2AddWeakV(const char *pszFormat, va_list va);
+
+#ifdef IN_RING0
+/**
+ * Panics the system as the result of a fail assertion.
+ */
+RTR0DECL(void) RTR0AssertPanicSystem(void);
+#endif /* IN_RING0 */
+
+/**
+ * Overridable function that decides whether assertions executes the panic
+ * (breakpoint) or not.
+ *
+ * The generic implementation will return true.
+ *
+ * @returns true if the breakpoint should be hit, false if it should be ignored.
+ *
+ * @remark The RTDECL() makes this a bit difficult to override on Windows. So,
+ * you'll have to use RTASSERT_HAVE_SHOULD_PANIC or
+ * RTASSERT_HAVE_SHOULD_PANIC_PRIVATE there to control the kind of
+ * prototype.
+ */
+#if !defined(RTASSERT_HAVE_SHOULD_PANIC) && !defined(RTASSERT_HAVE_SHOULD_PANIC_PRIVATE)
+RTDECL(bool) RTAssertShouldPanic(void);
+#elif defined(RTASSERT_HAVE_SHOULD_PANIC_PRIVATE)
+bool RTAssertShouldPanic(void);
+#else
+DECLEXPORT(bool) RTCALL RTAssertShouldPanic(void);
+#endif
+
+/**
+ * Controls whether the assertions should be quiet or noisy (default).
+ *
+ * @returns The old setting.
+ * @param fQuiet The new setting.
+ */
+RTDECL(bool) RTAssertSetQuiet(bool fQuiet);
+
+/**
+ * Are assertions quiet or noisy?
+ *
+ * @returns True if they are quiet, false if noisy.
+ */
+RTDECL(bool) RTAssertAreQuiet(void);
+
+/**
+ * Makes the assertions panic (default) or not.
+ *
+ * @returns The old setting.
+ * @param fPanic The new setting.
+ */
+RTDECL(bool) RTAssertSetMayPanic(bool fPanic);
+
+/**
+ * Can assertion panic.
+ *
+ * @returns True if they can, false if not.
+ */
+RTDECL(bool) RTAssertMayPanic(void);
+
+
+/** @name Globals for crash analysis
+ * @remarks This is the full potential set, it
+ * @{
+ */
+/** The last assert message, 1st part. */
+extern RTDATADECL(char) g_szRTAssertMsg1[1024];
+/** The last assert message, 2nd part. */
+extern RTDATADECL(char) g_szRTAssertMsg2[4096];
+/** The last assert message, expression. */
+extern RTDATADECL(const char * volatile) g_pszRTAssertExpr;
+/** The last assert message, file name. */
+extern RTDATADECL(const char * volatile) g_pszRTAssertFile;
+/** The last assert message, line number. */
+extern RTDATADECL(uint32_t volatile) g_u32RTAssertLine;
+/** The last assert message, function name. */
+extern RTDATADECL(const char * volatile) g_pszRTAssertFunction;
+/** @} */
+
+RT_C_DECLS_END
+
+/** @def RTAssertDebugBreak()
+ * Debugger breakpoint instruction.
+ *
+ * @remarks This macro does not depend on RT_STRICT.
+ */
+#define RTAssertDebugBreak() do { RT_BREAKPOINT(); } while (0)
+
+
+
+/** @name Compile time assertions.
+ *
+ * These assertions are used to check structure sizes, member/size alignments
+ * and similar compile time expressions.
+ *
+ * @{
+ */
+
+/**
+ * RTASSERTTYPE is the type the AssertCompile() macro redefines.
+ * It has no other function and shouldn't be used.
+ * Visual C++ uses this.
+ */
+typedef int RTASSERTTYPE[1];
+
+/**
+ * RTASSERTVAR is the type the AssertCompile() macro redefines.
+ * It has no other function and shouldn't be used.
+ * GCC uses this.
+ */
+#ifdef __GNUC__
+RT_C_DECLS_BEGIN
+#endif
+extern int RTASSERTVAR[1];
+#ifdef __GNUC__
+RT_C_DECLS_END
+#endif
+
+/** @def RTASSERT_HAVE_STATIC_ASSERT
+ * Indicates that the compiler implements static_assert(expr, msg).
+ */
+#ifdef _MSC_VER
+# if _MSC_VER >= 1600 && defined(__cplusplus)
+# define RTASSERT_HAVE_STATIC_ASSERT
+# endif
+#endif
+#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define RTASSERT_HAVE_STATIC_ASSERT
+#endif
+#ifdef DOXYGEN_RUNNING
+# define RTASSERT_HAVE_STATIC_ASSERT
+#endif
+
+/** @def AssertCompileNS
+ * Asserts that a compile-time expression is true. If it's not break the build.
+ *
+ * This differs from AssertCompile in that it accepts some more expressions
+ * than what C++0x allows - NS = Non-standard.
+ *
+ * @param expr Expression which should be true.
+ */
+#ifdef __GNUC__
+# define AssertCompileNS(expr) extern int RTASSERTVAR[1] __attribute__((unused)), RTASSERTVAR[(expr) ? 1 : 0] __attribute__((unused))
+#else
+# define AssertCompileNS(expr) typedef int RTASSERTTYPE[(expr) ? 1 : 0]
+#endif
+
+/** @def AssertCompile
+ * Asserts that a C++0x compile-time expression is true. If it's not break the
+ * build.
+ * @param expr Expression which should be true.
+ */
+#ifdef RTASSERT_HAVE_STATIC_ASSERT
+# define AssertCompile(expr) static_assert(!!(expr), #expr)
+#else
+# define AssertCompile(expr) AssertCompileNS(expr)
+#endif
+
+/** @def AssertCompileSize
+ * Asserts a size at compile.
+ * @param type The type.
+ * @param size The expected type size.
+ */
+#define AssertCompileSize(type, size) \
+ AssertCompile(sizeof(type) == (size))
+
+/** @def AssertCompileSizeAlignment
+ * Asserts a size alignment at compile.
+ * @param type The type.
+ * @param align The size alignment to assert.
+ */
+#define AssertCompileSizeAlignment(type, align) \
+ AssertCompile(!(sizeof(type) & ((align) - 1)))
+
+/** @def AssertCompileMemberSize
+ * Asserts a member offset alignment at compile.
+ * @param type The type.
+ * @param member The member.
+ * @param size The member size to assert.
+ */
+#define AssertCompileMemberSize(type, member, size) \
+ AssertCompile(RT_SIZEOFMEMB(type, member) == (size))
+
+/** @def AssertCompileMemberSizeAlignment
+ * Asserts a member size alignment at compile.
+ * @param type The type.
+ * @param member The member.
+ * @param align The member size alignment to assert.
+ */
+#define AssertCompileMemberSizeAlignment(type, member, align) \
+ AssertCompile(!(RT_SIZEOFMEMB(type, member) & ((align) - 1)))
+
+/** @def AssertCompileMemberAlignment
+ * Asserts a member offset alignment at compile.
+ * @param type The type.
+ * @param member The member.
+ * @param align The member offset alignment to assert.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4
+# define AssertCompileMemberAlignment(type, member, align) \
+ AssertCompile(!(__builtin_offsetof(type, member) & ((align) - 1)))
+# else
+# define AssertCompileMemberAlignment(type, member, align) \
+ AssertCompile(!(RT_OFFSETOF(type, member) & ((align) - 1)))
+# endif
+#else
+# define AssertCompileMemberAlignment(type, member, align) \
+ AssertCompile(!(RT_OFFSETOF(type, member) & ((align) - 1)))
+#endif
+
+/** @def AssertCompileMemberOffset
+ * Asserts an offset of a structure member at compile.
+ * @param type The type.
+ * @param member The member.
+ * @param off The expected offset.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4
+# define AssertCompileMemberOffset(type, member, off) \
+ AssertCompile(__builtin_offsetof(type, member) == (off))
+# else
+# define AssertCompileMemberOffset(type, member, off) \
+ AssertCompile(RT_OFFSETOF(type, member) == (off))
+# endif
+#else
+# define AssertCompileMemberOffset(type, member, off) \
+ AssertCompile(RT_OFFSETOF(type, member) == (off))
+#endif
+
+/** @def AssertCompile2MemberOffsets
+ * Asserts that two (sub-structure) members in union have the same offset.
+ * @param type The type.
+ * @param member1 The first member.
+ * @param member2 The second member.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4
+# define AssertCompile2MemberOffsets(type, member1, member2) \
+ AssertCompile(__builtin_offsetof(type, member1) == __builtin_offsetof(type, member2))
+# else
+# define AssertCompile2MemberOffsets(type, member1, member2) \
+ AssertCompile(RT_OFFSETOF(type, member1) == RT_OFFSETOF(type, member2))
+# endif
+#else
+# define AssertCompile2MemberOffsets(type, member1, member2) \
+ AssertCompile(RT_OFFSETOF(type, member1) == RT_OFFSETOF(type, member2))
+#endif
+
+/** @def AssertCompileAdjacentMembers
+ * Asserts that two structure members are adjacent.
+ * @param type The type.
+ * @param member1 The first member.
+ * @param member2 The second member.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4
+# define AssertCompileAdjacentMembers(type, member1, member2) \
+ AssertCompile(__builtin_offsetof(type, member1) + RT_SIZEOFMEMB(type, member1) == __builtin_offsetof(type, member2))
+# else
+# define AssertCompileAdjacentMembers(type, member1, member2) \
+ AssertCompile(RT_OFFSETOF(type, member1) + RT_SIZEOFMEMB(type, member1) == RT_OFFSETOF(type, member2))
+# endif
+#else
+# define AssertCompileAdjacentMembers(type, member1, member2) \
+ AssertCompile(RT_OFFSETOF(type, member1) + RT_SIZEOFMEMB(type, member1) == RT_OFFSETOF(type, member2))
+#endif
+
+/** @def AssertCompileMembersAtSameOffset
+ * Asserts that members of two different structures are at the same offset.
+ * @param type1 The first type.
+ * @param member1 The first member.
+ * @param type2 The second type.
+ * @param member2 The second member.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4
+# define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \
+ AssertCompile(__builtin_offsetof(type1, member1) == __builtin_offsetof(type2, member2))
+# else
+# define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \
+ AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2))
+# endif
+#else
+# define AssertCompileMembersAtSameOffset(type1, member1, type2, member2) \
+ AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2))
+#endif
+
+/** @def AssertCompileMembersSameSize
+ * Asserts that members of two different structures have the same size.
+ * @param type1 The first type.
+ * @param member1 The first member.
+ * @param type2 The second type.
+ * @param member2 The second member.
+ */
+#define AssertCompileMembersSameSize(type1, member1, type2, member2) \
+ AssertCompile(RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
+
+/** @def AssertCompileMembersSameSizeAndOffset
+ * Asserts that members of two different structures have the same size and are
+ * at the same offset.
+ * @param type1 The first type.
+ * @param member1 The first member.
+ * @param type2 The second type.
+ * @param member2 The second member.
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4
+# define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \
+ AssertCompile(__builtin_offsetof(type1, member1) == __builtin_offsetof(type2, member2) && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
+# else
+# define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \
+ AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2) && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
+# endif
+#else
+# define AssertCompileMembersSameSizeAndOffset(type1, member1, type2, member2) \
+ AssertCompile(RT_OFFSETOF(type1, member1) == RT_OFFSETOF(type2, member2) && RT_SIZEOFMEMB(type1, member1) == RT_SIZEOFMEMB(type2, member2))
+#endif
+
+/** @} */
+
+
+
+/** @name Assertions
+ *
+ * These assertions will only trigger when RT_STRICT is defined. When it is
+ * undefined they will all be no-ops and generate no code.
+ *
+ * @{
+ */
+
+
+/** @def RTASSERT_QUIET
+ * This can be defined to shut up the messages for a file where this would be
+ * problematic because the message printing code path passes thru it.
+ * @internal */
+#ifdef DOXYGEN_RUNNING
+# define RTASSERT_QUIET
+#endif
+#if defined(RTASSERT_QUIET) && !defined(DOXYGEN_RUNNING)
+# define RTAssertMsg1Weak(pszExpr, uLine, pszfile, pszFunction) \
+ do { } while (0)
+# define RTAssertMsg2Weak if (0) RTAssertMsg2Weak
+#endif
+
+/** @def RTAssertDoPanic
+ * Raises an assertion panic appropriate to the current context.
+ * @remarks This macro does not depend on RT_STRICT.
+ */
+#if defined(IN_RING0) \
+ && (defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS))
+# define RTAssertDoPanic() RTR0AssertPanicSystem()
+#else
+# define RTAssertDoPanic() RTAssertDebugBreak()
+#endif
+
+/** @def AssertBreakpoint()
+ * Assertion Breakpoint.
+ * @deprecated Use RTAssertPanic or RTAssertDebugBreak instead.
+ */
+#ifdef RT_STRICT
+# define AssertBreakpoint() RTAssertDebugBreak()
+#else
+# define AssertBreakpoint() do { } while (0)
+#endif
+
+/** @def RTAssertPanic()
+ * If RT_STRICT is defined this macro will invoke RTAssertDoPanic if
+ * RTAssertShouldPanic returns true. If RT_STRICT isn't defined it won't do any
+ * thing.
+ */
+#if defined(RT_STRICT) && !defined(RTASSERT_DONT_PANIC)
+# define RTAssertPanic() do { if (RTAssertShouldPanic()) RTAssertDoPanic(); } while (0)
+#else
+# define RTAssertPanic() do { } while (0)
+#endif
+
+/** @def Assert
+ * Assert that an expression is true. If false, hit breakpoint.
+ * @param expr Expression which should be true.
+ */
+#ifdef RT_STRICT
+# define Assert(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ } \
+ } while (0)
+#else
+# define Assert(expr) do { } while (0)
+#endif
+
+
+/** @def AssertStmt
+ * Assert that an expression is true. If false, hit breakpoint and execute the
+ * statement.
+ * @param expr Expression which should be true.
+ * @param stmt Statement to execute on failure.
+ */
+#ifdef RT_STRICT
+# define AssertStmt(expr, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ } \
+ } while (0)
+#else
+# define AssertStmt(expr, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ stmt; \
+ } \
+ } while (0)
+#endif
+
+
+/** @def AssertReturn
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ * @param rc What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertReturn(expr, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return (rc); \
+ } \
+ } while (0)
+#else
+# define AssertReturn(expr, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ return (rc); \
+ } while (0)
+#endif
+
+/** @def AssertReturnStmt
+ * Assert that an expression is true, if it isn't execute the given statement
+ * and return rc.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before executing the statement and
+ * returning.
+ *
+ * @param expr Expression which should be true.
+ * @param stmt Statement to execute before returning on failure.
+ * @param rc What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertReturnStmt(expr, stmt, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ return (rc); \
+ } \
+ } while (0)
+#else
+# define AssertReturnStmt(expr, stmt, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ stmt; \
+ return (rc); \
+ } \
+ } while (0)
+#endif
+
+/** @def AssertReturnVoid
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ */
+#ifdef RT_STRICT
+# define AssertReturnVoid(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return; \
+ } \
+ } while (0)
+#else
+# define AssertReturnVoid(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ return; \
+ } while (0)
+#endif
+
+/** @def AssertReturnVoidStmt
+ * Assert that an expression is true, if it isn't execute the given statement
+ * and return.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ * @param stmt Statement to execute before returning on failure.
+ */
+#ifdef RT_STRICT
+# define AssertReturnVoidStmt(expr, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+#else
+# define AssertReturnVoidStmt(expr, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+#endif
+
+
+/** @def AssertBreak
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ */
+#ifdef RT_STRICT
+# define AssertBreak(expr) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertBreak(expr) \
+ if (RT_UNLIKELY(!(expr))) \
+ break; \
+ else do {} while (0)
+#endif
+
+/** @def AssertBreakStmt
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before doing break.
+ *
+ * @param expr Expression which should be true.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#ifdef RT_STRICT
+# define AssertBreakStmt(expr, stmt) \
+ if (RT_UNLIKELY(!(expr))) { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertBreakStmt(expr, stmt) \
+ if (RT_UNLIKELY(!(expr))) { \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#endif
+
+
+/** @def AssertMsg
+ * Assert that an expression is true. If it's not print message and hit breakpoint.
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsg(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ } \
+ } while (0)
+#else
+# define AssertMsg(expr, a) do { } while (0)
+#endif
+
+/** @def AssertMsgStmt
+ * Assert that an expression is true. If it's not print message and hit
+ * breakpoint and execute the statement.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute in case of a failed assertion.
+ *
+ * @remarks The expression and statement will be evaluated in all build types.
+ */
+#ifdef RT_STRICT
+# define AssertMsgStmt(expr, a, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ stmt; \
+ } \
+ } while (0)
+#else
+# define AssertMsgStmt(expr, a, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ stmt; \
+ } \
+ } while (0)
+#endif
+
+/** @def AssertMsgReturn
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param rc What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturn(expr, a, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ return (rc); \
+ } \
+ } while (0)
+#else
+# define AssertMsgReturn(expr, a, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ return (rc); \
+ } while (0)
+#endif
+
+/** @def AssertMsgReturnStmt
+ * Assert that an expression is true, if it isn't execute the statement and
+ * return.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ * @param rc What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturnStmt(expr, a, stmt, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ stmt; \
+ return (rc); \
+ } \
+ } while (0)
+#else
+# define AssertMsgReturnStmt(expr, a, stmt, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ stmt; \
+ return (rc); \
+ } \
+ } while (0)
+#endif
+
+/** @def AssertMsgReturnVoid
+ * Assert that an expression is true and returns if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturnVoid(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ return; \
+ } \
+ } while (0)
+#else
+# define AssertMsgReturnVoid(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ return; \
+ } while (0)
+#endif
+
+/** @def AssertMsgReturnVoidStmt
+ * Assert that an expression is true, if it isn't execute the statement and
+ * return.
+ *
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#ifdef RT_STRICT
+# define AssertMsgReturnVoidStmt(expr, a, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+#else
+# define AssertMsgReturnVoidStmt(expr, a, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ stmt; \
+ return; \
+ } \
+ } while (0)
+#endif
+
+
+/** @def AssertMsgBreak
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before returning.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgBreak(expr, a) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertMsgBreak(expr, a) \
+ if (RT_UNLIKELY(!(expr))) \
+ break; \
+ else do {} while (0)
+#endif
+
+/** @def AssertMsgBreakStmt
+ * Assert that an expression is true and breaks if it isn't.
+ * In RT_STRICT mode it will hit a breakpoint before doing break.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#ifdef RT_STRICT
+# define AssertMsgBreakStmt(expr, a, stmt) \
+ if (RT_UNLIKELY(!(expr))) { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertMsgBreakStmt(expr, a, stmt) \
+ if (RT_UNLIKELY(!(expr))) { \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#endif
+
+/** @def AssertFailed
+ * An assertion failed hit breakpoint.
+ */
+#ifdef RT_STRICT
+# define AssertFailed() \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ } while (0)
+#else
+# define AssertFailed() do { } while (0)
+#endif
+
+/** @def AssertFailedReturn
+ * An assertion failed, hit breakpoint (RT_STRICT mode only) and return.
+ *
+ * @param rc The rc to return.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturn(rc) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return (rc); \
+ } while (0)
+#else
+# define AssertFailedReturn(rc) \
+ do { \
+ return (rc); \
+ } while (0)
+#endif
+
+/** @def AssertFailedReturnStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute a
+ * statement and return a value.
+ *
+ * @param stmt The statement to execute before returning.
+ * @param rc The value to return.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturnStmt(stmt, rc) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ return (rc); \
+ } while (0)
+#else
+# define AssertFailedReturnStmt(stmt, rc) \
+ do { \
+ stmt; \
+ return (rc); \
+ } while (0)
+#endif
+
+/** @def AssertFailedReturnVoid
+ * An assertion failed, hit breakpoint (RT_STRICT mode only) and return.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturnVoid() \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return; \
+ } while (0)
+#else
+# define AssertFailedReturnVoid() \
+ do { \
+ return; \
+ } while (0)
+#endif
+
+/** @def AssertFailedReturnVoidStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute a
+ * statement and return.
+ *
+ * @param stmt The statement to execute before returning.
+ */
+#ifdef RT_STRICT
+# define AssertFailedReturnVoidStmt(stmt) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ return; \
+ } while (0)
+#else
+# define AssertFailedReturnVoidStmt(stmt) \
+ do { \
+ stmt; \
+ return; \
+ } while (0)
+#endif
+
+
+/** @def AssertFailedBreak
+ * An assertion failed, hit breakpoint (RT_STRICT mode only) and break.
+ */
+#ifdef RT_STRICT
+# define AssertFailedBreak() \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertFailedBreak() \
+ if (1) \
+ break; \
+ else do {} while (0)
+#endif
+
+/** @def AssertFailedBreakStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute
+ * the given statement and break.
+ *
+ * @param stmt Statement to execute before break.
+ */
+#ifdef RT_STRICT
+# define AssertFailedBreakStmt(stmt) \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertFailedBreakStmt(stmt) \
+ if (1) { \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#endif
+
+
+/** @def AssertMsgFailed
+ * An assertion failed print a message and a hit breakpoint.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailed(a) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ } while (0)
+#else
+# define AssertMsgFailed(a) do { } while (0)
+#endif
+
+/** @def AssertMsgFailedReturn
+ * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and return.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param rc What is to be presented to return.
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedReturn(a, rc) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ return (rc); \
+ } while (0)
+#else
+# define AssertMsgFailedReturn(a, rc) \
+ do { \
+ return (rc); \
+ } while (0)
+#endif
+
+/** @def AssertMsgFailedReturnVoid
+ * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and return.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedReturnVoid(a) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ return; \
+ } while (0)
+#else
+# define AssertMsgFailedReturnVoid(a) \
+ do { \
+ return; \
+ } while (0)
+#endif
+
+
+/** @def AssertMsgFailedBreak
+ * An assertion failed, hit breakpoint with message (RT_STRICT mode only) and break.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedBreak(a) \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertMsgFailedBreak(a) \
+ if (1) \
+ break; \
+ else do {} while (0)
+#endif
+
+/** @def AssertMsgFailedBreakStmt
+ * An assertion failed, hit breakpoint (RT_STRICT mode only), execute
+ * the given statement and break.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break.
+ */
+#ifdef RT_STRICT
+# define AssertMsgFailedBreakStmt(a, stmt) \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#else
+# define AssertMsgFailedBreakStmt(a, stmt) \
+ if (1) { \
+ stmt; \
+ break; \
+ } else do {} while (0)
+#endif
+
+/** @} */
+
+
+
+/** @name Release Log Assertions
+ *
+ * These assertions will work like normal strict assertion when RT_STRICT is
+ * defined and LogRel statements when RT_STRICT is undefined. Typically used for
+ * things which shouldn't go wrong, but when it does you'd like to know one way
+ * or the other.
+ *
+ * @{
+ */
+
+/** @def RTAssertLogRelMsg1
+ * RTAssertMsg1Weak (strict builds) / LogRel wrapper (non-strict).
+ */
+#ifdef RT_STRICT
+# define RTAssertLogRelMsg1(pszExpr, iLine, pszFile, pszFunction) \
+ RTAssertMsg1Weak(pszExpr, iLine, pszFile, pszFunction)
+#else
+# define RTAssertLogRelMsg1(pszExpr, iLine, pszFile, pszFunction) \
+ LogRel(("AssertLogRel %s(%d) %s: %s\n",\
+ (pszFile), (iLine), (pszFunction), (pszExpr) ))
+#endif
+
+/** @def RTAssertLogRelMsg2
+ * RTAssertMsg2Weak (strict builds) / LogRel wrapper (non-strict).
+ */
+#ifdef RT_STRICT
+# define RTAssertLogRelMsg2(a) RTAssertMsg2Weak a
+#else
+# define RTAssertLogRelMsg2(a) LogRel(a)
+#endif
+
+/** @def AssertLogRel
+ * Assert that an expression is true.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ */
+#define AssertLogRel(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ } \
+ } while (0)
+
+/** @def AssertLogRelReturn
+ * Assert that an expression is true, return \a rc if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param rc What is to be presented to return.
+ */
+#define AssertLogRelReturn(expr, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return (rc); \
+ } \
+ } while (0)
+
+/** @def AssertLogRelReturnVoid
+ * Assert that an expression is true, return void if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ */
+#define AssertLogRelReturnVoid(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return; \
+ } \
+ } while (0)
+
+/** @def AssertLogRelBreak
+ * Assert that an expression is true, break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ */
+#define AssertLogRelBreak(expr) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ break; \
+ } \
+ else do {} while (0)
+
+/** @def AssertLogRelBreakStmt
+ * Assert that an expression is true, execute \a stmt and break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#define AssertLogRelBreakStmt(expr, stmt) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertLogRelMsg
+ * Assert that an expression is true.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsg(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ } \
+ } while (0)
+
+/** @def AssertLogRelMsgStmt
+ * Assert that an expression is true, execute \a stmt and break if it isn't
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute in case of a failed assertion.
+ */
+#define AssertLogRelMsgStmt(expr, a, stmt) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ stmt; \
+ } \
+ } while (0)
+
+/** @def AssertLogRelMsgReturn
+ * Assert that an expression is true, return \a rc if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param rc What is to be presented to return.
+ */
+#define AssertLogRelMsgReturn(expr, a, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ return (rc); \
+ } \
+ } while (0)
+
+/** @def AssertLogRelMsgReturnStmt
+ * Assert that an expression is true, execute @a stmt and return @a rcRet if it
+ * isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ * @param rcRet What is to be presented to return.
+ */
+#define AssertLogRelMsgReturnStmt(expr, a, stmt, rcRet) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ stmt; \
+ return (rcRet); \
+ } \
+ } while (0)
+
+/** @def AssertLogRelMsgReturnVoid
+ * Assert that an expression is true, return (void) if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgReturnVoid(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ return; \
+ } \
+ } while (0)
+
+/** @def AssertLogRelMsgBreak
+ * Assert that an expression is true, break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgBreak(expr, a) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ break; \
+ } \
+ else do {} while (0)
+
+/** @def AssertLogRelMsgBreakStmt
+ * Assert that an expression is true, execute \a stmt and break if it isn't.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#define AssertLogRelMsgBreakStmt(expr, a, stmt) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertLogRelMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertLogRelFailed
+ * An assertion failed.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ */
+#define AssertLogRelFailed() \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ } while (0)
+
+/** @def AssertLogRelFailedReturn
+ * An assertion failed.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param rc What is to be presented to return.
+ */
+#define AssertLogRelFailedReturn(rc) \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return (rc); \
+ } while (0)
+
+/** @def AssertLogRelFailedReturnVoid
+ * An assertion failed, hit a breakpoint and return.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ */
+#define AssertLogRelFailedReturnVoid() \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ return; \
+ } while (0)
+
+/** @def AssertLogRelFailedBreak
+ * An assertion failed, break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ */
+#define AssertLogRelFailedBreak() \
+ if (1) \
+ { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertLogRelFailedBreakStmt
+ * An assertion failed, execute \a stmt and break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param stmt Statement to execute before break.
+ */
+#define AssertLogRelFailedBreakStmt(stmt) \
+ if (1) \
+ { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertLogRelMsgFailed
+ * An assertion failed.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgFailed(a) \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ } while (0)
+
+/** @def AssertLogRelMsgFailedReturn
+ * An assertion failed, return \a rc.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param rc What is to be presented to return.
+ */
+#define AssertLogRelMsgFailedReturn(a, rc) \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ return (rc); \
+ } while (0)
+
+/** @def AssertLogRelMsgFailedReturn
+ * An assertion failed, execute @a stmt and return @a rc.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ * @param rc What is to be presented to return.
+ */
+#define AssertLogRelMsgFailedReturnStmt(a, stmt, rc) \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ stmt; \
+ return (rc); \
+ } while (0)
+
+/** @def AssertLogRelMsgFailedReturnVoid
+ * An assertion failed, return void.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgFailedReturnVoid(a) \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ return; \
+ } while (0)
+
+/** @def AssertLogRelMsgFailedReturnVoid
+ * An assertion failed, execute @a stmt and return void.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ */
+#define AssertLogRelMsgFailedReturnVoidStmt(a, stmt) \
+ do { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ stmt; \
+ return; \
+ } while (0)
+
+/** @def AssertLogRelMsgFailedBreak
+ * An assertion failed, break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertLogRelMsgFailedBreak(a) \
+ if (1)\
+ { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertLogRelMsgFailedBreakStmt
+ * An assertion failed, execute \a stmt and break.
+ * Strict builds will hit a breakpoint, non-strict will only do LogRel.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break.
+ */
+#define AssertLogRelMsgFailedBreakStmt(a, stmt) \
+ if (1) \
+ { \
+ RTAssertLogRelMsg1((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertLogRelMsg2(a); \
+ RTAssertPanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+/** @} */
+
+
+
+/** @name Release Assertions
+ *
+ * These assertions are always enabled.
+ * @{
+ */
+
+/** @def RTAssertReleasePanic()
+ * Invokes RTAssertShouldPanic and RTAssertDoPanic.
+ *
+ * It might seem odd that RTAssertShouldPanic is necessary when its result isn't
+ * checked, but it's done since RTAssertShouldPanic is overrideable and might be
+ * used to bail out before taking down the system (the VMMR0 case).
+ */
+#define RTAssertReleasePanic() do { RTAssertShouldPanic(); RTAssertDoPanic(); } while (0)
+
+
+/** @def AssertRelease
+ * Assert that an expression is true. If it's not hit a breakpoint.
+ *
+ * @param expr Expression which should be true.
+ */
+#define AssertRelease(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ } \
+ } while (0)
+
+/** @def AssertReleaseReturn
+ * Assert that an expression is true, hit a breakpoint and return if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param rc What is to be presented to return.
+ */
+#define AssertReleaseReturn(expr, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ return (rc); \
+ } \
+ } while (0)
+
+/** @def AssertReleaseReturnVoid
+ * Assert that an expression is true, hit a breakpoint and return if it isn't.
+ *
+ * @param expr Expression which should be true.
+ */
+#define AssertReleaseReturnVoid(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ return; \
+ } \
+ } while (0)
+
+
+/** @def AssertReleaseBreak
+ * Assert that an expression is true, hit a breakpoint and break if it isn't.
+ *
+ * @param expr Expression which should be true.
+ */
+#define AssertReleaseBreak(expr) \
+ if { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ break; \
+ } \
+ } else do {} while (0)
+
+/** @def AssertReleaseBreakStmt
+ * Assert that an expression is true, hit a breakpoint and break if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#define AssertReleaseBreakStmt(expr, stmt) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+
+/** @def AssertReleaseMsg
+ * Assert that an expression is true, print the message and hit a breakpoint if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsg(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ } \
+ } while (0)
+
+/** @def AssertReleaseMsgReturn
+ * Assert that an expression is true, print the message and hit a breakpoint and return if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param rc What is to be presented to return.
+ */
+#define AssertReleaseMsgReturn(expr, a, rc) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ return (rc); \
+ } \
+ } while (0)
+
+/** @def AssertReleaseMsgReturnVoid
+ * Assert that an expression is true, print the message and hit a breakpoint and return if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgReturnVoid(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ return; \
+ } \
+ } while (0)
+
+
+/** @def AssertReleaseMsgBreak
+ * Assert that an expression is true, print the message and hit a breakpoint and break if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgBreak(expr, a) \
+ if (RT_UNLIKELY(!(expr))) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertReleaseMsgBreakStmt
+ * Assert that an expression is true, print the message and hit a breakpoint and break if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#define AssertReleaseMsgBreakStmt(expr, a, stmt) \
+ if (RT_UNLIKELY(!(expr))) { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+
+/** @def AssertReleaseFailed
+ * An assertion failed, hit a breakpoint.
+ */
+#define AssertReleaseFailed() \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ } while (0)
+
+/** @def AssertReleaseFailedReturn
+ * An assertion failed, hit a breakpoint and return.
+ *
+ * @param rc What is to be presented to return.
+ */
+#define AssertReleaseFailedReturn(rc) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ return (rc); \
+ } while (0)
+
+/** @def AssertReleaseFailedReturnVoid
+ * An assertion failed, hit a breakpoint and return.
+ */
+#define AssertReleaseFailedReturnVoid() \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ return; \
+ } while (0)
+
+
+/** @def AssertReleaseFailedBreak
+ * An assertion failed, hit a breakpoint and break.
+ */
+#define AssertReleaseFailedBreak() \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertReleaseFailedBreakStmt
+ * An assertion failed, hit a breakpoint and break.
+ *
+ * @param stmt Statement to execute before break.
+ */
+#define AssertReleaseFailedBreakStmt(stmt) \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+
+/** @def AssertReleaseMsgFailed
+ * An assertion failed, print a message and hit a breakpoint.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgFailed(a) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ } while (0)
+
+/** @def AssertReleaseMsgFailedReturn
+ * An assertion failed, print a message, hit a breakpoint and return.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param rc What is to be presented to return.
+ */
+#define AssertReleaseMsgFailedReturn(a, rc) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ return (rc); \
+ } while (0)
+
+/** @def AssertReleaseMsgFailedReturnVoid
+ * An assertion failed, print a message, hit a breakpoint and return.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgFailedReturnVoid(a) \
+ do { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ return; \
+ } while (0)
+
+
+/** @def AssertReleaseMsgFailedBreak
+ * An assertion failed, print a message, hit a breakpoint and break.
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertReleaseMsgFailedBreak(a) \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ break; \
+ } else do {} while (0)
+
+/** @def AssertReleaseMsgFailedBreakStmt
+ * An assertion failed, print a message, hit a breakpoint and break.
+ *
+ * @param a printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break.
+ */
+#define AssertReleaseMsgFailedBreakStmt(a, stmt) \
+ if (1) { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ stmt; \
+ break; \
+ } else do {} while (0)
+
+/** @} */
+
+
+
+/** @name Fatal Assertions
+ * These are similar to release assertions except that you cannot ignore them in
+ * any way, they will loop for ever if RTAssertDoPanic returns.
+ *
+ * @{
+ */
+
+/** @def AssertFatal
+ * Assert that an expression is true. If it's not hit a breakpoint (for ever).
+ *
+ * @param expr Expression which should be true.
+ */
+#define AssertFatal(expr) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ for (;;) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ } \
+ } while (0)
+
+/** @def AssertFatalMsg
+ * Assert that an expression is true, print the message and hit a breakpoint (for ever) if it isn't.
+ *
+ * @param expr Expression which should be true.
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertFatalMsg(expr, a) \
+ do { \
+ if (RT_UNLIKELY(!(expr))) \
+ for (;;) \
+ { \
+ RTAssertMsg1Weak(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ } \
+ } while (0)
+
+/** @def AssertFatalFailed
+ * An assertion failed, hit a breakpoint (for ever).
+ */
+#define AssertFatalFailed() \
+ do { \
+ for (;;) \
+ { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertReleasePanic(); \
+ } \
+ } while (0)
+
+/** @def AssertFatalMsgFailed
+ * An assertion failed, print a message and hit a breakpoint (for ever).
+ *
+ * @param a printf argument list (in parenthesis).
+ */
+#define AssertFatalMsgFailed(a) \
+ do { \
+ for (;;) \
+ { \
+ RTAssertMsg1Weak((const char *)0, __LINE__, __FILE__, __PRETTY_FUNCTION__); \
+ RTAssertMsg2Weak a; \
+ RTAssertReleasePanic(); \
+ } \
+ } while (0)
+
+/** @} */
+
+
+
+/** @name Convenience Assertions Macros
+ * @{
+ */
+
+/** @def AssertRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure it will print info about the rc and hit a breakpoint.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRC(rc) AssertMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertRCReturn
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturn(rc, rcRet) AssertMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertRCReturn
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only), execute
+ * @a stmt and returns @a rcRet if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturnStmt(rc, stmt, rcRet) AssertMsgRCReturnStmt(rc, ("%Rra\n", (rc)), stmt, rcRet)
+
+/** @def AssertRCReturnVoid
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturnVoid(rc) AssertMsgRCReturnVoid(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReturnVoidStmt
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only), and
+ * execute the given statement/return if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before returning on failure.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCReturnVoidStmt(rc, stmt) AssertMsgRCReturnVoidStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertRCBreak
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCBreak(rc) AssertMsgRCBreak(rc, ("%Rra\n", (rc)))
+
+/** @def AssertRCBreakStmt
+ * Asserts a iprt status code successful, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCBreakStmt(rc, stmt) AssertMsgRCBreakStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * It prints a custom message and hits a breakpoint on FAILURE.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRC(rc, msg) \
+ do { AssertMsg(RT_SUCCESS_NP(rc), msg); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturn
+ * Asserts a iprt status code successful and if it's not return the specified status code.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturn(rc, msg, rcRet) \
+ do { AssertMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturnStmt
+ * Asserts a iprt status code successful and if it's not execute @a stmt and
+ * return the specified status code (@a rcRet).
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturnStmt(rc, msg, stmt, rcRet) \
+ do { AssertMsgReturnStmt(RT_SUCCESS_NP(rc), msg, stmt, rcRet); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturnVoid
+ * Asserts a iprt status code successful and if it's not return.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturnVoid(rc, msg) \
+ do { AssertMsgReturnVoid(RT_SUCCESS_NP(rc), msg); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCReturnVoidStmt
+ * Asserts a iprt status code successful and execute statement/break if it's not.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCReturnVoidStmt(rc, msg, stmt) \
+ do { AssertMsgReturnVoidStmt(RT_SUCCESS_NP(rc), msg, stmt); NOREF(rc); } while (0)
+
+/** @def AssertMsgRCBreak
+ * Asserts a iprt status code successful and if it's not break.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it breaks
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCBreak(rc, msg) \
+ if (1) { AssertMsgBreak(RT_SUCCESS(rc), msg); NOREF(rc); } else do {} while (0)
+
+/** @def AssertMsgRCBreakStmt
+ * Asserts a iprt status code successful and execute statement/break if it's not.
+ *
+ * If RT_STRICT is defined the message will be printed and a breakpoint hit before it returns
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertMsgRCBreakStmt(rc, msg, stmt) \
+ if (1) { AssertMsgBreakStmt(RT_SUCCESS_NP(rc), msg, stmt); NOREF(rc); } else do {} while (0)
+
+/** @def AssertRCSuccess
+ * Asserts an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure it will print info about the rc and hit a breakpoint.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccess(rc) do { AssertMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc))); NOREF(rc); } while (0)
+
+/** @def AssertRCSuccessReturn
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessReturn(rc, rcRet) AssertMsgReturn((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertRCSuccessReturnVoid
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and return if it isn't.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessReturnVoid(rc) AssertMsgReturnVoid((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertRCSuccessBreak
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessBreak(rc) AssertMsgBreak((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertRCSuccessBreakStmt
+ * Asserts that an iprt status code equals VINF_SUCCESS, bitch (RT_STRICT mode only) and break if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times. In release mode is NOREF()'ed.
+ */
+#define AssertRCSuccessBreakStmt(rc, stmt) AssertMsgBreakStmt((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), stmt)
+
+
+/** @def AssertLogRelRC
+ * Asserts a iprt status code successful.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRC(rc) AssertLogRelMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCReturn
+ * Asserts a iprt status code successful, returning \a rc if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCReturn(rc, rcRet) AssertLogRelMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertLogRelRCReturnStmt
+ * Asserts a iprt status code successful, executing \a stmt and returning \a rc
+ * if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCReturnStmt(rc, stmt, rcRet) AssertLogRelMsgRCReturnStmt(rc, ("%Rra\n", (rc)), stmt, rcRet)
+
+/** @def AssertLogRelRCReturnVoid
+ * Asserts a iprt status code successful, returning (void) if it isn't.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCReturnVoid(rc) AssertLogRelMsgRCReturnVoid(rc, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCBreak
+ * Asserts a iprt status code successful, breaking if it isn't.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCBreak(rc) AssertLogRelMsgRCBreak(rc, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCBreakStmt
+ * Asserts a iprt status code successful, execute \a statement and break if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCBreakStmt(rc, stmt) AssertLogRelMsgRCBreakStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertLogRelMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRC(rc, msg) AssertLogRelMsg(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertLogRelMsgRCReturn
+ * Asserts a iprt status code successful.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCReturn(rc, msg, rcRet) AssertLogRelMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet)
+
+/** @def AssertLogRelMsgRCReturnStmt
+ * Asserts a iprt status code successful, execute \a stmt and return on
+ * failure.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param stmt Statement to execute before returning in case of a failed
+ * assertion.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCReturnStmt(rc, msg, stmt, rcRet) AssertLogRelMsgReturnStmt(RT_SUCCESS_NP(rc), msg, stmt, rcRet)
+
+/** @def AssertLogRelMsgRCReturnVoid
+ * Asserts a iprt status code successful.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCReturnVoid(rc, msg) AssertLogRelMsgReturnVoid(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertLogRelMsgRCBreak
+ * Asserts a iprt status code successful.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCBreak(rc, msg) AssertLogRelMsgBreak(RT_SUCCESS(rc), msg)
+
+/** @def AssertLogRelMsgRCBreakStmt
+ * Asserts a iprt status code successful, execute \a stmt and break if it isn't.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelMsgRCBreakStmt(rc, msg, stmt) AssertLogRelMsgBreakStmt(RT_SUCCESS_NP(rc), msg, stmt)
+
+/** @def AssertLogRelRCSuccess
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccess(rc) AssertLogRelMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCSuccessReturn
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param rc iprt status code.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessReturn(rc, rcRet) AssertLogRelMsgReturn((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertLogRelRCSuccessReturnVoid
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessReturnVoid(rc) AssertLogRelMsgReturnVoid((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCSuccessBreak
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessBreak(rc) AssertLogRelMsgBreak((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertLogRelRCSuccessBreakStmt
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertLogRelRCSuccessBreakStmt(rc, stmt) AssertLogRelMsgBreakStmt((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), stmt)
+
+
+/** @def AssertReleaseRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRC(rc) AssertReleaseMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCReturn
+ * Asserts a iprt status code successful, returning if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCReturn(rc, rcRet) AssertReleaseMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertReleaseRCReturnVoid
+ * Asserts a iprt status code successful, returning if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCReturnVoid(rc) AssertReleaseMsgRCReturnVoid(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCBreak
+ * Asserts a iprt status code successful, breaking if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally breaking the current statement if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCBreak(rc) AssertReleaseMsgRCBreak(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCBreakStmt
+ * Asserts a iprt status code successful, break if it isn't.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally the break statement will be issued if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCBreakStmt(rc, stmt) AssertReleaseMsgRCBreakStmt(rc, ("%Rra\n", (rc)), stmt)
+
+/** @def AssertReleaseMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed and a breakpoint is hit.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRC(rc, msg) AssertReleaseMsg(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertReleaseMsgRCReturn
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCReturn(rc, msg, rcRet) AssertReleaseMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet)
+
+/** @def AssertReleaseMsgRCReturnVoid
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCReturnVoid(rc, msg) AssertReleaseMsgReturnVoid(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertReleaseMsgRCBreak
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * breaking the current status if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCBreak(rc, msg) AssertReleaseMsgBreak(RT_SUCCESS(rc), msg)
+
+/** @def AssertReleaseMsgRCBreakStmt
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed, a breakpoint is hit, and finally
+ * the break statement is issued if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseMsgRCBreakStmt(rc, msg, stmt) AssertReleaseMsgBreakStmt(RT_SUCCESS_NP(rc), msg, stmt)
+
+/** @def AssertReleaseRCSuccess
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccess(rc) AssertReleaseMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCSuccessReturn
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param rcRet What is to be presented to return.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessReturn(rc, rcRet) AssertReleaseMsgReturn((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), rcRet)
+
+/** @def AssertReleaseRCSuccessReturnVoid
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally returning from the function if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessReturnVoid(rc) AssertReleaseMsgReturnVoid((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCSuccessBreak
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally breaking the current statement if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessBreak(rc) AssertReleaseMsgBreak((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseRCSuccessBreakStmt
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed, a breakpoint hit
+ * and finally the break statement will be issued if the breakpoint is somehow ignored.
+ *
+ * @param rc iprt status code.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertReleaseRCSuccessBreakStmt(rc, stmt) AssertReleaseMsgBreakStmt((rc) == VINF_SUCCESS, ("%Rra\n", (rc)), stmt)
+
+
+/** @def AssertFatalRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertFatalRC(rc) AssertFatalMsgRC(rc, ("%Rra\n", (rc)))
+
+/** @def AssertReleaseMsgRC
+ * Asserts a iprt status code successful.
+ *
+ * On failure a custom message is printed and a breakpoint is hit.
+ *
+ * @param rc iprt status code.
+ * @param msg printf argument list (in parenthesis).
+ * @remark rc is referenced multiple times.
+ */
+#define AssertFatalMsgRC(rc, msg) AssertFatalMsg(RT_SUCCESS_NP(rc), msg)
+
+/** @def AssertFatalRCSuccess
+ * Asserts that an iprt status code equals VINF_SUCCESS.
+ *
+ * On failure information about the error will be printed and a breakpoint hit.
+ *
+ * @param rc iprt status code.
+ * @remark rc is referenced multiple times.
+ */
+#define AssertFatalRCSuccess(rc) AssertFatalMsg((rc) == VINF_SUCCESS, ("%Rra\n", (rc)))
+
+
+/** @def AssertPtr
+ * Asserts that a pointer is valid.
+ *
+ * @param pv The pointer.
+ */
+#define AssertPtr(pv) AssertMsg(VALID_PTR(pv), ("%p\n", (pv)))
+
+/** @def AssertPtrReturn
+ * Asserts that a pointer is valid.
+ *
+ * @param pv The pointer.
+ * @param rcRet What is to be presented to return.
+ */
+#define AssertPtrReturn(pv, rcRet) AssertMsgReturn(VALID_PTR(pv), ("%p\n", (pv)), rcRet)
+
+/** @def AssertPtrReturnVoid
+ * Asserts that a pointer is valid.
+ *
+ * @param pv The pointer.
+ */
+#define AssertPtrReturnVoid(pv) AssertMsgReturnVoid(VALID_PTR(pv), ("%p\n", (pv)))
+
+/** @def AssertPtrBreak
+ * Asserts that a pointer is valid.
+ *
+ * @param pv The pointer.
+ */
+#define AssertPtrBreak(pv) AssertMsgBreak(VALID_PTR(pv), ("%p\n", (pv)))
+
+/** @def AssertPtrBreakStmt
+ * Asserts that a pointer is valid.
+ *
+ * @param pv The pointer.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#define AssertPtrBreakStmt(pv, stmt) AssertMsgBreakStmt(VALID_PTR(pv), ("%p\n", (pv)), stmt)
+
+/** @def AssertPtrNull
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param pv The pointer.
+ */
+#define AssertPtrNull(pv) AssertMsg(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)))
+
+/** @def AssertPtrNullReturn
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param pv The pointer.
+ * @param rcRet What is to be presented to return.
+ */
+#define AssertPtrNullReturn(pv, rcRet) AssertMsgReturn(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)), rcRet)
+
+/** @def AssertPtrNullReturnVoid
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param pv The pointer.
+ */
+#define AssertPtrNullReturnVoid(pv) AssertMsgReturnVoid(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)))
+
+/** @def AssertPtrNullBreak
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param pv The pointer.
+ */
+#define AssertPtrNullBreak(pv) AssertMsgBreak(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)))
+
+/** @def AssertPtrNullBreakStmt
+ * Asserts that a pointer is valid or NULL.
+ *
+ * @param pv The pointer.
+ * @param stmt Statement to execute before break in case of a failed assertion.
+ */
+#define AssertPtrNullBreakStmt(pv, stmt) AssertMsgBreakStmt(VALID_PTR(pv) || (pv) == NULL, ("%p\n", (pv)), stmt)
+
+/** @def AssertGCPhys32
+ * Asserts that the high dword of a physical address is zero
+ *
+ * @param GCPhys The address (RTGCPHYS).
+ */
+#define AssertGCPhys32(GCPhys) AssertMsg(VALID_PHYS32(GCPhys), ("%RGp\n", (RTGCPHYS)(GCPhys)))
+
+/** @def AssertGCPtr32
+ * Asserts that the high dword of a physical address is zero
+ *
+ * @param GCPtr The address (RTGCPTR).
+ */
+#if GC_ARCH_BITS == 32
+# define AssertGCPtr32(GCPtr) do { } while (0)
+#else
+# define AssertGCPtr32(GCPtr) AssertMsg(!((GCPtr) & UINT64_C(0xffffffff00000000)), ("%RGv\n", GCPtr))
+#endif
+
+/** @def AssertForEach
+ * Equivalent to Assert for each value of the variable from the starting
+ * value to the finishing one.
+ *
+ * @param var Name of the counter variable.
+ * @param vartype Type of the counter variable.
+ * @param first Lowest inclusive value of the counter variable.
+ * This must be free from side effects.
+ * @param end Highest exclusive value of the counter variable.
+ * This must be free from side effects.
+ * @param expr Expression which should be true for each value of @a var.
+ */
+#define AssertForEach(var, vartype, first, end, expr) \
+ do { \
+ vartype var; \
+ Assert((first) == (first) && (end) == (end)); /* partial check for side effects */ \
+ for (var = (first); var < (end); var++) \
+ AssertMsg(expr, ("%s = %#RX64 (%RI64)", #var, (uint64_t)var, (int64_t)var)); \
+ } while (0)
+
+/** @} */
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/avl.h b/include/iprt/avl.h
new file mode 100644
index 00000000..9c1b99df
--- /dev/null
+++ b/include/iprt/avl.h
@@ -0,0 +1,1114 @@
+/** @file
+ * IPRT - AVL Trees.
+ */
+
+/*
+ * Copyright (C) 1999-2003 knut st. osmundsen <bird-src-spam@anduin.net>
+ *
+ * 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 ___iprt_avl_h
+#define ___iprt_avl_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_avl RTAvl - AVL Trees
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** AVL tree of void pointers.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef void * AVLPVKEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLPVNodeCore
+{
+ AVLPVKEY Key; /** Key value. */
+ struct _AVLPVNodeCore *pLeft; /** Pointer to left leaf node. */
+ struct _AVLPVNodeCore *pRight; /** Pointer to right leaf node. */
+ unsigned char uchHeight; /** Height of this tree: max(height(left), height(right)) + 1 */
+} AVLPVNODECORE, *PAVLPVNODECORE, **PPAVLPVNODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLPVNODECORE AVLPVTREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLPVNODECORE PAVLPVTREE;
+
+/** Callback function for AVLPVDoWithAll(). */
+typedef DECLCALLBACK(int) AVLPVCALLBACK(PAVLPVNODECORE, void *);
+/** Pointer to callback function for AVLPVDoWithAll(). */
+typedef AVLPVCALLBACK *PAVLPVCALLBACK;
+
+/*
+ * Functions.
+ */
+RTDECL(bool) RTAvlPVInsert(PAVLPVTREE ppTree, PAVLPVNODECORE pNode);
+RTDECL(PAVLPVNODECORE) RTAvlPVRemove(PAVLPVTREE ppTree, AVLPVKEY Key);
+RTDECL(PAVLPVNODECORE) RTAvlPVGet(PAVLPVTREE ppTree, AVLPVKEY Key);
+RTDECL(PAVLPVNODECORE) RTAvlPVGetBestFit(PAVLPVTREE ppTree, AVLPVKEY Key, bool fAbove);
+RTDECL(PAVLPVNODECORE) RTAvlPVRemoveBestFit(PAVLPVTREE ppTree, AVLPVKEY Key, bool fAbove);
+RTDECL(int) RTAvlPVDoWithAll(PAVLPVTREE ppTree, int fFromLeft, PAVLPVCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlPVDestroy(PAVLPVTREE ppTree, PAVLPVCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of unsigned long.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef unsigned long AVLULKEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLULNodeCore
+{
+ AVLULKEY Key; /** Key value. */
+ struct _AVLULNodeCore *pLeft; /** Pointer to left leaf node. */
+ struct _AVLULNodeCore *pRight; /** Pointer to right leaf node. */
+ unsigned char uchHeight; /** Height of this tree: max(height(left), height(right)) + 1 */
+} AVLULNODECORE, *PAVLULNODECORE, **PPAVLULNODECORE;
+
+
+/** Callback function for AVLULDoWithAll(). */
+typedef DECLCALLBACK(int) AVLULCALLBACK(PAVLULNODECORE, void*);
+/** Pointer to callback function for AVLULDoWithAll(). */
+typedef AVLULCALLBACK *PAVLULCALLBACK;
+
+
+/*
+ * Functions.
+ */
+RTDECL(bool) RTAvlULInsert(PPAVLULNODECORE ppTree, PAVLULNODECORE pNode);
+RTDECL(PAVLULNODECORE) RTAvlULRemove(PPAVLULNODECORE ppTree, AVLULKEY Key);
+RTDECL(PAVLULNODECORE) RTAvlULGet(PPAVLULNODECORE ppTree, AVLULKEY Key);
+RTDECL(PAVLULNODECORE) RTAvlULGetBestFit(PPAVLULNODECORE ppTree, AVLULKEY Key, bool fAbove);
+RTDECL(PAVLULNODECORE) RTAvlULRemoveBestFit(PPAVLULNODECORE ppTree, AVLULKEY Key, bool fAbove);
+RTDECL(int) RTAvlULDoWithAll(PPAVLULNODECORE ppTree, int fFromLeft, PAVLULCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlULDestroy(PPAVLULNODECORE pTree, PAVLULCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of void pointer ranges.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef void *AVLRPVKEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct AVLRPVNodeCore
+{
+ AVLRPVKEY Key; /**< First key value in the range (inclusive). */
+ AVLRPVKEY KeyLast; /**< Last key value in the range (inclusive). */
+ struct AVLRPVNodeCore *pLeft; /**< Pointer to left leaf node. */
+ struct AVLRPVNodeCore *pRight; /**< Pointer to right leaf node. */
+ unsigned char uchHeight; /**< Height of this tree: max(height(left), height(right)) + 1 */
+} AVLRPVNODECORE, *PAVLRPVNODECORE, **PPAVLRPVNODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLRPVNODECORE AVLRPVTREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLRPVNODECORE PAVLRPVTREE;
+
+/** Callback function for AVLPVDoWithAll(). */
+typedef DECLCALLBACK(int) AVLRPVCALLBACK(PAVLRPVNODECORE, void *);
+/** Pointer to callback function for AVLPVDoWithAll(). */
+typedef AVLRPVCALLBACK *PAVLRPVCALLBACK;
+
+/*
+ * Functions.
+ */
+RTDECL(bool) RTAvlrPVInsert(PAVLRPVTREE ppTree, PAVLRPVNODECORE pNode);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRemove(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVGet(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRangeGet(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRangeRemove(PAVLRPVTREE ppTree, AVLRPVKEY Key);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVGetBestFit(PAVLRPVTREE ppTree, AVLRPVKEY Key, bool fAbove);
+RTDECL(PAVLRPVNODECORE) RTAvlrPVRemoveBestFit(PAVLRPVTREE ppTree, AVLRPVKEY Key, bool fAbove);
+RTDECL(int) RTAvlrPVDoWithAll(PAVLRPVTREE ppTree, int fFromLeft, PAVLRPVCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlrPVDestroy(PAVLRPVTREE ppTree, PAVLRPVCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of uint32_t
+ * @{
+ */
+
+/** AVL key type. */
+typedef uint32_t AVLU32KEY;
+
+/** AVL Core node. */
+typedef struct _AVLU32NodeCore
+{
+ AVLU32KEY Key; /**< Key value. */
+ struct _AVLU32NodeCore *pLeft; /**< Pointer to left leaf node. */
+ struct _AVLU32NodeCore *pRight; /**< Pointer to right leaf node. */
+ unsigned char uchHeight; /**< Height of this tree: max(height(left), height(right)) + 1 */
+} AVLU32NODECORE, *PAVLU32NODECORE, **PPAVLU32NODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLU32NODECORE AVLU32TREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLU32NODECORE PAVLU32TREE;
+
+/** Callback function for AVLU32DoWithAll() & AVLU32Destroy(). */
+typedef DECLCALLBACK(int) AVLU32CALLBACK(PAVLU32NODECORE, void*);
+/** Pointer to callback function for AVLU32DoWithAll() & AVLU32Destroy(). */
+typedef AVLU32CALLBACK *PAVLU32CALLBACK;
+
+
+/*
+ * Functions.
+ */
+RTDECL(bool) RTAvlU32Insert(PAVLU32TREE pTree, PAVLU32NODECORE pNode);
+RTDECL(PAVLU32NODECORE) RTAvlU32Remove(PAVLU32TREE pTree, AVLU32KEY Key);
+RTDECL(PAVLU32NODECORE) RTAvlU32Get(PAVLU32TREE pTree, AVLU32KEY Key);
+RTDECL(PAVLU32NODECORE) RTAvlU32GetBestFit(PAVLU32TREE pTree, AVLU32KEY Key, bool fAbove);
+RTDECL(PAVLU32NODECORE) RTAvlU32RemoveBestFit(PAVLU32TREE pTree, AVLU32KEY Key, bool fAbove);
+RTDECL(int) RTAvlU32DoWithAll(PAVLU32TREE pTree, int fFromLeft, PAVLU32CALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlU32Destroy(PAVLU32TREE pTree, PAVLU32CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+/**
+ * AVL uint32_t type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLOU32;
+
+typedef uint32_t AVLOU32KEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOU32NodeCore
+{
+ /** Key value. */
+ AVLOU32KEY Key;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLOU32 pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLOU32 pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLOU32NODECORE, *PAVLOU32NODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOU32 AVLOU32TREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOU32TREE *PAVLOU32TREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOU32TREE *PPAVLOU32NODECORE;
+
+/** Callback function for RTAvloU32DoWithAll(). */
+typedef DECLCALLBACK(int) AVLOU32CALLBACK(PAVLOU32NODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloU32DoWithAll(). */
+typedef AVLOU32CALLBACK *PAVLOU32CALLBACK;
+
+RTDECL(bool) RTAvloU32Insert(PAVLOU32TREE pTree, PAVLOU32NODECORE pNode);
+RTDECL(PAVLOU32NODECORE) RTAvloU32Remove(PAVLOU32TREE pTree, AVLOU32KEY Key);
+RTDECL(PAVLOU32NODECORE) RTAvloU32Get(PAVLOU32TREE pTree, AVLOU32KEY Key);
+RTDECL(int) RTAvloU32DoWithAll(PAVLOU32TREE pTree, int fFromLeft, PAVLOU32CALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOU32NODECORE) RTAvloU32GetBestFit(PAVLOU32TREE ppTree, AVLOU32KEY Key, bool fAbove);
+RTDECL(PAVLOU32NODECORE) RTAvloU32RemoveBestFit(PAVLOU32TREE ppTree, AVLOU32KEY Key, bool fAbove);
+RTDECL(int) RTAvloU32Destroy(PAVLOU32TREE pTree, PAVLOU32CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of uint32_t, list duplicates.
+ * @{
+ */
+
+/** AVL key type. */
+typedef uint32_t AVLLU32KEY;
+
+/** AVL Core node. */
+typedef struct _AVLLU32NodeCore
+{
+ AVLLU32KEY Key; /**< Key value. */
+ unsigned char uchHeight; /**< Height of this tree: max(height(left), height(right)) + 1 */
+ struct _AVLLU32NodeCore *pLeft; /**< Pointer to left leaf node. */
+ struct _AVLLU32NodeCore *pRight; /**< Pointer to right leaf node. */
+ struct _AVLLU32NodeCore *pList; /**< Pointer to next node with the same key. */
+} AVLLU32NODECORE, *PAVLLU32NODECORE, **PPAVLLU32NODECORE;
+
+/** Callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). */
+typedef DECLCALLBACK(int) AVLLU32CALLBACK(PAVLLU32NODECORE, void*);
+/** Pointer to callback function for RTAvllU32DoWithAll() & RTAvllU32Destroy(). */
+typedef AVLLU32CALLBACK *PAVLLU32CALLBACK;
+
+
+/*
+ * Functions.
+ */
+RTDECL(bool) RTAvllU32Insert(PPAVLLU32NODECORE ppTree, PAVLLU32NODECORE pNode);
+RTDECL(PAVLLU32NODECORE) RTAvllU32Remove(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key);
+RTDECL(PAVLLU32NODECORE) RTAvllU32RemoveNode(PPAVLLU32NODECORE ppTree, PAVLLU32NODECORE pNode);
+RTDECL(PAVLLU32NODECORE) RTAvllU32Get(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key);
+RTDECL(PAVLLU32NODECORE) RTAvllU32GetBestFit(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key, bool fAbove);
+RTDECL(PAVLLU32NODECORE) RTAvllU32RemoveBestFit(PPAVLLU32NODECORE ppTree, AVLLU32KEY Key, bool fAbove);
+RTDECL(int) RTAvllU32DoWithAll(PPAVLLU32NODECORE ppTree, int fFromLeft, PAVLLU32CALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvllU32Destroy(PPAVLLU32NODECORE pTree, PAVLLU32CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of uint64_t ranges.
+ * @{
+ */
+
+/**
+ * AVL key type
+ */
+typedef uint64_t AVLRU64KEY;
+
+/**
+ * AVL Core node.
+ */
+typedef struct AVLRU64NodeCore
+{
+ AVLRU64KEY Key; /**< First key value in the range (inclusive). */
+ AVLRU64KEY KeyLast; /**< Last key value in the range (inclusive). */
+ struct AVLRU64NodeCore *pLeft; /**< Pointer to left leaf node. */
+ struct AVLRU64NodeCore *pRight; /**< Pointer to right leaf node. */
+ unsigned char uchHeight; /**< Height of this tree: max(height(left), height(right)) + 1 */
+} AVLRU64NODECORE, *PAVLRU64NODECORE, **PPAVLRU64NODECORE;
+
+/** A tree with void pointer keys. */
+typedef PAVLRU64NODECORE AVLRU64TREE;
+/** Pointer to a tree with void pointer keys. */
+typedef PPAVLRU64NODECORE PAVLRU64TREE;
+
+/** Callback function for AVLRU64DoWithAll(). */
+typedef DECLCALLBACK(int) AVLRU64CALLBACK(PAVLRU64NODECORE, void *);
+/** Pointer to callback function for AVLU64DoWithAll(). */
+typedef AVLRU64CALLBACK *PAVLRU64CALLBACK;
+
+/*
+ * Functions.
+ */
+RTDECL(bool) RTAvlrU64Insert(PAVLRU64TREE ppTree, PAVLRU64NODECORE pNode);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64Remove(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64Get(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64RangeGet(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64RangeRemove(PAVLRU64TREE ppTree, AVLRU64KEY Key);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64GetBestFit(PAVLRU64TREE ppTree, AVLRU64KEY Key, bool fAbove);
+RTDECL(PAVLRU64NODECORE) RTAvlrU64RemoveBestFit(PAVLRU64TREE ppTree, AVLRU64KEY Key, bool fAbove);
+RTDECL(int) RTAvlrU64DoWithAll(PAVLRU64TREE ppTree, int fFromLeft, PAVLRU64CALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlrU64Destroy(PAVLRU64TREE ppTree, PAVLRU64CALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of RTGCPHYSes - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLOGCPHYS;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOGCPhysNodeCore
+{
+ /** Key value. */
+ RTGCPHYS Key;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLOGCPHYS pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLOGCPHYS pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+ /** Padding */
+ unsigned char Padding[7];
+} AVLOGCPHYSNODECORE, *PAVLOGCPHYSNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOGCPHYS AVLOGCPHYSTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOGCPHYSTREE *PAVLOGCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOGCPHYSTREE *PPAVLOGCPHYSNODECORE;
+
+/** Callback function for RTAvloGCPhysDoWithAll() and RTAvloGCPhysDestroy(). */
+typedef DECLCALLBACK(int) AVLOGCPHYSCALLBACK(PAVLOGCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloGCPhysDoWithAll() and RTAvloGCPhysDestroy(). */
+typedef AVLOGCPHYSCALLBACK *PAVLOGCPHYSCALLBACK;
+
+RTDECL(bool) RTAvloGCPhysInsert(PAVLOGCPHYSTREE pTree, PAVLOGCPHYSNODECORE pNode);
+RTDECL(PAVLOGCPHYSNODECORE) RTAvloGCPhysRemove(PAVLOGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLOGCPHYSNODECORE) RTAvloGCPhysGet(PAVLOGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(int) RTAvloGCPhysDoWithAll(PAVLOGCPHYSTREE pTree, int fFromLeft, PAVLOGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOGCPHYSNODECORE) RTAvloGCPhysGetBestFit(PAVLOGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(PAVLOGCPHYSNODECORE) RTAvloGCPhysRemoveBestFit(PAVLOGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(int) RTAvloGCPhysDestroy(PAVLOGCPHYSTREE pTree, PAVLOGCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTGCPHYS ranges - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLROGCPHYS;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROGCPhysNodeCore
+{
+ /** First key value in the range (inclusive). */
+ RTGCPHYS Key;
+ /** Last key value in the range (inclusive). */
+ RTGCPHYS KeyLast;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLROGCPHYS pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLROGCPHYS pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+ /** Padding */
+ unsigned char Padding[7];
+} AVLROGCPHYSNODECORE, *PAVLROGCPHYSNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROGCPHYS AVLROGCPHYSTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROGCPHYSTREE *PAVLROGCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROGCPHYSTREE *PPAVLROGCPHYSNODECORE;
+
+/** Callback function for RTAvlroGCPhysDoWithAll() and RTAvlroGCPhysDestroy(). */
+typedef DECLCALLBACK(int) AVLROGCPHYSCALLBACK(PAVLROGCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlroGCPhysDoWithAll() and RTAvlroGCPhysDestroy(). */
+typedef AVLROGCPHYSCALLBACK *PAVLROGCPHYSCALLBACK;
+
+RTDECL(bool) RTAvlroGCPhysInsert(PAVLROGCPHYSTREE pTree, PAVLROGCPHYSNODECORE pNode);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysRemove(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysGet(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysRangeGet(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysRangeRemove(PAVLROGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysGetBestFit(PAVLROGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(int) RTAvlroGCPhysDoWithAll(PAVLROGCPHYSTREE pTree, int fFromLeft, PAVLROGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlroGCPhysDestroy(PAVLROGCPHYSTREE pTree, PAVLROGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysGetRoot(PAVLROGCPHYSTREE pTree);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysGetLeft(PAVLROGCPHYSNODECORE pNode);
+RTDECL(PAVLROGCPHYSNODECORE) RTAvlroGCPhysGetRight(PAVLROGCPHYSNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTRs.
+ * @{
+ */
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLGCPtrNodeCore
+{
+ /** Key value. */
+ RTGCPTR Key;
+ /** Pointer to the left node. */
+ struct _AVLGCPtrNodeCore *pLeft;
+ /** Pointer to the right node. */
+ struct _AVLGCPtrNodeCore *pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLGCPTRNODECORE, *PAVLGCPTRNODECORE, **PPAVLGCPTRNODECORE;
+
+/** A tree of RTGCPTR keys. */
+typedef PAVLGCPTRNODECORE AVLGCPTRTREE;
+/** Pointer to a tree of RTGCPTR keys. */
+typedef PPAVLGCPTRNODECORE PAVLGCPTRTREE;
+
+/** Callback function for RTAvlGCPtrDoWithAll(). */
+typedef DECLCALLBACK(int) AVLGCPTRCALLBACK(PAVLGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlGCPtrDoWithAll(). */
+typedef AVLGCPTRCALLBACK *PAVLGCPTRCALLBACK;
+
+RTDECL(bool) RTAvlGCPtrInsert(PAVLGCPTRTREE pTree, PAVLGCPTRNODECORE pNode);
+RTDECL(PAVLGCPTRNODECORE) RTAvlGCPtrRemove(PAVLGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLGCPTRNODECORE) RTAvlGCPtrGet(PAVLGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int) RTAvlGCPtrDoWithAll(PAVLGCPTRTREE pTree, int fFromLeft, PAVLGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLGCPTRNODECORE) RTAvlGCPtrGetBestFit(PAVLGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLGCPTRNODECORE) RTAvlGCPtrRemoveBestFit(PAVLGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(int) RTAvlGCPtrDestroy(PAVLGCPTRTREE pTree, PAVLGCPTRCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTRs - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLOGCPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOGCPtrNodeCore
+{
+ /** Key value. */
+ RTGCPTR Key;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLOGCPTR pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLOGCPTR pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+ unsigned char padding[GC_ARCH_BITS == 64 ? 7 : 3];
+} AVLOGCPTRNODECORE, *PAVLOGCPTRNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOGCPTR AVLOGCPTRTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOGCPTRTREE *PAVLOGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOGCPTRTREE *PPAVLOGCPTRNODECORE;
+
+/** Callback function for RTAvloGCPtrDoWithAll(). */
+typedef DECLCALLBACK(int) AVLOGCPTRCALLBACK(PAVLOGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloGCPtrDoWithAll(). */
+typedef AVLOGCPTRCALLBACK *PAVLOGCPTRCALLBACK;
+
+RTDECL(bool) RTAvloGCPtrInsert(PAVLOGCPTRTREE pTree, PAVLOGCPTRNODECORE pNode);
+RTDECL(PAVLOGCPTRNODECORE) RTAvloGCPtrRemove(PAVLOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLOGCPTRNODECORE) RTAvloGCPtrGet(PAVLOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int) RTAvloGCPtrDoWithAll(PAVLOGCPTRTREE pTree, int fFromLeft, PAVLOGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOGCPTRNODECORE) RTAvloGCPtrGetBestFit(PAVLOGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLOGCPTRNODECORE) RTAvloGCPtrRemoveBestFit(PAVLOGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(int) RTAvloGCPtrDestroy(PAVLOGCPTRTREE pTree, PAVLOGCPTRCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTR ranges.
+ * @{
+ */
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLRGCPtrNodeCore
+{
+ /** First key value in the range (inclusive). */
+ RTGCPTR Key;
+ /** Last key value in the range (inclusive). */
+ RTGCPTR KeyLast;
+ /** Offset to the left leaf node, relative to this field. */
+ struct _AVLRGCPtrNodeCore *pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ struct _AVLRGCPtrNodeCore *pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLRGCPTRNODECORE, *PAVLRGCPTRNODECORE;
+
+/** A offset base tree with RTGCPTR keys. */
+typedef PAVLRGCPTRNODECORE AVLRGCPTRTREE;
+/** Pointer to an offset base tree with RTGCPTR keys. */
+typedef AVLRGCPTRTREE *PAVLRGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLRGCPTRTREE *PPAVLRGCPTRNODECORE;
+
+/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */
+typedef DECLCALLBACK(int) AVLRGCPTRCALLBACK(PAVLRGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */
+typedef AVLRGCPTRCALLBACK *PAVLRGCPTRCALLBACK;
+
+RTDECL(bool) RTAvlrGCPtrInsert( PAVLRGCPTRTREE pTree, PAVLRGCPTRNODECORE pNode);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrRemove( PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrGet( PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrGetBestFit( PAVLRGCPTRTREE pTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrRangeGet( PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrRangeRemove( PAVLRGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int) RTAvlrGCPtrDoWithAll( PAVLRGCPTRTREE pTree, int fFromLeft, PAVLRGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlrGCPtrDestroy( PAVLRGCPTRTREE pTree, PAVLRGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrGetRoot( PAVLRGCPTRTREE pTree);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrGetLeft( PAVLRGCPTRNODECORE pNode);
+RTDECL(PAVLRGCPTRNODECORE) RTAvlrGCPtrGetRight( PAVLRGCPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTR ranges - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLROGCPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROGCPtrNodeCore
+{
+ /** First key value in the range (inclusive). */
+ RTGCPTR Key;
+ /** Last key value in the range (inclusive). */
+ RTGCPTR KeyLast;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLROGCPTR pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLROGCPTR pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+ unsigned char padding[GC_ARCH_BITS == 64 ? 7 : 7];
+} AVLROGCPTRNODECORE, *PAVLROGCPTRNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROGCPTR AVLROGCPTRTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROGCPTRTREE *PAVLROGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROGCPTRTREE *PPAVLROGCPTRNODECORE;
+
+/** Callback function for RTAvlroGCPtrDoWithAll() and RTAvlroGCPtrDestroy(). */
+typedef DECLCALLBACK(int) AVLROGCPTRCALLBACK(PAVLROGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlroGCPtrDoWithAll() and RTAvlroGCPtrDestroy(). */
+typedef AVLROGCPTRCALLBACK *PAVLROGCPTRCALLBACK;
+
+RTDECL(bool) RTAvlroGCPtrInsert(PAVLROGCPTRTREE pTree, PAVLROGCPTRNODECORE pNode);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrRemove(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrGet(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrGetBestFit(PAVLROGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrRangeGet(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrRangeRemove(PAVLROGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int) RTAvlroGCPtrDoWithAll(PAVLROGCPTRTREE pTree, int fFromLeft, PAVLROGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlroGCPtrDestroy(PAVLROGCPTRTREE pTree, PAVLROGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrGetRoot(PAVLROGCPTRTREE pTree);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrGetLeft(PAVLROGCPTRNODECORE pNode);
+RTDECL(PAVLROGCPTRNODECORE) RTAvlroGCPtrGetRight(PAVLROGCPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTGCPTR ranges (overlapping supported) - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLROOGCPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROOGCPtrNodeCore
+{
+ /** First key value in the range (inclusive). */
+ RTGCPTR Key;
+ /** Last key value in the range (inclusive). */
+ RTGCPTR KeyLast;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLROOGCPTR pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLROOGCPTR pRight;
+ /** Pointer to the list of string with the same key. Don't touch. */
+ AVLROOGCPTR pList;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLROOGCPTRNODECORE, *PAVLROOGCPTRNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROOGCPTR AVLROOGCPTRTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROOGCPTRTREE *PAVLROOGCPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROOGCPTRTREE *PPAVLROOGCPTRNODECORE;
+
+/** Callback function for RTAvlrooGCPtrDoWithAll() and RTAvlrooGCPtrDestroy(). */
+typedef DECLCALLBACK(int) AVLROOGCPTRCALLBACK(PAVLROOGCPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrooGCPtrDoWithAll() and RTAvlrooGCPtrDestroy(). */
+typedef AVLROOGCPTRCALLBACK *PAVLROOGCPTRCALLBACK;
+
+RTDECL(bool) RTAvlrooGCPtrInsert(PAVLROOGCPTRTREE pTree, PAVLROOGCPTRNODECORE pNode);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrRemove(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrGet(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrGetBestFit(PAVLROOGCPTRTREE ppTree, RTGCPTR Key, bool fAbove);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrRangeGet(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrRangeRemove(PAVLROOGCPTRTREE pTree, RTGCPTR Key);
+RTDECL(int) RTAvlrooGCPtrDoWithAll(PAVLROOGCPTRTREE pTree, int fFromLeft, PAVLROOGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlrooGCPtrDestroy(PAVLROOGCPTRTREE pTree, PAVLROOGCPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrGetRoot(PAVLROOGCPTRTREE pTree);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrGetLeft(PAVLROOGCPTRNODECORE pNode);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrGetRight(PAVLROOGCPTRNODECORE pNode);
+RTDECL(PAVLROOGCPTRNODECORE) RTAvlrooGCPtrGetNextEqual(PAVLROOGCPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTUINTPTR.
+ * @{
+ */
+
+/**
+ * AVL RTUINTPTR node core.
+ */
+typedef struct _AVLUIntPtrNodeCore
+{
+ /** Key value. */
+ RTUINTPTR Key;
+ /** Offset to the left leaf node, relative to this field. */
+ struct _AVLUIntPtrNodeCore *pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ struct _AVLUIntPtrNodeCore *pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLUINTPTRNODECORE;
+/** Pointer to a RTUINTPTR AVL node core.*/
+typedef AVLUINTPTRNODECORE *PAVLUINTPTRNODECORE;
+
+/** A pointer based tree with RTUINTPTR keys. */
+typedef PAVLUINTPTRNODECORE AVLUINTPTRTREE;
+/** Pointer to an offset base tree with RTUINTPTR keys. */
+typedef AVLUINTPTRTREE *PAVLUINTPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a pointer. */
+typedef AVLUINTPTRTREE *PPAVLUINTPTRNODECORE;
+
+/** Callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). */
+typedef DECLCALLBACK(int) AVLUINTPTRCALLBACK(PAVLUINTPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlUIntPtrDoWithAll() and RTAvlUIntPtrDestroy(). */
+typedef AVLUINTPTRCALLBACK *PAVLUINTPTRCALLBACK;
+
+RTDECL(bool) RTAvlUIntPtrInsert( PAVLUINTPTRTREE pTree, PAVLUINTPTRNODECORE pNode);
+RTDECL(PAVLUINTPTRNODECORE) RTAvlUIntPtrRemove( PAVLUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLUINTPTRNODECORE) RTAvlUIntPtrGet( PAVLUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLUINTPTRNODECORE) RTAvlUIntPtrGetBestFit(PAVLUINTPTRTREE pTree, RTUINTPTR Key, bool fAbove);
+RTDECL(int) RTAvlUIntPtrDoWithAll( PAVLUINTPTRTREE pTree, int fFromLeft, PAVLUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlUIntPtrDestroy( PAVLUINTPTRTREE pTree, PAVLUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLUINTPTRNODECORE) RTAvlUIntPtrGetRoot( PAVLUINTPTRTREE pTree);
+RTDECL(PAVLUINTPTRNODECORE) RTAvlUIntPtrGetLeft( PAVLUINTPTRNODECORE pNode);
+RTDECL(PAVLUINTPTRNODECORE) RTAvlUIntPtrGetRight( PAVLUINTPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTUINTPTR ranges.
+ * @{
+ */
+
+/**
+ * AVL RTUINTPTR range node core.
+ */
+typedef struct _AVLRUIntPtrNodeCore
+{
+ /** First key value in the range (inclusive). */
+ RTUINTPTR Key;
+ /** Last key value in the range (inclusive). */
+ RTUINTPTR KeyLast;
+ /** Offset to the left leaf node, relative to this field. */
+ struct _AVLRUIntPtrNodeCore *pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ struct _AVLRUIntPtrNodeCore *pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLRUINTPTRNODECORE;
+/** Pointer to an AVL RTUINTPTR range node code. */
+typedef AVLRUINTPTRNODECORE *PAVLRUINTPTRNODECORE;
+
+/** A pointer based tree with RTUINTPTR ranges. */
+typedef PAVLRUINTPTRNODECORE AVLRUINTPTRTREE;
+/** Pointer to a pointer based tree with RTUINTPTR ranges. */
+typedef AVLRUINTPTRTREE *PAVLRUINTPTRTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a pointer. */
+typedef AVLRUINTPTRTREE *PPAVLRUINTPTRNODECORE;
+
+/** Callback function for RTAvlrUIntPtrDoWithAll() and RTAvlrUIntPtrDestroy(). */
+typedef DECLCALLBACK(int) AVLRUINTPTRCALLBACK(PAVLRUINTPTRNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrUIntPtrDoWithAll() and RTAvlrUIntPtrDestroy(). */
+typedef AVLRUINTPTRCALLBACK *PAVLRUINTPTRCALLBACK;
+
+RTDECL(bool) RTAvlrUIntPtrInsert( PAVLRUINTPTRTREE pTree, PAVLRUINTPTRNODECORE pNode);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrRemove( PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrGet( PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrGetBestFit( PAVLRUINTPTRTREE pTree, RTUINTPTR Key, bool fAbove);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrRangeGet( PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrRangeRemove(PAVLRUINTPTRTREE pTree, RTUINTPTR Key);
+RTDECL(int) RTAvlrUIntPtrDoWithAll( PAVLRUINTPTRTREE pTree, int fFromLeft, PAVLRUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlrUIntPtrDestroy( PAVLRUINTPTRTREE pTree, PAVLRUINTPTRCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrGetRoot( PAVLRUINTPTRTREE pTree);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrGetLeft( PAVLRUINTPTRNODECORE pNode);
+RTDECL(PAVLRUINTPTRNODECORE) RTAvlrUIntPtrGetRight( PAVLRUINTPTRNODECORE pNode);
+
+/** @} */
+
+
+/** AVL tree of RTHCPHYSes - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLOHCPHYS;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOHCPhysNodeCore
+{
+ /** Key value. */
+ RTHCPHYS Key;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLOHCPHYS pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLOHCPHYS pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+#if HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64
+ unsigned char Padding[7]; /**< Alignment padding. */
+#endif
+} AVLOHCPHYSNODECORE, *PAVLOHCPHYSNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOHCPHYS AVLOHCPHYSTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOHCPHYSTREE *PAVLOHCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOHCPHYSTREE *PPAVLOHCPHYSNODECORE;
+
+/** Callback function for RTAvloHCPhysDoWithAll() and RTAvloHCPhysDestroy(). */
+typedef DECLCALLBACK(int) AVLOHCPHYSCALLBACK(PAVLOHCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloHCPhysDoWithAll() and RTAvloHCPhysDestroy(). */
+typedef AVLOHCPHYSCALLBACK *PAVLOHCPHYSCALLBACK;
+
+RTDECL(bool) RTAvloHCPhysInsert(PAVLOHCPHYSTREE pTree, PAVLOHCPHYSNODECORE pNode);
+RTDECL(PAVLOHCPHYSNODECORE) RTAvloHCPhysRemove(PAVLOHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(PAVLOHCPHYSNODECORE) RTAvloHCPhysGet(PAVLOHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(int) RTAvloHCPhysDoWithAll(PAVLOHCPHYSTREE pTree, int fFromLeft, PAVLOHCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOHCPHYSNODECORE) RTAvloHCPhysGetBestFit(PAVLOHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(PAVLOHCPHYSNODECORE) RTAvloHCPhysRemoveBestFit(PAVLOHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(int) RTAvloHCPhysDestroy(PAVLOHCPHYSTREE pTree, PAVLOHCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+
+/** AVL tree of RTIOPORTs - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLOIOPORTPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLOIOPortNodeCore
+{
+ /** Offset to the left leaf node, relative to this field. */
+ AVLOIOPORTPTR pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLOIOPORTPTR pRight;
+ /** Key value. */
+ RTIOPORT Key;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLOIOPORTNODECORE, *PAVLOIOPORTNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLOIOPORTPTR AVLOIOPORTTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLOIOPORTTREE *PAVLOIOPORTTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLOIOPORTTREE *PPAVLOIOPORTNODECORE;
+
+/** Callback function for RTAvloIOPortDoWithAll() and RTAvloIOPortDestroy(). */
+typedef DECLCALLBACK(int) AVLOIOPORTCALLBACK(PAVLOIOPORTNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvloIOPortDoWithAll() and RTAvloIOPortDestroy(). */
+typedef AVLOIOPORTCALLBACK *PAVLOIOPORTCALLBACK;
+
+RTDECL(bool) RTAvloIOPortInsert(PAVLOIOPORTTREE pTree, PAVLOIOPORTNODECORE pNode);
+RTDECL(PAVLOIOPORTNODECORE) RTAvloIOPortRemove(PAVLOIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLOIOPORTNODECORE) RTAvloIOPortGet(PAVLOIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(int) RTAvloIOPortDoWithAll(PAVLOIOPORTTREE pTree, int fFromLeft, PAVLOIOPORTCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLOIOPORTNODECORE) RTAvloIOPortGetBestFit(PAVLOIOPORTTREE ppTree, RTIOPORT Key, bool fAbove);
+RTDECL(PAVLOIOPORTNODECORE) RTAvloIOPortRemoveBestFit(PAVLOIOPORTTREE ppTree, RTIOPORT Key, bool fAbove);
+RTDECL(int) RTAvloIOPortDestroy(PAVLOIOPORTTREE pTree, PAVLOIOPORTCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTIOPORT ranges - using relative offsets internally.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef int32_t AVLROIOPORTPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLROIOPortNodeCore
+{
+ /** First key value in the range (inclusive). */
+ RTIOPORT Key;
+ /** Last key value in the range (inclusive). */
+ RTIOPORT KeyLast;
+ /** Offset to the left leaf node, relative to this field. */
+ AVLROIOPORTPTR pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLROIOPORTPTR pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLROIOPORTNODECORE, *PAVLROIOPORTNODECORE;
+
+/** A offset base tree with uint32_t keys. */
+typedef AVLROIOPORTPTR AVLROIOPORTTREE;
+/** Pointer to an offset base tree with uint32_t keys. */
+typedef AVLROIOPORTTREE *PAVLROIOPORTTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLROIOPORTTREE *PPAVLROIOPORTNODECORE;
+
+/** Callback function for RTAvlroIOPortDoWithAll() and RTAvlroIOPortDestroy(). */
+typedef DECLCALLBACK(int) AVLROIOPORTCALLBACK(PAVLROIOPORTNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlroIOPortDoWithAll() and RTAvlroIOPortDestroy(). */
+typedef AVLROIOPORTCALLBACK *PAVLROIOPORTCALLBACK;
+
+RTDECL(bool) RTAvlroIOPortInsert(PAVLROIOPORTTREE pTree, PAVLROIOPORTNODECORE pNode);
+RTDECL(PAVLROIOPORTNODECORE) RTAvlroIOPortRemove(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLROIOPORTNODECORE) RTAvlroIOPortGet(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLROIOPORTNODECORE) RTAvlroIOPortRangeGet(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(PAVLROIOPORTNODECORE) RTAvlroIOPortRangeRemove(PAVLROIOPORTTREE pTree, RTIOPORT Key);
+RTDECL(int) RTAvlroIOPortDoWithAll(PAVLROIOPORTTREE pTree, int fFromLeft, PAVLROIOPORTCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlroIOPortDestroy(PAVLROIOPORTTREE pTree, PAVLROIOPORTCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTHCPHYSes.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef struct _AVLHCPhysNodeCore *AVLHCPHYSPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLHCPhysNodeCore
+{
+ /** Offset to the left leaf node, relative to this field. */
+ AVLHCPHYSPTR pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLHCPHYSPTR pRight;
+ /** Key value. */
+ RTHCPHYS Key;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLHCPHYSNODECORE, *PAVLHCPHYSNODECORE;
+
+/** A offset base tree with RTHCPHYS keys. */
+typedef AVLHCPHYSPTR AVLHCPHYSTREE;
+/** Pointer to an offset base tree with RTHCPHYS keys. */
+typedef AVLHCPHYSTREE *PAVLHCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLHCPHYSTREE *PPAVLHCPHYSNODECORE;
+
+/** Callback function for RTAvlHCPhysDoWithAll() and RTAvlHCPhysDestroy(). */
+typedef DECLCALLBACK(int) AVLHCPHYSCALLBACK(PAVLHCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlHCPhysDoWithAll() and RTAvlHCPhysDestroy(). */
+typedef AVLHCPHYSCALLBACK *PAVLHCPHYSCALLBACK;
+
+RTDECL(bool) RTAvlHCPhysInsert(PAVLHCPHYSTREE pTree, PAVLHCPHYSNODECORE pNode);
+RTDECL(PAVLHCPHYSNODECORE) RTAvlHCPhysRemove(PAVLHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(PAVLHCPHYSNODECORE) RTAvlHCPhysGet(PAVLHCPHYSTREE pTree, RTHCPHYS Key);
+RTDECL(int) RTAvlHCPhysDoWithAll(PAVLHCPHYSTREE pTree, int fFromLeft, PAVLHCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLHCPHYSNODECORE) RTAvlHCPhysGetBestFit(PAVLHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(PAVLHCPHYSNODECORE) RTAvlHCPhysRemoveBestFit(PAVLHCPHYSTREE ppTree, RTHCPHYS Key, bool fAbove);
+RTDECL(int) RTAvlHCPhysDestroy(PAVLHCPHYSTREE pTree, PAVLHCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+/** AVL tree of RTGCPHYSes.
+ * @{
+ */
+
+/**
+ * AVL 'pointer' type for the relative offset pointer scheme.
+ */
+typedef struct _AVLGCPhysNodeCore *AVLGCPHYSPTR;
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLGCPhysNodeCore
+{
+ /** Offset to the left leaf node, relative to this field. */
+ AVLGCPHYSPTR pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ AVLGCPHYSPTR pRight;
+ /** Key value. */
+ RTGCPHYS Key;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLGCPHYSNODECORE, *PAVLGCPHYSNODECORE;
+
+/** A offset base tree with RTGCPHYS keys. */
+typedef AVLGCPHYSPTR AVLGCPHYSTREE;
+/** Pointer to an offset base tree with RTGCPHYS keys. */
+typedef AVLGCPHYSTREE *PAVLGCPHYSTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLGCPHYSTREE *PPAVLGCPHYSNODECORE;
+
+/** Callback function for RTAvlGCPhysDoWithAll() and RTAvlGCPhysDestroy(). */
+typedef DECLCALLBACK(int) AVLGCPHYSCALLBACK(PAVLGCPHYSNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlGCPhysDoWithAll() and RTAvlGCPhysDestroy(). */
+typedef AVLGCPHYSCALLBACK *PAVLGCPHYSCALLBACK;
+
+RTDECL(bool) RTAvlGCPhysInsert(PAVLGCPHYSTREE pTree, PAVLGCPHYSNODECORE pNode);
+RTDECL(PAVLGCPHYSNODECORE) RTAvlGCPhysRemove(PAVLGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(PAVLGCPHYSNODECORE) RTAvlGCPhysGet(PAVLGCPHYSTREE pTree, RTGCPHYS Key);
+RTDECL(int) RTAvlGCPhysDoWithAll(PAVLGCPHYSTREE pTree, int fFromLeft, PAVLGCPHYSCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLGCPHYSNODECORE) RTAvlGCPhysGetBestFit(PAVLGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(PAVLGCPHYSNODECORE) RTAvlGCPhysRemoveBestFit(PAVLGCPHYSTREE ppTree, RTGCPHYS Key, bool fAbove);
+RTDECL(int) RTAvlGCPhysDestroy(PAVLGCPHYSTREE pTree, PAVLGCPHYSCALLBACK pfnCallBack, void *pvParam);
+
+/** @} */
+
+
+/** AVL tree of RTFOFF ranges.
+ * @{
+ */
+
+/**
+ * AVL Core node.
+ */
+typedef struct _AVLRFOFFNodeCore
+{
+ /** First key value in the range (inclusive). */
+ RTFOFF Key;
+ /** Last key value in the range (inclusive). */
+ RTFOFF KeyLast;
+ /** Offset to the left leaf node, relative to this field. */
+ struct _AVLRFOFFNodeCore *pLeft;
+ /** Offset to the right leaf node, relative to this field. */
+ struct _AVLRFOFFNodeCore *pRight;
+ /** Height of this tree: max(height(left), height(right)) + 1 */
+ unsigned char uchHeight;
+} AVLRFOFFNODECORE, *PAVLRFOFFNODECORE;
+
+/** A pointer based tree with RTFOFF ranges. */
+typedef PAVLRFOFFNODECORE AVLRFOFFTREE;
+/** Pointer to a pointer based tree with RTFOFF ranges. */
+typedef AVLRFOFFTREE *PAVLRFOFFTREE;
+
+/** Pointer to an internal tree pointer.
+ * In this case it's a pointer to a relative offset. */
+typedef AVLRFOFFTREE *PPAVLRFOFFNODECORE;
+
+/** Callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */
+typedef DECLCALLBACK(int) AVLRFOFFCALLBACK(PAVLRFOFFNODECORE pNode, void *pvUser);
+/** Pointer to callback function for RTAvlrGCPtrDoWithAll() and RTAvlrGCPtrDestroy(). */
+typedef AVLRFOFFCALLBACK *PAVLRFOFFCALLBACK;
+
+RTDECL(bool) RTAvlrFileOffsetInsert( PAVLRFOFFTREE pTree, PAVLRFOFFNODECORE pNode);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetRemove( PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetGet( PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetGetBestFit( PAVLRFOFFTREE pTree, RTFOFF Key, bool fAbove);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetRangeGet( PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetRangeRemove( PAVLRFOFFTREE pTree, RTFOFF Key);
+RTDECL(int) RTAvlrFileOffsetDoWithAll( PAVLRFOFFTREE pTree, int fFromLeft, PAVLRFOFFCALLBACK pfnCallBack, void *pvParam);
+RTDECL(int) RTAvlrFileOffsetDestroy( PAVLRFOFFTREE pTree, PAVLRFOFFCALLBACK pfnCallBack, void *pvParam);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetGetRoot( PAVLRFOFFTREE pTree);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetGetLeft( PAVLRFOFFNODECORE pNode);
+RTDECL(PAVLRFOFFNODECORE) RTAvlrFileOffsetGetRight( PAVLRFOFFNODECORE pNode);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/base64.h b/include/iprt/base64.h
new file mode 100644
index 00000000..b52f48e1
--- /dev/null
+++ b/include/iprt/base64.h
@@ -0,0 +1,119 @@
+/** @file
+ * IPRT - Base64, MIME content transfer encoding.
+ */
+
+/*
+ * 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 ___iprt_base64_h
+#define ___iprt_base64_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_base64 RTBase64 - Base64, MIME content transfer encoding.
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @def RTBASE64_EOL_SIZE
+ * The size of the end-of-line marker. */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define RTBASE64_EOL_SIZE (sizeof("\r\n") - 1)
+#else
+# define RTBASE64_EOL_SIZE (sizeof("\n") - 1)
+#endif
+
+/**
+ * Calculates the decoded data size for a Base64 encoded string.
+ *
+ * @returns The length in bytes. -1 if the encoding is bad.
+ *
+ * @param pszString The Base64 encoded string.
+ * @param ppszEnd If not NULL, this will point to the first char
+ * following the Base64 encoded text block. If
+ * NULL the entire string is assumed to be Base64.
+ */
+RTDECL(ssize_t) RTBase64DecodedSize(const char *pszString, char **ppszEnd);
+
+/**
+ * Decodes a Base64 encoded string into the buffer supplied by the caller.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. pcbActual will not
+ * be set, nor will ppszEnd.
+ * @retval VERR_INVALID_BASE64_ENCODING if the encoding is wrong.
+ *
+ * @param pszString The Base64 string. Whether the entire string or
+ * just the start of the string is in Base64 depends
+ * on whether ppszEnd is specified or not.
+ * @param pvData Where to store the decoded data.
+ * @param cbData The size of the output buffer that pvData points to.
+ * @param pcbActual Where to store the actual number of bytes returned.
+ * Optional.
+ * @param ppszEnd Indicates that the string may contain other stuff
+ * after the Base64 encoded data when not NULL. Will
+ * be set to point to the first char that's not part of
+ * the encoding. If NULL the entire string must be part
+ * of the Base64 encoded data.
+ */
+RTDECL(int) RTBase64Decode(const char *pszString, void *pvData, size_t cbData, size_t *pcbActual, char **ppszEnd);
+
+/**
+ * Calculates the length of the Base64 encoding of a given number of bytes of
+ * data.
+ *
+ * This will assume line breaks every 64 chars. A RTBase64EncodedLengthEx
+ * function can be added if closer control over the output is found to be
+ * required.
+ *
+ * @returns The Base64 string length.
+ * @param cbData The number of bytes to encode.
+ */
+RTDECL(size_t) RTBase64EncodedLength(size_t cbData);
+
+/**
+ * Encodes the specifed data into a Base64 string, the caller supplies the
+ * output buffer.
+ *
+ * This will make the same assumptions about line breaks and EOL size as
+ * RTBase64EncodedLength() does. A RTBase64EncodeEx function can be added if
+ * more strict control over the output formatting is found necessary.
+ *
+ * @returns IRPT status code.
+ * @retval VERR_BUFFER_OVERFLOW if the output buffer is too small. The buffer
+ * may contain an invalid Base64 string.
+ *
+ * @param pvData The data to encode.
+ * @param cbData The number of bytes to encode.
+ * @param pszBuf Where to put the Base64 string.
+ * @param cbBuf The size of the output buffer, including the terminator.
+ * @param pcchActual The actual number of characters returned.
+ */
+RTDECL(int) RTBase64Encode(const void *pvData, size_t cbData, char *pszBuf, size_t cbBuf, size_t *pcchActual);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/buildconfig.h b/include/iprt/buildconfig.h
new file mode 100644
index 00000000..9e4a9c57
--- /dev/null
+++ b/include/iprt/buildconfig.h
@@ -0,0 +1,125 @@
+/** @file
+ * IPRT - Build Configuration Information
+ */
+
+/*
+ * 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 ___iprt_buildconfig_h
+#define ___iprt_buildconfig_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_buildconfig RTBldCfg - Build Configuration Information
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Gets the source code management revision of the IPRT build.
+ * @returns Source code management revision number.
+ */
+RTDECL(uint32_t) RTBldCfgRevision(void);
+
+/**
+ * Gets the source code management revision of the IPRT build.
+ * @returns Read only string containing the revision number.
+ */
+RTDECL(const char *) RTBldCfgRevisionStr(void);
+
+/**
+ * Gets the product version string.
+ *
+ * This will be a string on the form "x.y.z[_string]".
+ *
+ * @returns Read only version string.
+ *
+ * @remarks This is a build time configuration thing that the product using IPRT
+ * will set. It is therefore not any IPRT version, but rather the
+ * version of that product.
+ */
+RTDECL(const char *) RTBldCfgVersion(void);
+
+/**
+ * Gets the major product version number.
+ * @returns Major product version number.
+ * @remarks See RTBldCfgVersion.
+ */
+RTDECL(uint32_t) RTBldCfgVersionMajor(void);
+
+/**
+ * Gets the minor product version number.
+ * @returns Minor product version number.
+ * @remarks See RTBldCfgVersion.
+ */
+RTDECL(uint32_t) RTBldCfgVersionMinor(void);
+
+/**
+ * Gets the product build number.
+ * @returns Product build number.
+ * @remarks See RTBldCfgVersion.
+ */
+RTDECL(uint32_t) RTBldCfgVersionBuild(void);
+
+/**
+ * Gets the build target name.
+ *
+ * @returns Read only build target string.
+ */
+RTDECL(const char *) RTBldCfgTarget(void);
+
+/**
+ * Gets the build target architecture name.
+ *
+ * @returns Read only build target architecture string.
+ */
+RTDECL(const char *) RTBldCfgTargetArch(void);
+
+/**
+ * Gets the build target-dot-architecture name.
+ *
+ * @returns Read only build target-dot-architecture string.
+ */
+RTDECL(const char *) RTBldCfgTargetDotArch(void);
+
+/**
+ * Gets the build type name.
+ *
+ * @returns Read only build type string.
+ */
+RTDECL(const char *) RTBldCfgType(void);
+
+/**
+ * Gets the name of the compiler used for building IPRT.
+ *
+ * @returns Read only compiler name.
+ */
+RTDECL(const char *) RTBldCfgCompiler(void);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/cdefs.h b/include/iprt/cdefs.h
new file mode 100644
index 00000000..db52defa
--- /dev/null
+++ b/include/iprt/cdefs.h
@@ -0,0 +1,2500 @@
+/** @file
+ * IPRT - Common C and C++ 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 ___iprt_cdefs_h
+#define ___iprt_cdefs_h
+
+
+/** @defgroup grp_rt_cdefs IPRT Common Definitions and Macros
+ * @{
+ */
+
+/*
+ * Include sys/cdefs.h if present, if not define the stuff we need.
+ */
+#ifdef HAVE_SYS_CDEFS_H
+# if defined(RT_ARCH_LINUX) && defined(__KERNEL__)
+# error "oops"
+# endif
+# include <sys/cdefs.h>
+#else
+
+/** @def RT_C_DECLS_BEGIN
+ * Used to start a block of function declarations which are shared
+ * between C and C++ program.
+ */
+
+/** @def RT_C_DECLS_END
+ * Used to end a block of function declarations which are shared
+ * between C and C++ program.
+ */
+
+# if defined(__cplusplus)
+# define RT_C_DECLS_BEGIN extern "C" {
+# define RT_C_DECLS_END }
+# else
+# define RT_C_DECLS_BEGIN
+# define RT_C_DECLS_END
+# endif
+
+#endif
+
+
+/*
+ * Shut up DOXYGEN warnings and guide it properly thru the code.
+ */
+#ifdef DOXYGEN_RUNNING
+# define __AMD64__
+# define __X86__
+# define RT_ARCH_AMD64
+# define RT_ARCH_X86
+# define IN_RING0
+# define IN_RING3
+# define IN_RC
+# define IN_RC
+# define IN_RT_RC
+# define IN_RT_R0
+# define IN_RT_R3
+# define IN_RT_STATIC
+# define RT_STRICT
+# define RT_NO_STRICT
+# define RT_LOCK_STRICT
+# define RT_LOCK_NO_STRICT
+# define RT_LOCK_STRICT_ORDER
+# define RT_LOCK_NO_STRICT_ORDER
+# define Breakpoint
+# define RT_NO_DEPRECATED_MACROS
+# define RT_EXCEPTIONS_ENABLED
+# define RT_BIG_ENDIAN
+# define RT_LITTLE_ENDIAN
+# define RT_COMPILER_GROKS_64BIT_BITFIELDS
+# define RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+# define RT_NO_VISIBILITY_HIDDEN
+#endif /* DOXYGEN_RUNNING */
+
+/** @def RT_ARCH_X86
+ * Indicates that we're compiling for the X86 architecture.
+ */
+
+/** @def RT_ARCH_AMD64
+ * Indicates that we're compiling for the AMD64 architecture.
+ */
+
+/** @def RT_ARCH_SPARC
+ * Indicates that we're compiling for the SPARC V8 architecture (32-bit).
+ */
+
+/** @def RT_ARCH_SPARC64
+ * Indicates that we're compiling for the SPARC V9 architecture (64-bit).
+ */
+#if !defined(RT_ARCH_X86) \
+ && !defined(RT_ARCH_AMD64) \
+ && !defined(RT_ARCH_SPARC) \
+ && !defined(RT_ARCH_SPARC64) \
+ && !defined(RT_ARCH_ARM)
+# if defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || defined(__AMD64__)
+# define RT_ARCH_AMD64
+# elif defined(__i386__) || defined(_M_IX86) || defined(__X86__)
+# define RT_ARCH_X86
+# elif defined(__sparcv9)
+# define RT_ARCH_SPARC64
+# elif defined(__sparc__)
+# define RT_ARCH_SPARC
+# elif defined(__arm__) || defined(__arm32__)
+# define RT_ARCH_ARM
+# else /* PORTME: append test for new archs. */
+# error "Check what predefined macros your compiler uses to indicate architecture."
+# endif
+/* PORTME: append new archs checks. */
+#elif defined(RT_ARCH_X86) && defined(RT_ARCH_AMD64)
+# error "Both RT_ARCH_X86 and RT_ARCH_AMD64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_X86) && defined(RT_ARCH_SPARC)
+# error "Both RT_ARCH_X86 and RT_ARCH_SPARC cannot be defined at the same time!"
+#elif defined(RT_ARCH_X86) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_X86 and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_AMD64) && defined(RT_ARCH_SPARC)
+# error "Both RT_ARCH_AMD64 and RT_ARCH_SPARC cannot be defined at the same time!"
+#elif defined(RT_ARCH_AMD64) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_AMD64 and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_SPARC) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_SPARC and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_AMD64)
+# error "Both RT_ARCH_ARM and RT_ARCH_AMD64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_X86)
+# error "Both RT_ARCH_ARM and RT_ARCH_X86 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_SPARC64)
+# error "Both RT_ARCH_ARM and RT_ARCH_SPARC64 cannot be defined at the same time!"
+#elif defined(RT_ARCH_ARM) && defined(RT_ARCH_SPARC)
+# error "Both RT_ARCH_ARM and RT_ARCH_SPARC cannot be defined at the same time!"
+#endif
+
+
+/** @def __X86__
+ * Indicates that we're compiling for the X86 architecture.
+ * @deprecated
+ */
+
+/** @def __AMD64__
+ * Indicates that we're compiling for the AMD64 architecture.
+ * @deprecated
+ */
+#if !defined(__X86__) && !defined(__AMD64__) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
+# if defined(RT_ARCH_AMD64)
+# define __AMD64__
+# elif defined(RT_ARCH_X86)
+# define __X86__
+# else
+# error "Check what predefined macros your compiler uses to indicate architecture."
+# endif
+#elif defined(__X86__) && defined(__AMD64__)
+# error "Both __X86__ and __AMD64__ cannot be defined at the same time!"
+#elif defined(__X86__) && !defined(RT_ARCH_X86)
+# error "__X86__ without RT_ARCH_X86!"
+#elif defined(__AMD64__) && !defined(RT_ARCH_AMD64)
+# error "__AMD64__ without RT_ARCH_AMD64!"
+#endif
+
+/** @def RT_BIG_ENDIAN
+ * Defined if the architecture is big endian. */
+/** @def RT_LITTLE_ENDIAN
+ * Defined if the architecture is little endian. */
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) || defined(RT_ARCH_ARM)
+# define RT_LITTLE_ENDIAN
+#elif defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+# define RT_BIG_ENDIAN
+#else
+# error "PORTME: architecture endianess"
+#endif
+#if defined(RT_BIG_ENDIAN) && defined(RT_LITTLE_ENDIAN)
+# error "Both RT_BIG_ENDIAN and RT_LITTLE_ENDIAN are defined"
+#endif
+
+
+/** @def IN_RING0
+ * Used to indicate that we're compiling code which is running
+ * in Ring-0 Host Context.
+ */
+
+/** @def IN_RING3
+ * Used to indicate that we're compiling code which is running
+ * in Ring-3 Host Context.
+ */
+
+/** @def IN_RC
+ * Used to indicate that we're compiling code which is running
+ * in the Raw-mode Context (implies R0).
+ */
+#if !defined(IN_RING3) && !defined(IN_RING0) && !defined(IN_RC) && !defined(IN_RC)
+# error "You must define which context the compiled code should run in; IN_RING3, IN_RING0 or IN_RC"
+#endif
+#if (defined(IN_RING3) && (defined(IN_RING0) || defined(IN_RC)) ) \
+ || (defined(IN_RING0) && (defined(IN_RING3) || defined(IN_RC)) ) \
+ || (defined(IN_RC) && (defined(IN_RING3) || defined(IN_RING0)) )
+# error "Only one of the IN_RING3, IN_RING0, IN_RC defines should be defined."
+#endif
+
+
+/** @def ARCH_BITS
+ * Defines the bit count of the current context.
+ */
+#if !defined(ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64)
+# define ARCH_BITS 64
+# else
+# define ARCH_BITS 32
+# endif
+#endif
+
+/** @def HC_ARCH_BITS
+ * Defines the host architecture bit count.
+ */
+#if !defined(HC_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifndef IN_RC
+# define HC_ARCH_BITS ARCH_BITS
+# else
+# define HC_ARCH_BITS 32
+# endif
+#endif
+
+/** @def GC_ARCH_BITS
+ * Defines the guest architecture bit count.
+ */
+#if !defined(GC_ARCH_BITS) && !defined(DOXYGEN_RUNNING)
+# ifdef VBOX_WITH_64_BITS_GUESTS
+# define GC_ARCH_BITS 64
+# else
+# define GC_ARCH_BITS 32
+# endif
+#endif
+
+/** @def R3_ARCH_BITS
+ * Defines the host ring-3 architecture bit count.
+ */
+#if !defined(R3_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifdef IN_RING3
+# define R3_ARCH_BITS ARCH_BITS
+# else
+# define R3_ARCH_BITS HC_ARCH_BITS
+# endif
+#endif
+
+/** @def R0_ARCH_BITS
+ * Defines the host ring-0 architecture bit count.
+ */
+#if !defined(R0_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifdef IN_RING0
+# define R0_ARCH_BITS ARCH_BITS
+# else
+# define R0_ARCH_BITS HC_ARCH_BITS
+# endif
+#endif
+
+/** @def GC_ARCH_BITS
+ * Defines the guest architecture bit count.
+ */
+#if !defined(GC_ARCH_BITS) || defined(DOXYGEN_RUNNING)
+# ifdef IN_RC
+# define GC_ARCH_BITS ARCH_BITS
+# else
+# define GC_ARCH_BITS 32
+# endif
+#endif
+
+
+/** @def CTXTYPE
+ * Declare a type differently in GC, R3 and R0.
+ *
+ * @param GCType The GC type.
+ * @param R3Type The R3 type.
+ * @param R0Type The R0 type.
+ * @remark For pointers used only in one context use RCPTRTYPE(), R3R0PTRTYPE(), R3PTRTYPE() or R0PTRTYPE().
+ */
+#ifdef IN_RC
+# define CTXTYPE(GCType, R3Type, R0Type) GCType
+#elif defined(IN_RING3)
+# define CTXTYPE(GCType, R3Type, R0Type) R3Type
+#else
+# define CTXTYPE(GCType, R3Type, R0Type) R0Type
+#endif
+
+/** @def RCPTRTYPE
+ * Declare a pointer which is used in the raw mode context but appears in structure(s) used by
+ * both HC and RC. The main purpose is to make sure structures have the same
+ * size when built for different architectures.
+ *
+ * @param RCType The RC type.
+ */
+#define RCPTRTYPE(RCType) CTXTYPE(RCType, RTRCPTR, RTRCPTR)
+
+/** @def R3R0PTRTYPE
+ * Declare a pointer which is used in HC, is explicitly valid in ring 3 and 0,
+ * but appears in structure(s) used by both HC and GC. The main purpose is to
+ * make sure structures have the same size when built for different architectures.
+ *
+ * @param R3R0Type The R3R0 type.
+ * @remarks This used to be called HCPTRTYPE.
+ */
+#define R3R0PTRTYPE(R3R0Type) CTXTYPE(RTHCPTR, R3R0Type, R3R0Type)
+
+/** @def R3PTRTYPE
+ * Declare a pointer which is used in R3 but appears in structure(s) used by
+ * both HC and GC. The main purpose is to make sure structures have the same
+ * size when built for different architectures.
+ *
+ * @param R3Type The R3 type.
+ */
+#define R3PTRTYPE(R3Type) CTXTYPE(RTHCUINTPTR, R3Type, RTHCUINTPTR)
+
+/** @def R0PTRTYPE
+ * Declare a pointer which is used in R0 but appears in structure(s) used by
+ * both HC and GC. The main purpose is to make sure structures have the same
+ * size when built for different architectures.
+ *
+ * @param R0Type The R0 type.
+ */
+#define R0PTRTYPE(R0Type) CTXTYPE(RTHCUINTPTR, RTHCUINTPTR, R0Type)
+
+/** @def CTXSUFF
+ * Adds the suffix of the current context to the passed in
+ * identifier name. The suffix is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param var Identifier name.
+ * @deprecated Use CTX_SUFF. Do NOT use this for new code.
+ */
+/** @def OTHERCTXSUFF
+ * Adds the suffix of the other context to the passed in
+ * identifier name. The suffix is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param var Identifier name.
+ * @deprecated Use CTX_SUFF. Do NOT use this for new code.
+ */
+#ifdef IN_RC
+# define CTXSUFF(var) var##GC
+# define OTHERCTXSUFF(var) var##HC
+#else
+# define CTXSUFF(var) var##HC
+# define OTHERCTXSUFF(var) var##GC
+#endif
+
+/** @def CTXALLSUFF
+ * Adds the suffix of the current context to the passed in
+ * identifier name. The suffix is R3, R0 or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param var Identifier name.
+ * @deprecated Use CTX_SUFF. Do NOT use this for new code.
+ */
+#ifdef IN_RC
+# define CTXALLSUFF(var) var##GC
+#elif defined(IN_RING0)
+# define CTXALLSUFF(var) var##R0
+#else
+# define CTXALLSUFF(var) var##R3
+#endif
+
+/** @def CTX_SUFF
+ * Adds the suffix of the current context to the passed in
+ * identifier name. The suffix is R3, R0 or RC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param var Identifier name.
+ *
+ * @remark This will replace CTXALLSUFF and CTXSUFF before long.
+ */
+#ifdef IN_RC
+# define CTX_SUFF(var) var##RC
+#elif defined(IN_RING0)
+# define CTX_SUFF(var) var##R0
+#else
+# define CTX_SUFF(var) var##R3
+#endif
+
+/** @def CTX_SUFF_Z
+ * Adds the suffix of the current context to the passed in
+ * identifier name, combining RC and R0 into RZ.
+ * The suffix thus is R3 or RZ.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param var Identifier name.
+ *
+ * @remark This will replace CTXALLSUFF and CTXSUFF before long.
+ */
+#ifdef IN_RING3
+# define CTX_SUFF_Z(var) var##R3
+#else
+# define CTX_SUFF_Z(var) var##RZ
+#endif
+
+
+/** @def CTXMID
+ * Adds the current context as a middle name of an identifier name
+ * The middle name is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param first First name.
+ * @param last Surname.
+ */
+/** @def OTHERCTXMID
+ * Adds the other context as a middle name of an identifier name
+ * The middle name is HC or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param first First name.
+ * @param last Surname.
+ * @deprecated use CTX_MID or CTX_MID_Z
+ */
+#ifdef IN_RC
+# define CTXMID(first, last) first##GC##last
+# define OTHERCTXMID(first, last) first##HC##last
+#else
+# define CTXMID(first, last) first##HC##last
+# define OTHERCTXMID(first, last) first##GC##last
+#endif
+
+/** @def CTXALLMID
+ * Adds the current context as a middle name of an identifier name.
+ * The middle name is R3, R0 or GC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param first First name.
+ * @param last Surname.
+ * @deprecated use CTX_MID or CTX_MID_Z
+ */
+#ifdef IN_RC
+# define CTXALLMID(first, last) first##GC##last
+#elif defined(IN_RING0)
+# define CTXALLMID(first, last) first##R0##last
+#else
+# define CTXALLMID(first, last) first##R3##last
+#endif
+
+/** @def CTX_MID
+ * Adds the current context as a middle name of an identifier name.
+ * The middle name is R3, R0 or RC.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param first First name.
+ * @param last Surname.
+ */
+#ifdef IN_RC
+# define CTX_MID(first, last) first##RC##last
+#elif defined(IN_RING0)
+# define CTX_MID(first, last) first##R0##last
+#else
+# define CTX_MID(first, last) first##R3##last
+#endif
+
+/** @def CTX_MID_Z
+ * Adds the current context as a middle name of an identifier name, combining RC
+ * and R0 into RZ.
+ * The middle name thus is either R3 or RZ.
+ *
+ * This is macro should only be used in shared code to avoid a forest of ifdefs.
+ * @param first First name.
+ * @param last Surname.
+ */
+#ifdef IN_RING3
+# define CTX_MID_Z(first, last) first##R3##last
+#else
+# define CTX_MID_Z(first, last) first##RZ##last
+#endif
+
+
+/** @def R3STRING
+ * A macro which in GC and R0 will return a dummy string while in R3 it will return
+ * the parameter.
+ *
+ * This is typically used to wrap description strings in structures shared
+ * between R3, R0 and/or GC. The intention is to avoid the \#ifdef IN_RING3 mess.
+ *
+ * @param pR3String The R3 string. Only referenced in R3.
+ * @see R0STRING and GCSTRING
+ */
+#ifdef IN_RING3
+# define R3STRING(pR3String) (pR3String)
+#else
+# define R3STRING(pR3String) ("<R3_STRING>")
+#endif
+
+/** @def R0STRING
+ * A macro which in GC and R3 will return a dummy string while in R0 it will return
+ * the parameter.
+ *
+ * This is typically used to wrap description strings in structures shared
+ * between R3, R0 and/or GC. The intention is to avoid the \#ifdef IN_RING0 mess.
+ *
+ * @param pR0String The R0 string. Only referenced in R0.
+ * @see R3STRING and GCSTRING
+ */
+#ifdef IN_RING0
+# define R0STRING(pR0String) (pR0String)
+#else
+# define R0STRING(pR0String) ("<R0_STRING>")
+#endif
+
+/** @def RCSTRING
+ * A macro which in R3 and R0 will return a dummy string while in RC it will return
+ * the parameter.
+ *
+ * This is typically used to wrap description strings in structures shared
+ * between R3, R0 and/or RC. The intention is to avoid the \#ifdef IN_RC mess.
+ *
+ * @param pRCString The RC string. Only referenced in RC.
+ * @see R3STRING, R0STRING
+ */
+#ifdef IN_RC
+# define RCSTRING(pRCString) (pRCString)
+#else
+# define RCSTRING(pRCString) ("<RC_STRING>")
+#endif
+
+
+/** @def RT_NOTHING
+ * A macro that expands to nothing.
+ * This is primarily intended as a dummy argument for macros to avoid the
+ * undefined behavior passing empty arguments to an macro (ISO C90 and C++98,
+ * gcc v4.4 warns about it).
+ */
+#define RT_NOTHING
+
+/** @def RT_GCC_EXTENSION
+ * Macro for shutting up GCC warnings about using language extensions. */
+#ifdef __GNUC__
+# define RT_GCC_EXTENSION __extension__
+#else
+# define RT_GCC_EXTENSION
+#endif
+
+/** @def RT_COMPILER_GROKS_64BIT_BITFIELDS
+ * Macro that is defined if the compiler understands 64-bit bitfields. */
+#if !defined(RT_OS_OS2) || (!defined(__IBMC__) && !defined(__IBMCPP__))
+# define RT_COMPILER_GROKS_64BIT_BITFIELDS
+#endif
+
+/** @def RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+ * Macro that is defined if the compiler implements long double as the
+ * IEEE extended precision floating. */
+#if (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) && !defined(RT_OS_WINDOWS)
+# define RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+#endif
+
+
+/** @def RT_EXCEPTIONS_ENABLED
+ * Defined when C++ exceptions are enabled.
+ */
+#if !defined(RT_EXCEPTIONS_ENABLED) \
+ && defined(__cplusplus) \
+ && ( (defined(_MSC_VER) && defined(_CPPUNWIND)) \
+ || (defined(__GNUC__) && defined(__EXCEPTIONS)))
+# define RT_EXCEPTIONS_ENABLED
+#endif
+
+/** @def RT_NO_THROW
+ * How to express that a function doesn't throw C++ exceptions
+ * and the compiler can thus save itself the bother of trying
+ * to catch any of them. Put this between the closing parenthesis
+ * and the semicolon in function prototypes (and implementation if C++).
+ */
+#ifdef RT_EXCEPTIONS_ENABLED
+# define RT_NO_THROW throw()
+#else
+# define RT_NO_THROW
+#endif
+
+/** @def RT_THROW
+ * How to express that a method or function throws a type of exceptions. Some
+ * compilers does not want this kind of information and will warning about it.
+ *
+ * @param type The type exception.
+ *
+ * @remarks If the actual throwing is done from the header, enclose it by
+ * \#ifdef RT_EXCEPTIONS_ENABLED ... \#else ... \#endif so the header
+ * compiles cleanly without exceptions enabled.
+ *
+ * Do NOT use this for the actual throwing of exceptions!
+ */
+#ifdef RT_EXCEPTIONS_ENABLED
+# ifdef _MSC_VER
+# if _MSC_VER >= 1310
+# define RT_THROW(type)
+# else
+# define RT_THROW(type) throw(type)
+# endif
+# else
+# define RT_THROW(type) throw(type)
+# endif
+#else
+# define RT_THROW(type)
+#endif
+
+/** @def RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
+ * Indicates that the "hidden" visibility attribute can be used (GCC) */
+#if defined(__GNUC__)
+# if __GNUC__ >= 4 && !defined(RT_OS_OS2) && !defined(RT_OS_WINDOWS)
+# define RT_GCC_SUPPORTS_VISIBILITY_HIDDEN
+# endif
+#endif
+
+/** @def RTCALL
+ * The standard calling convention for the Runtime interfaces.
+ */
+#ifdef _MSC_VER
+# define RTCALL __cdecl
+#elif defined(RT_OS_OS2)
+# define RTCALL __cdecl
+#elif defined(__GNUC__) && defined(IN_RING0) && defined(RT_ARCH_X86) /** @todo consider dropping IN_RING0 here. */
+# define RTCALL __attribute__((cdecl,regparm(0))) /* regparm(0) deals with -mregparm=x use in the linux kernel. */
+#else
+# define RTCALL
+#endif
+
+/** @def DECLEXPORT
+ * How to declare an exported function.
+ * @param type The return type of the function declaration.
+ */
+#if defined(_MSC_VER) || defined(RT_OS_OS2)
+# define DECLEXPORT(type) __declspec(dllexport) type
+#elif defined(RT_USE_VISIBILITY_DEFAULT)
+# define DECLEXPORT(type) __attribute__((visibility("default"))) type
+#else
+# define DECLEXPORT(type) type
+#endif
+
+/** @def DECLIMPORT
+ * How to declare an imported function.
+ * @param type The return type of the function declaration.
+ */
+#if defined(_MSC_VER) || (defined(RT_OS_OS2) && !defined(__IBMC__) && !defined(__IBMCPP__))
+# define DECLIMPORT(type) __declspec(dllimport) type
+#else
+# define DECLIMPORT(type) type
+#endif
+
+/** @def DECLHIDDEN
+ * How to declare a non-exported function or variable.
+ * @param type The return type of the function or the data type of the variable.
+ */
+#if !defined(RT_GCC_SUPPORTS_VISIBILITY_HIDDEN) || defined(RT_NO_VISIBILITY_HIDDEN)
+# define DECLHIDDEN(type) type
+#else
+# define DECLHIDDEN(type) __attribute__((visibility("hidden"))) type
+#endif
+
+/** @def DECL_HIDDEN_CONST
+ * Workaround for g++ warnings when applying the hidden attribute to a const
+ * definition. Use DECLHIDDEN for the declaration.
+ * @param a_Type The return type of the function or the data type of
+ * the variable.
+ */
+#if defined(__cplusplus) && defined(__GNUC__)
+# define DECL_HIDDEN_CONST(a_Type) a_Type
+#else
+# define DECL_HIDDEN_CONST(a_Type) DECLHIDDEN(a_Type)
+#endif
+
+/** @def DECL_INVALID
+ * How to declare a function not available for linking in the current context.
+ * The purpose is to create compile or like time errors when used. This isn't
+ * possible on all platforms.
+ * @param type The return type of the function.
+ */
+#if defined(_MSC_VER)
+# define DECL_INVALID(type) __declspec(dllimport) type __stdcall
+#elif defined(__GNUC__) && defined(__cplusplus)
+# define DECL_INVALID(type) extern "C++" type
+#else
+# define DECL_INVALID(type) type
+#endif
+
+/** @def DECLASM
+ * How to declare an internal assembly function.
+ * @param type The return type of the function declaration.
+ */
+#ifdef __cplusplus
+# if defined(_MSC_VER) || defined(RT_OS_OS2)
+# define DECLASM(type) extern "C" type __cdecl
+# elif defined(__GNUC__) && defined(RT_ARCH_X86)
+# define DECLASM(type) extern "C" type __attribute__((cdecl,regparm(0)))
+# else
+# define DECLASM(type) extern "C" type
+# endif
+#else
+# if defined(_MSC_VER) || defined(RT_OS_OS2)
+# define DECLASM(type) type __cdecl
+# elif defined(__GNUC__) && defined(RT_ARCH_X86)
+# define DECLASM(type) type __attribute__((cdecl,regparm(0)))
+# else
+# define DECLASM(type) type
+# endif
+#endif
+
+/** @def DECLASMTYPE
+ * How to declare an internal assembly function type.
+ * @param type The return type of the function.
+ */
+# if defined(_MSC_VER) || defined(RT_OS_OS2)
+# define DECLASMTYPE(type) type __cdecl
+#else
+# define DECLASMTYPE(type) type
+#endif
+
+/** @def DECLNORETURN
+ * How to declare a function which does not return.
+ * @note: This macro can be combined with other macros, for example
+ * @code
+ * EMR3DECL(DECLNORETURN(void)) foo(void);
+ * @endcode
+ */
+#ifdef _MSC_VER
+# define DECLNORETURN(type) __declspec(noreturn) type
+#elif defined(__GNUC__)
+# define DECLNORETURN(type) __attribute__((noreturn)) type
+#else
+# define DECLNORETURN(type) type
+#endif
+
+/** @def DECLWEAK
+ * How to declare a variable which is not necessarily resolved at
+ * runtime.
+ * @note: This macro can be combined with other macros, for example
+ * @code
+ * EMR3DECL(DECLWEAK(int)) foo;
+ * @endcode
+ */
+#if defined(__GNUC__)
+# define DECLWEAK(type) type __attribute__((weak))
+#else
+# define DECLWEAK(type) type
+#endif
+
+/** @def DECLCALLBACK
+ * How to declare an call back function type.
+ * @param type The return type of the function declaration.
+ */
+#define DECLCALLBACK(type) type RTCALL
+
+/** @def DECLCALLBACKPTR
+ * How to declare an call back function pointer.
+ * @param type The return type of the function declaration.
+ * @param name The name of the variable member.
+ */
+#define DECLCALLBACKPTR(type, name) type (RTCALL * name)
+
+/** @def DECLCALLBACKMEMBER
+ * How to declare an call back function pointer member.
+ * @param type The return type of the function declaration.
+ * @param name The name of the struct/union/class member.
+ */
+#define DECLCALLBACKMEMBER(type, name) type (RTCALL * name)
+
+/** @def DECLR3CALLBACKMEMBER
+ * How to declare an call back function pointer member - R3 Ptr.
+ * @param type The return type of the function declaration.
+ * @param name The name of the struct/union/class member.
+ * @param args The argument list enclosed in parentheses.
+ */
+#ifdef IN_RING3
+# define DECLR3CALLBACKMEMBER(type, name, args) type (RTCALL * name) args
+#else
+# define DECLR3CALLBACKMEMBER(type, name, args) RTR3PTR name
+#endif
+
+/** @def DECLRCCALLBACKMEMBER
+ * How to declare an call back function pointer member - RC Ptr.
+ * @param type The return type of the function declaration.
+ * @param name The name of the struct/union/class member.
+ * @param args The argument list enclosed in parentheses.
+ */
+#ifdef IN_RC
+# define DECLRCCALLBACKMEMBER(type, name, args) type (RTCALL * name) args
+#else
+# define DECLRCCALLBACKMEMBER(type, name, args) RTRCPTR name
+#endif
+
+/** @def DECLR0CALLBACKMEMBER
+ * How to declare an call back function pointer member - R0 Ptr.
+ * @param type The return type of the function declaration.
+ * @param name The name of the struct/union/class member.
+ * @param args The argument list enclosed in parentheses.
+ */
+#ifdef IN_RING0
+# define DECLR0CALLBACKMEMBER(type, name, args) type (RTCALL * name) args
+#else
+# define DECLR0CALLBACKMEMBER(type, name, args) RTR0PTR name
+#endif
+
+/** @def DECLINLINE
+ * How to declare a function as inline.
+ * @param type The return type of the function declaration.
+ * @remarks Don't use this macro on C++ methods.
+ */
+#ifdef __GNUC__
+# define DECLINLINE(type) static __inline__ type
+#elif defined(__cplusplus)
+# define DECLINLINE(type) inline type
+#elif defined(_MSC_VER)
+# define DECLINLINE(type) _inline type
+#elif defined(__IBMC__)
+# define DECLINLINE(type) _Inline type
+#else
+# define DECLINLINE(type) inline type
+#endif
+
+
+/** @def DECL_FORCE_INLINE
+ * How to declare a function as inline and try convince the compiler to always
+ * inline it regardless of optimization switches.
+ * @param type The return type of the function declaration.
+ * @remarks Use sparsely and with care. Don't use this macro on C++ methods.
+ */
+#ifdef __GNUC__
+# define DECL_FORCE_INLINE(type) __attribute__((__always_inline__)) DECLINLINE(type)
+#elif defined(_MSC_VER)
+# define DECL_FORCE_INLINE(type) __forceinline type
+#else
+# define DECL_FORCE_INLINE(type) DECLINLINE(type)
+#endif
+
+
+/** @def DECL_NO_INLINE
+ * How to declare a function telling the compiler not to inline it.
+ * @param scope The function scope, static or RT_NOTHING.
+ * @param type The return type of the function declaration.
+ * @remarks Don't use this macro on C++ methods.
+ */
+#ifdef __GNUC__
+# define DECL_NO_INLINE(scope,type) __attribute__((noinline)) scope type
+#elif defined(_MSC_VER)
+# define DECL_NO_INLINE(scope,type) __declspec(noinline) scope type
+#else
+# define DECL_NO_INLINE(scope,type) scope type
+#endif
+
+
+/** @def IN_RT_STATIC
+ * Used to indicate whether we're linking against a static IPRT
+ * or not. The IPRT symbols will be declared as hidden (if
+ * supported). Note that this define has no effect without setting
+ * IN_RT_R0, IN_RT_R3 or IN_RT_RC indicators are set first.
+ */
+
+/** @def IN_RT_R0
+ * Used to indicate whether we're inside the same link module as
+ * the HC Ring-0 Runtime Library.
+ */
+/** @def RTR0DECL(type)
+ * Runtime Library HC Ring-0 export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_RT_R0
+# ifdef IN_RT_STATIC
+# define RTR0DECL(type) DECLHIDDEN(type) RTCALL
+# else
+# define RTR0DECL(type) DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTR0DECL(type) DECLIMPORT(type) RTCALL
+#endif
+
+/** @def IN_RT_R3
+ * Used to indicate whether we're inside the same link module as
+ * the HC Ring-3 Runtime Library.
+ */
+/** @def RTR3DECL(type)
+ * Runtime Library HC Ring-3 export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_RT_R3
+# ifdef IN_RT_STATIC
+# define RTR3DECL(type) DECLHIDDEN(type) RTCALL
+# else
+# define RTR3DECL(type) DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTR3DECL(type) DECLIMPORT(type) RTCALL
+#endif
+
+/** @def IN_RT_RC
+ * Used to indicate whether we're inside the same link module as the raw-mode
+ * context (RC) runtime library.
+ */
+/** @def RTRCDECL(type)
+ * Runtime Library raw-mode context export or import declaration.
+ * @param type The return type of the function declaration.
+ */
+#ifdef IN_RT_RC
+# ifdef IN_RT_STATIC
+# define RTRCDECL(type) DECLHIDDEN(type) RTCALL
+# else
+# define RTRCDECL(type) DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTRCDECL(type) DECLIMPORT(type) RTCALL
+#endif
+
+/** @def RTDECL(type)
+ * Runtime Library export or import declaration.
+ * Functions declared using this macro exists in all contexts.
+ * @param type The return type of the function declaration.
+ */
+#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
+# ifdef IN_RT_STATIC
+# define RTDECL(type) DECLHIDDEN(type) RTCALL
+# else
+# define RTDECL(type) DECLEXPORT(type) RTCALL
+# endif
+#else
+# define RTDECL(type) DECLIMPORT(type) RTCALL
+#endif
+
+/** @def RTDATADECL(type)
+ * Runtime Library export or import declaration.
+ * Data declared using this macro exists in all contexts.
+ * @param type The return type of the function declaration.
+ */
+#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
+# ifdef IN_RT_STATIC
+# define RTDATADECL(type) DECLHIDDEN(type)
+# else
+# define RTDATADECL(type) DECLEXPORT(type)
+# endif
+#else
+# define RTDATADECL(type) DECLIMPORT(type)
+#endif
+
+/** @def RT_DECL_CLASS
+ * Declares an class living in the runtime.
+ */
+#if defined(IN_RT_R3) || defined(IN_RT_RC) || defined(IN_RT_R0)
+# ifdef IN_RT_STATIC
+# define RT_DECL_CLASS
+# else
+# define RT_DECL_CLASS DECLEXPORT_CLASS
+# endif
+#else
+# define RT_DECL_CLASS DECLIMPORT_CLASS
+#endif
+
+
+/** @def RT_NOCRT
+ * Symbol name wrapper for the No-CRT bits.
+ *
+ * In order to coexist in the same process as other CRTs, we need to
+ * decorate the symbols such that they don't conflict the ones in the
+ * other CRTs. The result of such conflicts / duplicate symbols can
+ * confuse the dynamic loader on Unix like systems.
+ *
+ * Define RT_WITHOUT_NOCRT_WRAPPERS to drop the wrapping.
+ * Define RT_WITHOUT_NOCRT_WRAPPER_ALIASES to drop the aliases to the
+ * wrapped names.
+ */
+/** @def RT_NOCRT_STR
+ * Same as RT_NOCRT only it'll return a double quoted string of the result.
+ */
+#ifndef RT_WITHOUT_NOCRT_WRAPPERS
+# define RT_NOCRT(name) nocrt_ ## name
+# define RT_NOCRT_STR(name) "nocrt_" # name
+#else
+# define RT_NOCRT(name) name
+# define RT_NOCRT_STR(name) #name
+#endif
+
+
+
+/** @def RT_LIKELY
+ * Give the compiler a hint that an expression is very likely to hold true.
+ *
+ * Some compilers support explicit branch prediction so that the CPU backend
+ * can hint the processor and also so that code blocks can be reordered such
+ * that the predicted path sees a more linear flow, thus improving cache
+ * behaviour, etc.
+ *
+ * IPRT provides the macros RT_LIKELY() and RT_UNLIKELY() as a way to utilize
+ * this compiler feature when present.
+ *
+ * A few notes about the usage:
+ *
+ * - Generally, use RT_UNLIKELY() with error condition checks (unless you
+ * have some _strong_ reason to do otherwise, in which case document it),
+ * and/or RT_LIKELY() with success condition checks, assuming you want
+ * to optimize for the success path.
+ *
+ * - Other than that, if you don't know the likelihood of a test succeeding
+ * from empirical or other 'hard' evidence, don't make predictions unless
+ * you happen to be a Dirk Gently.
+ *
+ * - These macros are meant to be used in places that get executed a lot. It
+ * is wasteful to make predictions in code that is executed rarely (e.g.
+ * at subsystem initialization time) as the basic block reordering that this
+ * affects can often generate larger code.
+ *
+ * - Note that RT_SUCCESS() and RT_FAILURE() already makes use of RT_LIKELY()
+ * and RT_UNLIKELY(). Should you wish for prediction free status checks,
+ * use the RT_SUCCESS_NP() and RT_FAILURE_NP() macros instead.
+ *
+ *
+ * @returns the boolean result of the expression.
+ * @param expr The expression that's very likely to be true.
+ * @see RT_UNLIKELY
+ */
+/** @def RT_UNLIKELY
+ * Give the compiler a hint that an expression is highly unlikely to hold true.
+ *
+ * See the usage instructions give in the RT_LIKELY() docs.
+ *
+ * @returns the boolean result of the expression.
+ * @param expr The expression that's very unlikely to be true.
+ * @see RT_LIKELY
+ */
+#if defined(__GNUC__)
+# if __GNUC__ >= 3 && !defined(FORTIFY_RUNNING)
+# define RT_LIKELY(expr) __builtin_expect(!!(expr), 1)
+# define RT_UNLIKELY(expr) __builtin_expect(!!(expr), 0)
+# else
+# define RT_LIKELY(expr) (expr)
+# define RT_UNLIKELY(expr) (expr)
+# endif
+#else
+# define RT_LIKELY(expr) (expr)
+# define RT_UNLIKELY(expr) (expr)
+#endif
+
+
+/** @def RT_STR
+ * Returns the argument as a string constant.
+ * @param str Argument to stringify. */
+#define RT_STR(str) #str
+/** @def RT_XSTR
+ * Returns the expanded argument as a string.
+ * @param str Argument to expand and stringy. */
+#define RT_XSTR(str) RT_STR(str)
+
+/** @def RT_CONCAT
+ * Concatenate the expanded arguments without any extra spaces in between.
+ *
+ * @param a The first part.
+ * @param b The second part.
+ */
+#define RT_CONCAT(a,b) RT_CONCAT_HLP(a,b)
+/** RT_CONCAT helper, don't use. */
+#define RT_CONCAT_HLP(a,b) a##b
+
+/** @def RT_CONCAT
+ * Concatenate the expanded arguments without any extra spaces in between.
+ *
+ * @param a The 1st part.
+ * @param b The 2nd part.
+ * @param c The 3rd part.
+ */
+#define RT_CONCAT3(a,b,c) RT_CONCAT3_HLP(a,b,c)
+/** RT_CONCAT3 helper, don't use. */
+#define RT_CONCAT3_HLP(a,b,c) a##b##c
+
+/** @def RT_CONCAT
+ * Concatenate the expanded arguments without any extra spaces in between.
+ *
+ * @param a The 1st part.
+ * @param b The 2nd part.
+ * @param c The 3rd part.
+ */
+#define RT_CONCAT4(a,b,c,d) RT_CONCAT4_HLP(a,b,c,d)
+/** RT_CONCAT4 helper, don't use. */
+#define RT_CONCAT4_HLP(a,b,c,d) a##b##c##d
+
+/**
+ * String constant tuple - string constant, strlen(string constant).
+ *
+ * @param a_szConst String constant.
+ */
+#define RT_STR_TUPLE(a_szConst) a_szConst, (sizeof(a_szConst) - 1)
+
+
+/** @def RT_BIT
+ * Convert a bit number into an integer bitmask (unsigned).
+ * @param bit The bit number.
+ */
+#define RT_BIT(bit) ( 1U << (bit) )
+
+/** @def RT_BIT_32
+ * Convert a bit number into a 32-bit bitmask (unsigned).
+ * @param bit The bit number.
+ */
+#define RT_BIT_32(bit) ( UINT32_C(1) << (bit) )
+
+/** @def RT_BIT_64
+ * Convert a bit number into a 64-bit bitmask (unsigned).
+ * @param bit The bit number.
+ */
+#define RT_BIT_64(bit) ( UINT64_C(1) << (bit) )
+
+/** @def RT_ALIGN
+ * Align macro.
+ * @param u Value to align.
+ * @param uAlignment The alignment. Power of two!
+ *
+ * @remark Be extremely careful when using this macro with type which sizeof != sizeof int.
+ * When possible use any of the other RT_ALIGN_* macros. And when that's not
+ * possible, make 101% sure that uAlignment is specified with a right sized type.
+ *
+ * Specifying an unsigned 32-bit alignment constant with a 64-bit value will give
+ * you a 32-bit return value!
+ *
+ * In short: Don't use this macro. Use RT_ALIGN_T() instead.
+ */
+#define RT_ALIGN(u, uAlignment) ( ((u) + ((uAlignment) - 1)) & ~((uAlignment) - 1) )
+
+/** @def RT_ALIGN_T
+ * Align macro.
+ * @param u Value to align.
+ * @param uAlignment The alignment. Power of two!
+ * @param type Integer type to use while aligning.
+ * @remark This macro is the preferred alignment macro, it doesn't have any of the pitfalls RT_ALIGN has.
+ */
+#define RT_ALIGN_T(u, uAlignment, type) ( ((type)(u) + ((uAlignment) - 1)) & ~(type)((uAlignment) - 1) )
+
+/** @def RT_ALIGN_32
+ * Align macro for a 32-bit value.
+ * @param u32 Value to align.
+ * @param uAlignment The alignment. Power of two!
+ */
+#define RT_ALIGN_32(u32, uAlignment) RT_ALIGN_T(u32, uAlignment, uint32_t)
+
+/** @def RT_ALIGN_64
+ * Align macro for a 64-bit value.
+ * @param u64 Value to align.
+ * @param uAlignment The alignment. Power of two!
+ */
+#define RT_ALIGN_64(u64, uAlignment) RT_ALIGN_T(u64, uAlignment, uint64_t)
+
+/** @def RT_ALIGN_Z
+ * Align macro for size_t.
+ * @param cb Value to align.
+ * @param uAlignment The alignment. Power of two!
+ */
+#define RT_ALIGN_Z(cb, uAlignment) RT_ALIGN_T(cb, uAlignment, size_t)
+
+/** @def RT_ALIGN_P
+ * Align macro for pointers.
+ * @param pv Value to align.
+ * @param uAlignment The alignment. Power of two!
+ */
+#define RT_ALIGN_P(pv, uAlignment) RT_ALIGN_PT(pv, uAlignment, void *)
+
+/** @def RT_ALIGN_PT
+ * Align macro for pointers with type cast.
+ * @param u Value to align.
+ * @param uAlignment The alignment. Power of two!
+ * @param CastType The type to cast the result to.
+ */
+#define RT_ALIGN_PT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, uintptr_t) )
+
+/** @def RT_ALIGN_R3PT
+ * Align macro for ring-3 pointers with type cast.
+ * @param u Value to align.
+ * @param uAlignment The alignment. Power of two!
+ * @param CastType The type to cast the result to.
+ */
+#define RT_ALIGN_R3PT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, RTR3UINTPTR) )
+
+/** @def RT_ALIGN_R0PT
+ * Align macro for ring-0 pointers with type cast.
+ * @param u Value to align.
+ * @param uAlignment The alignment. Power of two!
+ * @param CastType The type to cast the result to.
+ */
+#define RT_ALIGN_R0PT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, RTR0UINTPTR) )
+
+/** @def RT_ALIGN_GCPT
+ * Align macro for GC pointers with type cast.
+ * @param u Value to align.
+ * @param uAlignment The alignment. Power of two!
+ * @param CastType The type to cast the result to.
+ */
+#define RT_ALIGN_GCPT(u, uAlignment, CastType) ( (CastType)RT_ALIGN_T(u, uAlignment, RTGCUINTPTR) )
+
+
+/** @def RT_OFFSETOF
+ * Our own special offsetof() variant, returns a signed result.
+ *
+ * This differs from the usual offsetof() in that it's not relying on builtin
+ * compiler stuff and thus can use variables in arrays the structure may
+ * contain. This is useful to determine the sizes of structures ending
+ * with a variable length field.
+ *
+ * @returns offset into the structure of the specified member. signed.
+ * @param type Structure type.
+ * @param member Member.
+ */
+#define RT_OFFSETOF(type, member) ( (int)(uintptr_t)&( ((type *)(void *)0)->member) )
+
+/** @def RT_UOFFSETOF
+ * Our own special offsetof() variant, returns an unsigned result.
+ *
+ * This differs from the usual offsetof() in that it's not relying on builtin
+ * compiler stuff and thus can use variables in arrays the structure may
+ * contain. This is useful to determine the sizes of structures ending
+ * with a variable length field.
+ *
+ * @returns offset into the structure of the specified member. unsigned.
+ * @param type Structure type.
+ * @param member Member.
+ */
+#define RT_UOFFSETOF(type, member) ( (uintptr_t)&( ((type *)(void *)0)->member) )
+
+/** @def RT_OFFSETOF_ADD
+ * RT_OFFSETOF with an addend.
+ *
+ * @returns offset into the structure of the specified member. signed.
+ * @param type Structure type.
+ * @param member Member.
+ * @param addend The addend to add to the offset.
+ */
+#define RT_OFFSETOF_ADD(type, member, addend) ( (int)RT_UOFFSETOF_ADD(type, member, addend) )
+
+/** @def RT_UOFFSETOF_ADD
+ * RT_UOFFSETOF with an addend.
+ *
+ * @returns offset into the structure of the specified member. signed.
+ * @param type Structure type.
+ * @param member Member.
+ * @param addend The addend to add to the offset.
+ */
+#define RT_UOFFSETOF_ADD(type, member, addend) ( (uintptr_t)&( ((type *)(void *)(uintptr_t)(addend))->member) )
+
+/** @def RT_SIZEOFMEMB
+ * Get the size of a structure member.
+ *
+ * @returns size of the structure member.
+ * @param type Structure type.
+ * @param member Member.
+ */
+#define RT_SIZEOFMEMB(type, member) ( sizeof(((type *)(void *)0)->member) )
+
+/** @def RT_FROM_MEMBER
+ * Convert a pointer to a structure member into a pointer to the structure.
+ *
+ * @returns pointer to the structure.
+ * @param pMem Pointer to the member.
+ * @param Type Structure type.
+ * @param Member Member name.
+ */
+#define RT_FROM_MEMBER(pMem, Type, Member) ( (Type *) ((uint8_t *)(void *)(pMem) - RT_UOFFSETOF(Type, Member)) )
+
+/** @def RT_FROM_CPP_MEMBER
+ * Same as RT_FROM_MEMBER except it avoids the annoying g++ warnings about
+ * invalid access to non-static data member of NULL object.
+ *
+ * @returns pointer to the structure.
+ * @param pMem Pointer to the member.
+ * @param Type Structure type.
+ * @param Member Member name.
+ *
+ * @remarks Using the __builtin_offsetof does not shut up the compiler.
+ */
+#if defined(__GNUC__) && defined(__cplusplus)
+# define RT_FROM_CPP_MEMBER(pMem, Type, Member) \
+ ( (Type *) ((uintptr_t)(pMem) - (uintptr_t)&((Type *)0x1000)->Member + 0x1000U) )
+#else
+# define RT_FROM_CPP_MEMBER(pMem, Type, Member) RT_FROM_MEMBER(pMem, Type, Member)
+#endif
+
+/** @def RT_ELEMENTS
+ * Calculates the number of elements in a statically sized array.
+ * @returns Element count.
+ * @param aArray Array in question.
+ */
+#define RT_ELEMENTS(aArray) ( sizeof(aArray) / sizeof((aArray)[0]) )
+
+/**
+ * Checks if the value is a power of two.
+ *
+ * @returns true if power of two, false if not.
+ * @param uVal The value to test.
+ * @remarks 0 is a power of two.
+ * @see VERR_NOT_POWER_OF_TWO
+ */
+#define RT_IS_POWER_OF_TWO(uVal) ( ((uVal) & ((uVal) - 1)) == 0)
+
+#ifdef RT_OS_OS2
+/* Undefine RT_MAX since there is an unfortunate clash with the max
+ resource type define in os2.h. */
+# undef RT_MAX
+#endif
+
+/** @def RT_MAX
+ * Finds the maximum value.
+ * @returns The higher of the two.
+ * @param Value1 Value 1
+ * @param Value2 Value 2
+ */
+#define RT_MAX(Value1, Value2) ( (Value1) >= (Value2) ? (Value1) : (Value2) )
+
+/** @def RT_MIN
+ * Finds the minimum value.
+ * @returns The lower of the two.
+ * @param Value1 Value 1
+ * @param Value2 Value 2
+ */
+#define RT_MIN(Value1, Value2) ( (Value1) <= (Value2) ? (Value1) : (Value2) )
+
+/** @def RT_CLAMP
+ * Clamps the value to minimum and maximum values.
+ * @returns The clamped value.
+ * @param Value The value to check.
+ * @param Min Minimum value.
+ * @param Max Maximum value.
+ */
+#define RT_CLAMP(Value, Min, Max) ( (Value) > (Max) ? (Max) : (Value) < (Min) ? (Min) : (Value) )
+
+/** @def RT_ABS
+ * Get the absolute (non-negative) value.
+ * @returns The absolute value of Value.
+ * @param Value The value.
+ */
+#define RT_ABS(Value) ( (Value) >= 0 ? (Value) : -(Value) )
+
+/** @def RT_BOOL
+ * Turn non-zero/zero into true/false
+ * @returns The resulting boolean value.
+ * @param Value The value.
+ */
+#define RT_BOOL(Value) ( !!(Value) )
+
+/** @def RT_LO_U8
+ * Gets the low uint8_t of a uint16_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_LO_U8(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint16_t)); (uint8_t)(a); })
+#else
+# define RT_LO_U8(a) ( (uint8_t)(a) )
+#endif
+/** @def RT_HI_U16
+ * Gets the high uint16_t of a uint32_t or something equivalent). */
+#ifdef __GNUC__
+# define RT_HI_U8(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint16_t)); (uint8_t)((a) >> 8); })
+#else
+# define RT_HI_U8(a) ( (uint8_t)((a) >> 8) )
+#endif
+
+/** @def RT_LO_U16
+ * Gets the low uint16_t of a uint32_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_LO_U16(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)(a); })
+#else
+# define RT_LO_U16(a) ( (uint32_t)(a) )
+#endif
+/** @def RT_HI_U16
+ * Gets the high uint16_t of a uint32_t or something equivalent). */
+#ifdef __GNUC__
+# define RT_HI_U16(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint32_t)); (uint16_t)((a) >> 16); })
+#else
+# define RT_HI_U16(a) ( (uint16_t)((a) >> 16) )
+#endif
+
+/** @def RT_LO_U32
+ * Gets the low uint32_t of a uint64_t or something equivalent. */
+#ifdef __GNUC__
+# define RT_LO_U32(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)(a); })
+#else
+# define RT_LO_U32(a) ( (uint32_t)(a) )
+#endif
+/** @def RT_HI_U32
+ * Gets the high uint32_t of a uint64_t or something equivalent). */
+#ifdef __GNUC__
+# define RT_HI_U32(a) __extension__ ({ AssertCompile(sizeof((a)) == sizeof(uint64_t)); (uint32_t)((a) >> 32); })
+#else
+# define RT_HI_U32(a) ( (uint32_t)((a) >> 32) )
+#endif
+
+/** @def RT_BYTE1
+ * Gets the first byte of something. */
+#define RT_BYTE1(a) ( (a) & 0xff )
+/** @def RT_BYTE2
+ * Gets the second byte of something. */
+#define RT_BYTE2(a) ( ((a) >> 8) & 0xff )
+/** @def RT_BYTE3
+ * Gets the second byte of something. */
+#define RT_BYTE3(a) ( ((a) >> 16) & 0xff )
+/** @def RT_BYTE4
+ * Gets the fourth byte of something. */
+#define RT_BYTE4(a) ( ((a) >> 24) & 0xff )
+/** @def RT_BYTE5
+ * Gets the fifth byte of something. */
+#define RT_BYTE5(a) ( ((a) >> 32) & 0xff )
+/** @def RT_BYTE6
+ * Gets the sixth byte of something. */
+#define RT_BYTE6(a) ( ((a) >> 40) & 0xff )
+/** @def RT_BYTE7
+ * Gets the seventh byte of something. */
+#define RT_BYTE7(a) ( ((a) >> 48) & 0xff )
+/** @def RT_BYTE8
+ * Gets the eight byte of something. */
+#define RT_BYTE8(a) ( ((a) >> 56) & 0xff )
+
+
+/** @def RT_LODWORD
+ * Gets the low dword (=uint32_t) of something.
+ * @deprecated Use RT_LO_U32. */
+#define RT_LODWORD(a) ( (uint32_t)(a) )
+/** @def RT_HIDWORD
+ * Gets the high dword (=uint32_t) of a 64-bit of something.
+ * @deprecated Use RT_HI_U32. */
+#define RT_HIDWORD(a) ( (uint32_t)((a) >> 32) )
+
+/** @def RT_LOWORD
+ * Gets the low word (=uint16_t) of something.
+ * @deprecated Use RT_LO_U16. */
+#define RT_LOWORD(a) ( (a) & 0xffff )
+/** @def RT_HIWORD
+ * Gets the high word (=uint16_t) of a 32-bit something.
+ * @deprecated Use RT_HI_U16. */
+#define RT_HIWORD(a) ( (a) >> 16 )
+
+/** @def RT_LOBYTE
+ * Gets the low byte of something.
+ * @deprecated Use RT_LO_U8. */
+#define RT_LOBYTE(a) ( (a) & 0xff )
+/** @def RT_HIBYTE
+ * Gets the low byte of a 16-bit something.
+ * @deprecated Use RT_HI_U8. */
+#define RT_HIBYTE(a) ( (a) >> 8 )
+
+
+/** @def RT_MAKE_U64
+ * Constructs a uint64_t value from two uint32_t values.
+ */
+#define RT_MAKE_U64(Lo, Hi) ( (uint64_t)((uint32_t)(Hi)) << 32 | (uint32_t)(Lo) )
+
+/** @def RT_MAKE_U64_FROM_U16
+ * Constructs a uint64_t value from four uint16_t values.
+ */
+#define RT_MAKE_U64_FROM_U16(w0, w1, w2, w3) \
+ ((uint64_t)( (uint64_t)((uint16_t)(w3)) << 48 \
+ | (uint64_t)((uint16_t)(w2)) << 32 \
+ | (uint32_t)((uint16_t)(w1)) << 16 \
+ | (uint16_t)(w0) ))
+
+/** @def RT_MAKE_U64_FROM_U8
+ * Constructs a uint64_t value from eight uint8_t values.
+ */
+#define RT_MAKE_U64_FROM_U8(b0, b1, b2, b3, b4, b5, b6, b7) \
+ ((uint64_t)( (uint64_t)((uint8_t)(b7)) << 56 \
+ | (uint64_t)((uint8_t)(b6)) << 48 \
+ | (uint64_t)((uint8_t)(b5)) << 40 \
+ | (uint64_t)((uint8_t)(b4)) << 32 \
+ | (uint32_t)((uint8_t)(b3)) << 24 \
+ | (uint32_t)((uint8_t)(b2)) << 16 \
+ | (uint16_t)((uint8_t)(b1)) << 8 \
+ | (uint8_t)(b0) ))
+
+/** @def RT_MAKE_U32
+ * Constructs a uint32_t value from two uint16_t values.
+ */
+#define RT_MAKE_U32(Lo, Hi) \
+ ((uint32_t)( (uint32_t)((uint16_t)(Hi)) << 16 \
+ | (uint16_t)(Lo) ))
+
+/** @def RT_MAKE_U32_FROM_U8
+ * Constructs a uint32_t value from four uint8_t values.
+ */
+#define RT_MAKE_U32_FROM_U8(b0, b1, b2, b3) \
+ ((uint32_t)( (uint32_t)((uint8_t)(b3)) << 24 \
+ | (uint32_t)((uint8_t)(b2)) << 16 \
+ | (uint16_t)((uint8_t)(b1)) << 8 \
+ | (uint8_t)(b0) ))
+
+/** @def RT_MAKE_U16
+ * Constructs a uint16_t value from two uint8_t values.
+ */
+#define RT_MAKE_U16(Lo, Hi) \
+ ((uint16_t)( (uint16_t)((uint8_t)(Hi)) << 8 \
+ | (uint8_t)(Lo) ))
+
+
+/** @def RT_BSWAP_U64
+ * Reverses the byte order of an uint64_t value. */
+#if 0
+# define RT_BSWAP_U64(u64) RT_BSWAP_U64_C(u64)
+#elif defined(__GNUC__)
+# define RT_BSWAP_U64(u64) (__builtin_constant_p((u64)) \
+ ? RT_BSWAP_U64_C(u64) : ASMByteSwapU64(u64))
+#else
+# define RT_BSWAP_U64(u64) ASMByteSwapU64(u64)
+#endif
+
+/** @def RT_BSWAP_U32
+ * Reverses the byte order of an uint32_t value. */
+#if 0
+# define RT_BSWAP_U32(u32) RT_BSWAP_U32_C(u32)
+#elif defined(__GNUC__)
+# define RT_BSWAP_U32(u32) (__builtin_constant_p((u32)) \
+ ? RT_BSWAP_U32_C(u32) : ASMByteSwapU32(u32))
+#else
+# define RT_BSWAP_U32(u32) ASMByteSwapU32(u32)
+#endif
+
+/** @def RT_BSWAP_U16
+ * Reverses the byte order of an uint16_t value. */
+#if 0
+# define RT_BSWAP_U16(u16) RT_BSWAP_U16_C(u16)
+#elif defined(__GNUC__)
+# define RT_BSWAP_U16(u16) (__builtin_constant_p((u16)) \
+ ? RT_BSWAP_U16_C(u16) : ASMByteSwapU16(u16))
+#else
+# define RT_BSWAP_U16(u16) ASMByteSwapU16(u16)
+#endif
+
+
+/** @def RT_BSWAP_U64_C
+ * Reverses the byte order of an uint64_t constant. */
+#define RT_BSWAP_U64_C(u64) RT_MAKE_U64(RT_BSWAP_U32_C((u64) >> 32), RT_BSWAP_U32_C((u64) & 0xffffffff))
+
+/** @def RT_BSWAP_U32_C
+ * Reverses the byte order of an uint32_t constant. */
+#define RT_BSWAP_U32_C(u32) RT_MAKE_U32_FROM_U8(RT_BYTE4(u32), RT_BYTE3(u32), RT_BYTE2(u32), RT_BYTE1(u32))
+
+/** @def RT_BSWAP_U16_C
+ * Reverses the byte order of an uint16_t constant. */
+#define RT_BSWAP_U16_C(u16) RT_MAKE_U16(RT_HIBYTE(u16), RT_LOBYTE(u16))
+
+
+/** @def RT_H2LE_U64
+ * Converts an uint64_t value from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U64(u64) RT_BSWAP_U64(u64)
+#else
+# define RT_H2LE_U64(u64) (u64)
+#endif
+
+/** @def RT_H2LE_U64_C
+ * Converts an uint64_t constant from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U64_C(u64) RT_BSWAP_U64_C(u64)
+#else
+# define RT_H2LE_U64_C(u64) (u64)
+#endif
+
+/** @def RT_H2LE_U32
+ * Converts an uint32_t value from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U32(u32) RT_BSWAP_U32(u32)
+#else
+# define RT_H2LE_U32(u32) (u32)
+#endif
+
+/** @def RT_H2LE_U32_C
+ * Converts an uint32_t constant from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U32_C(u32) RT_BSWAP_U32_C(u32)
+#else
+# define RT_H2LE_U32_C(u32) (u32)
+#endif
+
+/** @def RT_H2LE_U16
+ * Converts an uint16_t value from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U16(u16) RT_BSWAP_U16(u16)
+#else
+# define RT_H2LE_U16(u16) (u16)
+#endif
+
+/** @def RT_H2LE_U16_C
+ * Converts an uint16_t constant from host to little endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2LE_U16_C(u16) RT_BSWAP_U16_C(u16)
+#else
+# define RT_H2LE_U16_C(u16) (u16)
+#endif
+
+
+/** @def RT_LE2H_U64
+ * Converts an uint64_t value from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U64(u64) RT_BSWAP_U64(u64)
+#else
+# define RT_LE2H_U64(u64) (u64)
+#endif
+
+/** @def RT_LE2H_U64_C
+ * Converts an uint64_t constant from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U64_C(u64) RT_BSWAP_U64_C(u64)
+#else
+# define RT_LE2H_U64_C(u64) (u64)
+#endif
+
+/** @def RT_LE2H_U32
+ * Converts an uint32_t value from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U32(u32) RT_BSWAP_U32(u32)
+#else
+# define RT_LE2H_U32(u32) (u32)
+#endif
+
+/** @def RT_LE2H_U32_C
+ * Converts an uint32_t constant from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U32_C(u32) RT_BSWAP_U32_C(u32)
+#else
+# define RT_LE2H_U32_C(u32) (u32)
+#endif
+
+/** @def RT_LE2H_U16
+ * Converts an uint16_t value from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U16(u16) RT_BSWAP_U16(u16)
+#else
+# define RT_LE2H_U16(u16) (u16)
+#endif
+
+/** @def RT_LE2H_U16_C
+ * Converts an uint16_t constant from little endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_LE2H_U16_C(u16) RT_BSWAP_U16_C(u16)
+#else
+# define RT_LE2H_U16_C(u16) (u16)
+#endif
+
+
+/** @def RT_H2BE_U64
+ * Converts an uint64_t value from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U64(u64) (u64)
+#else
+# define RT_H2BE_U64(u64) RT_BSWAP_U64(u64)
+#endif
+
+/** @def RT_H2BE_U64_C
+ * Converts an uint64_t constant from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U64_C(u64) (u64)
+#else
+# define RT_H2BE_U64_C(u64) RT_BSWAP_U64_C(u64)
+#endif
+
+/** @def RT_H2BE_U32
+ * Converts an uint32_t value from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U32(u32) (u32)
+#else
+# define RT_H2BE_U32(u32) RT_BSWAP_U32(u32)
+#endif
+
+/** @def RT_H2BE_U32_C
+ * Converts an uint32_t constant from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U32_C(u32) (u32)
+#else
+# define RT_H2BE_U32_C(u32) RT_BSWAP_U32_C(u32)
+#endif
+
+/** @def RT_H2BE_U16
+ * Converts an uint16_t value from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U16(u16) (u16)
+#else
+# define RT_H2BE_U16(u16) RT_BSWAP_U16(u16)
+#endif
+
+/** @def RT_H2BE_U16_C
+ * Converts an uint16_t constant from host to big endian byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_H2BE_U16_C(u16) (u16)
+#else
+# define RT_H2BE_U16_C(u16) RT_BSWAP_U16_C(u16)
+#endif
+
+/** @def RT_BE2H_U64
+ * Converts an uint64_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U64(u64) (u64)
+#else
+# define RT_BE2H_U64(u64) RT_BSWAP_U64(u64)
+#endif
+
+/** @def RT_BE2H_U64
+ * Converts an uint64_t constant from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U64_C(u64) (u64)
+#else
+# define RT_BE2H_U64_C(u64) RT_BSWAP_U64_C(u64)
+#endif
+
+/** @def RT_BE2H_U32
+ * Converts an uint32_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U32(u32) (u32)
+#else
+# define RT_BE2H_U32(u32) RT_BSWAP_U32(u32)
+#endif
+
+/** @def RT_BE2H_U32_C
+ * Converts an uint32_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U32_C(u32) (u32)
+#else
+# define RT_BE2H_U32_C(u32) RT_BSWAP_U32_C(u32)
+#endif
+
+/** @def RT_BE2H_U16
+ * Converts an uint16_t value from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U16(u16) (u16)
+#else
+# define RT_BE2H_U16(u16) RT_BSWAP_U16(u16)
+#endif
+
+/** @def RT_BE2H_U16_C
+ * Converts an uint16_t constant from big endian to host byte order. */
+#ifdef RT_BIG_ENDIAN
+# define RT_BE2H_U16_C(u16) (u16)
+#else
+# define RT_BE2H_U16_C(u16) RT_BSWAP_U16_C(u16)
+#endif
+
+
+/** @def RT_H2N_U64
+ * Converts an uint64_t value from host to network byte order. */
+#define RT_H2N_U64(u64) RT_H2BE_U64(u64)
+
+/** @def RT_H2N_U64_C
+ * Converts an uint64_t constant from host to network byte order. */
+#define RT_H2N_U64_C(u64) RT_H2BE_U64_C(u64)
+
+/** @def RT_H2N_U32
+ * Converts an uint32_t value from host to network byte order. */
+#define RT_H2N_U32(u32) RT_H2BE_U32(u32)
+
+/** @def RT_H2N_U32_C
+ * Converts an uint32_t constant from host to network byte order. */
+#define RT_H2N_U32_C(u32) RT_H2BE_U32_C(u32)
+
+/** @def RT_H2N_U16
+ * Converts an uint16_t value from host to network byte order. */
+#define RT_H2N_U16(u16) RT_H2BE_U16(u16)
+
+/** @def RT_H2N_U16_C
+ * Converts an uint16_t constant from host to network byte order. */
+#define RT_H2N_U16_C(u16) RT_H2BE_U16_C(u16)
+
+/** @def RT_N2H_U64
+ * Converts an uint64_t value from network to host byte order. */
+#define RT_N2H_U64(u64) RT_BE2H_U64(u64)
+
+/** @def RT_N2H_U64_C
+ * Converts an uint64_t constant from network to host byte order. */
+#define RT_N2H_U64_C(u64) RT_BE2H_U64_C(u64)
+
+/** @def RT_N2H_U32
+ * Converts an uint32_t value from network to host byte order. */
+#define RT_N2H_U32(u32) RT_BE2H_U32(u32)
+
+/** @def RT_N2H_U32_C
+ * Converts an uint32_t constant from network to host byte order. */
+#define RT_N2H_U32_C(u32) RT_BE2H_U32_C(u32)
+
+/** @def RT_N2H_U16
+ * Converts an uint16_t value from network to host byte order. */
+#define RT_N2H_U16(u16) RT_BE2H_U16(u16)
+
+/** @def RT_N2H_U16_C
+ * Converts an uint16_t value from network to host byte order. */
+#define RT_N2H_U16_C(u16) RT_BE2H_U16_C(u16)
+
+
+/*
+ * The BSD sys/param.h + machine/param.h file is a major source of
+ * namespace pollution. Kill off some of the worse ones unless we're
+ * compiling kernel code.
+ */
+#if defined(RT_OS_DARWIN) \
+ && !defined(KERNEL) \
+ && !defined(RT_NO_BSD_PARAM_H_UNDEFING) \
+ && ( defined(_SYS_PARAM_H_) || defined(_I386_PARAM_H_) )
+/* sys/param.h: */
+# undef PSWP
+# undef PVM
+# undef PINOD
+# undef PRIBO
+# undef PVFS
+# undef PZERO
+# undef PSOCK
+# undef PWAIT
+# undef PLOCK
+# undef PPAUSE
+# undef PUSER
+# undef PRIMASK
+# undef MINBUCKET
+# undef MAXALLOCSAVE
+# undef FSHIFT
+# undef FSCALE
+
+/* i386/machine.h: */
+# undef ALIGN
+# undef ALIGNBYTES
+# undef DELAY
+# undef STATUS_WORD
+# undef USERMODE
+# undef BASEPRI
+# undef MSIZE
+# undef CLSIZE
+# undef CLSIZELOG2
+#endif
+
+/** @def NIL_OFFSET
+ * NIL offset.
+ * Whenever we use offsets instead of pointers to save space and relocation effort
+ * NIL_OFFSET shall be used as the equivalent to NULL.
+ */
+#define NIL_OFFSET (~0U)
+
+/** @def NOREF
+ * Keeps the compiler from bitching about an unused parameter.
+ */
+#define NOREF(var) (void)(var)
+
+/** @def RT_BREAKPOINT
+ * Emit a debug breakpoint instruction.
+ *
+ * @remarks In the x86/amd64 gnu world we add a nop instruction after the int3
+ * to force gdb to remain at the int3 source line.
+ * @remarks The L4 kernel will try make sense of the breakpoint, thus the jmp on
+ * x86/amd64.
+ */
+#ifdef __GNUC__
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+# if !defined(__L4ENV__)
+# define RT_BREAKPOINT() __asm__ __volatile__("int $3\n\tnop\n\t")
+# else
+# define RT_BREAKPOINT() __asm__ __volatile__("int3; jmp 1f; 1:\n\t")
+# endif
+# elif defined(RT_ARCH_SPARC64)
+# define RT_BREAKPOINT() __asm__ __volatile__("illtrap 0\n\t") /** @todo Sparc64: this is just a wild guess. */
+# elif defined(RT_ARCH_SPARC)
+# define RT_BREAKPOINT() __asm__ __volatile__("unimp 0\n\t") /** @todo Sparc: this is just a wild guess (same as Sparc64, just different name). */
+# endif
+#endif
+#ifdef _MSC_VER
+# define RT_BREAKPOINT() __debugbreak()
+#endif
+#if defined(__IBMC__) || defined(__IBMCPP__)
+# define RT_BREAKPOINT() __interrupt(3)
+#endif
+#ifndef RT_BREAKPOINT
+# error "This compiler/arch is not supported!"
+#endif
+
+
+/** @defgroup grp_rt_cdefs_size Size Constants
+ * (Of course, these are binary computer terms, not SI.)
+ * @{
+ */
+/** 1 K (Kilo) (1 024). */
+#define _1K 0x00000400
+/** 2 K (Kilo) (2 048). */
+#define _2K 0x00000800
+/** 4 K (Kilo) (4 096). */
+#define _4K 0x00001000
+/** 8 K (Kilo) (8 192). */
+#define _8K 0x00002000
+/** 16 K (Kilo) (16 384). */
+#define _16K 0x00004000
+/** 32 K (Kilo) (32 678). */
+#define _32K 0x00008000
+/** 64 K (Kilo) (65 536). */
+#define _64K 0x00010000
+/** 128 K (Kilo) (131 072). */
+#define _128K 0x00020000
+/** 256 K (Kilo) (262 144). */
+#define _256K 0x00040000
+/** 512 K (Kilo) (524 288). */
+#define _512K 0x00080000
+/** 1 M (Mega) (1 048 576). */
+#define _1M 0x00100000
+/** 2 M (Mega) (2 097 152). */
+#define _2M 0x00200000
+/** 4 M (Mega) (4 194 304). */
+#define _4M 0x00400000
+/** 1 G (Giga) (1 073 741 824). (32-bit) */
+#define _1G 0x40000000
+/** 1 G (Giga) (1 073 741 824). (64-bit) */
+#define _1G64 0x40000000LL
+/** 2 G (Giga) (2 147 483 648). (32-bit) */
+#define _2G32 0x80000000U
+/** 2 G (Giga) (2 147 483 648). (64-bit) */
+#define _2G 0x0000000080000000LL
+/** 4 G (Giga) (4 294 967 296). */
+#define _4G 0x0000000100000000LL
+/** 1 T (Tera) (1 099 511 627 776). */
+#define _1T 0x0000010000000000LL
+/** 1 P (Peta) (1 125 899 906 842 624). */
+#define _1P 0x0004000000000000LL
+/** 1 E (Exa) (1 152 921 504 606 846 976). */
+#define _1E 0x1000000000000000LL
+/** 2 E (Exa) (2 305 843 009 213 693 952). */
+#define _2E 0x2000000000000000ULL
+/** @} */
+
+/** @defgroup grp_rt_cdefs_decimal_grouping Decimal Constant Grouping Macros
+ * @{ */
+#define RT_D1(g1) g1
+#define RT_D2(g1, g2) g1#g2
+#define RT_D3(g1, g2, g3) g1#g2#g3
+#define RT_D4(g1, g2, g3, g4) g1#g2#g3#g4
+#define RT_D5(g1, g2, g3, g4, g5) g1#g2#g3#g4#g5
+#define RT_D6(g1, g2, g3, g4, g5, g6) g1#g2#g3#g4#g5#g6
+#define RT_D7(g1, g2, g3, g4, g5, g6, g7) g1#g2#g3#g4#g5#g6#g7
+
+#define RT_D1_U(g1) UINT32_C(g1)
+#define RT_D2_U(g1, g2) UINT32_C(g1#g2)
+#define RT_D3_U(g1, g2, g3) UINT32_C(g1#g2#g3)
+#define RT_D4_U(g1, g2, g3, g4) UINT64_C(g1#g2#g3#g4)
+#define RT_D5_U(g1, g2, g3, g4, g5) UINT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_U(g1, g2, g3, g4, g5, g6) UINT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_U(g1, g2, g3, g4, g5, g6, g7) UINT64_C(g1#g2#g3#g4#g5#g6#g7)
+
+#define RT_D1_S(g1) INT32_C(g1)
+#define RT_D2_S(g1, g2) INT32_C(g1#g2)
+#define RT_D3_S(g1, g2, g3) INT32_C(g1#g2#g3)
+#define RT_D4_S(g1, g2, g3, g4) INT64_C(g1#g2#g3#g4)
+#define RT_D5_S(g1, g2, g3, g4, g5) INT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_S(g1, g2, g3, g4, g5, g6) INT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_S(g1, g2, g3, g4, g5, g6, g7) INT64_C(g1#g2#g3#g4#g5#g6#g7)
+
+#define RT_D1_U32(g1) UINT32_C(g1)
+#define RT_D2_U32(g1, g2) UINT32_C(g1#g2)
+#define RT_D3_U32(g1, g2, g3) UINT32_C(g1#g2#g3)
+#define RT_D4_U32(g1, g2, g3, g4) UINT32_C(g1#g2#g3#g4)
+
+#define RT_D1_S32(g1) INT32_C(g1)
+#define RT_D2_S32(g1, g2) INT32_C(g1#g2)
+#define RT_D3_S32(g1, g2, g3) INT32_C(g1#g2#g3)
+#define RT_D4_S32(g1, g2, g3, g4) INT32_C(g1#g2#g3#g4)
+
+#define RT_D1_U64(g1) UINT64_C(g1)
+#define RT_D2_U64(g1, g2) UINT64_C(g1#g2)
+#define RT_D3_U64(g1, g2, g3) UINT64_C(g1#g2#g3)
+#define RT_D4_U64(g1, g2, g3, g4) UINT64_C(g1#g2#g3#g4)
+#define RT_D5_U64(g1, g2, g3, g4, g5) UINT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_U64(g1, g2, g3, g4, g5, g6) UINT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_U64(g1, g2, g3, g4, g5, g6, g7) UINT64_C(g1#g2#g3#g4#g5#g6#g7)
+
+#define RT_D1_S64(g1) INT64_C(g1)
+#define RT_D2_S64(g1, g2) INT64_C(g1#g2)
+#define RT_D3_S64(g1, g2, g3) INT64_C(g1#g2#g3)
+#define RT_D4_S64(g1, g2, g3, g4) INT64_C(g1#g2#g3#g4)
+#define RT_D5_S64(g1, g2, g3, g4, g5) INT64_C(g1#g2#g3#g4#g5)
+#define RT_D6_S64(g1, g2, g3, g4, g5, g6) INT64_C(g1#g2#g3#g4#g5#g6)
+#define RT_D7_S64(g1, g2, g3, g4, g5, g6, g7) INT64_C(g1#g2#g3#g4#g5#g6#g7)
+/** @} */
+
+
+/** @defgroup grp_rt_cdefs_time Time Constants
+ * @{
+ */
+/** 1 hour expressed in nanoseconds (64-bit). */
+#define RT_NS_1HOUR UINT64_C(3600000000000)
+/** 1 minute expressed in nanoseconds (64-bit). */
+#define RT_NS_1MIN UINT64_C(60000000000)
+/** 45 second expressed in nanoseconds. */
+#define RT_NS_45SEC UINT64_C(45000000000)
+/** 30 second expressed in nanoseconds. */
+#define RT_NS_30SEC UINT64_C(30000000000)
+/** 20 second expressed in nanoseconds. */
+#define RT_NS_20SEC UINT64_C(20000000000)
+/** 15 second expressed in nanoseconds. */
+#define RT_NS_15SEC UINT64_C(15000000000)
+/** 10 second expressed in nanoseconds. */
+#define RT_NS_10SEC UINT64_C(10000000000)
+/** 1 second expressed in nanoseconds. */
+#define RT_NS_1SEC UINT32_C(1000000000)
+/** 100 millsecond expressed in nanoseconds. */
+#define RT_NS_100MS UINT32_C(100000000)
+/** 10 millsecond expressed in nanoseconds. */
+#define RT_NS_10MS UINT32_C(10000000)
+/** 1 millsecond expressed in nanoseconds. */
+#define RT_NS_1MS UINT32_C(1000000)
+/** 100 microseconds expressed in nanoseconds. */
+#define RT_NS_100US UINT32_C(100000)
+/** 10 microseconds expressed in nanoseconds. */
+#define RT_NS_10US UINT32_C(10000)
+/** 1 microsecond expressed in nanoseconds. */
+#define RT_NS_1US UINT32_C(1000)
+
+/** 1 second expressed in nanoseconds - 64-bit type. */
+#define RT_NS_1SEC_64 UINT64_C(1000000000)
+/** 100 millsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_100MS_64 UINT64_C(100000000)
+/** 10 millsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_10MS_64 UINT64_C(10000000)
+/** 1 millsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_1MS_64 UINT64_C(1000000)
+/** 100 microseconds expressed in nanoseconds - 64-bit type. */
+#define RT_NS_100US_64 UINT64_C(100000)
+/** 10 microseconds expressed in nanoseconds - 64-bit type. */
+#define RT_NS_10US_64 UINT64_C(10000)
+/** 1 microsecond expressed in nanoseconds - 64-bit type. */
+#define RT_NS_1US_64 UINT64_C(1000)
+
+/** 1 hour expressed in microseconds. */
+#define RT_US_1HOUR UINT32_C(3600000000)
+/** 1 minute expressed in microseconds. */
+#define RT_US_1MIN UINT32_C(60000000)
+/** 1 second expressed in microseconds. */
+#define RT_US_1SEC UINT32_C(1000000)
+/** 100 millsecond expressed in microseconds. */
+#define RT_US_100MS UINT32_C(100000)
+/** 10 millsecond expressed in microseconds. */
+#define RT_US_10MS UINT32_C(10000)
+/** 1 millsecond expressed in microseconds. */
+#define RT_US_1MS UINT32_C(1000)
+
+/** 1 hour expressed in microseconds - 64-bit type. */
+#define RT_US_1HOUR_64 UINT64_C(3600000000)
+/** 1 minute expressed in microseconds - 64-bit type. */
+#define RT_US_1MIN_64 UINT64_C(60000000)
+/** 1 second expressed in microseconds - 64-bit type. */
+#define RT_US_1SEC_64 UINT64_C(1000000)
+/** 100 millsecond expressed in microseconds - 64-bit type. */
+#define RT_US_100MS_64 UINT64_C(100000)
+/** 10 millsecond expressed in microseconds - 64-bit type. */
+#define RT_US_10MS_64 UINT64_C(10000)
+/** 1 millsecond expressed in microseconds - 64-bit type. */
+#define RT_US_1MS_64 UINT64_C(1000)
+
+/** 1 hour expressed in milliseconds. */
+#define RT_MS_1HOUR UINT32_C(3600000)
+/** 1 minute expressed in milliseconds. */
+#define RT_MS_1MIN UINT32_C(60000)
+/** 1 second expressed in milliseconds. */
+#define RT_MS_1SEC UINT32_C(1000)
+
+/** 1 hour expressed in milliseconds - 64-bit type. */
+#define RT_MS_1HOUR_64 UINT64_C(3600000)
+/** 1 minute expressed in milliseconds - 64-bit type. */
+#define RT_MS_1MIN_64 UINT64_C(60000)
+/** 1 second expressed in milliseconds - 64-bit type. */
+#define RT_MS_1SEC_64 UINT64_C(1000)
+
+/** The number of seconds per week. */
+#define RT_SEC_1WEEK UINT32_C(604800)
+/** The number of seconds per day. */
+#define RT_SEC_1DAY UINT32_C(86400)
+/** The number of seconds per hour. */
+#define RT_SEC_1HOUR UINT32_C(3600)
+
+/** The number of seconds per week - 64-bit type. */
+#define RT_SEC_1WEEK_64 UINT64_C(604800)
+/** The number of seconds per day - 64-bit type. */
+#define RT_SEC_1DAY_64 UINT64_C(86400)
+/** The number of seconds per hour - 64-bit type. */
+#define RT_SEC_1HOUR_64 UINT64_C(3600)
+/** @} */
+
+
+/** @defgroup grp_rt_cdefs_dbgtype Debug Info Types
+ * @{ */
+/** Other format. */
+#define RT_DBGTYPE_OTHER RT_BIT_32(0)
+/** Stabs. */
+#define RT_DBGTYPE_STABS RT_BIT_32(1)
+/** Debug With Arbitrary Record Format (DWARF). */
+#define RT_DBGTYPE_DWARF RT_BIT_32(2)
+/** Microsoft Codeview debug info. */
+#define RT_DBGTYPE_CODEVIEW RT_BIT_32(3)
+/** Watcom debug info. */
+#define RT_DBGTYPE_WATCOM RT_BIT_32(4)
+/** IBM High Level Language debug info. */
+#define RT_DBGTYPE_HLL RT_BIT_32(5)
+/** Old OS/2 and Windows symbol file. */
+#define RT_DBGTYPE_SYM RT_BIT_32(6)
+/** Map file. */
+#define RT_DBGTYPE_MAP RT_BIT_32(7)
+/** @} */
+
+
+/** @defgroup grp_rt_cdefs_exetype Executable Image Types
+ * @{ */
+/** Some other format. */
+#define RT_EXETYPE_OTHER RT_BIT_32(0)
+/** Portable Executable. */
+#define RT_EXETYPE_PE RT_BIT_32(1)
+/** Linear eXecutable. */
+#define RT_EXETYPE_LX RT_BIT_32(2)
+/** Linear Executable. */
+#define RT_EXETYPE_LE RT_BIT_32(3)
+/** New Executable. */
+#define RT_EXETYPE_NE RT_BIT_32(4)
+/** DOS Executable (Mark Zbikowski). */
+#define RT_EXETYPE_MZ RT_BIT_32(5)
+/** COM Executable. */
+#define RT_EXETYPE_COM RT_BIT_32(6)
+/** a.out Executable. */
+#define RT_EXETYPE_AOUT RT_BIT_32(7)
+/** Executable and Linkable Format. */
+#define RT_EXETYPE_ELF RT_BIT_32(8)
+/** Mach-O Executable (including FAT ones). */
+#define RT_EXETYPE_MACHO RT_BIT_32(9)
+/** TE from UEFI. */
+#define RT_EXETYPE_TE RT_BIT_32(9)
+/** @} */
+
+
+/** @def VALID_PTR
+ * Pointer validation macro.
+ * @param ptr The pointer.
+ */
+#if defined(RT_ARCH_AMD64)
+# ifdef IN_RING3
+# if defined(RT_OS_DARWIN) /* first 4GB is reserved for legacy kernel. */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) >= _4G \
+ && !((uintptr_t)(ptr) & 0xffff800000000000ULL) )
+# elif defined(RT_OS_SOLARIS) /* The kernel only used the top 2TB, but keep it simple. */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
+ && ( ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0xffff800000000000ULL \
+ || ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0) )
+# else
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
+ && !((uintptr_t)(ptr) & 0xffff800000000000ULL) )
+# endif
+# else /* !IN_RING3 */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U \
+ && ( ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0xffff800000000000ULL \
+ || ((uintptr_t)(ptr) & 0xffff800000000000ULL) == 0) )
+# endif /* !IN_RING3 */
+
+#elif defined(RT_ARCH_X86)
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
+
+#elif defined(RT_ARCH_SPARC64)
+# ifdef IN_RING3
+# if defined(RT_OS_SOLARIS)
+/** Sparc64 user mode: According to Figure 9.4 in solaris internals */
+/** @todo # define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x80004000U >= 0x80004000U + 0x100000000ULL ) - figure this. */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x80000000U >= 0x80000000U + 0x100000000ULL )
+# else
+# error "Port me"
+# endif
+# else /* !IN_RING3 */
+# if defined(RT_OS_SOLARIS)
+/** @todo Sparc64 kernel mode: This is according to Figure 11.1 in solaris
+ * internals. Verify in sources. */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) >= 0x01000000U )
+# else
+# error "Port me"
+# endif
+# endif /* !IN_RING3 */
+
+#elif defined(RT_ARCH_SPARC)
+# ifdef IN_RING3
+# ifdef RT_OS_SOLARIS
+/** Sparc user mode: According to
+ * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/sun4/os/startup.c#510 */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x400000U >= 0x400000U + 0x2000U )
+
+# else
+# error "Port me"
+# endif
+# else /* !IN_RING3 */
+# ifdef RT_OS_SOLARIS
+/** @todo Sparc kernel mode: Check the sources! */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
+# else
+# error "Port me"
+# endif
+# endif /* !IN_RING3 */
+
+#elif defined(RT_ARCH_ARM)
+/* ASSUMES that at least the last and first 4K are out of bounds. */
+# define RT_VALID_PTR(ptr) ( (uintptr_t)(ptr) + 0x1000U >= 0x2000U )
+
+#else
+# error "Architecture identifier missing / not implemented."
+#endif
+
+/** Old name for RT_VALID_PTR. */
+#define VALID_PTR(ptr) RT_VALID_PTR(ptr)
+
+/** @def RT_VALID_ALIGNED_PTR
+ * Pointer validation macro that also checks the alignment.
+ * @param ptr The pointer.
+ * @param align The alignment, must be a power of two.
+ */
+#define RT_VALID_ALIGNED_PTR(ptr, align) \
+ ( !((uintptr_t)(ptr) & (uintptr_t)((align) - 1)) \
+ && VALID_PTR(ptr) )
+
+
+/** @def VALID_PHYS32
+ * 32 bits physical address validation macro.
+ * @param Phys The RTGCPHYS address.
+ */
+#define VALID_PHYS32(Phys) ( (uint64_t)(Phys) < (uint64_t)_4G )
+
+/** @def N_
+ * The \#define N_ is used to mark a string for translation. This is usable in
+ * any part of the code, as it is only used by the tools that create message
+ * catalogs. This macro is a no-op as far as the compiler and code generation
+ * is concerned.
+ *
+ * If you want to both mark a string for translation and translate it, use _().
+ */
+#define N_(s) (s)
+
+/** @def _
+ * The \#define _ is used to mark a string for translation and to translate it
+ * in one step.
+ *
+ * If you want to only mark a string for translation, use N_().
+ */
+#define _(s) gettext(s)
+
+
+/** @def __PRETTY_FUNCTION__
+ * With GNU C we'd like to use the builtin __PRETTY_FUNCTION__, so define that
+ * for the other compilers.
+ */
+#if !defined(__GNUC__) && !defined(__PRETTY_FUNCTION__)
+# ifdef _MSC_VER
+# define __PRETTY_FUNCTION__ __FUNCSIG__
+# else
+# define __PRETTY_FUNCTION__ __FUNCTION__
+# endif
+#endif
+
+
+/** @def RT_STRICT
+ * The \#define RT_STRICT controls whether or not assertions and other runtime
+ * checks should be compiled in or not. This is defined when DEBUG is defined.
+ * If RT_NO_STRICT is defined, it will unconditionally be undefined.
+ *
+ * If you want assertions which are not subject to compile time options use
+ * the AssertRelease*() flavors.
+ */
+#if !defined(RT_STRICT) && defined(DEBUG)
+# define RT_STRICT
+#endif
+#ifdef RT_NO_STRICT
+# undef RT_STRICT
+#endif
+
+/** @todo remove this: */
+#if !defined(RT_LOCK_STRICT) && !defined(DEBUG_bird)
+# define RT_LOCK_NO_STRICT
+#endif
+#if !defined(RT_LOCK_STRICT_ORDER) && !defined(DEBUG_bird)
+# define RT_LOCK_NO_STRICT_ORDER
+#endif
+
+/** @def RT_LOCK_STRICT
+ * The \#define RT_LOCK_STRICT controls whether deadlock detection and related
+ * checks are done in the lock and semaphore code. It is by default enabled in
+ * RT_STRICT builds, but this behavior can be overridden by defining
+ * RT_LOCK_NO_STRICT. */
+#if !defined(RT_LOCK_STRICT) && !defined(RT_LOCK_NO_STRICT) && defined(RT_STRICT)
+# define RT_LOCK_STRICT
+#endif
+/** @def RT_LOCK_NO_STRICT
+ * The \#define RT_LOCK_NO_STRICT disables RT_LOCK_STRICT. */
+#if defined(RT_LOCK_NO_STRICT) && defined(RT_LOCK_STRICT)
+# undef RT_LOCK_STRICT
+#endif
+
+/** @def RT_LOCK_STRICT_ORDER
+ * The \#define RT_LOCK_STRICT_ORDER controls whether locking order is checked
+ * by the lock and semaphore code. It is by default enabled in RT_STRICT
+ * builds, but this behavior can be overridden by defining
+ * RT_LOCK_NO_STRICT_ORDER. */
+#if !defined(RT_LOCK_STRICT_ORDER) && !defined(RT_LOCK_NO_STRICT_ORDER) && defined(RT_STRICT)
+# define RT_LOCK_STRICT_ORDER
+#endif
+/** @def RT_LOCK_NO_STRICT_ORDER
+ * The \#define RT_LOCK_NO_STRICT_ORDER disables RT_LOCK_STRICT_ORDER. */
+#if defined(RT_LOCK_NO_STRICT_ORDER) && defined(RT_LOCK_STRICT_ORDER)
+# undef RT_LOCK_STRICT_ORDER
+#endif
+
+
+/** Source position. */
+#define RT_SRC_POS __FILE__, __LINE__, __PRETTY_FUNCTION__
+
+/** Source position declaration. */
+#define RT_SRC_POS_DECL const char *pszFile, unsigned iLine, const char *pszFunction
+
+/** Source position arguments. */
+#define RT_SRC_POS_ARGS pszFile, iLine, pszFunction
+
+/** Applies NOREF() to the source position arguments. */
+#define RT_SRC_POS_NOREF() do { NOREF(pszFile); NOREF(iLine); NOREF(pszFunction); } while (0)
+
+
+/** @def RT_INLINE_ASM_EXTERNAL
+ * Defined as 1 if the compiler does not support inline assembly.
+ * The ASM* functions will then be implemented in external .asm files.
+ */
+#if (defined(_MSC_VER) && defined(RT_ARCH_AMD64)) \
+ || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
+# define RT_INLINE_ASM_EXTERNAL 1
+#else
+# define RT_INLINE_ASM_EXTERNAL 0
+#endif
+
+/** @def RT_INLINE_ASM_GNU_STYLE
+ * Defined as 1 if the compiler understands GNU style inline assembly.
+ */
+#if defined(_MSC_VER)
+# define RT_INLINE_ASM_GNU_STYLE 0
+#else
+# define RT_INLINE_ASM_GNU_STYLE 1
+#endif
+
+/** @def RT_INLINE_ASM_USES_INTRIN
+ * Defined as 1 if the compiler have and uses intrin.h. Otherwise it is 0. */
+#ifdef _MSC_VER
+# if _MSC_VER >= 1400
+# define RT_INLINE_ASM_USES_INTRIN 1
+# endif
+#endif
+#ifndef RT_INLINE_ASM_USES_INTRIN
+# define RT_INLINE_ASM_USES_INTRIN 0
+#endif
+
+/** @} */
+
+
+/** @defgroup grp_rt_cdefs_cpp Special Macros for C++
+ * @ingroup grp_rt_cdefs
+ * @{
+ */
+
+#ifdef __cplusplus
+
+/** @def DECLEXPORT_CLASS
+ * How to declare an exported class. Place this macro after the 'class'
+ * keyword in the declaration of every class you want to export.
+ *
+ * @note It is necessary to use this macro even for inner classes declared
+ * inside the already exported classes. This is a GCC specific requirement,
+ * but it seems not to harm other compilers.
+ */
+#if defined(_MSC_VER) || defined(RT_OS_OS2)
+# define DECLEXPORT_CLASS __declspec(dllexport)
+#elif defined(RT_USE_VISIBILITY_DEFAULT)
+# define DECLEXPORT_CLASS __attribute__((visibility("default")))
+#else
+# define DECLEXPORT_CLASS
+#endif
+
+/** @def DECLIMPORT_CLASS
+ * How to declare an imported class Place this macro after the 'class'
+ * keyword in the declaration of every class you want to export.
+ *
+ * @note It is necessary to use this macro even for inner classes declared
+ * inside the already exported classes. This is a GCC specific requirement,
+ * but it seems not to harm other compilers.
+ */
+#if defined(_MSC_VER) || (defined(RT_OS_OS2) && !defined(__IBMC__) && !defined(__IBMCPP__))
+# define DECLIMPORT_CLASS __declspec(dllimport)
+#elif defined(RT_USE_VISIBILITY_DEFAULT)
+# define DECLIMPORT_CLASS __attribute__((visibility("default")))
+#else
+# define DECLIMPORT_CLASS
+#endif
+
+/** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP
+ * Macro to work around error C2593 of the not-so-smart MSVC 7.x ambiguity
+ * resolver. The following snippet clearly demonstrates the code causing this
+ * error:
+ * @code
+ * class A
+ * {
+ * public:
+ * operator bool() const { return false; }
+ * operator int*() const { return NULL; }
+ * };
+ * int main()
+ * {
+ * A a;
+ * if (!a);
+ * if (a && 0);
+ * return 0;
+ * }
+ * @endcode
+ * The code itself seems pretty valid to me and GCC thinks the same.
+ *
+ * This macro fixes the compiler error by explicitly overloading implicit
+ * global operators !, && and || that take the given class instance as one of
+ * their arguments.
+ *
+ * The best is to use this macro right after the class declaration.
+ *
+ * @note The macro expands to nothing for compilers other than MSVC.
+ *
+ * @param Cls Class to apply the workaround to
+ */
+#if defined(_MSC_VER)
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls) \
+ inline bool operator! (const Cls &that) { return !bool (that); } \
+ inline bool operator&& (const Cls &that, bool b) { return bool (that) && b; } \
+ inline bool operator|| (const Cls &that, bool b) { return bool (that) || b; } \
+ inline bool operator&& (bool b, const Cls &that) { return b && bool (that); } \
+ inline bool operator|| (bool b, const Cls &that) { return b || bool (that); }
+#else
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP(Cls)
+#endif
+
+/** @def WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL
+ * Version of WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP for template classes.
+ *
+ * @param Tpl Name of the template class to apply the workaround to
+ * @param ArgsDecl arguments of the template, as declared in |<>| after the
+ * |template| keyword, including |<>|
+ * @param Args arguments of the template, as specified in |<>| after the
+ * template class name when using the, including |<>|
+ *
+ * Example:
+ * @code
+ * // template class declaration
+ * template <class C>
+ * class Foo { ... };
+ * // applied workaround
+ * WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL (Foo, <class C>, <C>)
+ * @endcode
+ */
+#if defined(_MSC_VER)
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL(Tpl, ArgsDecl, Args) \
+ template ArgsDecl \
+ inline bool operator! (const Tpl Args &that) { return !bool (that); } \
+ template ArgsDecl \
+ inline bool operator&& (const Tpl Args &that, bool b) { return bool (that) && b; } \
+ template ArgsDecl \
+ inline bool operator|| (const Tpl Args &that, bool b) { return bool (that) || b; } \
+ template ArgsDecl \
+ inline bool operator&& (bool b, const Tpl Args &that) { return b && bool (that); } \
+ template ArgsDecl \
+ inline bool operator|| (bool b, const Tpl Args &that) { return b || bool (that); }
+#else
+# define WORKAROUND_MSVC7_ERROR_C2593_FOR_BOOL_OP_TPL(Tpl, ArgsDecl, Args)
+#endif
+
+
+/** @def DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP
+ * Declares the copy constructor and the assignment operation as inlined no-ops
+ * (non-existent functions) for the given class. Use this macro inside the
+ * private section if you want to effectively disable these operations for your
+ * class.
+ *
+ * @param Cls class name to declare for
+ */
+
+#define DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(Cls) \
+ inline Cls (const Cls &); \
+ inline Cls &operator= (const Cls &);
+
+
+/** @def DECLARE_CLS_NEW_DELETE_NOOP
+ * Declares the new and delete operations as no-ops (non-existent functions)
+ * for the given class. Use this macro inside the private section if you want
+ * to effectively limit creating class instances on the stack only.
+ *
+ * @note The destructor of the given class must not be virtual, otherwise a
+ * compile time error will occur. Note that this is not a drawback: having
+ * the virtual destructor for a stack-based class is absolutely useless
+ * (the real class of the stack-based instance is always known to the compiler
+ * at compile time, so it will always call the correct destructor).
+ *
+ * @param Cls class name to declare for
+ */
+#define DECLARE_CLS_NEW_DELETE_NOOP(Cls) \
+ inline static void *operator new (size_t); \
+ inline static void operator delete (void *);
+
+#endif /* __cplusplus */
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/cdrom.h b/include/iprt/cdrom.h
new file mode 100644
index 00000000..927ee153
--- /dev/null
+++ b/include/iprt/cdrom.h
@@ -0,0 +1,181 @@
+/** @file
+ * IPRT CD/DVD/BD-ROM Drive 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 ___iprt_cdrom_h
+#define ___iprt_cdrom_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_cdrom IPRT CD/DVD/BD-ROM Drive API
+ *
+ * The user of the API is currently resposible for serializing calls to it.
+ *
+ * @{
+ */
+
+/** CD-ROM drive handle. */
+typedef struct RTCDROMINT *RTCDROM;
+/** Pointer to a CD-ROM handle. */
+typedef RTCDROM *PRTCDROM;
+/** NIL CD-ROM handle value. */
+#define NIL_RTCDROM ((RTCDROM)0)
+
+
+/** @name CD-ROM open flags.
+ * @{ */
+#define RTCDROM_O_READ RT_BIT(0)
+#define RTCDROM_O_WRITE RT_BIT(1)
+#define RTCDROM_O_CONTROL RT_BIT(2)
+#define RTCDROM_O_QUERY RT_BIT(3)
+#define RTCDROM_O_ALL_ACCESS (RTCDROM_O_READ | RTCDROM_O_WRITE | RTCDROM_O_CONTROL | RTCDROM_O_QUERY)
+/** @} */
+
+/**
+ * Opens the CD-ROM drive (by name).
+ *
+ * @returns IPRT status code.
+ * @param pszName The CD-ROM name (path).
+ * @param fFlags Open flags, see RTCDROM_O_XXX.
+ * @param phCdrom Where to return the CDROM handle.
+ */
+RTDECL(int) RTCdromOpen(const char *psz, uint32_t fFlags, PRTCDROM phCdrom);
+
+/**
+ * Retains a reference to the CD-ROM handle.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hCdrom The CD-ROM handle to retain.
+ */
+RTDECL(uint32_t) RTCdromRetain(RTCDROM hCdrom);
+
+/**
+ * Releases a reference to the CD-ROM handle.
+ *
+ * When the reference count reaches zero, the CD-ROM handle is destroy.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hCdrom The CD-ROM handle to retain.
+ */
+RTDECL(uint32_t) RTCdromRelease(RTCDROM hCdrom);
+
+/**
+ * Query the primary mount point of the CD-ROM.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. The buffer will be
+ * set to an empty string if possible.
+ *
+ * @param hCdrom The CD-ROM handle.
+ * @param pszMountPoint Where to return the mount point.
+ * @param cbMountPoint The size of the mount point buffer.
+ */
+RTDECL(int) RTCdromQueryMountPoint(RTCDROM hCdrom, char *pszMountPoint, size_t cbMountPoint);
+
+/**
+ * Unmounts all file-system mounts related to the CD-ROM.
+ *
+ * @returns IPRT status code.
+ * @param hCdrom The CD-ROM handle.
+ */
+RTDECL(int) RTCdromUnmount(RTCDROM hCdrom);
+
+/**
+ * Ejects the CD-ROM from the drive.
+ *
+ * @returns IPRT status code.
+ * @param hCdrom The CD-ROM handle.
+ * @param fForce If set, unmount and unlock will be performed.
+ */
+RTDECL(int) RTCdromEject(RTCDROM hCdrom, bool fForce);
+
+/**
+ * Locks the CD-ROM so it cannot be ejected by the user or system.
+ *
+ * @returns IPRT status code.
+ * @param hCdrom The CD-ROM handle.
+ */
+RTDECL(int) RTCdromLock(RTCDROM hCdrom);
+
+/**
+ * Unlocks the CD-ROM so it can be ejected by the user or system.
+ *
+ * @returns IPRT status code.
+ * @param hCdrom The CD-ROM handle.
+ */
+RTDECL(int) RTCdromUnlock(RTCDROM hCdrom);
+
+
+/** @name Ordinal / Enumeration
+ * @{ */
+/**
+ * Get the current number of CD-ROMs.
+ *
+ * This is handy for using RTCdromOpenByOrdinal() or RTCdromOrdinalToName() to
+ * perform some kind of enumeration of all drives.
+ *
+ * @returns Number of CD-ROM drivers in the system.
+ */
+RTDECL(unsigned) RTCdromCount(void);
+
+/**
+ * Translates an CD-ROM drive ordinal number to a path suitable for RTCdromOpen.
+ *
+ * @returns IRPT status code.
+ * @retval VINF_SUCCESS on success, with the name in the buffer.
+ * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. The buffer will be
+ * set to an empty string if possible, in order to prevent trouble.
+ * @retval VERR_OUT_OF_RANGE if the ordinal number is higher than the current
+ * number of CD-ROM drives.
+ *
+ * @param iCdrom The CD-ROM drive ordinal. Starts at 0.
+ * @param pszName Where to return the name (path).
+ * @param cbName Size of the output buffer.
+ *
+ * @remarks The ordinals are volatile. They may change as drives are attached
+ * or detected from the host.
+ */
+RTDECL(int) RTCdromOrdinalToName(unsigned iCdrom, char *pszName, size_t cbName);
+
+/**
+ * Combination of RTCdromOrdinalToName() and RTCdromOpen().
+ *
+ * @returns IPRT status code.
+ * @param pszName The CD-ROM name (path).
+ * @param fFlags Open flags, see RTCDROM_O_XXX.
+ * @param phCdrom Where to return the CDROM handle .
+ * @remarks See remarks on RTCdromOrdinalToName().
+ */
+RTDECL(int) RTCdromOpenByOrdinal(unsigned iCdrom, uint32_t fFlags, PRTCDROM phCdrom);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/cidr.h b/include/iprt/cidr.h
new file mode 100644
index 00000000..5e054186
--- /dev/null
+++ b/include/iprt/cidr.h
@@ -0,0 +1,61 @@
+/** @file
+ * IPRT - TCP/IP.
+ */
+
+/*
+ * 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 ___iprt_ip_h
+#define ___iprt_ip_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+/** @defgroup grp_rt_cidr RTCidr - Classless Inter-Domain Routing notation
+ * @ingroup grp_rt
+ * @{
+ */
+RT_C_DECLS_BEGIN
+
+/** An IPv4 address. */
+typedef uint32_t RTIPV4ADDR;
+/** Pointer to an IPv4 address. */
+typedef RTIPV4ADDR *PRTIPV4ADDR;
+/** Pointer to a const IPv4 address. */
+typedef RTIPV4ADDR const *PCRTIPV4ADDR;
+
+
+/**
+ * Parse a string which contains an IP address in CIDR (Classless Inter-Domain Routing) notation.
+ *
+ * @return iprt status code.
+ *
+ * @param pszAddress The IP address in CIDR specificaion.
+ * @param pNetwork The determined IP address / network.
+ * @param pNetmask The determined netmask.
+ */
+RTDECL(int) RTCidrStrToIPv4(const char *pszAddress, PRTIPV4ADDR pNetwork, PRTIPV4ADDR pNetmask);
+
+RT_C_DECLS_END
+/** @} */
+
+#endif
diff --git a/include/iprt/circbuf.h b/include/iprt/circbuf.h
new file mode 100644
index 00000000..b0c58ffe
--- /dev/null
+++ b/include/iprt/circbuf.h
@@ -0,0 +1,138 @@
+/** @file
+ * IPRT - Lock Free Circular Buffer
+ */
+
+/*
+ * 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 ___iprt_circbuf_h
+#define ___iprt_circbuf_h
+
+#include <iprt/types.h>
+
+/** @defgroup grp_rt_circbuf RTCircBuf - Lock Free Circular Buffer
+ * @ingroup grp_rt
+ *
+ * Implementation of a lock free circular buffer which could be used in a multi
+ * threaded environment. Note that only the acquire, release and getter
+ * functions are threading aware. So don't use reset if the circular buffer is
+ * still in use.
+ *
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/** Pointer to a circular buffer (abstract). */
+typedef struct RTCIRCBUF *PRTCIRCBUF;
+
+/**
+ * Create a circular buffer.
+ *
+ * @returns IPRT status code.
+ *
+ * @param ppBuf Where to store the buffer.
+ * @param cbSize The size of the new buffer.
+ */
+RTDECL(int) RTCircBufCreate(PRTCIRCBUF *ppBuf, size_t cbSize);
+
+/**
+ * Destroy the circular buffer.
+ *
+ * @param pBuf The buffer to destroy. NULL is ignored.
+ */
+RTDECL(void) RTCircBufDestroy(PRTCIRCBUF pBuf);
+
+/**
+ * Reset all position information in the circular buffer.
+ *
+ * @note This function is not multi threading aware.
+ *
+ * @param pBuf The buffer to reset.
+ */
+RTDECL(void) RTCircBufReset(PRTCIRCBUF pBuf);
+
+/**
+ * Returns the current free space of the buffer.
+ *
+ * @param pBuf The buffer to query.
+ */
+RTDECL(size_t) RTCircBufFree(PRTCIRCBUF pBuf);
+
+/**
+ * Returns the current used space of the buffer.
+ *
+ * @param pBuf The buffer to query.
+ */
+RTDECL(size_t) RTCircBufUsed(PRTCIRCBUF pBuf);
+
+/**
+ * Returns the size of the buffer.
+ *
+ * @param pBuf The buffer to query.
+ */
+RTDECL(size_t) RTCircBufSize(PRTCIRCBUF pBuf);
+
+RTDECL(bool) RTCircBufIsReading(PRTCIRCBUF pBuf);
+RTDECL(bool) RTCircBufIsWriting(PRTCIRCBUF pBuf);
+
+/**
+ * Acquire a block of the circular buffer for reading.
+ *
+ * @param pBuf The buffer to acquire from.
+ * @param cbReqSize The requested size of the block.
+ * @param ppvStart The resulting memory pointer.
+ * @param pcbSize The resulting size of the memory pointer.
+ */
+RTDECL(void) RTCircBufAcquireReadBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void **ppvStart, size_t *pcbSize);
+
+/**
+ * Release a block which was acquired by RTCircBufAcquireReadBlock.
+ *
+ * @param pBuf The buffer to acquire from.
+ * @param cbSize The size of the block.
+ */
+RTDECL(void) RTCircBufReleaseReadBlock(PRTCIRCBUF pBuf, size_t cbSize);
+
+/**
+ * Acquire a block of the circular buffer for writing.
+ *
+ * @param pBuf The buffer to acquire from.
+ * @param cbReqSize The requested size of the block.
+ * @param ppvStart The resulting memory pointer.
+ * @param pcbSize The resulting size of the memory pointer.
+ */
+RTDECL(void) RTCircBufAcquireWriteBlock(PRTCIRCBUF pBuf, size_t cbReqSize, void **ppvStart, size_t *pcbSize);
+
+/**
+ * Release a block which was acquired by RTCircBufAcquireWriteBlock.
+ *
+ * @param pBuf The buffer to acquire from.
+ * @param cbSize The size of the block.
+ */
+RTDECL(void) RTCircBufReleaseWriteBlock(PRTCIRCBUF pBuf, size_t cbSize);
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif /* !___iprt_circbuf_h */
+
diff --git a/include/iprt/condvar.h b/include/iprt/condvar.h
new file mode 100644
index 00000000..98e5e2dc
--- /dev/null
+++ b/include/iprt/condvar.h
@@ -0,0 +1,283 @@
+/** @file
+ * IPRT - Condition Variable.
+ */
+
+/*
+ * 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 ___iprt_condvar_h
+#define ___iprt_condvar_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3)
+# include <iprt/lockvalidator.h>
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_condvar RTCondVar - Condition Variable
+ *
+ * Condition variables combines mutex semaphore or critical sections with event
+ * semaphores. See @ref grp_rt_sems_mutex, @ref grp_rt_critsect,
+ * @ref grp_rt_sems_event and @ref grp_rt_sems_event_multi.
+ *
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Create a condition variable.
+ *
+ * @returns iprt status code.
+ * @param phCondVar Where to store the handle to the newly created
+ * condition variable.
+ */
+RTDECL(int) RTConvVarCreate(PRTCONDVAR phCondVar);
+
+/**
+ * Create a condition variable.
+ *
+ * @returns iprt status code.
+ * @param phCondVar Where to store the handle to the newly created
+ * condition variable.
+ * @param fFlags Flags, any combination of the
+ * RTCONDVAR_FLAGS_XXX \#defines.
+ * @param hClass The class (no reference consumed). Since we
+ * don't do order checks on condition variables,
+ * the use of the class is limited to controlling
+ * the timeout threshold for deadlock detection.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTConvVarCreateEx(PRTCONDVAR phCondVar, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...);
+
+/** @name RTConvVarCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTCONDVAR_FLAGS_NO_LOCK_VAL UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroy a condition variable.
+ *
+ * @returns iprt status code.
+ * @param hCondVar Handle of the condition variable. NIL_RTCONDVAR
+ * is quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTConvVarDestroy(RTCONDVAR hCondVar);
+
+/**
+ * Signal the condition variable, waking up exactly one thread.
+ *
+ * It is recommended that the caller holds the associated lock, but this is not
+ * strictly speaking necessary.
+ *
+ * If no threads are waiting on the condition variable, the call will have no
+ * effect on the variable.
+ *
+ * @returns iprt status code.
+ * @param hConvVar The condition variable to signal.
+ */
+RTDECL(int) RTConvVarSignal(RTCONDVAR hCondVar);
+
+/**
+ * Signal the condition variable, waking up all blocked threads.
+ *
+ * It is recommended that the caller holds the associated lock, but this is not
+ * strictly speaking necessary.
+ *
+ * If no threads are waiting on the condition variable, the call will have no
+ * effect on the variable.
+ *
+ * @returns iprt status code.
+ * @param hConvVar The condition variable to broadcast.
+ */
+RTDECL(int) RTConvVarBroadcast(RTCONDVAR hCondVar);
+
+/**
+ * Wait for the condition variable to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async system event
+ * (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hConvVar The condition variable to wait on.
+ * @param hMtx The mutex to leave during the wait and which
+ * will be re-enter before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarMutexWait(RTCONDVAR hCondVar, RTSEMMUTEX hMtx, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the condition variable to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param hConvVar The condition variable to wait on.
+ * @param hMtx The mutex to leave during the wait and which
+ * will be re-enter before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarMutexWaitNoResume(RTCONDVAR hCondVar, RTSEMMUTEX hMtx, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the condition variable to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async system event
+ * (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hConvVar The condition variable to wait on.
+ * @param hRWSem The read/write semaphore to write-leave during
+ * the wait and which will be re-enter in write
+ * mode before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarRWWriteWait(RTCONDVAR hCondVar, RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the condition variable to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param hConvVar The condition variable to wait on.
+ * @param hRWSem The read/write semaphore to write-leave during
+ * the wait and which will be re-enter in write
+ * mode before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarRWWriteWaitNoResume(RTCONDVAR hCondVar, RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the condition variable to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async system event
+ * (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hConvVar The condition variable to wait on.
+ * @param hRWSem The read/write semaphore to read-leave during
+ * the wait and which will be re-enter in read mode
+ * before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarRWReadWait(RTCONDVAR hCondVar, RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the condition variable to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param hConvVar The condition variable to wait on.
+ * @param hRWSem The read/write semaphore to read-leave during
+ * the wait and which will be re-enter in read mode
+ * before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarRWReadWaitNoResume(RTCONDVAR hCondVar, RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the condition variable to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async system event
+ * (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hConvVar The condition variable to wait on.
+ * @param pCritSect The critical section to leave during the wait
+ * and which will be re-enter before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarCritSectWait(RTCONDVAR hCondVar, PRTCRITSECT pCritSect, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the condition variable to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param hConvVar The condition variable to wait on.
+ * @param pCritSect The critical section to leave during the wait
+ * and which will be re-enter before returning.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait forever.
+ */
+RTDECL(int) RTConvVarCritSectWaitNoResume(RTCONDVAR hCondVar, PRTCRITSECT pCritSect, RTMSINTERVAL cMillies);
+
+/**
+ * Sets the signaller thread to one specific thread.
+ *
+ * This is only used for validating usage and deadlock detection. When used
+ * after calls to RTConvVarAddSignaller, the specified thread will be the only
+ * signalling thread.
+ *
+ * @param hConvVar The condition variable.
+ * @param hThread The thread that will signal it. Pass
+ * NIL_RTTHREAD to indicate that there is no
+ * special signalling thread.
+ */
+RTDECL(void) RTConvVarSetSignaller(RTCONDVAR hCondVar, RTTHREAD hThread);
+
+/**
+ * To add more signalling threads.
+ *
+ * First call RTCondVarSetSignaller then add further threads with this.
+ *
+ * @param hConvVar The condition variable.
+ * @param hThread The thread that will signal it. NIL_RTTHREAD is
+ * not accepted.
+ */
+RTDECL(void) RTConvVarAddSignaller(RTCONDVAR hCondVar, RTTHREAD hThread);
+
+/**
+ * To remove a signalling thread.
+ *
+ * Reverts work done by RTCondVarAddSignaller and RTCondVarSetSignaller.
+ *
+ * @param hConvVar The condition variable.
+ * @param hThread A previously added thread.
+ */
+RTDECL(void) RTConvVarRemoveSignaller(RTCONDVAR hCondVar, RTTHREAD hThread);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/coredumper.h b/include/iprt/coredumper.h
new file mode 100644
index 00000000..6c748bbf
--- /dev/null
+++ b/include/iprt/coredumper.h
@@ -0,0 +1,94 @@
+/** @file
+ * IPRT - Core Dumper.
+ */
+
+/*
+ * 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 ___iprt_coredumper_h
+#define ___iprt_coredumper_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_coredumper RTCoreDumper - Core Dumper.
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @name RTCoreDumperSetup flags
+ * @{ */
+/** Override system core dumper. Registers handlers for
+ * SIGSEGV/SIGTRAP/SIGBUS. */
+#define RTCOREDUMPER_FLAGS_REPLACE_SYSTEM_DUMP RT_BIT(0)
+/** Allow taking live process dumps (without killing process). Registers handler
+ * for SIGUSR2. */
+#define RTCOREDUMPER_FLAGS_LIVE_CORE RT_BIT(1)
+/** @} */
+
+/**
+ * Take a core dump of the current process without terminating it.
+ *
+ * @returns IPRT status code.
+ * @param pszOutputFile Name of the core file. If NULL use the
+ * default naming scheme.
+ * @param fLiveCore When true, the process is not killed after
+ * taking a core. Otherwise it will be killed. This
+ * works in conjuction with the flags set during
+ * RTCoreDumperSetup().
+ */
+RTDECL(int) RTCoreDumperTakeDump(const char *pszOutputFile, bool fLiveCore);
+
+/**
+ * Sets up and enables the core dumper.
+ *
+ * Installs signal / unhandled exception handlers for catching fatal errors
+ * that should result in a core dump. If you wish to install your own handlers
+ * you should do that after calling this function and make sure you pass on
+ * events you don't handle.
+ *
+ * This can be called multiple times to change the settings without needing to
+ * call RTCoreDumperDisable in between.
+ *
+ * @param pszOutputDir The directory to store the cores in. If NULL
+ * the current directory will be used.
+ * @param pszBaseName Base file name, no directory. If NULL the
+ * dumper will generate an appropriate name.
+ * @param fFlags Setup flags, 0 in NOT a valid flag, it must be
+ * one or more of RTCOREDUMPER_FLAGS_*.
+ */
+RTDECL(int) RTCoreDumperSetup(const char *pszOutputDir, uint32_t fFlags);
+
+/**
+ * Disables the core dumper, i.e. undoes what RTCoreDumperSetup did.
+ *
+ * @returns IPRT status code.
+ */
+RTDECL(int) RTCoreDumperDisable(void);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/cpp/Makefile.kup b/include/iprt/cpp/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/iprt/cpp/Makefile.kup
diff --git a/include/iprt/cpp/autores.h b/include/iprt/cpp/autores.h
new file mode 100644
index 00000000..0edad230
--- /dev/null
+++ b/include/iprt/cpp/autores.h
@@ -0,0 +1,203 @@
+/** @file
+ * IPRT - C++ Resource Management.
+ */
+
+/*
+ * Copyright (C) 2008-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 ___iprt_autores_h
+#define ___iprt_autores_h
+
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#include <iprt/cpp/utils.h>
+
+
+
+/** @defgroup grp_rt_cpp_autores C++ Resource Management
+ * @ingroup grp_rt_cpp
+ * @{
+ */
+
+/**
+ * A callable class template which returns the correct value against which an
+ * IPRT type must be compared to see if it is invalid.
+ *
+ * @warning This template *must* be specialised for the types it is to work with.
+ */
+template <class T>
+inline T RTAutoResNil(void)
+{
+ AssertFatalMsgFailed(("Unspecialized template!\n"));
+ return (T)0;
+}
+
+/** Specialisation of RTAutoResNil for RTFILE */
+template <>
+inline RTFILE RTAutoResNil(void)
+{
+ return NIL_RTFILE;
+}
+
+/**
+ * A function template which calls the correct destructor for an IPRT type.
+ *
+ * @warning This template *must* be specialised for the types it is to work with.
+ */
+template <class T>
+inline void RTAutoResDestruct(T a_h)
+{
+ AssertFatalMsgFailed(("Unspecialized template!\n"));
+ NOREF(a_h);
+}
+
+/**
+ * An auto pointer-type class for resources which take a C-style destructor
+ * (RTMemFree() or equivalent).
+ *
+ * The idea of this class is to manage resources which the current code is
+ * responsible for freeing. By wrapping the resource in an RTCAutoRes, you
+ * ensure that the resource will be freed when you leave the scope in which
+ * the RTCAutoRes is defined, unless you explicitly release the resource.
+ *
+ * A typical use case is when a function is allocating a number of resources.
+ * If any single allocation fails then all other resources must be freed. If
+ * all allocations succeed, then the resources should be returned to the
+ * caller. By placing all allocated resources in RTCAutoRes containers, you
+ * ensure that they will be freed on failure, and only have to take care of
+ * releasing them when you return them.
+ *
+ * @param T The type of the resource.
+ * @param Destruct The function to be used to free the resource.
+ * This parameter must be supplied if there is no
+ * specialisation of RTAutoDestruct available for @a T.
+ * @param NilRes The function returning the NIL value for T. Required.
+ * This parameter must be supplied if there is no
+ * specialisation of RTAutoResNil available for @a T.
+ *
+ * @note The class can not be initialised directly using assignment, due
+ * to the lack of a copy constructor. This is intentional.
+ */
+template <class T, void Destruct(T) = RTAutoResDestruct<T>, T NilRes(void) = RTAutoResNil<T> >
+class RTCAutoRes
+ : public RTCNonCopyable
+{
+protected:
+ /** The resource handle. */
+ T m_hRes;
+
+public:
+ /**
+ * Constructor
+ *
+ * @param a_hRes The handle to resource to manage. Defaults to NIL.
+ */
+ RTCAutoRes(T a_hRes = NilRes())
+ : m_hRes(a_hRes)
+ {
+ }
+
+ /**
+ * Destructor.
+ *
+ * This destroys any resource currently managed by the object.
+ */
+ ~RTCAutoRes()
+ {
+ if (m_hRes != NilRes())
+ Destruct(m_hRes);
+ }
+
+ /**
+ * Assignment from a value.
+ *
+ * This destroys any resource currently managed by the object
+ * before taking on the new one.
+ *
+ * @param a_hRes The handle to the new resource.
+ */
+ RTCAutoRes &operator=(T a_hRes)
+ {
+ if (m_hRes != NilRes())
+ Destruct(m_hRes);
+ m_hRes = a_hRes;
+ return *this;
+ }
+
+ /**
+ * Checks if the resource handle is NIL or not.
+ */
+ bool operator!()
+ {
+ return m_hRes == NilRes();
+ }
+
+ /**
+ * Give up ownership the current resource, handing it to the caller.
+ *
+ * @returns The current resource handle.
+ *
+ * @note Nothing happens to the resource when the object goes out of scope.
+ */
+ T release(void)
+ {
+ T Tmp = m_hRes;
+ m_hRes = NilRes();
+ return Tmp;
+ }
+
+ /**
+ * Deletes the current resources.
+ *
+ * @param a_hRes Handle to a new resource to manage. Defaults to NIL.
+ */
+ void reset(T a_hRes = NilRes())
+ {
+ if (a_hRes != m_hRes)
+ {
+ if (m_hRes != NilRes())
+ Destruct(m_hRes);
+ m_hRes = a_hRes;
+ }
+ }
+
+ /**
+ * Get the raw resource handle.
+ *
+ * Typically used passing the handle to some IPRT function while
+ * the object remains in scope.
+ *
+ * @returns The raw resource handle.
+ */
+ T get(void)
+ {
+ return m_hRes;
+ }
+};
+
+/** @} */
+
+
+/* include after template definition */
+#include <iprt/mem.h>
+
+#endif
+
diff --git a/include/iprt/cpp/exception.h b/include/iprt/cpp/exception.h
new file mode 100644
index 00000000..4fcbfb72
--- /dev/null
+++ b/include/iprt/cpp/exception.h
@@ -0,0 +1,95 @@
+/** @file
+ * IPRT - C++ Base Exceptions.
+ */
+
+/*
+ * 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 ___iprt_cpp_exception_h
+#define ___iprt_cpp_exception_h
+
+#include <iprt/cpp/ministring.h>
+#include <exception>
+
+/** @defgroup grp_rt_cpp_exceptions C++ Exceptions
+ * @ingroup grp_rt_cpp
+ * @{
+ */
+
+/**
+ * Base exception class for IPRT, derived from std::exception.
+ * The XML exceptions are based on this.
+ */
+class RT_DECL_CLASS RTCError
+ : public std::exception
+{
+public:
+
+ RTCError(const char *pszMessage)
+ : m_strMsg(pszMessage)
+ {
+ }
+
+ RTCError(const RTCString &a_rstrMessage)
+ : m_strMsg(a_rstrMessage)
+ {
+ }
+
+ RTCError(const RTCError &a_rSrc)
+ : std::exception(a_rSrc),
+ m_strMsg(a_rSrc.what())
+ {
+ }
+
+ virtual ~RTCError() throw()
+ {
+ }
+
+ void operator=(const RTCError &a_rSrc)
+ {
+ m_strMsg = a_rSrc.what();
+ }
+
+ void setWhat(const char *a_pszMessage)
+ {
+ m_strMsg = a_pszMessage;
+ }
+
+ virtual const char *what() const throw()
+ {
+ return m_strMsg.c_str();
+ }
+
+private:
+ /**
+ * Hidden default constructor making sure that the extended one above is
+ * always used.
+ */
+ RTCError();
+
+ /** The exception message. */
+ RTCString m_strMsg;
+};
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/cpp/list.h b/include/iprt/cpp/list.h
new file mode 100644
index 00000000..97c1a193
--- /dev/null
+++ b/include/iprt/cpp/list.h
@@ -0,0 +1,891 @@
+/** @file
+ * IPRT - Generic List Class.
+ */
+
+/*
+ * 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 ___iprt_cpp_list_h
+#define ___iprt_cpp_list_h
+
+#include <iprt/cpp/meta.h>
+#include <iprt/mem.h>
+#include <iprt/string.h> /* for memcpy */
+
+#include <new> /* For std::bad_alloc */
+
+/** @defgroup grp_rt_cpp_list C++ List support
+ * @ingroup grp_rt_cpp
+ *
+ * @brief Generic C++ list class support.
+ *
+ * This list classes manage any amount of data in a fast and easy to use way.
+ * They have no dependencies on STL, only on generic memory management methods
+ * of IRPT. This allows list handling in situations where the use of STL
+ * container classes is forbidden.
+ *
+ * Not all of the functionality of STL container classes is implemented. There
+ * are no iterators or any other high level access/modifier methods (e.g.
+ * std::algorithms).
+ *
+ * The implementation is array based which allows fast access to the items.
+ * Appending items is usually also fast, cause the internal array is
+ * preallocated. To minimize the memory overhead, native types (that is
+ * everything smaller then the size of void*) are directly saved in the array.
+ * If bigger types are used (e.g. RTCString) the internal array is an array of
+ * pointers to the objects.
+ *
+ * The size of the internal array will usually not shrink, but grow
+ * automatically. Only certain methods, like RTCList::clear or the "=" operator
+ * will reset any previously allocated memory. You can call
+ * RTCList::setCapacity for manual adjustment. If the size of an new list will
+ * be known, calling the constructor with the necessary capacity will speed up
+ * the insertion of the new items.
+ *
+ * For the full public interface these list classes offer see RTCListBase.
+ *
+ * There are some requirements for the types used which follow:
+ * -# They need a default and a copy constructor.
+ * -# Some methods (e.g. RTCList::contains) need an equal operator.
+ * -# If the type is some complex class (that is, having a constructor which
+ * allocates members on the heap) it has to be greater than sizeof(void*) to
+ * be used correctly. If this is not the case you can manually overwrite the
+ * list behavior. Just add T* as a second parameter to the list template if
+ * your class is called T. Another possibility is to specialize the list for
+ * your target class. See below for more information.
+ *
+ * The native types like int, bool, ptr, ..., are meeting this criteria, so
+ * they are save to use.
+ *
+ * Please note that the return type of some of the getter methods are slightly
+ * different depending on the list type. Native types return the item by value,
+ * items with a size greater than sizeof(void*) by reference. As native types
+ * saved directly in the internal array, returning a reference to them (and
+ * saving them in a reference as well) would make them invalid (or pointing to
+ * a wrong item) when the list is changed in the meanwhile. Returning a
+ * reference for bigger types isn't problematic and makes sure we get out the
+ * best speed of the list. The one exception to this rule is the index
+ * operator[]. This operator always return a reference to make it possible to
+ * use it as a lvalue. Its your responsibility to make sure the list isn't
+ * changed when using the value as reference returned by this operator.
+ *
+ * The list class is reentrant. For a thread-safe variant see RTCMTList.
+ *
+ * Implementation details:
+ * It is possible to specialize any type. This might be necessary to get the
+ * best speed out of the list. Examples are the 64-bit types, which use the
+ * native (no pointers) implementation even on a 32-bit host. Consult the
+ * source code for more details.
+ *
+ * Current specialized implementations:
+ * - int64_t: RTCList<int64_t>
+ * - uint64_t: RTCList<uint64_t>
+ *
+ * @{
+ */
+
+/**
+ * The guard definition.
+ */
+template <bool G>
+class RTCListGuard;
+
+/**
+ * The default guard which does nothing.
+ */
+template <>
+class RTCListGuard<false>
+{
+public:
+ inline void enterRead() const {}
+ inline void leaveRead() const {}
+ inline void enterWrite() {}
+ inline void leaveWrite() {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * General helper template for managing native values in RTCListBase.
+ */
+template <typename T1, typename T2>
+class RTCListHelper
+{
+public:
+ static inline void set(T2 *p, size_t i, const T1 &v) { p[i] = v; }
+ static inline T1 & at(T2 *p, size_t i) { return p[i]; }
+ static inline size_t find(T2 *p, const T1 &v, size_t cSize)
+ {
+ size_t i = 0;
+ while(i < cSize)
+ {
+ if (p[i] == v)
+ break;
+ ++i;
+ }
+ return i;
+ }
+ static inline void copyTo(T2 *p, T2 *const p1 , size_t iTo, size_t cSize)
+ {
+ if (cSize > 0)
+ memcpy(&p[iTo], &p1[0], sizeof(T1) * cSize);
+ }
+ static inline void erase(T2 *p, size_t /* i */) { /* Nothing to do here. */ }
+ static inline void eraseRange(T2 * /* p */, size_t /* cFrom */, size_t /* cSize */) { /* Nothing to do here. */ }
+};
+
+/**
+ * Specialized helper template for managing pointer values in RTCListBase.
+ */
+template <typename T1>
+class RTCListHelper<T1, T1*>
+{
+public:
+ static inline void set(T1 **p, size_t i, const T1 &v) { p[i] = new T1(v); }
+ static inline T1 & at(T1 **p, size_t i) { return *p[i]; }
+ static inline size_t find(T1 **p, const T1 &v, size_t cSize)
+ {
+ size_t i = 0;
+ while(i < cSize)
+ {
+ if (*p[i] == v)
+ break;
+ ++i;
+ }
+ return i;
+ }
+ static inline void copyTo(T1 **p, T1 **const p1 , size_t iTo, size_t cSize)
+ {
+ for (size_t i = 0; i < cSize; ++i)
+ p[iTo + i] = new T1(*p1[i]);
+ }
+ static inline void erase(T1 **p, size_t i) { delete p[i]; }
+ static inline void eraseRange(T1 **p, size_t cFrom, size_t cSize)
+ {
+ for (size_t i = cFrom; i < cFrom + cSize; ++i)
+ delete p[i];
+ }
+};
+
+/**
+ * This is the base class for all other list classes. It implements the
+ * necessary list functionality in a type independent way and offers the public
+ * list interface to the user.
+ */
+template <class T, typename ITYPE, bool MT>
+class RTCListBase
+{
+ /**
+ * Traits
+ *
+ * Defines the return type of most of the getter methods. If the internal
+ * used type is a pointer, we return a reference. If not we return by
+ * value.
+ */
+ typedef typename RTCIfPtr<ITYPE, T&, T>::result GET_RTYPE;
+ typedef typename RTCIfPtr<ITYPE, const T&, T>::result GET_CRTYPE;
+
+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
+ */
+ RTCListBase(size_t cCapacity = DefaultCapacity)
+ : m_pArray(0)
+ , m_cSize(0)
+ , m_cCapacity(0)
+ {
+ if (cCapacity > 0)
+ realloc_grow(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.
+ *
+ * @param other The list to copy.
+ * @throws std::bad_alloc
+ */
+ RTCListBase(const RTCListBase<T, ITYPE, MT>& other)
+ : m_pArray(0)
+ , m_cSize(0)
+ , m_cCapacity(0)
+ {
+ realloc_no_elements_clean(other.m_cSize);
+ RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
+ m_cSize = other.m_cSize;
+ }
+
+ /**
+ * Destructor.
+ */
+ ~RTCListBase()
+ {
+ RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
+ if (m_pArray)
+ RTMemFree(m_pArray);
+ }
+
+ /**
+ * Sets a new capacity within the list.
+ *
+ * If the new capacity is bigger than the old size, it will be simply
+ * preallocated more space for the new items. If the new capacity is
+ * smaller than the previous size, items at the end of the list will be
+ * deleted.
+ *
+ * @param cCapacity The new capacity within the list.
+ * @throws std::bad_alloc
+ */
+ void setCapacity(size_t cCapacity)
+ {
+ m_guard.enterWrite();
+ realloc(cCapacity);
+ m_guard.leaveWrite();
+ }
+
+ /**
+ * Return the current capacity of the list.
+ *
+ * @return The actual capacity.
+ */
+ size_t capacity() const { return m_cCapacity; }
+
+ /**
+ * Check if an list contains any items.
+ *
+ * @return True if there is more than zero items, false otherwise.
+ */
+ bool isEmpty() const { return m_cSize == 0; }
+
+ /**
+ * Return the current count of elements within the list.
+ *
+ * @return The current element count.
+ */
+ size_t size() const { return m_cSize; }
+
+ /**
+ * Inserts an item to the list at position @a i.
+ *
+ * @param i The position of the new item.
+ * @param val The new item.
+ * @return a reference to this list.
+ * @throws std::bad_alloc
+ */
+ RTCListBase<T, ITYPE, MT> &insert(size_t i, const T &val)
+ {
+ m_guard.enterWrite();
+ if (m_cSize == m_cCapacity)
+ realloc_grow(m_cCapacity + DefaultCapacity);
+ memmove(&m_pArray[i + 1], &m_pArray[i], (m_cSize - i) * sizeof(ITYPE));
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, val);
+ ++m_cSize;
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * Prepend an item to the list.
+ *
+ * @param val The new item.
+ * @return a reference to this list.
+ * @throws std::bad_alloc
+ */
+ RTCListBase<T, ITYPE, MT> &prepend(const T &val)
+ {
+ return insert(0, val);
+ }
+
+ /**
+ * Prepend a list of type T to the list.
+ *
+ * @param other The list to prepend.
+ * @return a reference to this list.
+ * @throws std::bad_alloc
+ */
+ RTCListBase<T, ITYPE, MT> &prepend(const RTCListBase<T, ITYPE, MT> &other)
+ {
+ m_guard.enterWrite();
+ if (m_cCapacity - m_cSize < other.m_cSize)
+ realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize)));
+ memmove(&m_pArray[other.m_cSize], &m_pArray[0], m_cSize * sizeof(ITYPE));
+ RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
+ m_cSize += other.m_cSize;
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * Append an item to the list.
+ *
+ * @param val The new item.
+ * @return a reference to this list.
+ * @throws std::bad_alloc
+ */
+ RTCListBase<T, ITYPE, MT> &append(const T &val)
+ {
+ m_guard.enterWrite();
+ if (m_cSize == m_cCapacity)
+ realloc_grow(m_cCapacity + DefaultCapacity);
+ RTCListHelper<T, ITYPE>::set(m_pArray, m_cSize, val);
+ ++m_cSize;
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * Append a list of type T to the list.
+ *
+ * @param other The list to append.
+ * @return a reference to this list.
+ * @throws std::bad_alloc
+ */
+ RTCListBase<T, ITYPE, MT> &append(const RTCListBase<T, ITYPE, MT> &other)
+ {
+ m_guard.enterWrite();
+ if (RT_LIKELY(other.m_cSize > 0))
+ {
+ if (m_cCapacity - m_cSize < other.m_cSize)
+ realloc_grow(m_cCapacity + (other.m_cSize - (m_cCapacity - m_cSize)));
+ RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, m_cSize, other.m_cSize);
+ m_cSize += other.m_cSize;
+ }
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * 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.
+ */
+ RTCListBase<T, ITYPE, MT> &operator=(const RTCListBase<T, ITYPE, MT>& other)
+ {
+ /* Prevent self assignment */
+ if (RT_UNLIKELY(this == &other))
+ return *this;
+
+ m_guard.enterWrite();
+ /* Delete all items. */
+ RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
+ /* Need we to realloc memory. */
+ if (other.m_cSize != m_cCapacity)
+ realloc_no_elements_clean(other.m_cSize);
+ m_cSize = other.m_cSize;
+ /* Copy new items. */
+ RTCListHelper<T, ITYPE>::copyTo(m_pArray, other.m_pArray, 0, other.m_cSize);
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * Replace an item in the list.
+ *
+ * @note No boundary checks are done. Make sure @a i is equal or greater zero
+ * and smaller than RTCList::size.
+ *
+ * @param i The position of the item to replace.
+ * @param val The new value.
+ * @return a reference to this list.
+ */
+ RTCListBase<T, ITYPE, MT> &replace(size_t i, const T &val)
+ {
+ m_guard.enterWrite();
+ RTCListHelper<T, ITYPE>::erase(m_pArray, i);
+ RTCListHelper<T, ITYPE>::set(m_pArray, i, val);
+ m_guard.leaveWrite();
+
+ return *this;
+ }
+
+ /**
+ * Return the first item as constant object.
+ *
+ * @note No boundary checks are done. Make sure there is at least one
+ * element.
+ *
+ * @return The first item.
+ */
+ GET_CRTYPE first() const
+ {
+ m_guard.enterRead();
+ GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the first item.
+ *
+ * @note No boundary checks are done. Make sure there is at least one
+ * element.
+ *
+ * @return The first item.
+ */
+ GET_RTYPE first()
+ {
+ m_guard.enterRead();
+ GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, 0);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the last item as constant object.
+ *
+ * @note No boundary checks are done. Make sure there is at least one
+ * element.
+ *
+ * @return The last item.
+ */
+ GET_CRTYPE last() const
+ {
+ m_guard.enterRead();
+ GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the last item.
+ *
+ * @note No boundary checks are done. Make sure there is at least one
+ * element.
+ *
+ * @return The last item.
+ */
+ GET_RTYPE last()
+ {
+ m_guard.enterRead();
+ GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, m_cSize - 1);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the item at position @a i as constant object.
+ *
+ * @note No boundary checks are done. Make sure @a i is equal or greater zero
+ * and smaller than RTCList::size.
+ *
+ * @param i The position of the item to return.
+ * @return The item at position @a i.
+ */
+ GET_CRTYPE at(size_t i) const
+ {
+ m_guard.enterRead();
+ GET_CRTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the item at position @a i.
+ *
+ * @note No boundary checks are done. Make sure @a i is equal or greater zero
+ * and smaller than RTCList::size.
+ *
+ * @param i The position of the item to return.
+ * @return The item at position @a i.
+ */
+ GET_RTYPE at(size_t i)
+ {
+ m_guard.enterRead();
+ GET_RTYPE res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the item at position @a i as mutable reference.
+ *
+ * @note No boundary checks are done. Make sure @a i is equal or greater zero
+ * and smaller than RTCList::size.
+ *
+ * @param i The position of the item to return.
+ * @return The item at position @a i.
+ */
+ T &operator[](size_t i)
+ {
+ m_guard.enterRead();
+ T &res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the item at position @a i. If @a i isn't valid within the list a
+ * default value is returned.
+ *
+ * @param i The position of the item to return.
+ * @return The item at position @a i.
+ */
+ T value(size_t i) const
+ {
+ m_guard.enterRead();
+ if (RT_UNLIKELY(i >= m_cSize))
+ {
+ m_guard.leaveRead();
+ return T();
+ }
+ T res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Return the item at position @a i. If @a i isn't valid within the list
+ * @a defaultVal is returned.
+ *
+ * @param i The position of the item to return.
+ * @param defaultVal The value to return in case @a i is invalid.
+ * @return The item at position @a i.
+ */
+ T value(size_t i, const T &defaultVal) const
+ {
+ m_guard.enterRead();
+ if (RT_UNLIKELY(i >= m_cSize))
+ {
+ m_guard.leaveRead();
+ return defaultVal;
+ }
+ T res = RTCListHelper<T, ITYPE>::at(m_pArray, i);
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Check if @a val is contained in the array.
+ *
+ * @param val The value to check for.
+ * @return true if it is found, false otherwise.
+ */
+ bool contains(const T &val) const
+ {
+ m_guard.enterRead();
+ bool res = RTCListHelper<T, ITYPE>::find(m_pArray, val, m_cSize) != m_cSize;
+ m_guard.leaveRead();
+ return res;
+ }
+
+ /**
+ * Remove the first item.
+ *
+ * @note No boundary checks are done. Make sure there is at least one
+ * element.
+ */
+ void removeFirst()
+ {
+ removeAt(0);
+ }
+
+ /**
+ * Remove the last item.
+ *
+ * @note No boundary checks are done. Make sure there is at least one
+ * element.
+ */
+ void removeLast()
+ {
+ removeAt(m_cSize - 1);
+ }
+
+ /**
+ * Remove the item at position @a i.
+ *
+ * @note No boundary checks are done. Make sure @a i is equal or greater zero
+ * and smaller than RTCList::size.
+ *
+ * @param i The position of the item to remove.
+ */
+ void removeAt(size_t i)
+ {
+ m_guard.enterWrite();
+ RTCListHelper<T, ITYPE>::erase(m_pArray, i);
+ /* Not last element? */
+ if (i < m_cSize - 1)
+ memmove(&m_pArray[i], &m_pArray[i + 1], (m_cSize - i - 1) * sizeof(ITYPE));
+ --m_cSize;
+ m_guard.leaveWrite();
+ }
+
+ /**
+ * Remove a range of items from the list.
+ *
+ * @note No boundary checks are done. Make sure @a iFrom is equal or
+ * greater zero and smaller than RTCList::size. @a iTo has to be
+ * greater than @a iFrom and equal or smaller than RTCList::size.
+ *
+ * @param iFrom The start position of the items to remove.
+ * @param iTo The end position of the items to remove (excluded).
+ */
+ void removeRange(size_t iFrom, size_t iTo)
+ {
+ m_guard.enterWrite();
+ RTCListHelper<T, ITYPE>::eraseRange(m_pArray, iFrom, iTo - iFrom);
+ /* Not last elements? */
+ if (m_cSize - iTo > 0)
+ memmove(&m_pArray[iFrom], &m_pArray[iTo], (m_cSize - iTo) * sizeof(ITYPE));
+ m_cSize -= iTo - iFrom;
+ m_guard.leaveWrite();
+ }
+
+ /**
+ * Delete all items in the list.
+ */
+ void clear()
+ {
+ m_guard.enterWrite();
+ /* Values cleanup */
+ RTCListHelper<T, ITYPE>::eraseRange(m_pArray, 0, m_cSize);
+ if (m_cSize != DefaultCapacity)
+ realloc_no_elements_clean(DefaultCapacity);
+ m_cSize = 0;
+ m_guard.leaveWrite();
+ }
+
+ /**
+ * Return the raw array. For native types this is a pointer to continuous
+ * memory of the items. For pointer types this is a continuous memory of
+ * pointers to the items.
+ *
+ * @warning If you change anything in the underlaying list, this memory
+ * will very likely become invalid. So take care when using this
+ * method and better try to avoid using it.
+ *
+ * @returns the raw memory.
+ */
+ ITYPE* raw() const
+ {
+ m_guard.enterRead();
+ ITYPE* res = m_pArray;
+ m_guard.leaveRead();
+ return res;
+ }
+
+ RTCListBase<T, ITYPE, MT> &operator<<(const T &val)
+ {
+ return append(val);
+ }
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+
+ /**
+ * The default capacity of the list. This is also used as grow factor.
+ */
+ static const size_t DefaultCapacity;
+
+protected:
+
+ /**
+ * Generic realloc, which does some kind of boundary checking.
+ */
+ void realloc(size_t cNewSize)
+ {
+ /* Same size? */
+ if (cNewSize == m_cCapacity)
+ return;
+
+ /* If we get smaller we have to delete some of the objects at the end
+ of the list. */
+ if ( cNewSize < m_cSize
+ && m_pArray)
+ RTCListHelper<T, ITYPE>::eraseRange(m_pArray, cNewSize, m_cSize - cNewSize);
+ realloc_no_elements_clean(cNewSize);
+ }
+
+ void realloc_no_elements_clean(size_t cNewSize)
+ {
+ /* Same size? */
+ if (cNewSize == m_cCapacity)
+ return;
+
+ /* If we get smaller we have to delete some of the objects at the end
+ of the list. */
+ if ( cNewSize < m_cSize
+ && m_pArray)
+ m_cSize -= m_cSize - cNewSize;
+
+ /* If we get zero we delete the array it self. */
+ if ( cNewSize == 0
+ && m_pArray)
+ {
+ RTMemFree(m_pArray);
+ m_pArray = 0;
+ }
+ m_cCapacity = cNewSize;
+
+ /* Resize the array. */
+ if (cNewSize > 0)
+ {
+ m_pArray = static_cast<ITYPE*>(RTMemRealloc(m_pArray, sizeof(ITYPE) * cNewSize));
+ if (!m_pArray)
+ {
+ /** @todo you leak memory. */
+ m_cCapacity = 0;
+ m_cSize = 0;
+#ifdef RT_EXCEPTIONS_ENABLED
+ throw std::bad_alloc();
+#endif
+ }
+ }
+ }
+
+ /**
+ * Special realloc method which require that the array will grow.
+ *
+ * @note No boundary checks are done!
+ */
+ void realloc_grow(size_t cNewSize)
+ {
+ /* Resize the array. */
+ m_cCapacity = cNewSize;
+ m_pArray = static_cast<ITYPE*>(RTMemRealloc(m_pArray, sizeof(ITYPE) * cNewSize));
+ if (!m_pArray)
+ {
+ /** @todo you leak memory. */
+ m_cCapacity = 0;
+ m_cSize = 0;
+#ifdef RT_EXCEPTIONS_ENABLED
+ throw std::bad_alloc();
+#endif
+ }
+ }
+
+ /** The internal list array. */
+ ITYPE *m_pArray;
+ /** The current count of items in use. */
+ size_t m_cSize;
+ /** The current capacity of the internal array. */
+ size_t m_cCapacity;
+ /** The guard used to serialize the access to the items. */
+ RTCListGuard<MT> m_guard;
+};
+
+template <class T, typename ITYPE, bool MT>
+const size_t RTCListBase<T, ITYPE, MT>::DefaultCapacity = 10;
+
+/**
+ * Template class which automatically determines the type of list to use.
+ *
+ * @see RTCListBase
+ */
+template <class T, typename ITYPE = typename RTCIf<(sizeof(T) > sizeof(void*)), T*, T>::result>
+class RTCList : public RTCListBase<T, ITYPE, false>
+{
+ /* Traits */
+ typedef RTCListBase<T, ITYPE, false> 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) {}
+
+ RTCList(const BASE &other)
+ : BASE(other) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * Specialized class for using the native type list for unsigned 64-bit
+ * values even on a 32-bit host.
+ *
+ * @see RTCListBase
+ */
+template <>
+class RTCList<uint64_t>: public RTCListBase<uint64_t, uint64_t, false>
+{
+ /* Traits */
+ typedef RTCListBase<uint64_t, uint64_t, false> 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 class for using the native type list for signed 64-bit
+ * values even on a 32-bit host.
+ *
+ * @see RTCListBase
+ */
+template <>
+class RTCList<int64_t>: public RTCListBase<int64_t, int64_t, false>
+{
+ /* Traits */
+ typedef RTCListBase<int64_t, int64_t, false> 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();
+};
+
+/** @} */
+
+#endif /* !___iprt_cpp_list_h */
+
diff --git a/include/iprt/cpp/lock.h b/include/iprt/cpp/lock.h
new file mode 100644
index 00000000..1ea6c3cc
--- /dev/null
+++ b/include/iprt/cpp/lock.h
@@ -0,0 +1,166 @@
+/** @file
+ * IPRT - Classes for Scope-based Locking.
+ */
+
+/*
+ * Copyright (C) 2007-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___iprt_cpp_lock_h
+#define ___iprt_cpp_lock_h
+
+#include <iprt/critsect.h>
+#ifdef RT_LOCK_STRICT
+# include <iprt/lockvalidator.h>
+#endif
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_cpp_lock C++ Scope-based Locking
+ * @ingroup grp_rt_cpp
+ * @{
+ */
+
+class RTCLock;
+
+/**
+ * The mutex lock.
+ *
+ * This is used as an object data member if the intention is to lock
+ * a single object. This can also be used statically, initialized in
+ * a global variable, for class wide purposes.
+ *
+ * This is best used together with RTCLock.
+ */
+class RTCLockMtx
+{
+friend class RTCLock;
+
+private:
+ RTCRITSECT mMtx;
+
+public:
+ RTCLockMtx()
+ {
+#ifdef RT_LOCK_STRICT_ORDER
+ RTCritSectInitEx(&mMtx, 0 /*fFlags*/,
+ RTLockValidatorClassCreateUnique(RT_SRC_POS, NULL),
+ RTLOCKVAL_SUB_CLASS_NONE, NULL);
+#else
+ RTCritSectInit(&mMtx);
+#endif
+ }
+
+ /** Use to when creating locks that belongs in the same "class". */
+ RTCLockMtx(RT_SRC_POS_DECL, uint32_t uSubClass = RTLOCKVAL_SUB_CLASS_NONE)
+ {
+#ifdef RT_LOCK_STRICT_ORDER
+ RTCritSectInitEx(&mMtx, 0 /*fFlags*/,
+ RTLockValidatorClassForSrcPos(RT_SRC_POS_ARGS, NULL),
+ uSubClass, NULL);
+#else
+ NOREF(uSubClass);
+ RTCritSectInit(&mMtx);
+ RT_SRC_POS_NOREF();
+#endif
+ }
+
+ ~RTCLockMtx()
+ {
+ RTCritSectDelete(&mMtx);
+ }
+
+ /* lock() and unlock() are private so that only friend RTCLock can access
+ them. */
+private:
+ inline void lock()
+ {
+ RTCritSectEnter(&mMtx);
+ }
+
+ inline void unlock()
+ {
+ RTCritSectLeave(&mMtx);
+ }
+};
+
+
+/**
+ * The stack object for automatic locking and unlocking.
+ *
+ * This is a helper class for automatic locks, to simplify requesting a
+ * RTCLockMtx and to not forget releasing it. To request a RTCLockMtx, simply
+ * create an instance of RTCLock on the stack and pass the mutex to it:
+ *
+ * @code
+ extern RTCLockMtx gMtx; // wherever this is
+ ...
+ if (...)
+ {
+ RTCLock lock(gMtx);
+ ... // do stuff
+ // when lock goes out of scope, destructor releases the mutex
+ }
+ @endcode
+ *
+ * You can also explicitly release the mutex by calling RTCLock::release().
+ * This might be helpful if the lock doesn't go out of scope early enough
+ * for your mutex to be released.
+ */
+class RTCLock
+{
+private:
+ /** Reference to the lock we're holding. */
+ RTCLockMtx &m_rMtx;
+ /** Whether we're currently holding the lock of if it was already
+ * explictily released by the release() method. */
+ bool m_fLocked;
+
+public:
+ RTCLock(RTCLockMtx &a_rMtx)
+ : m_rMtx(a_rMtx)
+ {
+ m_rMtx.lock();
+ m_fLocked = true;
+ }
+
+ ~RTCLock()
+ {
+ if (m_fLocked)
+ m_rMtx.unlock();
+ }
+
+ inline void release()
+ {
+ if (m_fLocked)
+ {
+ m_rMtx.unlock();
+ m_fLocked = false;
+ }
+ }
+};
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/cpp/mem.h b/include/iprt/cpp/mem.h
new file mode 100644
index 00000000..66f6ab95
--- /dev/null
+++ b/include/iprt/cpp/mem.h
@@ -0,0 +1,271 @@
+/** @file
+ * IPRT - C++ Memory Resource Management.
+ */
+
+/*
+ * 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 ___iprt_cpp_mem_h
+#define ___iprt_cpp_mem_h
+
+#include <iprt/cpp/autores.h>
+#include <iprt/assert.h>
+#include <iprt/mem.h>
+#include <iprt/string.h> /* for memset */
+
+/** @defgroup grp_rt_cpp_autores_mem C++ Memory Resource Management
+ * @ingroup grp_rt_cpp_autores
+ * @{
+ */
+
+/**
+ * Template function wrapping RTMemFree to get the correct a_fnDestruct
+ * signature for RTCAutoRes.
+ *
+ * We can't use a more complex template here, because the g++ on RHEL 3
+ * chokes on it with an internal compiler error.
+ *
+ * @tparam T The data type that's being managed.
+ * @param aMem Pointer to the memory that should be free.
+ */
+template <class T>
+inline void RTCMemAutoDestructor(T *aMem) RT_NO_THROW
+{
+ RTMemFree(aMem);
+}
+
+
+/**
+ * RTCMemAutoPtr allocator which uses RTMemTmpAlloc().
+ *
+ * @returns Allocated memory on success, NULL on failure.
+ * @param pvOld What to reallocate, shall always be NULL.
+ * @param cbNew The amount of memory to allocate (in bytes).
+ */
+inline void *RTCMemTmpAutoAllocator(void *pvOld, size_t cbNew) RT_NO_THROW
+{
+ AssertReturn(!pvOld, NULL);
+ return RTMemTmpAlloc(cbNew);
+}
+
+
+/**
+ * Template function wrapping RTMemTmpFree to get the correct a_fnDestruct
+ * signature for RTCAutoRes.
+ *
+ * We can't use a more complex template here, because the g++ on RHEL 3
+ * chokes on it with an internal compiler error.
+ *
+ * @tparam T The data type that's being managed.
+ * @param aMem Pointer to the memory that should be free.
+ */
+template <class T>
+inline void RTCMemTmpAutoDestructor(T *aMem) RT_NO_THROW
+{
+ RTMemTmpFree(aMem);
+}
+
+
+/**
+ * Template function wrapping RTMemEfFree to get the correct a_fnDestruct
+ * signature for RTCAutoRes.
+ *
+ * We can't use a more complex template here, because the g++ on RHEL 3
+ * chokes on it with an internal compiler error.
+ *
+ * @tparam T The data type that's being managed.
+ * @param aMem Pointer to the memory that should be free.
+ */
+template <class T>
+inline void RTCMemEfAutoFree(T *aMem) RT_NO_THROW
+{
+ RTMemEfFreeNP(aMem);
+}
+
+
+/**
+ * Template function wrapping NULL to get the correct NilRes signature
+ * for RTCAutoRes.
+ *
+ * @tparam T The data type that's being managed.
+ * @returns NULL with the right type.
+ */
+template <class T>
+inline T *RTCMemAutoNil(void) RT_NO_THROW
+{
+ return (T *)(NULL);
+}
+
+
+/**
+ * An auto pointer-type template class for managing memory allocating
+ * via C APIs like RTMem (the default).
+ *
+ * The main purpose of this class is to automatically free memory that
+ * isn't explicitly used (release()'ed) when the object goes out of scope.
+ *
+ * As an additional service it can also make the allocations and
+ * reallocations for you if you like, but it can also take of memory
+ * you hand it.
+ *
+ * @tparam T The data type to manage allocations for.
+ * @tparam a_fnDestruct The function to be used to free the resource.
+ * This will default to RTMemFree.
+ * @tparam a_fnAllocator The function to be used to allocate or reallocate
+ * the managed memory.
+ * This is standard realloc() like stuff, so it's
+ * possible to support simple allocation without
+ * actually having to support reallocating memory if
+ * that's a problem. This will default to
+ * RTMemRealloc.
+ */
+template <class T,
+ void a_fnDestruct(T *) = RTCMemAutoDestructor<T>,
+# if defined(RTMEM_WRAP_TO_EF_APIS) && !defined(RTMEM_NO_WRAP_TO_EF_APIS)
+ void *a_fnAllocator(void *, size_t, const char *) = RTMemEfReallocNP
+# else
+ void *a_fnAllocator(void *, size_t, const char *) = RTMemReallocTag
+# endif
+ >
+class RTCMemAutoPtr
+ : public RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >
+{
+public:
+ /**
+ * Constructor.
+ *
+ * @param aPtr Memory pointer to manage. Defaults to NULL.
+ */
+ RTCMemAutoPtr(T *aPtr = NULL)
+ : RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >(aPtr)
+ {
+ }
+
+ /**
+ * Constructor that allocates memory.
+ *
+ * @param a_cElements The number of elements (of the data type) to allocate.
+ * @param a_fZeroed Whether the memory should be memset with zeros after
+ * the allocation. Defaults to false.
+ */
+ RTCMemAutoPtr(size_t a_cElements, bool a_fZeroed = false)
+ : RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >((T *)a_fnAllocator(NULL, a_cElements * sizeof(T), RTMEM_TAG))
+ {
+ if (a_fZeroed && RT_LIKELY(this->get() != NULL))
+ memset(this->get(), '\0', a_cElements * sizeof(T));
+ }
+
+ /**
+ * Free current memory and start managing aPtr.
+ *
+ * @param aPtr Memory pointer to manage.
+ */
+ RTCMemAutoPtr &operator=(T *aPtr)
+ {
+ this->RTCAutoRes<T *, a_fnDestruct, RTCMemAutoNil<T> >::operator=(aPtr);
+ return *this;
+ }
+
+ /**
+ * Dereference with * operator.
+ */
+ T &operator*()
+ {
+ return *this->get();
+ }
+
+ /**
+ * Dereference with -> operator.
+ */
+ T *operator->()
+ {
+ return this->get();
+ }
+
+ /**
+ * Accessed with the subscript operator ([]).
+ *
+ * @returns Reference to the element.
+ * @param a_i The element to access.
+ */
+ T &operator[](size_t a_i)
+ {
+ return this->get()[a_i];
+ }
+
+ /**
+ * Allocates memory and start manage it.
+ *
+ * Any previously managed memory will be freed before making
+ * the new allocation.
+ *
+ * @returns Success indicator.
+ * @retval true if the new allocation succeeds.
+ * @retval false on failure, no memory is associated with the object.
+ *
+ * @param a_cElements The number of elements (of the data type) to allocate.
+ * This defaults to 1.
+ * @param a_fZeroed Whether the memory should be memset with zeros after
+ * the allocation. Defaults to false.
+ */
+ bool alloc(size_t a_cElements = 1, bool a_fZeroed = false)
+ {
+ this->reset(NULL);
+ T *pNewMem = (T *)a_fnAllocator(NULL, a_cElements * sizeof(T), RTMEM_TAG);
+ if (a_fZeroed && RT_LIKELY(pNewMem != NULL))
+ memset(pNewMem, '\0', a_cElements * sizeof(T));
+ this->reset(pNewMem);
+ return pNewMem != NULL;
+ }
+
+ /**
+ * Reallocate or allocates the memory resource.
+ *
+ * Free the old value if allocation fails.
+ *
+ * The content of any additional memory that was allocated is
+ * undefined when using the default allocator.
+ *
+ * @returns Success indicator.
+ * @retval true if the new allocation succeeds.
+ * @retval false on failure, no memory is associated with the object.
+ *
+ * @param a_cElements The new number of elements (of the data type) to
+ * allocate. The size of the allocation is the number of
+ * elements times the size of the data type - this is
+ * currently what's passed down to the a_fnAllocator.
+ * This defaults to 1.
+ */
+ bool realloc(size_t a_cElements = 1)
+ {
+ T *aNewValue = (T *)a_fnAllocator(this->get(), a_cElements * sizeof(T), RTMEM_TAG);
+ if (RT_LIKELY(aNewValue != NULL))
+ this->release();
+ /* We want this both if aNewValue is non-NULL and if it is NULL. */
+ this->reset(aNewValue);
+ return aNewValue != NULL;
+ }
+};
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/cpp/meta.h b/include/iprt/cpp/meta.h
new file mode 100644
index 00000000..81249d26
--- /dev/null
+++ b/include/iprt/cpp/meta.h
@@ -0,0 +1,110 @@
+/** @file
+ * IPRT - C++ Meta programming.
+ */
+
+/*
+ * 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 ___iprt_cpp_meta_h
+#define ___iprt_cpp_meta_h
+
+/** @defgroup grp_rt_cpp_meta C++ Meta programming utilities
+ * @ingroup grp_rt_cpp
+ * @{
+ */
+
+/**
+ * Check for a condition on compile time and dependent of the result TrueResult
+ * or FalseResult will be defined.
+ *
+ * @param Condition Condition to check.
+ * @param TrueResult Result when condition is true.
+ * @param FalseResult Result when condition is false
+ */
+template <bool Condition, typename TrueResult, typename FalseResult>
+struct RTCIf;
+
+/**
+ * Check for a condition on compile time and dependent of the result TrueResult
+ * or FalseResult will be defined.
+ *
+ * True specialization of RTCIf.
+ *
+ * @param TrueResult Result when condition is true.
+ * @param FalseResult Result when condition is false
+ */
+template <typename TrueResult, typename FalseResult>
+struct RTCIf<true, TrueResult, FalseResult>
+{
+ typedef TrueResult result;
+};
+
+/**
+ * Check for a condition on compile time and dependent of the result TrueResult
+ * or FalseResult will be defined.
+ *
+ * False specialization of RTCIf.
+ *
+ * @param TrueResult Result when condition is true.
+ * @param FalseResult Result when condition is false
+ */
+template <typename TrueResult, typename FalseResult>
+struct RTCIf<false, TrueResult, FalseResult>
+{
+ typedef FalseResult result;
+};
+
+/**
+ * Check if @a T is a pointer or not at compile time and dependent of the
+ * result TrueResult or FalseResult will be defined.
+ *
+ * False version of RTCIfPtr.
+ *
+ * @param Condition Condition to check.
+ * @param TrueResult Result when condition is true.
+ * @param FalseResult Result when condition is false
+ */
+template <class T, typename TrueResult, typename FalseResult>
+struct RTCIfPtr
+{
+ typedef FalseResult result;
+};
+
+/**
+ * Check if @a T is a pointer or not at compile time and dependent of the
+ * result TrueResult or FalseResult will be defined.
+ *
+ * True specialization of RTCIfPtr.
+ *
+ * @param Condition Condition to check.
+ * @param TrueResult Result when condition is true.
+ * @param FalseResult Result when condition is false
+ */
+template <class T, typename TrueResult, typename FalseResult>
+struct RTCIfPtr<T*, TrueResult, FalseResult>
+{
+ typedef TrueResult result;
+};
+
+/** @} */
+
+#endif /* !___iprt_cpp_meta_h */
+
diff --git a/include/iprt/cpp/ministring.h b/include/iprt/cpp/ministring.h
new file mode 100644
index 00000000..29c97409
--- /dev/null
+++ b/include/iprt/cpp/ministring.h
@@ -0,0 +1,1023 @@
+/** @file
+ * IPRT - C++ string class.
+ */
+
+/*
+ * Copyright (C) 2007-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___iprt_cpp_ministring_h
+#define ___iprt_cpp_ministring_h
+
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include <iprt/stdarg.h>
+#include <iprt/cpp/list.h>
+
+#include <new>
+
+
+/** @defgroup grp_rt_cpp_string C++ String support
+ * @ingroup grp_rt_cpp
+ * @{
+ */
+
+/** @brief C++ string class.
+ *
+ * This is a C++ string class that does not depend on anything else except IPRT
+ * memory management functions. Semantics are like in std::string, except it
+ * can do a lot less.
+ *
+ * Note that RTCString does not differentiate between NULL strings
+ * and empty strings. In other words, RTCString("") and RTCString(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 RTCString ASSUMES that all strings it deals with are valid UTF-8.
+ * The caller is responsible for not breaking this assumption.
+ */
+#ifdef VBOX
+ /** @remarks Much of the code in here used to be in com::Utf8Str so that
+ * com::Utf8Str can now derive from RTCString and only contain code
+ * that is COM-specific, such as com::Bstr conversions. Compared to
+ * the old Utf8Str though, RTCString always knows the length of its
+ * member string and the size of the buffer so it can use memcpy()
+ * instead of strdup().
+ */
+#endif
+class RT_DECL_CLASS RTCString
+{
+public:
+ /**
+ * Creates an empty string that has no memory allocated.
+ */
+ RTCString()
+ : m_psz(NULL),
+ m_cch(0),
+ m_cbAllocated(0)
+ {
+ }
+
+ /**
+ * Creates a copy of another RTCString.
+ *
+ * This allocates s.length() + 1 bytes for the new instance, unless s is empty.
+ *
+ * @param a_rSrc The source string.
+ *
+ * @throws std::bad_alloc
+ */
+ RTCString(const RTCString &a_rSrc)
+ {
+ copyFromN(a_rSrc.m_psz, a_rSrc.m_cch);
+ }
+
+ /**
+ * Creates a copy of a C string.
+ *
+ * This allocates strlen(pcsz) + 1 bytes for the new instance, unless s is empty.
+ *
+ * @param pcsz The source string.
+ *
+ * @throws std::bad_alloc
+ */
+ RTCString(const char *pcsz)
+ {
+ copyFromN(pcsz, pcsz ? strlen(pcsz) : 0);
+ }
+
+ /**
+ * Create a partial copy of another RTCString.
+ *
+ * @param a_rSrc The source string.
+ * @param a_offSrc The byte offset into the source string.
+ * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
+ * to copy from the source string.
+ */
+ RTCString(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos)
+ {
+ if (a_offSrc < a_rSrc.m_cch)
+ copyFromN(&a_rSrc.m_psz[a_offSrc], RT_MIN(a_cchSrc, a_rSrc.m_cch - a_offSrc));
+ else
+ {
+ m_psz = NULL;
+ m_cch = 0;
+ m_cbAllocated = 0;
+ }
+ }
+
+ /**
+ * Create a partial copy of a C string.
+ *
+ * @param a_pszSrc The source string (UTF-8).
+ * @param a_cchSrc The max number of chars (encoded UTF-8 bytes)
+ * to copy from the source string. This must not
+ * be '0' as the compiler could easily mistake
+ * that for the va_list constructor.
+ */
+ RTCString(const char *a_pszSrc, size_t a_cchSrc)
+ {
+ size_t cchMax = a_pszSrc ? RTStrNLen(a_pszSrc, a_cchSrc) : 0;
+ copyFromN(a_pszSrc, RT_MIN(a_cchSrc, cchMax));
+ }
+
+ /**
+ * Create a string containing @a a_cTimes repetitions of the character @a
+ * a_ch.
+ *
+ * @param a_cTimes The number of times the character is repeated.
+ * @param a_ch The character to fill the string with.
+ */
+ RTCString(size_t a_cTimes, char a_ch)
+ : m_psz(NULL),
+ m_cch(0),
+ m_cbAllocated(0)
+ {
+ Assert((unsigned)a_ch < 0x80);
+ if (a_cTimes)
+ {
+ reserve(a_cTimes + 1);
+ memset(m_psz, a_ch, a_cTimes);
+ m_psz[a_cTimes] = '\0';
+ m_cch = a_cTimes;
+ }
+ }
+
+ /**
+ * Create a new string given the format string and its arguments.
+ *
+ * @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 printfV
+ * @remarks Not part of std::string.
+ */
+ RTCString(const char *a_pszFormat, va_list a_va)
+ : m_psz(NULL),
+ m_cch(0),
+ m_cbAllocated(0)
+ {
+ printfV(a_pszFormat, a_va);
+ }
+
+ /**
+ * Destructor.
+ */
+ virtual ~RTCString()
+ {
+ cleanup();
+ }
+
+ /**
+ * String length in bytes.
+ *
+ * Returns the length of the member string in bytes, which is equal to strlen(c_str()).
+ * In other words, this does not count unicode codepoints; use utf8length() for that.
+ * The byte length is always cached so calling this is cheap and requires no
+ * strlen() invocation.
+ *
+ * @returns m_cbLength.
+ */
+ size_t length() const
+ {
+ return m_cch;
+ }
+
+ /**
+ * String length in unicode codepoints.
+ *
+ * As opposed to length(), which returns the length in bytes, this counts
+ * the number of unicode codepoints. This is *not* cached so calling this
+ * is expensive.
+ *
+ * @returns Number of codepoints in the member string.
+ */
+ size_t uniLength() const
+ {
+ return m_psz ? RTStrUniLen(m_psz) : 0;
+ }
+
+ /**
+ * The allocated buffer size (in bytes).
+ *
+ * Returns the number of bytes allocated in the internal string buffer, which is
+ * at least length() + 1 if length() > 0; for an empty string, this returns 0.
+ *
+ * @returns m_cbAllocated.
+ */
+ size_t capacity() const
+ {
+ return m_cbAllocated;
+ }
+
+ /**
+ * Make sure at that least cb of buffer space is reserved.
+ *
+ * Requests that the contained memory buffer have at least cb bytes allocated.
+ * This may expand or shrink the string's storage, but will never truncate the
+ * contained string. In other words, cb will be ignored if it's smaller than
+ * length() + 1.
+ *
+ * @param cb New minimum size (in bytes) of member memory buffer.
+ *
+ * @throws std::bad_alloc On allocation error. The object is left unchanged.
+ */
+ void reserve(size_t cb)
+ {
+ if ( cb != m_cbAllocated
+ && cb > m_cch + 1
+ )
+ {
+ int vrc = RTStrRealloc(&m_psz, cb);
+ if (RT_SUCCESS(vrc))
+ m_cbAllocated = cb;
+#ifdef RT_EXCEPTIONS_ENABLED
+ else
+ throw std::bad_alloc();
+#endif
+ }
+ }
+
+ /**
+ * Deallocates all memory.
+ */
+ inline void setNull()
+ {
+ cleanup();
+ }
+
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+
+ /**
+ * Assigns a copy of pcsz to "this".
+ *
+ * @param pcsz The source string.
+ *
+ * @throws std::bad_alloc On allocation failure. The object is left describing
+ * a NULL string.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &operator=(const char *pcsz)
+ {
+ if (m_psz != pcsz)
+ {
+ cleanup();
+ copyFromN(pcsz, pcsz ? strlen(pcsz) : 0);
+ }
+ return *this;
+ }
+
+ /**
+ * Assigns a copy of s to "this".
+ *
+ * @param s The source string.
+ *
+ * @throws std::bad_alloc On allocation failure. The object is left describing
+ * a NULL string.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &operator=(const RTCString &s)
+ {
+ if (this != &s)
+ {
+ cleanup();
+ copyFromN(s.m_psz, s.m_cch);
+ }
+ return *this;
+ }
+
+ /**
+ * Assigns the output of the string format operation (RTStrPrintf).
+ *
+ * @param pszFormat Pointer to the format string,
+ * @see pg_rt_str_format.
+ * @param ... Ellipsis containing the arguments specified by
+ * the format string.
+ *
+ * @throws std::bad_alloc On allocation error. The object is left unchanged.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &printf(const char *pszFormat, ...);
+
+ /**
+ * Assigns the output of the string format operation (RTStrPrintfV).
+ *
+ * @param pszFormat Pointer to the format string,
+ * @see pg_rt_str_format.
+ * @param va Argument vector containing the arguments
+ * specified by the format string.
+ *
+ * @throws std::bad_alloc On allocation error. The object is left unchanged.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &printfV(const char *pszFormat, va_list va);
+
+ /**
+ * Appends the string "that" to "this".
+ *
+ * @param that The string to append.
+ *
+ * @throws std::bad_alloc On allocation error. The object is left unchanged.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &append(const RTCString &that);
+
+ /**
+ * Appends the string "that" to "this".
+ *
+ * @param pszThat The C string to append.
+ *
+ * @throws std::bad_alloc On allocation error. The object is left unchanged.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &append(const char *pszThat);
+
+ /**
+ * Appends the given character to "this".
+ *
+ * @param ch The character to append.
+ *
+ * @throws std::bad_alloc On allocation error. The object is left unchanged.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &append(char ch);
+
+ /**
+ * Appends the given unicode code point to "this".
+ *
+ * @param uc The unicode code point to append.
+ *
+ * @throws std::bad_alloc On allocation error. The object is left unchanged.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &appendCodePoint(RTUNICP uc);
+
+ /**
+ * Shortcut to append(), RTCString variant.
+ *
+ * @param that The string to append.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &operator+=(const RTCString &that)
+ {
+ return append(that);
+ }
+
+ /**
+ * Shortcut to append(), const char* variant.
+ *
+ * @param pszThat The C string to append.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &operator+=(const char *pszThat)
+ {
+ return append(pszThat);
+ }
+
+ /**
+ * Shortcut to append(), char variant.
+ *
+ * @param pszThat The character to append.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &operator+=(char c)
+ {
+ return append(c);
+ }
+
+ /**
+ * Converts the member string to upper case.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &toUpper()
+ {
+ if (length())
+ {
+ /* Folding an UTF-8 string may result in a shorter encoding (see
+ testcase), so recalculate the length afterwars. */
+ ::RTStrToUpper(m_psz);
+ size_t cchNew = strlen(m_psz);
+ Assert(cchNew <= m_cch);
+ m_cch = cchNew;
+ }
+ return *this;
+ }
+
+ /**
+ * Converts the member string to lower case.
+ *
+ * @returns Reference to the object.
+ */
+ RTCString &toLower()
+ {
+ if (length())
+ {
+ /* Folding an UTF-8 string may result in a shorter encoding (see
+ testcase), so recalculate the length afterwars. */
+ ::RTStrToLower(m_psz);
+ size_t cchNew = strlen(m_psz);
+ Assert(cchNew <= m_cch);
+ m_cch = cchNew;
+ }
+ return *this;
+ }
+
+ /**
+ * Index operator.
+ *
+ * Returns the byte at the given index, or a null byte if the index is not
+ * smaller than length(). This does _not_ count codepoints but simply points
+ * into the member C string.
+ *
+ * @param i The index into the string buffer.
+ * @returns char at the index or null.
+ */
+ inline char operator[](size_t i) const
+ {
+ if (i < length())
+ return m_psz[i];
+ return '\0';
+ }
+
+ /**
+ * Returns the contained string as a C-style const char* pointer.
+ * This never returns NULL; if the string is empty, this returns a
+ * pointer to static null byte.
+ *
+ * @returns const pointer to C-style string.
+ */
+ inline const char *c_str() const
+ {
+ return (m_psz) ? m_psz : "";
+ }
+
+ /**
+ * Returns a non-const raw pointer that allows to modify the string directly.
+ * As opposed to c_str() and raw(), this DOES return NULL for an empty string
+ * because we cannot return a non-const pointer to a static "" global.
+ *
+ * @warning
+ * -# Be sure not to modify data beyond the allocated memory! Call
+ * capacity() to find out how large that buffer is.
+ * -# After any operation that modifies the length of the string,
+ * you _must_ call RTCString::jolt(), or subsequent copy operations
+ * may go nowhere. Better not use mutableRaw() at all.
+ */
+ char *mutableRaw()
+ {
+ return m_psz;
+ }
+
+ /**
+ * Clean up after using mutableRaw.
+ *
+ * Intended to be called after something has messed with the internal string
+ * buffer (e.g. after using mutableRaw() or Utf8Str::asOutParam()). Resets the
+ * internal lengths correctly. Otherwise subsequent copy operations may go
+ * nowhere.
+ */
+ void jolt()
+ {
+ if (m_psz)
+ {
+ m_cch = strlen(m_psz);
+ m_cbAllocated = m_cch + 1; /* (Required for the Utf8Str::asOutParam case) */
+ }
+ else
+ {
+ m_cch = 0;
+ m_cbAllocated = 0;
+ }
+ }
+
+ /**
+ * Returns @c true if the member string has no length.
+ *
+ * This is @c true for instances created from both NULL and "" input
+ * strings.
+ *
+ * This states nothing about how much memory might be allocated.
+ *
+ * @returns @c true if empty, @c false if not.
+ */
+ bool isEmpty() const
+ {
+ return length() == 0;
+ }
+
+ /**
+ * Returns @c false if the member string has no length.
+ *
+ * This is @c false for instances created from both NULL and "" input
+ * strings.
+ *
+ * This states nothing about how much memory might be allocated.
+ *
+ * @returns @c false if empty, @c true if not.
+ */
+ bool isNotEmpty() const
+ {
+ return length() != 0;
+ }
+
+ /** Case sensitivity selector. */
+ enum CaseSensitivity
+ {
+ CaseSensitive,
+ CaseInsensitive
+ };
+
+ /**
+ * Compares the member string to a C-string.
+ *
+ * @param pcszThat The string to compare with.
+ * @param cs Whether comparison should be case-sensitive.
+ * @returns 0 if equal, negative if this is smaller than @a pcsz, positive
+ * if larger.
+ */
+ int compare(const char *pcszThat, CaseSensitivity cs = CaseSensitive) const
+ {
+ /* This klugde is for m_cch=0 and m_psz=NULL. pcsz=NULL and psz=""
+ are treated the same way so that str.compare(str2.c_str()) works. */
+ if (length() == 0)
+ return pcszThat == NULL || *pcszThat == '\0' ? 0 : -1;
+
+ if (cs == CaseSensitive)
+ return ::RTStrCmp(m_psz, pcszThat);
+ return ::RTStrICmp(m_psz, pcszThat);
+ }
+
+ /**
+ * Compares the member string to another RTCString.
+ *
+ * @param pcszThat The string to compare with.
+ * @param cs Whether comparison should be case-sensitive.
+ * @returns 0 if equal, negative if this is smaller than @a pcsz, positive
+ * if larger.
+ */
+ int compare(const RTCString &that, CaseSensitivity cs = CaseSensitive) const
+ {
+ if (cs == CaseSensitive)
+ return ::RTStrCmp(m_psz, that.m_psz);
+ return ::RTStrICmp(m_psz, that.m_psz);
+ }
+
+ /**
+ * Compares the two strings.
+ *
+ * @returns true if equal, false if not.
+ * @param that The string to compare with.
+ */
+ bool equals(const RTCString &that) const
+ {
+ return that.length() == length()
+ && memcmp(that.m_psz, m_psz, length()) == 0;
+ }
+
+ /**
+ * Compares the two strings.
+ *
+ * @returns true if equal, false if not.
+ * @param pszThat The string to compare with.
+ */
+ bool equals(const char *pszThat) const
+ {
+ /* This klugde is for m_cch=0 and m_psz=NULL. pcsz=NULL and psz=""
+ are treated the same way so that str.equals(str2.c_str()) works. */
+ if (length() == 0)
+ return pszThat == NULL || *pszThat == '\0';
+ return RTStrCmp(pszThat, m_psz) == 0;
+ }
+
+ /**
+ * Compares the two strings ignoring differences in case.
+ *
+ * @returns true if equal, false if not.
+ * @param that The string to compare with.
+ */
+ bool equalsIgnoreCase(const RTCString &that) const
+ {
+ /* Unfolded upper and lower case characters may require different
+ amount of encoding space, so the length optimization doesn't work. */
+ return RTStrICmp(that.m_psz, m_psz) == 0;
+ }
+
+ /**
+ * Compares the two strings ignoring differences in case.
+ *
+ * @returns true if equal, false if not.
+ * @param pszThat The string to compare with.
+ */
+ bool equalsIgnoreCase(const char *pszThat) const
+ {
+ /* This klugde is for m_cch=0 and m_psz=NULL. pcsz=NULL and psz=""
+ are treated the same way so that str.equalsIgnoreCase(str2.c_str()) works. */
+ if (length() == 0)
+ return pszThat == NULL || *pszThat == '\0';
+ return RTStrICmp(pszThat, m_psz) == 0;
+ }
+
+ /** @name Comparison operators.
+ * @{ */
+ bool operator==(const RTCString &that) const { return equals(that); }
+ bool operator!=(const RTCString &that) const { return !equals(that); }
+ bool operator<( const RTCString &that) const { return compare(that) < 0; }
+ bool operator>( const RTCString &that) const { return compare(that) > 0; }
+
+ bool operator==(const char *pszThat) const { return equals(pszThat); }
+ bool operator!=(const char *pszThat) const { return !equals(pszThat); }
+ bool operator<( const char *pszThat) const { return compare(pszThat) < 0; }
+ bool operator>( const char *pszThat) const { return compare(pszThat) > 0; }
+ /** @} */
+
+ /** Max string offset value.
+ *
+ * When returned by a method, this indicates failure. When taken as input,
+ * typically a default, it means all the way to the string terminator.
+ */
+ static const size_t npos;
+
+ /**
+ * Find the given substring.
+ *
+ * Looks for pcszFind in "this" starting at "pos" and returns its position
+ * as a byte (not codepoint) offset, counting from the beginning of "this" at 0.
+ *
+ * @param pcszFind The substring to find.
+ * @param pos The (byte) offset into the string buffer to start
+ * searching.
+ *
+ * @returns 0 based position of pcszFind. npos if not found.
+ */
+ size_t find(const char *pcszFind, size_t pos = 0) const;
+
+ /**
+ * Replaces all occurences of cFind with cReplace in the member string.
+ * In order not to produce invalid UTF-8, the characters must be ASCII
+ * values less than 128; this is not verified.
+ *
+ * @param chFind Character to replace. Must be ASCII < 128.
+ * @param chReplace Character to replace cFind with. Must be ASCII < 128.
+ */
+ void findReplace(char chFind, char chReplace);
+
+ /**
+ * Count the occurences of the specified character in the string.
+ *
+ * @param ch What to search for. Must be ASCII < 128.
+ * @remarks QString::count
+ */
+ size_t count(char ch) const;
+
+ /**
+ * Count the occurences of the specified sub-string in the string.
+ *
+ * @param psz What to search for.
+ * @param cs Case sensitivity selector.
+ * @remarks QString::count
+ */
+ size_t count(const char *psz, CaseSensitivity cs = CaseSensitive) const;
+
+ /**
+ * Count the occurences of the specified sub-string in the string.
+ *
+ * @param pStr What to search for.
+ * @param cs Case sensitivity selector.
+ * @remarks QString::count
+ */
+ size_t count(const RTCString *pStr, CaseSensitivity cs = CaseSensitive) const;
+
+ /**
+ * Returns a substring of "this" as a new Utf8Str.
+ *
+ * Works exactly like its equivalent in std::string. With the default
+ * parameters "0" and "npos", this always copies the entire string. The
+ * "pos" and "n" arguments represent bytes; it is the caller's responsibility
+ * to ensure that the offsets do not copy invalid UTF-8 sequences. When
+ * used in conjunction with find() and length(), this will work.
+ *
+ * @param pos Index of first byte offset to copy from "this", counting from 0.
+ * @param n Number of bytes to copy, starting with the one at "pos".
+ * The copying will stop if the null terminator is encountered before
+ * n bytes have been copied.
+ */
+ RTCString substr(size_t pos = 0, size_t n = npos) const
+ {
+ return RTCString(*this, pos, n);
+ }
+
+ /**
+ * Returns a substring of "this" as a new Utf8Str. As opposed to substr(),
+ * this variant takes codepoint offsets instead of byte offsets.
+ *
+ * @param pos Index of first unicode codepoint to copy from
+ * "this", counting from 0.
+ * @param n Number of unicode codepoints to copy, starting with
+ * the one at "pos". The copying will stop if the null
+ * terminator is encountered before n codepoints have
+ * been copied.
+ */
+ RTCString substrCP(size_t pos = 0, size_t n = npos) const;
+
+ /**
+ * Returns true if "this" ends with "that".
+ *
+ * @param that Suffix to test for.
+ * @param cs Case sensitivity selector.
+ * @returns true if match, false if mismatch.
+ */
+ bool endsWith(const RTCString &that, CaseSensitivity cs = CaseSensitive) const;
+
+ /**
+ * Returns true if "this" begins with "that".
+ * @param that Prefix to test for.
+ * @param cs Case sensitivity selector.
+ * @returns true if match, false if mismatch.
+ */
+ bool startsWith(const RTCString &that, CaseSensitivity cs = CaseSensitive) const;
+
+ /**
+ * Returns true if "this" contains "that" (strstr).
+ *
+ * @param that Substring to look for.
+ * @param cs Case sensitivity selector.
+ * @returns true if match, false if mismatch.
+ */
+ bool contains(const RTCString &that, CaseSensitivity cs = CaseSensitive) const;
+
+ /**
+ * Attempts to convert the member string into a 32-bit integer.
+ *
+ * @returns 32-bit unsigned number on success.
+ * @returns 0 on failure.
+ */
+ int32_t toInt32() const
+ {
+ return RTStrToInt32(m_psz);
+ }
+
+ /**
+ * Attempts to convert the member string into an unsigned 32-bit integer.
+ *
+ * @returns 32-bit unsigned number on success.
+ * @returns 0 on failure.
+ */
+ uint32_t toUInt32() const
+ {
+ return RTStrToUInt32(m_psz);
+ }
+
+ /**
+ * Attempts to convert the member string into an 64-bit integer.
+ *
+ * @returns 64-bit unsigned number on success.
+ * @returns 0 on failure.
+ */
+ int64_t toInt64() const
+ {
+ return RTStrToInt64(m_psz);
+ }
+
+ /**
+ * Attempts to convert the member string into an unsigned 64-bit integer.
+ *
+ * @returns 64-bit unsigned number on success.
+ * @returns 0 on failure.
+ */
+ uint64_t toUInt64() const
+ {
+ return RTStrToUInt64(m_psz);
+ }
+
+ /**
+ * Attempts to convert the member string into an unsigned 64-bit integer.
+ *
+ * @param i Where to return the value on success.
+ * @returns IPRT error code, see RTStrToInt64.
+ */
+ int toInt(uint64_t &i) const;
+
+ /**
+ * Attempts to convert the member string into an unsigned 32-bit integer.
+ *
+ * @param i Where to return the value on success.
+ * @returns IPRT error code, see RTStrToInt32.
+ */
+ int toInt(uint32_t &i) const;
+
+ /** Splitting behavior regarding empty sections in the string. */
+ enum SplitMode
+ {
+ KeepEmptyParts, /**< Empty parts are added as empty strings to the result list. */
+ RemoveEmptyParts /**< Empty parts are skipped. */
+ };
+
+ /**
+ * Splits a string separated by strSep into its parts.
+ *
+ * @param a_rstrSep The separator to search for.
+ * @param a_enmMode How should empty parts be handled.
+ * @returns separated strings as string list.
+ */
+ RTCList<RTCString, RTCString *> split(const RTCString &a_rstrSep,
+ SplitMode a_enmMode = RemoveEmptyParts) const;
+
+ /**
+ * Joins a list of strings together using the provided separator.
+ *
+ * @param a_rList The list to join.
+ * @param a_rstrSep The separator used for joining.
+ * @returns joined string.
+ */
+ static RTCString join(const RTCList<RTCString, RTCString *> &a_rList,
+ const RTCString &a_rstrSep = "");
+
+protected:
+
+ /**
+ * Hide operator bool() to force people to use isEmpty() explicitly.
+ */
+ operator bool() const;
+
+ /**
+ * Destructor implementation, also used to clean up in operator=() before
+ * assigning a new string.
+ */
+ void cleanup()
+ {
+ if (m_psz)
+ {
+ RTStrFree(m_psz);
+ m_psz = NULL;
+ m_cch = 0;
+ m_cbAllocated = 0;
+ }
+ }
+
+ /**
+ * Protected internal helper to copy a string.
+ *
+ * This ignores the previous object state, so either call this from a
+ * constructor or call cleanup() first. copyFromN() unconditionally sets
+ * the members to a copy of the given other strings and makes no
+ * assumptions about previous contents. Can therefore be used both in copy
+ * constructors, when member variables have no defined value, and in
+ * assignments after having called cleanup().
+ *
+ * @param pcszSrc The source string.
+ * @param cchSrc The number of chars (bytes) to copy from the
+ * source strings. RTSTR_MAX is NOT accepted.
+ *
+ * @throws std::bad_alloc On allocation failure. The object is left
+ * describing a NULL string.
+ */
+ void copyFromN(const char *pcszSrc, size_t cchSrc)
+ {
+ if (cchSrc)
+ {
+ m_psz = RTStrAlloc(cchSrc + 1);
+ if (RT_LIKELY(m_psz))
+ {
+ m_cch = cchSrc;
+ m_cbAllocated = cchSrc + 1;
+ memcpy(m_psz, pcszSrc, cchSrc);
+ m_psz[cchSrc] = '\0';
+ }
+ else
+ {
+ m_cch = 0;
+ m_cbAllocated = 0;
+#ifdef RT_EXCEPTIONS_ENABLED
+ throw std::bad_alloc();
+#endif
+ }
+ }
+ else
+ {
+ m_cch = 0;
+ m_cbAllocated = 0;
+ m_psz = NULL;
+ }
+ }
+
+ static DECLCALLBACK(size_t) printfOutputCallback(void *pvArg, const char *pachChars, size_t cbChars);
+
+ char *m_psz; /**< The string buffer. */
+ size_t m_cch; /**< strlen(m_psz) - i.e. no terminator included. */
+ size_t m_cbAllocated; /**< Size of buffer that m_psz points to; at least m_cbLength + 1. */
+};
+
+/** @} */
+
+
+/** @addtogroup grp_rt_cpp_string
+ * @{
+ */
+
+/**
+ * Concatenate two strings.
+ *
+ * @param a_rstr1 String one.
+ * @param a_rstr2 String two.
+ * @returns the concatenate string.
+ *
+ * @relates RTCString
+ */
+RTDECL(const RTCString) operator+(const RTCString &a_rstr1, const RTCString &a_rstr2);
+
+/**
+ * Concatenate two strings.
+ *
+ * @param a_rstr1 String one.
+ * @param a_psz2 String two.
+ * @returns the concatenate string.
+ *
+ * @relates RTCString
+ */
+RTDECL(const RTCString) operator+(const RTCString &a_rstr1, const char *a_psz2);
+
+/**
+ * Concatenate two strings.
+ *
+ * @param a_psz1 String one.
+ * @param a_rstr2 String two.
+ * @returns the concatenate string.
+ *
+ * @relates RTCString
+ */
+RTDECL(const RTCString) operator+(const char *a_psz1, const RTCString &a_rstr2);
+
+/**
+ * Class with RTCString::printf as constructor for your convenience.
+ *
+ * Constructing a RTCString string object from a format string and a variable
+ * number of arguments can easily be confused with the other RTCString
+ * constructors, thus this child class.
+ *
+ * The usage of this class is like the following:
+ * @code
+ RTCStringFmt strName("program name = %s", argv[0]);
+ @endcode
+ */
+class RTCStringFmt : public RTCString
+{
+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 RTCStringFmt(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:
+ RTCStringFmt() {}
+};
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/cpp/mtlist.h b/include/iprt/cpp/mtlist.h
new file mode 100644
index 00000000..eb4e587c
--- /dev/null
+++ b/include/iprt/cpp/mtlist.h
@@ -0,0 +1,155 @@
+/** @file
+ * IPRT - Generic thread-safe list Class.
+ */
+
+/*
+ * 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 ___iprt_cpp_mtlist_h
+#define ___iprt_cpp_mtlist_h
+
+#include <iprt/cpp/list.h>
+
+#include <iprt/semaphore.h>
+
+/** @addtogroup grp_rt_cpp_list
+ * @{
+ */
+
+/**
+ * A guard class for thread-safe read/write access.
+ */
+template <>
+class RTCListGuard<true>
+{
+public:
+ RTCListGuard() { int rc = RTSemRWCreate(&m_hRWSem); AssertRC(rc); }
+ ~RTCListGuard() { RTSemRWDestroy(m_hRWSem); }
+ inline void enterRead() const { int rc = RTSemRWRequestRead(m_hRWSem, RT_INDEFINITE_WAIT); AssertRC(rc); }
+ inline void leaveRead() const { int rc = RTSemRWReleaseRead(m_hRWSem); AssertRC(rc); }
+ inline void enterWrite() { int rc = RTSemRWRequestWrite(m_hRWSem, RT_INDEFINITE_WAIT); AssertRC(rc); }
+ inline void leaveWrite() { int rc = RTSemRWReleaseWrite(m_hRWSem); AssertRC(rc); }
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+
+private:
+ mutable RTSEMRW m_hRWSem;
+};
+
+/**
+ * @brief Generic thread-safe list class.
+ *
+ * RTCMTList is a thread-safe implementation of the list class. It uses a
+ * read/write semaphore to serialize the access to the items. Several readers
+ * can simultaneous access different or the same item. If one thread is writing
+ * to an item, the other accessors are blocked until the write has finished.
+ *
+ * Although the access is guarded, the user has to make sure the list content
+ * is consistent when iterating over the list or doing any other kind of access
+ * which makes assumptions about the list content. For a finer control of access
+ * restrictions, use your own locking mechanism and the standard list
+ * implementation.
+ *
+ * @see RTCListBase
+ */
+template <class T, typename ITYPE = typename RTCIf<(sizeof(T) > sizeof(void*)), T*, T>::result>
+class RTCMTList : public RTCListBase<T, ITYPE, true>
+{
+ /* Traits */
+ typedef RTCListBase<T, ITYPE, true> 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) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * Specialized thread-safe list class for using the native type list for
+ * unsigned 64-bit values even on a 32-bit host.
+ *
+ * @see RTCListBase
+ */
+template <>
+class RTCMTList<uint64_t>: public RTCListBase<uint64_t, uint64_t, true>
+{
+ /* Traits */
+ typedef RTCListBase<uint64_t, uint64_t, true> 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) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/**
+ * Specialized thread-safe list class for using the native type list for
+ * signed 64-bit values even on a 32-bit host.
+ *
+ * @see RTCListBase
+ */
+template <>
+class RTCMTList<int64_t>: public RTCListBase<int64_t, int64_t, true>
+{
+ /* Traits */
+ typedef RTCListBase<int64_t, int64_t, true> 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) {}
+
+ /* Define our own new and delete. */
+ RTMEMEF_NEW_AND_DELETE_OPERATORS();
+};
+
+/** @} */
+
+#endif /* !___iprt_cpp_mtlist_h */
+
diff --git a/include/iprt/cpp/utils.h b/include/iprt/cpp/utils.h
new file mode 100644
index 00000000..e5b269a0
--- /dev/null
+++ b/include/iprt/cpp/utils.h
@@ -0,0 +1,102 @@
+/** @file
+ * IPRT - C++ Utilities (useful templates, defines and such).
+ */
+
+/*
+ * 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 ___iprt_cpputils_h
+#define ___iprt_cpputils_h
+
+/** @defgroup grp_rt_cpp IPRT C++ APIs */
+
+/** @defgroup grp_rt_cpp_util C++ Utilities
+ * @ingroup grp_rt_cpp
+ * @{
+ */
+
+#define DPTR(CLASS) CLASS##Private *d = static_cast<CLASS##Private *>(d_ptr)
+#define QPTR(CLASS) CLASS *q = static_cast<CLASS *>(q_ptr)
+
+/**
+ * A simple class used to prevent copying and assignment.
+ *
+ * Inherit from this class in order to prevent automatic generation
+ * of the copy constructor and assignment operator in your class.
+ *
+ * @addtogroup grp_rt_cpp_util
+ */
+class RTCNonCopyable
+{
+protected:
+ RTCNonCopyable() {}
+ ~RTCNonCopyable() {}
+private:
+ RTCNonCopyable(RTCNonCopyable const &);
+ RTCNonCopyable const &operator=(RTCNonCopyable const &);
+};
+
+
+/**
+ * Shortcut to |const_cast<C &>()| that automatically derives the correct
+ * type (class) for the const_cast template's argument from its own argument.
+ *
+ * Can be used to temporarily cancel the |const| modifier on the left-hand side
+ * of assignment expressions, like this:
+ * @code
+ * const Class That;
+ * ...
+ * unconst(That) = SomeValue;
+ * @endcode
+ *
+ * @todo What to do about the prefix here?
+ */
+template <class C>
+inline C &unconst(const C &that)
+{
+ return const_cast<C &>(that);
+}
+
+
+/**
+ * Shortcut to |const_cast<C *>()| that automatically derives the correct
+ * type (class) for the const_cast template's argument from its own argument.
+ *
+ * Can be used to temporarily cancel the |const| modifier on the left-hand side
+ * of assignment expressions, like this:
+ * @code
+ * const Class *pThat;
+ * ...
+ * unconst(pThat) = SomeValue;
+ * @endcode
+ *
+ * @todo What to do about the prefix here?
+ */
+template <class C>
+inline C *unconst(const C *that)
+{
+ return const_cast<C *>(that);
+}
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/cpp/xml.h b/include/iprt/cpp/xml.h
new file mode 100644
index 00000000..bb9f5a18
--- /dev/null
+++ b/include/iprt/cpp/xml.h
@@ -0,0 +1,748 @@
+/** @file
+ * IPRT - XML Helper APIs.
+ */
+
+/*
+ * Copyright (C) 2007-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___iprt_xml_h
+#define ___iprt_xml_h
+
+#ifndef IN_RING3
+# error "There are no XML APIs available in Ring-0 Context!"
+#endif
+
+#include <list>
+#include <memory>
+
+#include <iprt/cpp/exception.h>
+
+/** @defgroup grp_rt_cpp_xml C++ XML support
+ * @ingroup grp_rt_cpp
+ * @{
+ */
+
+/* Forwards */
+typedef struct _xmlParserInput xmlParserInput;
+typedef xmlParserInput *xmlParserInputPtr;
+typedef struct _xmlParserCtxt xmlParserCtxt;
+typedef xmlParserCtxt *xmlParserCtxtPtr;
+typedef struct _xmlError xmlError;
+typedef xmlError *xmlErrorPtr;
+
+typedef struct _xmlAttr xmlAttr;
+typedef struct _xmlNode xmlNode;
+
+/** @} */
+
+namespace xml
+{
+
+/**
+ * @addtogroup grp_rt_cpp_xml
+ * @{
+ */
+
+// Exceptions
+//////////////////////////////////////////////////////////////////////////////
+
+class RT_DECL_CLASS LogicError : public RTCError
+{
+public:
+
+ LogicError(const char *aMsg = NULL)
+ : RTCError(aMsg)
+ {}
+
+ LogicError(RT_SRC_POS_DECL);
+};
+
+class RT_DECL_CLASS RuntimeError : public RTCError
+{
+public:
+
+ RuntimeError(const char *aMsg = NULL)
+ : RTCError(aMsg)
+ {}
+};
+
+class RT_DECL_CLASS XmlError : public RuntimeError
+{
+public:
+ XmlError(xmlErrorPtr aErr);
+
+ static char* Format(xmlErrorPtr aErr);
+};
+
+// Logical errors
+//////////////////////////////////////////////////////////////////////////////
+
+class RT_DECL_CLASS ENotImplemented : public LogicError
+{
+public:
+ ENotImplemented(const char *aMsg = NULL) : LogicError(aMsg) {}
+ ENotImplemented(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
+};
+
+class RT_DECL_CLASS EInvalidArg : public LogicError
+{
+public:
+ EInvalidArg(const char *aMsg = NULL) : LogicError(aMsg) {}
+ EInvalidArg(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
+};
+
+class RT_DECL_CLASS EDocumentNotEmpty : public LogicError
+{
+public:
+ EDocumentNotEmpty(const char *aMsg = NULL) : LogicError(aMsg) {}
+ EDocumentNotEmpty(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
+};
+
+class RT_DECL_CLASS ENodeIsNotElement : public LogicError
+{
+public:
+ ENodeIsNotElement(const char *aMsg = NULL) : LogicError(aMsg) {}
+ ENodeIsNotElement(RT_SRC_POS_DECL) : LogicError(RT_SRC_POS_ARGS) {}
+};
+
+// Runtime errors
+//////////////////////////////////////////////////////////////////////////////
+
+class RT_DECL_CLASS EIPRTFailure : public RuntimeError
+{
+public:
+
+ EIPRTFailure(int aRC, const char *pcszContext, ...);
+
+ int rc() const
+ {
+ return mRC;
+ }
+
+private:
+ int mRC;
+};
+
+/**
+ * The Stream class is a base class for I/O streams.
+ */
+class RT_DECL_CLASS Stream
+{
+public:
+
+ virtual ~Stream() {}
+
+ virtual const char *uri() const = 0;
+
+ /**
+ * Returns the current read/write position in the stream. The returned
+ * position is a zero-based byte offset from the beginning of the file.
+ *
+ * Throws ENotImplemented if this operation is not implemented for the
+ * given stream.
+ */
+ virtual uint64_t pos() const = 0;
+
+ /**
+ * Sets the current read/write position in the stream.
+ *
+ * @param aPos Zero-based byte offset from the beginning of the stream.
+ *
+ * Throws ENotImplemented if this operation is not implemented for the
+ * given stream.
+ */
+ virtual void setPos (uint64_t aPos) = 0;
+};
+
+/**
+ * The Input class represents an input stream.
+ *
+ * This input stream is used to read the settings tree from.
+ * This is an abstract class that must be subclassed in order to fill it with
+ * useful functionality.
+ */
+class RT_DECL_CLASS Input : virtual public Stream
+{
+public:
+
+ /**
+ * Reads from the stream to the supplied buffer.
+ *
+ * @param aBuf Buffer to store read data to.
+ * @param aLen Buffer length.
+ *
+ * @return Number of bytes read.
+ */
+ virtual int read (char *aBuf, int aLen) = 0;
+};
+
+/**
+ *
+ */
+class RT_DECL_CLASS Output : virtual public Stream
+{
+public:
+
+ /**
+ * Writes to the stream from the supplied buffer.
+ *
+ * @param aBuf Buffer to write data from.
+ * @param aLen Buffer length.
+ *
+ * @return Number of bytes written.
+ */
+ virtual int write (const char *aBuf, int aLen) = 0;
+
+ /**
+ * Truncates the stream from the current position and upto the end.
+ * The new file size will become exactly #pos() bytes.
+ *
+ * Throws ENotImplemented if this operation is not implemented for the
+ * given stream.
+ */
+ virtual void truncate() = 0;
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+/**
+ * The File class is a stream implementation that reads from and writes to
+ * regular files.
+ *
+ * The File class uses IPRT File API for file operations. Note that IPRT File
+ * API is not thread-safe. This means that if you pass the same RTFILE handle to
+ * different File instances that may be simultaneously used on different
+ * threads, you should care about serialization; otherwise you will get garbage
+ * when reading from or writing to such File instances.
+ */
+class RT_DECL_CLASS File : public Input, public Output
+{
+public:
+
+ /**
+ * Possible file access modes.
+ */
+ enum Mode { Mode_Read, Mode_WriteCreate, Mode_Overwrite, Mode_ReadWrite };
+
+ /**
+ * Opens a file with the given name in the given mode. If @a aMode is Read
+ * or ReadWrite, the file must exist. If @a aMode is Write, the file must
+ * not exist. Otherwise, an EIPRTFailure excetion will be thrown.
+ *
+ * @param aMode File mode.
+ * @param aFileName File name.
+ * @param aFlushIt Whether to flush a writable file before closing it.
+ */
+ File(Mode aMode, const char *aFileName, bool aFlushIt = false);
+
+ /**
+ * Uses the given file handle to perform file operations. This file
+ * handle must be already open in necessary mode (read, or write, or mixed).
+ *
+ * The read/write position of the given handle will be reset to the
+ * beginning of the file on success.
+ *
+ * Note that the given file handle will not be automatically closed upon
+ * this object destruction.
+ *
+ * @note It you pass the same RTFILE handle to more than one File instance,
+ * please make sure you have provided serialization in case if these
+ * instasnces are to be simultaneously used by different threads.
+ * Otherwise you may get garbage when reading or writing.
+ *
+ * @param aHandle Open file handle.
+ * @param aFileName File name (for reference).
+ * @param aFlushIt Whether to flush a writable file before closing it.
+ */
+ File(RTFILE aHandle, const char *aFileName = NULL, bool aFlushIt = false);
+
+ /**
+ * Destroys the File object. If the object was created from a file name
+ * the corresponding file will be automatically closed. If the object was
+ * created from a file handle, it will remain open.
+ */
+ virtual ~File();
+
+ const char *uri() const;
+
+ uint64_t pos() const;
+ void setPos(uint64_t aPos);
+
+ /**
+ * See Input::read(). If this method is called in wrong file mode,
+ * LogicError will be thrown.
+ */
+ int read(char *aBuf, int aLen);
+
+ /**
+ * See Output::write(). If this method is called in wrong file mode,
+ * LogicError will be thrown.
+ */
+ int write(const char *aBuf, int aLen);
+
+ /**
+ * See Output::truncate(). If this method is called in wrong file mode,
+ * LogicError will be thrown.
+ */
+ void truncate();
+
+private:
+
+ /* Obscure class data */
+ struct Data;
+ Data *m;
+
+ /* auto_ptr data doesn't have proper copy semantics */
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP (File)
+};
+
+/**
+ * The MemoryBuf class represents a stream implementation that reads from the
+ * memory buffer.
+ */
+class RT_DECL_CLASS MemoryBuf : public Input
+{
+public:
+
+ MemoryBuf (const char *aBuf, size_t aLen, const char *aURI = NULL);
+
+ virtual ~MemoryBuf();
+
+ const char *uri() const;
+
+ int read(char *aBuf, int aLen);
+ uint64_t pos() const;
+ void setPos(uint64_t aPos);
+
+private:
+ /* Obscure class data */
+ struct Data;
+ Data *m;
+
+ /* auto_ptr data doesn't have proper copy semantics */
+ DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(MemoryBuf)
+};
+
+
+/*
+ * GlobalLock
+ *
+ *
+ */
+
+typedef xmlParserInput* FNEXTERNALENTITYLOADER(const char *aURI,
+ const char *aID,
+ xmlParserCtxt *aCtxt);
+typedef FNEXTERNALENTITYLOADER *PFNEXTERNALENTITYLOADER;
+
+class RT_DECL_CLASS GlobalLock
+{
+public:
+ GlobalLock();
+ ~GlobalLock();
+
+ void setExternalEntityLoader(PFNEXTERNALENTITYLOADER pFunc);
+
+ static xmlParserInput* callDefaultLoader(const char *aURI,
+ const char *aID,
+ xmlParserCtxt *aCtxt);
+
+private:
+ /* Obscure class data. */
+ struct Data;
+ struct Data *m;
+};
+
+class ElementNode;
+typedef std::list<const ElementNode*> ElementNodesList;
+
+class AttributeNode;
+
+class ContentNode;
+
+/**
+ * Node base class. Cannot be used directly, but ElementNode, ContentNode and
+ * AttributeNode derive from this. This does implement useful public methods though.
+ */
+class RT_DECL_CLASS Node
+{
+public:
+ ~Node();
+
+ const char* getName() const;
+ bool nameEquals(const char *pcszNamespace, const char *pcsz) const;
+ bool nameEquals(const char *pcsz) const
+ {
+ return nameEquals(NULL, pcsz);
+ }
+
+ const char* getValue() const;
+ bool copyValue(int32_t &i) const;
+ bool copyValue(uint32_t &i) const;
+ bool copyValue(int64_t &i) const;
+ bool copyValue(uint64_t &i) const;
+
+ int getLineNumber() const;
+
+ int isElement() const
+ {
+ return m_Type == IsElement;
+ }
+
+protected:
+ typedef enum {IsElement, IsAttribute, IsContent} EnumType;
+
+ EnumType m_Type;
+ Node *m_pParent;
+ xmlNode *m_plibNode; // != NULL if this is an element or content node
+ xmlAttr *m_plibAttr; // != NULL if this is an attribute node
+ const char *m_pcszNamespacePrefix; // not always set
+ const char *m_pcszNamespaceHref; // full http:// spec
+ const char *m_pcszName; // element or attribute name, points either into plibNode or plibAttr;
+ // NULL if this is a content node
+
+ // hide the default constructor so people use only our factory methods
+ Node(EnumType type,
+ Node *pParent,
+ xmlNode *plibNode,
+ xmlAttr *plibAttr);
+ Node(const Node &x); // no copying
+
+ void buildChildren(const ElementNode &elmRoot);
+
+ /* Obscure class data */
+ struct Data;
+ Data *m;
+
+ friend class AttributeNode;
+};
+
+/**
+ * Node subclass that represents an element.
+ *
+ * For elements, Node::getName() returns the element name, and Node::getValue()
+ * returns the text contents, if any.
+ *
+ * Since the Node constructor is private, one can create element nodes
+ * only through the following factory methods:
+ *
+ * -- Document::createRootElement()
+ * -- ElementNode::createChild()
+ */
+class RT_DECL_CLASS ElementNode : public Node
+{
+public:
+ int getChildElements(ElementNodesList &children,
+ const char *pcszMatch = NULL) const;
+
+ const ElementNode* findChildElement(const char *pcszNamespace,
+ const char *pcszMatch) const;
+ const ElementNode* findChildElement(const char *pcszMatch) const
+ {
+ return findChildElement(NULL, pcszMatch);
+ }
+ const ElementNode* findChildElementFromId(const char *pcszId) const;
+
+ const AttributeNode* findAttribute(const char *pcszMatch) const;
+ bool getAttributeValue(const char *pcszMatch, const char *&ppcsz) const;
+ bool getAttributeValue(const char *pcszMatch, RTCString &str) const;
+ bool getAttributeValuePath(const char *pcszMatch, RTCString &str) const;
+ bool getAttributeValue(const char *pcszMatch, int32_t &i) const;
+ bool getAttributeValue(const char *pcszMatch, uint32_t &i) const;
+ bool getAttributeValue(const char *pcszMatch, int64_t &i) const;
+ bool getAttributeValue(const char *pcszMatch, uint64_t &i) const;
+ bool getAttributeValue(const char *pcszMatch, bool &f) const;
+
+ ElementNode* createChild(const char *pcszElementName);
+
+ ContentNode* addContent(const char *pcszContent);
+ ContentNode* addContent(const RTCString &strContent)
+ {
+ return addContent(strContent.c_str());
+ }
+
+ AttributeNode* setAttribute(const char *pcszName, const char *pcszValue);
+ AttributeNode* setAttribute(const char *pcszName, const RTCString &strValue)
+ {
+ return setAttribute(pcszName, strValue.c_str());
+ }
+ AttributeNode* setAttributePath(const char *pcszName, const RTCString &strValue);
+ AttributeNode* setAttribute(const char *pcszName, int32_t i);
+ AttributeNode* setAttribute(const char *pcszName, uint32_t i);
+ AttributeNode* setAttribute(const char *pcszName, int64_t i);
+ AttributeNode* setAttribute(const char *pcszName, uint64_t i);
+ AttributeNode* setAttributeHex(const char *pcszName, uint32_t i);
+ AttributeNode* setAttribute(const char *pcszName, bool f);
+
+protected:
+ // hide the default constructor so people use only our factory methods
+ ElementNode(const ElementNode *pelmRoot, Node *pParent, xmlNode *plibNode);
+ ElementNode(const ElementNode &x); // no copying
+
+ const ElementNode *m_pelmRoot;
+
+ friend class Node;
+ friend class Document;
+ friend class XmlFileParser;
+};
+
+/**
+ * Node subclass that represents content (non-element text).
+ *
+ * Since the Node constructor is private, one can create new content nodes
+ * only through the following factory methods:
+ *
+ * -- ElementNode::addContent()
+ */
+class RT_DECL_CLASS ContentNode : public Node
+{
+public:
+
+protected:
+ // hide the default constructor so people use only our factory methods
+ ContentNode(Node *pParent, xmlNode *plibNode);
+ ContentNode(const ContentNode &x); // no copying
+
+ friend class Node;
+ friend class ElementNode;
+};
+
+/**
+ * Node subclass that represents an attribute of an element.
+ *
+ * For attributes, Node::getName() returns the attribute name, and Node::getValue()
+ * returns the attribute value, if any.
+ *
+ * Since the Node constructor is private, one can create new attribute nodes
+ * only through the following factory methods:
+ *
+ * -- ElementNode::setAttribute()
+ */
+class RT_DECL_CLASS AttributeNode : public Node
+{
+public:
+
+protected:
+ // hide the default constructor so people use only our factory methods
+ AttributeNode(const ElementNode &elmRoot,
+ Node *pParent,
+ xmlAttr *plibAttr,
+ const char **ppcszKey);
+ AttributeNode(const AttributeNode &x); // no copying
+
+ RTCString m_strKey;
+
+ friend class Node;
+ friend class ElementNode;
+};
+
+/**
+ * Handy helper class with which one can loop through all or some children
+ * of a particular element. See NodesLoop::forAllNodes() for details.
+ */
+class RT_DECL_CLASS NodesLoop
+{
+public:
+ NodesLoop(const ElementNode &node, const char *pcszMatch = NULL);
+ ~NodesLoop();
+ const ElementNode* forAllNodes() const;
+
+private:
+ /* Obscure class data */
+ struct Data;
+ Data *m;
+};
+
+/**
+ * The XML document class. An instance of this needs to be created by a user
+ * of the XML classes and then passed to
+ *
+ * -- XmlMemParser or XmlFileParser to read an XML document; those classes then
+ * fill the caller's Document with ElementNode, ContentNode and AttributeNode
+ * instances. The typical sequence then is:
+ * @code
+ Document doc;
+ XmlFileParser parser;
+ parser.read("file.xml", doc);
+ Element *pelmRoot = doc.getRootElement();
+ @endcode
+ *
+ * -- XmlMemWriter or XmlFileWriter to write out an XML document after it has
+ * been created and filled. Example:
+ *
+ * @code
+ Document doc;
+ Element *pelmRoot = doc.createRootElement();
+ // add children
+ xml::XmlFileWriter writer(doc);
+ writer.write("file.xml", true);
+ @endcode
+ */
+class RT_DECL_CLASS Document
+{
+public:
+ Document();
+ ~Document();
+
+ Document(const Document &x);
+ Document& operator=(const Document &x);
+
+ const ElementNode* getRootElement() const;
+ ElementNode* getRootElement();
+
+ ElementNode* createRootElement(const char *pcszRootElementName,
+ const char *pcszComment = NULL);
+
+private:
+ friend class XmlMemParser;
+ friend class XmlFileParser;
+ friend class XmlMemWriter;
+ friend class XmlFileWriter;
+
+ void refreshInternals();
+
+ /* Obscure class data */
+ struct Data;
+ Data *m;
+};
+
+/*
+ * XmlParserBase
+ *
+ */
+
+class RT_DECL_CLASS XmlParserBase
+{
+protected:
+ XmlParserBase();
+ ~XmlParserBase();
+
+ xmlParserCtxtPtr m_ctxt;
+};
+
+/*
+ * XmlMemParser
+ *
+ */
+
+class RT_DECL_CLASS XmlMemParser : public XmlParserBase
+{
+public:
+ XmlMemParser();
+ ~XmlMemParser();
+
+ void read(const void* pvBuf, size_t cbSize, const RTCString &strFilename, Document &doc);
+};
+
+/*
+ * XmlFileParser
+ *
+ */
+
+class RT_DECL_CLASS XmlFileParser : public XmlParserBase
+{
+public:
+ XmlFileParser();
+ ~XmlFileParser();
+
+ void read(const RTCString &strFilename, Document &doc);
+
+private:
+ /* Obscure class data */
+ struct Data;
+ struct Data *m;
+
+ static int ReadCallback(void *aCtxt, char *aBuf, int aLen);
+ static int CloseCallback (void *aCtxt);
+};
+
+/*
+ * XmlMemParser
+ *
+ */
+
+class RT_DECL_CLASS XmlMemWriter
+{
+public:
+ XmlMemWriter();
+ ~XmlMemWriter();
+
+ void write(const Document &doc, void** ppvBuf, size_t *pcbSize);
+
+private:
+ void* m_pBuf;
+};
+
+/*
+ * XmlFileWriter
+ *
+ */
+
+class RT_DECL_CLASS XmlFileWriter
+{
+public:
+ XmlFileWriter(Document &doc);
+ ~XmlFileWriter();
+
+ /**
+ * Writes the XML document to the specified file.
+ *
+ * @param pcszFilename The name of the output file.
+ * @param fSafe If @c true, some extra safety precautions will be
+ * taken when writing the file:
+ * -# The file is written with a '-tmp' suffix.
+ * -# It is flushed to disk after writing.
+ * -# Any original file is renamed to '-prev'.
+ * -# The '-tmp' file is then renamed to the
+ * specified name.
+ * -# The directory changes are flushed to disk.
+ * The suffixes are available via s_pszTmpSuff and
+ * s_pszPrevSuff.
+ */
+ void write(const char *pcszFilename, bool fSafe);
+
+ static int WriteCallback(void *aCtxt, const char *aBuf, int aLen);
+ static int CloseCallback(void *aCtxt);
+
+ /** The suffix used by XmlFileWriter::write() for the temporary file. */
+ static const char * const s_pszTmpSuff;
+ /** The suffix used by XmlFileWriter::write() for the previous (backup) file. */
+ static const char * const s_pszPrevSuff;
+
+private:
+ void writeInternal(const char *pcszFilename, bool fSafe);
+
+ /* Obscure class data */
+ struct Data;
+ Data *m;
+};
+
+#if defined(_MSC_VER)
+#pragma warning (default:4251)
+#endif
+
+/** @} */
+
+} // end namespace xml
+
+#endif /* !___iprt_xml_h */
+
diff --git a/include/iprt/cpuset.h b/include/iprt/cpuset.h
new file mode 100644
index 00000000..0d1e1c51
--- /dev/null
+++ b/include/iprt/cpuset.h
@@ -0,0 +1,286 @@
+/** @file
+ * IPRT - CPU Set.
+ */
+
+/*
+ * Copyright (C) 2008-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 ___iprt_cpuset_h
+#define ___iprt_cpuset_h
+
+#include <iprt/types.h>
+#include <iprt/mp.h> /* RTMpCpuIdToSetIndex */
+#include <iprt/asm.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_cpuset RTCpuSet - CPU Set
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Clear all CPUs.
+ *
+ * @returns pSet.
+ * @param pSet Pointer to the set.
+ */
+DECLINLINE(PRTCPUSET) RTCpuSetEmpty(PRTCPUSET pSet)
+{
+ unsigned i;
+ for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+ pSet->bmSet[i] = 0;
+ return pSet;
+}
+
+
+/**
+ * Set all CPUs.
+ *
+ * @returns pSet.
+ * @param pSet Pointer to the set.
+ */
+DECLINLINE(PRTCPUSET) RTCpuSetFill(PRTCPUSET pSet)
+{
+ unsigned i;
+ for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+ pSet->bmSet[i] = UINT64_MAX;
+ return pSet;
+}
+
+
+/**
+ * Adds a CPU given by its identifier to the set.
+ *
+ * @returns 0 on success, -1 if idCpu isn't valid.
+ * @param pSet Pointer to the set.
+ * @param idCpu The identifier of the CPU to add.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetAdd(PRTCPUSET pSet, RTCPUID idCpu)
+{
+ int iCpu = RTMpCpuIdToSetIndex(idCpu);
+ if (RT_UNLIKELY(iCpu < 0))
+ return -1;
+ ASMAtomicBitSet(pSet, iCpu);
+ return 0;
+}
+
+
+/**
+ * Adds a CPU given by its identifier to the set.
+ *
+ * @returns 0 on success, -1 if iCpu isn't valid.
+ * @param pSet Pointer to the set.
+ * @param iCpu The index of the CPU to add.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetAddByIndex(PRTCPUSET pSet, int iCpu)
+{
+ if (RT_UNLIKELY((unsigned)iCpu >= RTCPUSET_MAX_CPUS))
+ return -1;
+ ASMAtomicBitSet(pSet, iCpu);
+ return 0;
+}
+
+
+/**
+ * Removes a CPU given by its identifier from the set.
+ *
+ * @returns 0 on success, -1 if idCpu isn't valid.
+ * @param pSet Pointer to the set.
+ * @param idCpu The identifier of the CPU to delete.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetDel(PRTCPUSET pSet, RTCPUID idCpu)
+{
+ int iCpu = RTMpCpuIdToSetIndex(idCpu);
+ if (RT_UNLIKELY(iCpu < 0))
+ return -1;
+ ASMAtomicBitClear(pSet, iCpu);
+ return 0;
+}
+
+
+/**
+ * Removes a CPU given by its index from the set.
+ *
+ * @returns 0 on success, -1 if iCpu isn't valid.
+ * @param pSet Pointer to the set.
+ * @param iCpu The index of the CPU to delete.
+ * @remarks The modification is atomic.
+ */
+DECLINLINE(int) RTCpuSetDelByIndex(PRTCPUSET pSet, int iCpu)
+{
+ if (RT_UNLIKELY((unsigned)iCpu >= RTCPUSET_MAX_CPUS))
+ return -1;
+ ASMAtomicBitClear(pSet, iCpu);
+ return 0;
+}
+
+
+/**
+ * Checks if a CPU given by its identifier is a member of the set.
+ *
+ * @returns true / false accordingly.
+ * @param pSet Pointer to the set.
+ * @param idCpu The identifier of the CPU to look for.
+ * @remarks The test is atomic.
+ */
+DECLINLINE(bool) RTCpuSetIsMember(PCRTCPUSET pSet, RTCPUID idCpu)
+{
+ int iCpu = RTMpCpuIdToSetIndex(idCpu);
+ if (RT_UNLIKELY(iCpu < 0))
+ return false;
+ return ASMBitTest((volatile void *)pSet, iCpu);
+}
+
+
+/**
+ * Checks if a CPU given by its index is a member of the set.
+ *
+ * @returns true / false accordingly.
+ * @param pSet Pointer to the set.
+ * @param iCpu The index of the CPU in the set.
+ * @remarks The test is atomic.
+ */
+DECLINLINE(bool) RTCpuSetIsMemberByIndex(PCRTCPUSET pSet, int iCpu)
+{
+ if (RT_UNLIKELY((unsigned)iCpu >= RTCPUSET_MAX_CPUS))
+ return false;
+ return ASMBitTest((volatile void *)pSet, iCpu);
+}
+
+
+/**
+ * Checks if the two sets match or not.
+ *
+ * @returns true / false accordingly.
+ * @param pSet1 The first set.
+ * @param pSet2 The second set.
+ */
+DECLINLINE(bool) RTCpuSetIsEqual(PCRTCPUSET pSet1, PCRTCPUSET pSet2)
+{
+ unsigned i;
+ for (i = 0; i < RT_ELEMENTS(pSet1->bmSet); i++)
+ if (pSet1->bmSet[i] != pSet2->bmSet[i])
+ return false;
+ return true;
+}
+
+
+/**
+ * Converts the CPU set to a 64-bit mask.
+ *
+ * @returns The mask.
+ * @param pSet Pointer to the set.
+ * @remarks Use with extreme care as it may lose information!
+ */
+DECLINLINE(uint64_t) RTCpuSetToU64(PCRTCPUSET pSet)
+{
+ return pSet->bmSet[0];
+}
+
+
+/**
+ * Initializes the CPU set from a 64-bit mask.
+ *
+ * @param pSet Pointer to the set.
+ * @param fMask The mask.
+ */
+DECLINLINE(PRTCPUSET) RTCpuSetFromU64(PRTCPUSET pSet, uint64_t fMask)
+{
+ unsigned i;
+
+ pSet->bmSet[0] = fMask;
+ for (i = 1; i < RT_ELEMENTS(pSet->bmSet); i++)
+ pSet->bmSet[i] = 0;
+
+ return pSet;
+}
+
+
+/**
+ * Count the CPUs in the set.
+ *
+ * @returns CPU count.
+ * @param pSet Pointer to the set.
+ */
+DECLINLINE(int) RTCpuSetCount(PCRTCPUSET pSet)
+{
+ int cCpus = 0;
+ unsigned i;
+
+ for (i = 0; i < RT_ELEMENTS(pSet->bmSet); i++)
+ {
+ uint64_t u64 = pSet->bmSet[i];
+ if (u64 != 0)
+ {
+ unsigned iCpu = 64;
+ while (iCpu-- > 0)
+ {
+ if (u64 & 1)
+ cCpus++;
+ u64 >>= 1;
+ }
+ }
+ }
+ return cCpus;
+}
+
+
+/**
+ * Get the highest set index.
+ *
+ * @returns The higest set index, -1 if all bits are clear.
+ * @param pSet Pointer to the set.
+ */
+DECLINLINE(int) RTCpuLastIndex(PCRTCPUSET pSet)
+{
+ unsigned i = RT_ELEMENTS(pSet->bmSet);
+ while (i-- > 0)
+ {
+ uint64_t u64 = pSet->bmSet[i];
+ if (u64)
+ {
+ /* There are more efficient ways to do this in asm.h... */
+ unsigned iBit;
+ for (iBit = 63; iBit > 0; iBit--)
+ {
+ if (u64 & RT_BIT_64(63))
+ break;
+ u64 <<= 1;
+ }
+ return i * 64 + iBit;
+ }
+ }
+ return 0;
+}
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/crc.h b/include/iprt/crc.h
new file mode 100644
index 00000000..82e3b11b
--- /dev/null
+++ b/include/iprt/crc.h
@@ -0,0 +1,160 @@
+/** @file
+ * IPRT - CRCs and Checksums.
+ */
+
+/*
+ * 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 ___iprt_crc_h
+#define ___iprt_crc_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_crc RTCrc - Checksums and CRCs.
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** @defgroup grp_rt_crc32 CRC-32
+ * @{ */
+/**
+ * Calculate CRC-32 for a memory block.
+ *
+ * @returns CRC-32 for the memory block.
+ * @param pv Pointer to the memory block.
+ * @param cb Size of the memory block in bytes.
+ */
+RTDECL(uint32_t) RTCrc32(const void *pv, size_t cb);
+
+/**
+ * Start a multiblock CRC-32 calculation.
+ *
+ * @returns Start CRC-32.
+ */
+RTDECL(uint32_t) RTCrc32Start(void);
+
+/**
+ * Processes a multiblock of a CRC-32 calculation.
+ *
+ * @returns Intermediate CRC-32 value.
+ * @param uCRC32 Current CRC-32 intermediate value.
+ * @param pv The data block to process.
+ * @param cb The size of the data block in bytes.
+ */
+RTDECL(uint32_t) RTCrc32Process(uint32_t uCRC32, const void *pv, size_t cb);
+
+/**
+ * Complete a multiblock CRC-32 calculation.
+ *
+ * @returns CRC-32 value.
+ * @param uCRC32 Current CRC-32 intermediate value.
+ */
+RTDECL(uint32_t) RTCrc32Finish(uint32_t uCRC32);
+/** @} */
+
+
+/** @defgroup grp_rt_crc64 CRC-64 Calculation
+ * @{ */
+/**
+ * Calculate CRC-64 for a memory block.
+ *
+ * @returns CRC-64 for the memory block.
+ * @param pv Pointer to the memory block.
+ * @param cb Size of the memory block in bytes.
+ */
+RTDECL(uint64_t) RTCrc64(const void *pv, size_t cb);
+
+/**
+ * Start a multiblock CRC-64 calculation.
+ *
+ * @returns Start CRC-64.
+ */
+RTDECL(uint64_t) RTCrc64Start(void);
+
+/**
+ * Processes a multiblock of a CRC-64 calculation.
+ *
+ * @returns Intermediate CRC-64 value.
+ * @param uCRC64 Current CRC-64 intermediate value.
+ * @param pv The data block to process.
+ * @param cb The size of the data block in bytes.
+ */
+RTDECL(uint64_t) RTCrc64Process(uint64_t uCRC64, const void *pv, size_t cb);
+
+/**
+ * Complete a multiblock CRC-64 calculation.
+ *
+ * @returns CRC-64 value.
+ * @param uCRC64 Current CRC-64 intermediate value.
+ */
+RTDECL(uint64_t) RTCrc64Finish(uint64_t uCRC64);
+/** @} */
+
+
+/** @defgroup grp_rt_crc_adler32 Adler-32
+ * @{ */
+/**
+ * Calculate Adler-32 for a memory block.
+ *
+ * @returns Adler-32 for the memory block.
+ * @param pv Pointer to the memory block.
+ * @param cb Size of the memory block in bytes.
+ */
+RTDECL(uint32_t) RTCrcAdler32(void const *pv, size_t cb);
+
+/**
+ * Start a multiblock Adler-32 calculation.
+ *
+ * @returns Start Adler-32.
+ */
+RTDECL(uint32_t) RTCrcAdler32Start(void);
+
+/**
+ * Processes a multiblock of a Adler-32 calculation.
+ *
+ * @returns Intermediate Adler-32 value.
+ * @param uCrc Current Adler-32 intermediate value.
+ * @param pv The data block to process.
+ * @param cb The size of the data block in bytes.
+ */
+RTDECL(uint32_t) RTCrcAdler32Process(uint32_t uCrc, void const *pv, size_t cb);
+
+/**
+ * Complete a multiblock Adler-32 calculation.
+ *
+ * @returns Adler-32 value.
+ * @param uCrc Current Adler-32 intermediate value.
+ */
+RTDECL(uint32_t) RTCrcAdler32Finish(uint32_t uCrc);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/critsect.h b/include/iprt/critsect.h
new file mode 100644
index 00000000..41bb65bd
--- /dev/null
+++ b/include/iprt/critsect.h
@@ -0,0 +1,366 @@
+/** @file
+ * IPRT - Critical Sections.
+ */
+
+/*
+ * 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 ___iprt_critsect_h
+#define ___iprt_critsect_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#ifdef IN_RING3
+# include <iprt/thread.h>
+#endif
+#ifdef RT_LOCK_STRICT_ORDER
+# include <iprt/lockvalidator.h>
+#endif
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_critsect RTCritSect - Critical Sections
+ *
+ * "Critical section" synchronization primitives can be used to
+ * protect a section of code or data to which access must be exclusive;
+ * only one thread can hold access to a critical section at one time.
+ *
+ * A critical section is a fast recursive write lock; if the critical
+ * section is not acquired, then entering it is fast (requires no system
+ * call). IPRT uses the Windows terminology here; on other platform, this
+ * might be called a "futex" or a "fast mutex". As opposed to IPRT
+ * "fast mutexes" (see @ref grp_rt_sems_fast_mutex ), critical sections
+ * are recursive.
+ *
+ * Use RTCritSectInit to initialize a critical section; use RTCritSectEnter
+ * and RTCritSectLeave to acquire and release access.
+ *
+ * For an overview of all types of synchronization primitives provided
+ * by IPRT (event, mutex/fast mutex/read-write mutex semaphores), see
+ * @ref grp_rt_sems .
+ *
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Critical section.
+ */
+typedef struct RTCRITSECT
+{
+ /** Magic used to validate the section state.
+ * RTCRITSECT_MAGIC is the value of an initialized & operational section. */
+ volatile uint32_t u32Magic;
+ /** Number of lockers.
+ * -1 if the section is free. */
+ volatile int32_t cLockers;
+ /** The owner thread. */
+ volatile RTNATIVETHREAD NativeThreadOwner;
+ /** Number of nested enter operations performed.
+ * Greater or equal to 1 if owned, 0 when free.
+ */
+ volatile int32_t cNestings;
+ /** Section flags - the RTCRITSECT_FLAGS_* \#defines. */
+ uint32_t fFlags;
+ /** The semaphore to block on. */
+ RTSEMEVENT EventSem;
+ /** Lock validator record. Only used in strict builds. */
+ R3R0PTRTYPE(PRTLOCKVALRECEXCL) pValidatorRec;
+ /** Alignmnet padding. */
+ RTHCPTR Alignment;
+} RTCRITSECT;
+AssertCompileSize(RTCRITSECT, HC_ARCH_BITS == 32 ? 32 : 48);
+
+/** RTCRITSECT::u32Magic value. (Hiromi Uehara) */
+#define RTCRITSECT_MAGIC UINT32_C(0x19790326)
+
+/** @name RTCritSectInitEx flags / RTCRITSECT::fFlags
+ * @{ */
+/** If set, nesting(/recursion) is not allowed. */
+#define RTCRITSECT_FLAGS_NO_NESTING UINT32_C(0x00000001)
+/** Disables lock validation. */
+#define RTCRITSECT_FLAGS_NO_LOCK_VAL UINT32_C(0x00000002)
+/** Bootstrap hack for use with certain memory allocator locks only! */
+#define RTCRITSECT_FLAGS_BOOTSTRAP_HACK UINT32_C(0x00000004)
+/** If set, the critical section becomes a dummy that doesn't serialize any
+ * threads. This flag can only be set at creation time.
+ *
+ * The intended use is avoiding lots of conditional code where some component
+ * might or might not require entering a critical section before access. */
+#define RTCRITSECT_FLAGS_NOP UINT32_C(0x00000008)
+/** @} */
+
+#ifdef IN_RING3
+
+/**
+ * Initialize a critical section.
+ */
+RTDECL(int) RTCritSectInit(PRTCRITSECT pCritSect);
+
+/**
+ * Initialize a critical section.
+ *
+ * @returns iprt status code.
+ * @param pCritSect Pointer to the critical section structure.
+ * @param fFlags Flags, any combination of the RTCRITSECT_FLAGS
+ * \#defines.
+ * @param hClass The class (no reference consumed). If NIL, no
+ * lock order validation will be performed on this
+ * lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order within a class. RTLOCKVAL_SUB_CLASS_NONE
+ * is the recommended value here.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTCritSectInitEx(PRTCRITSECT pCritSect, uint32_t fFlags,
+ RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...);
+
+/**
+ * Changes the lock validator sub-class of the critical section.
+ *
+ * It is recommended to try make sure that nobody is using this critical section
+ * while changing the value.
+ *
+ * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ * lock validator isn't compiled in or either of the parameters are
+ * invalid.
+ * @param pCritSect The critical section.
+ * @param uSubClass The new sub-class value.
+ */
+RTDECL(uint32_t) RTCritSectSetSubClass(PRTCRITSECT pCritSect, uint32_t uSubClass);
+
+/**
+ * Enter a critical section.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
+ * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
+ * @param pCritSect The critical section.
+ */
+RTDECL(int) RTCritSectEnter(PRTCRITSECT pCritSect);
+
+/**
+ * Enter a critical section.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
+ * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
+ *
+ * @param pCritSect The critical section.
+ * @param uId Where we're entering the section.
+ * @param pszFile The source position - file.
+ * @param iLine The source position - line.
+ * @param pszFunction The source position - function.
+ */
+RTDECL(int) RTCritSectEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Try enter a critical section.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_BUSY if the critsect was owned.
+ * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
+ * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
+ *
+ * @param pCritSect The critical section.
+ */
+RTDECL(int) RTCritSectTryEnter(PRTCRITSECT pCritSect);
+
+/**
+ * Try enter a critical section.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_BUSY if the critsect was owned.
+ * @retval VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
+ * @retval VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
+ *
+ * @param pCritSect The critical section.
+ * @param uId Where we're entering the section.
+ * @param pszFile The source position - file.
+ * @param iLine The source position - line.
+ * @param pszFunction The source position - function.
+ */
+RTDECL(int) RTCritSectTryEnterDebug(PRTCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Enter multiple critical sections.
+ *
+ * This function will enter ALL the specified critical sections before returning.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
+ * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
+ * @param cCritSects Number of critical sections in the array.
+ * @param papCritSects Array of critical section pointers.
+ *
+ * @remark Please note that this function will not necessarily come out favourable in a
+ * fight with other threads which are using the normal RTCritSectEnter() function.
+ * Therefore, avoid having to enter multiple critical sections!
+ */
+RTDECL(int) RTCritSectEnterMultiple(size_t cCritSects, PRTCRITSECT *papCritSects);
+
+/**
+ * Enter multiple critical sections.
+ *
+ * This function will enter ALL the specified critical sections before returning.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns VERR_SEM_NESTED if nested enter on a no nesting section. (Asserted.)
+ * @returns VERR_SEM_DESTROYED if RTCritSectDelete was called while waiting.
+ *
+ * @param cCritSects Number of critical sections in the array.
+ * @param papCritSects Array of critical section pointers.
+ * @param uId Where we're entering the section.
+ * @param pszFile The source position - file.
+ * @param iLine The source position - line.
+ * @param pszFunction The source position - function.
+ *
+ * @remark See RTCritSectEnterMultiple().
+ */
+RTDECL(int) RTCritSectEnterMultipleDebug(size_t cCritSects, PRTCRITSECT *papCritSects, RTUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Leave a critical section.
+ *
+ * @returns VINF_SUCCESS.
+ * @param pCritSect The critical section.
+ */
+RTDECL(int) RTCritSectLeave(PRTCRITSECT pCritSect);
+
+/**
+ * Leave multiple critical sections.
+ *
+ * @returns VINF_SUCCESS.
+ * @param cCritSects Number of critical sections in the array.
+ * @param papCritSects Array of critical section pointers.
+ */
+RTDECL(int) RTCritSectLeaveMultiple(size_t cCritSects, PRTCRITSECT *papCritSects);
+
+/**
+ * Deletes a critical section.
+ *
+ * @returns VINF_SUCCESS.
+ * @param pCritSect The critical section.
+ */
+RTDECL(int) RTCritSectDelete(PRTCRITSECT pCritSect);
+
+/**
+ * Checks the caller is the owner of the critical section.
+ *
+ * @returns true if owner.
+ * @returns false if not owner.
+ * @param pCritSect The critical section.
+ */
+DECLINLINE(bool) RTCritSectIsOwner(PCRTCRITSECT pCritSect)
+{
+ return pCritSect->NativeThreadOwner == RTThreadNativeSelf();
+}
+
+#endif /* IN_RING3 */
+
+/**
+ * Checks the section is owned by anyone.
+ *
+ * @returns true if owned.
+ * @returns false if not owned.
+ * @param pCritSect The critical section.
+ */
+DECLINLINE(bool) RTCritSectIsOwned(PCRTCRITSECT pCritSect)
+{
+ return pCritSect->NativeThreadOwner != NIL_RTNATIVETHREAD;
+}
+
+/**
+ * Gets the thread id of the critical section owner.
+ *
+ * @returns Thread id of the owner thread if owned.
+ * @returns NIL_RTNATIVETHREAD is not owned.
+ * @param pCritSect The critical section.
+ */
+DECLINLINE(RTNATIVETHREAD) RTCritSectGetOwner(PCRTCRITSECT pCritSect)
+{
+ return pCritSect->NativeThreadOwner;
+}
+
+/**
+ * Checks if a critical section is initialized or not.
+ *
+ * @returns true if initialized.
+ * @returns false if not initialized.
+ * @param pCritSect The critical section.
+ */
+DECLINLINE(bool) RTCritSectIsInitialized(PCRTCRITSECT pCritSect)
+{
+ return pCritSect->u32Magic == RTCRITSECT_MAGIC;
+}
+
+/**
+ * Gets the recursion depth.
+ *
+ * @returns The recursion depth.
+ * @param pCritSect The Critical section
+ */
+DECLINLINE(uint32_t) RTCritSectGetRecursion(PCRTCRITSECT pCritSect)
+{
+ return pCritSect->cNestings;
+}
+
+/**
+ * Gets the waiter count
+ *
+ * @returns The waiter count
+ * @param pCritSect The Critical section
+ */
+DECLINLINE(int32_t) RTCritSectGetWaiters(PCRTCRITSECT pCritSect)
+{
+ return pCritSect->cLockers;
+}
+
+/* Lock strict build: Remap the three enter calls to the debug versions. */
+#if defined(RT_LOCK_STRICT) && !defined(RTCRITSECT_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# ifdef ___iprt_asm_h
+# define RTCritSectEnter(pCritSect) RTCritSectEnterDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTCritSectTryEnter(pCritSect) RTCritSectTryEnterDebug(pCritSect, (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTCritSectEnterMultiple(cCritSects, pCritSect) RTCritSectEnterMultipleDebug((cCritSects), (pCritSect), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+# define RTCritSectEnter(pCritSect) RTCritSectEnterDebug(pCritSect, 0, RT_SRC_POS)
+# define RTCritSectTryEnter(pCritSect) RTCritSectTryEnterDebug(pCritSect, 0, RT_SRC_POS)
+# define RTCritSectEnterMultiple(cCritSects, pCritSect) RTCritSectEnterMultipleDebug((cCritSects), (pCritSect), 0, RT_SRC_POS)
+# endif
+#endif
+
+/* Strict lock order: Automatically classify locks by init location. */
+#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTCRITSECT_WITHOUT_REMAPPING) &&!defined(RT_WITH_MANGLING)
+# define RTCritSectInit(pCritSect) \
+ RTCritSectInitEx((pCritSect), 0 /*fFlags*/, \
+ RTLockValidatorClassForSrcPos(RT_SRC_POS, NULL), \
+ RTLOCKVAL_SUB_CLASS_NONE, NULL)
+#endif
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/ctype.h b/include/iprt/ctype.h
new file mode 100644
index 00000000..b491aa32
--- /dev/null
+++ b/include/iprt/ctype.h
@@ -0,0 +1,238 @@
+/** @file
+ * IPRT - Simple character type classiciation and conversion.
+ */
+
+/*
+ * 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 ___iprt_ctype_h
+#define ___iprt_ctype_h
+
+#include <iprt/types.h>
+
+/** @name C locale predicates and conversions.
+ *
+ * For most practical purposes, this can safely be used when parsing UTF-8
+ * strings. Just keep in mind that we only deal with the first 127 chars and
+ * that full correctness is only archived using the non-existing RTLocIs* API.
+ *
+ * @remarks Use the marcros, not the inlined functions.
+ *
+ * @remarks ASSUMES the source code includes the basic ASCII chars. This is a
+ * general IPRT assumption.
+ * @{ */
+#define RT_C_IS_BLANK(ch) RTLocCIsBlank((ch))
+#define RT_C_IS_ALNUM(ch) RTLocCIsAlNum((ch))
+#define RT_C_IS_ALPHA(ch) RTLocCIsAlpha((ch))
+#define RT_C_IS_CNTRL(ch) RTLocCIsCntrl((ch))
+#define RT_C_IS_DIGIT(ch) RTLocCIsDigit((ch))
+#define RT_C_IS_LOWER(ch) RTLocCIsLower((ch))
+#define RT_C_IS_GRAPH(ch) RTLocCIsGraph((ch))
+#define RT_C_IS_ODIGIT(ch) RTLocCIsODigit((ch))
+#define RT_C_IS_PRINT(ch) RTLocCIsPrint((ch))
+#define RT_C_IS_PUNCT(ch) RTLocCIsPunct((ch))
+#define RT_C_IS_SPACE(ch) RTLocCIsSpace((ch))
+#define RT_C_IS_UPPER(ch) RTLocCIsUpper((ch))
+#define RT_C_IS_XDIGIT(ch) RTLocCIsXDigit((ch))
+
+#define RT_C_TO_LOWER(ch) RTLocCToLower((ch))
+#define RT_C_TO_UPPER(ch) RTLocCToUpper((ch))
+
+/**
+ * Checks for a blank character.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsBlank(int ch)
+{
+ return ch == 0x20 /* space */
+ || ch == 0x09; /* horizontal tab */
+}
+
+/**
+ * Checks for a control character.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsCntrl(int ch)
+{
+ return (unsigned)ch < 32U /* 0..2f */
+ || ch == 0x7f;
+}
+
+/**
+ * Checks for a decimal digit.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsDigit(int ch)
+{
+ return (unsigned)ch - 0x30 < 10U; /* 30..39 */
+}
+
+/**
+ * Checks for a lower case character.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsLower(int ch)
+{
+ return (unsigned)ch - 0x61U < 26U; /* 61..7a */
+}
+
+/**
+ * Checks for an octal digit.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsODigit(int ch)
+{
+ return (unsigned)ch - 0x30 < 8U; /* 30..37 */
+}
+
+/**
+ * Checks for a printable character (whitespace included).
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsPrint(int ch)
+{
+ return (unsigned)ch - 0x20U < 95U; /* 20..7e */
+}
+
+/**
+ * Checks for punctuation (?).
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsPunct(int ch)
+{
+ return (unsigned)ch - 0x21U < 15U /* 21..2f */
+ || (unsigned)ch - 0x2aU < 6U /* 2a..2f */
+ || (unsigned)ch - 0x3aU < 7U /* 3a..40 */
+ || (unsigned)ch - 0x5bU < 6U /* 5a..60 */
+ || (unsigned)ch - 0x7bU < 4U /* 7b..7e */;
+}
+
+/**
+ * Checks for a white-space character.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsSpace(int ch)
+{
+ return ch == 0x20 /* 20 (space) */
+ || (unsigned)ch - 0x09U < 5U; /* 09..0d */
+}
+
+/**
+ * Checks for an upper case character.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsUpper(int ch)
+{
+ return (unsigned)ch - 0x41 < 26U; /* 41..5a */
+}
+
+/**
+ * Checks for a hexadecimal digit.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsXDigit(int ch)
+{
+ return (unsigned)ch - 0x30 < 10U /* 30..39 (0-9) */
+ || (unsigned)ch - 0x41 < 6 /* 41..46 (A-F) */
+ || (unsigned)ch - 0x61 < 6; /* 61..66 (a-f) */
+}
+
+/**
+ * Checks for an alphabetic character.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsAlpha(int ch)
+{
+ return RTLocCIsLower(ch) || RTLocCIsUpper(ch);
+}
+
+/**
+ * Checks for an alphanumerical character.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsAlNum(int ch)
+{
+ return RTLocCIsDigit(ch) || RTLocCIsAlpha(ch);
+}
+
+/**
+ * Checks for a printable character whitespace excluded.
+ *
+ * @returns true / false.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(bool) RTLocCIsGraph(int ch)
+{
+ return RTLocCIsPrint(ch) && !RTLocCIsBlank(ch);
+}
+
+
+/**
+ * Converts the character to lower case if applictable.
+ *
+ * @returns lower cased character or ch.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(int) RTLocCToLower(int ch)
+{
+ return RTLocCIsUpper(ch) ? (ch) + 0x20 : (ch);
+}
+
+/**
+ * Converts the character to upper case if applictable.
+ *
+ * @returns upper cased character or ch.
+ * @param ch The character to test.
+ */
+DECL_FORCE_INLINE(int) RTLocCToUpper(int ch)
+{
+ return RTLocCIsLower(ch) ? (ch) - 0x20 : (ch);
+}
+
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/dbg.h b/include/iprt/dbg.h
new file mode 100644
index 00000000..04bea827
--- /dev/null
+++ b/include/iprt/dbg.h
@@ -0,0 +1,1273 @@
+/* $Id: dbg.h $ */
+/** @file
+ * IPRT - Debugging Routines.
+ */
+
+/*
+ * Copyright (C) 2008-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 ___iprt_dbg_h
+#define ___iprt_dbg_h
+
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+# ifdef IN_RING3
+
+/** @defgroup grp_rt_dbg RTDbg - Debugging Routines
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** Debug segment index. */
+typedef uint32_t RTDBGSEGIDX;
+/** Pointer to a debug segment index. */
+typedef RTDBGSEGIDX *PRTDBGSEGIDX;
+/** Pointer to a const debug segment index. */
+typedef RTDBGSEGIDX const *PCRTDBGSEGIDX;
+/** NIL debug segment index. */
+#define NIL_RTDBGSEGIDX UINT32_C(0xffffffff)
+/** The last normal segment index. */
+#define RTDBGSEGIDX_LAST UINT32_C(0xffffffef)
+/** Special segment index that indicates that the offset is a relative
+ * virtual address (RVA). I.e. an offset from the start of the module. */
+#define RTDBGSEGIDX_RVA UINT32_C(0xfffffff0)
+/** Special segment index that indicates that the offset is a absolute. */
+#define RTDBGSEGIDX_ABS UINT32_C(0xfffffff1)
+/** The last valid special segment index. */
+#define RTDBGSEGIDX_SPECIAL_LAST RTDBGSEGIDX_ABS
+/** The last valid special segment index. */
+#define RTDBGSEGIDX_SPECIAL_FIRST (RTDBGSEGIDX_LAST + 1U)
+
+
+/** @name RTDBGSYMADDR_FLAGS_XXX
+ * Flags used when looking up a symbol by address.
+ * @{ */
+/** Less or equal address. (default) */
+#define RTDBGSYMADDR_FLAGS_LESS_OR_EQUAL UINT32_C(0)
+/** Greater or equal address. */
+#define RTDBGSYMADDR_FLAGS_GREATER_OR_EQUAL UINT32_C(1)
+/** Mask of valid flags. */
+#define RTDBGSYMADDR_FLAGS_VALID_MASK UINT32_C(1)
+/** @} */
+
+
+/** Max length (including '\\0') of a segment name. */
+#define RTDBG_SEGMENT_NAME_LENGTH (128 - 8 - 8 - 8 - 4 - 4)
+
+/**
+ * Debug module segment.
+ */
+typedef struct RTDBGSEGMENT
+{
+ /** The load address.
+ * RTUINTPTR_MAX if not applicable. */
+ RTUINTPTR Address;
+ /** The image relative virtual address of the segment.
+ * RTUINTPTR_MAX if not applicable. */
+ RTUINTPTR uRva;
+ /** The segment size. */
+ RTUINTPTR cb;
+ /** The segment flags. (reserved) */
+ uint32_t fFlags;
+ /** The segment index. */
+ RTDBGSEGIDX iSeg;
+ /** Symbol name. */
+ char szName[RTDBG_SEGMENT_NAME_LENGTH];
+} RTDBGSEGMENT;
+/** Pointer to a debug module segment. */
+typedef RTDBGSEGMENT *PRTDBGSEGMENT;
+/** Pointer to a const debug module segment. */
+typedef RTDBGSEGMENT const *PCRTDBGSEGMENT;
+
+
+
+/** Max length (including '\\0') of a symbol name. */
+#define RTDBG_SYMBOL_NAME_LENGTH (384 - 8 - 8 - 8 - 4 - 4 - 8)
+
+/**
+ * Debug symbol.
+ */
+typedef struct RTDBGSYMBOL
+{
+ /** Symbol value (address).
+ * This depends a bit who you ask. It will be the same as offSeg when you
+ * as RTDbgMod, but the mapping address if you ask RTDbgAs. */
+ RTUINTPTR Value;
+ /** Symbol size. */
+ RTUINTPTR cb;
+ /** Offset into the segment specified by iSeg. */
+ RTUINTPTR offSeg;
+ /** Segment number. */
+ RTDBGSEGIDX iSeg;
+ /** Symbol Flags. (reserved). */
+ uint32_t fFlags;
+ /** Symbol ordinal.
+ * This is set to UINT32_MAX if the ordinals aren't supported. */
+ uint32_t iOrdinal;
+ /** Symbol name. */
+ char szName[RTDBG_SYMBOL_NAME_LENGTH];
+} RTDBGSYMBOL;
+/** Pointer to debug symbol. */
+typedef RTDBGSYMBOL *PRTDBGSYMBOL;
+/** Pointer to const debug symbol. */
+typedef const RTDBGSYMBOL *PCRTDBGSYMBOL;
+
+/**
+ * Allocate a new symbol structure.
+ *
+ * @returns Pointer to a new structure on success, NULL on failure.
+ */
+RTDECL(PRTDBGSYMBOL) RTDbgSymbolAlloc(void);
+
+/**
+ * Duplicates a symbol structure.
+ *
+ * @returns Pointer to duplicate on success, NULL on failure.
+ *
+ * @param pSymInfo The symbol info to duplicate.
+ */
+RTDECL(PRTDBGSYMBOL) RTDbgSymbolDup(PCRTDBGSYMBOL pSymInfo);
+
+/**
+ * Free a symbol structure previously allocated by a RTDbg method.
+ *
+ * @param pSymInfo The symbol info to free. NULL is ignored.
+ */
+RTDECL(void) RTDbgSymbolFree(PRTDBGSYMBOL pSymInfo);
+
+
+/** Max length (including '\\0') of a debug info file name. */
+#define RTDBG_FILE_NAME_LENGTH (260)
+
+
+/**
+ * Debug line number information.
+ */
+typedef struct RTDBGLINE
+{
+ /** Address.
+ * This depends a bit who you ask. It will be the same as offSeg when you
+ * as RTDbgMod, but the mapping address if you ask RTDbgAs. */
+ RTUINTPTR Address;
+ /** Offset into the segment specified by iSeg. */
+ RTUINTPTR offSeg;
+ /** Segment number. */
+ RTDBGSEGIDX iSeg;
+ /** Line number. */
+ uint32_t uLineNo;
+ /** Symbol ordinal.
+ * This is set to UINT32_MAX if the ordinals aren't supported. */
+ uint32_t iOrdinal;
+ /** Filename. */
+ char szFilename[RTDBG_FILE_NAME_LENGTH];
+} RTDBGLINE;
+/** Pointer to debug line number. */
+typedef RTDBGLINE *PRTDBGLINE;
+/** Pointer to const debug line number. */
+typedef const RTDBGLINE *PCRTDBGLINE;
+
+/**
+ * Allocate a new line number structure.
+ *
+ * @returns Pointer to a new structure on success, NULL on failure.
+ */
+RTDECL(PRTDBGLINE) RTDbgLineAlloc(void);
+
+/**
+ * Duplicates a line number structure.
+ *
+ * @returns Pointer to duplicate on success, NULL on failure.
+ *
+ * @param pLine The line number to duplicate.
+ */
+RTDECL(PRTDBGLINE) RTDbgLineDup(PCRTDBGLINE pLine);
+
+/**
+ * Free a line number structure previously allocated by a RTDbg method.
+ *
+ * @param pLine The line number to free. NULL is ignored.
+ */
+RTDECL(void) RTDbgLineFree(PRTDBGLINE pLine);
+
+
+/** @defgroup grp_rt_dbgas RTDbgAs - Debug Address Space
+ * @{
+ */
+
+/**
+ * Creates an empty address space.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phDbgAs Where to store the address space handle on success.
+ * @param FirstAddr The first address in the address space.
+ * @param LastAddr The last address in the address space.
+ * @param pszName The name of the address space.
+ */
+RTDECL(int) RTDbgAsCreate(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszName);
+
+/**
+ * Variant of RTDbgAsCreate that takes a name format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phDbgAs Where to store the address space handle on success.
+ * @param FirstAddr The first address in the address space.
+ * @param LastAddr The last address in the address space.
+ * @param pszNameFmt The name format of the address space.
+ * @param va Format arguments.
+ */
+RTDECL(int) RTDbgAsCreateV(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, va_list va);
+
+/**
+ * Variant of RTDbgAsCreate that takes a name format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phDbgAs Where to store the address space handle on success.
+ * @param FirstAddr The first address in the address space.
+ * @param LastAddr The last address in the address space.
+ * @param pszNameFmt The name format of the address space.
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTDbgAsCreateF(PRTDBGAS phDbgAs, RTUINTPTR FirstAddr, RTUINTPTR LastAddr, const char *pszNameFmt, ...);
+
+/**
+ * Retains a reference to the address space.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ *
+ * @param hDbgAs The address space handle.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(uint32_t) RTDbgAsRetain(RTDBGAS hDbgAs);
+
+/**
+ * Release a reference to the address space.
+ *
+ * When the reference count reaches zero, the address space is destroyed.
+ * That means unlinking all the modules it currently contains, potentially
+ * causing some or all of them to be destroyed as they are managed by
+ * reference counting.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ *
+ * @param hDbgAs The address space handle. The NIL handle is quietly
+ * ignored and 0 is returned.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(uint32_t) RTDbgAsRelease(RTDBGAS hDbgAs);
+
+/**
+ * Gets the name of an address space.
+ *
+ * @returns read only address space name.
+ * NULL if hDbgAs is invalid.
+ *
+ * @param hDbgAs The address space handle.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(const char *) RTDbgAsName(RTDBGAS hDbgAs);
+
+/**
+ * Gets the first address in an address space.
+ *
+ * @returns The address.
+ * 0 if hDbgAs is invalid.
+ *
+ * @param hDbgAs The address space handle.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(RTUINTPTR) RTDbgAsFirstAddr(RTDBGAS hDbgAs);
+
+/**
+ * Gets the last address in an address space.
+ *
+ * @returns The address.
+ * 0 if hDbgAs is invalid.
+ *
+ * @param hDbgAs The address space handle.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(RTUINTPTR) RTDbgAsLastAddr(RTDBGAS hDbgAs);
+
+/**
+ * Gets the number of modules in the address space.
+ *
+ * This can be used together with RTDbgAsModuleByIndex
+ * to enumerate the modules.
+ *
+ * @returns The number of modules.
+ *
+ * @param hDbgAs The address space handle.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(uint32_t) RTDbgAsModuleCount(RTDBGAS hDbgAs);
+
+/** @name Flags for RTDbgAsModuleLink and RTDbgAsModuleLinkSeg
+ * @{ */
+/** Replace all conflicting module.
+ * (The conflicting modules will be removed the address space and their
+ * references released.) */
+#define RTDBGASLINK_FLAGS_REPLACE RT_BIT_32(0)
+/** Mask containing the valid flags. */
+#define RTDBGASLINK_FLAGS_VALID_MASK UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Links a module into the address space at the give address.
+ *
+ * The size of the mapping is determined using RTDbgModImageSize().
+ *
+ * @returns IPRT status code.
+ * @retval VERR_OUT_OF_RANGE if the specified address will put the module
+ * outside the address space.
+ * @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
+ *
+ * @param hDbgAs The address space handle.
+ * @param hDbgMod The module handle of the module to be linked in.
+ * @param ImageAddr The address to link the module at.
+ * @param fFlags See RTDBGASLINK_FLAGS_*.
+ */
+RTDECL(int) RTDbgAsModuleLink(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTUINTPTR ImageAddr, uint32_t fFlags);
+
+/**
+ * Links a segment into the address space at the give address.
+ *
+ * The size of the mapping is determined using RTDbgModSegmentSize().
+ *
+ * @returns IPRT status code.
+ * @retval VERR_OUT_OF_RANGE if the specified address will put the module
+ * outside the address space.
+ * @retval VERR_ADDRESS_CONFLICT if the mapping clashes with existing mappings.
+ *
+ * @param hDbgAs The address space handle.
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment number (0-based) of the segment to be
+ * linked in.
+ * @param SegAddr The address to link the segment at.
+ * @param fFlags See RTDBGASLINK_FLAGS_*.
+ */
+RTDECL(int) RTDbgAsModuleLinkSeg(RTDBGAS hDbgAs, RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR SegAddr, uint32_t fFlags);
+
+/**
+ * Unlinks all the mappings of a module from the address space.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_FOUND if the module wasn't found.
+ *
+ * @param hDbgAs The address space handle.
+ * @param hDbgMod The module handle of the module to be unlinked.
+ */
+RTDECL(int) RTDbgAsModuleUnlink(RTDBGAS hDbgAs, RTDBGMOD hDbgMod);
+
+/**
+ * Unlinks the mapping at the specified address.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_FOUND if no module or segment is mapped at that address.
+ *
+ * @param hDbgAs The address space handle.
+ * @param Addr The address within the mapping to be unlinked.
+ */
+RTDECL(int) RTDbgAsModuleUnlinkByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr);
+
+/**
+ * Get a the handle of a module in the address space by is index.
+ *
+ * @returns A retained handle to the specified module. The caller must release
+ * the returned reference.
+ * NIL_RTDBGMOD if invalid index or handle.
+ *
+ * @param hDbgAs The address space handle.
+ * @param iModule The index of the module to get.
+ *
+ * @remarks The module indexes may change after calls to RTDbgAsModuleLink,
+ * RTDbgAsModuleLinkSeg, RTDbgAsModuleUnlink and
+ * RTDbgAsModuleUnlinkByAddr.
+ */
+RTDECL(RTDBGMOD) RTDbgAsModuleByIndex(RTDBGAS hDbgAs, uint32_t iModule);
+
+/**
+ * Queries mapping module information by handle.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_FOUND if no mapping was found at the specified address.
+ *
+ * @param hDbgAs The address space handle.
+ * @param Addr Address within the mapping of the module or segment.
+ * @param phMod Where to the return the retained module handle.
+ * Optional.
+ * @param pAddr Where to return the base address of the mapping.
+ * Optional.
+ * @param piSeg Where to return the segment index. This is set to
+ * NIL if the entire module is mapped as a single
+ * mapping. Optional.
+ */
+RTDECL(int) RTDbgAsModuleByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTDBGMOD phMod, PRTUINTPTR pAddr, PRTDBGSEGIDX piSeg);
+
+/**
+ * Queries mapping module information by name.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_FOUND if no mapping was found at the specified address.
+ * @retval VERR_OUT_OF_RANGE if the name index was out of range.
+ *
+ * @param hDbgAs The address space handle.
+ * @param pszName The module name.
+ * @param iName There can be more than one module by the same name
+ * in an address space. This argument indicates which
+ * is meant. (0 based)
+ * @param phMod Where to the return the retained module handle.
+ */
+RTDECL(int) RTDbgAsModuleByName(RTDBGAS hDbgAs, const char *pszName, uint32_t iName, PRTDBGMOD phMod);
+
+/**
+ * Information about a mapping.
+ *
+ * This is used by RTDbgAsModuleGetMapByIndex.
+ */
+typedef struct RTDBGASMAPINFO
+{
+ /** The mapping address. */
+ RTUINTPTR Address;
+ /** The segment mapped there.
+ * This is NIL_RTDBGSEGIDX if the entire module image is mapped here. */
+ RTDBGSEGIDX iSeg;
+} RTDBGASMAPINFO;
+/** Pointer to info about an address space mapping. */
+typedef RTDBGASMAPINFO *PRTDBGASMAPINFO;
+/** Pointer to const info about an address space mapping. */
+typedef RTDBGASMAPINFO const *PCRTDBGASMAPINFO;
+
+/**
+ * Queries mapping information for a module given by index.
+ *
+ * @returns IRPT status code.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_OUT_OF_RANGE if the name index was out of range.
+ * @retval VINF_BUFFER_OVERFLOW if the array is too small and the returned
+ * information is incomplete.
+ *
+ * @param hDbgAs The address space handle.
+ * @param iModule The index of the module to get.
+ * @param paMappings Where to return the mapping information. The buffer
+ * size is given by *pcMappings.
+ * @param pcMappings IN: Size of the paMappings array. OUT: The number of
+ * entries returned.
+ * @param fFlags Flags for reserved for future use. MBZ.
+ *
+ * @remarks See remarks for RTDbgAsModuleByIndex regarding the volatility of the
+ * iModule parameter.
+ */
+RTDECL(int) RTDbgAsModuleQueryMapByIndex(RTDBGAS hDbgAs, uint32_t iModule, PRTDBGASMAPINFO paMappings, uint32_t *pcMappings, uint32_t fFlags);
+
+/**
+ * Adds a symbol to a module in the address space.
+ *
+ * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_NOT_FOUND if no module was found at the specified address.
+ * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
+ * custom symbols.
+ *
+ * @param hDbgAs The address space handle.
+ * @param pszSymbol The symbol name.
+ * @param Addr The address of the symbol.
+ * @param cb The size of the symbol.
+ * @param fFlags Symbol flags.
+ * @param piOrdinal Where to return the symbol ordinal on success. If
+ * the interpreter doesn't do ordinals, this will be set to
+ * UINT32_MAX. Optional
+ */
+RTDECL(int) RTDbgAsSymbolAdd(RTDBGAS hDbgAs, const char *pszSymbol, RTUINTPTR Addr, RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal);
+
+/**
+ * Query a symbol by address.
+ *
+ * @returns IPRT status code. See RTDbgModSymbolAddr for more specific ones.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
+ * @retval VERR_INVALID_PARAMETER if incorrect flags.
+ *
+ * @param hDbgAs The address space handle.
+ * @param Addr The address which closest symbol is requested.
+ * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
+ * @param poffDisp Where to return the distance between the symbol
+ * and address. Optional.
+ * @param pSymbol Where to return the symbol info.
+ * @param phMod Where to return the module handle. Optional.
+ */
+RTDECL(int) RTDbgAsSymbolByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, uint32_t fFlags,
+ PRTINTPTR poffDisp, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
+
+/**
+ * Query a symbol by address.
+ *
+ * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
+ * @retval VERR_INVALID_PARAMETER if incorrect flags.
+ *
+ * @param hDbgAs The address space handle.
+ * @param Addr The address which closest symbol is requested.
+ * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
+ * @param poffDisp Where to return the distance between the symbol
+ * and address. Optional.
+ * @param ppSymInfo Where to return the pointer to the allocated symbol
+ * info. Always set. Free with RTDbgSymbolFree.
+ * @param phMod Where to return the module handle. Optional.
+ */
+RTDECL(int) RTDbgAsSymbolByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, uint32_t fFlags,
+ PRTINTPTR poffDisp, PRTDBGSYMBOL *ppSymInfo, PRTDBGMOD phMod);
+
+/**
+ * Query a symbol by name.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_SYMBOL_NOT_FOUND if not found.
+ *
+ * @param hDbgAs The address space handle.
+ * @param pszSymbol The symbol name. It is possible to limit the scope
+ * of the search by prefixing the symbol with a module
+ * name pattern followed by a bang (!) character.
+ * RTStrSimplePatternNMatch is used for the matching.
+ * @param pSymbol Where to return the symbol info.
+ * @param phMod Where to return the module handle. Optional.
+ */
+RTDECL(int) RTDbgAsSymbolByName(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL pSymbol, PRTDBGMOD phMod);
+
+/**
+ * Query a symbol by name, allocating the returned symbol structure.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_SYMBOL_NOT_FOUND if not found.
+ *
+ * @param hDbgAs The address space handle.
+ * @param pszSymbol The symbol name. See RTDbgAsSymbolByName for more.
+ * @param ppSymbol Where to return the pointer to the allocated
+ * symbol info. Always set. Free with RTDbgSymbolFree.
+ * @param phMod Where to return the module handle. Optional.
+ */
+RTDECL(int) RTDbgAsSymbolByNameA(RTDBGAS hDbgAs, const char *pszSymbol, PRTDBGSYMBOL *ppSymbol, PRTDBGMOD phMod);
+
+/**
+ * Query a line number by address.
+ *
+ * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
+ *
+ * @param hDbgAs The address space handle.
+ * @param Addr The address which closest symbol is requested.
+ * @param poffDisp Where to return the distance between the line
+ * number and address.
+ * @param pLine Where to return the line number information.
+ */
+RTDECL(int) RTDbgAs(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine);
+
+/**
+ * Adds a line number to a module in the address space.
+ *
+ * @returns IPRT status code. See RTDbgModSymbolAdd for more specific ones.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_NOT_FOUND if no module was found at the specified address.
+ * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
+ * custom symbols.
+ *
+ * @param hDbgAs The address space handle.
+ * @param pszFile The file name.
+ * @param uLineNo The line number.
+ * @param Addr The address of the symbol.
+ * @param piOrdinal Where to return the line number ordinal on success.
+ * If the interpreter doesn't do ordinals, this will be
+ * set to UINT32_MAX. Optional.
+ */
+RTDECL(int) RTDbgAsLineAdd(RTDBGAS hDbgAs, const char *pszFile, uint32_t uLineNo, RTUINTPTR Addr, uint32_t *piOrdinal);
+
+
+/**
+ * Query a line number by address.
+ *
+ * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
+ *
+ * @param hDbgAs The address space handle.
+ * @param Addr The address which closest symbol is requested.
+ * @param poffDisp Where to return the distance between the line
+ * number and address.
+ * @param pLine Where to return the line number information.
+ */
+RTDECL(int) RTDbgAsLineByAddr(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE pLine);
+
+/**
+ * Query a line number by address.
+ *
+ * @returns IPRT status code. See RTDbgModSymbolAddrA for more specific ones.
+ * @retval VERR_INVALID_HANDLE if hDbgAs is invalid.
+ * @retval VERR_NOT_FOUND if the address couldn't be mapped to a module.
+ *
+ * @param hDbgAs The address space handle.
+ * @param Addr The address which closest symbol is requested.
+ * @param poffDisp Where to return the distance between the line
+ * number and address.
+ * @param ppLine Where to return the pointer to the allocated line
+ * number info. Always set. Free with RTDbgLineFree.
+ */
+RTDECL(int) RTDbgAsLineByAddrA(RTDBGAS hDbgAs, RTUINTPTR Addr, PRTINTPTR poffDisp, PRTDBGLINE *ppLine);
+
+/** @todo Missing some bits here. */
+
+/** @} */
+
+
+/** @defgroup grp_rt_dbgmod RTDbgMod - Debug Module Interpreter
+ * @{
+ */
+
+/**
+ * Creates a module based on the default debug info container.
+ *
+ * This can be used to manually load a module and its symbol. The primary user
+ * group is the debug info interpreters, which use this API to create an
+ * efficient debug info container behind the scenes and forward all queries to
+ * it once the info has been loaded.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phDbgMod Where to return the module handle.
+ * @param pszName The name of the module (mandatory).
+ * @param cbSeg The size of initial segment. If zero, segments will
+ * have to be added manually using RTDbgModSegmentAdd.
+ * @param fFlags Flags reserved for future extensions, MBZ for now.
+ */
+RTDECL(int) RTDbgModCreate(PRTDBGMOD phDbgMod, const char *pszName, RTUINTPTR cbSeg, uint32_t fFlags);
+
+RTDECL(int) RTDbgModCreateDeferred(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR cb, uint32_t fFlags);
+RTDECL(int) RTDbgModCreateFromImage(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, uint32_t fFlags);
+RTDECL(int) RTDbgModCreateFromMap(PRTDBGMOD phDbgMod, const char *pszFilename, const char *pszName, RTUINTPTR uSubtrahend, uint32_t fFlags);
+
+
+/**
+ * Retains another reference to the module.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ *
+ * @param hDbgMod The module handle.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(uint32_t) RTDbgModRetain(RTDBGMOD hDbgMod);
+
+/**
+ * Release a reference to the module.
+ *
+ * When the reference count reaches zero, the module is destroyed.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ *
+ * @param hDbgMod The module handle. The NIL handle is quietly ignored
+ * and 0 is returned.
+ *
+ * @remarks Will not take any locks.
+ */
+RTDECL(uint32_t) RTDbgModRelease(RTDBGMOD hDbgMod);
+
+/**
+ * Gets the module name.
+ *
+ * @returns Pointer to a read only string containing the name.
+ *
+ * @param hDbgMod The module handle.
+ */
+RTDECL(const char *) RTDbgModName(RTDBGMOD hDbgMod);
+
+/**
+ * Converts an image relative address to a segment:offset address.
+ *
+ * @returns Segment index on success.
+ * NIL_RTDBGSEGIDX is returned if the module handle or the RVA are
+ * invalid.
+ *
+ * @param hDbgMod The module handle.
+ * @param uRva The image relative address to convert.
+ * @param poffSeg Where to return the segment offset. Optional.
+ */
+RTDECL(RTDBGSEGIDX) RTDbgModRvaToSegOff(RTDBGMOD hDbgMod, RTUINTPTR uRva, PRTUINTPTR poffSeg);
+
+/**
+ * Image size when mapped if segments are mapped adjacently.
+ *
+ * For ELF, PE, and Mach-O images this is (usually) a natural query, for LX and
+ * NE and such it's a bit odder and the answer may not make much sense for them.
+ *
+ * @returns Image mapped size.
+ * RTUINTPTR_MAX is returned if the handle is invalid.
+ *
+ * @param hDbgMod The module handle.
+ */
+RTDECL(RTUINTPTR) RTDbgModImageSize(RTDBGMOD hDbgMod);
+
+/**
+ * Gets the module tag value if any.
+ *
+ * @returns The tag. 0 if hDbgMod is invalid.
+ *
+ * @param hDbgMod The module handle.
+ */
+RTDECL(uint64_t) RTDbgModGetTag(RTDBGMOD hDbgMod);
+
+/**
+ * Tags or untags the module.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ *
+ * @param hDbgMod The module handle.
+ * @param uTag The tag value. The convention is that 0 is no tag
+ * and any other value means it's tagged. It's adviced
+ * to use some kind of unique number like an address
+ * (global or string cache for instance) to avoid
+ * collisions with other users
+ */
+RTDECL(int) RTDbgModSetTag(RTDBGMOD hDbgMod, uint64_t uTag);
+
+
+/**
+ * Adds a segment to the module. Optional feature.
+ *
+ * This method is intended used for manually constructing debug info for a
+ * module. The main usage is from other debug info interpreters that want to
+ * avoid writing a debug info database and instead uses the standard container
+ * behind the scenes.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if this feature isn't support by the debug info
+ * interpreter. This is a common return code.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_DBG_ADDRESS_WRAP if uRva+cb wraps around.
+ * @retval VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE if pszName is too short or long.
+ * @retval VERR_INVALID_PARAMETER if fFlags contains undefined flags.
+ * @retval VERR_DBG_SPECIAL_SEGMENT if *piSeg is a special segment.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if *piSeg doesn't meet expectations.
+ *
+ * @param hDbgMod The module handle.
+ * @param uRva The image relative address of the segment.
+ * @param cb The size of the segment.
+ * @param pszName The segment name. Does not normally need to be
+ * unique, although this is somewhat up to the
+ * debug interpreter to decide.
+ * @param fFlags Segment flags. Reserved for future used, MBZ.
+ * @param piSeg The segment index or NIL_RTDBGSEGIDX on input.
+ * The assigned segment index on successful return.
+ * Optional.
+ */
+RTDECL(int) RTDbgModSegmentAdd(RTDBGMOD hDbgMod, RTUINTPTR uRva, RTUINTPTR cb, const char *pszName,
+ uint32_t fFlags, PRTDBGSEGIDX piSeg);
+
+/**
+ * Gets the number of segments in the module.
+ *
+ * This is can be used to determine the range which can be passed to
+ * RTDbgModSegmentByIndex and derivates.
+ *
+ * @returns The segment relative address.
+ * NIL_RTDBGSEGIDX if the handle is invalid.
+ *
+ * @param hDbgMod The module handle.
+ */
+RTDECL(RTDBGSEGIDX) RTDbgModSegmentCount(RTDBGMOD hDbgMod);
+
+/**
+ * Query information about a segment.
+ *
+ * This can be used together with RTDbgModSegmentCount to enumerate segments.
+ * The index starts a 0 and stops one below RTDbgModSegmentCount.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if iSeg is too high.
+ * @retval VERR_DBG_SPECIAL_SEGMENT if iSeg indicates a special segment.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ *
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment index. No special segments.
+ * @param pSegInfo Where to return the segment info. The
+ * RTDBGSEGMENT::Address member will be set to
+ * RTUINTPTR_MAX or the load address used at link time.
+ */
+RTDECL(int) RTDbgModSegmentByIndex(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, PRTDBGSEGMENT pSegInfo);
+
+/**
+ * Gets the size of a segment.
+ *
+ * This is a just a wrapper around RTDbgModSegmentByIndex.
+ *
+ * @returns The segment size.
+ * RTUINTPTR_MAX is returned if either the handle and segment index are
+ * invalid.
+ *
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment index. RTDBGSEGIDX_ABS is not allowed.
+ * If RTDBGSEGIDX_RVA is used, the functions returns
+ * the same value as RTDbgModImageSize.
+ */
+RTDECL(RTUINTPTR) RTDbgModSegmentSize(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg);
+
+/**
+ * Gets the image relative address of a segment.
+ *
+ * This is a just a wrapper around RTDbgModSegmentByIndex.
+ *
+ * @returns The segment relative address.
+ * RTUINTPTR_MAX is returned if either the handle and segment index are
+ * invalid.
+ *
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment index. No special segment indexes
+ * allowed (asserted).
+ */
+RTDECL(RTUINTPTR) RTDbgModSegmentRva(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg);
+
+
+/**
+ * Adds a line number to the module.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
+ * custom symbols. This is a common place occurrence.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or
+ * short.
+ * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and
+ * it's not inside any of the segments defined by the module.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
+ * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
+ * end of the segment.
+ * @retval VERR_DBG_ADDRESS_WRAP if off+cb wraps around.
+ * @retval VERR_INVALID_PARAMETER if the symbol flags sets undefined bits.
+ *
+ * @param hDbgMod The module handle.
+ * @param pszSymbol The symbol name.
+ * @param iSeg The segment index.
+ * @param off The segment offset.
+ * @param cb The size of the symbol. Can be zero, although this
+ * may depend somewhat on the debug interpreter.
+ * @param fFlags Symbol flags. Reserved for the future, MBZ.
+ * @param piOrdinal Where to return the symbol ordinal on success. If
+ * the interpreter doesn't do ordinals, this will be set to
+ * UINT32_MAX. Optional.
+ */
+RTDECL(int) RTDbgModSymbolAdd(RTDBGMOD hDbgMod, const char *pszSymbol, RTDBGSEGIDX iSeg, RTUINTPTR off,
+ RTUINTPTR cb, uint32_t fFlags, uint32_t *piOrdinal);
+
+/**
+ * Gets the symbol count.
+ *
+ * This can be used together wtih RTDbgModSymbolByOrdinal or
+ * RTDbgModSymbolByOrdinalA to enumerate all the symbols.
+ *
+ * @returns The number of symbols in the module.
+ * UINT32_MAX is returned if the module handle is invalid or some other
+ * error occurs.
+ *
+ * @param hDbgMod The module handle.
+ */
+RTDECL(uint32_t) RTDbgModSymbolCount(RTDBGMOD hDbgMod);
+
+/**
+ * Queries symbol information by ordinal number.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_SYMBOL_NOT_FOUND if there is no symbol at the given number.
+ * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_NOT_SUPPORTED if lookup by ordinal is not supported.
+ *
+ * @param hDbgMod The module handle.
+ * @param iOrdinal The symbol ordinal number. 0-based. The highest
+ * number is RTDbgModSymbolCount() - 1.
+ * @param pSymInfo Where to store the symbol information.
+ */
+RTDECL(int) RTDbgModSymbolByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL pSymInfo);
+
+/**
+ * Queries symbol information by ordinal number.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.
+ * @retval VERR_NOT_SUPPORTED if lookup by ordinal is not supported.
+ * @retval VERR_SYMBOL_NOT_FOUND if there is no symbol at the given number.
+ * @retval VERR_NO_MEMORY if RTDbgSymbolAlloc fails.
+ *
+ * @param hDbgMod The module handle.
+ * @param iOrdinal The symbol ordinal number. 0-based. The highest
+ * number is RTDbgModSymbolCount() - 1.
+ * @param ppSymInfo Where to store the pointer to the returned
+ * symbol information. Always set. Free with
+ * RTDbgSymbolFree.
+ */
+RTDECL(int) RTDbgModSymbolByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGSYMBOL *ppSymInfo);
+
+/**
+ * Queries symbol information by address.
+ *
+ * The returned symbol is what the debug info interpreter considers the symbol
+ * most applicable to the specified address. This usually means a symbol with an
+ * address equal or lower than the requested.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
+ * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and
+ * it's not inside any of the segments defined by the module.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
+ * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
+ * end of the segment.
+ * @retval VERR_INVALID_PARAMETER if incorrect flags.
+ *
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment number.
+ * @param off The offset into the segment.
+ * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
+ * @param poffDisp Where to store the distance between the
+ * specified address and the returned symbol.
+ * Optional.
+ * @param pSymInfo Where to store the symbol information.
+ */
+RTDECL(int) RTDbgModSymbolByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
+ PRTINTPTR poffDisp, PRTDBGSYMBOL pSymInfo);
+
+/**
+ * Queries symbol information by address.
+ *
+ * The returned symbol is what the debug info interpreter considers the symbol
+ * most applicable to the specified address. This usually means a symbol with an
+ * address equal or lower than the requested.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
+ * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and
+ * it's not inside any of the segments defined by the module.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
+ * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
+ * end of the segment.
+ * @retval VERR_NO_MEMORY if RTDbgSymbolAlloc fails.
+ * @retval VERR_INVALID_PARAMETER if incorrect flags.
+ *
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment index.
+ * @param off The offset into the segment.
+ * @param fFlags Symbol search flags, see RTDBGSYMADDR_FLAGS_XXX.
+ * @param poffDisp Where to store the distance between the
+ * specified address and the returned symbol. Optional.
+ * @param ppSymInfo Where to store the pointer to the returned
+ * symbol information. Always set. Free with
+ * RTDbgSymbolFree.
+ */
+RTDECL(int) RTDbgModSymbolByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t fFlags,
+ PRTINTPTR poffDisp, PRTDBGSYMBOL *ppSymInfo);
+
+/**
+ * Queries symbol information by symbol name.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.
+ * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
+ * @retval VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or
+ * short.
+ *
+ * @param hDbgMod The module handle.
+ * @param pszSymbol The symbol name.
+ * @param pSymInfo Where to store the symbol information.
+ */
+RTDECL(int) RTDbgModSymbolByName(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL pSymInfo);
+
+/**
+ * Queries symbol information by symbol name.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_NO_SYMBOLS if there aren't any symbols.
+ * @retval VERR_SYMBOL_NOT_FOUND if no suitable symbol was found.
+ * @retval VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE if the symbol name is too long or
+ * short.
+ * @retval VERR_NO_MEMORY if RTDbgSymbolAlloc fails.
+ *
+ * @param hDbgMod The module handle.
+ * @param pszSymbol The symbol name.
+ * @param ppSymInfo Where to store the pointer to the returned
+ * symbol information. Always set. Free with
+ * RTDbgSymbolFree.
+ */
+RTDECL(int) RTDbgModSymbolByNameA(RTDBGMOD hDbgMod, const char *pszSymbol, PRTDBGSYMBOL *ppSymInfo);
+
+/**
+ * Adds a line number to the module.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the module interpret doesn't support adding
+ * custom symbols. This should be consider a normal response.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_DBG_FILE_NAME_OUT_OF_RANGE if the file name is too longer or
+ * empty.
+ * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and
+ * it's not inside any of the segments defined by the module.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
+ * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
+ * end of the segment.
+ * @retval VERR_INVALID_PARAMETER if the line number flags sets undefined bits.
+ *
+ * @param hDbgMod The module handle.
+ * @param pszFile The file name.
+ * @param uLineNo The line number.
+ * @param iSeg The segment index.
+ * @param off The segment offset.
+ * @param piOrdinal Where to return the line number ordinal on
+ * success. If the interpreter doesn't do ordinals,
+ * this will be set to UINT32_MAX. Optional.
+ */
+RTDECL(int) RTDbgModLineAdd(RTDBGMOD hDbgMod, const char *pszFile, uint32_t uLineNo,
+ RTDBGSEGIDX iSeg, RTUINTPTR off, uint32_t *piOrdinal);
+
+/**
+ * Gets the line number count.
+ *
+ * This can be used together wtih RTDbgModLineByOrdinal or RTDbgModSymbolByLineA
+ * to enumerate all the line number information.
+ *
+ * @returns The number of line numbers in the module.
+ * UINT32_MAX is returned if the module handle is invalid or some other
+ * error occurs.
+ *
+ * @param hDbgMod The module handle.
+ */
+RTDECL(uint32_t) RTDbgModLineCount(RTDBGMOD hDbgMod);
+
+/**
+ * Queries line number information by ordinal number.
+ *
+ * This can be used to enumerate the line numbers for the module. Use
+ * RTDbgModLineCount() to figure the end of the ordinals.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
+ * @retval VERR_DBG_LINE_NOT_FOUND if there is no line number with that
+ * ordinal.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+
+ * @param hDbgMod The module handle.
+ * @param iOrdinal The line number ordinal number.
+ * @param pLineInfo Where to store the information about the line
+ * number.
+ */
+RTDECL(int) RTDbgModLineByOrdinal(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE pLineInfo);
+
+/**
+ * Queries line number information by ordinal number.
+ *
+ * This can be used to enumerate the line numbers for the module. Use
+ * RTDbgModLineCount() to figure the end of the ordinals.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
+ * @retval VERR_DBG_LINE_NOT_FOUND if there is no line number with that
+ * ordinal.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_NO_MEMORY if RTDbgLineAlloc fails.
+ *
+ * @param hDbgMod The module handle.
+ * @param iOrdinal The line number ordinal number.
+ * @param ppLineInfo Where to store the pointer to the returned line
+ * number information. Always set. Free with
+ * RTDbgLineFree.
+ */
+RTDECL(int) RTDbgModLineByOrdinalA(RTDBGMOD hDbgMod, uint32_t iOrdinal, PRTDBGLINE *ppLineInfo);
+
+/**
+ * Queries line number information by address.
+ *
+ * The returned line number is what the debug info interpreter considers the
+ * one most applicable to the specified address. This usually means a line
+ * number with an address equal or lower than the requested.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
+ * @retval VERR_DBG_LINE_NOT_FOUND if no suitable line number was found.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and
+ * it's not inside any of the segments defined by the module.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
+ * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
+ * end of the segment.
+ *
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment number.
+ * @param off The offset into the segment.
+ * @param poffDisp Where to store the distance between the
+ * specified address and the returned symbol.
+ * Optional.
+ * @param pLineInfo Where to store the line number information.
+ */
+RTDECL(int) RTDbgModLineByAddr(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE pLineInfo);
+
+/**
+ * Queries line number information by address.
+ *
+ * The returned line number is what the debug info interpreter considers the
+ * one most applicable to the specified address. This usually means a line
+ * number with an address equal or lower than the requested.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_DBG_NO_LINE_NUMBERS if there aren't any line numbers.
+ * @retval VERR_DBG_LINE_NOT_FOUND if no suitable line number was found.
+ * @retval VERR_INVALID_HANDLE if hDbgMod is invalid.
+ * @retval VERR_DBG_INVALID_RVA if an image relative address is specified and
+ * it's not inside any of the segments defined by the module.
+ * @retval VERR_DBG_INVALID_SEGMENT_INDEX if the segment index isn't valid.
+ * @retval VERR_DBG_INVALID_SEGMENT_OFFSET if the segment offset is beyond the
+ * end of the segment.
+ * @retval VERR_NO_MEMORY if RTDbgLineAlloc fails.
+ *
+ * @param hDbgMod The module handle.
+ * @param iSeg The segment number.
+ * @param off The offset into the segment.
+ * @param poffDisp Where to store the distance between the
+ * specified address and the returned symbol.
+ * Optional.
+ * @param ppLineInfo Where to store the pointer to the returned line
+ * number information. Always set. Free with
+ * RTDbgLineFree.
+ */
+RTDECL(int) RTDbgModLineByAddrA(RTDBGMOD hDbgMod, RTDBGSEGIDX iSeg, RTUINTPTR off, PRTINTPTR poffDisp, PRTDBGLINE *ppLineInfo);
+/** @} */
+
+# endif /* IN_RING3 */
+
+
+/** @name Kernel Debug Info API
+ *
+ * This is a specialized API for obtaining symbols and structure information
+ * about the running kernel. It is relatively OS specific. Its purpose and
+ * operation is doesn't map all that well onto RTDbgMod, so a few dedicated
+ * functions was created for it.
+ *
+ * @{ */
+
+/** Handle to the kernel debug info. */
+typedef struct RTDBGKRNLINFOINT *RTDBGKRNLINFO;
+/** Pointer to a kernel debug info handle. */
+typedef RTDBGKRNLINFO *PRTDBGKRNLINFO;
+/** Nil kernel debug info handle. */
+#define NIL_RTDBGKRNLINFO ((RTDBGKRNLINFO)0)
+
+/**
+ * Opens the kernel debug info.
+ *
+ * @returns IPRT status code. Can fail for any number of reasons.
+ *
+ * @param phKrnlInfo Where to return the kernel debug info handle on
+ * success.
+ * @param fFlags Flags reserved for future use. Must be zero.
+ */
+RTR0DECL(int) RTR0DbgKrnlInfoOpen(PRTDBGKRNLINFO phKrnlInfo, uint32_t fFlags);
+
+/**
+ * Retains a reference to the kernel debug info handle.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hKrnlInfo The kernel info handle.
+ */
+RTR0DECL(uint32_t) RTR0DbgKrnlInfoRetain(RTDBGKRNLINFO hKrnlInfo);
+
+
+/**
+ * Releases a reference to the kernel debug info handle, destroying it when the
+ * counter reaches zero.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hKrnlInfo The kernel info handle. NIL_RTDBGKRNLINFO is
+ * quietly ignored.
+ */
+RTR0DECL(uint32_t) RTR0DbgKrnlInfoRelease(RTDBGKRNLINFO hKrnlInfo);
+
+/**
+ * Queries the offset (in bytes) of a member of a kernel structure.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and offset at @a poffMember.
+ * @retval VERR_NOT_FOUND if the structure or the member was not found.
+ * @retval VERR_INVALID_HANDLE if hKrnlInfo is bad.
+ * @retval VERR_INVALID_POINTER if any of the pointers are bad.
+ *
+ * @param hKrnlInfo The kernel info handle.
+ * @param pszStructure The structure name.
+ * @param pszMember The member name.
+ * @param poffMember Where to return the offset.
+ */
+RTR0DECL(int) RTR0DbgKrnlInfoQueryMember(RTDBGKRNLINFO hKrnlInfo, const char *pszStructure,
+ const char *pszMember, size_t *poffMember);
+
+
+/**
+ * Queries the value (usually the address) of a kernel symbol.
+ *
+ * This may go looking for the symbol in other modules, in which case it will
+ * always check the kernel symbol table first.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and value at @a ppvSymbol.
+ * @retval VERR_SYMBOL_NOT_FOUND
+ * @retval VERR_INVALID_HANDLE if hKrnlInfo is bad.
+ * @retval VERR_INVALID_POINTER if any of the pointers are bad.
+ *
+ * @param hKrnlInfo The kernel info handle.
+ * @param pszModule Reserved for future extensions. Pass NULL.
+ * @param pszSymbol The C name of the symbol.
+ * @param ppvSymbol Where to return the symbol value, passing NULL is
+ * OK. This may be modified even on failure, in
+ * particular, it will be set to NULL when
+ * VERR_SYMBOL_NOT_FOUND is returned.
+ *
+ * @sa RTLdrGetSymbol.
+ */
+RTR0DECL(int) RTR0DbgKrnlInfoQuerySymbol(RTDBGKRNLINFO hKrnlInfo, const char *pszModule,
+ const char *pszSymbol, void **ppvSymbol);
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/dir.h b/include/iprt/dir.h
new file mode 100644
index 00000000..38d99aa3
--- /dev/null
+++ b/include/iprt/dir.h
@@ -0,0 +1,473 @@
+/** @file
+ * IPRT - Directory Manipulation.
+ */
+
+/*
+ * 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 ___iprt_dir_h
+#define ___iprt_dir_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/fs.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_dir RTDir - Directory Manipulation
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Check for the existence of a directory.
+ *
+ * All symbolic links will be attemped resolved. If that is undesirable, please
+ * use RTPathQueryInfo instead.
+ *
+ * @returns true if exist and is a directory.
+ * @returns false if not exists or isn't a directory.
+ * @param pszPath Path to the directory.
+ */
+RTDECL(bool) RTDirExists(const char *pszPath);
+
+/** @name RTDirCreate flags.
+ * @{ */
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTDIRCREATE_FLAGS_NO_SYMLINKS RT_BIT(0)
+/** @} */
+
+/**
+ * Creates a directory.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the directory to create.
+ * @param fMode The mode of the new directory.
+ * @param fCreate Create flags, RTDIRCREATE_FLAGS_*.
+ */
+RTDECL(int) RTDirCreate(const char *pszPath, RTFMODE fMode, uint32_t fCreate);
+
+/**
+ * Creates a directory including all parent directories in the path
+ * if they don't exist.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the directory to create.
+ * @param fMode The mode of the new directories.
+ */
+RTDECL(int) RTDirCreateFullPath(const char *pszPath, RTFMODE fMode);
+
+/**
+ * Creates a new directory with a unique name using the given template.
+ *
+ * One or more trailing X'es in the template will be replaced by random alpha
+ * numeric characters until a RTDirCreate succeeds or we run out of patience.
+ * For instance:
+ * "/tmp/myprog-XXXXXX"
+ *
+ * As an alternative to trailing X'es, it
+ * is possible to put 3 or more X'es somewhere inside the directory name. In
+ * the following string only the last bunch of X'es will be modified:
+ * "/tmp/myprog-XXX-XXX.tmp"
+ *
+ * @returns iprt status code.
+ * @param pszTemplate The directory name template on input. The actual
+ * directory name on success. Empty string on failure.
+ * @param fMode The mode to create the directory with. Use 0700
+ * unless you have reason not to.
+ */
+RTDECL(int) RTDirCreateTemp(char *pszTemplate, RTFMODE fMode);
+
+/**
+ * Secure version of @a RTDirCreateTemp with a fixed mode of 0700.
+ *
+ * This function behaves in the same way as @a RTDirCreateTemp with two
+ * additional points. Firstly the mode is fixed to 0700. Secondly it will
+ * fail if it is not possible to perform the operation securely. Possible
+ * reasons include that the directory could be removed by another unprivileged
+ * user before it is used (e.g. if is created in a non-sticky /tmp directory)
+ * or that the path contains symbolic links which another unprivileged user
+ * could manipulate; however the exact criteria will be specified on a
+ * platform-by-platform basis as platform support is added.
+ * @see RTPathIsSecure for the current list of criteria.
+ * @returns iprt status code.
+ * @returns VERR_NOT_SUPPORTED if the interface can not be supported on the
+ * current platform at this time.
+ * @returns VERR_INSECURE if the directory could not be created securely.
+ * @param pszTemplate The directory name template on input. The
+ * actual directory name on success. Empty string
+ * on failure.
+ */
+RTDECL(int) RTDirCreateTempSecure(char *pszTemplate);
+
+/**
+ * Creates a new directory with a unique name by appending a number.
+ *
+ * First it is tried to create the directory without any numbers appended.
+ * When this fails a number string is appended (starting with 1) separated by
+ * the optional separator. The numbers are zero padded.
+ *
+ * On success @a pszPath contains the path created.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the directory to create.
+ * @param cbSize The size of pszPath. Needs enough space for holding the
+ * digits and the optional separator.
+ * @param fMode The mode of the new directory.
+ * @param cchDigits How many digits should the number maximal have.
+ * @param chSep The separator used between the path and the number. Can
+ * be zero. (optional)
+ */
+RTDECL(int) RTDirCreateUniqueNumbered(char *pszPath, size_t cbSize, RTFMODE fMode, signed int cchDigits, char chSep);
+
+/**
+ * Removes a directory if empty.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the directory to remove.
+ */
+RTDECL(int) RTDirRemove(const char *pszPath);
+
+/**
+ * Removes a directory tree recursively.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the directory to remove recursively.
+ * @param fFlags Flags, see RTDIRRMREC_F_XXX.
+ *
+ * @remarks This will not work on a root directory.
+ */
+RTDECL(int) RTDirRemoveRecursive(const char *pszPath, uint32_t fFlags);
+
+/** @name RTDirRemoveRecursive flags.
+ * @{ */
+/** Delete the content of the directory and the directory itself. */
+#define RTDIRRMREC_F_CONTENT_AND_DIR UINT32_C(0)
+/** Only delete the content of the directory, omit the directory it self. */
+#define RTDIRRMREC_F_CONTENT_ONLY RT_BIT_32(0)
+/** Mask of valid flags. */
+#define RTDIRRMREC_F_VALID_MASK UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Flushes the specified directory.
+ *
+ * This API is not implemented on all systems. On some systems it may be
+ * unnecessary if you've already flushed the file. If you really care for your
+ * data and is entering dangerous territories, it doesn't hurt calling it after
+ * flushing and closing the file.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_IMPLEMENTED must be expected.
+ * @retval VERR_NOT_SUPPORTED must be expected.
+ * @param pszPath Path to the directory.
+ */
+RTDECL(int) RTDirFlush(const char *pszPath);
+
+/**
+ * Flushes the parent directory of the specified file.
+ *
+ * This is just a wrapper around RTDirFlush.
+ *
+ * @returns IPRT status code, see RTDirFlush for details.
+ * @param pszChild Path to the file which parent should be flushed.
+ */
+RTDECL(int) RTDirFlushParent(const char *pszChild);
+
+
+/** Pointer to an open directory (sort of handle). */
+typedef struct RTDIR *PRTDIR;
+
+
+/**
+ * Filter option for RTDirOpenFiltered().
+ */
+typedef enum RTDIRFILTER
+{
+ /** The usual invalid 0 entry. */
+ RTDIRFILTER_INVALID = 0,
+ /** No filter should be applied (and none was specified). */
+ RTDIRFILTER_NONE,
+ /** The Windows NT filter.
+ * The following wildcard chars: *, ?, <, > and "
+ * The matching is done on the uppercased strings. */
+ RTDIRFILTER_WINNT,
+ /** The UNIX filter.
+ * The following wildcard chars: *, ?, [..]
+ * The matching is done on exact case. */
+ RTDIRFILTER_UNIX,
+ /** The UNIX filter, uppercased matching.
+ * Same as RTDIRFILTER_UNIX except that the strings are uppercased before comparing. */
+ RTDIRFILTER_UNIX_UPCASED,
+
+ /** The usual full 32-bit value. */
+ RTDIRFILTER_32BIT_HACK = 0x7fffffff
+} RTDIRFILTER;
+
+
+/**
+ * Directory entry type.
+ *
+ * This is the RTFS_TYPE_MASK stuff shifted down 12 bits and
+ * identical to the BSD/LINUX ABI.
+ */
+typedef enum RTDIRENTRYTYPE
+{
+ /** Unknown type (DT_UNKNOWN). */
+ RTDIRENTRYTYPE_UNKNOWN = 0,
+ /** Named pipe (fifo) (DT_FIFO). */
+ RTDIRENTRYTYPE_FIFO = 001,
+ /** Character device (DT_CHR). */
+ RTDIRENTRYTYPE_DEV_CHAR = 002,
+ /** Directory (DT_DIR). */
+ RTDIRENTRYTYPE_DIRECTORY = 004,
+ /** Block device (DT_BLK). */
+ RTDIRENTRYTYPE_DEV_BLOCK = 006,
+ /** Regular file (DT_REG). */
+ RTDIRENTRYTYPE_FILE = 010,
+ /** Symbolic link (DT_LNK). */
+ RTDIRENTRYTYPE_SYMLINK = 012,
+ /** Socket (DT_SOCK). */
+ RTDIRENTRYTYPE_SOCKET = 014,
+ /** Whiteout (DT_WHT). */
+ RTDIRENTRYTYPE_WHITEOUT = 016
+} RTDIRENTRYTYPE;
+
+
+/**
+ * Directory entry.
+ *
+ * This is inspired by the POSIX interfaces.
+ */
+#pragma pack(1)
+typedef struct RTDIRENTRY
+{
+ /** The unique identifier (within the file system) of this file system object (d_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;
+ /** The entry type. (d_type)
+ * RTDIRENTRYTYPE_UNKNOWN is a common return value here since not all file
+ * systems (or Unixes) stores the type of a directory entry and instead
+ * expects the user to use stat() to get it. So, when you see this you
+ * should use RTPathQueryInfo to get the type, or if if you're lazy, use
+ * RTDirReadEx. */
+ RTDIRENTRYTYPE enmType;
+ /** The length of the filename, excluding the terminating nul character. */
+ uint16_t cbName;
+ /** The filename. (no path)
+ * Using the pcbDirEntry parameter of RTDirRead makes this field variable in size. */
+ char szName[260];
+} RTDIRENTRY;
+#pragma pack()
+/** Pointer to a directory entry. */
+typedef RTDIRENTRY *PRTDIRENTRY;
+
+
+/**
+ * Directory entry with extended information.
+ *
+ * This is inspired by the PC interfaces.
+ */
+#pragma pack(1)
+typedef struct RTDIRENTRYEX
+{
+ /** Full information about the object. */
+ RTFSOBJINFO Info;
+ /** The length of the short field (number of RTUTF16 entries (not chars)).
+ * It is 16-bit for reasons of alignment. */
+ uint16_t cwcShortName;
+ /** The short name for 8.3 compatibility.
+ * Empty string if not available.
+ * Since the length is a bit tricky for a UTF-8 encoded name, and since this
+ * is practically speaking only a windows thing, it is encoded as UCS-2. */
+ RTUTF16 wszShortName[14];
+ /** The length of the filename. */
+ uint16_t cbName;
+ /** The filename. (no path)
+ * Using the pcbDirEntry parameter of RTDirReadEx makes this field variable in size. */
+ char szName[260];
+} RTDIRENTRYEX;
+#pragma pack()
+/** Pointer to a directory entry. */
+typedef RTDIRENTRYEX *PRTDIRENTRYEX;
+
+
+/**
+ * Opens a directory.
+ *
+ * @returns iprt status code.
+ * @param ppDir Where to store the open directory pointer.
+ * @param pszPath Path to the directory to open.
+ */
+RTDECL(int) RTDirOpen(PRTDIR *ppDir, const char *pszPath);
+
+/** @name RTDirOpenFiltered flags.
+ * @{ */
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTDIROPEN_FLAGS_NO_SYMLINKS RT_BIT(0)
+/** @} */
+
+/**
+ * Opens a directory filtering the entries using dos style wildcards.
+ *
+ * @returns iprt status code.
+ * @param ppDir Where to store the open directory pointer.
+ * @param pszPath Path to the directory to search, this must include wildcards.
+ * @param enmFilter The kind of filter to apply. Setting this to RTDIRFILTER_NONE makes
+ * this function behave like RTDirOpen.
+ * @param fOpen Open flags, RTDIROPENFILTERED_FLAGS_*.
+ */
+RTDECL(int) RTDirOpenFiltered(PRTDIR *ppDir, const char *pszPath, RTDIRFILTER enmFilter, uint32_t fOpen);
+
+/**
+ * Closes a directory.
+ *
+ * @returns iprt status code.
+ * @param pDir Pointer to open directory returned by RTDirOpen() or RTDirOpenFiltered().
+ */
+RTDECL(int) RTDirClose(PRTDIR pDir);
+
+/**
+ * Reads the next entry in the directory.
+ *
+ * @returns VINF_SUCCESS and data in pDirEntry on success.
+ * @returns VERR_NO_MORE_FILES when the end of the directory has been reached.
+ * @returns VERR_BUFFER_OVERFLOW if the buffer is too small to contain the filename. If
+ * pcbDirEntry is specified it will be updated with the required buffer size.
+ * @returns suitable iprt status code on other errors.
+ *
+ * @param pDir Pointer to the open directory.
+ * @param pDirEntry Where to store the information about the next
+ * directory entry on success.
+ * @param pcbDirEntry Optional parameter used for variable buffer size.
+ *
+ * On input the variable pointed to contains the size of the pDirEntry
+ * structure. This must be at least OFFSET(RTDIRENTRY, szName[2]) bytes.
+ *
+ * On successful output the field is updated to
+ * OFFSET(RTDIRENTRY, szName[pDirEntry->cbName + 1]).
+ *
+ * When the data doesn't fit in the buffer and VERR_BUFFER_OVERFLOW is
+ * returned, this field contains the required buffer size.
+ *
+ * The value is unchanged in all other cases.
+ */
+RTDECL(int) RTDirRead(PRTDIR pDir, PRTDIRENTRY pDirEntry, size_t *pcbDirEntry);
+
+/**
+ * Reads the next entry in the directory returning extended information.
+ *
+ * @returns VINF_SUCCESS and data in pDirEntry on success.
+ * @returns VERR_NO_MORE_FILES when the end of the directory has been reached.
+ * @returns VERR_BUFFER_OVERFLOW if the buffer is too small to contain the filename. If
+ * pcbDirEntry is specified it will be updated with the required buffer size.
+ * @returns suitable iprt status code on other errors.
+ *
+ * @param pDir Pointer to the open directory.
+ * @param pDirEntry Where to store the information about the next
+ * directory entry on success.
+ * @param pcbDirEntry Optional parameter used for variable buffer size.
+ *
+ * On input the variable pointed to contains the size of the pDirEntry
+ * structure. This must be at least OFFSET(RTDIRENTRYEX, szName[2]) bytes.
+ *
+ * On successful output the field is updated to
+ * OFFSET(RTDIRENTRYEX, szName[pDirEntry->cbName + 1]).
+ *
+ * When the data doesn't fit in the buffer and VERR_BUFFER_OVERFLOW is
+ * returned, this field contains the required buffer size.
+ *
+ * The value is unchanged in all other cases.
+ * @param enmAdditionalAttribs
+ * Which set of additional attributes to request.
+ * Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
+ * @param fFlags RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ */
+RTDECL(int) RTDirReadEx(PRTDIR pDir, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags);
+
+
+/**
+ * Renames a file.
+ *
+ * Identical to RTPathRename except that it will ensure that the source is a directory.
+ *
+ * @returns IPRT status code.
+ * @returns VERR_ALREADY_EXISTS if the destination file exists.
+ *
+ * @param pszSrc The path to the source file.
+ * @param pszDst The path to the destination file.
+ * This file will be created.
+ * @param fRename See RTPathRename.
+ */
+RTDECL(int) RTDirRename(const char *pszSrc, const char *pszDst, unsigned fRename);
+
+
+/**
+ * Query information about an open directory.
+ *
+ * @returns iprt status code.
+ *
+ * @param pDir Pointer to the open directory.
+ * @param pObjInfo Object information structure to be filled on successful return.
+ * @param enmAdditionalAttribs Which set of additional attributes to request.
+ * Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
+ */
+RTR3DECL(int) RTDirQueryInfo(PRTDIR pDir, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs);
+
+
+/**
+ * Changes one or more of the timestamps associated of file system object.
+ *
+ * @returns iprt status code.
+ * @returns VERR_NOT_SUPPORTED is returned if the operation isn't supported by the OS.
+ *
+ * @param pDir Pointer to the open directory.
+ * @param pAccessTime Pointer to the new access time. NULL if not to be changed.
+ * @param pModificationTime Pointer to the new modifcation time. NULL if not to be changed.
+ * @param pChangeTime Pointer to the new change time. NULL if not to be changed.
+ * @param pBirthTime Pointer to the new time of birth. NULL if not to be changed.
+ *
+ * @remark The file system might not implement all these time attributes,
+ * the API will ignore the ones which aren't supported.
+ *
+ * @remark The file system might not implement the time resolution
+ * employed by this interface, the time will be chopped to fit.
+ *
+ * @remark The file system may update the change time even if it's
+ * not specified.
+ *
+ * @remark POSIX can only set Access & Modification and will always set both.
+ */
+RTR3DECL(int) RTDirSetTimes(PRTDIR pDir, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+ PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/dvm.h b/include/iprt/dvm.h
new file mode 100644
index 00000000..f36a5f10
--- /dev/null
+++ b/include/iprt/dvm.h
@@ -0,0 +1,379 @@
+/** @file
+ * IPRT Disk Volume Management API (DVM).
+ */
+
+/*
+ * 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 ___iprt_dvm_h
+#define ___iprt_dvm_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_dvm IPRT Disk Volume Management
+ * @{
+ */
+
+/**
+ * Volume type.
+ * Comparable to the FS type in MBR partition maps
+ * or the partition type GUIDs in GPT tables.
+ */
+typedef enum RTDVMVOLTYPE
+{
+ /** Invalid. */
+ RTDVMVOLTYPE_INVALID = 0,
+ /** Unknown. */
+ RTDVMVOLTYPE_UNKNOWN,
+ /** Volume hosts a NTFS filesystem. */
+ RTDVMVOLTYPE_NTFS,
+ /** Volume hosts a FAT16 filesystem. */
+ RTDVMVOLTYPE_FAT16,
+ /** Volume hosts a FAT32 filesystem. */
+ RTDVMVOLTYPE_FAT32,
+ /** Volume hosts a Linux swap. */
+ RTDVMVOLTYPE_LINUX_SWAP,
+ /** Volume hosts a Linux filesystem. */
+ RTDVMVOLTYPE_LINUX_NATIVE,
+ /** Volume hosts a Linux LVM. */
+ RTDVMVOLTYPE_LINUX_LVM,
+ /** Volume hosts a Linux SoftRaid. */
+ RTDVMVOLTYPE_LINUX_SOFTRAID,
+ /** Volume hosts a FreeBSD disklabel. */
+ RTDVMVOLTYPE_FREEBSD,
+ /** Volume hosts a NetBSD disklabel. */
+ RTDVMVOLTYPE_NETBSD,
+ /** Volume hosts a OpenBSD disklabel. */
+ RTDVMVOLTYPE_OPENBSD,
+ /** Volume hosts a Mac OS X HFS or HFS+ filesystem. */
+ RTDVMVOLTYPE_MAC_OSX_HFS,
+ /** Volume hosts a Solaris volume. */
+ RTDVMVOLTYPE_SOLARIS,
+ /** End of the valid values. */
+ RTDVMVOLTYPE_END,
+ /** Usual 32bit hack. */
+ RTDVMVOLTYPE_32BIT_HACK = 0x7fffffff
+} RTDVMVOLTYPE;
+
+/** @defgroup grp_dvm_flags Flags used by RTDvmCreate.
+ * @{ */
+/** DVM flags - Blocks are always marked as unused if the volume has
+ * no block status callback set.
+ * The default is to mark them as used. */
+#define DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED RT_BIT_32(0)
+/** DVM flags - Space which is unused in the map will be marked as used
+ * when calling RTDvmMapQueryBlockStatus(). */
+#define DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED RT_BIT_32(1)
+/** Mask of all valid flags. */
+#define DVM_FLAGS_MASK (DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED | DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
+/** @} */
+
+
+/** @defgroup grp_dvm_vol_flags Volume flags used by DVMVolumeGetFlags.
+ * @{ */
+/** Volume flags - Volume is bootable. */
+#define DVMVOLUME_FLAGS_BOOTABLE RT_BIT_64(0)
+/** Volume flags - Volume is active. */
+#define DVMVOLUME_FLAGS_ACTIVE RT_BIT_64(1)
+/** @} */
+
+/** A handle to a volume manager. */
+typedef struct RTDVMINTERNAL *RTDVM;
+/** A pointer to a volume manager handle. */
+typedef RTDVM *PRTDVM;
+/** NIL volume manager handle. */
+#define NIL_RTDVM ((RTDVM)~0)
+
+/** A handle to a volume in a volume map. */
+typedef struct RTDVMVOLUMEINTERNAL *RTDVMVOLUME;
+/** A pointer to a volume handle. */
+typedef RTDVMVOLUME *PRTDVMVOLUME;
+/** NIL volume handle. */
+#define NIL_RTDVMVOLUME ((RTDVMVOLUME)~0)
+
+/**
+ * Callback to read data from the underlying medium.
+ *
+ * @returns IPRT status code.
+ * @param pvUser Opaque user data passed on creation.
+ * @param off Offset to start reading from.
+ * @param pvBuf Where to store the read data.
+ * @param cbRead How many bytes to read.
+ */
+typedef DECLCALLBACK(int) FNDVMREAD(void *pvUser, uint64_t off, void *pvBuf, size_t cbRead);
+/** Pointer to a read callback. */
+typedef FNDVMREAD *PFNDVMREAD;
+
+/**
+ * Callback to write data to the underlying medium.
+ *
+ * @returns IPRT status code.
+ * @param pvUser Opaque user data passed on creation.
+ * @param off Offset to start writing to.
+ * @param pvBuf The data to write.
+ * @param cbRead How many bytes to write.
+ */
+typedef DECLCALLBACK(int) FNDVMWRITE(void *pvUser, uint64_t off, const void *pvBuf, size_t cbWrite);
+/** Pointer to a read callback. */
+typedef FNDVMWRITE *PFNDVMWRITE;
+
+/**
+ * Callback for querying the block allocation status of a volume.
+ *
+ * @returns IPRT status code.
+ * @param pvUser Opaque user data passed when setting the callback.
+ * @param off Offset relative to the start of the volume.
+ * @param cb Range to check in bytes.
+ * @param pfAllocated Where to store the allocation status on success.
+ */
+typedef DECLCALLBACK(int) FNDVMVOLUMEQUERYBLOCKSTATUS(void *pvUser, uint64_t off,
+ uint64_t cb, bool *pfAllocated);
+/** Pointer to a query block allocation status callback. */
+typedef FNDVMVOLUMEQUERYBLOCKSTATUS *PFNDVMVOLUMEQUERYBLOCKSTATUS;
+
+/**
+ * Create a new volume manager.
+ *
+ * @returns IPRT status.
+ * @param phVolMgr Where to store the handle to the volume manager on
+ * success.
+ * @param pfnRead Read callback for the underlying
+ * disk/container/whatever.
+ * @param pfnWrite Write callback for the underlying
+ * disk/container/whatever.
+ * @param cbDisk Size of the underlying disk in bytes.
+ * @param cbSector Size of one sector in bytes.
+ * @param fFlags Combination of RTDVM_FLAGS_*
+ * @param pvUser Opaque user data passed to the callbacks.
+ */
+RTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
+ PFNDVMWRITE pfnWrite, uint64_t cbDisk,
+ uint64_t cbSector, uint32_t fFlags,
+ void *pvUser);
+
+/**
+ * Retain a given volume manager.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hVolMgr The volume manager to retain.
+ */
+RTDECL(uint32_t) RTDvmRetain(RTDVM hVolMgr);
+
+/**
+ * Releases a given volume manager.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hVolMgr The volume manager to release.
+ */
+RTDECL(uint32_t) RTDvmRelease(RTDVM hVolMgr);
+
+/**
+ * Probes the underyling disk for the best volume manager format handler
+ * and opens it.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_FOUND if no backend can handle the volume map on the disk.
+ * @param hVolMgr The volume manager handle.
+ */
+RTDECL(int) RTDvmMapOpen(RTDVM hVolMgr);
+
+/**
+ * Initializes a new volume map using the given format handler.
+ *
+ * @returns IPRT status code.
+ * @param hVolMgr The volume manager handle.
+ * @param pszFmt The format to use for the new map.
+ */
+RTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt);
+
+/**
+ * Gets the currently used format of the disk map.
+ *
+ * @returns Name of the format.
+ * @param hVolMgr The volume manager handle.
+ */
+RTDECL(const char *) RTDvmMapGetFormat(RTDVM hVolMgr);
+
+/**
+ * Gets the number of valid partitions in the map.
+ *
+ * @returns The number of valid volumes in the map or UINT32_MAX on failure.
+ * @param hVolMgr The volume manager handle.
+ */
+RTDECL(uint32_t) RTDvmMapGetValidVolumes(RTDVM hVolMgr);
+
+/**
+ * Gets the maximum number of partitions the map can hold.
+ *
+ * @returns The maximum number of volumes in the map or UINT32_MAX on failure.
+ * @param hVolMgr The volume manager handle.
+ */
+RTDECL(uint32_t) RTDvmMapGetMaxVolumes(RTDVM hVolMgr);
+
+/**
+ * Get the first valid volume from a map.
+ *
+ * @returns IPRT status code.
+ * @param hVolMgr The volume manager handle.
+ * @param phVol Where to store the handle to the first volume on
+ * success. Release with RTDvmVolumeRelease().
+ */
+RTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol);
+
+/**
+ * Get the first valid volume from a map.
+ *
+ * @returns IPRT status code.
+ * @param hVolMgr The volume manager handle.
+ * @param hVol Handle of the current volume.
+ * @param phVolNext Where to store the handle to the next volume on
+ * success. Release with RTDvmVolumeRelease().
+ */
+RTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext);
+
+/**
+ * Returns whether the given block on the disk is in use.
+ *
+ * @returns IPRT status code.
+ * @param hVolMgr The volume manager handler.
+ * @param off The start offset to check for.
+ * @param cb The range in bytes to check.
+ * @param pfAllocated Where to store the status on success.
+ *
+ * @remark This method will return true even if a part of the range is not in use.
+ */
+RTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
+ bool *pfAllocated);
+
+/**
+ * Retains a valid volume handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hVol The volume to retain.
+ */
+RTDECL(uint32_t) RTDvmVolumeRetain(RTDVMVOLUME hVol);
+
+/**
+ * Releases a valid volume handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hVol The volume to release.
+ */
+RTDECL(uint32_t) RTDvmVolumeRelease(RTDVMVOLUME hVol);
+
+/**
+ * Sets the callback to query the block allocation status for a volume.
+ * This overwrites any other callback set previously.
+ *
+ * @returns nothing.
+ * @param hVol The volume handle.
+ * @param pfnQueryBlockStatus The callback to set. Can be NULL to disable
+ * a previous callback.
+ * @param pvUser Opaque user data passed in the callback.
+ */
+RTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol,
+ PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus,
+ void *pvUser);
+
+/**
+ * Get the size of a volume in bytes.
+ *
+ * @returns Size of the volume in bytes or 0 on failure.
+ * @param hVol The volume handle.
+ */
+RTDECL(uint64_t) RTDvmVolumeGetSize(RTDVMVOLUME hVol);
+
+/**
+ * Gets the name of the volume if supported.
+ *
+ * @returns IPRT status code.
+ * @param hVol The volume handle.
+ * @param ppszVolName Where to store the name of the volume on success.
+ * The string must be freed with RTStrFree().
+ */
+RTDECL(int) RTDvmVolumeQueryName(RTDVMVOLUME hVol, char **ppszVolName);
+
+/**
+ * Get the volume type of the volume if supported.
+ *
+ * @returns The volume type on success, DVMVOLTYPE_INVALID if hVol is invalid.
+ * @param hVol The volume handle.
+ */
+RTDECL(RTDVMVOLTYPE) RTDvmVolumeGetType(RTDVMVOLUME hVol);
+
+/**
+ * Get the volume flags of the volume if supported.
+ *
+ * @returns The volume flags or UINT64_MAX on failure.
+ * @param hVol The volume handle.
+ */
+RTDECL(uint64_t) RTDvmVolumeGetFlags(RTDVMVOLUME hVol);
+
+/**
+ * Reads data from the given volume.
+ *
+ * @returns IPRT status code.
+ * @param hVol The volume handle.
+ * @param off Where to start reading from - 0 is the beginning of
+ * the volume.
+ * @param pvBuf Where to store the read data.
+ * @param cbRead How many bytes to read.
+ */
+RTDECL(int) RTDvmVolumeRead(RTDVMVOLUME hVol, uint64_t off, void *pvBuf, size_t cbRead);
+
+/**
+ * Writes data to the given volume.
+ *
+ * @returns IPRT status code.
+ * @param hVol The volume handle.
+ * @param off Where to start writing to - 0 is the beginning of
+ * the volume.
+ * @param pvBuf The data to write.
+ * @param cbWrite How many bytes to write.
+ */
+RTDECL(int) RTDvmVolumeWrite(RTDVMVOLUME hVol, uint64_t off, const void *pvBuf, size_t cbWrite);
+
+/**
+ * Returns the description of a given volume type.
+ *
+ * @returns The description of the type.
+ * @param enmVolType The volume type.
+ */
+RTDECL(const char *) RTDvmVolumeTypeGetDescr(RTDVMVOLTYPE enmVolType);
+
+/**
+ * Creates an VFS file from a volume handle.
+ *
+ * @returns IPRT status code.
+ * @param hVol The volume handle.
+ * @param phVfsFileOut Where to store the VFS file handle on success.
+ */
+RTDECL(int) RTDvmVolumeCreateVfsFile(RTDVMVOLUME hVol, PRTVFSFILE phVfsFileOut);
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/env.h b/include/iprt/env.h
new file mode 100644
index 00000000..64277d12
--- /dev/null
+++ b/include/iprt/env.h
@@ -0,0 +1,254 @@
+/** @file
+ * IPRT - Process Environment Strings.
+ */
+
+/*
+ * 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 ___iprt_env_h
+#define ___iprt_env_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_env RTEnv - Process Environment Strings
+ * @ingroup grp_rt
+ * @{
+ */
+
+#ifdef IN_RING3
+
+/** Special handle that indicates the default process environment. */
+#define RTENV_DEFAULT ((RTENV)~(uintptr_t)0)
+
+/**
+ * Creates an empty environment block.
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param pEnv Where to store the handle of the new environment block.
+ */
+RTDECL(int) RTEnvCreate(PRTENV pEnv);
+
+/**
+ * Creates an environment block and fill it with variables from the given
+ * environment array.
+ *
+ * @returns IPRT status code.
+ * @retval VWRN_ENV_NOT_FULLY_TRANSLATED may be returned when passing
+ * RTENV_DEFAULT and one or more of the environment variables have
+ * codeset incompatibilities. The problematic variables will be
+ * ignored and not included in the clone, thus the clone will have
+ * fewer variables.
+ * @retval VERR_NO_MEMORY
+ * @retval VERR_NO_STR_MEMORY
+ * @retval VERR_INVALID_HANDLE
+ *
+ * @param pEnv Where to store the handle of the new environment block.
+ * @param EnvToClone The environment to clone.
+ */
+RTDECL(int) RTEnvClone(PRTENV pEnv, RTENV EnvToClone);
+
+/**
+ * Destroys an environment block.
+ *
+ * @returns IPRT status code.
+ *
+ * @param Env Environment block handle.
+ * Both RTENV_DEFAULT and NIL_RTENV are silently ignored.
+ */
+RTDECL(int) RTEnvDestroy(RTENV Env);
+
+/**
+ * Get the execve/spawnve/main envp.
+ *
+ * All returned strings are in the current process' codepage.
+ * This array is only valid until the next RTEnv call.
+ *
+ * @returns Pointer to the raw array of environment variables.
+ * @returns NULL if Env is NULL or invalid.
+ *
+ * @param Env Environment block handle.
+ */
+RTDECL(char const * const *) RTEnvGetExecEnvP(RTENV Env);
+
+/**
+ * Get a sorted, UTF-16 environment block for CreateProcess.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hEnv Environment block handle.
+ * @param ppwszzBlock Where to return the environment block. This must be
+ * freed by calling RTEnvFreeUtf16Block.
+ */
+RTDECL(int) RTEnvQueryUtf16Block(RTENV hEnv, PRTUTF16 *ppwszzBlock);
+
+/**
+ * Frees an environment block returned by RTEnvGetUtf16Block().
+ *
+ * @param pwszzBlock What RTEnvGetUtf16Block returned. NULL is ignored.
+ */
+RTDECL(void) RTEnvFreeUtf16Block(PRTUTF16 pwszzBlock);
+
+/**
+ * Checks if an environment variable exists in the default environment block.
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param pszVar The environment variable name.
+ * @remark WARNING! The current implementation does not perform the appropriate
+ * codeset conversion. We'll figure this out when it becomes necessary.
+ */
+RTDECL(bool) RTEnvExist(const char *pszVar);
+
+/**
+ * Checks if an environment variable exists in a specific environment block.
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param Env The environment handle.
+ * @param pszVar The environment variable name.
+ */
+RTDECL(bool) RTEnvExistEx(RTENV Env, const char *pszVar);
+
+/**
+ * Gets an environment variable from the default environment block. (getenv).
+ *
+ * The caller is responsible for ensuring that nobody changes the environment
+ * while it's using the returned string pointer!
+ *
+ * @returns Pointer to read only string on success, NULL if the variable wasn't found.
+ *
+ * @param pszVar The environment variable name.
+ *
+ * @remark WARNING! The current implementation does not perform the appropriate
+ * codeset conversion. We'll figure this out when it becomes necessary.
+ */
+RTDECL(const char *) RTEnvGet(const char *pszVar);
+
+/**
+ * Gets an environment variable in a specific environment block.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_ENV_VAR_NOT_FOUND if the variable was not found.
+ *
+ * @param Env The environment handle.
+ * @param pszVar The environment variable name.
+ * @param pszValue Where to put the buffer.
+ * @param cbValue The size of the value buffer.
+ * @param pcchActual Returns the actual value string length. Optional.
+ */
+RTDECL(int) RTEnvGetEx(RTENV Env, const char *pszVar, char *pszValue, size_t cbValue, size_t *pcchActual);
+
+/**
+ * Puts an variable=value string into the environment (putenv).
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param pszVarEqualValue The variable '=' value string. If the value and '=' is
+ * omitted, the variable is removed from the environment.
+ *
+ * @remark Don't assume the value is copied.
+ * @remark WARNING! The current implementation does not perform the appropriate
+ * codeset conversion. We'll figure this out when it becomes necessary.
+ */
+RTDECL(int) RTEnvPut(const char *pszVarEqualValue);
+
+/**
+ * Puts a copy of the passed in 'variable=value' string into the environment block.
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param Env Handle of the environment block.
+ * @param pszVarEqualValue The variable '=' value string. If the value and '=' is
+ * omitted, the variable is removed from the environment.
+ */
+RTDECL(int) RTEnvPutEx(RTENV Env, const char *pszVarEqualValue);
+
+/**
+ * Sets an environment variable (setenv(,,1)).
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param pszVar The environment variable name.
+ * @param pszValue The environment variable value.
+ *
+ * @remark WARNING! The current implementation does not perform the appropriate
+ * codeset conversion. We'll figure this out when it becomes necessary.
+ */
+RTDECL(int) RTEnvSet(const char *pszVar, const char *pszValue);
+
+/**
+ * Sets an environment variable (setenv(,,1)).
+ *
+ * @returns IPRT status code. Typical error is VERR_NO_MEMORY.
+ *
+ * @param Env The environment handle.
+ * @param pszVar The environment variable name.
+ * @param pszValue The environment variable value.
+ */
+RTDECL(int) RTEnvSetEx(RTENV Env, const char *pszVar, const char *pszValue);
+
+/**
+ * Removes an environment variable from the default environment block.
+ *
+ * @returns IPRT status code.
+ * @returns VINF_ENV_VAR_NOT_FOUND if the variable was not found.
+ *
+ * @param pszVar The environment variable name.
+ *
+ * @remark WARNING! The current implementation does not perform the appropriate
+ * codeset conversion. We'll figure this out when it becomes necessary.
+ */
+RTDECL(int) RTEnvUnset(const char *pszVar);
+
+/**
+ * Removes an environment variable from the specified environment block.
+ *
+ * @returns IPRT status code.
+ * @returns VINF_ENV_VAR_NOT_FOUND if the variable was not found.
+ *
+ * @param Env The environment handle.
+ * @param pszVar The environment variable name.
+ */
+RTDECL(int) RTEnvUnsetEx(RTENV Env, const char *pszVar);
+
+/**
+ * Duplicates the value of a environment variable if it exists.
+ *
+ * @returns Pointer to a string containing the value, free it using RTStrFree.
+ * NULL if the variable was not found or we're out of memory.
+ *
+ * @param Env The environment handle.
+ * @param pszVar The environment variable name.
+ */
+RTDECL(char *) RTEnvDupEx(RTENV Env, const char *pszVar);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/err.h b/include/iprt/err.h
new file mode 100644
index 00000000..13b9914f
--- /dev/null
+++ b/include/iprt/err.h
@@ -0,0 +1,1733 @@
+/** @file
+ * IPRT - 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 ___iprt_err_h
+#define ___iprt_err_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+
+/** @defgroup grp_rt_err RTErr - Status Codes
+ * @ingroup grp_rt
+ *
+ * The IPRT status codes are in two ranges: {0..999} and {22000..32766}. The
+ * IPRT users are free to use the range {1000..21999}. See RTERR_RANGE1_FIRST,
+ * RTERR_RANGE1_LAST, RTERR_RANGE2_FIRST, RTERR_RANGE2_LAST, RTERR_USER_FIRST
+ * and RTERR_USER_LAST.
+ *
+ * @{
+ */
+
+/** @defgroup grp_rt_err_hlp Status Code Helpers
+ * @ingroup grp_rt_err
+ * @{
+ */
+
+#ifdef __cplusplus
+/**
+ * Strict type validation class.
+ *
+ * This is only really useful for type checking the arguments to RT_SUCCESS,
+ * RT_SUCCESS_NP, RT_FAILURE and RT_FAILURE_NP. The RTErrStrictType2
+ * constructor is for integration with external status code strictness regimes.
+ */
+class RTErrStrictType
+{
+protected:
+ int32_t m_rc;
+
+public:
+ /**
+ * Constructor for interaction with external status code strictness regimes.
+ *
+ * This is a special constructor for helping external return code validator
+ * classes interact cleanly with RT_SUCCESS, RT_SUCCESS_NP, RT_FAILURE and
+ * RT_FAILURE_NP while barring automatic cast to integer.
+ *
+ * @param rcObj IPRT status code object from an automatic cast.
+ */
+ RTErrStrictType(RTErrStrictType2 const rcObj)
+ : m_rc(rcObj.getValue())
+ {
+ }
+
+ /**
+ * Integer constructor used by RT_SUCCESS_NP.
+ *
+ * @param rc IPRT style status code.
+ */
+ RTErrStrictType(int32_t rc)
+ : m_rc(rc)
+ {
+ }
+
+#if 0 /** @todo figure where int32_t is long instead of int. */
+ /**
+ * Integer constructor used by RT_SUCCESS_NP.
+ *
+ * @param rc IPRT style status code.
+ */
+ RTErrStrictType(signed int rc)
+ : m_rc(rc)
+ {
+ }
+#endif
+
+ /**
+ * Test for success.
+ */
+ bool success() const
+ {
+ return m_rc >= 0;
+ }
+
+private:
+ /** @name Try ban a number of wrong types.
+ * @{ */
+ RTErrStrictType(uint8_t rc) : m_rc(-999) { NOREF(rc); }
+ RTErrStrictType(uint16_t rc) : m_rc(-999) { NOREF(rc); }
+ RTErrStrictType(uint32_t rc) : m_rc(-999) { NOREF(rc); }
+ RTErrStrictType(uint64_t rc) : m_rc(-999) { NOREF(rc); }
+ RTErrStrictType(int8_t rc) : m_rc(-999) { NOREF(rc); }
+ RTErrStrictType(int16_t rc) : m_rc(-999) { NOREF(rc); }
+ RTErrStrictType(int64_t rc) : m_rc(-999) { NOREF(rc); }
+ /** @todo fight long here - clashes with int32_t/int64_t on some platforms. */
+ /** @} */
+};
+#endif /* __cplusplus */
+
+
+/** @def RTERR_STRICT_RC
+ * Indicates that RT_SUCCESS_NP, RT_SUCCESS, RT_FAILURE_NP and RT_FAILURE should
+ * make type enforcing at compile time.
+ *
+ * @remarks Only define this for C++ code.
+ */
+#if defined(__cplusplus) \
+ && !defined(RTERR_STRICT_RC) \
+ && ( defined(DOXYGEN_RUNNING) \
+ || defined(DEBUG) \
+ || defined(RT_STRICT) )
+# define RTERR_STRICT_RC 1
+#endif
+
+
+/** @def RT_SUCCESS
+ * Check for success. We expect success in normal cases, that is the code path depending on
+ * this check is normally taken. To prevent any prediction use RT_SUCCESS_NP instead.
+ *
+ * @returns true if rc indicates success.
+ * @returns false if rc indicates failure.
+ *
+ * @param rc The iprt status code to test.
+ */
+#define RT_SUCCESS(rc) ( RT_LIKELY(RT_SUCCESS_NP(rc)) )
+
+/** @def RT_SUCCESS_NP
+ * Check for success. Don't predict the result.
+ *
+ * @returns true if rc indicates success.
+ * @returns false if rc indicates failure.
+ *
+ * @param rc The iprt status code to test.
+ */
+#ifdef RTERR_STRICT_RC
+# define RT_SUCCESS_NP(rc) ( RTErrStrictType(rc).success() )
+#else
+# define RT_SUCCESS_NP(rc) ( (int)(rc) >= VINF_SUCCESS )
+#endif
+
+/** @def RT_FAILURE
+ * Check for failure. We don't expect in normal cases, that is the code path depending on
+ * this check is normally NOT taken. To prevent any prediction use RT_FAILURE_NP instead.
+ *
+ * @returns true if rc indicates failure.
+ * @returns false if rc indicates success.
+ *
+ * @param rc The iprt status code to test.
+ */
+#define RT_FAILURE(rc) ( RT_UNLIKELY(!RT_SUCCESS_NP(rc)) )
+
+/** @def RT_FAILURE_NP
+ * Check for failure. Don't predict the result.
+ *
+ * @returns true if rc indicates failure.
+ * @returns false if rc indicates success.
+ *
+ * @param rc The iprt status code to test.
+ */
+#define RT_FAILURE_NP(rc) ( !RT_SUCCESS_NP(rc) )
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Converts a Darwin HRESULT error to an iprt status code.
+ *
+ * @returns iprt status code.
+ * @param iNativeCode HRESULT error code.
+ * @remark Darwin ring-3 only.
+ */
+RTDECL(int) RTErrConvertFromDarwinCOM(int32_t iNativeCode);
+
+/**
+ * Converts a Darwin IOReturn error to an iprt status code.
+ *
+ * @returns iprt status code.
+ * @param iNativeCode IOReturn error code.
+ * @remark Darwin only.
+ */
+RTDECL(int) RTErrConvertFromDarwinIO(int iNativeCode);
+
+/**
+ * Converts a Darwin kern_return_t error to an iprt status code.
+ *
+ * @returns iprt status code.
+ * @param iNativeCode kern_return_t error code.
+ * @remark Darwin only.
+ */
+RTDECL(int) RTErrConvertFromDarwinKern(int iNativeCode);
+
+/**
+ * Converts a Darwin error to an iprt status code.
+ *
+ * This will consult RTErrConvertFromDarwinKern, RTErrConvertFromDarwinIO
+ * and RTErrConvertFromDarwinCOM in this order. The latter is ring-3 only as it
+ * doesn't apply elsewhere.
+ *
+ * @returns iprt status code.
+ * @param iNativeCode Darwin error code.
+ * @remarks Darwin only.
+ * @remarks This is recommended over RTErrConvertFromDarwinKern and RTErrConvertFromDarwinIO
+ * since these are really just subsets of the same error space.
+ */
+RTDECL(int) RTErrConvertFromDarwin(int iNativeCode);
+
+/**
+ * Converts errno to iprt status code.
+ *
+ * @returns iprt status code.
+ * @param uNativeCode errno code.
+ */
+RTDECL(int) RTErrConvertFromErrno(unsigned uNativeCode);
+
+/**
+ * Converts a L4 errno to a iprt status code.
+ *
+ * @returns iprt status code.
+ * @param uNativeCode l4 errno.
+ * @remark L4 only.
+ */
+RTDECL(int) RTErrConvertFromL4Errno(unsigned uNativeCode);
+
+/**
+ * Converts NT status code to iprt status code.
+ *
+ * Needless to say, this is only available on NT and winXX targets.
+ *
+ * @returns iprt status code.
+ * @param lNativeCode NT status code.
+ * @remark Windows only.
+ */
+RTDECL(int) RTErrConvertFromNtStatus(long lNativeCode);
+
+/**
+ * Converts OS/2 error code to iprt status code.
+ *
+ * @returns iprt status code.
+ * @param uNativeCode OS/2 error code.
+ * @remark OS/2 only.
+ */
+RTDECL(int) RTErrConvertFromOS2(unsigned uNativeCode);
+
+/**
+ * Converts Win32 error code to iprt status code.
+ *
+ * @returns iprt status code.
+ * @param uNativeCode Win32 error code.
+ * @remark Windows only.
+ */
+RTDECL(int) RTErrConvertFromWin32(unsigned uNativeCode);
+
+/**
+ * Converts an iprt status code to a errno status code.
+ *
+ * @returns errno status code.
+ * @param iErr iprt status code.
+ */
+RTDECL(int) RTErrConvertToErrno(int iErr);
+
+#ifdef IN_RING3
+
+/**
+ * iprt status code message.
+ */
+typedef struct RTSTATUSMSG
+{
+ /** Pointer to the short message string. */
+ const char *pszMsgShort;
+ /** Pointer to the full message string. */
+ const char *pszMsgFull;
+ /** Pointer to the define string. */
+ const char *pszDefine;
+ /** Status code number. */
+ int iCode;
+} RTSTATUSMSG;
+/** Pointer to iprt status code message. */
+typedef RTSTATUSMSG *PRTSTATUSMSG;
+/** Pointer to const iprt status code message. */
+typedef const RTSTATUSMSG *PCRTSTATUSMSG;
+
+/**
+ * Get the message structure corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only message description.
+ * @param rc The status code.
+ */
+RTDECL(PCRTSTATUSMSG) RTErrGet(int rc);
+
+/**
+ * Get the define corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only string with the \#define identifier.
+ * @param rc The status code.
+ */
+#define RTErrGetDefine(rc) (RTErrGet(rc)->pszDefine)
+
+/**
+ * Get the short description corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only string with the description.
+ * @param rc The status code.
+ */
+#define RTErrGetShort(rc) (RTErrGet(rc)->pszMsgShort)
+
+/**
+ * Get the full description corresponding to a given iprt status code.
+ *
+ * @returns Pointer to read-only string with the description.
+ * @param rc The status code.
+ */
+#define RTErrGetFull(rc) (RTErrGet(rc)->pszMsgFull)
+
+#ifdef RT_OS_WINDOWS
+/**
+ * Windows error code message.
+ */
+typedef struct RTWINERRMSG
+{
+ /** Pointer to the full message string. */
+ const char *pszMsgFull;
+ /** Pointer to the define string. */
+ const char *pszDefine;
+ /** Error code number. */
+ long iCode;
+} RTWINERRMSG;
+/** Pointer to Windows error code message. */
+typedef RTWINERRMSG *PRTWINERRMSG;
+/** Pointer to const Windows error code message. */
+typedef const RTWINERRMSG *PCRTWINERRMSG;
+
+/**
+ * Get the message structure corresponding to a given Windows error code.
+ *
+ * @returns Pointer to read-only message description.
+ * @param rc The status code.
+ */
+RTDECL(PCRTWINERRMSG) RTErrWinGet(long rc);
+
+/** On windows COM errors are part of the Windows error database. */
+typedef RTWINERRMSG RTCOMERRMSG;
+
+#else /* !RT_OS_WINDOWS */
+
+/**
+ * COM/XPCOM error code message.
+ */
+typedef struct RTCOMERRMSG
+{
+ /** Pointer to the full message string. */
+ const char *pszMsgFull;
+ /** Pointer to the define string. */
+ const char *pszDefine;
+ /** Error code number. */
+ uint32_t iCode;
+} RTCOMERRMSG;
+#endif /* !RT_OS_WINDOWS */
+/** Pointer to a XPCOM/COM error code message. */
+typedef RTCOMERRMSG *PRTCOMERRMSG;
+/** Pointer to const a XPCOM/COM error code message. */
+typedef const RTCOMERRMSG *PCRTCOMERRMSG;
+
+/**
+ * Get the message structure corresponding to a given COM/XPCOM error code.
+ *
+ * @returns Pointer to read-only message description.
+ * @param rc The status code.
+ */
+RTDECL(PCRTCOMERRMSG) RTErrCOMGet(uint32_t rc);
+
+#endif /* IN_RING3 */
+
+/** @defgroup RTERRINFO_FLAGS_XXX RTERRINFO::fFlags
+ * @{ */
+/** Custom structure (the default). */
+#define RTERRINFO_FLAGS_T_CUSTOM UINT32_C(0)
+/** Static structure (RTERRINFOSTATIC). */
+#define RTERRINFO_FLAGS_T_STATIC UINT32_C(1)
+/** Allocated structure (RTErrInfoAlloc). */
+#define RTERRINFO_FLAGS_T_ALLOC UINT32_C(2)
+/** Reserved type. */
+#define RTERRINFO_FLAGS_T_RESERVED UINT32_C(3)
+/** Type mask. */
+#define RTERRINFO_FLAGS_T_MASK UINT32_C(3)
+/** Error info is set. */
+#define RTERRINFO_FLAGS_SET RT_BIT_32(2)
+/** Fixed flags (magic). */
+#define RTERRINFO_FLAGS_MAGIC UINT32_C(0xbabe0000)
+/** The bit mask for the magic value. */
+#define RTERRINFO_FLAGS_MAGIC_MASK UINT32_C(0xffff0000)
+/** @} */
+
+/**
+ * Initializes an error info structure.
+ *
+ * @returns @a pErrInfo.
+ * @param pErrInfo The error info structure to init.
+ * @param pszMsg The message buffer. Must be at least one byte.
+ * @param cbMsg The size of the message buffer.
+ */
+DECLINLINE(PRTERRINFO) RTErrInfoInit(PRTERRINFO pErrInfo, char *pszMsg, size_t cbMsg)
+{
+ *pszMsg = '\0';
+
+ pErrInfo->fFlags = RTERRINFO_FLAGS_T_CUSTOM | RTERRINFO_FLAGS_MAGIC;
+ pErrInfo->rc = /*VINF_SUCCESS*/ 0;
+ pErrInfo->pszMsg = pszMsg;
+ pErrInfo->cbMsg = cbMsg;
+ pErrInfo->apvReserved[0] = NULL;
+ pErrInfo->apvReserved[1] = NULL;
+
+ return pErrInfo;
+}
+
+/**
+ * Initialize a static error info structure.
+ *
+ * @param pStaticErrInfo The static error info structure to init.
+ */
+DECLINLINE(void) RTErrInfoInitStatic(PRTERRINFOSTATIC pStaticErrInfo)
+{
+ RTErrInfoInit(&pStaticErrInfo->Core, pStaticErrInfo->szMsg, sizeof(pStaticErrInfo->szMsg));
+ pStaticErrInfo->Core.fFlags = RTERRINFO_FLAGS_T_STATIC | RTERRINFO_FLAGS_MAGIC;
+}
+
+/**
+ * Allocates a error info structure with a buffer at least the given size.
+ *
+ * @returns Pointer to an error info structure on success, NULL on failure.
+ *
+ * @param cbMsg The minimum message buffer size. Use 0 to get
+ * the default buffer size.
+ */
+RTDECL(PRTERRINFO) RTErrInfoAlloc(size_t cbMsg);
+
+/**
+ * Same as RTErrInfoAlloc, except that an IPRT status code is returned.
+ *
+ * @returns IPRT status code.
+ *
+ * @param cbMsg The minimum message buffer size. Use 0 to get
+ * the default buffer size.
+ * @param ppErrInfo Where to store the pointer to the allocated
+ * error info structure on success. This is
+ * always set to NULL.
+ */
+RTDECL(int) RTErrInfoAllocEx(size_t cbMsg, PRTERRINFO *ppErrInfo);
+
+/**
+ * Frees an error info structure allocated by RTErrInfoAlloc or
+ * RTErrInfoAllocEx.
+ *
+ * @param pErrInfo The error info structure.
+ */
+RTDECL(void) RTErrInfoFree(PRTERRINFO pErrInfo);
+
+/**
+ * Fills in the error info details.
+ *
+ * @returns @a rc.
+ *
+ * @param pErrInfo The error info structure to fill in.
+ * @param rc The status code to return.
+ * @param pszMsg The error message string.
+ */
+RTDECL(int) RTErrInfoSet(PRTERRINFO pErrInfo, int rc, const char *pszMsg);
+
+/**
+ * Fills in the error info details, with a sprintf style message.
+ *
+ * @returns @a rc.
+ *
+ * @param pErrInfo The error info structure to fill in.
+ * @param rc The status code to return.
+ * @param pszFormat The format string.
+ * @param ... The format arguments.
+ */
+RTDECL(int) RTErrInfoSetF(PRTERRINFO pErrInfo, int rc, const char *pszFormat, ...);
+
+/**
+ * Fills in the error info details, with a vsprintf style message.
+ *
+ * @returns @a rc.
+ *
+ * @param pErrInfo The error info structure to fill in.
+ * @param rc The status code to return.
+ * @param pszFormat The format string.
+ * @param va The format arguments.
+ */
+RTDECL(int) RTErrInfoSetV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va);
+
+/**
+ * Checks if the error info is set.
+ *
+ * @returns true if set, false if not.
+ * @param pErrInfo The error info structure. NULL is OK.
+ */
+DECLINLINE(bool) RTErrInfoIsSet(PCRTERRINFO pErrInfo)
+{
+ if (!pErrInfo)
+ return false;
+ return (pErrInfo->fFlags & (RTERRINFO_FLAGS_MAGIC_MASK | RTERRINFO_FLAGS_SET))
+ == (RTERRINFO_FLAGS_MAGIC | RTERRINFO_FLAGS_SET);
+}
+
+/**
+ * Clears the error info structure.
+ *
+ * @param pErrInfo The error info structure. NULL is OK.
+ */
+DECLINLINE(void) RTErrInfoClear(PRTERRINFO pErrInfo)
+{
+ if (pErrInfo)
+ {
+ pErrInfo->fFlags &= ~RTERRINFO_FLAGS_SET;
+ pErrInfo->rc = /*VINF_SUCCESS*/0;
+ *pErrInfo->pszMsg = '\0';
+ }
+}
+
+/**
+ * Storage for error variables.
+ *
+ * @remarks Do NOT touch the members! They are platform specific and what's
+ * where may change at any time!
+ */
+typedef union RTERRVARS
+{
+ int8_t ai8Vars[32];
+ int16_t ai16Vars[16];
+ int32_t ai32Vars[8];
+ int64_t ai64Vars[4];
+} RTERRVARS;
+/** Pointer to an error variable storage union. */
+typedef RTERRVARS *PRTERRVARS;
+/** Pointer to a const error variable storage union. */
+typedef RTERRVARS const *PCRTERRVARS;
+
+/**
+ * Saves the error variables.
+ *
+ * @returns @a pVars.
+ * @param pVars The variable storage union.
+ */
+RTDECL(PRTERRVARS) RTErrVarsSave(PRTERRVARS pVars);
+
+/**
+ * Restores the error variables.
+ *
+ * @param pVars The variable storage union.
+ */
+RTDECL(void) RTErrVarsRestore(PCRTERRVARS pVars);
+
+/**
+ * Checks if the first variable set equals the second.
+ *
+ * @returns true if they are equal, false if not.
+ * @param pVars1 The first variable storage union.
+ * @param pVars2 The second variable storage union.
+ */
+RTDECL(bool) RTErrVarsAreEqual(PCRTERRVARS pVars1, PCRTERRVARS pVars2);
+
+/**
+ * Checks if the (live) error variables have changed since we saved them.
+ *
+ * @returns @c true if they have changed, @c false if not.
+ * @param pVars The saved variables to compare the current state
+ * against.
+ */
+RTDECL(bool) RTErrVarsHaveChanged(PCRTERRVARS pVars);
+
+RT_C_DECLS_END
+
+/** @} */
+
+/** @name Status Code Ranges
+ * @{ */
+/** The first status code in the primary IPRT range. */
+#define RTERR_RANGE1_FIRST 0
+/** The last status code in the primary IPRT range. */
+#define RTERR_RANGE1_LAST 999
+
+/** The first status code in the secondary IPRT range. */
+#define RTERR_RANGE2_FIRST 22000
+/** The last status code in the secondary IPRT range. */
+#define RTERR_RANGE2_LAST 32766
+
+/** The first status code in the user range. */
+#define RTERR_USER_FIRST 1000
+/** The last status code in the user range. */
+#define RTERR_USER_LAST 21999
+/** @} */
+
+
+/* SED-START */
+
+/** @name Misc. Status Codes
+ * @{
+ */
+/** Success. */
+#define VINF_SUCCESS 0
+
+/** General failure - DON'T USE THIS!!! */
+#define VERR_GENERAL_FAILURE (-1)
+/** Invalid parameter. */
+#define VERR_INVALID_PARAMETER (-2)
+/** Invalid parameter. */
+#define VWRN_INVALID_PARAMETER 2
+/** Invalid magic or cookie. */
+#define VERR_INVALID_MAGIC (-3)
+/** Invalid magic or cookie. */
+#define VWRN_INVALID_MAGIC 3
+/** Invalid loader handle. */
+#define VERR_INVALID_HANDLE (-4)
+/** Invalid loader handle. */
+#define VWRN_INVALID_HANDLE 4
+/** Failed to lock the address range. */
+#define VERR_LOCK_FAILED (-5)
+/** Invalid memory pointer. */
+#define VERR_INVALID_POINTER (-6)
+/** Failed to patch the IDT. */
+#define VERR_IDT_FAILED (-7)
+/** Memory allocation failed. */
+#define VERR_NO_MEMORY (-8)
+/** Already loaded. */
+#define VERR_ALREADY_LOADED (-9)
+/** Permission denied. */
+#define VERR_PERMISSION_DENIED (-10)
+/** Permission denied. */
+#define VINF_PERMISSION_DENIED 10
+/** Version mismatch. */
+#define VERR_VERSION_MISMATCH (-11)
+/** The request function is not implemented. */
+#define VERR_NOT_IMPLEMENTED (-12)
+
+/** Not equal. */
+#define VERR_NOT_EQUAL (-18)
+/** The specified path does not point at a symbolic link. */
+#define VERR_NOT_SYMLINK (-19)
+/** Failed to allocate temporary memory. */
+#define VERR_NO_TMP_MEMORY (-20)
+/** Invalid file mode mask (RTFMODE). */
+#define VERR_INVALID_FMODE (-21)
+/** Incorrect call order. */
+#define VERR_WRONG_ORDER (-22)
+/** There is no TLS (thread local storage) available for storing the current thread. */
+#define VERR_NO_TLS_FOR_SELF (-23)
+/** Failed to set the TLS (thread local storage) entry which points to our thread structure. */
+#define VERR_FAILED_TO_SET_SELF_TLS (-24)
+/** Not able to allocate contiguous memory. */
+#define VERR_NO_CONT_MEMORY (-26)
+/** No memory available for page table or page directory. */
+#define VERR_NO_PAGE_MEMORY (-27)
+/** Already initialized. */
+#define VINF_ALREADY_INITIALIZED 28
+/** The specified thread is dead. */
+#define VERR_THREAD_IS_DEAD (-29)
+/** The specified thread is not waitable. */
+#define VERR_THREAD_NOT_WAITABLE (-30)
+/** Pagetable not present. */
+#define VERR_PAGE_TABLE_NOT_PRESENT (-31)
+/** Invalid context.
+ * Typically an API was used by the wrong thread. */
+#define VERR_INVALID_CONTEXT (-32)
+/** The per process timer is busy. */
+#define VERR_TIMER_BUSY (-33)
+/** Address conflict. */
+#define VERR_ADDRESS_CONFLICT (-34)
+/** Unresolved (unknown) host platform error. */
+#define VERR_UNRESOLVED_ERROR (-35)
+/** Invalid function. */
+#define VERR_INVALID_FUNCTION (-36)
+/** Not supported. */
+#define VERR_NOT_SUPPORTED (-37)
+/** Not supported. */
+#define VINF_NOT_SUPPORTED 37
+/** Access denied. */
+#define VERR_ACCESS_DENIED (-38)
+/** Call interrupted. */
+#define VERR_INTERRUPTED (-39)
+/** Call interrupted. */
+#define VINF_INTERRUPTED 39
+/** Timeout. */
+#define VERR_TIMEOUT (-40)
+/** Timeout. */
+#define VINF_TIMEOUT 40
+/** Buffer too small to save result. */
+#define VERR_BUFFER_OVERFLOW (-41)
+/** Buffer too small to save result. */
+#define VINF_BUFFER_OVERFLOW 41
+/** Data size overflow. */
+#define VERR_TOO_MUCH_DATA (-42)
+/** Max threads number reached. */
+#define VERR_MAX_THRDS_REACHED (-43)
+/** Max process number reached. */
+#define VERR_MAX_PROCS_REACHED (-44)
+/** The recipient process has refused the signal. */
+#define VERR_SIGNAL_REFUSED (-45)
+/** A signal is already pending. */
+#define VERR_SIGNAL_PENDING (-46)
+/** The signal being posted is not correct. */
+#define VERR_SIGNAL_INVALID (-47)
+/** The state changed.
+ * This is a generic error message and needs a context to make sense. */
+#define VERR_STATE_CHANGED (-48)
+/** Warning, the state changed.
+ * This is a generic error message and needs a context to make sense. */
+#define VWRN_STATE_CHANGED 48
+/** Error while parsing UUID string */
+#define VERR_INVALID_UUID_FORMAT (-49)
+/** The specified process was not found. */
+#define VERR_PROCESS_NOT_FOUND (-50)
+/** The process specified to a non-block wait had not exited. */
+#define VERR_PROCESS_RUNNING (-51)
+/** Retry the operation. */
+#define VERR_TRY_AGAIN (-52)
+/** Retry the operation. */
+#define VINF_TRY_AGAIN 52
+/** Generic parse error. */
+#define VERR_PARSE_ERROR (-53)
+/** Value out of range. */
+#define VERR_OUT_OF_RANGE (-54)
+/** A numeric conversion encountered a value which was too big for the target. */
+#define VERR_NUMBER_TOO_BIG (-55)
+/** A numeric conversion encountered a value which was too big for the target. */
+#define VWRN_NUMBER_TOO_BIG 55
+/** The number begin converted (string) contained no digits. */
+#define VERR_NO_DIGITS (-56)
+/** The number begin converted (string) contained no digits. */
+#define VWRN_NO_DIGITS 56
+/** Encountered a '-' during conversion to an unsigned value. */
+#define VERR_NEGATIVE_UNSIGNED (-57)
+/** Encountered a '-' during conversion to an unsigned value. */
+#define VWRN_NEGATIVE_UNSIGNED 57
+/** Error while characters translation (unicode and so). */
+#define VERR_NO_TRANSLATION (-58)
+/** Error while characters translation (unicode and so). */
+#define VWRN_NO_TRANSLATION 58
+/** Encountered unicode code point which is reserved for use as endian indicator (0xffff or 0xfffe). */
+#define VERR_CODE_POINT_ENDIAN_INDICATOR (-59)
+/** Encountered unicode code point in the surrogate range (0xd800 to 0xdfff). */
+#define VERR_CODE_POINT_SURROGATE (-60)
+/** A string claiming to be UTF-8 is incorrectly encoded. */
+#define VERR_INVALID_UTF8_ENCODING (-61)
+/** Ad string claiming to be in UTF-16 is incorrectly encoded. */
+#define VERR_INVALID_UTF16_ENCODING (-62)
+/** Encountered a unicode code point which cannot be represented as UTF-16. */
+#define VERR_CANT_RECODE_AS_UTF16 (-63)
+/** Got an out of memory condition trying to allocate a string. */
+#define VERR_NO_STR_MEMORY (-64)
+/** Got an out of memory condition trying to allocate a UTF-16 (/UCS-2) string. */
+#define VERR_NO_UTF16_MEMORY (-65)
+/** Get an out of memory condition trying to allocate a code point array. */
+#define VERR_NO_CODE_POINT_MEMORY (-66)
+/** Can't free the memory because it's used in mapping. */
+#define VERR_MEMORY_BUSY (-67)
+/** The timer can't be started because it's already active. */
+#define VERR_TIMER_ACTIVE (-68)
+/** The timer can't be stopped because i's already suspended. */
+#define VERR_TIMER_SUSPENDED (-69)
+/** The operation was cancelled by the user (copy) or another thread (local ipc). */
+#define VERR_CANCELLED (-70)
+/** Failed to initialize a memory object.
+ * Exactly what this means is OS specific. */
+#define VERR_MEMOBJ_INIT_FAILED (-71)
+/** Out of memory condition when allocating memory with low physical backing. */
+#define VERR_NO_LOW_MEMORY (-72)
+/** Out of memory condition when allocating physical memory (without mapping). */
+#define VERR_NO_PHYS_MEMORY (-73)
+/** The address (virtual or physical) is too big. */
+#define VERR_ADDRESS_TOO_BIG (-74)
+/** Failed to map a memory object. */
+#define VERR_MAP_FAILED (-75)
+/** Trailing characters. */
+#define VERR_TRAILING_CHARS (-76)
+/** Trailing characters. */
+#define VWRN_TRAILING_CHARS 76
+/** Trailing spaces. */
+#define VERR_TRAILING_SPACES (-77)
+/** Trailing spaces. */
+#define VWRN_TRAILING_SPACES 77
+/** Generic not found error. */
+#define VERR_NOT_FOUND (-78)
+/** Generic not found warning. */
+#define VWRN_NOT_FOUND 78
+/** Generic invalid state error. */
+#define VERR_INVALID_STATE (-79)
+/** Generic invalid state warning. */
+#define VWRN_INVALID_STATE 79
+/** Generic out of resources error. */
+#define VERR_OUT_OF_RESOURCES (-80)
+/** Generic out of resources warning. */
+#define VWRN_OUT_OF_RESOURCES 80
+/** No more handles available, too many open handles. */
+#define VERR_NO_MORE_HANDLES (-81)
+/** Preemption is disabled.
+ * The requested operation can only be performed when preemption is enabled. */
+#define VERR_PREEMPT_DISABLED (-82)
+/** End of string. */
+#define VERR_END_OF_STRING (-83)
+/** End of string. */
+#define VINF_END_OF_STRING 83
+/** A page count is out of range. */
+#define VERR_PAGE_COUNT_OUT_OF_RANGE (-84)
+/** Generic object destroyed status. */
+#define VERR_OBJECT_DESTROYED (-85)
+/** Generic object was destroyed by the call status. */
+#define VINF_OBJECT_DESTROYED 85
+/** Generic dangling objects status. */
+#define VERR_DANGLING_OBJECTS (-86)
+/** Generic dangling objects status. */
+#define VWRN_DANGLING_OBJECTS 86
+/** Invalid Base64 encoding. */
+#define VERR_INVALID_BASE64_ENCODING (-87)
+/** Return instigated by a callback or similar. */
+#define VERR_CALLBACK_RETURN (-88)
+/** Return instigated by a callback or similar. */
+#define VINF_CALLBACK_RETURN 88
+/** Authentication failure. */
+#define VERR_AUTHENTICATION_FAILURE (-89)
+/** Not a power of two. */
+#define VERR_NOT_POWER_OF_TWO (-90)
+/** Status code, typically given as a parameter, that isn't supposed to be used. */
+#define VERR_IGNORED (-91)
+/** Concurrent access to the object is not allowed. */
+#define VERR_CONCURRENT_ACCESS (-92)
+/** The caller does not have a reference to the object.
+ * This status is used when two threads is caught sharing the same object
+ * reference. */
+#define VERR_CALLER_NO_REFERENCE (-93)
+/** Generic no change error. */
+#define VERR_NO_CHANGE (-95)
+/** Generic no change info. */
+#define VINF_NO_CHANGE 95
+/** Out of memory condition when allocating executable memory. */
+#define VERR_NO_EXEC_MEMORY (-96)
+/** The alignment is not supported. */
+#define VERR_UNSUPPORTED_ALIGNMENT (-97)
+/** The alignment is not really supported, however we got lucky with this
+ * allocation. */
+#define VINF_UNSUPPORTED_ALIGNMENT 97
+/** Duplicate something. */
+#define VERR_DUPLICATE (-98)
+/** Something is missing. */
+#define VERR_MISSING (-99)
+/** An unexpected (/unknown) exception was caught. */
+#define VERR_UNEXPECTED_EXCEPTION (-22400)
+/** Buffer underflow. */
+#define VERR_BUFFER_UNDERFLOW (-22401)
+/** Buffer underflow. */
+#define VINF_BUFFER_UNDERFLOW 22401
+/** Uneven input. */
+#define VERR_UNEVEN_INPUT (-22402)
+/** Something is not available or not working properly. */
+#define VERR_NOT_AVAILABLE (-22403)
+/** @} */
+
+
+/** @name Common File/Disk/Pipe/etc Status Codes
+ * @{
+ */
+/** Unresolved (unknown) file i/o error. */
+#define VERR_FILE_IO_ERROR (-100)
+/** File/Device open failed. */
+#define VERR_OPEN_FAILED (-101)
+/** File not found. */
+#define VERR_FILE_NOT_FOUND (-102)
+/** Path not found. */
+#define VERR_PATH_NOT_FOUND (-103)
+/** Invalid (malformed) file/path name. */
+#define VERR_INVALID_NAME (-104)
+/** The object in question already exists. */
+#define VERR_ALREADY_EXISTS (-105)
+/** The object in question already exists. */
+#define VWRN_ALREADY_EXISTS 105
+/** Too many open files. */
+#define VERR_TOO_MANY_OPEN_FILES (-106)
+/** Seek error. */
+#define VERR_SEEK (-107)
+/** Seek below file start. */
+#define VERR_NEGATIVE_SEEK (-108)
+/** Trying to seek on device. */
+#define VERR_SEEK_ON_DEVICE (-109)
+/** Reached the end of the file. */
+#define VERR_EOF (-110)
+/** Reached the end of the file. */
+#define VINF_EOF 110
+/** Generic file read error. */
+#define VERR_READ_ERROR (-111)
+/** Generic file write error. */
+#define VERR_WRITE_ERROR (-112)
+/** Write protect error. */
+#define VERR_WRITE_PROTECT (-113)
+/** Sharing violation, file is being used by another process. */
+#define VERR_SHARING_VIOLATION (-114)
+/** Unable to lock a region of a file. */
+#define VERR_FILE_LOCK_FAILED (-115)
+/** File access error, another process has locked a portion of the file. */
+#define VERR_FILE_LOCK_VIOLATION (-116)
+/** File or directory can't be created. */
+#define VERR_CANT_CREATE (-117)
+/** Directory can't be deleted. */
+#define VERR_CANT_DELETE_DIRECTORY (-118)
+/** Can't move file to another disk. */
+#define VERR_NOT_SAME_DEVICE (-119)
+/** The filename or extension is too long. */
+#define VERR_FILENAME_TOO_LONG (-120)
+/** Media not present in drive. */
+#define VERR_MEDIA_NOT_PRESENT (-121)
+/** The type of media was not recognized. Not formatted? */
+#define VERR_MEDIA_NOT_RECOGNIZED (-122)
+/** Can't unlock - region was not locked. */
+#define VERR_FILE_NOT_LOCKED (-123)
+/** Unrecoverable error: lock was lost. */
+#define VERR_FILE_LOCK_LOST (-124)
+/** Can't delete directory with files. */
+#define VERR_DIR_NOT_EMPTY (-125)
+/** A directory operation was attempted on a non-directory object. */
+#define VERR_NOT_A_DIRECTORY (-126)
+/** A non-directory operation was attempted on a directory object. */
+#define VERR_IS_A_DIRECTORY (-127)
+/** Tried to grow a file beyond the limit imposed by the process or the filesystem. */
+#define VERR_FILE_TOO_BIG (-128)
+/** No pending request the aio context has to wait for completion. */
+#define VERR_FILE_AIO_NO_REQUEST (-129)
+/** The request could not be canceled or prepared for another transfer
+ * because it is still in progress. */
+#define VERR_FILE_AIO_IN_PROGRESS (-130)
+/** The request could not be canceled because it already completed. */
+#define VERR_FILE_AIO_COMPLETED (-131)
+/** The I/O context couldn't be destroyed because there are still pending requests. */
+#define VERR_FILE_AIO_BUSY (-132)
+/** The requests couldn't be submitted because that would exceed the capacity of the context. */
+#define VERR_FILE_AIO_LIMIT_EXCEEDED (-133)
+/** The request was canceled. */
+#define VERR_FILE_AIO_CANCELED (-134)
+/** The request wasn't submitted so it can't be canceled. */
+#define VERR_FILE_AIO_NOT_SUBMITTED (-135)
+/** A request was not prepared and thus could not be submitted. */
+#define VERR_FILE_AIO_NOT_PREPARED (-136)
+/** Not all requests could be submitted due to resource shortage. */
+#define VERR_FILE_AIO_INSUFFICIENT_RESSOURCES (-137)
+/** Device or resource is busy. */
+#define VERR_RESOURCE_BUSY (-138)
+/** A file operation was attempted on a non-file object. */
+#define VERR_NOT_A_FILE (-139)
+/** A non-file operation was attempted on a file object. */
+#define VERR_IS_A_FILE (-140)
+/** Unexpected filesystem object type. */
+#define VERR_UNEXPECTED_FS_OBJ_TYPE (-141)
+/** A path does not start with a root specification. */
+#define VERR_PATH_DOES_NOT_START_WITH_ROOT (-142)
+/** A path is relative, expected an absolute path. */
+#define VERR_PATH_IS_RELATIVE (-143)
+/** A path is not relative (start with root), expected an relative path. */
+#define VERR_PATH_IS_NOT_RELATIVE (-144)
+/** @} */
+
+
+/** @name Generic Filesystem I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) disk i/o error. */
+#define VERR_DISK_IO_ERROR (-150)
+/** Invalid drive number. */
+#define VERR_INVALID_DRIVE (-151)
+/** Disk is full. */
+#define VERR_DISK_FULL (-152)
+/** Disk was changed. */
+#define VERR_DISK_CHANGE (-153)
+/** Drive is locked. */
+#define VERR_DRIVE_LOCKED (-154)
+/** The specified disk or diskette cannot be accessed. */
+#define VERR_DISK_INVALID_FORMAT (-155)
+/** Too many symbolic links. */
+#define VERR_TOO_MANY_SYMLINKS (-156)
+/** The OS does not support setting the time stamps on a symbolic link. */
+#define VERR_NS_SYMLINK_SET_TIME (-157)
+/** The OS does not support changing the owner of a symbolic link. */
+#define VERR_NS_SYMLINK_CHANGE_OWNER (-158)
+/** @} */
+
+
+/** @name Generic Directory Enumeration Status Codes
+ * @{
+ */
+/** Unresolved (unknown) search error. */
+#define VERR_SEARCH_ERROR (-200)
+/** No more files found. */
+#define VERR_NO_MORE_FILES (-201)
+/** No more search handles available. */
+#define VERR_NO_MORE_SEARCH_HANDLES (-202)
+/** RTDirReadEx() failed to retrieve the extra data which was requested. */
+#define VWRN_NO_DIRENT_INFO 203
+/** @} */
+
+
+/** @name Internal Processing Errors
+ * @{
+ */
+/** Internal error - this should never happen. */
+#define VERR_INTERNAL_ERROR (-225)
+/** Internal error no. 2. */
+#define VERR_INTERNAL_ERROR_2 (-226)
+/** Internal error no. 3. */
+#define VERR_INTERNAL_ERROR_3 (-227)
+/** Internal error no. 4. */
+#define VERR_INTERNAL_ERROR_4 (-228)
+/** Internal error no. 5. */
+#define VERR_INTERNAL_ERROR_5 (-229)
+/** Internal error: Unexpected status code. */
+#define VERR_IPE_UNEXPECTED_STATUS (-230)
+/** Internal error: Unexpected status code. */
+#define VERR_IPE_UNEXPECTED_INFO_STATUS (-231)
+/** Internal error: Unexpected status code. */
+#define VERR_IPE_UNEXPECTED_ERROR_STATUS (-232)
+/** Internal error: Uninitialized status code.
+ * @remarks This is used by value elsewhere. */
+#define VERR_IPE_UNINITIALIZED_STATUS (-233)
+/** Internal error: Supposedly unreachable default case in a switch. */
+#define VERR_IPE_NOT_REACHED_DEFAULT_CASE (-234)
+/** @} */
+
+
+/** @name Generic Device I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) device i/o error. */
+#define VERR_DEV_IO_ERROR (-250)
+/** Device i/o: Bad unit. */
+#define VERR_IO_BAD_UNIT (-251)
+/** Device i/o: Not ready. */
+#define VERR_IO_NOT_READY (-252)
+/** Device i/o: Bad command. */
+#define VERR_IO_BAD_COMMAND (-253)
+/** Device i/o: CRC error. */
+#define VERR_IO_CRC (-254)
+/** Device i/o: Bad length. */
+#define VERR_IO_BAD_LENGTH (-255)
+/** Device i/o: Sector not found. */
+#define VERR_IO_SECTOR_NOT_FOUND (-256)
+/** Device i/o: General failure. */
+#define VERR_IO_GEN_FAILURE (-257)
+/** @} */
+
+
+/** @name Generic Pipe I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) pipe i/o error. */
+#define VERR_PIPE_IO_ERROR (-300)
+/** Broken pipe. */
+#define VERR_BROKEN_PIPE (-301)
+/** Bad pipe. */
+#define VERR_BAD_PIPE (-302)
+/** Pipe is busy. */
+#define VERR_PIPE_BUSY (-303)
+/** No data in pipe. */
+#define VERR_NO_DATA (-304)
+/** Pipe is not connected. */
+#define VERR_PIPE_NOT_CONNECTED (-305)
+/** More data available in pipe. */
+#define VERR_MORE_DATA (-306)
+/** Expected read pipe, got a write pipe instead. */
+#define VERR_PIPE_NOT_READ (-307)
+/** Expected write pipe, got a read pipe instead. */
+#define VERR_PIPE_NOT_WRITE (-308)
+/** @} */
+
+
+/** @name Generic Semaphores Status Codes
+ * @{
+ */
+/** Unresolved (unknown) semaphore error. */
+#define VERR_SEM_ERROR (-350)
+/** Too many semaphores. */
+#define VERR_TOO_MANY_SEMAPHORES (-351)
+/** Exclusive semaphore is owned by another process. */
+#define VERR_EXCL_SEM_ALREADY_OWNED (-352)
+/** The semaphore is set and cannot be closed. */
+#define VERR_SEM_IS_SET (-353)
+/** The semaphore cannot be set again. */
+#define VERR_TOO_MANY_SEM_REQUESTS (-354)
+/** Attempt to release mutex not owned by caller. */
+#define VERR_NOT_OWNER (-355)
+/** The semaphore has been opened too many times. */
+#define VERR_TOO_MANY_OPENS (-356)
+/** The maximum posts for the event semaphore has been reached. */
+#define VERR_TOO_MANY_POSTS (-357)
+/** The event semaphore has already been posted. */
+#define VERR_ALREADY_POSTED (-358)
+/** The event semaphore has already been reset. */
+#define VERR_ALREADY_RESET (-359)
+/** The semaphore is in use. */
+#define VERR_SEM_BUSY (-360)
+/** The previous ownership of this semaphore has ended. */
+#define VERR_SEM_OWNER_DIED (-361)
+/** Failed to open semaphore by name - not found. */
+#define VERR_SEM_NOT_FOUND (-362)
+/** Semaphore destroyed while waiting. */
+#define VERR_SEM_DESTROYED (-363)
+/** Nested ownership requests are not permitted for this semaphore type. */
+#define VERR_SEM_NESTED (-364)
+/** The release call only release a semaphore nesting, i.e. the caller is still
+ * holding the semaphore. */
+#define VINF_SEM_NESTED (364)
+/** Deadlock detected. */
+#define VERR_DEADLOCK (-365)
+/** Ping-Pong listen or speak out of turn error. */
+#define VERR_SEM_OUT_OF_TURN (-366)
+/** Tried to take a semaphore in a bad context. */
+#define VERR_SEM_BAD_CONTEXT (-367)
+/** Don't spin for the semaphore, but it is safe to try grab it. */
+#define VINF_SEM_BAD_CONTEXT (367)
+/** Wrong locking order detected. */
+#define VERR_SEM_LV_WRONG_ORDER (-368)
+/** Wrong release order detected. */
+#define VERR_SEM_LV_WRONG_RELEASE_ORDER (-369)
+/** Attempt to recursively enter a non-recurisve lock. */
+#define VERR_SEM_LV_NESTED (-370)
+/** Invalid parameters passed to the lock validator. */
+#define VERR_SEM_LV_INVALID_PARAMETER (-371)
+/** The lock validator detected a deadlock. */
+#define VERR_SEM_LV_DEADLOCK (-372)
+/** The lock validator detected an existing deadlock.
+ * The deadlock was not caused by the current operation, but existed already. */
+#define VERR_SEM_LV_EXISTING_DEADLOCK (-373)
+/** Not the lock owner according our records. */
+#define VERR_SEM_LV_NOT_OWNER (-374)
+/** An illegal lock upgrade was attempted. */
+#define VERR_SEM_LV_ILLEGAL_UPGRADE (-375)
+/** The thread is not a valid signaller of the event. */
+#define VERR_SEM_LV_NOT_SIGNALLER (-376)
+/** Internal error in the lock validator or related components. */
+#define VERR_SEM_LV_INTERNAL_ERROR (-377)
+/** @} */
+
+
+/** @name Generic Network I/O Status Codes
+ * @{
+ */
+/** Unresolved (unknown) network error. */
+#define VERR_NET_IO_ERROR (-400)
+/** The network is busy or is out of resources. */
+#define VERR_NET_OUT_OF_RESOURCES (-401)
+/** Net host name not found. */
+#define VERR_NET_HOST_NOT_FOUND (-402)
+/** Network path not found. */
+#define VERR_NET_PATH_NOT_FOUND (-403)
+/** General network printing error. */
+#define VERR_NET_PRINT_ERROR (-404)
+/** The machine is not on the network. */
+#define VERR_NET_NO_NETWORK (-405)
+/** Name is not unique on the network. */
+#define VERR_NET_NOT_UNIQUE_NAME (-406)
+
+/* These are BSD networking error codes - numbers correspond, don't mess! */
+/** Operation in progress. */
+#define VERR_NET_IN_PROGRESS (-436)
+/** Operation already in progress. */
+#define VERR_NET_ALREADY_IN_PROGRESS (-437)
+/** Attempted socket operation with a non-socket handle.
+ * (This includes closed handles.) */
+#define VERR_NET_NOT_SOCKET (-438)
+/** Destination address required. */
+#define VERR_NET_DEST_ADDRESS_REQUIRED (-439)
+/** Message too long. */
+#define VERR_NET_MSG_SIZE (-440)
+/** Protocol wrong type for socket. */
+#define VERR_NET_PROTOCOL_TYPE (-441)
+/** Protocol not available. */
+#define VERR_NET_PROTOCOL_NOT_AVAILABLE (-442)
+/** Protocol not supported. */
+#define VERR_NET_PROTOCOL_NOT_SUPPORTED (-443)
+/** Socket type not supported. */
+#define VERR_NET_SOCKET_TYPE_NOT_SUPPORTED (-444)
+/** Operation not supported. */
+#define VERR_NET_OPERATION_NOT_SUPPORTED (-445)
+/** Protocol family not supported. */
+#define VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED (-446)
+/** Address family not supported by protocol family. */
+#define VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED (-447)
+/** Address already in use. */
+#define VERR_NET_ADDRESS_IN_USE (-448)
+/** Can't assign requested address. */
+#define VERR_NET_ADDRESS_NOT_AVAILABLE (-449)
+/** Network is down. */
+#define VERR_NET_DOWN (-450)
+/** Network is unreachable. */
+#define VERR_NET_UNREACHABLE (-451)
+/** Network dropped connection on reset. */
+#define VERR_NET_CONNECTION_RESET (-452)
+/** Software caused connection abort. */
+#define VERR_NET_CONNECTION_ABORTED (-453)
+/** Connection reset by peer. */
+#define VERR_NET_CONNECTION_RESET_BY_PEER (-454)
+/** No buffer space available. */
+#define VERR_NET_NO_BUFFER_SPACE (-455)
+/** Socket is already connected. */
+#define VERR_NET_ALREADY_CONNECTED (-456)
+/** Socket is not connected. */
+#define VERR_NET_NOT_CONNECTED (-457)
+/** Can't send after socket shutdown. */
+#define VERR_NET_SHUTDOWN (-458)
+/** Too many references: can't splice. */
+#define VERR_NET_TOO_MANY_REFERENCES (-459)
+/** Too many references: can't splice. */
+#define VERR_NET_CONNECTION_TIMED_OUT (-460)
+/** Connection refused. */
+#define VERR_NET_CONNECTION_REFUSED (-461)
+/* ELOOP is not net. */
+/* ENAMETOOLONG is not net. */
+/** Host is down. */
+#define VERR_NET_HOST_DOWN (-464)
+/** No route to host. */
+#define VERR_NET_HOST_UNREACHABLE (-465)
+/** Protocol error. */
+#define VERR_NET_PROTOCOL_ERROR (-466)
+/** Incomplete packet was submitted by guest. */
+#define VERR_NET_INCOMPLETE_TX_PACKET (-467)
+/** @} */
+
+
+/** @name TCP Status Codes
+ * @{
+ */
+/** Stop the TCP server. */
+#define VERR_TCP_SERVER_STOP (-500)
+/** The server was stopped. */
+#define VINF_TCP_SERVER_STOP 500
+/** The TCP server was shut down using RTTcpServerShutdown. */
+#define VERR_TCP_SERVER_SHUTDOWN (-501)
+/** The TCP server was destroyed. */
+#define VERR_TCP_SERVER_DESTROYED (-502)
+/** The TCP server has no client associated with it. */
+#define VINF_TCP_SERVER_NO_CLIENT 503
+/** @} */
+
+
+/** @name UDP Status Codes
+ * @{
+ */
+/** Stop the UDP server. */
+#define VERR_UDP_SERVER_STOP (-520)
+/** The server was stopped. */
+#define VINF_UDP_SERVER_STOP 520
+/** The UDP server was shut down using RTUdpServerShutdown. */
+#define VERR_UDP_SERVER_SHUTDOWN (-521)
+/** The UDP server was destroyed. */
+#define VERR_UDP_SERVER_DESTROYED (-522)
+/** The UDP server has no client associated with it. */
+#define VINF_UDP_SERVER_NO_CLIENT 523
+/** @} */
+
+
+/** @name L4 Specific Status Codes
+ * @{
+ */
+/** Invalid offset in an L4 dataspace */
+#define VERR_L4_INVALID_DS_OFFSET (-550)
+/** IPC error */
+#define VERR_IPC (-551)
+/** Item already used */
+#define VERR_RESOURCE_IN_USE (-552)
+/** Source/destination not found */
+#define VERR_IPC_PROCESS_NOT_FOUND (-553)
+/** Receive timeout */
+#define VERR_IPC_RECEIVE_TIMEOUT (-554)
+/** Send timeout */
+#define VERR_IPC_SEND_TIMEOUT (-555)
+/** Receive cancelled */
+#define VERR_IPC_RECEIVE_CANCELLED (-556)
+/** Send cancelled */
+#define VERR_IPC_SEND_CANCELLED (-557)
+/** Receive aborted */
+#define VERR_IPC_RECEIVE_ABORTED (-558)
+/** Send aborted */
+#define VERR_IPC_SEND_ABORTED (-559)
+/** Couldn't map pages during receive */
+#define VERR_IPC_RECEIVE_MAP_FAILED (-560)
+/** Couldn't map pages during send */
+#define VERR_IPC_SEND_MAP_FAILED (-561)
+/** Send pagefault timeout in receive */
+#define VERR_IPC_RECEIVE_SEND_PF_TIMEOUT (-562)
+/** Send pagefault timeout in send */
+#define VERR_IPC_SEND_SEND_PF_TIMEOUT (-563)
+/** (One) receive buffer was too small, or too few buffers */
+#define VINF_IPC_RECEIVE_MSG_CUT 564
+/** (One) send buffer was too small, or too few buffers */
+#define VINF_IPC_SEND_MSG_CUT 565
+/** Dataspace manager server not found */
+#define VERR_L4_DS_MANAGER_NOT_FOUND (-566)
+/** @} */
+
+
+/** @name Loader Status Codes.
+ * @{
+ */
+/** Invalid executable signature. */
+#define VERR_INVALID_EXE_SIGNATURE (-600)
+/** The iprt loader recognized a ELF image, but doesn't support loading it. */
+#define VERR_ELF_EXE_NOT_SUPPORTED (-601)
+/** The iprt loader recognized a PE image, but doesn't support loading it. */
+#define VERR_PE_EXE_NOT_SUPPORTED (-602)
+/** The iprt loader recognized a LX image, but doesn't support loading it. */
+#define VERR_LX_EXE_NOT_SUPPORTED (-603)
+/** The iprt loader recognized a LE image, but doesn't support loading it. */
+#define VERR_LE_EXE_NOT_SUPPORTED (-604)
+/** The iprt loader recognized a NE image, but doesn't support loading it. */
+#define VERR_NE_EXE_NOT_SUPPORTED (-605)
+/** The iprt loader recognized a MZ image, but doesn't support loading it. */
+#define VERR_MZ_EXE_NOT_SUPPORTED (-606)
+/** The iprt loader recognized an a.out image, but doesn't support loading it. */
+#define VERR_AOUT_EXE_NOT_SUPPORTED (-607)
+/** Bad executable. */
+#define VERR_BAD_EXE_FORMAT (-608)
+/** Symbol (export) not found. */
+#define VERR_SYMBOL_NOT_FOUND (-609)
+/** Module not found. */
+#define VERR_MODULE_NOT_FOUND (-610)
+/** The loader resolved an external symbol to an address to big for the image format. */
+#define VERR_SYMBOL_VALUE_TOO_BIG (-611)
+/** The image is too big. */
+#define VERR_IMAGE_TOO_BIG (-612)
+/** The image base address is to high for this image type. */
+#define VERR_IMAGE_BASE_TOO_HIGH (-614)
+/** Mismatching architecture. */
+#define VERR_LDR_ARCH_MISMATCH (-615)
+/** Mismatch between IPRT and native loader. */
+#define VERR_LDR_MISMATCH_NATIVE (-616)
+/** Failed to resolve an imported (external) symbol. */
+#define VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND (-617)
+/** Generic loader failure. */
+#define VERR_LDR_GENERAL_FAILURE (-618)
+/** Code signing error. */
+#define VERR_LDR_IMAGE_HASH (-619)
+/** The PE loader encountered delayed imports, a feature which hasn't been implemented yet. */
+#define VERR_LDRPE_DELAY_IMPORT (-620)
+/** The PE loader encountered a malformed certificate. */
+#define VERR_LDRPE_CERT_MALFORMED (-621)
+/** The PE loader encountered a certificate with an unsupported type or structure revision. */
+#define VERR_LDRPE_CERT_UNSUPPORTED (-622)
+/** The PE loader doesn't know how to deal with the global pointer data directory entry yet. */
+#define VERR_LDRPE_GLOBALPTR (-623)
+/** The PE loader doesn't support the TLS data directory yet. */
+#define VERR_LDRPE_TLS (-624)
+/** The PE loader doesn't grok the COM descriptor data directory entry. */
+#define VERR_LDRPE_COM_DESCRIPTOR (-625)
+/** The PE loader encountered an unknown load config directory/header size. */
+#define VERR_LDRPE_LOAD_CONFIG_SIZE (-626)
+/** The PE loader encountered a lock prefix table, a feature which hasn't been implemented yet. */
+#define VERR_LDRPE_LOCK_PREFIX_TABLE (-627)
+/** The ELF loader doesn't handle foreign endianness. */
+#define VERR_LDRELF_ODD_ENDIAN (-630)
+/** The ELF image is 'dynamic', the ELF loader can only deal with 'relocatable' images at present. */
+#define VERR_LDRELF_DYN (-631)
+/** The ELF image is 'executable', the ELF loader can only deal with 'relocatable' images at present. */
+#define VERR_LDRELF_EXEC (-632)
+/** The ELF image was created for an unsupported target machine type. */
+#define VERR_LDRELF_MACHINE (-633)
+/** The ELF version is not supported. */
+#define VERR_LDRELF_VERSION (-634)
+/** The ELF loader cannot handle multiple SYMTAB sections. */
+#define VERR_LDRELF_MULTIPLE_SYMTABS (-635)
+/** The ELF loader encountered a relocation type which is not implemented. */
+#define VERR_LDRELF_RELOCATION_NOT_SUPPORTED (-636)
+/** The ELF loader encountered a bad symbol index. */
+#define VERR_LDRELF_INVALID_SYMBOL_INDEX (-637)
+/** The ELF loader encountered an invalid symbol name offset. */
+#define VERR_LDRELF_INVALID_SYMBOL_NAME_OFFSET (-638)
+/** The ELF loader encountered an invalid relocation offset. */
+#define VERR_LDRELF_INVALID_RELOCATION_OFFSET (-639)
+/** The ELF loader didn't find the symbol/string table for the image. */
+#define VERR_LDRELF_NO_SYMBOL_OR_NO_STRING_TABS (-640)
+/** Invalid link address. */
+#define VERR_LDR_INVALID_LINK_ADDRESS (-647)
+/** Invalid image relative virtual address. */
+#define VERR_LDR_INVALID_RVA (-648)
+/** Invalid segment:offset address. */
+#define VERR_LDR_INVALID_SEG_OFFSET (-649)
+/** @}*/
+
+/** @name Debug Info Reader Status Codes.
+ * @{
+ */
+/** The module contains no line number information. */
+#define VERR_DBG_NO_LINE_NUMBERS (-650)
+/** The module contains no symbol information. */
+#define VERR_DBG_NO_SYMBOLS (-651)
+/** The specified segment:offset address was invalid. Typically an attempt at
+ * addressing outside the segment boundary. */
+#define VERR_DBG_INVALID_ADDRESS (-652)
+/** Invalid segment index. */
+#define VERR_DBG_INVALID_SEGMENT_INDEX (-653)
+/** Invalid segment offset. */
+#define VERR_DBG_INVALID_SEGMENT_OFFSET (-654)
+/** Invalid image relative virtual address. */
+#define VERR_DBG_INVALID_RVA (-655)
+/** Invalid image relative virtual address. */
+#define VERR_DBG_SPECIAL_SEGMENT (-656)
+/** Address conflict within a module/segment.
+ * Attempted to add a segment, symbol or line number that fully or partially
+ * overlaps with an existing one. */
+#define VERR_DBG_ADDRESS_CONFLICT (-657)
+/** Duplicate symbol within the module.
+ * Attempted to add a symbol which name already exists within the module. */
+#define VERR_DBG_DUPLICATE_SYMBOL (-658)
+/** The segment index specified when adding a new segment is already in use. */
+#define VERR_DBG_SEGMENT_INDEX_CONFLICT (-659)
+/** No line number was found for the specified address/ordinal/whatever. */
+#define VERR_DBG_LINE_NOT_FOUND (-660)
+/** The length of the symbol name is out of range.
+ * This means it is an empty string or that it's greater or equal to
+ * RTDBG_SYMBOL_NAME_LENGTH. */
+#define VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE (-661)
+/** The length of the file name is out of range.
+ * This means it is an empty string or that it's greater or equal to
+ * RTDBG_FILE_NAME_LENGTH. */
+#define VERR_DBG_FILE_NAME_OUT_OF_RANGE (-662)
+/** The length of the segment name is out of range.
+ * This means it is an empty string or that it is greater or equal to
+ * RTDBG_SEGMENT_NAME_LENGTH. */
+#define VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE (-663)
+/** The specified address range wraps around. */
+#define VERR_DBG_ADDRESS_WRAP (-664)
+/** The file is not a valid NM map file. */
+#define VERR_DBG_NOT_NM_MAP_FILE (-665)
+/** The file is not a valid /proc/kallsyms file. */
+#define VERR_DBG_NOT_LINUX_KALLSYMS (-666)
+/** No debug module interpreter matching the debug info. */
+#define VERR_DBG_NO_MATCHING_INTERPRETER (-667)
+/** Bad DWARF line number header. */
+#define VERR_DWARF_BAD_LINE_NUMBER_HEADER (-668)
+/** Unexpected end of DWARF unit. */
+#define VERR_DWARF_UNEXPECTED_END (-669)
+/** DWARF LEB value overflows the decoder type. */
+#define VERR_DWARF_LEB_OVERFLOW (-670)
+/** Bad DWARF extended line number opcode. */
+#define VERR_DWARF_BAD_LNE (-671)
+/** Bad DWARF string. */
+#define VERR_DWARF_BAD_STRING (-672)
+/** Bad DWARF position. */
+#define VERR_DWARF_BAD_POS (-673)
+/** Bad DWARF info. */
+#define VERR_DWARF_BAD_INFO (-674)
+/** Bad DWARF abbreviation data. */
+#define VERR_DWARF_BAD_ABBREV (-675)
+/** A DWARF abbreviation was not found. */
+#define VERR_DWARF_ABBREV_NOT_FOUND (-676)
+/** Encountered an unknown attribute form. */
+#define VERR_DWARF_UNKNOWN_FORM (-677)
+/** Encountered an unexpected attribute form. */
+#define VERR_DWARF_UNEXPECTED_FORM (-678)
+/** @} */
+
+/** @name Request Packet Status Codes.
+ * @{
+ */
+/** Invalid RT request type.
+ * For the RTReqAlloc() 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_RT_REQUEST_INVALID_TYPE (-700)
+/** Invalid RT 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_RT_REQUEST_STATE (-701)
+/** Invalid RT request packet.
+ * One or more of the RT controlled packet members didn't contain the correct
+ * values. Some thing's broken. */
+#define VERR_RT_REQUEST_INVALID_PACKAGE (-702)
+/** 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_RT_REQUEST_STATUS_STILL_PENDING (-703)
+/** The request has been freed, don't read the status now.
+ * Someone is reading the iStatus field of a freed request packet. */
+#define VERR_RT_REQUEST_STATUS_FREED (-704)
+/** @} */
+
+/** @name Environment Status Code
+ * @{
+ */
+/** The specified environment variable was not found. (RTEnvGetEx) */
+#define VERR_ENV_VAR_NOT_FOUND (-750)
+/** The specified environment variable was not found. (RTEnvUnsetEx) */
+#define VINF_ENV_VAR_NOT_FOUND (750)
+/** Unable to translate all the variables in the default environment due to
+ * codeset issues (LANG / LC_ALL / LC_CTYPE). */
+#define VWRN_ENV_NOT_FULLY_TRANSLATED (751)
+/** @} */
+
+/** @name Multiprocessor Status Codes.
+ * @{
+ */
+/** The specified cpu is offline. */
+#define VERR_CPU_OFFLINE (-800)
+/** The specified cpu was not found. */
+#define VERR_CPU_NOT_FOUND (-801)
+/** @} */
+
+/** @name RTGetOpt status codes
+ * @{ */
+/** RTGetOpt: Command line option not recognized. */
+#define VERR_GETOPT_UNKNOWN_OPTION (-825)
+/** RTGetOpt: Command line option needs argument. */
+#define VERR_GETOPT_REQUIRED_ARGUMENT_MISSING (-826)
+/** RTGetOpt: Command line option has argument with bad format. */
+#define VERR_GETOPT_INVALID_ARGUMENT_FORMAT (-827)
+/** RTGetOpt: Not an option. */
+#define VINF_GETOPT_NOT_OPTION 828
+/** RTGetOpt: Command line option needs an index. */
+#define VERR_GETOPT_INDEX_MISSING (-829)
+/** @} */
+
+/** @name RTCache status codes
+ * @{ */
+/** RTCache: cache is full. */
+#define VERR_CACHE_FULL (-850)
+/** RTCache: cache is empty. */
+#define VERR_CACHE_EMPTY (-851)
+/** @} */
+
+/** @name RTMemCache status codes
+ * @{ */
+/** Reached the max cache size. */
+#define VERR_MEM_CACHE_MAX_SIZE (-855)
+/** @} */
+
+/** @name RTS3 status codes
+ * @{ */
+/** Access denied error. */
+#define VERR_S3_ACCESS_DENIED (-875)
+/** The bucket/key wasn't found. */
+#define VERR_S3_NOT_FOUND (-876)
+/** Bucket already exists. */
+#define VERR_S3_BUCKET_ALREADY_EXISTS (-877)
+/** Can't delete bucket with keys. */
+#define VERR_S3_BUCKET_NOT_EMPTY (-878)
+/** The current operation was canceled. */
+#define VERR_S3_CANCELED (-879)
+/** @} */
+
+/** @name RTManifest status codes
+ * @{ */
+/** A digest type used in the manifest file isn't supported. */
+#define VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE (-900)
+/** An entry in the manifest file couldn't be interpreted correctly. */
+#define VERR_MANIFEST_WRONG_FILE_FORMAT (-901)
+/** A digest doesn't match the corresponding file. */
+#define VERR_MANIFEST_DIGEST_MISMATCH (-902)
+/** The file list doesn't match to the content of the manifest file. */
+#define VERR_MANIFEST_FILE_MISMATCH (-903)
+/** The specified attribute (name) was not found in the manifest. */
+#define VERR_MANIFEST_ATTR_NOT_FOUND (-904)
+/** The attribute type did not match. */
+#define VERR_MANIFEST_ATTR_TYPE_MISMATCH (-905)
+/** No attribute of the specified types was found. */
+#define VERR_MANIFEST_ATTR_TYPE_NOT_FOUND (-906)
+/** @} */
+
+/** @name RTTar status codes
+ * @{ */
+/** The checksum of a tar header record doesn't match. */
+#define VERR_TAR_CHKSUM_MISMATCH (-925)
+/** The tar end of file record was read. */
+#define VERR_TAR_END_OF_FILE (-926)
+/** The tar file ended unexpectedly. */
+#define VERR_TAR_UNEXPECTED_EOS (-927)
+/** The tar termination records was encountered without reaching the end of
+ * the input stream. */
+#define VERR_TAR_EOS_MORE_INPUT (-928)
+/** A number tar header field was malformed. */
+#define VERR_TAR_BAD_NUM_FIELD (-929)
+/** A numeric tar header field was not terminated correctly. */
+#define VERR_TAR_BAD_NUM_FIELD_TERM (-930)
+/** A number tar header field was encoded using base-256 which this
+ * tar implementation currently does not support. */
+#define VERR_TAR_BASE_256_NOT_SUPPORTED (-931)
+/** A number tar header field yielded a value too large for the internal
+ * variable of the tar interpreter. */
+#define VERR_TAR_NUM_VALUE_TOO_LARGE (-932)
+/** The combined minor and major device number type is too small to hold the
+ * value stored in the tar header. */
+#define VERR_TAR_DEV_VALUE_TOO_LARGE (-933)
+/** The mode field in a tar header is bad. */
+#define VERR_TAR_BAD_MODE_FIELD (-934)
+/** The mode field should not include the type. */
+#define VERR_TAR_MODE_WITH_TYPE (-935)
+/** The size field should be zero for links and symlinks. */
+#define VERR_TAR_SIZE_NOT_ZERO (-936)
+/** Encountered an unknown type flag. */
+#define VERR_TAR_UNKNOWN_TYPE_FLAG (-937)
+/** The tar header is all zeros. */
+#define VERR_TAR_ZERO_HEADER (-938)
+/** Not a uniform standard tape v0.0 archive header. */
+#define VERR_TAR_NOT_USTAR_V00 (-939)
+/** The name is empty. */
+#define VERR_TAR_EMPTY_NAME (-940)
+/** A non-directory entry has a name ending with a slash. */
+#define VERR_TAR_NON_DIR_ENDS_WITH_SLASH (-941)
+/** Encountered an unsupported portable archive exchange (pax) header. */
+#define VERR_TAR_UNSUPPORTED_PAX_TYPE (-942)
+/** Encountered an unsupported Solaris Tar extension. */
+#define VERR_TAR_UNSUPPORTED_SOLARIS_HDR_TYPE (-943)
+/** Encountered an unsupported GNU Tar extension. */
+#define VERR_TAR_UNSUPPORTED_GNU_HDR_TYPE (-944)
+/** Malformed checksum field in the tar header. */
+#define VERR_TAR_BAD_CHKSUM_FIELD (-945)
+/** Malformed checksum field in the tar header. */
+#define VERR_TAR_MALFORMED_GNU_LONGXXXX (-946)
+/** Too long name or link string. */
+#define VERR_TAR_NAME_TOO_LONG (-947)
+/** @} */
+
+/** @name RTPoll status codes
+ * @{ */
+/** The handle is not pollable. */
+#define VERR_POLL_HANDLE_NOT_POLLABLE (-950)
+/** The handle ID is already present in the poll set. */
+#define VERR_POLL_HANDLE_ID_EXISTS (-951)
+/** The handle ID was not found in the set. */
+#define VERR_POLL_HANDLE_ID_NOT_FOUND (-952)
+/** The poll set is full. */
+#define VERR_POLL_SET_IS_FULL (-953)
+/** @} */
+
+/** @name RTZip status codes
+ * @{ */
+/** Generic zip error. */
+#define VERR_ZIP_ERROR (-22000)
+/** The compressed data was corrupted. */
+#define VERR_ZIP_CORRUPTED (-22001)
+/** Ran out of memory while compressing or uncompressing. */
+#define VERR_ZIP_NO_MEMORY (-22002)
+/** The compression format version is unsupported. */
+#define VERR_ZIP_UNSUPPORTED_VERSION (-22003)
+/** The compression method is unsupported. */
+#define VERR_ZIP_UNSUPPORTED_METHOD (-22004)
+/** The compressed data started with a bad header. */
+#define VERR_ZIP_BAD_HEADER (-22005)
+/** @} */
+
+/** @name RTVfs status codes
+ * @{ */
+/** The VFS chain specification does not have a valid prefix. */
+#define VERR_VFS_CHAIN_NO_PREFIX (-22100)
+/** The VFS chain specification is empty. */
+#define VERR_VFS_CHAIN_EMPTY (-22101)
+/** Expected an element. */
+#define VERR_VFS_CHAIN_EXPECTED_ELEMENT (-22102)
+/** The VFS object type is not known. */
+#define VERR_VFS_CHAIN_UNKNOWN_TYPE (-22103)
+/** Expected a left paranthese. */
+#define VERR_VFS_CHAIN_EXPECTED_LEFT_PARENTHESES (-22104)
+/** Expected a right paranthese. */
+#define VERR_VFS_CHAIN_EXPECTED_RIGHT_PARENTHESES (-22105)
+/** Expected a provider name. */
+#define VERR_VFS_CHAIN_EXPECTED_PROVIDER_NAME (-22106)
+/** Expected an action (> or |). */
+#define VERR_VFS_CHAIN_EXPECTED_ACTION (-22107)
+/** Only one action element is currently supported. */
+#define VERR_VFS_CHAIN_MULTIPLE_ACTIONS (-22108)
+/** Expected to find a driving action (>), but there is none. */
+#define VERR_VFS_CHAIN_NO_ACTION (-22109)
+/** Expected pipe action. */
+#define VERR_VFS_CHAIN_EXPECTED_PIPE (-22110)
+/** Unexpected action type. */
+#define VERR_VFS_CHAIN_UNEXPECTED_ACTION_TYPE (-22111)
+/** @} */
+
+/** @name RTDvm status codes
+ * @{ */
+/** The volume map doesn't contain any valid volume. */
+#define VERR_DVM_MAP_EMPTY (-22200)
+/** There is no volume behind the current one. */
+#define VERR_DVM_MAP_NO_VOLUME (-22201)
+/** @} */
+
+/** @name Logger status codes
+ * @{ */
+/** The internal logger revision did not match. */
+#define VERR_LOG_REVISION_MISMATCH (-22300)
+/** @} */
+
+/* see above, 22400..22499 is used for misc codes! */
+
+/** @name Logger status codes
+ * @{ */
+/** Power off is not supported by the hardware or the OS. */
+#define VERR_SYS_CANNOT_POWER_OFF (-22500)
+/** The halt action was requested, but the OS may actually power
+ * off the machine. */
+#define VINF_SYS_MAY_POWER_OFF (22501)
+/** Shutdown failed. */
+#define VERR_SYS_SHUTDOWN_FAILED (-22502)
+/** @} */
+
+/** @name Filesystem status codes
+ * @{ */
+/** Filesystem can't be opened because it is corrupt. */
+#define VERR_FILESYSTEM_CORRUPT (-22600)
+/** @} */
+
+
+/* SED-END */
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/err.mac b/include/iprt/err.mac
new file mode 100644
index 00000000..00e330cc
--- /dev/null
+++ b/include/iprt/err.mac
@@ -0,0 +1,455 @@
+%define VINF_SUCCESS 0
+%define VERR_GENERAL_FAILURE (-1)
+%define VERR_INVALID_PARAMETER (-2)
+%define VWRN_INVALID_PARAMETER 2
+%define VERR_INVALID_MAGIC (-3)
+%define VWRN_INVALID_MAGIC 3
+%define VERR_INVALID_HANDLE (-4)
+%define VWRN_INVALID_HANDLE 4
+%define VERR_LOCK_FAILED (-5)
+%define VERR_INVALID_POINTER (-6)
+%define VERR_IDT_FAILED (-7)
+%define VERR_NO_MEMORY (-8)
+%define VERR_ALREADY_LOADED (-9)
+%define VERR_PERMISSION_DENIED (-10)
+%define VINF_PERMISSION_DENIED 10
+%define VERR_VERSION_MISMATCH (-11)
+%define VERR_NOT_IMPLEMENTED (-12)
+%define VERR_NOT_EQUAL (-18)
+%define VERR_NOT_SYMLINK (-19)
+%define VERR_NO_TMP_MEMORY (-20)
+%define VERR_INVALID_FMODE (-21)
+%define VERR_WRONG_ORDER (-22)
+%define VERR_NO_TLS_FOR_SELF (-23)
+%define VERR_FAILED_TO_SET_SELF_TLS (-24)
+%define VERR_NO_CONT_MEMORY (-26)
+%define VERR_NO_PAGE_MEMORY (-27)
+%define VINF_ALREADY_INITIALIZED 28
+%define VERR_THREAD_IS_DEAD (-29)
+%define VERR_THREAD_NOT_WAITABLE (-30)
+%define VERR_PAGE_TABLE_NOT_PRESENT (-31)
+%define VERR_INVALID_CONTEXT (-32)
+%define VERR_TIMER_BUSY (-33)
+%define VERR_ADDRESS_CONFLICT (-34)
+%define VERR_UNRESOLVED_ERROR (-35)
+%define VERR_INVALID_FUNCTION (-36)
+%define VERR_NOT_SUPPORTED (-37)
+%define VINF_NOT_SUPPORTED 37
+%define VERR_ACCESS_DENIED (-38)
+%define VERR_INTERRUPTED (-39)
+%define VINF_INTERRUPTED 39
+%define VERR_TIMEOUT (-40)
+%define VINF_TIMEOUT 40
+%define VERR_BUFFER_OVERFLOW (-41)
+%define VINF_BUFFER_OVERFLOW 41
+%define VERR_TOO_MUCH_DATA (-42)
+%define VERR_MAX_THRDS_REACHED (-43)
+%define VERR_MAX_PROCS_REACHED (-44)
+%define VERR_SIGNAL_REFUSED (-45)
+%define VERR_SIGNAL_PENDING (-46)
+%define VERR_SIGNAL_INVALID (-47)
+%define VERR_STATE_CHANGED (-48)
+%define VWRN_STATE_CHANGED 48
+%define VERR_INVALID_UUID_FORMAT (-49)
+%define VERR_PROCESS_NOT_FOUND (-50)
+%define VERR_PROCESS_RUNNING (-51)
+%define VERR_TRY_AGAIN (-52)
+%define VINF_TRY_AGAIN 52
+%define VERR_PARSE_ERROR (-53)
+%define VERR_OUT_OF_RANGE (-54)
+%define VERR_NUMBER_TOO_BIG (-55)
+%define VWRN_NUMBER_TOO_BIG 55
+%define VERR_NO_DIGITS (-56)
+%define VWRN_NO_DIGITS 56
+%define VERR_NEGATIVE_UNSIGNED (-57)
+%define VWRN_NEGATIVE_UNSIGNED 57
+%define VERR_NO_TRANSLATION (-58)
+%define VWRN_NO_TRANSLATION 58
+%define VERR_CODE_POINT_ENDIAN_INDICATOR (-59)
+%define VERR_CODE_POINT_SURROGATE (-60)
+%define VERR_INVALID_UTF8_ENCODING (-61)
+%define VERR_INVALID_UTF16_ENCODING (-62)
+%define VERR_CANT_RECODE_AS_UTF16 (-63)
+%define VERR_NO_STR_MEMORY (-64)
+%define VERR_NO_UTF16_MEMORY (-65)
+%define VERR_NO_CODE_POINT_MEMORY (-66)
+%define VERR_MEMORY_BUSY (-67)
+%define VERR_TIMER_ACTIVE (-68)
+%define VERR_TIMER_SUSPENDED (-69)
+%define VERR_CANCELLED (-70)
+%define VERR_MEMOBJ_INIT_FAILED (-71)
+%define VERR_NO_LOW_MEMORY (-72)
+%define VERR_NO_PHYS_MEMORY (-73)
+%define VERR_ADDRESS_TOO_BIG (-74)
+%define VERR_MAP_FAILED (-75)
+%define VERR_TRAILING_CHARS (-76)
+%define VWRN_TRAILING_CHARS 76
+%define VERR_TRAILING_SPACES (-77)
+%define VWRN_TRAILING_SPACES 77
+%define VERR_NOT_FOUND (-78)
+%define VWRN_NOT_FOUND 78
+%define VERR_INVALID_STATE (-79)
+%define VWRN_INVALID_STATE 79
+%define VERR_OUT_OF_RESOURCES (-80)
+%define VWRN_OUT_OF_RESOURCES 80
+%define VERR_NO_MORE_HANDLES (-81)
+%define VERR_PREEMPT_DISABLED (-82)
+%define VERR_END_OF_STRING (-83)
+%define VINF_END_OF_STRING 83
+%define VERR_PAGE_COUNT_OUT_OF_RANGE (-84)
+%define VERR_OBJECT_DESTROYED (-85)
+%define VINF_OBJECT_DESTROYED 85
+%define VERR_DANGLING_OBJECTS (-86)
+%define VWRN_DANGLING_OBJECTS 86
+%define VERR_INVALID_BASE64_ENCODING (-87)
+%define VERR_CALLBACK_RETURN (-88)
+%define VINF_CALLBACK_RETURN 88
+%define VERR_AUTHENTICATION_FAILURE (-89)
+%define VERR_NOT_POWER_OF_TWO (-90)
+%define VERR_IGNORED (-91)
+%define VERR_CONCURRENT_ACCESS (-92)
+%define VERR_CALLER_NO_REFERENCE (-93)
+%define VERR_NO_CHANGE (-95)
+%define VINF_NO_CHANGE 95
+%define VERR_NO_EXEC_MEMORY (-96)
+%define VERR_UNSUPPORTED_ALIGNMENT (-97)
+%define VINF_UNSUPPORTED_ALIGNMENT 97
+%define VERR_DUPLICATE (-98)
+%define VERR_MISSING (-99)
+%define VERR_UNEXPECTED_EXCEPTION (-22400)
+%define VERR_BUFFER_UNDERFLOW (-22401)
+%define VINF_BUFFER_UNDERFLOW 22401
+%define VERR_UNEVEN_INPUT (-22402)
+%define VERR_NOT_AVAILABLE (-22403)
+%define VERR_FILE_IO_ERROR (-100)
+%define VERR_OPEN_FAILED (-101)
+%define VERR_FILE_NOT_FOUND (-102)
+%define VERR_PATH_NOT_FOUND (-103)
+%define VERR_INVALID_NAME (-104)
+%define VERR_ALREADY_EXISTS (-105)
+%define VWRN_ALREADY_EXISTS 105
+%define VERR_TOO_MANY_OPEN_FILES (-106)
+%define VERR_SEEK (-107)
+%define VERR_NEGATIVE_SEEK (-108)
+%define VERR_SEEK_ON_DEVICE (-109)
+%define VERR_EOF (-110)
+%define VINF_EOF 110
+%define VERR_READ_ERROR (-111)
+%define VERR_WRITE_ERROR (-112)
+%define VERR_WRITE_PROTECT (-113)
+%define VERR_SHARING_VIOLATION (-114)
+%define VERR_FILE_LOCK_FAILED (-115)
+%define VERR_FILE_LOCK_VIOLATION (-116)
+%define VERR_CANT_CREATE (-117)
+%define VERR_CANT_DELETE_DIRECTORY (-118)
+%define VERR_NOT_SAME_DEVICE (-119)
+%define VERR_FILENAME_TOO_LONG (-120)
+%define VERR_MEDIA_NOT_PRESENT (-121)
+%define VERR_MEDIA_NOT_RECOGNIZED (-122)
+%define VERR_FILE_NOT_LOCKED (-123)
+%define VERR_FILE_LOCK_LOST (-124)
+%define VERR_DIR_NOT_EMPTY (-125)
+%define VERR_NOT_A_DIRECTORY (-126)
+%define VERR_IS_A_DIRECTORY (-127)
+%define VERR_FILE_TOO_BIG (-128)
+%define VERR_FILE_AIO_NO_REQUEST (-129)
+%define VERR_FILE_AIO_IN_PROGRESS (-130)
+%define VERR_FILE_AIO_COMPLETED (-131)
+%define VERR_FILE_AIO_BUSY (-132)
+%define VERR_FILE_AIO_LIMIT_EXCEEDED (-133)
+%define VERR_FILE_AIO_CANCELED (-134)
+%define VERR_FILE_AIO_NOT_SUBMITTED (-135)
+%define VERR_FILE_AIO_NOT_PREPARED (-136)
+%define VERR_FILE_AIO_INSUFFICIENT_RESSOURCES (-137)
+%define VERR_RESOURCE_BUSY (-138)
+%define VERR_NOT_A_FILE (-139)
+%define VERR_IS_A_FILE (-140)
+%define VERR_UNEXPECTED_FS_OBJ_TYPE (-141)
+%define VERR_PATH_DOES_NOT_START_WITH_ROOT (-142)
+%define VERR_PATH_IS_RELATIVE (-143)
+%define VERR_PATH_IS_NOT_RELATIVE (-144)
+%define VERR_DISK_IO_ERROR (-150)
+%define VERR_INVALID_DRIVE (-151)
+%define VERR_DISK_FULL (-152)
+%define VERR_DISK_CHANGE (-153)
+%define VERR_DRIVE_LOCKED (-154)
+%define VERR_DISK_INVALID_FORMAT (-155)
+%define VERR_TOO_MANY_SYMLINKS (-156)
+%define VERR_NS_SYMLINK_SET_TIME (-157)
+%define VERR_NS_SYMLINK_CHANGE_OWNER (-158)
+%define VERR_SEARCH_ERROR (-200)
+%define VERR_NO_MORE_FILES (-201)
+%define VERR_NO_MORE_SEARCH_HANDLES (-202)
+%define VWRN_NO_DIRENT_INFO 203
+%define VERR_INTERNAL_ERROR (-225)
+%define VERR_INTERNAL_ERROR_2 (-226)
+%define VERR_INTERNAL_ERROR_3 (-227)
+%define VERR_INTERNAL_ERROR_4 (-228)
+%define VERR_INTERNAL_ERROR_5 (-229)
+%define VERR_IPE_UNEXPECTED_STATUS (-230)
+%define VERR_IPE_UNEXPECTED_INFO_STATUS (-231)
+%define VERR_IPE_UNEXPECTED_ERROR_STATUS (-232)
+%define VERR_IPE_UNINITIALIZED_STATUS (-233)
+%define VERR_IPE_NOT_REACHED_DEFAULT_CASE (-234)
+%define VERR_DEV_IO_ERROR (-250)
+%define VERR_IO_BAD_UNIT (-251)
+%define VERR_IO_NOT_READY (-252)
+%define VERR_IO_BAD_COMMAND (-253)
+%define VERR_IO_CRC (-254)
+%define VERR_IO_BAD_LENGTH (-255)
+%define VERR_IO_SECTOR_NOT_FOUND (-256)
+%define VERR_IO_GEN_FAILURE (-257)
+%define VERR_PIPE_IO_ERROR (-300)
+%define VERR_BROKEN_PIPE (-301)
+%define VERR_BAD_PIPE (-302)
+%define VERR_PIPE_BUSY (-303)
+%define VERR_NO_DATA (-304)
+%define VERR_PIPE_NOT_CONNECTED (-305)
+%define VERR_MORE_DATA (-306)
+%define VERR_PIPE_NOT_READ (-307)
+%define VERR_PIPE_NOT_WRITE (-308)
+%define VERR_SEM_ERROR (-350)
+%define VERR_TOO_MANY_SEMAPHORES (-351)
+%define VERR_EXCL_SEM_ALREADY_OWNED (-352)
+%define VERR_SEM_IS_SET (-353)
+%define VERR_TOO_MANY_SEM_REQUESTS (-354)
+%define VERR_NOT_OWNER (-355)
+%define VERR_TOO_MANY_OPENS (-356)
+%define VERR_TOO_MANY_POSTS (-357)
+%define VERR_ALREADY_POSTED (-358)
+%define VERR_ALREADY_RESET (-359)
+%define VERR_SEM_BUSY (-360)
+%define VERR_SEM_OWNER_DIED (-361)
+%define VERR_SEM_NOT_FOUND (-362)
+%define VERR_SEM_DESTROYED (-363)
+%define VERR_SEM_NESTED (-364)
+%define VINF_SEM_NESTED (364)
+%define VERR_DEADLOCK (-365)
+%define VERR_SEM_OUT_OF_TURN (-366)
+%define VERR_SEM_BAD_CONTEXT (-367)
+%define VINF_SEM_BAD_CONTEXT (367)
+%define VERR_SEM_LV_WRONG_ORDER (-368)
+%define VERR_SEM_LV_WRONG_RELEASE_ORDER (-369)
+%define VERR_SEM_LV_NESTED (-370)
+%define VERR_SEM_LV_INVALID_PARAMETER (-371)
+%define VERR_SEM_LV_DEADLOCK (-372)
+%define VERR_SEM_LV_EXISTING_DEADLOCK (-373)
+%define VERR_SEM_LV_NOT_OWNER (-374)
+%define VERR_SEM_LV_ILLEGAL_UPGRADE (-375)
+%define VERR_SEM_LV_NOT_SIGNALLER (-376)
+%define VERR_SEM_LV_INTERNAL_ERROR (-377)
+%define VERR_NET_IO_ERROR (-400)
+%define VERR_NET_OUT_OF_RESOURCES (-401)
+%define VERR_NET_HOST_NOT_FOUND (-402)
+%define VERR_NET_PATH_NOT_FOUND (-403)
+%define VERR_NET_PRINT_ERROR (-404)
+%define VERR_NET_NO_NETWORK (-405)
+%define VERR_NET_NOT_UNIQUE_NAME (-406)
+%define VERR_NET_IN_PROGRESS (-436)
+%define VERR_NET_ALREADY_IN_PROGRESS (-437)
+%define VERR_NET_NOT_SOCKET (-438)
+%define VERR_NET_DEST_ADDRESS_REQUIRED (-439)
+%define VERR_NET_MSG_SIZE (-440)
+%define VERR_NET_PROTOCOL_TYPE (-441)
+%define VERR_NET_PROTOCOL_NOT_AVAILABLE (-442)
+%define VERR_NET_PROTOCOL_NOT_SUPPORTED (-443)
+%define VERR_NET_SOCKET_TYPE_NOT_SUPPORTED (-444)
+%define VERR_NET_OPERATION_NOT_SUPPORTED (-445)
+%define VERR_NET_PROTOCOL_FAMILY_NOT_SUPPORTED (-446)
+%define VERR_NET_ADDRESS_FAMILY_NOT_SUPPORTED (-447)
+%define VERR_NET_ADDRESS_IN_USE (-448)
+%define VERR_NET_ADDRESS_NOT_AVAILABLE (-449)
+%define VERR_NET_DOWN (-450)
+%define VERR_NET_UNREACHABLE (-451)
+%define VERR_NET_CONNECTION_RESET (-452)
+%define VERR_NET_CONNECTION_ABORTED (-453)
+%define VERR_NET_CONNECTION_RESET_BY_PEER (-454)
+%define VERR_NET_NO_BUFFER_SPACE (-455)
+%define VERR_NET_ALREADY_CONNECTED (-456)
+%define VERR_NET_NOT_CONNECTED (-457)
+%define VERR_NET_SHUTDOWN (-458)
+%define VERR_NET_TOO_MANY_REFERENCES (-459)
+%define VERR_NET_CONNECTION_TIMED_OUT (-460)
+%define VERR_NET_CONNECTION_REFUSED (-461)
+%define VERR_NET_HOST_DOWN (-464)
+%define VERR_NET_HOST_UNREACHABLE (-465)
+%define VERR_NET_PROTOCOL_ERROR (-466)
+%define VERR_TCP_SERVER_STOP (-500)
+%define VINF_TCP_SERVER_STOP 500
+%define VERR_TCP_SERVER_SHUTDOWN (-501)
+%define VERR_TCP_SERVER_DESTROYED (-502)
+%define VINF_TCP_SERVER_NO_CLIENT 503
+%define VERR_UDP_SERVER_STOP (-520)
+%define VINF_UDP_SERVER_STOP 520
+%define VERR_UDP_SERVER_SHUTDOWN (-521)
+%define VERR_UDP_SERVER_DESTROYED (-522)
+%define VINF_UDP_SERVER_NO_CLIENT 523
+%define VERR_L4_INVALID_DS_OFFSET (-550)
+%define VERR_IPC (-551)
+%define VERR_RESOURCE_IN_USE (-552)
+%define VERR_IPC_PROCESS_NOT_FOUND (-553)
+%define VERR_IPC_RECEIVE_TIMEOUT (-554)
+%define VERR_IPC_SEND_TIMEOUT (-555)
+%define VERR_IPC_RECEIVE_CANCELLED (-556)
+%define VERR_IPC_SEND_CANCELLED (-557)
+%define VERR_IPC_RECEIVE_ABORTED (-558)
+%define VERR_IPC_SEND_ABORTED (-559)
+%define VERR_IPC_RECEIVE_MAP_FAILED (-560)
+%define VERR_IPC_SEND_MAP_FAILED (-561)
+%define VERR_IPC_RECEIVE_SEND_PF_TIMEOUT (-562)
+%define VERR_IPC_SEND_SEND_PF_TIMEOUT (-563)
+%define VINF_IPC_RECEIVE_MSG_CUT 564
+%define VINF_IPC_SEND_MSG_CUT 565
+%define VERR_L4_DS_MANAGER_NOT_FOUND (-566)
+%define VERR_INVALID_EXE_SIGNATURE (-600)
+%define VERR_ELF_EXE_NOT_SUPPORTED (-601)
+%define VERR_PE_EXE_NOT_SUPPORTED (-602)
+%define VERR_LX_EXE_NOT_SUPPORTED (-603)
+%define VERR_LE_EXE_NOT_SUPPORTED (-604)
+%define VERR_NE_EXE_NOT_SUPPORTED (-605)
+%define VERR_MZ_EXE_NOT_SUPPORTED (-606)
+%define VERR_AOUT_EXE_NOT_SUPPORTED (-607)
+%define VERR_BAD_EXE_FORMAT (-608)
+%define VERR_SYMBOL_NOT_FOUND (-609)
+%define VERR_MODULE_NOT_FOUND (-610)
+%define VERR_SYMBOL_VALUE_TOO_BIG (-611)
+%define VERR_IMAGE_TOO_BIG (-612)
+%define VERR_IMAGE_BASE_TOO_HIGH (-614)
+%define VERR_LDR_ARCH_MISMATCH (-615)
+%define VERR_LDR_MISMATCH_NATIVE (-616)
+%define VERR_LDR_IMPORTED_SYMBOL_NOT_FOUND (-617)
+%define VERR_LDR_GENERAL_FAILURE (-618)
+%define VERR_LDR_IMAGE_HASH (-619)
+%define VERR_LDRPE_DELAY_IMPORT (-620)
+%define VERR_LDRPE_CERT_MALFORMED (-621)
+%define VERR_LDRPE_CERT_UNSUPPORTED (-622)
+%define VERR_LDRPE_GLOBALPTR (-623)
+%define VERR_LDRPE_TLS (-624)
+%define VERR_LDRPE_COM_DESCRIPTOR (-625)
+%define VERR_LDRPE_LOAD_CONFIG_SIZE (-626)
+%define VERR_LDRPE_LOCK_PREFIX_TABLE (-627)
+%define VERR_LDRELF_ODD_ENDIAN (-630)
+%define VERR_LDRELF_DYN (-631)
+%define VERR_LDRELF_EXEC (-632)
+%define VERR_LDRELF_MACHINE (-633)
+%define VERR_LDRELF_VERSION (-634)
+%define VERR_LDRELF_MULTIPLE_SYMTABS (-635)
+%define VERR_LDRELF_RELOCATION_NOT_SUPPORTED (-636)
+%define VERR_LDRELF_INVALID_SYMBOL_INDEX (-637)
+%define VERR_LDRELF_INVALID_SYMBOL_NAME_OFFSET (-638)
+%define VERR_LDRELF_INVALID_RELOCATION_OFFSET (-639)
+%define VERR_LDRELF_NO_SYMBOL_OR_NO_STRING_TABS (-640)
+%define VERR_LDR_INVALID_LINK_ADDRESS (-647)
+%define VERR_LDR_INVALID_RVA (-648)
+%define VERR_LDR_INVALID_SEG_OFFSET (-649)
+%define VERR_DBG_NO_LINE_NUMBERS (-650)
+%define VERR_DBG_NO_SYMBOLS (-651)
+%define VERR_DBG_INVALID_ADDRESS (-652)
+%define VERR_DBG_INVALID_SEGMENT_INDEX (-653)
+%define VERR_DBG_INVALID_SEGMENT_OFFSET (-654)
+%define VERR_DBG_INVALID_RVA (-655)
+%define VERR_DBG_SPECIAL_SEGMENT (-656)
+%define VERR_DBG_ADDRESS_CONFLICT (-657)
+%define VERR_DBG_DUPLICATE_SYMBOL (-658)
+%define VERR_DBG_SEGMENT_INDEX_CONFLICT (-659)
+%define VERR_DBG_LINE_NOT_FOUND (-660)
+%define VERR_DBG_SYMBOL_NAME_OUT_OF_RANGE (-661)
+%define VERR_DBG_FILE_NAME_OUT_OF_RANGE (-662)
+%define VERR_DBG_SEGMENT_NAME_OUT_OF_RANGE (-663)
+%define VERR_DBG_ADDRESS_WRAP (-664)
+%define VERR_DBG_NOT_NM_MAP_FILE (-665)
+%define VERR_DBG_NOT_LINUX_KALLSYMS (-666)
+%define VERR_DBG_NO_MATCHING_INTERPRETER (-667)
+%define VERR_DWARF_BAD_LINE_NUMBER_HEADER (-668)
+%define VERR_DWARF_UNEXPECTED_END (-669)
+%define VERR_DWARF_LEB_OVERFLOW (-670)
+%define VERR_DWARF_BAD_LNE (-671)
+%define VERR_DWARF_BAD_STRING (-672)
+%define VERR_DWARF_BAD_POS (-673)
+%define VERR_DWARF_BAD_INFO (-674)
+%define VERR_DWARF_BAD_ABBREV (-675)
+%define VERR_DWARF_ABBREV_NOT_FOUND (-676)
+%define VERR_DWARF_UNKNOWN_FORM (-677)
+%define VERR_DWARF_UNEXPECTED_FORM (-678)
+%define VERR_RT_REQUEST_INVALID_TYPE (-700)
+%define VERR_RT_REQUEST_STATE (-701)
+%define VERR_RT_REQUEST_INVALID_PACKAGE (-702)
+%define VERR_RT_REQUEST_STATUS_STILL_PENDING (-703)
+%define VERR_RT_REQUEST_STATUS_FREED (-704)
+%define VERR_ENV_VAR_NOT_FOUND (-750)
+%define VINF_ENV_VAR_NOT_FOUND (750)
+%define VWRN_ENV_NOT_FULLY_TRANSLATED (751)
+%define VERR_CPU_OFFLINE (-800)
+%define VERR_CPU_NOT_FOUND (-801)
+%define VERR_GETOPT_UNKNOWN_OPTION (-825)
+%define VERR_GETOPT_REQUIRED_ARGUMENT_MISSING (-826)
+%define VERR_GETOPT_INVALID_ARGUMENT_FORMAT (-827)
+%define VINF_GETOPT_NOT_OPTION 828
+%define VERR_GETOPT_INDEX_MISSING (-829)
+%define VERR_CACHE_FULL (-850)
+%define VERR_CACHE_EMPTY (-851)
+%define VERR_MEM_CACHE_MAX_SIZE (-855)
+%define VERR_S3_ACCESS_DENIED (-875)
+%define VERR_S3_NOT_FOUND (-876)
+%define VERR_S3_BUCKET_ALREADY_EXISTS (-877)
+%define VERR_S3_BUCKET_NOT_EMPTY (-878)
+%define VERR_S3_CANCELED (-879)
+%define VERR_MANIFEST_UNSUPPORTED_DIGEST_TYPE (-900)
+%define VERR_MANIFEST_WRONG_FILE_FORMAT (-901)
+%define VERR_MANIFEST_DIGEST_MISMATCH (-902)
+%define VERR_MANIFEST_FILE_MISMATCH (-903)
+%define VERR_MANIFEST_ATTR_NOT_FOUND (-904)
+%define VERR_MANIFEST_ATTR_TYPE_MISMATCH (-905)
+%define VERR_MANIFEST_ATTR_TYPE_NOT_FOUND (-906)
+%define VERR_TAR_CHKSUM_MISMATCH (-925)
+%define VERR_TAR_END_OF_FILE (-926)
+%define VERR_TAR_UNEXPECTED_EOS (-927)
+%define VERR_TAR_EOS_MORE_INPUT (-928)
+%define VERR_TAR_BAD_NUM_FIELD (-929)
+%define VERR_TAR_BAD_NUM_FIELD_TERM (-930)
+%define VERR_TAR_BASE_256_NOT_SUPPORTED (-931)
+%define VERR_TAR_NUM_VALUE_TOO_LARGE (-932)
+%define VERR_TAR_DEV_VALUE_TOO_LARGE (-933)
+%define VERR_TAR_BAD_MODE_FIELD (-934)
+%define VERR_TAR_MODE_WITH_TYPE (-935)
+%define VERR_TAR_SIZE_NOT_ZERO (-936)
+%define VERR_TAR_UNKNOWN_TYPE_FLAG (-937)
+%define VERR_TAR_ZERO_HEADER (-938)
+%define VERR_TAR_NOT_USTAR_V00 (-939)
+%define VERR_TAR_EMPTY_NAME (-940)
+%define VERR_TAR_NON_DIR_ENDS_WITH_SLASH (-941)
+%define VERR_TAR_UNSUPPORTED_PAX_TYPE (-942)
+%define VERR_TAR_UNSUPPORTED_SOLARIS_HDR_TYPE (-943)
+%define VERR_TAR_UNSUPPORTED_GNU_HDR_TYPE (-944)
+%define VERR_TAR_BAD_CHKSUM_FIELD (-945)
+%define VERR_TAR_MALFORMED_GNU_LONGXXXX (-946)
+%define VERR_TAR_NAME_TOO_LONG (-947)
+%define VERR_POLL_HANDLE_NOT_POLLABLE (-950)
+%define VERR_POLL_HANDLE_ID_EXISTS (-951)
+%define VERR_POLL_HANDLE_ID_NOT_FOUND (-952)
+%define VERR_POLL_SET_IS_FULL (-953)
+%define VERR_ZIP_ERROR (-22000)
+%define VERR_ZIP_CORRUPTED (-22001)
+%define VERR_ZIP_NO_MEMORY (-22002)
+%define VERR_ZIP_UNSUPPORTED_VERSION (-22003)
+%define VERR_ZIP_UNSUPPORTED_METHOD (-22004)
+%define VERR_ZIP_BAD_HEADER (-22005)
+%define VERR_VFS_CHAIN_NO_PREFIX (-22100)
+%define VERR_VFS_CHAIN_EMPTY (-22101)
+%define VERR_VFS_CHAIN_EXPECTED_ELEMENT (-22102)
+%define VERR_VFS_CHAIN_UNKNOWN_TYPE (-22103)
+%define VERR_VFS_CHAIN_EXPECTED_LEFT_PARENTHESES (-22104)
+%define VERR_VFS_CHAIN_EXPECTED_RIGHT_PARENTHESES (-22105)
+%define VERR_VFS_CHAIN_EXPECTED_PROVIDER_NAME (-22106)
+%define VERR_VFS_CHAIN_EXPECTED_ACTION (-22107)
+%define VERR_VFS_CHAIN_MULTIPLE_ACTIONS (-22108)
+%define VERR_VFS_CHAIN_NO_ACTION (-22109)
+%define VERR_VFS_CHAIN_EXPECTED_PIPE (-22110)
+%define VERR_VFS_CHAIN_UNEXPECTED_ACTION_TYPE (-22111)
+%define VERR_DVM_MAP_EMPTY (-22200)
+%define VERR_DVM_MAP_NO_VOLUME (-22201)
+%define VERR_LOG_REVISION_MISMATCH (-22300)
+%define VERR_SYS_CANNOT_POWER_OFF (-22500)
+%define VINF_SYS_MAY_POWER_OFF (22501)
+%define VERR_SYS_SHUTDOWN_FAILED (-22502)
+%define VERR_FILESYSTEM_CORRUPT (-22600)
diff --git a/include/iprt/err.sed b/include/iprt/err.sed
new file mode 100644
index 00000000..2271331c
--- /dev/null
+++ b/include/iprt/err.sed
@@ -0,0 +1,45 @@
+## @file
+# IPRT - 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/iprt/errno.h b/include/iprt/errno.h
new file mode 100644
index 00000000..ee57065d
--- /dev/null
+++ b/include/iprt/errno.h
@@ -0,0 +1,318 @@
+/** @file
+ * IPRT - errno.h wrapper.
+ */
+
+/*
+ * 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 ___iprt_errno_h___
+#define ___iprt_errno_h___
+
+#ifndef IPRT_NO_CRT
+# if defined(RT_OS_DARWIN) && defined(KERNEL)
+# include <sys/errno.h>
+# elif defined(RT_OS_LINUX) && defined(__KERNEL__)
+# include <linux/errno.h>
+# elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+# include <sys/errno.h>
+# else
+# include <errno.h>
+# endif
+#endif
+
+
+/*
+ * Supply missing errno values according to the current RT_OS_XXX definition.
+ *
+ * Note! These supplements are for making no-CRT mode, as well as making UNIXy
+ * code that makes used of odd errno defines internally, work smoothly.
+ *
+ * When adding more error codes, always check the following errno.h sources:
+ * - RT_OS_DARWIN: http://fxr.watson.org/fxr/source/bsd/sys/errno.h?v=xnu-1699.24.8
+ * - RT_OS_FREEBSD: http://fxr.watson.org/fxr/source/sys/errno.h?v=DFBSD
+ * - RT_OS_NETBSD: http://fxr.watson.org/fxr/source/sys/errno.h?v=NETBSD
+ * - RT_OS_OPENBSD: http://fxr.watson.org/fxr/source/sys/errno.h?v=OPENBSD
+ * - RT_OS_OS2: http://svn.netlabs.org/libc/browser/trunk/libc/include/sys/errno.h
+ * - RT_OS_LINUX: http://fxr.watson.org/fxr/source/include/asm-generic/errno.h?v=linux-2.6
+ * - RT_OS_SOLARIS: http://fxr.watson.org/fxr/source/common/sys/errno.h?v=OPENSOLARIS
+ * - RT_OS_WINDOWS: tools/win.x86/vcc/v8sp1/include/errno.h
+ */
+
+#if defined(RT_OS_DARWIN) \
+ || defined(RT_OS_FREEBSD) \
+ || defined(RT_OS_NETBSD) \
+ || defined(RT_OS_OPENBSD) \
+ || defined(RT_OS_OS2)
+# define RT_ERRNO_OS_BSD
+#endif
+#ifdef RT_OS_SOLARIS
+# define RT_ERRNO_OS_SYSV_HARDCORE /* ?? */
+#endif
+
+/* The relatively similar part. */
+#ifndef EPERM
+# define EPERM (1)
+#endif
+#ifndef ENOENT
+# define ENOENT (2)
+#endif
+#ifndef ESRCH
+# define ESRCH (3)
+#endif
+#ifndef EINTR
+# define EINTR (4)
+#endif
+#ifndef EIO
+# define EIO (5)
+#endif
+#ifndef ENXIO
+# define ENXIO (6)
+#endif
+#ifndef E2BIG
+# define E2BIG (7)
+#endif
+#ifndef ENOEXEC
+# define ENOEXEC (8)
+#endif
+#ifndef EBADF
+# define EBADF (9)
+#endif
+#ifndef ECHILD
+# define ECHILD (10)
+#endif
+#ifndef EAGAIN
+# if defined(RT_ERRNO_OS_BSD)
+# define EAGAIN (35)
+# else
+# define EAGAIN (11)
+# endif
+#endif
+#ifndef EWOULDBLOCK
+# define EWOULDBLOCK EAGAIN
+#endif
+#ifndef EDEADLK
+# if defined(RT_ERRNO_OS_BSD)
+# define EDEADLK (11)
+# elif defined(RT_OS_LINUX)
+# define EDEADLK (35)
+# elif defined(RT_OS_WINDOWS)
+# define EDEADLK (36)
+# else
+# define EDEADLK (45)
+# endif
+#endif
+#ifndef EDEADLOCK
+# define EDEADLOCK EDEADLK
+#endif
+#ifndef ENOMEM
+# define ENOMEM (12)
+#endif
+#ifndef EACCES
+# define EACCES (13)
+#endif
+#ifndef EFAULT
+# define EFAULT (14)
+#endif
+#ifndef ENOTBLK
+# define ENOTBLK (15)
+#endif
+#ifndef EBUSY
+# define EBUSY (16)
+#endif
+#ifndef EEXIST
+# define EEXIST (17)
+#endif
+#ifndef EXDEV
+# define EXDEV (18)
+#endif
+#ifndef ENODEV
+# define ENODEV (19)
+#endif
+#ifndef ENOTDIR
+# define ENOTDIR (20)
+#endif
+#ifndef EISDIR
+# define EISDIR (21)
+#endif
+#ifndef EINVAL
+# define EINVAL (22)
+#endif
+#ifndef ENFILE
+# define ENFILE (23)
+#endif
+#ifndef EMFILE
+# define EMFILE (24)
+#endif
+#ifndef ENOTTY
+# define ENOTTY (25)
+#endif
+#ifndef ETXTBSY
+# define ETXTBSY (26)
+#endif
+#ifndef EFBIG
+# define EFBIG (27)
+#endif
+#ifndef ENOSPC
+# define ENOSPC (28)
+#endif
+#ifndef ESPIPE
+# define ESPIPE (29)
+#endif
+#ifndef EROFS
+# define EROFS (30)
+#endif
+#ifndef EMLINK
+# define EMLINK (31)
+#endif
+#ifndef EPIPE
+# define EPIPE (32)
+#endif
+#ifndef EDOM
+# define EDOM (33)
+#endif
+#ifndef ERANGE
+# define ERANGE (34)
+#endif
+
+/* 35 - also EAGAIN on BSD and EDEADLK on Linux. */
+#ifndef ENOMSG
+# if defined(RT_OS_DARWIN)
+# define ENOMSG (91)
+# elif defined(RT_OS_FREEBSD)
+# define ENOMSG (83)
+# elif defined(RT_OS_LINUX)
+# define ENOMSG (42)
+# else
+# define ENOMSG (35)
+# endif
+#endif
+
+/* 36 - Also EDEADLK on Windows. */
+#ifndef EIDRM
+# if defined(RT_OS_DARWIN)
+# define EIDRM (90)
+# elif defined(RT_OS_FREEBSD) || defined(RT_OS_NETBSD)
+# define EIDRM (82)
+# elif defined(RT_OS_OPENBSD)
+# define EIDRM (89)
+# elif defined(RT_OS_LINUX)
+# define EIDRM (43)
+# elif defined(RT_OS_WINDOWS)
+# define EIDRM (600)
+# else
+# define EIDRM (36)
+# endif
+#endif
+#ifndef EINPROGRESS
+# if defined(RT_ERRNO_OS_BSD)
+# define EINPROGRESS (36)
+# elif defined(RT_OS_LINUX)
+# define EINPROGRESS (115)
+# else
+# define EINPROGRESS (150)
+# endif
+#endif
+#ifndef ENAMETOOLONG
+# if defined(RT_ERRNO_OS_BSD)
+# define ENAMETOOLONG (63)
+# elif defined(RT_OS_LINUX)
+# define ENAMETOOLONG (36)
+# else
+# define ENAMETOOLONG (78)
+# endif
+#endif
+
+/* 37 */
+#ifndef ECHRNG
+# if defined(RT_ERRNO_OS_SYSV_HARDCORE)
+# define ECHRNG (37)
+# else
+# define ECHRNG (599)
+# endif
+#endif
+#ifndef ENOLCK
+# if defined(RT_ERRNO_OS_BSD)
+# define ENOLCK (77)
+# elif defined(RT_OS_LINUX)
+# define ENOLCK (37)
+# else
+# define ENOLCK (46)
+# endif
+#endif
+#ifndef EALREADY
+# if defined(RT_ERRNO_OS_BSD)
+# define EALREADY (37)
+# elif defined(RT_OS_LINUX)
+# define EALREADY (114)
+# else
+# define EALREADY (149)
+# endif
+#endif
+
+/** @todo errno constants {37..44}. */
+
+/* 45 - also EDEADLK on Solaris, EL2NSYNC on Linux. */
+#ifndef ENOTSUP
+# if defined(RT_ERRNO_OS_BSD)
+# define ENOTSUP (45)
+# elif defined(RT_OS_LINUX)
+# define ENOTSUP (95)
+# else
+# define ENOTSUP (48)
+# endif
+#endif
+#ifndef EOPNOTSUPP
+# if defined(RT_ERRNO_OS_BSD)
+# define EOPNOTSUPP ENOTSUP
+# elif defined(RT_OS_LINUX)
+# define EOPNOTSUPP ENOTSUP
+# else
+# define EOPNOTSUPP (122)
+# endif
+#endif
+
+/** @todo errno constants {46..74}. */
+
+/* 75 - note that Solaris has constant with value 75. */
+#ifndef EOVERFLOW
+# if defined(RT_OS_OPENBSD)
+# define EOVERFLOW (87)
+# elif defined(RT_ERRNO_OS_BSD)
+# define EOVERFLOW (84)
+# elif defined(RT_OS_LINUX)
+# define EOVERFLOW (75)
+# else
+# define EOVERFLOW (79)
+# endif
+#endif
+#ifndef EPROGMISMATCH
+# if defined(RT_ERRNO_OS_BSD)
+# define EPROGMISMATCH (75)
+# else
+# define EPROGMISMATCH (598)
+# endif
+#endif
+
+/** @todo errno constants {76..}. */
+
+
+#endif
diff --git a/include/iprt/file.h b/include/iprt/file.h
new file mode 100644
index 00000000..3357ab23
--- /dev/null
+++ b/include/iprt/file.h
@@ -0,0 +1,1339 @@
+/** @file
+ * IPRT - File I/O.
+ */
+
+/*
+ * 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 ___iprt_file_h
+#define ___iprt_file_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+#include <iprt/fs.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_fileio RTFile - File I/O
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Platform specific text line break.
+ * @deprecated Use text I/O streams and '\\n'. See iprt/stream.h. */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define RTFILE_LINEFEED "\r\n"
+#else
+# define RTFILE_LINEFEED "\n"
+#endif
+
+/** Platform specific native standard input "handle". */
+#ifdef RT_OS_WINDOWS
+# define RTFILE_NATIVE_STDIN ((uint32_t)-10)
+#else
+# define RTFILE_NATIVE_STDIN 0
+#endif
+
+/** Platform specific native standard out "handle". */
+#ifdef RT_OS_WINDOWS
+# define RTFILE_NATIVE_STDOUT ((uint32_t)-11)
+#else
+# define RTFILE_NATIVE_STDOUT 1
+#endif
+
+/** Platform specific native standard error "handle". */
+#ifdef RT_OS_WINDOWS
+# define RTFILE_NATIVE_STDERR ((uint32_t)-12)
+#else
+# define RTFILE_NATIVE_STDERR 2
+#endif
+
+
+/**
+ * Checks if the specified file name exists and is a regular file.
+ *
+ * Symbolic links will be resolved.
+ *
+ * @returns true if it's a regular file, false if it isn't.
+ * @param pszPath The path to the file.
+ *
+ * @sa RTDirExists, RTPathExists, RTSymlinkExists.
+ */
+RTDECL(bool) RTFileExists(const char *pszPath);
+
+/**
+ * Queries the size of a file, given the path to it.
+ *
+ * Symbolic links will be resolved.
+ *
+ * @returns IPRT status code.
+ * @param pszPath The path to the file.
+ * @param pcbFile Where to return the file size (bytes).
+ *
+ * @sa RTFileGetSize, RTPathQueryInfoEx.
+ */
+RTDECL(int) RTFileQuerySize(const char *pszPath, uint64_t *pcbFile);
+
+
+/** @name Open flags
+ * @{ */
+/** Open the file with read access. */
+#define RTFILE_O_READ UINT32_C(0x00000001)
+/** Open the file with write access. */
+#define RTFILE_O_WRITE UINT32_C(0x00000002)
+/** Open the file with read & write access. */
+#define RTFILE_O_READWRITE UINT32_C(0x00000003)
+/** The file access mask.
+ * @remarks The value 0 is invalid. */
+#define RTFILE_O_ACCESS_MASK UINT32_C(0x00000003)
+
+/** Open file in APPEND mode, so all writes to the file handle will
+ * append data at the end of the file.
+ * @remarks It is ignored if write access is not requested, that is
+ * RTFILE_O_WRITE is not set. */
+#define RTFILE_O_APPEND UINT32_C(0x00000004)
+ /* UINT32_C(0x00000008) is unused atm. */
+
+/** Sharing mode: deny none. */
+#define RTFILE_O_DENY_NONE UINT32_C(0x00000080)
+/** Sharing mode: deny read. */
+#define RTFILE_O_DENY_READ UINT32_C(0x00000010)
+/** Sharing mode: deny write. */
+#define RTFILE_O_DENY_WRITE UINT32_C(0x00000020)
+/** Sharing mode: deny read and write. */
+#define RTFILE_O_DENY_READWRITE UINT32_C(0x00000030)
+/** Sharing mode: deny all. */
+#define RTFILE_O_DENY_ALL RTFILE_O_DENY_READWRITE
+/** Sharing mode: do NOT deny delete (NT).
+ * @remarks This might not be implemented on all platforms, and will be
+ * defaulted & ignored on those.
+ */
+#define RTFILE_O_DENY_NOT_DELETE UINT32_C(0x00000040)
+/** Sharing mode mask. */
+#define RTFILE_O_DENY_MASK UINT32_C(0x000000f0)
+
+/** Action: Open an existing file (the default action). */
+#define RTFILE_O_OPEN UINT32_C(0x00000700)
+/** Action: Create a new file or open an existing one. */
+#define RTFILE_O_OPEN_CREATE UINT32_C(0x00000100)
+/** Action: Create a new a file. */
+#define RTFILE_O_CREATE UINT32_C(0x00000200)
+/** Action: Create a new file or replace an existing one. */
+#define RTFILE_O_CREATE_REPLACE UINT32_C(0x00000300)
+/** Action mask. */
+#define RTFILE_O_ACTION_MASK UINT32_C(0x00000700)
+
+/** Turns off indexing of files on Windows hosts, *CREATE* only.
+ * @remarks Window only. */
+#define RTFILE_O_NOT_CONTENT_INDEXED UINT32_C(0x00000800)
+/** Truncate the file.
+ * @remarks This will not truncate files opened for read-only.
+ * @remarks The trunction doesn't have to be atomically, so anyone else opening
+ * the file may be racing us. The caller is responsible for not causing
+ * this race. */
+#define RTFILE_O_TRUNCATE UINT32_C(0x00001000)
+/** Make the handle inheritable on RTProcessCreate(/exec). */
+#define RTFILE_O_INHERIT UINT32_C(0x00002000)
+/** Open file in non-blocking mode - non-portable.
+ * @remarks This flag may not be supported on all platforms, in which case it's
+ * considered an invalid parameter. */
+#define RTFILE_O_NON_BLOCK UINT32_C(0x00004000)
+/** Write through directly to disk. Workaround to avoid iSCSI
+ * initiator deadlocks on Windows hosts.
+ * @remarks This might not be implemented on all platforms, and will be ignored
+ * on those. */
+#define RTFILE_O_WRITE_THROUGH UINT32_C(0x00008000)
+
+/** Attribute access: Attributes can be read if the file is being opened with
+ * read access, and can be written with write access. */
+#define RTFILE_O_ACCESS_ATTR_DEFAULT UINT32_C(0x00000000)
+/** Attribute access: Attributes can be read.
+ * @remarks Windows only. */
+#define RTFILE_O_ACCESS_ATTR_READ UINT32_C(0x00010000)
+/** Attribute access: Attributes can be written.
+ * @remarks Windows only. */
+#define RTFILE_O_ACCESS_ATTR_WRITE UINT32_C(0x00020000)
+/** Attribute access: Attributes can be both read & written.
+ * @remarks Windows only. */
+#define RTFILE_O_ACCESS_ATTR_READWRITE UINT32_C(0x00030000)
+/** Attribute access: The file attributes access mask.
+ * @remarks Windows only. */
+#define RTFILE_O_ACCESS_ATTR_MASK UINT32_C(0x00030000)
+
+/** Open file for async I/O
+ * @remarks This flag may not be needed on all platforms, and will be ignored on
+ * those. */
+#define RTFILE_O_ASYNC_IO UINT32_C(0x00040000)
+
+/** Disables caching.
+ *
+ * Useful when using very big files which might bring the host I/O scheduler to
+ * its knees during high I/O load.
+ *
+ * @remarks This flag might impose restrictions
+ * on the buffer alignment, start offset and/or transfer size.
+ *
+ * On Linux the buffer needs to be aligned to the 512 sector
+ * boundary.
+ *
+ * On Windows the FILE_FLAG_NO_BUFFERING is used (see
+ * http://msdn.microsoft.com/en-us/library/cc644950(VS.85).aspx ).
+ * The buffer address, the transfer size and offset needs to be aligned
+ * to the sector size of the volume. Furthermore FILE_APPEND_DATA is
+ * disabled. To write beyond the size of file use RTFileSetSize prior
+ * writing the data to the file.
+ *
+ * This flag does not work on Solaris if the target filesystem is ZFS.
+ * RTFileOpen will return an error with that configuration. When used
+ * with UFS the same alginment restrictions apply like Linux and
+ * Windows.
+ *
+ * @remarks This might not be implemented on all platforms, and will be ignored
+ * on those.
+ */
+#define RTFILE_O_NO_CACHE UINT32_C(0x00080000)
+
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTFILE_O_NO_SYMLINKS UINT32_C(0x20000000)
+
+/** Unix file mode mask for use when creating files. */
+#define RTFILE_O_CREATE_MODE_MASK UINT32_C(0x1ff00000)
+/** The number of bits to shift to get the file mode mask.
+ * To extract it: (fFlags & RTFILE_O_CREATE_MODE_MASK) >> RTFILE_O_CREATE_MODE_SHIFT.
+ */
+#define RTFILE_O_CREATE_MODE_SHIFT 20
+
+ /* UINT32_C(0x40000000)
+ and UINT32_C(0x80000000) are unused atm. */
+
+/** Mask of all valid flags.
+ * @remark This doesn't validate the access mode properly.
+ */
+#define RTFILE_O_VALID_MASK UINT32_C(0x3ffffff7)
+
+/** @} */
+
+
+#ifdef IN_RING3
+/**
+ * Force the use of open flags for all files opened after the setting is
+ * changed. The caller is responsible for not causing races with RTFileOpen().
+ *
+ * @returns iprt status code.
+ * @param fOpenForAccess Access mode to which the set/mask settings apply.
+ * @param fSet Open flags to be forced set.
+ * @param fMask Open flags to be masked out.
+ */
+RTR3DECL(int) RTFileSetForceFlags(unsigned fOpenForAccess, unsigned fSet, unsigned fMask);
+#endif /* IN_RING3 */
+
+/**
+ * Open a file.
+ *
+ * @returns iprt status code.
+ * @param pFile Where to store the handle to the opened file.
+ * @param pszFilename Path to the file which is to be opened. (UTF-8)
+ * @param fOpen Open flags, i.e a combination of the RTFILE_O_* defines.
+ * The ACCESS, ACTION and DENY flags are mandatory!
+ */
+RTDECL(int) RTFileOpen(PRTFILE pFile, const char *pszFilename, uint64_t fOpen);
+
+/**
+ * Open a file given as a format string.
+ *
+ * @returns iprt status code.
+ * @param pFile Where to store the handle to the opened file.
+ * @param fOpen Open flags, i.e a combination of the RTFILE_O_* defines.
+ * The ACCESS, ACTION and DENY flags are mandatory!
+ * @param pszFilenameFmt Format string givin the path to the file which is to
+ * be opened. (UTF-8)
+ * @param ... Arguments to the format string.
+ */
+RTDECL(int) RTFileOpenF(PRTFILE pFile, uint64_t fOpen, const char *pszFilenameFmt, ...);
+
+/**
+ * Open a file given as a format string.
+ *
+ * @returns iprt status code.
+ * @param pFile Where to store the handle to the opened file.
+ * @param fOpen Open flags, i.e a combination of the RTFILE_O_* defines.
+ * The ACCESS, ACTION and DENY flags are mandatory!
+ * @param pszFilenameFmt Format string givin the path to the file which is to
+ * be opened. (UTF-8)
+ * @param va Arguments to the format string.
+ */
+RTDECL(int) RTFileOpenV(PRTFILE pFile, uint64_t fOpen, const char *pszFilenameFmt, va_list va);
+
+/**
+ * Open the bit bucket (aka /dev/null or nul).
+ *
+ * @returns IPRT status code.
+ * @param phFile Where to store the handle to the opened file.
+ * @param fAccess The desired access only, i.e. read, write or both.
+ */
+RTDECL(int) RTFileOpenBitBucket(PRTFILE phFile, uint64_t fAccess);
+
+/**
+ * Close a file opened by RTFileOpen().
+ *
+ * @returns iprt status code.
+ * @param File The file handle to close.
+ */
+RTDECL(int) RTFileClose(RTFILE File);
+
+/**
+ * Creates an IPRT file handle from a native one.
+ *
+ * @returns IPRT status code.
+ * @param pFile Where to store the IPRT file handle.
+ * @param uNative The native handle.
+ */
+RTDECL(int) RTFileFromNative(PRTFILE pFile, RTHCINTPTR uNative);
+
+/**
+ * Gets the native handle for an IPRT file handle.
+ *
+ * @return The native handle.
+ * @param File The IPRT file handle.
+ */
+RTDECL(RTHCINTPTR) RTFileToNative(RTFILE File);
+
+/**
+ * Delete a file.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Path to the file which is to be deleted. (UTF-8)
+ * @todo This is a RTPath api!
+ */
+RTDECL(int) RTFileDelete(const char *pszFilename);
+
+/** @name Seek flags.
+ * @{ */
+/** Seek from the start of the file. */
+#define RTFILE_SEEK_BEGIN 0x00
+/** Seek from the current file position. */
+#define RTFILE_SEEK_CURRENT 0x01
+/** Seek from the end of the file. */
+#define RTFILE_SEEK_END 0x02
+/** @internal */
+#define RTFILE_SEEK_FIRST RTFILE_SEEK_BEGIN
+/** @internal */
+#define RTFILE_SEEK_LAST RTFILE_SEEK_END
+/** @} */
+
+
+/**
+ * Changes the read & write position in a file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param offSeek Offset to seek.
+ * @param uMethod Seek method, i.e. one of the RTFILE_SEEK_* defines.
+ * @param poffActual Where to store the new file position.
+ * NULL is allowed.
+ */
+RTDECL(int) RTFileSeek(RTFILE File, int64_t offSeek, unsigned uMethod, uint64_t *poffActual);
+
+/**
+ * Read bytes from a file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbToRead How much to read.
+ * @param *pcbRead How much we actually read .
+ * If NULL an error will be returned for a partial read.
+ */
+RTDECL(int) RTFileRead(RTFILE File, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Read bytes from a file at a given offset.
+ * This function may modify the file position.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param off Where to read.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbToRead How much to read.
+ * @param *pcbRead How much we actually read .
+ * If NULL an error will be returned for a partial read.
+ */
+RTDECL(int) RTFileReadAt(RTFILE File, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Write bytes to a file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param pvBuf What to write.
+ * @param cbToWrite How much to write.
+ * @param *pcbWritten How much we actually wrote.
+ * If NULL an error will be returned for a partial write.
+ */
+RTDECL(int) RTFileWrite(RTFILE File, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+
+/**
+ * Write bytes to a file at a given offset.
+ * This function may modify the file position.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param off Where to write.
+ * @param pvBuf What to write.
+ * @param cbToWrite How much to write.
+ * @param *pcbWritten How much we actually wrote.
+ * If NULL an error will be returned for a partial write.
+ */
+RTDECL(int) RTFileWriteAt(RTFILE File, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+
+/**
+ * Flushes the buffers for the specified file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ */
+RTDECL(int) RTFileFlush(RTFILE File);
+
+/**
+ * Set the size of the file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param cbSize The new file size.
+ */
+RTDECL(int) RTFileSetSize(RTFILE File, uint64_t cbSize);
+
+/**
+ * Query the size of the file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param pcbSize Where to store the filesize.
+ */
+RTDECL(int) RTFileGetSize(RTFILE File, uint64_t *pcbSize);
+
+/**
+ * Determine the maximum file size.
+ *
+ * @returns The max size of the file.
+ * -1 on failure, the file position is undefined.
+ * @param File Handle to the file.
+ * @see RTFileGetMaxSizeEx.
+ */
+RTDECL(RTFOFF) RTFileGetMaxSize(RTFILE File);
+
+/**
+ * Determine the maximum file size.
+ *
+ * @returns IPRT status code.
+ * @param File Handle to the file.
+ * @param pcbMax Where to store the max file size.
+ * @see RTFileGetMaxSize.
+ */
+RTDECL(int) RTFileGetMaxSizeEx(RTFILE File, PRTFOFF pcbMax);
+
+/**
+ * Determine the maximum file size depending on the file system the file is stored on.
+ *
+ * @returns The max size of the file.
+ * -1 on failure.
+ * @param File Handle to the file.
+ */
+RTDECL(RTFOFF) RTFileGetMaxSize(RTFILE File);
+
+/**
+ * Gets the current file position.
+ *
+ * @returns File offset.
+ * @returns ~0UUL on failure.
+ * @param File Handle to the file.
+ */
+RTDECL(uint64_t) RTFileTell(RTFILE File);
+
+/**
+ * Checks if the supplied handle is valid.
+ *
+ * @returns true if valid.
+ * @returns false if invalid.
+ * @param File The file handle
+ */
+RTDECL(bool) RTFileIsValid(RTFILE File);
+
+/**
+ * Copies a file.
+ *
+ * @returns VERR_ALREADY_EXISTS if the destination file exists.
+ * @returns VBox Status code.
+ *
+ * @param pszSrc The path to the source file.
+ * @param pszDst The path to the destination file.
+ * This file will be created.
+ */
+RTDECL(int) RTFileCopy(const char *pszSrc, const char *pszDst);
+
+/**
+ * Copies a file given the handles to both files.
+ *
+ * @returns VBox Status code.
+ *
+ * @param FileSrc The source file. The file position is unaltered.
+ * @param FileDst The destination file.
+ * On successful returns the file position is at the end of the file.
+ * On failures the file position and size is undefined.
+ */
+RTDECL(int) RTFileCopyByHandles(RTFILE FileSrc, RTFILE FileDst);
+
+/** Flags for RTFileCopyEx().
+ * @{ */
+/** Do not use RTFILE_O_DENY_WRITE on the source file to allow for copying files opened for writing. */
+#define RTFILECOPY_FLAGS_NO_SRC_DENY_WRITE RT_BIT(0)
+/** Do not use RTFILE_O_DENY_WRITE on the target file. */
+#define RTFILECOPY_FLAGS_NO_DST_DENY_WRITE RT_BIT(1)
+/** Do not use RTFILE_O_DENY_WRITE on either of the two files. */
+#define RTFILECOPY_FLAGS_NO_DENY_WRITE ( RTFILECOPY_FLAGS_NO_SRC_DENY_WRITE | RTFILECOPY_FLAGS_NO_DST_DENY_WRITE )
+/** */
+#define RTFILECOPY_FLAGS_MASK UINT32_C(0x00000003)
+/** @} */
+
+/**
+ * Copies a file.
+ *
+ * @returns VERR_ALREADY_EXISTS if the destination file exists.
+ * @returns VBox Status code.
+ *
+ * @param pszSrc The path to the source file.
+ * @param pszDst The path to the destination file.
+ * This file will be created.
+ * @param fFlags Flags (RTFILECOPY_*).
+ * @param pfnProgress Pointer to callback function for reporting progress.
+ * @param pvUser User argument to pass to pfnProgress along with the completion percentage.
+ */
+RTDECL(int) RTFileCopyEx(const char *pszSrc, const char *pszDst, uint32_t fFlags, PFNRTPROGRESS pfnProgress, void *pvUser);
+
+/**
+ * Copies a file given the handles to both files and
+ * provide progress callbacks.
+ *
+ * @returns IPRT status code.
+ *
+ * @param FileSrc The source file. The file position is unaltered.
+ * @param FileDst The destination file.
+ * On successful returns the file position is at the end of the file.
+ * On failures the file position and size is undefined.
+ * @param pfnProgress Pointer to callback function for reporting progress.
+ * @param pvUser User argument to pass to pfnProgress along with the completion percentage.
+ */
+RTDECL(int) RTFileCopyByHandlesEx(RTFILE FileSrc, RTFILE FileDst, PFNRTPROGRESS pfnProgress, void *pvUser);
+
+/**
+ * Renames a file.
+ *
+ * Identical to RTPathRename except that it will ensure that the source is not a directory.
+ *
+ * @returns IPRT status code.
+ * @returns VERR_ALREADY_EXISTS if the destination file exists.
+ *
+ * @param pszSrc The path to the source file.
+ * @param pszDst The path to the destination file.
+ * This file will be created.
+ * @param fRename See RTPathRename.
+ */
+RTDECL(int) RTFileRename(const char *pszSrc, const char *pszDst, unsigned fRename);
+
+
+/** @name RTFileMove flags (bit masks).
+ * @{ */
+/** Replace destination file if present. */
+#define RTFILEMOVE_FLAGS_REPLACE 0x1
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTFILEMOVE_FLAGS_NO_SYMLINKS 0x2
+/** @} */
+
+/**
+ * Moves a file.
+ *
+ * RTFileMove differs from RTFileRename in that it works across volumes.
+ *
+ * @returns IPRT status code.
+ * @returns VERR_ALREADY_EXISTS if the destination file exists.
+ *
+ * @param pszSrc The path to the source file.
+ * @param pszDst The path to the destination file.
+ * This file will be created.
+ * @param fMove A combination of the RTFILEMOVE_* flags.
+ */
+RTDECL(int) RTFileMove(const char *pszSrc, const char *pszDst, unsigned fMove);
+
+
+/**
+ * Creates a new file with a unique name using the given template.
+ *
+ * One or more trailing X'es in the template will be replaced by random alpha
+ * numeric characters until a RTFileOpen with RTFILE_O_CREATE succeeds or we
+ * run out of patience.
+ * For instance:
+ * "/tmp/myprog-XXXXXX"
+ *
+ * As an alternative to trailing X'es, it is possible to put 3 or more X'es
+ * somewhere inside the file name. In the following string only the last
+ * bunch of X'es will be modified:
+ * "/tmp/myprog-XXX-XXX.tmp"
+ *
+ * @returns iprt status code.
+ * @param pszTemplate The file name template on input. The actual file
+ * name on success. Empty string on failure.
+ * @param fMode The mode to create the file with. Use 0600 unless
+ * you have reason not to.
+ */
+RTDECL(int) RTFileCreateTemp(char *pszTemplate, RTFMODE fMode);
+
+/**
+ * Secure version of @a RTFileCreateTemp with a fixed mode of 0600.
+ *
+ * This function behaves in the same way as @a RTFileCreateTemp with two
+ * additional points. Firstly the mode is fixed to 0600. Secondly it will
+ * fail if it is not possible to perform the operation securely. Possible
+ * reasons include that the file could be removed by another unprivileged
+ * user before it is used (e.g. if is created in a non-sticky /tmp directory)
+ * or that the path contains symbolic links which another unprivileged user
+ * could manipulate; however the exact criteria will be specified on a
+ * platform-by-platform basis as platform support is added.
+ * @see RTPathIsSecure for the current list of criteria.
+ * @returns iprt status code.
+ * @returns VERR_NOT_SUPPORTED if the interface can not be supported on the
+ * current platform at this time.
+ * @returns VERR_INSECURE if the file could not be created securely.
+ * @param pszTemplate The file name template on input. The actual
+ * file name on success. Empty string on failure.
+ */
+RTDECL(int) RTFileCreateTempSecure(char *pszTemplate);
+
+
+/** @page pg_rt_filelock RT File locking API description
+ *
+ * File locking general rules:
+ *
+ * Region to lock or unlock can be located beyond the end of file, this can be used for
+ * growing files.
+ * Read (or Shared) locks can be acquired held by an unlimited number of processes at the
+ * same time, but a Write (or Exclusive) lock can only be acquired by one process, and
+ * cannot coexist with a Shared lock. To acquire a Read lock, a process must wait until
+ * there are no processes holding any Write locks. To acquire a Write lock, a process must
+ * wait until there are no processes holding either kind of lock.
+ * By default, RTFileLock and RTFileChangeLock calls returns error immediately if the lock
+ * can't be acquired due to conflict with other locks, however they can be called in wait mode.
+ *
+ * Differences in implementation:
+ *
+ * Win32, OS/2: Locking is mandatory, since locks are enforced by the operating system.
+ * I.e. when file region is locked in Read mode, any write in it will fail; in case of Write
+ * lock - region can be read and writed only by lock's owner.
+ *
+ * Win32: File size change (RTFileSetSize) is not controlled by locking at all (!) in the
+ * operation system. Also see comments to RTFileChangeLock API call.
+ *
+ * Linux/Posix: By default locks in Unixes are advisory. This means that cooperating processes
+ * may use locks to coordinate access to a file between themselves, but programs are also free
+ * to ignore locks and access the file in any way they choose to.
+ *
+ * Additional reading:
+ * http://en.wikipedia.org/wiki/File_locking
+ * http://unixhelp.ed.ac.uk/CGI/man-cgi?fcntl+2
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/lockfileex.asp
+ */
+
+/** @name Lock flags (bit masks).
+ * @{ */
+/** Read access, can be shared with others. */
+#define RTFILE_LOCK_READ 0x00
+/** Write access, one at a time. */
+#define RTFILE_LOCK_WRITE 0x01
+/** Don't wait for other locks to be released. */
+#define RTFILE_LOCK_IMMEDIATELY 0x00
+/** Wait till conflicting locks have been released. */
+#define RTFILE_LOCK_WAIT 0x02
+/** Valid flags mask */
+#define RTFILE_LOCK_MASK 0x03
+/** @} */
+
+
+/**
+ * Locks a region of file for read (shared) or write (exclusive) access.
+ *
+ * @returns iprt status code.
+ * @returns VERR_FILE_LOCK_VIOLATION if lock can't be acquired.
+ * @param File Handle to the file.
+ * @param fLock Lock method and flags, see RTFILE_LOCK_* defines.
+ * @param offLock Offset of lock start.
+ * @param cbLock Length of region to lock, may overlap the end of file.
+ */
+RTDECL(int) RTFileLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock);
+
+/**
+ * Changes a lock type from read to write or from write to read.
+ * The region to type change must correspond exactly to an existing locked region.
+ * If change can't be done due to locking conflict and non-blocking mode is used, error is
+ * returned and lock keeps its state (see next warning).
+ *
+ * WARNING: win32 implementation of this call is not atomic, it transforms to a pair of
+ * calls RTFileUnlock and RTFileLock. Potentially the previously acquired lock can be
+ * lost, i.e. function is called in non-blocking mode, previous lock is freed, new lock can't
+ * be acquired, and old lock (previous state) can't be acquired back too. This situation
+ * may occurs _only_ if the other process is acquiring a _write_ lock in blocking mode or
+ * in race condition with the current call.
+ * In this very bad case special error code VERR_FILE_LOCK_LOST will be returned.
+ *
+ * @returns iprt status code.
+ * @returns VERR_FILE_NOT_LOCKED if region was not locked.
+ * @returns VERR_FILE_LOCK_VIOLATION if lock type can't be changed, lock remains its type.
+ * @returns VERR_FILE_LOCK_LOST if lock was lost, we haven't this lock anymore :(
+ * @param File Handle to the file.
+ * @param fLock Lock method and flags, see RTFILE_LOCK_* defines.
+ * @param offLock Offset of lock start.
+ * @param cbLock Length of region to lock, may overlap the end of file.
+ */
+RTDECL(int) RTFileChangeLock(RTFILE File, unsigned fLock, int64_t offLock, uint64_t cbLock);
+
+/**
+ * Unlocks previously locked region of file.
+ * The region to unlock must correspond exactly to an existing locked region.
+ *
+ * @returns iprt status code.
+ * @returns VERR_FILE_NOT_LOCKED if region was not locked.
+ * @param File Handle to the file.
+ * @param offLock Offset of lock start.
+ * @param cbLock Length of region to unlock, may overlap the end of file.
+ */
+RTDECL(int) RTFileUnlock(RTFILE File, int64_t offLock, uint64_t cbLock);
+
+
+/**
+ * Query information about an open file.
+ *
+ * @returns iprt status code.
+ *
+ * @param File Handle to the file.
+ * @param pObjInfo Object information structure to be filled on successful return.
+ * @param enmAdditionalAttribs Which set of additional attributes to request.
+ * Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
+ */
+RTDECL(int) RTFileQueryInfo(RTFILE File, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs);
+
+/**
+ * Changes one or more of the timestamps associated of file system object.
+ *
+ * @returns iprt status code.
+ * @retval VERR_NOT_SUPPORTED is returned if the operation isn't supported by
+ * the OS.
+ *
+ * @param File Handle to the file.
+ * @param pAccessTime Pointer to the new access time. NULL if not to be changed.
+ * @param pModificationTime Pointer to the new modifcation time. NULL if not to be changed.
+ * @param pChangeTime Pointer to the new change time. NULL if not to be changed.
+ * @param pBirthTime Pointer to the new time of birth. NULL if not to be changed.
+ *
+ * @remark The file system might not implement all these time attributes,
+ * the API will ignore the ones which aren't supported.
+ *
+ * @remark The file system might not implement the time resolution
+ * employed by this interface, the time will be chopped to fit.
+ *
+ * @remark The file system may update the change time even if it's
+ * not specified.
+ *
+ * @remark POSIX can only set Access & Modification and will always set both.
+ */
+RTDECL(int) RTFileSetTimes(RTFILE File, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+ PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
+
+/**
+ * Gets one or more of the timestamps associated of file system object.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param pAccessTime Where to store the access time. NULL is ok.
+ * @param pModificationTime Where to store the modifcation time. NULL is ok.
+ * @param pChangeTime Where to store the change time. NULL is ok.
+ * @param pBirthTime Where to store the time of birth. NULL is ok.
+ *
+ * @remark This is wrapper around RTFileQueryInfo() and exists to complement RTFileSetTimes().
+ */
+RTDECL(int) RTFileGetTimes(RTFILE File, PRTTIMESPEC pAccessTime, PRTTIMESPEC pModificationTime,
+ PRTTIMESPEC pChangeTime, PRTTIMESPEC pBirthTime);
+
+/**
+ * Changes the mode flags of an open file.
+ *
+ * The API requires at least one of the mode flag sets (Unix/Dos) to
+ * be set. The type is ignored.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param fMode The new file mode, see @ref grp_rt_fs for details.
+ */
+RTDECL(int) RTFileSetMode(RTFILE File, RTFMODE fMode);
+
+/**
+ * Gets the mode flags of an open file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param pfMode Where to store the file mode, see @ref grp_rt_fs for details.
+ *
+ * @remark This is wrapper around RTFileQueryInfo()
+ * and exists to complement RTFileSetMode().
+ */
+RTDECL(int) RTFileGetMode(RTFILE File, uint32_t *pfMode);
+
+/**
+ * Changes the owner and/or group of an open file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param uid The new file owner user id. Pass NIL_RTUID to leave
+ * this unchanged.
+ * @param gid The new group id. Pass NIL_RTGID to leave this
+ * unchanged.
+ */
+RTDECL(int) RTFileSetOwner(RTFILE File, uint32_t uid, uint32_t gid);
+
+/**
+ * Gets the owner and/or group of an open file.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param pUid Where to store the owner user id. NULL is ok.
+ * @param pGid Where to store the group id. NULL is ok.
+ *
+ * @remark This is wrapper around RTFileQueryInfo() and exists to complement RTFileGetOwner().
+ */
+RTDECL(int) RTFileGetOwner(RTFILE File, uint32_t *pUid, uint32_t *pGid);
+
+/**
+ * Executes an IOCTL on a file descriptor.
+ *
+ * This function is currently only available in L4 and posix environments.
+ * Attemps at calling it from code shared with any other platforms will break things!
+ *
+ * The rational for defining this API is to simplify L4 porting of audio drivers,
+ * and to remove some of the assumptions on RTFILE being a file descriptor on
+ * platforms using the posix file implementation.
+ *
+ * @returns iprt status code.
+ * @param File Handle to the file.
+ * @param iRequest IOCTL request to carry out.
+ * @param pvData IOCTL data.
+ * @param cbData Size of the IOCTL data.
+ * @param piRet Return value of the IOCTL request.
+ */
+RTDECL(int) RTFileIoCtl(RTFILE File, unsigned long ulRequest, void *pvData, unsigned cbData, int *piRet);
+
+/**
+ * Query the sizes of a filesystem.
+ *
+ * @returns iprt status code.
+ * @retval VERR_NOT_SUPPORTED is returned if the operation isn't supported by
+ * the OS.
+ *
+ * @param hFile The file handle.
+ * @param pcbTotal Where to store the total filesystem space. (Optional)
+ * @param pcbFree Where to store the remaining free space in the filesystem. (Optional)
+ * @param pcbBlock Where to store the block size. (Optional)
+ * @param pcbSector Where to store the sector size. (Optional)
+ *
+ * @sa RTFsQuerySizes
+ */
+RTDECL(int) RTFileQueryFsSizes(RTFILE hFile, PRTFOFF pcbTotal, RTFOFF *pcbFree,
+ uint32_t *pcbBlock, uint32_t *pcbSector);
+
+/**
+ * Reads the file into memory.
+ *
+ * The caller must free the memory using RTFileReadAllFree().
+ *
+ * @returns IPRT status code.
+ * @param pszFilename The name of the file.
+ * @param ppvFile Where to store the pointer to the memory on successful return.
+ * @param pcbFile Where to store the size of the returned memory.
+ *
+ * @remarks Note that this function may be implemented using memory mapping, which means
+ * that the file may remain open until RTFileReadAllFree() is called. It also
+ * means that the return memory may reflect the state of the file when it's
+ * accessed instead of when this call was done. So, in short, don't use this
+ * API for volatile files, then rather use the extended variant with a
+ * yet-to-be-defined flag.
+ */
+RTDECL(int) RTFileReadAll(const char *pszFilename, void **ppvFile, size_t *pcbFile);
+
+/**
+ * Reads the file into memory.
+ *
+ * The caller must free the memory using RTFileReadAllFree().
+ *
+ * @returns IPRT status code.
+ * @param pszFilename The name of the file.
+ * @param off The offset to start reading at.
+ * @param cbMax The maximum number of bytes to read into memory. Specify RTFOFF_MAX
+ * to read to the end of the file.
+ * @param fFlags See RTFILE_RDALL_*.
+ * @param ppvFile Where to store the pointer to the memory on successful return.
+ * @param pcbFile Where to store the size of the returned memory.
+ *
+ * @remarks See the remarks for RTFileReadAll.
+ */
+RTDECL(int) RTFileReadAllEx(const char *pszFilename, RTFOFF off, RTFOFF cbMax, uint32_t fFlags, void **ppvFile, size_t *pcbFile);
+
+/**
+ * Reads the file into memory.
+ *
+ * The caller must free the memory using RTFileReadAllFree().
+ *
+ * @returns IPRT status code.
+ * @param File The handle to the file.
+ * @param ppvFile Where to store the pointer to the memory on successful return.
+ * @param pcbFile Where to store the size of the returned memory.
+ *
+ * @remarks See the remarks for RTFileReadAll.
+ */
+RTDECL(int) RTFileReadAllByHandle(RTFILE File, void **ppvFile, size_t *pcbFile);
+
+/**
+ * Reads the file into memory.
+ *
+ * The caller must free the memory using RTFileReadAllFree().
+ *
+ * @returns IPRT status code.
+ * @param File The handle to the file.
+ * @param off The offset to start reading at.
+ * @param cbMax The maximum number of bytes to read into memory. Specify RTFOFF_MAX
+ * to read to the end of the file.
+ * @param fFlags See RTFILE_RDALL_*.
+ * @param ppvFile Where to store the pointer to the memory on successful return.
+ * @param pcbFile Where to store the size of the returned memory.
+ *
+ * @remarks See the remarks for RTFileReadAll.
+ */
+RTDECL(int) RTFileReadAllByHandleEx(RTFILE File, RTFOFF off, RTFOFF cbMax, uint32_t fFlags, void **ppvFile, size_t *pcbFile);
+
+/**
+ * Frees the memory returned by one of the RTFileReadAll(), RTFileReadAllEx(),
+ * RTFileReadAllByHandle() and RTFileReadAllByHandleEx() functions.
+ *
+ * @param pvFile Pointer to the memory.
+ * @param cbFile The size of the memory.
+ */
+RTDECL(void) RTFileReadAllFree(void *pvFile, size_t cbFile);
+
+/** @name RTFileReadAllEx and RTFileReadAllHandleEx flags
+ * The open flags are ignored by RTFileReadAllHandleEx.
+ * @{ */
+#define RTFILE_RDALL_O_DENY_NONE RTFILE_O_DENY_NONE
+#define RTFILE_RDALL_O_DENY_READ RTFILE_O_DENY_READ
+#define RTFILE_RDALL_O_DENY_WRITE RTFILE_O_DENY_WRITE
+#define RTFILE_RDALL_O_DENY_READWRITE RTFILE_O_DENY_READWRITE
+#define RTFILE_RDALL_O_DENY_ALL RTFILE_O_DENY_ALL
+#define RTFILE_RDALL_O_DENY_NOT_DELETE RTFILE_O_DENY_NOT_DELETE
+#define RTFILE_RDALL_O_DENY_MASK RTFILE_O_DENY_MASK
+/** Mask of valid flags. */
+#define RTFILE_RDALL_VALID_MASK RTFILE_RDALL_O_DENY_MASK
+/** @} */
+
+
+#ifdef IN_RING3
+
+/** @page pg_rt_asyncio RT File async I/O API
+ *
+ * File operations are usually blocking the calling thread until
+ * they completed making it impossible to let the thread do anything
+ * else in-between.
+ * The RT File async I/O API provides an easy and efficient way to
+ * access files asynchronously using the native facilities provided
+ * by each operating system.
+ *
+ * @section sec_rt_asyncio_objects Objects
+ *
+ * There are two objects used in this API.
+ * The first object is the request. A request contains every information
+ * needed two complete the file operation successfully like the start offset
+ * and pointer to the source or destination buffer.
+ * Requests are created with RTFileAioReqCreate() and destroyed with
+ * RTFileAioReqDestroy().
+ * Because creating a request may require allocating various operating
+ * system dependent resources and may be quite expensive it is possible
+ * to use a request more than once to save CPU cycles.
+ * A request is constructed with either RTFileAioReqPrepareRead()
+ * which will set up a request to read from the given file or
+ * RTFileAioReqPrepareWrite() which will write to a given file.
+ *
+ * The second object is the context. A file is associated with a context
+ * and requests for this file may complete only on the context the file
+ * was associated with and not on the context given in RTFileAioCtxSubmit()
+ * (see below for further information).
+ * RTFileAioCtxWait() is used to wait for completion of requests which were
+ * associated with the context. While waiting for requests the thread can not
+ * respond to global state changes. That's why the API provides a way to let
+ * RTFileAioCtxWait() return immediately no matter how many requests
+ * have finished through RTFileAioCtxWakeup(). The return code is
+ * VERR_INTERRUPTED to let the thread know that he got interrupted.
+ *
+ * @section sec_rt_asyncio_request_states Request states
+ *
+ * Created:
+ * After a request was created with RTFileAioReqCreate() it is in the same state
+ * like it just completed successfully. RTFileAioReqGetRC() will return VINF_SUCCESS
+ * and a transfer size of 0. RTFileAioReqGetUser() will return NULL. The request can be
+ * destroyed RTFileAioReqDestroy(). It is also allowed to prepare a the request
+ * for a data transfer with the RTFileAioReqPrepare* methods.
+ * Calling any other method like RTFileAioCtxSubmit() will return VERR_FILE_AIO_NOT_PREPARED
+ * and RTFileAioReqCancel() returns VERR_FILE_AIO_NOT_SUBMITTED.
+ *
+ * Prepared:
+ * A request will enter this state if one of the RTFileAioReqPrepare* methods
+ * is called. In this state you can still destroy and retrieve the user data
+ * associated with the request but trying to cancel the request or getting
+ * the result of the operation will return VERR_FILE_AIO_NOT_SUBMITTED.
+ *
+ * Submitted:
+ * A prepared request can be submitted with RTFileAioCtxSubmit(). If the operation
+ * succeeds it is not allowed to touch the request or free any resources until
+ * it completed through RTFileAioCtxWait(). The only allowed method is RTFileAioReqCancel()
+ * which tries to cancel the request. The request will go into the completed state
+ * and RTFileAioReqGetRC() will return VERR_FILE_AIO_CANCELED.
+ * If the request completes not matter if successfully or with an error it will
+ * switch into the completed state. RTFileReqDestroy() fails if the given request
+ * is in this state.
+ *
+ * Completed:
+ * The request will be in this state after it completed and returned through
+ * RTFileAioCtxWait(). RTFileAioReqGetRC() returns the final result code
+ * and the number of bytes transferred.
+ * The request can be used for new data transfers.
+ *
+ * @section sec_rt_asyncio_threading Threading
+ *
+ * The API is a thin wrapper around the specific host OS APIs and therefore
+ * relies on the thread safety of the underlying API.
+ * The interesting functions with regards to thread safety are RTFileAioCtxSubmit()
+ * and RTFileAioCtxWait(). RTFileAioCtxWait() must not be called from different
+ * threads at the same time with the same context handle. The same applies to
+ * RTFileAioCtxSubmit(). However it is possible to submit new requests from a different
+ * thread while waiting for completed requests on another thread with RTFileAioCtxWait().
+ *
+ * @section sec_rt_asyncio_implementations Differences in implementation
+ *
+ * Because the host APIs are quite different on every OS and every API has other limitations
+ * there are some things to consider to make the code as portable as possible.
+ *
+ * The first restriction at the moment is that every buffer has to be aligned to a 512 byte boundary.
+ * This limitation comes from the Linux io_* interface. To use the interface the file
+ * must be opened with O_DIRECT. This flag disables the kernel cache too which may
+ * degrade performance but is unfortunately the only way to make asynchronous
+ * I/O work till today (if O_DIRECT is omitted io_submit will revert to sychronous behavior
+ * and will return when the requests finished and when they are queued).
+ * It is mostly used by DBMS which do theire own caching.
+ * Furthermore there is no filesystem independent way to discover the restrictions at least
+ * for the 2.4 kernel series. Since 2.6 the 512 byte boundary seems to be used by all
+ * file systems. So Linus comment about this flag is comprehensible but Linux
+ * lacks an alternative at the moment.
+ *
+ * The next limitation applies only to Windows. Requests are not associated with the
+ * I/O context they are associated with but with the file the request is for.
+ * The file needs to be associated with exactly one I/O completion port and requests
+ * for this file will only arrive at that context after they completed and not on
+ * the context the request was submitted.
+ * To associate a file with a specific context RTFileAioCtxAssociateWithFile() is
+ * used. It is only implemented on Windows and does nothing on the other platforms.
+ * If the file needs to be associated with different context for some reason
+ * the file must be closed first. After it was opened again the new context
+ * can be associated with the other context.
+ * This can't be done by the API because there is no way to retrieve the flags
+ * the file was opened with.
+ */
+
+/**
+ * Global limits for the AIO API.
+ */
+typedef struct RTFILEAIOLIMITS
+{
+ /** Global number of simultaneous outstanding requests allowed.
+ * RTFILEAIO_UNLIMITED_REQS means no limit. */
+ uint32_t cReqsOutstandingMax;
+ /** The alignment data buffers need to have.
+ * 0 means no alignment restrictions. */
+ uint32_t cbBufferAlignment;
+} RTFILEAIOLIMITS;
+/** A pointer to a AIO limits structure. */
+typedef RTFILEAIOLIMITS *PRTFILEAIOLIMITS;
+
+/**
+ * Returns the global limits for the AIO API.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the host does not support the async I/O API.
+ *
+ * @param pAioLimits Where to store the global limit information.
+ */
+RTDECL(int) RTFileAioGetLimits(PRTFILEAIOLIMITS pAioLimits);
+
+/**
+ * Creates an async I/O request handle.
+ *
+ * @returns IPRT status code.
+ * @param phReq Where to store the request handle.
+ */
+RTDECL(int) RTFileAioReqCreate(PRTFILEAIOREQ phReq);
+
+/**
+ * Destroys an async I/O request handle.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_FILE_AIO_IN_PROGRESS if the request is still in progress.
+ *
+ * @param hReq The request handle.
+ */
+RTDECL(int) RTFileAioReqDestroy(RTFILEAIOREQ hReq);
+
+/**
+ * Prepares an async read request.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_FILE_AIO_IN_PROGRESS if the request is still in progress.
+ *
+ * @param hReq The request handle.
+ * @param hFile The file to read from.
+ * @param off The offset to start reading at.
+ * @param pvBuf Where to store the read bits.
+ * @param cbRead Number of bytes to read.
+ * @param pvUser Opaque user data associated with this request which
+ * can be retrieved with RTFileAioReqGetUser().
+ */
+RTDECL(int) RTFileAioReqPrepareRead(RTFILEAIOREQ hReq, RTFILE hFile, RTFOFF off,
+ void *pvBuf, size_t cbRead, void *pvUser);
+
+/**
+ * Prepares an async write request.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_FILE_AIO_IN_PROGRESS if the request is still in progress.
+ *
+ * @param hReq The request handle.
+ * @param hFile The file to write to.
+ * @param off The offset to start writing at.
+ * @param pvBuf The bits to write.
+ * @param cbWrite Number of bytes to write.
+ * @param pvUser Opaque user data associated with this request which
+ * can be retrieved with RTFileAioReqGetUser().
+ */
+RTDECL(int) RTFileAioReqPrepareWrite(RTFILEAIOREQ hReq, RTFILE hFile, RTFOFF off,
+ void const *pvBuf, size_t cbWrite, void *pvUser);
+
+/**
+ * Prepares an async flush of all cached data associated with a file handle.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_FILE_AIO_IN_PROGRESS if the request is still in progress.
+ *
+ * @param hReq The request handle.
+ * @param hFile The file to flush.
+ * @param pvUser Opaque user data associated with this request which
+ * can be retrieved with RTFileAioReqGetUser().
+ *
+ * @remarks May also flush other caches on some platforms.
+ */
+RTDECL(int) RTFileAioReqPrepareFlush(RTFILEAIOREQ hReq, RTFILE hFile, void *pvUser);
+
+/**
+ * Gets the opaque user data associated with the given request.
+ *
+ * @returns Opaque user data.
+ * @retval NULL if the request hasn't been prepared yet.
+ *
+ * @param hReq The request handle.
+ */
+RTDECL(void *) RTFileAioReqGetUser(RTFILEAIOREQ hReq);
+
+/**
+ * Cancels a pending request.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS If the request was canceled.
+ * @retval VERR_FILE_AIO_NOT_SUBMITTED If the request wasn't submitted yet.
+ * @retval VERR_FILE_AIO_IN_PROGRESS If the request could not be canceled because it is already processed.
+ * @retval VERR_FILE_AIO_COMPLETED If the request could not be canceled because it already completed.
+ *
+ * @param hReq The request to cancel.
+ */
+RTDECL(int) RTFileAioReqCancel(RTFILEAIOREQ hReq);
+
+/**
+ * Gets the status of a completed request.
+ *
+ * @returns The IPRT status code of the given request.
+ * @retval VERR_FILE_AIO_NOT_SUBMITTED if the request wasn't submitted yet.
+ * @retval VERR_FILE_AIO_CANCELED if the request was canceled.
+ * @retval VERR_FILE_AIO_IN_PROGRESS if the request isn't yet completed.
+ *
+ * @param hReq The request handle.
+ * @param pcbTransferred Where to store the number of bytes transferred.
+ * Optional since it is not relevant for all kinds of
+ * requests.
+ */
+RTDECL(int) RTFileAioReqGetRC(RTFILEAIOREQ hReq, size_t *pcbTransferred);
+
+
+
+/**
+ * Creates an async I/O context.
+ *
+ * @todo briefly explain what an async context is here or in the page
+ * above.
+ *
+ * @returns IPRT status code.
+ * @param phAioCtx Where to store the async I/O context handle.
+ * @param cAioReqsMax How many async I/O requests the context should be capable
+ * to handle. Pass RTFILEAIO_UNLIMITED_REQS if the
+ * context should support an unlimited number of
+ * requests.
+ */
+RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax);
+
+/** Unlimited number of requests.
+ * Used with RTFileAioCtxCreate and RTFileAioCtxGetMaxReqCount. */
+#define RTFILEAIO_UNLIMITED_REQS UINT32_MAX
+
+/**
+ * Destroys an async I/O context.
+ *
+ * @returns IPRT status code.
+ * @param hAioCtx The async I/O context handle.
+ */
+RTDECL(int) RTFileAioCtxDestroy(RTFILEAIOCTX hAioCtx);
+
+/**
+ * Get the maximum number of requests one aio context can handle.
+ *
+ * @returns Maximum number of tasks the context can handle.
+ * RTFILEAIO_UNLIMITED_REQS if there is no limit.
+ *
+ * @param hAioCtx The async I/O context handle.
+ * If NIL_RTAIOCONTEXT is passed the maximum value
+ * which can be passed to RTFileAioCtxCreate()
+ * is returned.
+ */
+RTDECL(uint32_t) RTFileAioCtxGetMaxReqCount(RTFILEAIOCTX hAioCtx);
+
+/**
+ * Associates a file with an async I/O context.
+ * Requests for this file will arrive at the completion port
+ * associated with the file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hAioCtx The async I/O context handle.
+ * @param hFile The file handle.
+ */
+RTDECL(int) RTFileAioCtxAssociateWithFile(RTFILEAIOCTX hAioCtx, RTFILE hFile);
+
+/**
+ * Submits a set of requests to an async I/O context for processing.
+ *
+ * @returns IPRT status code.
+ * @returns VERR_FILE_AIO_INSUFFICIENT_RESSOURCES if the maximum number of
+ * simultaneous outstanding requests would be exceeded.
+ *
+ * @param hAioCtx The async I/O context handle.
+ * @param pahReqs Pointer to an array of request handles.
+ * @param cReqs The number of entries in the array.
+ *
+ * @remarks It is possible that some requests could be submitted successfully
+ * even if the method returns an error code. In that case RTFileAioReqGetRC()
+ * can be used to determine the status of a request.
+ * If it returns VERR_FILE_AIO_IN_PROGRESS it was submitted successfully.
+ * Any other error code may indicate why the request failed.
+ * VERR_FILE_AIO_NOT_SUBMITTED indicates that a request wasn't submitted
+ * probably because the previous request encountered an error.
+ *
+ * @remarks @a cReqs uses the type size_t while it really is a uint32_t, this is
+ * to avoid annoying warnings when using RT_ELEMENTS and similar
+ * macros.
+ */
+RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs);
+
+/**
+ * Waits for request completion.
+ *
+ * Only one thread at a time may call this API on a context.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_POINTER If pcReqs or/and pahReqs are invalid.
+ * @retval VERR_INVALID_HANDLE If hAioCtx is invalid.
+ * @retval VERR_OUT_OF_RANGE If cMinReqs is larger than cReqs.
+ * @retval VERR_INVALID_PARAMETER If cReqs is 0.
+ * @retval VERR_TIMEOUT If cMinReqs didn't complete before the
+ * timeout expired.
+ * @retval VERR_INTERRUPTED If the completion context was interrupted
+ * by RTFileAioCtxWakeup().
+ * @retval VERR_FILE_AIO_NO_REQUEST If there are no pending request.
+ *
+ * @param hAioCtx The async I/O context handle to wait and get
+ * completed requests from.
+ * @param cMinReqs The minimum number of requests which have to
+ * complete before this function returns.
+ * @param cMillies The number of milliseconds to wait before returning
+ * VERR_TIMEOUT. Use RT_INDEFINITE_WAIT to wait
+ * forever.
+ * @param pahReqs Pointer to an array where the handles of the
+ * completed requests will be stored on success.
+ * @param cReqs The number of entries @a pahReqs can hold.
+ * @param pcReqs Where to store the number of returned (complete)
+ * requests. This will always be set.
+ *
+ * @remarks The wait will be resume if interrupted by a signal. An
+ * RTFileAioCtxWaitNoResume variant can be added later if it becomes
+ * necessary.
+ *
+ * @remarks @a cMinReqs and @a cReqs use the type size_t while they really are
+ * uint32_t's, this is to avoid annoying warnings when using
+ * RT_ELEMENTS and similar macros.
+ */
+RTDECL(int) RTFileAioCtxWait(RTFILEAIOCTX hAioCtx, size_t cMinReqs, RTMSINTERVAL cMillies,
+ PRTFILEAIOREQ pahReqs, size_t cReqs, uint32_t *pcReqs);
+
+/**
+ * Forces any RTFileAioCtxWait() call on another thread to return immediately.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hAioCtx The handle of the async I/O context to wakeup.
+ */
+RTDECL(int) RTFileAioCtxWakeup(RTFILEAIOCTX hAioCtx);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/filesystem.h b/include/iprt/filesystem.h
new file mode 100644
index 00000000..82ab146e
--- /dev/null
+++ b/include/iprt/filesystem.h
@@ -0,0 +1,55 @@
+/** @file
+ * IPRT Filesystem 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 ___iprt_filesystem_h
+#define ___iprt_filesystem_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/vfs.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_filesystem IPRT Filesystem VFS
+ * @{
+ */
+
+/**
+ * Detect the filesystem in the image given by the VFS file handle
+ * and create a new VFS object.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the filesystem is not recognized.
+ * @param hVfsFile The file to use as the filesystem medium.
+ * @param phVfs Where to store the VFS handle on success.
+ */
+RTDECL(int) RTFilesystemVfsFromFile(RTVFSFILE hVfsFile, PRTVFS phVfs);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !___iprt_filesystem_h */
+
diff --git a/include/iprt/fs.h b/include/iprt/fs.h
new file mode 100644
index 00000000..6ad2d2c5
--- /dev/null
+++ b/include/iprt/fs.h
@@ -0,0 +1,618 @@
+/** @file
+ * IPRT - Filesystem.
+ */
+
+/*
+ * 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 ___iprt_fs_h
+#define ___iprt_fs_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/time.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_fs RTFs - Filesystem and Volume
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** @name Filesystem Object Mode Flags.
+ *
+ * There are two sets of flags: the unix mode flags and the dos attributes.
+ *
+ * APIs returning mode flags will provide both sets.
+ *
+ * When specifying mode flags to any API at least one of them must be given. If
+ * one set is missing the API will synthesize it from the one given if it
+ * requires it.
+ *
+ * Both sets match their x86 ABIs, the DOS/NT one is simply shifted up 16 bits.
+ * The DOS/NT range is bits 16 to 31 inclusively. The Unix range is bits 0 to 15
+ * (inclusively).
+ *
+ * @remarks These constants have been comitted to a binary format and must not
+ * be changed in any incompatible ways.
+ *
+ * @{
+ */
+
+/** Set user id on execution (S_ISUID). */
+#define RTFS_UNIX_ISUID 0004000U
+/** Set group id on execution (S_ISGID). */
+#define RTFS_UNIX_ISGID 0002000U
+/** Sticky bit (S_ISVTX / S_ISTXT). */
+#define RTFS_UNIX_ISTXT 0001000U
+
+/** Owner RWX mask (S_IRWXU). */
+#define RTFS_UNIX_IRWXU 0000700U
+/** Owner readable (S_IRUSR). */
+#define RTFS_UNIX_IRUSR 0000400U
+/** Owner writable (S_IWUSR). */
+#define RTFS_UNIX_IWUSR 0000200U
+/** Owner executable (S_IXUSR). */
+#define RTFS_UNIX_IXUSR 0000100U
+
+/** Group RWX mask (S_IRWXG). */
+#define RTFS_UNIX_IRWXG 0000070U
+/** Group readable (S_IRGRP). */
+#define RTFS_UNIX_IRGRP 0000040U
+/** Group writable (S_IWGRP). */
+#define RTFS_UNIX_IWGRP 0000020U
+/** Group executable (S_IXGRP). */
+#define RTFS_UNIX_IXGRP 0000010U
+
+/** Other RWX mask (S_IRWXO). */
+#define RTFS_UNIX_IRWXO 0000007U
+/** Other readable (S_IROTH). */
+#define RTFS_UNIX_IROTH 0000004U
+/** Other writable (S_IWOTH). */
+#define RTFS_UNIX_IWOTH 0000002U
+/** Other executable (S_IXOTH). */
+#define RTFS_UNIX_IXOTH 0000001U
+
+/** Named pipe (fifo) (S_IFIFO). */
+#define RTFS_TYPE_FIFO 0010000U
+/** Character device (S_IFCHR). */
+#define RTFS_TYPE_DEV_CHAR 0020000U
+/** Directory (S_IFDIR). */
+#define RTFS_TYPE_DIRECTORY 0040000U
+/** Block device (S_IFBLK). */
+#define RTFS_TYPE_DEV_BLOCK 0060000U
+/** Regular file (S_IFREG). */
+#define RTFS_TYPE_FILE 0100000U
+/** Symbolic link (S_IFLNK). */
+#define RTFS_TYPE_SYMLINK 0120000U
+/** Socket (S_IFSOCK). */
+#define RTFS_TYPE_SOCKET 0140000U
+/** Whiteout (S_IFWHT). */
+#define RTFS_TYPE_WHITEOUT 0160000U
+/** Type mask (S_IFMT). */
+#define RTFS_TYPE_MASK 0170000U
+
+/** Unix attribute mask. */
+#define RTFS_UNIX_MASK 0xffffU
+/** The mask of all the NT, OS/2 and DOS attributes. */
+#define RTFS_DOS_MASK (0x7fffU << RTFS_DOS_SHIFT)
+
+/** The shift value. */
+#define RTFS_DOS_SHIFT 16
+/** The mask of the OS/2 and DOS attributes. */
+#define RTFS_DOS_MASK_OS2 (0x003fU << RTFS_DOS_SHIFT)
+/** The mask of the NT attributes. */
+#define RTFS_DOS_MASK_NT (0x7fffU << RTFS_DOS_SHIFT)
+
+/** Readonly object. */
+#define RTFS_DOS_READONLY (0x0001U << RTFS_DOS_SHIFT)
+/** Hidden object. */
+#define RTFS_DOS_HIDDEN (0x0002U << RTFS_DOS_SHIFT)
+/** System object. */
+#define RTFS_DOS_SYSTEM (0x0004U << RTFS_DOS_SHIFT)
+/** Directory. */
+#define RTFS_DOS_DIRECTORY (0x0010U << RTFS_DOS_SHIFT)
+/** Archived object.
+ * This bit is set by the filesystem after each modification of a file. */
+#define RTFS_DOS_ARCHIVED (0x0020U << RTFS_DOS_SHIFT)
+/** Undocumented / Reserved, used to be the FAT volume label. */
+#define RTFS_DOS_NT_DEVICE (0x0040U << RTFS_DOS_SHIFT)
+/** Normal object, no other attribute set (NT). */
+#define RTFS_DOS_NT_NORMAL (0x0080U << RTFS_DOS_SHIFT)
+/** Temporary object (NT). */
+#define RTFS_DOS_NT_TEMPORARY (0x0100U << RTFS_DOS_SHIFT)
+/** Sparse file (NT). */
+#define RTFS_DOS_NT_SPARSE_FILE (0x0200U << RTFS_DOS_SHIFT)
+/** Reparse point (NT). */
+#define RTFS_DOS_NT_REPARSE_POINT (0x0400U << RTFS_DOS_SHIFT)
+/** Compressed object (NT).
+ * For a directory, compression is the default for new files. */
+#define RTFS_DOS_NT_COMPRESSED (0x0800U << RTFS_DOS_SHIFT)
+/** Physically offline data (NT).
+ * MSDN say, don't mess with this one. */
+#define RTFS_DOS_NT_OFFLINE (0x1000U << RTFS_DOS_SHIFT)
+/** Not content indexed by the content indexing service (NT). */
+#define RTFS_DOS_NT_NOT_CONTENT_INDEXED (0x2000U << RTFS_DOS_SHIFT)
+/** Encryped object (NT).
+ * For a directory, encrypted is the default for new files. */
+#define RTFS_DOS_NT_ENCRYPTED (0x4000U << RTFS_DOS_SHIFT)
+
+/** @} */
+
+
+/** @name Filesystem Object Type Predicates.
+ * @{ */
+/** Checks the mode flags indicate a named pipe (fifo) (S_ISFIFO). */
+#define RTFS_IS_FIFO(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_FIFO )
+/** Checks the mode flags indicate a character device (S_ISCHR). */
+#define RTFS_IS_DEV_CHAR(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_DEV_CHAR )
+/** Checks the mode flags indicate a directory (S_ISDIR). */
+#define RTFS_IS_DIRECTORY(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_DIRECTORY )
+/** Checks the mode flags indicate a block device (S_ISBLK). */
+#define RTFS_IS_DEV_BLOCK(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_DEV_BLOCK )
+/** Checks the mode flags indicate a regular file (S_ISREG). */
+#define RTFS_IS_FILE(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_FILE )
+/** Checks the mode flags indicate a symbolic link (S_ISLNK). */
+#define RTFS_IS_SYMLINK(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_SYMLINK )
+/** Checks the mode flags indicate a socket (S_ISSOCK). */
+#define RTFS_IS_SOCKET(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_SOCKET )
+/** Checks the mode flags indicate a whiteout (S_ISWHT). */
+#define RTFS_IS_WHITEOUT(fMode) ( ((fMode) & RTFS_TYPE_MASK) == RTFS_TYPE_WHITEOUT )
+/** @} */
+
+
+/**
+ * Filesystem type IDs returned by RTFsQueryType.
+ *
+ * This enum is subject to changes and must not be used as part of any ABI or
+ * binary format (file, network, etc).
+ *
+ * @remarks When adding new entries, please update RTFsTypeName(). Also, try
+ * add them to the most natural group.
+ */
+typedef enum RTFSTYPE
+{
+ /** Unknown file system. */
+ RTFSTYPE_UNKNOWN = 0,
+
+ /** Universal Disk Format. */
+ RTFSTYPE_UDF,
+ /** ISO 9660, aka Compact Disc File System (CDFS). */
+ RTFSTYPE_ISO9660,
+ /** Filesystem in Userspace. */
+ RTFSTYPE_FUSE,
+ /** VirtualBox shared folders. */
+ RTFSTYPE_VBOXSHF,
+
+ /* Linux: */
+ RTFSTYPE_EXT,
+ RTFSTYPE_EXT2,
+ RTFSTYPE_EXT3,
+ RTFSTYPE_EXT4,
+ RTFSTYPE_XFS,
+ RTFSTYPE_CIFS,
+ RTFSTYPE_SMBFS,
+ RTFSTYPE_TMPFS,
+ RTFSTYPE_SYSFS,
+ RTFSTYPE_PROC,
+ RTFSTYPE_OCFS2,
+
+ /* Windows: */
+ /** New Technology File System. */
+ RTFSTYPE_NTFS,
+ /** FAT12, FAT16 and FAT32 lumped into one basket.
+ * The partition size limit of FAT12 and FAT16 will be the factor
+ * limiting the file size (except, perhaps for the 64KB cluster case on
+ * non-Windows hosts). */
+ RTFSTYPE_FAT,
+
+ /* Solaris: */
+ /** Zettabyte File System. */
+ RTFSTYPE_ZFS,
+ /** Unix File System. */
+ RTFSTYPE_UFS,
+ /** Network File System. */
+ RTFSTYPE_NFS,
+
+ /* Mac OS X: */
+ /** Hierarchical File System. */
+ RTFSTYPE_HFS,
+ /** @todo RTFSTYPE_HFS_PLUS? */
+ RTFSTYPE_AUTOFS,
+ RTFSTYPE_DEVFS,
+
+ /* *BSD: */
+
+ /* OS/2: */
+ /** High Performance File System. */
+ RTFSTYPE_HPFS,
+ /** Journaled File System (v2). */
+ RTFSTYPE_JFS,
+
+ /** The end of valid Filesystem types IDs. */
+ RTFSTYPE_END,
+ /** The usual 32-bit type blow up. */
+ RTFSTYPE_32BIT_HACK = 0x7fffffff
+} RTFSTYPE;
+/** Pointer to a Filesystem type ID. */
+typedef RTFSTYPE *PRTFSTYPE;
+
+
+/**
+ * The available additional information in a RTFSOBJATTR object.
+ */
+typedef enum RTFSOBJATTRADD
+{
+ /** No additional information is available / requested. */
+ RTFSOBJATTRADD_NOTHING = 1,
+ /** The additional unix attributes (RTFSOBJATTR::u::Unix) are available /
+ * requested. */
+ RTFSOBJATTRADD_UNIX,
+ /** The additional unix attributes (RTFSOBJATTR::u::UnixOwner) are
+ * available / requested. */
+ RTFSOBJATTRADD_UNIX_OWNER,
+ /** The additional unix attributes (RTFSOBJATTR::u::UnixGroup) are
+ * available / requested. */
+ RTFSOBJATTRADD_UNIX_GROUP,
+ /** The additional extended attribute size (RTFSOBJATTR::u::EASize) is available / requested. */
+ RTFSOBJATTRADD_EASIZE,
+ /** The last valid item (inclusive).
+ * The valid range is RTFSOBJATTRADD_NOTHING thru RTFSOBJATTRADD_LAST. */
+ RTFSOBJATTRADD_LAST = RTFSOBJATTRADD_EASIZE,
+
+ /** The usual 32-bit hack. */
+ RTFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff
+} RTFSOBJATTRADD;
+
+/** The number of bytes reserved for the additional attribute union. */
+#define RTFSOBJATTRUNION_MAX_SIZE 128
+
+/**
+ * Additional Unix Attributes (RTFSOBJATTRADD_UNIX).
+ */
+typedef struct RTFSOBJATTRUNIX
+{
+ /** The user owning the filesystem object (st_uid).
+ * This field is NIL_UID if not supported. */
+ RTUID uid;
+
+ /** The group the filesystem object is assigned (st_gid).
+ * This field is NIL_GID 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;
+} RTFSOBJATTRUNIX;
+
+
+/**
+ * Additional Unix Attributes (RTFSOBJATTRADD_UNIX_OWNER).
+ *
+ * @remarks This interface is mainly for TAR.
+ */
+typedef struct RTFSOBJATTRUNIXOWNER
+{
+ /** The user owning the filesystem object (st_uid).
+ * This field is NIL_UID if not supported. */
+ RTUID uid;
+ /** The user name.
+ * Empty if not available or not supported, truncated if too long. */
+ char szName[RTFSOBJATTRUNION_MAX_SIZE - sizeof(RTUID)];
+} RTFSOBJATTRUNIXOWNER;
+
+
+/**
+ * Additional Unix Attributes (RTFSOBJATTRADD_UNIX_GROUP).
+ *
+ * @remarks This interface is mainly for TAR.
+ */
+typedef struct RTFSOBJATTRUNIXGROUP
+{
+ /** The user owning the filesystem object (st_uid).
+ * This field is NIL_GID if not supported. */
+ RTGID gid;
+ /** The group name.
+ * Empty if not available or not supported, truncated if too long. */
+ char szName[RTFSOBJATTRUNION_MAX_SIZE - sizeof(RTGID)];
+} RTFSOBJATTRUNIXGROUP;
+
+
+/**
+ * Filesystem object attributes.
+ */
+typedef struct RTFSOBJATTR
+{
+ /** Mode flags (st_mode). RTFS_UNIX_*, RTFS_TYPE_*, and RTFS_DOS_*. */
+ RTFMODE fMode;
+
+ /** The additional attributes available. */
+ RTFSOBJATTRADD enmAdditional;
+
+ /**
+ * Additional attributes.
+ *
+ * Unless explicitly specified to an API, the API can provide additional
+ * data as it is provided by the underlying OS.
+ */
+ union RTFSOBJATTRUNION
+ {
+ /** Additional Unix Attributes - RTFSOBJATTRADD_UNIX. */
+ RTFSOBJATTRUNIX Unix;
+ /** Additional Unix Owner Attributes - RTFSOBJATTRADD_UNIX_OWNER. */
+ RTFSOBJATTRUNIXOWNER UnixOwner;
+ /** Additional Unix Group Attributes - RTFSOBJATTRADD_UNIX_GROUP. */
+ RTFSOBJATTRUNIXGROUP UnixGroup;
+
+ /**
+ * Extended attribute size is available when RTFS_DOS_HAVE_EA_SIZE is set.
+ */
+ struct RTFSOBJATTREASIZE
+ {
+ /** Size of EAs. */
+ RTFOFF cb;
+ } EASize;
+ /** Reserved space. */
+ uint8_t abReserveSpace[128];
+ } u;
+} RTFSOBJATTR;
+/** Pointer to a filesystem object attributes structure. */
+typedef RTFSOBJATTR *PRTFSOBJATTR;
+/** Pointer to a const filesystem object attributes structure. */
+typedef const RTFSOBJATTR *PCRTFSOBJATTR;
+
+
+/**
+ * Filesystem object information structure.
+ *
+ * This is returned by the RTPathQueryInfo(), RTFileQueryInfo() and RTDirRead() APIs.
+ */
+typedef struct RTFSOBJINFO
+{
+ /** 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). */
+ 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. */
+ RTFSOBJATTR Attr;
+
+} RTFSOBJINFO;
+/** Pointer to a filesystem object information structure. */
+typedef RTFSOBJINFO *PRTFSOBJINFO;
+/** Pointer to a const filesystem object information structure. */
+typedef const RTFSOBJINFO *PCRTFSOBJINFO;
+
+
+#ifdef IN_RING3
+
+/**
+ * Query the sizes of a filesystem.
+ *
+ * @returns iprt status code.
+ * @param pszFsPath Path within the mounted filesystem.
+ * @param pcbTotal Where to store the total filesystem space. (Optional)
+ * @param pcbFree Where to store the remaining free space in the filesystem. (Optional)
+ * @param pcbBlock Where to store the block size. (Optional)
+ * @param pcbSector Where to store the sector size. (Optional)
+ *
+ * @sa RTFileQueryFsSizes
+ */
+RTR3DECL(int) RTFsQuerySizes(const char *pszFsPath, PRTFOFF pcbTotal, RTFOFF *pcbFree,
+ uint32_t *pcbBlock, uint32_t *pcbSector);
+
+/**
+ * Query the mountpoint of a filesystem.
+ *
+ * @returns iprt status code.
+ * @returns VERR_BUFFER_OVERFLOW if cbMountpoint isn't enough.
+ * @param pszFsPath Path within the mounted filesystem.
+ * @param pszMountpoint Where to store the mountpoint path.
+ * @param cbMountpoint Size of the buffer pointed to by pszMountpoint.
+ */
+RTR3DECL(int) RTFsQueryMountpoint(const char *pszFsPath, char *pszMountpoint, size_t cbMountpoint);
+
+/**
+ * Query the label of a filesystem.
+ *
+ * @returns iprt status code.
+ * @returns VERR_BUFFER_OVERFLOW if cbLabel isn't enough.
+ * @param pszFsPath Path within the mounted filesystem.
+ * @param pszLabel Where to store the label.
+ * @param cbLabel Size of the buffer pointed to by pszLabel.
+ */
+RTR3DECL(int) RTFsQueryLabel(const char *pszFsPath, char *pszLabel, size_t cbLabel);
+
+/**
+ * Query the serial number of a filesystem.
+ *
+ * @returns iprt status code.
+ * @param pszFsPath Path within the mounted filesystem.
+ * @param pu32Serial Where to store the serial number.
+ */
+RTR3DECL(int) RTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial);
+
+/**
+ * Query the name of the filesystem driver.
+ *
+ * @returns iprt status code.
+ * @returns VERR_BUFFER_OVERFLOW if cbFsDriver isn't enough.
+ * @param pszFsPath Path within the mounted filesystem.
+ * @param pszFsDriver Where to store the filesystem driver name.
+ * @param cbFsDriver Size of the buffer pointed to by pszFsDriver.
+ */
+RTR3DECL(int) RTFsQueryDriver(const char *pszFsPath, char *pszFsDriver, size_t cbFsDriver);
+
+/**
+ * Query the name of the filesystem the file is located on.
+ *
+ * @returns iprt status code.
+ * @param pszFsPath Path within the mounted filesystem. It must exist.
+ * In case this is a symlink, the file it refers to is
+ * evaluated.
+ * @param penmType Where to store the filesystem type, this is always
+ * set. See RTFSTYPE for the values.
+ */
+RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType);
+
+#endif /* IN_RING3 */
+
+/**
+ * Gets the name of a filesystem type.
+ *
+ * @returns Pointer to a read-only string containing the name.
+ * @param enmType A valid filesystem ID. If outside the valid range,
+ * the returned string will be pointing to a static
+ * memory buffer which will be changed on subsequent
+ * calls to this function by any thread.
+ */
+RTDECL(const char *) RTFsTypeName(RTFSTYPE enmType);
+
+/**
+ * Filesystem properties.
+ */
+typedef struct RTFSPROPERTIES
+{
+ /** 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? */
+} RTFSPROPERTIES;
+/** Pointer to a filesystem properties structure. */
+typedef RTFSPROPERTIES *PRTFSPROPERTIES;
+/** Pointer to a const filesystem properties structure. */
+typedef RTFSPROPERTIES const *PCRTFSPROPERTIES;
+
+#ifdef IN_RING3
+
+/**
+ * Query the properties of a mounted filesystem.
+ *
+ * @returns iprt status code.
+ * @param pszFsPath Path within the mounted filesystem.
+ * @param pProperties Where to store the properties.
+ */
+RTR3DECL(int) RTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties);
+
+
+/**
+ * Mountpoint enumerator callback.
+ *
+ * @returns iprt status code. Failure terminates the enumeration.
+ * @param pszMountpoint The mountpoint name.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(int) FNRTFSMOUNTPOINTENUM(const char *pszMountpoint, void *pvUser);
+/** Pointer to a FNRTFSMOUNTPOINTENUM(). */
+typedef FNRTFSMOUNTPOINTENUM *PFNRTFSMOUNTPOINTENUM;
+
+/**
+ * Enumerate mount points.
+ *
+ * @returns iprt status code.
+ * @param pfnCallback The callback function.
+ * @param pvUser The user argument to the callback.
+ */
+RTR3DECL(int) RTFsMountpointsEnum(PFNRTFSMOUNTPOINTENUM pfnCallback, void *pvUser);
+
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !___iprt_fs_h */
+
diff --git a/include/iprt/getopt.h b/include/iprt/getopt.h
new file mode 100644
index 00000000..bf976cef
--- /dev/null
+++ b/include/iprt/getopt.h
@@ -0,0 +1,447 @@
+/** @file
+ * IPRT - Command Line Parsing.
+ */
+
+/*
+ * Copyright (C) 2007-2011 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * 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 ___iprt_getopt_h
+#define ___iprt_getopt_h
+
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_getopt RTGetOpt - Command Line Parsing
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @name Values for RTGETOPTDEF::fFlags and the fFlags parameter of
+ * RTGetOptFetchValue.
+ *
+ * @remarks When neither of the RTGETOPT_FLAG_HEX, RTGETOPT_FLAG_OCT and RTGETOPT_FLAG_DEC
+ * flags are specified with a integer value format, RTGetOpt will default to
+ * decimal but recognize the 0x prefix when present. RTGetOpt will not look for
+ * for the octal prefix (0).
+ * @{ */
+/** Requires no extra argument.
+ * (Can be assumed to be 0 for ever.) */
+#define RTGETOPT_REQ_NOTHING 0
+/** A value is required or error will be returned. */
+#define RTGETOPT_REQ_STRING 1
+/** The value must be a valid signed 8-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_INT8 2
+/** The value must be a valid unsigned 8-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_UINT8 3
+/** The value must be a valid signed 16-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_INT16 4
+/** The value must be a valid unsigned 16-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_UINT16 5
+/** The value must be a valid signed 32-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_INT32 6
+/** The value must be a valid unsigned 32-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_UINT32 7
+/** The value must be a valid signed 64-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_INT64 8
+/** The value must be a valid unsigned 64-bit integer or an error will be returned. */
+#define RTGETOPT_REQ_UINT64 9
+/** The value must be a valid IPv4 address.
+ * (Not a name, but 4 values in the 0..255 range with dots separating them). */
+#define RTGETOPT_REQ_IPV4ADDR 10
+#if 0
+/** The value must be a valid IPv4 CIDR.
+ * As with RTGETOPT_REQ_IPV4ADDR, no name.
+ * @todo Mix CIDR with types.h or/and net.h first and find a way to make the
+ * mask optional like with ifconfig. See RTCidrStrToIPv4. */
+#define RTGETOPT_REQ_IPV4CIDR 11
+#endif
+/** The value must be a valid ethernet MAC address. */
+#define RTGETOPT_REQ_MACADDR 14
+/** The value must be a valid UUID. */
+#define RTGETOPT_REQ_UUID 15
+/** The value must be a string with value as "on" or "off". */
+#define RTGETOPT_REQ_BOOL_ONOFF 16
+/** Boolean option accepting a wide range of typical ways of
+ * expression true and false. */
+#define RTGETOPT_REQ_BOOL 17
+/** The mask of the valid required types. */
+#define RTGETOPT_REQ_MASK 31
+/** Treat the value as hexadecimal - only applicable with the RTGETOPT_REQ_*INT*. */
+#define RTGETOPT_FLAG_HEX RT_BIT(16)
+/** Treat the value as octal - only applicable with the RTGETOPT_REQ_*INT*. */
+#define RTGETOPT_FLAG_OCT RT_BIT(17)
+/** Treat the value as decimal - only applicable with the RTGETOPT_REQ_*INT*. */
+#define RTGETOPT_FLAG_DEC RT_BIT(18)
+/** The index value is attached to the argument - only valid for long arguments. */
+#define RTGETOPT_FLAG_INDEX RT_BIT(19)
+/** Treat the long option as case insensitive. */
+#define RTGETOPT_FLAG_ICASE RT_BIT(20)
+/** Mask of valid bits - for validation. */
+#define RTGETOPT_VALID_MASK ( RTGETOPT_REQ_MASK \
+ | RTGETOPT_FLAG_HEX \
+ | RTGETOPT_FLAG_OCT \
+ | RTGETOPT_FLAG_DEC \
+ | RTGETOPT_FLAG_INDEX \
+ | RTGETOPT_FLAG_ICASE)
+/** @} */
+
+/**
+ * An option definition.
+ */
+typedef struct RTGETOPTDEF
+{
+ /** The long option.
+ * This is optional */
+ const char *pszLong;
+ /** The short option character.
+ * This doesn't have to be a character, it may also be a \#define or enum value if
+ * there isn't any short version of this option. Must be greater than 0. */
+ int iShort;
+ /** The flags (RTGETOPT_*). */
+ unsigned fFlags;
+} RTGETOPTDEF;
+/** Pointer to an option definition. */
+typedef RTGETOPTDEF *PRTGETOPTDEF;
+/** Pointer to an const option definition. */
+typedef const RTGETOPTDEF *PCRTGETOPTDEF;
+
+/**
+ * Option argument union.
+ *
+ * What ends up here depends on argument format in the option definition.
+ *
+ * @remarks Integers will bet put in the \a i and \a u members and sign/zero extended
+ * according to the signedness indicated by the \a fFlags. So, you can choose
+ * use which ever of the integer members for accessing the value regardless
+ * of restrictions indicated in the \a fFlags.
+ */
+typedef union RTGETOPTUNION
+{
+ /** Pointer to the definition on failure or when the option doesn't take an argument.
+ * This can be NULL for some errors. */
+ PCRTGETOPTDEF pDef;
+ /** A RTGETOPT_REQ_STRING option argument. */
+ const char *psz;
+
+ /** A RTGETOPT_REQ_INT8 option argument. */
+ int8_t i8;
+ /** A RTGETOPT_REQ_UINT8 option argument . */
+ uint8_t u8;
+ /** A RTGETOPT_REQ_INT16 option argument. */
+ int16_t i16;
+ /** A RTGETOPT_REQ_UINT16 option argument . */
+ uint16_t u16;
+ /** A RTGETOPT_REQ_INT16 option argument. */
+ int32_t i32;
+ /** A RTGETOPT_REQ_UINT32 option argument . */
+ uint32_t u32;
+ /** A RTGETOPT_REQ_INT64 option argument. */
+ int64_t i64;
+ /** A RTGETOPT_REQ_UINT64 option argument. */
+ uint64_t u64;
+#ifdef ___iprt_net_h
+ /** A RTGETOPT_REQ_IPV4ADDR option argument. */
+ RTNETADDRIPV4 IPv4Addr;
+#endif
+ /** A RTGETOPT_REQ_MACADDR option argument. */
+ RTMAC MacAddr;
+ /** A RTGETOPT_REQ_UUID option argument. */
+ RTUUID Uuid;
+ /** A boolean flag. */
+ bool f;
+} RTGETOPTUNION;
+/** Pointer to an option argument union. */
+typedef RTGETOPTUNION *PRTGETOPTUNION;
+/** Pointer to a const option argument union. */
+typedef RTGETOPTUNION const *PCRTGETOPTUNION;
+
+
+/**
+ * RTGetOpt state.
+ */
+typedef struct RTGETOPTSTATE
+{
+ /** The next argument. */
+ int iNext;
+ /** Argument array. */
+ char **argv;
+ /** Number of items in argv. */
+ int argc;
+ /** Option definition array. */
+ PCRTGETOPTDEF paOptions;
+ /** Number of items in paOptions. */
+ size_t cOptions;
+ /** The next short option.
+ * (For parsing ls -latrT4 kind of option lists.) */
+ const char *pszNextShort;
+ /** The option definition which matched. NULL otherwise. */
+ PCRTGETOPTDEF pDef;
+ /** The index of an index option, otherwise UINT32_MAX. */
+ uint32_t uIndex;
+ /** The flags passed to RTGetOptInit. */
+ uint32_t fFlags;
+ /** Number of non-options that we're skipping during a sorted get. The value
+ * INT32_MAX is used to indicate that there are no more options. This is used
+ * to implement '--'. */
+ int32_t cNonOptions;
+
+ /* More members may be added later for dealing with new features. */
+} RTGETOPTSTATE;
+/** Pointer to RTGetOpt state. */
+typedef RTGETOPTSTATE *PRTGETOPTSTATE;
+
+
+/**
+ * Initialize the RTGetOpt state.
+ *
+ * The passed in argument vector may be sorted if fFlags indicates that this is
+ * desired (to be implemented).
+ *
+ * @returns VINF_SUCCESS, VERR_INVALID_PARAMETER or VERR_INVALID_POINTER.
+ * @param pState The state.
+ *
+ * @param argc Argument count, to be copied from what comes in with
+ * main().
+ * @param argv Argument array, to be copied from what comes in with
+ * main(). This may end up being modified by the
+ * option/argument sorting.
+ * @param paOptions Array of RTGETOPTDEF structures, which must specify what
+ * options are understood by the program.
+ * @param cOptions Number of array items passed in with paOptions.
+ * @param iFirst The argument to start with (in argv).
+ * @param fFlags The flags, see RTGETOPTINIT_FLAGS_XXX.
+ */
+RTDECL(int) RTGetOptInit(PRTGETOPTSTATE pState, int argc, char **argv,
+ PCRTGETOPTDEF paOptions, size_t cOptions,
+ int iFirst, uint32_t fFlags);
+
+/** @name RTGetOptInit flags.
+ * @{ */
+/** Sort the arguments so that options comes first, then non-options. */
+#define RTGETOPTINIT_FLAGS_OPTS_FIRST RT_BIT_32(0)
+/** Prevent add the standard version and help options:
+ * - "--help", "-h" and "-?" returns 'h'.
+ * - "--version" and "-V" return 'V'.
+ */
+#define RTGETOPTINIT_FLAGS_NO_STD_OPTS RT_BIT_32(1)
+/** @} */
+
+/**
+ * Command line argument parser, handling both long and short options and checking
+ * argument formats, if desired.
+ *
+ * This is to be called in a loop until it returns 0 (meaning that all options
+ * were parsed) or a negative value (meaning that an error occurred). How non-option
+ * arguments are dealt with depends on the flags passed to RTGetOptInit. The default
+ * (fFlags = 0) is to return VINF_GETOPT_NOT_OPTION with pValueUnion->psz pointing to
+ * the argument string.
+ *
+ * For example, for a program which takes the following options:
+ *
+ * --optwithstring (or -s) and a string argument;
+ * --optwithint (or -i) and a 32-bit signed integer argument;
+ * --verbose (or -v) with no arguments,
+ *
+ * code would look something like this:
+ *
+ * @code
+int main(int argc, char **argv)
+{
+ int rc = RTR3Init();
+ if (RT_FAILURE(rc))
+ return RTMsgInitFailure(rc);
+
+ static const RTGETOPTDEF s_aOptions[] =
+ {
+ { "--optwithstring", 's', RTGETOPT_REQ_STRING },
+ { "--optwithint", 'i', RTGETOPT_REQ_INT32 },
+ { "--verbose", 'v', 0 },
+ };
+
+ int ch;
+ RTGETOPTUNION ValueUnion;
+ RTGETOPTSTATE GetState;
+ RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
+ while ((ch = RTGetOpt(&GetState, &ValueUnion)))
+ {
+ // for options that require an argument, ValueUnion has received the value
+ switch (ch)
+ {
+ case 's': // --optwithstring or -s
+ // string argument, copy ValueUnion.psz
+ break;
+
+ case 'i': // --optwithint or -i
+ // integer argument, copy ValueUnion.i32
+ break;
+
+ case 'v': // --verbose or -v
+ g_fOptVerbose = true;
+ break;
+
+ case VINF_GETOPT_NOT_OPTION:
+ // handle non-option argument in ValueUnion.psz.
+ break;
+
+ default:
+ return RTGetOptPrintError(ch, &ValueUnion);
+ }
+ }
+
+ return RTEXITCODE_SUCCESS;
+}
+ @endcode
+ *
+ * @returns 0 when done parsing.
+ * @returns the iShort value of the option. pState->pDef points to the option
+ * definition which matched.
+ * @returns IPRT error status on parse error.
+ * @returns VINF_GETOPT_NOT_OPTION when encountering a non-option argument and
+ * RTGETOPT_FLAG_SORT was not specified. pValueUnion->psz points to the
+ * argument string.
+ * @returns VERR_GETOPT_UNKNOWN_OPTION when encountering an unknown option.
+ * pValueUnion->psz points to the option string.
+ * @returns VERR_GETOPT_REQUIRED_ARGUMENT_MISSING and pValueUnion->pDef if
+ * a required argument (aka value) was missing for an option.
+ * @returns VERR_GETOPT_INVALID_ARGUMENT_FORMAT and pValueUnion->pDef if
+ * argument (aka value) conversion failed.
+ *
+ * @param pState The state previously initialized with RTGetOptInit.
+ * @param pValueUnion Union with value; in the event of an error, psz member
+ * points to erroneous parameter; otherwise, for options
+ * that require an argument, this contains the value of
+ * that argument, depending on the type that is required.
+ */
+RTDECL(int) RTGetOpt(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion);
+
+/**
+ * Fetch a value.
+ *
+ * Used to retrive a value argument in a manner similar to what RTGetOpt does
+ * (@a fFlags -> @a pValueUnion). This can be used when handling
+ * VINF_GETOPT_NOT_OPTION, but is equally useful for decoding options that
+ * takes more than one value.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns IPRT error status on parse error.
+ * @returns VERR_INVALID_PARAMETER if the flags are wrong.
+ * @returns VERR_GETOPT_UNKNOWN_OPTION when pState->pDef is null.
+ * @returns VERR_GETOPT_REQUIRED_ARGUMENT_MISSING if there are no more
+ * available arguments. pValueUnion->pDef is NULL.
+ * @returns VERR_GETOPT_INVALID_ARGUMENT_FORMAT and pValueUnion->pDef is
+ * unchanged if value conversion failed.
+ *
+ * @param pState The state previously initialized with RTGetOptInit.
+ * @param pValueUnion Union with value; in the event of an error, psz member
+ * points to erroneous parameter; otherwise, for options
+ * that require an argument, this contains the value of
+ * that argument, depending on the type that is required.
+ * @param fFlags What to get, that is RTGETOPT_REQ_XXX.
+ */
+RTDECL(int) RTGetOptFetchValue(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion, uint32_t fFlags);
+
+/**
+ * Print error messages for a RTGetOpt default case.
+ *
+ * Uses RTMsgError.
+ *
+ * @returns Suitable exit code.
+ *
+ * @param ch The RTGetOpt return value.
+ * @param pValueUnion The value union returned by RTGetOpt.
+ */
+RTDECL(RTEXITCODE) RTGetOptPrintError(int ch, PCRTGETOPTUNION pValueUnion);
+
+/**
+ * Parses the @a pszCmdLine string into an argv array.
+ *
+ * This is useful for converting a response file or similar to an argument
+ * vector that can be used with RTGetOptInit().
+ *
+ * This function aims at following the bourn shell string quoting rules.
+ *
+ * @returns IPRT status code.
+ *
+ * @param ppapszArgv Where to return the argument vector. This must be
+ * freed by calling RTGetOptArgvFree.
+ * @param pcArgs Where to return the argument count.
+ * @param pszCmdLine The string to parse.
+ * @param pszSeparators String containing the argument separators. If NULL,
+ * then space, tab, line feed (\\n) and return (\\r)
+ * are used.
+ */
+RTDECL(int) RTGetOptArgvFromString(char ***ppapszArgv, int *pcArgs, const char *pszCmdLine, const char *pszSeparators);
+
+/**
+ * Frees and argument vector returned by RTGetOptStringToArgv.
+ *
+ * @param papszArgv Argument vector. NULL is fine.
+ */
+RTDECL(void) RTGetOptArgvFree(char **paArgv);
+
+/**
+ * Turns an argv array into a command line string.
+ *
+ * This is useful for calling CreateProcess on Windows, but can also be used for
+ * displaying an argv array.
+ *
+ * This function aims at following the bourn shell string quoting rules.
+ *
+ * @returns IPRT status code.
+ *
+ * @param ppszCmdLine Where to return the command line string. This must
+ * be freed by calling RTStrFree.
+ * @param papszArgs The argument vector to convert.
+ * @param fFlags A combination of the RTGETOPTARGV_CNV_XXX flags.
+ */
+RTDECL(int) RTGetOptArgvToString(char **ppszCmdLine, const char * const *papszArgv, uint32_t fFlags);
+
+/** @name RTGetOptArgvToString and RTGetOptArgvToUtf16String flags
+ * @{ */
+/** Quote strings according to the Microsoft CRT rules. */
+#define RTGETOPTARGV_CNV_QUOTE_MS_CRT UINT32_C(0)
+/** Quote strings according to the Unix Bourne Shell. */
+#define RTGETOPTARGV_CNV_QUOTE_BOURNE_SH UINT32_C(1)
+/** Mask for the quoting style. */
+#define RTGETOPTARGV_CNV_QUOTE_MASK UINT32_C(1)
+/** @} */
+
+/**
+ * Convenience wrapper around RTGetOpArgvToString and RTStrToUtf16.
+ *
+ * @returns IPRT status code.
+ *
+ * @param ppwszCmdLine Where to return the command line string. This must
+ * be freed by calling RTUtf16Free.
+ * @param papszArgs The argument vector to convert.
+ * @param fFlags A combination of the RTGETOPTARGV_CNV_XXX flags.
+ */
+RTDECL(int) RTGetOptArgvToUtf16String(PRTUTF16 *ppwszCmdLine, const char * const *papszArgv, uint32_t fFlags);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/handle.h b/include/iprt/handle.h
new file mode 100644
index 00000000..2d06db10
--- /dev/null
+++ b/include/iprt/handle.h
@@ -0,0 +1,64 @@
+/** @file
+ * IPRT - Generic Handle Operations.
+ */
+
+/*
+ * 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 ___iprt_handle_h
+#define ___iprt_handle_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_handle RTHandle - Generic Handle Operations
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Closes or destroy a generic handle.
+ *
+ * @returns IPRT status code.
+ * @param ph Pointer to the generic handle. The structure handle
+ * will be set to NIL. A NULL pointer or a NIL handle
+ * will be quietly ignore (VINF_SUCCESS).
+ */
+RTDECL(int) RTHandleClose(PRTHANDLE ph);
+
+/**
+ * Gets one of the standard handles.
+ *
+ * @returns IPRT status code.
+ * @param enmStdHandle The standard handle.
+ * @param ph Pointer to the generic handle. This will contain
+ * the most appropriate IPRT handle on success.
+ */
+RTDECL(int) RTHandleGetStandard(RTHANDLESTD enmStdHandle, PRTHANDLE ph);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/handletable.h b/include/iprt/handletable.h
new file mode 100644
index 00000000..0ade7412
--- /dev/null
+++ b/include/iprt/handletable.h
@@ -0,0 +1,243 @@
+/** @file
+ * IPRT - Handle Tables.
+ */
+
+/*
+ * 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 ___iprt_handletable_h
+#define ___iprt_handletable_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_handletable RTHandleTable - Handle Tables
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Callback for retaining an object during the lookup and free calls.
+ *
+ * This callback is executed when a handle is being looked up in one
+ * way or another from behind the handle table lock. This allows you
+ * to increase the reference (or some equivalent thing) during the
+ * handle lookup and thereby eliminate any race with anyone trying
+ * to free the handle.
+ *
+ * Note that there is no counterpart to this callback, so if you make
+ * use of this you'll have to release the object manually of course.
+ *
+ * Another use of this callback is to do some extra access checking.
+ * Use the return code to indicate whether the lookup should fail
+ * or not (no object is returned on faliure, naturally).
+ *
+ * @returns IPRT status code for the lookup (the caller won't see this).
+ *
+ * @param hHandleTable The handle table handle.
+ * @param pvObj The object which has been looked up.
+ * @param pvCtx The context argument if the handle table was created with the
+ * RTHANDLETABLE_FLAGS_CONTEXT set. Otherwise NULL.
+ * @param pvUser The user context argument specified when creating the table.
+ */
+typedef DECLCALLBACK(int) FNRTHANDLETABLERETAIN(RTHANDLETABLE hHandleTable, void *pvObj, void *pvCtx, void *pvUser);
+/** Pointer to a FNHANDLETABLERETAIN. */
+typedef FNRTHANDLETABLERETAIN *PFNRTHANDLETABLERETAIN;
+
+/**
+ * Callback for deleting a left over object during RTHandleTableDestroy.
+ *
+ * @param hHandleTable The handle table handle.
+ * @param h The handle.
+ * @param pvObj The object.
+ * @param pvCtx The context argument if the handle table was created with the
+ * RTHANDLETABLE_FLAGS_CONTEXT set. Otherwise NULL.
+ * @param pvUser The user context argument specified when creating the table.
+ *
+ */
+typedef DECLCALLBACK(void) FNRTHANDLETABLEDELETE(RTHANDLETABLE hHandleTable, uint32_t h, void *pvObj, void *pvCtx, void *pvUser);
+/** Pointer to a FNRTHANDLETABLEDELETE. */
+typedef FNRTHANDLETABLEDELETE *PFNRTHANDLETABLEDELETE;
+
+
+/** @name RTHandleTableCreateEx flags
+ * @{ */
+/** Whether the handle table entries takes a context or not.
+ *
+ * This can be useful for associating a handle with for instance a process or
+ * similar in order to prevent anyone but the owner from using the handle.
+ *
+ * Setting this means you will have to use the WithCtx functions to do the
+ * handle management. */
+#define RTHANDLETABLE_FLAGS_CONTEXT RT_BIT_32(0)
+/** Whether the handle table should take care of the serialization.
+ * If not specified the caller will have to take care of that. */
+#define RTHANDLETABLE_FLAGS_LOCKED RT_BIT_32(1)
+/** The mask of valid flags. */
+#define RTHANDLETABLE_FLAGS_MASK UINT32_C(0x00000003)
+/** @} */
+
+
+/**
+ * Creates a handle table.
+ *
+ * The handle table translates a 32-bit handle into an object pointer,
+ * optionally calling you back so you can retain the object without
+ * racing RTHandleTableFree.
+ *
+ * @returns IPRT status code and on success a handle table handle will be stored at the
+ * location phHandleTable points at.
+ *
+ * @param phHandleTable Where to store the handle table handle on success.
+ * @param fFlags Flags, see RTHANDLETABLE_FLAGS_*.
+ * @param uBase The handle base value. This is the value of the
+ * first handle to be returned.
+ * @param cMax The max number of handles. When exceeded the RTHandleTableAlloc
+ * or RTHandleTableAllocWithCtx calls will fail. Note that this
+ * number will be rounded up to a multiple of the sub-table size,
+ * or if it's too close to UINT32_MAX it will be rounded down.
+ * @param pfnRetain Optional retain callback that will be called from behind the
+ * lock (if any) during lookup.
+ * @param pvUser The user argument to the retain callback.
+ */
+RTDECL(int) RTHandleTableCreateEx(PRTHANDLETABLE phHandleTable, uint32_t fFlags, uint32_t uBase, uint32_t cMax,
+ PFNRTHANDLETABLERETAIN pfnRetain, void *pvUser);
+
+/**
+ * A simplified version of the RTHandleTableCreateEx API.
+ *
+ * It assumes a max of about 64K handles with 1 being the base. The table
+ * access will serialized (RTHANDLETABLE_FLAGS_LOCKED).
+ *
+ * @returns IPRT status code and *phHandleTable.
+ *
+ * @param phHandleTable Where to store the handle table handle on success.
+ */
+RTDECL(int) RTHandleTableCreate(PRTHANDLETABLE phHandleTable);
+
+/**
+ * Destroys a handle table.
+ *
+ * If any entries are still in used the pfnDelete callback will be invoked
+ * on each of them (if specfied) to allow to you clean things up.
+ *
+ * @returns IPRT status code
+ *
+ * @param hHandleTable The handle to the handle table.
+ * @param pfnDelete Function to be called back on each handle still in use. Optional.
+ * @param pvUser The user argument to pfnDelete.
+ */
+RTDECL(int) RTHandleTableDestroy(RTHANDLETABLE hHandleTable, PFNRTHANDLETABLEDELETE pfnDelete, void *pvUser);
+
+/**
+ * Allocates a handle from the handle table.
+ *
+ * @returns IPRT status code, almost any.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NO_MEMORY if we failed to extend the handle table.
+ * @retval VERR_NO_MORE_HANDLES if we're out of handles.
+ *
+ * @param hHandleTable The handle to the handle table.
+ * @param pvObj The object to associate with the new handle.
+ * This must be aligned on a 4 byte boundary.
+ * @param ph Where to return the handle on success.
+ *
+ * @remarks Do not call this if RTHANDLETABLE_FLAGS_CONTEXT was used during creation.
+ */
+RTDECL(int) RTHandleTableAlloc(RTHANDLETABLE hHandleTable, void *pvObj, uint32_t *ph);
+
+/**
+ * Looks up a handle.
+ *
+ * @returns The object pointer on success. NULL on failure.
+ *
+ * @param hHandleTable The handle to the handle table.
+ * @param h The handle to lookup.
+ *
+ * @remarks Do not call this if RTHANDLETABLE_FLAGS_CONTEXT was used during creation.
+ */
+RTDECL(void *) RTHandleTableLookup(RTHANDLETABLE hHandleTable, uint32_t h);
+
+/**
+ * Looks up and frees a handle.
+ *
+ * @returns The object pointer on success. NULL on failure.
+ *
+ * @param hHandleTable The handle to the handle table.
+ * @param h The handle to lookup.
+ *
+ * @remarks Do not call this if RTHANDLETABLE_FLAGS_CONTEXT was used during creation.
+ */
+RTDECL(void *) RTHandleTableFree(RTHANDLETABLE hHandleTable, uint32_t h);
+
+/**
+ * Allocates a handle from the handle table.
+ *
+ * @returns IPRT status code, almost any.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NO_MEMORY if we failed to extend the handle table.
+ * @retval VERR_NO_MORE_HANDLES if we're out of handles.
+ *
+ * @param hHandleTable The handle to the handle table.
+ * @param pvObj The object to associate with the new handle.
+ * This must be aligned on a 4 byte boundary.
+ * @param pvCtx The context to associate with the new handle.
+ * @param ph Where to return the handle on success.
+ *
+ * @remarks Call this if RTHANDLETABLE_FLAGS_CONTEXT was used during creation.
+ */
+RTDECL(int) RTHandleTableAllocWithCtx(RTHANDLETABLE hHandleTable, void *pvObj, void *pvCtx, uint32_t *ph);
+
+/**
+ * Looks up a handle.
+ *
+ * @returns The object pointer on success. NULL on failure.
+ *
+ * @param hHandleTable The handle to the handle table.
+ * @param h The handle to lookup.
+ * @param pvCtx The handle context, this must match what was given on allocation.
+ *
+ * @remarks Call this if RTHANDLETABLE_FLAGS_CONTEXT was used during creation.
+ */
+RTDECL(void *) RTHandleTableLookupWithCtx(RTHANDLETABLE hHandleTable, uint32_t h, void *pvCtx);
+
+/**
+ * Looks up and frees a handle.
+ *
+ * @returns The object pointer on success. NULL on failure.
+ *
+ * @param hHandleTable The handle to the handle table.
+ * @param h The handle to lookup.
+ * @param pvCtx The handle context, this must match what was given on allocation.
+ *
+ * @remarks Call this if RTHANDLETABLE_FLAGS_CONTEXT was used during creation.
+ */
+RTDECL(void *) RTHandleTableFreeWithCtx(RTHANDLETABLE hHandleTable, uint32_t h, void *pvCtx);
+
+/** @} */
+
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/iprt/heap.h b/include/iprt/heap.h
new file mode 100644
index 00000000..f9e0c524
--- /dev/null
+++ b/include/iprt/heap.h
@@ -0,0 +1,356 @@
+/** @file
+ * IPRT - Heap Implementations
+ */
+
+/*
+ * 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 ___iprt_heap_h
+#define ___iprt_heap_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_heap RTHeap - Heap Implementations
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** @defgroup grp_rt_heap_simple RTHeapSimple - Simple Heap
+ * @{
+ */
+
+/**
+ * Initializes the heap.
+ *
+ * @returns IPRT status code.
+ * @param pHeap Where to store the heap anchor block on success.
+ * @param pvMemory Pointer to the heap memory.
+ * @param cbMemory The size of the heap memory.
+ */
+RTDECL(int) RTHeapSimpleInit(PRTHEAPSIMPLE pHeap, void *pvMemory, size_t cbMemory);
+
+/**
+ * Merge two simple heaps into one.
+ *
+ * The requirement is of course that they next two each other memory wise.
+ *
+ * @returns IPRT status code.
+ * @param pHeap Where to store the handle to the merged heap on success.
+ * @param Heap1 Handle to the first heap.
+ * @param Heap2 Handle to the second heap.
+ * @remark This API isn't implemented yet.
+ */
+RTDECL(int) RTHeapSimpleMerge(PRTHEAPSIMPLE pHeap, RTHEAPSIMPLE Heap1, RTHEAPSIMPLE Heap2);
+
+/**
+ * Relocater the heap internal structures after copying it to a new location.
+ *
+ * This can be used when loading a saved heap.
+ *
+ * @returns IPRT status code.
+ * @param hHeap Heap handle that has already been adjusted by to the new
+ * location. That is to say, when calling
+ * RTHeapSimpleInit, the caller must note the offset of the
+ * returned heap handle into the heap memory. This offset
+ * must be used when calcuating the handle value for the
+ * new location. The offset may in some cases not be zero!
+ * @param offDelta The delta between the new and old location, i.e. what
+ * should be added to the internal pointers.
+ */
+RTDECL(int) RTHeapSimpleRelocate(RTHEAPSIMPLE hHeap, uintptr_t offDelta);
+
+/**
+ * Allocates memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param Heap The heap to allocate the memory on.
+ * @param cb The requested heap block size.
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ * Must be a power of 2.
+ */
+RTDECL(void *) RTHeapSimpleAlloc(RTHEAPSIMPLE Heap, size_t cb, size_t cbAlignment);
+
+/**
+ * Allocates zeroed memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param Heap The heap to allocate the memory on.
+ * @param cb The requested heap block size.
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ * Must be a power of 2.
+ */
+RTDECL(void *) RTHeapSimpleAllocZ(RTHEAPSIMPLE Heap, size_t cb, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block.
+ *
+ * @param Heap The heap. This is optional and will only be used for strict assertions.
+ * @param pv The heap block returned by RTHeapSimple. If NULL it behaves like RTHeapSimpleAlloc().
+ * @param cbNew The new size of the heap block. If NULL it behaves like RTHeapSimpleFree().
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ * Must be a power of 2.
+ * @remark This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapSimpleRealloc(RTHEAPSIMPLE Heap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block, zeroing any new bits.
+ *
+ * @param Heap The heap. This is optional and will only be used for strict assertions.
+ * @param pv The heap block returned by RTHeapSimple. If NULL it behaves like RTHeapSimpleAllocZ().
+ * @param cbNew The new size of the heap block. If NULL it behaves like RTHeapSimpleFree().
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ * Must be a power of 2.
+ * @remark This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapSimpleReallocZ(RTHEAPSIMPLE Heap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Frees memory allocated from a simple heap.
+ *
+ * @param Heap The heap. This is optional and will only be used for strict assertions.
+ * @param pv The heap block returned by RTHeapSimple
+ */
+RTDECL(void) RTHeapSimpleFree(RTHEAPSIMPLE Heap, void *pv);
+
+/**
+ * Gets the size of the specified heap block.
+ *
+ * @returns The actual size of the heap block.
+ * @returns 0 if \a pv is NULL or it doesn't point to a valid heap block. An invalid \a pv
+ * can also cause traps or trigger assertions.
+ * @param Heap The heap. This is optional and will only be used for strict assertions.
+ * @param pv The heap block returned by RTHeapSimple
+ */
+RTDECL(size_t) RTHeapSimpleSize(RTHEAPSIMPLE Heap, void *pv);
+
+/**
+ * Gets the size of the heap.
+ *
+ * This size includes all the internal heap structures. So, even if the heap is
+ * empty the RTHeapSimpleGetFreeSize() will never reach the heap size returned
+ * by this function.
+ *
+ * @returns The heap size.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param Heap The heap.
+ */
+RTDECL(size_t) RTHeapSimpleGetHeapSize(RTHEAPSIMPLE Heap);
+
+/**
+ * Returns the sum of all free heap blocks.
+ *
+ * This is the amount of memory you can theoretically allocate
+ * if you do allocations exactly matching the free blocks.
+ *
+ * @returns The size of the free blocks.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param Heap The heap.
+ */
+RTDECL(size_t) RTHeapSimpleGetFreeSize(RTHEAPSIMPLE Heap);
+
+/**
+ * Printf like callbaclk function for RTHeapSimpleDump.
+ * @param pszFormat IPRT format string.
+ * @param ... Format arguments.
+ */
+typedef DECLCALLBACK(void) FNRTHEAPSIMPLEPRINTF(const char *pszFormat, ...);
+/** Pointer to a FNRTHEAPSIMPLEPRINTF function. */
+typedef FNRTHEAPSIMPLEPRINTF *PFNRTHEAPSIMPLEPRINTF;
+
+/**
+ * Dumps the hypervisor heap.
+ *
+ * @param Heap The heap handle.
+ * @param pfnPrintf Printf like function that groks IPRT formatting.
+ */
+RTDECL(void) RTHeapSimpleDump(RTHEAPSIMPLE Heap, PFNRTHEAPSIMPLEPRINTF pfnPrintf);
+
+/** @} */
+
+
+
+/** @defgroup grp_rt_heap_offset RTHeapOffset - Offset Based Heap
+ *
+ * This is a variation on the simple heap that doesn't use pointers internally
+ * and therefore can be saved and restored without any extra effort.
+ *
+ * @{
+ */
+
+/**
+ * Initializes the heap.
+ *
+ * @returns IPRT status code.
+ * @param phHeap Where to store the heap anchor block on success.
+ * @param pvMemory Pointer to the heap memory.
+ * @param cbMemory The size of the heap memory.
+ */
+RTDECL(int) RTHeapOffsetInit(PRTHEAPOFFSET phHeap, void *pvMemory, size_t cbMemory);
+
+/**
+ * Merge two simple heaps into one.
+ *
+ * The requirement is of course that they next two each other memory wise.
+ *
+ * @returns IPRT status code.
+ * @param phHeap Where to store the handle to the merged heap on success.
+ * @param hHeap1 Handle to the first heap.
+ * @param hHeap2 Handle to the second heap.
+ * @remark This API isn't implemented yet.
+ */
+RTDECL(int) RTHeapOffsetMerge(PRTHEAPOFFSET phHeap, RTHEAPOFFSET hHeap1, RTHEAPOFFSET hHeap2);
+
+/**
+ * Allocates memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param hHeap The heap to allocate the memory on.
+ * @param cb The requested heap block size.
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default alignment.
+ * Must be a power of 2.
+ */
+RTDECL(void *) RTHeapOffsetAlloc(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment);
+
+/**
+ * Allocates zeroed memory from the specified simple heap.
+ *
+ * @returns Pointer to the allocated memory block on success.
+ * @returns NULL if the request cannot be satisfied. (A VERR_NO_MEMORY condition.)
+ *
+ * @param hHeap The heap to allocate the memory on.
+ * @param cb The requested heap block size.
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default
+ * alignment. Must be a power of 2.
+ */
+RTDECL(void *) RTHeapOffsetAllocZ(RTHEAPOFFSET hHeap, size_t cb, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block.
+ *
+ * @param hHeap The heap handle. This is optional and will only be used
+ * for strict assertions.
+ * @param pv The heap block returned by RTHeapOffset. If NULL it
+ * behaves like RTHeapOffsetAlloc().
+ * @param cbNew The new size of the heap block. If NULL it behaves like
+ * RTHeapOffsetFree().
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default
+ * alignment. Must be a power of 2.
+ * @remark This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapOffsetRealloc(RTHEAPOFFSET hHeap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Reallocates / Allocates / Frees a heap block, zeroing any new bits.
+ *
+ * @param hHeap The heap handle. This is optional and will only be used
+ * for strict assertions.
+ * @param pv The heap block returned by RTHeapOffset. If NULL it
+ * behaves like RTHeapOffsetAllocZ().
+ * @param cbNew The new size of the heap block. If NULL it behaves like
+ * RTHeapOffsetFree().
+ * @param cbAlignment The requested heap block alignment. Pass 0 for default
+ * alignment. Must be a power of 2.
+ * @remark This API isn't implemented yet.
+ */
+RTDECL(void *) RTHeapOffsetReallocZ(RTHEAPOFFSET hHeap, void *pv, size_t cbNew, size_t cbAlignment);
+
+/**
+ * Frees memory allocated from a simple heap.
+ *
+ * @param hHeap The heap handle. This is optional and will only be used
+ * for strict assertions.
+ * @param pv The heap block returned by RTHeapOffset
+ */
+RTDECL(void) RTHeapOffsetFree(RTHEAPOFFSET hHeap, void *pv);
+
+/**
+ * Gets the size of the specified heap block.
+ *
+ * @returns The actual size of the heap block.
+ * @returns 0 if \a pv is NULL or it doesn't point to a valid heap block. An
+ * invalid \a pv can also cause traps or trigger assertions.
+ *
+ * @param hHeap The heap handle. This is optional and will only be used
+ * for strict assertions.
+ * @param pv The heap block returned by RTHeapOffset
+ */
+RTDECL(size_t) RTHeapOffsetSize(RTHEAPOFFSET hHeap, void *pv);
+
+/**
+ * Gets the size of the heap.
+ *
+ * This size includes all the internal heap structures. So, even if the heap is
+ * empty the RTHeapOffsetGetFreeSize() will never reach the heap size returned
+ * by this function.
+ *
+ * @returns The heap size.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param hHeap The heap handle.
+ */
+RTDECL(size_t) RTHeapOffsetGetHeapSize(RTHEAPOFFSET hHeap);
+
+/**
+ * Returns the sum of all free heap blocks.
+ *
+ * This is the amount of memory you can theoretically allocate
+ * if you do allocations exactly matching the free blocks.
+ *
+ * @returns The size of the free blocks.
+ * @returns 0 if heap was safely detected as being bad.
+ * @param hHeap The heap handle.
+ */
+RTDECL(size_t) RTHeapOffsetGetFreeSize(RTHEAPOFFSET hHeap);
+
+/**
+ * Printf like callbaclk function for RTHeapOffsetDump.
+ * @param pszFormat IPRT format string.
+ * @param ... Format arguments.
+ */
+typedef DECLCALLBACK(void) FNRTHEAPOFFSETPRINTF(const char *pszFormat, ...);
+/** Pointer to a FNRTHEAPOFFSETPRINTF function. */
+typedef FNRTHEAPOFFSETPRINTF *PFNRTHEAPOFFSETPRINTF;
+
+/**
+ * Dumps the hypervisor heap.
+ *
+ * @param hHeap The heap handle.
+ * @param pfnPrintf Printf like function that groks IPRT formatting.
+ */
+RTDECL(void) RTHeapOffsetDump(RTHEAPOFFSET hHeap, PFNRTHEAPOFFSETPRINTF pfnPrintf);
+
+/** @} */
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/initterm.h b/include/iprt/initterm.h
new file mode 100644
index 00000000..9fff94fc
--- /dev/null
+++ b/include/iprt/initterm.h
@@ -0,0 +1,238 @@
+/** @file
+ * IPRT - Runtime Init/Term.
+ */
+
+/*
+ * 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 ___iprt_initterm_h
+#define ___iprt_initterm_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt IPRT C/C++ APIs
+ * @{
+ */
+
+/** @defgroup grp_rt_initterm Init / Term
+ * @{
+ */
+
+#ifdef IN_RING3
+/** @name RTR3Init flags (RTR3INIT_XXX).
+ * @{ */
+/** Try initialize SUPLib. */
+#define RTR3INIT_FLAGS_SUPLIB RT_BIT(0)
+/** Initializing IPRT from a DLL. */
+#define RTR3INIT_FLAGS_DLL RT_BIT(1)
+/** @} */
+
+/** @name RTR3InitEx version
+ * @{ */
+/** Version 1. */
+#define RTR3INIT_VER_1 UINT32_C(1)
+/** The current version. */
+#define RTR3INIT_VER_CUR RTR3INIT_VER_1
+/** @} */
+
+/**
+ * Initializes the runtime library.
+ *
+ * @returns iprt status code.
+ * @param fFlags Flags, see RTR3INIT_XXX.
+ */
+RTR3DECL(int) RTR3InitExeNoArguments(uint32_t fFlags);
+
+/**
+ * Initializes the runtime library.
+ *
+ * @returns iprt status code.
+ * @param cArgs Pointer to the argument count.
+ * @param ppapszArgs Pointer to the argument vector pointer.
+ * @param fFlags Flags, see RTR3INIT_XXX.
+ */
+RTR3DECL(int) RTR3InitExe(int cArgs, char ***papszArgs, uint32_t fFlags);
+
+/**
+ * Initializes the runtime library.
+ *
+ * @returns iprt status code.
+ * @param fFlags Flags, see RTR3INIT_XXX.
+ */
+RTR3DECL(int) RTR3InitDll(uint32_t fFlags);
+
+/**
+ * Initializes the runtime library and possibly also SUPLib too.
+ *
+ * Avoid this interface, it's not considered stable.
+ *
+ * @returns IPRT status code.
+ * @param iVersion The interface version. Must be 0 atm.
+ * @param fFlags Flags, see RTR3INIT_XXX.
+ * @param cArgs Pointer to the argument count.
+ * @param ppapszArgs Pointer to the argument vector pointer. NULL
+ * allowed if @a cArgs is 0.
+ * @param pszProgramPath The program path. Pass NULL if we're to figure it
+ * out ourselves.
+ */
+RTR3DECL(int) RTR3InitEx(uint32_t iVersion, uint32_t fFlags, int cArgs, char ***papszArgs, const char *pszProgramPath);
+
+/**
+ * Terminates the runtime library.
+ */
+RTR3DECL(void) RTR3Term(void);
+
+#endif /* IN_RING3 */
+
+
+#ifdef IN_RING0
+/**
+ * Initializes the ring-0 driver runtime library.
+ *
+ * @returns iprt status code.
+ * @param fReserved Flags reserved for the future.
+ */
+RTR0DECL(int) RTR0Init(unsigned fReserved);
+
+/**
+ * Terminates the ring-0 driver runtime library.
+ */
+RTR0DECL(void) RTR0Term(void);
+
+/**
+ * Forcibily terminates the ring-0 driver runtime library.
+ *
+ * This should be used when statically linking the IPRT. Module using dynamic
+ * linking shall use RTR0Term. If you're not sure, use RTR0Term!
+ */
+RTR0DECL(void) RTR0TermForced(void);
+#endif
+
+#ifdef IN_RC
+/**
+ * Initializes the raw-mode context runtime library.
+ *
+ * @returns iprt status code.
+ *
+ * @param u64ProgramStartNanoTS The startup timestamp.
+ */
+RTRCDECL(int) RTRCInit(uint64_t u64ProgramStartNanoTS);
+
+/**
+ * Terminates the raw-mode context runtime library.
+ */
+RTRCDECL(void) RTRCTerm(void);
+#endif
+
+
+/**
+ * Termination reason.
+ */
+typedef enum RTTERMREASON
+{
+ /** Normal exit. iStatus contains the exit code. */
+ RTTERMREASON_EXIT = 1,
+ /** Any abnormal exit. iStatus is 0 and has no meaning. */
+ RTTERMREASON_ABEND,
+ /** Killed by a signal. The iStatus contains the signal number. */
+ RTTERMREASON_SIGNAL,
+ /** The IPRT module is being unloaded. iStatus is 0 and has no meaning. */
+ RTTERMREASON_UNLOAD
+} RTTERMREASON;
+
+/** Whether lazy clean up is Okay or not.
+ * When the process is exiting, it is a waste of time to for instance free heap
+ * memory or close open files. OTOH, when the runtime is unloaded from the
+ * process, it is important to release absolutely all resources to prevent
+ * resource leaks. */
+#define RTTERMREASON_IS_LAZY_CLEANUP_OK(enmReason) ((enmReason) != RTTERMREASON_UNLOAD)
+
+
+/**
+ * IPRT termination callback function.
+ *
+ * @param enmReason The cause of the termination.
+ * @param iStatus The meaning of this depends on enmReason.
+ * @param pvUser User argument passed to RTTermRegisterCallback.
+ */
+typedef DECLCALLBACK(void) FNRTTERMCALLBACK(RTTERMREASON enmReason, int32_t iStatus, void *pvUser);
+/** Pointer to an IPRT termination callback function. */
+typedef FNRTTERMCALLBACK *PFNRTTERMCALLBACK;
+
+
+/**
+ * Registers a termination callback.
+ *
+ * This is intended for performing clean up during IPRT termination. Frequently
+ * paired with lazy initialization thru RTOnce.
+ *
+ * The callbacks are called in LIFO order.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pfnCallback The callback function.
+ * @param pvUser The user argument for the callback.
+ *
+ * @remarks May need to acquire a fast mutex or critical section, so use with
+ * some care in ring-0 context.
+ *
+ * @remarks Be very careful using this from code that may be unloaded before
+ * IPRT terminates. Unlike some atexit and on_exit implementations,
+ * IPRT will not automatically unregister callbacks when a module gets
+ * unloaded.
+ */
+RTDECL(int) RTTermRegisterCallback(PFNRTTERMCALLBACK pfnCallback, void *pvUser);
+
+/**
+ * Deregister a termination callback.
+ *
+ * @returns VINF_SUCCESS if found, VERR_NOT_FOUND if the callback/pvUser pair
+ * wasn't found.
+ *
+ * @param pfnCallback The callback function.
+ * @param pvUser The user argument for the callback.
+ */
+RTDECL(int) RTTermDeregisterCallback(PFNRTTERMCALLBACK pfnCallback, void *pvUser);
+
+/**
+ * Runs the termination callback queue.
+ *
+ * Normally called by an internal IPRT termination function, but may also be
+ * called by external code immediately prior to terminating IPRT if it is in a
+ * better position to state the termination reason and/or status.
+ *
+ * @param enmReason The reason why it's called.
+ * @param iStatus The associated exit status or signal number.
+ */
+RTDECL(void) RTTermRunCallbacks(RTTERMREASON enmReason, int32_t iStatus);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/iprt/isofs.h b/include/iprt/isofs.h
new file mode 100644
index 00000000..c7774cd9
--- /dev/null
+++ b/include/iprt/isofs.h
@@ -0,0 +1,225 @@
+/** @file
+ * IPRT - ISO 9660 file system handling.
+ */
+
+/*
+ * 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 ___iprt_isofs_h
+#define ___iprt_isofs_h
+
+#include <iprt/types.h>
+#include <iprt/list.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_isofs RTIsoFs - ISO 9660 Filesystem
+ * @ingroup grp_rt
+ * @{
+ */
+
+#define RTISOFS_MAX_SYSTEM_ID 32
+#define RTISOFS_MAX_VOLUME_ID 32
+#define RTISOFS_MAX_PUBLISHER_ID 128
+#define RTISOFS_MAX_VOLUME_ID 32
+#define RTISOFS_MAX_VOLUMESET_ID 128
+#define RTISOFS_MAX_PREPARER_ID 128
+#define RTISOFS_MAX_APPLICATION_ID 128
+#define RTISOFS_MAX_STRING_LEN 255
+
+/** Standard ID of volume descriptors. */
+#define RTISOFS_STANDARD_ID "CD001"
+
+/** Default sector size. */
+#define RTISOFS_SECTOR_SIZE 2048
+
+
+#pragma pack(1)
+typedef struct RTISOFSDATESHORT
+{
+ uint8_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hour;
+ uint8_t minute;
+ uint8_t second;
+ int8_t gmt_offset;
+} RTISOFSDATESHORT, *PRTISOFSDATESHORT;
+
+typedef struct RTISOFSDATELONG
+{
+ char year[4];
+ char month[2];
+ char day[2];
+ char hour[2];
+ char minute[2];
+ char second[2];
+ char hseconds[2];
+ int8_t gmt_offset;
+} RTISOFSDATELONG, *PRTISOFSDATELONG;
+
+/* Directory Record. */
+typedef struct RTISOFSDIRRECORD
+{
+ uint8_t record_length;
+ uint8_t extented_attr_length;
+ uint32_t extent_location;
+ uint32_t extent_location_big;
+ uint32_t extent_data_length; /* Number of bytes (file) / len (directory). */
+ uint32_t extent_data_length_big;
+ RTISOFSDATESHORT date;
+ uint8_t flags;
+ uint8_t interleave_unit_size;
+ uint8_t interleave_gap_size;
+ uint16_t volume_sequence_number;
+ uint16_t volume_sequence_number_big;
+ uint8_t name_len;
+ /* Starting here there will be the actual directory entry name
+ * and a padding of 1 byte if name_len is odd. */
+} RTISOFSDIRRECORD, *PRTISOFSDIRRECORD;
+
+/* Primary Volume Descriptor. */
+typedef struct RTISOFSPRIVOLDESC
+{
+ uint8_t type;
+ char name_id[6];
+ uint8_t version;
+ char system_id[RTISOFS_MAX_SYSTEM_ID];
+ char volume_id[RTISOFS_MAX_VOLUME_ID];
+ uint8_t unused2[8];
+ uint32_t volume_space_size; /* Number of sectors, Little Endian. */
+ uint32_t volume_space_size_big; /* Number of sectors Big Endian. */
+ uint8_t unused3[32];
+ uint16_t volume_set_size;
+ uint16_t volume_set_size_big;
+ uint16_t volume_sequence_number;
+ uint16_t volume_sequence_number_big;
+ uint16_t logical_block_size; /* 2048. */
+ uint16_t logical_block_size_big;
+ uint32_t path_table_size; /* Size in bytes. */
+ uint32_t path_table_size_big; /* Size in bytes. */
+ uint32_t path_table_start_first;
+ uint32_t path_table_start_second;
+ uint32_t path_table_start_first_big;
+ uint32_t path_table_start_second_big;
+ RTISOFSDIRRECORD root_directory_record;
+ uint8_t directory_padding;
+ char volume_set_id[RTISOFS_MAX_VOLUMESET_ID];
+ char publisher_id[RTISOFS_MAX_PUBLISHER_ID];
+ char preparer_id[RTISOFS_MAX_PREPARER_ID];
+ char application_id[RTISOFS_MAX_APPLICATION_ID];
+ char copyright_file_id[37];
+ char abstract_file_id[37];
+ char bibliographic_file_id[37];
+ RTISOFSDATELONG creation_date;
+ RTISOFSDATELONG modification_date;
+ RTISOFSDATELONG expiration_date;
+ RTISOFSDATELONG effective_date;
+ uint8_t file_structure_version;
+ uint8_t unused4[1];
+ char application_data[512];
+ uint8_t unused5[653];
+} RTISOFSPRIVOLDESC, *PRTISOFSPRIVOLDESC;
+
+typedef struct RTISOFSPATHTABLEHEADER
+{
+ uint8_t length;
+ uint8_t extended_attr_sectors;
+ /** Sector of starting directory table. */
+ uint32_t sector_dir_table;
+ /** Index of parent directory (1 for the root). */
+ uint16_t parent_index;
+ /* Starting here there will be the name of the directory,
+ * specified by length above. */
+} RTISOFSPATHTABLEHEADER, *PRTISOFSPATHTABLEHEADER;
+
+typedef struct RTISOFSPATHTABLEENTRY
+{
+ char *path;
+ char *path_full;
+ RTISOFSPATHTABLEHEADER header;
+ RTLISTNODE Node;
+} RTISOFSPATHTABLEENTRY, *PRTISOFSPATHTABLEENTRY;
+
+typedef struct RTISOFSFILE
+{
+ RTFILE file;
+ RTLISTANCHOR listPaths;
+ RTISOFSPRIVOLDESC pvd;
+} RTISOFSFILE, *PRTISOFSFILE;
+#pragma pack()
+
+
+#ifdef IN_RING3
+/**
+ * Opens an ISO file.
+ *
+ * The following limitations apply:
+ * - Fixed sector size (2048 bytes).
+ * - No extensions (Joliet, RockRidge etc.) support (yet).
+ * - Only primary volume descriptor (PVD) handled.
+ *
+ * @return IPRT status code.
+ * @param pFile Pointer to ISO handle.
+ * @param pszFileName Path to ISO file to open.
+ */
+RTR3DECL(int) RTIsoFsOpen(PRTISOFSFILE pFile, const char *pszFileName);
+
+/**
+ * Closes an ISO file.
+ *
+ * @param pFile Pointer to open ISO file returned by RTIsoFsOpen().
+ */
+RTR3DECL(void) RTIsoFsClose(PRTISOFSFILE pFile);
+
+/**
+ * Retrieves the offset + length (both in bytes) of a given file
+ * stored in the ISO.
+ * @note According to the standard, a file cannot be larger than 2^32-1 bytes.
+ * Therefore using size_t / uint32_t is not a problem.
+ *
+ * @return IPRT status code.
+ * @param pFile Pointer to open ISO file returned by RTIsoFsOpen().
+ * @param pszPath Path of file within the ISO to retrieve information for.
+ * @param pcbOffset Pointer to store the file's absolute offset within the ISO.
+ * @param pcbLength Pointer to store the file's size.
+ */
+RTR3DECL(int) RTIsoFsGetFileInfo(PRTISOFSFILE pFile, const char *pszPath,
+ uint32_t *pcbOffset, size_t *pcbLength);
+
+/**
+ * Extracts a file from an ISO to the given destination.
+ *
+ * @return IPRT status code.
+ * @param pFile Pointer to open ISO file returned by RTIsoFsOpen().
+ * @param pszPath Path of file within the ISO to extract.
+ * @param pszDest Where to store the extracted file.
+ */
+RTR3DECL(int) RTIsoFsExtractFile(PRTISOFSFILE pFile, const char *pszSource,
+ const char *pszDest);
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/ldr.h b/include/iprt/ldr.h
new file mode 100644
index 00000000..9e036d83
--- /dev/null
+++ b/include/iprt/ldr.h
@@ -0,0 +1,559 @@
+/** @file
+ * IPRT - Loader.
+ */
+
+/*
+ * 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 ___iprt_ldr_h
+#define ___iprt_ldr_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+/** @defgroup grp_ldr RTLdr - Loader
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+RT_C_DECLS_BEGIN
+
+/** Loader address (unsigned integer). */
+typedef RTUINTPTR RTLDRADDR;
+/** Pointer to a loader address. */
+typedef RTLDRADDR *PRTLDRADDR;
+/** Pointer to a const loader address. */
+typedef RTLDRADDR const *PCRTLDRADDR;
+/** The max loader address value. */
+#define RTLDRADDR_MAX RTUINTPTR_MAX
+/** NIL loader address value. */
+#define NIL_RTLDRADDR RTLDRADDR_MAX
+
+
+/**
+ * Gets the default file suffix for DLL/SO/DYLIB/whatever.
+ *
+ * @returns The stuff (readonly).
+ */
+RTDECL(const char *) RTLdrGetSuff(void);
+
+/**
+ * Checks if a library is loadable or not.
+ *
+ * This may attempt load and unload the library.
+ *
+ * @returns true/false accordingly.
+ * @param pszFilename Image filename.
+ */
+RTDECL(bool) RTLdrIsLoadable(const char *pszFilename);
+
+/**
+ * Loads a dynamic load library (/shared object) image file using native
+ * OS facilities.
+ *
+ * The filename will be appended the default DLL/SO extension of
+ * the platform if it have been omitted. This means that it's not
+ * possible to load DLLs/SOs with no extension using this interface,
+ * but that's not a bad tradeoff.
+ *
+ * If no path is specified in the filename, the OS will usually search it's library
+ * path to find the image file.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Image filename.
+ * @param phLdrMod Where to store the handle to the loader module.
+ */
+RTDECL(int) RTLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod);
+
+/**
+ * Loads a dynamic load library (/shared object) image file using native
+ * OS facilities.
+ *
+ * The filename will be appended the default DLL/SO extension of
+ * the platform if it have been omitted. This means that it's not
+ * possible to load DLLs/SOs with no extension using this interface,
+ * but that's not a bad tradeoff.
+ *
+ * If no path is specified in the filename, the OS will usually search it's library
+ * path to find the image file.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Image filename.
+ * @param phLdrMod Where to store the handle to the loader module.
+ * @param fFlags See RTLDRLOAD_FLAGS_XXX.
+ * @param pErrInfo Where to return extended error information. Optional.
+ */
+RTDECL(int) RTLdrLoadEx(const char *pszFilename, PRTLDRMOD phLdrMod, uint32_t fFlags, PRTERRINFO pErrInfo);
+
+/** @defgroup RTLDRLOAD_FLAGS_XXX RTLdrLoadEx flags.
+ * @{ */
+/** Symbols defined in this library are not made available to resolve
+ * references in subsequently loaded libraries (default). */
+#define RTLDRLOAD_FLAGS_LOCAL UINT32_C(0)
+/** Symbols defined in this library will be made available for symbol
+ * resolution of subsequently loaded libraries. */
+#define RTLDRLOAD_FLAGS_GLOBAL RT_BIT_32(0)
+/** The mask of valid flag bits. */
+#define RTLDRLOAD_FLAGS_VALID_MASK UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Loads a dynamic load library (/shared object) image file residing in the
+ * RTPathAppPrivateArch() directory.
+ *
+ * Suffix is not required.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Image filename. No path.
+ * @param phLdrMod Where to store the handle to the loaded module.
+ */
+RTDECL(int) RTLdrLoadAppPriv(const char *pszFilename, PRTLDRMOD phLdrMod);
+
+/**
+ * Image architecuture specifier for RTLdrOpenEx.
+ */
+typedef enum RTLDRARCH
+{
+ RTLDRARCH_INVALID = 0,
+ /** Whatever. */
+ RTLDRARCH_WHATEVER,
+ /** The host architecture. */
+ RTLDRARCH_HOST,
+ /** 32-bit x86. */
+ RTLDRARCH_X86_32,
+ /** AMD64 (64-bit x86 if you like). */
+ RTLDRARCH_AMD64,
+ /** End of the valid values. */
+ RTLDRARCH_END,
+ /** Make sure the type is a full 32-bit. */
+ RTLDRARCH_32BIT_HACK = 0x7fffffff
+} RTLDRARCH;
+/** Pointer to a RTLDRARCH. */
+typedef RTLDRARCH *PRTLDRARCH;
+
+/**
+ * Open a binary image file, extended version.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Image filename.
+ * @param fFlags Reserved, MBZ.
+ * @param enmArch CPU architecture specifier for the image to be loaded.
+ * @param phLdrMod Where to store the handle to the loader module.
+ */
+RTDECL(int) RTLdrOpen(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod);
+
+/**
+ * Opens a binary image file using kLdr.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Image filename.
+ * @param phLdrMod Where to store the handle to the loaded module.
+ * @param fFlags Reserved, MBZ.
+ * @param enmArch CPU architecture specifier for the image to be loaded.
+ * @remark Primarily for testing the loader.
+ */
+RTDECL(int) RTLdrOpenkLdr(const char *pszFilename, uint32_t fFlags, RTLDRARCH enmArch, PRTLDRMOD phLdrMod);
+
+/**
+ * What to expect and do with the bits passed to RTLdrOpenBits().
+ */
+typedef enum RTLDROPENBITS
+{
+ /** The usual invalid 0 entry. */
+ RTLDROPENBITS_INVALID = 0,
+ /** The bits are readonly and will never be changed. */
+ RTLDROPENBITS_READONLY,
+ /** The bits are going to be changed and the loader will have to duplicate them
+ * when opening the image. */
+ RTLDROPENBITS_WRITABLE,
+ /** The bits are both the source and destination for the loader operation.
+ * This means that the loader may have to duplicate them prior to changing them. */
+ RTLDROPENBITS_SRC_AND_DST,
+ /** The end of the valid enums. This entry marks the
+ * first invalid entry.. */
+ RTLDROPENBITS_END,
+ RTLDROPENBITS_32BIT_HACK = 0x7fffffff
+} RTLDROPENBITS;
+
+/**
+ * Open a binary image from in-memory bits.
+ *
+ * @returns iprt status code.
+ * @param pvBits The start of the raw-image.
+ * @param cbBits The size of the raw-image.
+ * @param enmBits What to expect from the pvBits.
+ * @param pszLogName What to call the raw-image when logging.
+ * For RTLdrLoad and RTLdrOpen the filename is used for this.
+ * @param phLdrMod Where to store the handle to the loader module.
+ */
+RTDECL(int) RTLdrOpenBits(const void *pvBits, size_t cbBits, RTLDROPENBITS enmBits, const char *pszLogName, PRTLDRMOD phLdrMod);
+
+/**
+ * Closes a loader module handle.
+ *
+ * The handle can be obtained using any of the RTLdrLoad(), RTLdrOpen()
+ * and RTLdrOpenBits() functions.
+ *
+ * @returns iprt status code.
+ * @param hLdrMod The loader module handle.
+ */
+RTDECL(int) RTLdrClose(RTLDRMOD hLdrMod);
+
+/**
+ * Gets the address of a named exported symbol.
+ *
+ * @returns iprt status code.
+ * @param hLdrMod The loader module handle.
+ * @param pszSymbol Symbol name.
+ * @param ppvValue Where to store the symbol value. Note that this is restricted to the
+ * pointer size used on the host!
+ */
+RTDECL(int) RTLdrGetSymbol(RTLDRMOD hLdrMod, const char *pszSymbol, void **ppvValue);
+
+/**
+ * Gets the address of a named exported symbol.
+ *
+ * This function differs from the plain one in that it can deal with
+ * both GC and HC address sizes, and that it can calculate the symbol
+ * value relative to any given base address.
+ *
+ * @returns iprt status code.
+ * @param hLdrMod The loader module handle.
+ * @param pvBits Optional pointer to the loaded image.
+ * Set this to NULL if no RTLdrGetBits() processed image bits are available.
+ * Not supported for RTLdrLoad() images.
+ * @param BaseAddress Image load address.
+ * Not supported for RTLdrLoad() images.
+ * @param pszSymbol Symbol name.
+ * @param pValue Where to store the symbol value.
+ */
+RTDECL(int) RTLdrGetSymbolEx(RTLDRMOD hLdrMod, const void *pvBits, RTLDRADDR BaseAddress, const char *pszSymbol,
+ PRTLDRADDR pValue);
+
+/**
+ * Gets the size of the loaded image.
+ * This is only supported for modules which has been opened using RTLdrOpen() and RTLdrOpenBits().
+ *
+ * @returns image size (in bytes).
+ * @returns ~(size_t)0 on if not opened by RTLdrOpen().
+ * @param hLdrMod Handle to the loader module.
+ * @remark Not supported for RTLdrLoad() images.
+ */
+RTDECL(size_t) RTLdrSize(RTLDRMOD hLdrMod);
+
+/**
+ * Resolve an external symbol during RTLdrGetBits().
+ *
+ * @returns iprt status code.
+ * @param hLdrMod The loader module handle.
+ * @param pszModule Module name.
+ * @param pszSymbol Symbol name, NULL if uSymbol should be used.
+ * @param uSymbol Symbol ordinal, ~0 if pszSymbol should be used.
+ * @param pValue Where to store the symbol value (address).
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) RTLDRIMPORT(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol,
+ PRTLDRADDR pValue, void *pvUser);
+/** Pointer to a FNRTLDRIMPORT() callback function. */
+typedef RTLDRIMPORT *PFNRTLDRIMPORT;
+
+/**
+ * Loads the image into a buffer provided by the user and applies fixups
+ * for the given base address.
+ *
+ * @returns iprt status code.
+ * @param hLdrMod The load module handle.
+ * @param pvBits Where to put the bits.
+ * Must be as large as RTLdrSize() suggests.
+ * @param BaseAddress The base address.
+ * @param pfnGetImport Callback function for resolving imports one by one.
+ * @param pvUser User argument for the callback.
+ * @remark Not supported for RTLdrLoad() images.
+ */
+RTDECL(int) RTLdrGetBits(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR BaseAddress, PFNRTLDRIMPORT pfnGetImport, void *pvUser);
+
+/**
+ * Relocates bits after getting them.
+ * Useful for code which moves around a bit.
+ *
+ * @returns iprt status code.
+ * @param hLdrMod The loader module handle.
+ * @param pvBits Where the image bits are.
+ * Must have been passed to RTLdrGetBits().
+ * @param NewBaseAddress The new base address.
+ * @param OldBaseAddress The old base address.
+ * @param pfnGetImport Callback function for resolving imports one by one.
+ * @param pvUser User argument for the callback.
+ * @remark Not supported for RTLdrLoad() images.
+ */
+RTDECL(int) RTLdrRelocate(RTLDRMOD hLdrMod, void *pvBits, RTLDRADDR NewBaseAddress, RTLDRADDR OldBaseAddress,
+ PFNRTLDRIMPORT pfnGetImport, void *pvUser);
+
+/**
+ * Enumeration callback function used by RTLdrEnumSymbols().
+ *
+ * @returns iprt status code. Failure will stop the enumeration.
+ * @param hLdrMod The loader module handle.
+ * @param pszSymbol Symbol name. NULL if ordinal only.
+ * @param uSymbol Symbol ordinal, ~0 if not used.
+ * @param Value Symbol value.
+ * @param pvUser The user argument specified to RTLdrEnumSymbols().
+ */
+typedef DECLCALLBACK(int) RTLDRENUMSYMS(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTLDRADDR Value, void *pvUser);
+/** Pointer to a RTLDRENUMSYMS() callback function. */
+typedef RTLDRENUMSYMS *PFNRTLDRENUMSYMS;
+
+/**
+ * Enumerates all symbols in a module.
+ *
+ * @returns iprt status code.
+ * @param hLdrMod The loader module handle.
+ * @param fFlags Flags indicating what to return and such.
+ * @param pvBits Optional pointer to the loaded image. (RTLDR_ENUM_SYMBOL_FLAGS_*)
+ * Set this to NULL if no RTLdrGetBits() processed image bits are available.
+ * @param BaseAddress Image load address.
+ * @param pfnCallback Callback function.
+ * @param pvUser User argument for the callback.
+ * @remark Not supported for RTLdrLoad() images.
+ */
+RTDECL(int) RTLdrEnumSymbols(RTLDRMOD hLdrMod, unsigned fFlags, const void *pvBits, RTLDRADDR BaseAddress, PFNRTLDRENUMSYMS pfnCallback, void *pvUser);
+
+/** @name RTLdrEnumSymbols flags.
+ * @{ */
+/** Returns ALL kinds of symbols. The default is to only return public/exported symbols. */
+#define RTLDR_ENUM_SYMBOL_FLAGS_ALL RT_BIT(1)
+/** @} */
+
+
+/**
+ * Debug info type (as far the loader can tell).
+ */
+typedef enum RTLDRDBGINFOTYPE
+{
+ /** The invalid 0 value. */
+ RTLDRDBGINFOTYPE_INVALID = 0,
+ /** Unknown debug info format. */
+ RTLDRDBGINFOTYPE_UNKNOWN,
+ /** Stabs. */
+ RTLDRDBGINFOTYPE_STABS,
+ /** Debug With Arbitrary Record Format (DWARF). */
+ RTLDRDBGINFOTYPE_DWARF,
+ /** Microsoft Codeview debug info. */
+ RTLDRDBGINFOTYPE_CODEVIEW,
+ /** Watcom debug info. */
+ RTLDRDBGINFOTYPE_WATCOM,
+ /** IBM High Level Language debug info.. */
+ RTLDRDBGINFOTYPE_HLL,
+ /** The end of the valid debug info values (exclusive). */
+ RTLDRDBGINFOTYPE_END,
+ /** Blow the type up to 32-bits. */
+ RTLDRDBGINFOTYPE_32BIT_HACK = 0x7fffffff
+} RTLDRDBGINFOTYPE;
+
+/**
+ * Debug info enumerator callback.
+ *
+ * @returns VINF_SUCCESS to continue the enumeration. Any other status code
+ * will cause RTLdrEnumDbgInfo to immediately return with that status.
+ *
+ * @param hLdrMod The module handle.
+ * @param iDbgInfo The debug info ordinal number / id.
+ * @param enmType The debug info type.
+ * @param iMajorVer The major version number of the debug info format.
+ * -1 if unknow - implies invalid iMinorVer.
+ * @param iMinorVer The minor version number of the debug info format.
+ * -1 when iMajorVer is -1.
+ * @param pszPartNm The name of the debug info part, NULL if not
+ * applicable.
+ * @param offFile The file offset *if* this type has one specific
+ * location in the executable image file. This is -1
+ * if there isn't any specific file location.
+ * @param LinkAddress The link address of the debug info if it's
+ * loadable. NIL_RTLDRADDR if not loadable.
+ * @param cb The size of the debug information. -1 is used if
+ * this isn't applicable.
+ * @param pszExtFile This points to the name of an external file
+ * containing the debug info. This is NULL if there
+ * isn't any external file.
+ * @param pvUser The user parameter specified to RTLdrEnumDbgInfo.
+ */
+typedef DECLCALLBACK(int) FNRTLDRENUMDBG(RTLDRMOD hLdrMod, uint32_t iDbgInfo, RTLDRDBGINFOTYPE enmType,
+ uint16_t iMajorVer, uint16_t iMinorVer, const char *pszPartNm,
+ RTFOFF offFile, RTLDRADDR LinkAddress, RTLDRADDR cb,
+ const char *pszExtFile, void *pvUser);
+/** Pointer to a debug info enumerator callback. */
+typedef FNRTLDRENUMDBG *PFNRTLDRENUMDBG;
+
+/**
+ * Enumerate the debug info contained in the executable image.
+ *
+ * @returns IPRT status code or whatever pfnCallback returns.
+ *
+ * @param hLdrMod The module handle.
+ * @param pvBits Optional pointer to bits returned by
+ * RTLdrGetBits(). This can be used by some module
+ * interpreters to reduce memory consumption.
+ * @param pfnCallback The callback function.
+ * @param pvUser The user argument.
+ */
+RTDECL(int) RTLdrEnumDbgInfo(RTLDRMOD hLdrMod, const void *pvBits, PFNRTLDRENUMDBG pfnCallback, void *pvUser);
+
+
+/**
+ * Loader segment.
+ */
+typedef struct RTLDRSEG
+{
+ /** The segment name. (Might not be zero terminated!) */
+ const char *pchName;
+ /** The length of the segment name. */
+ uint32_t cchName;
+ /** The flat selector to use for the segment (i.e. data/code).
+ * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
+ uint16_t SelFlat;
+ /** The 16-bit selector to use for the segment.
+ * Primarily a way for the user to specify selectors for the LX/LE and NE interpreters. */
+ uint16_t Sel16bit;
+ /** Segment flags. */
+ uint32_t fFlags;
+ /** The segment protection (RTMEM_PROT_XXX). */
+ uint32_t fProt;
+ /** The size of the segment. */
+ RTLDRADDR cb;
+ /** The required segment alignment.
+ * The to 0 if the segment isn't supposed to be mapped. */
+ RTLDRADDR Alignment;
+ /** The link address.
+ * Set to NIL_RTLDRADDR if the segment isn't supposed to be mapped or if
+ * the image doesn't have link addresses. */
+ RTLDRADDR LinkAddress;
+ /** File offset of the segment.
+ * Set to -1 if no file backing (like BSS). */
+ RTFOFF offFile;
+ /** Size of the file bits of the segment.
+ * Set to -1 if no file backing (like BSS). */
+ RTFOFF cbFile;
+ /** The relative virtual address when mapped.
+ * Set to NIL_RTLDRADDR if the segment isn't supposed to be mapped. */
+ RTLDRADDR RVA;
+ /** The size of the segment including the alignment gap up to the next segment when mapped.
+ * This is set to NIL_RTLDRADDR if not implemented. */
+ RTLDRADDR cbMapped;
+} RTLDRSEG;
+/** Pointer to a loader segment. */
+typedef RTLDRSEG *PRTLDRSEG;
+/** Pointer to a read only loader segment. */
+typedef RTLDRSEG const *PCRTLDRSEG;
+
+
+/** @name Segment flags
+ * @{ */
+/** The segment is 16-bit. When not set the default of the target architecture is assumed. */
+#define RTLDRSEG_FLAG_16BIT UINT32_C(1)
+/** The segment requires a 16-bit selector alias. (OS/2) */
+#define RTLDRSEG_FLAG_OS2_ALIAS16 UINT32_C(2)
+/** Conforming segment (x86 weirdness). (OS/2) */
+#define RTLDRSEG_FLAG_OS2_CONFORM UINT32_C(4)
+/** IOPL (ring-2) segment. (OS/2) */
+#define RTLDRSEG_FLAG_OS2_IOPL UINT32_C(8)
+/** @} */
+
+/**
+ * Segment enumerator callback.
+ *
+ * @returns VINF_SUCCESS to continue the enumeration. Any other status code
+ * will cause RTLdrEnumSegments to immediately return with that
+ * status.
+ *
+ * @param hLdrMod The module handle.
+ * @param pSeg The segment information.
+ * @param pvUser The user parameter specified to RTLdrEnumSegments.
+ */
+typedef DECLCALLBACK(int) FNRTLDRENUMSEGS(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser);
+/** Pointer to a segment enumerator callback. */
+typedef FNRTLDRENUMSEGS *PFNRTLDRENUMSEGS;
+
+/**
+ * Enumerate the debug info contained in the executable image.
+ *
+ * @returns IPRT status code or whatever pfnCallback returns.
+ *
+ * @param hLdrMod The module handle.
+ * @param pfnCallback The callback function.
+ * @param pvUser The user argument.
+ */
+RTDECL(int) RTLdrEnumSegments(RTLDRMOD hLdrMod, PFNRTLDRENUMSEGS pfnCallback, void *pvUser);
+
+/**
+ * Converts a link address to a segment:offset address.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hLdrMod The module handle.
+ * @param LinkAddress The link address to convert.
+ * @param piSeg Where to return the segment index.
+ * @param poffSeg Where to return the segment offset.
+ */
+RTDECL(int) RTLdrLinkAddressToSegOffset(RTLDRMOD hLdrMod, RTLDRADDR LinkAddress, uint32_t *piSeg, PRTLDRADDR poffSeg);
+
+/**
+ * Converts a link address to an image relative virtual address (RVA).
+ *
+ * @returns IPRT status code.
+ *
+ * @param hLdrMod The module handle.
+ * @param LinkAddress The link address to convert.
+ * @param pRva Where to return the RVA.
+ */
+RTDECL(int) RTLdrLinkAddressToRva(RTLDRMOD hLdrMod, RTLDRADDR LinkAddress, PRTLDRADDR pRva);
+
+/**
+ * Converts an image relative virtual address (RVA) to a segment:offset.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hLdrMod The module handle.
+ * @param Rva The link address to convert.
+ * @param piSeg Where to return the segment index.
+ * @param poffSeg Where to return the segment offset.
+ */
+RTDECL(int) RTLdrSegOffsetToRva(RTLDRMOD hLdrMod, uint32_t iSeg, RTLDRADDR offSeg, PRTLDRADDR pRva);
+
+/**
+ * Converts a segment:offset into an image relative virtual address (RVA).
+ *
+ * @returns IPRT status code.
+ *
+ * @param hLdrMod The module handle.
+ * @param iSeg The segment index.
+ * @param offSeg The segment offset.
+ * @param pRva Where to return the RVA.
+ */
+RTDECL(int) RTLdrRvaToSegOffset(RTLDRMOD hLdrMod, RTLDRADDR Rva, uint32_t *piSeg, PRTLDRADDR poffSeg);
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/linux/sysfs.h b/include/iprt/linux/sysfs.h
new file mode 100644
index 00000000..27010af4
--- /dev/null
+++ b/include/iprt/linux/sysfs.h
@@ -0,0 +1,262 @@
+/* $Id: sysfs.h $ */
+/** @file
+ * IPRT - Linux sysfs access.
+ */
+
+/*
+ * 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 ___iprt_linux_sysfs_h
+#define ___iprt_linux_sysfs_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+#include <sys/types.h> /* for dev_t */
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_linux_sysfs RTLinuxSysfs - Linux sysfs
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Checks if a sysfs file (or directory, device, symlink, whatever) exists.
+ *
+ * @returns true / false, errno is preserved.
+ * @param pszFormat The name format, either absolute or relative to "/sys/".
+ * @param va The format args.
+ */
+RTDECL(bool) RTLinuxSysFsExistsV(const char *pszFormat, va_list va);
+
+/**
+ * Checks if a sysfs file (or directory, device, symlink, whatever) exists.
+ *
+ * @returns true / false, errno is preserved.
+ * @param pszFormat The name format, either absolute or relative to "/sys/".
+ * @param ... The format args.
+ */
+RTDECL(bool) RTLinuxSysFsExists(const char *pszFormat, ...);
+
+/**
+ * Opens a sysfs file.
+ *
+ * @returns The file descriptor. -1 and errno on failure.
+ * @param pszFormat The name format, either absolute or relative to "/sys/".
+ * @param va The format args.
+ */
+RTDECL(int) RTLinuxSysFsOpenV(const char *pszFormat, va_list va);
+
+/**
+ * Opens a sysfs file.
+ *
+ * @returns The file descriptor. -1 and errno on failure.
+ * @param pszFormat The name format, either absolute or relative to "/sys/".
+ * @param ... The format args.
+ */
+RTDECL(int) RTLinuxSysFsOpen(const char *pszFormat, ...);
+
+/**
+ * Closes a file opened with RTLinuxSysFsOpen or RTLinuxSysFsOpenV.
+ *
+ * @param fd File descriptor returned by RTLinuxSysFsOpen or
+ * RTLinuxSysFsOpenV.
+ */
+RTDECL(void) RTLinuxSysFsClose(int fd);
+
+/**
+ * Reads a string from a file opened with RTLinuxSysFsOpen or RTLinuxSysFsOpenV.
+ *
+ * @returns The number of bytes read. -1 and errno on failure.
+ * @param fd The file descriptor returned by RTLinuxSysFsOpen or RTLinuxSysFsOpenV.
+ * @param pszBuf Where to store the string.
+ * @param cchBuf The size of the buffer. Must be at least 2 bytes.
+ */
+RTDECL(ssize_t) RTLinuxSysFsReadStr(int fd, char *pszBuf, size_t cchBuf);
+
+/**
+ * Reads the remainder of a file opened with RTLinuxSysFsOpen or
+ * RTLinuxSysFsOpenV.
+ *
+ * @returns IPRT status code.
+ * @param fd The file descriptor returned by RTLinuxSysFsOpen or RTLinuxSysFsOpenV.
+ * @param pvBuf Where to store the bits from the file.
+ * @param cbBuf The size of the buffer.
+ * @param pcbRead Where to return the number of bytes read. Optional.
+ */
+RTDECL(int) RTLinuxSysFsReadFile(int fd, void *pvBuf, size_t cbBuf, size_t *pcbRead);
+
+/**
+ * Reads a number from a sysfs file.
+ *
+ * @returns 64-bit signed value on success, -1 and errno on failure.
+ * @param uBase The number base, 0 for autodetect.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param va Format args.
+ */
+RTDECL(int64_t) RTLinuxSysFsReadIntFileV(unsigned uBase, const char *pszFormat, va_list va);
+
+/**
+ * Reads a number from a sysfs file.
+ *
+ * @returns 64-bit signed value on success, -1 and errno on failure.
+ * @param uBase The number base, 0 for autodetect.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param ... Format args.
+ */
+RTDECL(int64_t) RTLinuxSysFsReadIntFile(unsigned uBase, const char *pszFormat, ...);
+
+/**
+ * Reads a device number from a sysfs file.
+ *
+ * @returns device number on success, 0 and errno on failure.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param va Format args.
+ */
+RTDECL(dev_t) RTLinuxSysFsReadDevNumFileV(const char *pszFormat, va_list va);
+
+/**
+ * Reads a device number from a sysfs file.
+ *
+ * @returns device number on success, 0 and errno on failure.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param ... Format args.
+ */
+RTDECL(dev_t) RTLinuxSysFsReadDevNumFile(const char *pszFormat, ...);
+
+/**
+ * Reads a string from a sysfs file. If the file contains a newline, we only
+ * return the text up until there.
+ *
+ * @returns number of characters read on success, -1 and errno on failure.
+ * @param pszBuf Where to store the path element. Must be at least two
+ * characters, but a longer buffer would be advisable.
+ * @param cchBuf The size of the buffer pointed to by @a pszBuf.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param va Format args.
+ */
+RTDECL(ssize_t) RTLinuxSysFsReadStrFileV(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va);
+
+/**
+ * Reads a string from a sysfs file. If the file contains a newline, we only
+ * return the text up until there.
+ *
+ * @returns number of characters read on success, -1 and errno on failure.
+ * @param pszBuf Where to store the path element. Must be at least two
+ * characters, but a longer buffer would be advisable.
+ * @param cchBuf The size of the buffer pointed to by @a pszBuf.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param ... Format args.
+ */
+RTDECL(ssize_t) RTLinuxSysFsReadStrFile(char *pszBuf, size_t cchBuf, const char *pszFormat, ...);
+
+/**
+ * Reads the last element of the path of the file pointed to by the symbolic
+ * link specified.
+ *
+ * This is needed at least to get the name of the driver associated with a
+ * device, where pszFormat should be the "driver" link in the devices sysfs
+ * directory.
+ *
+ * @returns The length of the returned string on success, -1 and errno on
+ * failure.
+ * @param pszBuf Where to store the path element. Must be at least two
+ * characters, but a longer buffer would be advisable.
+ * @param cchBuf The size of the buffer pointed to by @a pszBuf.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param va Format args.
+ */
+RTDECL(ssize_t) RTLinuxSysFsGetLinkDestV(char *pszBuf, size_t cchBuf, const char *pszFormat, va_list va);
+
+/**
+ * Reads the last element of the path of the file pointed to by the symbolic
+ * link specified.
+ *
+ * This is needed at least to get the name of the driver associated with a
+ * device, where pszFormat should be the "driver" link in the devices sysfs
+ * directory.
+ *
+ * @returns The length of the returned string on success, -1 and errno on
+ * failure.
+ * @param pszBuf Where to store the path element. Must be at least two
+ * characters, but a longer buffer would be advisable.
+ * @param cchBuf The size of the buffer pointed to by @a pszBuf.
+ * @param pszFormat The filename format, either absolute or relative to "/sys/".
+ * @param ... Format args.
+ */
+RTDECL(ssize_t) RTLinuxSysFsGetLinkDest(char *pszBuf, size_t cchBuf, const char *pszFormat, ...);
+
+/**
+ * Find the path of a device node under /dev, given then device number.
+ *
+ * This function will recursively search under /dev until it finds a device node
+ * matching @a devnum, and store the path into @a pszBuf. The caller may
+ * provide an expected path in pszSuggestion, which will be tried before
+ * searching, but due to the variance in Linux systems it can be hard to always
+ * correctly predict the path.
+ *
+ * @returns The length of the returned string on success, -1 and errno on
+ * failure.
+ * @returns -1 and ENOENT if no matching device node could be found.
+ * @param DevNum The device number to search for.
+ * @param fMode The type of device - only RTFS_TYPE_DEV_CHAR and
+ * RTFS_TYPE_DEV_BLOCK are valid values.
+ * @param pszBuf Where to store the path.
+ * @param cchBuf The size of the buffer.
+ * @param pszSuggestion The expected path format of the device node, either
+ * absolute or relative to "/dev". (Optional)
+ * @param va Format args.
+ */
+RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
+ const char *pszSuggestion, va_list va);
+
+/**
+ * Find the path of a device node under /dev, given the device number.
+ *
+ * This function will recursively search under /dev until it finds a device node
+ * matching @a devnum, and store the path into @a pszBuf. The caller may
+ * provide an expected path in pszSuggestion, which will be tried before
+ * searching, but due to the variance in Linux systems it can be hard to always
+ * correctly predict the path.
+ *
+ * @returns The length of the returned string on success, -1 and errno on
+ * failure.
+ * @returns -1 and ENOENT if no matching device node could be found.
+ * @param DevNum The device number to search for
+ * @param fMode The type of device - only RTFS_TYPE_DEV_CHAR and
+ * RTFS_TYPE_DEV_BLOCK are valid values
+ * @param pszBuf Where to store the path.
+ * @param cchBuf The size of the buffer.
+ * @param pszSuggestion The expected path format of the device node, either
+ * absolute or relative to "/dev". (Optional)
+ * @param ... Format args.
+ */
+RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
+ const char *pszSuggestion, ...);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/list.h b/include/iprt/list.h
new file mode 100644
index 00000000..1a4a4bc0
--- /dev/null
+++ b/include/iprt/list.h
@@ -0,0 +1,364 @@
+/** @file
+ * IPRT - Generic Doubly Linked List.
+ */
+
+/*
+ * 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 ___iprt_list_h
+#define ___iprt_list_h
+
+#include <iprt/types.h>
+
+/** @defgroup grp_rt_list RTList - Generic Doubly Linked List
+ * @ingroup grp_rt
+ *
+ * The list implementation is circular without any type wise distintion between
+ * the list and its nodes. This can be confusing since the list head usually
+ * resides in a different structure than the nodes, so care must be taken when
+ * walking the list.
+ *
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/**
+ * A list node of a doubly linked list.
+ */
+typedef struct RTLISTNODE
+{
+ /** Pointer to the next list node. */
+ struct RTLISTNODE *pNext;
+ /** Pointer to the previous list node. */
+ struct RTLISTNODE *pPrev;
+} RTLISTNODE;
+/** Pointer to a list node. */
+typedef RTLISTNODE *PRTLISTNODE;
+/** Pointer to a list node pointer. */
+typedef PRTLISTNODE *PPRTLISTNODE;
+
+/** The anchor (head/tail) of a doubly linked list.
+ *
+ * @remarks Please use this instead of RTLISTNODE to indicate a list
+ * head/tail. It makes the code so much easier to read. Also,
+ * always mention the actual list node type(s) in the comment. */
+typedef RTLISTNODE RTLISTANCHOR;
+/** Pointer to a doubly linked list anchor. */
+typedef RTLISTANCHOR *PRTLISTANCHOR;
+
+
+/**
+ * Initialize a list.
+ *
+ * @param pList Pointer to an unitialised list.
+ */
+DECLINLINE(void) RTListInit(PRTLISTNODE pList)
+{
+ pList->pNext = pList;
+ pList->pPrev = pList;
+}
+
+/**
+ * Append a node to the end of the list.
+ *
+ * @param pList The list to append the node to.
+ * @param pNode The node to append.
+ */
+DECLINLINE(void) RTListAppend(PRTLISTNODE pList, PRTLISTNODE pNode)
+{
+ pList->pPrev->pNext = pNode;
+ pNode->pPrev = pList->pPrev;
+ pNode->pNext = pList;
+ pList->pPrev = pNode;
+}
+
+/**
+ * Add a node as the first element of the list.
+ *
+ * @param pList The list to prepend the node to.
+ * @param pNode The node to prepend.
+ */
+DECLINLINE(void) RTListPrepend(PRTLISTNODE pList, PRTLISTNODE pNode)
+{
+ pList->pNext->pPrev = pNode;
+ pNode->pNext = pList->pNext;
+ pNode->pPrev = pList;
+ pList->pNext = pNode;
+}
+
+/**
+ * Inserts a node after the specified one.
+ *
+ * @param pCurNode The current node.
+ * @param pNewNode The node to insert.
+ */
+DECLINLINE(void) RTListNodeInsertAfter(PRTLISTNODE pCurNode, PRTLISTNODE pNewNode)
+{
+ RTListPrepend(pCurNode, pNewNode);
+}
+
+/**
+ * Inserts a node before the specified one.
+ *
+ * @param pCurNode The current node.
+ * @param pNewNode The node to insert.
+ */
+DECLINLINE(void) RTListNodeInsertBefore(PRTLISTNODE pCurNode, PRTLISTNODE pNewNode)
+{
+ RTListAppend(pCurNode, pNewNode);
+}
+
+/**
+ * Remove a node from a list.
+ *
+ * @param pNode The node to remove.
+ */
+DECLINLINE(void) RTListNodeRemove(PRTLISTNODE pNode)
+{
+ PRTLISTNODE pPrev = pNode->pPrev;
+ PRTLISTNODE pNext = pNode->pNext;
+
+ pPrev->pNext = pNext;
+ pNext->pPrev = pPrev;
+
+ /* poison */
+ pNode->pNext = NULL;
+ pNode->pPrev = NULL;
+}
+
+/**
+ * Checks if a node is the last element in the list.
+ *
+ * @retval @c true if the node is the last element in the list.
+ * @retval @c false otherwise
+ *
+ * @param pList The list.
+ * @param pNode The node to check.
+ */
+#define RTListNodeIsLast(pList, pNode) ((pNode)->pNext == (pList))
+
+/**
+ * Checks if a node is the first element in the list.
+ *
+ * @retval @c true if the node is the first element in the list.
+ * @retval @c false otherwise.
+ *
+ * @param pList The list.
+ * @param pNode The node to check.
+ */
+#define RTListNodeIsFirst(pList, pNode) ((pNode)->pPrev == (pList))
+
+/**
+ * Checks if a type converted node is actually the dummy element (@a pList).
+ *
+ * @retval @c true if the node is the dummy element in the list.
+ * @retval @c false otherwise.
+ *
+ * @param pList The list.
+ * @param pNodeStruct The node structure to check. Typically
+ * something obtained from RTListNodeGetNext() or
+ * RTListNodeGetPrev(). This is NOT a PRTLISTNODE
+ * but something that contains a RTLISTNODE member!
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member.
+ */
+#define RTListNodeIsDummy(pList, pNode, Type, Member) \
+ ( (pNode) == RT_FROM_MEMBER((pList), Type, Member) )
+
+/**
+ * Checks if a list is empty.
+ *
+ * @retval @c true if the list is empty.
+ * @retval @c false otherwise.
+ *
+ * @param pList The list to check.
+ */
+#define RTListIsEmpty(pList) ((pList)->pPrev == (pList))
+
+/**
+ * Returns the next node in the list.
+ *
+ * @returns The next node.
+ *
+ * @param pCurNode The current node.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member.
+ */
+#define RTListNodeGetNext(pCurNode, Type, Member) \
+ RT_FROM_MEMBER((pCurNode)->pNext, Type, Member)
+
+/**
+ * Returns the previous node in the list.
+ *
+ * @returns The previous node.
+ *
+ * @param pCurNode The current node.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member.
+ */
+#define RTListNodeGetPrev(pCurNode, Type, Member) \
+ RT_FROM_MEMBER((pCurNode)->pPrev, Type, Member)
+
+/**
+ * Returns the first element in the list (checks for empty list).
+ *
+ * @retval Pointer to the first list element.
+ * @retval NULL if the list is empty.
+ *
+ * @param pList List to get the first element from.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member.
+ */
+#define RTListGetFirst(pList, Type, Member) \
+ (!RTListIsEmpty(pList) ? RTListNodeGetNext(pList, Type, Member) : NULL)
+
+/**
+ * Returns the last element in the list (checks for empty list).
+ *
+ * @retval Pointer to the last list element.
+ * @retval NULL if the list is empty.
+ *
+ * @param pList List to get the last element from.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member.
+ */
+#define RTListGetLast(pList, Type, Member) \
+ (!RTListIsEmpty(pList) ? RTListNodeGetPrev(pList, Type, Member) : NULL)
+
+/**
+ * Returns the next node in the list or NULL if the end has been reached.
+ *
+ * @returns The next node or NULL.
+ *
+ * @param pList The list @a pCurNode is linked on.
+ * @param pCurNode The current node, of type @a Type.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member.
+ */
+#define RTListGetNext(pList, pCurNode, Type, Member) \
+ ( (pCurNode)->Member.pNext != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pNext, Type, Member) : NULL )
+
+/**
+ * Returns the previous node in the list or NULL if the start has been reached.
+ *
+ * @returns The previous node or NULL.
+ *
+ * @param pList The list @a pCurNode is linked on.
+ * @param pCurNode The current node, of type @a Type.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member.
+ */
+#define RTListGetPrev(pList, pCurNode, Type, Member) \
+ ( (pCurNode)->Member.pPrev != (pList) ? RT_FROM_MEMBER((pCurNode)->Member.pPrev, Type, Member) : NULL )
+
+/**
+ * Enumerate the list in head to tail order.
+ *
+ * @param pList List to enumerate.
+ * @param pIterator The iterator variable name.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member name.
+ */
+#define RTListForEach(pList, pIterator, Type, Member) \
+ for (pIterator = RTListNodeGetNext(pList, Type, Member); \
+ !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+ pIterator = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) )
+
+
+/**
+ * Enumerate the list in head to tail order, safe against removal of the
+ * current node.
+ *
+ * @param pList List to enumerate.
+ * @param pIterator The iterator variable name.
+ * @param pIterNext The name of the variable saving the pointer to
+ * the next element.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member name.
+ */
+#define RTListForEachSafe(pList, pIterator, pIterNext, Type, Member) \
+ for (pIterator = RTListNodeGetNext(pList, Type, Member), \
+ pIterNext = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member); \
+ !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+ pIterator = pIterNext, \
+ pIterNext = RT_FROM_MEMBER((pIterator)->Member.pNext, Type, Member) )
+
+
+/**
+ * Enumerate the list in reverse order (tail to head).
+ *
+ * @param pList List to enumerate.
+ * @param pIterator The iterator variable name.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member name.
+ */
+#define RTListForEachReverse(pList, pIterator, Type, Member) \
+ for (pIterator = RTListNodeGetPrev(pList, Type, Member); \
+ !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+ pIterator = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) )
+
+
+/**
+ * Enumerate the list in reverse order (tail to head).
+ *
+ * @param pList List to enumerate.
+ * @param pIterator The iterator variable name.
+ * @param pIterPrev The name of the variable saving the pointer to
+ * the previous element.
+ * @param Type Structure the list node is a member of.
+ * @param Member The list node member name.
+ */
+#define RTListForEachReverseSafe(pList, pIterator, pIterPrev, Type, Member) \
+ for (pIterator = RTListNodeGetPrev(pList, Type, Member), \
+ pIterPrev = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member); \
+ !RTListNodeIsDummy(pList, pIterator, Type, Member); \
+ pIterator = pIterPrev, \
+ pIterPrev = RT_FROM_MEMBER((pIterator)->Member.pPrev, Type, Member) )
+
+
+/**
+ * Move the given list to a new list header.
+ *
+ * @param pListDst The new list.
+ * @param pListSrc The list to move.
+ */
+DECLINLINE(void) RTListMove(PRTLISTNODE pListDst, PRTLISTNODE pListSrc)
+{
+ if (!RTListIsEmpty(pListSrc))
+ {
+ pListDst->pNext = pListSrc->pNext;
+ pListDst->pPrev = pListSrc->pPrev;
+
+ /* Adjust the first and last element links */
+ pListDst->pNext->pPrev = pListDst;
+ pListDst->pPrev->pNext = pListDst;
+
+ /* Finally remove the elements from the source list */
+ RTListInit(pListSrc);
+ }
+}
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/iprt/localipc.h b/include/iprt/localipc.h
new file mode 100644
index 00000000..0a887e42
--- /dev/null
+++ b/include/iprt/localipc.h
@@ -0,0 +1,274 @@
+/** @file
+ * IPRT - TCP/IP.
+ */
+
+/*
+ * 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 ___iprt_tcp_h
+#define ___iprt_tcp_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/thread.h>
+
+#ifdef IN_RING0
+# error "There are no RTFile APIs available Ring-0 Host Context!"
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_localipc RTLocalIpc - Local IPC
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Handle to a local IPC server instance. */
+typedef struct RTLOCALIPCSERVERINT *RTLOCALIPCSERVER;
+/** Pointer to a local IPC server handle. */
+typedef RTLOCALIPCSERVER *PRTLOCALIPCSERVER;
+/** Local IPC server handle nil value. */
+#define NIL_RTLOCALIPCSERVER ((RTLOCALIPCSERVER)0)
+
+/** Handle to a local ICP session instance. */
+typedef struct RTLOCALIPCSESSIONINT *RTLOCALIPCSESSION;
+/** Pointer to a local ICP session handle. */
+typedef RTLOCALIPCSESSION *PRTLOCALIPCSESSION;
+/** Local ICP session handle nil value. */
+#define NIL_RTLOCALIPCSESSION ((RTLOCALIPCSESSION)0)
+
+
+
+/**
+ * Create a local IPC server.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success and *phServer containing the instance handle.
+ *
+ * @param phServer Where to put the server instance handle.
+ * @param pszName The servier name. This must be unique and not
+ * include any special chars or slashes. It will
+ * be morphed into a unique platform specific
+ * identifier.
+ * @param fFlags Flags, see RTLOCALIPC_FLAGS_*.
+ */
+RTDECL(int) RTLocalIpcServerCreate(PRTLOCALIPCSERVER phServer, const char *pszName, uint32_t fFlags);
+
+/** @name RTLocalIpcServerCreate flags
+ * @{ */
+/** The server can handle multiple session. */
+#define RTLOCALIPC_FLAGS_MULTI_SESSION RT_BIT_32(0)
+/** The mask of valid flags. */
+#define RTLOCALIPC_FLAGS_VALID_MASK UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroys a local IPC server.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hServer The server handle. The nil value is quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTLocalIpcServerDestroy(RTLOCALIPCSERVER hServer);
+
+/**
+ * Listen for clients.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success and *phClientSession containing the session handle.
+ * @retval VERR_CANCELLED if the listening was interrupted by RTLocalIpcServerCancel().
+ *
+ * @param hServer The server handle.
+ * @param phClientSession Where to store the client session handle on success.
+ *
+ */
+RTDECL(int) RTLocalIpcServerListen(RTLOCALIPCSERVER hServer, PRTLOCALIPCSESSION phClientSession);
+
+/**
+ * Cancel the current or subsequent RTLocalIpcServerListen call.
+ *
+ * @returns IPRT status code.
+ * @param hServer The server handle. The nil value is quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTLocalIpcServerCancel(RTLOCALIPCSERVER hServer);
+
+
+/**
+ * Connects to a local IPC server.
+ *
+ * This is used a client process (or thread).
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success and *phSession holding the session handle.
+ *
+ * @param phSession Where to store the sesson handle on success.
+ * @param pszName The server name (see RTLocalIpcServerCreate for details).
+ * @param fFlags Flags. Current undefined, pass 0.
+ */
+RTDECL(int) RTLocalIpcSessionConnect(PRTLOCALIPCSESSION phSession, const char *pszName, uint32_t fFlags);
+
+
+/**
+ * Closes the local IPC session.
+ *
+ * This can be used with sessions created by both RTLocalIpcSessionConnect
+ * and RTLocalIpcServerListen.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSession The session handle. The nil value is quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTLocalIpcSessionClose(RTLOCALIPCSESSION hSession);
+
+/**
+ * Receive data from the other end of an local IPC session.
+ *
+ * This will block if there isn't any data.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_CANCELLED if the operation was cancelled by RTLocalIpcSessionCancel.
+ *
+ * @param hSession The session handle.
+ * @param pvBuffer Where to store the data.
+ * @param cbBuffer If pcbRead is non-NULL this indicates the maximum number of
+ * bytes to read. If pcbRead is NULL the this is the exact number
+ * of bytes to read.
+ * @param pcbRead Optional argument for indicating a partial read and returning
+ * the number of bytes actually read.
+ * This may return 0 on some implementations?
+ */
+RTDECL(int) RTLocalIpcSessionRead(RTLOCALIPCSESSION hSession, void *pvBuffer, size_t cbBuffer, size_t *pcbRead);
+
+/**
+ * Send data to the other end of an local IPC session.
+ *
+ * This may or may not block until the data is received by the other party,
+ * this is an implementation detail. If you want to make sure that the data
+ * has been received you should always call RTLocalIpcSessionFlush().
+ *
+ * @returns IPRT status code.
+ * @retval VERR_CANCELLED if the operation was cancelled by RTLocalIpcSessionCancel.
+ *
+ * @param hSession The session handle.
+ * @param pvBuffer The data to write.
+ * @param cbBuffer The number of bytes to write.
+ */
+RTDECL(int) RTLocalIpcSessionWrite(RTLOCALIPCSESSION hSession, const void *pvBuffer, size_t cbBuffer);
+
+/**
+ * Flush any buffered data and (perhaps) wait for the other party to receive it.
+ *
+ * The waiting for the other party to receive the data is
+ * implementation dependent.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_CANCELLED if the operation was cancelled by RTLocalIpcSessionCancel.
+ *
+ * @param hSession The session handle.
+ */
+RTDECL(int) RTLocalIpcSessionFlush(RTLOCALIPCSESSION hSession);
+
+/**
+ * Wait for data to become read for reading or for the
+ * session to be disconnected.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS when there is data to read.
+ * @retval VERR_TIMEOUT if no data became available within the specified period (@a cMillies)
+ * @retval VERR_BROKEN_PIPE if the session was disconnected.
+ * @retval VERR_CANCELLED if the operation was cancelled by RTLocalIpcSessionCancel.
+ *
+ * @param hSession The session handle.
+ * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT
+ * to wait forever.
+ *
+ * @remark VERR_INTERRUPTED will not be returned. If this is desired at some later point
+ * add a RTLocalIpcSessionWaitForDataNoResume() variant like we're using elsewhere.
+ */
+RTDECL(int) RTLocalIpcSessionWaitForData(RTLOCALIPCSESSION hSession, uint32_t cMillies);
+
+/**
+ * Cancells a pending or subsequent operation.
+ *
+ * Not all methods are cancellable, only those which are specfied
+ * returning VERR_CANCELLED. The others are assumed to not be blocking
+ * for ever and ever.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSession The session handle.
+ */
+RTDECL(int) RTLocalIpcSessionCancel(RTLOCALIPCSESSION hSession);
+
+/**
+ * Query the process ID of the other party.
+ *
+ * This is an optional feature which may not be implemented, so don't
+ * depend on it and check for VERR_NOT_SUPPORTED.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and *pProcess on success.
+ * @retval VERR_CANCELLED if the operation was cancelled by RTLocalIpcSessionCancel.
+ * @retval VERR_NOT_SUPPORTED and *pProcess = NIL_RTPROCESS if not supported.
+ *
+ * @param hSession The session handle.
+ * @param pProcess Where to store the process ID.
+ */
+RTDECL(int) RTLocalIpcSessionQueryProcess(RTLOCALIPCSESSION hSession, PRTPROCESS pProcess);
+
+/**
+ * Query the user ID of the other party.
+ *
+ * This is an optional feature which may not be implemented, so don't
+ * depend on it and check for VERR_NOT_SUPPORTED.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and *pUid on success.
+ * @retval VERR_CANCELLED if the operation was cancelled by RTLocalIpcSessionCancel.
+ * @retval VERR_NOT_SUPPORTED and *pUid = NIL_RTUID if not supported.
+ *
+ * @param hSession The session handle.
+ * @param pUid Where to store the user ID on success.
+ */
+RTDECL(int) RTLocalIpcSessionQueryUserId(RTLOCALIPCSESSION hSession, PRTUID pUid);
+
+/**
+ * Query the group ID of the other party.
+ *
+ * This is an optional feature which may not be implemented, so don't
+ * depend on it and check for VERR_NOT_SUPPORTED.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and *pUid on success.
+ * @retval VERR_CANCELLED if the operation was cancelled by RTLocalIpcSessionCancel.
+ * @retval VERR_NOT_SUPPORTED and *pGid = NIL_RTUID if not supported.
+ *
+ * @param hSession The session handle.
+ * @param pGid Where to store the group ID on success.
+ */
+RTDECL(int) RTLocalIpcSessionQueryGroupId(RTLOCALIPCSESSION hSession, PRTGID pGid);
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/lockvalidator.h b/include/iprt/lockvalidator.h
new file mode 100644
index 00000000..7e0f08c1
--- /dev/null
+++ b/include/iprt/lockvalidator.h
@@ -0,0 +1,1062 @@
+/** @file
+ * IPRT - Lock Validator.
+ */
+
+/*
+ * 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 ___iprt_lockvalidator_h
+#define ___iprt_lockvalidator_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#include <iprt/thread.h>
+#include <iprt/stdarg.h>
+
+
+/** @defgroup grp_rtlockval RTLockValidator - Lock Validator
+ * @ingroup grp_rt
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/** Pointer to a record union.
+ * @internal */
+typedef union RTLOCKVALRECUNION *PRTLOCKVALRECUNION;
+
+/**
+ * Source position.
+ */
+typedef struct RTLOCKVALSRCPOS
+{
+ /** The file where the lock was taken. */
+ R3R0PTRTYPE(const char * volatile) pszFile;
+ /** The function where the lock was taken. */
+ R3R0PTRTYPE(const char * volatile) pszFunction;
+ /** Some ID indicating where the lock was taken, typically an address. */
+ RTHCUINTPTR volatile uId;
+ /** The line number in the file. */
+ uint32_t volatile uLine;
+#if HC_ARCH_BITS == 64
+ uint32_t u32Padding; /**< Alignment padding. */
+#endif
+} RTLOCKVALSRCPOS;
+AssertCompileSize(RTLOCKVALSRCPOS, HC_ARCH_BITS == 32 ? 16 : 32);
+/* The pointer types are defined in iprt/types.h. */
+
+/** @def RTLOCKVALSRCPOS_INIT
+ * Initializer for a RTLOCKVALSRCPOS variable.
+ *
+ * @param pszFile The file name. Optional (NULL).
+ * @param uLine The line number in that file. Optional (0).
+ * @param pszFunction The function. Optional (NULL).
+ * @param uId Some location ID, normally the return address.
+ * Optional (NULL).
+ */
+#if HC_ARCH_BITS == 64
+# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
+ { (pszFile), (pszFunction), (uId), (uLine), 0 }
+#else
+# define RTLOCKVALSRCPOS_INIT(pszFile, uLine, pszFunction, uId) \
+ { (pszFile), (pszFunction), (uId), (uLine) }
+#endif
+
+/** @def RTLOCKVALSRCPOS_INIT_DEBUG_API
+ * Initializer for a RTLOCKVALSRCPOS variable in a typicial debug API
+ * variant. Assumes RT_SRC_POS_DECL and RTHCUINTPTR uId as arguments.
+ */
+#define RTLOCKVALSRCPOS_INIT_DEBUG_API() \
+ RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, uId)
+
+/** @def RTLOCKVALSRCPOS_INIT_NORMAL_API
+ * Initializer for a RTLOCKVALSRCPOS variable in a normal API
+ * variant. Assumes iprt/asm.h is included.
+ */
+#define RTLOCKVALSRCPOS_INIT_NORMAL_API() \
+ RTLOCKVALSRCPOS_INIT(__FILE__, __LINE__, __PRETTY_FUNCTION__, (uintptr_t)ASMReturnAddress())
+
+/** @def RTLOCKVALSRCPOS_INIT_POS_NO_ID
+ * Initializer for a RTLOCKVALSRCPOS variable when no @c uId is present.
+ * Assumes iprt/asm.h is included.
+ */
+#define RTLOCKVALSRCPOS_INIT_POS_NO_ID() \
+ RTLOCKVALSRCPOS_INIT(pszFile, iLine, pszFunction, (uintptr_t)ASMReturnAddress())
+
+/** Pointer to a record of one ownership share. */
+typedef struct RTLOCKVALRECSHRD *PRTLOCKVALRECSHRD;
+
+
+/**
+ * Lock validator record core.
+ */
+typedef struct RTLOCKVALRECORE
+{
+ /** The magic value indicating the record type. */
+ uint32_t volatile u32Magic;
+} RTLOCKVALRECCORE;
+/** Pointer to a lock validator record core. */
+typedef RTLOCKVALRECCORE *PRTLOCKVALRECCORE;
+/** Pointer to a const lock validator record core. */
+typedef RTLOCKVALRECCORE const *PCRTLOCKVALRECCORE;
+
+
+/**
+ * Record recording the exclusive ownership of a lock.
+ *
+ * This is typically part of the per-lock data structure when compiling with
+ * the lock validator.
+ */
+typedef struct RTLOCKVALRECEXCL
+{
+ /** Record core with RTLOCKVALRECEXCL_MAGIC as the magic value. */
+ RTLOCKVALRECCORE Core;
+ /** Whether it's enabled or not. */
+ bool fEnabled;
+ /** Reserved. */
+ bool afReserved[3];
+ /** Source position where the lock was taken. */
+ RTLOCKVALSRCPOS SrcPos;
+ /** The current owner thread. */
+ RTTHREAD volatile hThread;
+ /** Pointer to the lock record below us. Only accessed by the owner. */
+ R3R0PTRTYPE(PRTLOCKVALRECUNION) pDown;
+ /** Recursion count */
+ uint32_t cRecursion;
+ /** The lock sub-class. */
+ uint32_t volatile uSubClass;
+ /** The lock class. */
+ RTLOCKVALCLASS hClass;
+ /** Pointer to the lock. */
+ RTHCPTR hLock;
+ /** Pointer to the next sibling record.
+ * This is used to find the read side of a read-write lock. */
+ R3R0PTRTYPE(PRTLOCKVALRECUNION) pSibling;
+ /** The lock name.
+ * @remarks The bytes beyond 32 are for better size alignment and can be
+ * taken and used for other purposes if it becomes necessary. */
+ char szName[32 + (HC_ARCH_BITS == 32 ? 12 : 8)];
+} RTLOCKVALRECEXCL;
+AssertCompileSize(RTLOCKVALRECEXCL, HC_ARCH_BITS == 32 ? 0x60 : 0x80);
+/* The pointer type is defined in iprt/types.h. */
+
+/**
+ * For recording the one ownership share.
+ */
+typedef struct RTLOCKVALRECSHRDOWN
+{
+ /** Record core with RTLOCKVALRECSHRDOWN_MAGIC as the magic value. */
+ RTLOCKVALRECCORE Core;
+ /** Recursion count */
+ uint16_t cRecursion;
+ /** Static (true) or dynamic (false) allocated record. */
+ bool fStaticAlloc;
+ /** Reserved. */
+ bool fReserved;
+ /** The current owner thread. */
+ RTTHREAD volatile hThread;
+ /** Pointer to the lock record below us. Only accessed by the owner. */
+ R3R0PTRTYPE(PRTLOCKVALRECUNION) pDown;
+ /** Pointer back to the shared record. */
+ R3R0PTRTYPE(PRTLOCKVALRECSHRD) pSharedRec;
+#if HC_ARCH_BITS == 32
+ /** Reserved. */
+ RTHCPTR pvReserved;
+#endif
+ /** Source position where the lock was taken. */
+ RTLOCKVALSRCPOS SrcPos;
+} RTLOCKVALRECSHRDOWN;
+AssertCompileSize(RTLOCKVALRECSHRDOWN, HC_ARCH_BITS == 32 ? 24 + 16 : 32 + 32);
+/** Pointer to a RTLOCKVALRECSHRDOWN. */
+typedef RTLOCKVALRECSHRDOWN *PRTLOCKVALRECSHRDOWN;
+
+/**
+ * Record recording the shared ownership of a lock.
+ *
+ * This is typically part of the per-lock data structure when compiling with
+ * the lock validator.
+ */
+typedef struct RTLOCKVALRECSHRD
+{
+ /** Record core with RTLOCKVALRECSHRD_MAGIC as the magic value. */
+ RTLOCKVALRECCORE Core;
+ /** The lock sub-class. */
+ uint32_t volatile uSubClass;
+ /** The lock class. */
+ RTLOCKVALCLASS hClass;
+ /** Pointer to the lock. */
+ RTHCPTR hLock;
+ /** Pointer to the next sibling record.
+ * This is used to find the write side of a read-write lock. */
+ R3R0PTRTYPE(PRTLOCKVALRECUNION) pSibling;
+
+ /** The number of entries in the table.
+ * Updated before inserting and after removal. */
+ uint32_t volatile cEntries;
+ /** The index of the last entry (approximately). */
+ uint32_t volatile iLastEntry;
+ /** The max table size. */
+ uint32_t volatile cAllocated;
+ /** Set if the table is being reallocated, clear if not.
+ * This is used together with rtLockValidatorSerializeDetectionEnter to make
+ * sure there is exactly one thread doing the reallocation and that nobody is
+ * using the table at that point. */
+ bool volatile fReallocating;
+ /** Whether it's enabled or not. */
+ bool fEnabled;
+ /** Set if event semaphore signaller, clear if read-write semaphore. */
+ bool fSignaller;
+ /** Alignment padding. */
+ bool fPadding;
+ /** Pointer to a table containing pointers to records of all the owners. */
+ R3R0PTRTYPE(PRTLOCKVALRECSHRDOWN volatile *) papOwners;
+
+ /** The lock name.
+ * @remarks The bytes beyond 32 are for better size alignment and can be
+ * taken and used for other purposes if it becomes necessary. */
+ char szName[32 + (HC_ARCH_BITS == 32 ? 8 : 8)];
+} RTLOCKVALRECSHRD;
+AssertCompileSize(RTLOCKVALRECSHRD, HC_ARCH_BITS == 32 ? 0x50 : 0x60);
+
+
+/**
+ * Makes the two records siblings.
+ *
+ * @returns VINF_SUCCESS on success, VERR_SEM_LV_INVALID_PARAMETER if either of
+ * the records are invalid.
+ * @param pRec1 Record 1.
+ * @param pRec2 Record 2.
+ */
+RTDECL(int) RTLockValidatorRecMakeSiblings(PRTLOCKVALRECCORE pRec1, PRTLOCKVALRECCORE pRec2);
+
+/**
+ * Initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDelete to deinitialize it.
+ *
+ * @param pRec The record.
+ * @param hClass The class (no reference consumed). If NIL, the
+ * no lock order validation will be performed on
+ * this lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order inside the same class. If you don't know,
+ * then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param hLock The lock handle.
+ * @param fEnabled Pass @c false to explicitly disable lock
+ * validation, otherwise @c true.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecExclInit(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+ void *hLock, bool fEnabled, const char *pszNameFmt, ...);
+/**
+ * Initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDelete to deinitialize it.
+ *
+ * @param pRec The record.
+ * @param hClass The class (no reference consumed). If NIL, the
+ * no lock order validation will be performed on
+ * this lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order inside the same class. If you don't know,
+ * then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param hLock The lock handle.
+ * @param fEnabled Pass @c false to explicitly disable lock
+ * validation, otherwise @c true.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param va Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecExclInitV(PRTLOCKVALRECEXCL pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+ void *hLock, bool fEnabled, const char *pszNameFmt, va_list va);
+/**
+ * Uninitialize a lock validator record previously initialized by
+ * RTLockRecValidatorInit.
+ *
+ * @param pRec The record. Must be valid.
+ */
+RTDECL(void) RTLockValidatorRecExclDelete(PRTLOCKVALRECEXCL pRec);
+
+/**
+ * Create and initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDestroy to deinitialize and destroy the returned
+ * record.
+ *
+ * @return VINF_SUCCESS or VERR_NO_MEMORY.
+ * @param ppRec Where to return the record pointer.
+ * @param hClass The class (no reference consumed). If NIL, the
+ * no lock order validation will be performed on
+ * this lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order inside the same class. If you don't know,
+ * then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param hLock The lock handle.
+ * @param fEnabled Pass @c false to explicitly disable lock
+ * validation, otherwise @c true.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTLockValidatorRecExclCreate(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+ void *hLock, bool fEnabled, const char *pszNameFmt, ...);
+
+/**
+ * Create and initialize a lock validator record.
+ *
+ * Use RTLockValidatorRecExclDestroy to deinitialize and destroy the returned
+ * record.
+ *
+ * @return VINF_SUCCESS or VERR_NO_MEMORY.
+ * @param ppRec Where to return the record pointer.
+ * @param hClass The class (no reference consumed). If NIL, the
+ * no lock order validation will be performed on
+ * this lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order inside the same class. If you don't know,
+ * then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param hLock The lock handle.
+ * @param fEnabled Pass @c false to explicitly disable lock
+ * validation, otherwise @c true.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param va Format string arguments.
+ */
+RTDECL(int) RTLockValidatorRecExclCreateV(PRTLOCKVALRECEXCL *ppRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+ void *hLock, bool fEnabled, const char *pszNameFmt, va_list va);
+
+/**
+ * Deinitialize and destroy a record created by RTLockValidatorRecExclCreate.
+ *
+ * @param ppRec Pointer to the record pointer. Will be set to
+ * NULL.
+ */
+RTDECL(void) RTLockValidatorRecExclDestroy(PRTLOCKVALRECEXCL *ppRec);
+
+/**
+ * Sets the sub-class of the record.
+ *
+ * It is recommended to try make sure that nobody is using this class while
+ * changing the value.
+ *
+ * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ * lock validator isn't compiled in or either of the parameters are
+ * invalid.
+ * @param pRec The validator record.
+ * @param uSubClass The new sub-class value.
+ */
+RTDECL(uint32_t) RTLockValidatorRecExclSetSubClass(PRTLOCKVALRECEXCL pRec, uint32_t uSubClass);
+
+/**
+ * Record the specified thread as lock owner and increment the write lock count.
+ *
+ * This function is typically called after acquiring the lock. It accounts for
+ * recursions so it can be used instead of RTLockValidatorRecExclRecursion. Use
+ * RTLockValidatorRecExclReleaseOwner to reverse the effect.
+ *
+ * @param pRec The validator record.
+ * @param hThreadSelf The handle of the calling thread. If not known,
+ * pass NIL_RTTHREAD and we'll figure it out.
+ * @param pSrcPos The source position of the lock operation.
+ * @param fFirstRecursion Set if it is the first recursion, clear if not
+ * sure.
+ */
+RTDECL(void) RTLockValidatorRecExclSetOwner(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+ PCRTLOCKVALSRCPOS pSrcPos, bool fFirstRecursion);
+
+/**
+ * Check the exit order and release (unset) the ownership.
+ *
+ * This is called by routines implementing releasing an exclusive lock,
+ * typically before getting down to the final lock releasing. Can be used for
+ * recursive releasing instead of RTLockValidatorRecExclUnwind.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong. Will have
+ * done all necessary whining and breakpointing before returning.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record.
+ * @param fFinalRecursion Set if it's the final recursion, clear if not
+ * sure.
+ */
+RTDECL(int) RTLockValidatorRecExclReleaseOwner(PRTLOCKVALRECEXCL pRec, bool fFinalRecursion);
+
+/**
+ * Clear the lock ownership and decrement the write lock count.
+ *
+ * This is only for special cases where we wish to drop lock validation
+ * recording. See RTLockValidatorRecExclCheckAndRelease.
+ *
+ * @param pRec The validator record.
+ */
+RTDECL(void) RTLockValidatorRecExclReleaseOwnerUnchecked(PRTLOCKVALRECEXCL pRec);
+
+/**
+ * Checks and records a lock recursion.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_NESTED if the semaphore class forbids recursion. Gone
+ * thru the motions.
+ * @retval VERR_SEM_LV_WRONG_ORDER if the locking order is wrong. Gone thru
+ * the motions.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record.
+ * @param pSrcPos The source position of the lock operation.
+ */
+RTDECL(int) RTLockValidatorRecExclRecursion(PRTLOCKVALRECEXCL pRec, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Checks and records a lock unwind (releasing one recursion).
+ *
+ * This should be coupled with called to RTLockValidatorRecExclRecursion.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong. Gone
+ * thru the motions.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record.
+ */
+RTDECL(int) RTLockValidatorRecExclUnwind(PRTLOCKVALRECEXCL pRec);
+
+/**
+ * Checks and records a mixed recursion.
+ *
+ * An example of a mixed recursion is a writer requesting read access to a
+ * SemRW.
+ *
+ * This should be coupled with called to RTLockValidatorRecExclUnwindMixed.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_NESTED if the semaphore class forbids recursion. Gone
+ * thru the motions.
+ * @retval VERR_SEM_LV_WRONG_ORDER if the locking order is wrong. Gone thru
+ * the motions.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record it to accounted it to.
+ * @param pRecMixed The validator record it came in on.
+ * @param pSrcPos The source position of the lock operation.
+ */
+RTDECL(int) RTLockValidatorRecExclRecursionMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Checks and records the unwinding of a mixed recursion.
+ *
+ * This should be coupled with called to RTLockValidatorRecExclRecursionMixed.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the release order is wrong. Gone
+ * thru the motions.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record it was accounted to.
+ * @param pRecMixed The validator record it came in on.
+ */
+RTDECL(int) RTLockValidatorRecExclUnwindMixed(PRTLOCKVALRECEXCL pRec, PRTLOCKVALRECCORE pRecMixed);
+
+/**
+ * Check the exclusive locking order.
+ *
+ * This is called by routines implementing exclusive lock acquisition.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_WRONG_ORDER if the order is wrong. Will have done all
+ * necessary whining and breakpointing before returning.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record.
+ * @param hThreadSelf The handle of the calling thread. If not known,
+ * pass NIL_RTTHREAD and we'll figure it out.
+ * @param pSrcPos The source position of the lock operation.
+ * @param cMillies The timeout, in milliseconds.
+ */
+RTDECL(int) RTLockValidatorRecExclCheckOrder(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+ PCRTLOCKVALSRCPOS pSrcPos, RTMSINTERVAL cMillies);
+
+/**
+ * Do deadlock detection before blocking on exclusive access to a lock and
+ * change the thread state.
+ *
+ * @retval VINF_SUCCESS - thread is in the specified sleep state.
+ * @retval VERR_SEM_LV_DEADLOCK if blocking would deadlock. Gone thru the
+ * motions.
+ * @retval VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
+ * already the owner. Gone thru the motions.
+ * @retval VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
+ * The caller must handle any legal upgrades without invoking this
+ * function (for now).
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record we're blocking on.
+ * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
+ * @param pSrcPos The source position of the lock operation.
+ * @param fRecursiveOk Whether it's ok to recurse.
+ * @param cMillies The timeout, in milliseconds.
+ * @param enmSleepState The sleep state to enter on successful return.
+ * @param fReallySleeping Is it really going to sleep now or not. Use
+ * false before calls to other IPRT synchronization
+ * methods.
+ */
+RTDECL(int) RTLockValidatorRecExclCheckBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+ PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+ RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * RTLockValidatorRecExclCheckOrder and RTLockValidatorRecExclCheckBlocking
+ * baked into one call.
+ *
+ * @returns Any of the statuses returned by the two APIs.
+ * @param pRec The validator record.
+ * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
+ * @param pSrcPos The source position of the lock operation.
+ * @param fRecursiveOk Whether it's ok to recurse.
+ * @param cMillies The timeout, in milliseconds.
+ * @param enmSleepState The sleep state to enter on successful return.
+ * @param fReallySleeping Is it really going to sleep now or not. Use
+ * false before calls to other IPRT synchronization
+ * methods.
+ */
+RTDECL(int) RTLockValidatorRecExclCheckOrderAndBlocking(PRTLOCKVALRECEXCL pRec, RTTHREAD hThreadSelf,
+ PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+ RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * Initialize a lock validator record for a shared lock.
+ *
+ * Use RTLockValidatorRecSharedDelete to deinitialize it.
+ *
+ * @param pRec The shared lock record.
+ * @param hClass The class (no reference consumed). If NIL, the
+ * no lock order validation will be performed on
+ * this lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order inside the same class. If you don't know,
+ * then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param hLock The lock handle.
+ * @param fSignaller Set if event semaphore signaller logic should be
+ * applied to this record, clear if read-write
+ * semaphore logic should be used.
+ * @param fEnabled Pass @c false to explicitly disable lock
+ * validation, otherwise @c true.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecSharedInit(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+ void *hLock, bool fSignaller, bool fEnabled, const char *pszNameFmt, ...);
+/**
+ * Initialize a lock validator record for a shared lock.
+ *
+ * Use RTLockValidatorRecSharedDelete to deinitialize it.
+ *
+ * @param pRec The shared lock record.
+ * @param hClass The class (no reference consumed). If NIL, the
+ * no lock order validation will be performed on
+ * this lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order inside the same class. If you don't know,
+ * then pass RTLOCKVAL_SUB_CLASS_NONE.
+ * @param hLock The lock handle.
+ * @param fSignaller Set if event semaphore signaller logic should be
+ * applied to this record, clear if read-write
+ * semaphore logic should be used.
+ * @param fEnabled Pass @c false to explicitly disable lock
+ * validation, otherwise @c true.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param va Format string arguments.
+ */
+RTDECL(void) RTLockValidatorRecSharedInitV(PRTLOCKVALRECSHRD pRec, RTLOCKVALCLASS hClass, uint32_t uSubClass,
+ void *hLock, bool fSignaller, bool fEnabled, const char *pszNameFmt, va_list va);
+/**
+ * Uninitialize a lock validator record previously initialized by
+ * RTLockValidatorRecSharedInit.
+ *
+ * @param pRec The shared lock record. Must be valid.
+ */
+RTDECL(void) RTLockValidatorRecSharedDelete(PRTLOCKVALRECSHRD pRec);
+
+/**
+ * Sets the sub-class of the record.
+ *
+ * It is recommended to try make sure that nobody is using this class while
+ * changing the value.
+ *
+ * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ * lock validator isn't compiled in or either of the parameters are
+ * invalid.
+ * @param pRec The validator record.
+ * @param uSubClass The new sub-class value.
+ */
+RTDECL(uint32_t) RTLockValidatorRecSharedSetSubClass(PRTLOCKVALRECSHRD pRec, uint32_t uSubClass);
+
+/**
+ * Check the shared locking order.
+ *
+ * This is called by routines implementing shared lock acquisition.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_WRONG_ORDER if the order is wrong. Will have done all
+ * necessary whining and breakpointing before returning.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record.
+ * @param hThreadSelf The handle of the calling thread. If not known,
+ * pass NIL_RTTHREAD and we'll figure it out.
+ * @param pSrcPos The source position of the lock operation.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckOrder(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
+ PCRTLOCKVALSRCPOS pSrcPos, RTMSINTERVAL cMillies);
+
+/**
+ * Do deadlock detection before blocking on shared access to a lock and change
+ * the thread state.
+ *
+ * @retval VINF_SUCCESS - thread is in the specified sleep state.
+ * @retval VERR_SEM_LV_DEADLOCK if blocking would deadlock. Gone thru the
+ * motions.
+ * @retval VERR_SEM_LV_NESTED if the semaphore isn't recursive and hThread is
+ * already the owner. Gone thru the motions.
+ * @retval VERR_SEM_LV_ILLEGAL_UPGRADE if it's a deadlock on the same lock.
+ * The caller must handle any legal upgrades without invoking this
+ * function (for now).
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record we're blocking on.
+ * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
+ * @param pSrcPos The source position of the lock operation.
+ * @param fRecursiveOk Whether it's ok to recurse.
+ * @param enmSleepState The sleep state to enter on successful return.
+ * @param fReallySleeping Is it really going to sleep now or not. Use
+ * false before calls to other IPRT synchronization
+ * methods.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
+ PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+ RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * RTLockValidatorRecSharedCheckOrder and RTLockValidatorRecSharedCheckBlocking
+ * baked into one call.
+ *
+ * @returns Any of the statuses returned by the two APIs.
+ * @param pRec The validator record.
+ * @param hThreadSelf The current thread. Shall not be NIL_RTTHREAD!
+ * @param pSrcPos The source position of the lock operation.
+ * @param fRecursiveOk Whether it's ok to recurse.
+ * @param enmSleepState The sleep state to enter on successful return.
+ * @param fReallySleeping Is it really going to sleep now or not. Use
+ * false before calls to other IPRT synchronization
+ * methods.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckOrderAndBlocking(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf,
+ PCRTLOCKVALSRCPOS pSrcPos, bool fRecursiveOk, RTMSINTERVAL cMillies,
+ RTTHREADSTATE enmSleepState, bool fReallySleeping);
+
+/**
+ * Removes all current owners and makes hThread the only owner.
+ *
+ * @param pRec The validator record.
+ * @param hThread The thread handle of the owner. NIL_RTTHREAD is
+ * an alias for the current thread.
+ * @param pSrcPos The source position of the lock operation.
+ */
+RTDECL(void) RTLockValidatorRecSharedResetOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Adds an owner to a shared locking record.
+ *
+ * Takes recursion into account. This function is typically called after
+ * acquiring the lock in shared mode.
+ *
+ * @param pRec The validator record.
+ * @param hThread The thread handle of the owner. NIL_RTTHREAD is
+ * an alias for the current thread.
+ * @param pSrcPos The source position of the lock operation.
+ */
+RTDECL(void) RTLockValidatorRecSharedAddOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread, PCRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Removes an owner from a shared locking record.
+ *
+ * Takes recursion into account. This function is typically called before
+ * releasing the lock.
+ *
+ * @param pRec The validator record.
+ * @param hThread The thread handle of the owner. NIL_RTTHREAD is
+ * an alias for the current thread.
+ */
+RTDECL(void) RTLockValidatorRecSharedRemoveOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
+
+/**
+ * Checks if the specified thread is one of the owners.
+ *
+ * @returns true if it is, false if not.
+ *
+ * @param pRec The validator record.
+ * @param hThread The thread handle of the owner. NIL_RTTHREAD is
+ * an alias for the current thread.
+ */
+RTDECL(bool) RTLockValidatorRecSharedIsOwner(PRTLOCKVALRECSHRD pRec, RTTHREAD hThread);
+
+/**
+ * Check the exit order and release (unset) the shared ownership.
+ *
+ * This is called by routines implementing releasing the read/write lock.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_WRONG_RELEASE_ORDER if the order is wrong. Will have
+ * done all necessary whining and breakpointing before returning.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record.
+ * @param hThreadSelf The handle of the calling thread. NIL_RTTHREAD
+ * is an alias for the current thread.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckAndRelease(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
+
+/**
+ * Check the signaller of an event.
+ *
+ * This is called by routines implementing releasing the event semaphore (both
+ * kinds).
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_SEM_LV_NOT_SIGNALLER if the thread is not in the record. Will
+ * have done all necessary whining and breakpointing before returning.
+ * @retval VERR_SEM_LV_INVALID_PARAMETER if the input is invalid.
+ *
+ * @param pRec The validator record.
+ * @param hThreadSelf The handle of the calling thread. NIL_RTTHREAD
+ * is an alias for the current thread.
+ */
+RTDECL(int) RTLockValidatorRecSharedCheckSignaller(PRTLOCKVALRECSHRD pRec, RTTHREAD hThreadSelf);
+
+/**
+ * Gets the number of write locks and critical sections the specified
+ * thread owns.
+ *
+ * This number does not include any nested lock/critect entries.
+ *
+ * Note that it probably will return 0 for non-strict builds since
+ * release builds doesn't do unnecessary diagnostic counting like this.
+ *
+ * @returns Number of locks on success (0+) and VERR_INVALID_HANDLER on failure
+ * @param Thread The thread we're inquiring about.
+ * @remarks Will only work for strict builds.
+ */
+RTDECL(int32_t) RTLockValidatorWriteLockGetCount(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cWriteLocks member, mostly internal.
+ *
+ * @param Thread The current thread.
+ */
+RTDECL(void) RTLockValidatorWriteLockInc(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cWriteLocks member, mostly internal.
+ *
+ * @param Thread The current thread.
+ */
+RTDECL(void) RTLockValidatorWriteLockDec(RTTHREAD Thread);
+
+/**
+ * Gets the number of read locks the specified thread owns.
+ *
+ * Note that nesting read lock entry will be included in the
+ * total sum. And that it probably will return 0 for non-strict
+ * builds since release builds doesn't do unnecessary diagnostic
+ * counting like this.
+ *
+ * @returns Number of read locks on success (0+) and VERR_INVALID_HANDLER on failure
+ * @param Thread The thread we're inquiring about.
+ */
+RTDECL(int32_t) RTLockValidatorReadLockGetCount(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cReadLocks member.
+ *
+ * @param Thread The current thread.
+ */
+RTDECL(void) RTLockValidatorReadLockInc(RTTHREAD Thread);
+
+/**
+ * Works the THREADINT::cReadLocks member.
+ *
+ * @param Thread The current thread.
+ */
+RTDECL(void) RTLockValidatorReadLockDec(RTTHREAD Thread);
+
+/**
+ * Query which lock the specified thread is waiting on.
+ *
+ * @returns The lock handle value or NULL.
+ * @param hThread The thread in question.
+ */
+RTDECL(void *) RTLockValidatorQueryBlocking(RTTHREAD hThread);
+
+/**
+ * Checks if the thread is running in the lock validator after it has entered a
+ * block state.
+ *
+ * @returns true if it is, false if it isn't.
+ * @param hThread The thread in question.
+ */
+RTDECL(bool) RTLockValidatorIsBlockedThreadInValidator(RTTHREAD hThread);
+
+/**
+ * Checks if the calling thread is holding a lock in the specified class.
+ *
+ * @returns true if it holds a lock in the specific class, false if it
+ * doesn't.
+ *
+ * @param hCurrentThread The current thread. Pass NIL_RTTHREAD if you're
+ * lazy.
+ * @param hClass The class.
+ */
+RTDECL(bool) RTLockValidatorHoldsLocksInClass(RTTHREAD hCurrentThread, RTLOCKVALCLASS hClass);
+
+/**
+ * Checks if the calling thread is holding a lock in the specified sub-class.
+ *
+ * @returns true if it holds a lock in the specific sub-class, false if it
+ * doesn't.
+ *
+ * @param hCurrentThread The current thread. Pass NIL_RTTHREAD if you're
+ * lazy.
+ * @param hClass The class.
+ * @param uSubClass The new sub-class value.
+ */
+RTDECL(bool) RTLockValidatorHoldsLocksInSubClass(RTTHREAD hCurrentThread, RTLOCKVALCLASS hClass, uint32_t uSubClass);
+
+
+
+/**
+ * Creates a new lock validator class, all properties specified.
+ *
+ * @returns IPRT status code
+ * @param phClass Where to return the class handle.
+ * @param pSrcPos The source position of the create call.
+ * @param fAutodidact Whether the class should be allowed to teach
+ * itself new locking order rules (true), or if the
+ * user will teach it all it needs to know (false).
+ * @param fRecursionOk Whether to allow lock recursion or not.
+ * @param fStrictReleaseOrder Enforce strict lock release order or not.
+ * @param cMsMinDeadlock Used to raise the sleep interval at which
+ * deadlock detection kicks in. Minimum is 1 ms,
+ * while RT_INDEFINITE_WAIT will disable it.
+ * @param cMsMinOrder Used to raise the sleep interval at which lock
+ * order validation kicks in. Minimum is 1 ms,
+ * while RT_INDEFINITE_WAIT will disable it.
+ * @param pszNameFmt Class name format string, optional (NULL). Max
+ * length is 32 bytes.
+ * @param ... Format string arguments.
+ *
+ * @remarks The properties can be modified after creation by the
+ * RTLockValidatorClassSet* methods.
+ */
+RTDECL(int) RTLockValidatorClassCreateEx(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos,
+ bool fAutodidact, bool fRecursionOk, bool fStrictReleaseOrder,
+ RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder,
+ const char *pszNameFmt, ...);
+
+/**
+ * Creates a new lock validator class, all properties specified.
+ *
+ * @returns IPRT status code
+ * @param phClass Where to return the class handle.
+ * @param pSrcPos The source position of the create call.
+ * @param fAutodidact Whether the class should be allowed to teach
+ * itself new locking order rules (true), or if the
+ * user will teach it all it needs to know (false).
+ * @param fRecursionOk Whether to allow lock recursion or not.
+ * @param fStrictReleaseOrder Enforce strict lock release order or not.
+ * @param cMsMinDeadlock Used to raise the sleep interval at which
+ * deadlock detection kicks in. Minimum is 1 ms,
+ * while RT_INDEFINITE_WAIT will disable it.
+ * @param cMsMinOrder Used to raise the sleep interval at which lock
+ * order validation kicks in. Minimum is 1 ms,
+ * while RT_INDEFINITE_WAIT will disable it.
+ * @param pszNameFmt Class name format string, optional (NULL). Max
+ * length is 32 bytes.
+ * @param va Format string arguments.
+ *
+ * @remarks The properties can be modified after creation by the
+ * RTLockValidatorClassSet* methods.
+ */
+RTDECL(int) RTLockValidatorClassCreateExV(PRTLOCKVALCLASS phClass, PCRTLOCKVALSRCPOS pSrcPos,
+ bool fAutodidact, bool fRecursionOk, bool fStrictReleaseOrder,
+ RTMSINTERVAL cMsMinDeadlock, RTMSINTERVAL cMsMinOrder,
+ const char *pszNameFmt, va_list va);
+
+/**
+ * Creates a new lock validator class.
+ *
+ * @returns IPRT status code
+ * @param phClass Where to return the class handle.
+ * @param fAutodidact Whether the class should be allowed to teach
+ * itself new locking order rules (true), or if the
+ * user will teach it all it needs to know (false).
+ * @param pszFile The source position of the call, file.
+ * @param iLine The source position of the call, line.
+ * @param pszFunction The source position of the call, function.
+ * @param pszNameFmt Class name format string, optional (NULL). Max
+ * length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTLockValidatorClassCreate(PRTLOCKVALCLASS phClass, bool fAutodidact, RT_SRC_POS_DECL, const char *pszNameFmt, ...);
+
+/**
+ * Creates a new lock validator class with a reference that is consumed by the
+ * first call to RTLockValidatorClassRetain.
+ *
+ * This is tailored for use in the parameter list of a semaphore constructor.
+ *
+ * @returns Class handle with a reference that is automatically consumed by the
+ * first retainer. NIL_RTLOCKVALCLASS if we run into trouble.
+ *
+ * @param pszFile The source position of the call, file.
+ * @param iLine The source position of the call, line.
+ * @param pszFunction The source position of the call, function.
+ * @param pszNameFmt Class name format string, optional (NULL). Max
+ * length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(RTLOCKVALCLASS) RTLockValidatorClassCreateUnique(RT_SRC_POS_DECL, const char *pszNameFmt, ...);
+
+/**
+ * Finds a class for the specified source position.
+ *
+ * @returns A handle to the class (not retained!) or NIL_RTLOCKVALCLASS.
+ * @param pSrcPos The source position.
+ */
+RTDECL(RTLOCKVALCLASS) RTLockValidatorClassFindForSrcPos(PRTLOCKVALSRCPOS pSrcPos);
+
+/**
+ * Finds or creates a class given the source position.
+ *
+ * @returns Class handle (not retained!) or NIL_RTLOCKVALCLASS.
+ * @param pszFile The source file.
+ * @param iLine The line in that source file.
+ * @param pszFunction The function name.
+ * @param pszNameFmt Class name format string, optional (NULL). Max
+ * length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(RTLOCKVALCLASS) RTLockValidatorClassForSrcPos(RT_SRC_POS_DECL, const char *pszNameFmt, ...);
+
+/**
+ * Retains a reference to a lock validator class.
+ *
+ * @returns New reference count; UINT32_MAX if the handle is invalid.
+ * @param hClass Handle to the class.
+ */
+RTDECL(uint32_t) RTLockValidatorClassRetain(RTLOCKVALCLASS hClass);
+
+/**
+ * Releases a reference to a lock validator class.
+ *
+ * @returns New reference count. 0 if hClass is NIL_RTLOCKVALCLASS. UINT32_MAX
+ * if the handle is invalid.
+ * @param hClass Handle to the class.
+ */
+RTDECL(uint32_t) RTLockValidatorClassRelease(RTLOCKVALCLASS hClass);
+
+/**
+ * Teaches the class @a hClass that locks in the class @a hPriorClass can be
+ * held when taking a lock of class @hClass
+ *
+ * @returns IPRT status.
+ * @param hClass Handle to the pupil class.
+ * @param hPriorClass Handle to the class that can be held prior to
+ * taking a lock in the pupil class. (No reference
+ * is consumed.)
+ */
+RTDECL(int) RTLockValidatorClassAddPriorClass(RTLOCKVALCLASS hClass, RTLOCKVALCLASS hPriorClass);
+
+/**
+ * Enables or disables the strict release order enforcing.
+ *
+ * @returns IPRT status.
+ * @param hClass Handle to the class to change.
+ * @param fEnable Enable it (true) or disable it (false).
+ */
+RTDECL(int) RTLockValidatorClassEnforceStrictReleaseOrder(RTLOCKVALCLASS hClass, bool fEnabled);
+
+/**
+ * Enables / disables the lock validator for new locks.
+ *
+ * @returns The old setting.
+ * @param fEnabled The new setting.
+ */
+RTDECL(bool) RTLockValidatorSetEnabled(bool fEnabled);
+
+/**
+ * Is the lock validator enabled?
+ *
+ * @returns True if enabled, false if not.
+ */
+RTDECL(bool) RTLockValidatorIsEnabled(void);
+
+/**
+ * Controls whether the lock validator should be quiet or noisy (default).
+ *
+ * @returns The old setting.
+ * @param fQuiet The new setting.
+ */
+RTDECL(bool) RTLockValidatorSetQuiet(bool fQuiet);
+
+/**
+ * Is the lock validator quiet or noisy?
+ *
+ * @returns True if it is quiet, false if noisy.
+ */
+RTDECL(bool) RTLockValidatorIsQuiet(void);
+
+/**
+ * Makes the lock validator panic (default) or not.
+ *
+ * @returns The old setting.
+ * @param fPanic The new setting.
+ */
+RTDECL(bool) RTLockValidatorSetMayPanic(bool fPanic);
+
+/**
+ * Can the lock validator cause panic.
+ *
+ * @returns True if it can, false if not.
+ */
+RTDECL(bool) RTLockValidatorMayPanic(void);
+
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/log.h b/include/iprt/log.h
new file mode 100644
index 00000000..cce17079
--- /dev/null
+++ b/include/iprt/log.h
@@ -0,0 +1,1984 @@
+/** @file
+ * IPRT - Logging.
+ */
+
+/*
+ * 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 ___iprt_log_h
+#define ___iprt_log_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_log RTLog - Logging
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * IPRT Logging Groups.
+ * (Remember to update RT_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 RTLOGGROUP
+{
+ /** Default logging group. */
+ RTLOGGROUP_DEFAULT,
+ RTLOGGROUP_DBG,
+ RTLOGGROUP_DBG_DWARF,
+ RTLOGGROUP_DIR,
+ RTLOGGROUP_FILE,
+ RTLOGGROUP_FS,
+ RTLOGGROUP_LDR,
+ RTLOGGROUP_PATH,
+ RTLOGGROUP_PROCESS,
+ RTLOGGROUP_SYMLINK,
+ RTLOGGROUP_THREAD,
+ RTLOGGROUP_TIME,
+ RTLOGGROUP_TIMER,
+ RTLOGGROUP_ZIP = 31,
+ RTLOGGROUP_FIRST_USER = 32
+} RTLOGGROUP;
+
+/** @def RT_LOGGROUP_NAMES
+ * IPRT Logging group names.
+ *
+ * Must correspond 100% to RTLOGGROUP!
+ * 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 RT_LOGGROUP_NAMES \
+ "DEFAULT", \
+ "RT_DBG", \
+ "RT_DBG_DWARF", \
+ "RT_DIR", \
+ "RT_FILE", \
+ "RT_FS", \
+ "RT_LDR", \
+ "RT_PATH", \
+ "RT_PROCESS", \
+ "RT_SYMLINK", \
+ "RT_THREAD", \
+ "RT_TIME", \
+ "RT_TIMER", \
+ "RT_13", \
+ "RT_14", \
+ "RT_15", \
+ "RT_16", \
+ "RT_17", \
+ "RT_18", \
+ "RT_19", \
+ "RT_20", \
+ "RT_21", \
+ "RT_22", \
+ "RT_23", \
+ "RT_24", \
+ "RT_25", \
+ "RT_26", \
+ "RT_27", \
+ "RT_28", \
+ "RT_29", \
+ "RT_30", \
+ "RT_ZIP" \
+
+
+/** @def LOG_GROUP
+ * Active logging group.
+ */
+#ifndef LOG_GROUP
+# define LOG_GROUP RTLOGGROUP_DEFAULT
+#endif
+
+/** @def LOG_INSTANCE
+ * Active logging instance.
+ */
+#ifndef LOG_INSTANCE
+# define LOG_INSTANCE NULL
+#endif
+
+/** @def LOG_REL_INSTANCE
+ * Active release logging instance.
+ */
+#ifndef LOG_REL_INSTANCE
+# define LOG_REL_INSTANCE NULL
+#endif
+
+/** @def LOG_FN_FMT
+ * You can use this to specify you desired way of printing __PRETTY_FUNCTION__
+ * if you dislike the default one.
+ */
+#ifndef LOG_FN_FMT
+# define LOG_FN_FMT "%Rfn"
+#endif
+
+/** Logger structure. */
+#ifdef IN_RC
+typedef struct RTLOGGERRC RTLOGGER;
+#else
+typedef struct RTLOGGER RTLOGGER;
+#endif
+/** Pointer to logger structure. */
+typedef RTLOGGER *PRTLOGGER;
+/** Pointer to const logger structure. */
+typedef const RTLOGGER *PCRTLOGGER;
+
+
+/** Guest context logger structure. */
+typedef struct RTLOGGERRC RTLOGGERRC;
+/** Pointer to guest context logger structure. */
+typedef RTLOGGERRC *PRTLOGGERRC;
+/** Pointer to const guest context logger structure. */
+typedef const RTLOGGERRC *PCRTLOGGERRC;
+
+
+/**
+ * Logger phase.
+ *
+ * Used for signalling the log header/footer callback what to do.
+ */
+typedef enum RTLOGPHASE
+{
+ /** Begin of the logging. */
+ RTLOGPHASE_BEGIN = 0,
+ /** End of the logging. */
+ RTLOGPHASE_END,
+ /** Before rotating the log file. */
+ RTLOGPHASE_PREROTATE,
+ /** After rotating the log file. */
+ RTLOGPHASE_POSTROTATE,
+ /** 32-bit type blow up hack. */
+ RTLOGPHASE_32BIT_HACK = 0x7fffffff
+} RTLOGPHASE;
+
+
+/**
+ * Logger function.
+ *
+ * @param pszFormat Format string.
+ * @param ... Optional arguments as specified in the format string.
+ */
+typedef DECLCALLBACK(void) FNRTLOGGER(const char *pszFormat, ...);
+/** Pointer to logger function. */
+typedef FNRTLOGGER *PFNRTLOGGER;
+
+/**
+ * Flush function.
+ *
+ * @param pLogger Pointer to the logger instance which is to be flushed.
+ */
+typedef DECLCALLBACK(void) FNRTLOGFLUSH(PRTLOGGER pLogger);
+/** Pointer to flush function. */
+typedef FNRTLOGFLUSH *PFNRTLOGFLUSH;
+
+/**
+ * Flush function.
+ *
+ * @param pLogger Pointer to the logger instance which is to be flushed.
+ */
+typedef DECLCALLBACK(void) FNRTLOGFLUSHGC(PRTLOGGERRC pLogger);
+/** Pointer to logger function. */
+typedef RCPTRTYPE(FNRTLOGFLUSHGC *) PFNRTLOGFLUSHGC;
+
+/**
+ * Header/footer message callback.
+ *
+ * @param pLogger Pointer to the logger instance.
+ * @param pszFormat Format string.
+ * @param ... Optional arguments specified in the format string.
+ */
+typedef DECLCALLBACK(void) FNRTLOGPHASEMSG(PRTLOGGER pLogger, const char *pszFormat, ...);
+/** Pointer to header/footer message callback function. */
+typedef FNRTLOGPHASEMSG *PFNRTLOGPHASEMSG;
+
+/**
+ * Log file header/footer callback.
+ *
+ * @param pLogger Pointer to the logger instance.
+ * @param enmLogPhase Indicates at what time the callback is invoked.
+ * @param pfnLogPhaseMsg Callback for writing the header/footer (RTLogPrintf
+ * and others are out of bounds).
+ */
+typedef DECLCALLBACK(void) FNRTLOGPHASE(PRTLOGGER pLogger, RTLOGPHASE enmLogPhase, PFNRTLOGPHASEMSG pfnLogPhaseMsg);
+/** Pointer to log header/footer callback function. */
+typedef FNRTLOGPHASE *PFNRTLOGPHASE;
+
+/**
+ * Custom log prefix callback.
+ *
+ *
+ * @returns The number of chars written.
+ *
+ * @param pLogger Pointer to the logger instance.
+ * @param pchBuf Output buffer pointer.
+ * No need to terminate the output.
+ * @param cchBuf The size of the output buffer.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(size_t) FNRTLOGPREFIX(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
+/** Pointer to prefix callback function. */
+typedef FNRTLOGPREFIX *PFNRTLOGPREFIX;
+
+
+
+/**
+ * Logger instance structure for GC.
+ */
+struct RTLOGGERRC
+{
+ /** Pointer to temporary scratch buffer.
+ * This is used to format the log messages. */
+ char achScratch[32768];
+ /** Current scratch buffer position. */
+ uint32_t offScratch;
+ /** This is set if a prefix is pending. */
+ bool fPendingPrefix;
+ bool afAlignment[3];
+ /** Pointer to the logger function.
+ * This is actually pointer to a wrapper which will push a pointer to the
+ * instance pointer onto the stack before jumping to the real logger function.
+ * A very unfortunate hack to work around the missing variadic macro support in C++. */
+ RCPTRTYPE(PFNRTLOGGER) pfnLogger;
+ /** Pointer to the flush function. */
+ PFNRTLOGFLUSHGC pfnFlush;
+ /** Magic number (RTLOGGERRC_MAGIC). */
+ uint32_t u32Magic;
+ /** Logger instance flags - RTLOGFLAGS. */
+ uint32_t fFlags;
+ /** Number of groups in the afGroups member. */
+ uint32_t cGroups;
+ /** Group flags array - RTLOGGRPFLAGS.
+ * This member have variable length and may extend way beyond
+ * the declared size of 1 entry. */
+ uint32_t afGroups[1];
+};
+
+/** RTLOGGERRC::u32Magic value. (John Rogers Searle) */
+#define RTLOGGERRC_MAGIC 0x19320731
+
+
+
+#ifndef IN_RC
+
+/** Pointer to internal logger bits. */
+typedef struct RTLOGGERINTERNAL *PRTLOGGERINTERNAL;
+
+/**
+ * Logger instance structure.
+ */
+struct RTLOGGER
+{
+ /** Pointer to temporary scratch buffer.
+ * This is used to format the log messages. */
+ char achScratch[49152];
+ /** Current scratch buffer position. */
+ uint32_t offScratch;
+ /** Magic number. */
+ uint32_t u32Magic;
+ /** Logger instance flags - RTLOGFLAGS. */
+ uint32_t fFlags;
+ /** Destination flags - RTLOGDEST. */
+ uint32_t fDestFlags;
+ /** Pointer to the internal bits of the logger.
+ * (The memory is allocated in the same block as RTLOGGER.) */
+ PRTLOGGERINTERNAL pInt;
+ /** Pointer to the logger function (used in non-C99 mode only).
+ *
+ * This is actually pointer to a wrapper which will push a pointer to the
+ * instance pointer onto the stack before jumping to the real logger function.
+ * A very unfortunate hack to work around the missing variadic macro
+ * support in older C++/C standards. (The memory is allocated using
+ * RTMemExecAlloc(), except for agnostic R0 code.) */
+ PFNRTLOGGER pfnLogger;
+ /** Number of groups in the afGroups and papszGroups members. */
+ uint32_t cGroups;
+ /** Group flags array - RTLOGGRPFLAGS.
+ * This member have variable length and may extend way beyond
+ * the declared size of 1 entry. */
+ uint32_t afGroups[1];
+};
+
+/** RTLOGGER::u32Magic value. (Avram Noam Chomsky) */
+# define RTLOGGER_MAGIC UINT32_C(0x19281207)
+
+#endif /* !IN_RC */
+
+
+/**
+ * Logger flags.
+ */
+typedef enum RTLOGFLAGS
+{
+ /** The logger instance is disabled for normal output. */
+ RTLOGFLAGS_DISABLED = 0x00000001,
+ /** The logger instance is using buffered output. */
+ RTLOGFLAGS_BUFFERED = 0x00000002,
+ /** The logger instance expands LF to CR/LF. */
+ RTLOGFLAGS_USECRLF = 0x00000010,
+ /** Append to the log destination where applicable. */
+ RTLOGFLAGS_APPEND = 0x00000020,
+ /** Show relative timestamps with PREFIX_TSC and PREFIX_TS */
+ RTLOGFLAGS_REL_TS = 0x00000040,
+ /** Show decimal timestamps with PREFIX_TSC and PREFIX_TS */
+ RTLOGFLAGS_DECIMAL_TS = 0x00000080,
+ /** Open the file in write through mode. */
+ RTLOGFLAGS_WRITE_THROUGH = 0x00000100,
+ /** Flush the file to disk when flushing the buffer. */
+ RTLOGFLAGS_FLUSH = 0x00000200,
+ /** Restrict the number of log entries per group. */
+ RTLOGFLAGS_RESTRICT_GROUPS = 0x00000400,
+ /** New lines should be prefixed with the write and read lock counts. */
+ RTLOGFLAGS_PREFIX_LOCK_COUNTS = 0x00008000,
+ /** New lines should be prefixed with the CPU id (ApicID on intel/amd). */
+ RTLOGFLAGS_PREFIX_CPUID = 0x00010000,
+ /** New lines should be prefixed with the native process id. */
+ RTLOGFLAGS_PREFIX_PID = 0x00020000,
+ /** New lines should be prefixed with group flag number causing the output. */
+ RTLOGFLAGS_PREFIX_FLAG_NO = 0x00040000,
+ /** New lines should be prefixed with group flag name causing the output. */
+ RTLOGFLAGS_PREFIX_FLAG = 0x00080000,
+ /** New lines should be prefixed with group number. */
+ RTLOGFLAGS_PREFIX_GROUP_NO = 0x00100000,
+ /** New lines should be prefixed with group name. */
+ RTLOGFLAGS_PREFIX_GROUP = 0x00200000,
+ /** New lines should be prefixed with the native thread id. */
+ RTLOGFLAGS_PREFIX_TID = 0x00400000,
+ /** New lines should be prefixed with thread name. */
+ RTLOGFLAGS_PREFIX_THREAD = 0x00800000,
+ /** New lines should be prefixed with data from a custom callback. */
+ RTLOGFLAGS_PREFIX_CUSTOM = 0x01000000,
+ /** New lines should be prefixed with formatted timestamp since program start. */
+ RTLOGFLAGS_PREFIX_TIME_PROG = 0x04000000,
+ /** New lines should be prefixed with formatted timestamp (UCT). */
+ RTLOGFLAGS_PREFIX_TIME = 0x08000000,
+ /** New lines should be prefixed with milliseconds since program start. */
+ RTLOGFLAGS_PREFIX_MS_PROG = 0x10000000,
+ /** New lines should be prefixed with timestamp. */
+ RTLOGFLAGS_PREFIX_TSC = 0x20000000,
+ /** New lines should be prefixed with timestamp. */
+ RTLOGFLAGS_PREFIX_TS = 0x40000000,
+ /** The prefix mask. */
+ RTLOGFLAGS_PREFIX_MASK = 0x7dff8000
+} RTLOGFLAGS;
+
+/**
+ * Logger per group flags.
+ */
+typedef enum RTLOGGRPFLAGS
+{
+ /** Enabled. */
+ RTLOGGRPFLAGS_ENABLED = 0x00000001,
+ /** Level 1 logging. */
+ RTLOGGRPFLAGS_LEVEL_1 = 0x00000002,
+ /** Level 2 logging. */
+ RTLOGGRPFLAGS_LEVEL_2 = 0x00000004,
+ /** Level 3 logging. */
+ RTLOGGRPFLAGS_LEVEL_3 = 0x00000008,
+ /** Level 4 logging. */
+ RTLOGGRPFLAGS_LEVEL_4 = 0x00000010,
+ /** Level 5 logging. */
+ RTLOGGRPFLAGS_LEVEL_5 = 0x00000020,
+ /** Level 6 logging. */
+ RTLOGGRPFLAGS_LEVEL_6 = 0x00000040,
+ /** Flow logging. */
+ RTLOGGRPFLAGS_FLOW = 0x00000080,
+ /** Restrict the number of log entries. */
+ RTLOGGRPFLAGS_RESTRICT = 0x00000100,
+
+ /** Lelik logging. */
+ RTLOGGRPFLAGS_LELIK = 0x00010000,
+ /** Michael logging. */
+ RTLOGGRPFLAGS_MICHAEL = 0x00020000,
+ /** sunlover logging. */
+ RTLOGGRPFLAGS_SUNLOVER = 0x00040000,
+ /** Achim logging. */
+ RTLOGGRPFLAGS_ACHIM = 0x00080000,
+ /** Sander logging. */
+ RTLOGGRPFLAGS_SANDER = 0x00100000,
+ /** Klaus logging. */
+ RTLOGGRPFLAGS_KLAUS = 0x00200000,
+ /** Frank logging. */
+ RTLOGGRPFLAGS_FRANK = 0x00400000,
+ /** bird logging. */
+ RTLOGGRPFLAGS_BIRD = 0x00800000,
+ /** aleksey logging. */
+ RTLOGGRPFLAGS_ALEKSEY = 0x01000000,
+ /** dj logging. */
+ RTLOGGRPFLAGS_DJ = 0x02000000,
+ /** NoName logging. */
+ RTLOGGRPFLAGS_NONAME = 0x04000000
+} RTLOGGRPFLAGS;
+
+/**
+ * Logger destination type.
+ */
+typedef enum RTLOGDEST
+{
+ /** Log to file. */
+ RTLOGDEST_FILE = 0x00000001,
+ /** Log to stdout. */
+ RTLOGDEST_STDOUT = 0x00000002,
+ /** Log to stderr. */
+ RTLOGDEST_STDERR = 0x00000004,
+ /** Log to debugger (win32 only). */
+ RTLOGDEST_DEBUGGER = 0x00000008,
+ /** Log to com port. */
+ RTLOGDEST_COM = 0x00000010,
+ /** Just a dummy flag to be used when no other flag applies. */
+ RTLOGDEST_DUMMY = 0x20000000,
+ /** Log to a user defined output stream. */
+ RTLOGDEST_USER = 0x40000000
+} RTLOGDEST;
+
+
+RTDECL(void) RTLogPrintfEx(void *pvInstance, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
+
+
+#ifdef DOXYGEN_RUNNING
+# define LOG_DISABLED
+# define LOG_ENABLED
+# define LOG_ENABLE_FLOW
+#endif
+
+/** @def LOG_DISABLED
+ * Use this compile time define to disable all logging macros. It can
+ * be overridden for each of the logging macros by the LOG_ENABLE*
+ * compile time defines.
+ */
+
+/** @def LOG_ENABLED
+ * Use this compile time define to enable logging when not in debug mode
+ * or LOG_DISABLED is set.
+ * This will enabled Log() only.
+ */
+
+/** @def LOG_ENABLE_FLOW
+ * Use this compile time define to enable flow logging when not in
+ * debug mode or LOG_DISABLED is defined.
+ * This will enable LogFlow() only.
+ */
+
+/*
+ * Determine whether logging is enabled and forcefully normalize the indicators.
+ */
+#if (defined(DEBUG) || defined(LOG_ENABLED)) && !defined(LOG_DISABLED)
+# undef LOG_DISABLED
+# undef LOG_ENABLED
+# define LOG_ENABLED
+#else
+# undef LOG_ENABLED
+# undef LOG_DISABLED
+# define LOG_DISABLED
+#endif
+
+
+/** @def LOG_USE_C99
+ * Governs the use of variadic macros.
+ */
+#ifndef LOG_USE_C99
+# if defined(RT_ARCH_AMD64) || defined(RT_OS_DARWIN) || defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+# define LOG_USE_C99
+# endif
+#endif
+
+
+/** @def LogIt
+ * Write to specific logger if group enabled.
+ */
+#ifdef LOG_ENABLED
+# if defined(LOG_USE_C99)
+# define _LogRemoveParentheseis(...) __VA_ARGS__
+# define _LogIt(a_pvInst, a_fFlags, a_iGroup, ...) RTLogLoggerEx((PRTLOGGER)a_pvInst, a_fFlags, a_iGroup, __VA_ARGS__)
+# define LogIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) _LogIt(a_pvInst, a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
+# define _LogItAlways(a_pvInst, a_fFlags, a_iGroup, ...) RTLogLoggerEx((PRTLOGGER)a_pvInst, a_fFlags, ~0U, __VA_ARGS__)
+# define LogItAlways(a_pvInst, a_fFlags, a_iGroup, fmtargs) _LogItAlways(a_pvInst, a_fFlags, a_iGroup, _LogRemoveParentheseis fmtargs)
+ /** @todo invent a flag or something for skipping the group check so we can pass iGroup. LogItAlways. */
+# else
+# define LogIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) \
+ do \
+ { \
+ register PRTLOGGER LogIt_pLogger = (PRTLOGGER)(a_pvInst) ? (PRTLOGGER)(a_pvInst) : RTLogDefaultInstance(); \
+ if ( LogIt_pLogger \
+ && !(LogIt_pLogger->fFlags & RTLOGFLAGS_DISABLED)) \
+ { \
+ register unsigned LogIt_fFlags = LogIt_pLogger->afGroups[(unsigned)(a_iGroup) < LogIt_pLogger->cGroups ? (unsigned)(a_iGroup) : 0]; \
+ if ((LogIt_fFlags & ((a_fFlags) | RTLOGGRPFLAGS_ENABLED)) == ((a_fFlags) | RTLOGGRPFLAGS_ENABLED)) \
+ LogIt_pLogger->pfnLogger fmtargs; \
+ } \
+ } while (0)
+# define LogItAlways(a_pvInst, a_fFlags, a_iGroup, fmtargs) \
+ do \
+ { \
+ register PRTLOGGER LogIt_pLogger = (PRTLOGGER)(a_pvInst) ? (PRTLOGGER)(a_pvInst) : RTLogDefaultInstance(); \
+ if ( LogIt_pLogger \
+ && !(LogIt_pLogger->fFlags & RTLOGFLAGS_DISABLED)) \
+ LogIt_pLogger->pfnLogger fmtargs; \
+ } while (0)
+# endif
+#else
+# define LogIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) do { } while (0)
+# define LogItAlways(a_pvInst, a_fFlags, a_iGroup, fmtargs) do { } while (0)
+# if defined(LOG_USE_C99)
+# define _LogRemoveParentheseis(...) __VA_ARGS__
+# define _LogIt(a_pvInst, a_fFlags, a_iGroup, ...) do { } while (0)
+# define _LogItAlways(a_pvInst, a_fFlags, a_iGroup, ...) do { } while (0)
+# endif
+#endif
+
+
+/** @def Log
+ * Level 1 logging that works regardless of the group settings.
+ */
+#define LogAlways(a) LogItAlways(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def Log
+ * Level 1 logging.
+ */
+#define Log(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def Log2
+ * Level 2 logging.
+ */
+#define Log2(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
+
+/** @def Log3
+ * Level 3 logging.
+ */
+#define Log3(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
+
+/** @def Log4
+ * Level 4 logging.
+ */
+#define Log4(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
+
+/** @def Log5
+ * Level 5 logging.
+ */
+#define Log5(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
+
+/** @def Log6
+ * Level 6 logging.
+ */
+#define Log6(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
+
+/** @def LogFlow
+ * Logging of execution flow.
+ */
+#define LogFlow(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
+
+/** @def LogLelik
+ * lelik logging.
+ */
+#define LogLelik(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LELIK, LOG_GROUP, a)
+
+
+/** @def LogMichael
+ * michael logging.
+ */
+#define LogMichael(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_MICHAEL, LOG_GROUP, a)
+
+/** @def LogSunlover
+ * sunlover logging.
+ */
+#define LogSunlover(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_SUNLOVER, LOG_GROUP, a)
+
+/** @def LogAchim
+ * Achim logging.
+ */
+#define LogAchim(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_ACHIM, LOG_GROUP, a)
+
+/** @def LogSander
+ * Sander logging.
+ */
+#define LogSander(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_SANDER, LOG_GROUP, a)
+
+/** @def LogKlaus
+ * klaus logging.
+ */
+#define LogKlaus(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_KLAUS, LOG_GROUP, a)
+
+/** @def LogFrank
+ * frank logging.
+ */
+#define LogFrank(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FRANK, LOG_GROUP, a)
+
+/** @def LogBird
+ * bird logging.
+ */
+#define LogBird(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_BIRD, LOG_GROUP, a)
+
+/** @def LogAleksey
+ * aleksey logging.
+ */
+#define LogAleksey(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_ALEKSEY, LOG_GROUP, a)
+
+/** @def LogDJ
+ * dj logging.
+ */
+#define LogDJ(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_DJ, LOG_GROUP, a)
+
+/** @def LogNoName
+ * NoName logging.
+ */
+#define LogNoName(a) LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_NONAME, LOG_GROUP, a)
+
+/** @def LogWarning
+ * The same as Log(), but prepents a <tt>"WARNING! "</tt> string to the message.
+ *
+ * @param a Custom log message in format <tt>("string\n" [, args])</tt>.
+ */
+#if defined(LOG_USE_C99)
+# define LogWarning(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "WARNING! %M", _LogRemoveParentheseis a )
+#else
+# define LogWarning(a) \
+ do { Log(("WARNING! ")); Log(a); } while (0)
+#endif
+
+/** @def LogTrace
+ * Macro to trace the execution flow: logs the file name, line number and
+ * function name. Can be easily searched for in log files using the
+ * ">>>>>" pattern (prepended to the beginning of each line).
+ */
+#define LogTrace() \
+ LogFlow((">>>>> %s (%d): " LOG_FN_FMT "\n", __FILE__, __LINE__, __PRETTY_FUNCTION__))
+
+/** @def LogTraceMsg
+ * The same as LogTrace but logs a custom log message right after the trace line.
+ *
+ * @param a Custom log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogTraceMsg(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, ">>>>> %s (%d): " LOG_FN_FMT ": %M", __FILE__, __LINE__, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogTraceMsg(a) \
+ do { LogFlow((">>>>> %s (%d): " LOG_FN_FMT ": ", __FILE__, __LINE__, __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
+#endif
+
+/** @def LogFunc
+ * Level 1 logging inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by a
+ * semicolon and space.
+ *
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogFunc(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogFunc(a) \
+ do { Log((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+/** @def LogThisFunc
+ * The same as LogFunc but for class functions (methods): the resulting log
+ * line is additionally prepended with a hex value of |this| pointer.
+ *
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogThisFunc(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogThisFunc(a) \
+ do { Log(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+/** @def LogFlowFunc
+ * Macro to log the execution flow inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by
+ * a semicolon and space.
+ *
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogFlowFunc(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogFlowFunc(a) \
+ do { LogFlow((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
+#endif
+
+/** @def LogWarningFunc
+ * The same as LogWarning(), but prepents the log message with the function name.
+ *
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogWarningFunc(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": WARNING! %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogWarningFunc(a) \
+ do { Log((LOG_FN_FMT ": WARNING! ", __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+/** @def LogFlowThisFunc
+ * The same as LogFlowFunc but for class functions (methods): the resulting log
+ * line is additionally prepended with a hex value of |this| pointer.
+ *
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogFlowThisFunc(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogFlowThisFunc(a) \
+ do { LogFlow(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogFlow(a); } while (0)
+#endif
+
+/** @def LogWarningThisFunc
+ * The same as LogWarningFunc() but for class functions (methods): the resulting
+ * log line is additionally prepended with a hex value of |this| pointer.
+ *
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogWarningThisFunc(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": WARNING! %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogWarningThisFunc(a) \
+ do { Log(("{%p} " LOG_FN_FMT ": WARNING! ", this, __PRETTY_FUNCTION__)); Log(a); } while (0)
+#endif
+
+/** Shortcut to |LogFlowFunc ("ENTER\n")|, marks the beginnig of the function. */
+#define LogFlowFuncEnter() LogFlowFunc(("ENTER\n"))
+
+/** Shortcut to |LogFlowFunc ("LEAVE\n")|, marks the end of the function. */
+#define LogFlowFuncLeave() LogFlowFunc(("LEAVE\n"))
+
+/** Shortcut to |LogFlowFunc ("LEAVE: %Rrc\n")|, marks the end of the function. */
+#define LogFlowFuncLeaveRC(rc) LogFlowFunc(("LEAVE: %Rrc\n", (rc)))
+
+/** Shortcut to |LogFlowThisFunc ("ENTER\n")|, marks the beginnig of the function. */
+#define LogFlowThisFuncEnter() LogFlowThisFunc(("ENTER\n"))
+
+/** Shortcut to |LogFlowThisFunc ("LEAVE\n")|, marks the end of the function. */
+#define LogFlowThisFuncLeave() LogFlowThisFunc(("LEAVE\n"))
+
+/** @def LogObjRefCnt
+ * Helper macro to print the current reference count of the given COM object
+ * to the log file.
+ *
+ * @param pObj Pointer to the object in question (must be a pointer to an
+ * IUnknown subclass or simply define COM-style AddRef() and
+ * Release() methods)
+ *
+ * @note Use it only for temporary debugging. It leaves dummy code even if
+ * logging is disabled.
+ */
+#define LogObjRefCnt(pObj) \
+ do { \
+ int refc = (pObj)->AddRef(); \
+ LogFlow((#pObj "{%p}.refCnt=%d\n", (pObj), refc - 1)); \
+ (pObj)->Release(); \
+ } while (0)
+
+
+/** @def LogIsItEnabled
+ * Checks whether the specified logging group is enabled or not.
+ */
+#ifdef LOG_ENABLED
+# define LogIsItEnabled(a_pvInst, a_fFlags, a_iGroup) \
+ LogIsItEnabledInternal((a_pvInst), (unsigned)(a_iGroup), (unsigned)(a_fFlags))
+#else
+# define LogIsItEnabled(a_pvInst, a_fFlags, a_iGroup) (false)
+#endif
+
+/** @def LogIsEnabled
+ * Checks whether level 1 logging is enabled.
+ */
+#define LogIsEnabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
+
+/** @def LogIs2Enabled
+ * Checks whether level 2 logging is enabled.
+ */
+#define LogIs2Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
+
+/** @def LogIs3Enabled
+ * Checks whether level 3 logging is enabled.
+ */
+#define LogIs3Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
+
+/** @def LogIs4Enabled
+ * Checks whether level 4 logging is enabled.
+ */
+#define LogIs4Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
+
+/** @def LogIs5Enabled
+ * Checks whether level 5 logging is enabled.
+ */
+#define LogIs5Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
+
+/** @def LogIs6Enabled
+ * Checks whether level 6 logging is enabled.
+ */
+#define LogIs6Enabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
+
+/** @def LogIsFlowEnabled
+ * Checks whether execution flow logging is enabled.
+ */
+#define LogIsFlowEnabled() LogIsItEnabled(LOG_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP)
+
+
+/** @name Passing Function Call Position When Logging.
+ *
+ * This is a little bit ugly as we have to omit the comma before the
+ * position parameters so that we don't inccur any overhead in non-logging
+ * builds (!defined(LOG_ENABLED).
+ *
+ * @{ */
+/** Source position for passing to a function call. */
+#ifdef LOG_ENABLED
+# define RTLOG_COMMA_SRC_POS , __FILE__, __LINE__, __PRETTY_FUNCTION__
+#else
+# define RTLOG_COMMA_SRC_POS RT_NOTHING
+#endif
+/** Source position declaration. */
+#ifdef LOG_ENABLED
+# define RTLOG_COMMA_SRC_POS_DECL , const char *pszFile, unsigned iLine, const char *pszFunction
+#else
+# define RTLOG_COMMA_SRC_POS_DECL RT_NOTHING
+#endif
+/** Source position arguments. */
+#ifdef LOG_ENABLED
+# define RTLOG_COMMA_SRC_POS_ARGS , pszFile, iLine, pszFunction
+#else
+# define RTLOG_COMMA_SRC_POS_ARGS RT_NOTHING
+#endif
+/** Applies NOREF() to the source position arguments. */
+#ifdef LOG_ENABLED
+# define RTLOG_SRC_POS_NOREF() do { NOREF(pszFile); NOREF(iLine); NOREF(pszFunction); } while (0)
+#else
+# define RTLOG_SRC_POS_NOREF() do { } while (0)
+#endif
+/** @} */
+
+
+
+/** @name Release Logging
+ * @{
+ */
+
+#ifdef DOXYGEN_RUNNING
+# define RTLOG_REL_DISABLED
+# define RTLOG_REL_ENABLED
+#endif
+
+/** @def RTLOG_REL_DISABLED
+ * Use this compile time define to disable all release logging
+ * macros.
+ */
+
+/** @def RTLOG_REL_ENABLED
+ * Use this compile time define to override RTLOG_REL_DISABLE.
+ */
+
+/*
+ * Determine whether release logging is enabled and forcefully normalize the indicators.
+ */
+#if !defined(RTLOG_REL_DISABLED) || defined(RTLOG_REL_ENABLED)
+# undef RTLOG_REL_DISABLED
+# undef RTLOG_REL_ENABLED
+# define RTLOG_REL_ENABLED
+#else
+# undef RTLOG_REL_ENABLED
+# undef RTLOG_REL_DISABLED
+# define RTLOG_REL_DISABLED
+#endif
+
+
+/** @def LogIt
+ * Write to specific logger if group enabled.
+ */
+#ifdef RTLOG_REL_ENABLED
+# if defined(LOG_USE_C99)
+# define _LogRelRemoveParentheseis(...) __VA_ARGS__
+# define _LogRelIt(a_pvInst, a_fFlags, a_iGroup, ...) \
+ do \
+ { \
+ PRTLOGGER LogRelIt_pLogger = (PRTLOGGER)(a_pvInst) ? (PRTLOGGER)(a_pvInst) : RTLogRelDefaultInstance(); \
+ if ( LogRelIt_pLogger \
+ && !(LogRelIt_pLogger->fFlags & RTLOGFLAGS_DISABLED)) \
+ RTLogLoggerEx(LogRelIt_pLogger, a_fFlags, a_iGroup, __VA_ARGS__); \
+ _LogIt(LOG_INSTANCE, a_fFlags, a_iGroup, __VA_ARGS__); \
+ } while (0)
+# define LogRelIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) _LogRelIt(a_pvInst, a_fFlags, a_iGroup, _LogRelRemoveParentheseis fmtargs)
+# else
+# define LogRelIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) \
+ do \
+ { \
+ PRTLOGGER LogRelIt_pLogger = (PRTLOGGER)(a_pvInst) ? (PRTLOGGER)(a_pvInst) : RTLogRelDefaultInstance(); \
+ if ( LogRelIt_pLogger \
+ && !(LogRelIt_pLogger->fFlags & RTLOGFLAGS_DISABLED)) \
+ { \
+ unsigned LogIt_fFlags = LogRelIt_pLogger->afGroups[(unsigned)(a_iGroup) < LogRelIt_pLogger->cGroups ? (unsigned)(a_iGroup) : 0]; \
+ if ((LogIt_fFlags & ((a_fFlags) | RTLOGGRPFLAGS_ENABLED)) == ((a_fFlags) | RTLOGGRPFLAGS_ENABLED)) \
+ LogRelIt_pLogger->pfnLogger fmtargs; \
+ } \
+ LogIt(LOG_INSTANCE, a_fFlags, a_iGroup, fmtargs); \
+ } while (0)
+# endif
+#else /* !RTLOG_REL_ENABLED */
+# define LogRelIt(a_pvInst, a_fFlags, a_iGroup, fmtargs) do { } while (0)
+# if defined(LOG_USE_C99)
+# define _LogRelRemoveParentheseis(...) __VA_ARGS__
+# define _LogRelIt(a_pvInst, a_fFlags, a_iGroup, ...) do { } while (0)
+# endif
+#endif /* !RTLOG_REL_ENABLED */
+
+
+/** @def LogRel
+ * Level 1 logging.
+ */
+#define LogRel(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, a)
+
+/** @def LogRel2
+ * Level 2 logging.
+ */
+#define LogRel2(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP, a)
+
+/** @def LogRel3
+ * Level 3 logging.
+ */
+#define LogRel3(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP, a)
+
+/** @def LogRel4
+ * Level 4 logging.
+ */
+#define LogRel4(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP, a)
+
+/** @def LogRel5
+ * Level 5 logging.
+ */
+#define LogRel5(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP, a)
+
+/** @def LogRel6
+ * Level 6 logging.
+ */
+#define LogRel6(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP, a)
+
+/** @def LogRelFlow
+ * Logging of execution flow.
+ */
+#define LogRelFlow(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, a)
+
+/** @def LogRelFunc
+ * Release logging. Prepends the given log message with the function name
+ * followed by a semicolon and space.
+ */
+#ifdef LOG_USE_C99
+# define LogRelFunc(a) \
+ _LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+# define LogFunc(a) \
+ _LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelFunc(a) \
+ do { LogRel((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRel(a); } while (0)
+#endif
+
+/** @def LogRelThisFunc
+ * The same as LogRelFunc but for class functions (methods): the resulting log
+ * line is additionally prepended with a hex value of |this| pointer.
+ */
+#ifdef LOG_USE_C99
+# define LogRelThisFunc(a) \
+ _LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP, "{%p} " LOG_FN_FMT ": %M", this, __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelThisFunc(a) \
+ do { LogRel(("{%p} " LOG_FN_FMT ": ", this, __PRETTY_FUNCTION__)); LogRel(a); } while (0)
+#endif
+
+/** @def LogRelFlowFunc
+ * Release logging. Macro to log the execution flow inside C/C++ functions.
+ *
+ * Prepends the given log message with the function name followed by
+ * a semicolon and space.
+ *
+ * @param a Log message in format <tt>("string\n" [, args])</tt>.
+ */
+#ifdef LOG_USE_C99
+# define LogRelFlowFunc(a) \
+ _LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP, LOG_FN_FMT ": %M", __PRETTY_FUNCTION__, _LogRemoveParentheseis a )
+#else
+# define LogRelFlowFunc(a) \
+ do { LogRelFlow((LOG_FN_FMT ": ", __PRETTY_FUNCTION__)); LogRelFlow(a); } while (0)
+#endif
+
+/** @def LogRelLelik
+ * lelik logging.
+ */
+#define LogRelLelik(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LELIK, LOG_GROUP, a)
+
+/** @def LogRelMichael
+ * michael logging.
+ */
+#define LogRelMichael(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_MICHAEL, LOG_GROUP, a)
+
+/** @def LogRelSunlover
+ * sunlover logging.
+ */
+#define LogRelSunlover(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_SUNLOVER, LOG_GROUP, a)
+
+/** @def LogRelAchim
+ * Achim logging.
+ */
+#define LogRelAchim(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_ACHIM, LOG_GROUP, a)
+
+/** @def LogRelSander
+ * Sander logging.
+ */
+#define LogRelSander(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_SANDER, LOG_GROUP, a)
+
+/** @def LogRelKlaus
+ * klaus logging.
+ */
+#define LogRelKlaus(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_KLAUS, LOG_GROUP, a)
+
+/** @def LogRelFrank
+ * frank logging.
+ */
+#define LogRelFrank(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_FRANK, LOG_GROUP, a)
+
+/** @def LogRelBird
+ * bird logging.
+ */
+#define LogRelBird(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_BIRD, LOG_GROUP, a)
+
+/** @def LogRelNoName
+ * NoName logging.
+ */
+#define LogRelNoName(a) LogRelIt(LOG_REL_INSTANCE, RTLOGGRPFLAGS_NONAME, LOG_GROUP, a)
+
+
+/** @def LogRelIsItEnabled
+ * Checks whether the specified logging group is enabled or not.
+ */
+#define LogRelIsItEnabled(a_pvInst, a_fFlags, a_iGroup) \
+ LogRelIsItEnabledInternal((a_pvInst), (unsigned)(a_iGroup), (unsigned)(a_fFlags))
+
+/** @def LogRelIsEnabled
+ * Checks whether level 1 logging is enabled.
+ */
+#define LogRelIsEnabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_1, LOG_GROUP)
+
+/** @def LogRelIs2Enabled
+ * Checks whether level 2 logging is enabled.
+ */
+#define LogRelIs2Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_2, LOG_GROUP)
+
+/** @def LogRelIs3Enabled
+ * Checks whether level 3 logging is enabled.
+ */
+#define LogRelIs3Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_3, LOG_GROUP)
+
+/** @def LogRelIs4Enabled
+ * Checks whether level 4 logging is enabled.
+ */
+#define LogRelIs4Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_4, LOG_GROUP)
+
+/** @def LogRelIs5Enabled
+ * Checks whether level 5 logging is enabled.
+ */
+#define LogRelIs5Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP)
+
+/** @def LogRelIs6Enabled
+ * Checks whether level 6 logging is enabled.
+ */
+#define LogRelIs6Enabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_LEVEL_6, LOG_GROUP)
+
+/** @def LogRelIsFlowEnabled
+ * Checks whether execution flow logging is enabled.
+ */
+#define LogRelIsFlowEnabled() LogRelIsItEnabled(LOG_REL_INSTANCE, RTLOGGRPFLAGS_FLOW, LOG_GROUP)
+
+
+#ifndef IN_RC
+/**
+ * Sets the default release logger instance.
+ *
+ * @returns The old default instance.
+ * @param pLogger The new default release logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogRelSetDefaultInstance(PRTLOGGER pLogger);
+#endif /* !IN_RC */
+
+/**
+ * Gets the default release logger instance.
+ *
+ * @returns Pointer to default release logger instance.
+ * @returns NULL if no default release logger instance available.
+ */
+RTDECL(PRTLOGGER) RTLogRelDefaultInstance(void);
+
+/** Internal worker function.
+ * Don't call directly, use the LogRelIsItEnabled macro!
+ */
+DECLINLINE(bool) LogRelIsItEnabledInternal(void *pvInst, unsigned iGroup, unsigned fFlags)
+{
+ register PRTLOGGER pLogger = (PRTLOGGER)pvInst ? (PRTLOGGER)pvInst : RTLogRelDefaultInstance();
+ if ( pLogger
+ && !(pLogger->fFlags & RTLOGFLAGS_DISABLED))
+ {
+ register unsigned fGrpFlags = pLogger->afGroups[(unsigned)iGroup < pLogger->cGroups ? (unsigned)iGroup : 0];
+ if ((fGrpFlags & (fFlags | RTLOGGRPFLAGS_ENABLED)) == (fFlags | RTLOGGRPFLAGS_ENABLED))
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Write to a logger instance, defaulting to the release one.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param pLogger Pointer to logger instance.
+ * @param fFlags The logging flags.
+ * @param iGroup The group.
+ * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ * only for internal usage!
+ * @param pszFormat Format string.
+ * @param ... Format arguments.
+ * @remark This is a worker function for LogRelIt.
+ */
+RTDECL(void) RTLogRelLogger(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
+
+/**
+ * Write to a logger instance, defaulting to the release one.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param pLogger Pointer to logger instance. If NULL the default release instance is attempted.
+ * @param fFlags The logging flags.
+ * @param iGroup The group.
+ * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ * only for internal usage!
+ * @param pszFormat Format string.
+ * @param args Format arguments.
+ */
+RTDECL(void) RTLogRelLoggerV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
+
+/**
+ * printf like function for writing to the default release log.
+ *
+ * @param pszFormat Printf like format string.
+ * @param ... Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogRelPrintf(const char *pszFormat, ...);
+
+/**
+ * vprintf like function for writing to the default release log.
+ *
+ * @param pszFormat Printf like format string.
+ * @param args Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogRelPrintfV(const char *pszFormat, va_list args);
+
+/**
+ * Changes the buffering setting of the default release logger.
+ *
+ * This can be used for optimizing longish logging sequences.
+ *
+ * @returns The old state.
+ * @param fBuffered The new state.
+ */
+RTDECL(bool) RTLogRelSetBuffering(bool fBuffered);
+
+/** @} */
+
+
+
+/** @name COM port logging
+ * {
+ */
+
+#ifdef DOXYGEN_RUNNING
+# define LOG_TO_COM
+# define LOG_NO_COM
+#endif
+
+/** @def LOG_TO_COM
+ * Redirects the normal logging macros to the serial versions.
+ */
+
+/** @def LOG_NO_COM
+ * Disables all LogCom* macros.
+ */
+
+/** @def LogCom
+ * Generic logging to serial port.
+ */
+#if defined(LOG_ENABLED) && !defined(LOG_NO_COM)
+# define LogCom(a) RTLogComPrintf a
+#else
+# define LogCom(a) do { } while (0)
+#endif
+
+/** @def LogComFlow
+ * Logging to serial port of execution flow.
+ */
+#if defined(LOG_ENABLED) && defined(LOG_ENABLE_FLOW) && !defined(LOG_NO_COM)
+# define LogComFlow(a) RTLogComPrintf a
+#else
+# define LogComFlow(a) do { } while (0)
+#endif
+
+#ifdef LOG_TO_COM
+# undef Log
+# define Log(a) LogCom(a)
+# undef LogFlow
+# define LogFlow(a) LogComFlow(a)
+#endif
+
+/** @} */
+
+
+/** @name Backdoor Logging
+ * @{
+ */
+
+#ifdef DOXYGEN_RUNNING
+# define LOG_TO_BACKDOOR
+# define LOG_NO_BACKDOOR
+#endif
+
+/** @def LOG_TO_BACKDOOR
+ * Redirects the normal logging macros to the backdoor versions.
+ */
+
+/** @def LOG_NO_BACKDOOR
+ * Disables all LogBackdoor* macros.
+ */
+
+/** @def LogBackdoor
+ * Generic logging to the VBox backdoor via port I/O.
+ */
+#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
+# define LogBackdoor(a) RTLogBackdoorPrintf a
+#else
+# define LogBackdoor(a) do { } while (0)
+#endif
+
+/** @def LogBackdoorFlow
+ * Logging of execution flow messages to the backdoor I/O port.
+ */
+#if defined(LOG_ENABLED) && !defined(LOG_NO_BACKDOOR)
+# define LogBackdoorFlow(a) RTLogBackdoorPrintf a
+#else
+# define LogBackdoorFlow(a) do { } while (0)
+#endif
+
+/** @def LogRelBackdoor
+ * Release logging to the VBox backdoor via port I/O.
+ */
+#if !defined(LOG_NO_BACKDOOR)
+# define LogRelBackdoor(a) RTLogBackdoorPrintf a
+#else
+# define LogRelBackdoor(a) do { } while (0)
+#endif
+
+#ifdef LOG_TO_BACKDOOR
+# undef Log
+# define Log(a) LogBackdoor(a)
+# undef LogFlow
+# define LogFlow(a) LogBackdoorFlow(a)
+# undef LogRel
+# define LogRel(a) LogRelBackdoor(a)
+# if defined(LOG_USE_C99)
+# undef _LogIt
+# define _LogIt(a_pvInst, a_fFlags, a_iGroup, ...) LogBackdoor((__VA_ARGS__))
+# endif
+#endif
+
+/** @} */
+
+
+
+/**
+ * Gets the default logger instance, creating it if necessary.
+ *
+ * @returns Pointer to default logger instance.
+ * @returns NULL if no default logger instance available.
+ */
+RTDECL(PRTLOGGER) RTLogDefaultInstance(void);
+
+/**
+ * Gets the default logger instance.
+ *
+ * @returns Pointer to default logger instance.
+ * @returns NULL if no default logger instance available.
+ */
+RTDECL(PRTLOGGER) RTLogGetDefaultInstance(void);
+
+#ifndef IN_RC
+/**
+ * Sets the default logger instance.
+ *
+ * @returns The old default instance.
+ * @param pLogger The new default logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogSetDefaultInstance(PRTLOGGER pLogger);
+#endif /* !IN_RC */
+
+#ifdef IN_RING0
+/**
+ * Changes the default logger instance for the current thread.
+ *
+ * @returns IPRT status code.
+ * @param pLogger The logger instance. Pass NULL for deregistration.
+ * @param uKey Associated key for cleanup purposes. If pLogger is NULL,
+ * all instances with this key will be deregistered. So in
+ * order to only deregister the instance associated with the
+ * current thread use 0.
+ */
+RTDECL(int) RTLogSetDefaultInstanceThread(PRTLOGGER pLogger, uintptr_t uKey);
+#endif /* IN_RING0 */
+
+
+#ifdef LOG_ENABLED
+/** Internal worker function.
+ * Don't call directly, use the LogIsItEnabled macro!
+ */
+DECLINLINE(bool) LogIsItEnabledInternal(void *pvInst, unsigned iGroup, unsigned fFlags)
+{
+ register PRTLOGGER pLogger = (PRTLOGGER)pvInst ? (PRTLOGGER)pvInst : RTLogDefaultInstance();
+ if ( pLogger
+ && !(pLogger->fFlags & RTLOGFLAGS_DISABLED))
+ {
+ register unsigned fGrpFlags = pLogger->afGroups[(unsigned)iGroup < pLogger->cGroups ? (unsigned)iGroup : 0];
+ if ((fGrpFlags & (fFlags | RTLOGGRPFLAGS_ENABLED)) == (fFlags | RTLOGGRPFLAGS_ENABLED))
+ return true;
+ }
+ return false;
+}
+#endif
+
+
+#ifndef IN_RC
+/**
+ * Creates the default logger instance for a iprt users.
+ *
+ * Any user of the logging features will need to implement
+ * this or use the generic dummy.
+ *
+ * @returns Pointer to the logger instance.
+ */
+RTDECL(PRTLOGGER) RTLogDefaultInit(void);
+
+/**
+ * Create a logger instance.
+ *
+ * @returns iprt status code.
+ *
+ * @param ppLogger Where to store the logger instance.
+ * @param fFlags Logger instance flags, a combination of the
+ * RTLOGFLAGS_* values.
+ * @param pszGroupSettings The initial group settings.
+ * @param pszEnvVarBase Base name for the environment variables for
+ * this instance.
+ * @param cGroups Number of groups in the array.
+ * @param papszGroups Pointer to array of groups. This must stick
+ * around for the life of the logger instance.
+ * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
+ * if pszFilenameFmt specified.
+ * @param pszFilenameFmt Log filename format string. Standard
+ * RTStrFormat().
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTLogCreate(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+ const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+ uint32_t fDestFlags, const char *pszFilenameFmt, ...);
+
+/**
+ * Create a logger instance.
+ *
+ * @returns iprt status code.
+ *
+ * @param ppLogger Where to store the logger instance.
+ * @param fFlags Logger instance flags, a combination of the
+ * RTLOGFLAGS_* values.
+ * @param pszGroupSettings The initial group settings.
+ * @param pszEnvVarBase Base name for the environment variables for
+ * this instance.
+ * @param cGroups Number of groups in the array.
+ * @param papszGroups Pointer to array of groups. This must stick
+ * around for the life of the logger instance.
+ * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
+ * if pszFilenameFmt specified.
+ * @param pfnPhase Callback function for starting logging and for
+ * ending or starting a new file for log history
+ * rotation. NULL is OK.
+ * @param cHistory Number of old log files to keep when performing
+ * log history rotation. 0 means no history.
+ * @param cbHistoryFileMax Maximum size of log file when performing
+ * history rotation. 0 means no size limit.
+ * @param cSecsHistoryTimeSlot Maximum time interval per log file when
+ * performing history rotation, in seconds.
+ * 0 means time limit.
+ * @param pszErrorMsg A buffer which is filled with an error message if something fails. May be NULL.
+ * @param cchErrorMsg The size of the error message buffer.
+ * @param pszFilenameFmt Log filename format string. Standard RTStrFormat().
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTLogCreateEx(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+ const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+ uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
+ uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
+ char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, ...);
+
+/**
+ * Create a logger instance.
+ *
+ * @returns iprt status code.
+ *
+ * @param ppLogger Where to store the logger instance.
+ * @param fFlags Logger instance flags, a combination of the
+ * RTLOGFLAGS_* values.
+ * @param pszGroupSettings The initial group settings.
+ * @param pszEnvVarBase Base name for the environment variables for
+ * this instance.
+ * @param cGroups Number of groups in the array.
+ * @param papszGroups Pointer to array of groups. This must stick
+ * around for the life of the logger instance.
+ * @param fDestFlags The destination flags. RTLOGDEST_FILE is ORed
+ * if pszFilenameFmt specified.
+ * @param pfnPhase Callback function for starting logging and for
+ * ending or starting a new file for log history
+ * rotation.
+ * @param cHistory Number of old log files to keep when performing
+ * log history rotation. 0 means no history.
+ * @param cbHistoryFileMax Maximum size of log file when performing
+ * history rotation. 0 means no size limit.
+ * @param cSecsHistoryTimeSlot Maximum time interval per log file when
+ * performing history rotation, in seconds.
+ * 0 means no time limit.
+ * @param pszErrorMsg A buffer which is filled with an error message
+ * if something fails. May be NULL.
+ * @param cchErrorMsg The size of the error message buffer.
+ * @param pszFilenameFmt Log filename format string. Standard
+ * RTStrFormat().
+ * @param args Format arguments.
+ */
+RTDECL(int) RTLogCreateExV(PRTLOGGER *ppLogger, uint32_t fFlags, const char *pszGroupSettings,
+ const char *pszEnvVarBase, unsigned cGroups, const char * const * papszGroups,
+ uint32_t fDestFlags, PFNRTLOGPHASE pfnPhase, uint32_t cHistory,
+ uint64_t cbHistoryFileMax, uint32_t cSecsHistoryTimeSlot,
+ char *pszErrorMsg, size_t cchErrorMsg, const char *pszFilenameFmt, va_list args);
+
+/**
+ * Create a logger instance for singled threaded ring-0 usage.
+ *
+ * @returns iprt status code.
+ *
+ * @param pLogger Where to create the logger instance.
+ * @param cbLogger The amount of memory available for the logger instance.
+ * @param pLoggerR0Ptr The ring-0 address corresponding to @a pLogger.
+ * @param pfnLoggerR0Ptr Pointer to logger wrapper function.
+ * @param pfnFlushR0Ptr Pointer to flush function.
+ * @param fFlags Logger instance flags, a combination of the RTLOGFLAGS_* values.
+ * @param fDestFlags The destination flags.
+ */
+RTDECL(int) RTLogCreateForR0(PRTLOGGER pLogger, size_t cbLogger,
+ RTR0PTR pLoggerR0Ptr, RTR0PTR pfnLoggerR0Ptr, RTR0PTR pfnFlushR0Ptr,
+ uint32_t fFlags, uint32_t fDestFlags);
+
+/**
+ * Calculates the minimum size of a ring-0 logger instance.
+ *
+ * @returns The minimum size.
+ * @param cGroups The number of groups.
+ * @param fFlags Relevant flags.
+ */
+RTDECL(size_t) RTLogCalcSizeForR0(uint32_t cGroups, uint32_t fFlags);
+
+/**
+ * Destroys a logger instance.
+ *
+ * The instance is flushed and all output destinations closed (where applicable).
+ *
+ * @returns iprt status code.
+ * @param pLogger The logger instance which close destroyed. NULL is fine.
+ */
+RTDECL(int) RTLogDestroy(PRTLOGGER pLogger);
+
+/**
+ * Create a logger instance clone for RC usage.
+ *
+ * @returns iprt status code.
+ *
+ * @param pLogger The logger instance to be cloned.
+ * @param pLoggerRC Where to create the RC logger instance.
+ * @param cbLoggerRC Amount of memory allocated to for the RC logger
+ * instance clone.
+ * @param pfnLoggerRCPtr Pointer to logger wrapper function for this
+ * instance (RC Ptr).
+ * @param pfnFlushRCPtr Pointer to flush function (RC Ptr).
+ * @param fFlags Logger instance flags, a combination of the RTLOGFLAGS_* values.
+ */
+RTDECL(int) RTLogCloneRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC, size_t cbLoggerRC,
+ RTRCPTR pfnLoggerRCPtr, RTRCPTR pfnFlushRCPtr, uint32_t fFlags);
+
+/**
+ * Flushes a RC logger instance to a R3 logger.
+ *
+ * @returns iprt status code.
+ * @param pLogger The R3 logger instance to flush pLoggerRC to. If NULL
+ * the default logger is used.
+ * @param pLoggerRC The RC logger instance to flush.
+ */
+RTDECL(void) RTLogFlushRC(PRTLOGGER pLogger, PRTLOGGERRC pLoggerRC);
+
+/**
+ * Flushes the buffer in one logger instance onto another logger.
+ *
+ * @returns iprt status code.
+ *
+ * @param pSrcLogger The logger instance to flush.
+ * @param pDstLogger The logger instance to flush onto.
+ * If NULL the default logger will be used.
+ */
+RTDECL(void) RTLogFlushToLogger(PRTLOGGER pSrcLogger, PRTLOGGER pDstLogger);
+
+/**
+ * Flushes a R0 logger instance to a R3 logger.
+ *
+ * @returns iprt status code.
+ * @param pLogger The R3 logger instance to flush pLoggerR0 to. If NULL
+ * the default logger is used.
+ * @param pLoggerR0 The R0 logger instance to flush.
+ */
+RTDECL(void) RTLogFlushR0(PRTLOGGER pLogger, PRTLOGGER pLoggerR0);
+
+/**
+ * Sets the custom prefix callback.
+ *
+ * @returns IPRT status code.
+ * @param pLogger The logger instance.
+ * @param pfnCallback The callback.
+ * @param pvUser The user argument for the callback.
+ * */
+RTDECL(int) RTLogSetCustomPrefixCallback(PRTLOGGER pLogger, PFNRTLOGPREFIX pfnCallback, void *pvUser);
+
+/**
+ * Same as RTLogSetCustomPrefixCallback for loggers created by
+ * RTLogCreateForR0.
+ *
+ * @returns IPRT status code.
+ * @param pLogger The logger instance.
+ * @param pLoggerR0Ptr The ring-0 address corresponding to @a pLogger.
+ * @param pfnCallbackR0Ptr The callback.
+ * @param pvUserR0Ptr The user argument for the callback.
+ * */
+RTDECL(int) RTLogSetCustomPrefixCallbackForR0(PRTLOGGER pLogger, RTR0PTR pLoggerR0Ptr,
+ RTR0PTR pfnCallbackR0Ptr, RTR0PTR pvUserR0Ptr);
+
+/**
+ * Copies the group settings and flags from logger instance to another.
+ *
+ * @returns IPRT status code.
+ * @param pDstLogger The destination logger instance.
+ * @param pDstLoggerR0Ptr The ring-0 address corresponding to @a pDstLogger.
+ * @param pSrcLogger The source logger instance. If NULL the default one is used.
+ * @param fFlagsOr OR mask for the flags.
+ * @param fFlagsAnd AND mask for the flags.
+ */
+RTDECL(int) RTLogCopyGroupsAndFlagsForR0(PRTLOGGER pDstLogger, RTR0PTR pDstLoggerR0Ptr,
+ PCRTLOGGER pSrcLogger, uint32_t fFlagsOr, uint32_t fFlagsAnd);
+
+/**
+ * Get the current log group settings as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pLogger Logger instance (NULL for default logger).
+ * @param pszBuf The output buffer.
+ * @param cchBuf The size of the output buffer. Must be greater
+ * than zero.
+ */
+RTDECL(int) RTLogGetGroupSettings(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
+
+/**
+ * Updates the group settings for the logger instance using the specified
+ * specification string.
+ *
+ * @returns iprt status code.
+ * Failures can safely be ignored.
+ * @param pLogger Logger instance (NULL for default logger).
+ * @param pszValue Value to parse.
+ */
+RTDECL(int) RTLogGroupSettings(PRTLOGGER pLogger, const char *pszValue);
+#endif /* !IN_RC */
+
+/**
+ * Updates the flags for the logger instance using the specified
+ * specification string.
+ *
+ * @returns iprt status code.
+ * Failures can safely be ignored.
+ * @param pLogger Logger instance (NULL for default logger).
+ * @param pszValue Value to parse.
+ */
+RTDECL(int) RTLogFlags(PRTLOGGER pLogger, const char *pszValue);
+
+/**
+ * Changes the buffering setting of the specified logger.
+ *
+ * This can be used for optimizing longish logging sequences.
+ *
+ * @returns The old state.
+ * @param pLogger The logger instance (NULL is an alias for the
+ * default logger).
+ * @param fBuffered The new state.
+ */
+RTDECL(bool) RTLogSetBuffering(PRTLOGGER pLogger, bool fBuffered);
+
+/**
+ * Sets the max number of entries per group.
+ *
+ * @returns Old restriction.
+ *
+ * @param pLogger The logger instance (NULL is an alias for the
+ * default logger).
+ * @param cMaxEntriesPerGroup The max number of entries per group.
+ *
+ * @remarks Lowering the limit of an active logger may quietly mute groups.
+ * Raising it may reactive already muted groups.
+ */
+RTDECL(uint32_t) RTLogSetGroupLimit(PRTLOGGER pLogger, uint32_t cMaxEntriesPerGroup);
+
+#ifndef IN_RC
+/**
+ * Get the current log flags as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pLogger Logger instance (NULL for default logger).
+ * @param pszBuf The output buffer.
+ * @param cchBuf The size of the output buffer. Must be greater
+ * than zero.
+ */
+RTDECL(int) RTLogGetFlags(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
+
+/**
+ * Updates the logger destination using the specified string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pLogger Logger instance (NULL for default logger).
+ * @param pszValue The value to parse.
+ */
+RTDECL(int) RTLogDestinations(PRTLOGGER pLogger, char const *pszValue);
+
+/**
+ * Get the current log destinations as a string.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW.
+ * @param pLogger Logger instance (NULL for default logger).
+ * @param pszBuf The output buffer.
+ * @param cchBuf The size of the output buffer. Must be greater
+ * than 0.
+ */
+RTDECL(int) RTLogGetDestinations(PRTLOGGER pLogger, char *pszBuf, size_t cchBuf);
+#endif /* !IN_RC */
+
+/**
+ * Flushes the specified logger.
+ *
+ * @param pLogger The logger instance to flush.
+ * If NULL the default instance is used. The default instance
+ * will not be initialized by this call.
+ */
+RTDECL(void) RTLogFlush(PRTLOGGER pLogger);
+
+/**
+ * Write to a logger instance.
+ *
+ * @param pLogger Pointer to logger instance.
+ * @param pvCallerRet Ignored.
+ * @param pszFormat Format string.
+ * @param ... Format arguments.
+ */
+RTDECL(void) RTLogLogger(PRTLOGGER pLogger, void *pvCallerRet, const char *pszFormat, ...);
+
+/**
+ * Write to a logger instance.
+ *
+ * @param pLogger Pointer to logger instance.
+ * @param pszFormat Format string.
+ * @param args Format arguments.
+ */
+RTDECL(void) RTLogLoggerV(PRTLOGGER pLogger, const char *pszFormat, va_list args);
+
+/**
+ * Write to a logger instance.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
+ * @param fFlags The logging flags.
+ * @param iGroup The group.
+ * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ * only for internal usage!
+ * @param pszFormat Format string.
+ * @param ... Format arguments.
+ * @remark This is a worker function of LogIt.
+ */
+RTDECL(void) RTLogLoggerEx(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, ...);
+
+/**
+ * Write to a logger instance.
+ *
+ * This function will check whether the instance, group and flags makes up a
+ * logging kind which is currently enabled before writing anything to the log.
+ *
+ * @param pLogger Pointer to logger instance. If NULL the default logger instance will be attempted.
+ * @param fFlags The logging flags.
+ * @param iGroup The group.
+ * The value ~0U is reserved for compatibility with RTLogLogger[V] and is
+ * only for internal usage!
+ * @param pszFormat Format string.
+ * @param args Format arguments.
+ */
+RTDECL(void) RTLogLoggerExV(PRTLOGGER pLogger, unsigned fFlags, unsigned iGroup, const char *pszFormat, va_list args);
+
+/**
+ * printf like function for writing to the default log.
+ *
+ * @param pszFormat Printf like format string.
+ * @param ... Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogPrintf(const char *pszFormat, ...);
+
+/**
+ * vprintf like function for writing to the default log.
+ *
+ * @param pszFormat Printf like format string.
+ * @param args Optional arguments as specified in pszFormat.
+ *
+ * @remark The API doesn't support formatting of floating point numbers at the moment.
+ */
+RTDECL(void) RTLogPrintfV(const char *pszFormat, va_list args);
+
+
+#ifndef DECLARED_FNRTSTROUTPUT /* duplicated in iprt/string.h */
+#define DECLARED_FNRTSTROUTPUT
+/**
+ * Output callback.
+ *
+ * @returns number of bytes written.
+ * @param pvArg User argument.
+ * @param pachChars Pointer to an array of utf-8 characters.
+ * @param cbChars Number of bytes in the character array pointed to by pachChars.
+ */
+typedef DECLCALLBACK(size_t) FNRTSTROUTPUT(void *pvArg, const char *pachChars, size_t cbChars);
+/** Pointer to callback function. */
+typedef FNRTSTROUTPUT *PFNRTSTROUTPUT;
+#endif
+
+/**
+ * Partial vsprintf worker implementation.
+ *
+ * @returns number of bytes formatted.
+ * @param pfnOutput Output worker.
+ * Called in two ways. Normally with a string an it's length.
+ * For termination, it's called with NULL for string, 0 for length.
+ * @param pvArg Argument to output worker.
+ * @param pszFormat Format string.
+ * @param args Argument list.
+ */
+RTDECL(size_t) RTLogFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArg, const char *pszFormat, va_list args);
+
+/**
+ * Write log buffer to COM port.
+ *
+ * @param pach Pointer to the buffer to write.
+ * @param cb Number of bytes to write.
+ */
+RTDECL(void) RTLogWriteCom(const char *pach, size_t cb);
+
+/**
+ * Prints a formatted string to the serial port used for logging.
+ *
+ * @returns Number of bytes written.
+ * @param pszFormat Format string.
+ * @param ... Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogComPrintf(const char *pszFormat, ...);
+
+/**
+ * Prints a formatted string to the serial port used for logging.
+ *
+ * @returns Number of bytes written.
+ * @param pszFormat Format string.
+ * @param args Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogComPrintfV(const char *pszFormat, va_list args);
+
+
+#if 0 /* not implemented yet */
+
+/** Indicates that the semaphores shall be used to notify the other
+ * part about buffer changes. */
+#define LOGHOOKBUFFER_FLAGS_SEMAPHORED 1
+
+/**
+ * Log Hook Buffer.
+ * Use to communicate between the logger and a log consumer.
+ */
+typedef struct RTLOGHOOKBUFFER
+{
+ /** Write pointer. */
+ volatile void *pvWrite;
+ /** Read pointer. */
+ volatile void *pvRead;
+ /** Buffer start. */
+ void *pvStart;
+ /** Buffer end (exclusive). */
+ void *pvEnd;
+ /** Signaling semaphore used by the writer to wait on a full buffer.
+ * Only used when indicated in flags. */
+ void *pvSemWriter;
+ /** Signaling semaphore used by the read to wait on an empty buffer.
+ * Only used when indicated in flags. */
+ void *pvSemReader;
+ /** Buffer flags. Current reserved and set to zero. */
+ volatile unsigned fFlags;
+} RTLOGHOOKBUFFER;
+/** Pointer to a log hook buffer. */
+typedef RTLOGHOOKBUFFER *PRTLOGHOOKBUFFER;
+
+
+/**
+ * Register a logging hook.
+ *
+ * This type of logging hooks are expecting different threads acting
+ * producer and consumer. They share a circular buffer which have two
+ * pointers one for each end. When the buffer is full there are two
+ * alternatives (indicated by a buffer flag), either wait for the
+ * consumer to get it's job done, or to write a generic message saying
+ * buffer overflow.
+ *
+ * Since the waiting would need a signal semaphore, we'll skip that for now.
+ *
+ * @returns iprt status code.
+ * @param pBuffer Pointer to a logger hook buffer.
+ */
+RTDECL(int) RTLogRegisterHook(PRTLOGGER pLogger, PRTLOGHOOKBUFFER pBuffer);
+
+/**
+ * Deregister a logging hook registered with RTLogRegisterHook().
+ *
+ * @returns iprt status code.
+ * @param pBuffer Pointer to a logger hook buffer.
+ */
+RTDECL(int) RTLogDeregisterHook(PRTLOGGER pLogger, PRTLOGHOOKBUFFER pBuffer);
+
+#endif /* not implemented yet */
+
+
+
+/**
+ * Write log buffer to a debugger (RTLOGDEST_DEBUGGER).
+ *
+ * @param pach What to write.
+ * @param cb How much to write.
+ * @remark When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteDebugger(const char *pach, size_t cb);
+
+/**
+ * Write log buffer to a user defined output stream (RTLOGDEST_USER).
+ *
+ * @param pach What to write.
+ * @param cb How much to write.
+ * @remark When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteUser(const char *pach, size_t cb);
+
+/**
+ * Write log buffer to stdout (RTLOGDEST_STDOUT).
+ *
+ * @param pach What to write.
+ * @param cb How much to write.
+ * @remark When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteStdOut(const char *pach, size_t cb);
+
+/**
+ * Write log buffer to stdout (RTLOGDEST_STDERR).
+ *
+ * @param pach What to write.
+ * @param cb How much to write.
+ * @remark When linking statically, this function can be replaced by defining your own.
+ */
+RTDECL(void) RTLogWriteStdErr(const char *pach, size_t cb);
+
+#ifdef VBOX
+
+/**
+ * Prints a formatted string to the backdoor port.
+ *
+ * @returns Number of bytes written.
+ * @param pszFormat Format string.
+ * @param ... Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogBackdoorPrintf(const char *pszFormat, ...);
+
+/**
+ * Prints a formatted string to the backdoor port.
+ *
+ * @returns Number of bytes written.
+ * @param pszFormat Format string.
+ * @param args Optional arguments specified in the format string.
+ */
+RTDECL(size_t) RTLogBackdoorPrintfV(const char *pszFormat, va_list args);
+
+#endif /* VBOX */
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/mangling.h b/include/iprt/mangling.h
new file mode 100644
index 00000000..cc8b4ec6
--- /dev/null
+++ b/include/iprt/mangling.h
@@ -0,0 +1,1796 @@
+/** @file
+ * IPRT - Symbol Mangling.
+ *
+ * This header is used to mangle public IPRT symbol to make it possible to have
+ * several IPRT version loaded into one symbol space at the same time. To
+ * enable symbol mangling you create a header which the compiler includes for
+ * every compilation unit (check out the -include option of gcc). Your header
+ * will define RT_MANGLER(name) and then include this header to set up the
+ * actual mappings.
+ */
+
+/*
+ * 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 ___iprt_mangling_h
+#define ___iprt_mangling_h
+
+#ifndef RT_MANGLER
+# error "RT_MANGLER is not defined."
+#endif
+
+#ifndef DOXYGEN_RUNNING
+
+/** @def RT_WITH_MANGLING
+ * Indicates that we're mangling symbols. */
+# define RT_WITH_MANGLING
+
+
+/*
+ * Stable functions (alphabetical order):
+ */
+# define ASMAtomicCmpXchgExU64 RT_MANGLER(ASMAtomicCmpXchgExU64) /* not-some-systems... */
+# define ASMAtomicCmpXchgExU64_EndProc RT_MANGLER(ASMAtomicCmpXchgExU64_EndProc)
+# define ASMAtomicCmpXchgU64 RT_MANGLER(ASMAtomicCmpXchgU64) /* not-some-systems... */
+# define ASMAtomicCmpXchgU64_EndProc RT_MANGLER(ASMAtomicCmpXchgU64_EndProc)
+# define ASMAtomicReadU64 RT_MANGLER(ASMAtomicReadU64) /* not-some-systems... */
+# define ASMAtomicReadU64_EndProc RT_MANGLER(ASMAtomicReadU64_EndProc)
+# define ASMAtomicUoReadU64 RT_MANGLER(ASMAtomicUoReadU64) /* not-some-systems... */
+# define ASMAtomicUoReadU64_EndProc RT_MANGLER(ASMAtomicUoReadU64_EndProc)
+# define ASMAtomicXchgU64 RT_MANGLER(ASMAtomicXchgU64) /* not-some-systems... */
+# define ASMAtomicXchgU64_EndProc RT_MANGLER(ASMAtomicXchgU64_EndProc)
+# define RTAssertAreQuiet RT_MANGLER(RTAssertAreQuiet)
+# define RTAssertMayPanic RT_MANGLER(RTAssertMayPanic)
+# define RTAssertMsg1 RT_MANGLER(RTAssertMsg1)
+# define RTAssertMsg1Weak RT_MANGLER(RTAssertMsg1Weak)
+# define RTAssertMsg2 RT_MANGLER(RTAssertMsg2)
+# define RTAssertMsg2Add RT_MANGLER(RTAssertMsg2Add)
+# define RTAssertMsg2AddV RT_MANGLER(RTAssertMsg2AddV)
+# define RTAssertMsg2AddWeak RT_MANGLER(RTAssertMsg2AddWeak)
+# define RTAssertMsg2AddWeakV RT_MANGLER(RTAssertMsg2AddWeakV)
+# define RTAssertMsg2V RT_MANGLER(RTAssertMsg2V)
+# define RTAssertMsg2Weak RT_MANGLER(RTAssertMsg2Weak)
+# define RTAssertMsg2WeakV RT_MANGLER(RTAssertMsg2WeakV)
+# define RTAssertSetMayPanic RT_MANGLER(RTAssertSetMayPanic)
+# define RTAssertSetQuiet RT_MANGLER(RTAssertSetQuiet)
+# define RTAssertShouldPanic RT_MANGLER(RTAssertShouldPanic)
+# define RTAvlGCPhysDestroy RT_MANGLER(RTAvlGCPhysDestroy)
+# define RTAvlGCPhysDoWithAll RT_MANGLER(RTAvlGCPhysDoWithAll)
+# define RTAvlGCPhysGet RT_MANGLER(RTAvlGCPhysGet)
+# define RTAvlGCPhysGetBestFit RT_MANGLER(RTAvlGCPhysGetBestFit)
+# define RTAvlGCPhysInsert RT_MANGLER(RTAvlGCPhysInsert)
+# define RTAvlGCPhysRemove RT_MANGLER(RTAvlGCPhysRemove)
+# define RTAvlGCPhysRemoveBestFit RT_MANGLER(RTAvlGCPhysRemoveBestFit)
+# define RTAvlGCPtrDestroy RT_MANGLER(RTAvlGCPtrDestroy)
+# define RTAvlGCPtrDoWithAll RT_MANGLER(RTAvlGCPtrDoWithAll)
+# define RTAvlGCPtrGet RT_MANGLER(RTAvlGCPtrGet)
+# define RTAvlGCPtrGetBestFit RT_MANGLER(RTAvlGCPtrGetBestFit)
+# define RTAvlGCPtrInsert RT_MANGLER(RTAvlGCPtrInsert)
+# define RTAvlGCPtrRemove RT_MANGLER(RTAvlGCPtrRemove)
+# define RTAvlGCPtrRemoveBestFit RT_MANGLER(RTAvlGCPtrRemoveBestFit)
+# define RTAvlHCPhysDestroy RT_MANGLER(RTAvlHCPhysDestroy)
+# define RTAvlHCPhysDoWithAll RT_MANGLER(RTAvlHCPhysDoWithAll)
+# define RTAvlHCPhysGet RT_MANGLER(RTAvlHCPhysGet)
+# define RTAvlHCPhysGetBestFit RT_MANGLER(RTAvlHCPhysGetBestFit)
+# define RTAvlHCPhysInsert RT_MANGLER(RTAvlHCPhysInsert)
+# define RTAvlHCPhysRemove RT_MANGLER(RTAvlHCPhysRemove)
+# define RTAvlHCPhysRemoveBestFit RT_MANGLER(RTAvlHCPhysRemoveBestFit)
+# define RTAvllU32Destroy RT_MANGLER(RTAvllU32Destroy)
+# define RTAvllU32DoWithAll RT_MANGLER(RTAvllU32DoWithAll)
+# define RTAvllU32Get RT_MANGLER(RTAvllU32Get)
+# define RTAvllU32GetBestFit RT_MANGLER(RTAvllU32GetBestFit)
+# define RTAvllU32Insert RT_MANGLER(RTAvllU32Insert)
+# define RTAvllU32Remove RT_MANGLER(RTAvllU32Remove)
+# define RTAvllU32RemoveBestFit RT_MANGLER(RTAvllU32RemoveBestFit)
+# define RTAvllU32RemoveNode RT_MANGLER(RTAvllU32RemoveNode)
+# define RTAvloGCPhysDestroy RT_MANGLER(RTAvloGCPhysDestroy)
+# define RTAvloGCPhysDoWithAll RT_MANGLER(RTAvloGCPhysDoWithAll)
+# define RTAvloGCPhysGet RT_MANGLER(RTAvloGCPhysGet)
+# define RTAvloGCPhysGetBestFit RT_MANGLER(RTAvloGCPhysGetBestFit)
+# define RTAvloGCPhysInsert RT_MANGLER(RTAvloGCPhysInsert)
+# define RTAvloGCPhysRemove RT_MANGLER(RTAvloGCPhysRemove)
+# define RTAvloGCPhysRemoveBestFit RT_MANGLER(RTAvloGCPhysRemoveBestFit)
+# define RTAvloGCPtrDestroy RT_MANGLER(RTAvloGCPtrDestroy)
+# define RTAvloGCPtrDoWithAll RT_MANGLER(RTAvloGCPtrDoWithAll)
+# define RTAvloGCPtrGet RT_MANGLER(RTAvloGCPtrGet)
+# define RTAvloGCPtrGetBestFit RT_MANGLER(RTAvloGCPtrGetBestFit)
+# define RTAvloGCPtrInsert RT_MANGLER(RTAvloGCPtrInsert)
+# define RTAvloGCPtrRemove RT_MANGLER(RTAvloGCPtrRemove)
+# define RTAvloGCPtrRemoveBestFit RT_MANGLER(RTAvloGCPtrRemoveBestFit)
+# define RTAvloHCPhysDestroy RT_MANGLER(RTAvloHCPhysDestroy)
+# define RTAvloHCPhysDoWithAll RT_MANGLER(RTAvloHCPhysDoWithAll)
+# define RTAvloHCPhysGet RT_MANGLER(RTAvloHCPhysGet)
+# define RTAvloHCPhysGetBestFit RT_MANGLER(RTAvloHCPhysGetBestFit)
+# define RTAvloHCPhysInsert RT_MANGLER(RTAvloHCPhysInsert)
+# define RTAvloHCPhysRemove RT_MANGLER(RTAvloHCPhysRemove)
+# define RTAvloHCPhysRemoveBestFit RT_MANGLER(RTAvloHCPhysRemoveBestFit)
+# define RTAvloIOPortDestroy RT_MANGLER(RTAvloIOPortDestroy)
+# define RTAvloIOPortDoWithAll RT_MANGLER(RTAvloIOPortDoWithAll)
+# define RTAvloIOPortGet RT_MANGLER(RTAvloIOPortGet)
+# define RTAvloIOPortGetBestFit RT_MANGLER(RTAvloIOPortGetBestFit)
+# define RTAvloIOPortInsert RT_MANGLER(RTAvloIOPortInsert)
+# define RTAvloIOPortRemove RT_MANGLER(RTAvloIOPortRemove)
+# define RTAvloIOPortRemoveBestFit RT_MANGLER(RTAvloIOPortRemoveBestFit)
+# define RTAvloU32Destroy RT_MANGLER(RTAvloU32Destroy)
+# define RTAvloU32DoWithAll RT_MANGLER(RTAvloU32DoWithAll)
+# define RTAvloU32Get RT_MANGLER(RTAvloU32Get)
+# define RTAvloU32GetBestFit RT_MANGLER(RTAvloU32GetBestFit)
+# define RTAvloU32Insert RT_MANGLER(RTAvloU32Insert)
+# define RTAvloU32Remove RT_MANGLER(RTAvloU32Remove)
+# define RTAvloU32RemoveBestFit RT_MANGLER(RTAvloU32RemoveBestFit)
+# define RTAvlPVDestroy RT_MANGLER(RTAvlPVDestroy)
+# define RTAvlPVDoWithAll RT_MANGLER(RTAvlPVDoWithAll)
+# define RTAvlPVGet RT_MANGLER(RTAvlPVGet)
+# define RTAvlPVGetBestFit RT_MANGLER(RTAvlPVGetBestFit)
+# define RTAvlPVInsert RT_MANGLER(RTAvlPVInsert)
+# define RTAvlPVRemove RT_MANGLER(RTAvlPVRemove)
+# define RTAvlPVRemoveBestFit RT_MANGLER(RTAvlPVRemoveBestFit)
+# define RTAvlrFileOffsetDestroy RT_MANGLER(RTAvlrFileOffsetDestroy)
+# define RTAvlrFileOffsetDoWithAll RT_MANGLER(RTAvlrFileOffsetDoWithAll)
+# define RTAvlrFileOffsetGet RT_MANGLER(RTAvlrFileOffsetGet)
+# define RTAvlrFileOffsetGetBestFit RT_MANGLER(RTAvlrFileOffsetGetBestFit)
+# define RTAvlrFileOffsetGetLeft RT_MANGLER(RTAvlrFileOffsetGetLeft)
+# define RTAvlrFileOffsetGetRight RT_MANGLER(RTAvlrFileOffsetGetRight)
+# define RTAvlrFileOffsetGetRoot RT_MANGLER(RTAvlrFileOffsetGetRoot)
+# define RTAvlrFileOffsetInsert RT_MANGLER(RTAvlrFileOffsetInsert)
+# define RTAvlrFileOffsetRangeGet RT_MANGLER(RTAvlrFileOffsetRangeGet)
+# define RTAvlrFileOffsetRangeRemove RT_MANGLER(RTAvlrFileOffsetRangeRemove)
+# define RTAvlrFileOffsetRemove RT_MANGLER(RTAvlrFileOffsetRemove)
+# define RTAvlrGCPtrDestroy RT_MANGLER(RTAvlrGCPtrDestroy)
+# define RTAvlrGCPtrDoWithAll RT_MANGLER(RTAvlrGCPtrDoWithAll)
+# define RTAvlrGCPtrGet RT_MANGLER(RTAvlrGCPtrGet)
+# define RTAvlrGCPtrGetBestFit RT_MANGLER(RTAvlrGCPtrGetBestFit)
+# define RTAvlrGCPtrGetLeft RT_MANGLER(RTAvlrGCPtrGetLeft)
+# define RTAvlrGCPtrGetRight RT_MANGLER(RTAvlrGCPtrGetRight)
+# define RTAvlrGCPtrGetRoot RT_MANGLER(RTAvlrGCPtrGetRoot)
+# define RTAvlrGCPtrInsert RT_MANGLER(RTAvlrGCPtrInsert)
+# define RTAvlrGCPtrRangeGet RT_MANGLER(RTAvlrGCPtrRangeGet)
+# define RTAvlrGCPtrRangeRemove RT_MANGLER(RTAvlrGCPtrRangeRemove)
+# define RTAvlrGCPtrRemove RT_MANGLER(RTAvlrGCPtrRemove)
+# define RTAvlroGCPhysDestroy RT_MANGLER(RTAvlroGCPhysDestroy)
+# define RTAvlroGCPhysDoWithAll RT_MANGLER(RTAvlroGCPhysDoWithAll)
+# define RTAvlroGCPhysGet RT_MANGLER(RTAvlroGCPhysGet)
+# define RTAvlroGCPhysGetBestFit RT_MANGLER(RTAvlroGCPhysGetBestFit)
+# define RTAvlroGCPhysGetLeft RT_MANGLER(RTAvlroGCPhysGetLeft)
+# define RTAvlroGCPhysGetRight RT_MANGLER(RTAvlroGCPhysGetRight)
+# define RTAvlroGCPhysGetRoot RT_MANGLER(RTAvlroGCPhysGetRoot)
+# define RTAvlroGCPhysInsert RT_MANGLER(RTAvlroGCPhysInsert)
+# define RTAvlroGCPhysRangeGet RT_MANGLER(RTAvlroGCPhysRangeGet)
+# define RTAvlroGCPhysRangeRemove RT_MANGLER(RTAvlroGCPhysRangeRemove)
+# define RTAvlroGCPhysRemove RT_MANGLER(RTAvlroGCPhysRemove)
+# define RTAvlroGCPtrDestroy RT_MANGLER(RTAvlroGCPtrDestroy)
+# define RTAvlroGCPtrDoWithAll RT_MANGLER(RTAvlroGCPtrDoWithAll)
+# define RTAvlroGCPtrGet RT_MANGLER(RTAvlroGCPtrGet)
+# define RTAvlroGCPtrGetBestFit RT_MANGLER(RTAvlroGCPtrGetBestFit)
+# define RTAvlroGCPtrGetLeft RT_MANGLER(RTAvlroGCPtrGetLeft)
+# define RTAvlroGCPtrGetRight RT_MANGLER(RTAvlroGCPtrGetRight)
+# define RTAvlroGCPtrGetRoot RT_MANGLER(RTAvlroGCPtrGetRoot)
+# define RTAvlroGCPtrInsert RT_MANGLER(RTAvlroGCPtrInsert)
+# define RTAvlroGCPtrRangeGet RT_MANGLER(RTAvlroGCPtrRangeGet)
+# define RTAvlroGCPtrRangeRemove RT_MANGLER(RTAvlroGCPtrRangeRemove)
+# define RTAvlroGCPtrRemove RT_MANGLER(RTAvlroGCPtrRemove)
+# define RTAvlroIOPortDestroy RT_MANGLER(RTAvlroIOPortDestroy)
+# define RTAvlroIOPortDoWithAll RT_MANGLER(RTAvlroIOPortDoWithAll)
+# define RTAvlroIOPortGet RT_MANGLER(RTAvlroIOPortGet)
+# define RTAvlroIOPortInsert RT_MANGLER(RTAvlroIOPortInsert)
+# define RTAvlroIOPortRangeGet RT_MANGLER(RTAvlroIOPortRangeGet)
+# define RTAvlroIOPortRangeRemove RT_MANGLER(RTAvlroIOPortRangeRemove)
+# define RTAvlroIOPortRemove RT_MANGLER(RTAvlroIOPortRemove)
+# define RTAvlrooGCPtrDestroy RT_MANGLER(RTAvlrooGCPtrDestroy)
+# define RTAvlrooGCPtrDoWithAll RT_MANGLER(RTAvlrooGCPtrDoWithAll)
+# define RTAvlrooGCPtrGet RT_MANGLER(RTAvlrooGCPtrGet)
+# define RTAvlrooGCPtrGetBestFit RT_MANGLER(RTAvlrooGCPtrGetBestFit)
+# define RTAvlrooGCPtrGetLeft RT_MANGLER(RTAvlrooGCPtrGetLeft)
+# define RTAvlrooGCPtrGetNextEqual RT_MANGLER(RTAvlrooGCPtrGetNextEqual)
+# define RTAvlrooGCPtrGetRight RT_MANGLER(RTAvlrooGCPtrGetRight)
+# define RTAvlrooGCPtrGetRoot RT_MANGLER(RTAvlrooGCPtrGetRoot)
+# define RTAvlrooGCPtrInsert RT_MANGLER(RTAvlrooGCPtrInsert)
+# define RTAvlrooGCPtrRangeGet RT_MANGLER(RTAvlrooGCPtrRangeGet)
+# define RTAvlrooGCPtrRangeRemove RT_MANGLER(RTAvlrooGCPtrRangeRemove)
+# define RTAvlrooGCPtrRemove RT_MANGLER(RTAvlrooGCPtrRemove)
+# define RTAvlrPVDestroy RT_MANGLER(RTAvlrPVDestroy)
+# define RTAvlrPVDoWithAll RT_MANGLER(RTAvlrPVDoWithAll)
+# define RTAvlrPVGet RT_MANGLER(RTAvlrPVGet)
+# define RTAvlrPVGetBestFit RT_MANGLER(RTAvlrPVGetBestFit)
+# define RTAvlrPVInsert RT_MANGLER(RTAvlrPVInsert)
+# define RTAvlrPVRangeGet RT_MANGLER(RTAvlrPVRangeGet)
+# define RTAvlrPVRangeRemove RT_MANGLER(RTAvlrPVRangeRemove)
+# define RTAvlrPVRemove RT_MANGLER(RTAvlrPVRemove)
+# define RTAvlrPVRemoveBestFit RT_MANGLER(RTAvlrPVRemoveBestFit)
+# define RTAvlrU64Destroy RT_MANGLER(RTAvlrU64Destroy)
+# define RTAvlrU64DoWithAll RT_MANGLER(RTAvlrU64DoWithAll)
+# define RTAvlrU64Get RT_MANGLER(RTAvlrU64Get)
+# define RTAvlrU64GetBestFit RT_MANGLER(RTAvlrU64GetBestFit)
+# define RTAvlrU64Insert RT_MANGLER(RTAvlrU64Insert)
+# define RTAvlrU64RangeGet RT_MANGLER(RTAvlrU64RangeGet)
+# define RTAvlrU64RangeRemove RT_MANGLER(RTAvlrU64RangeRemove)
+# define RTAvlrU64Remove RT_MANGLER(RTAvlrU64Remove)
+# define RTAvlrU64RemoveBestFit RT_MANGLER(RTAvlrU64RemoveBestFit)
+# define RTAvlrUIntPtrDestroy RT_MANGLER(RTAvlrUIntPtrDestroy)
+# define RTAvlrUIntPtrDoWithAll RT_MANGLER(RTAvlrUIntPtrDoWithAll)
+# define RTAvlrUIntPtrGet RT_MANGLER(RTAvlrUIntPtrGet)
+# define RTAvlrUIntPtrGetBestFit RT_MANGLER(RTAvlrUIntPtrGetBestFit)
+# define RTAvlrUIntPtrGetLeft RT_MANGLER(RTAvlrUIntPtrGetLeft)
+# define RTAvlrUIntPtrGetRight RT_MANGLER(RTAvlrUIntPtrGetRight)
+# define RTAvlrUIntPtrGetRoot RT_MANGLER(RTAvlrUIntPtrGetRoot)
+# define RTAvlrUIntPtrInsert RT_MANGLER(RTAvlrUIntPtrInsert)
+# define RTAvlrUIntPtrRangeGet RT_MANGLER(RTAvlrUIntPtrRangeGet)
+# define RTAvlrUIntPtrRangeRemove RT_MANGLER(RTAvlrUIntPtrRangeRemove)
+# define RTAvlrUIntPtrRemove RT_MANGLER(RTAvlrUIntPtrRemove)
+# define RTAvlU32Destroy RT_MANGLER(RTAvlU32Destroy)
+# define RTAvlU32DoWithAll RT_MANGLER(RTAvlU32DoWithAll)
+# define RTAvlU32Get RT_MANGLER(RTAvlU32Get)
+# define RTAvlU32GetBestFit RT_MANGLER(RTAvlU32GetBestFit)
+# define RTAvlU32Insert RT_MANGLER(RTAvlU32Insert)
+# define RTAvlU32Remove RT_MANGLER(RTAvlU32Remove)
+# define RTAvlU32RemoveBestFit RT_MANGLER(RTAvlU32RemoveBestFit)
+# define RTAvlUIntPtrDestroy RT_MANGLER(RTAvlUIntPtrDestroy)
+# define RTAvlUIntPtrDoWithAll RT_MANGLER(RTAvlUIntPtrDoWithAll)
+# define RTAvlUIntPtrGet RT_MANGLER(RTAvlUIntPtrGet)
+# define RTAvlUIntPtrGetBestFit RT_MANGLER(RTAvlUIntPtrGetBestFit)
+# define RTAvlUIntPtrGetLeft RT_MANGLER(RTAvlUIntPtrGetLeft)
+# define RTAvlUIntPtrGetRight RT_MANGLER(RTAvlUIntPtrGetRight)
+# define RTAvlUIntPtrGetRoot RT_MANGLER(RTAvlUIntPtrGetRoot)
+# define RTAvlUIntPtrInsert RT_MANGLER(RTAvlUIntPtrInsert)
+# define RTAvlUIntPtrRemove RT_MANGLER(RTAvlUIntPtrRemove)
+# define RTAvlULDestroy RT_MANGLER(RTAvlULDestroy)
+# define RTAvlULDoWithAll RT_MANGLER(RTAvlULDoWithAll)
+# define RTAvlULGet RT_MANGLER(RTAvlULGet)
+# define RTAvlULGetBestFit RT_MANGLER(RTAvlULGetBestFit)
+# define RTAvlULInsert RT_MANGLER(RTAvlULInsert)
+# define RTAvlULRemove RT_MANGLER(RTAvlULRemove)
+# define RTAvlULRemoveBestFit RT_MANGLER(RTAvlULRemoveBestFit)
+# define RTBase64Decode RT_MANGLER(RTBase64Decode)
+# define RTBase64DecodedSize RT_MANGLER(RTBase64DecodedSize)
+# define RTBase64Encode RT_MANGLER(RTBase64Encode)
+# define RTBase64EncodedLength RT_MANGLER(RTBase64EncodedLength)
+# define RTBldCfgCompiler RT_MANGLER(RTBldCfgCompiler)
+# define RTBldCfgRevision RT_MANGLER(RTBldCfgRevision)
+# define RTBldCfgRevisionStr RT_MANGLER(RTBldCfgRevisionStr)
+# define RTBldCfgTarget RT_MANGLER(RTBldCfgTarget)
+# define RTBldCfgTargetArch RT_MANGLER(RTBldCfgTargetArch)
+# define RTBldCfgTargetDotArch RT_MANGLER(RTBldCfgTargetDotArch)
+# define RTBldCfgType RT_MANGLER(RTBldCfgType)
+# define RTBldCfgVersion RT_MANGLER(RTBldCfgVersion)
+# define RTBldCfgVersionBuild RT_MANGLER(RTBldCfgVersionBuild)
+# define RTBldCfgVersionMajor RT_MANGLER(RTBldCfgVersionMajor)
+# define RTBldCfgVersionMinor RT_MANGLER(RTBldCfgVersionMinor)
+# define RTCdromOpen RT_MANGLER(RTCdromOpen)
+# define RTCdromRetain RT_MANGLER(RTCdromRetain)
+# define RTCdromRelease RT_MANGLER(RTCdromRelease)
+# define RTCdromQueryMountPoint RT_MANGLER(RTCdromQueryMountPoint)
+# define RTCdromUnmount RT_MANGLER(RTCdromUnmount)
+# define RTCdromEject RT_MANGLER(RTCdromEject)
+# define RTCdromLock RT_MANGLER(RTCdromLock)
+# define RTCdromUnlock RT_MANGLER(RTCdromUnlock)
+# define RTCdromCount RT_MANGLER(RTCdromCount)
+# define RTCdromOrdinalToName RT_MANGLER(RTCdromOrdinalToName)
+# define RTCdromOpenByOrdinal RT_MANGLER(RTCdromOpenByOrdinal)
+# define RTCidrStrToIPv4 RT_MANGLER(RTCidrStrToIPv4)
+# define RTCircBufAcquireReadBlock RT_MANGLER(RTCircBufAcquireReadBlock)
+# define RTCircBufAcquireWriteBlock RT_MANGLER(RTCircBufAcquireWriteBlock)
+# define RTCircBufCreate RT_MANGLER(RTCircBufCreate)
+# define RTCircBufDestroy RT_MANGLER(RTCircBufDestroy)
+# define RTCircBufFree RT_MANGLER(RTCircBufFree)
+# define RTCircBufIsReading RT_MANGLER(RTCircBufIsReading)
+# define RTCircBufIsWriting RT_MANGLER(RTCircBufIsWriting)
+# define RTCircBufReleaseReadBlock RT_MANGLER(RTCircBufReleaseReadBlock)
+# define RTCircBufReleaseWriteBlock RT_MANGLER(RTCircBufReleaseWriteBlock)
+# define RTCircBufReset RT_MANGLER(RTCircBufReset)
+# define RTCircBufSize RT_MANGLER(RTCircBufSize)
+# define RTCircBufUsed RT_MANGLER(RTCircBufUsed)
+# define RTCoreDumperDisable RT_MANGLER(RTCoreDumperDisable) /* solaris */
+# define RTCoreDumperSetup RT_MANGLER(RTCoreDumperSetup) /* solaris */
+# define RTCoreDumperTakeDump RT_MANGLER(RTCoreDumperTakeDump) /* solaris */
+# define RTCrc32 RT_MANGLER(RTCrc32)
+# define RTCrc32Finish RT_MANGLER(RTCrc32Finish)
+# define RTCrc32Process RT_MANGLER(RTCrc32Process)
+# define RTCrc32Start RT_MANGLER(RTCrc32Start)
+# define RTCrc64 RT_MANGLER(RTCrc64)
+# define RTCrc64Finish RT_MANGLER(RTCrc64Finish)
+# define RTCrc64Process RT_MANGLER(RTCrc64Process)
+# define RTCrc64Start RT_MANGLER(RTCrc64Start)
+# define RTCrcAdler32 RT_MANGLER(RTCrcAdler32)
+# define RTCrcAdler32Finish RT_MANGLER(RTCrcAdler32Finish)
+# define RTCrcAdler32Process RT_MANGLER(RTCrcAdler32Process)
+# define RTCrcAdler32Start RT_MANGLER(RTCrcAdler32Start)
+# define RTCritSectDelete RT_MANGLER(RTCritSectDelete)
+# define RTCritSectEnter RT_MANGLER(RTCritSectEnter)
+# define RTCritSectEnterDebug RT_MANGLER(RTCritSectEnterDebug)
+# define RTCritSectEnterMultiple RT_MANGLER(RTCritSectEnterMultiple)
+# define RTCritSectEnterMultipleDebug RT_MANGLER(RTCritSectEnterMultipleDebug)
+# define RTCritSectInit RT_MANGLER(RTCritSectInit)
+# define RTCritSectInitEx RT_MANGLER(RTCritSectInitEx)
+# define RTCritSectLeave RT_MANGLER(RTCritSectLeave)
+# define RTCritSectLeaveMultiple RT_MANGLER(RTCritSectLeaveMultiple)
+# define RTCritSectSetSubClass RT_MANGLER(RTCritSectSetSubClass)
+# define RTCritSectTryEnter RT_MANGLER(RTCritSectTryEnter)
+# define RTCritSectTryEnterDebug RT_MANGLER(RTCritSectTryEnterDebug)
+# define RTDbgAsCreate RT_MANGLER(RTDbgAsCreate)
+# define RTDbgAsCreateF RT_MANGLER(RTDbgAsCreateF)
+# define RTDbgAsCreateV RT_MANGLER(RTDbgAsCreateV)
+# define RTDbgAsFirstAddr RT_MANGLER(RTDbgAsFirstAddr)
+# define RTDbgAsLastAddr RT_MANGLER(RTDbgAsLastAddr)
+# define RTDbgAsLineAdd RT_MANGLER(RTDbgAsLineAdd)
+# define RTDbgAsLineByAddr RT_MANGLER(RTDbgAsLineByAddr)
+# define RTDbgAsLineByAddrA RT_MANGLER(RTDbgAsLineByAddrA)
+# define RTDbgAsModuleByAddr RT_MANGLER(RTDbgAsModuleByAddr)
+# define RTDbgAsModuleByIndex RT_MANGLER(RTDbgAsModuleByIndex)
+# define RTDbgAsModuleByName RT_MANGLER(RTDbgAsModuleByName)
+# define RTDbgAsModuleCount RT_MANGLER(RTDbgAsModuleCount)
+# define RTDbgAsModuleLink RT_MANGLER(RTDbgAsModuleLink)
+# define RTDbgAsModuleLinkSeg RT_MANGLER(RTDbgAsModuleLinkSeg)
+# define RTDbgAsModuleQueryMapByIndex RT_MANGLER(RTDbgAsModuleQueryMapByIndex)
+# define RTDbgAsModuleUnlink RT_MANGLER(RTDbgAsModuleUnlink)
+# define RTDbgAsModuleUnlinkByAddr RT_MANGLER(RTDbgAsModuleUnlinkByAddr)
+# define RTDbgAsName RT_MANGLER(RTDbgAsName)
+# define RTDbgAsRelease RT_MANGLER(RTDbgAsRelease)
+# define RTDbgAsRetain RT_MANGLER(RTDbgAsRetain)
+# define RTDbgAsSymbolAdd RT_MANGLER(RTDbgAsSymbolAdd)
+# define RTDbgAsSymbolByAddr RT_MANGLER(RTDbgAsSymbolByAddr)
+# define RTDbgAsSymbolByAddrA RT_MANGLER(RTDbgAsSymbolByAddrA)
+# define RTDbgAsSymbolByName RT_MANGLER(RTDbgAsSymbolByName)
+# define RTDbgAsSymbolByNameA RT_MANGLER(RTDbgAsSymbolByNameA)
+# define RTDbgLineAlloc RT_MANGLER(RTDbgLineAlloc)
+# define RTDbgLineDup RT_MANGLER(RTDbgLineDup)
+# define RTDbgLineFree RT_MANGLER(RTDbgLineFree)
+# define RTDbgModCreate RT_MANGLER(RTDbgModCreate)
+# define RTDbgModCreateDeferred RT_MANGLER(RTDbgModCreateDeferred)
+# define RTDbgModCreateFromImage RT_MANGLER(RTDbgModCreateFromImage)
+# define RTDbgModCreateFromMap RT_MANGLER(RTDbgModCreateFromMap)
+# define RTDbgModGetTag RT_MANGLER(RTDbgModGetTag)
+# define RTDbgModImageSize RT_MANGLER(RTDbgModImageSize)
+# define RTDbgModLineAdd RT_MANGLER(RTDbgModLineAdd)
+# define RTDbgModLineByAddr RT_MANGLER(RTDbgModLineByAddr)
+# define RTDbgModLineByAddrA RT_MANGLER(RTDbgModLineByAddrA)
+# define RTDbgModLineByOrdinal RT_MANGLER(RTDbgModLineByOrdinal)
+# define RTDbgModLineByOrdinalA RT_MANGLER(RTDbgModLineByOrdinalA)
+# define RTDbgModLineCount RT_MANGLER(RTDbgModLineCount)
+# define RTDbgModName RT_MANGLER(RTDbgModName)
+# define RTDbgModRelease RT_MANGLER(RTDbgModRelease)
+# define RTDbgModRetain RT_MANGLER(RTDbgModRetain)
+# define RTDbgModRvaToSegOff RT_MANGLER(RTDbgModRvaToSegOff)
+# define RTDbgModSegmentAdd RT_MANGLER(RTDbgModSegmentAdd)
+# define RTDbgModSegmentByIndex RT_MANGLER(RTDbgModSegmentByIndex)
+# define RTDbgModSegmentCount RT_MANGLER(RTDbgModSegmentCount)
+# define RTDbgModSegmentRva RT_MANGLER(RTDbgModSegmentRva)
+# define RTDbgModSegmentSize RT_MANGLER(RTDbgModSegmentSize)
+# define RTDbgModSetTag RT_MANGLER(RTDbgModSetTag)
+# define RTDbgModSymbolAdd RT_MANGLER(RTDbgModSymbolAdd)
+# define RTDbgModSymbolByAddr RT_MANGLER(RTDbgModSymbolByAddr)
+# define RTDbgModSymbolByAddrA RT_MANGLER(RTDbgModSymbolByAddrA)
+# define RTDbgModSymbolByName RT_MANGLER(RTDbgModSymbolByName)
+# define RTDbgModSymbolByNameA RT_MANGLER(RTDbgModSymbolByNameA)
+# define RTDbgModSymbolByOrdinal RT_MANGLER(RTDbgModSymbolByOrdinal)
+# define RTDbgModSymbolByOrdinalA RT_MANGLER(RTDbgModSymbolByOrdinalA)
+# define RTDbgModSymbolCount RT_MANGLER(RTDbgModSymbolCount)
+# define RTDbgSymbolAlloc RT_MANGLER(RTDbgSymbolAlloc)
+# define RTDbgSymbolDup RT_MANGLER(RTDbgSymbolDup)
+# define RTDbgSymbolFree RT_MANGLER(RTDbgSymbolFree)
+# define RTDirClose RT_MANGLER(RTDirClose)
+# define RTDirCreate RT_MANGLER(RTDirCreate)
+# define RTDirCreateFullPath RT_MANGLER(RTDirCreateFullPath)
+# define RTDirCreateTemp RT_MANGLER(RTDirCreateTemp)
+# define RTDirCreateTempSecure RT_MANGLER(RTDirCreateTempSecure)
+# define RTDirCreateUniqueNumbered RT_MANGLER(RTDirCreateUniqueNumbered)
+# define RTDirExists RT_MANGLER(RTDirExists)
+# define RTDirFlush RT_MANGLER(RTDirFlush)
+# define RTDirFlushParent RT_MANGLER(RTDirFlushParent)
+# define RTDirOpen RT_MANGLER(RTDirOpen)
+# define RTDirOpenFiltered RT_MANGLER(RTDirOpenFiltered)
+# define RTDirQueryInfo RT_MANGLER(RTDirQueryInfo)
+# define RTDirRead RT_MANGLER(RTDirRead)
+# define RTDirReadEx RT_MANGLER(RTDirReadEx)
+# define RTDirRemove RT_MANGLER(RTDirRemove)
+# define RTDirRemoveRecursive RT_MANGLER(RTDirRemoveRecursive)
+# define RTDirRename RT_MANGLER(RTDirRename)
+# define RTDirSetTimes RT_MANGLER(RTDirSetTimes)
+# define RTDvmCreate RT_MANGLER(RTDvmCreate)
+# define RTDvmRetain RT_MANGLER(RTDvmRetain)
+# define RTDvmRelease RT_MANGLER(RTDvmRelease)
+# define RTDvmMapOpen RT_MANGLER(RTDvmMapOpen)
+# define RTDvmMapInitialize RT_MANGLER(RTDvmMapInitialize)
+# define RTDvmMapGetFormat RT_MANGLER(RTDvmMapGetFormat)
+# define RTDvmMapGetValidVolumes RT_MANGLER(RTDvmMapGetValidVolumes)
+# define RTDvmMapGetMaxVolumes RT_MANGLER(RTDvmMapGetMaxVolumes)
+# define RTDvmMapQueryBlockStatus RT_MANGLER(RTDvmMapQueryBlockStatus)
+# define RTDvmMapQueryFirstVolume RT_MANGLER(RTDvmMapQueryFirstVolume)
+# define RTDvmMapQueryNextVolume RT_MANGLER(RTDvmMapQueryNextVolume)
+# define RTDvmVolumeRetain RT_MANGLER(RTDvmVolumeRetain)
+# define RTDvmVolumeRelease RT_MANGLER(RTDvmVolumeRelease)
+# define RTDvmVolumeGetSize RT_MANGLER(RTDvmVolumeGetSize)
+# define RTDvmVolumeQueryName RT_MANGLER(RTDvmVolumeQueryName)
+# define RTDvmVolumeGetType RT_MANGLER(RTDvmVolumeGetType)
+# define RTDvmVolumeGetFlags RT_MANGLER(RTDvmVolumeGetFlags)
+# define RTDvmVolumeRead RT_MANGLER(RTDvmVolumeRead)
+# define RTDvmVolumeWrite RT_MANGLER(RTDvmVolumeWrite)
+# define RTDvmVolumeSetQueryBlockStatusCallback RT_MANGLER(RTDvmVolumeSetQueryBlockStatusCallback)
+# define RTDvmVolumeTypeGetDescr RT_MANGLER(RTDvmVolumeTypeGetDescr)
+# define RTDvmVolumeCreateVfsFile RT_MANGLER(RTDvmVolumeCreateVfsFile)
+# define RTEnvClone RT_MANGLER(RTEnvClone)
+# define RTEnvCreate RT_MANGLER(RTEnvCreate)
+# define RTEnvDestroy RT_MANGLER(RTEnvDestroy)
+# define RTEnvDupEx RT_MANGLER(RTEnvDupEx)
+# define RTEnvExist RT_MANGLER(RTEnvExist)
+# define RTEnvExistEx RT_MANGLER(RTEnvExistEx)
+# define RTEnvFreeUtf16Block RT_MANGLER(RTEnvFreeUtf16Block)
+# define RTEnvGet RT_MANGLER(RTEnvGet)
+# define RTEnvGetEx RT_MANGLER(RTEnvGetEx)
+# define RTEnvGetExecEnvP RT_MANGLER(RTEnvGetExecEnvP)
+# define RTEnvPut RT_MANGLER(RTEnvPut)
+# define RTEnvPutEx RT_MANGLER(RTEnvPutEx)
+# define RTEnvQueryUtf16Block RT_MANGLER(RTEnvQueryUtf16Block)
+# define RTEnvSet RT_MANGLER(RTEnvSet)
+# define RTEnvSetEx RT_MANGLER(RTEnvSetEx)
+# define RTEnvUnset RT_MANGLER(RTEnvUnset)
+# define RTEnvUnsetEx RT_MANGLER(RTEnvUnsetEx)
+# define RTErrCOMGet RT_MANGLER(RTErrCOMGet)
+# define RTErrConvertFromErrno RT_MANGLER(RTErrConvertFromErrno)
+# define RTErrConvertToErrno RT_MANGLER(RTErrConvertToErrno)
+# define RTErrGet RT_MANGLER(RTErrGet)
+# define RTErrInfoAlloc RT_MANGLER(RTErrInfoAlloc)
+# define RTErrInfoAllocEx RT_MANGLER(RTErrInfoAllocEx)
+# define RTErrInfoFree RT_MANGLER(RTErrInfoFree)
+# define RTErrInfoSet RT_MANGLER(RTErrInfoSet)
+# define RTErrInfoSetF RT_MANGLER(RTErrInfoSetF)
+# define RTErrInfoSetV RT_MANGLER(RTErrInfoSetV)
+# define RTErrVarsAreEqual RT_MANGLER(RTErrVarsAreEqual)
+# define RTErrVarsHaveChanged RT_MANGLER(RTErrVarsHaveChanged)
+# define RTErrVarsRestore RT_MANGLER(RTErrVarsRestore)
+# define RTErrVarsSave RT_MANGLER(RTErrVarsSave)
+# define RTFileAioCtxAssociateWithFile RT_MANGLER(RTFileAioCtxAssociateWithFile)
+# define RTFileAioCtxCreate RT_MANGLER(RTFileAioCtxCreate)
+# define RTFileAioCtxDestroy RT_MANGLER(RTFileAioCtxDestroy)
+# define RTFileAioCtxGetMaxReqCount RT_MANGLER(RTFileAioCtxGetMaxReqCount)
+# define RTFileAioCtxSubmit RT_MANGLER(RTFileAioCtxSubmit)
+# define RTFileAioCtxWait RT_MANGLER(RTFileAioCtxWait)
+# define RTFileAioCtxWakeup RT_MANGLER(RTFileAioCtxWakeup)
+# define RTFileAioGetLimits RT_MANGLER(RTFileAioGetLimits)
+# define RTFileAioReqCancel RT_MANGLER(RTFileAioReqCancel)
+# define RTFileAioReqCreate RT_MANGLER(RTFileAioReqCreate)
+# define RTFileAioReqDestroy RT_MANGLER(RTFileAioReqDestroy)
+# define RTFileAioReqGetRC RT_MANGLER(RTFileAioReqGetRC)
+# define RTFileAioReqGetUser RT_MANGLER(RTFileAioReqGetUser)
+# define RTFileAioReqPrepareFlush RT_MANGLER(RTFileAioReqPrepareFlush)
+# define RTFileAioReqPrepareRead RT_MANGLER(RTFileAioReqPrepareRead)
+# define RTFileAioReqPrepareWrite RT_MANGLER(RTFileAioReqPrepareWrite)
+# define RTFileChangeLock RT_MANGLER(RTFileChangeLock)
+# define RTFileClose RT_MANGLER(RTFileClose)
+# define RTFileCopy RT_MANGLER(RTFileCopy)
+# define RTFileCopyByHandles RT_MANGLER(RTFileCopyByHandles)
+# define RTFileCopyByHandlesEx RT_MANGLER(RTFileCopyByHandlesEx)
+# define RTFileCopyEx RT_MANGLER(RTFileCopyEx)
+# define RTFileCreateTemp RT_MANGLER(RTFileCreateTemp)
+# define RTFileCreateTempSecure RT_MANGLER(RTFileCreateTempSecure)
+# define RTFileDelete RT_MANGLER(RTFileDelete)
+# define RTFileExists RT_MANGLER(RTFileExists)
+# define RTFileFlush RT_MANGLER(RTFileFlush)
+# define RTFileFromNative RT_MANGLER(RTFileFromNative)
+# define RTFileGetMaxSize RT_MANGLER(RTFileGetMaxSize)
+# define RTFileGetMaxSizeEx RT_MANGLER(RTFileGetMaxSizeEx)
+# define RTFileGetSize RT_MANGLER(RTFileGetSize)
+# define RTFileIoCtl RT_MANGLER(RTFileIoCtl)
+# define RTFileIsValid RT_MANGLER(RTFileIsValid)
+# define RTFileLock RT_MANGLER(RTFileLock)
+# define RTFileMove RT_MANGLER(RTFileMove)
+# define RTFileOpen RT_MANGLER(RTFileOpen)
+# define RTFileOpenBitBucket RT_MANGLER(RTFileOpenBitBucket)
+# define RTFileOpenF RT_MANGLER(RTFileOpenF)
+# define RTFileOpenV RT_MANGLER(RTFileOpenV)
+# define RTFileQueryFsSizes RT_MANGLER(RTFileQueryFsSizes)
+# define RTFileQueryInfo RT_MANGLER(RTFileQueryInfo)
+# define RTFileQuerySize RT_MANGLER(RTFileQuerySize)
+# define RTFileRead RT_MANGLER(RTFileRead)
+# define RTFileReadAll RT_MANGLER(RTFileReadAll)
+# define RTFileReadAllByHandle RT_MANGLER(RTFileReadAllByHandle)
+# define RTFileReadAllByHandleEx RT_MANGLER(RTFileReadAllByHandleEx)
+# define RTFileReadAllEx RT_MANGLER(RTFileReadAllEx)
+# define RTFileReadAllFree RT_MANGLER(RTFileReadAllFree)
+# define RTFileReadAt RT_MANGLER(RTFileReadAt)
+# define RTFileRename RT_MANGLER(RTFileRename)
+# define RTFileSeek RT_MANGLER(RTFileSeek)
+# define RTFileSetForceFlags RT_MANGLER(RTFileSetForceFlags)
+# define RTFileSetMode RT_MANGLER(RTFileSetMode)
+# define RTFileSetSize RT_MANGLER(RTFileSetSize)
+# define RTFileSetTimes RT_MANGLER(RTFileSetTimes)
+# define RTFileTell RT_MANGLER(RTFileTell)
+# define RTFileToNative RT_MANGLER(RTFileToNative)
+# define RTFileUnlock RT_MANGLER(RTFileUnlock)
+# define RTFileWrite RT_MANGLER(RTFileWrite)
+# define RTFileWriteAt RT_MANGLER(RTFileWriteAt)
+# define RTFilesystemVfsFromFile RT_MANGLER(RTFilesystemVfsFromFile)
+# define RTFsQueryProperties RT_MANGLER(RTFsQueryProperties)
+# define RTFsQuerySerial RT_MANGLER(RTFsQuerySerial)
+# define RTFsQuerySizes RT_MANGLER(RTFsQuerySizes)
+# define RTFsQueryType RT_MANGLER(RTFsQueryType)
+# define RTFsTypeName RT_MANGLER(RTFsTypeName)
+# define RTGetOpt RT_MANGLER(RTGetOpt)
+# define RTGetOptArgvFree RT_MANGLER(RTGetOptArgvFree)
+# define RTGetOptArgvFromString RT_MANGLER(RTGetOptArgvFromString)
+# define RTGetOptArgvToString RT_MANGLER(RTGetOptArgvToString)
+# define RTGetOptArgvToUtf16String RT_MANGLER(RTGetOptArgvToUtf16String)
+# define RTGetOptFetchValue RT_MANGLER(RTGetOptFetchValue)
+# define RTGetOptInit RT_MANGLER(RTGetOptInit)
+# define RTGetOptPrintError RT_MANGLER(RTGetOptPrintError)
+# define RTHandleClose RT_MANGLER(RTHandleClose)
+# define RTHandleGetStandard RT_MANGLER(RTHandleGetStandard)
+# define RTHandleTableAlloc RT_MANGLER(RTHandleTableAlloc)
+# define RTHandleTableAllocWithCtx RT_MANGLER(RTHandleTableAllocWithCtx)
+# define RTHandleTableCreate RT_MANGLER(RTHandleTableCreate)
+# define RTHandleTableCreateEx RT_MANGLER(RTHandleTableCreateEx)
+# define RTHandleTableDestroy RT_MANGLER(RTHandleTableDestroy)
+# define RTHandleTableFree RT_MANGLER(RTHandleTableFree)
+# define RTHandleTableFreeWithCtx RT_MANGLER(RTHandleTableFreeWithCtx)
+# define RTHandleTableLookup RT_MANGLER(RTHandleTableLookup)
+# define RTHandleTableLookupWithCtx RT_MANGLER(RTHandleTableLookupWithCtx)
+# define RTHeapOffsetAlloc RT_MANGLER(RTHeapOffsetAlloc)
+# define RTHeapOffsetAllocZ RT_MANGLER(RTHeapOffsetAllocZ)
+# define RTHeapOffsetDump RT_MANGLER(RTHeapOffsetDump)
+# define RTHeapOffsetFree RT_MANGLER(RTHeapOffsetFree)
+# define RTHeapOffsetGetFreeSize RT_MANGLER(RTHeapOffsetGetFreeSize)
+# define RTHeapOffsetGetHeapSize RT_MANGLER(RTHeapOffsetGetHeapSize)
+# define RTHeapOffsetInit RT_MANGLER(RTHeapOffsetInit)
+# define RTHeapOffsetSize RT_MANGLER(RTHeapOffsetSize)
+# define RTHeapSimpleAlloc RT_MANGLER(RTHeapSimpleAlloc)
+# define RTHeapSimpleAllocZ RT_MANGLER(RTHeapSimpleAllocZ)
+# define RTHeapSimpleDump RT_MANGLER(RTHeapSimpleDump)
+# define RTHeapSimpleFree RT_MANGLER(RTHeapSimpleFree)
+# define RTHeapSimpleGetFreeSize RT_MANGLER(RTHeapSimpleGetFreeSize)
+# define RTHeapSimpleGetHeapSize RT_MANGLER(RTHeapSimpleGetHeapSize)
+# define RTHeapSimpleInit RT_MANGLER(RTHeapSimpleInit)
+# define RTHeapSimpleRelocate RT_MANGLER(RTHeapSimpleRelocate)
+# define RTHeapSimpleSize RT_MANGLER(RTHeapSimpleSize)
+# define RTIsoFsClose RT_MANGLER(RTIsoFsClose)
+# define RTIsoFsExtractFile RT_MANGLER(RTIsoFsExtractFile)
+# define RTIsoFsGetFileInfo RT_MANGLER(RTIsoFsGetFileInfo)
+# define RTIsoFsOpen RT_MANGLER(RTIsoFsOpen)
+# define RTLatin1CalcUtf16Len RT_MANGLER(RTLatin1CalcUtf16Len)
+# define RTLatin1CalcUtf16LenEx RT_MANGLER(RTLatin1CalcUtf16LenEx)
+# define RTLatin1CalcUtf8Len RT_MANGLER(RTLatin1CalcUtf8Len)
+# define RTLatin1CalcUtf8LenEx RT_MANGLER(RTLatin1CalcUtf8LenEx)
+# define RTLatin1ToUtf16ExTag RT_MANGLER(RTLatin1ToUtf16ExTag)
+# define RTLatin1ToUtf16Tag RT_MANGLER(RTLatin1ToUtf16Tag)
+# define RTLatin1ToUtf8ExTag RT_MANGLER(RTLatin1ToUtf8ExTag)
+# define RTLatin1ToUtf8Tag RT_MANGLER(RTLatin1ToUtf8Tag)
+# define RTLdrClose RT_MANGLER(RTLdrClose)
+# define RTLdrEnumDbgInfo RT_MANGLER(RTLdrEnumDbgInfo)
+# define RTLdrEnumSegments RT_MANGLER(RTLdrEnumSegments)
+# define RTLdrEnumSymbols RT_MANGLER(RTLdrEnumSymbols)
+# define RTLdrGetBits RT_MANGLER(RTLdrGetBits)
+# define RTLdrGetSuff RT_MANGLER(RTLdrGetSuff)
+# define RTLdrGetSymbol RT_MANGLER(RTLdrGetSymbol)
+# define RTLdrGetSymbolEx RT_MANGLER(RTLdrGetSymbolEx)
+# define RTLdrIsLoadable RT_MANGLER(RTLdrIsLoadable)
+# define RTLdrLinkAddressToRva RT_MANGLER(RTLdrLinkAddressToRva)
+# define RTLdrLinkAddressToSegOffset RT_MANGLER(RTLdrLinkAddressToSegOffset)
+# define RTLdrLoad RT_MANGLER(RTLdrLoad)
+# define RTLdrLoadAppPriv RT_MANGLER(RTLdrLoadAppPriv)
+# define RTLdrLoadEx RT_MANGLER(RTLdrLoadEx)
+# define RTLdrOpen RT_MANGLER(RTLdrOpen)
+# define RTLdrOpenkLdr RT_MANGLER(RTLdrOpenkLdr)
+# define RTLdrRelocate RT_MANGLER(RTLdrRelocate)
+# define RTLdrRvaToSegOffset RT_MANGLER(RTLdrRvaToSegOffset)
+# define RTLdrSegOffsetToRva RT_MANGLER(RTLdrSegOffsetToRva)
+# define RTLdrSize RT_MANGLER(RTLdrSize)
+# define RTLinuxFindDevicePath RT_MANGLER(RTLinuxFindDevicePath)
+# define RTLinuxFindDevicePathV RT_MANGLER(RTLinuxFindDevicePathV)
+# define RTLinuxSysFsClose RT_MANGLER(RTLinuxSysFsClose)
+# define RTLinuxSysFsExists RT_MANGLER(RTLinuxSysFsExists)
+# define RTLinuxSysFsExistsV RT_MANGLER(RTLinuxSysFsExistsV)
+# define RTLinuxSysFsGetLinkDest RT_MANGLER(RTLinuxSysFsGetLinkDest)
+# define RTLinuxSysFsGetLinkDestV RT_MANGLER(RTLinuxSysFsGetLinkDestV)
+# define RTLinuxSysFsOpen RT_MANGLER(RTLinuxSysFsOpen)
+# define RTLinuxSysFsOpenV RT_MANGLER(RTLinuxSysFsOpenV)
+# define RTLinuxSysFsReadDevNumFile RT_MANGLER(RTLinuxSysFsReadDevNumFile)
+# define RTLinuxSysFsReadDevNumFileV RT_MANGLER(RTLinuxSysFsReadDevNumFileV)
+# define RTLinuxSysFsReadFile RT_MANGLER(RTLinuxSysFsReadFile)
+# define RTLinuxSysFsReadIntFile RT_MANGLER(RTLinuxSysFsReadIntFile)
+# define RTLinuxSysFsReadIntFileV RT_MANGLER(RTLinuxSysFsReadIntFileV)
+# define RTLinuxSysFsReadStr RT_MANGLER(RTLinuxSysFsReadStr)
+# define RTLinuxSysFsReadStrFile RT_MANGLER(RTLinuxSysFsReadStrFile)
+# define RTLinuxSysFsReadStrFileV RT_MANGLER(RTLinuxSysFsReadStrFileV)
+# define RTLockValidatorClassAddPriorClass RT_MANGLER(RTLockValidatorClassAddPriorClass)
+# define RTLockValidatorClassCreate RT_MANGLER(RTLockValidatorClassCreate)
+# define RTLockValidatorClassCreateEx RT_MANGLER(RTLockValidatorClassCreateEx)
+# define RTLockValidatorClassCreateExV RT_MANGLER(RTLockValidatorClassCreateExV)
+# define RTLockValidatorClassCreateUnique RT_MANGLER(RTLockValidatorClassCreateUnique)
+# define RTLockValidatorClassEnforceStrictReleaseOrder RT_MANGLER(RTLockValidatorClassEnforceStrictReleaseOrder)
+# define RTLockValidatorClassFindForSrcPos RT_MANGLER(RTLockValidatorClassFindForSrcPos)
+# define RTLockValidatorClassForSrcPos RT_MANGLER(RTLockValidatorClassForSrcPos)
+# define RTLockValidatorClassRelease RT_MANGLER(RTLockValidatorClassRelease)
+# define RTLockValidatorClassRetain RT_MANGLER(RTLockValidatorClassRetain)
+# define RTLockValidatorHoldsLocksInClass RT_MANGLER(RTLockValidatorHoldsLocksInClass)
+# define RTLockValidatorHoldsLocksInSubClass RT_MANGLER(RTLockValidatorHoldsLocksInSubClass)
+# define RTLockValidatorIsBlockedThreadInValidator RT_MANGLER(RTLockValidatorIsBlockedThreadInValidator)
+# define RTLockValidatorIsEnabled RT_MANGLER(RTLockValidatorIsEnabled)
+# define RTLockValidatorIsQuiet RT_MANGLER(RTLockValidatorIsQuiet)
+# define RTLockValidatorMayPanic RT_MANGLER(RTLockValidatorMayPanic)
+# define RTLockValidatorQueryBlocking RT_MANGLER(RTLockValidatorQueryBlocking)
+# define RTLockValidatorReadLockDec RT_MANGLER(RTLockValidatorReadLockDec)
+# define RTLockValidatorReadLockGetCount RT_MANGLER(RTLockValidatorReadLockGetCount)
+# define RTLockValidatorReadLockInc RT_MANGLER(RTLockValidatorReadLockInc)
+# define RTLockValidatorRecExclCheckBlocking RT_MANGLER(RTLockValidatorRecExclCheckBlocking)
+# define RTLockValidatorRecExclCheckOrder RT_MANGLER(RTLockValidatorRecExclCheckOrder)
+# define RTLockValidatorRecExclCheckOrderAndBlocking RT_MANGLER(RTLockValidatorRecExclCheckOrderAndBlocking)
+# define RTLockValidatorRecExclCreate RT_MANGLER(RTLockValidatorRecExclCreate)
+# define RTLockValidatorRecExclCreateV RT_MANGLER(RTLockValidatorRecExclCreateV)
+# define RTLockValidatorRecExclDelete RT_MANGLER(RTLockValidatorRecExclDelete)
+# define RTLockValidatorRecExclDestroy RT_MANGLER(RTLockValidatorRecExclDestroy)
+# define RTLockValidatorRecExclInit RT_MANGLER(RTLockValidatorRecExclInit)
+# define RTLockValidatorRecExclInitV RT_MANGLER(RTLockValidatorRecExclInitV)
+# define RTLockValidatorRecExclRecursion RT_MANGLER(RTLockValidatorRecExclRecursion)
+# define RTLockValidatorRecExclRecursionMixed RT_MANGLER(RTLockValidatorRecExclRecursionMixed)
+# define RTLockValidatorRecExclReleaseOwner RT_MANGLER(RTLockValidatorRecExclReleaseOwner)
+# define RTLockValidatorRecExclReleaseOwnerUnchecked RT_MANGLER(RTLockValidatorRecExclReleaseOwnerUnchecked)
+# define RTLockValidatorRecExclSetOwner RT_MANGLER(RTLockValidatorRecExclSetOwner)
+# define RTLockValidatorRecExclSetSubClass RT_MANGLER(RTLockValidatorRecExclSetSubClass)
+# define RTLockValidatorRecExclUnwind RT_MANGLER(RTLockValidatorRecExclUnwind)
+# define RTLockValidatorRecExclUnwindMixed RT_MANGLER(RTLockValidatorRecExclUnwindMixed)
+# define RTLockValidatorRecMakeSiblings RT_MANGLER(RTLockValidatorRecMakeSiblings)
+# define RTLockValidatorRecSharedAddOwner RT_MANGLER(RTLockValidatorRecSharedAddOwner)
+# define RTLockValidatorRecSharedCheckAndRelease RT_MANGLER(RTLockValidatorRecSharedCheckAndRelease)
+# define RTLockValidatorRecSharedCheckBlocking RT_MANGLER(RTLockValidatorRecSharedCheckBlocking)
+# define RTLockValidatorRecSharedCheckOrder RT_MANGLER(RTLockValidatorRecSharedCheckOrder)
+# define RTLockValidatorRecSharedCheckOrderAndBlocking RT_MANGLER(RTLockValidatorRecSharedCheckOrderAndBlocking)
+# define RTLockValidatorRecSharedCheckSignaller RT_MANGLER(RTLockValidatorRecSharedCheckSignaller)
+# define RTLockValidatorRecSharedDelete RT_MANGLER(RTLockValidatorRecSharedDelete)
+# define RTLockValidatorRecSharedInit RT_MANGLER(RTLockValidatorRecSharedInit)
+# define RTLockValidatorRecSharedInitV RT_MANGLER(RTLockValidatorRecSharedInitV)
+# define RTLockValidatorRecSharedIsOwner RT_MANGLER(RTLockValidatorRecSharedIsOwner)
+# define RTLockValidatorRecSharedRemoveOwner RT_MANGLER(RTLockValidatorRecSharedRemoveOwner)
+# define RTLockValidatorRecSharedResetOwner RT_MANGLER(RTLockValidatorRecSharedResetOwner)
+# define RTLockValidatorRecSharedSetSubClass RT_MANGLER(RTLockValidatorRecSharedSetSubClass)
+# define RTLockValidatorSetEnabled RT_MANGLER(RTLockValidatorSetEnabled)
+# define RTLockValidatorSetMayPanic RT_MANGLER(RTLockValidatorSetMayPanic)
+# define RTLockValidatorSetQuiet RT_MANGLER(RTLockValidatorSetQuiet)
+# define RTLockValidatorWriteLockDec RT_MANGLER(RTLockValidatorWriteLockDec)
+# define RTLockValidatorWriteLockGetCount RT_MANGLER(RTLockValidatorWriteLockGetCount)
+# define RTLockValidatorWriteLockInc RT_MANGLER(RTLockValidatorWriteLockInc)
+# define RTLogBackdoorPrintf RT_MANGLER(RTLogBackdoorPrintf) /* r0drv-guest */
+# define RTLogBackdoorPrintfV RT_MANGLER(RTLogBackdoorPrintfV) /* r0drv-guest */
+# define RTLogCalcSizeForR0 RT_MANGLER(RTLogCalcSizeForR0)
+# define RTLogCloneRC RT_MANGLER(RTLogCloneRC)
+# define RTLogComPrintf RT_MANGLER(RTLogComPrintf)
+# define RTLogComPrintfV RT_MANGLER(RTLogComPrintfV)
+# define RTLogCopyGroupsAndFlagsForR0 RT_MANGLER(RTLogCopyGroupsAndFlagsForR0)
+# define RTLogCreate RT_MANGLER(RTLogCreate)
+# define RTLogCreateEx RT_MANGLER(RTLogCreateEx)
+# define RTLogCreateExV RT_MANGLER(RTLogCreateExV)
+# define RTLogCreateForR0 RT_MANGLER(RTLogCreateForR0)
+# define RTLogDefaultInit RT_MANGLER(RTLogDefaultInit)
+# define RTLogDefaultInstance RT_MANGLER(RTLogDefaultInstance)
+# define RTLogDestinations RT_MANGLER(RTLogDestinations)
+# define RTLogDestroy RT_MANGLER(RTLogDestroy)
+# define RTLogFlags RT_MANGLER(RTLogFlags)
+# define RTLogFlush RT_MANGLER(RTLogFlush)
+# define RTLogFlushRC RT_MANGLER(RTLogFlushRC)
+# define RTLogFlushR0 RT_MANGLER(RTLogFlushR0)
+# define RTLogFlushToLogger RT_MANGLER(RTLogFlushToLogger)
+# define RTLogFormatV RT_MANGLER(RTLogFormatV)
+# define RTLogGetDefaultInstance RT_MANGLER(RTLogGetDefaultInstance)
+# define RTLogGetDestinations RT_MANGLER(RTLogGetDestinations)
+# define RTLogGetFlags RT_MANGLER(RTLogGetFlags)
+# define RTLogGetGroupSettings RT_MANGLER(RTLogGetGroupSettings)
+# define RTLogGroupSettings RT_MANGLER(RTLogGroupSettings)
+# define RTLogLogger RT_MANGLER(RTLogLogger)
+# define RTLogLoggerEx RT_MANGLER(RTLogLoggerEx)
+# define RTLogLoggerExV RT_MANGLER(RTLogLoggerExV)
+# define RTLogLoggerV RT_MANGLER(RTLogLoggerV)
+# define RTLogPrintf RT_MANGLER(RTLogPrintf)
+# define RTLogPrintfV RT_MANGLER(RTLogPrintfV)
+# define RTLogRelDefaultInstance RT_MANGLER(RTLogRelDefaultInstance)
+# define RTLogRelLogger RT_MANGLER(RTLogRelLogger)
+# define RTLogRelLoggerV RT_MANGLER(RTLogRelLoggerV)
+# define RTLogRelPrintf RT_MANGLER(RTLogRelPrintf)
+# define RTLogRelPrintfV RT_MANGLER(RTLogRelPrintfV)
+# define RTLogRelSetBuffering RT_MANGLER(RTLogRelSetBuffering)
+# define RTLogRelSetDefaultInstance RT_MANGLER(RTLogRelSetDefaultInstance)
+# define RTLogSetBuffering RT_MANGLER(RTLogSetBuffering)
+# define RTLogSetCustomPrefixCallback RT_MANGLER(RTLogSetCustomPrefixCallback)
+# define RTLogSetCustomPrefixCallbackForR0 RT_MANGLER(RTLogSetCustomPrefixCallbackForR0)
+# define RTLogSetDefaultInstance RT_MANGLER(RTLogSetDefaultInstance)
+# define RTLogSetDefaultInstanceThread RT_MANGLER(RTLogSetDefaultInstanceThread) /* r0drv */
+# define RTLogSetGroupLimit RT_MANGLER(RTLogSetGroupLimit)
+# define RTLogWriteCom RT_MANGLER(RTLogWriteCom)
+# define RTLogWriteCom RT_MANGLER(RTLogWriteCom)
+# define RTLogWriteDebugger RT_MANGLER(RTLogWriteDebugger)
+# define RTLogWriteStdErr RT_MANGLER(RTLogWriteStdErr)
+# define RTLogWriteStdOut RT_MANGLER(RTLogWriteStdOut)
+# define RTLogWriteUser RT_MANGLER(RTLogWriteUser)
+# define RTManifestCreate RT_MANGLER(RTManifestCreate)
+# define RTManifestDup RT_MANGLER(RTManifestDup)
+# define RTManifestEntryAdd RT_MANGLER(RTManifestEntryAdd)
+# define RTManifestEntryAddIoStream RT_MANGLER(RTManifestEntryAddIoStream)
+# define RTManifestEntryAddPassthruIoStream RT_MANGLER(RTManifestEntryAddPassthruIoStream)
+# define RTManifestEntryExists RT_MANGLER(RTManifestEntryExists)
+# define RTManifestEntryRemove RT_MANGLER(RTManifestEntryRemove)
+# define RTManifestEntryQueryAttr RT_MANGLER(RTManifestEntryQueryAttr)
+# define RTManifestEntrySetAttr RT_MANGLER(RTManifestEntrySetAttr)
+# define RTManifestEntryUnsetAttr RT_MANGLER(RTManifestEntryUnsetAttr)
+# define RTManifestEquals RT_MANGLER(RTManifestEquals)
+# define RTManifestEqualsEx RT_MANGLER(RTManifestEqualsEx)
+# define RTManifestPtIosAddEntryNow RT_MANGLER(RTManifestPtIosAddEntryNow)
+# define RTManifestQueryAttr RT_MANGLER(RTManifestQueryAttr)
+# define RTManifestReadStandard RT_MANGLER(RTManifestReadStandard)
+# define RTManifestReadStandardEx RT_MANGLER(RTManifestReadStandardEx)
+# define RTManifestReadStandardFromFile RT_MANGLER(RTManifestReadStandardFromFile)
+# define RTManifestRelease RT_MANGLER(RTManifestRelease)
+# define RTManifestRetain RT_MANGLER(RTManifestRetain)
+# define RTManifestSetAttr RT_MANGLER(RTManifestSetAttr)
+# define RTManifestUnsetAttr RT_MANGLER(RTManifestUnsetAttr)
+# define RTManifestVerify RT_MANGLER(RTManifestVerify)
+# define RTManifestVerifyFiles RT_MANGLER(RTManifestVerifyFiles)
+# define RTManifestVerifyFilesBuf RT_MANGLER(RTManifestVerifyFilesBuf)
+# define RTManifestWriteFiles RT_MANGLER(RTManifestWriteFiles)
+# define RTManifestWriteFilesBuf RT_MANGLER(RTManifestWriteFilesBuf)
+# define RTManifestWriteStandard RT_MANGLER(RTManifestWriteStandard)
+# define RTManifestWriteStandardToFile RT_MANGLER(RTManifestWriteStandardToFile)
+# define RTMd5 RT_MANGLER(RTMd5)
+# define RTMd5Final RT_MANGLER(RTMd5Final)
+# define RTMd5FromString RT_MANGLER(RTMd5FromString)
+# define RTMd5Init RT_MANGLER(RTMd5Init)
+# define RTMd5ToString RT_MANGLER(RTMd5ToString)
+# define RTMd5Update RT_MANGLER(RTMd5Update)
+# define RTMemAllocExTag RT_MANGLER(RTMemAllocExTag) /* r0drv */
+# define RTMemAllocTag RT_MANGLER(RTMemAllocTag)
+# define RTMemAllocVarTag RT_MANGLER(RTMemAllocVarTag)
+# define RTMemAllocZTag RT_MANGLER(RTMemAllocZTag)
+# define RTMemAllocZVarTag RT_MANGLER(RTMemAllocZVarTag)
+# define RTMemCacheAlloc RT_MANGLER(RTMemCacheAlloc)
+# define RTMemCacheAllocEx RT_MANGLER(RTMemCacheAllocEx)
+# define RTMemCacheCreate RT_MANGLER(RTMemCacheCreate)
+# define RTMemCacheDestroy RT_MANGLER(RTMemCacheDestroy)
+# define RTMemCacheFree RT_MANGLER(RTMemCacheFree)
+# define RTMemContAlloc RT_MANGLER(RTMemContAlloc) /* r0drv */
+# define RTMemContFree RT_MANGLER(RTMemContFree) /* r0drv */
+# define RTMemDump RT_MANGLER(RTMemDump)
+# define RTMemDupExTag RT_MANGLER(RTMemDupExTag)
+# define RTMemDupTag RT_MANGLER(RTMemDupTag)
+# define RTMemEfAlloc RT_MANGLER(RTMemEfAlloc)
+# define RTMemEfAllocNP RT_MANGLER(RTMemEfAllocNP)
+# define RTMemEfAllocVar RT_MANGLER(RTMemEfAllocVar)
+# define RTMemEfAllocVarNP RT_MANGLER(RTMemEfAllocVarNP)
+# define RTMemEfAllocZ RT_MANGLER(RTMemEfAllocZ)
+# define RTMemEfAllocZNP RT_MANGLER(RTMemEfAllocZNP)
+# define RTMemEfAllocZVar RT_MANGLER(RTMemEfAllocZVar)
+# define RTMemEfAllocZVarNP RT_MANGLER(RTMemEfAllocZVarNP)
+# define RTMemEfDup RT_MANGLER(RTMemEfDup)
+# define RTMemEfDupEx RT_MANGLER(RTMemEfDupEx)
+# define RTMemEfDupExNP RT_MANGLER(RTMemEfDupExNP)
+# define RTMemEfDupNP RT_MANGLER(RTMemEfDupNP)
+# define RTMemEfFree RT_MANGLER(RTMemEfFree)
+# define RTMemEfFreeNP RT_MANGLER(RTMemEfFreeNP)
+# define RTMemEfRealloc RT_MANGLER(RTMemEfRealloc)
+# define RTMemEfReallocNP RT_MANGLER(RTMemEfReallocNP)
+# define RTMemEfTmpAlloc RT_MANGLER(RTMemEfTmpAlloc)
+# define RTMemEfTmpAllocNP RT_MANGLER(RTMemEfTmpAllocNP)
+# define RTMemEfTmpAllocZ RT_MANGLER(RTMemEfTmpAllocZ)
+# define RTMemEfTmpAllocZNP RT_MANGLER(RTMemEfTmpAllocZNP)
+# define RTMemEfTmpFree RT_MANGLER(RTMemEfTmpFree)
+# define RTMemEfTmpFreeNP RT_MANGLER(RTMemEfTmpFreeNP)
+# define RTMemExecAllocTag RT_MANGLER(RTMemExecAllocTag)
+# define RTMemExecFree RT_MANGLER(RTMemExecFree)
+# define RTMemFree RT_MANGLER(RTMemFree)
+# define RTMemFreeEx RT_MANGLER(RTMemFreeEx) /* r0drv */
+# define RTMemPageAllocTag RT_MANGLER(RTMemPageAllocTag)
+# define RTMemPageAllocZTag RT_MANGLER(RTMemPageAllocZTag)
+# define RTMemPageFree RT_MANGLER(RTMemPageFree)
+# define RTMemPoolAlloc RT_MANGLER(RTMemPoolAlloc)
+# define RTMemPoolAllocZ RT_MANGLER(RTMemPoolAllocZ)
+# define RTMemPoolCreate RT_MANGLER(RTMemPoolCreate)
+# define RTMemPoolDestroy RT_MANGLER(RTMemPoolDestroy)
+# define RTMemPoolDup RT_MANGLER(RTMemPoolDup)
+# define RTMemPoolDupEx RT_MANGLER(RTMemPoolDupEx)
+# define RTMemPoolFree RT_MANGLER(RTMemPoolFree)
+# define RTMemPoolRealloc RT_MANGLER(RTMemPoolRealloc)
+# define RTMemPoolRefCount RT_MANGLER(RTMemPoolRefCount)
+# define RTMemPoolRelease RT_MANGLER(RTMemPoolRelease)
+# define RTMemPoolRetain RT_MANGLER(RTMemPoolRetain)
+# define RTMemProtect RT_MANGLER(RTMemProtect)
+# define RTMemReallocTag RT_MANGLER(RTMemReallocTag)
+# define RTMemTmpAllocTag RT_MANGLER(RTMemTmpAllocTag)
+# define RTMemTmpAllocZTag RT_MANGLER(RTMemTmpAllocZTag)
+# define RTMemTmpFree RT_MANGLER(RTMemTmpFree)
+# define RTMemTrackerDumpAllToFile RT_MANGLER(RTMemTrackerDumpAllToFile)
+# define RTMemTrackerDumpAllToLog RT_MANGLER(RTMemTrackerDumpAllToLog)
+# define RTMemTrackerDumpAllToLogRel RT_MANGLER(RTMemTrackerDumpAllToLogRel)
+# define RTMemTrackerDumpAllToStdErr RT_MANGLER(RTMemTrackerDumpAllToStdErr)
+# define RTMemTrackerDumpAllToStdOut RT_MANGLER(RTMemTrackerDumpAllToStdOut)
+# define RTMemTrackerDumpStatsToFile RT_MANGLER(RTMemTrackerDumpStatsToFile)
+# define RTMemTrackerDumpStatsToLog RT_MANGLER(RTMemTrackerDumpStatsToLog)
+# define RTMemTrackerDumpStatsToLogRel RT_MANGLER(RTMemTrackerDumpStatsToLogRel)
+# define RTMemTrackerDumpStatsToStdErr RT_MANGLER(RTMemTrackerDumpStatsToStdErr)
+# define RTMemTrackerDumpStatsToStdOut RT_MANGLER(RTMemTrackerDumpStatsToStdOut)
+# define RTMemTrackerHdrAlloc RT_MANGLER(RTMemTrackerHdrAlloc)
+# define RTMemTrackerHdrFree RT_MANGLER(RTMemTrackerHdrFree)
+# define RTMemTrackerHdrReallocDone RT_MANGLER(RTMemTrackerHdrReallocDone)
+# define RTMemTrackerHdrReallocPrep RT_MANGLER(RTMemTrackerHdrReallocPrep)
+# define RTMemWipeThoroughly RT_MANGLER(RTMemWipeThoroughly)
+# define RTMpCpuId RT_MANGLER(RTMpCpuId)
+# define RTMpCpuIdFromSetIndex RT_MANGLER(RTMpCpuIdFromSetIndex)
+# define RTMpCpuIdToSetIndex RT_MANGLER(RTMpCpuIdToSetIndex)
+# define RTMpGetArraySize RT_MANGLER(RTMpGetArraySize)
+# define RTMpGetCount RT_MANGLER(RTMpGetCount)
+# define RTMpGetCurFrequency RT_MANGLER(RTMpGetCurFrequency)
+# define RTMpGetDescription RT_MANGLER(RTMpGetDescription)
+# define RTMpGetMaxCpuId RT_MANGLER(RTMpGetMaxCpuId)
+# define RTMpGetMaxFrequency RT_MANGLER(RTMpGetMaxFrequency)
+# define RTMpGetOnlineCount RT_MANGLER(RTMpGetOnlineCount)
+# define RTMpGetOnlineSet RT_MANGLER(RTMpGetOnlineSet)
+# define RTMpGetPresentCount RT_MANGLER(RTMpGetPresentCount)
+# define RTMpGetPresentSet RT_MANGLER(RTMpGetPresentSet)
+# define RTMpGetSet RT_MANGLER(RTMpGetSet)
+# define RTMpIsCpuOnline RT_MANGLER(RTMpIsCpuOnline)
+# define RTMpIsCpuPossible RT_MANGLER(RTMpIsCpuPossible) /* r0drv */
+# define RTMpIsCpuPresent RT_MANGLER(RTMpIsCpuPresent)
+# define RTMpIsCpuWorkPending RT_MANGLER(RTMpIsCpuWorkPending)
+# define RTMpNotificationDeregister RT_MANGLER(RTMpNotificationDeregister) /* r0drv */
+# define RTMpNotificationRegister RT_MANGLER(RTMpNotificationRegister) /* r0drv */
+# define RTMpOnAll RT_MANGLER(RTMpOnAll) /* r0drv */
+# define RTMpOnOthers RT_MANGLER(RTMpOnOthers) /* r0drv */
+# define RTMpOnSpecific RT_MANGLER(RTMpOnSpecific) /* r0drv */
+# define RTMpPokeCpu RT_MANGLER(RTMpPokeCpu) /* r0drv */
+# define RTMsgError RT_MANGLER(RTMsgError)
+# define RTMsgErrorExit RT_MANGLER(RTMsgErrorExit)
+# define RTMsgErrorExitV RT_MANGLER(RTMsgErrorExitV)
+# define RTMsgErrorRc RT_MANGLER(RTMsgErrorRc)
+# define RTMsgErrorRcV RT_MANGLER(RTMsgErrorRcV)
+# define RTMsgErrorV RT_MANGLER(RTMsgErrorV)
+# define RTMsgInfo RT_MANGLER(RTMsgInfo)
+# define RTMsgInfoV RT_MANGLER(RTMsgInfoV)
+# define RTMsgInitFailure RT_MANGLER(RTMsgInitFailure)
+# define RTMsgSetProgName RT_MANGLER(RTMsgSetProgName)
+# define RTMsgWarning RT_MANGLER(RTMsgWarning)
+# define RTMsgWarningV RT_MANGLER(RTMsgWarningV)
+# define RTNetIPv4AddDataChecksum RT_MANGLER(RTNetIPv4AddDataChecksum)
+# define RTNetIPv4AddTCPChecksum RT_MANGLER(RTNetIPv4AddTCPChecksum)
+# define RTNetIPv4AddUDPChecksum RT_MANGLER(RTNetIPv4AddUDPChecksum)
+# define RTNetIPv4FinalizeChecksum RT_MANGLER(RTNetIPv4FinalizeChecksum)
+# define RTNetIPv4HdrChecksum RT_MANGLER(RTNetIPv4HdrChecksum)
+# define RTNetIPv4IsDHCPValid RT_MANGLER(RTNetIPv4IsDHCPValid)
+# define RTNetIPv4IsHdrValid RT_MANGLER(RTNetIPv4IsHdrValid)
+# define RTNetIPv4IsTCPSizeValid RT_MANGLER(RTNetIPv4IsTCPSizeValid)
+# define RTNetIPv4IsTCPValid RT_MANGLER(RTNetIPv4IsTCPValid)
+# define RTNetIPv4IsUDPSizeValid RT_MANGLER(RTNetIPv4IsUDPSizeValid)
+# define RTNetIPv4IsUDPValid RT_MANGLER(RTNetIPv4IsUDPValid)
+# define RTNetIPv4PseudoChecksum RT_MANGLER(RTNetIPv4PseudoChecksum)
+# define RTNetIPv4PseudoChecksumBits RT_MANGLER(RTNetIPv4PseudoChecksumBits)
+# define RTNetIPv4TCPChecksum RT_MANGLER(RTNetIPv4TCPChecksum)
+# define RTNetIPv4UDPChecksum RT_MANGLER(RTNetIPv4UDPChecksum)
+# define RTNetIPv6PseudoChecksum RT_MANGLER(RTNetIPv6PseudoChecksum)
+# define RTNetIPv6PseudoChecksumBits RT_MANGLER(RTNetIPv6PseudoChecksumBits)
+# define RTNetIPv6PseudoChecksumEx RT_MANGLER(RTNetIPv6PseudoChecksumEx)
+# define RTNetTCPChecksum RT_MANGLER(RTNetTCPChecksum)
+# define RTNetUDPChecksum RT_MANGLER(RTNetUDPChecksum)
+# define RTNetIsIPv4AddrStr RT_MANGLER(RTNetIsIPv4AddrStr)
+# define RTNetIsIPv6AddrStr RT_MANGLER(RTNetIsIPv6AddrStr)
+# define RTOnceSlow RT_MANGLER(RTOnceSlow)
+# define RTOnceReset RT_MANGLER(RTOnceReset)
+# define RTPathAbs RT_MANGLER(RTPathAbs)
+# define RTPathAbsDup RT_MANGLER(RTPathAbsDup)
+# define RTPathAbsEx RT_MANGLER(RTPathAbsEx)
+# define RTPathAbsExDup RT_MANGLER(RTPathAbsExDup)
+# define RTPathAppDocs RT_MANGLER(RTPathAppDocs)
+# define RTPathAppend RT_MANGLER(RTPathAppend)
+# define RTPathAppendEx RT_MANGLER(RTPathAppendEx)
+# define RTPathAppPrivateArch RT_MANGLER(RTPathAppPrivateArch)
+# define RTPathAppPrivateArchTop RT_MANGLER(RTPathAppPrivateArchTop)
+# define RTPathAppPrivateNoArch RT_MANGLER(RTPathAppPrivateNoArch)
+# define RTPathChangeToDosSlashes RT_MANGLER(RTPathChangeToDosSlashes)
+# define RTPathChangeToUnixSlashes RT_MANGLER(RTPathChangeToUnixSlashes)
+# define RTPathCompare RT_MANGLER(RTPathCompare)
+# define RTPathCopyComponents RT_MANGLER(RTPathCopyComponents)
+# define RTPathCountComponents RT_MANGLER(RTPathCountComponents)
+# define RTPathExecDir RT_MANGLER(RTPathExecDir)
+# define RTPathExists RT_MANGLER(RTPathExists)
+# define RTPathExistsEx RT_MANGLER(RTPathExistsEx)
+# define RTPathExt RT_MANGLER(RTPathExt)
+# define RTPathFilename RT_MANGLER(RTPathFilename)
+# define RTPathGetCurrent RT_MANGLER(RTPathGetCurrent)
+# define RTPathGetMode RT_MANGLER(RTPathGetMode)
+# define RTPathHasExt RT_MANGLER(RTPathHasExt)
+# define RTPathHasPath RT_MANGLER(RTPathHasPath)
+# define RTPathJoin RT_MANGLER(RTPathJoin)
+# define RTPathJoinA RT_MANGLER(RTPathJoinA)
+# define RTPathJoinEx RT_MANGLER(RTPathJoinEx)
+# define RTPathParse RT_MANGLER(RTPathParse)
+# define RTPathQueryInfo RT_MANGLER(RTPathQueryInfo)
+# define RTPathQueryInfoEx RT_MANGLER(RTPathQueryInfoEx)
+# define RTPathReal RT_MANGLER(RTPathReal)
+# define RTPathRealDup RT_MANGLER(RTPathRealDup)
+# define RTPathRename RT_MANGLER(RTPathRename)
+# define RTPathSetCurrent RT_MANGLER(RTPathSetCurrent)
+# define RTPathSetMode RT_MANGLER(RTPathSetMode) /* not-win */
+# define RTPathSetOwner RT_MANGLER(RTPathSetOwner) /* not-win */
+# define RTPathSetOwnerEx RT_MANGLER(RTPathSetOwnerEx) /* not-win */
+# define RTPathSetTimes RT_MANGLER(RTPathSetTimes)
+# define RTPathSetTimesEx RT_MANGLER(RTPathSetTimesEx)
+# define RTPathSharedLibs RT_MANGLER(RTPathSharedLibs)
+# define RTPathStartsWith RT_MANGLER(RTPathStartsWith)
+# define RTPathStartsWithRoot RT_MANGLER(RTPathStartsWithRoot)
+# define RTPathStripExt RT_MANGLER(RTPathStripExt)
+# define RTPathStripFilename RT_MANGLER(RTPathStripFilename)
+# define RTPathStripTrailingSlash RT_MANGLER(RTPathStripTrailingSlash)
+# define RTPathTemp RT_MANGLER(RTPathTemp)
+# define RTPathTraverseList RT_MANGLER(RTPathTraverseList)
+# define RTPathUnlink RT_MANGLER(RTPathUnlink)
+# define RTPathUserDocuments RT_MANGLER(RTPathUserDocuments)
+# define RTPathUserHome RT_MANGLER(RTPathUserHome)
+# define RTPipeClose RT_MANGLER(RTPipeClose)
+# define RTPipeCreate RT_MANGLER(RTPipeCreate)
+# define RTPipeFlush RT_MANGLER(RTPipeFlush)
+# define RTPipeFromNative RT_MANGLER(RTPipeFromNative)
+# define RTPipeQueryReadable RT_MANGLER(RTPipeQueryReadable)
+# define RTPipeRead RT_MANGLER(RTPipeRead)
+# define RTPipeReadBlocking RT_MANGLER(RTPipeReadBlocking)
+# define RTPipeSelectOne RT_MANGLER(RTPipeSelectOne)
+# define RTPipeToNative RT_MANGLER(RTPipeToNative)
+# define RTPipeWrite RT_MANGLER(RTPipeWrite)
+# define RTPipeWriteBlocking RT_MANGLER(RTPipeWriteBlocking)
+# define RTPoll RT_MANGLER(RTPoll)
+# define RTPollNoResume RT_MANGLER(RTPollNoResume)
+# define RTPollSetAdd RT_MANGLER(RTPollSetAdd)
+# define RTPollSetCreate RT_MANGLER(RTPollSetCreate)
+# define RTPollSetDestroy RT_MANGLER(RTPollSetDestroy)
+# define RTPollSetEventsChange RT_MANGLER(RTPollSetEventsChange)
+# define RTPollSetGetCount RT_MANGLER(RTPollSetGetCount)
+# define RTPollSetQueryHandle RT_MANGLER(RTPollSetQueryHandle)
+# define RTPollSetRemove RT_MANGLER(RTPollSetRemove)
+# define RTPowerNotificationDeregister RT_MANGLER(RTPowerNotificationDeregister) /* r0drv */
+# define RTPowerNotificationRegister RT_MANGLER(RTPowerNotificationRegister) /* r0drv */
+# define RTPowerSignalEvent RT_MANGLER(RTPowerSignalEvent) /* r0drv */
+# define RTPrintf RT_MANGLER(RTPrintf)
+# define RTPrintfV RT_MANGLER(RTPrintfV)
+# define RTProcCreate RT_MANGLER(RTProcCreate)
+# define RTProcCreateEx RT_MANGLER(RTProcCreateEx)
+# define RTProcDaemonize RT_MANGLER(RTProcDaemonize)
+# define RTProcDaemonizeUsingFork RT_MANGLER(RTProcDaemonizeUsingFork)
+# define RTProcGetAffinityMask RT_MANGLER(RTProcGetAffinityMask)
+# define RTProcGetExecutablePath RT_MANGLER(RTProcGetExecutablePath)
+# define RTProcGetPriority RT_MANGLER(RTProcGetPriority)
+# define RTProcIsRunningByName RT_MANGLER(RTProcIsRunningByName)
+# define RTProcQueryUsername RT_MANGLER(RTProcQueryUsername)
+# define RTProcQueryUsernameA RT_MANGLER(RTProcQueryUsernameA)
+# define RTProcSelf RT_MANGLER(RTProcSelf)
+# define RTProcSetPriority RT_MANGLER(RTProcSetPriority)
+# define RTProcShortName RT_MANGLER(RTProcShortName)
+# define RTProcTerminate RT_MANGLER(RTProcTerminate)
+# define RTProcWait RT_MANGLER(RTProcWait)
+# define RTProcWaitNoResume RT_MANGLER(RTProcWaitNoResume)
+# define RTR0AssertPanicSystem RT_MANGLER(RTR0AssertPanicSystem) /* r0drv */
+# define RTR0DbgKrnlInfoOpen RT_MANGLER(RTR0DbgKrnlInfoOpen) /* r0drv */
+# define RTR0DbgKrnlInfoQueryMember RT_MANGLER(RTR0DbgKrnlInfoQueryMember) /* r0drv */
+# define RTR0DbgKrnlInfoQuerySymbol RT_MANGLER(RTR0DbgKrnlInfoQuerySymbol) /* r0drv */
+# define RTR0DbgKrnlInfoRelease RT_MANGLER(RTR0DbgKrnlInfoRelease) /* r0drv */
+# define RTR0DbgKrnlInfoRetain RT_MANGLER(RTR0DbgKrnlInfoRetain) /* r0drv */
+# define RTR0Init RT_MANGLER(RTR0Init) /* r0drv */
+# define RTR0MemAreKrnlAndUsrDifferent RT_MANGLER(RTR0MemAreKrnlAndUsrDifferent) /* r0drv */
+# define RTR0MemExecDonate RT_MANGLER(RTR0MemExecDonate) /* r0drv */
+# define RTR0MemKernelIsValidAddr RT_MANGLER(RTR0MemKernelIsValidAddr) /* r0drv */
+# define RTR0MemObjAddress RT_MANGLER(RTR0MemObjAddress) /* r0drv */
+# define RTR0MemObjAddressR3 RT_MANGLER(RTR0MemObjAddressR3) /* r0drv */
+# define RTR0MemKernelCopyFrom RT_MANGLER(RTR0MemKernelCopyFrom) /* r0drv */
+# define RTR0MemKernelCopyTo RT_MANGLER(RTR0MemKernelCopyTo) /* r0drv */
+# define RTR0MemObjAllocContTag RT_MANGLER(RTR0MemObjAllocContTag) /* r0drv */
+# define RTR0MemObjAllocLowTag RT_MANGLER(RTR0MemObjAllocLowTag) /* r0drv */
+# define RTR0MemObjAllocPageTag RT_MANGLER(RTR0MemObjAllocPageTag) /* r0drv */
+# define RTR0MemObjAllocPhysExTag RT_MANGLER(RTR0MemObjAllocPhysExTag) /* r0drv */
+# define RTR0MemObjAllocPhysNCTag RT_MANGLER(RTR0MemObjAllocPhysNCTag) /* r0drv */
+# define RTR0MemObjAllocPhysTag RT_MANGLER(RTR0MemObjAllocPhysTag) /* r0drv */
+# define RTR0MemObjEnterPhysTag RT_MANGLER(RTR0MemObjEnterPhysTag) /* r0drv */
+# define RTR0MemObjFree RT_MANGLER(RTR0MemObjFree) /* r0drv */
+# define RTR0MemObjGetPagePhysAddr RT_MANGLER(RTR0MemObjGetPagePhysAddr) /* r0drv */
+# define RTR0MemObjIsMapping RT_MANGLER(RTR0MemObjIsMapping) /* r0drv */
+# define RTR0MemObjLockKernelTag RT_MANGLER(RTR0MemObjLockKernelTag) /* r0drv */
+# define RTR0MemObjLockUserTag RT_MANGLER(RTR0MemObjLockUserTag) /* r0drv */
+# define RTR0MemObjMapKernelExTag RT_MANGLER(RTR0MemObjMapKernelExTag) /* r0drv */
+# define RTR0MemObjMapKernelTag RT_MANGLER(RTR0MemObjMapKernelTag) /* r0drv */
+# define RTR0MemObjMapUserTag RT_MANGLER(RTR0MemObjMapUserTag) /* r0drv */
+# define RTR0MemObjProtect RT_MANGLER(RTR0MemObjProtect) /* r0drv */
+# define RTR0MemObjReserveKernelTag RT_MANGLER(RTR0MemObjReserveKernelTag) /* r0drv */
+# define RTR0MemObjReserveUserTag RT_MANGLER(RTR0MemObjReserveUserTag) /* r0drv */
+# define RTR0MemObjSize RT_MANGLER(RTR0MemObjSize) /* r0drv */
+# define RTR0MemUserCopyFrom RT_MANGLER(RTR0MemUserCopyFrom) /* r0drv */
+# define RTR0MemUserCopyTo RT_MANGLER(RTR0MemUserCopyTo) /* r0drv */
+# define RTR0MemUserIsValidAddr RT_MANGLER(RTR0MemUserIsValidAddr) /* r0drv */
+# define RTR0ProcHandleSelf RT_MANGLER(RTR0ProcHandleSelf) /* r0drv */
+# define RTR0Term RT_MANGLER(RTR0Term) /* r0drv */
+# define RTR0TermForced RT_MANGLER(RTR0TermForced) /* r0drv */
+# define RTR3InitDll RT_MANGLER(RTR3InitDll)
+# define RTR3InitExe RT_MANGLER(RTR3InitExe)
+# define RTR3InitExeNoArguments RT_MANGLER(RTR3InitExeNoArguments)
+# define RTR3InitEx RT_MANGLER(RTR3InitEx)
+# define rtR3MemAlloc RT_MANGLER(rtR3MemAlloc)
+# define rtR3MemFree RT_MANGLER(rtR3MemFree)
+# define rtR3MemRealloc RT_MANGLER(rtR3MemRealloc)
+# define RTRCInit RT_MANGLER(RTRCInit)
+# define RTRCTerm RT_MANGLER(RTRCTerm)
+# define RTRandAdvBytes RT_MANGLER(RTRandAdvBytes)
+# define RTRandAdvCreateParkMiller RT_MANGLER(RTRandAdvCreateParkMiller)
+# define RTRandAdvCreateSystemFaster RT_MANGLER(RTRandAdvCreateSystemFaster)
+# define RTRandAdvCreateSystemTruer RT_MANGLER(RTRandAdvCreateSystemTruer)
+# define RTRandAdvDestroy RT_MANGLER(RTRandAdvDestroy)
+# define RTRandAdvRestoreState RT_MANGLER(RTRandAdvRestoreState)
+# define RTRandAdvS32 RT_MANGLER(RTRandAdvS32)
+# define RTRandAdvS32Ex RT_MANGLER(RTRandAdvS32Ex)
+# define RTRandAdvS64 RT_MANGLER(RTRandAdvS64)
+# define RTRandAdvS64Ex RT_MANGLER(RTRandAdvS64Ex)
+# define RTRandAdvSaveState RT_MANGLER(RTRandAdvSaveState)
+# define RTRandAdvSeed RT_MANGLER(RTRandAdvSeed)
+# define RTRandAdvU32 RT_MANGLER(RTRandAdvU32)
+# define RTRandAdvU32Ex RT_MANGLER(RTRandAdvU32Ex)
+# define RTRandAdvU64 RT_MANGLER(RTRandAdvU64)
+# define RTRandAdvU64Ex RT_MANGLER(RTRandAdvU64Ex)
+# define RTRandBytes RT_MANGLER(RTRandBytes)
+# define RTRandS32 RT_MANGLER(RTRandS32)
+# define RTRandS32Ex RT_MANGLER(RTRandS32Ex)
+# define RTRandS64 RT_MANGLER(RTRandS64)
+# define RTRandS64Ex RT_MANGLER(RTRandS64Ex)
+# define RTRandU32 RT_MANGLER(RTRandU32)
+# define RTRandU32Ex RT_MANGLER(RTRandU32Ex)
+# define RTRandU64 RT_MANGLER(RTRandU64)
+# define RTRandU64Ex RT_MANGLER(RTRandU64Ex)
+# define RTReqPoolAlloc RT_MANGLER(RTReqPoolAlloc)
+# define RTReqPoolCallEx RT_MANGLER(RTReqPoolCallEx)
+# define RTReqPoolCallExV RT_MANGLER(RTReqPoolCallExV)
+# define RTReqPoolCallWait RT_MANGLER(RTReqPoolCallWait)
+# define RTReqPoolCallNoWait RT_MANGLER(RTReqPoolCallNoWait)
+# define RTReqPoolCallVoidWait RT_MANGLER(RTReqPoolCallVoidWait)
+# define RTReqPoolCallVoidNoWait RT_MANGLER(RTReqPoolCallVoidNoWait)
+# define RTReqPoolCreate RT_MANGLER(RTReqPoolCreate)
+# define RTReqPoolGetCfgVar RT_MANGLER(RTReqPoolGetCfgVar)
+# define RTReqPoolGetStat RT_MANGLER(RTReqPoolGetStat)
+# define RTReqPoolRetain RT_MANGLER(RTReqPoolRetain)
+# define RTReqPoolRelease RT_MANGLER(RTReqPoolRelease)
+# define RTReqPoolSetCfgVar RT_MANGLER(RTReqPoolSetCfgVar)
+# define RTReqQueueAlloc RT_MANGLER(RTReqQueueAlloc)
+# define RTReqQueueCall RT_MANGLER(RTReqQueueCall)
+# define RTReqQueueCallEx RT_MANGLER(RTReqQueueCallEx)
+# define RTReqQueueCallV RT_MANGLER(RTReqQueueCallV)
+# define RTReqQueueCallVoid RT_MANGLER(RTReqQueueCallVoid)
+# define RTReqQueueCreate RT_MANGLER(RTReqQueueCreate)
+# define RTReqQueueDestroy RT_MANGLER(RTReqQueueDestroy)
+# define RTReqQueueIsBusy RT_MANGLER(RTReqQueueIsBusy)
+# define RTReqQueueProcess RT_MANGLER(RTReqQueueProcess)
+# define RTReqSubmit RT_MANGLER(RTReqSubmit)
+# define RTReqRelease RT_MANGLER(RTReqRelease)
+# define RTReqRetain RT_MANGLER(RTReqRetain)
+# define RTReqWait RT_MANGLER(RTReqWait)
+# define RTReqGetStatus RT_MANGLER(RTReqGetStatus)
+# define RTS3BucketsDestroy RT_MANGLER(RTS3BucketsDestroy)
+# define RTS3Create RT_MANGLER(RTS3Create)
+# define RTS3CreateBucket RT_MANGLER(RTS3CreateBucket)
+# define RTS3DeleteBucket RT_MANGLER(RTS3DeleteBucket)
+# define RTS3DeleteKey RT_MANGLER(RTS3DeleteKey)
+# define RTS3Destroy RT_MANGLER(RTS3Destroy)
+# define RTS3GetBucketKeys RT_MANGLER(RTS3GetBucketKeys)
+# define RTS3GetBuckets RT_MANGLER(RTS3GetBuckets)
+# define RTS3GetKey RT_MANGLER(RTS3GetKey)
+# define RTS3KeysDestroy RT_MANGLER(RTS3KeysDestroy)
+# define RTS3PutKey RT_MANGLER(RTS3PutKey)
+# define RTS3SetProgressCallback RT_MANGLER(RTS3SetProgressCallback)
+# define RTSemEventAddSignaller RT_MANGLER(RTSemEventAddSignaller)
+# define RTSemEventCreate RT_MANGLER(RTSemEventCreate)
+# define RTSemEventCreateEx RT_MANGLER(RTSemEventCreateEx)
+# define RTSemEventDestroy RT_MANGLER(RTSemEventDestroy)
+# define RTSemEventGetResolution RT_MANGLER(RTSemEventGetResolution) /* r0drv */
+# define RTSemEventMultiAddSignaller RT_MANGLER(RTSemEventMultiAddSignaller)
+# define RTSemEventMultiCreate RT_MANGLER(RTSemEventMultiCreate)
+# define RTSemEventMultiCreateEx RT_MANGLER(RTSemEventMultiCreateEx)
+# define RTSemEventMultiDestroy RT_MANGLER(RTSemEventMultiDestroy)
+# define RTSemEventMultiGetResolution RT_MANGLER(RTSemEventMultiGetResolution) /* r0drv */
+# define RTSemEventMultiRemoveSignaller RT_MANGLER(RTSemEventMultiRemoveSignaller)
+# define RTSemEventMultiReset RT_MANGLER(RTSemEventMultiReset)
+# define RTSemEventMultiSetSignaller RT_MANGLER(RTSemEventMultiSetSignaller)
+# define RTSemEventMultiSignal RT_MANGLER(RTSemEventMultiSignal)
+# define RTSemEventMultiWait RT_MANGLER(RTSemEventMultiWait)
+# define RTSemEventMultiWaitEx RT_MANGLER(RTSemEventMultiWaitEx)
+# define RTSemEventMultiWaitEx RT_MANGLER(RTSemEventMultiWaitEx) /* r0drv */
+# define RTSemEventMultiWaitExDebug RT_MANGLER(RTSemEventMultiWaitExDebug)
+# define RTSemEventMultiWaitExDebug RT_MANGLER(RTSemEventMultiWaitExDebug) /* r0drv */
+# define RTSemEventMultiWaitNoResume RT_MANGLER(RTSemEventMultiWaitNoResume)
+# define RTSemEventRemoveSignaller RT_MANGLER(RTSemEventRemoveSignaller)
+# define RTSemEventSetSignaller RT_MANGLER(RTSemEventSetSignaller)
+# define RTSemEventSignal RT_MANGLER(RTSemEventSignal)
+# define RTSemEventWait RT_MANGLER(RTSemEventWait)
+# define RTSemEventWaitEx RT_MANGLER(RTSemEventWaitEx) /* r0drv */
+# define RTSemEventWaitExDebug RT_MANGLER(RTSemEventWaitExDebug) /* r0drv */
+# define RTSemEventWaitNoResume RT_MANGLER(RTSemEventWaitNoResume)
+# define RTSemFastMutexCreate RT_MANGLER(RTSemFastMutexCreate)
+# define RTSemFastMutexDestroy RT_MANGLER(RTSemFastMutexDestroy)
+# define RTSemFastMutexRelease RT_MANGLER(RTSemFastMutexRelease)
+# define RTSemFastMutexRequest RT_MANGLER(RTSemFastMutexRequest)
+# define RTSemMutexCreate RT_MANGLER(RTSemMutexCreate)
+# define RTSemMutexCreateEx RT_MANGLER(RTSemMutexCreateEx)
+# define RTSemMutexDestroy RT_MANGLER(RTSemMutexDestroy)
+# define RTSemMutexIsOwned RT_MANGLER(RTSemMutexIsOwned)
+# define RTSemMutexRelease RT_MANGLER(RTSemMutexRelease)
+# define RTSemMutexRequest RT_MANGLER(RTSemMutexRequest)
+# define RTSemMutexRequestDebug RT_MANGLER(RTSemMutexRequestDebug)
+# define RTSemMutexRequestNoResume RT_MANGLER(RTSemMutexRequestNoResume)
+# define RTSemMutexRequestNoResumeDebug RT_MANGLER(RTSemMutexRequestNoResumeDebug)
+# define RTSemMutexSetSubClass RT_MANGLER(RTSemMutexSetSubClass)
+# define RTSemPing RT_MANGLER(RTSemPing)
+# define RTSemPingPongDelete RT_MANGLER(RTSemPingPongDelete)
+# define RTSemPingPongInit RT_MANGLER(RTSemPingPongInit)
+# define RTSemPingWait RT_MANGLER(RTSemPingWait)
+# define RTSemPong RT_MANGLER(RTSemPong)
+# define RTSemPongWait RT_MANGLER(RTSemPongWait)
+# define RTSemRWCreate RT_MANGLER(RTSemRWCreate)
+# define RTSemRWCreateEx RT_MANGLER(RTSemRWCreateEx)
+# define RTSemRWDestroy RT_MANGLER(RTSemRWDestroy)
+# define RTSemRWGetReadCount RT_MANGLER(RTSemRWGetReadCount)
+# define RTSemRWGetWriteRecursion RT_MANGLER(RTSemRWGetWriteRecursion)
+# define RTSemRWGetWriterReadRecursion RT_MANGLER(RTSemRWGetWriterReadRecursion)
+# define RTSemRWIsReadOwner RT_MANGLER(RTSemRWIsReadOwner)
+# define RTSemRWIsWriteOwner RT_MANGLER(RTSemRWIsWriteOwner)
+# define RTSemRWReleaseRead RT_MANGLER(RTSemRWReleaseRead)
+# define RTSemRWReleaseWrite RT_MANGLER(RTSemRWReleaseWrite)
+# define RTSemRWRequestRead RT_MANGLER(RTSemRWRequestRead)
+# define RTSemRWRequestReadDebug RT_MANGLER(RTSemRWRequestReadDebug)
+# define RTSemRWRequestReadNoResume RT_MANGLER(RTSemRWRequestReadNoResume)
+# define RTSemRWRequestReadNoResumeDebug RT_MANGLER(RTSemRWRequestReadNoResumeDebug)
+# define RTSemRWRequestWrite RT_MANGLER(RTSemRWRequestWrite)
+# define RTSemRWRequestWriteDebug RT_MANGLER(RTSemRWRequestWriteDebug)
+# define RTSemRWRequestWriteNoResume RT_MANGLER(RTSemRWRequestWriteNoResume)
+# define RTSemRWRequestWriteNoResumeDebug RT_MANGLER(RTSemRWRequestWriteNoResumeDebug)
+# define RTSemRWSetSubClass RT_MANGLER(RTSemRWSetSubClass)
+# define RTSemSpinMutexCreate RT_MANGLER(RTSemSpinMutexCreate)
+# define RTSemSpinMutexDestroy RT_MANGLER(RTSemSpinMutexDestroy)
+# define RTSemSpinMutexRelease RT_MANGLER(RTSemSpinMutexRelease)
+# define RTSemSpinMutexRequest RT_MANGLER(RTSemSpinMutexRequest)
+# define RTSemSpinMutexTryRequest RT_MANGLER(RTSemSpinMutexTryRequest)
+# define RTSemXRoadsCreate RT_MANGLER(RTSemXRoadsCreate)
+# define RTSemXRoadsDestroy RT_MANGLER(RTSemXRoadsDestroy)
+# define RTSemXRoadsEWEnter RT_MANGLER(RTSemXRoadsEWEnter)
+# define RTSemXRoadsEWLeave RT_MANGLER(RTSemXRoadsEWLeave)
+# define RTSemXRoadsNSEnter RT_MANGLER(RTSemXRoadsNSEnter)
+# define RTSemXRoadsNSLeave RT_MANGLER(RTSemXRoadsNSLeave)
+# define RTSgBufAdvance RT_MANGLER(RTSgBufAdvance)
+# define RTSgBufClone RT_MANGLER(RTSgBufClone)
+# define RTSgBufCmp RT_MANGLER(RTSgBufCmp)
+# define RTSgBufCmpEx RT_MANGLER(RTSgBufCmpEx)
+# define RTSgBufCopy RT_MANGLER(RTSgBufCopy)
+# define RTSgBufCopyFromBuf RT_MANGLER(RTSgBufCopyFromBuf)
+# define RTSgBufCopyToBuf RT_MANGLER(RTSgBufCopyToBuf)
+# define RTSgBufInit RT_MANGLER(RTSgBufInit)
+# define RTSgBufReset RT_MANGLER(RTSgBufReset)
+# define RTSgBufSegArrayCreate RT_MANGLER(RTSgBufSegArrayCreate)
+# define RTSgBufSet RT_MANGLER(RTSgBufSet)
+# define RTSgBufGetNextSegment RT_MANGLER(RTSgBufGetNextSegment)
+# define RTSha1 RT_MANGLER(RTSha1)
+# define RTSha1Digest RT_MANGLER(RTSha1Digest)
+# define RTSha1DigestFromFile RT_MANGLER(RTSha1DigestFromFile)
+# define RTSha1Final RT_MANGLER(RTSha1Final)
+# define RTSha1FromString RT_MANGLER(RTSha1FromString)
+# define RTSha1Init RT_MANGLER(RTSha1Init)
+# define RTSha1ToString RT_MANGLER(RTSha1ToString)
+# define RTSha1Update RT_MANGLER(RTSha1Update)
+# define RTSha256 RT_MANGLER(RTSha256)
+# define RTSha256Final RT_MANGLER(RTSha256Final)
+# define RTSha256FromString RT_MANGLER(RTSha256FromString)
+# define RTSha256Init RT_MANGLER(RTSha256Init)
+# define RTSha256ToString RT_MANGLER(RTSha256ToString)
+# define RTSha256Update RT_MANGLER(RTSha256Update)
+# define RTSha512 RT_MANGLER(RTSha512)
+# define RTSha512Final RT_MANGLER(RTSha512Final)
+# define RTSha512FromString RT_MANGLER(RTSha512FromString)
+# define RTSha512Init RT_MANGLER(RTSha512Init)
+# define RTSha512ToString RT_MANGLER(RTSha512ToString)
+# define RTSha512Update RT_MANGLER(RTSha512Update)
+# define RTSocketClose RT_MANGLER(RTSocketClose)
+# define RTSocketFromNative RT_MANGLER(RTSocketFromNative)
+# define RTSocketQueryAddressStr RT_MANGLER(RTSocketQueryAddressStr)
+# define RTSocketGetLocalAddress RT_MANGLER(RTSocketGetLocalAddress)
+# define RTSocketGetPeerAddress RT_MANGLER(RTSocketGetPeerAddress)
+# define RTSocketParseInetAddress RT_MANGLER(RTSocketParseInetAddress)
+# define RTSocketRead RT_MANGLER(RTSocketRead)
+# define RTSocketReadFrom RT_MANGLER(RTSocketReadFrom)
+# define RTSocketReadNB RT_MANGLER(RTSocketReadNB)
+# define RTSocketRelease RT_MANGLER(RTSocketRelease)
+# define RTSocketRetain RT_MANGLER(RTSocketRetain)
+# define RTSocketSelectOne RT_MANGLER(RTSocketSelectOne)
+# define RTSocketSelectOneEx RT_MANGLER(RTSocketSelectOneEx)
+# define RTSocketSetInheritance RT_MANGLER(RTSocketSetInheritance)
+# define RTSocketSgWrite RT_MANGLER(RTSocketSgWrite)
+# define RTSocketSgWriteL RT_MANGLER(RTSocketSgWriteL)
+# define RTSocketSgWriteLNB RT_MANGLER(RTSocketSgWriteLNB)
+# define RTSocketSgWriteLV RT_MANGLER(RTSocketSgWriteLV)
+# define RTSocketSgWriteLVNB RT_MANGLER(RTSocketSgWriteLVNB)
+# define RTSocketSgWriteNB RT_MANGLER(RTSocketSgWriteNB)
+# define RTSocketShutdown RT_MANGLER(RTSocketShutdown)
+# define RTSocketToNative RT_MANGLER(RTSocketToNative)
+# define RTSocketWrite RT_MANGLER(RTSocketWrite)
+# define RTSocketWriteNB RT_MANGLER(RTSocketWriteNB)
+# define RTSocketWriteTo RT_MANGLER(RTSocketWriteTo)
+# define RTSortApvIsSorted RT_MANGLER(RTSortApvIsSorted)
+# define RTSortApvShell RT_MANGLER(RTSortApvShell)
+# define RTSortIsSorted RT_MANGLER(RTSortIsSorted)
+# define RTSpinlockAcquire RT_MANGLER(RTSpinlockAcquire)
+# define RTSpinlockAcquireNoInts RT_MANGLER(RTSpinlockAcquireNoInts)
+# define RTSpinlockCreate RT_MANGLER(RTSpinlockCreate)
+# define RTSpinlockDestroy RT_MANGLER(RTSpinlockDestroy)
+# define RTSpinlockRelease RT_MANGLER(RTSpinlockRelease)
+# define RTSpinlockReleaseNoInts RT_MANGLER(RTSpinlockReleaseNoInts)
+# define RTStrAAppendExNVTag RT_MANGLER(RTStrAAppendExNVTag)
+# define RTStrAAppendNTag RT_MANGLER(RTStrAAppendNTag)
+# define RTStrAAppendTag RT_MANGLER(RTStrAAppendTag)
+# define RTStrAllocExTag RT_MANGLER(RTStrAllocExTag)
+# define RTStrAllocTag RT_MANGLER(RTStrAllocTag)
+# define RTStrAPrintf2VTag RT_MANGLER(RTStrAPrintf2VTag)
+# define RTStrAPrintfVTag RT_MANGLER(RTStrAPrintfVTag)
+# define RTStrATruncateTag RT_MANGLER(RTStrATruncateTag)
+# define RTStrCacheCreate RT_MANGLER(RTStrCacheCreate)
+# define RTStrCacheDestroy RT_MANGLER(RTStrCacheDestroy)
+# define RTStrCacheEnter RT_MANGLER(RTStrCacheEnter)
+# define RTStrCacheEnterN RT_MANGLER(RTStrCacheEnterN)
+# define RTStrCacheLength RT_MANGLER(RTStrCacheLength)
+# define RTStrCacheRelease RT_MANGLER(RTStrCacheRelease)
+# define RTStrCacheRetain RT_MANGLER(RTStrCacheRetain)
+# define RTStrCalcLatin1Len RT_MANGLER(RTStrCalcLatin1Len)
+# define RTStrCalcLatin1LenEx RT_MANGLER(RTStrCalcLatin1LenEx)
+# define RTStrCalcUtf16Len RT_MANGLER(RTStrCalcUtf16Len)
+# define RTStrCalcUtf16LenEx RT_MANGLER(RTStrCalcUtf16LenEx)
+# define RTStrCat RT_MANGLER(RTStrCat)
+# define RTStrCatEx RT_MANGLER(RTStrCatEx)
+# define RTStrCatP RT_MANGLER(RTStrCatP)
+# define RTStrCatPEx RT_MANGLER(RTStrCatPEx)
+# define RTStrCmp RT_MANGLER(RTStrCmp)
+# define RTStrConvertHexBytes RT_MANGLER(RTStrConvertHexBytes)
+# define RTStrCopy RT_MANGLER(RTStrCopy)
+# define RTStrCopyEx RT_MANGLER(RTStrCopyEx)
+# define RTStrCopyP RT_MANGLER(RTStrCopyP)
+# define RTStrCopyPEx RT_MANGLER(RTStrCopyPEx)
+# define RTStrCurrentCPToUtf8Tag RT_MANGLER(RTStrCurrentCPToUtf8Tag)
+# define RTStrDupExTag RT_MANGLER(RTStrDupExTag)
+# define RTStrDupNTag RT_MANGLER(RTStrDupNTag)
+# define RTStrDupTag RT_MANGLER(RTStrDupTag)
+# define RTStrFormat RT_MANGLER(RTStrFormat)
+# define RTStrFormatNumber RT_MANGLER(RTStrFormatNumber)
+# define RTStrFormatR80 RT_MANGLER(RTStrFormatR80)
+# define RTStrFormatR80u2 RT_MANGLER(RTStrFormatR80u2)
+# define RTStrFormatTypeDeregister RT_MANGLER(RTStrFormatTypeDeregister)
+# define RTStrFormatTypeRegister RT_MANGLER(RTStrFormatTypeRegister)
+# define RTStrFormatTypeSetUser RT_MANGLER(RTStrFormatTypeSetUser)
+# define RTStrFormatU128 RT_MANGLER(RTStrFormatU128)
+# define RTStrFormatU16 RT_MANGLER(RTStrFormatU16)
+# define RTStrFormatU32 RT_MANGLER(RTStrFormatU32)
+# define RTStrFormatU64 RT_MANGLER(RTStrFormatU64)
+# define RTStrFormatU8 RT_MANGLER(RTStrFormatU8)
+# define RTStrFormatV RT_MANGLER(RTStrFormatV)
+# define RTStrFree RT_MANGLER(RTStrFree)
+# define RTStrGetCpExInternal RT_MANGLER(RTStrGetCpExInternal)
+# define RTStrGetCpInternal RT_MANGLER(RTStrGetCpInternal)
+# define RTStrGetCpNExInternal RT_MANGLER(RTStrGetCpNExInternal)
+# define RTStrHash1 RT_MANGLER(RTStrHash1)
+# define RTStrHash1ExN RT_MANGLER(RTStrHash1ExN)
+# define RTStrHash1ExNV RT_MANGLER(RTStrHash1ExNV)
+# define RTStrHash1N RT_MANGLER(RTStrHash1N)
+# define RTStrICmp RT_MANGLER(RTStrICmp)
+# define RTStrIStr RT_MANGLER(RTStrIStr)
+# define RTStrIsValidEncoding RT_MANGLER(RTStrIsValidEncoding)
+# define RTStrmClearError RT_MANGLER(RTStrmClearError)
+# define RTStrmClose RT_MANGLER(RTStrmClose)
+# define RTStrmError RT_MANGLER(RTStrmError)
+# define RTStrmFlush RT_MANGLER(RTStrmFlush)
+# define RTStrmGetCh RT_MANGLER(RTStrmGetCh)
+# define RTStrmGetLine RT_MANGLER(RTStrmGetLine)
+# define RTStrmOpen RT_MANGLER(RTStrmOpen)
+# define RTStrmOpenF RT_MANGLER(RTStrmOpenF)
+# define RTStrmOpenFV RT_MANGLER(RTStrmOpenFV)
+# define RTStrmPrintf RT_MANGLER(RTStrmPrintf)
+# define RTStrmPrintfV RT_MANGLER(RTStrmPrintfV)
+# define RTStrmPutCh RT_MANGLER(RTStrmPutCh)
+# define RTStrmPutStr RT_MANGLER(RTStrmPutStr)
+# define RTStrmReadEx RT_MANGLER(RTStrmReadEx)
+# define RTStrmRewind RT_MANGLER(RTStrmRewind)
+# define RTStrmSetMode RT_MANGLER(RTStrmSetMode)
+# define RTStrmWriteEx RT_MANGLER(RTStrmWriteEx)
+# define RTStrNCmp RT_MANGLER(RTStrNCmp)
+# define RTStrNICmp RT_MANGLER(RTStrNICmp)
+# define RTStrNLen RT_MANGLER(RTStrNLen)
+# define RTStrNLenEx RT_MANGLER(RTStrNLenEx)
+# define RTStrPrevCp RT_MANGLER(RTStrPrevCp)
+# define RTStrPrintf RT_MANGLER(RTStrPrintf)
+# define RTStrPrintfEx RT_MANGLER(RTStrPrintfEx)
+# define RTStrPrintfExV RT_MANGLER(RTStrPrintfExV)
+# define RTStrPrintfV RT_MANGLER(RTStrPrintfV)
+# define RTStrPrintHexBytes RT_MANGLER(RTStrPrintHexBytes)
+# define RTStrPurgeEncoding RT_MANGLER(RTStrPurgeEncoding)
+# define RTStrPurgeComplementSet RT_MANGLER(RTStrPurgeComplementSet)
+# define RTStrPutCpInternal RT_MANGLER(RTStrPutCpInternal)
+# define RTStrReallocTag RT_MANGLER(RTStrReallocTag)
+# define RTStrSimplePatternMatch RT_MANGLER(RTStrSimplePatternMatch)
+# define RTStrSimplePatternMultiMatch RT_MANGLER(RTStrSimplePatternMultiMatch)
+# define RTStrSimplePatternNMatch RT_MANGLER(RTStrSimplePatternNMatch)
+# define RTStrSpaceDestroy RT_MANGLER(RTStrSpaceDestroy)
+# define RTStrSpaceEnumerate RT_MANGLER(RTStrSpaceEnumerate)
+# define RTStrSpaceGet RT_MANGLER(RTStrSpaceGet)
+# define RTStrSpaceGetN RT_MANGLER(RTStrSpaceGetN)
+# define RTStrSpaceInsert RT_MANGLER(RTStrSpaceInsert)
+# define RTStrSpaceRemove RT_MANGLER(RTStrSpaceRemove)
+# define RTStrStr RT_MANGLER(RTStrStr)
+# define RTStrStrip RT_MANGLER(RTStrStrip)
+# define RTStrStripL RT_MANGLER(RTStrStripL)
+# define RTStrStripR RT_MANGLER(RTStrStripR)
+# define RTStrToInt16 RT_MANGLER(RTStrToInt16)
+# define RTStrToInt16Ex RT_MANGLER(RTStrToInt16Ex)
+# define RTStrToInt16Full RT_MANGLER(RTStrToInt16Full)
+# define RTStrToInt32 RT_MANGLER(RTStrToInt32)
+# define RTStrToInt32Ex RT_MANGLER(RTStrToInt32Ex)
+# define RTStrToInt32Full RT_MANGLER(RTStrToInt32Full)
+# define RTStrToInt64 RT_MANGLER(RTStrToInt64)
+# define RTStrToInt64Ex RT_MANGLER(RTStrToInt64Ex)
+# define RTStrToInt64Full RT_MANGLER(RTStrToInt64Full)
+# define RTStrToInt8 RT_MANGLER(RTStrToInt8)
+# define RTStrToInt8Ex RT_MANGLER(RTStrToInt8Ex)
+# define RTStrToInt8Full RT_MANGLER(RTStrToInt8Full)
+# define RTStrToLatin1ExTag RT_MANGLER(RTStrToLatin1ExTag)
+# define RTStrToLatin1Tag RT_MANGLER(RTStrToLatin1Tag)
+# define RTStrToLower RT_MANGLER(RTStrToLower)
+# define RTStrToUInt16 RT_MANGLER(RTStrToUInt16)
+# define RTStrToUInt16Ex RT_MANGLER(RTStrToUInt16Ex)
+# define RTStrToUInt16Full RT_MANGLER(RTStrToUInt16Full)
+# define RTStrToUInt32 RT_MANGLER(RTStrToUInt32)
+# define RTStrToUInt32Ex RT_MANGLER(RTStrToUInt32Ex)
+# define RTStrToUInt32Full RT_MANGLER(RTStrToUInt32Full)
+# define RTStrToUInt64 RT_MANGLER(RTStrToUInt64)
+# define RTStrToUInt64Ex RT_MANGLER(RTStrToUInt64Ex)
+# define RTStrToUInt64Full RT_MANGLER(RTStrToUInt64Full)
+# define RTStrToUInt8 RT_MANGLER(RTStrToUInt8)
+# define RTStrToUInt8Ex RT_MANGLER(RTStrToUInt8Ex)
+# define RTStrToUInt8Full RT_MANGLER(RTStrToUInt8Full)
+# define RTStrToUni RT_MANGLER(RTStrToUni)
+# define RTStrToUniEx RT_MANGLER(RTStrToUniEx)
+# define RTStrToUpper RT_MANGLER(RTStrToUpper)
+# define RTStrToUtf16ExTag RT_MANGLER(RTStrToUtf16ExTag)
+# define RTStrToUtf16Tag RT_MANGLER(RTStrToUtf16Tag)
+# define RTStrUniLen RT_MANGLER(RTStrUniLen)
+# define RTStrUniLenEx RT_MANGLER(RTStrUniLenEx)
+# define RTStrUtf8ToCurrentCPTag RT_MANGLER(RTStrUtf8ToCurrentCPTag)
+# define RTStrValidateEncoding RT_MANGLER(RTStrValidateEncoding)
+# define RTStrValidateEncodingEx RT_MANGLER(RTStrValidateEncodingEx)
+# define RTStrVersionCompare RT_MANGLER(RTStrVersionCompare)
+# define RTSymlinkCreate RT_MANGLER(RTSymlinkCreate)
+# define RTSymlinkDelete RT_MANGLER(RTSymlinkDelete)
+# define RTSymlinkExists RT_MANGLER(RTSymlinkExists)
+# define RTSymlinkIsDangling RT_MANGLER(RTSymlinkIsDangling)
+# define RTSymlinkRead RT_MANGLER(RTSymlinkRead)
+# define RTSymlinkReadA RT_MANGLER(RTSymlinkReadA)
+# define RTSystemQueryAvailableRam RT_MANGLER(RTSystemQueryAvailableRam)
+# define RTSystemQueryDmiString RT_MANGLER(RTSystemQueryDmiString)
+# define RTSystemQueryOSInfo RT_MANGLER(RTSystemQueryOSInfo)
+# define RTSystemQueryTotalRam RT_MANGLER(RTSystemQueryTotalRam)
+# define RTSystemShutdown RT_MANGLER(RTSystemShutdown)
+# define RTTarClose RT_MANGLER(RTTarClose)
+# define RTTarCreate RT_MANGLER(RTTarCreate)
+# define RTTarCurrentFile RT_MANGLER(RTTarCurrentFile)
+# define RTTarExtractAll RT_MANGLER(RTTarExtractAll)
+# define RTTarExtractFiles RT_MANGLER(RTTarExtractFiles)
+# define RTTarExtractFileToBuf RT_MANGLER(RTTarExtractFileToBuf)
+# define RTTarFileClose RT_MANGLER(RTTarFileClose)
+# define RTTarFileExists RT_MANGLER(RTTarFileExists)
+# define RTTarFileGetMode RT_MANGLER(RTTarFileGetMode)
+# define RTTarFileGetOwner RT_MANGLER(RTTarFileGetOwner)
+# define RTTarFileGetSize RT_MANGLER(RTTarFileGetSize)
+# define RTTarFileGetTime RT_MANGLER(RTTarFileGetTime)
+# define RTTarFileOpen RT_MANGLER(RTTarFileOpen)
+# define RTTarFileOpenCurrentFile RT_MANGLER(RTTarFileOpenCurrentFile)
+# define RTTarFileRead RT_MANGLER(RTTarFileRead)
+# define RTTarFileReadAt RT_MANGLER(RTTarFileReadAt)
+# define RTTarFileSeek RT_MANGLER(RTTarFileSeek)
+# define RTTarFileSetMode RT_MANGLER(RTTarFileSetMode)
+# define RTTarFileSetOwner RT_MANGLER(RTTarFileSetOwner)
+# define RTTarFileSetSize RT_MANGLER(RTTarFileSetSize)
+# define RTTarFileSetTime RT_MANGLER(RTTarFileSetTime)
+# define RTTarFileTell RT_MANGLER(RTTarFileTell)
+# define RTTarFileWrite RT_MANGLER(RTTarFileWrite)
+# define RTTarFileWriteAt RT_MANGLER(RTTarFileWriteAt)
+# define RTTarList RT_MANGLER(RTTarList)
+# define RTTarOpen RT_MANGLER(RTTarOpen)
+# define RTTarSeekNextFile RT_MANGLER(RTTarSeekNextFile)
+# define RTTcpClientClose RT_MANGLER(RTTcpClientClose)
+# define RTTcpClientCloseEx RT_MANGLER(RTTcpClientCloseEx)
+# define RTTcpClientConnect RT_MANGLER(RTTcpClientConnect)
+# define RTTcpFlush RT_MANGLER(RTTcpFlush)
+# define RTTcpGetLocalAddress RT_MANGLER(RTTcpGetLocalAddress)
+# define RTTcpGetPeerAddress RT_MANGLER(RTTcpGetPeerAddress)
+# define RTTcpRead RT_MANGLER(RTTcpRead)
+# define RTTcpReadNB RT_MANGLER(RTTcpReadNB)
+# define RTTcpSelectOne RT_MANGLER(RTTcpSelectOne)
+# define RTTcpSelectOneEx RT_MANGLER(RTTcpSelectOneEx)
+# define RTTcpServerCreate RT_MANGLER(RTTcpServerCreate)
+# define RTTcpServerCreateEx RT_MANGLER(RTTcpServerCreateEx)
+# define RTTcpServerDestroy RT_MANGLER(RTTcpServerDestroy)
+# define RTTcpServerDisconnectClient RT_MANGLER(RTTcpServerDisconnectClient)
+# define RTTcpServerDisconnectClient2 RT_MANGLER(RTTcpServerDisconnectClient2)
+# define RTTcpServerListen RT_MANGLER(RTTcpServerListen)
+# define RTTcpServerListen2 RT_MANGLER(RTTcpServerListen2)
+# define RTTcpServerShutdown RT_MANGLER(RTTcpServerShutdown)
+# define RTTcpSetSendCoalescing RT_MANGLER(RTTcpSetSendCoalescing)
+# define RTTcpSgWrite RT_MANGLER(RTTcpSgWrite)
+# define RTTcpSgWriteL RT_MANGLER(RTTcpSgWriteL)
+# define RTTcpSgWriteLNB RT_MANGLER(RTTcpSgWriteLNB)
+# define RTTcpSgWriteLV RT_MANGLER(RTTcpSgWriteLV)
+# define RTTcpSgWriteLVNB RT_MANGLER(RTTcpSgWriteLVNB)
+# define RTTcpSgWriteNB RT_MANGLER(RTTcpSgWriteNB)
+# define RTTcpWrite RT_MANGLER(RTTcpWrite)
+# define RTTcpWriteNB RT_MANGLER(RTTcpWriteNB)
+# define RTTermDeregisterCallback RT_MANGLER(RTTermDeregisterCallback)
+# define RTTermRegisterCallback RT_MANGLER(RTTermRegisterCallback)
+# define RTTermRunCallbacks RT_MANGLER(RTTermRunCallbacks)
+# define RTTestBanner RT_MANGLER(RTTestBanner)
+# define RTTestCreate RT_MANGLER(RTTestCreate)
+# define RTTestDestroy RT_MANGLER(RTTestDestroy)
+# define RTTestErrorCount RT_MANGLER(RTTestErrorCount)
+# define RTTestErrorInc RT_MANGLER(RTTestErrorInc)
+# define RTTestFailed RT_MANGLER(RTTestFailed)
+# define RTTestFailedV RT_MANGLER(RTTestFailedV)
+# define RTTestFailureDetails RT_MANGLER(RTTestFailureDetails)
+# define RTTestFailureDetailsV RT_MANGLER(RTTestFailureDetailsV)
+# define RTTestGuardedAlloc RT_MANGLER(RTTestGuardedAlloc)
+# define RTTestGuardedAllocHead RT_MANGLER(RTTestGuardedAllocHead)
+# define RTTestGuardedAllocTail RT_MANGLER(RTTestGuardedAllocTail)
+# define RTTestGuardedFree RT_MANGLER(RTTestGuardedFree)
+# define RTTestIErrorCount RT_MANGLER(RTTestIErrorCount)
+# define RTTestIErrorInc RT_MANGLER(RTTestIErrorInc)
+# define RTTestIFailed RT_MANGLER(RTTestIFailed)
+# define RTTestIFailedRc RT_MANGLER(RTTestIFailedRc)
+# define RTTestIFailedRcV RT_MANGLER(RTTestIFailedRcV)
+# define RTTestIFailedV RT_MANGLER(RTTestIFailedV)
+# define RTTestIFailureDetails RT_MANGLER(RTTestIFailureDetails)
+# define RTTestIFailureDetailsV RT_MANGLER(RTTestIFailureDetailsV)
+# define RTTestInitAndCreate RT_MANGLER(RTTestInitAndCreate)
+# define RTTestIPassed RT_MANGLER(RTTestIPassed)
+# define RTTestIPassedV RT_MANGLER(RTTestIPassedV)
+# define RTTestIPrintf RT_MANGLER(RTTestIPrintf)
+# define RTTestIPrintfV RT_MANGLER(RTTestIPrintfV)
+# define RTTestISub RT_MANGLER(RTTestISub)
+# define RTTestISubDone RT_MANGLER(RTTestISubDone)
+# define RTTestISubF RT_MANGLER(RTTestISubF)
+# define RTTestISubV RT_MANGLER(RTTestISubV)
+# define RTTestIValue RT_MANGLER(RTTestIValue)
+# define RTTestIValueF RT_MANGLER(RTTestIValueF)
+# define RTTestIValueV RT_MANGLER(RTTestIValueV)
+# define RTTestPassed RT_MANGLER(RTTestPassed)
+# define RTTestPassedV RT_MANGLER(RTTestPassedV)
+# define RTTestPrintf RT_MANGLER(RTTestPrintf)
+# define RTTestPrintfNl RT_MANGLER(RTTestPrintfNl)
+# define RTTestPrintfNlV RT_MANGLER(RTTestPrintfNlV)
+# define RTTestPrintfV RT_MANGLER(RTTestPrintfV)
+# define RTTestSetDefault RT_MANGLER(RTTestSetDefault)
+# define RTTestSkipAndDestroy RT_MANGLER(RTTestSkipAndDestroy)
+# define RTTestSkipAndDestroyV RT_MANGLER(RTTestSkipAndDestroyV)
+# define RTTestSub RT_MANGLER(RTTestSub)
+# define RTTestSubDone RT_MANGLER(RTTestSubDone)
+# define RTTestSubF RT_MANGLER(RTTestSubF)
+# define RTTestSubV RT_MANGLER(RTTestSubV)
+# define RTTestSummaryAndDestroy RT_MANGLER(RTTestSummaryAndDestroy)
+# define RTTestValue RT_MANGLER(RTTestValue)
+# define RTTestValueF RT_MANGLER(RTTestValueF)
+# define RTTestValueV RT_MANGLER(RTTestValueV)
+# define RTThreadAdopt RT_MANGLER(RTThreadAdopt)
+# define RTThreadBlocking RT_MANGLER(RTThreadBlocking)
+# define RTThreadCreate RT_MANGLER(RTThreadCreate)
+# define RTThreadCreateF RT_MANGLER(RTThreadCreateF)
+# define RTThreadCreateV RT_MANGLER(RTThreadCreateV)
+# define RTThreadFromNative RT_MANGLER(RTThreadFromNative)
+# define RTThreadGetAffinity RT_MANGLER(RTThreadGetAffinity)
+# define RTThreadGetExecutionTimeMilli RT_MANGLER(RTThreadGetExecutionTimeMilli)
+# define RTThreadGetName RT_MANGLER(RTThreadGetName)
+# define RTThreadGetNative RT_MANGLER(RTThreadGetNative)
+# define RTThreadGetNativeState RT_MANGLER(RTThreadGetNativeState)
+# define RTThreadGetReallySleeping RT_MANGLER(RTThreadGetReallySleeping)
+# define RTThreadGetState RT_MANGLER(RTThreadGetState)
+# define RTThreadGetType RT_MANGLER(RTThreadGetType)
+# define RTThreadIsInInterrupt RT_MANGLER(RTThreadIsInInterrupt) /* r0drv */
+# define RTThreadIsInitialized RT_MANGLER(RTThreadIsInitialized)
+# define RTThreadIsMain RT_MANGLER(RTThreadIsMain)
+# define RTThreadIsSelfAlive RT_MANGLER(RTThreadIsSelfAlive)
+# define RTThreadIsSelfKnown RT_MANGLER(RTThreadIsSelfKnown)
+# define RTThreadNativeSelf RT_MANGLER(RTThreadNativeSelf)
+# define RTThreadPoke RT_MANGLER(RTThreadPoke) /* not-win not-os2 */
+# define RTThreadPreemptDisable RT_MANGLER(RTThreadPreemptDisable) /* r0drv */
+# define RTThreadPreemptIsEnabled RT_MANGLER(RTThreadPreemptIsEnabled) /* r0drv */
+# define RTThreadPreemptIsPending RT_MANGLER(RTThreadPreemptIsPending) /* r0drv */
+# define RTThreadPreemptIsPendingTrusty RT_MANGLER(RTThreadPreemptIsPendingTrusty) /* r0drv */
+# define RTThreadPreemptIsPossible RT_MANGLER(RTThreadPreemptIsPossible) /* r0drv */
+# define RTThreadPreemptRestore RT_MANGLER(RTThreadPreemptRestore) /* r0drv */
+# define RTThreadSelf RT_MANGLER(RTThreadSelf)
+# define RTThreadSelfAutoAdopt RT_MANGLER(RTThreadSelfAutoAdopt)
+# define RTThreadSelfName RT_MANGLER(RTThreadSelfName)
+# define RTThreadSetAffinity RT_MANGLER(RTThreadSetAffinity)
+# define RTThreadSetAffinityToCpu RT_MANGLER(RTThreadSetAffinityToCpu)
+# define RTThreadSetName RT_MANGLER(RTThreadSetName)
+# define RTThreadSetType RT_MANGLER(RTThreadSetType)
+# define RTThreadSleep RT_MANGLER(RTThreadSleep)
+# define RTThreadSleepNoLog RT_MANGLER(RTThreadSleepNoLog)
+# define RTThreadStateName RT_MANGLER(RTThreadStateName)
+# define RTThreadUnblocked RT_MANGLER(RTThreadUnblocked)
+# define RTThreadUserReset RT_MANGLER(RTThreadUserReset)
+# define RTThreadUserSignal RT_MANGLER(RTThreadUserSignal)
+# define RTThreadUserWait RT_MANGLER(RTThreadUserWait)
+# define RTThreadUserWaitNoResume RT_MANGLER(RTThreadUserWaitNoResume)
+# define RTThreadWait RT_MANGLER(RTThreadWait)
+# define RTThreadWaitNoResume RT_MANGLER(RTThreadWaitNoResume)
+# define RTThreadYield RT_MANGLER(RTThreadYield)
+# define RTTimeDbgBad RT_MANGLER(RTTimeDbgBad)
+# define RTTimeDbgExpired RT_MANGLER(RTTimeDbgExpired)
+# define RTTimeDbgRaces RT_MANGLER(RTTimeDbgRaces)
+# define RTTimeDbgSteps RT_MANGLER(RTTimeDbgSteps)
+# define RTTimeExplode RT_MANGLER(RTTimeExplode)
+# define RTTimeImplode RT_MANGLER(RTTimeImplode)
+# define RTTimeIsLeapYear RT_MANGLER(RTTimeIsLeapYear)
+# define RTTimeLocalDeltaNano RT_MANGLER(RTTimeLocalDeltaNano)
+# define RTTimeLocalExplode RT_MANGLER(RTTimeLocalExplode)
+# define RTTimeLocalNow RT_MANGLER(RTTimeLocalNow)
+# define RTTimeMilliTS RT_MANGLER(RTTimeMilliTS)
+# define RTTimeNanoTS RT_MANGLER(RTTimeNanoTS)
+# define RTTimeNanoTSLegacyAsync RT_MANGLER(RTTimeNanoTSLegacyAsync)
+# define RTTimeNanoTSLegacySync RT_MANGLER(RTTimeNanoTSLegacySync)
+# define RTTimeNanoTSLFenceAsync RT_MANGLER(RTTimeNanoTSLFenceAsync)
+# define RTTimeNanoTSLFenceSync RT_MANGLER(RTTimeNanoTSLFenceSync)
+# define RTTimeNormalize RT_MANGLER(RTTimeNormalize)
+# define RTTimeNow RT_MANGLER(RTTimeNow)
+# define RTTimeProgramMicroTS RT_MANGLER(RTTimeProgramMicroTS)
+# define RTTimeProgramMilliTS RT_MANGLER(RTTimeProgramMilliTS)
+# define RTTimeProgramNanoTS RT_MANGLER(RTTimeProgramNanoTS)
+# define RTTimeProgramSecTS RT_MANGLER(RTTimeProgramSecTS)
+# define RTTimeProgramStartNanoTS RT_MANGLER(RTTimeProgramStartNanoTS)
+# define RTTimerCanDoHighResolution RT_MANGLER(RTTimerCanDoHighResolution)
+# define RTTimerChangeInterval RT_MANGLER(RTTimerChangeInterval)
+# define RTTimerCreate RT_MANGLER(RTTimerCreate)
+# define RTTimerCreateEx RT_MANGLER(RTTimerCreateEx)
+# define RTTimerDestroy RT_MANGLER(RTTimerDestroy)
+# define RTTimerGetSystemGranularity RT_MANGLER(RTTimerGetSystemGranularity) /* r0drv */
+# define RTTimerLRCreate RT_MANGLER(RTTimerLRCreate)
+# define RTTimerLRCreateEx RT_MANGLER(RTTimerLRCreateEx)
+# define RTTimerLRDestroy RT_MANGLER(RTTimerLRDestroy)
+# define RTTimerLRStart RT_MANGLER(RTTimerLRStart)
+# define RTTimerLRStop RT_MANGLER(RTTimerLRStop)
+# define RTTimerLRChangeInterval RT_MANGLER(RTTimerLRChangeInterval)
+# define RTTimerReleaseSystemGranularity RT_MANGLER(RTTimerReleaseSystemGranularity) /* r0drv */
+# define RTTimerRequestSystemGranularity RT_MANGLER(RTTimerRequestSystemGranularity) /* r0drv */
+# define RTTimerStart RT_MANGLER(RTTimerStart)
+# define RTTimerStop RT_MANGLER(RTTimerStop)
+# define RTTimeSet RT_MANGLER(RTTimeSet)
+# define RTTimeSpecToString RT_MANGLER(RTTimeSpecToString)
+# define RTTimeSystemMilliTS RT_MANGLER(RTTimeSystemMilliTS)
+# define RTTimeSystemNanoTS RT_MANGLER(RTTimeSystemNanoTS)
+# define RTTimeToString RT_MANGLER(RTTimeToString)
+# define RTTlsAlloc RT_MANGLER(RTTlsAlloc)
+# define RTTlsAllocEx RT_MANGLER(RTTlsAllocEx)
+# define RTTlsFree RT_MANGLER(RTTlsFree)
+# define RTTlsGet RT_MANGLER(RTTlsGet)
+# define RTTlsGetEx RT_MANGLER(RTTlsGetEx)
+# define RTTlsSet RT_MANGLER(RTTlsSet)
+# define RTTraceBufAddMsg RT_MANGLER(RTTraceBufAddMsg)
+# define RTTraceBufAddMsgEx RT_MANGLER(RTTraceBufAddMsgEx)
+# define RTTraceBufAddMsgF RT_MANGLER(RTTraceBufAddMsgF)
+# define RTTraceBufAddMsgV RT_MANGLER(RTTraceBufAddMsgV)
+# define RTTraceBufAddPos RT_MANGLER(RTTraceBufAddPos)
+# define RTTraceBufAddPosMsg RT_MANGLER(RTTraceBufAddPosMsg)
+# define RTTraceBufAddPosMsgEx RT_MANGLER(RTTraceBufAddPosMsgEx)
+# define RTTraceBufAddPosMsgF RT_MANGLER(RTTraceBufAddPosMsgF)
+# define RTTraceBufAddPosMsgV RT_MANGLER(RTTraceBufAddPosMsgV)
+# define RTTraceBufCarve RT_MANGLER(RTTraceBufCarve)
+# define RTTraceBufCreate RT_MANGLER(RTTraceBufCreate)
+# define RTTraceBufDisable RT_MANGLER(RTTraceBufDisable)
+# define RTTraceBufDumpToAssert RT_MANGLER(RTTraceBufDumpToAssert)
+# define RTTraceBufDumpToLog RT_MANGLER(RTTraceBufDumpToLog)
+# define RTTraceBufEnable RT_MANGLER(RTTraceBufEnable)
+# define RTTraceBufEnumEntries RT_MANGLER(RTTraceBufEnumEntries)
+# define RTTraceBufGetEntryCount RT_MANGLER(RTTraceBufGetEntryCount)
+# define RTTraceBufGetEntrySize RT_MANGLER(RTTraceBufGetEntrySize)
+# define RTTraceBufRelease RT_MANGLER(RTTraceBufRelease)
+# define RTTraceBufRetain RT_MANGLER(RTTraceBufRetain)
+# define RTTraceGetDefaultBuf RT_MANGLER(RTTraceGetDefaultBuf)
+# define RTTraceSetDefaultBuf RT_MANGLER(RTTraceSetDefaultBuf)
+# define RTUdpRead RT_MANGLER(RTUdpRead)
+# define RTUdpServerCreate RT_MANGLER(RTUdpServerCreate)
+# define RTUdpServerCreateEx RT_MANGLER(RTUdpServerCreateEx)
+# define RTUdpServerDestroy RT_MANGLER(RTUdpServerDestroy)
+# define RTUdpServerListen RT_MANGLER(RTUdpServerListen)
+# define RTUdpServerShutdown RT_MANGLER(RTUdpServerShutdown)
+# define RTUdpWrite RT_MANGLER(RTUdpWrite)
+# define RTUniFree RT_MANGLER(RTUniFree)
+# define RTUriAuthority RT_MANGLER(RTUriAuthority)
+# define RTUriCreate RT_MANGLER(RTUriCreate)
+# define RTUriFileCreate RT_MANGLER(RTUriFileCreate)
+# define RTUriFileNPath RT_MANGLER(RTUriFileNPath)
+# define RTUriFilePath RT_MANGLER(RTUriFilePath)
+# define RTUriFragment RT_MANGLER(RTUriFragment)
+# define RTUriHasScheme RT_MANGLER(RTUriHasScheme)
+# define RTUriPath RT_MANGLER(RTUriPath)
+# define RTUriQuery RT_MANGLER(RTUriQuery)
+# define RTUriScheme RT_MANGLER(RTUriScheme)
+# define RTUtf16CalcLatin1Len RT_MANGLER(RTUtf16CalcLatin1Len)
+# define RTUtf16CalcLatin1LenEx RT_MANGLER(RTUtf16CalcLatin1LenEx)
+# define RTUtf16CalcUtf8Len RT_MANGLER(RTUtf16CalcUtf8Len)
+# define RTUtf16CalcUtf8LenEx RT_MANGLER(RTUtf16CalcUtf8LenEx)
+# define RTUtf16Cmp RT_MANGLER(RTUtf16Cmp)
+# define RTUtf16DupExTag RT_MANGLER(RTUtf16DupExTag)
+# define RTUtf16DupTag RT_MANGLER(RTUtf16DupTag)
+# define RTUtf16Free RT_MANGLER(RTUtf16Free)
+# define RTUtf16GetCpExInternal RT_MANGLER(RTUtf16GetCpExInternal)
+# define RTUtf16GetCpInternal RT_MANGLER(RTUtf16GetCpInternal)
+# define RTUtf16ICmp RT_MANGLER(RTUtf16ICmp)
+# define RTUtf16Len RT_MANGLER(RTUtf16Len)
+# define RTUtf16LocaleICmp RT_MANGLER(RTUtf16LocaleICmp)
+# define RTUtf16PutCpInternal RT_MANGLER(RTUtf16PutCpInternal)
+# define RTUtf16ToLatin1ExTag RT_MANGLER(RTUtf16ToLatin1ExTag)
+# define RTUtf16ToLatin1Tag RT_MANGLER(RTUtf16ToLatin1Tag)
+# define RTUtf16ToLower RT_MANGLER(RTUtf16ToLower)
+# define RTUtf16ToUpper RT_MANGLER(RTUtf16ToUpper)
+# define RTUtf16PurgeComplementSet RT_MANGLER(RTUtf16PurgeComplementSet)
+# define RTUtf16ToUtf8ExTag RT_MANGLER(RTUtf16ToUtf8ExTag)
+# define RTUtf16ToUtf8Tag RT_MANGLER(RTUtf16ToUtf8Tag)
+# define RTUuidClear RT_MANGLER(RTUuidClear)
+# define RTUuidCompare RT_MANGLER(RTUuidCompare)
+# define RTUuidCompare2Strs RT_MANGLER(RTUuidCompare2Strs)
+# define RTUuidCompareStr RT_MANGLER(RTUuidCompareStr)
+# define RTUuidCreate RT_MANGLER(RTUuidCreate)
+# define RTUuidFromStr RT_MANGLER(RTUuidFromStr)
+# define RTUuidFromUtf16 RT_MANGLER(RTUuidFromUtf16)
+# define RTUuidIsNull RT_MANGLER(RTUuidIsNull)
+# define RTUuidToStr RT_MANGLER(RTUuidToStr)
+# define RTUuidToUtf16 RT_MANGLER(RTUuidToUtf16)
+# define RTVfsChainElementDeregisterProvider RT_MANGLER(RTVfsChainElementDeregisterProvider)
+# define RTVfsChainElementRegisterProvider RT_MANGLER(RTVfsChainElementRegisterProvider)
+# define RTVfsChainIsSpec RT_MANGLER(RTVfsChainIsSpec)
+# define RTVfsChainOpenFile RT_MANGLER(RTVfsChainOpenFile)
+# define RTVfsChainOpenIoStream RT_MANGLER(RTVfsChainOpenIoStream)
+# define RTVfsChainSpecFree RT_MANGLER(RTVfsChainSpecFree)
+# define RTVfsChainSpecParse RT_MANGLER(RTVfsChainSpecParse)
+# define RTVfsDirRelease RT_MANGLER(RTVfsDirRelease)
+# define RTVfsDirRetain RT_MANGLER(RTVfsDirRetain)
+# define RTVfsFileFlush RT_MANGLER(RTVfsFileFlush)
+# define RTVfsFileFromRTFile RT_MANGLER(RTVfsFileFromRTFile)
+# define RTVfsFileGetSize RT_MANGLER(RTVfsFileGetSize)
+# define RTVfsFileOpen RT_MANGLER(RTVfsFileOpen)
+# define RTVfsFilePoll RT_MANGLER(RTVfsFilePoll)
+# define RTVfsFileQueryInfo RT_MANGLER(RTVfsFileQueryInfo)
+# define RTVfsFileRead RT_MANGLER(RTVfsFileRead)
+# define RTVfsFileReadAt RT_MANGLER(RTVfsFileReadAt)
+# define RTVfsFileRelease RT_MANGLER(RTVfsFileRelease)
+# define RTVfsFileRetain RT_MANGLER(RTVfsFileRetain)
+# define RTVfsFileSeek RT_MANGLER(RTVfsFileSeek)
+# define RTVfsFileTell RT_MANGLER(RTVfsFileTell)
+# define RTVfsFileToIoStream RT_MANGLER(RTVfsFileToIoStream)
+# define RTVfsFileWrite RT_MANGLER(RTVfsFileWrite)
+# define RTVfsFileWriteAt RT_MANGLER(RTVfsFileWriteAt)
+# define RTVfsFsStrmNext RT_MANGLER(RTVfsFsStrmNext)
+# define RTVfsFsStrmQueryInfo RT_MANGLER(RTVfsFsStrmQueryInfo)
+# define RTVfsFsStrmRelease RT_MANGLER(RTVfsFsStrmRelease)
+# define RTVfsFsStrmRetain RT_MANGLER(RTVfsFsStrmRetain)
+# define RTVfsIoStreamToPrivate RT_MANGLER(RTVfsIoStreamToPrivate)
+# define RTVfsIoStrmFlush RT_MANGLER(RTVfsIoStrmFlush)
+# define RTVfsIoStrmFromRTFile RT_MANGLER(RTVfsIoStrmFromRTFile)
+# define RTVfsIoStrmFromStdHandle RT_MANGLER(RTVfsIoStrmFromStdHandle)
+# define RTVfsIoStrmIsAtEnd RT_MANGLER(RTVfsIoStrmIsAtEnd)
+# define RTVfsIoStrmPoll RT_MANGLER(RTVfsIoStrmPoll)
+# define RTVfsIoStrmQueryInfo RT_MANGLER(RTVfsIoStrmQueryInfo)
+# define RTVfsIoStrmRead RT_MANGLER(RTVfsIoStrmRead)
+# define RTVfsIoStrmReadAt RT_MANGLER(RTVfsIoStrmReadAt)
+# define RTVfsIoStrmRelease RT_MANGLER(RTVfsIoStrmRelease)
+# define RTVfsIoStrmRetain RT_MANGLER(RTVfsIoStrmRetain)
+# define RTVfsIoStrmSgRead RT_MANGLER(RTVfsIoStrmSgRead)
+# define RTVfsIoStrmSgWrite RT_MANGLER(RTVfsIoStrmSgWrite)
+# define RTVfsIoStrmSkip RT_MANGLER(RTVfsIoStrmSkip)
+# define RTVfsIoStrmTell RT_MANGLER(RTVfsIoStrmTell)
+# define RTVfsIoStrmToFile RT_MANGLER(RTVfsIoStrmToFile)
+# define RTVfsIoStrmValidateUtf8Encoding RT_MANGLER(RTVfsIoStrmValidateUtf8Encoding)
+# define RTVfsIoStrmWrite RT_MANGLER(RTVfsIoStrmWrite)
+# define RTVfsIoStrmWriteAt RT_MANGLER(RTVfsIoStrmWriteAt)
+# define RTVfsIoStrmZeroFill RT_MANGLER(RTVfsIoStrmZeroFill)
+# define RTVfsIsRangeInUse RT_MANGLER(RTVfsIsRangeInUse)
+# define RTVfsLockAcquireReadSlow RT_MANGLER(RTVfsLockAcquireReadSlow)
+# define RTVfsLockAcquireWriteSlow RT_MANGLER(RTVfsLockAcquireWriteSlow)
+# define RTVfsLockRelease RT_MANGLER(RTVfsLockRelease)
+# define RTVfsLockReleaseReadSlow RT_MANGLER(RTVfsLockReleaseReadSlow)
+# define RTVfsLockReleaseWriteSlow RT_MANGLER(RTVfsLockReleaseWriteSlow)
+# define RTVfsLockRetain RT_MANGLER(RTVfsLockRetain)
+# define RTVfsMemorizeIoStreamAsFile RT_MANGLER(RTVfsMemorizeIoStreamAsFile)
+# define RTVfsNew RT_MANGLER(RTVfsNew)
+# define RTVfsNewBaseObj RT_MANGLER(RTVfsNewBaseObj)
+# define RTVfsNewFile RT_MANGLER(RTVfsNewFile)
+# define RTVfsNewFsStream RT_MANGLER(RTVfsNewFsStream)
+# define RTVfsNewIoStream RT_MANGLER(RTVfsNewIoStream)
+# define RTVfsNewSymlink RT_MANGLER(RTVfsNewSymlink)
+# define RTVfsObjFromDir RT_MANGLER(RTVfsObjFromDir)
+# define RTVfsObjFromFile RT_MANGLER(RTVfsObjFromFile)
+# define RTVfsObjFromFsStream RT_MANGLER(RTVfsObjFromFsStream)
+# define RTVfsObjFromIoStream RT_MANGLER(RTVfsObjFromIoStream)
+# define RTVfsObjFromSymlink RT_MANGLER(RTVfsObjFromSymlink)
+# define RTVfsObjFromVfs RT_MANGLER(RTVfsObjFromVfs)
+# define RTVfsObjQueryInfo RT_MANGLER(RTVfsObjQueryInfo)
+# define RTVfsObjRelease RT_MANGLER(RTVfsObjRelease)
+# define RTVfsObjRetain RT_MANGLER(RTVfsObjRetain)
+# define RTVfsObjToDir RT_MANGLER(RTVfsObjToDir)
+# define RTVfsObjToFile RT_MANGLER(RTVfsObjToFile)
+# define RTVfsObjToFsStream RT_MANGLER(RTVfsObjToFsStream)
+# define RTVfsObjToIoStream RT_MANGLER(RTVfsObjToIoStream)
+# define RTVfsObjToSymlink RT_MANGLER(RTVfsObjToSymlink)
+# define RTVfsObjToVfs RT_MANGLER(RTVfsObjToVfs)
+# define RTVfsParsePath RT_MANGLER(RTVfsParsePath)
+# define RTVfsParsePathA RT_MANGLER(RTVfsParsePathA)
+# define RTVfsParsePathAppend RT_MANGLER(RTVfsParsePathAppend)
+# define RTVfsParsePathFree RT_MANGLER(RTVfsParsePathFree)
+# define RTVfsRelease RT_MANGLER(RTVfsRelease)
+# define RTVfsRetain RT_MANGLER(RTVfsRetain)
+# define RTVfsSymlinkQueryInfo RT_MANGLER(RTVfsSymlinkQueryInfo)
+# define RTVfsSymlinkRead RT_MANGLER(RTVfsSymlinkRead)
+# define RTVfsSymlinkRelease RT_MANGLER(RTVfsSymlinkRelease)
+# define RTVfsSymlinkRetain RT_MANGLER(RTVfsSymlinkRetain)
+# define RTVfsSymlinkSetMode RT_MANGLER(RTVfsSymlinkSetMode)
+# define RTVfsSymlinkSetOwner RT_MANGLER(RTVfsSymlinkSetOwner)
+# define RTVfsSymlinkSetTimes RT_MANGLER(RTVfsSymlinkSetTimes)
+# define RTVfsUtilDummyPollOne RT_MANGLER(RTVfsUtilDummyPollOne)
+# define RTVfsUtilPumpIoStreams RT_MANGLER(RTVfsUtilPumpIoStreams)
+# define RTZipBlockCompress RT_MANGLER(RTZipBlockCompress)
+# define RTZipBlockDecompress RT_MANGLER(RTZipBlockDecompress)
+# define RTZipCompCreate RT_MANGLER(RTZipCompCreate)
+# define RTZipCompDestroy RT_MANGLER(RTZipCompDestroy)
+# define RTZipCompFinish RT_MANGLER(RTZipCompFinish)
+# define RTZipCompress RT_MANGLER(RTZipCompress)
+# define RTZipDecompCreate RT_MANGLER(RTZipDecompCreate)
+# define RTZipDecompDestroy RT_MANGLER(RTZipDecompDestroy)
+# define RTZipDecompress RT_MANGLER(RTZipDecompress)
+# define RTZipGzipDecompressIoStream RT_MANGLER(RTZipGzipDecompressIoStream)
+# define RTZipTarCmd RT_MANGLER(RTZipTarCmd)
+# define RTZipTarFsStreamFromIoStream RT_MANGLER(RTZipTarFsStreamFromIoStream)
+
+/*
+ * Stable variables (alphabetical order):
+ */
+# define g_apfnRTZlibDeps RT_MANGLER(g_apfnRTZlibDeps) /* os2 win solaris */
+# define g_aRTUniFlagsRanges RT_MANGLER(g_aRTUniFlagsRanges)
+# define g_aRTUniLowerRanges RT_MANGLER(g_aRTUniLowerRanges)
+# define g_aRTUniUpperRanges RT_MANGLER(g_aRTUniUpperRanges)
+# define g_fRTAlignmentChecks RT_MANGLER(g_fRTAlignmentChecks)
+# define g_hKrnlDbgInfo RT_MANGLER(g_hKrnlDbgInfo) /* solaris */
+# define g_pStdErr RT_MANGLER(g_pStdErr)
+# define g_pStdIn RT_MANGLER(g_pStdIn)
+# define g_pStdOut RT_MANGLER(g_pStdOut)
+# define g_pszRTAssertExpr RT_MANGLER(g_pszRTAssertExpr)
+# define g_pszRTAssertFile RT_MANGLER(g_pszRTAssertFile)
+# define g_pszRTAssertFunction RT_MANGLER(g_pszRTAssertFunction)
+# define g_szRTAssertMsg1 RT_MANGLER(g_szRTAssertMsg1)
+# define g_szRTAssertMsg2 RT_MANGLER(g_szRTAssertMsg2)
+# define g_u32RTAssertLine RT_MANGLER(g_u32RTAssertLine)
+
+
+
+/*
+ * Unstable functions (alphabetical order):
+ */
+/** @todo the list is incomplete! See the .def files + libraries. */
+
+
+/*
+ * Unstable variables (alphabetical order):
+ */
+/* none */
+
+#endif /* !DOXYGEN_RUNNING */
+
+#endif
+
diff --git a/include/iprt/manifest.h b/include/iprt/manifest.h
new file mode 100644
index 00000000..f7092b2a
--- /dev/null
+++ b/include/iprt/manifest.h
@@ -0,0 +1,523 @@
+/** @file
+ * IPRT - Manifest file handling.
+ */
+
+/*
+ * 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 ___iprt_manifest_h
+#define ___iprt_manifest_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_manifest RTManifest - Manifest file creation and checking
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @name Manifest attribute types.
+ * The types can be ORed together to form a set.
+ * @{ */
+/** For use with other attributes. Representation unknown. */
+#define RTMANIFEST_ATTR_UNKNOWN 0
+/** The size of the content. Represented as a decimal number. */
+#define RTMANIFEST_ATTR_SIZE RT_BIT_32(0)
+/** The MD5 of the content. Represented as a hex string. */
+#define RTMANIFEST_ATTR_MD5 RT_BIT_32(1)
+/** The SHA-1 of the content. Represented as a hex string. */
+#define RTMANIFEST_ATTR_SHA1 RT_BIT_32(2)
+/** The SHA-256 of the content. Represented as a hex string. */
+#define RTMANIFEST_ATTR_SHA256 RT_BIT_32(3)
+/** The SHA-512 of the content. Represented as a hex string. */
+#define RTMANIFEST_ATTR_SHA512 RT_BIT_32(4)
+/** The end of the valid values. */
+#define RTMANIFEST_ATTR_END RT_BIT_32(5)
+/** Wildcard for use in queries. */
+#define RTMANIFEST_ATTR_ANY UINT32_C(0xffffffff)
+/** @} */
+
+/** @name Digest types. */
+typedef enum RTDIGESTTYPE
+{
+ /** CRC32 checksum */
+ RTDIGESTTYPE_CRC32 = 1,
+ /** CRC64 checksum */
+ RTDIGESTTYPE_CRC64,
+ /** MD5 checksum (unsafe!) */
+ RTDIGESTTYPE_MD5,
+ /** SHA1 checksum (unsafe!) */
+ RTDIGESTTYPE_SHA1,
+ /** SHA256 checksum */
+ RTDIGESTTYPE_SHA256,
+ /** SHA512 checksum */
+ RTDIGESTTYPE_SHA512
+} RTDIGESTTYPE;
+/** @} */
+
+
+/**
+ * Creates an empty manifest.
+ *
+ * @returns IPRT status code.
+ * @param fFlags Flags, MBZ.
+ * @param phManifest Where to return the handle to the manifest.
+ */
+RTDECL(int) RTManifestCreate(uint32_t fFlags, PRTMANIFEST phManifest);
+
+/**
+ * Retains a reference to the manifest handle.
+ *
+ * @returns The new reference count, UINT32_MAX if the handle is invalid.
+ * @param hManifest The handle to retain.
+ */
+RTDECL(uint32_t) RTManifestRetain(RTMANIFEST hManifest);
+
+/**
+ * Releases a reference to the manifest handle.
+ *
+ * @returns The new reference count, 0 if free. UINT32_MAX is returned if the
+ * handle is invalid.
+ * @param hManifest The handle to release.
+ * NIL is quietly ignored (returns 0).
+ */
+RTDECL(uint32_t) RTManifestRelease(RTMANIFEST hManifest);
+
+/**
+ * Creates a duplicate of the specified manifest.
+ *
+ * @returns IPRT status code
+ * @param hManifestSrc The manifest to clone.
+ * @param phManifestDst Where to store the handle to the duplicate.
+ */
+RTDECL(int) RTManifestDup(RTMANIFEST hManifestSrc, PRTMANIFEST phManifestDst);
+
+/**
+ * Compares two manifests for equality.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if equal.
+ * @retval VERR_NOT_EQUAL if not equal.
+ *
+ * @param hManifest1 The first manifest.
+ * @param hManifest2 The second manifest.
+ * @param papszIgnoreEntries Entries to ignore. Ends with a NULL entry.
+ * @param papszIgnoreAttrs Attributes to ignore. Ends with a NULL entry.
+ * @param fFlags A combination of RTMANIFEST_EQUALS_XXX values.
+ * @param pszError Where to store the name of the mismatching
+ * entry, or as much of the name as there is room
+ * for. This is always set. Optional.
+ * @param cbError The size of the buffer pointed to by @a
+ * pszError.
+ */
+RTDECL(int) RTManifestEqualsEx(RTMANIFEST hManifest1, RTMANIFEST hManifest2, const char * const *papszIgnoreEntries,
+ const char * const *papszIgnoreAttr, uint32_t fFlags, char *pszError, size_t cbError);
+
+/** @defgroup RTMANIFEST_EQUALS_XXX RTManifestEqualsEx flags
+ * @{ */
+/** Ignore missing attributes if there is one or more to compare. */
+#define RTMANIFEST_EQUALS_IGN_MISSING_ATTRS RT_BIT_32(0)
+/** Ignore attributes missing in the 1st manifest.
+ * @todo implement this */
+#define RTMANIFEST_EQUALS_IGN_MISSING_ATTRS_1ST RT_BIT_32(1)
+/** Mask of valid flags. */
+#define RTMANIFEST_EQUALS_VALID_MASK UINT32_C(0x00000003)
+/** @} */
+
+/**
+ * Compares two manifests for equality.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if equal.
+ * @retval VERR_NOT_EQUAL if not equal.
+ *
+ * @param hManifest1 The first manifest.
+ * @param hManifest2 The second manifest.
+ */
+RTDECL(int) RTManifestEquals(RTMANIFEST hManifest1, RTMANIFEST hManifest2);
+
+/**
+ * Sets a manifest attribute.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The manifest handle.
+ * @param pszAttr The attribute name. If this already exists,
+ * its value will be replaced.
+ * @param pszValue The value string.
+ * @param fType The attribute type, pass
+ * RTMANIFEST_ATTR_UNKNOWN if not known.
+ */
+RTDECL(int) RTManifestSetAttr(RTMANIFEST hManifest, const char *pszAttr, const char *pszValue, uint32_t fType);
+
+/**
+ * Unsets (removes) a manifest attribute if it exists.
+ *
+ * @returns IPRT status code.
+ * @retval VWRN_NOT_FOUND if not found.
+ *
+ * @param hManifest The manifest handle.
+ * @param pszAttr The attribute name.
+ */
+RTDECL(int) RTManifestUnsetAttr(RTMANIFEST hManifest, const char *pszAttr);
+
+/**
+ * Query a manifest entry attribute.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_BUFFER_OVERFLOW if the value buffer is too small. The @a
+ * pszValue buffer will not be modified.
+ * @retval VERR_MANIFEST_ATTR_NOT_FOUND
+ * @retval VERR_MANIFEST_ATTR_TYPE_NOT_FOUND
+ * @retval VERR_MANIFEST_ATTR_TYPE_MISMATCH
+ *
+ * @param hManifest The manifest handle.
+ * @param pszEntry The entry name.
+ * @param pszAttr The attribute name. If NULL, it will be
+ * selected by @a fType alone.
+ * @param fType The attribute types the entry should match. Pass
+ * Pass RTMANIFEST_ATTR_ANY match any. If more
+ * than one is given, the first matching one is
+ * returned.
+ * @param pszValue Where to return value.
+ * @param cbValue The size of the buffer @a pszValue points to.
+ * @param pfType Where to return the attribute type value.
+ */
+RTDECL(int) RTManifestQueryAttr(RTMANIFEST hManifest, const char *pszAttr, uint32_t fType,
+ char *pszValue, size_t cbValue, uint32_t *pfType);
+
+/**
+ * Sets an attribute of a manifest entry.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The manifest handle.
+ * @param pszEntry The entry name. This will automatically be
+ * added if there was no previous call to
+ * RTManifestEntryAdd for this name. See
+ * RTManifestEntryAdd for the entry name rules.
+ * @param pszAttr The attribute name. If this already exists,
+ * its value will be replaced.
+ * @param pszValue The value string.
+ * @param fType The attribute type, pass
+ * RTMANIFEST_ATTR_UNKNOWN if not known.
+ */
+RTDECL(int) RTManifestEntrySetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr,
+ const char *pszValue, uint32_t fType);
+
+/**
+ * Unsets (removes) an attribute of a manifest entry if they both exist.
+ *
+ * @returns IPRT status code.
+ * @retval VWRN_NOT_FOUND if not found.
+ *
+ * @param hManifest The manifest handle.
+ * @param pszEntry The entry name.
+ * @param pszAttr The attribute name.
+ */
+RTDECL(int) RTManifestEntryUnsetAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr);
+
+/**
+ * Query a manifest entry attribute.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_BUFFER_OVERFLOW if the value buffer is too small. The @a
+ * pszValue buffer will not be modified.
+ * @retval VERR_NOT_FOUND if the entry was not found.
+ * @retval VERR_MANIFEST_ATTR_NOT_FOUND
+ * @retval VERR_MANIFEST_ATTR_TYPE_NOT_FOUND
+ * @retval VERR_MANIFEST_ATTR_TYPE_MISMATCH
+ *
+ * @param hManifest The manifest handle.
+ * @param pszEntry The entry name.
+ * @param pszAttr The attribute name. If NULL, it will be
+ * selected by @a fType alone.
+ * @param fType The attribute types the entry should match. Pass
+ * Pass RTMANIFEST_ATTR_ANY match any. If more
+ * than one is given, the first matching one is
+ * returned.
+ * @param pszValue Where to return value.
+ * @param cbValue The size of the buffer @a pszValue points to.
+ * @param pfType Where to return the attribute type value.
+ */
+RTDECL(int) RTManifestEntryQueryAttr(RTMANIFEST hManifest, const char *pszEntry, const char *pszAttr, uint32_t fType,
+ char *pszValue, size_t cbValue, uint32_t *pfType);
+
+/**
+ * Adds a new entry to a manifest.
+ *
+ * The entry name rules:
+ * - The entry name can contain any character defined by unicode, except
+ * control characters, ':', '(' and ')'. The exceptions are mainly there
+ * because of uncertainty around how various formats handles these.
+ * - It is considered case sensitive.
+ * - Forward (unix) and backward (dos) slashes are considered path
+ * separators and converted to forward slashes.
+ *
+ * @returns IPRT status code.
+ * @retval VWRN_ALREADY_EXISTS if the entry already exists.
+ *
+ * @param hManifest The manifest handle.
+ * @param pszEntry The entry name (UTF-8).
+ *
+ * @remarks Some manifest formats will not be able to store an entry without
+ * any attributes. So, this is just here in case it comes in handy
+ * when dealing with formats which can.
+ */
+RTDECL(int) RTManifestEntryAdd(RTMANIFEST hManifest, const char *pszEntry);
+
+/**
+ * Removes an entry.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The manifest handle.
+ * @param pszEntry The entry name.
+ */
+RTDECL(int) RTManifestEntryRemove(RTMANIFEST hManifest, const char *pszEntry);
+
+/**
+ * Add an entry for an I/O stream using a passthru stream.
+ *
+ * The passthru I/O stream will hash all the data read from or written to the
+ * stream and automatically add an entry to the manifest with the desired
+ * attributes when it is released. Alternatively one can call
+ * RTManifestPtIosAddEntryNow() to have more control over exactly when this
+ * action is performed and which status it yields.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The manifest to add the entry to.
+ * @param hVfsIos The I/O stream to pass thru to/from.
+ * @param pszEntry The entry name.
+ * @param fAttrs The attributes to create for this stream.
+ * @param fReadOrWrite Whether it's a read or write I/O stream.
+ * @param phVfsIosPassthru Where to return the new handle.
+ */
+RTDECL(int) RTManifestEntryAddPassthruIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry,
+ uint32_t fAttrs, bool fReadOrWrite, PRTVFSIOSTREAM phVfsIosPassthru);
+
+/**
+ * Adds the entry to the manifest right now.
+ *
+ * @returns IPRT status code.
+ * @param hVfsPtIos The manifest passthru I/O stream returned by
+ * RTManifestEntryAddPassthruIoStream().
+ */
+RTDECL(int) RTManifestPtIosAddEntryNow(RTVFSIOSTREAM hVfsPtIos);
+
+/**
+ * Adds an entry for a file with the specified set of attributes.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hManifest The manifest handle.
+ * @param hVfsIos The I/O stream handle of the entry. This will
+ * be processed to its end on successful return.
+ * (Must be positioned at the start to get
+ * the expected results.)
+ * @param pszEntry The entry name.
+ * @param fAttrs The attributes to create for this stream. See
+ * RTMANIFEST_ATTR_XXX.
+ */
+RTDECL(int) RTManifestEntryAddIoStream(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, const char *pszEntry, uint32_t fAttrs);
+
+/**
+ * Checks if there is a manifest entry by the given name.
+ *
+ * @returns true if there is, false if not or if the handle is invalid.
+ * @param hManifest The manifest handle.
+ * @param pszEntry The entry name.
+ */
+RTDECL(bool) RTManifestEntryExists(RTMANIFEST hManifest, const char *pszEntry);
+
+/**
+ * Reads in a "standard" manifest.
+ *
+ * This reads the format used by OVF, the distinfo in FreeBSD ports, and
+ * others.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The handle to the manifest where to add the
+ * manifest that's read in.
+ * @param hVfsIos The I/O stream to read the manifest from.
+ */
+RTDECL(int) RTManifestReadStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Reads in a "standard" manifest.
+ *
+ * This reads the format used by OVF, the distinfo in FreeBSD ports, and
+ * others.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The handle to the manifest where to add the
+ * manifest that's read in.
+ * @param hVfsIos The I/O stream to read the manifest from.
+ * @param pszErr Where to return extended error info on failure.
+ * Optional.
+ * @param cbErr The size of the buffer @a pszErr points to.
+ */
+RTDECL(int) RTManifestReadStandardEx(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos, char *pszErr, size_t cbErr);
+
+/**
+ * Reads in a "standard" manifest from the specified file.
+ *
+ * This reads the format used by OVF, the distinfo in FreeBSD ports, and
+ * others.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The handle to the manifest where to add the
+ * manifest that's read in.
+ * @param pszFilename The name of the file to read in.
+ */
+RTDECL(int) RTManifestReadStandardFromFile(RTMANIFEST hManifest, const char *pszFilename);
+
+/**
+ * Writes a "standard" manifest.
+ *
+ * This writes the format used by OVF, the distinfo in FreeBSD ports, and
+ * others.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The handle to the manifest to write.
+ * @param hVfsIos The I/O stream to read the manifest from.
+ */
+RTDECL(int) RTManifestWriteStandard(RTMANIFEST hManifest, RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Writes a "standard" manifest to the specified file.
+ *
+ * @returns IPRT status code.
+ * @param hManifest The handle to the manifest to write.
+ * @param pszFilename The name of the file.
+ */
+RTDECL(int) RTManifestWriteStandardToFile(RTMANIFEST hManifest, const char *pszFilename);
+
+
+
+
+
+/**
+ * Input structure for RTManifestVerify() which contains the filename & the
+ * SHA1/SHA256 digest.
+ */
+typedef struct RTMANIFESTTEST
+{
+ /** The filename. */
+ const char *pszTestFile;
+ /** The SHA1/SHA256 digest of the file. */
+ const char *pszTestDigest;
+} RTMANIFESTTEST;
+/** Pointer to the input structure. */
+typedef RTMANIFESTTEST* PRTMANIFESTTEST;
+
+
+/**
+ * Verify the given SHA1 digests against the entries in the manifest file.
+ *
+ * Please note that not only the various digest have to match, but the
+ * filenames as well. If there are more or even less files listed in the
+ * manifest file than provided by paTests, VERR_MANIFEST_FILE_MISMATCH will be
+ * returned.
+ *
+ * @returns iprt status code.
+ *
+ * @param pszManifestFile Filename of the manifest file to verify.
+ * @param paTests Array of files & SHA1 sums.
+ * @param cTests Number of entries in paTests.
+ * @param piFailed A index to paTests in the
+ * VERR_MANIFEST_DIGEST_MISMATCH error case
+ * (optional).
+ */
+RTR3DECL(int) RTManifestVerify(const char *pszManifestFile, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed);
+
+/**
+ * This is analogous to function RTManifestVerify(), but calculates the SHA1
+ * sums of the given files itself.
+ *
+ * @returns iprt status code.
+ *
+ * @param pszManifestFile Filename of the manifest file to verify.
+ * @param papszFiles Array of files to check SHA1 sums.
+ * @param cFiles Number of entries in papszFiles.
+ * @param piFailed A index to papszFiles in the
+ * VERR_MANIFEST_DIGEST_MISMATCH error case
+ * (optional).
+ * @param pfnProgressCallback optional callback for the progress indication
+ * @param pvUser user defined pointer for the callback
+ */
+RTR3DECL(int) RTManifestVerifyFiles(const char *pszManifestFile, const char * const *papszFiles, size_t cFiles, size_t *piFailed,
+ PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+/**
+ * Creates a manifest file for a set of files. The manifest file contains SHA1
+ * sums of every provided file and could be used to verify the data integrity
+ * of them.
+ *
+ * @returns iprt status code.
+ *
+ * @param pszManifestFile Filename of the manifest file to create.
+ * @param enmDigestType The digest type (RTDIGESTTYPE_*)
+ * @param papszFiles Array of files to create SHA1 sums for.
+ * @param cFiles Number of entries in papszFiles.
+ * @param pfnProgressCallback optional callback for the progress indication
+ * @param pvUser user defined pointer for the callback
+ */
+RTR3DECL(int) RTManifestWriteFiles(const char *pszManifestFile, RTDIGESTTYPE enmDigestType,
+ const char * const *papszFiles, size_t cFiles,
+ PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+/**
+ * Verify the given SHA1 digests against the entries in the manifest file in
+ * memory.
+ *
+ * @returns iprt status code.
+ *
+ * @param pvBuf Pointer to memory buffer of the manifest file.
+ * @param cbSize Size of the memory buffer.
+ * @param paTests Array of file names and digests.
+ * @param cTest Number of entries in paTests.
+ * @param piFailed A index to paTests in the
+ * VERR_MANIFEST_DIGEST_MISMATCH error case
+ * (optional).
+ */
+RTR3DECL(int) RTManifestVerifyFilesBuf(void *pvBuf, size_t cbSize, PRTMANIFESTTEST paTests, size_t cTests, size_t *piFailed);
+
+/**
+ * Creates a manifest file in memory for a set of files. The manifest file
+ * contains SHA1 sums of every provided file and could be used to verify the
+ * data integrity of them.
+ *
+ * @returns iprt status code.
+ *
+ * @param ppvBuf Pointer to resulting memory buffer.
+ * @param pcbSize Pointer for the size of the memory buffer.
+ * @param enmDigestType Which type of digest ("SHA1", "SHA256", ...)
+ * @param paFiles Array of file names and digests.
+ * @param cFiles Number of entries in paFiles.
+ */
+RTR3DECL(int) RTManifestWriteFilesBuf(void **ppvBuf, size_t *pcbSize, RTDIGESTTYPE enmDigestType, PRTMANIFESTTEST paFiles, size_t cFiles);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/md5.h b/include/iprt/md5.h
new file mode 100644
index 00000000..e085abb6
--- /dev/null
+++ b/include/iprt/md5.h
@@ -0,0 +1,126 @@
+/** @file
+ * IPRT - Message-Digest algorithm 5.
+ */
+
+/*
+ * 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 ___iprt_md5_h
+#define ___iprt_md5_h
+
+#include <iprt/types.h>
+
+/** @defgroup grp_rt_md5 RTMd5 - Message-Digest algorithm 5
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Size of a MD5 hash. */
+#define RTMD5_HASH_SIZE 16
+/** @deprecated Use RTMD5_HASH_SIZE. */
+#define RTMD5HASHSIZE RTMD5_HASH_SIZE
+/** The length of a MD5 digest string. The terminator is not included. */
+#define RTMD5_DIGEST_LEN 32
+/** Size of a MD5 hash.
+ * @deprecated Use RTMD5_DIGEST_LEN */
+#define RTMD5_STRING_LEN RTMD5_DIGEST_LEN
+
+/**
+ * MD5 hash algorithm context.
+ */
+typedef struct RTMD5CONTEXT
+{
+ uint32_t in[16];
+ uint32_t buf[4];
+ uint32_t bits[2];
+} RTMD5CONTEXT;
+
+/** Pointer to MD5 hash algorithm context. */
+typedef RTMD5CONTEXT *PRTMD5CONTEXT;
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Compute the MD5 hash of the data.
+ *
+ * @param pvBuf Pointer to data.
+ * @param cbBuf Length of data (in bytes).
+ * @param pabDigest Where to store the hash.
+ * (What's passed is a pointer to the caller's buffer.)
+ */
+RTDECL(void) RTMd5(const void *pvBuf, size_t cbBuf, uint8_t pabDigest[RTMD5HASHSIZE]);
+
+/**
+ * Initialize MD5 context.
+ *
+ * @param pCtx Pointer to the MD5 context to initialize.
+ */
+RTDECL(void) RTMd5Init(PRTMD5CONTEXT pCtx);
+
+/**
+ * Feed data into the MD5 computation.
+ *
+ * @param pCtx Pointer to the MD5 context.
+ * @param pvBuf Pointer to data.
+ * @param cbBuf Length of data (in bytes).
+ */
+RTDECL(void) RTMd5Update(PRTMD5CONTEXT pCtx, const void *pvBuf, size_t cbBuf);
+
+/**
+ * Compute the MD5 hash of the data.
+ *
+ * @param pabDigest Where to store the hash.
+ * (What's passed is a pointer to the caller's buffer.)
+ * @param pCtx Pointer to the MD5 context.
+ */
+RTDECL(void) RTMd5Final(uint8_t pabDigest[RTMD5HASHSIZE], PRTMD5CONTEXT pCtx);
+
+/**
+ * Converts a MD5 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pabDigest The binary digest returned by RTMd5Final or RTMd5.
+ * @param pszDigest Where to return the stringified digest.
+ * @param cchDigest The size of the output buffer. Should be at least
+ * RTMD5_STRING_LEN + 1 bytes.
+ */
+RTDECL(int) RTMd5ToString(uint8_t const pabDigest[RTMD5_HASH_SIZE], char *pszDigest, size_t cchDigest);
+
+/**
+ * Converts a MD5 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszDigest The stringified digest. Leading and trailing spaces are
+ * ignored.
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(int) RTMd5FromString(char const *pszDigest, uint8_t pabDigest[RTMD5_HASH_SIZE]);
+
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/mem.h b/include/iprt/mem.h
new file mode 100644
index 00000000..883de0fe
--- /dev/null
+++ b/include/iprt/mem.h
@@ -0,0 +1,924 @@
+/** @file
+ * IPRT - Memory Management and Manipulation.
+ */
+
+/*
+ * 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 ___iprt_mem_h
+#define ___iprt_mem_h
+
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+#ifdef IN_RC
+# error "There are no RTMem APIs available Guest Context!"
+#endif
+
+
+/** @defgroup grp_rt_mem RTMem - Memory Management and Manipulation
+ * @ingroup grp_rt
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/** @def RTMEM_ALIGNMENT
+ * The alignment of the memory blocks returned by RTMemAlloc(), RTMemAllocZ(),
+ * RTMemRealloc(), RTMemTmpAlloc() and RTMemTmpAllocZ() for allocations greater
+ * than RTMEM_ALIGNMENT.
+ *
+ * @note This alignment is not forced if the electric fence is active!
+ */
+#if defined(RT_OS_OS2)
+# define RTMEM_ALIGNMENT 4
+#else
+# define RTMEM_ALIGNMENT 8
+#endif
+
+/** @def RTMEM_TAG
+ * The default allocation tag used by the RTMem allocation APIs.
+ *
+ * When not defined before the inclusion of iprt/mem.h or iprt/memobj.h, this
+ * will default to the pointer to the current file name. The memory API will
+ * make of use of this as pointer to a volatile but read-only string.
+ * The alternative tag includes the line number for a more-detailed analysis.
+ */
+#ifndef RTMEM_TAG
+# if 0
+# define RTMEM_TAG (__FILE__ ":" RT_XSTR(__LINE__))
+# else
+# define RTMEM_TAG (__FILE__)
+# endif
+#endif
+
+
+/** @name Allocate temporary memory.
+ * @{ */
+/**
+ * Allocates temporary memory with default tag.
+ *
+ * Temporary memory blocks are used for not too large memory blocks which
+ * are believed not to stick around for too long. Using this API instead
+ * of RTMemAlloc() not only gives the heap manager room for optimization
+ * but makes the code easier to read.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param cb Size in bytes of the memory block to allocated.
+ */
+#define RTMemTmpAlloc(cb) RTMemTmpAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates temporary memory with custom tag.
+ *
+ * Temporary memory blocks are used for not too large memory blocks which
+ * are believed not to stick around for too long. Using this API instead
+ * of RTMemAlloc() not only gives the heap manager room for optimization
+ * but makes the code easier to read.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param cb Size in bytes of the memory block to allocated.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemTmpAllocTag(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Allocates zero'd temporary memory with default tag.
+ *
+ * Same as RTMemTmpAlloc() but the memory will be zero'd.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param cb Size in bytes of the memory block to allocated.
+ */
+#define RTMemTmpAllocZ(cb) RTMemTmpAllocZTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates zero'd temporary memory with custom tag.
+ *
+ * Same as RTMemTmpAlloc() but the memory will be zero'd.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param cb Size in bytes of the memory block to allocated.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemTmpAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Free temporary memory.
+ *
+ * @param pv Pointer to memory block.
+ */
+RTDECL(void) RTMemTmpFree(void *pv) RT_NO_THROW;
+
+/** @} */
+
+
+/**
+ * Allocates memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param cb Size in bytes of the memory block to allocated.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+#define RTMemAlloc(cb) RTMemAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure, assertion raised in strict builds.
+ * @param cb Size in bytes of the memory block to allocated.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemAllocTag(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Allocates zero'd memory with default tag.
+ *
+ * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
+ * memory. This keeps the code smaller and the heap can skip the memset
+ * in about 0.42% of calls :-).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocated.
+ */
+#define RTMemAllocZ(cb) RTMemAllocZTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates zero'd memory with custom tag.
+ *
+ * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
+ * memory. This keeps the code smaller and the heap can skip the memset
+ * in about 0.42% of calls :-).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocated.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Wrapper around RTMemAlloc for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAlloc.
+ * @param cbUnaligned The unaligned size.
+ */
+#define RTMemAllocVar(cbUnaligned) RTMemAllocVarTag((cbUnaligned), RTMEM_TAG)
+
+/**
+ * Wrapper around RTMemAllocTag for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAlloc.
+ * @param cbUnaligned The unaligned size.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemAllocVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Wrapper around RTMemAllocZ for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAllocZ.
+ * @param cbUnaligned The unaligned size.
+ */
+#define RTMemAllocZVar(cbUnaligned) RTMemAllocZVarTag((cbUnaligned), RTMEM_TAG)
+
+/**
+ * Wrapper around RTMemAllocZTag for automatically aligning variable sized
+ * allocations so that the various electric fence heaps works correctly.
+ *
+ * @returns See RTMemAllocZ.
+ * @param cbUnaligned The unaligned size.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemAllocZVarTag(size_t cbUnaligned, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Duplicates a chunk of memory into a new heap block (default tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param pvSrc The memory to duplicate.
+ * @param cb The amount of memory to duplicate.
+ */
+#define RTMemDup(pvSrc, cb) RTMemDupTag((pvSrc), (cb), RTMEM_TAG)
+
+/**
+ * Duplicates a chunk of memory into a new heap block (custom tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param pvSrc The memory to duplicate.
+ * @param cb The amount of memory to duplicate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemDupTag(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Duplicates a chunk of memory into a new heap block with some additional
+ * zeroed memory (default tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param pvSrc The memory to duplicate.
+ * @param cbSrc The amount of memory to duplicate.
+ * @param cbExtra The amount of extra memory to allocate and zero.
+ */
+#define RTMemDupEx(pvSrc, cbSrc, cbExtra) RTMemDupExTag((pvSrc), (cbSrc), (cbExtra), RTMEM_TAG)
+
+/**
+ * Duplicates a chunk of memory into a new heap block with some additional
+ * zeroed memory (default tag).
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param pvSrc The memory to duplicate.
+ * @param cbSrc The amount of memory to duplicate.
+ * @param cbExtra The amount of extra memory to allocate and zero.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemDupExTag(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Reallocates memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param pvOld The memory block to reallocate.
+ * @param cbNew The new block size (in bytes).
+ */
+#define RTMemRealloc(pvOld, cbNew) RTMemReallocTag((pvOld), (cbNew), RTMEM_TAG)
+
+/**
+ * Reallocates memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param pvOld The memory block to reallocate.
+ * @param cbNew The new block size (in bytes).
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemReallocTag(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Frees memory.
+ *
+ * @param pv Pointer to memory block.
+ */
+RTDECL(void) RTMemFree(void *pv) RT_NO_THROW;
+
+
+
+/** @def RTR0MemAllocEx and RTR0MemAllocExTag flags.
+ * @{ */
+/** The returned memory should be zeroed. */
+#define RTMEMALLOCEX_FLAGS_ZEROED RT_BIT(0)
+/** It must be load code into the returned memory block and execute it. */
+#define RTMEMALLOCEX_FLAGS_EXEC RT_BIT(1)
+/** Allocation from any context.
+ * Will return VERR_NOT_SUPPORTED if not supported. */
+#define RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC RT_BIT(2)
+/** Allocate the memory such that it can be freed from any context.
+ * Will return VERR_NOT_SUPPORTED if not supported. */
+#define RTMEMALLOCEX_FLAGS_ANY_CTX_FREE RT_BIT(3)
+/** Allocate and free from any context.
+ * Will return VERR_NOT_SUPPORTED if not supported. */
+#define RTMEMALLOCEX_FLAGS_ANY_CTX (RTMEMALLOCEX_FLAGS_ANY_CTX_ALLOC | RTMEMALLOCEX_FLAGS_ANY_CTX_FREE)
+/** Mask of valid flags. */
+#define RTMEMALLOCEX_FLAGS_VALID_MASK UINT32_C(0x0000000f)
+/** @} */
+
+/**
+ * Extended heap allocation API, default tag.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NO_MEMORY if we're out of memory.
+ * @retval VERR_NO_EXEC_MEMORY if we're out of executable memory.
+ * @retval VERR_NOT_SUPPORTED if any of the specified flags are unsupported.
+ *
+ * @param cb The amount of memory to allocate.
+ * @param cbAlignment The alignment requirements. Use 0 to indicate
+ * default alignment.
+ * @param fFlags A combination of the RTMEMALLOCEX_FLAGS_XXX
+ * defines.
+ * @param ppv Where to return the memory.
+ */
+#define RTMemAllocEx(cb, cbAlignment, fFlags, ppv) RTMemAllocExTag((cb), (cbAlignment), (fFlags), RTMEM_TAG, (ppv))
+
+/**
+ * Extended heap allocation API, custom tag.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NO_MEMORY if we're out of memory.
+ * @retval VERR_NO_EXEC_MEMORY if we're out of executable memory.
+ * @retval VERR_NOT_SUPPORTED if any of the specified flags are unsupported.
+ *
+ * @param cb The amount of memory to allocate.
+ * @param cbAlignment The alignment requirements. Use 0 to indicate
+ * default alignment.
+ * @param fFlags A combination of the RTMEMALLOCEX_FLAGS_XXX
+ * defines.
+ * @param pszTag The tag.
+ * @param ppv Where to return the memory.
+ */
+RTDECL(int) RTMemAllocExTag(size_t cb, size_t cbAlignment, uint32_t fFlags, const char *pszTag, void **ppv) RT_NO_THROW;
+
+/**
+ * For freeing memory allocated by RTMemAllocEx or RTMemAllocExTag.
+ *
+ * @param pv What to free, NULL is fine.
+ * @param cb The amount of allocated memory.
+ */
+RTDECL(void) RTMemFreeEx(void *pv, size_t cb) RT_NO_THROW;
+
+
+
+/**
+ * Allocates memory which may contain code (default tag).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocate.
+ */
+#define RTMemExecAlloc(cb) RTMemExecAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocates memory which may contain code (custom tag).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemExecAllocTag(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Free executable/read/write memory allocated by RTMemExecAlloc().
+ *
+ * @param pv Pointer to memory block.
+ * @param cb The allocation size.
+ */
+RTDECL(void) RTMemExecFree(void *pv, size_t cb) RT_NO_THROW;
+
+#if defined(IN_RING0) && defined(RT_ARCH_AMD64) && defined(RT_OS_LINUX)
+/**
+ * Donate read+write+execute memory to the exec heap.
+ *
+ * This API is specific to AMD64 and Linux/GNU. A kernel module that desires to
+ * use RTMemExecAlloc on AMD64 Linux/GNU will have to donate some statically
+ * allocated memory in the module if it wishes for GCC generated code to work.
+ * GCC can only generate modules that work in the address range ~2GB to ~0
+ * currently.
+ *
+ * The API only accept one single donation.
+ *
+ * @returns IPRT status code.
+ * @param pvMemory Pointer to the memory block.
+ * @param cb The size of the memory block.
+ */
+RTR0DECL(int) RTR0MemExecDonate(void *pvMemory, size_t cb) RT_NO_THROW;
+#endif /* R0+AMD64+LINUX */
+
+/**
+ * Allocate page aligned memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param cb Size of the memory block. Will be rounded up to page size.
+ */
+#define RTMemPageAlloc(cb) RTMemPageAllocTag((cb), RTMEM_TAG)
+
+/**
+ * Allocate page aligned memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param cb Size of the memory block. Will be rounded up to page size.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemPageAllocTag(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Allocate zero'd page aligned memory with default tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param cb Size of the memory block. Will be rounded up to page size.
+ */
+#define RTMemPageAllocZ(cb) RTMemPageAllocZTag((cb), RTMEM_TAG)
+
+/**
+ * Allocate zero'd page aligned memory with custom tag.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL if we're out of memory.
+ * @param cb Size of the memory block. Will be rounded up to page size.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemPageAllocZTag(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Free a memory block allocated with RTMemPageAlloc() or RTMemPageAllocZ().
+ *
+ * @param pv Pointer to the block as it was returned by the allocation function.
+ * NULL will be ignored.
+ * @param cb The allocation size. Will be rounded up to page size.
+ * Ignored if @a pv is NULL.
+ */
+RTDECL(void) RTMemPageFree(void *pv, size_t cb) RT_NO_THROW;
+
+/** Page level protection flags for RTMemProtect().
+ * @{
+ */
+/** No access at all. */
+#define RTMEM_PROT_NONE 0
+/** Read access. */
+#define RTMEM_PROT_READ 1
+/** Write access. */
+#define RTMEM_PROT_WRITE 2
+/** Execute access. */
+#define RTMEM_PROT_EXEC 4
+/** @} */
+
+/**
+ * Change the page level protection of a memory region.
+ *
+ * @returns iprt status code.
+ * @param pv Start of the region. Will be rounded down to nearest page boundary.
+ * @param cb Size of the region. Will be rounded up to the nearest page boundary.
+ * @param fProtect The new protection, a combination of the RTMEM_PROT_* defines.
+ */
+RTDECL(int) RTMemProtect(void *pv, size_t cb, unsigned fProtect) RT_NO_THROW;
+
+/**
+ * Goes thru some pains to make sure the specified memory block is thoroughly
+ * scrambled.
+ *
+ * @param pv The start of the memory block.
+ * @param cb The size of the memory block.
+ * @param cMinPasses The minimum number of passes to make.
+ */
+RTDECL(void) RTMemWipeThoroughly(void *pv, size_t cb, size_t cMinPasses) RT_NO_THROW;
+
+#ifdef IN_RING0
+
+/**
+ * Allocates physical contiguous memory (below 4GB).
+ * The allocation is page aligned and the content is undefined.
+ *
+ * @returns Pointer to the memory block. This is page aligned.
+ * @param pPhys Where to store the physical address.
+ * @param cb The allocation size in bytes. This is always
+ * rounded up to PAGE_SIZE.
+ */
+RTR0DECL(void *) RTMemContAlloc(PRTCCPHYS pPhys, size_t cb) RT_NO_THROW;
+
+/**
+ * Frees memory allocated ysing RTMemContAlloc().
+ *
+ * @param pv Pointer to return from RTMemContAlloc().
+ * @param cb The cb parameter passed to RTMemContAlloc().
+ */
+RTR0DECL(void) RTMemContFree(void *pv, size_t cb) RT_NO_THROW;
+
+/**
+ * Copy memory from an user mode buffer into a kernel buffer.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_ACCESS_DENIED on error.
+ *
+ * @param pvDst The kernel mode destination address.
+ * @param R3PtrSrc The user mode source address.
+ * @param cb The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemUserCopyFrom(void *pvDst, RTR3PTR R3PtrSrc, size_t cb);
+
+/**
+ * Copy memory from a kernel buffer into a user mode one.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_ACCESS_DENIED on error.
+ *
+ * @param R3PtrDst The user mode destination address.
+ * @param pvSrc The kernel mode source address.
+ * @param cb The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemUserCopyTo(RTR3PTR R3PtrDst, void const *pvSrc, size_t cb);
+
+/**
+ * Tests if the specified address is in the user addressable range.
+ *
+ * This function does not check whether the memory at that address is accessible
+ * or anything of that sort, only if the address it self is in the user mode
+ * range.
+ *
+ * @returns true if it's in the user addressable range. false if not.
+ * @param R3Ptr The user mode pointer to test.
+ *
+ * @remarks Some systems may have overlapping kernel and user address ranges.
+ * One prominent example of this is the x86 version of Mac OS X. Use
+ * RTR0MemAreKrnlAndUsrDifferent() to check.
+ */
+RTR0DECL(bool) RTR0MemUserIsValidAddr(RTR3PTR R3Ptr);
+
+/**
+ * Tests if the specified address is in the kernel mode range.
+ *
+ * This function does not check whether the memory at that address is accessible
+ * or anything of that sort, only if the address it self is in the kernel mode
+ * range.
+ *
+ * @returns true if it's in the kernel range. false if not.
+ * @param pv The alleged kernel mode pointer.
+ *
+ * @remarks Some systems may have overlapping kernel and user address ranges.
+ * One prominent example of this is the x86 version of Mac OS X. Use
+ * RTR0MemAreKrnlAndUsrDifferent() to check.
+ */
+RTR0DECL(bool) RTR0MemKernelIsValidAddr(void *pv);
+
+/**
+ * Are user mode and kernel mode address ranges distinctly different.
+ *
+ * This determines whether RTR0MemKernelIsValidAddr and RTR0MemUserIsValidAddr
+ * can be used for deciding whether some arbitrary address is a user mode or a
+ * kernel mode one.
+ *
+ * @returns true if they are, false if not.
+ */
+RTR0DECL(bool) RTR0MemAreKrnlAndUsrDifferent(void);
+
+/**
+ * Copy memory from an potentially unsafe kernel mode location and into a safe
+ * (kernel) buffer.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_ACCESS_DENIED on error.
+ * @retval VERR_NOT_SUPPORTED if not (yet) supported.
+ *
+ * @param pvDst The destination address (safe).
+ * @param pvSrc The source address (potentially unsafe).
+ * @param cb The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemKernelCopyFrom(void *pvDst, void const *pvSrc, size_t cb);
+
+/**
+ * Copy from a safe (kernel) buffer and to a potentially unsafe kenrel mode
+ * location.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_ACCESS_DENIED on error.
+ * @retval VERR_NOT_SUPPORTED if not (yet) supported.
+ *
+ * @param pvDst The destination address (potentially unsafe).
+ * @param pvSrc The source address (safe).
+ * @param cb The number of bytes to copy.
+ */
+RTR0DECL(int) RTR0MemKernelCopyTo(void *pvDst, void const *pvSrc, size_t cb);
+
+#endif /* IN_RING0 */
+
+
+/** @name Electrical Fence Version of some APIs.
+ * @{
+ */
+
+/**
+ * Same as RTMemTmpAllocTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfTmpAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemTmpAllocZTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfTmpAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemTmpFree() except that it's for fenced memory.
+ *
+ * @param pv Pointer to memory block.
+ */
+RTDECL(void) RTMemEfTmpFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemAllocTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory. Free with RTMemEfFree().
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfAlloc(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemAllocZTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cb Size in bytes of the memory block to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfAllocZ(size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemAllocVarTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory. Free with RTMemEfFree().
+ * @returns NULL on failure.
+ * @param cbUnaligned Size in bytes of the memory block to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfAllocVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemAllocZVarTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param cbUnaligned Size in bytes of the memory block to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfAllocZVar(size_t cbUnaligned, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemReallocTag() except that it's fenced.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ * @param pvOld The memory block to reallocate.
+ * @param cbNew The new block size (in bytes).
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfRealloc(void *pvOld, size_t cbNew, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Free memory allocated by any of the RTMemEf* allocators.
+ *
+ * @param pv Pointer to memory block.
+ */
+RTDECL(void) RTMemEfFree(void *pv, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemDupTag() except that it's fenced.
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param pvSrc The memory to duplicate.
+ * @param cb The amount of memory to duplicate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfDup(const void *pvSrc, size_t cb, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/**
+ * Same as RTMemEfDupExTag except that it's fenced.
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ * @param pvSrc The memory to duplicate.
+ * @param cbSrc The amount of memory to duplicate.
+ * @param cbExtra The amount of extra memory to allocate and zero.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(void *) RTMemEfDupEx(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag, RT_SRC_POS_DECL) RT_NO_THROW;
+
+/** @def RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF
+ * Define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF to enable electric fence new and
+ * delete operators for classes which uses the RTMEMEF_NEW_AND_DELETE_OPERATORS
+ * macro.
+ */
+/** @def RTMEMEF_NEW_AND_DELETE_OPERATORS
+ * Defines the electric fence new and delete operators for a class when
+ * RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF is define.
+ */
+#if defined(RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF) && !defined(RTMEM_NO_WRAP_SOME_NEW_AND_DELETE_TO_EF)
+# if defined(RT_EXCEPTIONS_ENABLED)
+# define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
+ void *operator new(size_t cb) RT_THROW(std::bad_alloc) \
+ { \
+ void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ if (RT_UNLIKELY(!pv)) \
+ throw std::bad_alloc(); \
+ return pv; \
+ } \
+ void *operator new(size_t cb, const std::nothrow_t &nothrow_constant) RT_NO_THROW \
+ { \
+ NOREF(nothrow_constant); \
+ return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ } \
+ void *operator new[](size_t cb) RT_THROW(std::bad_alloc) \
+ { \
+ void *pv = RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ if (RT_UNLIKELY(!pv)) \
+ throw std::bad_alloc(); \
+ return pv; \
+ } \
+ void *operator new[](size_t cb, const std::nothrow_t &nothrow_constant) RT_NO_THROW \
+ { \
+ NOREF(nothrow_constant); \
+ return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ } \
+ \
+ void operator delete(void *pv) RT_NO_THROW \
+ { \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ void operator delete(void *pv, const std::nothrow_t &nothrow_constant) RT_NO_THROW \
+ { \
+ NOREF(nothrow_constant); \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ void operator delete[](void *pv) RT_NO_THROW \
+ { \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ void operator delete[](void *pv, const std::nothrow_t &nothrow_constant) RT_NO_THROW \
+ { \
+ NOREF(nothrow_constant); \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ \
+ typedef int UsingElectricNewAndDeleteOperators
+# else
+# define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
+ void *operator new(size_t cb) \
+ { \
+ return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ } \
+ void *operator new(size_t cb, const std::nothrow_t &nothrow_constant) \
+ { \
+ NOREF(nothrow_constant); \
+ return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ } \
+ void *operator new[](size_t cb) \
+ { \
+ return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ } \
+ void *operator new[](size_t cb, const std::nothrow_t &nothrow_constant) \
+ { \
+ NOREF(nothrow_constant); \
+ return RTMemEfAlloc(cb, RTMEM_TAG, RT_SRC_POS); \
+ } \
+ \
+ void operator delete(void *pv) \
+ { \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ void operator delete(void *pv, const std::nothrow_t &nothrow_constant) \
+ { \
+ NOREF(nothrow_constant); \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ void operator delete[](void *pv) \
+ { \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ void operator delete[](void *pv, const std::nothrow_t &nothrow_constant) \
+ { \
+ NOREF(nothrow_constant); \
+ RTMemEfFree(pv, RT_SRC_POS); \
+ } \
+ \
+ typedef int UsingElectricNewAndDeleteOperators
+# endif
+#else
+# define RTMEMEF_NEW_AND_DELETE_OPERATORS() \
+ typedef int UsingDefaultNewAndDeleteOperators
+#endif
+#ifdef DOXYGEN_RUNNING
+# define RTMEM_WRAP_SOME_NEW_AND_DELETE_TO_EF
+#endif
+
+/** @def RTMEM_WRAP_TO_EF_APIS
+ * Define RTMEM_WRAP_TO_EF_APIS to wrap RTMem APIs to RTMemEf APIs.
+ */
+#if defined(RTMEM_WRAP_TO_EF_APIS) && defined(IN_RING3) && !defined(RTMEM_NO_WRAP_TO_EF_APIS)
+# define RTMemTmpAllocTag(cb, pszTag) RTMemEfTmpAlloc((cb), (pszTag), RT_SRC_POS)
+# define RTMemTmpAllocZTag(cb, pszTag) RTMemEfTmpAllocZ((cb), (pszTag), RT_SRC_POS)
+# define RTMemTmpFree(pv) RTMemEfTmpFree((pv), RT_SRC_POS)
+# define RTMemAllocTag(cb, pszTag) RTMemEfAlloc((cb), (pszTag), RT_SRC_POS)
+# define RTMemAllocZTag(cb, pszTag) RTMemEfAllocZ((cb), (pszTag), RT_SRC_POS)
+# define RTMemAllocVarTag(cbUnaligned, pszTag) RTMemEfAllocVar((cbUnaligned), (pszTag), RT_SRC_POS)
+# define RTMemAllocZVarTag(cbUnaligned, pszTag) RTMemEfAllocZVar((cbUnaligned), (pszTag), RT_SRC_POS)
+# define RTMemReallocTag(pvOld, cbNew, pszTag) RTMemEfRealloc((pvOld), (cbNew), (pszTag), RT_SRC_POS)
+# define RTMemFree(pv) RTMemEfFree((pv), RT_SRC_POS)
+# define RTMemDupTag(pvSrc, cb, pszTag) RTMemEfDup((pvSrc), (cb), (pszTag), RT_SRC_POS)
+# define RTMemDupExTag(pvSrc, cbSrc, cbExtra, pszTag) RTMemEfDupEx((pvSrc), (cbSrc), (cbExtra), (pszTag), RT_SRC_POS)
+#endif
+#ifdef DOXYGEN_RUNNING
+# define RTMEM_WRAP_TO_EF_APIS
+#endif
+
+/**
+ * Fenced drop-in replacement for RTMemTmpAllocTag.
+ * @copydoc RTMemTmpAllocTag
+ */
+RTDECL(void *) RTMemEfTmpAllocNP(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemTmpAllocZTag.
+ * @copydoc RTMemTmpAllocZTag
+ */
+RTDECL(void *) RTMemEfTmpAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemTmpFreeTag.
+ * @copydoc RTMemTmpFreeTag
+ */
+RTDECL(void) RTMemEfTmpFreeNP(void *pv) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocTag.
+ * @copydoc RTMemAllocTag
+ */
+RTDECL(void *) RTMemEfAllocNP(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocZTag.
+ * @copydoc RTMemAllocZTag
+ */
+RTDECL(void *) RTMemEfAllocZNP(size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocVarTag
+ * @copydoc RTMemAllocVarTag
+ */
+RTDECL(void *) RTMemEfAllocVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemAllocZVarTag.
+ * @copydoc RTMemAllocZVarTag
+ */
+RTDECL(void *) RTMemEfAllocZVarNP(size_t cbUnaligned, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemReallocTag.
+ * @copydoc RTMemReallocTag
+ */
+RTDECL(void *) RTMemEfReallocNP(void *pvOld, size_t cbNew, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemFree.
+ * @copydoc RTMemFree
+ */
+RTDECL(void) RTMemEfFreeNP(void *pv) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemDupExTag.
+ * @copydoc RTMemDupExTag
+ */
+RTDECL(void *) RTMemEfDupNP(const void *pvSrc, size_t cb, const char *pszTag) RT_NO_THROW;
+
+/**
+ * Fenced drop-in replacement for RTMemDupExTag.
+ * @copydoc RTMemDupExTag
+ */
+RTDECL(void *) RTMemEfDupExNP(const void *pvSrc, size_t cbSrc, size_t cbExtra, const char *pszTag) RT_NO_THROW;
+
+/** @} */
+
+RT_C_DECLS_END
+
+/** @} */
+
+
+#endif
+
diff --git a/include/iprt/memcache.h b/include/iprt/memcache.h
new file mode 100644
index 00000000..cad496b1
--- /dev/null
+++ b/include/iprt/memcache.h
@@ -0,0 +1,147 @@
+/** @file
+ * IPRT - Memory Object Allocation Cache.
+ */
+
+/*
+ * 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 ___iprt_memcache_h
+#define ___iprt_memcache_h
+
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_rt_memcache RTMemCache - Memory Object Allocation Cache
+ * @ingroup grp_rt
+ *
+ * Optimized allocation, initialization, freeing and destruction of memory
+ * objects of the same kind and size.
+ *
+ * @{
+ */
+
+/** A memory cache handle. */
+typedef R3R0PTRTYPE(struct RTMEMCACHEINT *) RTMEMCACHE;
+/** Pointer to a memory cache handle. */
+typedef RTMEMCACHE *PRTMEMCACHE;
+/** Nil memory cache handle. */
+#define NIL_RTMEMCACHE ((RTMEMCACHE)0)
+
+
+/**
+ * Object constructor.
+ *
+ * This is called for when an element is allocated for the first time.
+ *
+ * @returns IPRT status code.
+ * @param hMemCache The cache handle.
+ * @param pvObj The memory object that should be initialized.
+ * @param pvUser The user argument.
+ *
+ * @remarks No serialization is performed.
+ */
+typedef DECLCALLBACK(int) FNMEMCACHECTOR(RTMEMCACHE hMemCache, void *pvObj, void *pvUser);
+/** Pointer to an object constructor for the memory cache. */
+typedef FNMEMCACHECTOR *PFNMEMCACHECTOR;
+
+/**
+ * Object destructor.
+ *
+ * This is called when we're shrinking or destroying the cache.
+ *
+ * @param hMemCache The cache handle.
+ * @param pvObj The memory object that should be initialized.
+ * @param pvUser The user argument.
+ *
+ * @remarks No serialization is performed.
+ */
+typedef DECLCALLBACK(void) FNMEMCACHEDTOR(RTMEMCACHE hMemCache, void *pvObj, void *pvUser);
+/** Pointer to an object destructor for the memory cache. */
+typedef FNMEMCACHEDTOR *PFNMEMCACHEDTOR;
+
+
+/**
+ * Create an allocation cache for fixed size memory objects.
+ *
+ * @returns IPRT status code.
+ * @param phMemCache Where to return the cache handle.
+ * @param cbObject The size of one memory object.
+ * @param cbAlignment The object alignment. This must be a power of
+ * two. The higest alignment is 64. If set to 0,
+ * a sensible alignment value will be derived from
+ * the object size.
+ * @param cMaxObjects The maximum cache size. Pass UINT32_MAX if unsure.
+ * @param pfnCtor Object constructor callback. Optional.
+ * @param pfnDtor Object destructor callback. Optional.
+ * @param pvUser User argument for the two callbacks.
+ * @param fFlags Flags reserved for future use. Must be zero.
+ */
+RTDECL(int) RTMemCacheCreate(PRTMEMCACHE phMemCache, size_t cbObject, size_t cbAlignment, uint32_t cMaxObjects,
+ PFNMEMCACHECTOR pfnCtor, PFNMEMCACHEDTOR pfnDtor, void *pvUser, uint32_t fFlags);
+
+/**
+ * Destroy a cache destroying and freeing allocated memory.
+ *
+ * @returns IPRT status code.
+ * @param hMemCache The cache handle. NIL is quietly (VINF_SUCCESS)
+ * ignored.
+ */
+RTDECL(int) RTMemCacheDestroy(RTMEMCACHE hMemCache);
+
+/**
+ * Allocate an object.
+ *
+ * @returns Pointer to the allocated cache object.
+ * @param hMemCache The cache handle.
+ */
+RTDECL(void *) RTMemCacheAlloc(RTMEMCACHE hMemCache);
+
+/**
+ * Allocate an object and return a proper status code.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_MEM_CACHE_MAX_SIZE if we've reached maximum size (see
+ * RTMemCacheCreate).
+ * @retval VERR_NO_MEMORY if we failed to allocate more memory for the cache.
+ *
+ * @param hMemCache The cache handle.
+ * @param ppvObj Where to return the object.
+ */
+RTDECL(int) RTMemCacheAllocEx(RTMEMCACHE hMemCache, void **ppvObj);
+
+/**
+ * Free an object previously returned by RTMemCacheAlloc or RTMemCacheAllocEx.
+ *
+ * @param hMemCache The cache handle.
+ * @param pvObj The object to free. NULL is fine.
+ */
+RTDECL(void) RTMemCacheFree(RTMEMCACHE hMemCache, void *pvObj);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/memobj.h b/include/iprt/memobj.h
new file mode 100644
index 00000000..3a3b7025
--- /dev/null
+++ b/include/iprt/memobj.h
@@ -0,0 +1,629 @@
+/** @file
+ * IPRT - Memory Objects (Ring-0).
+ */
+
+/*
+ * 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 ___iprt_memobj_h
+#define ___iprt_memobj_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_memobj RTMemObj - Memory Object Manipulation (Ring-0)
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @def RTMEM_TAG
+ * The default allocation tag used by the RTMem allocation APIs.
+ *
+ * When not defined before the inclusion of iprt/memobj.h or iprt/mem.h, this
+ * will default to the pointer to the current file name. The memory API will
+ * make of use of this as pointer to a volatile but read-only string.
+ */
+#ifndef RTMEM_TAG
+# define RTMEM_TAG (__FILE__)
+#endif
+
+#ifdef IN_RING0
+
+/**
+ * Checks if this is mapping or not.
+ *
+ * @returns true if it's a mapping, otherwise false.
+ * @param MemObj The ring-0 memory object handle.
+ */
+RTR0DECL(bool) RTR0MemObjIsMapping(RTR0MEMOBJ MemObj);
+
+/**
+ * Gets the address of a ring-0 memory object.
+ *
+ * @returns The address of the memory object.
+ * @returns NULL if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
+ * @param MemObj The ring-0 memory object handle.
+ */
+RTR0DECL(void *) RTR0MemObjAddress(RTR0MEMOBJ MemObj);
+
+/**
+ * Gets the ring-3 address of a ring-0 memory object.
+ *
+ * This only applies to ring-0 memory object with ring-3 mappings of some kind, i.e.
+ * locked user memory, reserved user address space and user mappings. This API should
+ * not be used on any other objects.
+ *
+ * @returns The address of the memory object.
+ * @returns NIL_RTR3PTR if the handle is invalid or if it's not an object with a ring-3 mapping.
+ * Strict builds will assert in both cases.
+ * @param MemObj The ring-0 memory object handle.
+ */
+RTR0DECL(RTR3PTR) RTR0MemObjAddressR3(RTR0MEMOBJ MemObj);
+
+/**
+ * Gets the size of a ring-0 memory object.
+ *
+ * The returned value may differ from the one specified to the API creating the
+ * object because of alignment adjustments. The minimal alignment currently
+ * employed by any API is PAGE_SIZE, so the result can safely be shifted by
+ * PAGE_SHIFT to calculate a page count.
+ *
+ * @returns The object size.
+ * @returns 0 if the handle is invalid (asserts in strict builds) or if there isn't any mapping.
+ * @param MemObj The ring-0 memory object handle.
+ */
+RTR0DECL(size_t) RTR0MemObjSize(RTR0MEMOBJ MemObj);
+
+/**
+ * Get the physical address of an page in the memory object.
+ *
+ * @returns The physical address.
+ * @returns NIL_RTHCPHYS if the object doesn't contain fixed physical pages.
+ * @returns NIL_RTHCPHYS if the iPage is out of range.
+ * @returns NIL_RTHCPHYS if the object handle isn't valid.
+ * @param MemObj The ring-0 memory object handle.
+ * @param iPage The page number within the object.
+ */
+RTR0DECL(RTHCPHYS) RTR0MemObjGetPagePhysAddr(RTR0MEMOBJ MemObj, size_t iPage);
+
+/**
+ * Frees a ring-0 memory object.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if
+ * @param MemObj The ring-0 memory object to be freed. NULL is accepted.
+ * @param fFreeMappings Whether or not to free mappings of the object.
+ */
+RTR0DECL(int) RTR0MemObjFree(RTR0MEMOBJ MemObj, bool fFreeMappings);
+
+/**
+ * Allocates page aligned virtual kernel memory (default tag).
+ *
+ * The memory is taken from a non paged (= fixed physical memory backing) pool.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+#define RTR0MemObjAllocPage(pMemObj, cb, fExecutable) \
+ RTR0MemObjAllocPageTag((pMemObj), (cb), (fExecutable), RTMEM_TAG)
+
+/**
+ * Allocates page aligned virtual kernel memory (custom tag).
+ *
+ * The memory is taken from a non paged (= fixed physical memory backing) pool.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPageTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+
+/**
+ * Allocates page aligned virtual kernel memory with physical backing below 4GB
+ * (default tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+#define RTR0MemObjAllocLow(pMemObj, cb, fExecutable) \
+ RTR0MemObjAllocLowTag((pMemObj), (cb), (fExecutable), RTMEM_TAG)
+
+/**
+ * Allocates page aligned virtual kernel memory with physical backing below 4GB
+ * (custom tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocLowTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+
+/**
+ * Allocates page aligned virtual kernel memory with contiguous physical backing
+ * below 4GB (default tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
+ */
+#define RTR0MemObjAllocCont(pMemObj, cb, fExecutable) \
+ RTR0MemObjAllocContTag((pMemObj), (cb), (fExecutable), RTMEM_TAG)
+
+/**
+ * Allocates page aligned virtual kernel memory with contiguous physical backing
+ * below 4GB (custom tag).
+ *
+ * The physical memory backing the allocation is fixed.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param fExecutable Flag indicating whether it should be permitted to executed code in the memory object.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocContTag(PRTR0MEMOBJ pMemObj, size_t cb, bool fExecutable, const char *pszTag);
+
+/**
+ * Locks a range of user virtual memory (default tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param R3Ptr User virtual address. This is rounded down to a page
+ * boundary.
+ * @param cb Number of bytes to lock. This is rounded up to
+ * nearest page boundary.
+ * @param fAccess The desired access, a combination of RTMEM_PROT_READ
+ * and RTMEM_PROT_WRITE.
+ * @param R0Process The process to lock pages in. NIL_R0PROCESS is an
+ * alias for the current one.
+ *
+ * @remarks RTR0MemGetAddressR3() and RTR0MemGetAddress() will return therounded
+ * down address.
+ *
+ * @remarks Linux: This API requires that the memory begin locked is in a memory
+ * mapping that is not required in any forked off child process. This
+ * is not intented as permanent restriction, feel free to help out
+ * lifting it.
+ */
+#define RTR0MemObjLockUser(pMemObj, R3Ptr, cb, fAccess, R0Process) \
+ RTR0MemObjLockUserTag((pMemObj), (R3Ptr), (cb), (fAccess), (R0Process), RTMEM_TAG)
+
+/**
+ * Locks a range of user virtual memory (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param R3Ptr User virtual address. This is rounded down to a page
+ * boundary.
+ * @param cb Number of bytes to lock. This is rounded up to
+ * nearest page boundary.
+ * @param fAccess The desired access, a combination of RTMEM_PROT_READ
+ * and RTMEM_PROT_WRITE.
+ * @param R0Process The process to lock pages in. NIL_R0PROCESS is an
+ * alias for the current one.
+ * @param pszTag Allocation tag used for statistics and such.
+ *
+ * @remarks RTR0MemGetAddressR3() and RTR0MemGetAddress() will return therounded
+ * down address.
+ *
+ * @remarks Linux: This API requires that the memory begin locked is in a memory
+ * mapping that is not required in any forked off child process. This
+ * is not intented as permanent restriction, feel free to help out
+ * lifting it.
+ */
+RTR0DECL(int) RTR0MemObjLockUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3Ptr, size_t cb, uint32_t fAccess,
+ RTR0PROCESS R0Process, const char *pszTag);
+
+/**
+ * Locks a range of kernel virtual memory (default tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param pv Kernel virtual address. This is rounded down to a page boundary.
+ * @param cb Number of bytes to lock. This is rounded up to nearest page boundary.
+ * @param fAccess The desired access, a combination of RTMEM_PROT_READ
+ * and RTMEM_PROT_WRITE.
+ *
+ * @remark RTR0MemGetAddress() will return the rounded down address.
+ */
+#define RTR0MemObjLockKernel(pMemObj, pv, cb, fAccess) \
+ RTR0MemObjLockKernelTag((pMemObj), (pv), (cb), (fAccess), RTMEM_TAG)
+
+/**
+ * Locks a range of kernel virtual memory (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param pv Kernel virtual address. This is rounded down to a page boundary.
+ * @param cb Number of bytes to lock. This is rounded up to nearest page boundary.
+ * @param fAccess The desired access, a combination of RTMEM_PROT_READ
+ * and RTMEM_PROT_WRITE.
+ * @param pszTag Allocation tag used for statistics and such.
+ *
+ * @remark RTR0MemGetAddress() will return the rounded down address.
+ */
+RTR0DECL(int) RTR0MemObjLockKernelTag(PRTR0MEMOBJ pMemObj, void *pv, size_t cb, uint32_t fAccess, const char *pszTag);
+
+/**
+ * Allocates contiguous page aligned physical memory without (necessarily) any
+ * kernel mapping (default tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param PhysHighest The highest permitable address (inclusive).
+ * Pass NIL_RTHCPHYS if any address is acceptable.
+ */
+#define RTR0MemObjAllocPhys(pMemObj, cb, PhysHighest) \
+ RTR0MemObjAllocPhysTag((pMemObj), (cb), (PhysHighest), RTMEM_TAG)
+
+/**
+ * Allocates contiguous page aligned physical memory without (necessarily) any
+ * kernel mapping (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param PhysHighest The highest permitable address (inclusive).
+ * Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPhysTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag);
+
+/**
+ * Allocates contiguous physical memory without (necessarily) any kernel mapping
+ * (default tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param PhysHighest The highest permitable address (inclusive).
+ * Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M, _4M and _1G.
+ */
+#define RTR0MemObjAllocPhysEx(pMemObj, cb, PhysHighest, uAlignment) \
+ RTR0MemObjAllocPhysExTag((pMemObj), (cb), (PhysHighest), (uAlignment), RTMEM_TAG)
+
+/**
+ * Allocates contiguous physical memory without (necessarily) any kernel mapping
+ * (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param PhysHighest The highest permitable address (inclusive).
+ * Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M, _4M and _1G.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPhysExTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment, const char *pszTag);
+
+/**
+ * Allocates non-contiguous page aligned physical memory without (necessarily)
+ * any kernel mapping (default tag).
+ *
+ * This API is for allocating huge amounts of pages and will return
+ * VERR_NOT_SUPPORTED if this cannot be implemented in a satisfactory
+ * manner.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if it's not possible to allocated unmapped
+ * physical memory on this platform. The caller should expect
+ * this error and have a fallback strategy for it.
+ *
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param PhysHighest The highest permitable address (inclusive).
+ * Pass NIL_RTHCPHYS if any address is acceptable.
+ */
+#define RTR0MemObjAllocPhysNC(pMemObj, cb, PhysHighest) \
+ RTR0MemObjAllocPhysNCTag((pMemObj), (cb), (PhysHighest), RTMEM_TAG)
+
+/**
+ * Allocates non-contiguous page aligned physical memory without (necessarily)
+ * any kernel mapping (custom tag).
+ *
+ * This API is for allocating huge amounts of pages and will return
+ * VERR_NOT_SUPPORTED if this cannot be implemented in a satisfactory
+ * manner.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if it's not possible to allocated unmapped
+ * physical memory on this platform. The caller should expect
+ * this error and have a fallback strategy for it.
+ *
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param cb Number of bytes to allocate. This is rounded up to nearest page.
+ * @param PhysHighest The highest permitable address (inclusive).
+ * Pass NIL_RTHCPHYS if any address is acceptable.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjAllocPhysNCTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, const char *pszTag);
+
+/** Memory cache policy for RTR0MemObjEnterPhys.
+ * @{
+ */
+/** Default caching policy -- don't care. */
+#define RTMEM_CACHE_POLICY_DONT_CARE UINT32_C(0)
+/** MMIO caching policy -- uncachable. */
+#define RTMEM_CACHE_POLICY_MMIO UINT32_C(1)
+/** @} */
+
+/**
+ * Creates a page aligned, contiguous, physical memory object (default tag).
+ *
+ * No physical memory is allocated, we trust you do know what you're doing.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param Phys The physical address to start at. This is rounded down to the
+ * nearest page boundary.
+ * @param cb The size of the object in bytes. This is rounded up to nearest page boundary.
+ * @param uCachePolicy One of the RTMEM_CACHE_XXX modes.
+ */
+#define RTR0MemObjEnterPhys(pMemObj, Phys, cb, uCachePolicy) \
+ RTR0MemObjEnterPhysTag((pMemObj), (Phys), (cb), (uCachePolicy), RTMEM_TAG)
+
+/**
+ * Creates a page aligned, contiguous, physical memory object (custom tag).
+ *
+ * No physical memory is allocated, we trust you do know what you're doing.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param Phys The physical address to start at. This is rounded down to the
+ * nearest page boundary.
+ * @param cb The size of the object in bytes. This is rounded up to nearest page boundary.
+ * @param uCachePolicy One of the RTMEM_CACHE_XXX modes.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjEnterPhysTag(PRTR0MEMOBJ pMemObj, RTHCPHYS Phys, size_t cb, uint32_t uCachePolicy, const char *pszTag);
+
+/**
+ * Reserves kernel virtual address space (default tag).
+ *
+ * If this function fails with VERR_NOT_SUPPORTED, the idea is that you
+ * can use RTR0MemObjEnterPhys() + RTR0MemObjMapKernel() as a fallback if
+ * you have a safe physical address range to make use of...
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param pvFixed Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param cb The number of bytes to reserve. This is rounded up to nearest page.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ */
+#define RTR0MemObjReserveKernel(pMemObj, pvFixed, cb, uAlignment) \
+ RTR0MemObjReserveKernelTag((pMemObj), (pvFixed), (cb), (uAlignment), RTMEM_TAG)
+
+/**
+ * Reserves kernel virtual address space (custom tag).
+ *
+ * If this function fails with VERR_NOT_SUPPORTED, the idea is that you
+ * can use RTR0MemObjEnterPhys() + RTR0MemObjMapKernel() as a fallback if
+ * you have a safe physical address range to make use of...
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param pvFixed Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param cb The number of bytes to reserve. This is rounded up to nearest page.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjReserveKernelTag(PRTR0MEMOBJ pMemObj, void *pvFixed, size_t cb, size_t uAlignment, const char *pszTag);
+
+/**
+ * Reserves user virtual address space in the current process (default tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param R3PtrFixed Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param cb The number of bytes to reserve. This is rounded up to nearest PAGE_SIZE.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param R0Process The process to reserve the memory in. NIL_R0PROCESS is an alias for the current one.
+ */
+#define RTR0MemObjReserveUser(pMemObj, R3PtrFixed, cb, uAlignment, R0Process) \
+ RTR0MemObjReserveUserTag((pMemObj), (R3PtrFixed), (cb), (uAlignment), (R0Process), RTMEM_TAG)
+
+/**
+ * Reserves user virtual address space in the current process (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle.
+ * @param R3PtrFixed Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param cb The number of bytes to reserve. This is rounded up to nearest PAGE_SIZE.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param R0Process The process to reserve the memory in. NIL_R0PROCESS is an alias for the current one.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjReserveUserTag(PRTR0MEMOBJ pMemObj, RTR3PTR R3PtrFixed, size_t cb, size_t uAlignment,
+ RTR0PROCESS R0Process, const char *pszTag);
+
+/**
+ * Maps a memory object into kernel virtual address space (default tag).
+ *
+ * This is the same as calling RTR0MemObjMapKernelEx with cbSub and offSub set
+ * to zero.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle of the mapping object.
+ * @param MemObjToMap The object to be map.
+ * @param pvFixed Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ */
+#define RTR0MemObjMapKernel(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt) \
+ RTR0MemObjMapKernelTag((pMemObj), (MemObjToMap), (pvFixed), (uAlignment), (fProt), RTMEM_TAG)
+
+/**
+ * Maps a memory object into kernel virtual address space (custom tag).
+ *
+ * This is the same as calling RTR0MemObjMapKernelEx with cbSub and offSub set
+ * to zero.
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle of the mapping object.
+ * @param MemObjToMap The object to be map.
+ * @param pvFixed Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjMapKernelTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed,
+ size_t uAlignment, unsigned fProt, const char *pszTag);
+
+/**
+ * Maps a memory object into kernel virtual address space (default tag).
+ *
+ * The ability to map subsections of the object into kernel space is currently
+ * not implemented on all platforms. All/Most of platforms supports mapping the
+ * whole object into kernel space.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if it's not possible to map a subsection of a
+ * memory object on this platform. When you hit this, try implement it.
+ *
+ * @param pMemObj Where to store the ring-0 memory object handle of the mapping object.
+ * @param MemObjToMap The object to be map.
+ * @param pvFixed Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param offSub Where in the object to start mapping. If non-zero
+ * the value must be page aligned and cbSub must be
+ * non-zero as well.
+ * @param cbSub The size of the part of the object to be mapped. If
+ * zero the entire object is mapped. The value must be
+ * page aligned.
+ */
+#define RTR0MemObjMapKernelEx(pMemObj, MemObjToMap, pvFixed, uAlignment, fProt, offSub, cbSub) \
+ RTR0MemObjMapKernelExTag((pMemObj), (MemObjToMap), (pvFixed), (uAlignment), (fProt), (offSub), (cbSub), RTMEM_TAG)
+
+/**
+ * Maps a memory object into kernel virtual address space (custom tag).
+ *
+ * The ability to map subsections of the object into kernel space is currently
+ * not implemented on all platforms. All/Most of platforms supports mapping the
+ * whole object into kernel space.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if it's not possible to map a subsection of a
+ * memory object on this platform. When you hit this, try implement it.
+ *
+ * @param pMemObj Where to store the ring-0 memory object handle of the mapping object.
+ * @param MemObjToMap The object to be map.
+ * @param pvFixed Requested address. (void *)-1 means any address. This must match the alignment.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param offSub Where in the object to start mapping. If non-zero
+ * the value must be page aligned and cbSub must be
+ * non-zero as well.
+ * @param cbSub The size of the part of the object to be mapped. If
+ * zero the entire object is mapped. The value must be
+ * page aligned.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjMapKernelExTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, void *pvFixed, size_t uAlignment,
+ unsigned fProt, size_t offSub, size_t cbSub, const char *pszTag);
+
+/**
+ * Maps a memory object into user virtual address space in the current process
+ * (default tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle of the mapping object.
+ * @param MemObjToMap The object to be map.
+ * @param R3PtrFixed Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param R0Process The process to map the memory into. NIL_R0PROCESS is an alias for the current one.
+ */
+#define RTR0MemObjMapUser(pMemObj, MemObjToMap, R3PtrFixed, uAlignment, fProt, R0Process) \
+ RTR0MemObjMapUserTag((pMemObj), (MemObjToMap), (R3PtrFixed), (uAlignment), (fProt), (R0Process), RTMEM_TAG)
+
+/**
+ * Maps a memory object into user virtual address space in the current process
+ * (custom tag).
+ *
+ * @returns IPRT status code.
+ * @param pMemObj Where to store the ring-0 memory object handle of the mapping object.
+ * @param MemObjToMap The object to be map.
+ * @param R3PtrFixed Requested address. (RTR3PTR)-1 means any address. This must match the alignment.
+ * @param uAlignment The alignment of the reserved memory.
+ * Supported values are 0 (alias for PAGE_SIZE), PAGE_SIZE, _2M and _4M.
+ * @param fProt Combination of RTMEM_PROT_* flags (except RTMEM_PROT_NONE).
+ * @param R0Process The process to map the memory into. NIL_R0PROCESS is an alias for the current one.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR0DECL(int) RTR0MemObjMapUserTag(PRTR0MEMOBJ pMemObj, RTR0MEMOBJ MemObjToMap, RTR3PTR R3PtrFixed,
+ size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process, const char *pszTag);
+
+/**
+ * Change the page level protection of one or more pages in a memory object.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the OS doesn't provide any way to manipulate
+ * page level protection. The caller must handle this status code
+ * gracefully. (Note that it may also occur if the implementation is
+ * missing, in which case just go ahead and implement it.)
+ *
+ * @param hMemObj Memory object handle.
+ * @param offSub Offset into the memory object. Must be page aligned.
+ * @param cbSub Number of bytes to change the protection of. Must be
+ * page aligned.
+ * @param fProt Combination of RTMEM_PROT_* flags.
+ */
+RTR0DECL(int) RTR0MemObjProtect(RTR0MEMOBJ hMemObj, size_t offSub, size_t cbSub, uint32_t fProt);
+
+#endif /* IN_RING0 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/memory b/include/iprt/memory
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/iprt/memory
diff --git a/include/iprt/mempool.h b/include/iprt/mempool.h
new file mode 100644
index 00000000..6be563d3
--- /dev/null
+++ b/include/iprt/mempool.h
@@ -0,0 +1,165 @@
+/** @file
+ * IPRT - Memory Allocation Pool.
+ */
+
+/*
+ * 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 ___iprt_mempool_h
+#define ___iprt_mempool_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Creates a new memory pool.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phMemPool Where to return the handle to the new memory
+ * pool.
+ * @param pszName The name of the pool (for debug purposes).
+ */
+RTDECL(int) RTMemPoolCreate(PRTMEMPOOL phMemPool, const char *pszName);
+
+/**
+ * Destroys the specified pool, freeing all the memory it contains.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hMemPool The handle to the pool. The nil handle and
+ * RTMEMPOOL_DEFAULT are quietly ignored (retval
+ * VINF_SUCCESS).
+ */
+RTDECL(int) RTMemPoolDestroy(RTMEMPOOL hMemPool);
+
+/**
+ * Allocates memory.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ *
+ * @param hMemPool Handle to the pool to allocate the memory from.
+ * @param cb Size in bytes of the memory block to allocated.
+ */
+RTDECL(void *) RTMemPoolAlloc(RTMEMPOOL hMemPool, size_t cb) RT_NO_THROW;
+
+/**
+ * Allocates zero'd memory.
+ *
+ * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
+ * memory. This keeps the code smaller and the heap can skip the memset
+ * in about 0.42% of calls :-).
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ *
+ * @param hMemPool Handle to the pool to allocate the memory from.
+ * @param cb Size in bytes of the memory block to allocated.
+ */
+RTDECL(void *) RTMemPoolAllocZ(RTMEMPOOL hMemPool, size_t cb) RT_NO_THROW;
+
+/**
+ * Duplicates a chunk of memory into a new heap block.
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ *
+ * @param hMemPool Handle to the pool to allocate the memory from.
+ * @param pvSrc The memory to duplicate.
+ * @param cb The amount of memory to duplicate.
+ */
+RTDECL(void *) RTMemPoolDup(RTMEMPOOL hMemPool, const void *pvSrc, size_t cb) RT_NO_THROW;
+
+/**
+ * Duplicates a chunk of memory into a new heap block with some
+ * additional zeroed memory.
+ *
+ * @returns New heap block with the duplicate data.
+ * @returns NULL if we're out of memory.
+ *
+ * @param hMemPool Handle to the pool to allocate the memory from.
+ * @param pvSrc The memory to duplicate.
+ * @param cbSrc The amount of memory to duplicate.
+ * @param cbExtra The amount of extra memory to allocate and zero.
+ */
+RTDECL(void *) RTMemPoolDupEx(RTMEMPOOL hMemPool, const void *pvSrc, size_t cbSrc, size_t cbExtra) RT_NO_THROW;
+
+/**
+ * Reallocates memory.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure.
+ *
+ * @param hMemPool Handle to the pool containing the old memory.
+ * @param pvOld The memory block to reallocate.
+ * @param cbNew The new block size (in bytes).
+ */
+RTDECL(void *) RTMemPoolRealloc(RTMEMPOOL hMemPool, void *pvOld, size_t cbNew) RT_NO_THROW;
+
+/**
+ * Frees memory allocated from a pool.
+ *
+ * @param hMemPool Handle to the pool containing the memory. Passing
+ * NIL here is fine, but it may come at a slight
+ * performance cost.
+ * @param pv Pointer to memory block.
+ *
+ * @remarks This is the same a RTMemPoolRelease but included here as a separate
+ * function to simplify code migration.
+ */
+RTDECL(void) RTMemPoolFree(RTMEMPOOL hMemPool, void *pv) RT_NO_THROW;
+
+/**
+ * Retains a reference to a memory block in a pool.
+ *
+ * @returns New reference count, UINT32_MAX on error (asserted).
+ *
+ * @param pv Pointer to memory block.
+ */
+RTDECL(uint32_t) RTMemPoolRetain(void *pv) RT_NO_THROW;
+
+/**
+ * Releases a reference to a memory block in a pool.
+ *
+ * @returns New reference count, UINT32_MAX on error (asserted).
+ *
+ * @param hMemPool Handle to the pool containing the memory. Passing
+ * NIL here is fine, but it may come at a slight
+ * performance cost.
+ * @param pv Pointer to memory block.
+ */
+RTDECL(uint32_t) RTMemPoolRelease(RTMEMPOOL hMemPool, void *pv) RT_NO_THROW;
+
+/**
+ * Get the current reference count.
+ *
+ * @returns The reference count, UINT32_MAX on error (asserted).
+ * @param pv Pointer to memory block.
+ */
+RTDECL(uint32_t) RTMemPoolRefCount(void *pv) RT_NO_THROW;
+
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/memtracker.h b/include/iprt/memtracker.h
new file mode 100644
index 00000000..5d557b20
--- /dev/null
+++ b/include/iprt/memtracker.h
@@ -0,0 +1,236 @@
+/** @file
+ * IPRT - Memory Tracker.
+ */
+
+/*
+ * 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 ___iprt_memtracker_h
+#define ___iprt_memtracker_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/list.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_memtracker RTMemTracker - Memory Allocation Tracker.
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * The allocation/free method.
+ */
+typedef enum RTMEMTRACKERMETHOD
+{
+ RTMEMTRACKERMETHOD_INVALID = 0,
+ RTMEMTRACKERMETHOD_ALLOC,
+ RTMEMTRACKERMETHOD_ALLOCZ,
+ RTMEMTRACKERMETHOD_REALLOC_PREP, /**< Internal, don't use. */
+ RTMEMTRACKERMETHOD_REALLOC_DONE, /**< Internal, don't use. */
+ RTMEMTRACKERMETHOD_REALLOC_FAILED, /**< Internal, don't use. */
+ RTMEMTRACKERMETHOD_FREE,
+
+ RTMEMTRACKERMETHOD_NEW,
+ RTMEMTRACKERMETHOD_NEW_ARRAY,
+ RTMEMTRACKERMETHOD_DELETE,
+ RTMEMTRACKERMETHOD_DELETE_ARRAY,
+ RTMEMTRACKERMETHOD_END,
+ RTMEMTRACKERMETHOD_32BIT_HACK = 0x7fffffff
+} RTMEMTRACKERMETHOD;
+
+/** Pointer to a tag structure. */
+typedef struct RTMEMTRACKERTAG *PRTMEMTRACKERTAG;
+
+/** Pointer to a user structure. */
+typedef struct RTMEMTRACKERUSER *PRTMEMTRACKERUSER;
+
+/**
+ * Memory Tracking Header for use with RTMemTrackerHdrAlloc,
+ * RTMemTrackerHdrReallocPrep, RTMemTrackerHdrReallocDone and
+ * RTMemTrackerHdrFree.
+ */
+typedef struct RTMEMTRACKERHDR
+{
+ /** Magic value / eye catcher (RTMEMTRACKERHDR_MAGIC). */
+ size_t uMagic;
+ /** The allocation size, user data only. */
+ size_t cbUser;
+ /** The list entry. */
+ RTLISTNODE ListEntry;
+ /** Pointer to the user structure where this header is linked. */
+ PRTMEMTRACKERUSER pUser;
+ /** Pointer to the per-tag structure. */
+ PRTMEMTRACKERTAG pTag;
+ /** The tag string. */
+ const char *pszTag;
+ /** Pointer to the user data we're tracking. */
+ void *pvUser;
+} RTMEMTRACKERHDR;
+/** Pointer to a memory tracker header. */
+typedef RTMEMTRACKERHDR *PRTMEMTRACKERHDR;
+/** Pointer to a const memory tracker header. */
+typedef RTMEMTRACKERHDR *PPRTMEMTRACKERHDR;
+
+/** Magic value for RTMEMTRACKERHDR::uMagic (Kelly Link). */
+#if ARCH_BITS == 64
+# define RTMEMTRACKERHDR_MAGIC UINT64_C(0x1907691919690719)
+#else
+# define RTMEMTRACKERHDR_MAGIC UINT32_C(0x19690719)
+#endif
+/** Magic number used when reallocated. */
+#if ARCH_BITS == 64
+# define RTMEMTRACKERHDR_MAGIC_REALLOC UINT64_C(0x0000691919690000)
+#else
+# define RTMEMTRACKERHDR_MAGIC_REALLOC UINT32_C(0x19690000)
+#endif
+/** Magic number used when freed. */
+#define RTMEMTRACKERHDR_MAGIC_FREE (~RTMEMTRACKERHDR_MAGIC)
+
+
+/**
+ * Initializes the allocation header and links it to the relevant tag.
+ *
+ * @returns Pointer to the user data part.
+ * @param pv The header + user data block. This must be at
+ * least @a cb + sizeof(RTMEMTRACKERHDR).
+ * @param cbUser The user data size (bytes).
+ * @param pszTag The tag string.
+ * @param enmMethod The method that the user called.
+ */
+RTDECL(void *) RTMemTrackerHdrAlloc(void *pv, size_t cbUser, const char *pszTag, RTMEMTRACKERMETHOD enmMethod);
+
+/**
+ * Prepares for a realloc, i.e. invalidates the header.
+ *
+ * @returns Pointer to the user data part.
+ * @param pvOldUser Pointer to the old user data.
+ * @param cbOldUser The size of the old user data, 0 if not
+ * known.
+ * @param pszTag The tag string.
+ */
+RTDECL(void *) RTMemTrackerHdrReallocPrep(void *pvOldUser, size_t cbOldUser, const char *pszTag);
+
+/**
+ * Initializes the allocation header and links it to the relevant tag.
+ *
+ * @returns Pointer to the user data part.
+ * @param pvNew The new header + user data block. This must be
+ * at least @a cb + sizeof(RTMEMTRACKERHDR). If
+ * this is NULL, we assume the realloc() call
+ * failed.
+ * @param cbNewUser The user data size (bytes).
+ * @param pvOldUser Pointer to the old user data. This is only
+ * valid on failure of course and used to bail out
+ * in that case. Should not be NULL.
+ * @param pszTag The tag string.
+ */
+RTDECL(void *) RTMemTrackerHdrReallocDone(void *pvNew, size_t cbNewUser, void *pvOldUser, const char *pszTag);
+
+
+/**
+ * Do the accounting on free.
+ *
+ * @returns @a pv.
+ * @param pvUser Pointer to the user data.
+ * @param cbUser The size of the user data, 0 if not known.
+ * @param pszTag The tag string.
+ * @param enmMethod The method that the user called.
+ */
+RTDECL(void *) RTMemTrackerHdrFree(void *pvUser, size_t cbUser, const char *pszTag, RTMEMTRACKERMETHOD enmMethod);
+
+
+/**
+ * Dumps all the allocations and tag statistics to the log.
+ */
+RTDECL(void) RTMemTrackerDumpAllToLog(void);
+
+/**
+ * Dumps all the allocations and tag statistics to the release log.
+ */
+RTDECL(void) RTMemTrackerDumpAllToLogRel(void);
+
+/**
+ * Dumps all the allocations and tag statistics to standard out.
+ */
+RTDECL(void) RTMemTrackerDumpAllToStdOut(void);
+
+/**
+ * Dumps all the allocations and tag statistics to standard err.
+ */
+RTDECL(void) RTMemTrackerDumpAllToStdErr(void);
+
+/**
+ * Dumps all the allocations and tag statistics to the specified filename.
+ */
+RTDECL(void) RTMemTrackerDumpAllToFile(const char *pszFilename);
+
+
+/**
+ * Dumps all the tag statistics to the log.
+ *
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+RTDECL(void) RTMemTrackerDumpStatsToLog(bool fVerbose);
+
+/**
+ * Dumps all the tag statistics to the release log.
+ *
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+RTDECL(void) RTMemTrackerDumpStatsToLogRel(bool fVerbose);
+
+/**
+ * Dumps all the tag statistics to standard out.
+ *
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+RTDECL(void) RTMemTrackerDumpStatsToStdOut(bool fVerbose);
+
+/**
+ * Dumps all the tag statistics to standard err.
+ *
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ */
+RTDECL(void) RTMemTrackerDumpStatsToStdErr(bool fVerbose);
+
+/**
+ * Dumps all the tag statistics to the specified filename.
+ *
+ * @param fVerbose Whether to print all the stats or just the ones
+ * relevant to hunting leaks.
+ * @param pszFilename The name of the file to dump to.
+ */
+RTDECL(void) RTMemTrackerDumpStatsToFile(bool fVerbose, const char *pszFilename);
+
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/message.h b/include/iprt/message.h
new file mode 100644
index 00000000..b70a79be
--- /dev/null
+++ b/include/iprt/message.h
@@ -0,0 +1,198 @@
+/** @file
+ * IPRT - Message Formatting.
+ */
+
+/*
+ * 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 ___iprt_msg_h
+#define ___iprt_msg_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_msg RTMsg - Message Formatting
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Sets the program name to use.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The program name format string.
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTMsgSetProgName(const char *pszFormat, ...);
+
+/**
+ * Print error message to standard error.
+ *
+ * The message will be prefixed with the file name part of process image name
+ * (i.e. no path) and "error: ". If the message doesn't end with a new line,
+ * one will be added. The caller should call this with an empty string if
+ * unsure whether the cursor is currently position at the start of a new line.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message format string.
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTMsgError(const char *pszFormat, ...);
+
+/**
+ * Print error message to standard error.
+ *
+ * The message will be prefixed with the file name part of process image name
+ * (i.e. no path) and "error: ". If the message doesn't end with a new line,
+ * one will be added. The caller should call this with an empty string if
+ * unsure whether the cursor is currently position at the start of a new line.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message format string.
+ * @param va Format arguments.
+ */
+RTDECL(int) RTMsgErrorV(const char *pszFormat, va_list va);
+
+/**
+ * Same as RTMsgError() except for the return value.
+ *
+ * @returns @a enmExitCode
+ * @param enmExitCode What to exit code to return. This is mainly for
+ * saving some vertical space in the source file.
+ * @param pszFormat The message format string.
+ * @param ... Format arguments.
+ */
+RTDECL(RTEXITCODE) RTMsgErrorExit(RTEXITCODE enmExitcode, const char *pszFormat, ...);
+
+/**
+ * Same as RTMsgErrorV() except for the return value.
+ *
+ * @returns @a enmExitCode
+ * @param enmExitCode What to exit code to return. This is mainly for
+ * saving some vertical space in the source file.
+ * @param pszFormat The message format string.
+ * @param va Format arguments.
+ */
+RTDECL(RTEXITCODE) RTMsgErrorExitV(RTEXITCODE enmExitCode, const char *pszFormat, va_list va);
+
+/**
+ * Same as RTMsgError() except for the return value.
+ *
+ * @returns @a rcRet
+ * @param rcRet What IPRT status to return. This is mainly for
+ * saving some vertical space in the source file.
+ * @param pszFormat The message format string.
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTMsgErrorRc(int rc, const char *pszFormat, ...);
+
+/**
+ * Same as RTMsgErrorV() except for the return value.
+ *
+ * @returns @a rcRet
+ * @param rcRet What IPRT status to return. This is mainly for
+ * saving some vertical space in the source file.
+ * @param pszFormat The message format string.
+ * @param va Format arguments.
+ */
+RTDECL(int) RTMsgErrorRcV(int rc, const char *pszFormat, va_list va);
+
+/**
+ * Print an error message for a RTR3Init failure and suggest an exit code.
+ *
+ * @code
+ *
+ * int rc = RTR3Init();
+ * if (RT_FAILURE(rc))
+ * return RTMsgInitFailure(rc);
+ *
+ * @endcode
+ *
+ * @returns Appropriate exit code.
+ * @param rcRTR3Init The status code returned by RTR3Init.
+ */
+RTDECL(RTEXITCODE) RTMsgInitFailure(int rcRTR3Init);
+
+/**
+ * Print informational message to standard error.
+ *
+ * The message will be prefixed with the file name part of process image name
+ * (i.e. no path) and "warning: ". If the message doesn't end with a new line,
+ * one will be added. The caller should call this with an empty string if
+ * unsure whether the cursor is currently position at the start of a new line.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message format string.
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTMsgWarning(const char *pszFormat, ...);
+
+/**
+ * Print informational message to standard error.
+ *
+ * The message will be prefixed with the file name part of process image name
+ * (i.e. no path) and "warning: ". If the message doesn't end with a new line,
+ * one will be added. The caller should call this with an empty string if
+ * unsure whether the cursor is currently position at the start of a new line.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message format string.
+ * @param va Format arguments.
+ */
+RTDECL(int) RTMsgWarningV(const char *pszFormat, va_list va);
+
+/**
+ * Print informational message to standard output.
+ *
+ * The message will be prefixed with the file name part of process image name
+ * (i.e. no path) and "info: ". If the message doesn't end with a new line,
+ * one will be added. The caller should call this with an empty string if
+ * unsure whether the cursor is currently position at the start of a new line.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message format string.
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTMsgInfo(const char *pszFormat, ...);
+
+/**
+ * Print informational message to standard output.
+ *
+ * The message will be prefixed with the file name part of process image name
+ * (i.e. no path) and "info: ". If the message doesn't end with a new line,
+ * one will be added. The caller should call this with an empty string if
+ * unsure whether the cursor is currently position at the start of a new line.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message format string.
+ * @param va Format arguments.
+ */
+RTDECL(int) RTMsgInfoV(const char *pszFormat, va_list va);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/mp.h b/include/iprt/mp.h
new file mode 100644
index 00000000..70c0bf5e
--- /dev/null
+++ b/include/iprt/mp.h
@@ -0,0 +1,365 @@
+/** @file
+ * IPRT - Multiprocessor.
+ */
+
+/*
+ * 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 ___iprt_mp_h
+#define ___iprt_mp_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_mp RTMp - Multiprocessor
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Gets the identifier of the CPU executing the call.
+ *
+ * When called from a system mode where scheduling is active, like ring-3 or
+ * kernel mode with interrupts enabled on some systems, no assumptions should
+ * be made about the current CPU when the call returns.
+ *
+ * @returns CPU Id.
+ */
+RTDECL(RTCPUID) RTMpCpuId(void);
+
+/**
+ * Converts a CPU identifier to a CPU set index.
+ *
+ * This may or may not validate the presence of the CPU.
+ *
+ * @returns The CPU set index on success, -1 on failure.
+ * @param idCpu The identifier of the CPU.
+ */
+RTDECL(int) RTMpCpuIdToSetIndex(RTCPUID idCpu);
+
+/**
+ * Converts a CPU set index to a a CPU identifier.
+ *
+ * This may or may not validate the presence of the CPU, so, use
+ * RTMpIsCpuPossible for that.
+ *
+ * @returns The corresponding CPU identifier, NIL_RTCPUID on failure.
+ * @param iCpu The CPU set index.
+ */
+RTDECL(RTCPUID) RTMpCpuIdFromSetIndex(int iCpu);
+
+/**
+ * Gets the max CPU identifier (inclusive).
+ *
+ * Intended for brute force enumerations, but use with
+ * care as it may be expensive.
+ *
+ * @returns The current higest CPU identifier value.
+ */
+RTDECL(RTCPUID) RTMpGetMaxCpuId(void);
+
+/**
+ * Gets the size of a CPU array that is indexed by CPU set index.
+ *
+ * This takes both online, offline and hot-plugged cpus into account.
+ *
+ * @returns Number of elements.
+ *
+ * @remarks Use RTMpCpuIdToSetIndex to convert a RTCPUID into an array index.
+ */
+RTDECL(uint32_t) RTMpGetArraySize(void);
+
+/**
+ * Checks if a CPU exists in the system or may possibly be hotplugged later.
+ *
+ * @returns true/false accordingly.
+ * @param idCpu The identifier of the CPU.
+ */
+RTDECL(bool) RTMpIsCpuPossible(RTCPUID idCpu);
+
+/**
+ * Gets set of the CPUs present in the system plus any that may
+ * possibly be hotplugged later.
+ *
+ * @returns pSet.
+ * @param pSet Where to put the set.
+ */
+RTDECL(PRTCPUSET) RTMpGetSet(PRTCPUSET pSet);
+
+/**
+ * Get the count of CPUs present in the system plus any that may
+ * possibly be hotplugged later.
+ *
+ * @returns The count.
+ * @remarks Don't use this for CPU array sizing, use RTMpGetArraySize instead.
+ */
+RTDECL(RTCPUID) RTMpGetCount(void);
+
+
+/**
+ * Gets set of the CPUs present that are currently online.
+ *
+ * @returns pSet.
+ * @param pSet Where to put the set.
+ */
+RTDECL(PRTCPUSET) RTMpGetOnlineSet(PRTCPUSET pSet);
+
+/**
+ * Get the count of CPUs that are currently online.
+ *
+ * @return The count.
+ */
+RTDECL(RTCPUID) RTMpGetOnlineCount(void);
+
+/**
+ * Checks if a CPU is online or not.
+ *
+ * @returns true/false accordingly.
+ * @param idCpu The identifier of the CPU.
+ */
+RTDECL(bool) RTMpIsCpuOnline(RTCPUID idCpu);
+
+
+/**
+ * Gets set of the CPUs present in the system.
+ *
+ * @returns pSet.
+ * @param pSet Where to put the set.
+ */
+RTDECL(PRTCPUSET) RTMpGetPresentSet(PRTCPUSET pSet);
+
+/**
+ * Get the count of CPUs that are present in the system.
+ *
+ * @return The count.
+ */
+RTDECL(RTCPUID) RTMpGetPresentCount(void);
+
+/**
+ * Checks if a CPU is present in the system.
+ *
+ * @returns true/false accordingly.
+ * @param idCpu The identifier of the CPU.
+ */
+RTDECL(bool) RTMpIsCpuPresent(RTCPUID idCpu);
+
+
+/**
+ * Get the current frequency of a CPU.
+ *
+ * The CPU must be online.
+ *
+ * @returns The frequency as MHz. 0 if the CPU is offline
+ * or the information is not available.
+ * @param idCpu The identifier of the CPU.
+ */
+RTDECL(uint32_t) RTMpGetCurFrequency(RTCPUID idCpu);
+
+/**
+ * Get the maximum frequency of a CPU.
+ *
+ * The CPU must be online.
+ *
+ * @returns The frequency as MHz. 0 if the CPU is offline
+ * or the information is not available.
+ * @param idCpu The identifier of the CPU.
+ */
+RTDECL(uint32_t) RTMpGetMaxFrequency(RTCPUID idCpu);
+
+/**
+ * Get the CPU description string.
+ *
+ * The CPU must be online.
+ *
+ * @returns IPRT status code.
+ * @param idCpu The identifier of the CPU.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ */
+RTDECL(int) RTMpGetDescription(RTCPUID idCpu, char *pszBuf, size_t cbBuf);
+
+
+#ifdef IN_RING0
+
+/**
+ * Check if there's work (DPCs on Windows) pending on the current CPU.
+ *
+ * @return true if there's pending work on the current CPU, false otherwise.
+ */
+RTDECL(bool) RTMpIsCpuWorkPending(void);
+
+
+/**
+ * Worker function passed to RTMpOnAll, RTMpOnOthers and RTMpOnSpecific that
+ * is to be called on the target cpus.
+ *
+ * @param idCpu The identifier for the CPU the function is called on.
+ * @param pvUser1 The 1st user argument.
+ * @param pvUser2 The 2nd user argument.
+ */
+typedef DECLCALLBACK(void) FNRTMPWORKER(RTCPUID idCpu, void *pvUser1, void *pvUser2);
+/** Pointer to a FNRTMPWORKER. */
+typedef FNRTMPWORKER *PFNRTMPWORKER;
+
+/**
+ * Executes a function on each (online) CPU in the system.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
+ *
+ * @param pfnWorker The worker function.
+ * @param pvUser1 The first user argument for the worker.
+ * @param pvUser2 The second user argument for the worker.
+ *
+ * @remarks The execution isn't in any way guaranteed to be simultaneous,
+ * it might even be serial (cpu by cpu).
+ */
+RTDECL(int) RTMpOnAll(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+
+/**
+ * Executes a function on a all other (online) CPUs in the system.
+ *
+ * The caller must disable preemption prior to calling this API if the outcome
+ * is to make any sense. But do *not* disable interrupts.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
+ *
+ * @param pfnWorker The worker function.
+ * @param pvUser1 The first user argument for the worker.
+ * @param pvUser2 The second user argument for the worker.
+ *
+ * @remarks The execution isn't in any way guaranteed to be simultaneous,
+ * it might even be serial (cpu by cpu).
+ */
+RTDECL(int) RTMpOnOthers(PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+
+/**
+ * Executes a function on a specific CPU in the system.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the system.
+ * @retval VERR_CPU_OFFLINE if the CPU is offline.
+ * @retval VERR_CPU_NOT_FOUND if the CPU wasn't found.
+ *
+ * @param idCpu The id of the CPU.
+ * @param pfnWorker The worker function.
+ * @param pvUser1 The first user argument for the worker.
+ * @param pvUser2 The second user argument for the worker.
+ */
+RTDECL(int) RTMpOnSpecific(RTCPUID idCpu, PFNRTMPWORKER pfnWorker, void *pvUser1, void *pvUser2);
+
+/**
+ * Pokes the specified CPU.
+ *
+ * This should cause the execution on the CPU to be interrupted and forcing it
+ * to enter kernel context. It is optimized version of a RTMpOnSpecific call
+ * with a worker which returns immediately.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if this kind of operation isn't supported by the
+ * system. The caller must not automatically assume that this API works
+ * when any of the RTMpOn* APIs works. This is because not all systems
+ * supports unicast MP events and this API will not be implemented as a
+ * broadcast.
+ * @retval VERR_CPU_OFFLINE if the CPU is offline.
+ * @retval VERR_CPU_NOT_FOUND if the CPU wasn't found.
+ *
+ * @param idCpu The id of the CPU to poke.
+ */
+RTDECL(int) RTMpPokeCpu(RTCPUID idCpu);
+
+
+/**
+ * MP event, see FNRTMPNOTIFICATION.
+ */
+typedef enum RTMPEVENT
+{
+ /** The CPU goes online. */
+ RTMPEVENT_ONLINE = 1,
+ /** The CPU goes offline. */
+ RTMPEVENT_OFFLINE
+} RTMPEVENT;
+
+/**
+ * Notification callback.
+ *
+ * The context this is called in differs a bit from platform to
+ * platform, so be careful while in here.
+ *
+ * @param idCpu The CPU this applies to.
+ * @param enmEvent The event.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(void) FNRTMPNOTIFICATION(RTMPEVENT enmEvent, RTCPUID idCpu, void *pvUser);
+/** Pointer to a FNRTMPNOTIFICATION(). */
+typedef FNRTMPNOTIFICATION *PFNRTMPNOTIFICATION;
+
+/**
+ * Registers a notification callback for cpu events.
+ *
+ * On platforms which doesn't do cpu offline/online events this API
+ * will just be a no-op that pretends to work.
+ *
+ * @todo We'll be adding a flag to this soon to indicate whether the callback should be called on all
+ * CPUs that are currently online while it's being registered. This is to help avoid some race
+ * conditions (we'll hopefully be able to implement this on linux, solaris/win is no issue).
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NO_MEMORY if a registration record cannot be allocated.
+ * @retval VERR_ALREADY_EXISTS if the pfnCallback and pvUser already exist
+ * in the callback list.
+ *
+ * @param pfnCallback The callback.
+ * @param pvUser The user argument to the callback function.
+ */
+RTDECL(int) RTMpNotificationRegister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
+
+/**
+ * This deregisters a notification callback registered via RTMpNotificationRegister().
+ *
+ * The pfnCallback and pvUser arguments must be identical to the registration call
+ * of we won't find the right entry.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NOT_FOUND if no matching entry was found.
+ *
+ * @param pfnCallback The callback.
+ * @param pvUser The user argument to the callback function.
+ */
+RTDECL(int) RTMpNotificationDeregister(PFNRTMPNOTIFICATION pfnCallback, void *pvUser);
+
+#endif /* IN_RING0 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/net.h b/include/iprt/net.h
new file mode 100644
index 00000000..38e066b9
--- /dev/null
+++ b/include/iprt/net.h
@@ -0,0 +1,816 @@
+/** @file
+ * IPRT - Network Protocols.
+ */
+
+/*
+ * 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 ___iprt_net_h
+#define ___iprt_net_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_net RTNet - Network Protocols
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * IPv4 address.
+ */
+typedef RTUINT32U RTNETADDRIPV4;
+AssertCompileSize(RTNETADDRIPV4, 4);
+/** Pointer to a IPv4 address. */
+typedef RTNETADDRIPV4 *PRTNETADDRIPV4;
+/** Pointer to a const IPv4 address. */
+typedef RTNETADDRIPV4 const *PCRTNETADDRIPV4;
+
+/**
+ * Tests if the given string is an IPv4 address.
+ *
+ * @returns boolean.
+ * @param pszAddress String which may be an IPv4 address.
+ */
+RTDECL(bool) RTNetIsIPv4AddrStr(const char *pszAddress);
+
+
+/**
+ * IPv6 address.
+ */
+typedef RTUINT128U RTNETADDRIPV6;
+AssertCompileSize(RTNETADDRIPV6, 16);
+/** Pointer to a IPv6 address. */
+typedef RTNETADDRIPV6 *PRTNETADDRIPV6;
+/** Pointer to a const IPv6 address. */
+typedef RTNETADDRIPV6 const *PCRTNETADDRIPV6;
+
+/**
+ * Tests if the given string is a valid IPv6 address.
+ *
+ * @returns @c true if it is, @c false if not.
+ * @param pszAddress String which may be an IPv6 address.
+ */
+RTDECL(bool) RTNetIsIPv6AddrStr(const char *pszAddress);
+
+
+/**
+ * IPX address.
+ */
+#pragma pack(1)
+typedef struct RTNETADDRIPX
+{
+ /** The network ID. */
+ uint32_t Network;
+ /** The node ID. (Defaults to the MAC address apparently.) */
+ RTMAC Node;
+} RTNETADDRIPX;
+#pragma pack()
+AssertCompileSize(RTNETADDRIPX, 4+6);
+/** Pointer to an IPX address. */
+typedef RTNETADDRIPX *PRTNETADDRIPX;
+/** Pointer to a const IPX address. */
+typedef RTNETADDRIPX const *PCRTNETADDRIPX;
+
+/**
+ * Network address union.
+ *
+ * @remarks The size of this structure may change in the future.
+ */
+typedef union RTNETADDRU
+{
+ /** 64-bit view. */
+ uint64_t au64[2];
+ /** 32-bit view. */
+ uint32_t au32[4];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 8-bit view. */
+ uint8_t au8[16];
+ /** IPv4 view. */
+ RTNETADDRIPV4 IPv4;
+#ifndef IPv6 /* Work around X11 and RDP defining IPv6 to 1. */
+ /** IPv6 view. */
+ RTNETADDRIPV6 IPv6;
+#endif
+ /** IPX view. */
+ RTNETADDRIPX Ipx;
+ /** MAC address view. */
+ RTMAC Mac;
+} RTNETADDRU;
+AssertCompileSize(RTNETADDRU, 16);
+/** Pointer to an address union. */
+typedef RTNETADDRU *PRTNETADDRU;
+/** Pointer to a const address union. */
+typedef RTNETADDRU const *PCRTNETADDRU;
+
+/**
+ * Network address type.
+ *
+ * @remarks The value assignments may change in the future.
+ */
+typedef enum RTNETADDRTYPE
+{
+ /** The invalid 0 entry. */
+ RTNETADDRTYPE_INVALID = 0,
+ /** IP version 4. */
+ RTNETADDRTYPE_IPV4,
+ /** IP version 6. */
+ RTNETADDRTYPE_IPV6,
+ /** IPX. */
+ RTNETADDRTYPE_IPX,
+ /** MAC address. */
+ RTNETADDRTYPE_MAC,
+ /** The end of the valid values. */
+ RTNETADDRTYPE_END,
+ /** The usual 32-bit hack. */
+ RTNETADDRTYPE_32_BIT_HACK = 0x7fffffff
+} RTNETADDRTYPE;
+/** Pointer to a network address type. */
+typedef RTNETADDRTYPE *PRTNETADDRTYPE;
+/** Pointer to a const network address type. */
+typedef RTNETADDRTYPE const *PCRTNETADDRTYPE;
+
+/**
+ * Network address.
+ *
+ * @remarks The size and type values may change.
+ */
+typedef struct RTNETADDR
+{
+ /** The address union. */
+ RTNETADDRU uAddr;
+ /** Indicates which view of @a u that is valid. */
+ RTNETADDRTYPE enmType;
+ /** The port number for IPv4 and IPv6 addresses. This is set to
+ * RTNETADDR_NA_PORT if not applicable. */
+ uint32_t uPort;
+} RTNETADDR;
+/** Pointer to a network address. */
+typedef RTNETADDR *PRTNETADDR;
+/** Pointer to a const network address. */
+typedef RTNETADDR const *PCRTNETADDR;
+
+/** The not applicable value of RTNETADDR::uPort value use to inid. */
+#define RTNETADDR_PORT_NA UINT32_MAX
+
+/**
+ * Ethernet header.
+ */
+#pragma pack(1)
+typedef struct RTNETETHERHDR
+{
+ RTMAC DstMac;
+ RTMAC SrcMac;
+ /** Ethernet frame type or frame size, depending on the kind of ethernet.
+ * This is big endian on the wire. */
+ uint16_t EtherType;
+} RTNETETHERHDR;
+#pragma pack()
+AssertCompileSize(RTNETETHERHDR, 14);
+/** Pointer to an ethernet header. */
+typedef RTNETETHERHDR *PRTNETETHERHDR;
+/** Pointer to a const ethernet header. */
+typedef RTNETETHERHDR const *PCRTNETETHERHDR;
+
+/** @name EtherType (RTNETETHERHDR::EtherType)
+ * @{ */
+#define RTNET_ETHERTYPE_IPV4 UINT16_C(0x0800)
+#define RTNET_ETHERTYPE_ARP UINT16_C(0x0806)
+#define RTNET_ETHERTYPE_IPV6 UINT16_C(0x86dd)
+#define RTNET_ETHERTYPE_VLAN UINT16_C(0x8100)
+#define RTNET_ETHERTYPE_IPX_1 UINT16_C(0x8037)
+#define RTNET_ETHERTYPE_IPX_2 UINT16_C(0x8137)
+#define RTNET_ETHERTYPE_IPX_3 UINT16_C(0x8138)
+/** @} */
+
+
+/**
+ * IPv4 header.
+ * All is bigendian on the wire.
+ */
+#pragma pack(1)
+typedef struct RTNETIPV4
+{
+#ifdef RT_BIG_ENDIAN
+ unsigned int ip_v : 4;
+ unsigned int ip_hl : 4;
+ unsigned int ip_tos : 8;
+ unsigned int ip_len : 16;
+#else
+ /** 00:0 - Header length given as a 32-bit word count. */
+ unsigned int ip_hl : 4;
+ /** 00:4 - Header version. */
+ unsigned int ip_v : 4;
+ /** 01 - Type of service. */
+ unsigned int ip_tos : 8;
+ /** 02 - Total length (header + data). */
+ unsigned int ip_len : 16;
+#endif
+ /** 04 - Packet idenficiation. */
+ uint16_t ip_id;
+ /** 06 - Offset if fragmented. */
+ uint16_t ip_off;
+ /** 08 - Time to live. */
+ uint8_t ip_ttl;
+ /** 09 - Protocol. */
+ uint8_t ip_p;
+ /** 0a - Header check sum. */
+ uint16_t ip_sum;
+ /** 0c - Source address. */
+ RTNETADDRIPV4 ip_src;
+ /** 10 - Destination address. */
+ RTNETADDRIPV4 ip_dst;
+ /** 14 - Options (optional). */
+ uint32_t ip_options[1];
+} RTNETIPV4;
+#pragma pack()
+AssertCompileSize(RTNETIPV4, 6 * 4);
+/** Pointer to a IPv4 header. */
+typedef RTNETIPV4 *PRTNETIPV4;
+/** Pointer to a const IPv4 header. */
+typedef RTNETIPV4 const *PCRTNETIPV4;
+
+/** The minimum IPv4 header length (in bytes).
+ * Up to and including RTNETIPV4::ip_dst. */
+#define RTNETIPV4_MIN_LEN (20)
+
+
+/** @name IPv4 Protocol Numbers
+ * @{ */
+/** IPv4: ICMP */
+#define RTNETIPV4_PROT_ICMP (1)
+/** IPv4: TCP */
+#define RTNETIPV4_PROT_TCP (6)
+/** IPv4: UDP */
+#define RTNETIPV4_PROT_UDP (17)
+/** @} */
+
+/** @name Common IPv4 Port Assignments
+ * @{
+ */
+/** Boostrap Protocol / DHCP) Server. */
+#define RTNETIPV4_PORT_BOOTPS (67)
+/** Boostrap Protocol / DHCP) Client. */
+#define RTNETIPV4_PORT_BOOTPC (68)
+/** @} */
+
+/** @name IPv4 Flags
+ * @{ */
+/** IPv4: Don't fragment */
+#define RTNETIPV4_FLAGS_DF (0x4000)
+/** IPv4: More fragments */
+#define RTNETIPV4_FLAGS_MF (0x2000)
+/** @} */
+
+RTDECL(uint16_t) RTNetIPv4HdrChecksum(PCRTNETIPV4 pIpHdr);
+RTDECL(bool) RTNetIPv4IsHdrValid(PCRTNETIPV4 pIpHdr, size_t cbHdrMax, size_t cbPktMax, bool fChecksum);
+RTDECL(uint32_t) RTNetIPv4PseudoChecksum(PCRTNETIPV4 pIpHdr);
+RTDECL(uint32_t) RTNetIPv4PseudoChecksumBits(RTNETADDRIPV4 SrcAddr, RTNETADDRIPV4 DstAddr, uint8_t bProtocol, uint16_t cbPkt);
+RTDECL(uint32_t) RTNetIPv4AddDataChecksum(void const *pvData, size_t cbData, uint32_t u32Sum, bool *pfOdd);
+RTDECL(uint16_t) RTNetIPv4FinalizeChecksum(uint32_t u32Sum);
+
+
+/**
+ * IPv6 header.
+ * All is bigendian on the wire.
+ */
+#pragma pack(1)
+typedef struct RTNETIPV6
+{
+ /** Version (4 bits), Traffic Class (8 bits) and Flow Lable (20 bits).
+ * @todo this is probably mislabeled - ip6_flow vs. ip6_vfc, fix later. */
+ uint32_t ip6_vfc;
+ /** 04 - Payload length, including extension headers. */
+ uint16_t ip6_plen;
+ /** 06 - Next header type (RTNETIPV4_PROT_XXX). */
+ uint8_t ip6_nxt;
+ /** 07 - Hop limit. */
+ uint8_t ip6_hlim;
+ /** xx - Source address. */
+ RTNETADDRIPV6 ip6_src;
+ /** xx - Destination address. */
+ RTNETADDRIPV6 ip6_dst;
+} RTNETIPV6;
+#pragma pack()
+AssertCompileSize(RTNETIPV6, 8 + 16 + 16);
+/** Pointer to a IPv6 header. */
+typedef RTNETIPV6 *PRTNETIPV6;
+/** Pointer to a const IPv6 header. */
+typedef RTNETIPV6 const *PCRTNETIPV6;
+
+/** The minimum IPv6 header length (in bytes).
+ * Up to and including RTNETIPV6::ip6_dst. */
+#define RTNETIPV6_MIN_LEN (40)
+
+RTDECL(uint32_t) RTNetIPv6PseudoChecksum(PCRTNETIPV6 pIpHdr);
+RTDECL(uint32_t) RTNetIPv6PseudoChecksumEx(PCRTNETIPV6 pIpHdr, uint8_t bProtocol, uint16_t cbPkt);
+RTDECL(uint32_t) RTNetIPv6PseudoChecksumBits(PCRTNETADDRIPV6 pSrcAddr, PCRTNETADDRIPV6 pDstAddr,
+ uint8_t bProtocol, uint16_t cbPkt);
+
+
+/**
+ * UDP header.
+ */
+#pragma pack(1)
+typedef struct RTNETUDP
+{
+ /** The source port. */
+ uint16_t uh_sport;
+ /** The destination port. */
+ uint16_t uh_dport;
+ /** The length of the UDP header and associated data. */
+ uint16_t uh_ulen;
+ /** The checksum of the pseudo header, the UDP header and the data. */
+ uint16_t uh_sum;
+} RTNETUDP;
+#pragma pack()
+AssertCompileSize(RTNETUDP, 8);
+/** Pointer to an UDP header. */
+typedef RTNETUDP *PRTNETUDP;
+/** Pointer to a const UDP header. */
+typedef RTNETUDP const *PCRTNETUDP;
+
+/** The minimum UDP packet length (in bytes). (RTNETUDP::uh_ulen) */
+#define RTNETUDP_MIN_LEN (8)
+
+RTDECL(uint16_t) RTNetUDPChecksum(uint32_t u32Sum, PCRTNETUDP pUdpHdr);
+RTDECL(uint32_t) RTNetIPv4AddUDPChecksum(PCRTNETUDP pUdpHdr, uint32_t u32Sum);
+RTDECL(uint16_t) RTNetIPv4UDPChecksum(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, void const *pvData);
+RTDECL(bool) RTNetIPv4IsUDPSizeValid(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, size_t cbPktMax);
+RTDECL(bool) RTNetIPv4IsUDPValid(PCRTNETIPV4 pIpHdr, PCRTNETUDP pUdpHdr, void const *pvData, size_t cbPktMax, bool fChecksum);
+
+
+/**
+ * IPv4 BOOTP / DHCP packet.
+ */
+#pragma pack(1)
+typedef struct RTNETBOOTP
+{
+ /** 00 - The packet opcode (RTNETBOOTP_OP_*). */
+ uint8_t bp_op;
+ /** 01 - Hardware address type. Same as RTNETARPHDR::ar_htype. */
+ uint8_t bp_htype;
+ /** 02 - Hardware address length. */
+ uint8_t bp_hlen;
+ /** 03 - Gateway hops. */
+ uint8_t bp_hops;
+ /** 04 - Transaction ID. */
+ uint32_t bp_xid;
+ /** 08 - Seconds since boot started. */
+ uint16_t bp_secs;
+ /** 0a - Unused (BOOTP) / Flags (DHCP) (RTNET_DHCP_FLAGS_*). */
+ uint16_t bp_flags;
+ /** 0c - Client IPv4 address. */
+ RTNETADDRIPV4 bp_ciaddr;
+ /** 10 - Your IPv4 address. */
+ RTNETADDRIPV4 bp_yiaddr;
+ /** 14 - Server IPv4 address. */
+ RTNETADDRIPV4 bp_siaddr;
+ /** 18 - Gateway IPv4 address. */
+ RTNETADDRIPV4 bp_giaddr;
+ /** 1c - Client hardware address. */
+ union
+ {
+ uint8_t au8[16];
+ RTMAC Mac;
+ } bp_chaddr;
+ /** 2c - Server name. */
+ uint8_t bp_sname[64];
+ /** 6c - File name / more DHCP options. */
+ uint8_t bp_file[128];
+ /** ec - Vendor specific area (BOOTP) / Options (DHCP).
+ * @remark This is really 312 bytes in the DHCP version. */
+ union
+ {
+ uint8_t au8[128];
+ struct DHCP
+ {
+ /** ec - The DHCP cookie (RTNET_DHCP_COOKIE). */
+ uint32_t dhcp_cookie;
+ /** f0 - The DHCP options. */
+ uint8_t dhcp_opts[124];
+ } Dhcp;
+ } bp_vend;
+
+} RTNETBOOTP;
+#pragma pack()
+AssertCompileSize(RTNETBOOTP, 0xec + 128);
+/** Pointer to a BOOTP / DHCP packet. */
+typedef RTNETBOOTP *PRTNETBOOTP;
+/** Pointer to a const BOOTP / DHCP packet. */
+typedef RTNETBOOTP const *PCRTNETBOOTP;
+
+/** Minimum BOOTP packet length. For quick validation, no standard thing really. */
+#define RTNETBOOTP_MIN_LEN 0xec
+/** Minimum DHCP packet length. For quick validation, no standard thing really. */
+#define RTNETBOOTP_DHCP_MIN_LEN 0xf1
+
+/** The normal size of the a DHCP packet (i.e. a RTNETBOOTP).
+ * Same as RTNET_DHCP_OPT_SIZE, just expressed differently. */
+#define RTNET_DHCP_NORMAL_SIZE (0xec + 4 + RTNET_DHCP_OPT_SIZE)
+/** The normal size of RTNETBOOTP::bp_vend::Dhcp::dhcp_opts. */
+#define RTNET_DHCP_OPT_SIZE (312 - 4)
+
+/** @name BOOTP packet opcode values
+ * @{ */
+#define RTNETBOOTP_OP_REQUEST 1
+#define RTNETBOOTP_OP_REPLY 2
+/** @} */
+
+/** @name DHCP flags (RTNETBOOTP::bp_flags)
+ * @{ */
+#define RTNET_DHCP_FLAGS_NO_BROADCAST UINT16_C(0x8000) /** @todo check test!!! */
+/** @} */
+
+/** The DHCP cookie (network endian). */
+#define RTNET_DHCP_COOKIE UINT32_C(0x63825363)
+
+/**
+ * An IPv4 DHCP option header.
+ */
+typedef struct RTNETDHCPOPT
+{
+ /** 00 - The DHCP option. */
+ uint8_t dhcp_opt;
+ /** 01 - The data length (excluding this header). */
+ uint8_t dhcp_len;
+ /* 02 - The option data follows here, optional and of variable length. */
+} RTNETDHCPOPT;
+AssertCompileSize(RTNETDHCPOPT, 2);
+/** Pointer to a DHCP option header. */
+typedef RTNETDHCPOPT *PRTNETDHCPOPT;
+/** Pointer to a const DHCP option header. */
+typedef RTNETDHCPOPT const *PCRTNETDHCPOPT;
+
+/** @name DHCP options
+ * @{ */
+/** 1 byte padding, this has no dhcp_len field. */
+#define RTNET_DHCP_OPT_PAD 0
+
+/** The subnet mask. */
+#define RTNET_DHCP_OPT_SUBNET_MASK 1
+/** The time offset. */
+#define RTNET_DHCP_OPT_TIME_OFFSET 2
+/** The routers for the subnet. */
+#define RTNET_DHCP_OPT_ROUTERS 3
+/** Domain Name Server. */
+#define RTNET_DHCP_OPT_DNS 6
+/** Host name. */
+#define RTNET_DHCP_OPT_HOST_NAME 12
+/** Domain name. */
+#define RTNET_DHCP_OPT_DOMAIN_NAME 15
+
+/** The requested address. */
+#define RTNET_DHCP_OPT_REQ_ADDR 50
+/** The lease time in seconds. */
+#define RTNET_DHCP_OPT_LEASE_TIME 51
+/** Option overload.
+ * Indicates that the bp_file and/or bp_sname holds contains DHCP options. */
+#define RTNET_DHCP_OPT_OPTION_OVERLOAD 52
+/** Have a 8-bit message type value as data, see RTNET_DHCP_MT_*. */
+#define RTNET_DHCP_OPT_MSG_TYPE 53
+/** Server ID. */
+#define RTNET_DHCP_OPT_SERVER_ID 54
+/** Parameter request list. */
+#define RTNET_DHCP_OPT_PARAM_REQ_LIST 55
+/** The maximum DHCP message size a client is willing to accept. */
+#define RTNET_DHCP_OPT_MAX_DHCP_MSG_SIZE 57
+/** Client ID. */
+#define RTNET_DHCP_OPT_CLIENT_ID 61
+/** TFTP server name. */
+#define RTNET_DHCP_OPT_TFTP_SERVER_NAME 66
+/** Bootfile name. */
+#define RTNET_DHCP_OPT_BOOTFILE_NAME 67
+
+/** Marks the end of the DHCP options, this has no dhcp_len field. */
+#define RTNET_DHCP_OPT_END 255
+/** @} */
+
+/** @name DHCP Message Types (option 53)
+ * @{ */
+#define RTNET_DHCP_MT_DISCOVER 1
+#define RTNET_DHCP_MT_OFFER 2
+#define RTNET_DHCP_MT_REQUEST 3
+#define RTNET_DHCP_MT_DECLINE 4
+#define RTNET_DHCP_MT_ACK 5
+#define RTNET_DHCP_MT_NAC 6
+#define RTNET_DHCP_MT_RELEASE 7
+#define RTNET_DHCP_MT_INFORM 8
+/** @} */
+
+/** @name DHCP Flags
+ * @{ */
+#define RTNET_DHCP_FLAG_BROADCAST 0x8000
+/** @} */
+
+RTDECL(bool) RTNetIPv4IsDHCPValid(PCRTNETUDP pUdpHdr, PCRTNETBOOTP pDhcp, size_t cbDhcp, uint8_t *pMsgType);
+
+
+/**
+ * IPv4 DHCP packet.
+ * @deprecated Use RTNETBOOTP.
+ */
+#pragma pack(1)
+typedef struct RTNETDHCP
+{
+ /** 00 - The packet opcode. */
+ uint8_t Op;
+ /** Hardware address type. */
+ uint8_t HType;
+ /** Hardware address length. */
+ uint8_t HLen;
+ uint8_t Hops;
+ uint32_t XID;
+ uint16_t Secs;
+ uint16_t Flags;
+ /** Client IPv4 address. */
+ RTNETADDRIPV4 CIAddr;
+ /** Your IPv4 address. */
+ RTNETADDRIPV4 YIAddr;
+ /** Server IPv4 address. */
+ RTNETADDRIPV4 SIAddr;
+ /** Gateway IPv4 address. */
+ RTNETADDRIPV4 GIAddr;
+ /** Client hardware address. */
+ uint8_t CHAddr[16];
+ /** Server name. */
+ uint8_t SName[64];
+ uint8_t File[128];
+ uint8_t abMagic[4];
+ uint8_t DhcpOpt;
+ uint8_t DhcpLen; /* 1 */
+ uint8_t DhcpReq;
+ uint8_t abOptions[57];
+} RTNETDHCP;
+#pragma pack()
+/** @todo AssertCompileSize(RTNETDHCP, ); */
+/** Pointer to a DHCP packet. */
+typedef RTNETDHCP *PRTNETDHCP;
+/** Pointer to a const DHCP packet. */
+typedef RTNETDHCP const *PCRTNETDHCP;
+
+
+/**
+ * TCP packet.
+ */
+#pragma pack(1)
+typedef struct RTNETTCP
+{
+ /** 00 - The source port. */
+ uint16_t th_sport;
+ /** 02 - The destination port. */
+ uint16_t th_dport;
+ /** 04 - The sequence number. */
+ uint32_t th_seq;
+ /** 08 - The acknowledgement number. */
+ uint32_t th_ack;
+#ifdef RT_BIG_ENDIAN
+ unsigned int th_win : 16;
+ unsigned int th_flags : 8;
+ unsigned int th_off : 4;
+ unsigned int th_x2 : 4;
+#else
+ /** 0c:0 - Reserved. */
+ unsigned int th_x2 : 4;
+ /** 0c:4 - The data offset given as a dword count from the start of this header. */
+ unsigned int th_off : 4;
+ /** 0d - flags. */
+ unsigned int th_flags : 8;
+ /** 0e - The window. */
+ unsigned int th_win : 16;
+#endif
+ /** 10 - The checksum of the pseudo header, the TCP header and the data. */
+ uint16_t th_sum;
+ /** 12 - The urgent pointer. */
+ uint16_t th_urp;
+ /* (options follows here and then the data (aka text).) */
+} RTNETTCP;
+#pragma pack()
+AssertCompileSize(RTNETTCP, 20);
+/** Pointer to a TCP packet. */
+typedef RTNETTCP *PRTNETTCP;
+/** Pointer to a const TCP packet. */
+typedef RTNETTCP const *PCRTNETTCP;
+
+/** The minimum TCP header length (in bytes). (RTNETTCP::th_off * 4) */
+#define RTNETTCP_MIN_LEN (20)
+
+/** @name TCP flags (RTNETTCP::th_flags)
+ * @{ */
+#define RTNETTCP_F_FIN 0x01
+#define RTNETTCP_F_SYN 0x02
+#define RTNETTCP_F_RST 0x04
+#define RTNETTCP_F_PSH 0x08
+#define RTNETTCP_F_ACK 0x10
+#define RTNETTCP_F_URG 0x20
+#define RTNETTCP_F_ECE 0x40
+#define RTNETTCP_F_CWR 0x80
+/** @} */
+
+RTDECL(uint16_t) RTNetTCPChecksum(uint32_t u32Sum, PCRTNETTCP pTcpHdr, void const *pvData, size_t cbData);
+RTDECL(uint32_t) RTNetIPv4AddTCPChecksum(PCRTNETTCP pTcpHdr, uint32_t u32Sum);
+RTDECL(uint16_t) RTNetIPv4TCPChecksum(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, void const *pvData);
+RTDECL(bool) RTNetIPv4IsTCPSizeValid(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, size_t cbHdrMax, size_t cbPktMax);
+RTDECL(bool) RTNetIPv4IsTCPValid(PCRTNETIPV4 pIpHdr, PCRTNETTCP pTcpHdr, size_t cbHdrMax, void const *pvData,
+ size_t cbPktMax, bool fChecksum);
+
+
+/**
+ * IPv4 ICMP packet header.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4HDR
+{
+ /** 00 - The ICMP message type. */
+ uint8_t icmp_type;
+ /** 01 - Type specific code that further qualifies the message. */
+ uint8_t icmp_code;
+ /** 02 - Checksum of the ICMP message. */
+ uint16_t icmp_cksum;
+} RTNETICMPV4HDR;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4HDR, 4);
+/** Pointer to an ICMP packet header. */
+typedef RTNETICMPV4HDR *PRTNETICMPV4HDR;
+/** Pointer to a const ICMP packet header. */
+typedef RTNETICMPV4HDR const *PCRTNETICMPV4HDR;
+
+/** @name ICMP (v4) message types.
+ * @{ */
+#define RTNETICMPV4_TYPE_ECHO_REPLY 0
+#define RTNETICMPV4_TYPE_ECHO_REQUEST 8
+#define RTNETICMPV4_TYPE_TRACEROUTE 30
+/** @} */
+
+/**
+ * IPv4 ICMP ECHO Reply & Request packet.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4ECHO
+{
+ /** 00 - The ICMP header. */
+ RTNETICMPV4HDR Hdr;
+ /** 04 - The identifier to help the requestor match up the reply.
+ * Can be 0. Typically fixed value. */
+ uint16_t icmp_id;
+ /** 06 - The sequence number to help the requestor match up the reply.
+ * Can be 0. Typically incrementing between requests. */
+ uint16_t icmp_seq;
+ /** 08 - Variable length data that is to be returned unmodified in the reply. */
+ uint8_t icmp_data[1];
+} RTNETICMPV4ECHO;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4ECHO, 9);
+/** Pointer to an ICMP ECHO packet. */
+typedef RTNETICMPV4ECHO *PRTNETICMPV4ECHO;
+/** Pointer to a const ICMP ECHO packet. */
+typedef RTNETICMPV4ECHO const *PCRTNETICMPV4ECHO;
+
+/**
+ * IPv4 ICMP TRACEROUTE packet.
+ * This is an reply to an IP packet with the traceroute option set.
+ */
+#pragma pack(1)
+typedef struct RTNETICMPV4TRACEROUTE
+{
+ /** 00 - The ICMP header. */
+ RTNETICMPV4HDR Hdr;
+ /** 04 - Identifier copied from the traceroute option's ID number. */
+ uint16_t icmp_id;
+ /** 06 - Unused. (Possibly an icmp_seq?) */
+ uint16_t icmp_void;
+ /** 08 - Outbound hop count. From the IP packet causing this message. */
+ uint16_t icmp_ohc;
+ /** 0a - Return hop count. From the IP packet causing this message. */
+ uint16_t icmp_rhc;
+ /** 0c - Output link speed, 0 if not known. */
+ uint32_t icmp_speed;
+ /** 10 - Output link MTU, 0 if not known. */
+ uint32_t icmp_mtu;
+} RTNETICMPV4TRACEROUTE;
+#pragma pack()
+AssertCompileSize(RTNETICMPV4TRACEROUTE, 20);
+/** Pointer to an ICMP TRACEROUTE packet. */
+typedef RTNETICMPV4TRACEROUTE *PRTNETICMPV4TRACEROUTE;
+/** Pointer to a const ICMP TRACEROUTE packet. */
+typedef RTNETICMPV4TRACEROUTE const *PCRTNETICMPV4TRACEROUTE;
+
+/** @todo add more ICMPv4 as needed. */
+
+/**
+ * IPv4 ICMP union packet.
+ */
+typedef union RTNETICMPV4
+{
+ RTNETICMPV4HDR Hdr;
+ RTNETICMPV4ECHO Echo;
+ RTNETICMPV4TRACEROUTE Traceroute;
+} RTNETICMPV4;
+/** Pointer to an ICMP union packet. */
+typedef RTNETICMPV4 *PRTNETICMPV4;
+/** Pointer to a const ICMP union packet. */
+typedef RTNETICMPV4 const *PCRTNETICMPV4;
+
+
+/** @todo add ICMPv6 when needed. */
+
+
+/**
+ * Ethernet ARP header.
+ */
+#pragma pack(1)
+typedef struct RTNETARPHDR
+{
+ /** The hardware type. */
+ uint16_t ar_htype;
+ /** The protocol type (ethertype). */
+ uint16_t ar_ptype;
+ /** The hardware address length. */
+ uint8_t ar_hlen;
+ /** The protocol address length. */
+ uint8_t ar_plen;
+ /** The operation. */
+ uint16_t ar_oper;
+} RTNETARPHDR;
+#pragma pack()
+AssertCompileSize(RTNETARPHDR, 8);
+/** Pointer to an ethernet ARP header. */
+typedef RTNETARPHDR *PRTNETARPHDR;
+/** Pointer to a const ethernet ARP header. */
+typedef RTNETARPHDR const *PCRTNETARPHDR;
+
+/** ARP hardware type - ethernet. */
+#define RTNET_ARP_ETHER UINT16_C(1)
+
+/** @name ARP operations
+ * @{ */
+#define RTNET_ARPOP_REQUEST UINT16_C(1) /**< Request hardware address given a protocol address (ARP). */
+#define RTNET_ARPOP_REPLY UINT16_C(2)
+#define RTNET_ARPOP_REVREQUEST UINT16_C(3) /**< Request protocol address given a hardware address (RARP). */
+#define RTNET_ARPOP_REVREPLY UINT16_C(4)
+#define RTNET_ARPOP_INVREQUEST UINT16_C(8) /**< Inverse ARP. */
+#define RTNET_ARPOP_INVREPLY UINT16_C(9)
+/** Check if an ARP operation is a request or not. */
+#define RTNET_ARPOP_IS_REQUEST(Op) ((Op) & 1)
+/** Check if an ARP operation is a reply or not. */
+#define RTNET_ARPOP_IS_REPLY(Op) (!RTNET_ARPOP_IS_REQUEST(Op))
+/** @} */
+
+
+/**
+ * Ethernet IPv4 + 6-byte MAC ARP request packet.
+ */
+#pragma pack(1)
+typedef struct RTNETARPIPV4
+{
+ /** ARP header. */
+ RTNETARPHDR Hdr;
+ /** The sender hardware address. */
+ RTMAC ar_sha;
+ /** The sender protocol address. */
+ RTNETADDRIPV4 ar_spa;
+ /** The target hardware address. */
+ RTMAC ar_tha;
+ /** The arget protocol address. */
+ RTNETADDRIPV4 ar_tpa;
+} RTNETARPIPV4;
+#pragma pack()
+AssertCompileSize(RTNETARPIPV4, 8+6+4+6+4);
+/** Pointer to an ethernet IPv4+MAC ARP request packet. */
+typedef RTNETARPIPV4 *PRTNETARPIPV4;
+/** Pointer to a const ethernet IPv4+MAC ARP request packet. */
+typedef RTNETARPIPV4 const *PCRTNETARPIPV4;
+
+
+/** @todo RTNETNDP (IPv6)*/
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/nocrt/amd64/fenv.h b/include/iprt/nocrt/amd64/fenv.h
new file mode 100644
index 00000000..002aa01f
--- /dev/null
+++ b/include/iprt/nocrt/amd64/fenv.h
@@ -0,0 +1,232 @@
+/** @file
+ * IPRT / No-CRT - fenv.h, AMD64.
+ */
+
+/*
+ * 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.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on:
+ *
+ * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef ___iprt_nocrt_amd64_fenv_h
+#define ___iprt_nocrt_amd64_fenv_h
+
+#include <iprt/types.h>
+
+typedef struct {
+ struct {
+ uint32_t __control;
+ uint32_t __status;
+ uint32_t __tag;
+ char __other[16];
+ } __x87;
+ uint32_t __mxcsr;
+} fenv_t;
+
+typedef uint16_t fexcept_t;
+
+/* Exception flags */
+#define FE_INVALID 0x01
+#define FE_DENORMAL 0x02
+#define FE_DIVBYZERO 0x04
+#define FE_OVERFLOW 0x08
+#define FE_UNDERFLOW 0x10
+#define FE_INEXACT 0x20
+#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
+ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/* Rounding modes */
+#define FE_TONEAREST 0x0000
+#define FE_DOWNWARD 0x0400
+#define FE_UPWARD 0x0800
+#define FE_TOWARDZERO 0x0c00
+#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
+ FE_UPWARD | FE_TOWARDZERO)
+
+/*
+ * As compared to the x87 control word, the SSE unit's control word
+ * has the rounding control bits offset by 3 and the exception mask
+ * bits offset by 7.
+ */
+#define _SSE_ROUND_SHIFT 3
+#define _SSE_EMASK_SHIFT 7
+
+RT_C_DECLS_BEGIN
+
+/* Default floating-point environment */
+extern const fenv_t RT_NOCRT(__fe_dfl_env);
+#define FE_DFL_ENV (&__fe_dfl_env)
+
+#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw))
+#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env))
+#define __fnclex() __asm __volatile("fnclex")
+#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env)))
+#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
+#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
+#define __fwait() __asm __volatile("fwait")
+#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
+#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
+
+DECLINLINE(int)
+feclearexcept(int __excepts)
+{
+ fenv_t __env;
+
+ if (__excepts == FE_ALL_EXCEPT) {
+ __fnclex();
+ } else {
+ __fnstenv(&__env.__x87);
+ __env.__x87.__status &= ~__excepts;
+ __fldenv(__env.__x87);
+ }
+ __stmxcsr(&__env.__mxcsr);
+ __env.__mxcsr &= ~__excepts;
+ __ldmxcsr(__env.__mxcsr);
+ return (0);
+}
+
+DECLINLINE(int)
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+ int __mxcsr, __status;
+
+ __stmxcsr(&__mxcsr);
+ __fnstsw(&__status);
+ *__flagp = (__mxcsr | __status) & __excepts;
+ return (0);
+}
+
+int RT_NOCRT(fesetexceptflag)(const fexcept_t *__flagp, int __excepts);
+int RT_NOCRT(feraiseexcept)(int __excepts);
+
+DECLINLINE(int)
+fetestexcept(int __excepts)
+{
+ int __mxcsr, __status;
+
+ __stmxcsr(&__mxcsr);
+ __fnstsw(&__status);
+ return ((__status | __mxcsr) & __excepts);
+}
+
+DECLINLINE(int)
+fegetround(void)
+{
+ int __control;
+
+ /*
+ * We assume that the x87 and the SSE unit agree on the
+ * rounding mode. Reading the control word on the x87 turns
+ * out to be about 5 times faster than reading it on the SSE
+ * unit on an Opteron 244.
+ */
+ __fnstcw(&__control);
+ return (__control & _ROUND_MASK);
+}
+
+DECLINLINE(int)
+fesetround(int __round)
+{
+ int __mxcsr, __control;
+
+ if (__round & ~_ROUND_MASK)
+ return (-1);
+
+ __fnstcw(&__control);
+ __control &= ~_ROUND_MASK;
+ __control |= __round;
+ __fldcw(__control);
+
+ __stmxcsr(&__mxcsr);
+ __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
+ __mxcsr |= __round << _SSE_ROUND_SHIFT;
+ __ldmxcsr(__mxcsr);
+
+ return (0);
+}
+
+int RT_NOCRT(fegetenv)(fenv_t *__envp);
+int RT_NOCRT(feholdexcept)(fenv_t *__envp);
+
+DECLINLINE(int)
+fesetenv(const fenv_t *__envp)
+{
+
+ __fldenv(__envp->__x87);
+ __ldmxcsr(__envp->__mxcsr);
+ return (0);
+}
+
+int RT_NOCRT(feupdateenv)(const fenv_t *__envp);
+int RT_NOCRT(feenableexcept)(int __mask);
+int RT_NOCRT(fedisableexcept)(int __mask);
+
+DECLINLINE(int)
+fegetexcept(void)
+{
+ int __control;
+
+ /*
+ * We assume that the masks for the x87 and the SSE unit are
+ * the same.
+ */
+ __fnstcw(&__control);
+ return (~__control & FE_ALL_EXCEPT);
+}
+
+RT_C_DECLS_END
+
+#ifndef RT_WITHOUT_NOCRT_WRAPPERS
+# define fesetexceptflag RT_NOCRT(fesetexceptflag)
+# define feraiseexcept RT_NOCRT(feraiseexcept)
+# define fegetenv RT_NOCRT(fegetenv)
+# define feholdexcept RT_NOCRT(feholdexcept)
+# define feupdateenv RT_NOCRT(feupdateenv)
+# define feenableexcept RT_NOCRT(feenableexcept)
+# define fedisableexcept RT_NOCRT(fedisableexcept)
+# define __fe_dfl_env RT_NOCRT(__fe_dfl_env)
+#endif
+
+#endif /* !__iprt_nocrt_amd64_fenv_h__ */
diff --git a/include/iprt/nocrt/amd64/math.h b/include/iprt/nocrt/amd64/math.h
new file mode 100644
index 00000000..8d1e6536
--- /dev/null
+++ b/include/iprt/nocrt/amd64/math.h
@@ -0,0 +1,102 @@
+/** @file
+ * IPRT / No-CRT - math.h, AMD inlined functions.
+ */
+
+/*
+ * 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 ___iprt_nocrt_amd64_math_h
+#define ___iprt_nocrt_amd64_math_h
+
+#include <iprt/asm.h>
+
+
+#if RT_INLINE_ASM_GNU_STYLE && defined(__SSE__)
+
+DECLINLINE(long double) inline_atan2l(long double lrd1, long double lrd2)
+{
+ long double lrdResult;
+ __asm__ __volatile__("fpatan"
+ : "=t" (lrdResult)
+ : "u" (lrd1),
+ "0" (lrd2)
+ : "st(1)");
+ return lrdResult;
+}
+
+DECLINLINE(long double) inline_rintl(long double lrd)
+{
+ long double lrdResult;
+ __asm__ __volatile__("frndint"
+ : "=t" (lrdResult)
+ : "0" (lrd));
+ return lrdResult;
+}
+
+DECLINLINE(float) inline_rintf(float rf)
+{
+ return (float)inline_rintl(rf);
+}
+
+DECLINLINE(double) inline_rint(double rd)
+{
+ return (double)inline_rintl(rd);
+}
+
+DECLINLINE(long double) inline_sqrtl(long double lrd)
+{
+ long double lrdResult;
+ __asm__ __volatile__("fsqrt"
+ : "=t" (lrdResult)
+ : "0" (lrd));
+ return lrdResult;
+}
+
+DECLINLINE(float) inline_sqrtf(float rf)
+{
+ return (float)inline_sqrtl(rf);
+}
+
+DECLINLINE(double) inline_sqrt(double rd)
+{
+ return (double)inline_sqrtl(rd);
+}
+
+
+# undef atan2l
+# define atan2l(lrd1, lrd2) inline_atan2l(lrd1, lrd2)
+# undef rint
+# define rint(rd) inline_rint(rd)
+# undef rintf
+# define rintf(rf) inline_rintf(rf)
+# undef rintl
+# define rintl(lrd) inline_rintl(lrd)
+# undef sqrt
+# define sqrt(rd) inline_sqrt(rd)
+# undef sqrtf
+# define sqrtf(rf) inline_sqrtf(rf)
+# undef sqrtl
+# define sqrtl(lrd) inline_sqrtl(lrd)
+
+#endif /* RT_INLINE_ASM_GNU_STYLE */
+
+#endif
+
diff --git a/include/iprt/nocrt/compiler/compiler.h b/include/iprt/nocrt/compiler/compiler.h
new file mode 100644
index 00000000..ea9f8952
--- /dev/null
+++ b/include/iprt/nocrt/compiler/compiler.h
@@ -0,0 +1,37 @@
+/** @file
+ * IPRT / No-CRT - compiler specifics.
+ */
+
+/*
+ * 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 ___iprt_nocrt_compiler_compiler_h
+#define ___iprt_nocrt_compiler_compiler_h
+
+#ifdef __GNUC__
+# include <iprt/nocrt/compiler/gcc.h>
+#elif defined(_MSC_VER)
+# include <iprt/nocrt/compiler/msc.h>
+#else
+# error "Unsupported compiler."
+#endif
+
+#endif
diff --git a/include/iprt/nocrt/compiler/gcc.h b/include/iprt/nocrt/compiler/gcc.h
new file mode 100644
index 00000000..890448b3
--- /dev/null
+++ b/include/iprt/nocrt/compiler/gcc.h
@@ -0,0 +1,121 @@
+/** @file
+ * IPRT / No-CRT - GCC specifics.
+ *
+ * A quick hack for freebsd where there are no separate location
+ * for compiler specific headers like on linux, mingw, os2, ++.
+ * This file will be cleaned up later...
+ */
+
+/*
+ * 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 ___iprt_nocrt_compiler_gcc_h
+#define ___iprt_nocrt_compiler_gcc_h
+
+
+/* stddef.h */
+#ifdef __PTRDIFF_TYPE__
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#elif ARCH_BITS == 32
+typedef int32_t ptrdiff_t;
+#elif ARCH_BITS == 64
+typedef int64_t ptrdiff_t;
+#else
+# error "ARCH_BITS is undefined or incorrect."
+#endif
+#define _PTRDIFF_T_DECLARED
+
+#ifdef __SIZE_TYPE__
+typedef __SIZE_TYPE__ size_t;
+#elif ARCH_BITS == 32
+typedef uint32_t size_t;
+#elif ARCH_BITS == 64
+typedef uint64_t size_t;
+#else
+# error "ARCH_BITS is undefined or incorrect."
+#endif
+#define _SIZE_T_DECLARED
+
+#ifndef __cplusplus
+# ifdef __WCHAR_TYPE__
+typedef __WCHAR_TYPE__ wchar_t;
+# elif defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+typedef uint16_t wchar_t;
+# else
+typedef int wchar_t;
+# endif
+# define _WCHAR_T_DECLARED
+#endif
+
+#ifdef __WINT_TYPE__
+typedef __WINT_TYPE__ wint_t;
+#else
+typedef unsigned int wint_t;
+#endif
+#define _WINT_T_DECLARED
+
+#ifndef NULL
+# ifdef __cplusplus
+# define NULL 0
+# else
+# define NULL ((void *)0)
+# endif
+#endif
+
+
+#ifndef offsetof
+# if defined(__cplusplus) && defined(__offsetof__)
+# define offsetof(type, memb)
+ (__offsetof__ (reinterpret_cast<size_t>(&reinterpret_cast<const volatile char &>(static_cast<type *>(0)->memb))) )
+# else
+# define offsetof(type, memb) ((size_t)&((type *)0)->memb)
+# endif
+#endif
+
+
+/* sys/types.h */
+#ifdef __SSIZE_TYPE__
+typedef __SSIZE_TYPE__ ssize_t;
+#elif ARCH_BITS == 32
+typedef int32_t ssize_t;
+#elif ARCH_BITS == 64
+typedef int64_t ssize_t;
+#else
+# define ARCH_BITS 123123
+# error "ARCH_BITS is undefined or incorrect."
+#endif
+#define _SSIZE_T_DECLARED
+
+
+/* stdarg.h */
+typedef __builtin_va_list va_list;
+#if __GNUC__ == 3 \
+ && __GNUC_MINOR__ == 2
+# define va_start(va, arg) __builtin_stdarg_start(va, arg)
+#else
+# define va_start(va, arg) __builtin_va_start(va, arg)
+#endif
+#define va_end(va) __builtin_va_end(va)
+#define va_arg(va, type) __builtin_va_arg(va, type)
+#define va_copy(dst, src) __builtin_va_copy(dst, src)
+
+
+#endif
diff --git a/include/iprt/nocrt/compiler/msc.h b/include/iprt/nocrt/compiler/msc.h
new file mode 100644
index 00000000..1fbb3a14
--- /dev/null
+++ b/include/iprt/nocrt/compiler/msc.h
@@ -0,0 +1,45 @@
+/** @file
+ * IPRT / No-CRT - MSC specifics.
+ */
+
+/*
+ * 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 ___iprt_nocrt_compiler_msc_h
+#define ___iprt_nocrt_compiler_msc_h
+
+
+/* stddef.h */
+#if !defined(_MT) && !defined(_DLL) && _MSC_VER < 1400
+# define errno msvcrt_errno
+#endif
+#include <../include/stddef.h>
+#undef errno
+
+#undef ssize_t
+typedef intptr_t ssize_t;
+
+
+/* stdarg.h */
+#include <../include/stdarg.h>
+
+#endif
+
diff --git a/include/iprt/nocrt/fenv.h b/include/iprt/nocrt/fenv.h
new file mode 100644
index 00000000..32d8163c
--- /dev/null
+++ b/include/iprt/nocrt/fenv.h
@@ -0,0 +1,38 @@
+/** @file
+ * IPRT / No-CRT - fenv.h wrapper.
+ */
+
+/*
+ * 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 ___iprt_nocrt_fenv_h
+#define ___iprt_nocrt_fenv_h
+
+#include <iprt/cdefs.h>
+#ifdef RT_ARCH_AMD64
+# include <iprt/nocrt/amd64/fenv.h>
+#elif defined(RT_ARCH_X86)
+# include <iprt/nocrt/x86/fenv.h>
+#else
+# error "IPRT: no fenv.h available for this platform, or the platform define is missing!"
+#endif
+
+#endif
diff --git a/include/iprt/nocrt/inttypes.h b/include/iprt/nocrt/inttypes.h
new file mode 100644
index 00000000..dc42dbb4
--- /dev/null
+++ b/include/iprt/nocrt/inttypes.h
@@ -0,0 +1,42 @@
+/** @file
+ * IPRT / No-CRT - Our minimal inttypes.h.
+ */
+
+/*
+ * 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 ___iprt_nocrt_inttypes_h
+#define ___iprt_nocrt_inttypes_h
+
+#include <iprt/types.h>
+
+#define PRId32 "RI32"
+#define PRIx32 "RX32"
+#define PRIu32 "RU32"
+#define PRIo32 huh? anyone using this? great!
+
+#define PRId64 "RI64"
+#define PRIx64 "RX64"
+#define PRIu64 "RU64"
+#define PRIo64 huh? anyone using this? great!
+
+#endif
+
diff --git a/include/iprt/nocrt/limits.h b/include/iprt/nocrt/limits.h
new file mode 100644
index 00000000..047f9644
--- /dev/null
+++ b/include/iprt/nocrt/limits.h
@@ -0,0 +1,86 @@
+/** @file
+ * IPRT / No-CRT - Our own limits 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 ___iprt_nocrt_limits_h
+#define ___iprt_nocrt_limits_h
+
+#include <iprt/types.h>
+
+#define CHAR_BIT 8
+#define SCHAR_MAX 0x7f
+#define SCHAR_MIN (-0x7f - 1)
+#define UCHAR_MAX 0xff
+#if 1 /* ASSUMES: signed char */
+# define CHAR_MAX SCHAR_MAX
+# define CHAR_MIN SCHAR_MIN
+#else
+# define CHAR_MAX UCHAR_MAX
+# define CHAR_MIN 0
+#endif
+
+#define WORD_BIT 16
+#define USHRT_MAX 0xffff
+#define SHRT_MAX 0x7fff
+#define SHRT_MIN (-0x7fff - 1)
+
+/* ASSUMES 32-bit int */
+#define UINT_MAX 0xffffffffU
+#define INT_MAX 0x7fffffff
+#define INT_MIN (-0x7fffffff - 1)
+
+#if defined(RT_ARCH_X86) || defined(RT_OS_WINDOWS) || defined(RT_ARCH_SPARC)
+# define LONG_BIT 32
+# define ULONG_MAX 0xffffffffU
+# define LONG_MAX 0x7fffffff
+# define LONG_MIN (-0x7fffffff - 1)
+#elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_SPARC64)
+# define LONG_BIT 64
+# define ULONG_MAX UINT64_C(0xffffffffffffffff)
+# define LONG_MAX INT64_C(0x7fffffffffffffff)
+# define LONG_MIN (INT64_C(-0x7fffffffffffffff) - 1)
+#else
+# error "PORTME"
+#endif
+
+#define LLONG_BIT 64
+#define ULLONG_MAX UINT64_C(0xffffffffffffffff)
+#define LLONG_MAX INT64_C(0x7fffffffffffffff)
+#define LLONG_MIN (INT64_C(-0x7fffffffffffffff) - 1)
+
+#if ARCH_BITS == 32
+# define SIZE_T_MAX 0xffffffffU
+# define SSIZE_MAX 0x7fffffff
+#elif ARCH_BITS == 64
+# define SIZE_T_MAX UINT64_C(0xffffffffffffffff)
+# define SSIZE_MAX INT64_C(0x7fffffffffffffff)
+#else
+# error "huh?"
+#endif
+
+/*#define OFF_MAX __OFF_MAX
+#define OFF_MIN __OFF_MIN*/
+
+#endif
+
diff --git a/include/iprt/nocrt/math.h b/include/iprt/nocrt/math.h
new file mode 100644
index 00000000..da37c5f6
--- /dev/null
+++ b/include/iprt/nocrt/math.h
@@ -0,0 +1,823 @@
+/** @file
+ * IPRT / No-CRT - math.h.
+ */
+
+/*
+ * 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.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on:
+ *
+ * from: @(#)fdlibm.h 5.1 93/09/24
+ * $FreeBSD: src/lib/msun/src/math.h,v 1.61 2005/04/16 21:12:47 das Exp $
+ * FreeBSD HEAD 2005-06-xx
+ *
+ * ====================================================
+ * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+ *
+ * Developed at SunPro, a Sun Microsystems, Inc. business.
+ * Permission to use, copy, modify, and distribute this
+ * software is freely granted, provided that this notice
+ * is preserved.
+ * ====================================================
+ */
+
+#ifndef ___iprt_nocrt_math_h
+#define ___iprt_nocrt_math_h
+
+#if !defined(__GNUC__) /* && !defined(__YOUR_COMPILER__) */
+# error "IPRT: Adjust this header for your compiler"
+#endif
+
+#include <iprt/types.h>
+/*#include <machine/_limits.h>*/
+
+/* from sys/cdefs.h */
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+#define __GNUC_PREREQ__(ma, mi) \
+ (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
+#else
+#define __GNUC_PREREQ__(ma, mi) 0
+#endif
+#define __pure2
+
+
+/*
+ * ANSI/POSIX
+ */
+extern const union __infinity_un {
+ unsigned char __uc[8];
+ double __ud;
+} RT_NOCRT(__infinity);
+
+extern const union __nan_un {
+ unsigned char __uc[sizeof(float)];
+ float __uf;
+} RT_NOCRT(__nan);
+
+#if __GNUC_PREREQ__(3, 3) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
+#define __MATH_BUILTIN_CONSTANTS
+#endif
+
+#if __GNUC_PREREQ__(3, 0) && !defined(__INTEL_COMPILER)
+#define __MATH_BUILTIN_RELOPS
+#endif
+
+#ifdef __MATH_BUILTIN_CONSTANTS
+#define HUGE_VAL __builtin_huge_val()
+#else
+#define HUGE_VAL (RT_NOCRT(__infinity).__ud)
+#endif
+
+#if 1/* __ISO_C_VISIBLE >= 1999*/
+#define FP_ILOGB0 (-__INT_MAX)
+#define FP_ILOGBNAN __INT_MAX
+
+#ifdef __MATH_BUILTIN_CONSTANTS
+#define HUGE_VALF __builtin_huge_valf()
+#define HUGE_VALL __builtin_huge_vall()
+#define INFINITY __builtin_inf()
+#define NAN __builtin_nan("")
+#else
+#define HUGE_VALF (float)HUGE_VAL
+#define HUGE_VALL (long double)HUGE_VAL
+#define INFINITY HUGE_VALF
+#define NAN (__nan.__uf)
+#endif /* __MATH_BUILTIN_CONSTANTS */
+
+#define MATH_ERRNO 1
+#define MATH_ERREXCEPT 2
+#define math_errhandling MATH_ERREXCEPT
+
+/* XXX We need a <machine/math.h>. */
+#if defined(__ia64__) || defined(__sparc64__)
+#define FP_FAST_FMA
+#endif
+#ifdef __ia64__
+#define FP_FAST_FMAL
+#endif
+#define FP_FAST_FMAF
+
+/* Symbolic constants to classify floating point numbers. */
+#define FP_INFINITE 0x01
+#define FP_NAN 0x02
+#define FP_NORMAL 0x04
+#define FP_SUBNORMAL 0x08
+#define FP_ZERO 0x10
+#define fpclassify(x) \
+ ((sizeof (x) == sizeof (float)) ? RT_NOCRT(__fpclassifyf)(x) \
+ : (sizeof (x) == sizeof (double)) ? RT_NOCRT(__fpclassifyd)(x) \
+ : RT_NOCRT(__fpclassifyl)(x))
+
+#define isfinite(x) \
+ ((sizeof (x) == sizeof (float)) ? RT_NOCRT(__isfinitef)(x) \
+ : (sizeof (x) == sizeof (double)) ? RT_NOCRT(__isfinite)(x) \
+ : RT_NOCRT(__isfinitel)(x))
+#define isinf(x) \
+ ((sizeof (x) == sizeof (float)) ? RT_NOCRT(__isinff)(x) \
+ : (sizeof (x) == sizeof (double)) ? isinf(x) \
+ : RT_NOCRT(__isinfl)(x))
+#define isnan(x) \
+ ((sizeof (x) == sizeof (float)) ? isnanf(x) \
+ : (sizeof (x) == sizeof (double)) ? isnan(x) \
+ : RT_NOCRT(__isnanl)(x))
+#define isnormal(x) \
+ ((sizeof (x) == sizeof (float)) ? RT_NOCRT(__isnormalf)(x) \
+ : (sizeof (x) == sizeof (double)) ? RT_NOCRT(__isnormal)(x) \
+ : RT_NOCRT(__isnormall)(x))
+
+#ifdef __MATH_BUILTIN_RELOPS
+#define isgreater(x, y) __builtin_isgreater((x), (y))
+#define isgreaterequal(x, y) __builtin_isgreaterequal((x), (y))
+#define isless(x, y) __builtin_isless((x), (y))
+#define islessequal(x, y) __builtin_islessequal((x), (y))
+#define islessgreater(x, y) __builtin_islessgreater((x), (y))
+#define isunordered(x, y) __builtin_isunordered((x), (y))
+#else
+#define isgreater(x, y) (!isunordered((x), (y)) && (x) > (y))
+#define isgreaterequal(x, y) (!isunordered((x), (y)) && (x) >= (y))
+#define isless(x, y) (!isunordered((x), (y)) && (x) < (y))
+#define islessequal(x, y) (!isunordered((x), (y)) && (x) <= (y))
+#define islessgreater(x, y) (!isunordered((x), (y)) && \
+ ((x) > (y) || (y) > (x)))
+#define isunordered(x, y) (isnan(x) || isnan(y))
+#endif /* __MATH_BUILTIN_RELOPS */
+
+#define signbit(x) \
+ ((sizeof (x) == sizeof (float)) ? RT_NOCRT(__signbitf)(x) \
+ : (sizeof (x) == sizeof (double)) ? RT_NOCRT(__signbit)(x) \
+ : RT_NOCRT(__signbitl)(x))
+
+typedef double double_t;
+typedef float float_t;
+#endif /* __ISO_C_VISIBLE >= 1999 */
+
+/*
+ * XOPEN/SVID
+ */
+#if 1/* __BSD_VISIBLE || __XSI_VISIBLE*/
+#define M_E 2.7182818284590452354 /* e */
+#define M_LOG2E 1.4426950408889634074 /* log 2e */
+#define M_LOG10E 0.43429448190325182765 /* log 10e */
+#define M_LN2 0.69314718055994530942 /* log e2 */
+#define M_LN10 2.30258509299404568402 /* log e10 */
+#define M_PI 3.14159265358979323846 /* pi */
+#define M_PI_2 1.57079632679489661923 /* pi/2 */
+#define M_PI_4 0.78539816339744830962 /* pi/4 */
+#define M_1_PI 0.31830988618379067154 /* 1/pi */
+#define M_2_PI 0.63661977236758134308 /* 2/pi */
+#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */
+#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
+#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
+
+#define MAXFLOAT ((float)3.40282346638528860e+38)
+extern int RT_NOCRT(signgam);
+#endif /* __BSD_VISIBLE || __XSI_VISIBLE */
+
+#if 1/* __BSD_VISIBLE*/
+#if 0
+/* Old value from 4.4BSD-Lite math.h; this is probably better. */
+#define HUGE HUGE_VAL
+#else
+#define HUGE MAXFLOAT
+#endif
+#endif /* __BSD_VISIBLE */
+
+/*
+ * Most of these functions depend on the rounding mode and have the side
+ * effect of raising floating-point exceptions, so they are not declared
+ * as __pure2. In C99, FENV_ACCESS affects the purity of these functions.
+ */
+RT_C_DECLS_BEGIN
+/*
+ * ANSI/POSIX
+ */
+int RT_NOCRT(__fpclassifyd)(double) __pure2;
+int RT_NOCRT(__fpclassifyf)(float) __pure2;
+int RT_NOCRT(__fpclassifyl)(long double) __pure2;
+int RT_NOCRT(__isfinitef)(float) __pure2;
+int RT_NOCRT(__isfinite)(double) __pure2;
+int RT_NOCRT(__isfinitel)(long double) __pure2;
+int RT_NOCRT(__isinff)(float) __pure2;
+int RT_NOCRT(__isinfl)(long double) __pure2;
+int RT_NOCRT(__isnanl)(long double) __pure2;
+int RT_NOCRT(__isnormalf)(float) __pure2;
+int RT_NOCRT(__isnormal)(double) __pure2;
+int RT_NOCRT(__isnormall)(long double) __pure2;
+int RT_NOCRT(__signbit)(double) __pure2;
+int RT_NOCRT(__signbitf)(float) __pure2;
+int RT_NOCRT(__signbitl)(long double) __pure2;
+
+double RT_NOCRT(acos)(double);
+double RT_NOCRT(asin)(double);
+double RT_NOCRT(atan)(double);
+double RT_NOCRT(atan2)(double, double);
+double RT_NOCRT(cos)(double);
+double RT_NOCRT(sin)(double);
+double RT_NOCRT(tan)(double);
+
+double RT_NOCRT(cosh)(double);
+double RT_NOCRT(sinh)(double);
+double RT_NOCRT(tanh)(double);
+
+double RT_NOCRT(exp)(double);
+double RT_NOCRT(frexp)(double, int *); /* fundamentally !__pure2 */
+double RT_NOCRT(ldexp)(double, int);
+double RT_NOCRT(log)(double);
+double RT_NOCRT(log10)(double);
+double RT_NOCRT(modf)(double, double *); /* fundamentally !__pure2 */
+
+double RT_NOCRT(pow)(double, double);
+double RT_NOCRT(sqrt)(double);
+
+double RT_NOCRT(ceil)(double);
+double RT_NOCRT(fabs)(double) __pure2;
+double RT_NOCRT(floor)(double);
+double RT_NOCRT(fmod)(double, double);
+
+/*
+ * These functions are not in C90.
+ */
+#if 1 /*__BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE*/
+double RT_NOCRT(acosh)(double);
+double RT_NOCRT(asinh)(double);
+double RT_NOCRT(atanh)(double);
+double RT_NOCRT(cbrt)(double);
+double RT_NOCRT(erf)(double);
+double RT_NOCRT(erfc)(double);
+double RT_NOCRT(exp2)(double);
+double RT_NOCRT(expm1)(double);
+double RT_NOCRT(fma)(double, double, double);
+double RT_NOCRT(hypot)(double, double);
+int RT_NOCRT(ilogb)(double) __pure2;
+/*int isinf(double) __pure2;*/
+/*int isnan(double) __pure2;*/
+double RT_NOCRT(lgamma)(double);
+long long RT_NOCRT(llrint)(double);
+long long RT_NOCRT(llround)(double);
+double RT_NOCRT(log1p)(double);
+double RT_NOCRT(logb)(double);
+long RT_NOCRT(lrint)(double);
+long RT_NOCRT(lround)(double);
+double RT_NOCRT(nextafter)(double, double);
+double RT_NOCRT(remainder)(double, double);
+double RT_NOCRT(remquo)(double, double, int *);
+double RT_NOCRT(rint)(double);
+#endif /* __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999 || __XSI_VISIBLE */
+
+#if 1/* __BSD_VISIBLE || __XSI_VISIBLE*/
+double RT_NOCRT(j0)(double);
+double RT_NOCRT(j1)(double);
+double RT_NOCRT(jn)(int, double);
+double RT_NOCRT(scalb)(double, double);
+double RT_NOCRT(y0)(double);
+double RT_NOCRT(y1)(double);
+double RT_NOCRT(yn)(int, double);
+
+#if 1/* __XSI_VISIBLE <= 500 || __BSD_VISIBLE*/
+double RT_NOCRT(gamma)(double);
+#endif
+#endif /* __BSD_VISIBLE || __XSI_VISIBLE */
+
+#if 1/* __BSD_VISIBLE || __ISO_C_VISIBLE >= 1999*/
+double RT_NOCRT(copysign)(double, double) __pure2;
+double RT_NOCRT(fdim)(double, double);
+double RT_NOCRT(fmax)(double, double) __pure2;
+double RT_NOCRT(fmin)(double, double) __pure2;
+double RT_NOCRT(nearbyint)(double);
+double RT_NOCRT(round)(double);
+double RT_NOCRT(scalbln)(double, long);
+double RT_NOCRT(scalbn)(double, int);
+double RT_NOCRT(tgamma)(double);
+double RT_NOCRT(trunc)(double);
+#endif
+
+/*
+ * BSD math library entry points
+ */
+#if 1/* __BSD_VISIBLE*/
+double RT_NOCRT(drem)(double, double);
+int RT_NOCRT(finite)(double) __pure2;
+int RT_NOCRT(isnanf)(float) __pure2;
+
+/*
+ * Reentrant version of gamma & lgamma; passes signgam back by reference
+ * as the second argument; user must allocate space for signgam.
+ */
+double RT_NOCRT(gamma_r)(double, int *);
+double RT_NOCRT(lgamma_r)(double, int *);
+
+/*
+ * IEEE Test Vector
+ */
+double RT_NOCRT(significand)(double);
+#endif /* __BSD_VISIBLE */
+
+/* float versions of ANSI/POSIX functions */
+#if 1/* __ISO_C_VISIBLE >= 1999*/
+float RT_NOCRT(acosf)(float);
+float RT_NOCRT(asinf)(float);
+float RT_NOCRT(atanf)(float);
+float RT_NOCRT(atan2f)(float, float);
+float RT_NOCRT(cosf)(float);
+float RT_NOCRT(sinf)(float);
+float RT_NOCRT(tanf)(float);
+
+float RT_NOCRT(coshf)(float);
+float RT_NOCRT(sinhf)(float);
+float RT_NOCRT(tanhf)(float);
+
+float RT_NOCRT(exp2f)(float);
+float RT_NOCRT(expf)(float);
+float RT_NOCRT(expm1f)(float);
+float RT_NOCRT(frexpf)(float, int *); /* fundamentally !__pure2 */
+int RT_NOCRT(ilogbf)(float) __pure2;
+float RT_NOCRT(ldexpf)(float, int);
+float RT_NOCRT(log10f)(float);
+float RT_NOCRT(log1pf)(float);
+float RT_NOCRT(logf)(float);
+float RT_NOCRT(modff)(float, float *); /* fundamentally !__pure2 */
+
+float RT_NOCRT(powf)(float, float);
+float RT_NOCRT(sqrtf)(float);
+
+float RT_NOCRT(ceilf)(float);
+float RT_NOCRT(fabsf)(float) __pure2;
+float RT_NOCRT(floorf)(float);
+float RT_NOCRT(fmodf)(float, float);
+float RT_NOCRT(roundf)(float);
+
+float RT_NOCRT(erff)(float);
+float RT_NOCRT(erfcf)(float);
+float RT_NOCRT(hypotf)(float, float);
+float RT_NOCRT(lgammaf)(float);
+
+float RT_NOCRT(acoshf)(float);
+float RT_NOCRT(asinhf)(float);
+float RT_NOCRT(atanhf)(float);
+float RT_NOCRT(cbrtf)(float);
+float RT_NOCRT(logbf)(float);
+float RT_NOCRT(copysignf)(float, float) __pure2;
+long long RT_NOCRT(llrintf)(float);
+long long RT_NOCRT(llroundf)(float);
+long RT_NOCRT(lrintf)(float);
+long RT_NOCRT(lroundf)(float);
+float RT_NOCRT(nearbyintf)(float);
+float RT_NOCRT(nextafterf)(float, float);
+float RT_NOCRT(remainderf)(float, float);
+float RT_NOCRT(remquof)(float, float, int *);
+float RT_NOCRT(rintf)(float);
+float RT_NOCRT(scalblnf)(float, long);
+float RT_NOCRT(scalbnf)(float, int);
+float RT_NOCRT(truncf)(float);
+
+float RT_NOCRT(fdimf)(float, float);
+float RT_NOCRT(fmaf)(float, float, float);
+float RT_NOCRT(fmaxf)(float, float) __pure2;
+float RT_NOCRT(fminf)(float, float) __pure2;
+#endif
+
+/*
+ * float versions of BSD math library entry points
+ */
+#if 1/* __BSD_VISIBLE*/
+float RT_NOCRT(dremf)(float, float);
+int RT_NOCRT(finitef)(float) __pure2;
+float RT_NOCRT(gammaf)(float);
+float RT_NOCRT(j0f)(float);
+float RT_NOCRT(j1f)(float);
+float RT_NOCRT(jnf)(int, float);
+float RT_NOCRT(scalbf)(float, float);
+float RT_NOCRT(y0f)(float);
+float RT_NOCRT(y1f)(float);
+float RT_NOCRT(ynf)(int, float);
+
+/*
+ * Float versions of reentrant version of gamma & lgamma; passes
+ * signgam back by reference as the second argument; user must
+ * allocate space for signgam.
+ */
+float RT_NOCRT(gammaf_r)(float, int *);
+float RT_NOCRT(lgammaf_r)(float, int *);
+
+/*
+ * float version of IEEE Test Vector
+ */
+float RT_NOCRT(significandf)(float);
+#endif /* __BSD_VISIBLE */
+
+/*
+ * long double versions of ISO/POSIX math functions
+ */
+#if 1/* __ISO_C_VISIBLE >= 1999*/
+#if 1 /* bird: we've got these */
+long double RT_NOCRT(acoshl)(long double);
+long double RT_NOCRT(acosl)(long double);
+long double RT_NOCRT(asinhl)(long double);
+long double RT_NOCRT(asinl)(long double);
+long double RT_NOCRT(atan2l)(long double, long double);
+long double RT_NOCRT(atanhl)(long double);
+long double RT_NOCRT(atanl)(long double);
+long double RT_NOCRT(cbrtl)(long double);
+#endif
+long double RT_NOCRT(ceill)(long double);
+long double RT_NOCRT(copysignl)(long double, long double) __pure2;
+#if 1 /* bird */
+long double RT_NOCRT(coshl)(long double);
+long double RT_NOCRT(cosl)(long double);
+long double RT_NOCRT(erfcl)(long double);
+long double RT_NOCRT(erfl)(long double);
+long double RT_NOCRT(exp2l)(long double);
+long double RT_NOCRT(expl)(long double);
+long double RT_NOCRT(expm1l)(long double);
+#endif
+long double RT_NOCRT(fabsl)(long double) __pure2;
+long double RT_NOCRT(fdiml)(long double, long double);
+long double RT_NOCRT(floorl)(long double);
+long double RT_NOCRT(fmal)(long double, long double, long double);
+long double RT_NOCRT(fmaxl)(long double, long double) __pure2;
+long double RT_NOCRT(fminl)(long double, long double) __pure2;
+#if 1 /* bird */
+long double RT_NOCRT(fmodl)(long double, long double);
+#endif
+long double RT_NOCRT(frexpl)(long double value, int *); /* fundamentally !__pure2 */
+#if 1 /* bird */
+long double RT_NOCRT(hypotl)(long double, long double);
+#endif
+int RT_NOCRT(ilogbl)(long double) __pure2;
+long double RT_NOCRT(ldexpl)(long double, int);
+#if 1 /* bird */
+long double RT_NOCRT(lgammal)(long double);
+long long RT_NOCRT(llrintl)(long double);
+#endif
+long long RT_NOCRT(llroundl)(long double);
+#if 1 /* bird */
+long double RT_NOCRT(log10l)(long double);
+long double RT_NOCRT(log1pl)(long double);
+long double RT_NOCRT(log2l)(long double);
+long double RT_NOCRT(logbl)(long double);
+long double RT_NOCRT(logl)(long double);
+long RT_NOCRT(lrintl)(long double);
+#endif
+long RT_NOCRT(lroundl)(long double);
+#if 1 /* bird */
+long double RT_NOCRT(modfl)(long double, long double *); /* fundamentally !__pure2 */
+long double RT_NOCRT(nanl)(const char *) __pure2;
+long double RT_NOCRT(nearbyintl)(long double);
+#endif
+long double RT_NOCRT(nextafterl)(long double, long double);
+double RT_NOCRT(nexttoward)(double, long double);
+float RT_NOCRT(nexttowardf)(float, long double);
+long double RT_NOCRT(nexttowardl)(long double, long double);
+#if 1 /* bird */
+long double RT_NOCRT(powl)(long double, long double);
+long double RT_NOCRT(remainderl)(long double, long double);
+long double RT_NOCRT(remquol)(long double, long double, int *);
+long double RT_NOCRT(rintl)(long double);
+#endif
+long double RT_NOCRT(roundl)(long double);
+long double RT_NOCRT(scalblnl)(long double, long);
+long double RT_NOCRT(scalbnl)(long double, int);
+#if 1 /* bird: we 've got most of these. */
+long double RT_NOCRT(sinhl)(long double);
+long double RT_NOCRT(sinl)(long double);
+long double RT_NOCRT(sqrtl)(long double);
+long double RT_NOCRT(tanhl)(long double);
+long double RT_NOCRT(tanl)(long double);
+long double RT_NOCRT(tgammal)(long double);
+#endif
+long double RT_NOCRT(truncl)(long double);
+
+/* bird: these were missing, gcc apparently inlines them. */
+double RT_NOCRT(nan)(const char *);
+float RT_NOCRT(nanf)(const char *);
+
+#endif /* __ISO_C_VISIBLE >= 1999 */
+
+#if 1/*def __USE_GNU*/
+/*
+ * In GLIBC there are long variants of the XOPEN/SVID constant
+ * block some pages ago. We need this to get the math tests going.
+ */
+#define M_El 2.7182818284590452353602874713526625L
+#define M_LOG2El 1.4426950408889634073599246810018921L
+#define M_LOG10El 0.4342944819032518276511289189166051L
+#define M_LN2l 0.6931471805599453094172321214581766L
+#define M_LN10l 2.3025850929940456840179914546843642L
+#define M_PIl 3.1415926535897932384626433832795029L
+#define M_PI_2l 1.5707963267948966192313216916397514L
+#define M_PI_4l 0.7853981633974483096156608458198757L
+#define M_1_PIl 0.3183098861837906715377675267450287L
+#define M_2_PIl 0.6366197723675813430755350534900574L
+#define M_2_SQRTPIl 1.1283791670955125738961589031215452L
+#define M_SQRT2l 1.4142135623730950488016887242096981L
+#define M_SQRT1_2l 0.7071067811865475244008443621048490L
+#endif
+
+#if 1/*def __USE_GNU*/
+
+void RT_NOCRT(sincos)(double, double *, double *);
+void RT_NOCRT(sincosf)(float, float *, float *);
+void RT_NOCRT(sincosl)(long double, long double *, long double *);
+float RT_NOCRT(exp10f)(float);
+double RT_NOCRT(exp10)(double);
+long double RT_NOCRT(exp10l)(long double);
+float RT_NOCRT(log2f)(float);
+double RT_NOCRT(log2)(double);
+long double RT_NOCRT(log2l)(long double);
+float RT_NOCRT(tgammaf)(float);
+long double RT_NOCRT(significandl)(long double);
+long double RT_NOCRT(j0l)(long double);
+long double RT_NOCRT(j1l)(long double);
+long double RT_NOCRT(jnl)(int, long double);
+long double RT_NOCRT(scalbl)(long double, long double);
+long double RT_NOCRT(y0l)(long double);
+long double RT_NOCRT(y1l)(long double);
+long double RT_NOCRT(ynl)(int, long double);
+long double RT_NOCRT(lgammal_r)(long double,int *);
+long double RT_NOCRT(gammal)(long double);
+#endif
+RT_C_DECLS_END
+
+
+
+#if !defined(RT_WITHOUT_NOCRT_WRAPPERS) && !defined(RT_WITHOUT_NOCRT_WRAPPER_ALIASES)
+/* sed -e "/#/d" -e "/RT_NOCRT/!d" -e "s/^.*RT_NOCRT(\([a-z0-9_]*\)).*$/# define \1 RT_NOCRT(\1)/" */
+# define __infinity RT_NOCRT(__infinity)
+# define __nan RT_NOCRT(__nan)
+# define __fpclassifyf RT_NOCRT(__fpclassifyf)
+# define __fpclassifyd RT_NOCRT(__fpclassifyd)
+# define __fpclassifyl RT_NOCRT(__fpclassifyl)
+# define __isfinitef RT_NOCRT(__isfinitef)
+# define __isfinite RT_NOCRT(__isfinite)
+# define __isfinitel RT_NOCRT(__isfinitel)
+# define __isinff RT_NOCRT(__isinff)
+# define __isinfl RT_NOCRT(__isinfl)
+# define __isnanl RT_NOCRT(__isnanl)
+# define __isnormalf RT_NOCRT(__isnormalf)
+# define __isnormal RT_NOCRT(__isnormal)
+# define __isnormall RT_NOCRT(__isnormall)
+# define __signbitf RT_NOCRT(__signbitf)
+# define __signbit RT_NOCRT(__signbit)
+# define __signbitl RT_NOCRT(__signbitl)
+# define signgam RT_NOCRT(signgam)
+# define __fpclassifyd RT_NOCRT(__fpclassifyd)
+# define __fpclassifyf RT_NOCRT(__fpclassifyf)
+# define __fpclassifyl RT_NOCRT(__fpclassifyl)
+# define __isfinitef RT_NOCRT(__isfinitef)
+# define __isfinite RT_NOCRT(__isfinite)
+# define __isfinitel RT_NOCRT(__isfinitel)
+# define __isinff RT_NOCRT(__isinff)
+# define __isinfl RT_NOCRT(__isinfl)
+# define __isnanl RT_NOCRT(__isnanl)
+# define __isnormalf RT_NOCRT(__isnormalf)
+# define __isnormal RT_NOCRT(__isnormal)
+# define __isnormall RT_NOCRT(__isnormall)
+# define __signbit RT_NOCRT(__signbit)
+# define __signbitf RT_NOCRT(__signbitf)
+# define __signbitl RT_NOCRT(__signbitl)
+# define acos RT_NOCRT(acos)
+# define asin RT_NOCRT(asin)
+# define atan RT_NOCRT(atan)
+# define atan2 RT_NOCRT(atan2)
+# define cos RT_NOCRT(cos)
+# define sin RT_NOCRT(sin)
+# define tan RT_NOCRT(tan)
+# define cosh RT_NOCRT(cosh)
+# define sinh RT_NOCRT(sinh)
+# define tanh RT_NOCRT(tanh)
+# define exp RT_NOCRT(exp)
+# define frexp RT_NOCRT(frexp)
+# define ldexp RT_NOCRT(ldexp)
+# define log RT_NOCRT(log)
+# define log10 RT_NOCRT(log10)
+# define modf RT_NOCRT(modf)
+# define pow RT_NOCRT(pow)
+# define sqrt RT_NOCRT(sqrt)
+# define ceil RT_NOCRT(ceil)
+# define fabs RT_NOCRT(fabs)
+# define floor RT_NOCRT(floor)
+# define fmod RT_NOCRT(fmod)
+# define acosh RT_NOCRT(acosh)
+# define asinh RT_NOCRT(asinh)
+# define atanh RT_NOCRT(atanh)
+# define cbrt RT_NOCRT(cbrt)
+# define erf RT_NOCRT(erf)
+# define erfc RT_NOCRT(erfc)
+# define exp2 RT_NOCRT(exp2)
+# define expm1 RT_NOCRT(expm1)
+# define fma RT_NOCRT(fma)
+# define hypot RT_NOCRT(hypot)
+# define ilogb RT_NOCRT(ilogb)
+# define lgamma RT_NOCRT(lgamma)
+# define llrint RT_NOCRT(llrint)
+# define llround RT_NOCRT(llround)
+# define log1p RT_NOCRT(log1p)
+# define logb RT_NOCRT(logb)
+# define lrint RT_NOCRT(lrint)
+# define lround RT_NOCRT(lround)
+# define nextafter RT_NOCRT(nextafter)
+# define remainder RT_NOCRT(remainder)
+# define remquo RT_NOCRT(remquo)
+# define rint RT_NOCRT(rint)
+# define j0 RT_NOCRT(j0)
+# define j1 RT_NOCRT(j1)
+# define jn RT_NOCRT(jn)
+# define scalb RT_NOCRT(scalb)
+# define y0 RT_NOCRT(y0)
+# define y1 RT_NOCRT(y1)
+# define yn RT_NOCRT(yn)
+# define gamma RT_NOCRT(gamma)
+# define copysign RT_NOCRT(copysign)
+# define fdim RT_NOCRT(fdim)
+# define fmax RT_NOCRT(fmax)
+# define fmin RT_NOCRT(fmin)
+# define nearbyint RT_NOCRT(nearbyint)
+# define round RT_NOCRT(round)
+# define scalbln RT_NOCRT(scalbln)
+# define scalbn RT_NOCRT(scalbn)
+# define tgamma RT_NOCRT(tgamma)
+# define trunc RT_NOCRT(trunc)
+# define drem RT_NOCRT(drem)
+# define finite RT_NOCRT(finite)
+# define isnanf RT_NOCRT(isnanf)
+# define gamma_r RT_NOCRT(gamma_r)
+# define lgamma_r RT_NOCRT(lgamma_r)
+# define significand RT_NOCRT(significand)
+# define acosf RT_NOCRT(acosf)
+# define asinf RT_NOCRT(asinf)
+# define atanf RT_NOCRT(atanf)
+# define atan2f RT_NOCRT(atan2f)
+# define cosf RT_NOCRT(cosf)
+# define sinf RT_NOCRT(sinf)
+# define tanf RT_NOCRT(tanf)
+# define coshf RT_NOCRT(coshf)
+# define sinhf RT_NOCRT(sinhf)
+# define tanhf RT_NOCRT(tanhf)
+# define exp2f RT_NOCRT(exp2f)
+# define expf RT_NOCRT(expf)
+# define expm1f RT_NOCRT(expm1f)
+# define frexpf RT_NOCRT(frexpf)
+# define ilogbf RT_NOCRT(ilogbf)
+# define ldexpf RT_NOCRT(ldexpf)
+# define log10f RT_NOCRT(log10f)
+# define log1pf RT_NOCRT(log1pf)
+# define logf RT_NOCRT(logf)
+# define modff RT_NOCRT(modff)
+# define powf RT_NOCRT(powf)
+# define sqrtf RT_NOCRT(sqrtf)
+# define ceilf RT_NOCRT(ceilf)
+# define fabsf RT_NOCRT(fabsf)
+# define floorf RT_NOCRT(floorf)
+# define fmodf RT_NOCRT(fmodf)
+# define roundf RT_NOCRT(roundf)
+# define erff RT_NOCRT(erff)
+# define erfcf RT_NOCRT(erfcf)
+# define hypotf RT_NOCRT(hypotf)
+# define lgammaf RT_NOCRT(lgammaf)
+# define acoshf RT_NOCRT(acoshf)
+# define asinhf RT_NOCRT(asinhf)
+# define atanhf RT_NOCRT(atanhf)
+# define cbrtf RT_NOCRT(cbrtf)
+# define logbf RT_NOCRT(logbf)
+# define copysignf RT_NOCRT(copysignf)
+# define llrintf RT_NOCRT(llrintf)
+# define llroundf RT_NOCRT(llroundf)
+# define lrintf RT_NOCRT(lrintf)
+# define lroundf RT_NOCRT(lroundf)
+# define nearbyintf RT_NOCRT(nearbyintf)
+# define nextafterf RT_NOCRT(nextafterf)
+# define remainderf RT_NOCRT(remainderf)
+# define remquof RT_NOCRT(remquof)
+# define rintf RT_NOCRT(rintf)
+# define scalblnf RT_NOCRT(scalblnf)
+# define scalbnf RT_NOCRT(scalbnf)
+# define truncf RT_NOCRT(truncf)
+# define fdimf RT_NOCRT(fdimf)
+# define fmaf RT_NOCRT(fmaf)
+# define fmaxf RT_NOCRT(fmaxf)
+# define fminf RT_NOCRT(fminf)
+# define dremf RT_NOCRT(dremf)
+# define finitef RT_NOCRT(finitef)
+# define gammaf RT_NOCRT(gammaf)
+# define j0f RT_NOCRT(j0f)
+# define j1f RT_NOCRT(j1f)
+# define jnf RT_NOCRT(jnf)
+# define scalbf RT_NOCRT(scalbf)
+# define y0f RT_NOCRT(y0f)
+# define y1f RT_NOCRT(y1f)
+# define ynf RT_NOCRT(ynf)
+# define gammaf_r RT_NOCRT(gammaf_r)
+# define lgammaf_r RT_NOCRT(lgammaf_r)
+# define significandf RT_NOCRT(significandf)
+# define acoshl RT_NOCRT(acoshl)
+# define acosl RT_NOCRT(acosl)
+# define asinhl RT_NOCRT(asinhl)
+# define asinl RT_NOCRT(asinl)
+# define atan2l RT_NOCRT(atan2l)
+# define atanhl RT_NOCRT(atanhl)
+# define atanl RT_NOCRT(atanl)
+# define cbrtl RT_NOCRT(cbrtl)
+# define ceill RT_NOCRT(ceill)
+# define copysignl RT_NOCRT(copysignl)
+# define coshl RT_NOCRT(coshl)
+# define cosl RT_NOCRT(cosl)
+# define erfcl RT_NOCRT(erfcl)
+# define erfl RT_NOCRT(erfl)
+# define exp2l RT_NOCRT(exp2l)
+# define expl RT_NOCRT(expl)
+# define expm1l RT_NOCRT(expm1l)
+# define fabsl RT_NOCRT(fabsl)
+# define fdiml RT_NOCRT(fdiml)
+# define floorl RT_NOCRT(floorl)
+# define fmal RT_NOCRT(fmal)
+# define fmaxl RT_NOCRT(fmaxl)
+# define fminl RT_NOCRT(fminl)
+# define fmodl RT_NOCRT(fmodl)
+# define frexpl RT_NOCRT(frexpl)
+# define hypotl RT_NOCRT(hypotl)
+# define ilogbl RT_NOCRT(ilogbl)
+# define ldexpl RT_NOCRT(ldexpl)
+# define lgammal RT_NOCRT(lgammal)
+# define llrintl RT_NOCRT(llrintl)
+# define llroundl RT_NOCRT(llroundl)
+# define log10l RT_NOCRT(log10l)
+# define log1pl RT_NOCRT(log1pl)
+# define log2l RT_NOCRT(log2l)
+# define logbl RT_NOCRT(logbl)
+# define logl RT_NOCRT(logl)
+# define lrintl RT_NOCRT(lrintl)
+# define lroundl RT_NOCRT(lroundl)
+# define modfl RT_NOCRT(modfl)
+# define nanl RT_NOCRT(nanl)
+# define nearbyintl RT_NOCRT(nearbyintl)
+# define nextafterl RT_NOCRT(nextafterl)
+# define nexttoward RT_NOCRT(nexttoward)
+# define nexttowardf RT_NOCRT(nexttowardf)
+# define nexttowardl RT_NOCRT(nexttowardl)
+# define powl RT_NOCRT(powl)
+# define remainderl RT_NOCRT(remainderl)
+# define remquol RT_NOCRT(remquol)
+# define rintl RT_NOCRT(rintl)
+# define roundl RT_NOCRT(roundl)
+# define scalblnl RT_NOCRT(scalblnl)
+# define scalbnl RT_NOCRT(scalbnl)
+# define sinhl RT_NOCRT(sinhl)
+# define sinl RT_NOCRT(sinl)
+# define sqrtl RT_NOCRT(sqrtl)
+# define tanhl RT_NOCRT(tanhl)
+# define tanl RT_NOCRT(tanl)
+# define tgammal RT_NOCRT(tgammal)
+# define truncl RT_NOCRT(truncl)
+# define nan RT_NOCRT(nan)
+# define nanf RT_NOCRT(nanf)
+# define sincos RT_NOCRT(sincos)
+# define sincosf RT_NOCRT(sincosf)
+# define sincosl RT_NOCRT(sincosl)
+# define exp10f RT_NOCRT(exp10f)
+# define exp10 RT_NOCRT(exp10)
+# define exp10l RT_NOCRT(exp10l)
+# define log2f RT_NOCRT(log2f)
+# define log2 RT_NOCRT(log2)
+# define log2l RT_NOCRT(log2l)
+# define tgammaf RT_NOCRT(tgammaf)
+# define significandl RT_NOCRT(significandl)
+# define j0l RT_NOCRT(j0l)
+# define j1l RT_NOCRT(j1l)
+# define jnl RT_NOCRT(jnl)
+# define scalbl RT_NOCRT(scalbl)
+# define y0l RT_NOCRT(y0l)
+# define y1l RT_NOCRT(y1l)
+# define ynl RT_NOCRT(ynl)
+# define lgammal_r RT_NOCRT(lgammal_r)
+# define gammal RT_NOCRT(gammal)
+#endif
+
+/*
+ * Include inlined implementations.
+ */
+#ifdef RT_ARCH_AMD64
+# include <iprt/nocrt/amd64/math.h>
+#elif defined(RT_ARCH_X86)
+# include <iprt/nocrt/x86/math.h>
+#endif
+
+#endif
+
diff --git a/include/iprt/nocrt/setjmp.h b/include/iprt/nocrt/setjmp.h
new file mode 100644
index 00000000..c7c7aaf0
--- /dev/null
+++ b/include/iprt/nocrt/setjmp.h
@@ -0,0 +1,55 @@
+/** @file
+ * IPRT / No-CRT - Our own setjmp 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 ___iprt_nocrt_setjmp_h
+#define ___iprt_nocrt_setjmp_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+#ifdef RT_ARCH_AMD64
+# ifdef RT_OS_WINDOWS /* Also saves rsi, rdi and xmm6-xmm15. */
+typedef uint64_t RT_NOCRT(jmp_buf)[10 + (2*10)];
+# else
+typedef uint64_t RT_NOCRT(jmp_buf)[8];
+# endif
+#else
+typedef uint32_t RT_NOCRT(jmp_buf)[6+2];
+#endif
+
+extern int RT_NOCRT(setjmp)(RT_NOCRT(jmp_buf));
+extern int RT_NOCRT(longjmp)(RT_NOCRT(jmp_buf), int);
+
+#if !defined(RT_WITHOUT_NOCRT_WRAPPERS) && !defined(RT_WITHOUT_NOCRT_WRAPPER_ALIASES)
+# define jmp_buf RT_NOCRT(jmp_buf)
+# define setjmp RT_NOCRT(setjmp)
+# define longjmp RT_NOCRT(longjmp)
+#endif
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/nocrt/stdarg.h b/include/iprt/nocrt/stdarg.h
new file mode 100644
index 00000000..daa6e0a7
--- /dev/null
+++ b/include/iprt/nocrt/stdarg.h
@@ -0,0 +1,27 @@
+/** @file
+ * IPRT / No-CRT - stdarg.h (-> iprt/stdarg.h).
+ */
+
+/*
+ * 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.
+ */
+
+#include <iprt/stdarg.h>
+
diff --git a/include/iprt/nocrt/stddef.h b/include/iprt/nocrt/stddef.h
new file mode 100644
index 00000000..8487c26e
--- /dev/null
+++ b/include/iprt/nocrt/stddef.h
@@ -0,0 +1,27 @@
+/** @file
+ * IPRT / No-CRT - stddef.h (-> iprt/types.h).
+ */
+
+/*
+ * 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.
+ */
+
+#include <iprt/types.h>
+
diff --git a/include/iprt/nocrt/stdlib.h b/include/iprt/nocrt/stdlib.h
new file mode 100644
index 00000000..9bfc1d2f
--- /dev/null
+++ b/include/iprt/nocrt/stdlib.h
@@ -0,0 +1,36 @@
+/** @file
+ * IPRT / No-CRT - Our minimal stdlib.h.
+ */
+
+/*
+ * 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 ___iprt_nocrt_stdlib_h
+#define ___iprt_nocrt_stdlib_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/iprt/nocrt/string.h b/include/iprt/nocrt/string.h
new file mode 100644
index 00000000..2ed2f72d
--- /dev/null
+++ b/include/iprt/nocrt/string.h
@@ -0,0 +1,80 @@
+/** @file
+ * IPRT / No-CRT - string.h.
+ */
+
+/*
+ * 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 ___iprt_nocrt_string_h
+#define ___iprt_nocrt_string_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+void * RT_NOCRT(memchr)(const void *pv, int ch, size_t cb);
+int RT_NOCRT(memcmp)(const void *pv1, const void *pv2, size_t cb);
+void * RT_NOCRT(memcpy)(void *pvDst, const void *pvSrc, size_t cb);
+void * RT_NOCRT(mempcpy)(void *pvDst, const void *pvSrc, size_t cb);
+void * RT_NOCRT(memmove)(void *pvDst, const void *pvSrc, size_t cb);
+void * RT_NOCRT(memset)(void *pvDst, int ch, size_t cb);
+
+char * RT_NOCRT(strcat)(char *pszDst, const char *pszSrc);
+char * RT_NOCRT(strncat)(char *pszDst, const char *pszSrc, size_t cch);
+char * RT_NOCRT(strchr)(const char *psz, int ch);
+int RT_NOCRT(strcmp)(const char *psz1, const char *psz2);
+int RT_NOCRT(strncmp)(const char *psz1, const char *psz2, size_t cch);
+int RT_NOCRT(stricmp)(const char *psz1, const char *psz2);
+int RT_NOCRT(strnicmp)(const char *psz1, const char *psz2, size_t cch);
+char * RT_NOCRT(strcpy)(char *pszDst, const char *pszSrc);
+char * RT_NOCRT(strncpy)(char *pszDst, const char *pszSrc, size_t cch);
+char * RT_NOCRT(strcat)(char *pszDst, const char *pszSrc);
+char * RT_NOCRT(strncat)(char *pszDst, const char *pszSrc, size_t cch);
+size_t RT_NOCRT(strlen)(const char *psz);
+size_t RT_NOCRT(strnlen)(const char *psz, size_t cch);
+char * RT_NOCRT(strstr)(const char *psz, const char *pszSub);
+
+#if !defined(RT_WITHOUT_NOCRT_WRAPPERS) && !defined(RT_WITHOUT_NOCRT_WRAPPER_ALIASES)
+# define memchr RT_NOCRT(memchr)
+# define memcmp RT_NOCRT(memcmp)
+# define memcpy RT_NOCRT(memcpy)
+# define mempcpy RT_NOCRT(mempcpy)
+# define memmove RT_NOCRT(memmove)
+# define memset RT_NOCRT(memset)
+# define strcat RT_NOCRT(strcat)
+# define strncat RT_NOCRT(strncat)
+# define strchr RT_NOCRT(strchr)
+# define strcmp RT_NOCRT(strcmp)
+# define strncmp RT_NOCRT(strncmp)
+# define stricmp RT_NOCRT(stricmp)
+# define strnicmp RT_NOCRT(strnicmp)
+# define strcpy RT_NOCRT(strcpy)
+# define strncpy RT_NOCRT(strncpy)
+# define strcat RT_NOCRT(strcat)
+# define strncat RT_NOCRT(strncat)
+# define strlen RT_NOCRT(strlen)
+# define strnlen RT_NOCRT(strnlen)
+# define strstr RT_NOCRT(strstr)
+#endif
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/iprt/nocrt/x86/fenv.h b/include/iprt/nocrt/x86/fenv.h
new file mode 100644
index 00000000..3a3db7da
--- /dev/null
+++ b/include/iprt/nocrt/x86/fenv.h
@@ -0,0 +1,274 @@
+/** @file
+ * IPRT / No-CRT - fenv.h, X86.
+ */
+
+/*
+ * 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.
+ * --------------------------------------------------------------------
+ *
+ * This code is based on:
+ *
+ * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/msun/i387/fenv.h,v 1.4 2005/03/17 22:21:46 das Exp $
+ */
+
+#ifndef ___iprt_nocrt_x86_fenv_h
+#define ___iprt_nocrt_x86_fenv_h
+
+#include <iprt/types.h>
+
+/*
+ * To preserve binary compatibility with FreeBSD 5.3, we pack the
+ * mxcsr into some reserved fields, rather than changing sizeof(fenv_t).
+ */
+typedef struct {
+ uint16_t __control;
+ uint16_t __mxcsr_hi;
+ uint16_t __status;
+ uint16_t __mxcsr_lo;
+ uint32_t __tag;
+ char __other[16];
+} fenv_t;
+
+#define __get_mxcsr(env) (((env).__mxcsr_hi << 16) | \
+ ((env).__mxcsr_lo))
+#define __set_mxcsr(env, x) do { \
+ (env).__mxcsr_hi = (uint32_t)(x) >> 16; \
+ (env).__mxcsr_lo = (uint16_t)(x); \
+} while (0)
+
+typedef uint16_t fexcept_t;
+
+/* Exception flags */
+#define FE_INVALID 0x01
+#define FE_DENORMAL 0x02
+#define FE_DIVBYZERO 0x04
+#define FE_OVERFLOW 0x08
+#define FE_UNDERFLOW 0x10
+#define FE_INEXACT 0x20
+#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \
+ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
+
+/* Rounding modes */
+#define FE_TONEAREST 0x0000
+#define FE_DOWNWARD 0x0400
+#define FE_UPWARD 0x0800
+#define FE_TOWARDZERO 0x0c00
+#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
+ FE_UPWARD | FE_TOWARDZERO)
+
+/*
+ * As compared to the x87 control word, the SSE unit's control word
+ * has the rounding control bits offset by 3 and the exception mask
+ * bits offset by 7.
+ */
+#define _SSE_ROUND_SHIFT 3
+#define _SSE_EMASK_SHIFT 7
+
+/* After testing for SSE support once, we cache the result in __has_sse. */
+enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK };
+extern enum __sse_support RT_NOCRT(__has_sse);
+int RT_NOCRT(__test_sse)(void);
+#ifdef __SSE__
+#define __HAS_SSE() 1
+#else
+#define __HAS_SSE() (RT_NOCRT(__has_sse) == __SSE_YES || \
+ (RT_NOCRT(__has_sse) == __SSE_UNK && RT_NOCRT(__test_sse)()))
+#endif
+
+RT_C_DECLS_BEGIN
+
+/* Default floating-point environment */
+extern const fenv_t __fe_dfl_env;
+#define FE_DFL_ENV (&__fe_dfl_env)
+
+#define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw))
+#define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env))
+#define __fnclex() __asm __volatile("fnclex")
+#define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env)))
+#define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw)))
+#define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw)))
+#define __fwait() __asm __volatile("fwait")
+#define __ldmxcsr(__csr) __asm __volatile("ldmxcsr %0" : : "m" (__csr))
+#define __stmxcsr(__csr) __asm __volatile("stmxcsr %0" : "=m" (*(__csr)))
+
+DECLINLINE(int)
+feclearexcept(int __excepts)
+{
+ fenv_t __env;
+ int __mxcsr;
+
+ if (__excepts == FE_ALL_EXCEPT) {
+ __fnclex();
+ } else {
+ __fnstenv(&__env);
+ __env.__status &= ~__excepts;
+ __fldenv(__env);
+ }
+ if (__HAS_SSE()) {
+ __stmxcsr(&__mxcsr);
+ __mxcsr &= ~__excepts;
+ __ldmxcsr(__mxcsr);
+ }
+ return (0);
+}
+
+DECLINLINE(int)
+fegetexceptflag(fexcept_t *__flagp, int __excepts)
+{
+ int __mxcsr, __status;
+
+ __fnstsw(&__status);
+ if (__HAS_SSE())
+ __stmxcsr(&__mxcsr);
+ else
+ __mxcsr = 0;
+ *__flagp = (__mxcsr | __status) & __excepts;
+ return (0);
+}
+
+int RT_NOCRT(fesetexceptflag)(const fexcept_t *__flagp, int __excepts);
+int RT_NOCRT(feraiseexcept)(int __excepts);
+
+DECLINLINE(int)
+fetestexcept(int __excepts)
+{
+ int __mxcsr, __status;
+
+ __fnstsw(&__status);
+ if (__HAS_SSE())
+ __stmxcsr(&__mxcsr);
+ else
+ __mxcsr = 0;
+ return ((__status | __mxcsr) & __excepts);
+}
+
+DECLINLINE(int)
+fegetround(void)
+{
+ int __control;
+
+ /*
+ * We assume that the x87 and the SSE unit agree on the
+ * rounding mode. Reading the control word on the x87 turns
+ * out to be about 5 times faster than reading it on the SSE
+ * unit on an Opteron 244.
+ */
+ __fnstcw(&__control);
+ return (__control & _ROUND_MASK);
+}
+
+DECLINLINE(int)
+fesetround(int __round)
+{
+ int __mxcsr, __control;
+
+ if (__round & ~_ROUND_MASK)
+ return (-1);
+
+ __fnstcw(&__control);
+ __control &= ~_ROUND_MASK;
+ __control |= __round;
+ __fldcw(__control);
+
+ if (__HAS_SSE()) {
+ __stmxcsr(&__mxcsr);
+ __mxcsr &= ~(_ROUND_MASK << _SSE_ROUND_SHIFT);
+ __mxcsr |= __round << _SSE_ROUND_SHIFT;
+ __ldmxcsr(__mxcsr);
+ }
+
+ return (0);
+}
+
+int RT_NOCRT(fegetenv)(fenv_t *__envp);
+int RT_NOCRT(feholdexcept)(fenv_t *__envp);
+
+DECLINLINE(int)
+fesetenv(const fenv_t *__envp)
+{
+ fenv_t __env = *__envp;
+ int __mxcsr;
+
+ __mxcsr = __get_mxcsr(__env);
+ __set_mxcsr(__env, 0xffffffff);
+ __fldenv(__env);
+ if (__HAS_SSE())
+ __ldmxcsr(__mxcsr);
+ return (0);
+}
+
+int RT_NOCRT(feupdateenv)(const fenv_t *__envp);
+int RT_NOCRT(feenableexcept)(int __mask);
+int RT_NOCRT(fedisableexcept)(int __mask);
+
+DECLINLINE(int)
+fegetexcept(void)
+{
+ int __control;
+
+ /*
+ * We assume that the masks for the x87 and the SSE unit are
+ * the same.
+ */
+ __fnstcw(&__control);
+ return (~__control & FE_ALL_EXCEPT);
+}
+
+RT_C_DECLS_END
+
+#ifndef RT_WIHTOUT_NOCRT_WRAPPERS
+# define __has_sse RT_NOCRT(__has_sse)
+# define __test_sse RT_NOCRT(__test_sse)
+# define __test_sse RT_NOCRT(__test_sse)
+# define fesetexceptflag RT_NOCRT(fesetexceptflag)
+# define feraiseexcept RT_NOCRT(feraiseexcept)
+# define fegetenv RT_NOCRT(fegetenv)
+# define feholdexcept RT_NOCRT(feholdexcept)
+# define feupdateenv RT_NOCRT(feupdateenv)
+# define feenableexcept RT_NOCRT(feenableexcept)
+# define fedisableexcept RT_NOCRT(fedisableexcept)
+#endif
+
+#endif /* !__iprt_nocrt_x86_fenv_h__ */
+
diff --git a/include/iprt/nocrt/x86/math.h b/include/iprt/nocrt/x86/math.h
new file mode 100644
index 00000000..1d5dbed4
--- /dev/null
+++ b/include/iprt/nocrt/x86/math.h
@@ -0,0 +1,101 @@
+/** @file
+ * IPRT / No-CRT - math.h, x86 inlined functions.
+ */
+
+/*
+ * 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 ___iprt_nocrt_x86_math_h
+#define ___iprt_nocrt_x86_math_h
+
+#include <iprt/asm.h>
+
+#if RT_INLINE_ASM_GNU_STYLE
+
+DECLINLINE(long double) inline_atan2l(long double lrd1, long double lrd2)
+{
+ long double lrdResult;
+ __asm__ __volatile__("fpatan"
+ : "=t" (lrdResult)
+ : "u" (lrd1),
+ "0" (lrd2)
+ : "st(1)");
+ return lrdResult;
+}
+
+DECLINLINE(long double) inline_rintl(long double lrd)
+{
+ long double lrdResult;
+ __asm__ __volatile__("frndint"
+ : "=t" (lrdResult)
+ : "0" (lrd));
+ return lrdResult;
+}
+
+DECLINLINE(float) inline_rintf(float rf)
+{
+ return (float)inline_rintl(rf);
+}
+
+DECLINLINE(double) inline_rint(double rd)
+{
+ return (double)inline_rintl(rd);
+}
+
+DECLINLINE(long double) inline_sqrtl(long double lrd)
+{
+ long double lrdResult;
+ __asm__ __volatile__("fsqrt"
+ : "=t" (lrdResult)
+ : "0" (lrd));
+ return lrdResult;
+}
+
+DECLINLINE(float) inline_sqrtf(float rf)
+{
+ return (float)inline_sqrtl(rf);
+}
+
+DECLINLINE(double) inline_sqrt(double rd)
+{
+ return (double)inline_sqrtl(rd);
+}
+
+
+# undef atan2l
+# define atan2l(lrd1, lrd2) inline_atan2l(lrd1, lrd2)
+# undef rint
+# define rint(rd) inline_rint(rd)
+# undef rintf
+# define rintf(rf) inline_rintf(rf)
+# undef rintl
+# define rintl(lrd) inline_rintl(lrd)
+# undef sqrt
+# define sqrt(rd) inline_sqrt(rd)
+# undef sqrtf
+# define sqrtf(rf) inline_sqrtf(rf)
+# undef sqrtl
+# define sqrtl(lrd) inline_sqrtl(lrd)
+
+#endif /* RT_INLINE_ASM_GNU_STYLE */
+
+#endif
+
diff --git a/include/iprt/ntwrap.mac b/include/iprt/ntwrap.mac
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/include/iprt/ntwrap.mac
diff --git a/include/iprt/once.h b/include/iprt/once.h
new file mode 100644
index 00000000..31afb739
--- /dev/null
+++ b/include/iprt/once.h
@@ -0,0 +1,162 @@
+/** @file
+ * IPRT - Execute Once.
+ */
+
+/*
+ * 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 ___iprt_once_h
+#define ___iprt_once_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/asm.h>
+#include <iprt/err.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_once RTOnce - Execute Once
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Execute once structure.
+ *
+ * This is typically a global variable that is statically initialized
+ * by RTONCE_INITIALIZER.
+ */
+typedef struct RTONCE
+{
+ /** Event semaphore that the other guys are blocking on. */
+ RTSEMEVENTMULTI volatile hEventMulti;
+ /** Reference counter for hEventMulti. */
+ int32_t volatile cEventRefs;
+ /** -1 when uninitialized, 1 when initializing (busy) and 2 when done. */
+ int32_t volatile iState;
+ /** The return code of pfnOnce. */
+ int32_t volatile rc;
+} RTONCE;
+/** Pointer to a execute once struct. */
+typedef RTONCE *PRTONCE;
+
+/**
+ * The execute once statemachine.
+ */
+typedef enum RTONCESTATE
+{
+ /** RTOnce() has not been called.
+ * Next: NO_SEM */
+ RTONCESTATE_UNINITIALIZED = 1,
+ /** RTOnce() is busy, no race.
+ * Next: CREATING_SEM, DONE */
+ RTONCESTATE_BUSY_NO_SEM,
+ /** More than one RTOnce() caller is busy.
+ * Next: BUSY_HAVE_SEM, BUSY_SPIN, DONE_CREATING_SEM, DONE */
+ RTONCESTATE_BUSY_CREATING_SEM,
+ /** More than one RTOnce() caller, the first is busy, the others are
+ * waiting.
+ * Next: DONE */
+ RTONCESTATE_BUSY_HAVE_SEM,
+ /** More than one RTOnce() caller, the first is busy, the others failed to
+ * create a semaphore and are spinning.
+ * Next: DONE */
+ RTONCESTATE_BUSY_SPIN,
+ /** More than one RTOnce() caller, the first has completed, the others
+ * are busy creating the semaphore.
+ * Next: DONE_HAVE_SEM */
+ RTONCESTATE_DONE_CREATING_SEM,
+ /** More than one RTOnce() caller, the first is busy grabbing the
+ * semaphore, while the others are waiting.
+ * Next: DONE */
+ RTONCESTATE_DONE_HAVE_SEM,
+ /** The execute once stuff has completed. */
+ RTONCESTATE_DONE = 16
+} RTONCESTATE;
+
+/** Static initializer for RTONCE variables. */
+#define RTONCE_INITIALIZER { NIL_RTSEMEVENTMULTI, 0, RTONCESTATE_UNINITIALIZED, VERR_INTERNAL_ERROR }
+
+
+/**
+ * Callback that gets executed once.
+ *
+ * @returns IPRT style status code, RTOnce returns this.
+ *
+ * @param pvUser1 The first user parameter.
+ * @param pvUser2 The second user parameter.
+ */
+typedef DECLCALLBACK(int32_t) FNRTONCE(void *pvUser1, void *pvUser2);
+/** Pointer to a FNRTONCE. */
+typedef FNRTONCE *PFNRTONCE;
+
+/**
+ * Serializes execution of the pfnOnce function, making sure it's
+ * executed exactly once and that nobody returns from RTOnce before
+ * it has executed successfully.
+ *
+ * @returns IPRT like status code returned by pfnOnce.
+ *
+ * @param pOnce Pointer to the execute once variable.
+ * @param pfnOnce The function to executed once.
+ * @param pvUser1 The first user parameter for pfnOnce.
+ * @param pvUser2 The second user parameter for pfnOnce.
+ */
+RTDECL(int) RTOnceSlow(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pvUser2);
+
+/**
+ * Serializes execution of the pfnOnce function, making sure it's
+ * executed exactly once and that nobody returns from RTOnce before
+ * it has executed successfully.
+ *
+ * @returns IPRT like status code returned by pfnOnce.
+ *
+ * @param pOnce Pointer to the execute once variable.
+ * @param pfnOnce The function to executed once.
+ * @param pvUser1 The first user parameter for pfnOnce.
+ * @param pvUser2 The second user parameter for pfnOnce.
+ */
+DECLINLINE(int) RTOnce(PRTONCE pOnce, PFNRTONCE pfnOnce, void *pvUser1, void *pvUser2)
+{
+ int32_t iState = ASMAtomicUoReadS32(&pOnce->iState);
+ if (RT_LIKELY( iState == RTONCESTATE_DONE
+ || iState == RTONCESTATE_DONE_CREATING_SEM
+ || iState == RTONCESTATE_DONE_HAVE_SEM ))
+ return ASMAtomicUoReadS32(&pOnce->rc);
+ return RTOnceSlow(pOnce, pfnOnce, pvUser1, pvUser2);
+}
+
+/**
+ * Resets an execute once variable.
+ *
+ * The caller is responsible for making sure there are no concurrent accesses to
+ * the execute once variable.
+ *
+ * @param pOnce Pointer to the execute once variable.
+ */
+RTDECL(void) RTOnceReset(PRTONCE pOnce);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/param.h b/include/iprt/param.h
new file mode 100644
index 00000000..0e95e52d
--- /dev/null
+++ b/include/iprt/param.h
@@ -0,0 +1,131 @@
+/** @file
+ * IPRT - Parameter 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 ___iprt_param_h
+#define ___iprt_param_h
+
+/** @todo Much of the PAGE_* stuff here is obsolete and highly risky to have around.
+ * As for component configs (MM_*), either we gather all in here or we move those bits away! */
+
+/** @defgroup grp_rt_param System Parameter Definitions
+ * @ingroup grp_rt_cdefs
+ * @{
+ */
+
+/* Undefine PAGE_SIZE and PAGE_SHIFT to avoid unnecessary noice when clashing
+ * with system headers. Include system headers before / after iprt depending
+ * on which you wish to take precedence. */
+#undef PAGE_SIZE
+#undef PAGE_SHIFT
+
+/* Undefine PAGE_OFFSET_MASK to avoid the conflict with the-linux-kernel.h */
+#undef PAGE_OFFSET_MASK
+
+/**
+ * i386 Page size.
+ */
+#if defined(RT_ARCH_SPARC64)
+# define PAGE_SIZE 8192
+#else
+# define PAGE_SIZE 4096
+#endif
+
+/**
+ * i386 Page shift.
+ * This is used to convert between size (in bytes) and page count.
+ */
+#if defined(RT_ARCH_SPARC64)
+# define PAGE_SHIFT 13
+#else
+# define PAGE_SHIFT 12
+#endif
+
+/**
+ * i386 Page offset mask.
+ *
+ * Do NOT one-complement this for whatever purpose. You may get a 32-bit const when you want a 64-bit one.
+ * Use PAGE_BASE_MASK, PAGE_BASE_GC_MASK, PAGE_BASE_HC_MASK, PAGE_ADDRESS() or X86_PTE_PAE_PG_MASK.
+ */
+#if defined(RT_ARCH_SPARC64)
+# define PAGE_OFFSET_MASK 0x1fff
+#else
+# define PAGE_OFFSET_MASK 0xfff
+#endif
+
+/**
+ * Page address mask for the guest context POINTERS.
+ * @remark Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ */
+#define PAGE_BASE_GC_MASK (~(RTGCUINTPTR)PAGE_OFFSET_MASK)
+
+/**
+ * Page address mask for the host context POINTERS.
+ * @remark Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ */
+#define PAGE_BASE_HC_MASK (~(RTHCUINTPTR)PAGE_OFFSET_MASK)
+
+/**
+ * Page address mask for the both context POINTERS.
+ *
+ * Be careful when using this since it may be a size too big!
+ * @remark Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ */
+#define PAGE_BASE_MASK (~(RTUINTPTR)PAGE_OFFSET_MASK)
+
+/**
+ * Get the page aligned address of a POINTER in the CURRENT context.
+ *
+ * @returns Page aligned address (it's an uintptr_t).
+ * @param pv The virtual address to align.
+ *
+ * @remarks Physical addresses are always masked using X86_PTE_PAE_PG_MASK!
+ * @remarks This only works with POINTERS in the current context.
+ * Do NOT use on guest address or physical address!
+ */
+#define PAGE_ADDRESS(pv) ((uintptr_t)(pv) & ~(uintptr_t)PAGE_OFFSET_MASK)
+
+/**
+ * Get the page aligned address of a physical address
+ *
+ * @returns Page aligned address (it's an RTHCPHYS or RTGCPHYS).
+ * @param Phys The physical address to align.
+ */
+#define PHYS_PAGE_ADDRESS(Phys) ((Phys) & X86_PTE_PAE_PG_MASK)
+
+/**
+ * Host max path (the reasonable value).
+ * @remarks defined both by iprt/param.h and iprt/path.h.
+ */
+#if !defined(___iprt_path_h) || defined(DOXYGEN_RUNNING)
+# define RTPATH_MAX (4096 + 4) /* (PATH_MAX + 1) on linux w/ some alignment */
+#endif
+
+/** @} */
+
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/path.h b/include/iprt/path.h
new file mode 100644
index 00000000..7e51f87d
--- /dev/null
+++ b/include/iprt/path.h
@@ -0,0 +1,942 @@
+/** @file
+ * IPRT - Path Manipulation.
+ */
+
+/*
+ * 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 ___iprt_path_h
+#define ___iprt_path_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#ifdef IN_RING3
+# include <iprt/fs.h>
+#endif
+
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_path RTPath - Path Manipulation
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Host max path (the reasonable value).
+ * @remarks defined both by iprt/param.h and iprt/path.h.
+ */
+#if !defined(___iprt_param_h) || defined(DOXYGEN_RUNNING)
+# define RTPATH_MAX (4096 + 4) /* (PATH_MAX + 1) on linux w/ some alignment */
+#endif
+
+/** @def RTPATH_SLASH
+ * The preferred slash character.
+ *
+ * @remark IPRT will always accept unix slashes. So, normally you would
+ * never have to use this define.
+ */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define RTPATH_SLASH '\\'
+#else
+# define RTPATH_SLASH '/'
+#endif
+
+/** @deprecated Use '/'! */
+#define RTPATH_DELIMITER RTPATH_SLASH
+
+
+/** @def RTPATH_SLASH_STR
+ * The preferred slash character as a string, handy for concatenations
+ * with other strings.
+ *
+ * @remark IPRT will always accept unix slashes. So, normally you would
+ * never have to use this define.
+ */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define RTPATH_SLASH_STR "\\"
+#else
+# define RTPATH_SLASH_STR "/"
+#endif
+
+
+/** @def RTPATH_IS_SLASH
+ * Checks if a character is a slash.
+ *
+ * @returns true if it's a slash and false if not.
+ * @returns @param ch Char to check.
+ */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define RTPATH_IS_SLASH(ch) ( (ch) == '\\' || (ch) == '/' )
+#else
+# define RTPATH_IS_SLASH(ch) ( (ch) == '/' )
+#endif
+
+
+/** @def RTPATH_IS_VOLSEP
+ * Checks if a character marks the end of the volume specification.
+ *
+ * @remark This is sufficient for the drive letter concept on PC.
+ * However it might be insufficient on other platforms
+ * and even on PC a UNC volume spec won't be detected this way.
+ * Use the RTPath@<too be created@>() instead.
+ *
+ * @returns true if it is and false if it isn't.
+ * @returns @param ch Char to check.
+ */
+#if defined(RT_OS_OS2) || defined(RT_OS_WINDOWS)
+# define RTPATH_IS_VOLSEP(ch) ( (ch) == ':' )
+#else
+# define RTPATH_IS_VOLSEP(ch) (false)
+#endif
+
+
+/** @def RTPATH_IS_SEP
+ * Checks if a character is path component separator
+ *
+ * @returns true if it is and false if it isn't.
+ * @returns @param ch Char to check.
+ * @
+ */
+#define RTPATH_IS_SEP(ch) ( RTPATH_IS_SLASH(ch) || RTPATH_IS_VOLSEP(ch) )
+
+
+/** @name Generic RTPath flags
+ * @{ */
+/** Last component: Work on the link. */
+#define RTPATH_F_ON_LINK RT_BIT_32(0)
+/** Last component: Follow if link. */
+#define RTPATH_F_FOLLOW_LINK RT_BIT_32(1)
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTPATH_F_NO_SYMLINKS RT_BIT_32(2)
+/** @} */
+
+
+/** Validates a flags parameter containing RTPATH_F_*.
+ * @remarks The parameters will be referenced multiple times. */
+#define RTPATH_F_IS_VALID(fFlags, fIgnore) \
+ ( ((fFlags) & ~(uint32_t)((fIgnore)|RTPATH_F_NO_SYMLINKS)) == RTPATH_F_ON_LINK \
+ || ((fFlags) & ~(uint32_t)((fIgnore)|RTPATH_F_NO_SYMLINKS)) == RTPATH_F_FOLLOW_LINK )
+
+
+/**
+ * Checks if the path exists.
+ *
+ * Symbolic links will all be attempted resolved and broken links means false.
+ *
+ * @returns true if it exists and false if it doesn't.
+ * @param pszPath The path to check.
+ */
+RTDECL(bool) RTPathExists(const char *pszPath);
+
+/**
+ * Checks if the path exists.
+ *
+ * @returns true if it exists and false if it doesn't.
+ * @param pszPath The path to check.
+ * @param fFlags RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ */
+RTDECL(bool) RTPathExistsEx(const char *pszPath, uint32_t fFlags);
+
+/**
+ * Sets the current working directory of the process.
+ *
+ * @returns IPRT status code.
+ * @param pszPath The path to the new working directory.
+ */
+RTDECL(int) RTPathSetCurrent(const char *pszPath);
+
+/**
+ * Gets the current working directory of the process.
+ *
+ * @returns IPRT status code.
+ * @param pszPath Where to store the path.
+ * @param cchPath The size of the buffer pszPath points to.
+ */
+RTDECL(int) RTPathGetCurrent(char *pszPath, size_t cchPath);
+
+/**
+ * Get the real path (no symlinks, no . or .. components), must exist.
+ *
+ * @returns iprt status code.
+ * @param pszPath The path to resolve.
+ * @param pszRealPath Where to store the real path.
+ * @param cchRealPath Size of the buffer.
+ */
+RTDECL(int) RTPathReal(const char *pszPath, char *pszRealPath, size_t cchRealPath);
+
+/**
+ * Same as RTPathReal only the result is RTStrDup()'ed.
+ *
+ * @returns Pointer to real path. Use RTStrFree() to free this string.
+ * @returns NULL if RTPathReal() or RTStrDup() fails.
+ * @param pszPath The path to resolve.
+ */
+RTDECL(char *) RTPathRealDup(const char *pszPath);
+
+/**
+ * Get the absolute path (starts from root, no . or .. components), doesn't have
+ * to exist. Note that this method is designed to never perform actual file
+ * system access, therefore symlinks are not resolved.
+ *
+ * @returns iprt status code.
+ * @param pszPath The path to resolve.
+ * @param pszAbsPath Where to store the absolute path.
+ * @param cchAbsPath Size of the buffer.
+ */
+RTDECL(int) RTPathAbs(const char *pszPath, char *pszAbsPath, size_t cchAbsPath);
+
+/**
+ * Same as RTPathAbs only the result is RTStrDup()'ed.
+ *
+ * @returns Pointer to the absolute path. Use RTStrFree() to free this string.
+ * @returns NULL if RTPathAbs() or RTStrDup() fails.
+ * @param pszPath The path to resolve.
+ */
+RTDECL(char *) RTPathAbsDup(const char *pszPath);
+
+/**
+ * Get the absolute path (no symlinks, no . or .. components), assuming the
+ * given base path as the current directory. The resulting path doesn't have
+ * to exist.
+ *
+ * @returns iprt status code.
+ * @param pszBase The base path to act like a current directory.
+ * When NULL, the actual cwd is used (i.e. the call
+ * is equivalent to RTPathAbs(pszPath, ...).
+ * @param pszPath The path to resolve.
+ * @param pszAbsPath Where to store the absolute path.
+ * @param cchAbsPath Size of the buffer.
+ */
+RTDECL(int) RTPathAbsEx(const char *pszBase, const char *pszPath, char *pszAbsPath, size_t cchAbsPath);
+
+/**
+ * Same as RTPathAbsEx only the result is RTStrDup()'ed.
+ *
+ * @returns Pointer to the absolute path. Use RTStrFree() to free this string.
+ * @returns NULL if RTPathAbsEx() or RTStrDup() fails.
+ * @param pszBase The base path to act like a current directory.
+ * When NULL, the actual cwd is used (i.e. the call
+ * is equivalent to RTPathAbs(pszPath, ...).
+ * @param pszPath The path to resolve.
+ */
+RTDECL(char *) RTPathAbsExDup(const char *pszBase, const char *pszPath);
+
+/**
+ * Strips the filename from a path. Truncates the given string in-place by overwriting the
+ * last path separator character with a null byte in a platform-neutral way.
+ *
+ * @param pszPath Path from which filename should be extracted, will be truncated.
+ * If the string contains no path separator, it will be changed to a "." string.
+ */
+RTDECL(void) RTPathStripFilename(char *pszPath);
+
+/**
+ * Strips the extension from a path.
+ *
+ * @param pszPath Path which extension should be stripped.
+ */
+RTDECL(void) RTPathStripExt(char *pszPath);
+
+/**
+ * Strips the trailing slashes of a path name.
+ *
+ * Won't strip root slashes.
+ *
+ * @returns The new length of pszPath.
+ * @param pszPath Path to strip.
+ */
+RTDECL(size_t) RTPathStripTrailingSlash(char *pszPath);
+
+/**
+ * Changes all the slashes in the specified path to DOS style.
+ *
+ * Unless @a fForce is set, nothing will be done when on a UNIX flavored system
+ * since paths wont work with DOS style slashes there.
+ *
+ * @returns @a pszPath.
+ * @param pszPath The path to modify.
+ * @param fForce Whether to force the conversion on non-DOS OSes.
+ */
+RTDECL(char *) RTPathChangeToDosSlashes(char *pszPath, bool fForce);
+
+/**
+ * Changes all the slashes in the specified path to unix style.
+ *
+ * Unless @a fForce is set, nothing will be done when on a UNIX flavored system
+ * since paths wont work with DOS style slashes there.
+ *
+ * @returns @a pszPath.
+ * @param pszPath The path to modify.
+ * @param fForce Whether to force the conversion on non-DOS OSes.
+ */
+RTDECL(char *) RTPathChangeToUnixSlashes(char *pszPath, bool fForce);
+
+/**
+ * Parses a path.
+ *
+ * It figures the length of the directory component, the offset of
+ * the file name and the location of the suffix dot.
+ *
+ * @returns The path length.
+ *
+ * @param pszPath Path to find filename in.
+ * @param pcchDir Where to put the length of the directory component. If
+ * no directory, this will be 0. Optional.
+ * @param poffName Where to store the filename offset.
+ * If empty string or if it's ending with a slash this
+ * will be set to -1. Optional.
+ * @param poffSuff Where to store the suffix offset (the last dot).
+ * If empty string or if it's ending with a slash this
+ * will be set to -1. Optional.
+ */
+RTDECL(size_t) RTPathParse(const char *pszPath, size_t *pcchDir, ssize_t *poffName, ssize_t *poffSuff);
+
+/**
+ * Finds the filename in a path.
+ *
+ * @returns Pointer to filename within pszPath.
+ * @returns NULL if no filename (i.e. empty string or ends with a slash).
+ * @param pszPath Path to find filename in.
+ */
+RTDECL(char *) RTPathFilename(const char *pszPath);
+
+/**
+ * Finds the extension part of in a path.
+ *
+ * @returns Pointer to extension within pszPath.
+ * @returns NULL if no extension.
+ * @param pszPath Path to find extension in.
+ */
+RTDECL(char *) RTPathExt(const char *pszPath);
+
+/**
+ * Checks if a path has an extension.
+ *
+ * @returns true if extension present.
+ * @returns false if no extension.
+ * @param pszPath Path to check.
+ */
+RTDECL(bool) RTPathHasExt(const char *pszPath);
+/** Misspelled, don't use. */
+#define RTPathHaveExt RTPathHasExt
+
+/**
+ * Checks if a path includes more than a filename.
+ *
+ * @returns true if path present.
+ * @returns false if no path.
+ * @param pszPath Path to check.
+ */
+RTDECL(bool) RTPathHasPath(const char *pszPath);
+/** Misspelled, don't use. */
+#define RTPathHavePath RTPathHasPath
+
+/**
+ * Checks if the path starts with a root specifier or not.
+ *
+ * @returns @c true if it starts with root, @c false if not.
+ *
+ * @param pszPath Path to check.
+ */
+RTDECL(bool) RTPathStartsWithRoot(const char *pszPath);
+
+/**
+ * Counts the components in the specified path.
+ *
+ * An empty string has zero components. A lone root slash is considered have
+ * one. The paths "/init" and "/bin/" are considered having two components. An
+ * UNC share specifier like "\\myserver\share" will be considered as one single
+ * component.
+ *
+ * @returns The number of path components.
+ * @param pszPath The path to parse.
+ */
+RTDECL(size_t) RTPathCountComponents(const char *pszPath);
+
+/**
+ * Copies the specified number of path components from @a pszSrc and into @a
+ * pszDst.
+ *
+ * @returns VINF_SUCCESS or VERR_BUFFER_OVERFLOW. In the latter case the buffer
+ * is not touched.
+ *
+ * @param pszDst The destination buffer.
+ * @param cbDst The size of the destination buffer.
+ * @param pszSrc The source path.
+ * @param cComponents The number of components to copy from @a pszSrc.
+ */
+RTDECL(int) RTPathCopyComponents(char *pszDst, size_t cbDst, const char *pszSrc, size_t cComponents);
+
+/**
+ * Compares two paths.
+ *
+ * The comparison takes platform-dependent details into account,
+ * such as:
+ * <ul>
+ * <li>On DOS-like platforms, both separator chars (|\| and |/|) are considered
+ * to be equal.
+ * <li>On platforms with case-insensitive file systems, mismatching characters
+ * are uppercased and compared again.
+ * </ul>
+ *
+ * @returns @< 0 if the first path less than the second path.
+ * @returns 0 if the first path identical to the second path.
+ * @returns @> 0 if the first path greater than the second path.
+ *
+ * @param pszPath1 Path to compare (must be an absolute path).
+ * @param pszPath2 Path to compare (must be an absolute path).
+ *
+ * @remarks File system details are currently ignored. This means that you won't
+ * get case-insensitive compares on unix systems when a path goes into a
+ * case-insensitive filesystem like FAT, HPFS, HFS, NTFS, JFS, or
+ * similar. For NT, OS/2 and similar you'll won't get case-sensitive
+ * compares on a case-sensitive file system.
+ */
+RTDECL(int) RTPathCompare(const char *pszPath1, const char *pszPath2);
+
+/**
+ * Checks if a path starts with the given parent path.
+ *
+ * This means that either the path and the parent path matches completely, or
+ * that the path is to some file or directory residing in the tree given by the
+ * parent directory.
+ *
+ * The path comparison takes platform-dependent details into account,
+ * see RTPathCompare() for details.
+ *
+ * @returns |true| when \a pszPath starts with \a pszParentPath (or when they
+ * are identical), or |false| otherwise.
+ *
+ * @param pszPath Path to check, must be an absolute path.
+ * @param pszParentPath Parent path, must be an absolute path.
+ * No trailing directory slash!
+ *
+ * @remarks This API doesn't currently handle root directory compares in a
+ * manner consistent with the other APIs. RTPathStartsWith(pszSomePath,
+ * "/") will not work if pszSomePath isn't "/".
+ */
+RTDECL(bool) RTPathStartsWith(const char *pszPath, const char *pszParentPath);
+
+/**
+ * Appends one partial path to another.
+ *
+ * The main purpose of this function is to deal correctly with the slashes when
+ * concatenating the two partial paths.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ * cbPathDst bytes. No changes has been made.
+ * @retval VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ * than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param pszPath The path to append pszAppend to. This serves as both
+ * input and output. This can be empty, in which case
+ * pszAppend is just copied over.
+ * @param cbPathDst The size of the buffer pszPath points to, terminator
+ * included. This should NOT be strlen(pszPath).
+ * @param pszAppend The partial path to append to pszPath. This can be
+ * NULL, in which case nothing is done.
+ *
+ * @remarks See the RTPathAppendEx remarks.
+ */
+RTDECL(int) RTPathAppend(char *pszPath, size_t cbPathDst, const char *pszAppend);
+
+/**
+ * Appends one partial path to another.
+ *
+ * The main purpose of this function is to deal correctly with the slashes when
+ * concatenating the two partial paths.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ * cbPathDst bytes. No changes has been made.
+ * @retval VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ * than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param pszPath The path to append pszAppend to. This serves as both
+ * input and output. This can be empty, in which case
+ * pszAppend is just copied over.
+ * @param cbPathDst The size of the buffer pszPath points to, terminator
+ * included. This should NOT be strlen(pszPath).
+ * @param pszAppend The partial path to append to pszPath. This can be
+ * NULL, in which case nothing is done.
+ * @param cchAppendMax The maximum number or characters to take from @a
+ * pszAppend. RTSTR_MAX is fine.
+ *
+ * @remarks On OS/2, Window and similar systems, concatenating a drive letter
+ * specifier with a slash prefixed path will result in an absolute
+ * path. Meaning, RTPathAppend(strcpy(szBuf, "C:"), sizeof(szBuf),
+ * "/bar") will result in "C:/bar". (This follows directly from the
+ * behavior when pszPath is empty.)
+ *
+ * On the other hand, when joining a drive letter specifier with a
+ * partial path that does not start with a slash, the result is not an
+ * absolute path. Meaning, RTPathAppend(strcpy(szBuf, "C:"),
+ * sizeof(szBuf), "bar") will result in "C:bar".
+ */
+RTDECL(int) RTPathAppendEx(char *pszPath, size_t cbPathDst, const char *pszAppend, size_t cchAppendMax);
+
+/**
+ * Like RTPathAppend, but with the base path as a separate argument instead of
+ * in the path buffer.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ * cbPathDst bytes.
+ * @retval VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ * than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param pszPathDst Where to store the resulting path.
+ * @param cbPathDst The size of the buffer pszPathDst points to,
+ * terminator included.
+ * @param pszPathSrc The base path to copy into @a pszPathDst before
+ * appending @a pszAppend.
+ * @param pszAppend The partial path to append to pszPathSrc. This can
+ * be NULL, in which case nothing is done.
+ *
+ */
+RTDECL(int) RTPathJoin(char *pszPathDst, size_t cbPathDst, const char *pszPathSrc,
+ const char *pszAppend);
+
+/**
+ * Same as RTPathJoin, except that the output buffer is allocated.
+ *
+ * @returns Buffer containing the joined up path, call RTStrFree to free. NULL
+ * on allocation failure.
+ * @param pszPathSrc The base path to copy into @a pszPathDst before
+ * appending @a pszAppend.
+ * @param pszAppend The partial path to append to pszPathSrc. This can
+ * be NULL, in which case nothing is done.
+ *
+ */
+RTDECL(char *) RTPathJoinA(const char *pszPathSrc, const char *pszAppend);
+
+/**
+ * Extended version of RTPathJoin, both inputs can be specified as substrings.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the result is too big to fit within
+ * cbPathDst bytes.
+ * @retval VERR_INVALID_PARAMETER if the string pointed to by pszPath is longer
+ * than cbPathDst-1 bytes (failed to find terminator). Asserted.
+ *
+ * @param pszPathDst Where to store the resulting path.
+ * @param cbPathDst The size of the buffer pszPathDst points to,
+ * terminator included.
+ * @param pszPathSrc The base path to copy into @a pszPathDst before
+ * appending @a pszAppend.
+ * @param cchPathSrcMax The maximum number of bytes to copy from @a
+ * pszPathSrc. RTSTR_MAX is find.
+ * @param pszAppend The partial path to append to pszPathSrc. This can
+ * be NULL, in which case nothing is done.
+ * @param cchAppendMax The maximum number of bytes to copy from @a
+ * pszAppend. RTSTR_MAX is find.
+ *
+ */
+RTDECL(int) RTPathJoinEx(char *pszPathDst, size_t cbPathDst,
+ const char *pszPathSrc, size_t cchPathSrcMax,
+ const char *pszAppend, size_t cchAppendMax);
+
+/**
+ * Callback for RTPathTraverseList that's called for each element.
+ *
+ * @returns IPRT style status code. Return VERR_TRY_AGAIN to continue, any other
+ * value will abort the traversing and be returned to the caller.
+ *
+ * @param pchPath Pointer to the start of the current path. This is
+ * not null terminated.
+ * @param cchPath The length of the path.
+ * @param pvUser1 The first user parameter.
+ * @param pvUser2 The second user parameter.
+ */
+typedef DECLCALLBACK(int) FNRTPATHTRAVERSER(char const *pchPath, size_t cchPath, void *pvUser1, void *pvUser2);
+/** Pointer to a FNRTPATHTRAVERSER. */
+typedef FNRTPATHTRAVERSER *PFNRTPATHTRAVERSER;
+
+/**
+ * Traverses a string that can contain multiple paths separated by a special
+ * character.
+ *
+ * @returns IPRT style status code from the callback or VERR_END_OF_STRING if
+ * the callback returned VERR_TRY_AGAIN for all paths in the string.
+ *
+ * @param pszPathList The string to traverse.
+ * @param chSep The separator character. Using the null terminator
+ * is fine, but the result will simply be that there
+ * will only be one callback for the entire string
+ * (save any leading white space).
+ * @param pfnCallback The callback.
+ * @param pvUser1 First user argument for the callback.
+ * @param pvUser2 Second user argument for the callback.
+ */
+RTDECL(int) RTPathTraverseList(const char *pszPathList, char chSep, PFNRTPATHTRAVERSER pfnCallback, void *pvUser1, void *pvUser2);
+
+
+#ifdef IN_RING3
+
+/**
+ * Gets the path to the directory containing the executable.
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathExecDir(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the user home directory.
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the user documents directory.
+ *
+ * The returned path isn't guarantied to exist.
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathUserDocuments(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory of shared libraries.
+ *
+ * This is not the same as RTPathAppPrivateArch() as Linux depends all shared
+ * libraries in a common global directory where ld.so can find them.
+ *
+ * Linux: /usr/lib
+ * Solaris: /opt/@<application@>/@<arch>@ or something
+ * Windows: @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathSharedLibs(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory for architecture-independent application data, for
+ * example NLS files, module sources, ...
+ *
+ * Linux: /usr/shared/@<application@>
+ * Solaris: /opt/@<application@>
+ * Windows: @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppPrivateNoArch(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory for architecture-dependent application data, for
+ * example modules which can be loaded at runtime.
+ *
+ * Linux: /usr/lib/@<application@>
+ * Solaris: /opt/@<application@>/@<arch>@ or something
+ * Windows: @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppPrivateArch(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the toplevel directory for architecture-dependent application data.
+ *
+ * This differs from RTPathAppPrivateArch on Solaris only where it will work
+ * around the /opt/@<application@>/amd64 and /opt/@<application@>/i386 multi
+ * architecture installation style.
+ *
+ * Linux: /usr/lib/@<application@>
+ * Solaris: /opt/@<application@>
+ * Windows: @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppPrivateArchTop(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the directory for documentation.
+ *
+ * Linux: /usr/share/doc/@<application@>
+ * Solaris: /opt/@<application@>
+ * Windows: @<program files directory@>/@<application@>
+ * Old path: same as RTPathExecDir()
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathAppDocs(char *pszPath, size_t cchPath);
+
+/**
+ * Gets the temporary directory path.
+ *
+ * @returns iprt status code.
+ * @param pszPath Buffer where to store the path.
+ * @param cchPath Buffer size in bytes.
+ */
+RTDECL(int) RTPathTemp(char *pszPath, size_t cchPath);
+
+/**
+ * Query information about a file system object.
+ *
+ * This API will resolve NOT symbolic links in the last component (just like
+ * unix lstat()).
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if the object exists, information returned.
+ * @retval VERR_PATH_NOT_FOUND if any but the last component in the specified
+ * path was not found or was not a directory.
+ * @retval VERR_FILE_NOT_FOUND if the object does not exist (but path to the
+ * parent directory exists).
+ *
+ * @param pszPath Path to the file system object.
+ * @param pObjInfo Object information structure to be filled on successful
+ * return.
+ * @param enmAdditionalAttribs
+ * Which set of additional attributes to request.
+ * Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
+ */
+RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs);
+
+/**
+ * Query information about a file system object.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if the object exists, information returned.
+ * @retval VERR_PATH_NOT_FOUND if any but the last component in the specified
+ * path was not found or was not a directory.
+ * @retval VERR_FILE_NOT_FOUND if the object does not exist (but path to the
+ * parent directory exists).
+ *
+ * @param pszPath Path to the file system object.
+ * @param pObjInfo Object information structure to be filled on successful return.
+ * @param enmAdditionalAttribs
+ * Which set of additional attributes to request.
+ * Use RTFSOBJATTRADD_NOTHING if this doesn't matter.
+ * @param fFlags RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ */
+RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags);
+
+/**
+ * Changes the mode flags of a file system object.
+ *
+ * The API requires at least one of the mode flag sets (Unix/Dos) to
+ * be set. The type is ignored.
+ *
+ * This API will resolve symbolic links in the last component since
+ * mode isn't important for symbolic links.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param fMode The new file mode, see @ref grp_rt_fs for details.
+ */
+RTR3DECL(int) RTPathSetMode(const char *pszPath, RTFMODE fMode);
+
+/**
+ * Gets the mode flags of a file system object.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param pfMode Where to store the file mode, see @ref grp_rt_fs for details.
+ *
+ * @remark This is wrapper around RTPathQueryInfoEx(RTPATH_F_FOLLOW_LINK) and
+ * exists to complement RTPathSetMode().
+ */
+RTR3DECL(int) RTPathGetMode(const char *pszPath, PRTFMODE pfMode);
+
+/**
+ * Changes one or more of the timestamps associated of file system object.
+ *
+ * This API will not resolve symbolic links in the last component (just
+ * like unix lutimes()).
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param pAccessTime Pointer to the new access time.
+ * @param pModificationTime Pointer to the new modification time.
+ * @param pChangeTime Pointer to the new change time. NULL if not to be changed.
+ * @param pBirthTime Pointer to the new time of birth. NULL if not to be changed.
+ *
+ * @remark The file system might not implement all these time attributes,
+ * the API will ignore the ones which aren't supported.
+ *
+ * @remark The file system might not implement the time resolution
+ * employed by this interface, the time will be chopped to fit.
+ *
+ * @remark The file system may update the change time even if it's
+ * not specified.
+ *
+ * @remark POSIX can only set Access & Modification and will always set both.
+ */
+RTR3DECL(int) RTPathSetTimes(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+ PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
+
+/**
+ * Changes one or more of the timestamps associated of file system object.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param pAccessTime Pointer to the new access time.
+ * @param pModificationTime Pointer to the new modification time.
+ * @param pChangeTime Pointer to the new change time. NULL if not to be changed.
+ * @param pBirthTime Pointer to the new time of birth. NULL if not to be changed.
+ * @param fFlags RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ *
+ * @remark The file system might not implement all these time attributes,
+ * the API will ignore the ones which aren't supported.
+ *
+ * @remark The file system might not implement the time resolution
+ * employed by this interface, the time will be chopped to fit.
+ *
+ * @remark The file system may update the change time even if it's
+ * not specified.
+ *
+ * @remark POSIX can only set Access & Modification and will always set both.
+ */
+RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+ PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags);
+
+/**
+ * Gets one or more of the timestamps associated of file system object.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param pAccessTime Where to store the access time. NULL is ok.
+ * @param pModificationTime Where to store the modification time. NULL is ok.
+ * @param pChangeTime Where to store the change time. NULL is ok.
+ * @param pBirthTime Where to store the creation time. NULL is ok.
+ *
+ * @remark This is wrapper around RTPathQueryInfo() and exists to complement
+ * RTPathSetTimes(). If the last component is a symbolic link, it will
+ * not be resolved.
+ */
+RTR3DECL(int) RTPathGetTimes(const char *pszPath, PRTTIMESPEC pAccessTime, PRTTIMESPEC pModificationTime,
+ PRTTIMESPEC pChangeTime, PRTTIMESPEC pBirthTime);
+
+/**
+ * Changes the owner and/or group of a file system object.
+ *
+ * This API will not resolve symbolic links in the last component (just
+ * like unix lchown()).
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param uid The new file owner user id. Pass NIL_RTUID to leave
+ * this unchanged.
+ * @param gid The new group id. Pass NIL_RTGUID to leave this
+ * unchanged.
+ */
+RTR3DECL(int) RTPathSetOwner(const char *pszPath, uint32_t uid, uint32_t gid);
+
+/**
+ * Changes the owner and/or group of a file system object.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param uid The new file owner user id. Pass NIL_RTUID to leave
+ * this unchanged.
+ * @param gid The new group id. Pass NIL_RTGID to leave this
+ * unchanged.
+ * @param fFlags RTPATH_F_ON_LINK or RTPATH_F_FOLLOW_LINK.
+ */
+RTR3DECL(int) RTPathSetOwnerEx(const char *pszPath, uint32_t uid, uint32_t gid, uint32_t fFlags);
+
+/**
+ * Gets the owner and/or group of a file system object.
+ *
+ * @returns iprt status code.
+ * @param pszPath Path to the file system object.
+ * @param pUid Where to store the owner user id. NULL is ok.
+ * @param pGid Where to store the group id. NULL is ok.
+ *
+ * @remark This is wrapper around RTPathQueryInfo() and exists to complement
+ * RTPathGetOwner(). If the last component is a symbolic link, it will
+ * not be resolved.
+ */
+RTR3DECL(int) RTPathGetOwner(const char *pszPath, uint32_t *pUid, uint32_t *pGid);
+
+
+/** @name RTPathRename, RTDirRename & RTFileRename flags.
+ * @{ */
+/** Do not replace anything. */
+#define RTPATHRENAME_FLAGS_NO_REPLACE UINT32_C(0)
+/** This will replace attempt any target which isn't a directory. */
+#define RTPATHRENAME_FLAGS_REPLACE RT_BIT(0)
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTPATHRENAME_FLAGS_NO_SYMLINKS RT_BIT(1)
+/** @} */
+
+/**
+ * Renames a path within a filesystem.
+ *
+ * This will rename symbolic links. If RTPATHRENAME_FLAGS_REPLACE is used and
+ * pszDst is a symbolic link, it will be replaced and not its target.
+ *
+ * @returns IPRT status code.
+ * @param pszSrc The source path.
+ * @param pszDst The destination path.
+ * @param fRename Rename flags, RTPATHRENAME_FLAGS_*.
+ */
+RTR3DECL(int) RTPathRename(const char *pszSrc, const char *pszDst, unsigned fRename);
+
+/** @name RTPathUnlink flags.
+ * @{ */
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTPATHUNLINK_FLAGS_NO_SYMLINKS RT_BIT(0)
+/** @} */
+
+/**
+ * Removes the last component of the path.
+ *
+ * @returns IPRT status code.
+ * @param pszPath The path.
+ * @param fUnlink Unlink flags, RTPATHUNLINK_FLAGS_*.
+ */
+RTR3DECL(int) RTPathUnlink(const char *pszPath, uint32_t fUnlink);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/pipe.h b/include/iprt/pipe.h
new file mode 100644
index 00000000..11715c88
--- /dev/null
+++ b/include/iprt/pipe.h
@@ -0,0 +1,226 @@
+/** @file
+ * IPRT - Anonymous Pipes.
+ */
+
+/*
+ * 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 ___iprt_pipe_h
+#define ___iprt_pipe_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_pipe RTPipe - Anonymous Pipes
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Create an anonymous pipe.
+ *
+ * @returns IPRT status code.
+ * @param phPipeRead Where to return the read end of the pipe.
+ * @param phPipeWrite Where to return the write end of the pipe.
+ * @param fFlags A combination of RTPIPE_C_XXX defines.
+ */
+RTDECL(int) RTPipeCreate(PRTPIPE phPipeRead, PRTPIPE phPipeWrite, uint32_t fFlags);
+
+/** @name RTPipeCreate flags.
+ * @{ */
+/** Mark the read end as inheritable. */
+#define RTPIPE_C_INHERIT_READ RT_BIT(0)
+/** Mark the write end as inheritable. */
+#define RTPIPE_C_INHERIT_WRITE RT_BIT(1)
+/** Mask of valid flags. */
+#define RTPIPE_C_VALID_MASK UINT32_C(0x00000003)
+/** @} */
+
+/**
+ * Closes one end of a pipe created by RTPipeCreate.
+ *
+ * @returns IPRT status code.
+ * @param hPipe The pipe end to close.
+ */
+RTDECL(int) RTPipeClose(RTPIPE hPipe);
+
+/**
+ * Creates an IPRT pipe handle from a native one.
+ *
+ * Do NOT use the native handle after passing it to this function, IPRT owns it
+ * and might even have closed in some cases (in order to gain some query
+ * information access on Windows).
+ *
+ * @returns IPRT status code.
+ * @param phPipe Where to return the pipe handle.
+ * @param hNativePipe The native pipe handle.
+ * @param fFlags Pipe flags, RTPIPE_N_XXX.
+ */
+RTDECL(int) RTPipeFromNative(PRTPIPE phPipe, RTHCINTPTR hNativePipe, uint32_t fFlags);
+
+/** @name RTPipeFromNative flags.
+ * @{ */
+/** The read end. */
+#define RTPIPE_N_READ RT_BIT(0)
+/** The write end. */
+#define RTPIPE_N_WRITE RT_BIT(1)
+/** Make sure the pipe is inheritable if set and not inheritable when clear. */
+#define RTPIPE_N_INHERIT RT_BIT(2)
+/** Mask of valid flags. */
+#define RTPIPE_N_VALID_MASK UINT32_C(0x00000007)
+/** @} */
+
+/**
+ * Gets the native handle for an IPRT pipe handle.
+ *
+ * This is mainly for passing a pipe to a child and then closing the parent
+ * handle. IPRT also uses it internally to implement RTProcCreatEx and
+ * RTPollSetAdd on some platforms. Do NOT expect sane API behavior if used
+ * for any other purpose.
+ *
+ * @returns The native handle. -1 on failure.
+ * @param hPipe The IPRT pipe handle.
+ */
+RTDECL(RTHCINTPTR) RTPipeToNative(RTPIPE hPipe);
+
+/**
+ * Read bytes from a pipe, non-blocking.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_WRONG_ORDER if racing a call to RTPipeReadBlocking.
+ * @retval VERR_BROKEN_PIPE if the remote party has disconnected and we've read
+ * all the buffered data.
+ * @retval VINF_TRY_AGAIN if no data was available. @a *pcbRead will be set to
+ * 0.
+ * @retval VERR_ACCESS_DENIED if it's a write pipe.
+ *
+ * @param hPipe The IPRT pipe handle to read from.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbToRead How much to read. Must be greater than 0.
+ * @param pcbRead Where to return the number of bytes that has been
+ * read (mandatory). This is 0 if there is no more
+ * bytes to read.
+ * @sa RTPipeReadBlocking.
+ */
+RTDECL(int) RTPipeRead(RTPIPE hPipe, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Read bytes from a pipe, blocking.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_WRONG_ORDER if racing a call to RTPipeRead.
+ * @retval VERR_BROKEN_PIPE if the remote party has disconnected and we've read
+ * all the buffered data.
+ * @retval VERR_ACCESS_DENIED if it's a write pipe.
+ *
+ * @param hPipe The IPRT pipe handle to read from.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbToRead How much to read.
+ * @param pcbRead Where to return the number of bytes that has been
+ * read. Optional.
+ */
+RTDECL(int) RTPipeReadBlocking(RTPIPE hPipe, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Write bytes to a pipe, non-blocking.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_WRONG_ORDER if racing a call to RTPipeWriteBlocking.
+ * @retval VERR_BROKEN_PIPE if the remote party has disconnected. Does not
+ * trigger when @a cbToWrite is 0.
+ * @retval VINF_TRY_AGAIN if no data was written. @a *pcbWritten will be set
+ * to 0.
+ * @retval VERR_ACCESS_DENIED if it's a read pipe.
+ *
+ * @param hPipe The IPRT pipe handle to write to.
+ * @param pvBuf What to write.
+ * @param cbToWrite How much to write.
+ * @param pcbWritten How many bytes we wrote, mandatory. The return can
+ * be 0.
+ */
+RTDECL(int) RTPipeWrite(RTPIPE hPipe, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+
+/**
+ * Write bytes to a pipe, blocking.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_WRONG_ORDER if racing a call to RTPipeWrite.
+ * @retval VERR_BROKEN_PIPE if the remote party has disconnected. Does not
+ * trigger when @a cbToWrite is 0.
+ * @retval VERR_ACCESS_DENIED if it's a read pipe.
+ *
+ * @param hPipe The IPRT pipe handle to write to.
+ * @param pvBuf What to write.
+ * @param cbToWrite How much to write.
+ * @param pcbWritten How many bytes we wrote, optional. If NULL then all
+ * bytes will be written.
+ */
+RTDECL(int) RTPipeWriteBlocking(RTPIPE hPipe, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+
+/**
+ * Flushes the buffers for the specified pipe and making sure the other party
+ * reads them.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if not supported by the OS.
+ * @retval VERR_BROKEN_PIPE if the remote party has disconnected.
+ * @retval VERR_ACCESS_DENIED if it's a read pipe.
+ *
+ * @param hPipe The IPRT pipe handle to flush.
+ */
+RTDECL(int) RTPipeFlush(RTPIPE hPipe);
+
+/**
+ * Checks if the pipe is ready for reading or writing (depending on the pipe
+ * end).
+ *
+ * @returns IPRT status code.
+ * @retval VERR_TIMEOUT if the timeout was reached before the pipe was ready
+ * for reading/writing.
+ * @retval VERR_NOT_SUPPORTED if not supported by the OS?
+ *
+ * @param hPipe The IPRT pipe handle to select on.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait for ever.
+ */
+RTDECL(int) RTPipeSelectOne(RTPIPE hPipe, RTMSINTERVAL cMillies);
+
+/**
+ * Queries the number of bytes immediately available for reading.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if not supported by the OS. The caller shall
+ * handle this case.
+ *
+ * @param hPipe The IPRT read pipe handle.
+ * @param pcbReadable Where to return the number of bytes that is ready
+ * to be read.
+ */
+RTDECL(int) RTPipeQueryReadable(RTPIPE hPipe, size_t *pcbReadable);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/poll.h b/include/iprt/poll.h
new file mode 100644
index 00000000..33da9c31
--- /dev/null
+++ b/include/iprt/poll.h
@@ -0,0 +1,243 @@
+/** @file
+ * IPRT - Polling I/O Handles.
+ */
+
+/*
+ * 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 ___iprt_poll_h
+#define ___iprt_poll_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_poll RTPoll - Polling I/O Handles
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @name Poll events
+ * @{ */
+/** Readable without blocking. */
+#define RTPOLL_EVT_READ RT_BIT_32(0)
+/** Writable without blocking. */
+#define RTPOLL_EVT_WRITE RT_BIT_32(1)
+/** Error condition, hangup, exception or similar. */
+#define RTPOLL_EVT_ERROR RT_BIT_32(2)
+/** Mask of the valid bits. */
+#define RTPOLL_EVT_VALID_MASK UINT32_C(0x00000007)
+/** @} */
+
+/**
+ * Polls on the specified poll set until an event occurs on one of the handles
+ * or the timeout expires.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if an event occurred on a handle. Note that these
+ * @retval VERR_INVALID_HANDLE if @a hPollSet is invalid.
+ * @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
+ * user is responsible for ensuring single threaded access.
+ * @retval VERR_TIMEOUT if @a cMillies ellapsed without any events.
+ * @retval VERR_DEADLOCK if @a cMillies is set to RT_INDEFINITE_WAIT and there
+ * are no valid handles in the set.
+ *
+ * @param hPollSet The set to poll on.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait for ever.
+ * @param pfEvents Where to return details about the events that
+ * occurred. Optional.
+ * @param pid Where to return the ID associated with the
+ * handle when calling RTPollSetAdd. Optional.
+ *
+ * @sa RTPollNoResume
+ *
+ * @remarks The caller is responsible for ensuring
+ */
+RTDECL(int) RTPoll(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid);
+
+/**
+ * Same as RTPoll except that it will return when interrupted.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if an event occurred on a handle. Note that these
+ * @retval VERR_INVALID_HANDLE if @a hPollSet is invalid.
+ * @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
+ * user is responsible for ensuring single threaded access.
+ * @retval VERR_TIMEOUT if @a cMillies ellapsed without any events.
+ * @retval VERR_DEADLOCK if @a cMillies is set to RT_INDEFINITE_WAIT and there
+ * are no valid handles in the set.
+ * @retval VERR_INTERRUPTED if a signal or other asynchronous event interrupted
+ * the polling.
+ *
+ * @param hPollSet The set to poll on.
+ * @param cMillies Number of milliseconds to wait. Use
+ * RT_INDEFINITE_WAIT to wait for ever.
+ * @param pfEvents Where to return details about the events that
+ * occurred. Optional.
+ * @param pid Where to return the ID associated with the
+ * handle when calling RTPollSetAdd. Optional.
+ */
+RTDECL(int) RTPollNoResume(RTPOLLSET hPollSet, RTMSINTERVAL cMillies, uint32_t *pfEvents, uint32_t *pid);
+
+/**
+ * Creates a poll set with no members.
+ *
+ * @returns IPRT status code.
+ * @param phPollSet Where to return the poll set handle.
+ */
+RTDECL(int) RTPollSetCreate(PRTPOLLSET phPollSet);
+
+/**
+ * Destroys a poll set.
+ *
+ * @returns IPRT status code.
+ * @param hPollSet The poll set to destroy. NIL_POLLSET is quietly
+ * ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTPollSetDestroy(RTPOLLSET hPollSet);
+
+/**
+ * Adds a generic handle to the poll set.
+ *
+ * @returns IPRT status code
+ * @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
+ * user is responsible for ensuring single threaded access.
+ * @retval VERR_POLL_HANDLE_NOT_POLLABLE if the specified handle is not
+ * pollable.
+ * @retval VERR_POLL_HANDLE_ID_EXISTS if the handle ID is already in use in the
+ * set.
+ *
+ * @param hPollSet The poll set to modify.
+ * @param pHandle The handle to add. NIL handles are quietly
+ * ignored.
+ * @param fEvents Which events to poll for.
+ * @param id The handle ID.
+ */
+RTDECL(int) RTPollSetAdd(RTPOLLSET hPollSet, PCRTHANDLE pHandle, uint32_t fEvents, uint32_t id);
+
+/**
+ * Removes a generic handle from the poll set.
+ *
+ * @returns IPRT status code
+ * @retval VERR_INVALID_HANDLE if @a hPollSet not valid.
+ * @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
+ * user is responsible for ensuring single threaded access.
+ * @retval VERR_POLL_HANDLE_ID_NOT_FOUND if @a id doesn't resolve to a valid
+ * handle.
+ *
+ * @param hPollSet The poll set to modify.
+ * @param id The handle ID of the handle that should be
+ * removed.
+ */
+RTDECL(int) RTPollSetRemove(RTPOLLSET hPollSet, uint32_t id);
+
+
+/**
+ * Query a handle in the poll set by it's ID.
+ *
+ * @returns IPRT status code
+ * @retval VINF_SUCCESS if the handle was found. @a *pHandle is set.
+ * @retval VERR_INVALID_HANDLE if @a hPollSet is invalid.
+ * @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
+ * user is responsible for ensuring single threaded access.
+ * @retval VERR_POLL_HANDLE_ID_NOT_FOUND if there is no handle with that ID.
+ *
+ * @param hPollSet The poll set to query.
+ * @param id The ID of the handle.
+ * @param pHandle Where to return the handle details. Optional.
+ */
+RTDECL(int) RTPollSetQueryHandle(RTPOLLSET hPollSet, uint32_t id, PRTHANDLE pHandle);
+
+/**
+ * Gets the number of handles in the set.
+ *
+ * @retval The handle count.
+ * @retval UINT32_MAX if @a hPollSet is invalid or there is concurrent access.
+ *
+ * @param hPollSet The poll set.
+ */
+RTDECL(uint32_t) RTPollSetGetCount(RTPOLLSET hPollSet);
+
+/**
+ * Modifies the events to poll for for the given id.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if @a hPollSet not valid.
+ * @retval VERR_CONCURRENT_ACCESS if another thread is already accessing the set. The
+ * user is responsible for ensuring single threaded access.
+ * @retval VERR_POLL_HANDLE_ID_NOT_FOUND if @a id doesn't resolve to a valid
+ * handle.
+ *
+ * @param hPollSet The poll set to modify.
+ * @param id The handle ID to change the events for.
+ * @param fEvents Which events to poll for.
+ */
+RTDECL(int) RTPollSetEventsChange(RTPOLLSET hPollSet, uint32_t id, uint32_t fEvents);
+
+/**
+ * Adds a pipe handle to the set.
+ *
+ * @returns See RTPollSetAdd.
+ *
+ * @param hPollSet The poll set.
+ * @param hPipe The pipe handle.
+ * @param fEvents Which events to poll for.
+ * @param id The handle ID.
+ *
+ * @todo Maybe we could figure out what to poll for depending on the kind of
+ * pipe we're dealing with.
+ */
+DECLINLINE(int) RTPollSetAddPipe(RTPOLLSET hPollSet, RTPIPE hPipe, uint32_t fEvents, uint32_t id)
+{
+ RTHANDLE Handle;
+ Handle.enmType = RTHANDLETYPE_PIPE;
+ Handle.u.uInt = 0;
+ Handle.u.hPipe = hPipe;
+ return RTPollSetAdd(hPollSet, &Handle, fEvents, id);
+}
+
+/**
+ * Adds a socket handle to the set.
+ *
+ * @returns See RTPollSetAdd.
+ *
+ * @param hPollSet The poll set.
+ * @param hSocket The socket handle.
+ * @param fEvents Which events to poll for.
+ * @param id The handle ID.
+ */
+DECLINLINE(int) RTPollSetAddSocket(RTPOLLSET hPollSet, RTSOCKET hSocket, uint32_t fEvents, uint32_t id)
+{
+ RTHANDLE Handle;
+ Handle.enmType = RTHANDLETYPE_SOCKET;
+ Handle.u.uInt = 0;
+ Handle.u.hSocket = hSocket;
+ return RTPollSetAdd(hPollSet, &Handle, fEvents, id);
+}
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/power.h b/include/iprt/power.h
new file mode 100644
index 00000000..7a290734
--- /dev/null
+++ b/include/iprt/power.h
@@ -0,0 +1,112 @@
+/** @file
+ * IPRT - Power management.
+ */
+
+/*
+ * 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 ___iprt_power_h
+#define ___iprt_power_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_power RTPower - Power management
+ * @ingroup grp_rt
+ * @{
+ */
+
+#ifdef IN_RING0
+
+/**
+ * MP event, see FNRTPOWERNOTIFICATION.
+ */
+typedef enum RTPOWEREVENT
+{
+ /** The system will go into suspend mode. */
+ RTPOWEREVENT_SUSPEND = 1,
+ /** The system has resumed. */
+ RTPOWEREVENT_RESUME
+} RTPOWEREVENT;
+
+/**
+ * Notification callback.
+ *
+ * The context this is called in differs a bit from platform to
+ * platform, so be careful while in here.
+ *
+ * @param enmEvent The event.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(void) FNRTPOWERNOTIFICATION(RTPOWEREVENT enmEvent, void *pvUser);
+/** Pointer to a FNRTPOWERNOTIFICATION(). */
+typedef FNRTPOWERNOTIFICATION *PFNRTPOWERNOTIFICATION;
+
+/**
+ * Registers a notification callback for power events.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NO_MEMORY if a registration record cannot be allocated.
+ * @retval VERR_ALREADY_EXISTS if the pfnCallback and pvUser already exist
+ * in the callback list.
+ *
+ * @param pfnCallback The callback.
+ * @param pvUser The user argument to the callback function.
+ */
+RTDECL(int) RTPowerNotificationRegister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser);
+
+/**
+ * This deregisters a notification callback registered via RTPowerNotificationRegister().
+ *
+ * The pfnCallback and pvUser arguments must be identical to the registration call
+ * of we won't find the right entry.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_NOT_FOUND if no matching entry was found.
+ *
+ * @param pfnCallback The callback.
+ * @param pvUser The user argument to the callback function.
+ */
+RTDECL(int) RTPowerNotificationDeregister(PFNRTPOWERNOTIFICATION pfnCallback, void *pvUser);
+
+/**
+ * This calls all registered power management callback handlers registered via RTPowerNotificationRegister().
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ *
+ * @param enmEvent Power Management event
+ */
+RTDECL(int) RTPowerSignalEvent(RTPOWEREVENT enmEvent);
+
+#endif /* IN_RING0 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/process.h b/include/iprt/process.h
new file mode 100644
index 00000000..b359e8ad
--- /dev/null
+++ b/include/iprt/process.h
@@ -0,0 +1,398 @@
+/** @file
+ * IPRT - Process Management.
+ */
+
+/*
+ * 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 ___iprt_process_h
+#define ___iprt_process_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_process RTProc - Process Management
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Process priority.
+ *
+ * The process priority is used to select how scheduling properties
+ * are assigned to the different thread types (see THREADTYPE).
+ *
+ * In addition to using the policy assigned to the process at startup (DEFAULT)
+ * it is possible to change the process priority at runtime. This allows for
+ * a GUI, resource manager or admin to adjust the general priority of a task
+ * without upsetting the fine-tuned priority of the threads within.
+ */
+typedef enum RTPROCPRIORITY
+{
+ /** Invalid priority. */
+ RTPROCPRIORITY_INVALID = 0,
+ /** Default priority.
+ * Derive the scheduling policy from the priority of the RTR3Init()
+ * and RTProcSetPriority() callers and the rights the process have
+ * to alter its own priority.
+ */
+ RTPROCPRIORITY_DEFAULT,
+ /** Flat priority.
+ * Assumes a scheduling policy which puts the process at the default priority
+ * and with all thread at the same priority.
+ */
+ RTPROCPRIORITY_FLAT,
+ /** Low priority.
+ * Assumes a scheduling policy which puts the process mostly below the
+ * default priority of the host OS.
+ */
+ RTPROCPRIORITY_LOW,
+ /** Normal priority.
+ * Assume a scheduling policy which shares the CPU resources fairly with
+ * other processes running with the default priority of the host OS.
+ */
+ RTPROCPRIORITY_NORMAL,
+ /** High priority.
+ * Assumes a scheduling policy which puts the task above the default
+ * priority of the host OS. This policy might easily cause other tasks
+ * in the system to starve.
+ */
+ RTPROCPRIORITY_HIGH,
+ /** Last priority, used for validation. */
+ RTPROCPRIORITY_LAST
+} RTPROCPRIORITY;
+
+
+/**
+ * Get the current process identifier.
+ *
+ * @returns Process identifier.
+ */
+RTDECL(RTPROCESS) RTProcSelf(void);
+
+
+#ifdef IN_RING0
+/**
+ * Get the current process handle.
+ *
+ * @returns Ring-0 process handle.
+ */
+RTR0DECL(RTR0PROCESS) RTR0ProcHandleSelf(void);
+#endif
+
+
+#ifdef IN_RING3
+
+/**
+ * Attempts to alter the priority of the current process.
+ *
+ * @returns iprt status code.
+ * @param enmPriority The new priority.
+ */
+RTR3DECL(int) RTProcSetPriority(RTPROCPRIORITY enmPriority);
+
+/**
+ * Gets the current priority of this process.
+ *
+ * @returns The priority (see RTPROCPRIORITY).
+ */
+RTR3DECL(RTPROCPRIORITY) RTProcGetPriority(void);
+
+/**
+ * Create a child process.
+ *
+ * @returns iprt status code.
+ * @param pszExec Executable image to use to create the child process.
+ * @param papszArgs Pointer to an array of arguments to the child. The array terminated by an entry containing NULL.
+ * @param Env Handle to the environment block for the child.
+ * @param fFlags Flags, one of the RTPROC_FLAGS_* defines.
+ * @param pProcess Where to store the process identifier on successful return.
+ * The content is not changed on failure. NULL is allowed.
+ */
+RTR3DECL(int) RTProcCreate(const char *pszExec, const char * const *papszArgs, RTENV Env, unsigned fFlags, PRTPROCESS pProcess);
+
+
+/**
+ * Create a child process.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszExec Executable image to use to create the child process.
+ * @param papszArgs Pointer to an array of arguments to the child. The
+ * array terminated by an entry containing NULL.
+ * @param hEnv Handle to the environment block for the child. Pass
+ * RTENV_DEFAULT to use the environment of the current
+ * process.
+ * @param fFlags Flags, one of the RTPROC_FLAGS_* defines.
+ * @param phStdIn The standard in handle to assign the new process. Pass
+ * NULL to use the same as the current process. If the
+ * handle is NIL, we'll close the standard input of the
+ * guest.
+ * @param phStdOut The standard out handle to assign the new process. Pass
+ * NULL to use the same as the current process. If the
+ * handle is NIL, we'll close the standard output of the
+ * guest.
+ * @param phStdErr The standard error handle to assign the new process. Pass
+ * NULL to use the same as the current process. If the
+ * handle is NIL, we'll close the standard error of the
+ * guest.
+ * @param pszAsUser User to run the process as. Pass NULL to use the same
+ * user as the current process.
+ * Windows: Use user@domain format to specify a domain.
+ * @param pszPassword Password to use to authenticate @a pszAsUser. Must be
+ * NULL wif pszAsUser is NULL. Whether this is actually
+ * used or not depends on the platform.
+ * @param phProcess Where to store the process handle on successful return.
+ * The content is not changed on failure. NULL is allowed.
+ *
+ * @remarks The handles does not have to be created as inheritable, but it
+ * doesn't hurt if they are as it may avoid race conditions on some
+ * platforms.
+ *
+ * @remarks The as-user feature isn't supported/implemented on all platforms and
+ * will cause a-yet-to-be-determined-error-status on these.
+ */
+RTR3DECL(int) RTProcCreateEx(const char *pszExec, const char * const *papszArgs, RTENV hEnv, uint32_t fFlags,
+ PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr, const char *pszAsUser,
+ const char *pszPassword, PRTPROCESS phProcess);
+
+/** @name RTProcCreate and RTProcCreateEx flags
+ * @{ */
+/** Detach the child process from the parents process tree and process group,
+ * session or/and console (depends on the platform what's done applicable).
+ *
+ * The new process will not be a direct decendent of the parent and it will not
+ * be possible to wait for it, i.e. @a phProcess shall be NULL. */
+#define RTPROC_FLAGS_DETACHED RT_BIT(0)
+/** Don't show the started process.
+ * This is a window (and maybe OS/2) concept, do not use on other platforms. */
+#define RTPROC_FLAGS_HIDDEN RT_BIT(1)
+/** Use special code path for starting child processes from a service (daemon).
+ * This is a windows concept for dealing with the so called "Session 0"
+ * isolation which was introduced with Windows Vista. Do not use on other
+ * platforms. */
+#define RTPROC_FLAGS_SERVICE RT_BIT(2)
+/** Suppress changing the process contract id for the child process
+ * on Solaris. Without this flag the contract id is always changed, as that's
+ * the more frequently used case. */
+#define RTPROC_FLAGS_SAME_CONTRACT RT_BIT(3)
+/** Do not load user profile data when executing a process.
+ * This bit at the moment only is valid on Windows. */
+#define RTPROC_FLAGS_NO_PROFILE RT_BIT(4)
+/** Create process without a console window.
+ * This is a Windows (and OS/2) concept, do not use on other platforms. */
+#define RTPROC_FLAGS_NO_WINDOW RT_BIT(5)
+/** Search the PATH for the executable. */
+#define RTPROC_FLAGS_SEARCH_PATH RT_BIT(6)
+
+/** @} */
+
+
+/**
+ * Process exit reason.
+ */
+typedef enum RTPROCEXITREASON
+{
+ /** Normal exit. iStatus contains the exit code. */
+ RTPROCEXITREASON_NORMAL = 1,
+ /** Any abnormal exit. iStatus is undefined. */
+ RTPROCEXITREASON_ABEND,
+ /** Killed by a signal. The iStatus field contains the signal number. */
+ RTPROCEXITREASON_SIGNAL
+} RTPROCEXITREASON;
+
+/**
+ * Process exit status.
+ */
+typedef struct RTPROCSTATUS
+{
+ /** The process exit status if the exit was a normal one. */
+ int iStatus;
+ /** The reason the process terminated. */
+ RTPROCEXITREASON enmReason;
+} RTPROCSTATUS;
+/** Pointer to a process exit status structure. */
+typedef RTPROCSTATUS *PRTPROCSTATUS;
+/** Pointer to a const process exit status structure. */
+typedef const RTPROCSTATUS *PCRTPROCSTATUS;
+
+
+/** Flags for RTProcWait().
+ * @{ */
+/** Block indefinitly waiting for the process to exit. */
+#define RTPROCWAIT_FLAGS_BLOCK 0
+/** Don't block, just check if the process have exited. */
+#define RTPROCWAIT_FLAGS_NOBLOCK 1
+/** @} */
+
+/**
+ * Waits for a process, resumes on interruption.
+ *
+ * @returns VINF_SUCCESS when the status code for the process was collected and
+ * put in *pProcStatus.
+ * @returns VERR_PROCESS_NOT_FOUND if the specified process wasn't found.
+ * @returns VERR_PROCESS_RUNNING when the RTPROCWAIT_FLAGS_NOBLOCK and the
+ * process haven't exited yet.
+ *
+ * @param Process The process to wait for.
+ * @param fFlags The wait flags, any of the RTPROCWAIT_FLAGS_ \#defines.
+ * @param pProcStatus Where to store the exit status on success.
+ * Optional.
+ */
+RTR3DECL(int) RTProcWait(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus);
+
+/**
+ * Waits for a process, returns on interruption.
+ *
+ * @returns VINF_SUCCESS when the status code for the process was collected and
+ * put in *pProcStatus.
+ * @returns VERR_PROCESS_NOT_FOUND if the specified process wasn't found.
+ * @returns VERR_PROCESS_RUNNING when the RTPROCWAIT_FLAGS_NOBLOCK and the
+ * process haven't exited yet.
+ * @returns VERR_INTERRUPTED when the wait was interrupted by the arrival of a
+ * signal or other async event.
+ *
+ * @param Process The process to wait for.
+ * @param fFlags The wait flags, any of the RTPROCWAIT_FLAGS_ \#defines.
+ * @param pProcStatus Where to store the exit status on success.
+ * Optional.
+ */
+RTR3DECL(int) RTProcWaitNoResume(RTPROCESS Process, unsigned fFlags, PRTPROCSTATUS pProcStatus);
+
+/**
+ * Terminates (kills) a running process.
+ *
+ * @returns IPRT status code.
+ * @param Process The process to terminate.
+ */
+RTR3DECL(int) RTProcTerminate(RTPROCESS Process);
+
+/**
+ * Gets the processor affinity mask of the current process.
+ *
+ * @returns The affinity mask.
+ */
+RTR3DECL(uint64_t) RTProcGetAffinityMask(void);
+
+/**
+ * Gets the short process name.
+ *
+ * @returns Pointer to read-only name string.
+ */
+RTR3DECL(const char *) RTProcShortName(void);
+
+/**
+ * Gets the path to the executable image of the current process.
+ *
+ * @returns pszExecPath on success. NULL on buffer overflow or other errors.
+ *
+ * @param pszExecPath Where to store the path.
+ * @param cbExecPath The size of the buffer.
+ */
+RTR3DECL(char *) RTProcGetExecutablePath(char *pszExecPath, size_t cbExecPath);
+
+/**
+ * Daemonize the current process, making it a background process.
+ *
+ * The way this work is that it will spawn a detached / backgrounded /
+ * daemonized / call-it-what-you-want process that isn't a direct child of the
+ * current process. The spawned will have the same arguments a the caller,
+ * except that the @a pszDaemonizedOpt is appended to prevent that the new
+ * process calls this API again.
+ *
+ * The new process will have the standard handles directed to/from the
+ * bitbucket.
+ *
+ * @returns IPRT status code. On success it is normal for the caller to exit
+ * the process by returning from main().
+ *
+ * @param papszArgs The argument vector of the calling process.
+ * @param pszDaemonized The daemonized option. This is appended to the end
+ * of the parameter list of the daemonized process.
+ */
+RTR3DECL(int) RTProcDaemonize(const char * const *papszArgs, const char *pszDaemonizedOpt);
+
+/**
+ * Daemonize the current process, making it a background process. The current
+ * process will exit if daemonizing is successful.
+ *
+ * @returns IPRT status code. On success it will only return in the child
+ * process, the parent will exit. On failure, it will return in the
+ * parent process and no child has been spawned.
+ *
+ * @param fNoChDir Pass false to change working directory to "/".
+ * @param fNoClose Pass false to redirect standard file streams to the null device.
+ * @param pszPidfile Path to a file to write the process id of the daemon
+ * process to. Daemonizing will fail if this file already
+ * exists or cannot be written. May be NULL.
+ */
+RTR3DECL(int) RTProcDaemonizeUsingFork(bool fNoChDir, bool fNoClose, const char *pszPidfile);
+
+/**
+ * Check if the given process is running on the system.
+ *
+ * This check is case sensitive on most systems, except for Windows, OS/2 and
+ * Darwin.
+ *
+ * @returns true if the process is running & false otherwise.
+ * @param pszName Process name to search for. If no path is given only the
+ * filename part of the running process set will be
+ * matched. If a path is specified, the full path will be
+ * matched.
+ */
+RTR3DECL(bool) RTProcIsRunningByName(const char *pszName);
+
+/**
+ * Query the username of the given process.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_BUFFER_OVERFLOW if the given buffer size is to small for the username.
+ * @param hProcess The process handle to query the username for.
+ * @param pszUser Where to store the user name on success.
+ * @param cbUser The size of the user name buffer.
+ * @param pcbUser Where to store the username length on success
+ * or the required buffer size if VERR_BUFFER_OVERFLOW
+ * is returned.
+ */
+RTR3DECL(int) RTProcQueryUsername(RTPROCESS hProcess, char *pszUser, size_t cbUser,
+ size_t *pcbUser);
+
+/**
+ * Query the username of the given process allocating the string for the username.
+ *
+ * @returns IPRT status code.
+ * @param hProcess The process handle to query the username for.
+ * @param ppszUser Where to store the pointer to the string containing
+ * the username on success. Free with RTStrFree().
+ */
+RTR3DECL(int) RTProcQueryUsernameA(RTPROCESS hProcess, char **ppszUser);
+
+#endif /* IN_RING3 */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/rand.h b/include/iprt/rand.h
new file mode 100644
index 00000000..f9fa5b80
--- /dev/null
+++ b/include/iprt/rand.h
@@ -0,0 +1,317 @@
+/** @file
+ * IPRT - Random Numbers and Byte Streams.
+ */
+
+/*
+ * 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 ___iprt_rand_h
+#define ___iprt_rand_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_rand RTRand - Random Numbers and Byte Streams
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Fills a buffer with random bytes.
+ *
+ * @param pv Where to store the random bytes.
+ * @param cb Number of bytes to generate.
+ */
+RTDECL(void) RTRandBytes(void *pv, size_t cb) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit signed random number in the set [i32First..i32Last].
+ *
+ * @returns The random number.
+ * @param i32First First number in the set.
+ * @param i32Last Last number in the set.
+ */
+RTDECL(int32_t) RTRandS32Ex(int32_t i32First, int32_t i32Last) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit signed random number.
+ *
+ * @returns The random number.
+ */
+RTDECL(int32_t) RTRandS32(void) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit unsigned random number in the set [u32First..u32Last].
+ *
+ * @returns The random number.
+ * @param u32First First number in the set.
+ * @param u32Last Last number in the set.
+ */
+RTDECL(uint32_t) RTRandU32Ex(uint32_t u32First, uint32_t u32Last) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit unsigned random number.
+ *
+ * @returns The random number.
+ */
+RTDECL(uint32_t) RTRandU32(void) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit signed random number in the set [i64First..i64Last].
+ *
+ * @returns The random number.
+ * @param i64First First number in the set.
+ * @param i64Last Last number in the set.
+ */
+RTDECL(int64_t) RTRandS64Ex(int64_t i64First, int64_t i64Last) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit signed random number.
+ *
+ * @returns The random number.
+ */
+RTDECL(int64_t) RTRandS64(void) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit unsigned random number in the set [u64First..u64Last].
+ *
+ * @returns The random number.
+ * @param u64First First number in the set.
+ * @param u64Last Last number in the set.
+ */
+RTDECL(uint64_t) RTRandU64Ex(uint64_t u64First, uint64_t u64Last) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit unsigned random number.
+ *
+ * @returns The random number.
+ */
+RTDECL(uint64_t) RTRandU64(void) RT_NO_THROW;
+
+
+/**
+ * Create an instance of the default random number generator.
+ *
+ * @returns IPRT status code.
+ * @param phRand Where to return the handle to the new random number
+ * generator.
+ */
+RTDECL(int) RTRandAdvCreate(PRTRAND phRand) RT_NO_THROW;
+
+/**
+ * Create an instance of the default pseudo random number generator.
+ *
+ * @returns IPRT status code.
+ * @param phRand Where to store the handle to the generator.
+ */
+RTDECL(int) RTRandAdvCreatePseudo(PRTRAND phRand) RT_NO_THROW;
+
+/**
+ * Create an instance of the Park-Miller pseudo random number generator.
+ *
+ * @returns IPRT status code.
+ * @param phRand Where to store the handle to the generator.
+ */
+RTDECL(int) RTRandAdvCreateParkMiller(PRTRAND phRand) RT_NO_THROW;
+
+/**
+ * Create an instance of the faster random number generator for the OS.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED on platforms which doesn't have this feature.
+ * @retval VERR_FILE_NOT_FOUND on system where the random generator hasn't
+ * been installed or configured correctly.
+ * @retval VERR_PATH_NOT_FOUND for the same reasons as VERR_FILE_NOT_FOUND.
+ *
+ * @param phRand Where to store the handle to the generator.
+ *
+ * @remarks Think /dev/urandom.
+ */
+RTDECL(int) RTRandAdvCreateSystemFaster(PRTRAND phRand) RT_NO_THROW;
+
+/**
+ * Create an instance of the truer random number generator for the OS.
+ *
+ * Don't use this unless you seriously need good random numbers because most
+ * systems will have will have problems producing sufficient entropy for this
+ * and you'll end up blocking while it accumulates.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED on platforms which doesn't have this feature.
+ * @retval VERR_FILE_NOT_FOUND on system where the random generator hasn't
+ * been installed or configured correctly.
+ * @retval VERR_PATH_NOT_FOUND for the same reasons as VERR_FILE_NOT_FOUND.
+ *
+ * @param phRand Where to store the handle to the generator.
+ *
+ * @remarks Think /dev/random.
+ */
+RTDECL(int) RTRandAdvCreateSystemTruer(PRTRAND phRand) RT_NO_THROW;
+
+/**
+ * Destroys a random number generator.
+ *
+ * @returns IPRT status code.
+ * @param hRand Handle to the random number generator.
+ */
+RTDECL(int) RTRandAdvDestroy(RTRAND hRand) RT_NO_THROW;
+
+/**
+ * Generic method for seeding of a random number generator.
+ *
+ * The different generators may have specialized methods for
+ * seeding, use one of those if you desire better control
+ * over the result.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if it isn't a pseudo generator.
+ *
+ * @param hRand Handle to the random number generator.
+ * @param u64Seed Seed.
+ */
+RTDECL(int) RTRandAdvSeed(RTRAND hRand, uint64_t u64Seed) RT_NO_THROW;
+
+/**
+ * Save the current state of a pseudo generator.
+ *
+ * This can be use to save the state so it can later be resumed at the same
+ * position.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success. *pcbState contains the length of the
+ * returned string and pszState contains the state string.
+ * @retval VERR_BUFFER_OVERFLOW if the supplied buffer is too small. *pcbState
+ * will contain the necessary buffer size.
+ * @retval VERR_NOT_SUPPORTED by non-psuedo generators.
+ *
+ * @param hRand Handle to the random number generator.
+ * @param pszState Where to store the state. The returned string will be
+ * null terminated and printable.
+ * @param pcbState The size of the buffer pszState points to on input, the
+ * size required / used on return (including the
+ * terminator, thus the 'cb' instead of 'cch').
+ */
+RTDECL(int) RTRandAdvSaveState(RTRAND hRand, char *pszState, size_t *pcbState) RT_NO_THROW;
+
+/**
+ * Restores the state of a pseudo generator.
+ *
+ * The state must have been obtained using RTRandAdvGetState.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_PARSE_ERROR if the state string is malformed.
+ * @retval VERR_NOT_SUPPORTED by non-psuedo generators.
+ *
+ * @param hRand Handle to the random number generator.
+ * @param pszState The state to load.
+ */
+RTDECL(int) RTRandAdvRestoreState(RTRAND hRand, char const *pszState) RT_NO_THROW;
+
+/**
+ * Fills a buffer with random bytes.
+ *
+ * @param hRand Handle to the random number generator.
+ * @param pv Where to store the random bytes.
+ * @param cb Number of bytes to generate.
+ */
+RTDECL(void) RTRandAdvBytes(RTRAND hRand, void *pv, size_t cb) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit signed random number in the set [i32First..i32Last].
+ *
+ * @returns The random number.
+ * @param hRand Handle to the random number generator.
+ * @param i32First First number in the set.
+ * @param i32Last Last number in the set.
+ */
+RTDECL(int32_t) RTRandAdvS32Ex(RTRAND hRand, int32_t i32First, int32_t i32Last) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit signed random number.
+ *
+ * @returns The random number.
+ * @param hRand Handle to the random number generator.
+ */
+RTDECL(int32_t) RTRandAdvS32(RTRAND hRand) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit unsigned random number in the set [u32First..u32Last].
+ *
+ * @returns The random number.
+ * @param hRand Handle to the random number generator.
+ * @param u32First First number in the set.
+ * @param u32Last Last number in the set.
+ */
+RTDECL(uint32_t) RTRandAdvU32Ex(RTRAND hRand, uint32_t u32First, uint32_t u32Last) RT_NO_THROW;
+
+/**
+ * Generate a 32-bit unsigned random number.
+ *
+ * @returns The random number.
+ * @param hRand Handle to the random number generator.
+ */
+RTDECL(uint32_t) RTRandAdvU32(RTRAND hRand) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit signed random number in the set [i64First..i64Last].
+ *
+ * @returns The random number.
+ * @param hRand Handle to the random number generator.
+ * @param i64First First number in the set.
+ * @param i64Last Last number in the set.
+ */
+RTDECL(int64_t) RTRandAdvS64Ex(RTRAND hRand, int64_t i64First, int64_t i64Last) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit signed random number.
+ *
+ * @returns The random number.
+ */
+RTDECL(int64_t) RTRandAdvS64(RTRAND hRand) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit unsigned random number in the set [u64First..u64Last].
+ *
+ * @returns The random number.
+ * @param hRand Handle to the random number generator.
+ * @param u64First First number in the set.
+ * @param u64Last Last number in the set.
+ */
+RTDECL(uint64_t) RTRandAdvU64Ex(RTRAND hRand, uint64_t u64First, uint64_t u64Last) RT_NO_THROW;
+
+/**
+ * Generate a 64-bit unsigned random number.
+ *
+ * @returns The random number.
+ * @param hRand Handle to the random number generator.
+ */
+RTDECL(uint64_t) RTRandAdvU64(RTRAND hRand) RT_NO_THROW;
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+
+#endif
+
diff --git a/include/iprt/req.h b/include/iprt/req.h
new file mode 100644
index 00000000..ea5abb63
--- /dev/null
+++ b/include/iprt/req.h
@@ -0,0 +1,598 @@
+/** @file
+ * IPRT - Request Queue & Pool.
+ */
+
+/*
+ * 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 ___iprt_req_h
+#define ___iprt_req_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_req RTReq - Request Queue & Pool.
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Request queue handle. */
+typedef struct RTREQQUEUEINT *RTREQQUEUE;
+/** Pointer to a request queue handle. */
+typedef RTREQQUEUE *PRTREQQUEUE;
+/** NIL request queue handle. */
+#define NIL_RTREQQUEUE ((RTREQQUEUE)0)
+
+/** Request thread pool handle. */
+typedef struct RTREQPOOLINT *RTREQPOOL;
+/** Poiner to a request thread pool handle. */
+typedef RTREQPOOL *PRTREQPOOL;
+/** NIL request pool handle. */
+#define NIL_RTREQPOOL ((RTREQPOOL)0)
+
+
+/**
+ * Request type.
+ */
+typedef enum RTREQTYPE
+{
+ /** Invalid request. */
+ RTREQTYPE_INVALID = 0,
+ /** RT: Internal. */
+ RTREQTYPE_INTERNAL,
+ /** Maximum request type (exclusive). Used for validation. */
+ RTREQTYPE_MAX
+} RTREQTYPE;
+
+/**
+ * Request flags.
+ */
+typedef enum RTREQFLAGS
+{
+ /** The request returns a iprt status code. */
+ RTREQFLAGS_IPRT_STATUS = 0,
+ /** The request is a void request and have no status code. */
+ RTREQFLAGS_VOID = 1,
+ /** Return type mask. */
+ RTREQFLAGS_RETURN_MASK = 1,
+ /** Caller does not wait on the packet, Queue process thread will free it. */
+ RTREQFLAGS_NO_WAIT = 2
+} RTREQFLAGS;
+
+
+/** A request packet. */
+typedef struct RTREQ RTREQ;
+/** Pointer to an RT request packet. */
+typedef RTREQ *PRTREQ;
+/** Nil request handle. */
+#define NIL_RTREQ ((PRTREQ)0)
+
+
+#ifdef IN_RING3
+
+/**
+ * Create a request packet queue
+ *
+ * @returns iprt status code.
+ * @param phQueue Where to store the request queue handle.
+ */
+RTDECL(int) RTReqQueueCreate(PRTREQQUEUE phQueue);
+
+/**
+ * Destroy a request packet queue
+ *
+ * @returns iprt status code.
+ * @param hQueue The request queue.
+ */
+RTDECL(int) RTReqQueueDestroy(RTREQQUEUE hQueue);
+
+/**
+ * Process one or more request packets
+ *
+ * @returns iprt status code.
+ * @returns VERR_TIMEOUT if cMillies was reached without the packet being added.
+ *
+ * @param hQueue The request queue.
+ * @param cMillies Number of milliseconds to wait for a pending request.
+ * Use RT_INDEFINITE_WAIT to only wait till one is added.
+ */
+RTDECL(int) RTReqQueueProcess(RTREQQUEUE hQueue, RTMSINTERVAL cMillies);
+
+/**
+ * Allocate and queue a call request.
+ *
+ * If it's desired to poll on the completion of the request set cMillies
+ * to 0 and use RTReqWait() to check for completion. In the other case
+ * use RT_INDEFINITE_WAIT.
+ * The returned request packet must be freed using RTReqRelease().
+ *
+ * @returns iprt statuscode.
+ * Will not return VERR_INTERRUPTED.
+ * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
+ *
+ * @param hQueue The request queue.
+ * @param ppReq Where to store the pointer to the request.
+ * This will be NULL or a valid request pointer not matter what happens.
+ * @param cMillies Number of milliseconds to wait for the request to
+ * be completed. Use RT_INDEFINITE_WAIT to only
+ * wait till it's completed.
+ * @param pfnFunction Pointer to the function to call.
+ * @param cArgs Number of arguments following in the ellipsis.
+ * @param ... Function arguments.
+ *
+ * @remarks See remarks on RTReqQueueCallV.
+ */
+RTDECL(int) RTReqQueueCall(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
+
+/**
+ * Allocate and queue a call request to a void function.
+ *
+ * If it's desired to poll on the completion of the request set cMillies
+ * to 0 and use RTReqWait() to check for completion. In the other case
+ * use RT_INDEFINITE_WAIT.
+ * The returned request packet must be freed using RTReqRelease().
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
+ *
+ * @param hQueue The request queue.
+ * @param ppReq Where to store the pointer to the request.
+ * This will be NULL or a valid request pointer not matter what happens.
+ * @param cMillies Number of milliseconds to wait for the request to
+ * be completed. Use RT_INDEFINITE_WAIT to only
+ * wait till it's completed.
+ * @param pfnFunction Pointer to the function to call.
+ * @param cArgs Number of arguments following in the ellipsis.
+ * @param ... Function arguments.
+ *
+ * @remarks See remarks on RTReqQueueCallV.
+ */
+RTDECL(int) RTReqQueueCallVoid(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, PFNRT pfnFunction, unsigned cArgs, ...);
+
+/**
+ * Allocate and queue a call request to a void function.
+ *
+ * If it's desired to poll on the completion of the request set cMillies
+ * to 0 and use RTReqWait() to check for completion. In the other case
+ * use RT_INDEFINITE_WAIT.
+ * The returned request packet must be freed using RTReqRelease().
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
+ *
+ * @param hQueue The request queue.
+ * @param ppReq Where to store the pointer to the request.
+ * This will be NULL or a valid request pointer not matter what happens, unless fFlags
+ * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
+ * @param cMillies Number of milliseconds to wait for the request to
+ * be completed. Use RT_INDEFINITE_WAIT to only
+ * wait till it's completed.
+ * @param fFlags A combination of the RTREQFLAGS values.
+ * @param pfnFunction Pointer to the function to call.
+ * @param cArgs Number of arguments following in the ellipsis.
+ * @param ... Function arguments.
+ *
+ * @remarks See remarks on RTReqQueueCallV.
+ */
+RTDECL(int) RTReqQueueCallEx(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
+
+/**
+ * Allocate and queue a call request.
+ *
+ * If it's desired to poll on the completion of the request set cMillies
+ * to 0 and use RTReqWait() to check for completion. In the other case
+ * use RT_INDEFINITE_WAIT.
+ * The returned request packet must be freed using RTReqRelease().
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
+ *
+ * @param hQueue The request queue.
+ * @param ppReq Where to store the pointer to the request.
+ * This will be NULL or a valid request pointer not matter what happens, unless fFlags
+ * contains RTREQFLAGS_NO_WAIT when it will be optional and always NULL.
+ * @param cMillies Number of milliseconds to wait for the request to
+ * be completed. Use RT_INDEFINITE_WAIT to only
+ * wait till it's completed.
+ * @param fFlags A combination of the RTREQFLAGS values.
+ * @param pfnFunction Pointer to the function to call.
+ * @param cArgs Number of arguments following in the ellipsis.
+ * @param Args Variable argument vector.
+ *
+ * @remarks Caveats:
+ * - Do not pass anything which is larger than an uintptr_t.
+ * - 64-bit integers are larger than uintptr_t on 32-bit hosts.
+ * Pass integers > 32-bit by reference (pointers).
+ * - Don't use NULL since it should be the integer 0 in C++ and may
+ * therefore end up with garbage in the bits 63:32 on 64-bit
+ * hosts because 'int' is 32-bit.
+ * Use (void *)NULL or (uintptr_t)0 instead of NULL.
+ */
+RTDECL(int) RTReqQueueCallV(RTREQQUEUE hQueue, PRTREQ *ppReq, RTMSINTERVAL cMillies, unsigned fFlags, PFNRT pfnFunction, unsigned cArgs, va_list Args);
+
+/**
+ * Checks if the queue is busy or not.
+ *
+ * The caller is responsible for dealing with any concurrent submitts.
+ *
+ * @returns true if busy, false if idle.
+ * @param hQueue The queue.
+ */
+RTDECL(bool) RTReqQueueIsBusy(RTREQQUEUE hQueue);
+
+/**
+ * Allocates a request packet.
+ *
+ * The caller allocates a request packet, fills in the request data
+ * union and queues the request.
+ *
+ * @returns iprt status code.
+ *
+ * @param hQueue The request queue.
+ * @param enmType Package type.
+ * @param phReq Where to store the handle to the new request.
+ */
+RTDECL(int) RTReqQueueAlloc(RTREQQUEUE hQueue, RTREQTYPE enmType, PRTREQ *phReq);
+
+
+/**
+ * Creates a request thread pool.
+ *
+ * The core configuration is given as parameters, finer pool tuning can be
+ * achieved via RTReqPoolSetCfgVar.
+ *
+ * @returns IPRT status code.
+ * @param cMaxThreads The maximum number of worker threads.
+ * UINT32_MAX is an alias for the highest
+ * allowed thread count.
+ * @param cMsMinIdle The number of milliseconds a worker
+ * thread needs to be idle before it is
+ * considered for shutdown. The value
+ * RT_INDEFINITE_WAIT disables automatic
+ * idle thread shutdown.
+ * @param cThreadsPushBackThreshold At which worker thread count the push
+ * back should kick in.
+ * @param cMsMaxPushBack The max number of milliseconds to push
+ * back a submitter. UINT32_MAX is an
+ * alias for the highest allowed push back.
+ * @param pszName The pool name. Keep it short as it is
+ * used for naming worker threads.
+ * @param phPool Where to return the pool handle.
+ */
+RTDECL(int) RTReqPoolCreate(uint32_t cMaxThreads, RTMSINTERVAL cMsMinIdle,
+ uint32_t cThreadsPushBackThreshold, uint32_t cMsMaxPushBack,
+ const char *pszName, PRTREQPOOL phPool);
+
+/**
+ * Retainsa reference to a request thread pool.
+ *
+ * @returns The new reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hPool The request thread pool handle.
+ */
+RTDECL(uint32_t) RTReqPoolRetain(RTREQPOOL hPool);
+
+/**
+ * Releases a reference to the request thread pool.
+ *
+ * When the reference count reaches zero, the request will be pooled for reuse.
+ *
+ * @returns The new reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hPool The request thread pool handle.
+ */
+RTDECL(uint32_t) RTReqPoolRelease(RTREQPOOL hPool);
+
+/**
+ * Request thread pool configuration variable.
+ */
+typedef enum RTREQPOOLCFGVAR
+{
+ /** Invalid zero value. */
+ RTREQPOOLCFGVAR_INVALID = 0,
+ /** The desired RTTHREADTYPE of the worker threads. */
+ RTREQPOOLCFGVAR_THREAD_TYPE,
+ /** The minimum number of threads to keep handy once spawned. */
+ RTREQPOOLCFGVAR_MIN_THREADS,
+ /** The maximum number of thread to start. */
+ RTREQPOOLCFGVAR_MAX_THREADS,
+ /** The minimum number of milliseconds a worker thread needs to be idle
+ * before we consider shutting it down. The other shutdown criteria
+ * being set by RTREQPOOLCFGVAR_MIN_THREADS. The value
+ * RT_INDEFINITE_WAIT can be used to disable shutting down idle threads. */
+ RTREQPOOLCFGVAR_MS_MIN_IDLE,
+ /** The sleep period, in milliseoncds, to employ when idling. The value
+ * RT_INDEFINITE_WAIT can be used to disable shutting down idle threads. */
+ RTREQPOOLCFGVAR_MS_IDLE_SLEEP,
+ /** The number of threads at which to start pushing back. The value
+ * UINT64_MAX is an alias for the current upper thread count limit, i.e.
+ * disabling push back. The value 0 (zero) is an alias for the current
+ * lower thread count, a good value to start pushing back at. The value
+ * must otherwise be within */
+ RTREQPOOLCFGVAR_PUSH_BACK_THRESHOLD,
+ /** The minimum push back time in milliseconds. */
+ RTREQPOOLCFGVAR_PUSH_BACK_MIN_MS,
+ /** The maximum push back time in milliseconds. */
+ RTREQPOOLCFGVAR_PUSH_BACK_MAX_MS,
+ /** The maximum number of free requests to keep handy for recycling. */
+ RTREQPOOLCFGVAR_MAX_FREE_REQUESTS,
+ /** The end of the range of valid config variables. */
+ RTREQPOOLCFGVAR_END,
+ /** Blow the type up to 32-bits. */
+ RTREQPOOLCFGVAR_32BIT_HACK = 0x7fffffff
+} RTREQPOOLCFGVAR;
+
+
+/**
+ * Sets a config variable for a request thread pool.
+ *
+ * @returns IPRT status code.
+ * @param hPool The pool handle.
+ * @param enmVar The variable to set.
+ * @param uValue The new value.
+ */
+RTDECL(int) RTReqPoolSetCfgVar(RTREQPOOL hPool, RTREQPOOLCFGVAR enmVar, uint64_t uValue);
+
+/**
+ * Gets a config variable for a request thread pool.
+ *
+ * @returns The value, UINT64_MAX on invalid parameters.
+ * @param hPool The pool handle.
+ * @param enmVar The variable to query.
+ */
+RTDECL(uint64_t) RTReqPoolGetCfgVar(RTREQPOOL hPool, RTREQPOOLCFGVAR enmVar);
+
+/**
+ * Request thread pool statistics value names.
+ */
+typedef enum RTREQPOOLSTAT
+{
+ /** The invalid zero value, as per tradition. */
+ RTREQPOOLSTAT_INVALID = 0,
+ /** The current number of worker threads. */
+ RTREQPOOLSTAT_THREADS,
+ /** The number of threads that have been created. */
+ RTREQPOOLSTAT_THREADS_CREATED,
+ /** The total number of requests that have been processed. */
+ RTREQPOOLSTAT_REQUESTS_PROCESSED,
+ /** The total number of requests that have been submitted. */
+ RTREQPOOLSTAT_REQUESTS_SUBMITTED,
+ /** the current number of pending (waiting) requests. */
+ RTREQPOOLSTAT_REQUESTS_PENDING,
+ /** The current number of active (executing) requests. */
+ RTREQPOOLSTAT_REQUESTS_ACTIVE,
+ /** The current number of free (recycled) requests. */
+ RTREQPOOLSTAT_REQUESTS_FREE,
+ /** Total time the requests took to process. */
+ RTREQPOOLSTAT_NS_TOTAL_REQ_PROCESSING,
+ /** Total time the requests had to wait in the queue before being
+ * scheduled. */
+ RTREQPOOLSTAT_NS_TOTAL_REQ_QUEUED,
+ /** Average time the requests took to process. */
+ RTREQPOOLSTAT_NS_AVERAGE_REQ_PROCESSING,
+ /** Average time the requests had to wait in the queue before being
+ * scheduled. */
+ RTREQPOOLSTAT_NS_AVERAGE_REQ_QUEUED,
+ /** The end of the valid statistics value names. */
+ RTREQPOOLSTAT_END,
+ /** Blow the type up to 32-bit. */
+ RTREQPOOLSTAT_32BIT_HACK = 0x7fffffff
+} RTREQPOOLSTAT;
+
+/**
+ * Read a statistics value from the request thread pool.
+ *
+ * @returns The value, UINT64_MAX if an invalid parameter was given.
+ * @param hPool The request thread pool handle.
+ * @param enmStat The statistics value to get.
+ */
+RTDECL(uint64_t) RTReqPoolGetStat(RTREQPOOL hPool, RTREQPOOLSTAT enmStat);
+
+/**
+ * Allocates a request packet.
+ *
+ * This is mostly for internal use, please use the convenience methods.
+ *
+ * @returns iprt status code.
+ *
+ * @param hPool The request thread pool handle.
+ * @param enmType Package type.
+ * @param phReq Where to store the handle to the new request.
+ */
+RTDECL(int) RTReqPoolAlloc(RTREQPOOL hPool, RTREQTYPE enmType, PRTREQ *phReq);
+
+/**
+ * Call a function on a worker thread.
+ *
+ * @returns IPRT status code.
+ * @param hPool The request thread pool handle.
+ * @param cMillies The number of milliseconds to wait for the request
+ * to be processed.
+ * @param phReq Where to return the request. Can be NULL if the
+ * RTREQFLAGS_NO_WAIT flag is used.
+ * @param fFlags A combination of RTREQFLAGS values.
+ * @param pfnFunction The function to be called. Must be declared by a
+ * DECL macro because of calling conventions.
+ * @param cArgs The number of arguments in the ellipsis.
+ * @param ... Arguments.
+ *
+ * @remarks The function better avoid taking uint64_t and structs as part of the
+ * arguments (use pointers to these instead). In general anything
+ * that's larger than an uintptr_t is problematic.
+ */
+RTDECL(int) RTReqPoolCallEx( RTREQPOOL hPool, RTMSINTERVAL cMillies, PRTREQ *phReq, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, ...);
+
+
+/**
+ * Call a function on a worker thread.
+ *
+ * @returns IPRT status code.
+ * @param hPool The request thread pool handle.
+ * @param cMillies The number of milliseconds to wait for the request
+ * to be processed.
+ * @param phReq Where to return the request. Can be NULL if the
+ * RTREQFLAGS_NO_WAIT flag is used.
+ * @param fFlags A combination of RTREQFLAGS values.
+ * @param pfnFunction The function to be called. Must be declared by a
+ * DECL macro because of calling conventions.
+ * @param cArgs The number of arguments in the variable argument
+ * list.
+ * @param va Arguments.
+ * @remarks See remarks on RTReqPoolCallEx.
+ */
+RTDECL(int) RTReqPoolCallExV(RTREQPOOL hPool, RTMSINTERVAL cMillies, PRTREQ *phReq, uint32_t fFlags, PFNRT pfnFunction, unsigned cArgs, va_list va);
+
+/**
+ * Call a function on a worker thread, wait for it to return.
+ *
+ * @returns IPRT status code returned by @a pfnFunction or request pool error.
+ * @param hPool The request thread pool handle.
+ * @param pfnFunction The function to be called. Must be declared by a
+ * DECL macro because of calling conventions. The
+ * function must return an int value compatible with
+ * the IPRT status code convention.
+ * @param cArgs The number of arguments in the elipsis.
+ * @param ... Arguments.
+ * @remarks See remarks on RTReqPoolCallEx.
+ */
+RTDECL(int) RTReqPoolCallWait(RTREQPOOL hPool, PFNRT pfnFunction, unsigned cArgs, ...);
+
+/**
+ * Call a function on a worker thread, don't wait for it to return.
+ *
+ * @returns IPRT status code.
+ * @param hPool The request thread pool handle.
+ * @param pfnFunction The function to be called. Must be declared by a
+ * DECL macro because of calling conventions. The
+ * function should return an int value compatible with
+ * the IPRT status code convention, thought it's not
+ * all that important as it's thrown away.
+ * @param cArgs The number of arguments in the elipsis.
+ * @param ... Arguments.
+ * @remarks See remarks on RTReqPoolCallEx.
+ */
+RTDECL(int) RTReqPoolCallNoWait(RTREQPOOL hPool, PFNRT pfnFunction, unsigned cArgs, ...);
+
+/**
+ * Call a void function on a worker thread.
+ *
+ * @returns IPRT status code.
+ * @param hPool The request thread pool handle.
+ * @param pfnFunction The function to be called. Must be declared by a
+ * DECL macro because of calling conventions. The
+ * function is taken to return void.
+ * @param cArgs The number of arguments in the elipsis.
+ * @param ... Arguments.
+ * @remarks See remarks on RTReqPoolCallEx.
+ */
+RTDECL(int) RTReqPoolCallVoidWait(RTREQPOOL hPool, PFNRT pfnFunction, unsigned cArgs, ...);
+
+/**
+ * Call a void function on a worker thread, don't wait for it to return.
+ *
+ * @returns IPRT status code.
+ * @param hPool The request thread pool handle.
+ * @param pfnFunction The function to be called. Must be declared by a
+ * DECL macro because of calling conventions. The
+ * function is taken to return void.
+ * @param cArgs The number of arguments in the elipsis.
+ * @param ... Arguments.
+ * @remarks See remarks on RTReqPoolCallEx.
+ */
+RTDECL(int) RTReqPoolCallVoidNoWait(RTREQPOOL hPool, PFNRT pfnFunction, unsigned cArgs, ...);
+
+
+/**
+ * Retainsa reference to a request.
+ *
+ * @returns The new reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hReq The request handle.
+ */
+RTDECL(uint32_t) RTReqRetain(PRTREQ hReq);
+
+/**
+ * Releases a reference to the request.
+ *
+ * When the reference count reaches zero, the request will be pooled for reuse.
+ *
+ * @returns The new reference count, UINT32_MAX on invalid handle (asserted).
+ * @param hReq Package to release.
+ */
+RTDECL(uint32_t) RTReqRelease(PRTREQ hReq);
+
+/**
+ * Queue a request.
+ *
+ * The quest must be allocated using RTReqQueueAlloc() or RTReqPoolAlloc() and
+ * contain all the required data.
+ *
+ * If it's desired to poll on the completion of the request set cMillies
+ * to 0 and use RTReqWait() to check for completion. In the other case
+ * use RT_INDEFINITE_WAIT.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
+ *
+ * @param pReq The request to queue.
+ * @param cMillies Number of milliseconds to wait for the request to
+ * be completed. Use RT_INDEFINITE_WAIT to only
+ * wait till it's completed.
+ */
+RTDECL(int) RTReqSubmit(PRTREQ pReq, RTMSINTERVAL cMillies);
+
+
+/**
+ * Wait for a request to be completed.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @returns VERR_TIMEOUT if cMillies was reached without the packet being completed.
+ *
+ * @param pReq The request to wait for.
+ * @param cMillies Number of milliseconds to wait.
+ * Use RT_INDEFINITE_WAIT to only wait till it's completed.
+ */
+RTDECL(int) RTReqWait(PRTREQ pReq, RTMSINTERVAL cMillies);
+
+/**
+ * Get the status of the request.
+ *
+ * @returns Status code in the IPRT tradition.
+ *
+ * @param pReq The request.
+ */
+RTDECL(int) RTReqGetStatus(PRTREQ pReq);
+
+#endif /* IN_RING3 */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/runtime-loader.h b/include/iprt/runtime-loader.h
new file mode 100644
index 00000000..81ba40e6
--- /dev/null
+++ b/include/iprt/runtime-loader.h
@@ -0,0 +1,179 @@
+/** @file
+ * IPRT - Runtime Loader Generation.
+ */
+
+/*
+ * 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 <iprt/types.h>
+#ifdef RT_RUNTIME_LOADER_GENERATE_BODY_STUBS
+# include <iprt/ldr.h>
+# include <iprt/log.h>
+# include <iprt/once.h>
+#endif
+
+/** @defgroup grp_rt_runtime_loader Runtime Loader Generation
+ * @ingroup grp_rt
+ *
+ * How to use this loader generator
+ *
+ * This loader generator can be used to generate stub code for loading a shared
+ * library and its functions at runtime, or for generating a header file with
+ * the declaration of the loader function and optionally declarations for the
+ * functions loaded. It should be included in a header file or a C source
+ * file, after defining certain macros which it makes use of.
+ *
+ * To generate the C source code for function proxy stubs and the library
+ * loader function, you should define the following macros in your source file
+ * before including this header:
+ *
+ * RT_RUNTIME_LOADER_LIB_NAME - the file name of the library to load
+ * RT_RUNTIME_LOADER_FUNCTION - the name of the loader function
+ * RT_RUNTIME_LOADER_INSERT_SYMBOLS - a macro containing the names of the
+ * functions to be loaded, defined in the
+ * following pattern:
+ * @code
+ * #define RT_RUNTIME_LOADER_INSERT_SYMBOLS \
+ * RT_PROXY_STUB(func_name, ret_type, (long_param_list), (short_param_list)) \
+ * RT_PROXY_STUB(func_name2, ret_type2, (long_param_list2), (short_param_list2)) \
+ * ...
+ * @endcode
+ *
+ * where long_param_list is a parameter list for declaring the function of the
+ * form (type1 arg1, type2 arg2, ...) and short_param_list for calling it, of
+ * the form (arg1, arg2, ...).
+ *
+ * To generate the header file, you should define RT_RUNTIME_LOADER_FUNCTION
+ * and if you wish to generate declarations for the functions you should
+ * additionally define RT_RUNTIME_LOADER_INSERT_SYMBOLS as above and
+ * RT_RUNTIME_LOADER_GENERATE_DECLS (without a value) before including this
+ * file.
+ *
+ * @{
+ */
+/** @todo this is far too complicated. A script for generating the files would
+ * probably be preferable.
+ *
+ * bird> An alternative is to generate assembly jump wrappers, this only
+ * requires the symbol names and prefix. I've done this ages ago when we forked
+ * the EMX/GCC toolchain on OS/2... It's a wee bit more annoying in x86 PIC/PIE
+ * mode, but nothing that cannot be dealt with.
+ */
+/** @todo r=bird: The use of RTR3DECL here is an unresolved issue. */
+/** @todo r=bird: The lack of RT_C_DECLS_BEGIN/END is an unresolved issue. Here
+ * we'll get into trouble if we use the same symbol names as the
+ * original! */
+/** @todo r=bird: The prefix usage here is very confused: RT_RUNTIME_LOADER_XXX,
+ * RT_PROXY_STUB, etc. */
+
+#ifdef RT_RUNTIME_LOADER_GENERATE_BODY_STUBS
+
+/* The following are the symbols which we need from the library. */
+# define RT_PROXY_STUB(function, rettype, signature, shortsig) \
+ void (*function ## _fn)(void); \
+ RTR3DECL(rettype) function signature \
+ { return ( (rettype (*) signature) function ## _fn ) shortsig; }
+
+RT_RUNTIME_LOADER_INSERT_SYMBOLS
+
+# undef RT_PROXY_STUB
+
+/* Now comes a table of functions to be loaded from the library. */
+typedef struct
+{
+ const char *pszName;
+ void (**ppfn)(void);
+} RTLDRSHAREDFUNC;
+
+# define RT_PROXY_STUB(s, dummy1, dummy2, dummy3 ) { #s , & s ## _fn } ,
+static RTLDRSHAREDFUNC g_aSharedFuncs[] =
+{
+ RT_RUNTIME_LOADER_INSERT_SYMBOLS
+ { NULL, NULL }
+};
+# undef RT_PROXY_STUB
+
+/**
+ * The function which does the actual work for RT_RUNTIME_LOADER_FUNCTION,
+ * serialised for thread safety.
+ */
+static DECLCALLBACK(int) rtldrLoadOnce(void *, void *)
+{
+ RTLDRMOD hLib;
+ int rc;
+
+ LogFlowFunc(("\n"));
+ rc = RTLdrLoad(RT_RUNTIME_LOADER_LIB_NAME, &hLib);
+ for (unsigned i = 0; RT_SUCCESS(rc) && g_aSharedFuncs[i].pszName != NULL; ++i)
+ rc = RTLdrGetSymbol(hLib, g_aSharedFuncs[i].pszName, (void **)g_aSharedFuncs[i].ppfn);
+ LogFlowFunc(("rc = %Rrc\n", rc));
+
+ return rc;
+}
+
+/**
+ * Load the shared library RT_RUNTIME_LOADER_LIB_NAME and resolve the symbols
+ * pointed to by RT_RUNTIME_LOADER_INSERT_SYMBOLS.
+ *
+ * May safely be called from multiple threads and will not return until the
+ * library is loaded or has failed to load.
+ *
+ * @returns IPRT status code.
+ */
+RTR3DECL(int) RT_RUNTIME_LOADER_FUNCTION(void)
+{
+ static RTONCE s_Once = RTONCE_INITIALIZER;
+ int rc;
+
+ LogFlowFunc(("\n"));
+ rc = RTOnce(&s_Once, rtldrLoadOnce, NULL, NULL);
+ LogFlowFunc(("rc = %Rrc\n", rc));
+
+ return rc;
+}
+
+#elif defined(RT_RUNTIME_LOADER_GENERATE_HEADER)
+# ifdef RT_RUNTIME_LOADER_GENERATE_DECLS
+/* Declarations of the functions that we need from
+ * RT_RUNTIME_LOADER_LIB_NAME */
+# define RT_PROXY_STUB(function, rettype, signature, shortsig) \
+ RTR3DECL(rettype) ( function ) signature ;
+
+RT_RUNTIME_LOADER_INSERT_SYMBOLS
+
+# undef RT_PROXY_STUB
+# endif /* RT_RUNTIME_LOADER_GENERATE_DECLS */
+
+/**
+ * Try to dynamically load the library. This function should be called before
+ * attempting to use any of the library functions. It is safe to call this
+ * function multiple times.
+ *
+ * @returns iprt status code
+ */
+RTR3DECL(int) RT_RUNTIME_LOADER_FUNCTION(void);
+
+#else
+# error "One of RT_RUNTIME_LOADER_GENERATE_HEADER or RT_RUNTIME_LOADER_GENERATE_BODY_STUBS must be defined when including this file"
+#endif
+
+/** @} */
+
diff --git a/include/iprt/runtime.h b/include/iprt/runtime.h
new file mode 100644
index 00000000..b70bfd1b
--- /dev/null
+++ b/include/iprt/runtime.h
@@ -0,0 +1,86 @@
+/** @file
+ * IPRT - Include Everything.
+ */
+
+/*
+ * 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 ___iprt_runtime_h
+#define ___iprt_runtime_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/param.h>
+#include <iprt/initterm.h>
+
+#if !defined(IN_RC) && !defined(IN_RING0_AGNOSTIC)
+# include <iprt/alloca.h>
+#endif
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/avl.h>
+#include <iprt/crc.h>
+#include <iprt/critsect.h>
+#include <iprt/dir.h>
+#include <iprt/err.h>
+#ifndef IN_RC
+# include <iprt/file.h>
+# include <iprt/fs.h>
+#endif
+#include <iprt/getopt.h>
+#include <iprt/ldr.h>
+#include <iprt/log.h>
+#include <iprt/md5.h>
+#ifndef IN_RC
+# include <iprt/mem.h>
+# include <iprt/mp.h>
+#endif
+#include <iprt/path.h>
+#include <iprt/semaphore.h>
+#include <iprt/spinlock.h>
+#include <iprt/stdarg.h>
+#include <iprt/string.h>
+#include <iprt/system.h>
+#include <iprt/table.h>
+#ifndef IN_RC
+# include <iprt/thread.h>
+#endif
+#include <iprt/time.h>
+#include <iprt/timer.h>
+#include <iprt/uni.h>
+#include <iprt/uuid.h>
+#include <iprt/zip.h>
+
+#ifdef IN_RING3
+# include <iprt/stream.h>
+# include <iprt/tcp.h>
+# include <iprt/ctype.h>
+# include <iprt/alloca.h> /** @todo iprt/alloca.h should be made available in R0 and GC too! */
+# include <iprt/process.h> /** @todo iprt/process.h should be made available in R0 too (partly). */
+#endif
+
+#ifdef IN_RING0
+# include <iprt/memobj.h>
+#endif
+
+
+#endif
+
diff --git a/include/iprt/s3.h b/include/iprt/s3.h
new file mode 100644
index 00000000..2c200d5a
--- /dev/null
+++ b/include/iprt/s3.h
@@ -0,0 +1,270 @@
+/* $Id: s3.h $ */
+/** @file
+ * IPRT - Simple Storage Service (S3) Communication API.
+ */
+
+/*
+ * 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 ___iprt_s3_h
+#define ___iprt_s3_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_s3 RTS3 - Simple Storage Service (S3) Communication API
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @todo the following three definitions may move the iprt/types.h later. */
+/** RTS3 interface handle. */
+typedef R3PTRTYPE(struct RTS3INTERNAL *) RTS3;
+/** Pointer to a RTS3 interface handle. */
+typedef RTS3 *PRTS3;
+/** Nil RTS3 interface handle. */
+#define NIL_RTS3 ((RTS3)0)
+
+
+/**
+ * S3 progress callback.
+ *
+ * @returns Reserved, must be 0.
+ *
+ * @param uPercent The process completion percentage.
+ * @param pvUser The user parameter given to RTS3SetProgressCallback.
+ */
+typedef DECLCALLBACK(int) FNRTS3PROGRESS(unsigned uPercent, void *pvUser);
+/** Pointer to a S3 progress callback. */
+typedef FNRTS3PROGRESS *PFNRTS3PROGRESS;
+
+
+/** Pointer to an S3 bucket entry. */
+typedef struct RTS3BUCKETENTRY *PRTS3BUCKETENTRY;
+/** Pointer to a const S3 bucket entry. */
+typedef struct RTS3BUCKETENTRY const *PCRTS3BUCKETENTRY;
+/**
+ * RTS3 bucket entry.
+ *
+ * Represent a bucket of the S3 storage server. Bucket entries are chained as a
+ * doubly linked list using the pPrev & pNext member.
+ *
+ * @todo Consider making the entire list const unless there are plans for
+ * more APIs using this structure which requires the caller to create
+ * or modify it.
+ */
+typedef struct RTS3BUCKETENTRY
+{
+ /** The previous element. */
+ PRTS3BUCKETENTRY pPrev;
+ /** The next element. */
+ PRTS3BUCKETENTRY pNext;
+
+ /** The name of the bucket. */
+ char const *pszName;
+ /** The creation date of the bucket as string. */
+ char const *pszCreationDate;
+} RTS3BUCKETENTRY;
+
+
+/** Pointer to an S3 key entry. */
+typedef struct RTS3KEYENTRY *PRTS3KEYENTRY;
+/** Pointer to a const S3 key entry. */
+typedef struct RTS3KEYENTRY const *PCRTS3KEYENTRY;
+/**
+ * RTS3 key entry.
+ *
+ * Represent a key of the S3 storage server. Key entries are chained as a doubly
+ * linked list using the pPrev & pNext member.
+ *
+ * @todo Consider making the entire list const unless there are plans for
+ * more APIs using this structure which requires the caller to create
+ * or modify it.
+ */
+typedef struct RTS3KEYENTRY
+{
+ /** The previous element. */
+ PRTS3KEYENTRY pPrev;
+ /** The next element. */
+ PRTS3KEYENTRY pNext;
+
+ /** The name of the key. */
+ char const *pszName;
+ /** The date this key was last modified as string. */
+ char const *pszLastModified;
+ /** The size of the file behind this key in bytes. */
+ uint64_t cbFile;
+} RTS3KEYENTRY;
+
+
+/**
+ * Creates a RTS3 interface handle.
+ *
+ * @returns iprt status code.
+ *
+ * @param phS3 Where to store the RTS3 handle.
+ * @param pszAccessKey The access key for the S3 storage server.
+ * @param pszSecretKey The secret access key for the S3 storage server.
+ * @param pszBaseUrl The base URL of the S3 storage server.
+ * @param pszUserAgent An optional user agent string used in the HTTP
+ * communication.
+ */
+RTR3DECL(int) RTS3Create(PRTS3 phS3, const char *pszAccessKey, const char *pszSecretKey, const char *pszBaseUrl, const char *pszUserAgent);
+
+/**
+ * Destroys a RTS3 interface handle.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ */
+RTR3DECL(void) RTS3Destroy(RTS3 hS3);
+
+/**
+ * Sets an optional progress callback.
+ *
+ * This callback function will be called when the completion percentage of an S3
+ * operation changes.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param pfnProgressCB The pointer to the progress function.
+ * @param pvUser The pvUser arg of FNRTS3PROGRESS.
+ */
+RTR3DECL(void) RTS3SetProgressCallback(RTS3 hS3, PFNRTS3PROGRESS pfnProgressCB, void *pvUser);
+
+/**
+ * Gets a list of all available buckets on the S3 storage server.
+ *
+ * You have to delete ppBuckets after usage with RTS3BucketsDestroy.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param ppBuckets Where to store the pointer to the head of the
+ * returned bucket list. Consider the entire list
+ * read-only.
+ */
+RTR3DECL(int) RTS3GetBuckets(RTS3 hS3, PCRTS3BUCKETENTRY *ppBuckets);
+
+/**
+ * Destroys the bucket list returned by RTS3GetBuckets.
+ *
+ * @returns iprt status code.
+ *
+ * @param pBuckets Pointer to the first bucket entry.
+ */
+RTR3DECL(int) RTS3BucketsDestroy(PCRTS3BUCKETENTRY pBuckets);
+
+/**
+ * Creates a new bucket on the S3 storage server.
+ *
+ * This name have to be unique over all accounts on the S3 storage server.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param pszBucketName Name of the new bucket.
+ */
+RTR3DECL(int) RTS3CreateBucket(RTS3 hS3, const char *pszBucketName);
+
+/**
+ * Deletes a bucket on the S3 storage server.
+ *
+ * The bucket must be empty.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param pszBucketName Name of the bucket to delete.
+ */
+RTR3DECL(int) RTS3DeleteBucket(RTS3 hS3, const char *pszBucketName);
+
+/**
+ * Gets a list of all available keys in a bucket on the S3 storage server.
+ *
+ * You have to delete ppKeys after usage with RTS3KeysDestroy.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param pszBucketName Name of the bucket to delete.
+ * @param ppKeys Where to store the pointer to the head of the
+ * returned key list. Consider the entire list
+ * read-only.
+ */
+RTR3DECL(int) RTS3GetBucketKeys(RTS3 hS3, const char *pszBucketName, PCRTS3KEYENTRY *ppKeys);
+
+/**
+ * Delete the key list returned by RTS3GetBucketKeys.
+ *
+ * @returns iprt status code.
+ *
+ * @param pKeys Pointer to the first key entry.
+ */
+RTR3DECL(int) RTS3KeysDestroy(PCRTS3KEYENTRY pKeys);
+
+/**
+ * Deletes a key in a bucket on the S3 storage server.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param pszBucketName Name of the bucket contains pszKeyName.
+ * @param pszKeyName Name of the key to delete.
+ */
+RTR3DECL(int) RTS3DeleteKey(RTS3 hS3, const char *pszBucketName, const char *pszKeyName);
+
+/**
+ * Downloads a key from a bucket into a file.
+ *
+ * The file must not exists.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param pszBucketName Name of the bucket that contains pszKeyName.
+ * @param pszKeyName Name of the key to download.
+ * @param pszFilename Name of the file to store the downloaded key as.
+ */
+RTR3DECL(int) RTS3GetKey(RTS3 hS3, const char *pszBucketName, const char *pszKeyName, const char *pszFilename);
+
+/**
+ * Uploads the content of a file into a key in the specified bucked.
+ *
+ * @returns iprt status code.
+ *
+ * @param hS3 Handle to the RTS3 interface.
+ * @param pszBucketName Name of the bucket where the new key should be
+ * created.
+ * @param pszKeyName Name of the new key.
+ * @param pszFilename Name of the file to upload the content of.
+ */
+RTR3DECL(int) RTS3PutKey(RTS3 hS3, const char *pszBucketName, const char *pszKeyName, const char *pszFilename);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/semaphore.h b/include/iprt/semaphore.h
new file mode 100644
index 00000000..0eba39c7
--- /dev/null
+++ b/include/iprt/semaphore.h
@@ -0,0 +1,1441 @@
+/** @file
+ * IPRT - Semaphore.
+ */
+
+/*
+ * 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 ___iprt_semaphore_h
+#define ___iprt_semaphore_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3)
+# include <iprt/lockvalidator.h>
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_sems RTSem - Semaphores
+ *
+ * This module implements all kinds of event and mutex semaphores; in addition
+ * to these, IPRT implements "critical sections", which are fast recursive
+ * mutexes (see @ref grp_rt_critsect ). C++ users may find @ref grp_rt_cpp_lock
+ * interesting.
+ *
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** @name Generic Semaphore Wait Flags.
+ *
+ * @remarks Exactly one of RTSEMWAIT_FLAGS_RELATIVE and
+ * RTSEMWAIT_FLAGS_ABSOLUTE must be set, unless
+ * RTSEMWAIT_FLAGS_INDEFINITE is used.
+ *
+ * Exactly one of RTSEMWAIT_FLAGS_NANOSECS and
+ * RTSEMWAIT_FLAGS_MILLISECS must be set, unless
+ * RTSEMWAIT_FLAGS_INDEFINITE is used.
+ *
+ * Exactly one of RTSEMWAIT_FLAGS_RESUME and RTSEMWAIT_FLAGS_NORESUME
+ * must be set.
+ *
+ * The interruptible vs resume stuff is ring-0 vs ring-3 semantics.
+ *
+ * @{ */
+/** The timeout is relative. */
+#define RTSEMWAIT_FLAGS_RELATIVE RT_BIT_32(0)
+/** The timeout is absolute. */
+#define RTSEMWAIT_FLAGS_ABSOLUTE RT_BIT_32(1)
+/** The timeout is specified in nanoseconds. */
+#define RTSEMWAIT_FLAGS_NANOSECS RT_BIT_32(2)
+/** The timeout is specified in milliseconds. */
+#define RTSEMWAIT_FLAGS_MILLISECS RT_BIT_32(3)
+/** Indefinite wait.
+ * The relative/absolute and nano-/millisecond flags are ignored. */
+#define RTSEMWAIT_FLAGS_INDEFINITE RT_BIT_32(4)
+/** Mask covering the time related bits. */
+#define RTSEMWAIT_FLAGS_TIME_MASK UINT32_C(0x0000001f)
+
+/** Interruptible wait. */
+#define RTSEMWAIT_FLAGS_INTERRUPTIBLE RT_BIT_32(5)
+/** No automatic resume, same as interruptible. */
+#define RTSEMWAIT_FLAGS_NORESUME RTSEMWAIT_FLAGS_INTERRUPTIBLE
+/** Uninterruptible wait. */
+#define RTSEMWAIT_FLAGS_UNINTERRUPTIBLE RT_BIT_32(6)
+/** Resume on interrupt, same as uninterruptible. */
+#define RTSEMWAIT_FLAGS_RESUME RTSEMWAIT_FLAGS_UNINTERRUPTIBLE
+
+/** Macro for validate the flags. */
+#define RTSEMWAIT_FLAGS_ARE_VALID(fFlags) \
+ ( !((fFlags) & UINT32_C(0xffffff80)) \
+ && ( ((fFlags) & RTSEMWAIT_FLAGS_INDEFINITE) \
+ ? ( (((fFlags) & UINT32_C(0x20))) ^ (((fFlags) >> 1) & UINT32_C(0x20)) ) == UINT32_C(0x20) \
+ : ( (((fFlags) & UINT32_C(0x25))) ^ (((fFlags) >> 1) & UINT32_C(0x25)) ) == UINT32_C(0x25) ))
+/** @} */
+
+
+
+/** @defgroup grp_rt_sems_event RTSemEvent - Single Release Event Semaphores
+ *
+ * Event semaphores can be used for inter-thread communication when one thread
+ * wants to notify another thread that something happened. A thread can block
+ * ("wait") on an event semaphore until it is signalled by another thread; see
+ * RTSemEventCreate, RTSemEventSignal and RTSemEventWait.
+ *
+ * @{ */
+
+/**
+ * Create an event semaphore.
+ *
+ * @returns iprt status code.
+ * @param phEventSem Where to store the handle to the newly created
+ * event semaphore.
+ */
+RTDECL(int) RTSemEventCreate(PRTSEMEVENT phEventSem);
+
+/**
+ * Create an event semaphore.
+ *
+ * @returns iprt status code.
+ * @param phEventSem Where to store the handle to the newly created
+ * event semaphore.
+ * @param fFlags Flags, any combination of the
+ * RTSEMEVENT_FLAGS_XXX \#defines.
+ * @param hClass The class (no reference consumed). Since we
+ * don't do order checks on event semaphores, the
+ * use of the class is limited to controlling the
+ * timeout threshold for deadlock detection.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTSemEventCreateEx(PRTSEMEVENT phEventSem, uint32_t fFlags, RTLOCKVALCLASS hClass, const char *pszNameFmt, ...);
+
+/** @name RTSemMutexCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMEVENT_FLAGS_NO_LOCK_VAL UINT32_C(0x00000001)
+/** Bootstrap hack for use with certain memory allocator locks only! */
+#define RTSEMEVENT_FLAGS_BOOTSTRAP_HACK UINT32_C(0x00000004)
+/** @} */
+
+/**
+ * Destroy an event semaphore.
+ *
+ * @returns iprt status code.
+ * @param hEventSem Handle of the event semaphore. NIL_RTSEMEVENT
+ * is quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemEventDestroy(RTSEMEVENT hEventSem);
+
+/**
+ * Signal an event semaphore.
+ *
+ * The event semaphore will be signaled and automatically reset after exactly
+ * one thread have successfully returned from RTSemEventWait() after
+ * waiting/polling on that semaphore.
+ *
+ * @returns iprt status code.
+ * @param hEventSem The event semaphore to signal.
+ *
+ * @remarks ring-0: This works when preemption is disabled. However it is
+ * system specific whether it works in interrupt context or with
+ * interrupts disabled.
+ */
+RTDECL(int) RTSemEventSignal(RTSEMEVENT hEventSem);
+
+/**
+ * Wait for the event semaphore to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async system event
+ * (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hEventSem The event semaphore to wait on.
+ * @param cMillies Number of milliseconds to wait.
+ */
+RTDECL(int) RTSemEventWait(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the event semaphore to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param hEventSem The event semaphore to wait on.
+ * @param cMillies Number of milliseconds to wait.
+ */
+RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies);
+
+/**
+ * Extended API for waiting on an event semaphore to be signaled.
+ *
+ * @returns IPRT status code.
+ * @param hEventSem The event semaphore to wait on.
+ * @param fFlags Combination of RTSEMWAIT_FLAGS_XXX.
+ * @param uTimeout The timeout, ignored if
+ * RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ * Whether this is absolute or relative,
+ * milliseconds or nanoseconds depends on the @a
+ * fFlags value. Do not pass RT_INDEFINITE_WAIT
+ * here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int) RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemEventWaitEx that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemEventWaitEx.
+ * @param hEventSem The event semaphore to wait on.
+ * @param fFlags See RTSemEventWaitEx.
+ * @param uTimeout See RTSemEventWaitEx.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Gets the best timeout resolution that RTSemEventWaitEx can do.
+ *
+ * @returns The resolution in nanoseconds.
+ */
+RTDECL(uint32_t) RTSemEventGetResolution(void);
+
+/**
+ * Sets the signaller thread to one specific thread.
+ *
+ * This is only used for validating usage and deadlock detection. When used
+ * after calls to RTSemEventAddSignaller, the specified thread will be the only
+ * signalling thread.
+ *
+ * @param hEventSem The event semaphore.
+ * @param hThread The thread that will signal it. Pass
+ * NIL_RTTHREAD to indicate that there is no
+ * special signalling thread.
+ */
+RTDECL(void) RTSemEventSetSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/**
+ * To add more signalling threads.
+ *
+ * First call RTSemEventSetSignaller then add further threads with this.
+ *
+ * @param hEventSem The event semaphore.
+ * @param hThread The thread that will signal it. NIL_RTTHREAD is
+ * not accepted.
+ */
+RTDECL(void) RTSemEventAddSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/**
+ * To remove a signalling thread.
+ *
+ * Reverts work done by RTSemEventAddSignaller and RTSemEventSetSignaller.
+ *
+ * @param hEventSem The event semaphore.
+ * @param hThread A previously added thread.
+ */
+RTDECL(void) RTSemEventRemoveSignaller(RTSEMEVENT hEventSem, RTTHREAD hThread);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_event_multi RTSemEventMulti - Multiple Release Event Semaphores
+ *
+ * A variant of @ref grp_rt_sems_event where all threads will be unblocked when
+ * signalling the semaphore.
+ *
+ * @{ */
+
+/**
+ * Creates a multiple release event semaphore.
+ *
+ * @returns iprt status code.
+ * @param phEventMultiSem Where to store the handle to the newly created
+ * multiple release event semaphore.
+ */
+RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI phEventMultiSem);
+
+/**
+ * Creates a multiple release event semaphore.
+ *
+ * @returns iprt status code.
+ * @param phEventMultiSem Where to store the handle to the newly created
+ * multiple release event semaphore.
+ * @param fFlags Flags, any combination of the
+ * RTSEMEVENTMULTI_FLAGS_XXX \#defines.
+ * @param hClass The class (no reference consumed). Since we
+ * don't do order checks on event semaphores, the
+ * use of the class is limited to controlling the
+ * timeout threshold for deadlock detection.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTSemEventMultiCreateEx(PRTSEMEVENTMULTI phEventMultiSem, uint32_t fFlags, RTLOCKVALCLASS hClass,
+ const char *pszNameFmt, ...);
+
+/** @name RTSemMutexCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMEVENTMULTI_FLAGS_NO_LOCK_VAL UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroy an event multi semaphore.
+ *
+ * @returns iprt status code.
+ * @param hEventMultiSem The multiple release event semaphore. NIL is
+ * quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI hEventMultiSem);
+
+/**
+ * Signal an event multi semaphore.
+ *
+ * @returns iprt status code.
+ * @param hEventMultiSem The multiple release event semaphore.
+ *
+ * @remarks ring-0: This works when preemption is disabled. However it is
+ * system specific whether it works in interrupt context or with
+ * interrupts disabled.
+ */
+RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem);
+
+/**
+ * Resets an event multi semaphore to non-signaled state.
+ *
+ * @returns iprt status code.
+ * @param hEventMultiSem The multiple release event semaphore.
+ */
+RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem);
+
+/**
+ * Wait for the event multi semaphore to be signaled, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async
+ * system event (like a unix signal) or similar.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hEventMultiSem The multiple release event semaphore.
+ * @param cMillies Number of milliseconds to wait.
+ */
+RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the event multi semaphore to be signaled, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * @returns iprt status code.
+ * @param hEventMultiSem The multiple release event semaphore.
+ * @param cMillies Number of milliseconds to wait.
+ * @todo Rename to RTSemEventMultiWaitIntr since it is mainly for
+ * ring-0 consumption.
+ */
+RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies);
+
+/**
+ * Extended API for waiting on an event semaphore to be signaled.
+ *
+ * @returns IPRT status code.
+ * @param hEventMultiSem The multiple release event semaphore to wait
+ * on.
+ * @param fFlags Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param uTimeout The timeout, ignored if
+ * RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ * Whether this is absolute or relative,
+ * milliseconds or nanoseconds depends on the @a
+ * fFlags value. Do not pass RT_INDEFINITE_WAIT
+ * here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int) RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemEventMultiWaitEx that tracks the location.
+
+ * @returns IPRT status code, see RTSemEventMultiWaitEx.
+ * @param hEventMultiSem The multiple release event semaphore handle.
+ * @param fFlags See RTSemEventMultiWaitEx.
+ * @param uTimeout See RTSemEventMultiWaitEx.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Gets the best timeout resolution that RTSemEventMultiWaitEx can do.
+ *
+ * @returns The resolution in nanoseconds.
+ */
+RTDECL(uint32_t) RTSemEventMultiGetResolution(void);
+
+/**
+ * Sets the signaller thread to one specific thread.
+ *
+ * This is only used for validating usage and deadlock detection. When used
+ * after calls to RTSemEventAddSignaller, the specified thread will be the only
+ * signalling thread.
+ *
+ * @param hEventMultiSem The multiple release event semaphore.
+ * @param hThread The thread that will signal it. Pass
+ * NIL_RTTHREAD to indicate that there is no
+ * special signalling thread.
+ */
+RTDECL(void) RTSemEventMultiSetSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread);
+
+/**
+ * To add more signalling threads.
+ *
+ * First call RTSemEventSetSignaller then add further threads with this.
+ *
+ * @param hEventMultiSem The multiple release event semaphore.
+ * @param hThread The thread that will signal it. NIL_RTTHREAD is
+ * not accepted.
+ */
+RTDECL(void) RTSemEventMultiAddSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread);
+
+/**
+ * To remove a signalling thread.
+ *
+ * Reverts work done by RTSemEventAddSignaller and RTSemEventSetSignaller.
+ *
+ * @param hEventMultiSem The multiple release event semaphore.
+ * @param hThread A previously added thread.
+ */
+RTDECL(void) RTSemEventMultiRemoveSignaller(RTSEMEVENTMULTI hEventMultiSem, RTTHREAD hThread);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_mutex RTSemMutex - Mutex semaphores.
+ *
+ * Mutex semaphores protect a section of code or data to which access must be
+ * exclusive. Only one thread can hold access to a critical section at one
+ * time. See RTSemMutexCreate, RTSemMutexRequest and RTSemMutexRelease.
+ *
+ * @remarks These are less efficient than "fast mutexes" and "critical
+ * sections", which IPRT implements as well; see @ref
+ * grp_rt_sems_fast_mutex and @ref grp_rt_critsect .
+ *
+ * @{ */
+
+/**
+ * Create a mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param phMutexSem Where to store the mutex semaphore handle.
+ */
+RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMutexSem);
+
+/**
+ * Creates a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param phRWSem Where to store the handle to the newly created
+ * RW semaphore.
+ * @param fFlags Flags, any combination of the
+ * RTSEMMUTEX_FLAGS_XXX \#defines.
+ * @param hClass The class (no reference consumed). If NIL, no
+ * lock order validation will be performed on this
+ * lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order within a class. RTLOCKVAL_SUB_CLASS_NONE
+ * is the recommended value here.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTSemMutexCreateEx(PRTSEMMUTEX phMutexSem, uint32_t fFlags,
+ RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...);
+
+/** @name RTSemMutexCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMMUTEX_FLAGS_NO_LOCK_VAL UINT32_C(0x00000001)
+/** @} */
+
+
+/**
+ * Destroy a mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param hMutexSem The mutex semaphore to destroy. NIL is quietly
+ * ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX hMutexSem);
+
+/**
+ * Changes the lock validator sub-class of the mutex semaphore.
+ *
+ * It is recommended to try make sure that nobody is using this semaphore while
+ * changing the value.
+ *
+ * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ * lock validator isn't compiled in or either of the parameters are
+ * invalid.
+ * @param hMutexSem The handle to the mutex semaphore.
+ * @param uSubClass The new sub-class value.
+ */
+RTDECL(uint32_t) RTSemMutexSetSubClass(RTSEMMUTEX hMutexSem, uint32_t uSubClass);
+
+/**
+ * Request ownership of a mutex semaphore, resume on interruption.
+ *
+ * This function will resume if the wait is interrupted by an async
+ * system event (like a unix signal) or similar.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hMutexSem The mutex semaphore to request ownership over.
+ * @param cMillies The number of milliseconds to wait.
+ */
+RTDECL(int) RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies);
+
+/**
+ * Request ownership of a mutex semaphore, return on interruption.
+ *
+ * This function will not resume the wait if interrupted.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ * @param hMutexSem The mutex semaphore to request ownership over.
+ * @param cMillies The number of milliseconds to wait.
+ */
+RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies);
+
+/**
+ * Debug version of RTSemMutexRequest that tracks the location.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param hMutexSem The mutex semaphore to request ownership over.
+ * @param cMillies The number of milliseconds to wait.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Debug version of RTSemMutexRequestNoResume that tracks the location.
+ *
+ * @returns iprt status code.
+ * @param hMutexSem The mutex semaphore to request ownership over.
+ * @param cMillies The number of milliseconds to wait.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Request ownership of a mutex semaphore, extended edition.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ * @param hMutexSem The mutex semaphore to request ownership over.
+ * @param fFlags Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param uTimeout The timeout, ignored if
+ * RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ * Whether this is absolute or relative,
+ * milliseconds or nanoseconds depends on the @a
+ * fFlags value. Do not pass RT_INDEFINITE_WAIT
+ * here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int) RTSemMutexRequestEx(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemMutexRequestEx that tracks the location.
+ *
+ * @returns iprt status code.
+ * @param hMutexSem The mutex semaphore to request ownership over.
+ * @param fFlags See RTSemMutexRequestEx.
+ * @param uTimeout See RTSemMutexRequestEx.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemMutexRequestExDebug(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Release the ownership of a mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param hMutexSem The mutex to release the ownership of. It goes
+ * without saying the the calling thread must own
+ * it.
+ */
+RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem);
+
+/**
+ * Checks if the mutex semaphore is owned or not.
+ *
+ * @returns true if owned, false if not.
+ * @param hMutexSem The mutex semaphore.
+ */
+RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutexSem);
+
+/* Strict build: Remap the two request calls to the debug versions. */
+#if defined(RT_STRICT) && !defined(RTSEMMUTEX_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# ifdef ___iprt_asm_h
+# define RTSemMutexRequest(hMutexSem, cMillies) RTSemMutexRequestDebug((hMutexSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTSemMutexRequestNoResume(hMutexSem, cMillies) RTSemMutexRequestNoResumeDebug((hMutexSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTSemMutexRequestEx(hMutexSem, fFlags, uTimeout) RTSemMutexRequestExDebug((hMutexSem), (fFlags), (uTimeout), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+# define RTSemMutexRequest(hMutexSem, cMillies) RTSemMutexRequestDebug((hMutexSem), (cMillies), 0, RT_SRC_POS)
+# define RTSemMutexRequestNoResume(hMutexSem, cMillies) RTSemMutexRequestNoResumeDebug((hMutexSem), (cMillies), 0, RT_SRC_POS)
+# define RTSemMutexRequestEx(hMutexSem, fFlags, uTimeout) RTSemMutexRequestExDebug((hMutexSem), (fFlags), (uTimeout), 0, RT_SRC_POS)
+# endif
+#endif
+
+/* Strict lock order: Automatically classify locks by init location. */
+#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTSEMMUTEX_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# define RTSemMutexCreate(phMutexSem) \
+ RTSemMutexCreateEx((phMutexSem), 0 /*fFlags*/, \
+ RTLockValidatorClassForSrcPos(RT_SRC_POS, NULL), \
+ RTLOCKVAL_SUB_CLASS_NONE, NULL)
+#endif
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_fast_mutex RTSemFastMutex - Fast Mutex Semaphores
+ *
+ * Fast mutexes work like regular mutexes in that they allow only a single
+ * thread access to a critical piece of code or data. As opposed to mutexes,
+ * they require no syscall if the fast mutex is not held (like critical
+ * sections). Unlike critical sections however, they are *not* recursive.
+ *
+ * @remarks The fast mutexes has sideeffects on IRQL on Windows hosts. So use
+ * with care and test on windows with driver verifier.
+ *
+ * @{ */
+
+/**
+ * Create a fast mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param phFastMtx Where to store the handle to the newly created
+ * fast mutex semaphore.
+ *
+ * @remarks Fast mutex semaphores are not recursive.
+ */
+RTDECL(int) RTSemFastMutexCreate(PRTSEMFASTMUTEX phFastMtx);
+
+/**
+ * Destroy a fast mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param hFastMtx Handle to the fast mutex semaphore. NIL is
+ * quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemFastMutexDestroy(RTSEMFASTMUTEX hFastMtx);
+
+/**
+ * Request ownership of a fast mutex semaphore.
+ *
+ * The same thread may request a mutex semaphore multiple times,
+ * a nested counter is kept to make sure it's released on the right
+ * RTSemMutexRelease() call.
+ *
+ * @returns iprt status code.
+ * @param hFastMtx Handle to the fast mutex semaphore.
+ */
+RTDECL(int) RTSemFastMutexRequest(RTSEMFASTMUTEX hFastMtx);
+
+/**
+ * Release the ownership of a fast mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @param hFastMtx Handle to the fast mutex semaphore. It goes
+ * without saying the the calling thread must own
+ * it.
+ */
+RTDECL(int) RTSemFastMutexRelease(RTSEMFASTMUTEX hFastMtx);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_spin_mutex RTSemSpinMutex - Spinning Mutex Semaphores
+ *
+ * A very adaptive variant of mutex semaphore that is tailored for the ring-0
+ * logger.
+ *
+ * @{ */
+
+/**
+ * Creates a spinning mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @retval VERR_INVALID_PARAMETER on invalid flags.
+ * @retval VERR_NO_MEMORY if out of memory for the semaphore structure and
+ * handle.
+ *
+ * @param phSpinMtx Where to return the handle to the create semaphore.
+ * @param fFlags Flags, see RTSEMSPINMUTEX_FLAGS_XXX.
+ */
+RTDECL(int) RTSemSpinMutexCreate(PRTSEMSPINMUTEX phSpinMtx, uint32_t fFlags);
+
+/** @name RTSemSpinMutexCreate flags.
+ * @{ */
+/** Always take the semaphore in a IRQ safe way.
+ * (In plain words: always disable interrupts.) */
+#define RTSEMSPINMUTEX_FLAGS_IRQ_SAFE RT_BIT_32(0)
+/** Mask of valid flags. */
+#define RTSEMSPINMUTEX_FLAGS_VALID_MASK UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroys a spinning mutex semaphore.
+ *
+ * @returns iprt status code.
+ * @retval VERR_INVALID_HANDLE (or crash) if the handle is invalid. (NIL will
+ * not cause this status.)
+ *
+ * @param hSpinMtx The semaphore handle. NIL_RTSEMSPINMUTEX is ignored
+ * quietly (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemSpinMutexDestroy(RTSEMSPINMUTEX hSpinMtx);
+
+/**
+ * Request the spinning mutex semaphore.
+ *
+ * This may block if the context we're called in allows this. If not it will
+ * spin. If called in an interrupt context, we will only spin if the current
+ * owner isn't interrupted. Also, on some systems it is not always possible to
+ * wake up blocking threads in all contexts, so, which will either be indicated
+ * by returning VERR_SEM_BAD_CONTEXT or by temporarily switching the semaphore
+ * into pure spinlock state.
+ *
+ * Preemption will be disabled upon return. IRQs may also be disabled.
+ *
+ * @returns iprt status code.
+ * @retval VERR_SEM_BAD_CONTEXT if the context it's called in isn't suitable
+ * for releasing it if someone is sleeping on it.
+ * @retval VERR_SEM_DESTROYED if destroyed.
+ * @retval VERR_SEM_NESTED if held by the caller. Asserted.
+ * @retval VERR_INVALID_HANDLE if the handle is invalid. Asserted
+ *
+ * @param hSpinMtx The semaphore handle.
+ */
+RTDECL(int) RTSemSpinMutexRequest(RTSEMSPINMUTEX hSpinMtx);
+
+/**
+ * Like RTSemSpinMutexRequest but it won't block or spin if the semaphore is
+ * held by someone else.
+ *
+ * @returns iprt status code.
+ * @retval VERR_SEM_BUSY if held by someone else.
+ * @retval VERR_SEM_DESTROYED if destroyed.
+ * @retval VERR_SEM_NESTED if held by the caller. Asserted.
+ * @retval VERR_INVALID_HANDLE if the handle is invalid. Asserted
+ *
+ * @param hSpinMtx The semaphore handle.
+ */
+RTDECL(int) RTSemSpinMutexTryRequest(RTSEMSPINMUTEX hSpinMtx);
+
+/**
+ * Releases the semaphore previously acquired by RTSemSpinMutexRequest or
+ * RTSemSpinMutexTryRequest.
+ *
+ * @returns iprt status code.
+ * @retval VERR_SEM_DESTROYED if destroyed.
+ * @retval VERR_NOT_OWNER if not owner. Asserted.
+ * @retval VERR_INVALID_HANDLE if the handle is invalid. Asserted.
+ *
+ * @param hSpinMtx The semaphore handle.
+ */
+RTDECL(int) RTSemSpinMutexRelease(RTSEMSPINMUTEX hSpinMtx);
+
+/** @} */
+
+
+/** @defgroup grp_rt_sem_rw RTSemRW - Read / Write Semaphores
+ *
+ * Read/write semaphores are a fancier version of mutexes in that they grant
+ * read access to the protected data to several threads at the same time but
+ * allow only one writer at a time. This can make code scale better at the
+ * expense of slightly more overhead in mutex management.
+ *
+ * @{ */
+
+/**
+ * Creates a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param phRWSem Where to store the handle to the newly created
+ * RW semaphore.
+ */
+RTDECL(int) RTSemRWCreate(PRTSEMRW phRWSem);
+
+/**
+ * Creates a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param phRWSem Where to store the handle to the newly created
+ * RW semaphore.
+ * @param fFlags Flags, any combination of the RTSEMRW_FLAGS_XXX
+ * \#defines.
+ * @param hClass The class (no reference consumed). If NIL, no
+ * lock order validation will be performed on this
+ * lock.
+ * @param uSubClass The sub-class. This is used to define lock
+ * order within a class. RTLOCKVAL_SUB_CLASS_NONE
+ * is the recommended value here.
+ * @param pszNameFmt Name format string for the lock validator,
+ * optional (NULL). Max length is 32 bytes.
+ * @param ... Format string arguments.
+ */
+RTDECL(int) RTSemRWCreateEx(PRTSEMRW phRWSem, uint32_t fFlags,
+ RTLOCKVALCLASS hClass, uint32_t uSubClass, const char *pszNameFmt, ...);
+
+/** @name RTSemRWCreateEx flags
+ * @{ */
+/** Disables lock validation. */
+#define RTSEMRW_FLAGS_NO_LOCK_VAL UINT32_C(0x00000001)
+/** @} */
+
+/**
+ * Destroys a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param hRWSem Handle to the read/write semaphore. NIL is
+ * quietly ignored (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemRWDestroy(RTSEMRW hRWSem);
+
+/**
+ * Changes the lock validator sub-class of the read/write semaphore.
+ *
+ * It is recommended to try make sure that nobody is using this semaphore while
+ * changing the value.
+ *
+ * @returns The old sub-class. RTLOCKVAL_SUB_CLASS_INVALID is returns if the
+ * lock validator isn't compiled in or either of the parameters are
+ * invalid.
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param uSubClass The new sub-class value.
+ */
+RTDECL(uint32_t) RTSemRWSetSubClass(RTSEMRW hRWSem, uint32_t uSubClass);
+
+/**
+ * Request read access to a read/write semaphore, resume on interruption
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPT if the wait was interrupted.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ */
+RTDECL(int) RTSemRWRequestRead(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Request read access to a read/write semaphore, return on interruption
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPT if the wait was interrupted.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ */
+RTDECL(int) RTSemRWRequestReadNoResume(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Debug version of RTSemRWRequestRead that tracks the location.
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPT if the wait was interrupted.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemRWRequestReadDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Debug version of RTSemRWRequestWriteNoResume that tracks the location.
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPT if the wait was interrupted.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemRWRequestReadNoResumeDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Request read access to a read/write semaphore, extended edition.
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPT if the wait was interrupted.
+ * @retval VERR_TIMEOUT if the wait timed out.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param fFlags Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param uTimeout The timeout, ignored if
+ * RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ * Whether this is absolute or relative,
+ * milliseconds or nanoseconds depends on the @a
+ * fFlags value. Do not pass RT_INDEFINITE_WAIT
+ * here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int) RTSemRWRequestReadEx(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout);
+
+
+/**
+ * Debug version of RTSemRWRequestReadEx that tracks the location.
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPT if the wait was interrupted.
+ * @retval VERR_TIMEOUT if the wait timed out.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param fFlags See RTSemRWRequestReadEx.
+ * @param uTimeout See RTSemRWRequestReadEx.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemRWRequestReadExDebug(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Release read access to a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param hRWSem Handle to the read/write semaphore. It goes
+ * without saying that caller must own read
+ * privileges to the semaphore.
+ */
+RTDECL(int) RTSemRWReleaseRead(RTSEMRW hRWSem);
+
+/**
+ * Request write access to a read/write semaphore, resume on interruption.
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_DEADLOCK if the caller owned the read lock.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ */
+RTDECL(int) RTSemRWRequestWrite(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Request write access to a read/write semaphore, return on interruption.
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPT if the wait was interrupted.
+ * @retval VERR_DEADLOCK if the caller owned the read lock.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ */
+RTDECL(int) RTSemRWRequestWriteNoResume(RTSEMRW hRWSem, RTMSINTERVAL cMillies);
+
+/**
+ * Debug version of RTSemRWRequestWrite that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemRWRequestWrite.
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemRWRequestWriteDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Debug version of RTSemRWRequestWriteNoResume that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemRWRequestWriteNoResume.
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param cMillies The number of milliseconds to wait.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemRWRequestWriteNoResumeDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Request write access to a read/write semaphore, extended edition.
+ *
+ * @returns iprt status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INTERRUPTED if the wait was interrupted.
+ * @retval VERR_TIMEOUT if the wait timed out.
+ * @retval VERR_DEADLOCK if the caller owned the read lock. Do not depend on
+ * this as it is implementation specific.
+ * @retval VERR_INVALID_HANDLE if hRWSem is invalid.
+ *
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param fFlags Combination of the RTSEMWAIT_FLAGS_XXX.
+ * @param uTimeout The timeout, ignored if
+ * RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
+ * Whether this is absolute or relative,
+ * milliseconds or nanoseconds depends on the @a
+ * fFlags value. Do not pass RT_INDEFINITE_WAIT
+ * here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
+ */
+RTDECL(int) RTSemRWRequestWriteEx(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout);
+
+/**
+ * Debug version of RTSemRWRequestWriteEx that tracks the location.
+ *
+ * @returns IPRT status code, see RTSemRWRequestWriteEx.
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param fFlags See RTSemRWRequestWriteEx.
+ * @param uTimeout See RTSemRWRequestWriteEx.
+ * @param uId Some kind of locking location ID. Typically a
+ * return address up the stack. Optional (0).
+ * @param pszFile The file where the lock is being acquired from.
+ * Optional.
+ * @param iLine The line number in that file. Optional (0).
+ * @param pszFunction The function where the lock is being acquired
+ * from. Optional.
+ */
+RTDECL(int) RTSemRWRequestWriteExDebug(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout,
+ RTHCUINTPTR uId, RT_SRC_POS_DECL);
+
+/**
+ * Release write access to a read/write semaphore.
+ *
+ * @returns iprt status code.
+ * @param hRWSem Handle to the read/write semaphore. Goes
+ * without saying that caller must have write
+ * access to the semaphore.
+ */
+RTDECL(int) RTSemRWReleaseWrite(RTSEMRW hRWSem);
+
+/**
+ * Checks if the caller is the exclusive semaphore owner.
+ *
+ * @returns true / false accoringly.
+ * @param hRWSem Handle to the read/write semaphore.
+ */
+RTDECL(bool) RTSemRWIsWriteOwner(RTSEMRW hRWSem);
+
+/**
+ * Checks if the caller is one of the read owners of the semaphore.
+ *
+ * @note !CAUTION! This API doesn't work reliably if lock validation isn't
+ * enabled. Meaning, the answer is not trustworhty unless
+ * RT_LOCK_STRICT or RTSEMRW_STRICT was defined at build time. Also,
+ * make sure you do not use RTSEMRW_FLAGS_NO_LOCK_VAL when creating
+ * the semaphore. And finally, if you used a locking class, don't
+ * disable deadlock detection by setting cMsMinDeadlock to
+ * RT_INDEFINITE_WAIT.
+ *
+ * In short, only use this for assertions.
+ *
+ * @returns true if reader, false if not.
+ * @param hRWSem Handle to the read/write semaphore.
+ * @param fWannaHear What you'd like to hear when lock validation is
+ * not available. (For avoiding asserting all over
+ * the place.)
+ */
+RTDECL(bool) RTSemRWIsReadOwner(RTSEMRW hRWSem, bool fWannaHear);
+
+/**
+ * Gets the write recursion count.
+ *
+ * @returns The write recursion count (0 if bad semaphore handle).
+ * @param hRWSem Handle to the read/write semaphore.
+ */
+RTDECL(uint32_t) RTSemRWGetWriteRecursion(RTSEMRW hRWSem);
+
+/**
+ * Gets the read recursion count of the current writer.
+ *
+ * @returns The read recursion count (0 if bad semaphore handle).
+ * @param hRWSem Handle to the read/write semaphore.
+ */
+RTDECL(uint32_t) RTSemRWGetWriterReadRecursion(RTSEMRW hRWSem);
+
+/**
+ * Gets the current number of reads.
+ *
+ * This includes all read recursions, so it might be higher than the number of
+ * read owners. It does not include reads done by the current writer.
+ *
+ * @returns The read count (0 if bad semaphore handle).
+ * @param hRWSem Handle to the read/write semaphore.
+ */
+RTDECL(uint32_t) RTSemRWGetReadCount(RTSEMRW hRWSem);
+
+/* Strict build: Remap the four request calls to the debug versions. */
+#if defined(RT_STRICT) && !defined(RTSEMRW_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# ifdef ___iprt_asm_h
+# define RTSemRWRequestRead(hRWSem, cMillies) RTSemRWRequestReadDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTSemRWRequestReadNoResume(hRWSem, cMillies) RTSemRWRequestReadNoResumeDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTSemRWRequestWrite(hRWSem, cMillies) RTSemRWRequestWriteDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTSemRWRequestWriteNoResume(hRWSem, cMillies) RTSemRWRequestWriteNoResumeDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# define RTSemRWRequestWriteEx(hRWSem, fFlags, uTimeout) RTSemRWRequestWriteExDebug((hRWSem), (fFlags), (uTimeout), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
+# else
+# define RTSemRWRequestRead(hRWSem, cMillies) RTSemRWRequestReadDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+# define RTSemRWRequestReadNoResume(hRWSem, cMillies) RTSemRWRequestReadNoResumeDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+# define RTSemRWRequestWrite(hRWSem, cMillies) RTSemRWRequestWriteDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+# define RTSemRWRequestWriteNoResume(hRWSem, cMillies) RTSemRWRequestWriteNoResumeDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
+# define RTSemRWRequestWriteEx(hRWSem, fFlags, uTimeout) RTSemRWRequestWriteExDebug((hRWSem), (fFlags), (uTimeout), 0, RT_SRC_POS)
+# endif
+#endif
+
+/* Strict lock order: Automatically classify locks by init location. */
+#if defined(RT_LOCK_STRICT_ORDER) && defined(IN_RING3) && !defined(RTSEMRW_WITHOUT_REMAPPING) && !defined(RT_WITH_MANGLING)
+# define RTSemRWCreate(phSemRW) \
+ RTSemRWCreateEx((phSemRW), 0 /*fFlags*/, \
+ RTLockValidatorClassForSrcPos(RT_SRC_POS, NULL), \
+ RTLOCKVAL_SUB_CLASS_NONE, NULL)
+#endif
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_pingpong RTSemPingPong - Ping-Pong Construct
+ *
+ * Serialization of a two way communication.
+ *
+ * @{ */
+
+/**
+ * Ping-pong speaker
+ */
+typedef enum RTPINGPONGSPEAKER
+{
+ /** Not initialized. */
+ RTPINGPONGSPEAKER_UNINITIALIZE = 0,
+ /** Ping is speaking, Pong is waiting. */
+ RTPINGPONGSPEAKER_PING,
+ /** Pong is signaled, Ping is waiting. */
+ RTPINGPONGSPEAKER_PONG_SIGNALED,
+ /** Pong is speaking, Ping is waiting. */
+ RTPINGPONGSPEAKER_PONG,
+ /** Ping is signaled, Pong is waiting. */
+ RTPINGPONGSPEAKER_PING_SIGNALED,
+ /** Hack to ensure that it's at least 32-bits wide. */
+ RTPINGPONGSPEAKER_HACK = 0x7fffffff
+} RTPINGPONGSPEAKER;
+
+/**
+ * Ping-Pong construct.
+ *
+ * Two threads, one saying Ping and the other saying Pong. The construct
+ * makes sure they don't speak out of turn and that they can wait and poll
+ * on the conversation.
+ */
+typedef struct RTPINGPONG
+{
+ /** The semaphore the Ping thread waits on. */
+ RTSEMEVENT Ping;
+ /** The semaphore the Pong thread waits on. */
+ RTSEMEVENT Pong;
+ /** The current speaker. */
+ volatile RTPINGPONGSPEAKER enmSpeaker;
+#if HC_ARCH_BITS == 64
+ /** Padding the structure to become a multiple of sizeof(RTHCPTR). */
+ uint32_t u32Padding;
+#endif
+} RTPINGPONG;
+/** Pointer to Ping-Pong construct. */
+typedef RTPINGPONG *PRTPINGPONG;
+
+/**
+ * Init a Ping-Pong construct.
+ *
+ * @returns iprt status code.
+ * @param pPP Pointer to the ping-pong structure which needs initialization.
+ */
+RTDECL(int) RTSemPingPongInit(PRTPINGPONG pPP);
+
+/**
+ * Deletes a Ping-Pong construct.
+ *
+ * @returns iprt status code.
+ * @param pPP Pointer to the ping-pong structure which is to be destroyed.
+ * (I.e. put into uninitialized state.)
+ */
+RTDECL(int) RTSemPingPongDelete(PRTPINGPONG pPP);
+
+/**
+ * Signals the pong thread in a ping-pong construct. (I.e. sends ping.)
+ * This is called by the ping thread.
+ *
+ * @returns iprt status code.
+ * @param pPP Pointer to the ping-pong structure to ping.
+ */
+RTDECL(int) RTSemPing(PRTPINGPONG pPP);
+
+/**
+ * Signals the ping thread in a ping-pong construct. (I.e. sends pong.)
+ * This is called by the pong thread.
+ *
+ * @returns iprt status code.
+ * @param pPP Pointer to the ping-pong structure to pong.
+ */
+RTDECL(int) RTSemPong(PRTPINGPONG pPP);
+
+/**
+ * Wait function for the ping thread.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param pPP Pointer to the ping-pong structure to wait on.
+ * @param cMillies Number of milliseconds to wait.
+ */
+RTDECL(int) RTSemPingWait(PRTPINGPONG pPP, RTMSINTERVAL cMillies);
+
+/**
+ * Wait function for the pong thread.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param pPP Pointer to the ping-pong structure to wait on.
+ * @param cMillies Number of milliseconds to wait.
+ */
+RTDECL(int) RTSemPongWait(PRTPINGPONG pPP, RTMSINTERVAL cMillies);
+
+
+/**
+ * Checks if the pong thread is speaking.
+ *
+ * @returns true / false.
+ * @param pPP Pointer to the ping-pong structure.
+ * @remark This is NOT the same as !RTSemPongIsSpeaker().
+ */
+DECLINLINE(bool) RTSemPingIsSpeaker(PRTPINGPONG pPP)
+{
+ RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+ return enmSpeaker == RTPINGPONGSPEAKER_PING;
+}
+
+
+/**
+ * Checks if the pong thread is speaking.
+ *
+ * @returns true / false.
+ * @param pPP Pointer to the ping-pong structure.
+ * @remark This is NOT the same as !RTSemPingIsSpeaker().
+ */
+DECLINLINE(bool) RTSemPongIsSpeaker(PRTPINGPONG pPP)
+{
+ RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+ return enmSpeaker == RTPINGPONGSPEAKER_PONG;
+}
+
+
+/**
+ * Checks whether the ping thread should wait.
+ *
+ * @returns true / false.
+ * @param pPP Pointer to the ping-pong structure.
+ * @remark This is NOT the same as !RTSemPongShouldWait().
+ */
+DECLINLINE(bool) RTSemPingShouldWait(PRTPINGPONG pPP)
+{
+ RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+ return enmSpeaker == RTPINGPONGSPEAKER_PONG
+ || enmSpeaker == RTPINGPONGSPEAKER_PONG_SIGNALED
+ || enmSpeaker == RTPINGPONGSPEAKER_PING_SIGNALED;
+}
+
+
+/**
+ * Checks whether the pong thread should wait.
+ *
+ * @returns true / false.
+ * @param pPP Pointer to the ping-pong structure.
+ * @remark This is NOT the same as !RTSemPingShouldWait().
+ */
+DECLINLINE(bool) RTSemPongShouldWait(PRTPINGPONG pPP)
+{
+ RTPINGPONGSPEAKER enmSpeaker = pPP->enmSpeaker;
+ return enmSpeaker == RTPINGPONGSPEAKER_PING
+ || enmSpeaker == RTPINGPONGSPEAKER_PING_SIGNALED
+ || enmSpeaker == RTPINGPONGSPEAKER_PONG_SIGNALED;
+}
+
+/** @} */
+
+
+/** @defgroup grp_rt_sems_xroads RTSemXRoads - Crossroads
+ *
+ * The crossroads semaphore is intended to prevent two classes of incompatible
+ * events from occurring simultaneously, like south/north bound traffic and
+ * west/east bound traffic at a 4-way junction.
+ *
+ * @remarks In order to simplify the implementation, the current flow is always
+ * given priority. So, it won't work at all well when busy!
+ *
+ * @remarks "XRoads" is used as a name because it is briefer than "crossroads"
+ * and it slightly stresses that is a 4 way crossing to the users of
+ * American English.
+ * @{
+ */
+
+/**
+ * Creates a crossroads semaphore.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phXRoads Where to return the handle to the newly created
+ * crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsCreate(PRTSEMXROADS phXRoads);
+
+/**
+ * Destroys a crossroads semaphore.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hXRoads Handle to the crossroads semaphore that is to be
+ * destroyed. NIL_RTSEMXROADS is quitetly ignored
+ * (VINF_SUCCESS).
+ */
+RTDECL(int) RTSemXRoadsDestroy(RTSEMXROADS hXRoads);
+
+/**
+ * Enter the crossroads from the south or north.
+ *
+ * (Coupled with RTSemXRoadsNSLeave.)
+ *
+ * @returns IPRT status code.
+ * @param hXRoads Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsNSEnter(RTSEMXROADS hXRoads);
+
+/**
+ * Leave the crossroads to the north or south.
+ *
+ * (Coupled with RTSemXRoadsNSEnter.)
+ *
+ * @returns IPRT status code.
+ * @param hXRoads Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsNSLeave(RTSEMXROADS hXRoads);
+
+/**
+ * Leave the crossroads from the east or west.
+ *
+ * (Coupled with RTSemXRoadsEWLeave.)
+ *
+ * @returns IPRT status code.
+ * @param hXRoads Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsEWEnter(RTSEMXROADS hXRoads);
+
+/**
+ * Leave the crossroads to the west or east.
+ *
+ * (Coupled with RTSemXRoadsEWEnter.)
+ *
+ * @returns IPRT status code.
+ * @param hXRoads Handle to the crossroads semaphore.
+ */
+RTDECL(int) RTSemXRoadsEWLeave(RTSEMXROADS hXRoads);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/sg.h b/include/iprt/sg.h
new file mode 100644
index 00000000..d515de8b
--- /dev/null
+++ b/include/iprt/sg.h
@@ -0,0 +1,278 @@
+/** @file
+ * IPRT - S/G buffer handling.
+ */
+
+/*
+ * 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 ___iprt_sg_h
+#define ___iprt_sg_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/**
+ * A S/G entry.
+ */
+typedef struct RTSGSEG
+{
+ /** Pointer to the segment buffer. */
+ void *pvSeg;
+ /** Size of the segment buffer. */
+ size_t cbSeg;
+} RTSGSEG;
+/** Pointer to a S/G entry. */
+typedef RTSGSEG *PRTSGSEG;
+/** Pointer to a const S/G entry. */
+typedef const RTSGSEG *PCRTSGSEG;
+/** Pointer to a S/G entry pointer. */
+typedef PRTSGSEG *PPRTSGSEG;
+
+/**
+ * A S/G buffer.
+ *
+ * The members should be treated as private.
+ */
+typedef struct RTSGBUF
+{
+ /** Pointer to the scatter/gather array. */
+ PCRTSGSEG paSegs;
+ /** Number of segments. */
+ unsigned cSegs;
+ /** Current segment we are in. */
+ unsigned idxSeg;
+ /** Pointer to the current segment start. */
+ void *pvSegCur;
+ /** Number of bytes left in the current buffer. */
+ size_t cbSegLeft;
+} RTSGBUF;
+/** Pointer to a S/G entry. */
+typedef RTSGBUF *PRTSGBUF;
+/** Pointer to a const S/G entry. */
+typedef const RTSGBUF *PCRTSGBUF;
+/** Pointer to a S/G entry pointer. */
+typedef PRTSGBUF *PPRTSGBUF;
+
+/**
+ * Initialize a S/G buffer structure.
+ *
+ * @returns nothing.
+ * @param pSgBuf Pointer to the S/G buffer to initialize.
+ * @param paSegs Pointer to the start of the segment array.
+ * @param cSegs Number of segments in the array.
+ */
+RTDECL(void) RTSgBufInit(PRTSGBUF pSgBuf, PCRTSGSEG paSegs, size_t cSegs);
+
+/**
+ * Resets the internal buffer position of the S/G buffer to the beginning.
+ *
+ * @returns nothing.
+ * @param pSgBuf The S/G buffer to reset.
+ */
+RTDECL(void) RTSgBufReset(PRTSGBUF pSgBuf);
+
+/**
+ * Clones a given S/G buffer.
+ *
+ * @returns nothing.
+ * @param pSgBufNew The new S/G buffer to clone to.
+ * @param pSgBufOld The source S/G buffer to clone from.
+ *
+ * @note This is only a shallow copy. Both S/G buffers will point to the
+ * same segment array.
+ */
+RTDECL(void) RTSgBufClone(PRTSGBUF pSgBufNew, PCRTSGBUF pSgBufOld);
+
+/**
+ * Returns the next segment in the S/G buffer or NULL if no segment is left.
+ *
+ * @returns Pointer to the next segment in the S/G buffer.
+ * @param pSgBuf The S/G buffer.
+ * @param pcbSeg Where to store the size of the returned segment.
+ * Holds the number of bytes requested initially or 0 to
+ * indicate that the size doesn't matter.
+ * This may contain fewer bytes on success if the current segment
+ * is smaller than the amount of bytes requested.
+ *
+ * @note This operation advances the internal buffer pointer of both S/G buffers.
+ */
+RTDECL(void *) RTSgBufGetNextSegment(PRTSGBUF pSgBuf, size_t *pcbSeg);
+
+/**
+ * Copy data between two S/G buffers.
+ *
+ * @returns The number of bytes copied.
+ * @param pSgBufDst The destination S/G buffer.
+ * @param pSgBufSrc The source S/G buffer.
+ * @param cbCopy Number of bytes to copy.
+ *
+ * @note This operation advances the internal buffer pointer of both S/G buffers.
+ */
+RTDECL(size_t) RTSgBufCopy(PRTSGBUF pSgBufDst, PRTSGBUF pSgBufSrc, size_t cbCopy);
+
+/**
+ * Compares the content of two S/G buffers.
+ *
+ * @returns Whatever memcmp returns.
+ * @param pSgBuf1 First S/G buffer.
+ * @param pSgBuf2 Second S/G buffer.
+ * @param cbCmp How many bytes to compare.
+ *
+ * @note This operation doesn't change the internal position of the S/G buffers.
+ */
+RTDECL(int) RTSgBufCmp(PCRTSGBUF pSgBuf1, PCRTSGBUF pSgBuf2, size_t cbCmp);
+
+/**
+ * Compares the content of two S/G buffers - advanced version.
+ *
+ * @returns Whatever memcmp returns.
+ * @param pSgBuf1 First S/G buffer.
+ * @param pSgBuf2 Second S/G buffer.
+ * @param cbCmp How many bytes to compare.
+ * @param pcbOff Where to store the offset of the first different byte
+ * in the buffer starting from the position of the S/G
+ * buffer before this call.
+ * @param fAdvance Flag whether the internal buffer position should be advanced.
+ *
+ */
+RTDECL(int) RTSgBufCmpEx(PRTSGBUF pSgBuf1, PRTSGBUF pSgBuf2, size_t cbCmp,
+ size_t *pcbOff, bool fAdvance);
+
+/**
+ * Fills an S/G buf with a constant byte.
+ *
+ * @returns The number of actually filled bytes.
+ * Can be less than than cbSet if the end of the S/G buffer was reached.
+ * @param pSgBuf The S/G buffer.
+ * @param ubFill The byte to fill the buffer with.
+ * @param cbSet How many bytes to set.
+ *
+ * @note This operation advances the internal buffer pointer of the S/G buffer.
+ */
+RTDECL(size_t) RTSgBufSet(PRTSGBUF pSgBuf, uint8_t ubFill, size_t cbSet);
+
+/**
+ * Copies data from an S/G buffer into a given non scattered buffer.
+ *
+ * @returns Number of bytes copied.
+ * @param pSgBuf The S/G buffer to copy from.
+ * @param pvBuf Buffer to copy the data into.
+ * @param cbCopy How many bytes to copy.
+ *
+ * @note This operation advances the internal buffer pointer of the S/G buffer.
+ */
+RTDECL(size_t) RTSgBufCopyToBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy);
+
+/**
+ * Copies data from a non scattered buffer into an S/G buffer.
+ *
+ * @returns Number of bytes copied.
+ * @param pSgBuf The S/G buffer to copy to.
+ * @param pvBuf Buffer to copy the data into.
+ * @param cbCopy How many bytes to copy.
+ *
+ * @note This operation advances the internal buffer pointer of the S/G buffer.
+ */
+RTDECL(size_t) RTSgBufCopyFromBuf(PRTSGBUF pSgBuf, void *pvBuf, size_t cbCopy);
+
+/**
+ * Advances the internal buffer pointer.
+ *
+ * @returns Number of bytes the pointer was moved forward.
+ * @param pSgBuf The S/G buffer.
+ * @param cbAdvance Number of bytes to move forward.
+ */
+RTDECL(size_t) RTSgBufAdvance(PRTSGBUF pSgBuf, size_t cbAdvance);
+
+/**
+ * Constructs a new segment array starting from the current position
+ * and describing the given number of bytes.
+ *
+ * @returns Number of bytes the array describes.
+ * @param pSgBuf The S/G buffer.
+ * @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.
+ *
+ * @note This operation advances the internal buffer pointer of the S/G buffer if paSeg is not NULL.
+ */
+RTDECL(size_t) RTSgBufSegArrayCreate(PRTSGBUF pSgBuf, PRTSGSEG paSeg, unsigned *pcSeg, size_t cbData);
+
+/**
+ * Maps the given S/G buffer to a segment array of another type (for example to
+ * iovec on POSIX or WSABUF on Windows).
+ *
+ * @param paMapped Where to store the pointer to the start of the native
+ * array or NULL. The memory needs to be freed with
+ * RTMemTmpFree().
+ * @param pSgBuf The S/G buffer to map.
+ * @param Struct Struct used as the destination.
+ * @param pvBufField Name of the field holding the pointer to a buffer.
+ * @param TypeBufPtr Type of the buffer pointer.
+ * @param cbBufField Name of the field holding the size of the buffer.
+ * @param TypeBufSize Type of the field for the buffer size.
+ * @param cSegsMapped Where to store the number of segments the native array
+ * has.
+ *
+ * @note This operation maps the whole S/G buffer starting at the current
+ * internal position. The internal buffer position is unchanged by
+ * this operation.
+ *
+ * @remark Usage is a bit ugly but saves a few lines of duplicated code
+ * somewhere else and makes it possible to keep the S/G buffer members
+ * private without going through RTSgBufSegArrayCreate() first.
+ */
+#define RTSgBufMapToNative(paMapped, pSgBuf, Struct, pvBufField, TypeBufPtr, cbBufField, TypeBufSize, cSegsMapped) \
+ do \
+ { \
+ AssertCompileMemberSize(Struct, pvBufField, RT_SIZEOFMEMB(RTSGSEG, pvSeg)); \
+ /*AssertCompile(RT_SIZEOFMEMB(Struct, cbBufField) >= RT_SIZEOFMEMB(RTSGSEG, cbSeg));*/ \
+ (cSegsMapped) = (pSgBuf)->cSegs - (pSgBuf)->idxSeg; \
+ \
+ /* We need room for at least one segment. */ \
+ if ((pSgBuf)->cSegs == (pSgBuf)->idxSeg) \
+ (cSegsMapped)++; \
+ \
+ (paMapped) = (Struct *)RTMemTmpAllocZ((cSegsMapped) * sizeof(Struct)); \
+ if ((paMapped)) \
+ { \
+ /* The first buffer is special because we could be in the middle of a segment. */ \
+ (paMapped)[0].pvBufField = (TypeBufPtr)(pSgBuf)->pvSegCur; \
+ (paMapped)[0].cbBufField = (TypeBufSize)(pSgBuf)->cbSegLeft; \
+ \
+ for (unsigned i = 1; i < (cSegsMapped); i++) \
+ { \
+ (paMapped)[i].pvBufField = (TypeBufPtr)(pSgBuf)->paSegs[(pSgBuf)->idxSeg + i].pvSeg; \
+ (paMapped)[i].cbBufField = (TypeBufSize)(pSgBuf)->paSegs[(pSgBuf)->idxSeg + i].cbSeg; \
+ } \
+ } \
+ } while (0)
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/sha.h b/include/iprt/sha.h
new file mode 100644
index 00000000..046ca813
--- /dev/null
+++ b/include/iprt/sha.h
@@ -0,0 +1,302 @@
+/** @file
+ * IPRT - SHA1 digest creation
+ */
+
+/*
+ * 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 ___iprt_sha_h
+#define ___iprt_sha_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_sha RTSha - SHA Family of Hash Functions
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** The size of a SHA-1 hash. */
+#define RTSHA1_HASH_SIZE 20
+/** The length of a SHA-1 digest string. The terminator is not included. */
+#define RTSHA1_DIGEST_LEN 40
+
+/**
+ * SHA-1 context.
+ */
+typedef union RTSHA1CONTEXT
+{
+ uint8_t abPadding[ARCH_BITS == 32 ? 96 : 128];
+#ifdef RT_SHA1_PRIVATE_CONTEXT
+ SHA_CTX Private;
+#endif
+} RTSHA1CONTEXT;
+/** Pointer to an SHA-1 context. */
+typedef RTSHA1CONTEXT *PRTSHA1CONTEXT;
+
+/**
+ * Compute the SHA-1 hash of the data.
+ *
+ * @param pvBuf Pointer to the data.
+ * @param cbBuf The amount of data (in bytes).
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(void) RTSha1(const void *pvBuf, size_t cbBuf, uint8_t pabDigest[RTSHA1_HASH_SIZE]);
+
+/**
+ * Initializes the SHA-1 context.
+ *
+ * @param pCtx Pointer to the SHA-1 context.
+ */
+RTDECL(void) RTSha1Init(PRTSHA1CONTEXT pCtx);
+
+/**
+ * Feed data into the SHA-1 computation.
+ *
+ * @param pCtx Pointer to the SHA-1 context.
+ * @param pvBuf Pointer to the data.
+ * @param cbBuf The length of the data (in bytes).
+ */
+RTDECL(void) RTSha1Update(PRTSHA1CONTEXT pCtx, const void *pvBuf, size_t cbBuf);
+
+/**
+ * Compute the SHA-1 hash of the data.
+ *
+ * @param pCtx Pointer to the SHA-1 context.
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(void) RTSha1Final(PRTSHA1CONTEXT pCtx, uint8_t pabDigest[RTSHA1_HASH_SIZE]);
+
+/**
+ * Converts a SHA-1 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pabDigest The binary digest returned by RTSha1Final or RTSha1.
+ * @param pszDigest Where to return the stringified digest.
+ * @param cchDigest The size of the output buffer. Should be at least
+ * RTSHA1_DIGEST_LEN + 1 bytes.
+ */
+RTDECL(int) RTSha1ToString(uint8_t const pabDigest[RTSHA1_HASH_SIZE], char *pszDigest, size_t cchDigest);
+
+/**
+ * Converts a SHA-1 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszDigest The stringified digest. Leading and trailing spaces are
+ * ignored.
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(int) RTSha1FromString(char const *pszDigest, uint8_t pabDigest[RTSHA1_HASH_SIZE]);
+
+/**
+ * Creates a SHA1 digest for the given memory buffer.
+ *
+ * @returns iprt status code.
+ *
+ * @param pvBuf Memory buffer to create a SHA1 digest for.
+ * @param cbBuf The amount of data (in bytes).
+ * @param ppszDigest On success the SHA1 digest.
+ * @param pfnProgressCallback optional callback for the progress indication
+ * @param pvUser user defined pointer for the callback
+ */
+RTR3DECL(int) RTSha1Digest(void* pvBuf, size_t cbBuf, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+/**
+ * Creates a SHA1 digest for the given file.
+ *
+ * @returns iprt status code.
+ *
+ * @param pszFile Filename to create a SHA1 digest for.
+ * @param ppszDigest On success the SHA1 digest.
+ * @param pfnProgressCallback optional callback for the progress indication
+ * @param pvUser user defined pointer for the callback
+ */
+RTR3DECL(int) RTSha1DigestFromFile(const char *pszFile, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+
+/** The size of a SHA-256 hash. */
+#define RTSHA256_HASH_SIZE 32
+/** The length of a SHA-256 digest string. The terminator is not included. */
+#define RTSHA256_DIGEST_LEN 64
+
+/**
+ * SHA-256 context.
+ */
+typedef union RTSHA256CONTEXT
+{
+ uint8_t abPadding[ARCH_BITS == 32 ? 112 : 160];
+#ifdef RT_SHA256_PRIVATE_CONTEXT
+ SHA256_CTX Private;
+#endif
+} RTSHA256CONTEXT;
+/** Pointer to an SHA-256 context. */
+typedef RTSHA256CONTEXT *PRTSHA256CONTEXT;
+
+/**
+ * Compute the SHA-256 hash of the data.
+ *
+ * @param pvBuf Pointer to the data.
+ * @param cbBuf The amount of data (in bytes).
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(void) RTSha256(const void *pvBuf, size_t cbBuf, uint8_t pabDigest[RTSHA256_HASH_SIZE]);
+
+/**
+ * Initializes the SHA-256 context.
+ *
+ * @param pCtx Pointer to the SHA-256 context.
+ */
+RTDECL(void) RTSha256Init(PRTSHA256CONTEXT pCtx);
+
+/**
+ * Feed data into the SHA-256 computation.
+ *
+ * @param pCtx Pointer to the SHA-256 context.
+ * @param pvBuf Pointer to the data.
+ * @param cbBuf The length of the data (in bytes).
+ */
+RTDECL(void) RTSha256Update(PRTSHA256CONTEXT pCtx, const void *pvBuf, size_t cbBuf);
+
+/**
+ * Compute the SHA-256 hash of the data.
+ *
+ * @param pCtx Pointer to the SHA-256 context.
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(void) RTSha256Final(PRTSHA256CONTEXT pCtx, uint8_t pabDigest[RTSHA256_HASH_SIZE]);
+
+/**
+ * Converts a SHA-256 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pabDigest The binary digest returned by RTSha256Final or RTSha256.
+ * @param pszDigest Where to return the stringified digest.
+ * @param cchDigest The size of the output buffer. Should be at least
+ * RTSHA256_DIGEST_LEN + 1 bytes.
+ */
+RTDECL(int) RTSha256ToString(uint8_t const pabDigest[RTSHA256_HASH_SIZE], char *pszDigest, size_t cchDigest);
+
+/**
+ * Converts a SHA-256 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszDigest The stringified digest. Leading and trailing spaces are
+ * ignored.
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(int) RTSha256FromString(char const *pszDigest, uint8_t pabDigest[RTSHA256_HASH_SIZE]);
+
+
+
+/** The size of a SHA-512 hash. */
+#define RTSHA512_HASH_SIZE 64
+/** The length of a SHA-512 digest string. The terminator is not included. */
+#define RTSHA512_DIGEST_LEN 128
+
+/**
+ * SHA-512 context.
+ */
+typedef union RTSHA512CONTEXT
+{
+ uint8_t abPadding[ARCH_BITS == 32 ? 216 : 256];
+#ifdef RT_SHA512_PRIVATE_CONTEXT
+ SHA512_CTX Private;
+#endif
+} RTSHA512CONTEXT;
+/** Pointer to an SHA-512 context. */
+typedef RTSHA512CONTEXT *PRTSHA512CONTEXT;
+
+/**
+ * Compute the SHA-512 hash of the data.
+ *
+ * @param pvBuf Pointer to the data.
+ * @param cbBuf The amount of data (in bytes).
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(void) RTSha512(const void *pvBuf, size_t cbBuf, uint8_t pabDigest[RTSHA512_HASH_SIZE]);
+
+/**
+ * Initializes the SHA-512 context.
+ *
+ * @param pCtx Pointer to the SHA-512 context.
+ */
+RTDECL(void) RTSha512Init(PRTSHA512CONTEXT pCtx);
+
+/**
+ * Feed data into the SHA-512 computation.
+ *
+ * @param pCtx Pointer to the SHA-512 context.
+ * @param pvBuf Pointer to the data.
+ * @param cbBuf The length of the data (in bytes).
+ */
+RTDECL(void) RTSha512Update(PRTSHA512CONTEXT pCtx, const void *pvBuf, size_t cbBuf);
+
+/**
+ * Compute the SHA-512 hash of the data.
+ *
+ * @param pCtx Pointer to the SHA-512 context.
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(void) RTSha512Final(PRTSHA512CONTEXT pCtx, uint8_t pabDigest[RTSHA512_HASH_SIZE]);
+
+/**
+ * Converts a SHA-512 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pabDigest The binary digest returned by RTSha512Final or RTSha512.
+ * @param pszDigest Where to return the stringified digest.
+ * @param cchDigest The size of the output buffer. Should be at least
+ * RTSHA512_DIGEST_LEN + 1 bytes.
+ */
+RTDECL(int) RTSha512ToString(uint8_t const pabDigest[RTSHA512_HASH_SIZE], char *pszDigest, size_t cchDigest);
+
+/**
+ * Converts a SHA-512 hash to a digest string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszDigest The stringified digest. Leading and trailing spaces are
+ * ignored.
+ * @param pabDigest Where to store the hash. (What is passed is a pointer to
+ * the caller's buffer.)
+ */
+RTDECL(int) RTSha512FromString(char const *pszDigest, uint8_t pabDigest[RTSHA512_HASH_SIZE]);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* ___iprt_sha1_h */
+
diff --git a/include/iprt/socket.h b/include/iprt/socket.h
new file mode 100644
index 00000000..0b577c5b
--- /dev/null
+++ b/include/iprt/socket.h
@@ -0,0 +1,399 @@
+/** @file
+ * IPRT - Network Sockets.
+ */
+
+/*
+ * 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 ___iprt_socket_h
+#define ___iprt_socket_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/thread.h>
+#include <iprt/net.h>
+#include <iprt/sg.h>
+
+#ifdef IN_RING0
+# error "There are no RTSocket APIs available Ring-0 Host Context!"
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_tcp RTSocket - Network Sockets
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Retains a reference to the socket handle.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ *
+ * @param hSocket The socket handle.
+ */
+RTDECL(uint32_t) RTSocketRetain(RTSOCKET hSocket);
+
+/**
+ * Release a reference to the socket handle.
+ *
+ * When the reference count reaches zero, the socket handle is shut down and
+ * destroyed. This will not be graceful shutdown, use the protocol specific
+ * close method if this is desired.
+ *
+ * @returns New reference count, UINT32_MAX on invalid handle (asserted).
+ *
+ * @param hSocket The socket handle. The NIL handle is quietly
+ * ignored and 0 is returned.
+ */
+RTDECL(uint32_t) RTSocketRelease(RTSOCKET hSocket);
+
+/**
+ * Shuts down the socket, close it and then release one handle reference.
+ *
+ * This is slightly different from RTSocketRelease which will first do the
+ * shutting down and closing when the reference count reaches zero.
+ *
+ * @returns IPRT status code.
+ * @param hSocket The socket handle. NIL is ignored.
+ *
+ * @remarks This will not perform a graceful shutdown of the socket, it will
+ * just destroy it. Use the protocol specific close method if this is
+ * desired.
+ */
+RTDECL(int) RTSocketClose(RTSOCKET hSocket);
+
+/**
+ * Creates an IPRT socket handle from a native one.
+ *
+ * Do NOT use the native handle after passing it to this function, IPRT owns it
+ * and might even have closed upon a successful return.
+ *
+ * @returns IPRT status code.
+ * @param phSocket Where to store the IPRT socket handle.
+ * @param uNative The native handle.
+ */
+RTDECL(int) RTSocketFromNative(PRTSOCKET phSocket, RTHCINTPTR uNative);
+
+/**
+ * Gets the native socket handle.
+ *
+ * @returns The native socket handle or RTHCUINTPTR_MAX if not invalid.
+ * @param hSocket The socket handle.
+ */
+RTDECL(RTHCUINTPTR) RTSocketToNative(RTSOCKET hSocket);
+
+/**
+ * Helper that ensures the correct inheritability of a socket.
+ *
+ * We're currently ignoring failures.
+ *
+ * @returns IPRT status code
+ * @param hSocket The socket handle.
+ * @param fInheritable The desired inheritability state.
+ */
+RTDECL(int) RTSocketSetInheritance(RTSOCKET hSocket, bool fInheritable);
+
+/**
+ * Parse Internet style addresses, getting a generic IPRT network address.
+ *
+ * @returns IPRT status code
+ * @param pszAddress Name or IP address. NULL or empty string (no
+ * spaces) is taken to mean INADDR_ANY, which is
+ * meaningful when binding a server socket for
+ * instance.
+ * @param uPort Port number (host byte order).
+ * @param pAddr Where to return the generic IPRT network address.
+ */
+RTDECL(int) RTSocketParseInetAddress(const char *pszAddress, unsigned uPort, PRTNETADDR pAddr);
+
+/**
+ * Try resolve a host name, returning the first matching address.
+ *
+ * @returns IPRT status code.
+ * @param pszHost Name or IP address to look up.
+ * @param pszAddress Where to return the stringified address.
+ * @param pcbAddress Input: The size of the @a pszResult buffer.
+ * Output: size of the returned string. This is set on
+ * VERR_BUFFER_OVERFLOW and most other error statuses.
+ * @param penmAddrType Input: Which kind of address to return. Valid values
+ * are:
+ * - RTNETADDRTYPE_IPV4 -> lookup AF_INET.
+ * - RTNETADDRTYPE_IPV6 -> lookup AF_INET6.
+ * - RTNETADDRTYPE_INVALID/NULL -> lookup anything.
+ * Output: The type of address that is being returned.
+ * Not modified on failure.
+ */
+RTDECL(int) RTSocketQueryAddressStr(const char *pszHost, char *pszAddress, size_t *pcbAddress, PRTNETADDRTYPE penmAddrType);
+
+/**
+ * Receive data from a socket.
+ *
+ * @returns IPRT status code.
+ * @param hSocket The socket handle.
+ * @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.
+ */
+RTDECL(int) RTSocketRead(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead);
+
+/**
+ * Receive data from a socket, including sender address. Mainly useful
+ * for datagram sockets.
+ *
+ * @returns IPRT status code.
+ * @param hSocket The socket handle.
+ * @param pvBuffer Where to put the data we read.
+ * @param cbBuffer Read buffer size.
+ * @param pcbRead Number of bytes read. Must be non-NULL.
+ * @param pSrcAddr Pointer to sender address buffer. May be NULL.
+ */
+RTDECL(int) RTSocketReadFrom(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr);
+
+/**
+ * Send data to a socket.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param hSocket The socket handle.
+ * @param pvBuffer Buffer to write data to socket.
+ * @param cbBuffer How much to write.
+ */
+RTDECL(int) RTSocketWrite(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer);
+
+/**
+ * Send data to a socket, including destination address. Mainly useful
+ * for datagram sockets.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param hSocket The socket handle.
+ * @param pvBuffer Buffer to write data to socket.
+ * @param cbBuffer How much to write.
+ * @param pDstAddr Pointer to destination address. May be NULL.
+ */
+RTDECL(int) RTSocketWriteTo(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, PCRTNETADDR pDstAddr);
+
+/**
+ * Checks if the socket is ready for reading (for I/O multiplexing).
+ *
+ * @returns IPRT status code.
+ * @param hSocket The socket handle.
+ * @param cMillies Number of milliseconds to wait for the socket. Use
+ * RT_INDEFINITE_WAIT to wait for ever.
+ */
+RTDECL(int) RTSocketSelectOne(RTSOCKET hSocket, RTMSINTERVAL cMillies);
+
+/** @name Select events
+ * @{ */
+/** Readable without blocking. */
+#define RTSOCKET_EVT_READ RT_BIT_32(0)
+/** Writable without blocking. */
+#define RTSOCKET_EVT_WRITE RT_BIT_32(1)
+/** Error condition, hangup, exception or similar. */
+#define RTSOCKET_EVT_ERROR RT_BIT_32(2)
+/** Mask of the valid bits. */
+#define RTSOCKET_EVT_VALID_MASK UINT32_C(0x00000007)
+/** @} */
+
+/**
+ * Socket I/O multiplexing
+ * Checks if the socket is ready for one of the given events.
+ *
+ * @returns iprt status code.
+ * @param Sock Socket descriptor.
+ * @param fEvents Event mask to wait for.
+ * @param pfEvents Where to store the event mask on return.
+ * @param cMillies Number of milliseconds to wait for the socket.
+ * Use RT_INDEFINITE_WAIT to wait for ever.
+ */
+RTR3DECL(int) RTSocketSelectOneEx(RTSOCKET Sock, uint32_t fEvents, uint32_t *pfEvents,
+ RTMSINTERVAL cMillies);
+
+/**
+ * Shuts down one or both directions of communciation.
+ *
+ * @returns IPRT status code.
+ * @param hSocket The socket handle.
+ * @param fRead Whether to shutdown our read direction.
+ * @param fWrite Whether to shutdown our write direction.
+ */
+RTDECL(int) RTSocketShutdown(RTSOCKET hSocket, bool fRead, bool fWrite);
+
+/**
+ * Gets the address of the local side.
+ *
+ * @returns IPRT status code.
+ * @param Sock Socket descriptor.
+ * @param pAddr Where to store the local address on success.
+ */
+RTDECL(int) RTSocketGetLocalAddress(RTSOCKET hSocket, PRTNETADDR pAddr);
+
+/**
+ * Gets the address of the other party.
+ *
+ * @returns IPRT status code.
+ * @param Sock Socket descriptor.
+ * @param pAddr Where to store the peer address on success.
+ */
+RTDECL(int) RTSocketGetPeerAddress(RTSOCKET hSocket, PRTNETADDR pAddr);
+
+/**
+ * Send data from a scatter/gather buffer to a socket.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param hSocket The socket handle.
+ * @param pSgBuf Scatter/gather buffer to write data to socket.
+ */
+RTDECL(int) RTSocketSgWrite(RTSOCKET hSocket, PCRTSGBUF pSgBuf);
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * ellipsis.
+ * @param ... Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTDECL(int) RTSocketSgWriteL(RTSOCKET hSocket, size_t cSegs, ...);
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * argument list.
+ * @param va Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTDECL(int) RTSocketSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va);
+
+/**
+ * Receive data from a socket.
+ *
+ * This version doesn't block if there is no data on the socket.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSocket The socket handle.
+ * @param pvBuffer Where to put the data we read.
+ * @param cbBuffer Read buffer size.
+ * @param pcbRead Number of bytes read.
+ */
+RTDECL(int) RTSocketReadNB(RTSOCKET hSocket, void *pvBuffer, size_t cbBuffer, size_t *pcbRead);
+
+/**
+ * Send data to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSocket The socket handle.
+ * @param pvBuffer Buffer to write data to socket.
+ * @param cbBuffer How much to write.
+ * @param pcbWritten Number of bytes written.
+ */
+RTDECL(int) RTSocketWriteNB(RTSOCKET hSocket, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten);
+
+/**
+ * Send data from a scatter/gather buffer to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ *
+ * @returns iprt status code.
+ *
+ * @param Sock Socket descriptor.
+ * @param pSgBuf Scatter/gather buffer to write data to socket.
+ * @param pcbWritten Number of bytes written.
+ */
+RTR3DECL(int) RTSocketSgWriteNB(RTSOCKET Sock, PCRTSGBUF pSgBuf, size_t *pcbWritten);
+
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * ellipsis.
+ * @param pcbWritten Number of bytes written.
+ * @param ... Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTR3DECL(int) RTSocketSgWriteLNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, ...);
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * argument list.
+ * @param pcbWritten Number of bytes written.
+ * @param va Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTR3DECL(int) RTSocketSgWriteLVNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, va_list va);
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/solaris/kmoddeps.mac b/include/iprt/solaris/kmoddeps.mac
new file mode 100644
index 00000000..6b8a4003
--- /dev/null
+++ b/include/iprt/solaris/kmoddeps.mac
@@ -0,0 +1,183 @@
+; $Id: kmoddeps.mac $
+;; @file
+; Assembly macros for generating Solaris kernel module dependencies
+;
+
+;
+; 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.
+;
+
+; Solaris kernel modules use non-standard ELF constructions to express inter-
+; module dependencies, namely a DT_NEEDED tag inside a relocatable ELF file.
+; The Solaris linker can generate these automatically; since yasm can't
+; produce an ELF file which quite fits Solaris's requirements we create one
+; manually using flat binary output format. In order to save unnecessary
+; repetition, this file defines macros for the repetitive bits which can be
+; reused by the actual dependency objects. Certainly not the nicest way to
+; get the effect we want, but probably a reasonable compromise between
+; cleanness and required effort.
+;
+
+%ifdef RT_ARCH_AMD64
+
+BITS 64
+;;
+; Native word size
+%define DNAT dq
+
+;;
+; ELF machine number for the current architecture.
+%define EM_CUR 62 ; EM_X86_64
+
+;;
+; ELF header class for the current architecture.
+%define CLASS 2
+
+%else
+
+BITS 32
+%define DNAT dd
+%define EM_CUR 3 ; EM_386
+%define CLASS 1
+
+%endif
+
+;;
+; ELF file header, section tables and shared string table for the dependency
+; object.
+%macro kmoddeps_header 0
+elf_hdr: ; elfxx_hdr structure
+ db 7fh, "ELF" ; e_ident
+ db CLASS, 1, 1 ; e_ident
+ times 9 db 0 ; padding
+ dw 1 ; e_type ET_REL
+ dw EM_CUR ; e_machine
+ dd 1 ; e_version EV_CURRENT
+ DNAT 0 ; e_entry
+ DNAT 0 ; e_phoff
+ DNAT sect_hdr - $$ ; e_shoff
+ dd 0 ; e_flags
+ dw elf_hsize ; e_ehsize
+ dw 0 ; e_phentsize
+ dw 0 ; e_phnum
+ dw sect_hsize ; e_shentsize
+ dw 4 ; e_shnum
+ dw 1 ; e_shstrndx section .shstrtab
+elf_hsize equ $ - elf_hdr
+
+sect_hdr: ; elfxx_shdr structure
+ times sect_hsize db 0 ; undefined section
+
+sect_hdr1:
+ dd str_shstrtab ; sh_name .shstrtab
+ dd 3 ; sh_type SHT_STRTAB
+ DNAT 20h ; sh_flags SHF_STRINGS
+ DNAT 0 ; sh_addr
+ DNAT shstrtab - $$ ; sh_offset
+ DNAT shstrtab_size ; sh_size
+ dd 0 ; sh_link
+ dd 0 ; sh_info
+ DNAT 1 ; sh_addralign
+ DNAT 0 ; sh_entsize
+sect_hsize equ $ - sect_hdr1
+
+ dd str_dynstr ; sh_name .dynstr
+ dd 3 ; sh_type SHT_STRTAB
+ DNAT 20h ; sh_flags SHF_STRINGS
+ DNAT 0 ; sh_addr
+ DNAT dynstr - $$ ; sh_offset
+ DNAT dynstr_size ; sh_size
+ dd 0 ; sh_link
+ dd 0 ; sh_info
+ DNAT 1 ; sh_addralign
+ DNAT 0 ; sh_entsize
+
+ dd str_dynamic ; sh_name .dynamic
+ dd 6 ; sh_type SHT_DYNAMIC
+ DNAT 1 ; sh_flags SHF_WRITE
+ DNAT 0 ; sh_addr
+ DNAT dynamic - $$ ; sh_offset
+ DNAT dynamic_size ; sh_size
+ dd 2 ; sh_link .dynstr
+ dd 0 ; sh_info
+ DNAT 8 ; sh_addralign
+ DNAT 0 ; sh_entsize
+
+shstrtab:
+str_shstrtab equ $ - shstrtab
+ db ".shstrtab", 0
+str_dynstr equ $ - shstrtab
+ db ".dynstr", 0
+str_dynamic equ $ - shstrtab
+ db ".dynamic", 0
+shstrtab_size equ $ - shstrtab
+%endmacro ; kmoddeps_header
+
+;;
+; Start of the .dynstr section for the dependency object.
+%macro kmoddeps_dynstr_start 0
+dynstr:
+ db 0
+%endmacro
+
+;;
+; A .dynstr string entry for the dependency object.
+; The parameters are a symbolic name for the string and the string itself.
+%macro kmoddeps_dynstr_string 2
+dynstr_name_%1 equ $ - dynstr
+ db %2, 0
+%endmacro
+
+;;
+; End of the .dynstr section for the dependency object.
+%macro kmoddeps_dynstr_end 0
+dynstr_size equ $ - dynstr
+%endmacro
+
+;;
+; Start of the .dynamic section for the dependency object.
+%macro kmoddeps_dynamic_start 0
+dynamic:
+%endmacro
+
+;;
+; A .dynamic DT_NEEDED entry for the dependency object.
+; The parameter is a symbolic string name previously defined using
+; @a kmoddeps_dynstr_string.
+%macro kmoddeps_dynamic_needed 1
+ DNAT 1 ; DT_NEEDED
+ DNAT dynstr_name_%1
+%endmacro
+
+;;
+; End of the .dynamic section for the dependency object.
+%macro kmoddeps_dynamic_end 0
+ DNAT 1ah ; DT_FLAGS
+ DNAT 4 ; TEXTREL
+ DNAT 6ffffffbh ; DT_FLAGS1
+ DNAT 0
+ DNAT 601900h ; SUNW_STRPAD
+ DNAT 200h
+ DNAT 601b00h ; SUNW_LDMACH
+ DNAT 62 ; EM_X86_64
+ times 22 DNAT 0 ; padding
+dynamic_size equ $ - dynamic
+%endmacro ; kmoddeps_dynamic_end
+
diff --git a/include/iprt/sort.h b/include/iprt/sort.h
new file mode 100644
index 00000000..dd4e93e5
--- /dev/null
+++ b/include/iprt/sort.h
@@ -0,0 +1,128 @@
+/** @file
+ * IPRT - Sorting.
+ */
+
+/*
+ * 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 ___iprt_sort_h
+#define ___iprt_sort_h
+
+#include <iprt/types.h>
+
+/** @defgroup grp_rt_sort RTSort - Sorting Algorithms
+ * @ingroup grp_rt
+ * @{ */
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Callback for comparing two array elements.
+ *
+ * @retval 0 if equal.
+ * @retval -1 if @a pvElement1 comes before @a pvElement2.
+ * @retval 1 if @a pvElement1 comes after @a pvElement2.
+ *
+ * @param pvElement1 The 1st element.
+ * @param pvElement2 The 2nd element.
+ * @param pvUser The user argument passed to the sorting function.
+ */
+typedef DECLCALLBACK(int) FNRTSORTCMP(void const *pvElement1, void const *pvElement2, void *pvUser);
+/** Pointer to a compare function. */
+typedef FNRTSORTCMP *PFNRTSORTCMP;
+
+/**
+ * Sorter function for an array of variable sized elementes.
+ *
+ * @param papvArray The array to sort.
+ * @param cElements The number of elements in the array.
+ * @param cbElements The size of an array element.
+ * @param pfnCmp Callback function comparing two elements.
+ * @param pvUser User argument for the callback.
+ */
+typedef DECLCALLBACK(void) FNRTSORT(void *pvArray, size_t cElements, size_t cbElement, PFNRTSORTCMP pfnCmp, void *pvUser);
+/** Pointer to a sorter function for an array of variable sized elements. */
+typedef FNRTSORT *PFNRTSORT;
+
+/**
+ * Pointer array sorter function.
+ *
+ * @param papvArray The array to sort.
+ * @param cElements The number of elements in the array.
+ * @param pfnCmp Callback function comparing two elements.
+ * @param pvUser User argument for the callback.
+ */
+typedef DECLCALLBACK(void) FNRTSORTAPV(void **papvArray, size_t cElements, PFNRTSORTCMP pfnCmp, void *pvUser);
+/** Pointer to a pointer array sorter function. */
+typedef FNRTSORTAPV *PFNRTSORTAPV;
+
+/**
+ * Shell sort an array of variable sized elementes.
+ *
+ * @param papvArray The array to sort.
+ * @param cElements The number of elements in the array.
+ * @param cbElements The size of an array element.
+ * @param pfnCmp Callback function comparing two elements.
+ * @param pvUser User argument for the callback.
+ */
+RTDECL(void) RTSortShell(void *pvArray, size_t cElements, size_t cbElement, PFNRTSORTCMP pfnCmp, void *pvUser);
+
+/**
+ * Same as RTSortShell but speciallized for an array containing element
+ * pointers.
+ *
+ * @param papvArray The array to sort.
+ * @param cElements The number of elements in the array.
+ * @param pfnCmp Callback function comparing two elements.
+ * @param pvUser User argument for the callback.
+ */
+RTDECL(void) RTSortApvShell(void **papvArray, size_t cElements, PFNRTSORTCMP pfnCmp, void *pvUser);
+
+/**
+ * Checks if an array of variable sized elementes is sorted.
+ *
+ * @returns true if it is sorted, false if it isn't.
+ * @param papvArray The array to check.
+ * @param cElements The number of elements in the array.
+ * @param cbElements The size of an array element.
+ * @param pfnCmp Callback function comparing two elements.
+ * @param pvUser User argument for the callback.
+ */
+RTDECL(bool) RTSortIsSorted(void const *pvArray, size_t cElements, size_t cbElement, PFNRTSORTCMP pfnCmp, void *pvUser);
+
+/**
+ * Same as RTSortShell but speciallized for an array containing element
+ * pointers.
+ *
+ * @returns true if it is sorted, false if it isn't.
+ * @param papvArray The array to check.
+ * @param cElements The number of elements in the array.
+ * @param pfnCmp Callback function comparing two elements.
+ * @param pvUser User argument for the callback.
+ */
+RTDECL(bool) RTSortApvIsSorted(void const * const *papvArray, size_t cElements, PFNRTSORTCMP pfnCmp, void *pvUser);
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/spinlock.h b/include/iprt/spinlock.h
new file mode 100644
index 00000000..2c36a0fd
--- /dev/null
+++ b/include/iprt/spinlock.h
@@ -0,0 +1,97 @@
+/** @file
+ * IPRT - Spinlocks.
+ */
+
+/*
+ * 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 ___iprt_spinlock_h
+#define ___iprt_spinlock_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+
+/** @defgroup grp_rt_spinlock RTSpinlock - Spinlocks
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Creates a spinlock.
+ *
+ * @returns iprt status code.
+ * @param pSpinlock Where to store the spinlock handle.
+ * @param fFlags Creation flags, see RTSPINLOCK_FLAGS_XXX.
+ * @param pszName Spinlock name, for debugging purposes. String lifetime
+ * must be the same as the lock as it won't be copied.
+ */
+RTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName);
+
+/** @name RTSPINLOCK_FLAGS_XXX
+ * @{ */
+/** Disable interrupts when taking the spinlock, making it interrupt safe
+ * (sans NMI of course).
+ *
+ * This is generally the safest option, though it isn't really required unless
+ * the data being protect is also accessed from interrupt handler context. */
+#define RTSPINLOCK_FLAGS_INTERRUPT_SAFE RT_BIT(1)
+/** No need to disable interrupts, the protect code/data is not used by
+ * interrupt handlers. */
+#define RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE RT_BIT(2)
+/** @} */
+
+/**
+ * Destroys a spinlock created by RTSpinlockCreate().
+ *
+ * @returns iprt status code.
+ * @param Spinlock Spinlock returned by RTSpinlockCreate().
+ */
+RTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock);
+
+/**
+ * Acquires the spinlock.
+ *
+ * @param Spinlock The spinlock to acquire.
+ * @param pTmp Where to save the state.
+ */
+RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock);
+
+/**
+ * Releases the spinlock.
+ *
+ * @param Spinlock The spinlock to acquire.
+ * @param pTmp The state to restore. (This better be the same as for the RTSpinlockAcquire() call!)
+ */
+RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock);
+
+/* Temporarily, only for checking the spinlock creation flags. */
+RTDECL(void) RTSpinlockReleaseNoInts(RTSPINLOCK Spinlock);
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/stdarg.h b/include/iprt/stdarg.h
new file mode 100644
index 00000000..4b93fb01
--- /dev/null
+++ b/include/iprt/stdarg.h
@@ -0,0 +1,54 @@
+/** @file
+ * IPRT - stdarg.h wrapper.
+ */
+
+/*
+ * 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 ___iprt_stdarg_h
+#define ___iprt_stdarg_h
+
+#ifdef IPRT_NO_CRT
+# include <iprt/types.h>
+# include <iprt/nocrt/compiler/compiler.h>
+#else
+# include <iprt/cdefs.h>
+# if defined(RT_OS_FREEBSD) && defined(_KERNEL)
+# include <machine/stdarg.h>
+# elif defined(RT_OS_SOLARIS) && defined(_KERNEL) && defined(__GNUC__)
+# include <stdarg.h>
+# if __GNUC__ >= 4 /* System headers refers to __builtin_stdarg_start. */
+# define __builtin_stdarg_start __builtin_va_start
+# endif
+# else
+# include <stdarg.h>
+# endif
+#endif
+
+/*
+ * MSC doesn't implement va_copy.
+ */
+#ifndef va_copy
+# define va_copy(dst, src) do { (dst) = (src); } while (0) /** @todo check AMD64 */
+#endif
+
+#endif
+
diff --git a/include/iprt/stdint.h b/include/iprt/stdint.h
new file mode 100644
index 00000000..59c2d726
--- /dev/null
+++ b/include/iprt/stdint.h
@@ -0,0 +1,244 @@
+/** @file
+ * IPRT - stdint.h wrapper (for backlevel compilers like MSC).
+ */
+
+/*
+ * 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 __iprt_stdint_h
+#define __iprt_stdint_h
+
+#include <iprt/cdefs.h>
+
+
+/*
+ * Use the stdint.h on systems that have one.
+ */
+#if !(defined(RT_OS_LINUX) && defined(__KERNEL__)) \
+ && !(defined(RT_OS_FREEBSD) && defined(_KERNEL)) \
+ && !defined(_MSC_VER) \
+ && !defined(__IBMC__) \
+ && !defined(__IBMCPP__) \
+ && !defined(IPRT_NO_CRT) \
+ && !defined(IPRT_DONT_USE_SYSTEM_STDINT_H) \
+ && !defined(DOXYGEN_RUNNING)
+
+# ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS
+# endif
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS
+# endif
+# include <stdint.h>
+
+# if defined(RT_OS_DARWIN) && defined(KERNEL) && defined(RT_ARCH_AMD64)
+ /*
+ * Kludge to fix the incorrect 32-bit constant macros in
+ * Kernel.framework/Headers/stdin.h. uint32_t and int32_t are
+ * int not long as these macros use, which is significant when
+ * targeting AMD64. (10a222)
+ */
+# undef INT32_C
+# define INT32_C(Value) (Value)
+# undef UINT32_C
+# define UINT32_C(Value) (Value ## U)
+# endif /* 64-bit darwin kludge. */
+
+#elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+
+# ifndef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS
+# endif
+# ifndef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS
+# endif
+# include <sys/stdint.h>
+
+#else /* No system stdint.h */
+
+/*
+ * Define the types we use.
+ * The linux kernel defines all these in linux/types.h, so skip it.
+ */
+# if !(defined(RT_OS_LINUX) && defined(__KERNEL__)) \
+ || defined(IPRT_NO_CRT) \
+ || defined(IPRT_DONT_USE_SYSTEM_STDINT_H) \
+ || defined(DOXGEN_RUNNING)
+
+ /* Simplify the [u]int64_t type detection mess. */
+# undef IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES
+# ifdef __IBMCPP__
+# if __IBMCPP__ < 350 && (defined(__WINDOWS__) || defined(_AIX) || defined(__OS2__))
+# defined IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES
+# endif
+# endif
+# ifdef __IBMC__
+# if __IBMC__ < 350 && (defined(__WINDOWS__) || defined(_AIX) || defined(__OS2__))
+# defined IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES
+# endif
+# endif
+
+ /* x-bit types */
+# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86) || defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+# if !defined(_INT8_T_DECLARED) && !defined(_INT8_T)
+typedef signed char int8_t;
+# endif
+# if !defined(_UINT8_T_DECLARED) && !defined(_UINT8_T)
+typedef unsigned char uint8_t;
+# endif
+# if !defined(_INT16_T_DECLARED) && !defined(_INT16_T)
+typedef signed short int16_t;
+# endif
+# if !defined(_UINT16_T_DECLARED) && !defined(_UINT16_T)
+typedef unsigned short uint16_t;
+# endif
+# if !defined(_INT32_T_DECLARED) && !defined(_INT32_T)
+typedef signed int int32_t;
+# endif
+# if !defined(_UINT32_T_DECLARED) && !defined(_UINT32_T)
+typedef unsigned int uint32_t;
+# endif
+# if defined(_MSC_VER)
+# if !defined(_INT64_T_DECLARED) && !defined(_INT64_T)
+typedef signed _int64 int64_t;
+# endif
+# if !defined(_UINT64_T_DECLARED) && !defined(_UINT64_T)
+typedef unsigned _int64 uint64_t;
+# endif
+# elif defined(IPRT_STDINT_USE_STRUCT_FOR_64_BIT_TYPES)
+# if !defined(_INT64_T_DECLARED) && !defined(_INT64_T)
+typedef struct { uint32_t lo; int32_t hi; } int64_t;
+# endif
+# if !defined(_UINT64_T_DECLARED) && !defined(_UINT64_T)
+typedef struct { uint32_t lo; uint32_t hi; } uint64_t;
+# endif
+# else /* Use long long for 64-bit types */
+# if !defined(_INT64_T_DECLARED) && !defined(_INT64_T)
+typedef signed long long int64_t;
+# endif
+# if !defined(_UINT64_T_DECLARED) && !defined(_UINT64_T)
+typedef unsigned long long uint64_t;
+# endif
+# endif
+
+ /* max integer types */
+# if !defined(_INTMAX_T_DECLARED) && !defined(_INTMAX_T)
+typedef int64_t intmax_t;
+# endif
+# if !defined(_UINTMAX_T_DECLARED) && !defined(_UINTMAX_T)
+typedef uint64_t uintmax_t;
+# endif
+
+# else
+# error "PORTME: Add architecture. Don't forget to check the [U]INTx_C() and [U]INTMAX_MIN/MAX macros."
+# endif
+
+# endif /* !linux kernel or stuff */
+
+ /* pointer <-> integer types */
+# if !defined(_MSC_VER) || defined(DOXYGEN_RUNNING)
+# if ARCH_BITS == 32 \
+ || defined(RT_OS_LINUX) \
+ || defined(RT_OS_FREEBSD)
+# if !defined(_INTPTR_T_DECLARED) && !defined(_INTPTR_T)
+typedef signed long intptr_t;
+# endif
+# if !defined(_UINTPTR_T_DECLARED) && !defined(_UINTPTR_T)
+typedef unsigned long uintptr_t;
+# endif
+# else
+# if !defined(_INTPTR_T_DECLARED) && !defined(_INTPTR_T)
+typedef int64_t intptr_t;
+# endif
+# if !defined(_UINTPTR_T_DECLARED) && !defined(_UINTPTR_T)
+typedef uint64_t uintptr_t;
+# endif
+# endif
+# endif /* !_MSC_VER */
+
+#endif /* no system stdint.h */
+
+
+/*
+ * Make sure the [U]INTx_C(c) macros are present.
+ * For In C++ source the system stdint.h may have skipped these if it was
+ * included before we managed to define __STDC_CONSTANT_MACROS. (Kludge alert!)
+ */
+#if !defined(INT8_C) \
+ || !defined(INT16_C) \
+ || !defined(INT32_C) \
+ || !defined(INT64_C) \
+ || !defined(INTMAX_C) \
+ || !defined(UINT8_C) \
+ || !defined(UINT16_C) \
+ || !defined(UINT32_C) \
+ || !defined(UINT64_C) \
+ || !defined(UINTMAX_C)
+# define INT8_C(Value) (Value)
+# define INT16_C(Value) (Value)
+# define INT32_C(Value) (Value)
+# define INT64_C(Value) (Value ## LL)
+# define UINT8_C(Value) (Value)
+# define UINT16_C(Value) (Value)
+# define UINT32_C(Value) (Value ## U)
+# define UINT64_C(Value) (Value ## ULL)
+# define INTMAX_C(Value) INT64_C(Value)
+# define UINTMAX_C(Value) UINT64_C(Value)
+#endif
+
+
+/*
+ * Make sure the INTx_MIN and [U]INTx_MAX macros are present.
+ * For In C++ source the system stdint.h may have skipped these if it was
+ * included before we managed to define __STDC_LIMIT_MACROS. (Kludge alert!)
+ */
+#if !defined(INT8_MIN) \
+ || !defined(INT16_MIN) \
+ || !defined(INT32_MIN) \
+ || !defined(INT64_MIN) \
+ || !defined(INT8_MAX) \
+ || !defined(INT16_MAX) \
+ || !defined(INT32_MAX) \
+ || !defined(INT64_MAX) \
+ || !defined(UINT8_MAX) \
+ || !defined(UINT16_MAX) \
+ || !defined(UINT32_MAX) \
+ || !defined(UINT64_MAX)
+# define INT8_MIN (INT8_C(-0x7f) - 1)
+# define INT16_MIN (INT16_C(-0x7fff) - 1)
+# define INT32_MIN (INT32_C(-0x7fffffff) - 1)
+# define INT64_MIN (INT64_C(-0x7fffffffffffffff) - 1)
+# define INT8_MAX INT8_C(0x7f)
+# define INT16_MAX INT16_C(0x7fff)
+# define INT32_MAX INT32_C(0x7fffffff)
+# define INT64_MAX INT64_C(0x7fffffffffffffff)
+# define UINT8_MAX UINT8_C(0xff)
+# define UINT16_MAX UINT16_C(0xffff)
+# define UINT32_MAX UINT32_C(0xffffffff)
+# define UINT64_MAX UINT64_C(0xffffffffffffffff)
+
+# define INTMAX_MIN INT64_MIN
+# define INTMAX_MAX INT64_MAX
+# define UINTMAX_MAX UINT64_MAX
+#endif
+
+#endif
+
diff --git a/include/iprt/strcache.h b/include/iprt/strcache.h
new file mode 100644
index 00000000..d3883483
--- /dev/null
+++ b/include/iprt/strcache.h
@@ -0,0 +1,121 @@
+/* $Id: strcache.h $ */
+/** @file
+ * IPRT - String Cache, stub implementation.
+ */
+
+/*
+ * 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 ___iprt_strcache_h
+#define ___iprt_strcache_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+
+/**
+ * Create a new string cache.
+ *
+ * @returns IPRT status code
+ *
+ * @param phStrCache Where to return the string cache handle.
+ * @param pszName The name of the cache (for debug purposes).
+ */
+RTDECL(int) RTStrCacheCreate(PRTSTRCACHE phStrCache, const char *pszName);
+
+
+/**
+ * Destroys a string cache.
+ *
+ * This will cause all strings in the cache to be released and thus become
+ * invalid.
+ *
+ * @returns IPRT status.
+ *
+ * @param hStrCache Handle to the string cache. The nil and default
+ * handles are ignored quietly (VINF_SUCCESS).
+ */
+RTDECL(int) RTStrCacheDestroy(RTSTRCACHE hStrCache);
+
+
+/**
+ * Enters a string into the cache.
+ *
+ * @returns Pointer to a read-only copy of the string.
+ *
+ * @param hStrCache Handle to the string cache.
+ * @param pchString Pointer to a string. This does not need to be
+ * zero terminated, but must not contain any zero
+ * characters.
+ * @param cchString The number of characters (bytes) to enter.
+ *
+ * @remarks It is implementation dependent whether the returned string pointer
+ * differs when entering the same string twice.
+ */
+RTDECL(const char *) RTStrCacheEnterN(RTSTRCACHE hStrCache, const char *pchString, size_t cchString);
+
+/**
+ * Enters a string into the cache.
+ *
+ * @returns Pointer to a read-only copy of the string.
+ *
+ * @param hStrCache Handle to the string cache.
+ * @param psz Pointer to a zero terminated string.
+ *
+ * @remarks See RTStrCacheEnterN.
+ */
+RTDECL(const char *) RTStrCacheEnter(RTSTRCACHE hStrCache, const char *psz);
+
+
+/**
+ * Retains a reference to a string.
+ *
+ * @returns The new reference count. UINT32_MAX is returned if the string
+ * pointer is invalid.
+ */
+RTDECL(uint32_t) RTStrCacheRetain(const char *psz);
+
+/**
+ * Releases a reference to a string.
+ *
+ * @returns The new reference count.
+ * UINT32_MAX is returned if the string pointer is invalid.
+ *
+ * @param hStrCache Handle to the string cache. Passing NIL is ok,
+ * but this may come a performance hit.
+ * @param psz Pointer to a cached string.
+ */
+RTDECL(uint32_t) RTStrCacheRelease(RTSTRCACHE hStrCache, const char *psz);
+
+/**
+ * Gets the string length of a cache entry.
+ *
+ * @returns The string length. 0 if the string is invalid (asserted).
+ *
+ * @param psz Pointer to a cached string.
+ */
+RTDECL(size_t) RTStrCacheLength(const char *psz);
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/stream.h b/include/iprt/stream.h
new file mode 100644
index 00000000..e8ac0d08
--- /dev/null
+++ b/include/iprt/stream.h
@@ -0,0 +1,292 @@
+/** @file
+ * IPRT - I/O Stream.
+ */
+
+/*
+ * 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 ___iprt_stream_h
+#define ___iprt_stream_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_stream RTStrm - File Streams
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Pointer to a stream. */
+typedef struct RTSTREAM *PRTSTREAM;
+
+/** Pointer to the standard input stream. */
+extern RTDATADECL(PRTSTREAM) g_pStdIn;
+
+/** Pointer to the standard error stream. */
+extern RTDATADECL(PRTSTREAM) g_pStdErr;
+
+/** Pointer to the standard output stream. */
+extern RTDATADECL(PRTSTREAM) g_pStdOut;
+
+
+/**
+ * Opens a file stream.
+ *
+ * @returns iprt status code.
+ * @param pszFilename Path to the file to open.
+ * @param pszMode The open mode. See fopen() standard.
+ * Format: <a|r|w>[+][b|t]
+ * @param ppStream Where to store the opened stream.
+ */
+RTR3DECL(int) RTStrmOpen(const char *pszFilename, const char *pszMode, PRTSTREAM *ppStream);
+
+/**
+ * Opens a file stream.
+ *
+ * @returns iprt status code.
+ * @param pszMode The open mode. See fopen() standard.
+ * Format: <a|r|w>[+][b|t]
+ * @param ppStream Where to store the opened stream.
+ * @param pszFilenameFmt Filename path format string.
+ * @param args Arguments to the format string.
+ */
+RTR3DECL(int) RTStrmOpenFV(const char *pszMode, PRTSTREAM *ppStream, const char *pszFilenameFmt, va_list args);
+
+/**
+ * Opens a file stream.
+ *
+ * @returns iprt status code.
+ * @param pszMode The open mode. See fopen() standard.
+ * Format: <a|r|w>[+][b|t]
+ * @param ppStream Where to store the opened stream.
+ * @param pszFilenameFmt Filename path format string.
+ * @param ... Arguments to the format string.
+ */
+RTR3DECL(int) RTStrmOpenF(const char *pszMode, PRTSTREAM *ppStream, const char *pszFilenameFmt, ...);
+
+/**
+ * Closes the specified stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream to close.
+ */
+RTR3DECL(int) RTStrmClose(PRTSTREAM pStream);
+
+/**
+ * Get the pending error of the stream.
+ *
+ * @returns iprt status code. of the stream.
+ * @param pStream The stream.
+ */
+RTR3DECL(int) RTStrmError(PRTSTREAM pStream);
+
+/**
+ * Clears stream error condition.
+ *
+ * All stream operations save RTStrmClose and this will fail
+ * while an error is asserted on the stream
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ */
+RTR3DECL(int) RTStrmClearError(PRTSTREAM pStream);
+
+/**
+ * Changes the stream mode.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ * @param fBinary The desired binary (@c true) / text mode (@c false).
+ * Pass -1 to leave it unchanged.
+ * @param fCurrentCodeSet Whether converting the stream from UTF-8 to the
+ * current code set is desired (@c true) or not (@c
+ * false). Pass -1 to leave this property unchanged.
+ */
+RTR3DECL(int) RTStrmSetMode(PRTSTREAM pStream, int fBinary, int fCurrentCodeSet);
+
+/**
+ * Rewinds the stream.
+ *
+ * Stream errors will be reset on success.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pStream The stream.
+ *
+ * @remarks Not all streams are rewindable and that behavior is currently
+ * undefined for those.
+ */
+RTR3DECL(int) RTStrmRewind(PRTSTREAM pStream);
+
+/**
+ * Reads from a file stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ * @param pvBuf Where to put the read bits.
+ * Must be cbRead bytes or more.
+ * @param cbRead Number of bytes to read.
+ * @param pcbRead Where to store the number of bytes actually read.
+ * If NULL cbRead bytes are read or an error is returned.
+ */
+RTR3DECL(int) RTStrmReadEx(PRTSTREAM pStream, void *pvBuf, size_t cbRead, size_t *pcbRead);
+
+/**
+ * Writes to a file stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ * @param pvBuf Where to get the bits to write from.
+ * @param cbWrite Number of bytes to write.
+ * @param pcbWritten Where to store the number of bytes actually written.
+ * If NULL cbWrite bytes are written or an error is returned.
+ */
+RTR3DECL(int) RTStrmWriteEx(PRTSTREAM pStream, const void *pvBuf, size_t cbWrite, size_t *pcbWritten);
+
+/**
+ * Reads from a file stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ * @param pvBuf Where to put the read bits.
+ * Must be cbRead bytes or more.
+ * @param cbRead Number of bytes to read.
+ */
+DECLINLINE(int) RTStrmRead(PRTSTREAM pStream, void *pvBuf, size_t cbRead)
+{
+ return RTStrmReadEx(pStream, pvBuf, cbRead, NULL);
+}
+
+/**
+ * Writes to a file stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ * @param pvBuf Where to get the bits to write from.
+ * @param cbWrite Number of bytes to write.
+ */
+DECLINLINE(int) RTStrmWrite(PRTSTREAM pStream, const void *pvBuf, size_t cbWrite)
+{
+ return RTStrmWriteEx(pStream, pvBuf, cbWrite, NULL);
+}
+
+/**
+ * Reads a character from a file stream.
+ *
+ * @returns The char as an unsigned char cast to int.
+ * @returns -1 on failure.
+ * @param pStream The stream.
+ */
+RTR3DECL(int) RTStrmGetCh(PRTSTREAM pStream);
+
+/**
+ * Writes a character to a file stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ * @param ch The char to write.
+ */
+RTR3DECL(int) RTStrmPutCh(PRTSTREAM pStream, int ch);
+
+/**
+ * Writes a string to a file stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream.
+ * @param pszString The string to write.
+ * No newlines or anything is appended or prepended.
+ * The terminating '\\0' is not written, of course.
+ */
+RTR3DECL(int) RTStrmPutStr(PRTSTREAM pStream, const char *pszString);
+
+/**
+ * Reads a line from a file stream.
+ *
+ * A line ends with a '\\n', '\\r\\n', '\\0' or the end of the file.
+ *
+ * @returns iprt status code.
+ * @retval VINF_BUFFER_OVERFLOW if the buffer wasn't big enough to read an
+ * entire line.
+ * @retval VERR_BUFFER_OVERFLOW if a lone '\\r' was encountered at the end of
+ * the buffer and we ended up dropping the following character.
+ *
+ * @param pStream The stream.
+ * @param pszString Where to store the line.
+ * The line will *NOT* contain any '\\n'.
+ * @param cbString The size of the string buffer.
+ */
+RTR3DECL(int) RTStrmGetLine(PRTSTREAM pStream, char *pszString, size_t cbString);
+
+/**
+ * Flushes a stream.
+ *
+ * @returns iprt status code.
+ * @param pStream The stream to flush.
+ */
+RTR3DECL(int) RTStrmFlush(PRTSTREAM pStream);
+
+/**
+ * Prints a formatted string to the specified stream.
+ *
+ * @returns Number of bytes printed.
+ * @param pStream The stream to print to.
+ * @param pszFormat Runtime format string.
+ * @param ... Arguments specified by pszFormat.
+ */
+RTR3DECL(int) RTStrmPrintf(PRTSTREAM pStream, const char *pszFormat, ...);
+
+/**
+ * Prints a formatted string to the specified stream.
+ *
+ * @returns Number of bytes printed.
+ * @param pStream The stream to print to.
+ * @param pszFormat Runtime format string.
+ * @param args Arguments specified by pszFormat.
+ */
+RTR3DECL(int) RTStrmPrintfV(PRTSTREAM pStream, const char *pszFormat, va_list args);
+
+/**
+ * Prints a formatted string to the standard output stream (g_pStdOut).
+ *
+ * @returns Number of bytes printed.
+ * @param pszFormat Runtime format string.
+ * @param ... Arguments specified by pszFormat.
+ */
+RTR3DECL(int) RTPrintf(const char *pszFormat, ...);
+
+/**
+ * Prints a formatted string to the standard output stream (g_pStdOut).
+ *
+ * @returns Number of bytes printed.
+ * @param pszFormat Runtime format string.
+ * @param args Arguments specified by pszFormat.
+ */
+RTR3DECL(int) RTPrintfV(const char *pszFormat, va_list args);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/string.h b/include/iprt/string.h
new file mode 100644
index 00000000..1f52c75d
--- /dev/null
+++ b/include/iprt/string.h
@@ -0,0 +1,3868 @@
+/** @file
+ * IPRT - String Manipulation.
+ */
+
+/*
+ * 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 ___iprt_string_h
+#define ___iprt_string_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/assert.h>
+#include <iprt/stdarg.h>
+#include <iprt/err.h> /* for VINF_SUCCESS */
+#if defined(RT_OS_LINUX) && defined(__KERNEL__)
+ RT_C_DECLS_BEGIN
+# include <linux/string.h>
+ RT_C_DECLS_END
+
+#elif defined(IN_XF86_MODULE) && !defined(NO_ANSIC)
+ RT_C_DECLS_BEGIN
+# include "xf86_ansic.h"
+ RT_C_DECLS_END
+
+#elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+ RT_C_DECLS_BEGIN
+ /** @todo
+ * XXX: Very ugly hack to get things build on recent FreeBSD builds. They have
+ * memchr now and we need to include param.h to get __FreeBSD_version and make
+ * memchr available based on the version below or we can't compile the kernel
+ * module on older versions anymore.
+ *
+ * But including param.h here opens Pandora's box because we clash with a few
+ * defines namely PVM and PAGE_SIZE. We can safely undefine PVM here but not
+ * PAGE_SIZE because this results in build errors sooner or later. Luckily this
+ * define is in a header included by param.h (machine/param.h). We define the
+ * guards here to prevent inclusion of it if PAGE_SIZE was defined already.
+ *
+ * @todo aeichner: Search for an elegant solution and cleanup this mess ASAP!
+ */
+# ifdef PAGE_SIZE
+# define _AMD64_INCLUDE_PARAM_H_
+# define _I386_INCLUDE_PARAM_H_
+# define _MACHINE_PARAM_H_
+# endif
+# include <sys/param.h> /* __FreeBSD_version */
+# undef PVM
+# include <sys/libkern.h>
+ /*
+ * No memmove on versions < 7.2
+ * Defining a macro using bcopy here
+ */
+# define memmove(dst, src, size) bcopy(src, dst, size)
+ RT_C_DECLS_END
+
+#elif defined(RT_OS_SOLARIS) && defined(_KERNEL)
+ /*
+ * Same case as with FreeBSD kernel:
+ * The string.h stuff clashes with sys/system.h
+ * ffs = find first set bit.
+ */
+# define ffs ffs_string_h
+# include <string.h>
+# undef ffs
+# undef strpbrk
+
+#else
+# include <string.h>
+#endif
+
+/*
+ * Supply prototypes for standard string functions provided by
+ * IPRT instead of the operating environment.
+ */
+#if defined(RT_OS_DARWIN) && defined(KERNEL)
+RT_C_DECLS_BEGIN
+void *memchr(const void *pv, int ch, size_t cb);
+char *strpbrk(const char *pszStr, const char *pszChars);
+RT_C_DECLS_END
+#endif
+
+#if defined(RT_OS_FREEBSD) && defined(_KERNEL)
+RT_C_DECLS_BEGIN
+#if __FreeBSD_version < 900000
+void *memchr(const void *pv, int ch, size_t cb);
+#endif
+char *strpbrk(const char *pszStr, const char *pszChars);
+RT_C_DECLS_END
+#endif
+
+/** @def RT_USE_RTC_3629
+ * When defined the UTF-8 range will stop at 0x10ffff. If not defined, the
+ * range stops at 0x7fffffff.
+ * @remarks Must be defined both when building and using the IPRT. */
+#ifdef DOXYGEN_RUNNING
+# define RT_USE_RTC_3629
+#endif
+
+
+/**
+ * Byte zero the specified object.
+ *
+ * This will use sizeof(Obj) to figure the size and will call memset, bzero
+ * or some compiler intrinsic to perform the actual zeroing.
+ *
+ * @param Obj The object to zero. Make sure to dereference pointers.
+ *
+ * @remarks Because the macro may use memset it has been placed in string.h
+ * instead of cdefs.h to avoid build issues because someone forgot
+ * to include this header.
+ *
+ * @ingroup grp_rt_cdefs
+ */
+#define RT_ZERO(Obj) RT_BZERO(&(Obj), sizeof(Obj))
+
+/**
+ * Byte zero the specified memory area.
+ *
+ * This will call memset, bzero or some compiler intrinsic to clear the
+ * specified bytes of memory.
+ *
+ * @param pv Pointer to the memory.
+ * @param cb The number of bytes to clear. Please, don't pass 0.
+ *
+ * @remarks Because the macro may use memset it has been placed in string.h
+ * instead of cdefs.h to avoid build issues because someone forgot
+ * to include this header.
+ *
+ * @ingroup grp_rt_cdefs
+ */
+#define RT_BZERO(pv, cb) do { memset((pv), 0, cb); } while (0)
+
+
+
+/** @defgroup grp_rt_str RTStr - String Manipulation
+ * Mostly UTF-8 related helpers where the standard string functions won't do.
+ * @ingroup grp_rt
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+
+/**
+ * The maximum string length.
+ */
+#define RTSTR_MAX (~(size_t)0)
+
+
+/** @def RTMEM_TAG
+ * The default allocation tag used by the RTStr allocation APIs.
+ *
+ * When not defined before the inclusion of iprt/string.h, this will default to
+ * the pointer to the current file name. The string API will make of use of
+ * this as pointer to a volatile but read-only string.
+ */
+#ifndef RTSTR_TAG
+# define RTSTR_TAG (__FILE__)
+#endif
+
+
+#ifdef IN_RING3
+
+/**
+ * Allocates tmp buffer with default tag, translates pszString from UTF8 to
+ * current codepage.
+ *
+ * @returns iprt status code.
+ * @param ppszString Receives pointer of allocated native CP string.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszString UTF-8 string to convert.
+ */
+#define RTStrUtf8ToCurrentCP(ppszString, pszString) RTStrUtf8ToCurrentCPTag((ppszString), (pszString), RTSTR_TAG)
+
+/**
+ * Allocates tmp buffer with custom tag, translates pszString from UTF8 to
+ * current codepage.
+ *
+ * @returns iprt status code.
+ * @param ppszString Receives pointer of allocated native CP string.
+ * The returned pointer must be freed using
+ * RTStrFree()., const char *pszTag
+ * @param pszString UTF-8 string to convert.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR3DECL(int) RTStrUtf8ToCurrentCPTag(char **ppszString, const char *pszString, const char *pszTag);
+
+/**
+ * Allocates tmp buffer, translates pszString from current codepage to UTF-8.
+ *
+ * @returns iprt status code.
+ * @param ppszString Receives pointer of allocated UTF-8 string.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszString Native string to convert.
+ */
+#define RTStrCurrentCPToUtf8(ppszString, pszString) RTStrCurrentCPToUtf8Tag((ppszString), (pszString), RTSTR_TAG)
+
+/**
+ * Allocates tmp buffer, translates pszString from current codepage to UTF-8.
+ *
+ * @returns iprt status code.
+ * @param ppszString Receives pointer of allocated UTF-8 string.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszString Native string to convert.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTR3DECL(int) RTStrCurrentCPToUtf8Tag(char **ppszString, const char *pszString, const char *pszTag);
+
+#endif /* IN_RING3 */
+
+/**
+ * Free string allocated by any of the non-UCS-2 string functions.
+ *
+ * @returns iprt status code.
+ * @param pszString Pointer to buffer with string to free.
+ * NULL is accepted.
+ */
+RTDECL(void) RTStrFree(char *pszString);
+
+/**
+ * Allocates a new copy of the given UTF-8 string (default tag).
+ *
+ * @returns Pointer to the allocated UTF-8 string.
+ * @param pszString UTF-8 string to duplicate.
+ */
+#define RTStrDup(pszString) RTStrDupTag((pszString), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the given UTF-8 string (custom tag).
+ *
+ * @returns Pointer to the allocated UTF-8 string.
+ * @param pszString UTF-8 string to duplicate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrDupTag(const char *pszString, const char *pszTag);
+
+/**
+ * Allocates a new copy of the given UTF-8 string (default tag).
+ *
+ * @returns iprt status code.
+ * @param ppszString Receives pointer of the allocated UTF-8 string.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszString UTF-8 string to duplicate.
+ */
+#define RTStrDupEx(ppszString, pszString) RTStrDupExTag((ppszString), (pszString), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the given UTF-8 string (custom tag).
+ *
+ * @returns iprt status code.
+ * @param ppszString Receives pointer of the allocated UTF-8 string.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszString UTF-8 string to duplicate.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrDupExTag(char **ppszString, const char *pszString, const char *pszTag);
+
+/**
+ * Allocates a new copy of the given UTF-8 substring (default tag).
+ *
+ * @returns Pointer to the allocated UTF-8 substring.
+ * @param pszString UTF-8 string to duplicate.
+ * @param cchMax The max number of chars to duplicate, not counting
+ * the terminator.
+ */
+#define RTStrDupN(pszString, cchMax) RTStrDupNTag((pszString), (cchMax), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the given UTF-8 substring (custom tag).
+ *
+ * @returns Pointer to the allocated UTF-8 substring.
+ * @param pszString UTF-8 string to duplicate.
+ * @param cchMax The max number of chars to duplicate, not counting
+ * the terminator.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrDupNTag(const char *pszString, size_t cchMax, const char *pszTag);
+
+/**
+ * Appends a string onto an existing IPRT allocated string (default tag).
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param pszAppend The string to append. NULL and empty strings
+ * are quietly ignored.
+ */
+#define RTStrAAppend(ppsz, pszAppend) RTStrAAppendTag((ppsz), (pszAppend), RTSTR_TAG)
+
+/**
+ * Appends a string onto an existing IPRT allocated string (custom tag).
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param pszAppend The string to append. NULL and empty strings
+ * are quietly ignored.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAAppendTag(char **ppsz, const char *pszAppend, const char *pszTag);
+
+/**
+ * Appends N bytes from a strings onto an existing IPRT allocated string
+ * (default tag).
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param pszAppend The string to append. Can be NULL if cchAppend
+ * is NULL.
+ * @param cchAppend The number of chars (not code points) to append
+ * from pszAppend. Must not be more than
+ * @a pszAppend contains, except for the special
+ * value RTSTR_MAX that can be used to indicate all
+ * of @a pszAppend without having to strlen it.
+ */
+#define RTStrAAppendN(ppsz, pszAppend, cchAppend) RTStrAAppendNTag((ppsz), (pszAppend), (cchAppend), RTSTR_TAG)
+
+/**
+ * Appends N bytes from a strings onto an existing IPRT allocated string (custom
+ * tag).
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param pszAppend The string to append. Can be NULL if cchAppend
+ * is NULL.
+ * @param cchAppend The number of chars (not code points) to append
+ * from pszAppend. Must not be more than
+ * @a pszAppend contains, except for the special
+ * value RTSTR_MAX that can be used to indicate all
+ * of @a pszAppend without having to strlen it.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAAppendNTag(char **ppsz, const char *pszAppend, size_t cchAppend, const char *pszTag);
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string.
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param cPairs The number of string / length pairs in the
+ * @a va.
+ * @param va List of string (const char *) and length
+ * (size_t) pairs. The strings will be appended to
+ * the string in the first argument.
+ */
+#define RTStrAAppendExNV(ppsz, cPairs, va) RTStrAAppendExNVTag((ppsz), (cPairs), (va), RTSTR_TAG)
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string.
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param cPairs The number of string / length pairs in the
+ * @a va.
+ * @param va List of string (const char *) and length
+ * (size_t) pairs. The strings will be appended to
+ * the string in the first argument.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAAppendExNVTag(char **ppsz, size_t cPairs, va_list va, const char *pszTag);
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string
+ * (untagged).
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param cPairs The number of string / length pairs in the
+ * ellipsis.
+ * @param ... List of string (const char *) and length
+ * (size_t) pairs. The strings will be appended to
+ * the string in the first argument.
+ */
+DECLINLINE(int) RTStrAAppendExN(char **ppsz, size_t cPairs, ...)
+{
+ int rc;
+ va_list va;
+ va_start(va, cPairs);
+ rc = RTStrAAppendExNVTag(ppsz, cPairs, va, RTSTR_TAG);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * Appends one or more strings onto an existing IPRT allocated string (custom
+ * tag).
+ *
+ * This is a very flexible and efficient alternative to using RTStrAPrintf to
+ * combine several strings together.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer must either be NULL or point to a string
+ * returned by an IPRT string API. (In/Out)
+ * @param pszTag Allocation tag used for statistics and such.
+ * @param cPairs The number of string / length pairs in the
+ * ellipsis.
+ * @param ... List of string (const char *) and length
+ * (size_t) pairs. The strings will be appended to
+ * the string in the first argument.
+ */
+DECLINLINE(int) RTStrAAppendExNTag(char **ppsz, const char *pszTag, size_t cPairs, ...)
+{
+ int rc;
+ va_list va;
+ va_start(va, cPairs);
+ rc = RTStrAAppendExNVTag(ppsz, cPairs, va, pszTag);
+ va_end(va);
+ return rc;
+}
+
+/**
+ * Truncates an IPRT allocated string (default tag).
+ *
+ * @retval VINF_SUCCESS.
+ * @retval VERR_OUT_OF_RANGE if cchNew is too long. Nothing is done.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer can be NULL if @a cchNew is 0, no change
+ * is made then. If we actually reallocate the
+ * string, the string pointer might be changed by
+ * this call. (In/Out)
+ * @param cchNew The new string length (excluding the
+ * terminator). The string must be at least this
+ * long or we'll return VERR_OUT_OF_RANGE and
+ * assert on you.
+ */
+#define RTStrATruncate(ppsz, cchNew) RTStrATruncateTag((ppsz), (cchNew), RTSTR_TAG)
+
+/**
+ * Truncates an IPRT allocated string.
+ *
+ * @retval VINF_SUCCESS.
+ * @retval VERR_OUT_OF_RANGE if cchNew is too long. Nothing is done.
+ *
+ * @param ppsz Pointer to the string pointer. The string
+ * pointer can be NULL if @a cchNew is 0, no change
+ * is made then. If we actually reallocate the
+ * string, the string pointer might be changed by
+ * this call. (In/Out)
+ * @param cchNew The new string length (excluding the
+ * terminator). The string must be at least this
+ * long or we'll return VERR_OUT_OF_RANGE and
+ * assert on you.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrATruncateTag(char **ppsz, size_t cchNew, const char *pszTag);
+
+/**
+ * Allocates memory for string storage (default tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns Pointer to the allocated string. The first byte is always set
+ * to the string terminator char, the contents of the remainder of the
+ * memory is undefined. The string must be freed by calling RTStrFree.
+ *
+ * NULL is returned if the allocation failed. Please translate this to
+ * VERR_NO_STR_MEMORY and not VERR_NO_MEMORY. Also consider
+ * RTStrAllocEx if an IPRT status code is required.
+ *
+ * @param cb How many bytes to allocate. If this is zero, we
+ * will allocate a terminator byte anyway.
+ */
+#define RTStrAlloc(cb) RTStrAllocTag((cb), RTSTR_TAG)
+
+/**
+ * Allocates memory for string storage (custom tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @returns Pointer to the allocated string. The first byte is always set
+ * to the string terminator char, the contents of the remainder of the
+ * memory is undefined. The string must be freed by calling RTStrFree.
+ *
+ * NULL is returned if the allocation failed. Please translate this to
+ * VERR_NO_STR_MEMORY and not VERR_NO_MEMORY. Also consider
+ * RTStrAllocEx if an IPRT status code is required.
+ *
+ * @param cb How many bytes to allocate. If this is zero, we
+ * will allocate a terminator byte anyway.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrAllocTag(size_t cb, const char *pszTag);
+
+/**
+ * Allocates memory for string storage, with status code (default tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY
+ *
+ * @param ppsz Where to return the allocated string. This will
+ * be set to NULL on failure. On success, the
+ * returned memory will always start with a
+ * terminator char so that it is considered a valid
+ * C string, the contents of rest of the memory is
+ * undefined.
+ * @param cb How many bytes to allocate. If this is zero, we
+ * will allocate a terminator byte anyway.
+ */
+#define RTStrAllocEx(ppsz, cb) RTStrAllocExTag((ppsz), (cb), RTSTR_TAG)
+
+/**
+ * Allocates memory for string storage, with status code (custom tag).
+ *
+ * You should normally not use this function, except if there is some very
+ * custom string handling you need doing that isn't covered by any of the other
+ * APIs.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_STR_MEMORY
+ *
+ * @param ppsz Where to return the allocated string. This will
+ * be set to NULL on failure. On success, the
+ * returned memory will always start with a
+ * terminator char so that it is considered a valid
+ * C string, the contents of rest of the memory is
+ * undefined.
+ * @param cb How many bytes to allocate. If this is zero, we
+ * will allocate a terminator byte anyway.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAllocExTag(char **ppsz, size_t cb, const char *pszTag);
+
+/**
+ * Reallocates the specified string (default tag).
+ *
+ * You should normally not have use this function, except perhaps to truncate a
+ * really long string you've got from some IPRT string API, but then you should
+ * use RTStrATruncate.
+ *
+ * @returns VINF_SUCCESS.
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string variable containing the
+ * input and output string.
+ *
+ * When not freeing the string, the result will
+ * always have the last byte set to the terminator
+ * character so that when used for string
+ * truncation the result will be a valid C string
+ * (your job to keep it a valid UTF-8 string).
+ *
+ * When the input string is NULL and we're supposed
+ * to reallocate, the returned string will also
+ * have the first byte set to the terminator char
+ * so it will be a valid C string.
+ *
+ * @param cbNew When @a cbNew is zero, we'll behave like
+ * RTStrFree and @a *ppsz will be set to NULL.
+ *
+ * When not zero, this will be the new size of the
+ * memory backing the string, i.e. it includes the
+ * terminator char.
+ */
+#define RTStrRealloc(ppsz, cbNew) RTStrReallocTag((ppsz), (cbNew), RTSTR_TAG)
+
+/**
+ * Reallocates the specified string (custom tag).
+ *
+ * You should normally not have use this function, except perhaps to truncate a
+ * really long string you've got from some IPRT string API, but then you should
+ * use RTStrATruncate.
+ *
+ * @returns VINF_SUCCESS.
+ * @retval VERR_NO_STR_MEMORY if we failed to reallocate the string, @a *ppsz
+ * remains unchanged.
+ *
+ * @param ppsz Pointer to the string variable containing the
+ * input and output string.
+ *
+ * When not freeing the string, the result will
+ * always have the last byte set to the terminator
+ * character so that when used for string
+ * truncation the result will be a valid C string
+ * (your job to keep it a valid UTF-8 string).
+ *
+ * When the input string is NULL and we're supposed
+ * to reallocate, the returned string will also
+ * have the first byte set to the terminator char
+ * so it will be a valid C string.
+ *
+ * @param cbNew When @a cbNew is zero, we'll behave like
+ * RTStrFree and @a *ppsz will be set to NULL.
+ *
+ * When not zero, this will be the new size of the
+ * memory backing the string, i.e. it includes the
+ * terminator char.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrReallocTag(char **ppsz, size_t cbNew, const char *pszTag);
+
+/**
+ * Validates the UTF-8 encoding of the string.
+ *
+ * @returns iprt status code.
+ * @param psz The string.
+ */
+RTDECL(int) RTStrValidateEncoding(const char *psz);
+
+/** @name Flags for RTStrValidateEncodingEx
+ */
+/** Check that the string is zero terminated within the given size.
+ * VERR_BUFFER_OVERFLOW will be returned if the check fails. */
+#define RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED RT_BIT_32(0)
+/** @} */
+
+/**
+ * Validates the UTF-8 encoding of the string.
+ *
+ * @returns iprt status code.
+ * @param psz The string.
+ * @param cch The max string length. Use RTSTR_MAX to process the entire string.
+ * @param fFlags Reserved for future. Pass 0.
+ */
+RTDECL(int) RTStrValidateEncodingEx(const char *psz, size_t cch, uint32_t fFlags);
+
+/**
+ * Checks if the UTF-8 encoding is valid.
+ *
+ * @returns true / false.
+ * @param psz The string.
+ */
+RTDECL(bool) RTStrIsValidEncoding(const char *psz);
+
+/**
+ * Purge all bad UTF-8 encoding in the string, replacing it with '?'.
+ *
+ * @returns The number of bad characters (0 if nothing was done).
+ * @param psz The string to purge.
+ */
+RTDECL(size_t) RTStrPurgeEncoding(char *psz);
+
+/**
+ * Sanitise a (valid) UTF-8 string by replacing all characters outside a white
+ * list in-place by an ASCII replacement character. Multi-byte characters will
+ * be replaced byte by byte.
+ *
+ * @returns The number of code points replaced, or a negative value if the
+ * string is not correctly encoded. In this last case the string
+ * may be partially processed.
+ * @param psz The string to sanitise.
+ * @param puszValidSets A zero-terminated array of pairs of Unicode points.
+ * Each pair is the start and end point of a range,
+ * and the union of these ranges forms the white list.
+ * @param chReplacement The ASCII replacement character.
+ */
+RTDECL(ssize_t) RTStrPurgeComplementSet(char *psz, PCRTUNICP puszValidSet, char chReplacement);
+
+/**
+ * Gets the number of code points the string is made up of, excluding
+ * the terminator.
+ *
+ *
+ * @returns Number of code points (RTUNICP).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param psz The string.
+ */
+RTDECL(size_t) RTStrUniLen(const char *psz);
+
+/**
+ * Gets the number of code points the string is made up of, excluding
+ * the terminator.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param psz The string.
+ * @param cch The max string length. Use RTSTR_MAX to process the entire string.
+ * @param pcuc Where to store the code point count.
+ * This is undefined on failure.
+ */
+RTDECL(int) RTStrUniLenEx(const char *psz, size_t cch, size_t *pcuc);
+
+/**
+ * Translate a UTF-8 string into an unicode string (i.e. RTUNICPs), allocating the string buffer.
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param ppUniString Receives pointer to the allocated unicode string.
+ * The returned string must be freed using RTUniFree().
+ */
+RTDECL(int) RTStrToUni(const char *pszString, PRTUNICP *ppUniString);
+
+/**
+ * Translates pszString from UTF-8 to an array of code points, allocating the result
+ * array if requested.
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param cchString The maximum size in chars (the type) to convert. The conversion stop
+ * when it reaches cchString or the string terminator ('\\0').
+ * Use RTSTR_MAX to translate the entire string.
+ * @param ppaCps If cCps is non-zero, this must either be pointing to pointer to
+ * a buffer of the specified size, or pointer to a NULL pointer.
+ * If *ppusz is NULL or cCps is zero a buffer of at least cCps items
+ * will be allocated to hold the translated string.
+ * If a buffer was requested it must be freed using RTUtf16Free().
+ * @param cCps The number of code points in the unicode string. This includes the terminator.
+ * @param pcCps Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ */
+RTDECL(int) RTStrToUniEx(const char *pszString, size_t cchString, PRTUNICP *ppaCps, size_t cCps, size_t *pcCps);
+
+/**
+ * Calculates the length of the string in RTUTF16 items.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings will be rejected. The primary purpose of this function is to
+ * help allocate buffers for RTStrToUtf16Ex of the correct size. For most
+ * other purposes RTStrCalcUtf16LenEx() should be used.
+ *
+ * @returns Number of RTUTF16 items.
+ * @returns 0 if the string was incorrectly encoded.
+ * @param psz The string.
+ */
+RTDECL(size_t) RTStrCalcUtf16Len(const char *psz);
+
+/**
+ * Calculates the length of the string in RTUTF16 items.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param psz The string.
+ * @param cch The max string length. Use RTSTR_MAX to process the entire string.
+ * @param pcwc Where to store the string length. Optional.
+ * This is undefined on failure.
+ */
+RTDECL(int) RTStrCalcUtf16LenEx(const char *psz, size_t cch, size_t *pcwc);
+
+/**
+ * Translate a UTF-8 string into a UTF-16 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param ppwszString Receives pointer to the allocated UTF-16 string.
+ * The returned string must be freed using RTUtf16Free().
+ */
+#define RTStrToUtf16(pszString, ppwszString) RTStrToUtf16Tag((pszString), (ppwszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-8 string into a UTF-16 allocating the result buffer (custom
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param ppwszString Receives pointer to the allocated UTF-16 string.
+ * The returned string must be freed using RTUtf16Free().
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrToUtf16Tag(const char *pszString, PRTUTF16 *ppwszString, const char *pszTag);
+
+/**
+ * Translates pszString from UTF-8 to UTF-16, allocating the result buffer if requested.
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param cchString The maximum size in chars (the type) to convert. The conversion stop
+ * when it reaches cchString or the string terminator ('\\0').
+ * Use RTSTR_MAX to translate the entire string.
+ * @param ppwsz If cwc is non-zero, this must either be pointing to pointer to
+ * a buffer of the specified size, or pointer to a NULL pointer.
+ * If *ppwsz is NULL or cwc is zero a buffer of at least cwc items
+ * will be allocated to hold the translated string.
+ * If a buffer was requested it must be freed using RTUtf16Free().
+ * @param cwc The buffer size in RTUTF16s. This includes the terminator.
+ * @param pcwc Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ */
+#define RTStrToUtf16Ex(pszString, cchString, ppwsz, cwc, pcwc) \
+ RTStrToUtf16ExTag((pszString), (cchString), (ppwsz), (cwc), (pcwc), RTSTR_TAG)
+
+/**
+ * Translates pszString from UTF-8 to UTF-16, allocating the result buffer if
+ * requested (custom tag).
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param cchString The maximum size in chars (the type) to convert. The conversion stop
+ * when it reaches cchString or the string terminator ('\\0').
+ * Use RTSTR_MAX to translate the entire string.
+ * @param ppwsz If cwc is non-zero, this must either be pointing to pointer to
+ * a buffer of the specified size, or pointer to a NULL pointer.
+ * If *ppwsz is NULL or cwc is zero a buffer of at least cwc items
+ * will be allocated to hold the translated string.
+ * If a buffer was requested it must be freed using RTUtf16Free().
+ * @param cwc The buffer size in RTUTF16s. This includes the terminator.
+ * @param pcwc Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrToUtf16ExTag(const char *pszString, size_t cchString, PRTUTF16 *ppwsz, size_t cwc, size_t *pcwc, const char *pszTag);
+
+
+/**
+ * Calculates the length of the string in Latin-1 characters.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings as well as string with codepoints outside the latin-1 range will be
+ * rejected. The primary purpose of this function is to help allocate buffers
+ * for RTStrToLatin1Ex of the correct size. For most other purposes
+ * RTStrCalcLatin1LenEx() should be used.
+ *
+ * @returns Number of Latin-1 characters.
+ * @returns 0 if the string was incorrectly encoded.
+ * @param psz The string.
+ */
+RTDECL(size_t) RTStrCalcLatin1Len(const char *psz);
+
+/**
+ * Calculates the length of the string in Latin-1 characters.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-8
+ * strings as well as string with codepoints outside the latin-1 range will be
+ * rejected.
+ *
+ * @returns iprt status code.
+ * @param psz The string.
+ * @param cch The max string length. Use RTSTR_MAX to process the
+ * entire string.
+ * @param pcch Where to store the string length. Optional.
+ * This is undefined on failure.
+ */
+RTDECL(int) RTStrCalcLatin1LenEx(const char *psz, size_t cch, size_t *pcwc);
+
+/**
+ * Translate a UTF-8 string into a Latin-1 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param ppszString Receives pointer to the allocated Latin-1 string.
+ * The returned string must be freed using RTStrFree().
+ */
+#define RTStrToLatin1(pszString, ppszString) RTStrToLatin1Tag((pszString), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-8 string into a Latin-1 allocating the result buffer (custom
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param ppszString Receives pointer to the allocated Latin-1 string.
+ * The returned string must be freed using RTStrFree().
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrToLatin1Tag(const char *pszString, char **ppszString, const char *pszTag);
+
+/**
+ * Translates pszString from UTF-8 to Latin-1, allocating the result buffer if requested.
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param cchString The maximum size in chars (the type) to convert.
+ * The conversion stop when it reaches cchString or
+ * the string terminator ('\\0'). Use RTSTR_MAX to
+ * translate the entire string.
+ * @param ppsz If cch is non-zero, this must either be pointing to
+ * pointer to a buffer of the specified size, or
+ * pointer to a NULL pointer. If *ppsz is NULL or cch
+ * is zero a buffer of at least cch items will be
+ * allocated to hold the translated string. If a
+ * buffer was requested it must be freed using
+ * RTStrFree().
+ * @param cch The buffer size in bytes. This includes the
+ * terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ */
+#define RTStrToLatin1Ex(pszString, cchString, ppsz, cch, pcch) \
+ RTStrToLatin1ExTag((pszString), (cchString), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates pszString from UTF-8 to Latin1, allocating the result buffer if
+ * requested (custom tag).
+ *
+ * @returns iprt status code.
+ * @param pszString UTF-8 string to convert.
+ * @param cchString The maximum size in chars (the type) to convert.
+ * The conversion stop when it reaches cchString or
+ * the string terminator ('\\0'). Use RTSTR_MAX to
+ * translate the entire string.
+ * @param ppsz If cch is non-zero, this must either be pointing to
+ * pointer to a buffer of the specified size, or
+ * pointer to a NULL pointer. If *ppsz is NULL or cch
+ * is zero a buffer of at least cch items will be
+ * allocated to hold the translated string. If a
+ * buffer was requested it must be freed using
+ * RTStrFree().
+ * @param cch The buffer size in bytes. This includes the
+ * terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrToLatin1ExTag(const char *pszString, size_t cchString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
+
+
+/**
+ * Translate a Latin1 string into a UTF-8 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param pszString Latin1 string to convert.
+ * @param ppszString Receives pointer of allocated UTF-8 string on
+ * success, and is always set to NULL on failure.
+ * The returned pointer must be freed using RTStrFree().
+ */
+#define RTLatin1ToUtf8(pszString, ppszString) RTLatin1ToUtf8Tag((pszString), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a Latin-1 string into a UTF-8 allocating the result buffer.
+ *
+ * @returns iprt status code.
+ * @param pszString Latin-1 string to convert.
+ * @param ppszString Receives pointer of allocated UTF-8 string on
+ * success, and is always set to NULL on failure.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTLatin1ToUtf8Tag(const char *pszString, char **ppszString, const char *pszTag);
+
+/**
+ * Translates Latin-1 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (default tag).
+ *
+ * @returns iprt status code.
+ * @param pszString The Latin-1 string to convert.
+ * @param cchString The number of Latin-1 characters to translate from
+ * pszString. The translation will stop when reaching
+ * cchString or the terminator ('\\0'). Use RTSTR_MAX
+ * to translate the entire string.
+ * @param ppsz If cch is non-zero, this must either be pointing to
+ * a pointer to a buffer of the specified size, or
+ * pointer to a NULL pointer. If *ppsz is NULL or cch
+ * is zero a buffer of at least cch chars will be
+ * allocated to hold the translated string. If a
+ * buffer was requested it must be freed using
+ * RTStrFree().
+ * @param cch The buffer size in chars (the type). This includes the terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ */
+#define RTLatin1ToUtf8Ex(pszString, cchString, ppsz, cch, pcch) \
+ RTLatin1ToUtf8ExTag((pszString), (cchString), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates Latin1 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (custom tag).
+ *
+ * @returns iprt status code.
+ * @param pszString The Latin1 string to convert.
+ * @param cchString The number of Latin1 characters to translate from
+ * pwszString. The translation will stop when
+ * reaching cchString or the terminator ('\\0'). Use
+ * RTSTR_MAX to translate the entire string.
+ * @param ppsz If cch is non-zero, this must either be pointing to
+ * a pointer to a buffer of the specified size, or
+ * pointer to a NULL pointer. If *ppsz is NULL or cch
+ * is zero a buffer of at least cch chars will be
+ * allocated to hold the translated string. If a
+ * buffer was requested it must be freed using
+ * RTStrFree().
+ * @param cch The buffer size in chars (the type). This includes
+ * the terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTLatin1ToUtf8ExTag(const char *pszString, size_t cchString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
+
+/**
+ * Calculates the length of the Latin-1 string in UTF-8 chars (bytes).
+ *
+ * The primary purpose of this function is to help allocate buffers for
+ * RTLatin1ToUtf8() of the correct size. For most other purposes
+ * RTLatin1ToUtf8Ex() should be used.
+ *
+ * @returns Number of chars (bytes).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param psz The Latin-1 string.
+ */
+RTDECL(size_t) RTLatin1CalcUtf8Len(const char *psz);
+
+/**
+ * Calculates the length of the Latin-1 string in UTF-8 chars (bytes).
+ *
+ * @returns iprt status code.
+ * @param psz The string.
+ * @param cch The max string length. Use RTSTR_MAX to process the entire string.
+ * @param pcch Where to store the string length (in bytes). Optional.
+ * This is undefined on failure.
+ */
+RTDECL(int) RTLatin1CalcUtf8LenEx(const char *psz, size_t cch, size_t *pcch);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param psz The string.
+ */
+RTDECL(RTUNICP) RTStrGetCpInternal(const char *psz);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code
+ * @returns VERR_INVALID_UTF8_ENCODING if the encoding is invalid.
+ * @param ppsz The string cursor.
+ * This is advanced one character forward on failure.
+ * @param pCp Where to store the unicode code point.
+ * Stores RTUNICP_INVALID if the encoding is invalid.
+ */
+RTDECL(int) RTStrGetCpExInternal(const char **ppsz, PRTUNICP pCp);
+
+/**
+ * Get the unicode code point at the given string position for a string of a
+ * given length.
+ *
+ * @returns iprt status code
+ * @retval VERR_INVALID_UTF8_ENCODING if the encoding is invalid.
+ * @retval VERR_END_OF_STRING if *pcch is 0. *pCp is set to RTUNICP_INVALID.
+ *
+ * @param ppsz The string.
+ * @param pcch Pointer to the length of the string. This will be
+ * decremented by the size of the code point.
+ * @param pCp Where to store the unicode code point.
+ * Stores RTUNICP_INVALID if the encoding is invalid.
+ */
+RTDECL(int) RTStrGetCpNExInternal(const char **ppsz, size_t *pcch, PRTUNICP pCp);
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by psz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param psz The string.
+ * @param CodePoint The code point to write.
+ * This should not be RTUNICP_INVALID or any other
+ * character out of the UTF-8 range.
+ *
+ * @remark This is a worker function for RTStrPutCp().
+ *
+ */
+RTDECL(char *) RTStrPutCpInternal(char *psz, RTUNICP CodePoint);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param psz The string.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * the most frequent and simplest sequence, the rest is
+ * handled by RTStrGetCpInternal().
+ */
+DECLINLINE(RTUNICP) RTStrGetCp(const char *psz)
+{
+ const unsigned char uch = *(const unsigned char *)psz;
+ if (!(uch & RT_BIT(7)))
+ return uch;
+ return RTStrGetCpInternal(psz);
+}
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param ppsz Pointer to the string pointer. This will be updated to
+ * point to the char following the current code point.
+ * This is advanced one character forward on failure.
+ * @param pCp Where to store the code point.
+ * RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * the most frequent and simplest sequence, the rest is
+ * handled by RTStrGetCpExInternal().
+ */
+DECLINLINE(int) RTStrGetCpEx(const char **ppsz, PRTUNICP pCp)
+{
+ const unsigned char uch = **(const unsigned char **)ppsz;
+ if (!(uch & RT_BIT(7)))
+ {
+ (*ppsz)++;
+ *pCp = uch;
+ return VINF_SUCCESS;
+ }
+ return RTStrGetCpExInternal(ppsz, pCp);
+}
+
+/**
+ * Get the unicode code point at the given string position for a string of a
+ * given maximum length.
+ *
+ * @returns iprt status code.
+ * @retval VERR_INVALID_UTF8_ENCODING if the encoding is invalid.
+ * @retval VERR_END_OF_STRING if *pcch is 0. *pCp is set to RTUNICP_INVALID.
+ *
+ * @param ppsz Pointer to the string pointer. This will be updated to
+ * point to the char following the current code point.
+ * @param pcch Pointer to the maximum string length. This will be
+ * decremented by the size of the code point found.
+ * @param pCp Where to store the code point.
+ * RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * the most frequent and simplest sequence, the rest is
+ * handled by RTStrGetCpNExInternal().
+ */
+DECLINLINE(int) RTStrGetCpNEx(const char **ppsz, size_t *pcch, PRTUNICP pCp)
+{
+ if (RT_LIKELY(*pcch != 0))
+ {
+ const unsigned char uch = **(const unsigned char **)ppsz;
+ if (!(uch & RT_BIT(7)))
+ {
+ (*ppsz)++;
+ (*pcch)--;
+ *pCp = uch;
+ return VINF_SUCCESS;
+ }
+ }
+ return RTStrGetCpNExInternal(ppsz, pcch, pCp);
+}
+
+/**
+ * Get the UTF-8 size in characters of a given Unicode code point.
+ *
+ * The code point is expected to be a valid Unicode one, but not necessarily in
+ * the range supported by UTF-8.
+ *
+ * @returns The number of chars (bytes) required to encode the code point, or
+ * zero if there is no UTF-8 encoding.
+ * @param CodePoint The unicode code point.
+ */
+DECLINLINE(size_t) RTStrCpSize(RTUNICP CodePoint)
+{
+ if (CodePoint < 0x00000080)
+ return 1;
+ if (CodePoint < 0x00000800)
+ return 2;
+ if (CodePoint < 0x00010000)
+ return 3;
+#ifdef RT_USE_RTC_3629
+ if (CodePoint < 0x00011000)
+ return 4;
+#else
+ if (CodePoint < 0x00200000)
+ return 4;
+ if (CodePoint < 0x04000000)
+ return 5;
+ if (CodePoint < 0x7fffffff)
+ return 6;
+#endif
+ return 0;
+}
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by psz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param psz The string.
+ * @param CodePoint The code point to write.
+ * This should not be RTUNICP_INVALID or any other
+ * character out of the UTF-8 range.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * the most frequent and simplest sequence, the rest is
+ * handled by RTStrPutCpInternal().
+ */
+DECLINLINE(char *) RTStrPutCp(char *psz, RTUNICP CodePoint)
+{
+ if (CodePoint < 0x80)
+ {
+ *psz++ = (unsigned char)CodePoint;
+ return psz;
+ }
+ return RTStrPutCpInternal(psz, CodePoint);
+}
+
+/**
+ * Skips ahead, past the current code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param psz Pointer to the current code point.
+ * @remark This will not move the next valid code point, only past the current one.
+ */
+DECLINLINE(char *) RTStrNextCp(const char *psz)
+{
+ RTUNICP Cp;
+ RTStrGetCpEx(&psz, &Cp);
+ return (char *)psz;
+}
+
+/**
+ * Skips back to the previous code point.
+ *
+ * @returns Pointer to the char before the current code point.
+ * @returns pszStart on failure.
+ * @param pszStart Pointer to the start of the string.
+ * @param psz Pointer to the current code point.
+ */
+RTDECL(char *) RTStrPrevCp(const char *pszStart, const char *psz);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param psz The string.
+ */
+DECLINLINE(RTUNICP) RTLatin1GetCp(const char *psz)
+{
+ return *(const unsigned char *)psz;
+}
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param ppsz Pointer to the string pointer. This will be updated to
+ * point to the char following the current code point.
+ * This is advanced one character forward on failure.
+ * @param pCp Where to store the code point.
+ * RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * the most frequent and simplest sequence, the rest is
+ * handled by RTStrGetCpExInternal().
+ */
+DECLINLINE(int) RTLatin1GetCpEx(const char **ppsz, PRTUNICP pCp)
+{
+ const unsigned char uch = **(const unsigned char **)ppsz;
+ (*ppsz)++;
+ *pCp = uch;
+ return VINF_SUCCESS;
+}
+
+/**
+ * Get the unicode code point at the given string position for a string of a
+ * given maximum length.
+ *
+ * @returns iprt status code.
+ * @retval VERR_END_OF_STRING if *pcch is 0. *pCp is set to RTUNICP_INVALID.
+ *
+ * @param ppsz Pointer to the string pointer. This will be updated to
+ * point to the char following the current code point.
+ * @param pcch Pointer to the maximum string length. This will be
+ * decremented by the size of the code point found.
+ * @param pCp Where to store the code point.
+ * RTUNICP_INVALID is stored here on failure.
+ */
+DECLINLINE(int) RTLatin1GetCpNEx(const char **ppsz, size_t *pcch, PRTUNICP pCp)
+{
+ if (RT_LIKELY(*pcch != 0))
+ {
+ const unsigned char uch = **(const unsigned char **)ppsz;
+ (*ppsz)++;
+ (*pcch)--;
+ *pCp = uch;
+ return VINF_SUCCESS;
+ }
+ *pCp = RTUNICP_INVALID;
+ return VERR_END_OF_STRING;
+}
+
+/**
+ * Get the Latin-1 size in characters of a given Unicode code point.
+ *
+ * The code point is expected to be a valid Unicode one, but not necessarily in
+ * the range supported by Latin-1.
+ *
+ * @returns the size in characters, or zero if there is no Latin-1 encoding
+ */
+DECLINLINE(size_t) RTLatin1CpSize(RTUNICP CodePoint)
+{
+ if (CodePoint < 0x100)
+ return 1;
+ return 0;
+}
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by psz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param psz The string.
+ * @param CodePoint The code point to write.
+ * This should not be RTUNICP_INVALID or any other
+ * character out of the Latin-1 range.
+ */
+DECLINLINE(char *) RTLatin1PutCp(char *psz, RTUNICP CodePoint)
+{
+ AssertReturn(CodePoint < 0x100, NULL);
+ *psz++ = (unsigned char)CodePoint;
+ return psz;
+}
+
+/**
+ * Skips ahead, past the current code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param psz Pointer to the current code point.
+ * @remark This will not move the next valid code point, only past the current one.
+ */
+DECLINLINE(char *) RTLatin1NextCp(const char *psz)
+{
+ psz++;
+ return (char *)psz;
+}
+
+/**
+ * Skips back to the previous code point.
+ *
+ * @returns Pointer to the char before the current code point.
+ * @returns pszStart on failure.
+ * @param pszStart Pointer to the start of the string.
+ * @param psz Pointer to the current code point.
+ */
+DECLINLINE(char *) RTLatin1PrevCp(const char *psz)
+{
+ psz--;
+ return (char *)psz;
+}
+
+
+/** @page pg_rt_str_format The IPRT Format Strings
+ *
+ * IPRT implements most of the commonly used format types and flags with the
+ * exception of floating point which is completely missing. In addition IPRT
+ * provides a number of IPRT specific format types for the IPRT typedefs and
+ * other useful things. Note that several of these extensions are similar to
+ * \%p and doesn't care much if you try add formating flags/width/precision.
+ *
+ *
+ * Group 0a, The commonly used format types:
+ * - \%s - Takes a pointer to a zero terminated string (UTF-8) and
+ * prints it with the optionally adjustment (width, -) and
+ * length restriction (precision).
+ * - \%ls - Same as \%s except that the input is UTF-16 (output UTF-8).
+ * - \%Ls - Same as \%s except that the input is UCS-32 (output UTF-8).
+ * - \%S - Same as \%s, used to convert to current codeset but this is
+ * now done by the streams code. Deprecated, use \%s.
+ * - \%lS - Ditto. Deprecated, use \%ls.
+ * - \%LS - Ditto. Deprecated, use \%Ls.
+ * - \%c - Takes a char and prints it.
+ * - \%d - Takes a signed integer and prints it as decimal. Thousand
+ * separator (\'), zero padding (0), adjustment (-+), width,
+ * precision
+ * - \%i - Same as \%d.
+ * - \%u - Takes an unsigned integer and prints it as decimal. Thousand
+ * separator (\'), zero padding (0), adjustment (-+), width,
+ * precision
+ * - \%x - Takes an unsigned integer and prints it as lowercased
+ * hexadecimal. The special hash (\#) flag causes a '0x'
+ * prefixed to be printed. Zero padding (0), adjustment (-+),
+ * width, precision.
+ * - \%X - Same as \%x except that it is uppercased.
+ * - \%o - Takes an unsigned (?) integer and prints it as octal. Zero
+ * padding (0), adjustment (-+), width, precision.
+ * - \%p - Takes a pointer (void technically) and prints it. Zero
+ * padding (0), adjustment (-+), width, precision.
+ *
+ * The \%d, \%i, \%u, \%x, \%X and \%o format types support the following
+ * argument type specifiers:
+ * - \%ll - long long (uint64_t).
+ * - \%L - long long (uint64_t).
+ * - \%l - long (uint32_t, uint64_t)
+ * - \%h - short (int16_t).
+ * - \%hh - char (int8_t).
+ * - \%H - char (int8_t).
+ * - \%z - size_t.
+ * - \%j - intmax_t (int64_t).
+ * - \%t - ptrdiff_t.
+ * The type in parentheses is typical sizes, however when printing those types
+ * you are better off using the special group 2 format types below (\%RX32 and
+ * such).
+ *
+ *
+ * Group 0b, IPRT format tricks:
+ * - %M - Replaces the format string, takes a string pointer.
+ * - %N - Nested formatting, takes a pointer to a format string
+ * followed by the pointer to a va_list variable. The va_list
+ * variable will not be modified and the caller must do va_end()
+ * on it. Make sure the va_list variable is NOT in a parameter
+ * list or some gcc versions/targets may get it all wrong.
+ *
+ *
+ * Group 1, the basic runtime typedefs (excluding those which obviously are
+ * pointer):
+ * - \%RTbool - Takes a bool value and prints 'true', 'false', or '!%d!'.
+ * - \%RTfile - Takes a #RTFILE value.
+ * - \%RTfmode - Takes a #RTFMODE value.
+ * - \%RTfoff - Takes a #RTFOFF value.
+ * - \%RTfp16 - Takes a #RTFAR16 value.
+ * - \%RTfp32 - Takes a #RTFAR32 value.
+ * - \%RTfp64 - Takes a #RTFAR64 value.
+ * - \%RTgid - Takes a #RTGID value.
+ * - \%RTino - Takes a #RTINODE value.
+ * - \%RTint - Takes a #RTINT value.
+ * - \%RTiop - Takes a #RTIOPORT value.
+ * - \%RTldrm - Takes a #RTLDRMOD value.
+ * - \%RTmac - Takes a #PCRTMAC pointer.
+ * - \%RTnaddr - Takes a #PCRTNETADDR value.
+ * - \%RTnaipv4 - Takes a #RTNETADDRIPV4 value.
+ * - \%RTnaipv6 - Takes a #PCRTNETADDRIPV6 value.
+ * - \%RTnthrd - Takes a #RTNATIVETHREAD value.
+ * - \%RTnthrd - Takes a #RTNATIVETHREAD value.
+ * - \%RTproc - Takes a #RTPROCESS value.
+ * - \%RTptr - Takes a #RTINTPTR or #RTUINTPTR value (but not void *).
+ * - \%RTreg - Takes a #RTCCUINTREG value.
+ * - \%RTsel - Takes a #RTSEL value.
+ * - \%RTsem - Takes a #RTSEMEVENT, #RTSEMEVENTMULTI, #RTSEMMUTEX, #RTSEMFASTMUTEX, or #RTSEMRW value.
+ * - \%RTsock - Takes a #RTSOCKET value.
+ * - \%RTthrd - Takes a #RTTHREAD value.
+ * - \%RTuid - Takes a #RTUID value.
+ * - \%RTuint - Takes a #RTUINT value.
+ * - \%RTunicp - Takes a #RTUNICP value.
+ * - \%RTutf16 - Takes a #RTUTF16 value.
+ * - \%RTuuid - Takes a #PCRTUUID and will print the UUID as a string.
+ * - \%RTxuint - Takes a #RTUINT or #RTINT value, formatting it as hex.
+ * - \%RGi - Takes a #RTGCINT value.
+ * - \%RGp - Takes a #RTGCPHYS value.
+ * - \%RGr - Takes a #RTGCUINTREG value.
+ * - \%RGu - Takes a #RTGCUINT value.
+ * - \%RGv - Takes a #RTGCPTR, #RTGCINTPTR or #RTGCUINTPTR value.
+ * - \%RGx - Takes a #RTGCUINT or #RTGCINT value, formatting it as hex.
+ * - \%RHi - Takes a #RTHCINT value.
+ * - \%RHp - Takes a #RTHCPHYS value.
+ * - \%RHr - Takes a #RTHCUINTREG value.
+ * - \%RHu - Takes a #RTHCUINT value.
+ * - \%RHv - Takes a #RTHCPTR, #RTHCINTPTR or #RTHCUINTPTR value.
+ * - \%RHx - Takes a #RTHCUINT or #RTHCINT value, formatting it as hex.
+ * - \%RRv - Takes a #RTRCPTR, #RTRCINTPTR or #RTRCUINTPTR value.
+ * - \%RCi - Takes a #RTINT value.
+ * - \%RCp - Takes a #RTCCPHYS value.
+ * - \%RCr - Takes a #RTCCUINTREG value.
+ * - \%RCu - Takes a #RTUINT value.
+ * - \%RCv - Takes a #uintptr_t, #intptr_t, void * value.
+ * - \%RCx - Takes a #RTUINT or #RTINT value, formatting it as hex.
+ *
+ *
+ * Group 2, the generic integer types which are prefered over relying on what
+ * bit-count a 'long', 'short', or 'long long' has on a platform. This are
+ * highly prefered for the [u]intXX_t kind of types:
+ * - \%RI[8|16|32|64] - Signed integer value of the specifed bit count.
+ * - \%RU[8|16|32|64] - Unsigned integer value of the specifed bit count.
+ * - \%RX[8|16|32|64] - Hexadecimal integer value of the specifed bit count.
+ *
+ *
+ * Group 3, hex dumpers and other complex stuff which requires more than simple
+ * formatting:
+ * - \%Rhxd - Takes a pointer to the memory which is to be dumped in typical
+ * hex format. Use the precision to specify the length, and the width to
+ * set the number of bytes per line. Default width and precision is 16.
+ * - \%Rhxs - Takes a pointer to the memory to be displayed as a hex string,
+ * i.e. a series of space separated bytes formatted as two digit hex value.
+ * Use the precision to specify the length. Default length is 16 bytes.
+ * The width, if specified, is ignored.
+ * - \%Rrc - Takes an integer iprt status code as argument. Will insert the
+ * status code define corresponding to the iprt status code.
+ * - \%Rrs - Takes an integer iprt status code as argument. Will insert the
+ * short description of the specified status code.
+ * - \%Rrf - Takes an integer iprt status code as argument. Will insert the
+ * full description of the specified status code.
+ * - \%Rra - Takes an integer iprt status code as argument. Will insert the
+ * status code define + full description.
+ * - \%Rwc - Takes a long Windows error code as argument. Will insert the status
+ * code define corresponding to the Windows error code.
+ * - \%Rwf - Takes a long Windows error code as argument. Will insert the
+ * full description of the specified status code.
+ * - \%Rwa - Takes a long Windows error code as argument. Will insert the
+ * error code define + full description.
+ *
+ * - \%Rhrc - Takes a COM/XPCOM status code as argument. Will insert the status
+ * code define corresponding to the Windows error code.
+ * - \%Rhrf - Takes a COM/XPCOM status code as argument. Will insert the
+ * full description of the specified status code.
+ * - \%Rhra - Takes a COM/XPCOM error code as argument. Will insert the
+ * error code define + full description.
+ *
+ * - \%Rfn - Pretty printing of a function or method. It drops the
+ * return code and parameter list.
+ * - \%Rbn - Prints the base name. For dropping the path in
+ * order to save space when printing a path name.
+ *
+ * On other platforms, \%Rw? simply prints the argument in a form of 0xXXXXXXXX.
+ *
+ *
+ * Group 4, structure dumpers:
+ * - \%RDtimespec - Takes a PCRTTIMESPEC.
+ *
+ *
+ * Group 5, XML / HTML escapers:
+ * - \%RMas - Takes a string pointer (const char *) and outputs
+ * it as an attribute value with the proper escaping.
+ * This typically ends up in double quotes.
+ *
+ * - \%RMes - Takes a string pointer (const char *) and outputs
+ * it as an element with the necessary escaping.
+ *
+ * Group 6, CPU Architecture Register dumpers:
+ * - \%RAx86[reg] - Takes a 64-bit register value if the register is
+ * 64-bit or smaller. Check the code wrt which
+ * registers are implemented.
+ *
+ */
+
+#ifndef DECLARED_FNRTSTROUTPUT /* duplicated in iprt/log.h */
+# define DECLARED_FNRTSTROUTPUT
+/**
+ * Output callback.
+ *
+ * @returns number of bytes written.
+ * @param pvArg User argument.
+ * @param pachChars Pointer to an array of utf-8 characters.
+ * @param cbChars Number of bytes in the character array pointed to by pachChars.
+ */
+typedef DECLCALLBACK(size_t) FNRTSTROUTPUT(void *pvArg, const char *pachChars, size_t cbChars);
+/** Pointer to callback function. */
+typedef FNRTSTROUTPUT *PFNRTSTROUTPUT;
+#endif
+
+/** Format flag.
+ * These are used by RTStrFormat extensions and RTStrFormatNumber, mind
+ * that not all flags makes sense to both of the functions.
+ * @{ */
+#define RTSTR_F_CAPITAL 0x0001
+#define RTSTR_F_LEFT 0x0002
+#define RTSTR_F_ZEROPAD 0x0004
+#define RTSTR_F_SPECIAL 0x0008
+#define RTSTR_F_VALSIGNED 0x0010
+#define RTSTR_F_PLUS 0x0020
+#define RTSTR_F_BLANK 0x0040
+#define RTSTR_F_WIDTH 0x0080
+#define RTSTR_F_PRECISION 0x0100
+#define RTSTR_F_THOUSAND_SEP 0x0200
+
+#define RTSTR_F_BIT_MASK 0xf800
+#define RTSTR_F_8BIT 0x0800
+#define RTSTR_F_16BIT 0x1000
+#define RTSTR_F_32BIT 0x2000
+#define RTSTR_F_64BIT 0x4000
+#define RTSTR_F_128BIT 0x8000
+/** @} */
+
+/** @def RTSTR_GET_BIT_FLAG
+ * Gets the bit flag for the specified type.
+ */
+#define RTSTR_GET_BIT_FLAG(type) \
+ ( sizeof(type) * 8 == 32 ? RTSTR_F_32BIT \
+ : sizeof(type) * 8 == 64 ? RTSTR_F_64BIT \
+ : sizeof(type) * 8 == 16 ? RTSTR_F_16BIT \
+ : sizeof(type) * 8 == 8 ? RTSTR_F_8BIT \
+ : sizeof(type) * 8 == 128 ? RTSTR_F_128BIT \
+ : 0)
+
+
+/**
+ * Callback to format non-standard format specifiers.
+ *
+ * @returns The number of bytes formatted.
+ * @param pvArg Formatter argument.
+ * @param pfnOutput Pointer to output function.
+ * @param pvArgOutput Argument for the output function.
+ * @param ppszFormat Pointer to the format string pointer. Advance this till the char
+ * after the format specifier.
+ * @param pArgs Pointer to the argument list. Use this to fetch the arguments.
+ * @param cchWidth Format Width. -1 if not specified.
+ * @param cchPrecision Format Precision. -1 if not specified.
+ * @param fFlags Flags (RTSTR_NTFS_*).
+ * @param chArgSize The argument size specifier, 'l' or 'L'.
+ */
+typedef DECLCALLBACK(size_t) FNSTRFORMAT(void *pvArg, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char **ppszFormat, va_list *pArgs, int cchWidth,
+ int cchPrecision, unsigned fFlags, char chArgSize);
+/** Pointer to a FNSTRFORMAT() function. */
+typedef FNSTRFORMAT *PFNSTRFORMAT;
+
+
+/**
+ * Partial implementation of a printf like formatter.
+ * It doesn't do everything correct, and there is no floating point support.
+ * However, it supports custom formats by the means of a format callback.
+ *
+ * @returns number of bytes formatted.
+ * @param pfnOutput Output worker.
+ * Called in two ways. Normally with a string and its length.
+ * For termination, it's called with NULL for string, 0 for length.
+ * @param pvArgOutput Argument to the output worker.
+ * @param pfnFormat Custom format worker.
+ * @param pvArgFormat Argument to the format worker.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param InArgs Argument list.
+ */
+RTDECL(size_t) RTStrFormatV(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat, const char *pszFormat, va_list InArgs);
+
+/**
+ * Partial implementation of a printf like formatter.
+ * It doesn't do everything correct, and there is no floating point support.
+ * However, it supports custom formats by the means of a format callback.
+ *
+ * @returns number of bytes formatted.
+ * @param pfnOutput Output worker.
+ * Called in two ways. Normally with a string and its length.
+ * For termination, it's called with NULL for string, 0 for length.
+ * @param pvArgOutput Argument to the output worker.
+ * @param pfnFormat Custom format worker.
+ * @param pvArgFormat Argument to the format worker.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param ... Argument list.
+ */
+RTDECL(size_t) RTStrFormat(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, PFNSTRFORMAT pfnFormat, void *pvArgFormat, const char *pszFormat, ...);
+
+/**
+ * Formats an integer number according to the parameters.
+ *
+ * @returns Length of the formatted number.
+ * @param psz Pointer to output string buffer of sufficient size.
+ * @param u64Value Value to format.
+ * @param uiBase Number representation base.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(int) RTStrFormatNumber(char *psz, uint64_t u64Value, unsigned int uiBase, signed int cchWidth, signed int cchPrecision, unsigned int fFlags);
+
+/**
+ * Formats an unsigned 8-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param u8Value The value to format.
+ * @param uiBase Number representation base.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU8(char *pszBuf, size_t cbBuf, uint8_t u8Value, unsigned int uiBase,
+ signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 16-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param u16Value The value to format.
+ * @param uiBase Number representation base.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU16(char *pszBuf, size_t cbBuf, uint16_t u16Value, unsigned int uiBase,
+ signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 32-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param u32Value The value to format.
+ * @param uiBase Number representation base.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU32(char *pszBuf, size_t cbBuf, uint32_t u32Value, unsigned int uiBase,
+ signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 64-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param u64Value The value to format.
+ * @param uiBase Number representation base.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU64(char *pszBuf, size_t cbBuf, uint64_t u64Value, unsigned int uiBase,
+ signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an unsigned 128-bit number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param pu128Value The value to format.
+ * @param uiBase Number representation base.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatU128(char *pszBuf, size_t cbBuf, PCRTUINT128U pu128Value, unsigned int uiBase,
+ signed int cchWidth, signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an 80-bit extended floating point number.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param pr80Value The value to format.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatR80(char *pszBuf, size_t cbBuf, PCRTFLOAT80U pr80Value, signed int cchWidth,
+ signed int cchPrecision, uint32_t fFlags);
+
+/**
+ * Formats an 80-bit extended floating point number, version 2.
+ *
+ * @returns The length of the formatted number or VERR_BUFFER_OVERFLOW.
+ * @param pszBuf The output buffer.
+ * @param cbBuf The size of the output buffer.
+ * @param pr80Value The value to format.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags, RTSTR_F_XXX.
+ */
+RTDECL(ssize_t) RTStrFormatR80u2(char *pszBuf, size_t cbBuf, PCRTFLOAT80U2 pr80Value, signed int cchWidth,
+ signed int cchPrecision, uint32_t fFlags);
+
+
+
+/**
+ * Callback for formatting a type.
+ *
+ * This is registered using the RTStrFormatTypeRegister function and will
+ * be called during string formatting to handle the specified %R[type].
+ * The argument for this format type is assumed to be a pointer and it's
+ * passed in the @a pvValue argument.
+ *
+ * @returns Length of the formatted output.
+ * @param pfnOutput Output worker.
+ * @param pvArgOutput Argument to the output worker.
+ * @param pszType The type name.
+ * @param pvValue The argument value.
+ * @param cchWidth Width.
+ * @param cchPrecision Precision.
+ * @param fFlags Flags (NTFS_*).
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(size_t) FNRTSTRFORMATTYPE(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
+ const char *pszType, void const *pvValue,
+ int cchWidth, int cchPrecision, unsigned fFlags,
+ void *pvUser);
+/** Pointer to a FNRTSTRFORMATTYPE. */
+typedef FNRTSTRFORMATTYPE *PFNRTSTRFORMATTYPE;
+
+
+/**
+ * Register a format handler for a type.
+ *
+ * The format handler is used to handle '%R[type]' format types, where the argument
+ * in the vector is a pointer value (a bit restrictive, but keeps it simple).
+ *
+ * The caller must ensure that no other thread will be making use of any of
+ * the dynamic formatting type facilities simultaneously with this call.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_ALREADY_EXISTS if the type has already been registered.
+ * @retval VERR_TOO_MANY_OPEN_FILES if all the type slots has been allocated already.
+ *
+ * @param pszType The type name.
+ * @param pfnHandler The handler address. See FNRTSTRFORMATTYPE for details.
+ * @param pvUser The user argument to pass to the handler. See RTStrFormatTypeSetUser
+ * for how to update this later.
+ */
+RTDECL(int) RTStrFormatTypeRegister(const char *pszType, PFNRTSTRFORMATTYPE pfnHandler, void *pvUser);
+
+/**
+ * Deregisters a format type.
+ *
+ * The caller must ensure that no other thread will be making use of any of
+ * the dynamic formatting type facilities simultaneously with this call.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_FILE_NOT_FOUND if not found.
+ *
+ * @param pszType The type to deregister.
+ */
+RTDECL(int) RTStrFormatTypeDeregister(const char *pszType);
+
+/**
+ * Sets the user argument for a type.
+ *
+ * This can be used if a user argument needs relocating in GC.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_FILE_NOT_FOUND if not found.
+ *
+ * @param pszType The type to update.
+ * @param pvUser The new user argument value.
+ */
+RTDECL(int) RTStrFormatTypeSetUser(const char *pszType, void *pvUser);
+
+
+/**
+ * String printf.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ * terminator.
+ * @param pszBuffer Output buffer.
+ * @param cchBuffer Size of the output buffer.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param args The format argument.
+ */
+RTDECL(size_t) RTStrPrintfV(char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args);
+
+/**
+ * String printf.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ * terminator.
+ * @param pszBuffer Output buffer.
+ * @param cchBuffer Size of the output buffer.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param ... The format argument.
+ */
+RTDECL(size_t) RTStrPrintf(char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...);
+
+
+/**
+ * String printf with custom formatting.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ * terminator.
+ * @param pfnFormat Pointer to handler function for the custom formats.
+ * @param pvArg Argument to the pfnFormat function.
+ * @param pszBuffer Output buffer.
+ * @param cchBuffer Size of the output buffer.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param args The format argument.
+ */
+RTDECL(size_t) RTStrPrintfExV(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, va_list args);
+
+/**
+ * String printf with custom formatting.
+ *
+ * @returns The length of the returned string (in pszBuffer) excluding the
+ * terminator.
+ * @param pfnFormat Pointer to handler function for the custom formats.
+ * @param pvArg Argument to the pfnFormat function.
+ * @param pszBuffer Output buffer.
+ * @param cchBuffer Size of the output buffer.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param ... The format argument.
+ */
+RTDECL(size_t) RTStrPrintfEx(PFNSTRFORMAT pfnFormat, void *pvArg, char *pszBuffer, size_t cchBuffer, const char *pszFormat, ...);
+
+
+/**
+ * Allocating string printf (default tag).
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ * terminator.
+ * @returns -1 on failure.
+ * @param ppszBuffer Where to store the pointer to the allocated output buffer.
+ * The buffer should be freed using RTStrFree().
+ * On failure *ppszBuffer will be set to NULL.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param args The format argument.
+ */
+#define RTStrAPrintfV(ppszBuffer, pszFormat, args) RTStrAPrintfVTag((ppszBuffer), (pszFormat), (args), RTSTR_TAG)
+
+/**
+ * Allocating string printf (custom tag).
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ * terminator.
+ * @returns -1 on failure.
+ * @param ppszBuffer Where to store the pointer to the allocated output buffer.
+ * The buffer should be freed using RTStrFree().
+ * On failure *ppszBuffer will be set to NULL.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param args The format argument.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTStrAPrintfVTag(char **ppszBuffer, const char *pszFormat, va_list args, const char *pszTag);
+
+/**
+ * Allocating string printf.
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ * terminator.
+ * @returns -1 on failure.
+ * @param ppszBuffer Where to store the pointer to the allocated output buffer.
+ * The buffer should be freed using RTStrFree().
+ * On failure *ppszBuffer will be set to NULL.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param ... The format argument.
+ */
+DECLINLINE(int) RTStrAPrintf(char **ppszBuffer, const char *pszFormat, ...)
+{
+ int cbRet;
+ va_list va;
+ va_start(va, pszFormat);
+ cbRet = RTStrAPrintfVTag(ppszBuffer, pszFormat, va, RTSTR_TAG);
+ va_end(va);
+ return cbRet;
+}
+
+/**
+ * Allocating string printf (custom tag).
+ *
+ * @returns The length of the string in the returned *ppszBuffer excluding the
+ * terminator.
+ * @returns -1 on failure.
+ * @param ppszBuffer Where to store the pointer to the allocated output buffer.
+ * The buffer should be freed using RTStrFree().
+ * On failure *ppszBuffer will be set to NULL.
+ * @param pszTag Allocation tag used for statistics and such.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param ... The format argument.
+ */
+DECLINLINE(int) RTStrAPrintfTag(char **ppszBuffer, const char *pszTag, const char *pszFormat, ...)
+{
+ int cbRet;
+ va_list va;
+ va_start(va, pszFormat);
+ cbRet = RTStrAPrintfVTag(ppszBuffer, pszFormat, va, pszTag);
+ va_end(va);
+ return cbRet;
+}
+
+/**
+ * Allocating string printf, version 2.
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ * memory.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param args The format argument.
+ */
+#define RTStrAPrintf2V(pszFormat, args) RTStrAPrintf2VTag((pszFormat), (args), RTSTR_TAG)
+
+/**
+ * Allocating string printf, version 2.
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ * memory.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param args The format argument.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(char *) RTStrAPrintf2VTag(const char *pszFormat, va_list args, const char *pszTag);
+
+/**
+ * Allocating string printf, version 2 (default tag).
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ * memory.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param ... The format argument.
+ */
+DECLINLINE(char *) RTStrAPrintf2(const char *pszFormat, ...)
+{
+ char *pszRet;
+ va_list va;
+ va_start(va, pszFormat);
+ pszRet = RTStrAPrintf2VTag(pszFormat, va, RTSTR_TAG);
+ va_end(va);
+ return pszRet;
+}
+
+/**
+ * Allocating string printf, version 2 (custom tag).
+ *
+ * @returns Formatted string. Use RTStrFree() to free it. NULL when out of
+ * memory.
+ * @param pszTag Allocation tag used for statistics and such.
+ * @param pszFormat Pointer to the format string, @see pg_rt_str_format.
+ * @param ... The format argument.
+ */
+DECLINLINE(char *) RTStrAPrintf2Tag(const char *pszTag, const char *pszFormat, ...)
+{
+ char *pszRet;
+ va_list va;
+ va_start(va, pszFormat);
+ pszRet = RTStrAPrintf2VTag(pszFormat, va, pszTag);
+ va_end(va);
+ return pszRet;
+}
+
+/**
+ * Strips blankspaces from both ends of the string.
+ *
+ * @returns Pointer to first non-blank char in the string.
+ * @param psz The string to strip.
+ */
+RTDECL(char *) RTStrStrip(char *psz);
+
+/**
+ * Strips blankspaces from the start of the string.
+ *
+ * @returns Pointer to first non-blank char in the string.
+ * @param psz The string to strip.
+ */
+RTDECL(char *) RTStrStripL(const char *psz);
+
+/**
+ * Strips blankspaces from the end of the string.
+ *
+ * @returns psz.
+ * @param psz The string to strip.
+ */
+RTDECL(char *) RTStrStripR(char *psz);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param pszDst The destination buffer.
+ * @param cbDst The size of the destination buffer (in bytes).
+ * @param pszSrc The source string. NULL is not OK.
+ */
+RTDECL(int) RTStrCopy(char *pszDst, size_t cbDst, const char *pszSrc);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param pszDst The destination buffer.
+ * @param cbDst The size of the destination buffer (in bytes).
+ * @param pszSrc The source string. NULL is not OK.
+ * @param cchSrcMax The maximum number of chars (not code points) to
+ * copy from the source string, not counting the
+ * terminator as usual.
+ */
+RTDECL(int) RTStrCopyEx(char *pszDst, size_t cbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * String copy with overflow handling and buffer advancing.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param ppszDst Pointer to the destination buffer pointer.
+ * This will be advanced to the end of the copied
+ * bytes (points at the terminator). This is also
+ * updated on overflow.
+ * @param pcbDst Pointer to the destination buffer size
+ * variable. This will be updated in accord with
+ * the buffer pointer.
+ * @param pszSrc The source string. NULL is not OK.
+ */
+RTDECL(int) RTStrCopyP(char **ppszDst, size_t *pcbDst, const char *pszSrc);
+
+/**
+ * String copy with overflow handling.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param ppszDst Pointer to the destination buffer pointer.
+ * This will be advanced to the end of the copied
+ * bytes (points at the terminator). This is also
+ * updated on overflow.
+ * @param pcbDst Pointer to the destination buffer size
+ * variable. This will be updated in accord with
+ * the buffer pointer.
+ * @param pszSrc The source string. NULL is not OK.
+ * @param cchSrcMax The maximum number of chars (not code points) to
+ * copy from the source string, not counting the
+ * terminator as usual.
+ */
+RTDECL(int) RTStrCopyPEx(char **ppszDst, size_t *pcbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param pszDst The destination buffer.
+ * @param cbDst The size of the destination buffer (in bytes).
+ * @param pszSrc The source string. NULL is not OK.
+ */
+RTDECL(int) RTStrCat(char *pszDst, size_t cbDst, const char *pszSrc);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param pszDst The destination buffer.
+ * @param cbDst The size of the destination buffer (in bytes).
+ * @param pszSrc The source string. NULL is not OK.
+ * @param cchSrcMax The maximum number of chars (not code points) to
+ * copy from the source string, not counting the
+ * terminator as usual.
+ */
+RTDECL(int) RTStrCatEx(char *pszDst, size_t cbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * String concatenation with overflow handling.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param ppszDst Pointer to the destination buffer pointer.
+ * This will be advanced to the end of the copied
+ * bytes (points at the terminator). This is also
+ * updated on overflow.
+ * @param pcbDst Pointer to the destination buffer size
+ * variable. This will be updated in accord with
+ * the buffer pointer.
+ * @param pszSrc The source string. NULL is not OK.
+ */
+RTDECL(int) RTStrCatP(char **ppszDst, size_t *pcbDst, const char *pszSrc);
+
+/**
+ * String concatenation with overflow handling and buffer advancing.
+ *
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the destination buffer is too small. The
+ * buffer will contain as much of the string as it can hold, fully
+ * terminated.
+ *
+ * @param ppszDst Pointer to the destination buffer pointer.
+ * This will be advanced to the end of the copied
+ * bytes (points at the terminator). This is also
+ * updated on overflow.
+ * @param pcbDst Pointer to the destination buffer size
+ * variable. This will be updated in accord with
+ * the buffer pointer.
+ * @param pszSrc The source string. NULL is not OK.
+ * @param cchSrcMax The maximum number of chars (not code points) to
+ * copy from the source string, not counting the
+ * terminator as usual.
+ */
+RTDECL(int) RTStrCatPEx(char **ppszDst, size_t *pcbDst, const char *pszSrc, size_t cchSrcMax);
+
+/**
+ * Performs a case sensitive string compare between two UTF-8 strings.
+ *
+ * Encoding errors are ignored by the current implementation. So, the only
+ * difference between this and the CRT strcmp function is the handling of
+ * NULL arguments.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param psz1 First UTF-8 string. Null is allowed.
+ * @param psz2 Second UTF-8 string. Null is allowed.
+ */
+RTDECL(int) RTStrCmp(const char *psz1, const char *psz2);
+
+/**
+ * Performs a case sensitive string compare between two UTF-8 strings, given
+ * a maximum string length.
+ *
+ * Encoding errors are ignored by the current implementation. So, the only
+ * difference between this and the CRT strncmp function is the handling of
+ * NULL arguments.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param psz1 First UTF-8 string. Null is allowed.
+ * @param psz2 Second UTF-8 string. Null is allowed.
+ * @param cchMax The maximum string length
+ */
+RTDECL(int) RTStrNCmp(const char *psz1, const char *psz2, size_t cchMax);
+
+/**
+ * Performs a case insensitive string compare between two UTF-8 strings.
+ *
+ * This is a simplified compare, as only the simplified lower/upper case folding
+ * specified by the unicode specs are used. It does not consider character pairs
+ * as they are used in some languages, just simple upper & lower case compares.
+ *
+ * The result is the difference between the mismatching codepoints after they
+ * both have been lower cased.
+ *
+ * If the string encoding is invalid the function will assert (strict builds)
+ * and use RTStrCmp for the remainder of the string.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param psz1 First UTF-8 string. Null is allowed.
+ * @param psz2 Second UTF-8 string. Null is allowed.
+ */
+RTDECL(int) RTStrICmp(const char *psz1, const char *psz2);
+
+/**
+ * Performs a case insensitive string compare between two UTF-8 strings, given a
+ * maximum string length.
+ *
+ * This is a simplified compare, as only the simplified lower/upper case folding
+ * specified by the unicode specs are used. It does not consider character pairs
+ * as they are used in some languages, just simple upper & lower case compares.
+ *
+ * The result is the difference between the mismatching codepoints after they
+ * both have been lower cased.
+ *
+ * If the string encoding is invalid the function will assert (strict builds)
+ * and use RTStrCmp for the remainder of the string.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param psz1 First UTF-8 string. Null is allowed.
+ * @param psz2 Second UTF-8 string. Null is allowed.
+ * @param cchMax Maximum string length
+ */
+RTDECL(int) RTStrNICmp(const char *psz1, const char *psz2, size_t cchMax);
+
+/**
+ * Locates a case sensitive substring.
+ *
+ * If any of the two strings are NULL, then NULL is returned. If the needle is
+ * an empty string, then the haystack is returned (i.e. matches anything).
+ *
+ * @returns Pointer to the first occurrence of the substring if found, NULL if
+ * not.
+ *
+ * @param pszHaystack The string to search.
+ * @param pszNeedle The substring to search for.
+ *
+ * @remarks The difference between this and strstr is the handling of NULL
+ * pointers.
+ */
+RTDECL(char *) RTStrStr(const char *pszHaystack, const char *pszNeedle);
+
+/**
+ * Locates a case insensitive substring.
+ *
+ * If any of the two strings are NULL, then NULL is returned. If the needle is
+ * an empty string, then the haystack is returned (i.e. matches anything).
+ *
+ * @returns Pointer to the first occurrence of the substring if found, NULL if
+ * not.
+ *
+ * @param pszHaystack The string to search.
+ * @param pszNeedle The substring to search for.
+ *
+ */
+RTDECL(char *) RTStrIStr(const char *pszHaystack, const char *pszNeedle);
+
+/**
+ * Converts the string to lower case.
+ *
+ * @returns Pointer to the converted string.
+ * @param psz The string to convert.
+ */
+RTDECL(char *) RTStrToLower(char *psz);
+
+/**
+ * Converts the string to upper case.
+ *
+ * @returns Pointer to the converted string.
+ * @param psz The string to convert.
+ */
+RTDECL(char *) RTStrToUpper(char *psz);
+
+/**
+ * Find the length of a zero-terminated byte string, given
+ * a max string length.
+ *
+ * See also RTStrNLenEx.
+ *
+ * @returns The string length or cbMax. The returned length does not include
+ * the zero terminator if it was found.
+ *
+ * @param pszString The string.
+ * @param cchMax The max string length.
+ */
+RTDECL(size_t) RTStrNLen(const char *pszString, size_t cchMax);
+
+/**
+ * Find the length of a zero-terminated byte string, given
+ * a max string length.
+ *
+ * See also RTStrNLen.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if the string has a length less than cchMax.
+ * @retval VERR_BUFFER_OVERFLOW if the end of the string wasn't found
+ * before cchMax was reached.
+ *
+ * @param pszString The string.
+ * @param cchMax The max string length.
+ * @param pcch Where to store the string length excluding the
+ * terminator. This is set to cchMax if the terminator
+ * isn't found.
+ */
+RTDECL(int) RTStrNLenEx(const char *pszString, size_t cchMax, size_t *pcch);
+
+RT_C_DECLS_END
+
+/** The maximum size argument of a memchr call. */
+#define RTSTR_MEMCHR_MAX ((~(size_t)0 >> 1) - 15)
+
+/**
+ * Find the zero terminator in a string with a limited length.
+ *
+ * @returns Pointer to the zero terminator.
+ * @returns NULL if the zero terminator was not found.
+ *
+ * @param pszString The string.
+ * @param cchMax The max string length. RTSTR_MAX is fine.
+ */
+#if defined(__cplusplus) && !defined(DOXYGEN_RUNNING)
+DECLINLINE(char const *) RTStrEnd(char const *pszString, size_t cchMax)
+{
+ /* Avoid potential issues with memchr seen in glibc.
+ * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
+ while (cchMax > RTSTR_MEMCHR_MAX)
+ {
+ char const *pszRet = (char const *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
+ if (RT_LIKELY(pszRet))
+ return pszRet;
+ pszString += RTSTR_MEMCHR_MAX;
+ cchMax -= RTSTR_MEMCHR_MAX;
+ }
+ return (char const *)memchr(pszString, '\0', cchMax);
+}
+
+DECLINLINE(char *) RTStrEnd(char *pszString, size_t cchMax)
+#else
+DECLINLINE(char *) RTStrEnd(const char *pszString, size_t cchMax)
+#endif
+{
+ /* Avoid potential issues with memchr seen in glibc.
+ * See sysdeps/x86_64/memchr.S in glibc versions older than 2.11 */
+ while (cchMax > RTSTR_MEMCHR_MAX)
+ {
+ char *pszRet = (char *)memchr(pszString, '\0', RTSTR_MEMCHR_MAX);
+ if (RT_LIKELY(pszRet))
+ return pszRet;
+ pszString += RTSTR_MEMCHR_MAX;
+ cchMax -= RTSTR_MEMCHR_MAX;
+ }
+ return (char *)memchr(pszString, '\0', cchMax);
+}
+
+RT_C_DECLS_BEGIN
+
+/**
+ * Matches a simple string pattern.
+ *
+ * @returns true if the string matches the pattern, otherwise false.
+ *
+ * @param pszPattern The pattern. Special chars are '*' and '?', where the
+ * asterisk matches zero or more characters and question
+ * mark matches exactly one character.
+ * @param pszString The string to match against the pattern.
+ */
+RTDECL(bool) RTStrSimplePatternMatch(const char *pszPattern, const char *pszString);
+
+/**
+ * Matches a simple string pattern, neither which needs to be zero terminated.
+ *
+ * This is identical to RTStrSimplePatternMatch except that you can optionally
+ * specify the length of both the pattern and the string. The function will
+ * stop when it hits a string terminator or either of the lengths.
+ *
+ * @returns true if the string matches the pattern, otherwise false.
+ *
+ * @param pszPattern The pattern. Special chars are '*' and '?', where the
+ * asterisk matches zero or more characters and question
+ * mark matches exactly one character.
+ * @param cchPattern The pattern length. Pass RTSTR_MAX if you don't know the
+ * length and wish to stop at the string terminator.
+ * @param pszString The string to match against the pattern.
+ * @param cchString The string length. Pass RTSTR_MAX if you don't know the
+ * length and wish to match up to the string terminator.
+ */
+RTDECL(bool) RTStrSimplePatternNMatch(const char *pszPattern, size_t cchPattern,
+ const char *pszString, size_t cchString);
+
+/**
+ * Matches multiple patterns against a string.
+ *
+ * The patterns are separated by the pipe character (|).
+ *
+ * @returns true if the string matches the pattern, otherwise false.
+ *
+ * @param pszPatterns The patterns.
+ * @param cchPatterns The lengths of the patterns to use. Pass RTSTR_MAX to
+ * stop at the terminator.
+ * @param pszString The string to match against the pattern.
+ * @param cchString The string length. Pass RTSTR_MAX stop stop at the
+ * terminator.
+ * @param poffPattern Offset into the patterns string of the patttern that
+ * matched. If no match, this will be set to RTSTR_MAX.
+ * This is optional, NULL is fine.
+ */
+RTDECL(bool) RTStrSimplePatternMultiMatch(const char *pszPatterns, size_t cchPatterns,
+ const char *pszString, size_t cchString,
+ size_t *poffPattern);
+
+/**
+ * Compares two version strings RTStrICmp fashion.
+ *
+ * The version string is split up into sections at punctuation, spaces,
+ * underscores, dashes and plus signs. The sections are then split up into
+ * numeric and string sub-sections. Finally, the sub-sections are compared
+ * in a numeric or case insesntivie fashion depending on what they are.
+ *
+ * The following strings are considered to be equal: "1.0.0", "1.00.0", "1.0",
+ * "1". These aren't: "1.0.0r993", "1.0", "1.0r993", "1.0_Beta3", "1.1"
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ *
+ * @param pszVer1 First version string to compare.
+ * @param pszVer2 Second version string to compare first version with.
+ */
+RTDECL(int) RTStrVersionCompare(const char *pszVer1, const char *pszVer2);
+
+
+/** @defgroup rt_str_conv String To/From Number Conversions
+ * @ingroup grp_rt_str
+ * @{ */
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu64 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint64_t *pu64);
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_TRAILING_CHARS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu64 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBase, uint64_t *pu64);
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 64-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(uint64_t) RTStrToUInt64(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 32-bit unsigned number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu32 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32);
+
+/**
+ * Converts a string representation of a number to a 32-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_TRAILING_CHARS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu32 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32);
+
+/**
+ * Converts a string representation of a number to a 64-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 32-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(uint32_t) RTStrToUInt32(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu16 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint16_t *pu16);
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_TRAILING_CHARS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu16 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt16Full(const char *pszValue, unsigned uBase, uint16_t *pu16);
+
+/**
+ * Converts a string representation of a number to a 16-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 16-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(uint16_t) RTStrToUInt16(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu8 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint8_t *pu8);
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_NEGATIVE_UNSIGNED
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_TRAILING_CHARS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pu8 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBase, uint8_t *pu8);
+
+/**
+ * Converts a string representation of a number to a 8-bit unsigned number.
+ * The base is guessed.
+ *
+ * @returns 8-bit unsigned number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(uint8_t) RTStrToUInt8(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi64 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, int64_t *pi64);
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VINF_SUCCESS
+ * @retval VERR_TRAILING_CHARS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi64 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt64Full(const char *pszValue, unsigned uBase, int64_t *pi64);
+
+/**
+ * Converts a string representation of a number to a 64-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 64-bit signed number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(int64_t) RTStrToInt64(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi32 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, int32_t *pi32);
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VINF_SUCCESS
+ * @retval VERR_TRAILING_CHARS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi32 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt32Full(const char *pszValue, unsigned uBase, int32_t *pi32);
+
+/**
+ * Converts a string representation of a number to a 32-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 32-bit signed number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(int32_t) RTStrToInt32(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi16 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, int16_t *pi16);
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VINF_SUCCESS
+ * @retval VERR_TRAILING_CHARS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi16 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt16Full(const char *pszValue, unsigned uBase, int16_t *pi16);
+
+/**
+ * Converts a string representation of a number to a 16-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 16-bit signed number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(int16_t) RTStrToInt16(const char *pszValue);
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param ppszNext Where to store the pointer to the first char following the number. (Optional)
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi8 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, int8_t *pi8);
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number,
+ * making sure the full string is converted.
+ *
+ * @returns iprt status code.
+ * Warnings are used to indicate conversion problems.
+ * @retval VWRN_NUMBER_TOO_BIG
+ * @retval VINF_SUCCESS
+ * @retval VERR_TRAILING_CHARS
+ * @retval VERR_TRAILING_SPACES
+ * @retval VERR_NO_DIGITS
+ *
+ * @param pszValue Pointer to the string value.
+ * @param uBase The base of the representation used.
+ * If 0 the function will look for known prefixes before defaulting to 10.
+ * @param pi8 Where to store the converted number. (optional)
+ */
+RTDECL(int) RTStrToInt8Full(const char *pszValue, unsigned uBase, int8_t *pi8);
+
+/**
+ * Converts a string representation of a number to a 8-bit signed number.
+ * The base is guessed.
+ *
+ * @returns 8-bit signed number on success.
+ * @returns 0 on failure.
+ * @param pszValue Pointer to the string value.
+ */
+RTDECL(int8_t) RTStrToInt8(const char *pszValue);
+
+/**
+ * Formats a buffer stream as hex bytes.
+ *
+ * The default is no separating spaces or line breaks or anything.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_POINTER if any of the pointers are wrong.
+ * @retval VERR_BUFFER_OVERFLOW if the buffer is insufficent to hold the bytes.
+ *
+ * @param pszBuf Output string buffer.
+ * @param cchBuf The size of the output buffer.
+ * @param pv Pointer to the bytes to stringify.
+ * @param cb The number of bytes to stringify.
+ * @param fFlags Must be zero, reserved for future use.
+ */
+RTDECL(int) RTStrPrintHexBytes(char *pszBuf, size_t cchBuf, void const *pv, size_t cb, uint32_t fFlags);
+
+/**
+ * Converts a string of hex bytes back into binary data.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_POINTER if any of the pointers are wrong.
+ * @retval VERR_BUFFER_OVERFLOW if the string contains too many hex bytes.
+ * @retval VERR_BUFFER_UNDERFLOW if there aren't enough hex bytes to fill up
+ * the output buffer.
+ * @retval VERR_UNEVEN_INPUT if the input contains a half byte.
+ * @retval VERR_NO_DIGITS
+ * @retval VWRN_TRAILING_CHARS
+ * @retval VWRN_TRAILING_SPACES
+ *
+ * @param pszHex The string containing the hex bytes.
+ * @param pv Output buffer.
+ * @param cb The size of the output buffer.
+ * @param fFlags Must be zero, reserved for future use.
+ */
+RTDECL(int) RTStrConvertHexBytes(char const *pszHex, void *pv, size_t cb, uint32_t fFlags);
+
+/** @} */
+
+
+/** @defgroup rt_str_space Unique String Space
+ * @ingroup grp_rt_str
+ * @{
+ */
+
+/** Pointer to a string name space container node core. */
+typedef struct RTSTRSPACECORE *PRTSTRSPACECORE;
+/** Pointer to a pointer to a string name space container node core. */
+typedef PRTSTRSPACECORE *PPRTSTRSPACECORE;
+
+/**
+ * String name space container node core.
+ */
+typedef struct RTSTRSPACECORE
+{
+ /** Hash key. Don't touch. */
+ uint32_t Key;
+ /** Pointer to the left leaf node. Don't touch. */
+ PRTSTRSPACECORE pLeft;
+ /** Pointer to the left right node. Don't touch. */
+ PRTSTRSPACECORE pRight;
+ /** Pointer to the list of string with the same key. Don't touch. */
+ PRTSTRSPACECORE pList;
+ /** Height of this tree: max(heigth(left), heigth(right)) + 1. Don't touch */
+ unsigned char uchHeight;
+ /** The string length. Read only! */
+ size_t cchString;
+ /** Pointer to the string. Read only! */
+ const char *pszString;
+} RTSTRSPACECORE;
+
+/** String space. (Initialize with NULL.) */
+typedef PRTSTRSPACECORE RTSTRSPACE;
+/** Pointer to a string space. */
+typedef PPRTSTRSPACECORE PRTSTRSPACE;
+
+
+/**
+ * Inserts a string into a unique string space.
+ *
+ * @returns true on success.
+ * @returns false if the string collided with an existing string.
+ * @param pStrSpace The space to insert it into.
+ * @param pStr The string node.
+ */
+RTDECL(bool) RTStrSpaceInsert(PRTSTRSPACE pStrSpace, PRTSTRSPACECORE pStr);
+
+/**
+ * Removes a string from a unique string space.
+ *
+ * @returns Pointer to the removed string node.
+ * @returns NULL if the string was not found in the string space.
+ * @param pStrSpace The space to remove it from.
+ * @param pszString The string to remove.
+ */
+RTDECL(PRTSTRSPACECORE) RTStrSpaceRemove(PRTSTRSPACE pStrSpace, const char *pszString);
+
+/**
+ * Gets a string from a unique string space.
+ *
+ * @returns Pointer to the string node.
+ * @returns NULL if the string was not found in the string space.
+ * @param pStrSpace The space to get it from.
+ * @param pszString The string to get.
+ */
+RTDECL(PRTSTRSPACECORE) RTStrSpaceGet(PRTSTRSPACE pStrSpace, const char *pszString);
+
+/**
+ * Gets a string from a unique string space.
+ *
+ * @returns Pointer to the string node.
+ * @returns NULL if the string was not found in the string space.
+ * @param pStrSpace The space to get it from.
+ * @param pszString The string to get.
+ * @param cchMax The max string length to evaluate. Passing
+ * RTSTR_MAX is ok and makes it behave just like
+ * RTStrSpaceGet.
+ */
+RTDECL(PRTSTRSPACECORE) RTStrSpaceGetN(PRTSTRSPACE pStrSpace, const char *pszString, size_t cchMax);
+
+/**
+ * Callback function for RTStrSpaceEnumerate() and RTStrSpaceDestroy().
+ *
+ * @returns 0 on continue.
+ * @returns Non-zero to aborts the operation.
+ * @param pStr The string node
+ * @param pvUser The user specified argument.
+ */
+typedef DECLCALLBACK(int) FNRTSTRSPACECALLBACK(PRTSTRSPACECORE pStr, void *pvUser);
+/** Pointer to callback function for RTStrSpaceEnumerate() and RTStrSpaceDestroy(). */
+typedef FNRTSTRSPACECALLBACK *PFNRTSTRSPACECALLBACK;
+
+/**
+ * Destroys the string space.
+ *
+ * The caller supplies a callback which will be called for each of the string
+ * nodes in for freeing their memory and other resources.
+ *
+ * @returns 0 or what ever non-zero return value pfnCallback returned
+ * when aborting the destruction.
+ * @param pStrSpace The space to destroy.
+ * @param pfnCallback The callback.
+ * @param pvUser The user argument.
+ */
+RTDECL(int) RTStrSpaceDestroy(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser);
+
+/**
+ * Enumerates the string space.
+ * The caller supplies a callback which will be called for each of
+ * the string nodes.
+ *
+ * @returns 0 or what ever non-zero return value pfnCallback returned
+ * when aborting the destruction.
+ * @param pStrSpace The space to enumerate.
+ * @param pfnCallback The callback.
+ * @param pvUser The user argument.
+ */
+RTDECL(int) RTStrSpaceEnumerate(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser);
+
+/** @} */
+
+
+/** @defgroup rt_str_hash Sting hashing
+ * @ingroup grp_rt_str
+ * @{ */
+
+/**
+ * Hashes the given string using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param pszString The string to hash.
+ */
+RTDECL(uint32_t) RTStrHash1(const char *pszString);
+
+/**
+ * Hashes the given string using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param pszString The string to hash.
+ * @param cchString The max length to hash. Hashing will stop if the
+ * terminator character is encountered first. Passing
+ * RTSTR_MAX is fine.
+ */
+RTDECL(uint32_t) RTStrHash1N(const char *pszString, size_t cchString);
+
+/**
+ * Hashes the given strings as if they were concatenated using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param cPairs The number of string / length pairs in the
+ * ellipsis.
+ * @param ... List of string (const char *) and length
+ * (size_t) pairs. Passing RTSTR_MAX as the size is
+ * fine.
+ */
+RTDECL(uint32_t) RTStrHash1ExN(size_t cPairs, ...);
+
+/**
+ * Hashes the given strings as if they were concatenated using algorithm \#1.
+ *
+ * @returns String hash.
+ * @param cPairs The number of string / length pairs in the @a va.
+ * @param va List of string (const char *) and length
+ * (size_t) pairs. Passing RTSTR_MAX as the size is
+ * fine.
+ */
+RTDECL(uint32_t) RTStrHash1ExNV(size_t cPairs, va_list va);
+
+/** @} */
+
+
+/** @defgroup rt_str_utf16 UTF-16 String Manipulation
+ * @ingroup grp_rt_str
+ * @{
+ */
+
+/**
+ * Free a UTF-16 string allocated by RTStrToUtf16(), RTStrToUtf16Ex(),
+ * RTLatin1ToUtf16(), RTLatin1ToUtf16Ex(), RTUtf16Dup() or RTUtf16DupEx().
+ *
+ * @returns iprt status code.
+ * @param pwszString The UTF-16 string to free. NULL is accepted.
+ */
+RTDECL(void) RTUtf16Free(PRTUTF16 pwszString);
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (default tag).
+ *
+ * @returns Pointer to the allocated string copy. Use RTUtf16Free() to free it.
+ * @returns NULL when out of memory.
+ * @param pwszString UTF-16 string to duplicate.
+ * @remark This function will not make any attempt to validate the encoding.
+ */
+#define RTUtf16Dup(pwszString) RTUtf16DupTag((pwszString), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (custom tag).
+ *
+ * @returns Pointer to the allocated string copy. Use RTUtf16Free() to free it.
+ * @returns NULL when out of memory.
+ * @param pwszString UTF-16 string to duplicate.
+ * @param pszTag Allocation tag used for statistics and such.
+ * @remark This function will not make any attempt to validate the encoding.
+ */
+RTDECL(PRTUTF16) RTUtf16DupTag(PCRTUTF16 pwszString, const char *pszTag);
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (default tag).
+ *
+ * @returns iprt status code.
+ * @param ppwszString Receives pointer of the allocated UTF-16 string.
+ * The returned pointer must be freed using RTUtf16Free().
+ * @param pwszString UTF-16 string to duplicate.
+ * @param cwcExtra Number of extra RTUTF16 items to allocate.
+ * @remark This function will not make any attempt to validate the encoding.
+ */
+#define RTUtf16DupEx(ppwszString, pwszString, cwcExtra) \
+ RTUtf16DupExTag((ppwszString), (pwszString), (cwcExtra), RTSTR_TAG)
+
+/**
+ * Allocates a new copy of the specified UTF-16 string (custom tag).
+ *
+ * @returns iprt status code.
+ * @param ppwszString Receives pointer of the allocated UTF-16 string.
+ * The returned pointer must be freed using RTUtf16Free().
+ * @param pwszString UTF-16 string to duplicate.
+ * @param cwcExtra Number of extra RTUTF16 items to allocate.
+ * @param pszTag Allocation tag used for statistics and such.
+ * @remark This function will not make any attempt to validate the encoding.
+ */
+RTDECL(int) RTUtf16DupExTag(PRTUTF16 *ppwszString, PCRTUTF16 pwszString, size_t cwcExtra, const char *pszTag);
+
+/**
+ * Returns the length of a UTF-16 string in UTF-16 characters
+ * without trailing '\\0'.
+ *
+ * Surrogate pairs counts as two UTF-16 characters here. Use RTUtf16CpCnt()
+ * to get the exact number of code points in the string.
+ *
+ * @returns The number of RTUTF16 items in the string.
+ * @param pwszString Pointer the UTF-16 string.
+ * @remark This function will not make any attempt to validate the encoding.
+ */
+RTDECL(size_t) RTUtf16Len(PCRTUTF16 pwszString);
+
+/**
+ * Performs a case sensitive string compare between two UTF-16 strings.
+ *
+ * @returns < 0 if the first string less than the second string.s
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param pwsz1 First UTF-16 string. Null is allowed.
+ * @param pwsz2 Second UTF-16 string. Null is allowed.
+ * @remark This function will not make any attempt to validate the encoding.
+ */
+RTDECL(int) RTUtf16Cmp(register PCRTUTF16 pwsz1, register PCRTUTF16 pwsz2);
+
+/**
+ * Performs a case insensitive string compare between two UTF-16 strings.
+ *
+ * This is a simplified compare, as only the simplified lower/upper case folding
+ * specified by the unicode specs are used. It does not consider character pairs
+ * as they are used in some languages, just simple upper & lower case compares.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param pwsz1 First UTF-16 string. Null is allowed.
+ * @param pwsz2 Second UTF-16 string. Null is allowed.
+ */
+RTDECL(int) RTUtf16ICmp(PCRTUTF16 pwsz1, PCRTUTF16 pwsz2);
+
+/**
+ * Performs a case insensitive string compare between two UTF-16 strings
+ * using the current locale of the process (if applicable).
+ *
+ * This differs from RTUtf16ICmp() in that it will try, if a locale with the
+ * required data is available, to do a correct case-insensitive compare. It
+ * follows that it is more complex and thereby likely to be more expensive.
+ *
+ * @returns < 0 if the first string less than the second string.
+ * @returns 0 if the first string identical to the second string.
+ * @returns > 0 if the first string greater than the second string.
+ * @param pwsz1 First UTF-16 string. Null is allowed.
+ * @param pwsz2 Second UTF-16 string. Null is allowed.
+ */
+RTDECL(int) RTUtf16LocaleICmp(PCRTUTF16 pwsz1, PCRTUTF16 pwsz2);
+
+/**
+ * Folds a UTF-16 string to lowercase.
+ *
+ * This is a very simple folding; is uses the simple lowercase
+ * code point, it is not related to any locale just the most common
+ * lowercase codepoint setup by the unicode specs, and it will not
+ * create new surrogate pairs or remove existing ones.
+ *
+ * @returns Pointer to the passed in string.
+ * @param pwsz The string to fold.
+ */
+RTDECL(PRTUTF16) RTUtf16ToLower(PRTUTF16 pwsz);
+
+/**
+ * Folds a UTF-16 string to uppercase.
+ *
+ * This is a very simple folding; is uses the simple uppercase
+ * code point, it is not related to any locale just the most common
+ * uppercase codepoint setup by the unicode specs, and it will not
+ * create new surrogate pairs or remove existing ones.
+ *
+ * @returns Pointer to the passed in string.
+ * @param pwsz The string to fold.
+ */
+RTDECL(PRTUTF16) RTUtf16ToUpper(PRTUTF16 pwsz);
+
+/**
+ * Sanitise a (valid) UTF-16 string by replacing all characters outside a white
+ * list in-place by an ASCII replacement character. Multi-byte characters will
+ * be replaced byte by byte.
+ *
+ * @returns The number of code points replaced, or a negative value if the
+ * string is not correctly encoded. In this last case the string
+ * may be partially processed.
+ * @param pwsz The string to sanitise.
+ * @param puszValidSets A zero-terminated array of pairs of Unicode points.
+ * Each pair is the start and end point of a range,
+ * and the union of these ranges forms the white list.
+ * @param chReplacement The ASCII replacement character.
+ */
+RTDECL(ssize_t) RTUtf16PurgeComplementSet(PRTUTF16 pwsz, PCRTUNICP puszValidSet, char chReplacement);
+
+/**
+ * Translate a UTF-16 string into a UTF-8 allocating the result buffer (default
+ * tag).
+ *
+ * @returns iprt status code.
+ * @param pwszString UTF-16 string to convert.
+ * @param ppszString Receives pointer of allocated UTF-8 string on
+ * success, and is always set to NULL on failure.
+ * The returned pointer must be freed using RTStrFree().
+ */
+#define RTUtf16ToUtf8(pwszString, ppszString) RTUtf16ToUtf8Tag((pwszString), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-16 string into a UTF-8 allocating the result buffer.
+ *
+ * @returns iprt status code.
+ * @param pwszString UTF-16 string to convert.
+ * @param ppszString Receives pointer of allocated UTF-8 string on
+ * success, and is always set to NULL on failure.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTUtf16ToUtf8Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag);
+
+/**
+ * Translates UTF-16 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (default tag).
+ *
+ * @returns iprt status code.
+ * @param pwszString The UTF-16 string to convert.
+ * @param cwcString The number of RTUTF16 items to translate from pwszString.
+ * The translation will stop when reaching cwcString or the terminator ('\\0').
+ * Use RTSTR_MAX to translate the entire string.
+ * @param ppsz If cch is non-zero, this must either be pointing to a pointer to
+ * a buffer of the specified size, or pointer to a NULL pointer.
+ * If *ppsz is NULL or cch is zero a buffer of at least cch chars
+ * will be allocated to hold the translated string.
+ * If a buffer was requested it must be freed using RTStrFree().
+ * @param cch The buffer size in chars (the type). This includes the terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ */
+#define RTUtf16ToUtf8Ex(pwszString, cwcString, ppsz, cch, pcch) \
+ RTUtf16ToUtf8ExTag((pwszString), (cwcString), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates UTF-16 to UTF-8 using buffer provided by the caller or a fittingly
+ * sized buffer allocated by the function (custom tag).
+ *
+ * @returns iprt status code.
+ * @param pwszString The UTF-16 string to convert.
+ * @param cwcString The number of RTUTF16 items to translate from pwszString.
+ * The translation will stop when reaching cwcString or the terminator ('\\0').
+ * Use RTSTR_MAX to translate the entire string.
+ * @param ppsz If cch is non-zero, this must either be pointing to a pointer to
+ * a buffer of the specified size, or pointer to a NULL pointer.
+ * If *ppsz is NULL or cch is zero a buffer of at least cch chars
+ * will be allocated to hold the translated string.
+ * If a buffer was requested it must be freed using RTStrFree().
+ * @param cch The buffer size in chars (the type). This includes the terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTUtf16ToUtf8ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
+
+/**
+ * Calculates the length of the UTF-16 string in UTF-8 chars (bytes).
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected. The primary purpose of this function is to
+ * help allocate buffers for RTUtf16ToUtf8() of the correct size. For most
+ * other purposes RTUtf16ToUtf8Ex() should be used.
+ *
+ * @returns Number of char (bytes).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param pwsz The UTF-16 string.
+ */
+RTDECL(size_t) RTUtf16CalcUtf8Len(PCRTUTF16 pwsz);
+
+/**
+ * Calculates the length of the UTF-16 string in UTF-8 chars (bytes).
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param pwsz The string.
+ * @param cwc The max string length. Use RTSTR_MAX to process the entire string.
+ * @param pcch Where to store the string length (in bytes). Optional.
+ * This is undefined on failure.
+ */
+RTDECL(int) RTUtf16CalcUtf8LenEx(PCRTUTF16 pwsz, size_t cwc, size_t *pcch);
+
+/**
+ * Translate a UTF-16 string into a Latin-1 (ISO-8859-1) allocating the result
+ * buffer (default tag).
+ *
+ * @returns iprt status code.
+ * @param pwszString UTF-16 string to convert.
+ * @param ppszString Receives pointer of allocated Latin1 string on
+ * success, and is always set to NULL on failure.
+ * The returned pointer must be freed using RTStrFree().
+ */
+#define RTUtf16ToLatin1(pwszString, ppszString) RTUtf16ToLatin1Tag((pwszString), (ppszString), RTSTR_TAG)
+
+/**
+ * Translate a UTF-16 string into a Latin-1 (ISO-8859-1) allocating the result
+ * buffer (custom tag).
+ *
+ * @returns iprt status code.
+ * @param pwszString UTF-16 string to convert.
+ * @param ppszString Receives pointer of allocated Latin1 string on
+ * success, and is always set to NULL on failure.
+ * The returned pointer must be freed using RTStrFree().
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTUtf16ToLatin1Tag(PCRTUTF16 pwszString, char **ppszString, const char *pszTag);
+
+/**
+ * Translates UTF-16 to Latin-1 (ISO-8859-1) using buffer provided by the caller
+ * or a fittingly sized buffer allocated by the function (default tag).
+ *
+ * @returns iprt status code.
+ * @param pwszString The UTF-16 string to convert.
+ * @param cwcString The number of RTUTF16 items to translate from
+ * pwszString. The translation will stop when reaching
+ * cwcString or the terminator ('\\0'). Use RTSTR_MAX
+ * to translate the entire string.
+ * @param ppsz Pointer to the pointer to the Latin-1 string. The
+ * buffer can optionally be preallocated by the caller.
+ *
+ * If cch is zero, *ppsz is undefined.
+ *
+ * If cch is non-zero and *ppsz is not NULL, then this
+ * will be used as the output buffer.
+ * VERR_BUFFER_OVERFLOW will be returned if this is
+ * insufficient.
+ *
+ * If cch is zero or *ppsz is NULL, then a buffer of
+ * sufficient size is allocated. cch can be used to
+ * specify a minimum size of this buffer. Use
+ * RTUtf16Free() to free the result.
+ *
+ * @param cch The buffer size in chars (the type). This includes
+ * the terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ */
+#define RTUtf16ToLatin1Ex(pwszString, cwcString, ppsz, cch, pcch) \
+ RTUtf16ToLatin1ExTag((pwszString), (cwcString), (ppsz), (cch), (pcch), RTSTR_TAG)
+
+/**
+ * Translates UTF-16 to Latin-1 (ISO-8859-1) using buffer provided by the caller
+ * or a fittingly sized buffer allocated by the function (custom tag).
+ *
+ * @returns iprt status code.
+ * @param pwszString The UTF-16 string to convert.
+ * @param cwcString The number of RTUTF16 items to translate from
+ * pwszString. The translation will stop when reaching
+ * cwcString or the terminator ('\\0'). Use RTSTR_MAX
+ * to translate the entire string.
+ * @param ppsz Pointer to the pointer to the Latin-1 string. The
+ * buffer can optionally be preallocated by the caller.
+ *
+ * If cch is zero, *ppsz is undefined.
+ *
+ * If cch is non-zero and *ppsz is not NULL, then this
+ * will be used as the output buffer.
+ * VERR_BUFFER_OVERFLOW will be returned if this is
+ * insufficient.
+ *
+ * If cch is zero or *ppsz is NULL, then a buffer of
+ * sufficient size is allocated. cch can be used to
+ * specify a minimum size of this buffer. Use
+ * RTUtf16Free() to free the result.
+ *
+ * @param cch The buffer size in chars (the type). This includes
+ * the terminator.
+ * @param pcch Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTUtf16ToLatin1ExTag(PCRTUTF16 pwszString, size_t cwcString, char **ppsz, size_t cch, size_t *pcch, const char *pszTag);
+
+/**
+ * Calculates the length of the UTF-16 string in Latin-1 (ISO-8859-1) chars.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected. The primary purpose of this function is to
+ * help allocate buffers for RTUtf16ToLatin1() of the correct size. For most
+ * other purposes RTUtf16ToLatin1Ex() should be used.
+ *
+ * @returns Number of char (bytes).
+ * @returns 0 if the string was incorrectly encoded.
+ * @param pwsz The UTF-16 string.
+ */
+RTDECL(size_t) RTUtf16CalcLatin1Len(PCRTUTF16 pwsz);
+
+/**
+ * Calculates the length of the UTF-16 string in Latin-1 (ISO-8859-1) chars.
+ *
+ * This function will validate the string, and incorrectly encoded UTF-16
+ * strings will be rejected.
+ *
+ * @returns iprt status code.
+ * @param pwsz The string.
+ * @param cwc The max string length. Use RTSTR_MAX to process the
+ * entire string.
+ * @param pcch Where to store the string length (in bytes). Optional.
+ * This is undefined on failure.
+ */
+RTDECL(int) RTUtf16CalcLatin1LenEx(PCRTUTF16 pwsz, size_t cwc, size_t *pcch);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param pwsz The string.
+ *
+ * @remark This is an internal worker for RTUtf16GetCp().
+ */
+RTDECL(RTUNICP) RTUtf16GetCpInternal(PCRTUTF16 pwsz);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param ppwsz Pointer to the string pointer. This will be updated to
+ * point to the char following the current code point.
+ * @param pCp Where to store the code point.
+ * RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark This is an internal worker for RTUtf16GetCpEx().
+ */
+RTDECL(int) RTUtf16GetCpExInternal(PCRTUTF16 *ppwsz, PRTUNICP pCp);
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by pwsz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param pwsz The string.
+ * @param CodePoint The code point to write.
+ * This should not be RTUNICP_INVALID or any other
+ * character out of the UTF-16 range.
+ *
+ * @remark This is an internal worker for RTUtf16GetCpEx().
+ */
+RTDECL(PRTUTF16) RTUtf16PutCpInternal(PRTUTF16 pwsz, RTUNICP CodePoint);
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns unicode code point.
+ * @returns RTUNICP_INVALID if the encoding is invalid.
+ * @param pwsz The string.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * everything which isn't a surrogate pair or an endian indicator.
+ */
+DECLINLINE(RTUNICP) RTUtf16GetCp(PCRTUTF16 pwsz)
+{
+ const RTUTF16 wc = *pwsz;
+ if (wc < 0xd800 || (wc > 0xdfff && wc < 0xfffe))
+ return wc;
+ return RTUtf16GetCpInternal(pwsz);
+}
+
+/**
+ * Get the unicode code point at the given string position.
+ *
+ * @returns iprt status code.
+ * @param ppwsz Pointer to the string pointer. This will be updated to
+ * point to the char following the current code point.
+ * @param pCp Where to store the code point.
+ * RTUNICP_INVALID is stored here on failure.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * everything which isn't a surrogate pair or and endian indicator.
+ */
+DECLINLINE(int) RTUtf16GetCpEx(PCRTUTF16 *ppwsz, PRTUNICP pCp)
+{
+ const RTUTF16 wc = **ppwsz;
+ if (wc < 0xd800 || (wc > 0xdfff && wc < 0xfffe))
+ {
+ (*ppwsz)++;
+ *pCp = wc;
+ return VINF_SUCCESS;
+ }
+ return RTUtf16GetCpExInternal(ppwsz, pCp);
+}
+
+/**
+ * Put the unicode code point at the given string position
+ * and return the pointer to the char following it.
+ *
+ * This function will not consider anything at or following the
+ * buffer area pointed to by pwsz. It is therefore not suitable for
+ * inserting code points into a string, only appending/overwriting.
+ *
+ * @returns pointer to the char following the written code point.
+ * @param pwsz The string.
+ * @param CodePoint The code point to write.
+ * This should not be RTUNICP_INVALID or any other
+ * character out of the UTF-16 range.
+ *
+ * @remark We optimize this operation by using an inline function for
+ * everything which isn't a surrogate pair or and endian indicator.
+ */
+DECLINLINE(PRTUTF16) RTUtf16PutCp(PRTUTF16 pwsz, RTUNICP CodePoint)
+{
+ if (CodePoint < 0xd800 || (CodePoint > 0xd800 && CodePoint < 0xfffe))
+ {
+ *pwsz++ = (RTUTF16)CodePoint;
+ return pwsz;
+ }
+ return RTUtf16PutCpInternal(pwsz, CodePoint);
+}
+
+/**
+ * Skips ahead, past the current code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param pwsz Pointer to the current code point.
+ * @remark This will not move the next valid code point, only past the current one.
+ */
+DECLINLINE(PRTUTF16) RTUtf16NextCp(PCRTUTF16 pwsz)
+{
+ RTUNICP Cp;
+ RTUtf16GetCpEx(&pwsz, &Cp);
+ return (PRTUTF16)pwsz;
+}
+
+/**
+ * Skips backwards, to the previous code point.
+ *
+ * @returns Pointer to the char after the current code point.
+ * @param pwszStart Pointer to the start of the string.
+ * @param pwsz Pointer to the current code point.
+ */
+RTDECL(PRTUTF16) RTUtf16PrevCp(PCRTUTF16 pwszStart, PCRTUTF16 pwsz);
+
+
+/**
+ * Checks if the UTF-16 char is the high surrogate char (i.e.
+ * the 1st char in the pair).
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param wc The character to investigate.
+ */
+DECLINLINE(bool) RTUtf16IsHighSurrogate(RTUTF16 wc)
+{
+ return wc >= 0xd800 && wc <= 0xdbff;
+}
+
+/**
+ * Checks if the UTF-16 char is the low surrogate char (i.e.
+ * the 2nd char in the pair).
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param wc The character to investigate.
+ */
+DECLINLINE(bool) RTUtf16IsLowSurrogate(RTUTF16 wc)
+{
+ return wc >= 0xdc00 && wc <= 0xdfff;
+}
+
+
+/**
+ * Checks if the two UTF-16 chars form a valid surrogate pair.
+ *
+ * @returns true if they do.
+ * @returns false if they doesn't.
+ * @param wcHigh The high (1st) character.
+ * @param wcLow The low (2nd) character.
+ */
+DECLINLINE(bool) RTUtf16IsSurrogatePair(RTUTF16 wcHigh, RTUTF16 wcLow)
+{
+ return RTUtf16IsHighSurrogate(wcHigh)
+ && RTUtf16IsLowSurrogate(wcLow);
+}
+
+/** @} */
+
+
+/** @defgroup rt_str_latin1 Latin-1 (ISO-8859-1) String Manipulation
+ * @ingroup grp_rt_str
+ * @{
+ */
+
+/**
+ * Calculates the length of the Latin-1 (ISO-8859-1) string in RTUTF16 items.
+ *
+ * @returns Number of RTUTF16 items.
+ * @param psz The Latin-1 string.
+ */
+RTDECL(size_t) RTLatin1CalcUtf16Len(const char *psz);
+
+/**
+ * Calculates the length of the Latin-1 (ISO-8859-1) string in RTUTF16 items.
+ *
+ * @returns iprt status code.
+ * @param psz The Latin-1 string.
+ * @param cch The max string length. Use RTSTR_MAX to process the
+ * entire string.
+ * @param pcwc Where to store the string length. Optional.
+ * This is undefined on failure.
+ */
+RTDECL(int) RTLatin1CalcUtf16LenEx(const char *psz, size_t cch, size_t *pcwc);
+
+/**
+ * Translate a Latin-1 (ISO-8859-1) string into a UTF-16 allocating the result
+ * buffer (default tag).
+ *
+ * @returns iprt status code.
+ * @param pszString The Latin-1 string to convert.
+ * @param ppwszString Receives pointer to the allocated UTF-16 string. The
+ * returned string must be freed using RTUtf16Free().
+ */
+#define RTLatin1ToUtf16(pszString, ppwszString) RTLatin1ToUtf16Tag((pszString), (ppwszString), RTSTR_TAG)
+
+/**
+ * Translate a Latin-1 (ISO-8859-1) string into a UTF-16 allocating the result
+ * buffer (custom tag).
+ *
+ * @returns iprt status code.
+ * @param pszString The Latin-1 string to convert.
+ * @param ppwszString Receives pointer to the allocated UTF-16 string. The
+ * returned string must be freed using RTUtf16Free().
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTLatin1ToUtf16Tag(const char *pszString, PRTUTF16 *ppwszString, const char *pszTag);
+
+/**
+ * Translates pszString from Latin-1 (ISO-8859-1) to UTF-16, allocating the
+ * result buffer if requested (default tag).
+ *
+ * @returns iprt status code.
+ * @param pszString The Latin-1 string to convert.
+ * @param cchString The maximum size in chars (the type) to convert.
+ * The conversion stops when it reaches cchString or
+ * the string terminator ('\\0').
+ * Use RTSTR_MAX to translate the entire string.
+ * @param ppwsz If cwc is non-zero, this must either be pointing
+ * to pointer to a buffer of the specified size, or
+ * pointer to a NULL pointer.
+ * If *ppwsz is NULL or cwc is zero a buffer of at
+ * least cwc items will be allocated to hold the
+ * translated string. If a buffer was requested it
+ * must be freed using RTUtf16Free().
+ * @param cwc The buffer size in RTUTF16s. This includes the
+ * terminator.
+ * @param pcwc Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ */
+#define RTLatin1ToUtf16Ex(pszString, cchString, ppwsz, cwc, pcwc) \
+ RTLatin1ToUtf16ExTag((pszString), (cchString), (ppwsz), (cwc), (pcwc), RTSTR_TAG)
+
+/**
+ * Translates pszString from Latin-1 (ISO-8859-1) to UTF-16, allocating the
+ * result buffer if requested.
+ *
+ * @returns iprt status code.
+ * @param pszString The Latin-1 string to convert.
+ * @param cchString The maximum size in chars (the type) to convert.
+ * The conversion stops when it reaches cchString or
+ * the string terminator ('\\0').
+ * Use RTSTR_MAX to translate the entire string.
+ * @param ppwsz If cwc is non-zero, this must either be pointing
+ * to pointer to a buffer of the specified size, or
+ * pointer to a NULL pointer.
+ * If *ppwsz is NULL or cwc is zero a buffer of at
+ * least cwc items will be allocated to hold the
+ * translated string. If a buffer was requested it
+ * must be freed using RTUtf16Free().
+ * @param cwc The buffer size in RTUTF16s. This includes the
+ * terminator.
+ * @param pcwc Where to store the length of the translated string,
+ * excluding the terminator. (Optional)
+ *
+ * This may be set under some error conditions,
+ * however, only for VERR_BUFFER_OVERFLOW and
+ * VERR_NO_STR_MEMORY will it contain a valid string
+ * length that can be used to resize the buffer.
+ * @param pszTag Allocation tag used for statistics and such.
+ */
+RTDECL(int) RTLatin1ToUtf16ExTag(const char *pszString, size_t cchString,
+ PRTUTF16 *ppwsz, size_t cwc, size_t *pcwc, const char *pszTag);
+
+/** @} */
+
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/symlink.h b/include/iprt/symlink.h
new file mode 100644
index 00000000..85edf1ad
--- /dev/null
+++ b/include/iprt/symlink.h
@@ -0,0 +1,176 @@
+/** @file
+ * IPRT - Symbolic Link Manipulation.
+ */
+
+/*
+ * 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 ___iprt_symlink_h
+#define ___iprt_symlink_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_symlink RTSymlink - Symbolic Link Manipulation
+ * @ingroup grp_rt
+ *
+ * For querying and changing symlink info (mode, ownership, etc) please refer
+ * to the @ref grp_rt_path "RTPath" API: RTPathQueryInfoEx, RTPathSetOwnerEx,
+ * RTPathSetModeEx and RTPathSetTimesEx.
+ *
+ * @{
+ */
+
+/**
+ * Checks if the specified path exists and is a symlink.
+ *
+ * @returns true if it's a symlink, false if it isn't.
+ * @param pszSymlink The path to the symlink.
+ *
+ * @sa RTDirExists, RTPathExists, RTSymlinkExists.
+ */
+RTDECL(bool) RTSymlinkExists(const char *pszSymlink);
+
+/**
+ * Checks if this is a dangling link or not.
+ *
+ * If the target of @a pszSymlink is a symbolic link, this may return false if
+ * that or any subsequent links are dangling.
+ *
+ * @returns true if it's dangling, false if it isn't.
+ * @param pszSymlink The path to the symlink.
+ */
+RTDECL(bool) RTSymlinkIsDangling(const char *pszSymlink);
+
+/**
+ * RTSymlinkCreate link type argument.
+ */
+typedef enum RTSYMLINKTYPE
+{
+ /** Invalid value. */
+ RTSYMLINKTYPE_INVALID = 0,
+ /** The link targets a directory. */
+ RTSYMLINKTYPE_DIR,
+ /** The link targets a file (or whatever else). */
+ RTSYMLINKTYPE_FILE,
+ /** It is not known what is being targeted.
+ * @remarks The RTSymlinkCreate API may probe the target to try figure
+ * out what is being targeted. */
+ RTSYMLINKTYPE_UNKNOWN,
+ /** The end of the valid type values. */
+ RTSYMLINKTYPE_END,
+ /** Blow the type up to 32-bit. */
+ RTSYMLINKTYPE_32BIT_HACK = 0x7fffffff
+} RTSYMLINKTYPE;
+
+/** @name RTSymlinkCreate flags.
+ * @{ */
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTSYMLINKCREATE_FLAGS_NO_SYMLINKS RT_BIT(0)
+/** @} */
+
+/**
+ * Creates a symbolic link (@a pszSymlink) targeting @a pszTarget.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszSymlink The name of the symbolic link.
+ * @param pszTarget The path to the symbolic link target. This is
+ * relative to @a pszSymlink or an absolute path.
+ * @param enmType The symbolic link type. For Windows compatability
+ * it is very important to set this correctly. When
+ * RTSYMLINKTYPE_UNKNOWN is used, the API will try
+ * make a guess and may attempt query information
+ * about @a pszTarget in the process.
+ * @param fCreate Create flags, RTSYMLINKCREATE_FLAGS_*.
+ */
+RTDECL(int) RTSymlinkCreate(const char *pszSymlink, const char *pszTarget,
+ RTSYMLINKTYPE enmType, uint32_t fCreate);
+
+/** @name RTSymlinkDelete flags.
+ * @{ */
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTSYMLINKDELETE_FLAGS_NO_SYMLINKS RT_BIT(0)
+/** @} */
+
+/**
+ * Deletes the specified symbolic link.
+ *
+ * This will try to refuse deleting non-symlinks, however there are usually
+ * races in the implementation of this check so no guarantees can be are made.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SYMLINK if @a pszSymlink does not specify a symbolic link.
+ *
+ * @param pszSymlink The symbolic link that should be removed.
+ * @param fDelete Delete flags, RTSYMLINKDELETE_FLAGS_*.
+ */
+RTDECL(int) RTSymlinkDelete(const char *pszSymlink, uint32_t fDelete);
+
+/** @name RTSymlinkRead flags.
+ * @{ */
+/** Don't allow symbolic links as part of the path.
+ * @remarks this flag is currently not implemented and will be ignored. */
+#define RTSYMLINKREAD_FLAGS_NO_SYMLINKS RT_BIT(0)
+/** @} */
+
+/**
+ * Read the symlink target.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SYMLINK if @a pszSymlink does not specify a symbolic link.
+ * @retval VERR_BUFFER_OVERFLOW if the link is larger than @a cbTarget. The
+ * buffer will contain what all we managed to read, fully terminated
+ * if @a cbTarget > 0.
+ *
+ * @param pszSymlink The symbolic link that should be read.
+ * @param pszTarget The target buffer.
+ * @param cbTarget The size of the target buffer.
+ * @param fRead Read flags, RTSYMLINKREAD_FLAGS_*.
+ */
+RTDECL(int) RTSymlinkRead(const char *pszSymlink, char *pszTarget, size_t cbTarget, uint32_t fRead);
+
+/**
+ * Read the symlink target into an API allocated buffer.
+ *
+ * This API eliminates the race involved in determining the right buffer size.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SYMLINK if @a pszSymlink does not specify a symbolic link.
+ *
+ * @param pszSymlink The symbolic link that should be read.
+ * @param ppszTarget Where to return the target string. Free the string
+ * by calling RTStrFree.
+ */
+RTDECL(int) RTSymlinkReadA(const char *pszSymlink, char **ppszTarget);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/system.h b/include/iprt/system.h
new file mode 100644
index 00000000..e7083e27
--- /dev/null
+++ b/include/iprt/system.h
@@ -0,0 +1,250 @@
+/** @file
+ * IPRT - System Information.
+ */
+
+/*
+ * 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 ___iprt_system_h
+#define ___iprt_system_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_system RTSystem - System Information
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Info level for RTSystemGetOSInfo().
+ */
+typedef enum RTSYSOSINFO
+{
+ RTSYSOSINFO_INVALID = 0, /**< The usual invalid entry. */
+ RTSYSOSINFO_PRODUCT, /**< OS product name. (uname -o) */
+ RTSYSOSINFO_RELEASE, /**< OS release. (uname -r) */
+ RTSYSOSINFO_VERSION, /**< OS version, optional. (uname -v) */
+ RTSYSOSINFO_SERVICE_PACK, /**< Service/fix pack level, optional. */
+ RTSYSOSINFO_END /**< End of the valid info levels. */
+} RTSYSOSINFO;
+
+
+/**
+ * Queries information about the OS.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_INVALID_PARAMETER if enmInfo is invalid.
+ * @retval VERR_INVALID_POINTER if pszInfoStr is invalid.
+ * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. The buffer will
+ * contain the chopped off result in this case, provided cchInfo isn't 0.
+ * @retval VERR_NOT_SUPPORTED if the info level isn't implemented. The buffer will
+ * contain an empty string.
+ *
+ * @param enmInfo The OS info level.
+ * @param pszInfo Where to store the result.
+ * @param cchInfo The size of the output buffer.
+ */
+RTDECL(int) RTSystemQueryOSInfo(RTSYSOSINFO enmInfo, char *pszInfo, size_t cchInfo);
+
+/**
+ * Queries the total amount of RAM in the system.
+ *
+ * This figure does not given any information about how much memory is
+ * currently available. Use RTSystemQueryAvailableRam instead.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and *pcb on sucess.
+ * @retval VERR_ACCESS_DENIED if the information isn't accessible to the
+ * caller.
+ *
+ * @param pcb Where to store the result (in bytes).
+ */
+RTDECL(int) RTSystemQueryTotalRam(uint64_t *pcb);
+
+/**
+ * Queries the total amount of RAM accessible to the system.
+ *
+ * This figure should not include memory that is installed but not used,
+ * nor memory that will be slow to bring online. The definition of 'slow'
+ * here is slower than swapping out a MB of pages to disk.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and *pcb on success.
+ * @retval VERR_ACCESS_DENIED if the information isn't accessible to the
+ * caller.
+ *
+ * @param pcb Where to store the result (in bytes).
+ */
+RTDECL(int) RTSystemQueryAvailableRam(uint64_t *pcb);
+
+/**
+ * Queries the amount of RAM that is currently locked down or in some other
+ * way made impossible to virtualize within reasonably short time.
+ *
+ * The purposes of this API is, when combined with RTSystemQueryTotalRam, to
+ * be able to determine an absolute max limit for how much fixed memory it is
+ * (theoretically) possible to allocate (or lock down).
+ *
+ * The kind memory covered by this function includes:
+ * - locked (wired) memory - like for instance RTR0MemObjLockUser
+ * and RTR0MemObjLockKernel makes,
+ * - kernel pools and heaps - like for instance the ring-0 variant
+ * of RTMemAlloc taps into,
+ * - fixed (not pageable) kernel allocations - like for instance
+ * all the RTR0MemObjAlloc* functions makes,
+ * - any similar memory that isn't easily swapped out, discarded,
+ * or flushed to disk.
+ *
+ * This works against the value returned by RTSystemQueryTotalRam, and
+ * the value reported by this function can never be larger than what a
+ * call to RTSystemQueryTotalRam returns.
+ *
+ * The short time term here is relative to swapping to disk like in
+ * RTSystemQueryTotalRam. This could mean that (part of) the dirty buffers
+ * in the dynamic I/O cache could be included in the total. If the dynamic
+ * I/O cache isn't likely to either flush buffers when the load increases
+ * and put them back into normal circulation, they should be included in
+ * the memory accounted for here.
+ *
+ * @retval VINF_SUCCESS and *pcb on success.
+ * @retval VERR_NOT_SUPPORTED if the information isn't available on the
+ * system in general. The caller must handle this scenario.
+ * @retval VERR_ACCESS_DENIED if the information isn't accessible to the
+ * caller.
+ *
+ * @param pcb Where to store the result (in bytes).
+ *
+ * @remarks This function could've been inverted and called
+ * RTSystemQueryAvailableRam, but that might give impression that
+ * it would be possible to allocate the amount of memory it
+ * indicates for a single purpose, something which would be very
+ * improbable on most systems.
+ *
+ * @remarks We might have to add another output parameter to this function
+ * that indicates if some of the memory kinds listed above cannot
+ * be accounted for on the system and therefore is not include in
+ * the returned amount.
+ */
+RTDECL(int) RTSystemQueryUnavailableRam(uint64_t *pcb);
+
+
+/**
+ * The DMI strings.
+ */
+typedef enum RTSYSDMISTR
+{
+ /** Invalid zero entry. */
+ RTSYSDMISTR_INVALID = 0,
+ /** The product name. */
+ RTSYSDMISTR_PRODUCT_NAME,
+ /** The product version. */
+ RTSYSDMISTR_PRODUCT_VERSION,
+ /** The product UUID. */
+ RTSYSDMISTR_PRODUCT_UUID,
+ /** The product serial. */
+ RTSYSDMISTR_PRODUCT_SERIAL,
+ /** The system manufacturer. */
+ RTSYSDMISTR_MANUFACTURER,
+ /** The end of the valid strings. */
+ RTSYSDMISTR_END,
+ /** The usual 32-bit hack. */
+ RTSYSDMISTR_32_BIT_HACK = 0x7fffffff
+} RTSYSDMISTR;
+
+/**
+ * Queries a DMI string.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS on success.
+ * @retval VERR_BUFFER_OVERFLOW if the buffer is too small. The buffer will
+ * contain the chopped off result in this case, provided cbBuf isn't 0.
+ * @retval VERR_ACCESS_DENIED if the information isn't accessible to the
+ * caller.
+ * @retval VERR_NOT_SUPPORTED if the information isn't available on the system
+ * in general. The caller must expect this status code and deal with
+ * it.
+ *
+ * @param enmString Which string to query.
+ * @param pszBuf Where to store the string. This is always
+ * terminated, even on error.
+ * @param cbBuf The buffer size.
+ */
+RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t cbBuf);
+
+/** @name Flags for RTSystemReboot and RTSystemShutdown.
+ * @{ */
+/** Reboot the system after shutdown. */
+#define RTSYSTEM_SHUTDOWN_REBOOT UINT32_C(0)
+/** Reboot the system after shutdown.
+ * The call may return VINF_SYS_MAY_POWER_OFF if the OS /
+ * hardware combination may power off instead of halting. */
+#define RTSYSTEM_SHUTDOWN_HALT UINT32_C(1)
+/** Power off the system after shutdown.
+ * This may be equvivalent to a RTSYSTEM_SHUTDOWN_HALT on systems where we
+ * cannot figure out whether the hardware/OS implements the actual powering
+ * off. If we can figure out that it's not supported, an
+ * VERR_SYS_CANNOT_POWER_OFF error is raised. */
+#define RTSYSTEM_SHUTDOWN_POWER_OFF UINT32_C(2)
+/** Power off the system after shutdown, or halt it if that's not possible. */
+#define RTSYSTEM_SHUTDOWN_POWER_OFF_HALT UINT32_C(3)
+/** The shutdown action mask. */
+#define RTSYSTEM_SHUTDOWN_ACTION_MASK UINT32_C(3)
+/** Unplanned shutdown/reboot. */
+#define RTSYSTEM_SHUTDOWN_UNPLANNED UINT32_C(0)
+/** Planned shutdown/reboot. */
+#define RTSYSTEM_SHUTDOWN_PLANNED RT_BIT_32(2)
+/** Force the system to shutdown/reboot regardless of objecting application
+ * or other stuff. This flag might not be realized on all systems. */
+#define RTSYSTEM_SHUTDOWN_FORCE RT_BIT_32(3)
+/** Parameter validation mask. */
+#define RTSYSTEM_SHUTDOWN_VALID_MASK UINT32_C(0x0000000f)
+/** @} */
+
+/**
+ * Shuts down the system.
+ *
+ * @returns IPRT status code on failure, on success it may or may not return
+ * depending on the OS.
+ * @retval VINF_SUCCESS
+ * @retval VINF_SYS_MAY_POWER_OFF
+ * @retval VERR_SYS_SHUTDOWN_FAILED
+ * @retval VERR_SYS_CANNOT_POWER_OFF
+ *
+ * @param cMsDelay The delay before the actual reboot. If this is
+ * not supported by the OS, an immediate reboot
+ * will be performed.
+ * @param fFlags Shutdown flags, see RTSYSTEM_SHUTDOWN_XXX.
+ * @param pszLogMsg Message for the log and users about why we're
+ * shutting down.
+ */
+RTDECL(int) RTSystemShutdown(RTMSINTERVAL cMsDelay, uint32_t fFlags, const char *pszLogMsg);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/table.h b/include/iprt/table.h
new file mode 100644
index 00000000..70023979
--- /dev/null
+++ b/include/iprt/table.h
@@ -0,0 +1,713 @@
+/** @file
+ * IPRT - Abstract Table/Trees.
+ */
+
+/*
+ * 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 ___iprt_table_h
+#define ___iprt_table_h
+
+#include <iprt/types.h>
+
+/** @defgroup grp_rt_tab RTTab - Generic Tree and Table Interface.
+ * @ingroup grp_rt
+ * @{
+ */
+
+RT_C_DECLS_BEGIN
+
+/** Pointer to an allocator. */
+typedef struct RTTABALLOCATOR *PRTTABALLOCATOR;
+
+/**
+ * Allocates memory.
+ *
+ * @returns Pointer to the allocated memory.
+ * @returns NULL on failure. (don't throw!)
+ * @param pAllocator The allocator structure.
+ * @param cb The number of bytes to allocate. (Never 0.)
+ */
+typedef DECLCALLBACK(void *) FNRTTABALLOC(PRTTABALLOCATOR pAllocator, size_t cb);
+/** Pointer to a FNRTTABALLOC() function. */
+typedef FNRTTABALLOC *PFNRTTABALLOC;
+
+/**
+ * Frees memory.
+ *
+ * @param pAllocator The allocator structure.
+ * @param pv The memory to free. (can be NULL)
+ */
+typedef DECLCALLBACK(void *) FNRTTABFREE(PRTTABALLOCATOR pAllocator, void *pv);
+/** Pointer to a FNRTTABFREE() function. */
+typedef FNRTTABFREE *PFNRTTABFREE;
+
+/**
+ * The allocator structure.
+ * (Hint: use this as like 'base class' for your custom allocators.)
+ */
+typedef struct RTTABALLOCATOR
+{
+ /** The allocation function. */
+ PFNRTTABALLOC pfnAlloc;
+ /** The free function. */
+ PFNRTTABFREE pfnFree;
+} RTTABALLOCATOR;
+
+/**
+ * Gets the default allocator.
+ *
+ * @returns Pointer to the default allocator.
+ */
+RTDECL(RTTABALLOCATOR) RTTabDefaultAllocator(void);
+
+
+/**
+ * Compares two table items.
+ *
+ * @returns 0 if equal
+ * @returns <0 if pvItem1 is less than pvItem2 (pvItem2 is then greater than pvItem1).
+ * @returns >0 if pvItem1 is less than pvItem2 (pvItem1 is then greater than pvItem2).
+ *
+ * @param pvItem1 The first item.
+ * @param pvItem2 The second item.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(int) FNRTTABCOMP(const void *pvItem1, const void *pvItem2, void *pvUser);
+/** Pointer to a FNRTTABCOMP() function. */
+typedef FNRTTABCOMP *PFNRTTABCOMP;
+
+/**
+ * Duplicates a table item.
+ * This is used when duplicating or copying a table.
+ *
+ * @returns Pointer to the copy.
+ * @returns NULL on failure.
+ *
+ * @param pvItem The item to copy.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(void *) FNRTTABDUPLICATE(const void *pvItem, void *pvUser);
+/** Pointer to a FNRTTABDUPLICATE() function. */
+typedef FNRTTABDUPLICATE *PFNRTTABDUPLICATE;
+
+/**
+ * Callback function for doing something with an item.
+ *
+ * What exactly we're doing is specific to the context of the call.
+ *
+ * @param pvItem The item.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(void) FNRTTABCALLBACK(const void *pvItem, void *pvUser);
+/** Pointer to a FNRTTABCALLBACK() function. */
+typedef FNRTTABCALLBACK *PFNRTTABCALLBACK;
+
+
+/** Pointer to const table operations. */
+typedef const struct RTTABOPS *PCRTTABOPS;
+/** Pointer to a table. */
+typedef struct RTTAB *PRTTAB;
+/** Pointer to a const table. */
+typedef const struct RTTAB *PCRTTAB;
+/** Pointer to a traverser. */
+typedef struct RTTABTRAVERSER *PRTTABTRAVERSER;
+/** Pointer to a const traverser. */
+typedef const struct RTTABTRAVERSER *PCRTTABTRAVERSER;
+/** Pointer to a traverser core. */
+typedef struct RTTABTRAVERSERCORE *PRTTABTRAVERSERCORE;
+/** Pointer to a const traverser core. */
+typedef const struct RTTABTRAVERSERCORE *PCRTTABTRAVERSERCORE;
+
+
+/**
+ * Table operations.
+ */
+typedef struct RTTABOPS
+{
+ /**
+ * Create a table.
+ *
+ * @returns Pointer to the new table.
+ * @returns NULL if we're out of memory or some other resource.
+ * @param pOps The table operations.
+ * @param fCreateFlags The table type specific creation flags.
+ * @param pAllocator Custom allocator. Pass NULL for the default allocator.
+ * @param pfnComp The comparision function.
+ */
+ DECLCALLBACKMEMBER(PRTTAB, pfnCreate)(PCRTTABOPS pOps, unsigned fCreateFlags, PRTTABALLOCATOR pAllocator, PFNRTTABCOMP pfnComp);
+
+ /**
+ * Duplicates a table to a table of the same type.
+ *
+ * @returns Pointer to the new table.
+ * @returns NULL if we're out of memory or some other resource.
+ * @param pTab The table to duplicate.
+ * @param pfnDuplicate Pointer to the item duplication function. If NULL the new table will
+ * be referencing the same data as the old one.
+ * @param pfnNewCB Callback which is called for all the items in the new table. Optional.
+ * @param pAllocator Custom allocator. Pass NULL to use the same allocator as pTab.
+ */
+ DECLCALLBACKMEMBER(PRTTAB, pfnDuplicate)(PCRTTAB pTab, PFNRTTABDUPLICATE pfnDuplicate, PFNRTTABCALLBACK pfnNewCB, PRTTABALLOCATOR pAllocator);
+
+ /**
+ * Destroys a table.
+ *
+ * @param pTab The table to destroy.
+ */
+ DECLCALLBACKMEMBER(void, pfnDestroy)(PRTTAB pTab);
+
+ /**
+ * Inserts an item into the table, if a matching item is encountered
+ * the pointer to the pointer to it will be returned.
+ *
+ * @returns Pointer to the item pointer in the table.
+ * This can be used to replace existing items (don't break anything, dude).
+ * @returns NULL if we failed to allocate memory for the new node.
+ * @param pTab The table.
+ * @param pvItem The item which will be inserted if an matching item was not found in the table.
+ */
+ DECLCALLBACKMEMBER(void **, pfnProbe)(PRTTAB pTab, void *pvItem);
+
+ /**
+ * Inserts an item into the table, fail if a matching item exists.
+ *
+ * @returns NULL on success and allocation failure.
+ * @returns Pointer to the matching item.
+ * @param pTab The table.
+ * @param pvItem The item which is to be inserted.
+ */
+ DECLCALLBACKMEMBER(void *, pfnInsert)(PRTTAB pTab, void *pvItem);
+
+ /**
+ * Inserts an item into the table, if a matching item is encountered
+ * it will be replaced and returned.
+ *
+ * @returns NULL if inserted and allocation failure.
+ * @returns Pointer to the replaced item.
+ * @param pTab The table.
+ * @param pvItem The item which is to be inserted.
+ */
+ DECLCALLBACKMEMBER(void *, pfnReplace)(PRTTAB pTab, void *pvItem);
+
+ /**
+ * Removes an item from the table if found.
+ *
+ * @returns Pointer to the removed item.
+ * @returns NULL if no item matched pvItem.
+ * @param pTab The table.
+ * @param pvItem The item which is to be inserted.
+ */
+ DECLCALLBACKMEMBER(void *, pfnRemove)(PRTTAB pTab, const void *pvItem);
+
+ /**
+ * Finds an item in the table.
+ *
+ * @returns Pointer to the item it found.
+ * @returns NULL if no item matched pvItem.
+ * @param pTab The table.
+ * @param pvItem The item which is to be inserted.
+ */
+ DECLCALLBACKMEMBER(void *, pfnFind)(PRTTAB pTab, const void *pvItem);
+
+ /**
+ * Initializes a traverser to the NULL item.
+ *
+ * The NULL item is an imaginary table item before the first and after
+ * the last items in the table.
+ *
+ * @returns Pointer to the traverser positioned at the NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+ DECLCALLBACKMEMBER(PRTTABTRAVERSERCORE, pfnTravInit)(PRTTAB pTab, PRTTABTRAVERSER pTravNew);
+
+ /**
+ * Initializes a traverser to the first item in the table.
+ *
+ * If the table is empty, the traverser will be positioned at the NULL item
+ * like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the first item or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+ DECLCALLBACKMEMBER(PRTTABTRAVERSERCORE, pfnTravFirst)(PRTTAB pTab, PRTTABTRAVERSER pTravNew);
+
+ /**
+ * Initializes a traverser to the last item in the table.
+ *
+ * If the table is empty, the traverser will be positioned at the NULL item
+ * like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the last item or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+ DECLCALLBACKMEMBER(PRTTABTRAVERSERCORE, pfnTravLast)(PRTTAB pTab, PRTTABTRAVERSER pTravNew);
+
+ /**
+ * Initializes a traverser to an item matching the given one.
+ *
+ * If the item isn't found, the traverser will be positioned at the NULL item
+ * like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the matching item or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ * @param pvItem The item to find the match to.
+ */
+ DECLCALLBACKMEMBER(PRTTABTRAVERSERCORE, pfnTravFind)(PRTTAB pTab, PRTTABTRAVERSER pTravNew, const void *pvItem);
+
+ /**
+ * Initializes a traverser to the inserted item.
+ *
+ * If there already exists an item in the tree matching pvItem, the traverser
+ * is positioned at that item like with RTTabTravFind().
+ *
+ * If the insert operation failes because of an out of memory condition, the
+ * traverser will be positioned at the NULL item like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the inserted, existing or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ * @param pvItem The item to be inserted.
+ */
+ DECLCALLBACKMEMBER(PRTTABTRAVERSERCORE, pfnTravInsert)(PRTTAB pTab, PRTTABTRAVERSER pTravNew, void *pvItem);
+
+ /**
+ * Duplicates a traverser.
+ *
+ * @returns The pointer to the duplicate.
+ * @returns NULL on allocation failure.
+ *
+ * @param pTrav The traverser to duplicate.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+ DECLCALLBACKMEMBER(PRTTABTRAVERSERCORE, pfnTravDuplicate)(PRTTABTRAVERSERCORE pTrav, PCRTTABTRAVERSER pTravNew);
+
+ /**
+ * Frees a traverser.
+ *
+ * This can safely be called even if the traverser structure
+ * wasn't dynamically allocated or the constructor failed.
+ *
+ * @param pTrav The traverser which is to be free.
+ */
+ DECLCALLBACKMEMBER(void, pfnTravFree)(PRTTABTRAVERSERCORE pTrav);
+
+ /**
+ * Gets the current item.
+ *
+ * @returns The current item. (NULL indicates the imaginary NULL item.)
+ * @param pTrav The traverser.
+ */
+ DECLCALLBACKMEMBER(void *, pfnTravCur)(PCRTTABTRAVERSERCORE pTrav);
+
+ /**
+ * Advances to the next item.
+ *
+ * @returns The new current item. (NULL indicates the imaginary NULL item.)
+ * @param pTrav The traverser.
+ */
+ DECLCALLBACKMEMBER(void *, pfnTravNext)(PRTTABTRAVERSERCORE pTrav);
+
+ /**
+ * Advances to the previous item.
+ *
+ * @returns The new current item. (NULL indicates the imaginary NULL item.)
+ * @param pTrav The traverser.
+ */
+ DECLCALLBACKMEMBER(void *, pfnTravPrev)(PRTTABTRAVERSERCORE pTrav);
+
+ /**
+ * Replaces the current item.
+ *
+ * This has the same restrictions as RTTabProbe(), e.g. it's not permitted to
+ * break the order of the table.
+ *
+ * @returns The replaced item.
+ * @returns NULL if the current item is the NULL item. The traverser
+ * and table remains unchanged.
+ * @param pTrav The traverser.
+ * @param pvItem The item to be inserted.
+ */
+ DECLCALLBACKMEMBER(void *, pfnTravReplace)(PRTTABTRAVERSERCORE pTrav, void *pvItem);
+
+ /** The type of table type. */
+ const char *pszType;
+} RTTABOPS;
+
+/**
+ * A table.
+ */
+typedef struct RTTAB
+{
+ /** The table operations. */
+ PCRTTABOPS pOps;
+ /** The function for comparing table items. */
+ PFNRTTABCOMP pfnComp;
+ /** The number of items in the table. */
+ RTUINT cItems;
+ /** The table generation number.
+ * This must be updated whenever the table changes. */
+ RTUINT idGeneration;
+} RTTAB;
+
+
+/**
+ * Create a table.
+ *
+ * @returns Pointer to the new table.
+ * @returns NULL if we're out of memory or some other resource.
+ * @param pOps The table operations.
+ * @param fCreateFlags The table type specific creation flags.
+ * @param pAllocator Custom allocator. Pass NULL for the default allocator.
+ * @param pfnComp The comparision function.
+ */
+DECLINLINE(PRTTAB) RTTabCreate(PCRTTABOPS pOps, unsigned fCreateFlags, PRTTABALLOCATOR pAllocator, PFNRTTABCOMP pfnComp)
+{
+ return pOps->pfnCreate(pOps, fCreateFlags, pAllocator, pfnComp);
+}
+
+/**
+ * Duplicates a table to a table of the same type.
+ *
+ * @returns Pointer to the new table.
+ * @returns NULL if we're out of memory or some other resource.
+ * @param pTab The table to duplicate.
+ * @param pfnDuplicate Pointer to the item duplication function. If NULL the new table will
+ * be referencing the same data as the old one.
+ * @param pfnNewCB Callback which is called for all the items in the new table. Optional.
+ * @param pAllocator Custom allocator. Pass NULL to use the same allocator as pTab.
+ */
+DECLINLINE(PRTTAB) RTTabDuplicate(PCRTTAB pTab, PFNRTTABDUPLICATE pfnDuplicate, PFNRTTABCALLBACK pfnNewCB, PRTTABALLOCATOR pAllocator)
+{
+ return pTab->pOps->pfnDuplicate(pTab, pfnDuplicate, pfnNewCB, pAllocator);
+}
+
+/**
+ * Destroys a table.
+ *
+ * @param pTab The table to destroy.
+ */
+DECLINLINE(void) RTTabDestroy(PRTTAB pTab)
+{
+ pTab->pOps->pfnDestroy(pTab);
+}
+
+/**
+ * Count the item in the table.
+ *
+ * @returns Number of items in the table.
+ * @param pTab The table to count.
+ */
+DECLINLINE(RTUINT) RTTabCount(PRTTAB pTab)
+{
+ return pTab->cItems;
+}
+
+/**
+ * Inserts an item into the table, if a matching item is encountered
+ * the pointer to the pointer to it will be returned.
+ *
+ * @returns Pointer to the item pointer in the table.
+ * This can be used to replace existing items (don't break anything, dude).
+ * @returns NULL if we failed to allocate memory for the new node.
+ * @param pTab The table.
+ * @param pvItem The item which will be inserted if an matching item was not found in the table.
+ */
+DECLINLINE(void **) RTTabProbe(PRTTAB pTab, void *pvItem)
+{
+ return pTab->pOps->pfnProbe(pTab, pvItem);
+}
+
+/**
+ * Inserts an item into the table, fail if a matching item exists.
+ *
+ * @returns NULL on success and allocation failure.
+ * @returns Pointer to the matching item.
+ * @param pTab The table.
+ * @param pvItem The item which is to be inserted.
+ */
+DECLINLINE(void *) RTTabInsert(PRTTAB pTab, void *pvItem)
+{
+ return pTab->pOps->pfnInsert(pTab, pvItem);
+}
+
+/**
+ * Inserts an item into the table, if a matching item is encountered
+ * it will be replaced and returned.
+ *
+ * @returns NULL if inserted and allocation failure.
+ * @returns Pointer to the replaced item.
+ * @param pTab The table.
+ * @param pvItem The item which is to be inserted.
+ */
+DECLINLINE(void *) RTTabReplace(PRTTAB pTab, void *pvItem)
+{
+ return pTab->pOps->pfnReplace(pTab, pvItem);
+}
+
+/**
+ * Removes an item from the table if found.
+ *
+ * @returns Pointer to the removed item.
+ * @returns NULL if no item matched pvItem.
+ * @param pTab The table.
+ * @param pvItem The item which is to be inserted.
+ */
+DECLINLINE(void *) RTTabRemove(PRTTAB pTab, const void *pvItem)
+{
+ return pTab->pOps->pfnRemove(pTab, pvItem);
+}
+
+/**
+ * Finds an item in the table.
+ *
+ * @returns Pointer to the item it found.
+ * @returns NULL if no item matched pvItem.
+ * @param pTab The table.
+ * @param pvItem The item to find the match to.
+ */
+DECLINLINE(void *) RTTabFind(PRTTAB pTab, const void *pvItem)
+{
+ return pTab->pOps->pfnFind(pTab, pvItem);
+}
+
+
+/**
+ * Common traverser core.
+ */
+typedef struct RTTABTRAVERSERCORE
+{
+ /** The table being traversed. */
+ PRTTAB pTab;
+ /** Indicates that this traverser was allocated. */
+ bool fAllocated;
+ /** The table generation id this traverser was last updated for.
+ * This is used to catch up with table changes. */
+ RTUINT idGeneration;
+} RTTABTRAVERSERCORE;
+
+/**
+ * Generic traverser structure.
+ *
+ * Tree implementations will use the tree specific part by mapping
+ * this structure onto their own internal traverser structure.
+ *
+ * @remark It would be better to use alloca() for allocating the structure,
+ * OTOH this is simpler for the user.
+ */
+typedef struct RTTABTRAVERSER
+{
+ /** The common core of the traverser data. */
+ RTTABTRAVERSERCORE Core;
+ /** The tree specific data. */
+ void *apvTreeSpecific[32];
+} RTTABTRAVERSER;
+
+
+/**
+ * Initializes a traverser to the NULL item.
+ *
+ * The NULL item is an imaginary table item before the first and after
+ * the last items in the table.
+ *
+ * @returns Pointer to the traverser positioned at the NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+DECLINLINE(PRTTABTRAVERSERCORE) RTTabTravInit(PRTTAB pTab, PRTTABTRAVERSER pTravNew)
+{
+ return pTab->pOps->pfnTravInit(pTab, pTravNew);
+}
+
+/**
+ * Initializes a traverser to the first item in the table.
+ *
+ * If the table is empty, the traverser will be positioned at the NULL item
+ * like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the first item or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+DECLINLINE(PRTTABTRAVERSERCORE) RTTabTravFirst(PRTTAB pTab, PRTTABTRAVERSER pTravNew)
+{
+ return pTab->pOps->pfnTravFirst(pTab, pTravNew);
+}
+
+/**
+ * Initializes a traverser to the last item in the table.
+ *
+ * If the table is empty, the traverser will be positioned at the NULL item
+ * like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the last item or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+DECLINLINE(PRTTABTRAVERSERCORE) RTTabTravLast(PRTTAB pTab, PRTTABTRAVERSER pTravNew)
+{
+ return pTab->pOps->pfnTravLast(pTab, pTravNew);
+}
+
+/**
+ * Initializes a traverser to an item matching the given one.
+ *
+ * If the item isn't found, the traverser will be positioned at the NULL item
+ * like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the matching item or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ * @param pvItem The item to find the match to.
+ */
+DECLINLINE(PRTTABTRAVERSERCORE) RTTabTravFind(PRTTAB pTab, PRTTABTRAVERSER pTravNew, const void *pvItem)
+{
+ return pTab->pOps->pfnTravFind(pTab, pTravNew, pvItem);
+}
+
+/**
+ * Initializes a traverser to the inserted item.
+ *
+ * If there already exists an item in the tree matching pvItem, the traverser
+ * is positioned at that item like with RTTabTravFind().
+ *
+ * If the insert operation failes because of an out of memory condition, the
+ * traverser will be positioned at the NULL item like with RTTabTravInit().
+ *
+ * @returns Pointer to the traverser positioned at the inserted, existing or NULL item.
+ * @returns NULL on failure to allocate the traverser.
+ *
+ * @param pTab The table.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ * @param pvItem The item to be inserted.
+ */
+DECLINLINE(PRTTABTRAVERSERCORE) RTTabTravInsert(PRTTAB pTab, PRTTABTRAVERSER pTravNew, void *pvItem)
+{
+ return pTab->pOps->pfnTravInsert(pTab, pTravNew, pvItem);
+}
+
+/**
+ * Duplicates a traverser.
+ *
+ * @returns The pointer to the duplicate.
+ * @returns NULL on allocation failure.
+ *
+ * @param pTrav The traverser to duplicate.
+ * @param pTravNew Pointer to a preallocated structure. Optional.
+ */
+DECLINLINE(PRTTABTRAVERSERCORE) RTTabTravDuplicate(PRTTABTRAVERSERCORE pTrav, PCRTTABTRAVERSER pTravNew)
+{
+ if (pTrav)
+ return pTrav->pTab->pOps->pfnTravDuplicate(pTrav, pTravNew);
+ return NULL;
+}
+
+/**
+ * Frees a traverser.
+ *
+ * This can safely be called even if the traverser structure
+ * wasn't dynamically allocated or the constructor failed.
+ *
+ * @param pTrav The traverser which is to be free.
+ */
+DECLINLINE(void) RTTabTravFree(PRTTABTRAVERSERCORE pTrav)
+{
+ if (pTrav && pTrav->fAllocated)
+ pTrav->pTab->pOps->pfnTravFree(pTrav);
+}
+
+/**
+ * Gets the current item.
+ *
+ * @returns The current item. (NULL indicates the imaginary NULL item.)
+ * @param pTrav The traverser.
+ */
+DECLINLINE(void *) RTTabTravCur(PCRTTABTRAVERSERCORE pTrav)
+{
+ return pTrav->pTab->pOps->pfnTravCur(pTrav);
+}
+
+/**
+ * Advances to the next item.
+ *
+ * @returns The new current item. (NULL indicates the imaginary NULL item.)
+ * @param pTrav The traverser.
+ */
+DECLINLINE(void *) RTTabTravNext(PRTTABTRAVERSERCORE pTrav)
+{
+ return pTrav->pTab->pOps->pfnTravNext(pTrav);
+}
+
+/**
+ * Advances to the previous item.
+ *
+ * @returns The new current item. (NULL indicates the imaginary NULL item.)
+ * @param pTrav The traverser.
+ */
+DECLINLINE(void *) RTTabTravPrev(PRTTABTRAVERSERCORE pTrav)
+{
+ return pTrav->pTab->pOps->pfnTravPrev(pTrav);
+}
+
+/**
+ * Replaces the current item.
+ *
+ * This has the same restrictions as RTTabProbe(), e.g. it's not permitted to
+ * break the order of the table.
+ *
+ * @returns The replaced item.
+ * @returns NULL if the current item is the NULL item. The traverser
+ * and table remains unchanged.
+ * @param pTrav The traverser.
+ * @param pvItem The item to be inserted.
+ */
+DECLINLINE(void *) RTTabTravReplace(PRTTABTRAVERSERCORE pTrav, void *pvItem)
+{
+ return pTrav->pTab->pOps->pfnTravReplace(pTrav, pvItem);
+}
+
+RT_C_DECLS_END
+
+/** @} */
+
+#endif
diff --git a/include/iprt/tar.h b/include/iprt/tar.h
new file mode 100644
index 00000000..96fad7a6
--- /dev/null
+++ b/include/iprt/tar.h
@@ -0,0 +1,456 @@
+/** @file
+ * IPRT - Tar archive I/O.
+ */
+
+/*
+ * Copyright (C) 2009-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 ___iprt_tar_h
+#define ___iprt_tar_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/time.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_tar RTTar - Tar archive I/O
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** A tar handle */
+typedef R3PTRTYPE(struct RTTARINTERNAL *) RTTAR;
+/** Pointer to a RTTAR interface handle. */
+typedef RTTAR *PRTTAR;
+/** Nil RTTAR interface handle. */
+#define NIL_RTTAR ((RTTAR)0)
+
+/** A tar file handle */
+typedef R3PTRTYPE(struct RTTARFILEINTERNAL *) RTTARFILE;
+/** Pointer to a RTTARFILE interface handle. */
+typedef RTTARFILE *PRTTARFILE;
+/** Nil RTTARFILE interface handle. */
+#define NIL_RTTARFILE ((RTTARFILE)0)
+
+/**
+ * Opens a Tar archive.
+ *
+ * Use the mask to specify the access type. In create mode the target file
+ * have not to exists.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phTar Where to store the RTTAR handle.
+ * @param pszTarname The file name of the tar archive to open.
+ * @param fMode Open flags, i.e a combination of the RTFILE_O_* defines.
+ * The ACCESS, ACTION and DENY flags are mandatory!
+ * @param fStream Open the file in stream mode. Within this mode no
+ * seeking is allowed. Use this together with
+ * RTTarFileCurrent, RTTarFileOpenCurrent,
+ * RTTarFileSeekNextFile and the read method to
+ * sequential read a tar file. Currently ignored with
+ * RTFILE_O_WRITE.
+ */
+RTR3DECL(int) RTTarOpen(PRTTAR phTar, const char *pszTarname, uint32_t fMode, bool fStream);
+
+#if 0
+/**
+ * Opens a Tar archive by handle.
+ *
+ * Use the mask to specify the access type. In create mode the target file
+ * have not to exists.
+ *
+ * @returns IPRT status code.
+ *
+ * @param phTar Where to store the RTTAR handle.
+ * @param hFile The file handle of the tar file. This is expected
+ * to be a regular file at the moment.
+ * @param fStream Open the file in stream mode. Within this mode no
+ * seeking is allowed. Use this together with
+ * RTTarFileCurrent, RTTarFileOpenCurrent,
+ * RTTarFileSeekNextFile and the read method to
+ * sequential read a tar file. Currently ignored with
+ * RTFILE_O_WRITE.
+ */
+RTR3DECL(int) RTTarOpenByHandle(PRTTAR phTar, RTFILE hFile, uint32_t fMode, bool fStream);
+#endif
+
+/**
+ * Close the Tar archive.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTar Handle to the RTTAR interface.
+ */
+RTR3DECL(int) RTTarClose(RTTAR hTar);
+
+/**
+ * Open a file in the Tar archive.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTar The handle of the tar archive.
+ * @param phFile Where to store the handle to the opened file.
+ * @param pszFilename Path to the file which is to be opened. (UTF-8)
+ * @param fOpen Open flags, i.e a combination of the RTFILE_O_* defines.
+ * The ACCESS, ACTION flags are mandatory! DENY flags
+ * are currently not supported.
+ *
+ * @remarks Write mode means append mode only. It is not possible to make
+ * changes to existing files.
+ *
+ * @remarks Currently it is not possible to open more than one file in write
+ * mode. Although open more than one file in read only mode (even when
+ * one file is opened in write mode) is always possible.
+ */
+RTR3DECL(int) RTTarFileOpen(RTTAR hTar, PRTTARFILE phFile, const char *pszFilename, uint32_t fOpen);
+
+/**
+ * Close the file opened by RTTarFileOpen.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile The file handle to close.
+ */
+RTR3DECL(int) RTTarFileClose(RTTARFILE hFile);
+
+/**
+ * Changes the read & write position in a file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param offSeek Offset to seek.
+ * @param uMethod Seek method, i.e. one of the RTFILE_SEEK_* defines.
+ * @param poffActual Where to store the new file position.
+ * NULL is allowed.
+ */
+RTR3DECL(int) RTTarFileSeek(RTTARFILE hFile, uint64_t offSeek, unsigned uMethod, uint64_t *poffActual);
+
+/**
+ * Gets the current file position.
+ *
+ * @returns File offset.
+ * @returns UINT64_MAX on failure.
+ *
+ * @param hFile Handle to the file.
+ */
+RTR3DECL(uint64_t) RTTarFileTell(RTTARFILE hFile);
+
+/**
+ * Read bytes from a file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbToRead How much to read.
+ * @param *pcbRead How much we actually read .
+ * If NULL an error will be returned for a partial read.
+ */
+RTR3DECL(int) RTTarFileRead(RTTARFILE hFile, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Read bytes from a file at a given offset.
+ * This function may modify the file position.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param off Where to read.
+ * @param pvBuf Where to put the bytes we read.
+ * @param cbToRead How much to read.
+ * @param *pcbRead How much we actually read .
+ * If NULL an error will be returned for a partial read.
+ */
+RTR3DECL(int) RTTarFileReadAt(RTTARFILE hFile, uint64_t off, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Write bytes to a file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param pvBuf What to write.
+ * @param cbToWrite How much to write.
+ * @param *pcbWritten How much we actually wrote.
+ * If NULL an error will be returned for a partial write.
+ */
+RTR3DECL(int) RTTarFileWrite(RTTARFILE hFile, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+
+/**
+ * Write bytes to a file at a given offset.
+ * This function may modify the file position.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param off Where to write.
+ * @param pvBuf What to write.
+ * @param cbToWrite How much to write.
+ * @param *pcbWritten How much we actually wrote.
+ * If NULL an error will be returned for a partial write.
+ */
+RTR3DECL(int) RTTarFileWriteAt(RTTARFILE hFile, uint64_t off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+
+/**
+ * Query the size of the file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param pcbSize Where to store the filesize.
+ */
+RTR3DECL(int) RTTarFileGetSize(RTTARFILE hFile, uint64_t *pcbSize);
+
+/**
+ * Set the size of the file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param cbSize The new file size.
+ */
+RTR3DECL(int) RTTarFileSetSize(RTTARFILE hFile, uint64_t cbSize);
+
+/**
+ * Gets the mode flags of an open file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param pfMode Where to store the file mode, see @ref grp_rt_fs for details.
+ */
+RTR3DECL(int) RTTarFileGetMode(RTTARFILE hFile, uint32_t *pfMode);
+
+/**
+ * Changes the mode flags of an open file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param fMode The new file mode, see @ref grp_rt_fs for details.
+ */
+RTR3DECL(int) RTTarFileSetMode(RTTARFILE hFile, uint32_t fMode);
+
+/**
+ * Gets the modification timestamp of the file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pFile Handle to the file.
+ * @param pTime Where to store the time.
+ */
+RTR3DECL(int) RTTarFileGetTime(RTTARFILE hFile, PRTTIMESPEC pTime);
+
+/**
+ * Sets the modification timestamp of the file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pFile Handle to the file.
+ * @param pTime The time to store.
+ */
+RTR3DECL(int) RTTarFileSetTime(RTTARFILE hFile, PRTTIMESPEC pTime);
+
+/**
+ * Gets the owner and/or group of an open file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param pUid Where to store the owner user id. NULL is ok.
+ * @param pGid Where to store the group id. NULL is ok.
+ */
+RTR3DECL(int) RTTarFileGetOwner(RTTARFILE hFile, uint32_t *pUid, uint32_t *pGid);
+
+/**
+ * Changes the owner and/or group of an open file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hFile Handle to the file.
+ * @param uid The new file owner user id. Use -1 (or ~0) to leave this unchanged.
+ * @param gid The new group id. Use -1 (or ~0) to leave this unchanged.
+ */
+RTR3DECL(int) RTTarFileSetOwner(RTTARFILE hFile, uint32_t uid, uint32_t gid);
+
+/******************************************************************************
+ * Convenience Functions *
+ ******************************************************************************/
+
+/**
+ * Check if the specified file exists in the Tar archive.
+ *
+ * (The matching is case sensitive.)
+ *
+ * @note Currently only regular files are supported.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS when the file exists in the Tar archive.
+ * @retval VERR_FILE_NOT_FOUND when the file not exists in the Tar archive.
+ *
+ * @param pszTarFile Tar file to check.
+ * @param pszFile Filename to check for.
+ *
+ * @todo This is predicate function which SHALL return bool!
+ */
+RTR3DECL(int) RTTarFileExists(const char *pszTarFile, const char *pszFile);
+
+/**
+ * Create a file list from a Tar archive.
+ *
+ * @note Currently only regular files are supported.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszTarFile Tar file to list files from.
+ * @param ppapszFiles On success an array with array with the filenames is
+ * returned. The names must be freed with RTStrFree and
+ * the array with RTMemFree.
+ * @param pcFiles On success the number of entries in ppapszFiles.
+ */
+RTR3DECL(int) RTTarList(const char *pszTarFile, char ***ppapszFiles, size_t *pcFiles);
+
+/**
+ * Extract a file from a Tar archive into a memory buffer.
+ *
+ * The caller is responsible for the deletion of the returned memory buffer.
+ *
+ * (The matching is case sensitive.)
+ *
+ * @note Currently only regular files are supported. Also some of the header
+ * fields are not used (uid, gid, uname, gname, mtime).
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszTarFile Tar file to extract files from.
+ * @param ppBuf The buffer which will held the extracted data.
+ * @param pcbSize The size (in bytes) of ppBuf after successful
+ * extraction.
+ * @param pszFile The file to extract.
+ * @param pfnProgressCallback Progress callback function. Optional.
+ * @param pvUser User defined data for the progress
+ * callback. Optional.
+ */
+RTR3DECL(int) RTTarExtractFileToBuf(const char *pszTarFile, void **ppvBuf, size_t *pcbSize, const char *pszFile,
+ PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+/**
+ * Extract a set of files from a Tar archive.
+ *
+ * Also note that this function is atomic. If an error occurs all previously
+ * extracted files will be deleted.
+ *
+ * (The matching is case sensitive.)
+ *
+ * @note Currently only regular files are supported. Also some of the header
+ * fields are not used (uid, gid, uname, gname, mtime).
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszTarFile Tar file to extract files from.
+ * @param pszOutputDir Where to store the extracted files. Must exist.
+ * @param papszFiles Which files should be extracted.
+ * @param cFiles The number of files in papszFiles.
+ * @param pfnProgressCallback Progress callback function. Optional.
+ * @param pvUser User defined data for the progress
+ * callback. Optional.
+ */
+RTR3DECL(int) RTTarExtractFiles(const char *pszTarFile, const char *pszOutputDir, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+/**
+ * Extract all files of the archive.
+ *
+ * @note Currently only regular files are supported. Also some of the header
+ * fields are not used (uid, gid, uname, gname, mtime).
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszTarFile Tar file to extract the files from.
+ * @param pszOutputDir Where to store the extracted files. Must exist.
+ * @param pfnProgressCallback Progress callback function. Optional.
+ * @param pvUser User defined data for the progress
+ * callback. Optional.
+ */
+RTR3DECL(int) RTTarExtractAll(const char *pszTarFile, const char *pszOutputDir, PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+/**
+ * Create a Tar archive out of the given files.
+ *
+ * @note Currently only regular files are supported.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszTarFile Where to create the Tar archive.
+ * @param papszFiles Which files should be included.
+ * @param cFiles The number of files in papszFiles.
+ * @param pfnProgressCallback Progress callback function. Optional.
+ * @param pvUser User defined data for the progress
+ * callback. Optional.
+ */
+RTR3DECL(int) RTTarCreate(const char *pszTarFile, const char * const *papszFiles, size_t cFiles, PFNRTPROGRESS pfnProgressCallback, void *pvUser);
+
+/******************************************************************************
+ * Streaming Functions *
+ ******************************************************************************/
+
+/**
+ * Return the filename where RTTar currently stays at.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTar Handle to the RTTAR interface.
+ * @param ppszFilename On success the filename.
+ */
+RTR3DECL(int) RTTarCurrentFile(RTTAR hTar, char **ppszFilename);
+
+/**
+ * Jumps to the next file from the current RTTar position.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTar Handle to the RTTAR interface.
+ */
+RTR3DECL(int) RTTarSeekNextFile(RTTAR hTar);
+
+/**
+ * Opens the file where RTTar currently stays at.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTar Handle to the RTTAR interface.
+ * @param phFile Where to store the handle to the opened file.
+ * @param ppszFilename On success the filename.
+ * @param fOpen Open flags, i.e a combination of the RTFILE_O_* defines.
+ * The ACCESS, ACTION flags are mandatory! Currently
+ * only RTFILE_O_OPEN | RTFILE_O_READ is supported.
+ */
+RTR3DECL(int) RTTarFileOpenCurrentFile(RTTAR hTar, PRTTARFILE phFile, char **ppszFilename, uint32_t fOpen);
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* ___iprt_tar_h */
+
diff --git a/include/iprt/tcp.h b/include/iprt/tcp.h
new file mode 100644
index 00000000..32d7de45
--- /dev/null
+++ b/include/iprt/tcp.h
@@ -0,0 +1,443 @@
+/** @file
+ * IPRT - TCP/IP.
+ */
+
+/*
+ * 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 ___iprt_tcp_h
+#define ___iprt_tcp_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/thread.h>
+#include <iprt/net.h>
+#include <iprt/sg.h>
+#include <iprt/socket.h>
+
+#ifdef IN_RING0
+# error "There are no RTFile APIs available Ring-0 Host Context!"
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_tcp RTTcp - TCP/IP
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Serve a TCP Server connection.
+ *
+ * @returns iprt status code.
+ * @returns VERR_TCP_SERVER_STOP to terminate the server loop forcing
+ * the RTTcpCreateServer() call to return.
+ * @param Sock The socket which the client is connected to.
+ * The call will close this socket.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNRTTCPSERVE(RTSOCKET Sock, void *pvUser);
+/** Pointer to a RTTCPSERVE(). */
+typedef FNRTTCPSERVE *PFNRTTCPSERVE;
+
+/**
+ * Create single connection at a time TCP Server in a separate thread.
+ *
+ * The thread will loop accepting connections and call pfnServe for
+ * each of the incoming connections in turn. The pfnServe function can
+ * return VERR_TCP_SERVER_STOP too terminate this loop. RTTcpServerDestroy()
+ * should be used to terminate the server.
+ *
+ * @returns iprt status code.
+ * @param pszAddress The address for creating a listening socket.
+ * If NULL or empty string the server is bound to all interfaces.
+ * @param uPort The port for creating a listening socket.
+ * @param enmType The thread type.
+ * @param pszThrdName The name of the worker thread.
+ * @param pfnServe The function which will serve a new client connection.
+ * @param pvUser User argument passed to pfnServe.
+ * @param ppServer Where to store the serverhandle.
+ */
+RTR3DECL(int) RTTcpServerCreate(const char *pszAddress, unsigned uPort, RTTHREADTYPE enmType, const char *pszThrdName,
+ PFNRTTCPSERVE pfnServe, void *pvUser, PPRTTCPSERVER ppServer);
+
+/**
+ * Create single connection at a time TCP Server.
+ * The caller must call RTTcpServerListen() to actually start the server.
+ *
+ * @returns iprt status code.
+ * @param pszAddress The address for creating a listening socket.
+ * If NULL the server is bound to all interfaces.
+ * @param uPort The port for creating a listening socket.
+ * @param ppServer Where to store the serverhandle.
+ */
+RTR3DECL(int) RTTcpServerCreateEx(const char *pszAddress, uint32_t uPort, PPRTTCPSERVER ppServer);
+
+/**
+ * Closes down and frees a TCP Server.
+ * This will also terminate any open connections to the server.
+ *
+ * @returns iprt status code.
+ * @param pServer Handle to the server.
+ */
+RTR3DECL(int) RTTcpServerDestroy(PRTTCPSERVER pServer);
+
+/**
+ * Listen for incoming connections.
+ *
+ * The function will loop accepting connections and call pfnServe for
+ * each of the incoming connections in turn. The pfnServe function can
+ * return VERR_TCP_SERVER_STOP too terminate this loop. A stopped server
+ * can only be destroyed.
+ *
+ * @returns iprt status code.
+ * @param pServer The server handle as returned from RTTcpServerCreateEx().
+ * @param pfnServe The function which will serve a new client connection.
+ * @param pvUser User argument passed to pfnServe.
+ */
+RTR3DECL(int) RTTcpServerListen(PRTTCPSERVER pServer, PFNRTTCPSERVE pfnServe, void *pvUser);
+
+/**
+ * Listen and accept one incoming connection.
+ *
+ * This is an alternative to RTTcpServerListen for the use the callbacks are not
+ * possible.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_TCP_SERVER_SHUTDOWN if shut down by RTTcpServerShutdown.
+ * @retval VERR_INTERRUPTED if the listening was interrupted.
+ *
+ * @param pServer The server handle as returned from RTTcpServerCreateEx().
+ * @param phClientSocket Where to return the socket handle to the client
+ * connection (on success only). This must be closed
+ * by calling RTTcpServerDisconnectClient2().
+ */
+RTR3DECL(int) RTTcpServerListen2(PRTTCPSERVER pServer, PRTSOCKET phClientSocket);
+
+/**
+ * Terminate the open connection to the server.
+ *
+ * @returns iprt status code.
+ * @param pServer Handle to the server.
+ */
+RTR3DECL(int) RTTcpServerDisconnectClient(PRTTCPSERVER pServer);
+
+/**
+ * Terminates an open client connect when using RTTcpListen2
+ *
+ * @returns IPRT status code.
+ * @param hClientSocket The client socket handle. This will be invalid upon
+ * return, whether successful or not. NIL is quietly
+ * ignored (VINF_SUCCESS).
+ */
+RTR3DECL(int) RTTcpServerDisconnectClient2(RTSOCKET hClientSocket);
+
+/**
+ * Shuts down the server, leaving client connections open.
+ *
+ * @returns IPRT status code.
+ * @param pServer Handle to the server.
+ */
+RTR3DECL(int) RTTcpServerShutdown(PRTTCPSERVER pServer);
+
+/**
+ * Connect (as a client) to a TCP Server.
+ *
+ * @returns iprt status code.
+ * @param pszAddress The address to connect to.
+ * @param uPort The port to connect to.
+ * @param pSock Where to store the handle to the established connection.
+ */
+RTR3DECL(int) RTTcpClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock);
+
+/**
+ * Close a socket returned by RTTcpClientConnect().
+ *
+ * @returns iprt status code.
+ * @param Sock Socket descriptor.
+ */
+RTR3DECL(int) RTTcpClientClose(RTSOCKET Sock);
+
+/**
+ * Close a socket returned by RTTcpClientConnect().
+ *
+ * @returns iprt status code.
+ * @param hSocket The socket handle.
+ * @param fGracefulShutdown If true, try do a graceful shutdown of the
+ * outgoing pipe and draining any lingering input.
+ * This is sometimes better for the server side.
+ * If false, just close the connection without
+ * further ado.
+ */
+RTR3DECL(int) RTTcpClientCloseEx(RTSOCKET Sock, bool fGracefulShutdown);
+
+/**
+ * Receive data from a socket.
+ *
+ * @returns 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.
+ */
+RTR3DECL(int) RTTcpRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead);
+
+/**
+ * Send data to a socket.
+ *
+ * @returns iprt status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param Sock Socket descriptor.
+ * @param pvBuffer Buffer to write data to socket.
+ * @param cbBuffer How much to write.
+ */
+RTR3DECL(int) RTTcpWrite(RTSOCKET Sock, const void *pvBuffer, size_t cbBuffer);
+
+/**
+ * Flush socket write buffers.
+ *
+ * @returns iprt status code.
+ * @param Sock Socket descriptor.
+ */
+RTR3DECL(int) RTTcpFlush(RTSOCKET Sock);
+
+/**
+ * Enables or disables delaying sends to coalesce packets.
+ *
+ * The TCP/IP stack usually uses the Nagle algorithm (RFC 896) to implement the
+ * coalescing.
+ *
+ * @returns iprt status code.
+ * @param Sock Socket descriptor.
+ * @param fEnable When set to true enables coalescing.
+ */
+RTR3DECL(int) RTTcpSetSendCoalescing(RTSOCKET Sock, bool fEnable);
+
+/**
+ * Socket I/O multiplexing.
+ * Checks if the socket is ready for reading.
+ *
+ * @returns 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.
+ */
+RTR3DECL(int) RTTcpSelectOne(RTSOCKET Sock, RTMSINTERVAL cMillies);
+
+/**
+ * Socket I/O multiplexing
+ * Checks if the socket is ready for one of the given events.
+ *
+ * @returns iprt status code.
+ * @param Sock Socket descriptor.
+ * @param fEvents Event mask to wait for.
+ * Use the RTSOCKET_EVT_* defines.
+ * @param pfEvents Where to store the event mask on return.
+ * @param cMillies Number of milliseconds to wait for the socket.
+ * Use RT_INDEFINITE_WAIT to wait for ever.
+ */
+RTR3DECL(int) RTTcpSelectOneEx(RTSOCKET Sock, uint32_t fEvents, uint32_t *pfEvents,
+ RTMSINTERVAL cMillies);
+
+#if 0 /* skipping these for now - RTTcpServer* handles this. */
+/**
+ * Listen for connection on a socket.
+ *
+ * @returns iprt status code.
+ * @param Sock Socket descriptor.
+ * @param cBackLog The maximum length the queue of pending connections
+ * may grow to.
+ */
+RTR3DECL(int) RTTcpListen(RTSOCKET Sock, int cBackLog);
+
+/**
+ * Accept a connection on a socket.
+ *
+ * @returns iprt status code.
+ * @param Sock Socket descriptor.
+ * @param uPort The port for accepting connection.
+ * @param pSockAccepted Where to store the handle to the accepted connection.
+ */
+RTR3DECL(int) RTTcpAccept(RTSOCKET Sock, unsigned uPort, PRTSOCKET pSockAccepted);
+
+#endif
+
+/**
+ * Gets the address of the local side.
+ *
+ * @returns IPRT status code.
+ * @param Sock Socket descriptor.
+ * @param pAddr Where to store the local address on success.
+ */
+RTR3DECL(int) RTTcpGetLocalAddress(RTSOCKET Sock, PRTNETADDR pAddr);
+
+/**
+ * Gets the address of the other party.
+ *
+ * @returns IPRT status code.
+ * @param Sock Socket descriptor.
+ * @param pAddr Where to store the peer address on success.
+ */
+RTR3DECL(int) RTTcpGetPeerAddress(RTSOCKET Sock, PRTNETADDR pAddr);
+
+/**
+ * Send data from a scatter/gather buffer to a socket.
+ *
+ * @returns iprt status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param Sock Socket descriptor.
+ * @param pSgBuf Scatter/gather buffer to write data to socket.
+ */
+RTR3DECL(int) RTTcpSgWrite(RTSOCKET Sock, PCRTSGBUF pSgBuf);
+
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * ellipsis.
+ * @param ... Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTR3DECL(int) RTTcpSgWriteL(RTSOCKET hSocket, size_t cSegs, ...);
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * argument list.
+ * @param va Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTR3DECL(int) RTTcpSgWriteLV(RTSOCKET hSocket, size_t cSegs, va_list va);
+
+/**
+ * Receive data from a socket.
+ *
+ * This version doesn't block if there is no data on the socket.
+ *
+ * @returns 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.
+ */
+RTR3DECL(int) RTTcpReadNB(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead);
+
+/**
+ * Send data to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ *
+ * @returns 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.
+ */
+RTR3DECL(int) RTTcpWriteNB(RTSOCKET Sock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten);
+
+/**
+ * Send data from a scatter/gather buffer to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ *
+ * @returns iprt status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param Sock Socket descriptor.
+ * @param pSgBuf Scatter/gather buffer to write data to socket.
+ * @param pcbWritten Number of bytes written.
+ */
+RTR3DECL(int) RTTcpSgWriteNB(RTSOCKET Sock, PCRTSGBUF pSgBuf, size_t *pcbWritten);
+
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * ellipsis.
+ * @param pcbWritten Number of bytes written.
+ * @param ... Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTR3DECL(int) RTTcpSgWriteLNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, ...);
+
+/**
+ * Send data from multiple buffers to a socket.
+ *
+ * This version doesn't block if there is not enough room for the message.
+ * This is convenience wrapper around the RTSocketSgWrite and RTSgBufInit calls
+ * for lazy coders. The "L" in the function name is short for "list" just like
+ * in the execl libc API.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hSocket The socket handle.
+ * @param cSegs The number of data segments in the following
+ * argument list.
+ * @param pcbWritten Number of bytes written.
+ * @param va Pairs of buffer pointers (void const *) and buffer
+ * sizes (size_t). Make 101% sure the pointer is
+ * really size_t.
+ */
+RTR3DECL(int) RTTcpSgWriteLVNB(RTSOCKET hSocket, size_t cSegs, size_t *pcbWritten, va_list va);
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/test.h b/include/iprt/test.h
new file mode 100644
index 00000000..c004ab4f
--- /dev/null
+++ b/include/iprt/test.h
@@ -0,0 +1,1200 @@
+/** @file
+ * IPRT - Testcase Framework.
+ */
+
+/*
+ * 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 ___iprt_test_h
+#define ___iprt_test_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_test RTTest - Testcase Framework.
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** A test handle. */
+typedef struct RTTESTINT *RTTEST;
+/** A pointer to a test handle. */
+typedef RTTEST *PRTTEST;
+/** A const pointer to a test handle. */
+typedef RTTEST const *PCRTTEST;
+
+/** A NIL Test handle. */
+#define NIL_RTTEST ((RTTEST)0)
+
+/**
+ * Test message importance level.
+ */
+typedef enum RTTESTLVL
+{
+ /** Invalid 0. */
+ RTTESTLVL_INVALID = 0,
+ /** Message should always be printed. */
+ RTTESTLVL_ALWAYS,
+ /** Failure message. */
+ RTTESTLVL_FAILURE,
+ /** Sub-test banner. */
+ RTTESTLVL_SUB_TEST,
+ /** Info message. */
+ RTTESTLVL_INFO,
+ /** Debug message. */
+ RTTESTLVL_DEBUG,
+ /** The last (invalid). */
+ RTTESTLVL_END
+} RTTESTLVL;
+
+
+/**
+ * Creates a test instance.
+ *
+ * @returns IPRT status code.
+ * @param pszTest The test name.
+ * @param phTest Where to store the test instance handle.
+ */
+RTR3DECL(int) RTTestCreate(const char *pszTest, PRTTEST phTest);
+
+/**
+ * Initializes IPRT and creates a test instance.
+ *
+ * Typical usage is:
+ * @code
+ int main(int argc, char **argv)
+ {
+ RTTEST hTest;
+ int rc = RTTestInitAndCreate("tstSomething", &hTest);
+ if (rc)
+ return rc;
+ ...
+ }
+ @endcode
+ *
+ * @returns RTEXITCODE_SUCCESS on success. On failure an error message is
+ * printed and a suitable exit code is return.
+ *
+ * @param pszTest The test name.
+ * @param phTest Where to store the test instance handle.
+ */
+RTR3DECL(RTEXITCODE) RTTestInitAndCreate(const char *pszTest, PRTTEST phTest);
+
+/**
+ * Destroys a test instance previously created by RTTestCreate.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. NIL_RTTEST is ignored.
+ */
+RTR3DECL(int) RTTestDestroy(RTTEST hTest);
+
+/**
+ * Changes the default test instance for the calling thread.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hNewDefaultTest The new default test. NIL_RTTEST is fine.
+ * @param phOldTest Where to store the old test handle. Optional.
+ */
+RTR3DECL(int) RTTestSetDefault(RTTEST hNewDefaultTest, PRTTEST phOldTest);
+
+/**
+ * Allocate a block of guarded memory.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param cb The amount of memory to allocate.
+ * @param cbAlign The alignment of the returned block.
+ * @param fHead Head or tail optimized guard.
+ * @param ppvUser Where to return the pointer to the block.
+ */
+RTR3DECL(int) RTTestGuardedAlloc(RTTEST hTest, size_t cb, uint32_t cbAlign, bool fHead, void **ppvUser);
+
+/**
+ * Allocates a block of guarded memory where the guarded is immediately after
+ * the user memory.
+ *
+ * @returns Pointer to the allocated memory. NULL on failure.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param cb The amount of memory to allocate.
+ */
+RTR3DECL(void *) RTTestGuardedAllocTail(RTTEST hTest, size_t cb);
+
+/**
+ * Allocates a block of guarded memory where the guarded is right in front of
+ * the user memory.
+ *
+ * @returns Pointer to the allocated memory. NULL on failure.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param cb The amount of memory to allocate.
+ */
+RTR3DECL(void *) RTTestGuardedAllocHead(RTTEST hTest, size_t cb);
+
+/**
+ * Frees a block of guarded memory.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pv The memory. NULL is ignored.
+ */
+RTR3DECL(int) RTTestGuardedFree(RTTEST hTest, void *pv);
+
+/**
+ * Test vprintf making sure the output starts on a new line.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestPrintfNlV(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, va_list va);
+
+/**
+ * Test printf making sure the output starts on a new line.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestPrintfNl(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, ...);
+
+/**
+ * Test vprintf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestPrintfV(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, va_list va);
+
+/**
+ * Test printf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestPrintf(RTTEST hTest, RTTESTLVL enmLevel, const char *pszFormat, ...);
+
+/**
+ * Prints the test banner.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(int) RTTestBanner(RTTEST hTest);
+
+/**
+ * Summaries the test, destroys the test instance and return an exit code.
+ *
+ * @returns Test program exit code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(RTEXITCODE) RTTestSummaryAndDestroy(RTTEST hTest);
+
+/**
+ * Skips the test, destroys the test instance and return an exit code.
+ *
+ * @returns Test program exit code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszReasonFmt Text explaining why, optional (NULL).
+ * @param va Arguments for the reason format string.
+ */
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroyV(RTTEST hTest, const char *pszReasonFmt, va_list va);
+
+/**
+ * Skips the test, destroys the test instance and return an exit code.
+ *
+ * @returns Test program exit code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszReasonFmt Text explaining why, optional (NULL).
+ * @param ... Arguments for the reason format string.
+ */
+RTR3DECL(RTEXITCODE) RTTestSkipAndDestroy(RTTEST hTest, const char *pszReasonFmt, ...);
+
+/**
+ * Starts a sub-test.
+ *
+ * This will perform an implicit RTTestSubDone() call if that has not been done
+ * since the last RTTestSub call.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszSubTest The sub-test name.
+ */
+RTR3DECL(int) RTTestSub(RTTEST hTest, const char *pszSubTest);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestSubF(RTTEST hTest, const char *pszSubTestFmt, ...);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestSubV(RTTEST hTest, const char *pszSubTestFmt, va_list va);
+
+/**
+ * Completes a sub-test.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(int) RTTestSubDone(RTTEST hTest);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestPassedV(RTTEST hTest, const char *pszFormat, va_list va);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestPassed(RTTEST hTest, const char *pszFormat, ...);
+
+/**
+ * Value units.
+ */
+typedef enum RTTESTUNIT
+{
+ /** The usual invalid value. */
+ RTTESTUNIT_INVALID = 0,
+ /** Percentage. */
+ RTTESTUNIT_PCT,
+ /** Bytes. */
+ RTTESTUNIT_BYTES,
+ /** Bytes per second. */
+ RTTESTUNIT_BYTES_PER_SEC,
+ /** Kilobytes. */
+ RTTESTUNIT_KILOBYTES,
+ /** Kilobytes per second. */
+ RTTESTUNIT_KILOBYTES_PER_SEC,
+ /** Megabytes. */
+ RTTESTUNIT_MEGABYTES,
+ /** Megabytes per second. */
+ RTTESTUNIT_MEGABYTES_PER_SEC,
+ /** Packets. */
+ RTTESTUNIT_PACKETS,
+ /** Packets per second. */
+ RTTESTUNIT_PACKETS_PER_SEC,
+ /** Frames. */
+ RTTESTUNIT_FRAMES,
+ /** Frames per second. */
+ RTTESTUNIT_FRAMES_PER_SEC,
+ /** Occurrences. */
+ RTTESTUNIT_OCCURRENCES,
+ /** Occurrences per second. */
+ RTTESTUNIT_OCCURRENCES_PER_SEC,
+ /** Calls. */
+ RTTESTUNIT_CALLS,
+ /** Calls per second. */
+ RTTESTUNIT_CALLS_PER_SEC,
+ /** Round trips. */
+ RTTESTUNIT_ROUND_TRIP,
+ /** Seconds. */
+ RTTESTUNIT_SECS,
+ /** Milliseconds. */
+ RTTESTUNIT_MS,
+ /** Nanoseconds. */
+ RTTESTUNIT_NS,
+ /** Nanoseconds per call. */
+ RTTESTUNIT_NS_PER_CALL,
+ /** Nanoseconds per frame. */
+ RTTESTUNIT_NS_PER_FRAME,
+ /** Nanoseconds per occurrence. */
+ RTTESTUNIT_NS_PER_OCCURRENCE,
+ /** Nanoseconds per frame. */
+ RTTESTUNIT_NS_PER_PACKET,
+ /** Nanoseconds per round trip. */
+ RTTESTUNIT_NS_PER_ROUND_TRIP,
+ /** The end of valid units. */
+ RTTESTUNIT_END
+} RTTESTUNIT;
+
+/**
+ * Report a named test result value.
+ *
+ * This is typically used for benchmarking but can be used for other purposes
+ * like reporting limits of some implementation. The value gets associated with
+ * the current sub test, the name must be unique within the sub test.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszName The value name.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ */
+RTR3DECL(int) RTTestValue(RTTEST hTest, const char *pszName, uint64_t u64Value, RTTESTUNIT enmUnit);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param ... String arguments.
+ */
+RTR3DECL(int) RTTestValueF(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, ...);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param va_list String arguments.
+ */
+RTR3DECL(int) RTTestValueV(RTTEST hTest, uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, va_list va);
+
+/**
+ * Increments the error counter.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(int) RTTestErrorInc(RTTEST hTest);
+
+/**
+ * Get the current error count.
+ *
+ * @returns The error counter, UINT32_MAX if no valid test handle.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ */
+RTR3DECL(uint32_t) RTTestErrorCount(RTTEST hTest);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestFailedV(RTTEST hTest, const char *pszFormat, va_list va);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestFailed(RTTEST hTest, const char *pszFormat, ...);
+
+/**
+ * Same as RTTestPrintfV with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestFailureDetailsV(RTTEST hTest, const char *pszFormat, va_list va);
+
+/**
+ * Same as RTTestPrintf with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param hTest The test handle. If NIL_RTTEST we'll use the one
+ * associated with the calling thread.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestFailureDetails(RTTEST hTest, const char *pszFormat, ...);
+
+
+/** @def RTTEST_CHECK
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ */
+#define RTTEST_CHECK(hTest, expr) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and
+ * expression, then return @a rcRet.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param rcRet What to return on failure.
+ */
+#define RTTEST_CHECK_RET(hTest, expr, rcRet) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RETV
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and
+ * expression, then return void.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ */
+#define RTTEST_CHECK_RETV(hTest, expr) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_BREAK
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and
+ * expression, then break.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ */
+#define RTTEST_CHECK_BREAK(hTest, expr) \
+ if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ break; \
+ } else do {} while (0)
+
+
+/** @def RTTEST_CHECK_MSG
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestFailureDetails, including
+ * parenthesis.
+ */
+#define RTTEST_CHECK_MSG(hTest, expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ RTTestFailureDetails DetailsArgs; \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestFailureDetails, including
+ * parenthesis.
+ * @param rcRet What to return on failure.
+ */
+#define RTTEST_CHECK_MSG_RET(hTest, expr, DetailsArgs, rcRet) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ RTTestFailureDetails DetailsArgs; \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestFailed giving the line number and expression.
+ *
+ * @param hTest The test handle.
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestFailureDetails, including
+ * parenthesis.
+ */
+#define RTTEST_CHECK_MSG_RETV(hTest, expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestFailed((hTest), "line %u: %s", __LINE__, #expr); \
+ RTTestFailureDetails DetailsArgs; \
+ return; \
+ } \
+ } while (0)
+
+
+/** @def RTTEST_CHECK_RC
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTEST_CHECK_RC(hTest, rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_RET
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ * @param rcRet The return code.
+ */
+#define RTTEST_CHECK_RC_RET(hTest, rcExpr, rcExpect, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_RETV
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTEST_CHECK_RC_RETV(hTest, rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_BREAK
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestFailed giving the line
+ * number, expression, actual and expected status codes, then break.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTEST_CHECK_RC_BREAK(hTest, rcExpr, rcExpect) \
+ if (1) { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestFailed((hTest), "line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ break; \
+ } \
+ } else do {} while (0)
+
+
+/** @def RTTEST_CHECK_RC_OK
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestFailed giving the line number,
+ * expression and status code.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTEST_CHECK_RC_OK(hTest, rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestFailed((hTest), "line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_OK_RET
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestFailed giving the line number,
+ * expression and status code, then return with the specified value.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcRet The return code.
+ */
+#define RTTEST_CHECK_RC_OK_RET(hTest, rcExpr, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestFailed((hTest), "line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTEST_CHECK_RC_OK_RETV
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestFailed giving the line number,
+ * expression and status code, then return.
+ *
+ * @param hTest The test handle.
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTEST_CHECK_RC_OK_RETV(hTest, rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestFailed((hTest), "line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return; \
+ } \
+ } while (0)
+
+
+
+
+/** @name Implicit Test Handle API Variation
+ * The test handle is retrieved from the test TLS entry of the calling thread.
+ * @{
+ */
+
+/**
+ * Test vprintf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestIPrintfV(RTTESTLVL enmLevel, const char *pszFormat, va_list va);
+
+/**
+ * Test printf, makes sure lines are prefixed and so forth.
+ *
+ * @returns Number of chars printed.
+ * @param enmLevel Message importance level.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestIPrintf(RTTESTLVL enmLevel, const char *pszFormat, ...);
+
+/**
+ * Starts a sub-test.
+ *
+ * This will perform an implicit RTTestSubDone() call if that has not been done
+ * since the last RTTestSub call.
+ *
+ * @returns Number of chars printed.
+ * @param pszSubTest The sub-test name.
+ */
+RTR3DECL(int) RTTestISub(const char *pszSubTest);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestISubF(const char *pszSubTestFmt, ...);
+
+/**
+ * Format string version of RTTestSub.
+ *
+ * See RTTestSub for details.
+ *
+ * @returns Number of chars printed.
+ * @param pszSubTestFmt The sub-test name format string.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestISubV(const char *pszSubTestFmt, va_list va);
+
+/**
+ * Completes a sub-test.
+ *
+ * @returns Number of chars printed.
+ */
+RTR3DECL(int) RTTestISubDone(void);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestIPassedV(const char *pszFormat, va_list va);
+
+/**
+ * Prints an extended PASSED message, optional.
+ *
+ * This does not conclude the sub-test, it could be used to report the passing
+ * of a sub-sub-to-the-power-of-N-test.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestIPassed(const char *pszFormat, ...);
+
+/**
+ * Report a named test result value.
+ *
+ * This is typically used for benchmarking but can be used for other purposes
+ * like reporting limits of some implementation. The value gets associated with
+ * the current sub test, the name must be unique within the sub test.
+ *
+ * @returns IPRT status code.
+ *
+ * @param pszName The value name.
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ */
+RTR3DECL(int) RTTestIValue(const char *pszName, uint64_t u64Value, RTTESTUNIT enmUnit);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param ... String arguments.
+ */
+RTR3DECL(int) RTTestIValueF(uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, ...);
+
+/**
+ * Same as RTTestValue, except that the name is now a format string.
+ *
+ * @returns IPRT status code.
+ *
+ * @param u64Value The value.
+ * @param enmUnit The value unit.
+ * @param pszNameFmt The value name format string.
+ * @param va_list String arguments.
+ */
+RTR3DECL(int) RTTestIValueV(uint64_t u64Value, RTTESTUNIT enmUnit, const char *pszNameFmt, va_list va);
+
+/**
+ * Increments the error counter.
+ *
+ * @returns IPRT status code.
+ */
+RTR3DECL(int) RTTestIErrorInc(void);
+
+/**
+ * Get the current error count.
+ *
+ * @returns The error counter, UINT32_MAX if no valid test handle.
+ */
+RTR3DECL(uint32_t) RTTestIErrorCount(void);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestIFailedV(const char *pszFormat, va_list va);
+
+/**
+ * Increments the error counter and prints a failure message.
+ *
+ * @returns IPRT status code.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestIFailed(const char *pszFormat, ...);
+
+/**
+ * Increments the error counter, prints a failure message and returns the
+ * specified status code.
+ *
+ * This is mainly a convenience method for saving vertical space in the source
+ * code.
+ *
+ * @returns @a rcRet
+ * @param rcRet The IPRT status code to return.
+ * @param pszFormat The message. No trailing newline.
+ * @param va The arguments.
+ */
+RTR3DECL(int) RTTestIFailedRcV(int rcRet, const char *pszFormat, va_list va);
+
+/**
+ * Increments the error counter, prints a failure message and returns the
+ * specified status code.
+ *
+ * This is mainly a convenience method for saving vertical space in the source
+ * code.
+ *
+ * @returns @a rcRet
+ * @param rcRet The IPRT status code to return.
+ * @param pszFormat The message. No trailing newline.
+ * @param ... The arguments.
+ */
+RTR3DECL(int) RTTestIFailedRc(int rcRet, const char *pszFormat, ...);
+
+/**
+ * Same as RTTestIPrintfV with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param pszFormat The message.
+ * @param va Arguments.
+ */
+RTR3DECL(int) RTTestIFailureDetailsV(const char *pszFormat, va_list va);
+
+/**
+ * Same as RTTestIPrintf with RTTESTLVL_FAILURE.
+ *
+ * @returns Number of chars printed.
+ * @param pszFormat The message.
+ * @param ... Arguments.
+ */
+RTR3DECL(int) RTTestIFailureDetails(const char *pszFormat, ...);
+
+
+/** @def RTTESTI_CHECK
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ */
+#define RTTESTI_CHECK(expr) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression, then return @a rcRet.
+ *
+ * @param expr The expression to evaluate.
+ * @param rcRet What to return on failure.
+ */
+#define RTTESTI_CHECK_RET(expr, rcRet) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RETV
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression, then return void.
+ *
+ * @param expr The expression to evaluate.
+ */
+#define RTTESTI_CHECK_RETV(expr) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RETV
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression, then break.
+ *
+ * @param expr The expression to evaluate.
+ */
+#define RTTESTI_CHECK_BREAK(expr) \
+ if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ break; \
+ } do {} while (0)
+
+
+/** @def RTTESTI_CHECK_MSG
+ * Check whether a boolean expression holds true.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestIFailureDetails, including
+ * parenthesis.
+ */
+#define RTTESTI_CHECK_MSG(expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ RTTestIFailureDetails DetailsArgs; \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestIFailureDetails, including
+ * parenthesis.
+ * @param rcRet What to return on failure.
+ */
+#define RTTESTI_CHECK_MSG_RET(expr, DetailsArgs, rcRet) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ RTTestIFailureDetails DetailsArgs; \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_MSG_RET
+ * Check whether a boolean expression holds true, returns void on false.
+ *
+ * If the expression is false, call RTTestIFailed giving the line number and
+ * expression.
+ *
+ * @param expr The expression to evaluate.
+ * @param DetailsArgs Argument list for RTTestIFailureDetails, including
+ * parenthesis.
+ */
+#define RTTESTI_CHECK_MSG_RETV(expr, DetailsArgs) \
+ do { if (!(expr)) { \
+ RTTestIFailed("line %u: %s", __LINE__, #expr); \
+ RTTestIFailureDetails DetailsArgs; \
+ return; \
+ } \
+ } while (0)
+
+
+/** @def RTTESTI_CHECK_RC
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTESTI_CHECK_RC(rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_RET
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ * @param rcRet The return code.
+ */
+#define RTTESTI_CHECK_RC_RET(rcExpr, rcExpect, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_RETV
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes, then return.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTESTI_CHECK_RC_RETV(rcExpr, rcExpect) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ return; \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_BREAK
+ * Check whether an expression returns a specific IPRT style status code.
+ *
+ * If a different status code is return, call RTTestIFailed giving the line
+ * number, expression, actual and expected status codes, then break.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * @param rcExpect The expected return code. This may be referenced
+ * more than once by the macro.
+ */
+#define RTTESTI_CHECK_RC_BREAK(rcExpr, rcExpect) \
+ if (1) { \
+ int rcCheck = (rcExpr); \
+ if (rcCheck != (rcExpect)) { \
+ RTTestIFailed("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
+ break; \
+ } \
+ } else do {} while (0)
+
+
+/** @def RTTESTI_CHECK_RC_OK
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestIFailed giving the line number,
+ * expression and status code.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTESTI_CHECK_RC_OK(rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestIFailed("line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_OK_RET
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestIFailed giving the line number,
+ * expression and status code, then return with the specified value.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ * This will be assigned to a local rcCheck variable
+ * that can be used as return value.
+ * @param rcRet The return code.
+ */
+#define RTTESTI_CHECK_RC_OK_RET(rcExpr, rcRet) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestIFailed("line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return (rcRet); \
+ } \
+ } while (0)
+/** @def RTTESTI_CHECK_RC_OK_RETV
+ * Check whether a IPRT style status code indicates success.
+ *
+ * If the status indicates failure, call RTTestIFailed giving the line number,
+ * expression and status code, then return.
+ *
+ * @param rcExpr The expression resulting in an IPRT status code.
+ */
+#define RTTESTI_CHECK_RC_OK_RETV(rcExpr) \
+ do { \
+ int rcCheck = (rcExpr); \
+ if (RT_FAILURE(rcCheck)) { \
+ RTTestIFailed("line %u: %s: %Rrc", __LINE__, #rcExpr, rcCheck); \
+ return; \
+ } \
+ } while (0)
+
+/** @} */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/thread.h b/include/iprt/thread.h
new file mode 100644
index 00000000..6bd63b99
--- /dev/null
+++ b/include/iprt/thread.h
@@ -0,0 +1,832 @@
+/** @file
+ * IPRT - Threads.
+ */
+
+/*
+ * 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 ___iprt_thread_h
+#define ___iprt_thread_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_thread RTThread - Thread Management
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * The thread state.
+ */
+typedef enum RTTHREADSTATE
+{
+ /** The usual invalid 0 value. */
+ RTTHREADSTATE_INVALID = 0,
+ /** The thread is being initialized. */
+ RTTHREADSTATE_INITIALIZING,
+ /** The thread has terminated */
+ RTTHREADSTATE_TERMINATED,
+ /** Probably running. */
+ RTTHREADSTATE_RUNNING,
+
+ /** Waiting on a critical section. */
+ RTTHREADSTATE_CRITSECT,
+ /** Waiting on a event semaphore. */
+ RTTHREADSTATE_EVENT,
+ /** Waiting on a event multiple wakeup semaphore. */
+ RTTHREADSTATE_EVENT_MULTI,
+ /** Waiting on a fast mutex. */
+ RTTHREADSTATE_FAST_MUTEX,
+ /** Waiting on a mutex. */
+ RTTHREADSTATE_MUTEX,
+ /** Waiting on a read write semaphore, read (shared) access. */
+ RTTHREADSTATE_RW_READ,
+ /** Waiting on a read write semaphore, write (exclusive) access. */
+ RTTHREADSTATE_RW_WRITE,
+ /** The thread is sleeping. */
+ RTTHREADSTATE_SLEEP,
+ /** Waiting on a spin mutex. */
+ RTTHREADSTATE_SPIN_MUTEX,
+ /** End of the thread states. */
+ RTTHREADSTATE_END,
+
+ /** The usual 32-bit size hack. */
+ RTTHREADSTATE_32BIT_HACK = 0x7fffffff
+} RTTHREADSTATE;
+
+/** Checks if a thread state indicates that the thread is sleeping. */
+#define RTTHREAD_IS_SLEEPING(enmState) ((enmState) >= RTTHREADSTATE_CRITSECT)
+
+/**
+ * Thread types.
+ * Besides identifying the purpose of the thread, the thread type is
+ * used to select the scheduling properties.
+ *
+ * The types in are placed in a rough order of ascending priority.
+ */
+typedef enum RTTHREADTYPE
+{
+ /** Invalid type. */
+ RTTHREADTYPE_INVALID = 0,
+ /** Infrequent poller thread.
+ * This type of thread will sleep for the most of the time, and do
+ * infrequent polls on resources at 0.5 sec or higher intervals.
+ */
+ RTTHREADTYPE_INFREQUENT_POLLER,
+ /** Main heavy worker thread.
+ * Thread of this type is driving asynchronous tasks in the Main
+ * API which takes a long time and might involve a bit of CPU. Like
+ * for instance creating a fixed sized VDI.
+ */
+ RTTHREADTYPE_MAIN_HEAVY_WORKER,
+ /** The emulation thread type.
+ * While being a thread with very high workload it still is vital
+ * that it gets scheduled frequently. When possible all other thread
+ * types except DEFAULT and GUI should interrupt this one ASAP when
+ * they become ready.
+ */
+ RTTHREADTYPE_EMULATION,
+ /** The default thread type.
+ * Since it doesn't say much about the purpose of the thread
+ * nothing special is normally done to the scheduling. This type
+ * should be avoided.
+ * The main thread is registered with default type during RTR3Init()
+ * and that's what the default process priority is derived from.
+ */
+ RTTHREADTYPE_DEFAULT,
+ /** The GUI thread type
+ * The GUI normally have a low workload but is frequently scheduled
+ * to handle events. When possible the scheduler should not leave
+ * threads of this kind waiting for too long (~50ms).
+ */
+ RTTHREADTYPE_GUI,
+ /** Main worker thread.
+ * Thread of this type is driving asynchronous tasks in the Main API.
+ * In most cases this means little work an a lot of waiting.
+ */
+ RTTHREADTYPE_MAIN_WORKER,
+ /** VRDP I/O thread.
+ * These threads are I/O threads in the RDP server will hang around
+ * waiting for data, process it and pass it on.
+ */
+ RTTHREADTYPE_VRDP_IO,
+ /** The debugger type.
+ * Threads involved in servicing the debugger. It must remain
+ * responsive even when things are running wild in.
+ */
+ RTTHREADTYPE_DEBUGGER,
+ /** Message pump thread.
+ * Thread pumping messages from one thread/process to another
+ * thread/process. The workload is very small, most of the time
+ * it's blocked waiting for messages to be procduced or processed.
+ * This type of thread will be favored after I/O threads.
+ */
+ RTTHREADTYPE_MSG_PUMP,
+ /** The I/O thread type.
+ * Doing I/O means shuffling data, waiting for request to arrive and
+ * for them to complete. The thread should be favored when competing
+ * with any other threads except timer threads.
+ */
+ RTTHREADTYPE_IO,
+ /** The timer thread type.
+ * A timer thread is mostly waiting for the timer to tick
+ * and then perform a little bit of work. Accuracy is important here,
+ * so the thread should be favoured over all threads. If premention can
+ * be configured at thread level, it could be made very short.
+ */
+ RTTHREADTYPE_TIMER,
+ /** Only used for validation. */
+ RTTHREADTYPE_END
+} RTTHREADTYPE;
+
+
+#ifndef IN_RC
+
+/**
+ * Checks if the IPRT thread component has been initialized.
+ *
+ * This is used to avoid calling into RTThread before the runtime has been
+ * initialized.
+ *
+ * @returns @c true if it's initialized, @c false if not.
+ */
+RTDECL(bool) RTThreadIsInitialized(void);
+
+/**
+ * Get the thread handle of the current thread.
+ *
+ * @returns Thread handle.
+ */
+RTDECL(RTTHREAD) RTThreadSelf(void);
+
+/**
+ * Get the native thread handle of the current thread.
+ *
+ * @returns Native thread handle.
+ */
+RTDECL(RTNATIVETHREAD) RTThreadNativeSelf(void);
+
+/**
+ * Millisecond granular sleep function.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns VERR_INTERRUPTED if a signal or other asynchronous stuff happened
+ * which interrupt the peaceful sleep.
+ * @param cMillies Number of milliseconds to sleep.
+ * 0 milliseconds means yielding the timeslice - deprecated!
+ * @remark See RTThreadNanoSleep() for sleeping for smaller periods of time.
+ */
+RTDECL(int) RTThreadSleep(RTMSINTERVAL cMillies);
+
+/**
+ * Millisecond granular sleep function, no logger calls.
+ *
+ * Same as RTThreadSleep, except it will never call into the IPRT logger. It
+ * can therefore safely be used in places where the logger is off limits, like
+ * at termination or init time. The electric fence heap is one consumer of
+ * this API.
+ *
+ * @returns VINF_SUCCESS on success.
+ * @returns VERR_INTERRUPTED if a signal or other asynchronous stuff happened
+ * which interrupt the peaceful sleep.
+ * @param cMillies Number of milliseconds to sleep.
+ * 0 milliseconds means yielding the timeslice - deprecated!
+ */
+RTDECL(int) RTThreadSleepNoLog(RTMSINTERVAL cMillies);
+
+/**
+ * Yields the CPU.
+ *
+ * @returns true if we yielded.
+ * @returns false if it's probable that we didn't yield.
+ */
+RTDECL(bool) RTThreadYield(void);
+
+
+
+/**
+ * Thread function.
+ *
+ * @returns 0 on success.
+ * @param ThreadSelf Thread handle to this thread.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNRTTHREAD(RTTHREAD ThreadSelf, void *pvUser);
+/** Pointer to a FNRTTHREAD(). */
+typedef FNRTTHREAD *PFNRTTHREAD;
+
+/**
+ * Thread creation flags.
+ */
+typedef enum RTTHREADFLAGS
+{
+ /** This flag is used to keep the thread structure around so it can
+ * be waited on after termination. @sa RTThreadWait and
+ * RTThreadWaitNoResume. Not required for RTThreadUserWait and friends!
+ */
+ RTTHREADFLAGS_WAITABLE = RT_BIT(0),
+ /** The bit number corresponding to the RTTHREADFLAGS_WAITABLE mask. */
+ RTTHREADFLAGS_WAITABLE_BIT = 0,
+
+ /** Mask of valid flags, use for validation. */
+ RTTHREADFLAGS_MASK = RT_BIT(0)
+} RTTHREADFLAGS;
+
+
+/**
+ * Create a new thread.
+ *
+ * @returns iprt status code.
+ * @param pThread Where to store the thread handle to the new thread. (optional)
+ * @param pfnThread The thread function.
+ * @param pvUser User argument.
+ * @param cbStack The size of the stack for the new thread.
+ * Use 0 for the default stack size.
+ * @param enmType The thread type. Used for deciding scheduling attributes
+ * of the thread.
+ * @param fFlags Flags of the RTTHREADFLAGS type (ORed together).
+ * @param pszName Thread name.
+ *
+ * @remark When called in Ring-0, this API will create a new kernel thread and not a thread in
+ * the context of the calling process.
+ */
+RTDECL(int) RTThreadCreate(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+ RTTHREADTYPE enmType, unsigned fFlags, const char *pszName);
+
+/**
+ * Create a new thread.
+ *
+ * Same as RTThreadCreate except the name is given in the RTStrPrintfV form.
+ *
+ * @returns iprt status code.
+ * @param pThread See RTThreadCreate.
+ * @param pfnThread See RTThreadCreate.
+ * @param pvUser See RTThreadCreate.
+ * @param cbStack See RTThreadCreate.
+ * @param enmType See RTThreadCreate.
+ * @param fFlags See RTThreadCreate.
+ * @param pszName Thread name format.
+ * @param va Format arguments.
+ */
+RTDECL(int) RTThreadCreateV(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+ RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, va_list va);
+
+/**
+ * Create a new thread.
+ *
+ * Same as RTThreadCreate except the name is given in the RTStrPrintf form.
+ *
+ * @returns iprt status code.
+ * @param pThread See RTThreadCreate.
+ * @param pfnThread See RTThreadCreate.
+ * @param pvUser See RTThreadCreate.
+ * @param cbStack See RTThreadCreate.
+ * @param enmType See RTThreadCreate.
+ * @param fFlags See RTThreadCreate.
+ * @param pszName Thread name format.
+ * @param ... Format arguments.
+ */
+RTDECL(int) RTThreadCreateF(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack,
+ RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, ...);
+
+/**
+ * Gets the native thread id of a IPRT thread.
+ *
+ * @returns The native thread id.
+ * @param Thread The IPRT thread.
+ */
+RTDECL(RTNATIVETHREAD) RTThreadGetNative(RTTHREAD Thread);
+
+/**
+ * Gets the IPRT thread of a native thread.
+ *
+ * @returns The IPRT thread handle
+ * @returns NIL_RTTHREAD if not a thread known to IPRT.
+ * @param NativeThread The native thread handle/id.
+ */
+RTDECL(RTTHREAD) RTThreadFromNative(RTNATIVETHREAD NativeThread);
+
+/**
+ * Changes the type of the specified thread.
+ *
+ * @returns iprt status code.
+ * @param Thread The thread which type should be changed.
+ * @param enmType The new thread type.
+ * @remark In Ring-0 it only works if Thread == RTThreadSelf().
+ */
+RTDECL(int) RTThreadSetType(RTTHREAD Thread, RTTHREADTYPE enmType);
+
+/**
+ * Wait for the thread to terminate, resume on interruption.
+ *
+ * @returns iprt status code.
+ * Will not return VERR_INTERRUPTED.
+ * @param Thread The thread to wait for.
+ * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ * an indefinite wait.
+ * @param prc Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWait(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
+
+/**
+ * Wait for the thread to terminate, return on interruption.
+ *
+ * @returns iprt status code.
+ * @param Thread The thread to wait for.
+ * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ * an indefinite wait.
+ * @param prc Where to store the return code of the thread. Optional.
+ */
+RTDECL(int) RTThreadWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies, int *prc);
+
+/**
+ * Gets the name of the current thread thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ */
+RTDECL(const char *) RTThreadSelfName(void);
+
+/**
+ * Gets the name of a thread.
+ *
+ * @returns Pointer to readonly name string.
+ * @returns NULL on failure.
+ * @param Thread Thread handle of the thread to query the name of.
+ */
+RTDECL(const char *) RTThreadGetName(RTTHREAD Thread);
+
+/**
+ * Gets the type of the specified thread.
+ *
+ * @returns The thread type.
+ * @returns RTTHREADTYPE_INVALID if the thread handle is invalid.
+ * @param Thread The thread in question.
+ */
+RTDECL(RTTHREADTYPE) RTThreadGetType(RTTHREAD Thread);
+
+/**
+ * Sets the name of a thread.
+ *
+ * @returns iprt status code.
+ * @param Thread Thread handle of the thread to query the name of.
+ * @param pszName The thread name.
+ */
+RTDECL(int) RTThreadSetName(RTTHREAD Thread, const char *pszName);
+
+/**
+ * Checks if the specified thread is the main thread.
+ *
+ * @returns true if it is, false if it isn't.
+ *
+ * @param hThread The thread handle.
+ */
+RTDECL(bool) RTThreadIsMain(RTTHREAD hThread);
+
+/**
+ * Checks if the calling thread is known to IPRT.
+ *
+ * @returns @c true if it is, @c false if it isn't.
+ */
+RTDECL(bool) RTThreadIsSelfKnown(void);
+
+/**
+ * Checks if the calling thread is know to IPRT and is alive.
+ *
+ * @returns @c true if it is, @c false if it isn't.
+ */
+RTDECL(bool) RTThreadIsSelfAlive(void);
+
+/**
+ * Checks if the calling thread is known to IPRT.
+ *
+ * @returns @c true if it is, @c false if it isn't.
+ */
+RTDECL(bool) RTThreadIsOperational(void);
+
+/**
+ * Signal the user event.
+ *
+ * @returns iprt status code.
+ */
+RTDECL(int) RTThreadUserSignal(RTTHREAD Thread);
+
+/**
+ * Wait for the user event.
+ *
+ * @returns iprt status code.
+ * @param Thread The thread to wait for.
+ * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ * an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWait(RTTHREAD Thread, RTMSINTERVAL cMillies);
+
+/**
+ * Wait for the user event, return on interruption.
+ *
+ * @returns iprt status code.
+ * @param Thread The thread to wait for.
+ * @param cMillies The number of milliseconds to wait. Use RT_INDEFINITE_WAIT for
+ * an indefinite wait.
+ */
+RTDECL(int) RTThreadUserWaitNoResume(RTTHREAD Thread, RTMSINTERVAL cMillies);
+
+/**
+ * Reset the user event.
+ *
+ * @returns iprt status code.
+ * @param Thread The thread to reset.
+ */
+RTDECL(int) RTThreadUserReset(RTTHREAD Thread);
+
+/**
+ * Pokes the thread.
+ *
+ * This will signal the thread, attempting to interrupt whatever it's currently
+ * doing. This is *NOT* implemented on all platforms and may cause unresolved
+ * symbols during linking or VERR_NOT_IMPLEMENTED at runtime.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hThread The thread to poke. This must not be the
+ * calling thread.
+ */
+RTDECL(int) RTThreadPoke(RTTHREAD hThread);
+
+# ifdef IN_RING0
+
+/**
+ * Check if preemption is currently enabled or not for the current thread.
+ *
+ * @note This may return true even on systems where preemption isn't
+ * possible. In that case, it means no call to RTThreadPreemptDisable
+ * has been made and interrupts are still enabled.
+ *
+ * @returns true if preemption is enabled, false if preemetion is disabled.
+ * @param hThread Must be NIL_RTTHREAD for now.
+ */
+RTDECL(bool) RTThreadPreemptIsEnabled(RTTHREAD hThread);
+
+/**
+ * Check if preemption is pending for the current thread.
+ *
+ * This function should be called regularly when executing larger portions of
+ * code with preemption disabled.
+ *
+ * @returns true if pending, false if not.
+ * @param hThread Must be NIL_RTTHREAD for now.
+ */
+RTDECL(bool) RTThreadPreemptIsPending(RTTHREAD hThread);
+
+/**
+ * Is RTThreadPreemptIsPending reliable?
+ *
+ * @returns true if reliable, false if not.
+ */
+RTDECL(bool) RTThreadPreemptIsPendingTrusty(void);
+
+/**
+ * Is preemption possible on this system.
+ *
+ * @returns true if possible, false if not.
+ */
+RTDECL(bool) RTThreadPreemptIsPossible(void);
+
+/**
+ * Preemption state saved by RTThreadPreemptDisable and used by
+ * RTThreadPreemptRestore to restore the previous state.
+ */
+typedef struct RTTHREADPREEMPTSTATE
+{
+ /** In debug builds this will be used to check for cpu migration. */
+ RTCPUID idCpu;
+# ifdef RT_OS_WINDOWS
+ /** The old IRQL. Don't touch! */
+ unsigned char uchOldIrql;
+ /** Reserved, MBZ. */
+ uint8_t bReserved1;
+ /** Reserved, MBZ. */
+ uint8_t bReserved2;
+ /** Reserved, MBZ. */
+ uint8_t bReserved3;
+# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 255, 0, 0, 0 }
+# elif defined(RT_OS_SOLARIS)
+ /** The Old PIL. Don't touch! */
+ uint32_t uOldPil;
+# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, UINT32_MAX }
+# else
+ /** Reserved, MBZ. */
+ uint32_t u32Reserved;
+# define RTTHREADPREEMPTSTATE_INITIALIZER { NIL_RTCPUID, 0 }
+# endif
+} RTTHREADPREEMPTSTATE;
+/** Pointer to a preemption state. */
+typedef RTTHREADPREEMPTSTATE *PRTTHREADPREEMPTSTATE;
+
+/**
+ * Disable preemption.
+ *
+ * A call to this function must be matched by exactly one call to
+ * RTThreadPreemptRestore().
+ *
+ * @param pState Where to store the preemption state.
+ */
+RTDECL(void) RTThreadPreemptDisable(PRTTHREADPREEMPTSTATE pState);
+
+/**
+ * Restores the preemption state, undoing a previous call to
+ * RTThreadPreemptDisable.
+ *
+ * A call to this function must be matching a previous call to
+ * RTThreadPreemptDisable.
+ *
+ * @param pState The state return by RTThreadPreemptDisable.
+ */
+RTDECL(void) RTThreadPreemptRestore(PRTTHREADPREEMPTSTATE pState);
+
+/**
+ * Check if the thread is executing in interrupt context.
+ *
+ * @returns true if in interrupt context, false if not.
+ * @param hThread Must be NIL_RTTHREAD for now.
+ */
+RTDECL(bool) RTThreadIsInInterrupt(RTTHREAD hThread);
+
+# endif /* IN_RING0 */
+
+
+# ifdef IN_RING3
+
+/**
+ * Adopts a non-IPRT thread.
+ *
+ * @returns IPRT status code.
+ * @param enmType The thread type.
+ * @param fFlags The thread flags. RTTHREADFLAGS_WAITABLE is not currently allowed.
+ * @param pszName The thread name. Optional
+ * @param pThread Where to store the thread handle. Optional.
+ */
+RTDECL(int) RTThreadAdopt(RTTHREADTYPE enmType, unsigned fFlags, const char *pszName, PRTTHREAD pThread);
+
+/**
+ * Get the thread handle of the current thread, automatically adopting alien
+ * threads.
+ *
+ * @returns Thread handle.
+ */
+RTDECL(RTTHREAD) RTThreadSelfAutoAdopt(void);
+
+/**
+ * Gets the affinity mask of the current thread.
+ *
+ * @returns IPRT status code.
+ * @param pCpuSet Where to return the CPU affienty set of the calling
+ * thread.
+ */
+RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet);
+
+/**
+ * Sets the affinity mask of the current thread.
+ *
+ * @returns iprt status code.
+ * @param pCpuSet The set of CPUs this thread can run on. NULL means
+ * all CPUs.
+ */
+RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet);
+
+/**
+ * Binds the thread to one specific CPU.
+ *
+ * @returns iprt status code.
+ * @param idCpu The ID of the CPU to bind this thread to. Use
+ * NIL_RTCPUID to unbind it.
+ */
+RTR3DECL(int) RTThreadSetAffinityToCpu(RTCPUID idCpu);
+
+/**
+ * Unblocks a thread.
+ *
+ * This function is paired with RTThreadBlocking and RTThreadBlockingDebug.
+ *
+ * @param hThread The current thread.
+ * @param enmCurState The current state, used to check for nested blocking.
+ * The new state will be running.
+ */
+RTDECL(void) RTThreadUnblocked(RTTHREAD hThread, RTTHREADSTATE enmCurState);
+
+/**
+ * Change the thread state to blocking.
+ *
+ * @param hThread The current thread.
+ * @param enmState The sleep state.
+ * @param fReallySleeping Really going to sleep now. Use false before calls
+ * to other IPRT synchronization methods.
+ */
+RTDECL(void) RTThreadBlocking(RTTHREAD hThread, RTTHREADSTATE enmState, bool fReallySleeping);
+
+/**
+ * Get the current thread state.
+ *
+ * A thread that is reported as sleeping may actually still be running inside
+ * the lock validator or/and in the code of some other IPRT synchronization
+ * primitive. Use RTThreadGetReallySleeping
+ *
+ * @returns The thread state.
+ * @param hThread The thread.
+ */
+RTDECL(RTTHREADSTATE) RTThreadGetState(RTTHREAD hThread);
+
+/**
+ * Checks if the thread is really sleeping or not.
+ *
+ * @returns RTTHREADSTATE_RUNNING if not really sleeping, otherwise the state it
+ * is sleeping in.
+ * @param hThread The thread.
+ */
+RTDECL(RTTHREADSTATE) RTThreadGetReallySleeping(RTTHREAD hThread);
+
+/**
+ * Translate a thread state into a string.
+ *
+ * @returns Pointer to a read-only string containing the state name.
+ * @param enmState The state.
+ */
+RTDECL(const char *) RTThreadStateName(RTTHREADSTATE enmState);
+
+
+/**
+ * Native thread states returned by RTThreadNativeState.
+ */
+typedef enum RTTHREADNATIVESTATE
+{
+ /** Invalid thread handle. */
+ RTTHREADNATIVESTATE_INVALID = 0,
+ /** Unable to determine the thread state. */
+ RTTHREADNATIVESTATE_UNKNOWN,
+ /** The thread is running. */
+ RTTHREADNATIVESTATE_RUNNING,
+ /** The thread is blocked. */
+ RTTHREADNATIVESTATE_BLOCKED,
+ /** The thread is suspended / stopped. */
+ RTTHREADNATIVESTATE_SUSPENDED,
+ /** The thread has terminated. */
+ RTTHREADNATIVESTATE_TERMINATED,
+ /** Make sure it's a 32-bit type. */
+ RTTHREADNATIVESTATE_32BIT_HACK = 0x7fffffff
+} RTTHREADNATIVESTATE;
+
+
+/**
+ * Get the native state of a thread.
+ *
+ * @returns Native state.
+ * @param hThread The thread handle.
+ *
+ * @remarks Not yet implemented on all systems, so have a backup plan for
+ * RTTHREADNATIVESTATE_UNKNOWN.
+ */
+RTDECL(RTTHREADNATIVESTATE) RTThreadGetNativeState(RTTHREAD hThread);
+
+
+/**
+ * Get the execution times of the specified thread
+ *
+ * @returns IPRT status code.
+ * @param pKernelTime Kernel execution time in ms (out)
+ * @param pUserTime User execution time in ms (out)
+ *
+ */
+RTR3DECL(int) RTThreadGetExecutionTimeMilli(uint64_t *pKernelTime, uint64_t *pUserTime);
+
+/** @name Thread Local Storage
+ * @{
+ */
+/**
+ * Thread termination callback for destroying a non-zero TLS entry.
+ *
+ * @remarks It is not permitable to use any RTTls APIs at this time. Doing so
+ * may lead to endless loops, crashes, and other bad stuff.
+ *
+ * @param pvValue The current value.
+ */
+typedef DECLCALLBACK(void) FNRTTLSDTOR(void *pvValue);
+/** Pointer to a FNRTTLSDTOR. */
+typedef FNRTTLSDTOR *PFNRTTLSDTOR;
+
+/**
+ * Allocates a TLS entry (index).
+ *
+ * Example code:
+ * @code
+ RTTLS g_iTls = NIL_RTTLS;
+
+ ...
+
+ // once for the process, allocate the TLS index
+ if (g_iTls == NIL_RTTLS)
+ g_iTls = RTTlsAlloc();
+
+ // set the thread-local value.
+ RTTlsSet(g_iTls, pMyData);
+
+ ...
+
+ // get the thread-local value
+ PMYDATA pMyData = (PMYDATA)RTTlsGet(g_iTls);
+
+ @endcode
+ *
+ * @returns the index of the allocated TLS entry.
+ * @returns NIL_RTTLS on failure.
+ */
+RTR3DECL(RTTLS) RTTlsAlloc(void);
+
+/**
+ * Variant of RTTlsAlloc that returns a status code.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if pfnDestructor is non-NULL and the platform
+ * doesn't support this feature.
+ *
+ * @param piTls Where to store the index of the allocated TLS entry.
+ * This is set to NIL_RTTLS on failure.
+ * @param pfnDestructor Optional callback function for cleaning up on
+ * thread termination. WARNING! This feature may not
+ * be implemented everywhere.
+ */
+RTR3DECL(int) RTTlsAllocEx(PRTTLS piTls, PFNRTTLSDTOR pfnDestructor);
+
+/**
+ * Frees a TLS entry.
+ *
+ * @returns IPRT status code.
+ * @param iTls The index of the TLS entry.
+ */
+RTR3DECL(int) RTTlsFree(RTTLS iTls);
+
+/**
+ * Get the (thread-local) value stored in a TLS entry.
+ *
+ * @returns value in given TLS entry.
+ * @retval NULL if RTTlsSet() has not yet been called on this thread, or if the
+ * TLS index is invalid.
+ *
+ * @param iTls The index of the TLS entry.
+ */
+RTR3DECL(void *) RTTlsGet(RTTLS iTls);
+
+/**
+ * Get the value stored in a TLS entry.
+ *
+ * @returns IPRT status code.
+ * @param iTls The index of the TLS entry.
+ * @param ppvValue Where to store the value. The value will be NULL if
+ * RTTlsSet has not yet been called on this thread.
+ */
+RTR3DECL(int) RTTlsGetEx(RTTLS iTls, void **ppvValue);
+
+/**
+ * Set the value stored in an allocated TLS entry.
+ *
+ * @returns IPRT status.
+ * @param iTls The index of the TLS entry.
+ * @param pvValue The value to store.
+ *
+ * @remarks Note that NULL is considered a special value.
+ */
+RTR3DECL(int) RTTlsSet(RTTLS iTls, void *pvValue);
+
+/** @} */
+
+# endif /* IN_RING3 */
+# endif /* !IN_RC */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/time.h b/include/iprt/time.h
new file mode 100644
index 00000000..7a94dcd7
--- /dev/null
+++ b/include/iprt/time.h
@@ -0,0 +1,941 @@
+/** @file
+ * IPRT - Time.
+ */
+
+/*
+ * 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 ___iprt_time_h
+#define ___iprt_time_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_time RTTime - Time
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** Time Specification.
+ *
+ * Use the inline RTTimeSpecGet/Set to operate on structure this so we
+ * can easily change the representation if required later.
+ *
+ * The current representation is in nanoseconds relative to the unix epoch
+ * (1970-01-01 00:00:00 UTC). This gives us an approximate span from
+ * 1678 to 2262 without sacrificing the resolution offered by the various
+ * host OSes (BSD & LINUX 1ns, NT 100ns).
+ */
+typedef struct RTTIMESPEC
+{
+ /** Nanoseconds since epoch.
+ * The name is intentially too long to be comfortable to use because you should be
+ * using inline helpers! */
+ int64_t i64NanosecondsRelativeToUnixEpoch;
+} RTTIMESPEC;
+
+
+/** @name RTTIMESPEC methods
+ * @{ */
+
+/**
+ * Gets the time as nanoseconds relative to the unix epoch.
+ *
+ * @returns Nanoseconds relative to unix epoch.
+ * @param pTime The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetNano(PCRTTIMESPEC pTime)
+{
+ return pTime->i64NanosecondsRelativeToUnixEpoch;
+}
+
+
+/**
+ * Sets the time give by nanoseconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Nano The new time in nanoseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNano(PRTTIMESPEC pTime, int64_t i64Nano)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch = i64Nano;
+ return pTime;
+}
+
+
+/**
+ * Gets the time as microseconds relative to the unix epoch.
+ *
+ * @returns microseconds relative to unix epoch.
+ * @param pTime The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetMicro(PCRTTIMESPEC pTime)
+{
+ return pTime->i64NanosecondsRelativeToUnixEpoch / 1000;
+}
+
+
+/**
+ * Sets the time given by microseconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Micro The new time in microsecond.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMicro(PRTTIMESPEC pTime, int64_t i64Micro)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch = i64Micro * 1000;
+ return pTime;
+}
+
+
+/**
+ * Gets the time as milliseconds relative to the unix epoch.
+ *
+ * @returns milliseconds relative to unix epoch.
+ * @param pTime The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetMilli(PCRTTIMESPEC pTime)
+{
+ return pTime->i64NanosecondsRelativeToUnixEpoch / 1000000;
+}
+
+
+/**
+ * Sets the time given by milliseconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Milli The new time in milliseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetMilli(PRTTIMESPEC pTime, int64_t i64Milli)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch = i64Milli * 1000000;
+ return pTime;
+}
+
+
+/**
+ * Gets the time as seconds relative to the unix epoch.
+ *
+ * @returns seconds relative to unix epoch.
+ * @param pTime The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetSeconds(PCRTTIMESPEC pTime)
+{
+ return pTime->i64NanosecondsRelativeToUnixEpoch / 1000000000;
+}
+
+
+/**
+ * Sets the time given by seconds relative to the unix epoch.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Seconds The new time in seconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * 1000000000;
+ return pTime;
+}
+
+
+/**
+ * Makes the time spec absolute like abs() does (i.e. a positive value).
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAbsolute(PRTTIMESPEC pTime)
+{
+ if (pTime->i64NanosecondsRelativeToUnixEpoch < 0)
+ pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
+ return pTime;
+}
+
+
+/**
+ * Negates the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecNegate(PRTTIMESPEC pTime)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch = -pTime->i64NanosecondsRelativeToUnixEpoch;
+ return pTime;
+}
+
+
+/**
+ * Adds a time period to the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param pTimeAdd The time spec to add to pTime.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAdd(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeAdd)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch += pTimeAdd->i64NanosecondsRelativeToUnixEpoch;
+ return pTime;
+}
+
+
+/**
+ * Adds a time period give as nanoseconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Nano The time period in nanoseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddNano(PRTTIMESPEC pTime, int64_t i64Nano)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch += i64Nano;
+ return pTime;
+}
+
+
+/**
+ * Adds a time period give as microseconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Micro The time period in microseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMicro(PRTTIMESPEC pTime, int64_t i64Micro)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch += i64Micro * 1000;
+ return pTime;
+}
+
+
+/**
+ * Adds a time period give as milliseconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Milli The time period in milliseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddMilli(PRTTIMESPEC pTime, int64_t i64Milli)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch += i64Milli * 1000000;
+ return pTime;
+}
+
+
+/**
+ * Adds a time period give as seconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Seconds The time period in seconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecAddSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch += i64Seconds * 1000000000;
+ return pTime;
+}
+
+
+/**
+ * Subtracts a time period from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param pTimeSub The time spec to subtract from pTime.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSub(PRTTIMESPEC pTime, PCRTTIMESPEC pTimeSub)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch -= pTimeSub->i64NanosecondsRelativeToUnixEpoch;
+ return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as nanoseconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Nano The time period in nanoseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubNano(PRTTIMESPEC pTime, int64_t i64Nano)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch -= i64Nano;
+ return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as microseconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Micro The time period in microseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMicro(PRTTIMESPEC pTime, int64_t i64Micro)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch -= i64Micro * 1000;
+ return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as milliseconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Milli The time period in milliseconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubMilli(PRTTIMESPEC pTime, int64_t i64Milli)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch -= i64Milli * 1000000;
+ return pTime;
+}
+
+
+/**
+ * Subtracts a time period give as seconds from the time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Seconds The time period in seconds.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSubSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch -= i64Seconds * 100000000;
+ return pTime;
+}
+
+
+/* PORTME: Add struct timeval guard macro here. */
+#if defined(RTTIME_INCL_TIMEVAL) || defined(_STRUCT_TIMEVAL) || defined(_SYS__TIMEVAL_H_) || defined(_SYS_TIME_H) || defined(_TIMEVAL) || defined(_LINUX_TIME_H)
+/**
+ * Gets the time as POSIX timeval.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to interpret.
+ * @param pTimeval Where to store the time as POSIX timeval.
+ */
+DECLINLINE(struct timeval *) RTTimeSpecGetTimeval(PCRTTIMESPEC pTime, struct timeval *pTimeval)
+{
+ int64_t i64 = RTTimeSpecGetMicro(pTime);
+ int32_t i32Micro = (int32_t)(i64 % 1000000);
+ i64 /= 1000000;
+ if (i32Micro < 0)
+ {
+ i32Micro += 1000000;
+ i64--;
+ }
+ pTimeval->tv_sec = (time_t)i64;
+ pTimeval->tv_usec = i32Micro;
+ return pTimeval;
+}
+
+/**
+ * Sets the time as POSIX timeval.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param pTimeval Pointer to the POSIX timeval struct with the new time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimeval(PRTTIMESPEC pTime, const struct timeval *pTimeval)
+{
+ return RTTimeSpecAddMicro(RTTimeSpecSetSeconds(pTime, pTimeval->tv_sec), pTimeval->tv_usec);
+}
+#endif /* various ways of detecting struct timeval */
+
+
+/* PORTME: Add struct timespec guard macro here. */
+#if defined(RTTIME_INCL_TIMESPEC) || defined(_STRUCT_TIMESPEC) || defined(_SYS__TIMESPEC_H_) || defined(TIMEVAL_TO_TIMESPEC) || defined(_TIMESPEC)
+/**
+ * Gets the time as POSIX timespec.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to interpret.
+ * @param pTimespec Where to store the time as POSIX timespec.
+ */
+DECLINLINE(struct timespec *) RTTimeSpecGetTimespec(PCRTTIMESPEC pTime, struct timespec *pTimespec)
+{
+ int64_t i64 = RTTimeSpecGetNano(pTime);
+ int32_t i32Nano = (int32_t)(i64 % 1000000000);
+ i64 /= 1000000000;
+ if (i32Nano < 0)
+ {
+ i32Nano += 1000000000;
+ i64--;
+ }
+ pTimespec->tv_sec = (time_t)i64;
+ pTimespec->tv_nsec = i32Nano;
+ return pTimespec;
+}
+
+/**
+ * Sets the time as POSIX timespec.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param pTimespec Pointer to the POSIX timespec struct with the new time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetTimespec(PRTTIMESPEC pTime, const struct timespec *pTimespec)
+{
+ return RTTimeSpecAddNano(RTTimeSpecSetSeconds(pTime, pTimespec->tv_sec), pTimespec->tv_nsec);
+}
+#endif /* various ways of detecting struct timespec */
+
+
+
+/** The offset of the unix epoch and the base for NT time (in 100ns units).
+ * Nt time starts at 1601-01-01 00:00:00. */
+#define RTTIME_NT_TIME_OFFSET_UNIX (116444736000000000LL)
+
+
+/**
+ * Gets the time as NT time.
+ *
+ * @returns Nt time.
+ * @param pTime The time spec to interpret.
+ */
+DECLINLINE(uint64_t) RTTimeSpecGetNtTime(PCRTTIMESPEC pTime)
+{
+ return pTime->i64NanosecondsRelativeToUnixEpoch / 100
+ + RTTIME_NT_TIME_OFFSET_UNIX;
+}
+
+
+/**
+ * Sets the time given by Nt time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param u64NtTime The new time in Nt time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtTime(PRTTIMESPEC pTime, uint64_t u64NtTime)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch =
+ ((int64_t)u64NtTime - RTTIME_NT_TIME_OFFSET_UNIX) * 100;
+ return pTime;
+}
+
+
+#ifdef _FILETIME_
+/**
+ * Gets the time as NT file time.
+ *
+ * @returns pFileTime.
+ * @param pTime The time spec to interpret.
+ * @param pFileTime Pointer to NT filetime structure.
+ */
+DECLINLINE(PFILETIME) RTTimeSpecGetNtFileTime(PCRTTIMESPEC pTime, PFILETIME pFileTime)
+{
+ *((uint64_t *)pFileTime) = RTTimeSpecGetNtTime(pTime);
+ return pFileTime;
+}
+
+/**
+ * Sets the time as NT file time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param pFileTime Where to store the time as Nt file time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetNtFileTime(PRTTIMESPEC pTime, const FILETIME *pFileTime)
+{
+ return RTTimeSpecSetNtTime(pTime, *(const uint64_t *)pFileTime);
+}
+#endif
+
+
+/** The offset to the start of DOS time.
+ * DOS time starts 1980-01-01 00:00:00. */
+#define RTTIME_OFFSET_DOS_TIME (315532800000000000LL)
+
+
+/**
+ * Gets the time as seconds relative to the start of dos time.
+ *
+ * @returns seconds relative to the start of dos time.
+ * @param pTime The time spec to interpret.
+ */
+DECLINLINE(int64_t) RTTimeSpecGetDosSeconds(PCRTTIMESPEC pTime)
+{
+ return (pTime->i64NanosecondsRelativeToUnixEpoch - RTTIME_OFFSET_DOS_TIME)
+ / 1000000000;
+}
+
+
+/**
+ * Sets the time given by seconds relative to the start of dos time.
+ *
+ * @returns pTime.
+ * @param pTime The time spec to modify.
+ * @param i64Seconds The new time in seconds relative to the start of dos time.
+ */
+DECLINLINE(PRTTIMESPEC) RTTimeSpecSetDosSeconds(PRTTIMESPEC pTime, int64_t i64Seconds)
+{
+ pTime->i64NanosecondsRelativeToUnixEpoch = i64Seconds * 1000000000
+ + RTTIME_OFFSET_DOS_TIME;
+ return pTime;
+}
+
+
+/**
+ * Compare two time specs.
+ *
+ * @returns true they are equal.
+ * @returns false they are not equal.
+ * @param pTime1 The 1st time spec.
+ * @param pTime2 The 2nd time spec.
+ */
+DECLINLINE(bool) RTTimeSpecIsEqual(PCRTTIMESPEC pTime1, PCRTTIMESPEC pTime2)
+{
+ return pTime1->i64NanosecondsRelativeToUnixEpoch == pTime2->i64NanosecondsRelativeToUnixEpoch;
+}
+
+/**
+ * Converts a time spec to a ISO date string.
+ *
+ * @returns psz on success.
+ * @returns NULL on buffer underflow.
+ * @param pTime The time spec.
+ * @param psz Where to store the string.
+ * @param cb The size of the buffer.
+ */
+RTDECL(char *) RTTimeSpecToString(PCRTTIMESPEC pTime, char *psz, size_t cb);
+
+/** @} */
+
+
+/**
+ * Exploded time.
+ */
+#pragma pack(1)
+typedef struct RTTIME
+{
+ /** The year number. */
+ int32_t i32Year;
+ /** The month of the year (1-12). January is 1. */
+ uint8_t u8Month;
+ /** The day of the week (0-6). Monday is 0. */
+ uint8_t u8WeekDay;
+ /** The day of the year (1-366). January the 1st is 1. */
+ uint16_t u16YearDay;
+ /** The day of the month (1-31). */
+ uint8_t u8MonthDay;
+ /** Hour of the day (0-23). */
+ uint8_t u8Hour;
+ /** The minute of the hour (0-59). */
+ uint8_t u8Minute;
+ /** The second of the minute (0-60).
+ * (u32Nanosecond / 1000000) */
+ uint8_t u8Second;
+ /** The nanoseconds of the second (0-999999999). */
+ uint32_t u32Nanosecond;
+ /** Flags, of the RTTIME_FLAGS_* \#defines. */
+ uint32_t fFlags;
+ /** UCT time offset in minutes (-840-840).
+ * @remarks The implementation of RTTimeLocal* isn't quite there yet, so this might not be 100% correct. */
+ int32_t offUTC;
+} RTTIME;
+#pragma pack()
+/** Pointer to a exploded time structure. */
+typedef RTTIME *PRTTIME;
+/** Pointer to a const exploded time structure. */
+typedef const RTTIME *PCRTTIME;
+
+/** @name RTTIME::fFlags values.
+ * @{ */
+/** Set if the time is UTC. If clear the time local time. */
+#define RTTIME_FLAGS_TYPE_MASK 3
+/** the time is UTC time. */
+#define RTTIME_FLAGS_TYPE_UTC 2
+/** The time is local time. */
+#define RTTIME_FLAGS_TYPE_LOCAL 3
+
+/** Set if the time is local and daylight saving time is in effect.
+ * Not bit is not valid if RTTIME_FLAGS_NO_DST_DATA is set. */
+#define RTTIME_FLAGS_DST RT_BIT(4)
+/** Set if the time is local and there is no data available on daylight saving time. */
+#define RTTIME_FLAGS_NO_DST_DATA RT_BIT(5)
+/** Set if the year is a leap year.
+ * This is mutual exclusiv with RTTIME_FLAGS_COMMON_YEAR. */
+#define RTTIME_FLAGS_LEAP_YEAR RT_BIT(6)
+/** Set if the year is a common year.
+ * This is mutual exclusiv with RTTIME_FLAGS_LEAP_YEAR. */
+#define RTTIME_FLAGS_COMMON_YEAR RT_BIT(7)
+/** The mask of valid flags. */
+#define RTTIME_FLAGS_MASK UINT32_C(0xff)
+/** @} */
+
+
+/**
+ * Gets the current system time (UTC).
+ *
+ * @returns pTime.
+ * @param pTime Where to store the time.
+ */
+RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime);
+
+/**
+ * Sets the system time.
+ *
+ * @returns IPRT status code
+ * @param pTime The new system time (UTC).
+ *
+ * @remarks This will usually fail because changing the wall time is usually
+ * requires extra privileges.
+ */
+RTDECL(int) RTTimeSet(PCRTTIMESPEC pTime);
+
+/**
+ * Explodes a time spec (UTC).
+ *
+ * @returns pTime.
+ * @param pTime Where to store the exploded time.
+ * @param pTimeSpec The time spec to exploded.
+ */
+RTDECL(PRTTIME) RTTimeExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
+
+/**
+ * Implodes exploded time to a time spec (UTC).
+ *
+ * @returns pTime on success.
+ * @returns NULL if the pTime data is invalid.
+ * @param pTimeSpec Where to store the imploded UTC time.
+ * If pTime specifies a time which outside the range, maximum or
+ * minimum values will be returned.
+ * @param pTime Pointer to the exploded time to implode.
+ * The fields u8Month, u8WeekDay and u8MonthDay are not used,
+ * and all the other fields are expected to be within their
+ * bounds. Use RTTimeNormalize() to calculate u16YearDay and
+ * normalize the ranges of the fields.
+ */
+RTDECL(PRTTIMESPEC) RTTimeImplode(PRTTIMESPEC pTimeSpec, PCRTTIME pTime);
+
+/**
+ * Normalizes the fields of a time structure.
+ *
+ * It is possible to calculate year-day from month/day and vice
+ * versa. If you adjust any of of these, make sure to zero the
+ * other so you make it clear which of the fields to use. If
+ * it's ambiguous, the year-day field is used (and you get
+ * assertions in debug builds).
+ *
+ * All the time fields and the year-day or month/day fields will
+ * be adjusted for overflows. (Since all fields are unsigned, there
+ * is no underflows.) It is possible to exploit this for simple
+ * date math, though the recommended way of doing that to implode
+ * the time into a timespec and do the math on that.
+ *
+ * @returns pTime on success.
+ * @returns NULL if the data is invalid.
+ *
+ * @param pTime The time structure to normalize.
+ *
+ * @remarks This function doesn't work with local time, only with UTC time.
+ */
+RTDECL(PRTTIME) RTTimeNormalize(PRTTIME pTime);
+
+/**
+ * Gets the current local system time.
+ *
+ * @returns pTime.
+ * @param pTime Where to store the local time.
+ */
+RTDECL(PRTTIMESPEC) RTTimeLocalNow(PRTTIMESPEC pTime);
+
+/**
+ * Gets the delta between UTC and local time.
+ *
+ * @code
+ * RTTIMESPEC LocalTime;
+ * RTTimeSpecAddNano(RTTimeNow(&LocalTime), RTTimeLocalDeltaNano());
+ * @endcode
+ *
+ * @returns Returns the nanosecond delta between UTC and local time.
+ */
+RTDECL(int64_t) RTTimeLocalDeltaNano(void);
+
+/**
+ * Explodes a time spec to the localized timezone.
+ *
+ * @returns pTime.
+ * @param pTime Where to store the exploded time.
+ * @param pTimeSpec The time spec to exploded (UTC).
+ */
+RTDECL(PRTTIME) RTTimeLocalExplode(PRTTIME pTime, PCRTTIMESPEC pTimeSpec);
+
+/**
+ * Normalizes the fields of a time structure containing local time.
+ *
+ * See RTTimeNormalize for details.
+ *
+ * @returns pTime on success.
+ * @returns NULL if the data is invalid.
+ * @param pTime The time structure to normalize.
+ */
+RTDECL(PRTTIME) RTTimeLocalNormalize(PRTTIME pTime);
+
+/**
+ * Converts a time spec to a ISO date string.
+ *
+ * @returns psz on success.
+ * @returns NULL on buffer underflow.
+ * @param pTime The time. Caller should've normalized this.
+ * @param psz Where to store the string.
+ * @param cb The size of the buffer.
+ */
+RTDECL(char *) RTTimeToString(PCRTTIME pTime, char *psz, size_t cb);
+
+/**
+ * Checks if a year is a leap year or not.
+ *
+ * @returns true if it's a leap year.
+ * @returns false if it's a common year.
+ * @param i32Year The year in question.
+ */
+RTDECL(bool) RTTimeIsLeapYear(int32_t i32Year);
+
+/**
+ * Gets the current nanosecond timestamp.
+ *
+ * @returns nanosecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeNanoTS(void);
+
+/**
+ * Gets the current millisecond timestamp.
+ *
+ * @returns millisecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeMilliTS(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of 1ns steps which has been applied by RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgSteps(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of times the TSC interval expired RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgExpired(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of bad previous values encountered by RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgBad(void);
+
+/**
+ * Debugging the time api.
+ *
+ * @returns the number of update races in RTTimeNanoTS().
+ */
+RTDECL(uint32_t) RTTimeDbgRaces(void);
+
+/** @name RTTimeNanoTS GIP worker functions, for TM.
+ * @{ */
+/** Pointer to a RTTIMENANOTSDATA structure. */
+typedef struct RTTIMENANOTSDATA *PRTTIMENANOTSDATA;
+
+/**
+ * Nanosecond timestamp data.
+ *
+ * This is used to keep track of statistics and callback so IPRT
+ * and TM (VirtualBox) can share code.
+ *
+ * @remark Keep this in sync with the assembly version in timesupA.asm.
+ */
+typedef struct RTTIMENANOTSDATA
+{
+ /** Where the previous timestamp is stored.
+ * This is maintained to ensure that time doesn't go backwards or anything. */
+ uint64_t volatile *pu64Prev;
+
+ /**
+ * Helper function that's used by the assembly routines when something goes bust.
+ *
+ * @param pData Pointer to this structure.
+ * @param u64NanoTS The calculated nano ts.
+ * @param u64DeltaPrev The delta relative to the previously returned timestamp.
+ * @param u64PrevNanoTS The previously returned timestamp (as it was read it).
+ */
+ DECLCALLBACKMEMBER(void, pfnBad)(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS);
+
+ /**
+ * Callback for when rediscovery is required.
+ *
+ * @returns Nanosecond timestamp.
+ * @param pData Pointer to this structure.
+ */
+ DECLCALLBACKMEMBER(uint64_t, pfnRediscover)(PRTTIMENANOTSDATA pData);
+
+ /** Just a dummy alignment member. */
+ void *pvDummy;
+
+ /** Number of 1ns steps because of overshooting the period. */
+ uint32_t c1nsSteps;
+ /** The number of times the interval expired (overflow). */
+ uint32_t cExpired;
+ /** Number of "bad" previous values. */
+ uint32_t cBadPrev;
+ /** The number of update races. */
+ uint32_t cUpdateRaces;
+} RTTIMENANOTSDATA;
+
+#ifndef IN_RING3
+/**
+ * The Ring-3 layout of the RTTIMENANOTSDATA structure.
+ */
+typedef struct RTTIMENANOTSDATAR3
+{
+ R3PTRTYPE(uint64_t volatile *) pu64Prev;
+ DECLR3CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
+ DECLR3CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
+ RTR3PTR pvDummy;
+ uint32_t c1nsSteps;
+ uint32_t cExpired;
+ uint32_t cBadPrev;
+ uint32_t cUpdateRaces;
+} RTTIMENANOTSDATAR3;
+#else
+typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR3;
+#endif
+
+#ifndef IN_RING0
+/**
+ * The Ring-3 layout of the RTTIMENANOTSDATA structure.
+ */
+typedef struct RTTIMENANOTSDATAR0
+{
+ R0PTRTYPE(uint64_t volatile *) pu64Prev;
+ DECLR0CALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
+ DECLR0CALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
+ RTR0PTR pvDummy;
+ uint32_t c1nsSteps;
+ uint32_t cExpired;
+ uint32_t cBadPrev;
+ uint32_t cUpdateRaces;
+} RTTIMENANOTSDATAR0;
+#else
+typedef RTTIMENANOTSDATA RTTIMENANOTSDATAR0;
+#endif
+
+#ifndef IN_RC
+/**
+ * The RC layout of the RTTIMENANOTSDATA structure.
+ */
+typedef struct RTTIMENANOTSDATARC
+{
+ RCPTRTYPE(uint64_t volatile *) pu64Prev;
+ DECLRCCALLBACKMEMBER(void, pfnBad,(PRTTIMENANOTSDATA pData, uint64_t u64NanoTS, uint64_t u64DeltaPrev, uint64_t u64PrevNanoTS));
+ DECLRCCALLBACKMEMBER(uint64_t, pfnRediscover,(PRTTIMENANOTSDATA pData));
+ RCPTRTYPE(void *) pvDummy;
+ uint32_t c1nsSteps;
+ uint32_t cExpired;
+ uint32_t cBadPrev;
+ uint32_t cUpdateRaces;
+} RTTIMENANOTSDATARC;
+#else
+typedef RTTIMENANOTSDATA RTTIMENANOTSDATARC;
+#endif
+
+/** Internal RTTimeNanoTS worker (assembly). */
+typedef DECLCALLBACK(uint64_t) FNTIMENANOTSINTERNAL(PRTTIMENANOTSDATA pData);
+/** Pointer to an internal RTTimeNanoTS worker (assembly). */
+typedef FNTIMENANOTSINTERNAL *PFNTIMENANOTSINTERNAL;
+
+RTDECL(uint64_t) RTTimeNanoTSLegacySync(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLegacyAsync(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceSync(PRTTIMENANOTSDATA pData);
+RTDECL(uint64_t) RTTimeNanoTSLFenceAsync(PRTTIMENANOTSDATA pData);
+/** @} */
+
+
+/**
+ * Gets the current nanosecond timestamp.
+ *
+ * This differs from RTTimeNanoTS in that it will use system APIs and not do any
+ * resolution or performance optimizations.
+ *
+ * @returns nanosecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeSystemNanoTS(void);
+
+/**
+ * Gets the current millisecond timestamp.
+ *
+ * This differs from RTTimeNanoTS in that it will use system APIs and not do any
+ * resolution or performance optimizations.
+ *
+ * @returns millisecond timestamp.
+ */
+RTDECL(uint64_t) RTTimeSystemMilliTS(void);
+
+/**
+ * Get the nanosecond timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint64_t) RTTimeProgramNanoTS(void);
+
+/**
+ * Get the microsecond timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint64_t) RTTimeProgramMicroTS(void);
+
+/**
+ * Get the millisecond timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint64_t) RTTimeProgramMilliTS(void);
+
+/**
+ * Get the second timestamp relative to program startup.
+ *
+ * @returns Timestamp relative to program startup.
+ */
+RTDECL(uint32_t) RTTimeProgramSecTS(void);
+
+/**
+ * Get the RTTimeNanoTS() of when the program started.
+ *
+ * @returns Program startup timestamp.
+ */
+RTDECL(uint64_t) RTTimeProgramStartNanoTS(void);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/timer.h b/include/iprt/timer.h
new file mode 100644
index 00000000..54e63a7a
--- /dev/null
+++ b/include/iprt/timer.h
@@ -0,0 +1,379 @@
+/** @file
+ * IPRT - Timer.
+ */
+
+/*
+ * 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 ___iprt_timer_h
+#define ___iprt_timer_h
+
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_timer RTTimer - Timer
+ *
+ * The IPRT timer API provides a simple abstraction of recurring and one-shot callback timers.
+ *
+ * Because of the great variation in the native APIs and the quality of
+ * the service delivered by those native APIs, the timers are operated
+ * on at best effort basis.
+ *
+ * All the ring-3 implementations are naturally at the mercy of the scheduler,
+ * which means that the callback rate might vary quite a bit and we might skip
+ * ticks. Many systems have a restriction that a process can only have one
+ * timer. IPRT currently makes no efforts at multiplexing timers in those kind
+ * of situations and will simply fail if you try to create more than one timer.
+ *
+ * Things are generally better in ring-0. The implementations will use interrupt
+ * time callbacks wherever available, and if not, resort to a high priority
+ * kernel thread.
+ *
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/** Timer handle. */
+typedef struct RTTIMER *PRTTIMER;
+
+/**
+ * Timer callback function.
+ *
+ * The context this call is made in varies with different platforms and
+ * kernel / user mode IPRT.
+ *
+ * In kernel mode a timer callback should not waste time, it shouldn't
+ * waste stack and it should be prepared that some APIs might not work
+ * correctly because of weird OS restrictions in this context that we
+ * haven't discovered and avoided yet. Please fix those APIs so they
+ * at least avoid panics and weird behaviour.
+ *
+ * @param pTimer Timer handle.
+ * @param pvUser User argument.
+ * @param iTick The current timer tick. This is always 1 on the first
+ * callback after the timer was started. For omni timers
+ * this will be 1 when a cpu comes back online.
+ */
+typedef DECLCALLBACK(void) FNRTTIMER(PRTTIMER pTimer, void *pvUser, uint64_t iTick);
+/** Pointer to FNRTTIMER() function. */
+typedef FNRTTIMER *PFNRTTIMER;
+
+
+/**
+ * Create a recurring timer.
+ *
+ * @returns iprt status code.
+ * @param ppTimer Where to store the timer handle.
+ * @param uMilliesInterval Milliseconds between the timer ticks.
+ * This is rounded up to the system granularity.
+ * @param pfnTimer Callback function which shall be scheduled for execution
+ * on every timer tick.
+ * @param pvUser User argument for the callback.
+ * @see RTTimerCreateEx, RTTimerStart, RTTimerStop, RTTimerChangeInterval,
+ * RTTimerDestroy, RTTimerGetSystemGranularity
+ */
+RTDECL(int) RTTimerCreate(PRTTIMER *ppTimer, unsigned uMilliesInterval, PFNRTTIMER pfnTimer, void *pvUser);
+
+/**
+ * Create a suspended timer.
+ *
+ * @returns iprt status code.
+ * @retval VERR_NOT_SUPPORTED if an unsupported flag was specfied.
+ * @retval VERR_CPU_NOT_FOUND if the specified CPU
+ *
+ * @param ppTimer Where to store the timer handle.
+ * @param u64NanoInterval The interval between timer ticks specified in nanoseconds if it's
+ * a recurring timer. This is rounded to the fit the system timer granularity.
+ * For one shot timers, pass 0.
+ * @param fFlags Timer flags.
+ * @param pfnTimer Callback function which shall be scheduled for execution
+ * on every timer tick.
+ * @param pvUser User argument for the callback.
+ * @see RTTimerStart, RTTimerStop, RTTimerChangeInterval, RTTimerDestroy,
+ * RTTimerGetSystemGranularity, RTTimerCanDoHighResolution
+ */
+RTDECL(int) RTTimerCreateEx(PRTTIMER *ppTimer, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMER pfnTimer, void *pvUser);
+
+/** @name RTTimerCreateEx flags
+ * @{ */
+/** Any CPU is fine. (Must be 0.) */
+#define RTTIMER_FLAGS_CPU_ANY UINT32_C(0)
+/** One specific CPU */
+#define RTTIMER_FLAGS_CPU_SPECIFIC RT_BIT(8)
+/** Omni timer, run on all online CPUs.
+ * @remarks The timer callback isn't necessarily running at the time same time on each CPU. */
+#define RTTIMER_FLAGS_CPU_ALL ( RTTIMER_FLAGS_CPU_MASK | RTTIMER_FLAGS_CPU_SPECIFIC )
+/** CPU mask. */
+#define RTTIMER_FLAGS_CPU_MASK UINT32_C(0xff)
+/** Desire a high resolution timer that works with RTTimerChangeInterval and
+ * isn't subject to RTTimerGetSystemGranularity rounding.
+ * @remarks This is quietly ignored if the feature isn't supported. */
+#define RTTIMER_FLAGS_HIGH_RES RT_BIT(9)
+/** Convert a CPU set index (0-based) to RTTimerCreateEx flags.
+ * This will automatically OR in the RTTIMER_FLAGS_CPU_SPECIFIC flag. */
+#define RTTIMER_FLAGS_CPU(iCpu) ( (iCpu) | RTTIMER_FLAGS_CPU_SPECIFIC )
+/** Macro that validates the flags. */
+#define RTTIMER_FLAGS_ARE_VALID(fFlags) \
+ ( !((fFlags) & ~((fFlags) & RTTIMER_FLAGS_CPU_SPECIFIC ? UINT32_C(0x3ff) : UINT32_C(0x300))) )
+/** @} */
+
+/**
+ * Stops and destroys a running timer.
+ *
+ * @returns iprt status code.
+ * @param pTimer Timer to stop and destroy. NULL is ok.
+ */
+RTDECL(int) RTTimerDestroy(PRTTIMER pTimer);
+
+/**
+ * Starts a suspended timer.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval VERR_TIMER_ACTIVE if the timer isn't suspended.
+ * @retval VERR_CPU_OFFLINE if the CPU the timer was created to run on is not
+ * online (this include the case where it's not present in the
+ * system).
+ *
+ * @param pTimer The timer to activate.
+ * @param u64First The RTTimeSystemNanoTS() for when the timer should start
+ * firing (relative). If 0 is specified, the timer will
+ * fire ASAP.
+ * @remarks When RTTimerCanDoHighResolution returns true, this API is
+ * callable with preemption disabled in ring-0.
+ * @see RTTimerStop
+ */
+RTDECL(int) RTTimerStart(PRTTIMER pTimer, uint64_t u64First);
+
+/**
+ * Stops an active timer.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval VERR_TIMER_SUSPENDED if the timer isn't active.
+ * @retval VERR_NOT_SUPPORTED if the IPRT implementation doesn't support
+ * stopping a timer.
+ *
+ * @param pTimer The timer to suspend.
+ * @remarks Can be called from the timer callback function to stop it.
+ * @see RTTimerStart
+ */
+RTDECL(int) RTTimerStop(PRTTIMER pTimer);
+
+/**
+ * Changes the interval of a periodic timer.
+ *
+ * If the timer is active, it is implementation dependent whether the change
+ * takes place immediately or after the next tick. To get defined behavior,
+ * stop the timer before calling this API.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval VERR_NOT_SUPPORTED if not supported.
+ *
+ * @param pTimer The timer to activate.
+ * @param u64NanoInterval The interval between timer ticks specified in
+ * nanoseconds. This is rounded to the fit the
+ * system timer granularity.
+ * @remarks Callable from the timer callback. Callable with preemption
+ * disabled in ring-0.
+ */
+RTDECL(int) RTTimerChangeInterval(PRTTIMER pTimer, uint64_t u64NanoInterval);
+
+/**
+ * Gets the (current) timer granularity of the system.
+ *
+ * @returns The timer granularity of the system in nanoseconds.
+ * @see RTTimerRequestSystemGranularity
+ */
+RTDECL(uint32_t) RTTimerGetSystemGranularity(void);
+
+/**
+ * Requests a specific system timer granularity.
+ *
+ * Successfull calls to this API must be coupled with the exact same number of
+ * calls to RTTimerReleaseSystemGranularity() in order to undo any changes made.
+ *
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the requested value isn't supported by the host platform
+ * or if the host platform doesn't support modifying the system timer granularity.
+ * @retval VERR_PERMISSION_DENIED if the caller doesn't have the necessary privilege to
+ * modify the system timer granularity.
+ *
+ * @param u32Request The requested system timer granularity in nanoseconds.
+ * @param pu32Granted Where to store the granted system granularity. This is the value
+ * that should be passed to RTTimerReleaseSystemGranularity(). It
+ * is what RTTimerGetSystemGranularity() would return immediately
+ * after the change was made.
+ *
+ * The value differ from the request in two ways; rounding and
+ * scale. Meaning if your request is for 10.000.000 you might
+ * be granted 10.000.055 or 1.000.000.
+ * @see RTTimerReleaseSystemGranularity, RTTimerGetSystemGranularity
+ */
+RTDECL(int) RTTimerRequestSystemGranularity(uint32_t u32Request, uint32_t *pu32Granted);
+
+/**
+ * Releases a system timer granularity grant acquired by RTTimerRequestSystemGranularity().
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the host platform doesn't have any way of modifying
+ * the system timer granularity.
+ * @retval VERR_WRONG_ORDER if nobody call RTTimerRequestSystemGranularity() with the
+ * given grant value.
+ * @param u32Granted The granted system granularity.
+ * @see RTTimerRequestSystemGranularity
+ */
+RTDECL(int) RTTimerReleaseSystemGranularity(uint32_t u32Granted);
+
+/**
+ * Checks if the system support high resolution timers.
+ *
+ * The kind of support we are checking for is the kind of dynamically
+ * reprogrammable timers employed by recent Solaris and Linux kernels. It also
+ * implies that we can specify microsecond (or even better maybe) intervals
+ * without getting into trouble.
+ *
+ * @returns true if supported, false it not.
+ *
+ * @remarks Returning true also means RTTimerChangeInterval must be implemented
+ * and RTTimerStart be callable with preemption disabled.
+ */
+RTDECL(bool) RTTimerCanDoHighResolution(void);
+
+
+/**
+ * Timer callback function for low res timers.
+ *
+ * This is identical to FNRTTIMER except for the first parameter, so
+ * see FNRTTIMER for details.
+ *
+ * @param hTimerLR The low resolution timer handle.
+ * @param pvUser User argument.
+ * @param iTick The current timer tick. This is always 1 on the first
+ * callback after the timer was started. Will jump if we've
+ * skipped ticks when lagging behind.
+ */
+typedef DECLCALLBACK(void) FNRTTIMERLR(RTTIMERLR hTimerLR, void *pvUser, uint64_t iTick);
+/** Pointer to FNRTTIMER() function. */
+typedef FNRTTIMERLR *PFNRTTIMERLR;
+
+
+/**
+ * Create a recurring low resolution timer.
+ *
+ * @returns iprt status code.
+ * @param phTimerLR Where to store the timer handle.
+ * @param uMilliesInterval Milliseconds between the timer ticks, at least 100 ms.
+ * If higher resolution is required use the other API.
+ * @param pfnTimer Callback function which shall be scheduled for execution
+ * on every timer tick.
+ * @param pvUser User argument for the callback.
+ * @see RTTimerLRCreateEx, RTTimerLRDestroy, RTTimerLRStop
+ */
+RTDECL(int) RTTimerLRCreate(PRTTIMERLR phTimerLR, uint32_t uMilliesInterval, PFNRTTIMERLR pfnTimer, void *pvUser);
+
+/**
+ * Create a suspended low resolution timer.
+ *
+ * @returns iprt status code.
+ * @retval VERR_NOT_SUPPORTED if an unsupported flag was specfied.
+ *
+ * @param phTimerLR Where to store the timer handle.
+ * @param u64NanoInterval The interval between timer ticks specified in nanoseconds if it's
+ * a recurring timer, the minimum for is 100000000 ns.
+ * For one shot timers, pass 0.
+ * @param fFlags Timer flags. Same as RTTimerCreateEx.
+ * @param pfnTimer Callback function which shall be scheduled for execution
+ * on every timer tick.
+ * @param pvUser User argument for the callback.
+ * @see RTTimerLRStart, RTTimerLRStop, RTTimerLRDestroy
+ */
+RTDECL(int) RTTimerLRCreateEx(PRTTIMERLR phTimerLR, uint64_t u64NanoInterval, uint32_t fFlags, PFNRTTIMERLR pfnTimer, void *pvUser);
+
+/**
+ * Stops and destroys a running low resolution timer.
+ *
+ * @returns iprt status code.
+ * @param hTimerLR The low resolution timer to stop and destroy.
+ * NIL_RTTIMERLR is accepted.
+ */
+RTDECL(int) RTTimerLRDestroy(RTTIMERLR hTimerLR);
+
+/**
+ * Starts a low resolution timer.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval VERR_TIMER_ACTIVE if the timer isn't suspended.
+ *
+ * @param hTimerLR The low resolution timer to activate.
+ * @param u64First The RTTimeSystemNanoTS() for when the timer should start
+ * firing (relative), the minimum is 100000000 ns.
+ * If 0 is specified, the timer will fire ASAP.
+ *
+ * @see RTTimerLRStop
+ */
+RTDECL(int) RTTimerLRStart(RTTIMERLR hTimerLR, uint64_t u64First);
+
+/**
+ * Stops an active low resolution timer.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval VERR_TIMER_SUSPENDED if the timer isn't active.
+ * @retval VERR_NOT_SUPPORTED if the IPRT implementation doesn't support stopping a timer.
+ *
+ * @param hTimerLR The low resolution timer to suspend.
+ *
+ * @see RTTimerLRStart
+ */
+RTDECL(int) RTTimerLRStop(RTTIMERLR hTimerLR);
+
+/**
+ * Changes the interval of a low resolution timer.
+ *
+ * If the timer is active, the next tick will occure immediately just like with
+ * RTTimerLRStart() when u64First parameter is zero.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_INVALID_HANDLE if pTimer isn't valid.
+ * @retval VERR_NOT_SUPPORTED if not supported.
+ *
+ * @param hTimerLR The low resolution timer to update.
+ * @param u64NanoInterval The interval between timer ticks specified in
+ * nanoseconds. This is rounded to the fit the
+ * system timer granularity.
+ * @remarks Callable from the timer callback.
+ */
+RTDECL(int) RTTimerLRChangeInterval(RTTIMERLR hTimerLR, uint64_t u64NanoInterval);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
diff --git a/include/iprt/trace.h b/include/iprt/trace.h
new file mode 100644
index 00000000..263c715b
--- /dev/null
+++ b/include/iprt/trace.h
@@ -0,0 +1,215 @@
+/** @file
+ * IPRT - Tracing.
+ */
+
+/*
+ * 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 ___iprt_trace_h
+#define ___iprt_trace_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/stdarg.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_trace RTTrace - Tracing
+ * @ingroup grp_rt
+ *
+ * The tracing facility is somewhat similar to a stripped down logger that
+ * outputs to a circular buffer. Part of the idea here is that it can the
+ * overhead is much smaller and that it can be done without involving any
+ * locking or other thing that could throw off timing.
+ *
+ * @{
+ */
+
+
+#ifdef DOXYGEN_RUNNING
+# define RTTRACE_DISABLED
+# define RTTRACE_ENABLED
+#endif
+
+/** @def RTTRACE_DISABLED
+ * Use this compile time define to disable all tracing macros. This trumps
+ * RTTRACE_ENABLED.
+ */
+
+/** @def RTTRACE_ENABLED
+ * Use this compile time define to enable tracing when not in debug mode
+ */
+
+/*
+ * Determine whether tracing is enabled and forcefully normalize the indicators.
+ */
+#if (defined(DEBUG) || defined(RTTRACE_ENABLED)) && !defined(RTTRACE_DISABLED)
+# undef RTTRACE_DISABLED
+# undef RTTRACE_ENABLED
+# define RTTRACE_ENABLED
+#else
+# undef RTTRACE_DISABLED
+# undef RTTRACE_ENABLED
+# define RTTRACE_DISABLED
+#endif
+
+
+/** @name RTTRACEBUF_FLAGS_XXX - RTTraceBufCarve and RTTraceBufCreate flags.
+ * @{ */
+/** Free the memory block on release using RTMemFree(). */
+#define RTTRACEBUF_FLAGS_FREE_ME RT_BIT_32(0)
+/** Whether the trace buffer is disabled or enabled. */
+#define RTTRACEBUF_FLAGS_DISABLED RT_BIT_32(RTTRACEBUF_FLAGS_DISABLED_BIT)
+/** The bit number corresponding to the RTTRACEBUF_FLAGS_DISABLED mask. */
+#define RTTRACEBUF_FLAGS_DISABLED_BIT 1
+/** Mask of the valid flags. */
+#define RTTRACEBUF_FLAGS_MASK UINT32_C(0x00000003)
+/** @} */
+
+
+RTDECL(int) RTTraceBufCreate(PRTTRACEBUF hTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags);
+RTDECL(int) RTTraceBufCarve(PRTTRACEBUF hTraceBuf, uint32_t cEntries, uint32_t cbEntry, uint32_t fFlags,
+ void *pvBlock, size_t *pcbBlock);
+RTDECL(uint32_t) RTTraceBufRetain(RTTRACEBUF hTraceBuf);
+RTDECL(uint32_t) RTTraceBufRelease(RTTRACEBUF hTraceBuf);
+RTDECL(int) RTTraceBufDumpToLog(RTTRACEBUF hTraceBuf);
+RTDECL(int) RTTraceBufDumpToAssert(RTTRACEBUF hTraceBuf);
+
+/**
+ * Trace buffer callback for processing one entry.
+ *
+ * Used by RTTraceBufEnumEntries.
+ *
+ * @returns IPRT status code. Any status code but VINF_SUCCESS will abort the
+ * enumeration and be returned by RTTraceBufEnumEntries.
+ * @param hTraceBuf The trace buffer handle.
+ * @param iEntry The entry number.
+ * @param NanoTS The timestamp of the entry.
+ * @param idCpu The ID of the CPU which added the entry.
+ * @param pszMsg The message text.
+ * @param pvUser The user argument.
+ */
+typedef DECLCALLBACK(int) FNRTTRACEBUFCALLBACK(RTTRACEBUF hTraceBuf, uint32_t iEntry, uint64_t NanoTS,
+ RTCPUID idCpu, const char *pszMsg, void *pvUser);
+/** Pointer to trace buffer enumeration callback function. */
+typedef FNRTTRACEBUFCALLBACK *PFNRTTRACEBUFCALLBACK;
+
+/**
+ * Enumerates the used trace buffer entries, calling @a pfnCallback for each.
+ *
+ * @returns IPRT status code. Should the callback (@a pfnCallback) return
+ * anything other than VINF_SUCCESS, then the enumeration will be
+ * aborted and the status code will be returned by this function.
+ * @retval VINF_SUCCESS
+ * @retval VERR_INVALID_HANDLE
+ * @retval VERR_INVALID_PARAMETER
+ * @retval VERR_INVALID_POINTER
+ *
+ * @param hTraceBuf The trace buffer handle. Special handles are
+ * accepted.
+ * @param pfnCallback The callback to call for each entry.
+ * @param pvUser The user argument for the callback.
+ */
+RTDECL(int) RTTraceBufEnumEntries(RTTRACEBUF hTraceBuf, PFNRTTRACEBUFCALLBACK pfnCallback, void *pvUser);
+
+/**
+ * Gets the entry size used by the specified trace buffer.
+ *
+ * @returns The size on success, 0 if the handle is invalid.
+ *
+ * @param hTraceBuf The trace buffer handle. Special handles are
+ * accepted.
+ */
+RTDECL(uint32_t) RTTraceBufGetEntrySize(RTTRACEBUF hTraceBuf);
+
+/**
+ * Gets the number of entries in the specified trace buffer.
+ *
+ * @returns The entry count on success, 0 if the handle is invalid.
+ *
+ * @param hTraceBuf The trace buffer handle. Special handles are
+ * accepted.
+ */
+RTDECL(uint32_t) RTTraceBufGetEntryCount(RTTRACEBUF hTraceBuf);
+
+
+/**
+ * Disables tracing.
+ *
+ * @returns @c true if tracing was enabled prior to this call, @c false if
+ * disabled already.
+ *
+ * @param hTraceBuf The trace buffer handle. Special handles are
+ * accepted.
+ */
+RTDECL(bool) RTTraceBufDisable(RTTRACEBUF hTraceBuf);
+
+/**
+ * Enables tracing.
+ *
+ * @returns @c true if tracing was enabled prior to this call, @c false if
+ * disabled already.
+ *
+ * @param hTraceBuf The trace buffer handle. Special handles are
+ * accepted.
+ */
+RTDECL(bool) RTTraceBufEnable(RTTRACEBUF hTraceBuf);
+
+
+RTDECL(int) RTTraceBufAddMsg( RTTRACEBUF hTraceBuf, const char *pszMsg);
+RTDECL(int) RTTraceBufAddMsgF( RTTRACEBUF hTraceBuf, const char *pszMsgFmt, ...);
+RTDECL(int) RTTraceBufAddMsgV( RTTRACEBUF hTraceBuf, const char *pszMsgFmt, va_list va);
+RTDECL(int) RTTraceBufAddMsgEx( RTTRACEBUF hTraceBuf, const char *pszMsg, size_t cbMaxMsg);
+
+RTDECL(int) RTTraceBufAddPos( RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL);
+RTDECL(int) RTTraceBufAddPosMsg( RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsg);
+RTDECL(int) RTTraceBufAddPosMsgEx( RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsg, size_t cbMaxMsg);
+RTDECL(int) RTTraceBufAddPosMsgF( RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsgFmt, ...);
+RTDECL(int) RTTraceBufAddPosMsgV( RTTRACEBUF hTraceBuf, RT_SRC_POS_DECL, const char *pszMsgFmt, va_list va);
+
+
+RTDECL(int) RTTraceSetDefaultBuf(RTTRACEBUF hTraceBuf);
+RTDECL(RTTRACEBUF) RTTraceGetDefaultBuf(void);
+
+
+/** @def RTTRACE_BUF
+ * The trace buffer used by the macros.
+ */
+#ifndef RTTRACE_BUF
+# define RTTRACE_BUF NULL
+#endif
+
+/**
+ * Record the current source position.
+ */
+#ifdef RTTRACE_ENABLED
+# define RTTRACE_POS() do { RTTraceBufAddPos(RTTRACE_BUF, RT_SRC_POS); } while (0)
+#else
+# define RTTRACE_POS() do { } while (0)
+#endif
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/types.h b/include/iprt/types.h
new file mode 100644
index 00000000..e841dea5
--- /dev/null
+++ b/include/iprt/types.h
@@ -0,0 +1,2371 @@
+/** @file
+ * IPRT - Types.
+ */
+
+/*
+ * 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 ___iprt_types_h
+#define ___iprt_types_h
+
+#include <iprt/cdefs.h>
+#include <iprt/stdint.h>
+
+/*
+ * Include standard C types.
+ */
+#ifndef IPRT_NO_CRT
+
+# if defined(IN_XF86_MODULE) && !defined(NO_ANSIC)
+ /*
+ * Kludge for xfree86 modules: size_t and other types are redefined.
+ */
+RT_C_DECLS_BEGIN
+# include "xf86_ansic.h"
+# undef NULL
+RT_C_DECLS_END
+
+# elif defined(RT_OS_DARWIN) && defined(KERNEL)
+ /*
+ * Kludge for the darwin kernel:
+ * stddef.h is missing IIRC.
+ */
+# ifndef _PTRDIFF_T
+# define _PTRDIFF_T
+ typedef __darwin_ptrdiff_t ptrdiff_t;
+# endif
+# include <sys/types.h>
+
+# elif defined(RT_OS_FREEBSD) && defined(_KERNEL)
+ /*
+ * Kludge for the FreeBSD kernel:
+ * stddef.h and sys/types.h have slightly different offsetof definitions
+ * when compiling in kernel mode. This is just to make GCC shut up.
+ */
+# ifndef _STDDEF_H_
+# undef offsetof
+# endif
+# include <sys/stddef.h>
+# ifndef _SYS_TYPES_H_
+# undef offsetof
+# endif
+# include <sys/types.h>
+# ifndef offsetof
+# error "offsetof is not defined..."
+# endif
+
+# elif defined(RT_OS_FREEBSD) && HC_ARCH_BITS == 64 && defined(RT_ARCH_X86)
+ /*
+ * Kludge for compiling 32-bit code on a 64-bit FreeBSD:
+ * FreeBSD declares uint64_t and int64_t wrong (long unsigned and long int
+ * though they need to be long long unsigned and long long int). These
+ * defines conflict with our decleration in stdint.h. Adding the defines
+ * below omits the definitions in the system header.
+ */
+# include <stddef.h>
+# define _UINT64_T_DECLARED
+# define _INT64_T_DECLARED
+# define _UINTPTR_T_DECLARED
+# define _INTPTR_T_DECLARED
+# include <sys/types.h>
+
+# elif defined(RT_OS_LINUX) && defined(__KERNEL__)
+ /*
+ * Kludge for the linux kernel:
+ * 1. sys/types.h doesn't mix with the kernel.
+ * 2. Starting with 2.6.19, linux/types.h typedefs bool and linux/stddef.h
+ * declares false and true as enum values.
+ * 3. Starting with 2.6.24, linux/types.h typedefs uintptr_t.
+ * We work around these issues here and nowhere else.
+ */
+# include <stddef.h>
+# if defined(__cplusplus)
+ typedef bool _Bool;
+# endif
+# define bool linux_bool
+# define true linux_true
+# define false linux_false
+# define uintptr_t linux_uintptr_t
+# include <linux/version.h>
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
+# include <generated/autoconf.h>
+# else
+# ifndef AUTOCONF_INCLUDED
+# include <linux/autoconf.h>
+# endif
+# endif
+# include <linux/compiler.h>
+# if defined(__cplusplus)
+ /*
+ * Starting with 3.3, <linux/compiler-gcc.h> appends 'notrace' (which
+ * expands to __attribute__((no_instrument_function))) to inline,
+ * __inline and __inline__. Revert that.
+ */
+# undef inline
+# define inline inline
+# undef __inline__
+# define __inline__ __inline__
+# undef __inline
+# define __inline __inline
+# endif
+# include <linux/types.h>
+# include <linux/stddef.h>
+ /*
+ * Starting with 3.4, <linux/stddef.h> defines NULL as '((void*)0)' which
+ * does not work for C++ code.
+ */
+# undef NULL
+# undef uintptr_t
+# ifdef __GNUC__
+# if (__GNUC__ * 100 + __GNUC_MINOR__) <= 400
+ /*
+ * <linux/compiler-gcc{3,4}.h> does
+ * #define __inline__ __inline__ __attribute__((always_inline))
+ * in some older Linux kernels. Forcing inlining will fail for some RTStrA*
+ * functions with gcc <= 4.0 due to passing variable argument lists.
+ */
+# undef __inline__
+# define __inline__ __inline__
+# endif
+# endif
+# undef false
+# undef true
+# undef bool
+# else
+# include <stddef.h>
+# include <sys/types.h>
+# endif
+
+
+/* Define any types missing from sys/types.h on windows. */
+# ifdef _MSC_VER
+# undef ssize_t
+ typedef intptr_t ssize_t;
+# endif
+
+#else /* no crt */
+# include <iprt/nocrt/compiler/compiler.h>
+#endif /* no crt */
+
+/** @def NULL
+ * NULL pointer.
+ */
+#ifndef NULL
+# ifdef __cplusplus
+# define NULL 0
+# else
+# define NULL ((void*)0)
+# endif
+#endif
+
+
+
+/** @defgroup grp_rt_types IPRT Base Types
+ * @{
+ */
+
+/* define wchar_t, we don't wanna include all the wcsstuff to get this. */
+#ifdef _MSC_VER
+# ifndef _WCHAR_T_DEFINED
+ typedef unsigned short wchar_t;
+# define _WCHAR_T_DEFINED
+# endif
+#endif
+#ifdef __GNUC__
+/** @todo wchar_t on GNUC */
+#endif
+
+/*
+ * C doesn't have bool.
+ */
+#ifndef __cplusplus
+# if defined(__GNUC__)
+# if defined(RT_OS_LINUX) && __GNUC__ < 3
+typedef uint8_t bool;
+# elif defined(RT_OS_FREEBSD)
+# ifndef __bool_true_false_are_defined
+typedef _Bool bool;
+# endif
+# else
+# if defined(RT_OS_DARWIN) && defined(_STDBOOL_H)
+# undef bool
+# endif
+typedef _Bool bool;
+# endif
+# else
+typedef unsigned char bool;
+# endif
+# ifndef true
+# define true (1)
+# endif
+# ifndef false
+# define false (0)
+# endif
+#endif
+
+/**
+ * 128-bit unsigned integer.
+ */
+#if defined(__GNUC__) && defined(RT_ARCH_AMD64)
+typedef __uint128_t uint128_t;
+#else
+typedef struct uint128_s
+{
+# ifdef RT_BIG_ENDIAN
+ uint64_t Hi;
+ uint64_t Lo;
+# else
+ uint64_t Lo;
+ uint64_t Hi;
+# endif
+} uint128_t;
+#endif
+
+
+/**
+ * 128-bit signed integer.
+ */
+#if defined(__GNUC__) && defined(RT_ARCH_AMD64)
+typedef __int128_t int128_t;
+#else
+typedef struct int128_s
+{
+# ifdef RT_BIG_ENDIAN
+ int64_t Hi;
+ uint64_t Lo;
+# else
+ uint64_t Lo;
+ int64_t Hi;
+# endif
+} int128_t;
+#endif
+
+
+/**
+ * 16-bit unsigned integer union.
+ */
+typedef union RTUINT16U
+{
+ /** natural view. */
+ uint16_t u;
+
+ /** 16-bit view. */
+ uint16_t au16[1];
+ /** 8-bit view. */
+ uint8_t au8[2];
+ /** 16-bit hi/lo view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint8_t Hi;
+ uint8_t Lo;
+#else
+ uint8_t Lo;
+ uint8_t Hi;
+#endif
+ } s;
+} RTUINT16U;
+/** Pointer to a 16-bit unsigned integer union. */
+typedef RTUINT16U *PRTUINT16U;
+/** Pointer to a const 32-bit unsigned integer union. */
+typedef const RTUINT16U *PCRTUINT16U;
+
+
+/**
+ * 32-bit unsigned integer union.
+ */
+typedef union RTUINT32U
+{
+ /** natural view. */
+ uint32_t u;
+ /** Hi/Low view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint16_t Hi;
+ uint16_t Lo;
+#else
+ uint16_t Lo;
+ uint16_t Hi;
+#endif
+ } s;
+ /** Word view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint16_t w1;
+ uint16_t w0;
+#else
+ uint16_t w0;
+ uint16_t w1;
+#endif
+ } Words;
+
+ /** 32-bit view. */
+ uint32_t au32[1];
+ /** 16-bit view. */
+ uint16_t au16[2];
+ /** 8-bit view. */
+ uint8_t au8[4];
+} RTUINT32U;
+/** Pointer to a 32-bit unsigned integer union. */
+typedef RTUINT32U *PRTUINT32U;
+/** Pointer to a const 32-bit unsigned integer union. */
+typedef const RTUINT32U *PCRTUINT32U;
+
+
+/**
+ * 64-bit unsigned integer union.
+ */
+typedef union RTUINT64U
+{
+ /** Natural view. */
+ uint64_t u;
+ /** Hi/Low view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint32_t Hi;
+ uint32_t Lo;
+#else
+ uint32_t Lo;
+ uint32_t Hi;
+#endif
+ } s;
+ /** Double-Word view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint32_t dw1;
+ uint32_t dw0;
+#else
+ uint32_t dw0;
+ uint32_t dw1;
+#endif
+ } DWords;
+ /** Word view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint16_t w3;
+ uint16_t w2;
+ uint16_t w1;
+ uint16_t w0;
+#else
+ uint16_t w0;
+ uint16_t w1;
+ uint16_t w2;
+ uint16_t w3;
+#endif
+ } Words;
+
+ /** 64-bit view. */
+ uint64_t au64[1];
+ /** 32-bit view. */
+ uint32_t au32[2];
+ /** 16-bit view. */
+ uint16_t au16[4];
+ /** 8-bit view. */
+ uint8_t au8[8];
+} RTUINT64U;
+/** Pointer to a 64-bit unsigned integer union. */
+typedef RTUINT64U *PRTUINT64U;
+/** Pointer to a const 64-bit unsigned integer union. */
+typedef const RTUINT64U *PCRTUINT64U;
+
+
+/**
+ * 128-bit unsigned integer union.
+ */
+typedef union RTUINT128U
+{
+ /** Natural view.
+ * WARNING! This member depends on the compiler supporting 128-bit stuff. */
+ uint128_t u;
+ /** Hi/Low view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint64_t Hi;
+ uint64_t Lo;
+#else
+ uint64_t Lo;
+ uint64_t Hi;
+#endif
+ } s;
+ /** Quad-Word view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint64_t qw1;
+ uint64_t qw0;
+#else
+ uint64_t qw0;
+ uint64_t qw1;
+#endif
+ } QWords;
+ /** Double-Word view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint32_t dw3;
+ uint32_t dw2;
+ uint32_t dw1;
+ uint32_t dw0;
+#else
+ uint32_t dw0;
+ uint32_t dw1;
+ uint32_t dw2;
+ uint32_t dw3;
+#endif
+ } DWords;
+ /** Word view. */
+ struct
+ {
+#ifdef RT_BIG_ENDIAN
+ uint16_t w7;
+ uint16_t w6;
+ uint16_t w5;
+ uint16_t w4;
+ uint16_t w3;
+ uint16_t w2;
+ uint16_t w1;
+ uint16_t w0;
+#else
+ uint16_t w0;
+ uint16_t w1;
+ uint16_t w2;
+ uint16_t w3;
+ uint16_t w4;
+ uint16_t w5;
+ uint16_t w6;
+ uint16_t w7;
+#endif
+ } Words;
+
+ /** 64-bit view. */
+ uint64_t au64[2];
+ /** 32-bit view. */
+ uint32_t au32[4];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 8-bit view. */
+ uint8_t au8[16];
+} RTUINT128U;
+/** Pointer to a 64-bit unsigned integer union. */
+typedef RTUINT128U *PRTUINT128U;
+/** Pointer to a const 64-bit unsigned integer union. */
+typedef const RTUINT128U *PCRTUINT128U;
+
+
+/**
+ * Double precision floating point format (64-bit).
+ */
+typedef union RTFLOAT64U
+{
+#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
+ /** Double view. */
+ double rd;
+#endif
+ /** Format using regular bitfields. */
+ struct
+ {
+# ifdef RT_BIG_ENDIAN
+ /** The sign indicator. */
+ uint32_t fSign : 1;
+ /** The exponent (offseted by 1023). */
+ uint32_t uExponent : 11;
+ /** The fraction, bits 32 thru 51. */
+ uint32_t u20FractionHigh : 20;
+ /** The fraction, bits 0 thru 31. */
+ uint32_t u32FractionLow;
+# else
+ /** The fraction, bits 0 thru 31. */
+ uint32_t u32FractionLow;
+ /** The fraction, bits 32 thru 51. */
+ uint32_t u20FractionHigh : 20;
+ /** The exponent (offseted by 1023). */
+ uint32_t uExponent : 11;
+ /** The sign indicator. */
+ uint32_t fSign : 1;
+# endif
+ } s;
+
+#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
+ /** Format using 64-bit bitfields. */
+ RT_GCC_EXTENSION struct
+ {
+# ifdef RT_BIG_ENDIAN
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint64_t fSign : 1;
+ /** The exponent (offseted by 1023). */
+ RT_GCC_EXTENSION uint64_t uExponent : 11;
+ /** The fraction. */
+ RT_GCC_EXTENSION uint64_t uFraction : 52;
+# else
+ /** The fraction. */
+ RT_GCC_EXTENSION uint64_t uFraction : 52;
+ /** The exponent (offseted by 1023). */
+ RT_GCC_EXTENSION uint64_t uExponent : 11;
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint64_t fSign : 1;
+# endif
+ } s64;
+#endif
+
+ /** 64-bit view. */
+ uint64_t au64[1];
+ /** 32-bit view. */
+ uint32_t au32[2];
+ /** 16-bit view. */
+ uint16_t au16[4];
+ /** 8-bit view. */
+ uint8_t au8[8];
+} RTFLOAT64U;
+/** Pointer to a double precision floating point format union. */
+typedef RTFLOAT64U *PRTFLOAT64U;
+/** Pointer to a const double precision floating point format union. */
+typedef const RTFLOAT64U *PCRTFLOAT64U;
+
+
+/**
+ * Extended Double precision floating point format (80-bit).
+ */
+#pragma pack(1)
+typedef union RTFLOAT80U
+{
+ /** Format using bitfields. */
+ RT_GCC_EXTENSION struct
+ {
+# ifdef RT_BIG_ENDIAN
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The mantissa. */
+ uint64_t u64Mantissa;
+# else
+ /** The mantissa. */
+ uint64_t u64Mantissa;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+# endif
+ } s;
+
+ /** 64-bit view. */
+ uint64_t au64[1];
+ /** 32-bit view. */
+ uint32_t au32[2];
+ /** 16-bit view. */
+ uint16_t au16[5];
+ /** 8-bit view. */
+ uint8_t au8[10];
+} RTFLOAT80U;
+#pragma pack()
+/** Pointer to a extended precision floating point format union. */
+typedef RTFLOAT80U *PRTFLOAT80U;
+/** Pointer to a const extended precision floating point format union. */
+typedef const RTFLOAT80U *PCRTFLOAT80U;
+
+
+/**
+ * A variant of RTFLOAT80U that may be larger than 80-bits depending on how the
+ * compiler implements long double.
+ */
+#pragma pack(1)
+typedef union RTFLOAT80U2
+{
+#ifdef RT_COMPILER_WITH_80BIT_LONG_DOUBLE
+ /** Long double view. */
+ long double lrd;
+#endif
+ /** Format using bitfields. */
+ RT_GCC_EXTENSION struct
+ {
+#ifdef RT_BIG_ENDIAN
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The mantissa. */
+ uint64_t u64Mantissa;
+#else
+ /** The mantissa. */
+ uint64_t u64Mantissa;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+#endif
+ } s;
+
+ /** Bitfield exposing the J bit and the fraction. */
+ RT_GCC_EXTENSION struct
+ {
+#ifdef RT_BIG_ENDIAN
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The J bit, aka the integer bit. */
+ uint32_t fInteger;
+ /** The fraction, bits 32 thru 62. */
+ uint32_t u31FractionHigh : 31;
+ /** The fraction, bits 0 thru 31. */
+ uint32_t u32FractionLow : 32;
+#else
+ /** The fraction, bits 0 thru 31. */
+ uint32_t u32FractionLow : 32;
+ /** The fraction, bits 32 thru 62. */
+ uint32_t u31FractionHigh : 31;
+ /** The J bit, aka the integer bit. */
+ uint32_t fInteger;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+#endif
+ } sj;
+
+#ifdef RT_COMPILER_GROKS_64BIT_BITFIELDS
+ /** 64-bit bitfields exposing the J bit and the fraction. */
+ RT_GCC_EXTENSION struct
+ {
+# ifdef RT_BIG_ENDIAN
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The J bit, aka the integer bit. */
+ RT_GCC_EXTENSION uint64_t fInteger : 1;
+ /** The fraction. */
+ RT_GCC_EXTENSION uint64_t u63Fraction : 63;
+# else
+ /** The fraction. */
+ RT_GCC_EXTENSION uint64_t u63Fraction : 63;
+ /** The J bit, aka the integer bit. */
+ RT_GCC_EXTENSION uint64_t fInteger : 1;
+ /** The exponent (offseted by 16383). */
+ RT_GCC_EXTENSION uint16_t uExponent : 15;
+ /** The sign indicator. */
+ RT_GCC_EXTENSION uint16_t fSign : 1;
+# endif
+ } sj64;
+#endif
+
+ /** 64-bit view. */
+ uint64_t au64[1];
+ /** 32-bit view. */
+ uint32_t au32[2];
+ /** 16-bit view. */
+ uint16_t au16[5];
+ /** 8-bit view. */
+ uint8_t au8[10];
+} RTFLOAT80U2;
+#pragma pack()
+/** Pointer to a extended precision floating point format union, 2nd
+ * variant. */
+typedef RTFLOAT80U2 *PRTFLOAT80U2;
+/** Pointer to a const extended precision floating point format union, 2nd
+ * variant. */
+typedef const RTFLOAT80U2 *PCRTFLOAT80U2;
+
+
+/** Generic function type.
+ * @see PFNRT
+ */
+typedef DECLCALLBACK(void) FNRT(void);
+
+/** Generic function pointer.
+ * With -pedantic, gcc-4 complains when casting a function to a data object, for
+ * example:
+ *
+ * @code
+ * void foo(void)
+ * {
+ * }
+ *
+ * void *bar = (void *)foo;
+ * @endcode
+ *
+ * The compiler would warn with "ISO C++ forbids casting between
+ * pointer-to-function and pointer-to-object". The purpose of this warning is
+ * not to bother the programmer but to point out that he is probably doing
+ * something dangerous, assigning a pointer to executable code to a data object.
+ */
+typedef FNRT *PFNRT;
+
+/** Millisecond interval. */
+typedef uint32_t RTMSINTERVAL;
+/** Pointer to a millisecond interval. */
+typedef RTMSINTERVAL *PRTMSINTERVAL;
+/** Pointer to a const millisecond interval. */
+typedef const RTMSINTERVAL *PCRTMSINTERVAL;
+
+/** Pointer to a time spec structure. */
+typedef struct RTTIMESPEC *PRTTIMESPEC;
+/** Pointer to a const time spec structure. */
+typedef const struct RTTIMESPEC *PCRTTIMESPEC;
+
+/**
+ * Generic pointer union.
+ */
+typedef union RTPTRUNION
+{
+ /** Pointer into the void... */
+ void *pv;
+ /** Pointer to a 8-bit unsigned value. */
+ uint8_t *pu8;
+ /** Pointer to a 16-bit unsigned value. */
+ uint16_t *pu16;
+ /** Pointer to a 32-bit unsigned value. */
+ uint32_t *pu32;
+ /** Pointer to a 64-bit unsigned value. */
+ uint64_t *pu64;
+} RTPTRUNION;
+/** Pointer to a pointer union. */
+typedef RTPTRUNION *PRTPTRUNION;
+
+/**
+ * Generic const pointer union.
+ */
+typedef union RTCPTRUNION
+{
+ /** Pointer into the void... */
+ void const *pv;
+ /** Pointer to a 8-bit unsigned value. */
+ uint8_t const *pu8;
+ /** Pointer to a 16-bit unsigned value. */
+ uint16_t const *pu16;
+ /** Pointer to a 32-bit unsigned value. */
+ uint32_t const *pu32;
+ /** Pointer to a 64-bit unsigned value. */
+ uint64_t const *pu64;
+} RTCPTRUNION;
+/** Pointer to a const pointer union. */
+typedef RTCPTRUNION *PRTCPTRUNION;
+
+/**
+ * Generic volatile pointer union.
+ */
+typedef union RTVPTRUNION
+{
+ /** Pointer into the void... */
+ void volatile *pv;
+ /** Pointer to a 8-bit unsigned value. */
+ uint8_t volatile *pu8;
+ /** Pointer to a 16-bit unsigned value. */
+ uint16_t volatile *pu16;
+ /** Pointer to a 32-bit unsigned value. */
+ uint32_t volatile *pu32;
+ /** Pointer to a 64-bit unsigned value. */
+ uint64_t volatile *pu64;
+} RTVPTRUNION;
+/** Pointer to a const pointer union. */
+typedef RTVPTRUNION *PRTVPTRUNION;
+
+/**
+ * Generic const volatile pointer union.
+ */
+typedef union RTCVPTRUNION
+{
+ /** Pointer into the void... */
+ void const volatile *pv;
+ /** Pointer to a 8-bit unsigned value. */
+ uint8_t const volatile *pu8;
+ /** Pointer to a 16-bit unsigned value. */
+ uint16_t const volatile *pu16;
+ /** Pointer to a 32-bit unsigned value. */
+ uint32_t const volatile *pu32;
+ /** Pointer to a 64-bit unsigned value. */
+ uint64_t const volatile *pu64;
+} RTCVPTRUNION;
+/** Pointer to a const pointer union. */
+typedef RTCVPTRUNION *PRTCVPTRUNION;
+
+
+/** @defgroup grp_rt_types_both Common Guest and Host Context Basic Types
+ * @ingroup grp_rt_types
+ * @{
+ */
+
+/** Signed integer which can contain both GC and HC pointers. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+typedef int32_t RTINTPTR;
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+typedef int64_t RTINTPTR;
+#else
+# error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+/** Pointer to signed integer which can contain both GC and HC pointers. */
+typedef RTINTPTR *PRTINTPTR;
+/** Pointer const to signed integer which can contain both GC and HC pointers. */
+typedef const RTINTPTR *PCRTINTPTR;
+/** The maximum value the RTINTPTR type can hold. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+# define RTINTPTR_MAX INT32_MAX
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+# define RTINTPTR_MAX INT64_MAX
+#else
+# error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+/** The minimum value the RTINTPTR type can hold. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+# define RTINTPTR_MIN INT32_MIN
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+# define RTINTPTR_MIN INT64_MIN
+#else
+# error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+
+/** Unsigned integer which can contain both GC and HC pointers. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+typedef uint32_t RTUINTPTR;
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+typedef uint64_t RTUINTPTR;
+#else
+# error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+/** Pointer to unsigned integer which can contain both GC and HC pointers. */
+typedef RTUINTPTR *PRTUINTPTR;
+/** Pointer const to unsigned integer which can contain both GC and HC pointers. */
+typedef const RTUINTPTR *PCRTUINTPTR;
+/** The maximum value the RTUINTPTR type can hold. */
+#if (HC_ARCH_BITS == 32 && GC_ARCH_BITS == 32)
+# define RTUINTPTR_MAX UINT32_MAX
+#elif (HC_ARCH_BITS == 64 || GC_ARCH_BITS == 64)
+# define RTUINTPTR_MAX UINT64_MAX
+#else
+# error Unsupported HC_ARCH_BITS and/or GC_ARCH_BITS values.
+#endif
+
+/** Signed integer. */
+typedef int32_t RTINT;
+/** Pointer to signed integer. */
+typedef RTINT *PRTINT;
+/** Pointer to const signed integer. */
+typedef const RTINT *PCRTINT;
+
+/** Unsigned integer. */
+typedef uint32_t RTUINT;
+/** Pointer to unsigned integer. */
+typedef RTUINT *PRTUINT;
+/** Pointer to const unsigned integer. */
+typedef const RTUINT *PCRTUINT;
+
+/** A file offset / size (off_t). */
+typedef int64_t RTFOFF;
+/** Pointer to a file offset / size. */
+typedef RTFOFF *PRTFOFF;
+/** The max value for RTFOFF. */
+#define RTFOFF_MAX INT64_MAX
+/** The min value for RTFOFF. */
+#define RTFOFF_MIN INT64_MIN
+
+/** File mode (see iprt/fs.h). */
+typedef uint32_t RTFMODE;
+/** Pointer to file mode. */
+typedef RTFMODE *PRTFMODE;
+
+/** Device unix number. */
+typedef uint32_t RTDEV;
+/** Pointer to a device unix number. */
+typedef RTDEV *PRTDEV;
+
+/** @name RTDEV Macros
+ * @{ */
+/**
+ * Our makedev macro.
+ * @returns RTDEV
+ * @param uMajor The major device number.
+ * @param uMinor The minor device number.
+ */
+#define RTDEV_MAKE(uMajor, uMinor) ((RTDEV)( ((RTDEV)(uMajor) << 24) | (uMinor & UINT32_C(0x00ffffff)) ))
+/**
+ * Get the major device node number from an RTDEV type.
+ * @returns The major device number of @a uDev
+ * @param uDev The device number.
+ */
+#define RTDEV_MAJOR(uDev) ((uDev) >> 24)
+/**
+ * Get the minor device node number from an RTDEV type.
+ * @returns The minor device number of @a uDev
+ * @param uDev The device number.
+ */
+#define RTDEV_MINOR(uDev) ((uDev) & UINT32_C(0x00ffffff))
+/** @} */
+
+/** i-node number. */
+typedef uint64_t RTINODE;
+/** Pointer to a i-node number. */
+typedef RTINODE *PRTINODE;
+
+/** User id. */
+typedef uint32_t RTUID;
+/** Pointer to a user id. */
+typedef RTUID *PRTUID;
+/** NIL user id.
+ * @todo check this for portability! */
+#define NIL_RTUID (~(RTUID)0)
+
+/** Group id. */
+typedef uint32_t RTGID;
+/** Pointer to a group id. */
+typedef RTGID *PRTGID;
+/** NIL group id.
+ * @todo check this for portability! */
+#define NIL_RTGID (~(RTGID)0)
+
+/** I/O Port. */
+typedef uint16_t RTIOPORT;
+/** Pointer to I/O Port. */
+typedef RTIOPORT *PRTIOPORT;
+/** Pointer to const I/O Port. */
+typedef const RTIOPORT *PCRTIOPORT;
+
+/** Selector. */
+typedef uint16_t RTSEL;
+/** Pointer to selector. */
+typedef RTSEL *PRTSEL;
+/** Pointer to const selector. */
+typedef const RTSEL *PCRTSEL;
+/** Max selector value. */
+#define RTSEL_MAX UINT16_MAX
+
+/** Far 16-bit pointer. */
+#pragma pack(1)
+typedef struct RTFAR16
+{
+ uint16_t off;
+ RTSEL sel;
+} RTFAR16;
+#pragma pack()
+/** Pointer to Far 16-bit pointer. */
+typedef RTFAR16 *PRTFAR16;
+/** Pointer to const Far 16-bit pointer. */
+typedef const RTFAR16 *PCRTFAR16;
+
+/** Far 32-bit pointer. */
+#pragma pack(1)
+typedef struct RTFAR32
+{
+ uint32_t off;
+ RTSEL sel;
+} RTFAR32;
+#pragma pack()
+/** Pointer to Far 32-bit pointer. */
+typedef RTFAR32 *PRTFAR32;
+/** Pointer to const Far 32-bit pointer. */
+typedef const RTFAR32 *PCRTFAR32;
+
+/** Far 64-bit pointer. */
+#pragma pack(1)
+typedef struct RTFAR64
+{
+ uint64_t off;
+ RTSEL sel;
+} RTFAR64;
+#pragma pack()
+/** Pointer to Far 64-bit pointer. */
+typedef RTFAR64 *PRTFAR64;
+/** Pointer to const Far 64-bit pointer. */
+typedef const RTFAR64 *PCRTFAR64;
+
+/** @} */
+
+
+/** @defgroup grp_rt_types_hc Host Context Basic Types
+ * @ingroup grp_rt_types
+ * @{
+ */
+
+/** HC Natural signed integer.
+ * @deprecated silly type. */
+typedef int32_t RTHCINT;
+/** Pointer to HC Natural signed integer.
+ * @deprecated silly type. */
+typedef RTHCINT *PRTHCINT;
+/** Pointer to const HC Natural signed integer.
+ * @deprecated silly type. */
+typedef const RTHCINT *PCRTHCINT;
+
+/** HC Natural unsigned integer.
+ * @deprecated silly type. */
+typedef uint32_t RTHCUINT;
+/** Pointer to HC Natural unsigned integer.
+ * @deprecated silly type. */
+typedef RTHCUINT *PRTHCUINT;
+/** Pointer to const HC Natural unsigned integer.
+ * @deprecated silly type. */
+typedef const RTHCUINT *PCRTHCUINT;
+
+
+/** Signed integer which can contain a HC pointer. */
+#if HC_ARCH_BITS == 32
+typedef int32_t RTHCINTPTR;
+#elif HC_ARCH_BITS == 64
+typedef int64_t RTHCINTPTR;
+#else
+# error Unsupported HC_ARCH_BITS value.
+#endif
+/** Pointer to signed integer which can contain a HC pointer. */
+typedef RTHCINTPTR *PRTHCINTPTR;
+/** Pointer to const signed integer which can contain a HC pointer. */
+typedef const RTHCINTPTR *PCRTHCINTPTR;
+/** Max RTHCINTPTR value. */
+#if HC_ARCH_BITS == 32
+# define RTHCINTPTR_MAX INT32_MAX
+#else
+# define RTHCINTPTR_MAX INT64_MAX
+#endif
+/** Min RTHCINTPTR value. */
+#if HC_ARCH_BITS == 32
+# define RTHCINTPTR_MIN INT32_MIN
+#else
+# define RTHCINTPTR_MIN INT64_MIN
+#endif
+
+/** Signed integer which can contain a HC ring-3 pointer. */
+#if R3_ARCH_BITS == 32
+typedef int32_t RTR3INTPTR;
+#elif R3_ARCH_BITS == 64
+typedef int64_t RTR3INTPTR;
+#else
+# error Unsupported R3_ARCH_BITS value.
+#endif
+/** Pointer to signed integer which can contain a HC ring-3 pointer. */
+typedef RTR3INTPTR *PRTR3INTPTR;
+/** Pointer to const signed integer which can contain a HC ring-3 pointer. */
+typedef const RTR3INTPTR *PCRTR3INTPTR;
+/** Max RTR3INTPTR value. */
+#if R3_ARCH_BITS == 32
+# define RTR3INTPTR_MAX INT32_MAX
+#else
+# define RTR3INTPTR_MAX INT64_MAX
+#endif
+/** Min RTR3INTPTR value. */
+#if R3_ARCH_BITS == 32
+# define RTR3INTPTR_MIN INT32_MIN
+#else
+# define RTR3INTPTR_MIN INT64_MIN
+#endif
+
+/** Signed integer which can contain a HC ring-0 pointer. */
+#if R0_ARCH_BITS == 32
+typedef int32_t RTR0INTPTR;
+#elif R0_ARCH_BITS == 64
+typedef int64_t RTR0INTPTR;
+#else
+# error Unsupported R0_ARCH_BITS value.
+#endif
+/** Pointer to signed integer which can contain a HC ring-0 pointer. */
+typedef RTR0INTPTR *PRTR0INTPTR;
+/** Pointer to const signed integer which can contain a HC ring-0 pointer. */
+typedef const RTR0INTPTR *PCRTR0INTPTR;
+/** Max RTR0INTPTR value. */
+#if R0_ARCH_BITS == 32
+# define RTR0INTPTR_MAX INT32_MAX
+#else
+# define RTR0INTPTR_MAX INT64_MAX
+#endif
+/** Min RTHCINTPTR value. */
+#if R0_ARCH_BITS == 32
+# define RTR0INTPTR_MIN INT32_MIN
+#else
+# define RTR0INTPTR_MIN INT64_MIN
+#endif
+
+
+/** Unsigned integer which can contain a HC pointer. */
+#if HC_ARCH_BITS == 32
+typedef uint32_t RTHCUINTPTR;
+#elif HC_ARCH_BITS == 64
+typedef uint64_t RTHCUINTPTR;
+#else
+# error Unsupported HC_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a HC pointer. */
+typedef RTHCUINTPTR *PRTHCUINTPTR;
+/** Pointer to unsigned integer which can contain a HC pointer. */
+typedef const RTHCUINTPTR *PCRTHCUINTPTR;
+/** Max RTHCUINTTPR value. */
+#if HC_ARCH_BITS == 32
+# define RTHCUINTPTR_MAX UINT32_MAX
+#else
+# define RTHCUINTPTR_MAX UINT64_MAX
+#endif
+
+/** Unsigned integer which can contain a HC ring-3 pointer. */
+#if R3_ARCH_BITS == 32
+typedef uint32_t RTR3UINTPTR;
+#elif R3_ARCH_BITS == 64
+typedef uint64_t RTR3UINTPTR;
+#else
+# error Unsupported R3_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a HC ring-3 pointer. */
+typedef RTR3UINTPTR *PRTR3UINTPTR;
+/** Pointer to unsigned integer which can contain a HC ring-3 pointer. */
+typedef const RTR3UINTPTR *PCRTR3UINTPTR;
+/** Max RTHCUINTTPR value. */
+#if R3_ARCH_BITS == 32
+# define RTR3UINTPTR_MAX UINT32_MAX
+#else
+# define RTR3UINTPTR_MAX UINT64_MAX
+#endif
+
+/** Unsigned integer which can contain a HC ring-0 pointer. */
+#if R0_ARCH_BITS == 32
+typedef uint32_t RTR0UINTPTR;
+#elif R0_ARCH_BITS == 64
+typedef uint64_t RTR0UINTPTR;
+#else
+# error Unsupported R0_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a HC ring-0 pointer. */
+typedef RTR0UINTPTR *PRTR0UINTPTR;
+/** Pointer to unsigned integer which can contain a HC ring-0 pointer. */
+typedef const RTR0UINTPTR *PCRTR0UINTPTR;
+/** Max RTR0UINTTPR value. */
+#if HC_ARCH_BITS == 32
+# define RTR0UINTPTR_MAX UINT32_MAX
+#else
+# define RTR0UINTPTR_MAX UINT64_MAX
+#endif
+
+
+/** Host Physical Memory Address. */
+typedef uint64_t RTHCPHYS;
+/** Pointer to Host Physical Memory Address. */
+typedef RTHCPHYS *PRTHCPHYS;
+/** Pointer to const Host Physical Memory Address. */
+typedef const RTHCPHYS *PCRTHCPHYS;
+/** @def NIL_RTHCPHYS
+ * NIL HC Physical Address.
+ * NIL_RTHCPHYS is used to signal an invalid physical address, similar
+ * to the NULL pointer.
+ */
+#define NIL_RTHCPHYS (~(RTHCPHYS)0)
+/** Max RTHCPHYS value. */
+#define RTHCPHYS_MAX UINT64_MAX
+
+
+/** HC pointer. */
+#ifndef IN_RC
+typedef void * RTHCPTR;
+#else
+typedef RTHCUINTPTR RTHCPTR;
+#endif
+/** Pointer to HC pointer. */
+typedef RTHCPTR *PRTHCPTR;
+/** Pointer to const HC pointer. */
+typedef const RTHCPTR *PCRTHCPTR;
+/** @def NIL_RTHCPTR
+ * NIL HC pointer.
+ */
+#define NIL_RTHCPTR ((RTHCPTR)0)
+/** Max RTHCPTR value. */
+#define RTHCPTR_MAX ((RTHCPTR)RTHCUINTPTR_MAX)
+
+
+/** HC ring-3 pointer. */
+#ifdef IN_RING3
+typedef void * RTR3PTR;
+#else
+typedef RTR3UINTPTR RTR3PTR;
+#endif
+/** Pointer to HC ring-3 pointer. */
+typedef RTR3PTR *PRTR3PTR;
+/** Pointer to const HC ring-3 pointer. */
+typedef const RTR3PTR *PCRTR3PTR;
+/** @def NIL_RTR3PTR
+ * NIL HC ring-3 pointer.
+ */
+#ifndef IN_RING3
+# define NIL_RTR3PTR ((RTR3PTR)0)
+#else
+# define NIL_RTR3PTR (NULL)
+#endif
+/** Max RTR3PTR value. */
+#define RTR3PTR_MAX ((RTR3PTR)RTR3UINTPTR_MAX)
+
+/** HC ring-0 pointer. */
+#ifdef IN_RING0
+typedef void * RTR0PTR;
+#else
+typedef RTR0UINTPTR RTR0PTR;
+#endif
+/** Pointer to HC ring-0 pointer. */
+typedef RTR0PTR *PRTR0PTR;
+/** Pointer to const HC ring-0 pointer. */
+typedef const RTR0PTR *PCRTR0PTR;
+/** @def NIL_RTR0PTR
+ * NIL HC ring-0 pointer.
+ */
+#ifndef IN_RING0
+# define NIL_RTR0PTR ((RTR0PTR)0)
+#else
+# define NIL_RTR0PTR (NULL)
+#endif
+/** Max RTR3PTR value. */
+#define RTR0PTR_MAX ((RTR0PTR)RTR0UINTPTR_MAX)
+
+
+/** Unsigned integer register in the host context. */
+#if HC_ARCH_BITS == 32
+typedef uint32_t RTHCUINTREG;
+#elif HC_ARCH_BITS == 64
+typedef uint64_t RTHCUINTREG;
+#else
+# error "Unsupported HC_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the host context. */
+typedef RTHCUINTREG *PRTHCUINTREG;
+/** Pointer to a const unsigned integer register in the host context. */
+typedef const RTHCUINTREG *PCRTHCUINTREG;
+
+/** Unsigned integer register in the host ring-3 context. */
+#if R3_ARCH_BITS == 32
+typedef uint32_t RTR3UINTREG;
+#elif R3_ARCH_BITS == 64
+typedef uint64_t RTR3UINTREG;
+#else
+# error "Unsupported R3_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the host ring-3 context. */
+typedef RTR3UINTREG *PRTR3UINTREG;
+/** Pointer to a const unsigned integer register in the host ring-3 context. */
+typedef const RTR3UINTREG *PCRTR3UINTREG;
+
+/** Unsigned integer register in the host ring-3 context. */
+#if R0_ARCH_BITS == 32
+typedef uint32_t RTR0UINTREG;
+#elif R0_ARCH_BITS == 64
+typedef uint64_t RTR0UINTREG;
+#else
+# error "Unsupported R3_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the host ring-3 context. */
+typedef RTR0UINTREG *PRTR0UINTREG;
+/** Pointer to a const unsigned integer register in the host ring-3 context. */
+typedef const RTR0UINTREG *PCRTR0UINTREG;
+
+/** @} */
+
+
+/** @defgroup grp_rt_types_gc Guest Context Basic Types
+ * @ingroup grp_rt_types
+ * @{
+ */
+
+/** Natural signed integer in the GC.
+ * @deprecated silly type. */
+#if GC_ARCH_BITS == 32
+typedef int32_t RTGCINT;
+#elif GC_ARCH_BITS == 64 /** @todo this isn't right, natural int is 32-bit, see RTHCINT. */
+typedef int64_t RTGCINT;
+#endif
+/** Pointer to natural signed integer in GC.
+ * @deprecated silly type. */
+typedef RTGCINT *PRTGCINT;
+/** Pointer to const natural signed integer in GC.
+ * @deprecated silly type. */
+typedef const RTGCINT *PCRTGCINT;
+
+/** Natural unsigned integer in the GC.
+ * @deprecated silly type. */
+#if GC_ARCH_BITS == 32
+typedef uint32_t RTGCUINT;
+#elif GC_ARCH_BITS == 64 /** @todo this isn't right, natural int is 32-bit, see RTHCUINT. */
+typedef uint64_t RTGCUINT;
+#endif
+/** Pointer to natural unsigned integer in GC.
+ * @deprecated silly type. */
+typedef RTGCUINT *PRTGCUINT;
+/** Pointer to const natural unsigned integer in GC.
+ * @deprecated silly type. */
+typedef const RTGCUINT *PCRTGCUINT;
+
+/** Signed integer which can contain a GC pointer. */
+#if GC_ARCH_BITS == 32
+typedef int32_t RTGCINTPTR;
+#elif GC_ARCH_BITS == 64
+typedef int64_t RTGCINTPTR;
+#endif
+/** Pointer to signed integer which can contain a GC pointer. */
+typedef RTGCINTPTR *PRTGCINTPTR;
+/** Pointer to const signed integer which can contain a GC pointer. */
+typedef const RTGCINTPTR *PCRTGCINTPTR;
+
+/** Unsigned integer which can contain a GC pointer. */
+#if GC_ARCH_BITS == 32
+typedef uint32_t RTGCUINTPTR;
+#elif GC_ARCH_BITS == 64
+typedef uint64_t RTGCUINTPTR;
+#else
+# error Unsupported GC_ARCH_BITS value.
+#endif
+/** Pointer to unsigned integer which can contain a GC pointer. */
+typedef RTGCUINTPTR *PRTGCUINTPTR;
+/** Pointer to unsigned integer which can contain a GC pointer. */
+typedef const RTGCUINTPTR *PCRTGCUINTPTR;
+
+/** Unsigned integer which can contain a 32 bits GC pointer. */
+typedef uint32_t RTGCUINTPTR32;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef RTGCUINTPTR32 *PRTGCUINTPTR32;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef const RTGCUINTPTR32 *PCRTGCUINTPTR32;
+
+/** Unsigned integer which can contain a 64 bits GC pointer. */
+typedef uint64_t RTGCUINTPTR64;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef RTGCUINTPTR64 *PRTGCUINTPTR64;
+/** Pointer to unsigned integer which can contain a 32 bits GC pointer. */
+typedef const RTGCUINTPTR64 *PCRTGCUINTPTR64;
+
+/** Guest Physical Memory Address.*/
+typedef uint64_t RTGCPHYS;
+/** Pointer to Guest Physical Memory Address. */
+typedef RTGCPHYS *PRTGCPHYS;
+/** Pointer to const Guest Physical Memory Address. */
+typedef const RTGCPHYS *PCRTGCPHYS;
+/** @def NIL_RTGCPHYS
+ * NIL GC Physical Address.
+ * NIL_RTGCPHYS is used to signal an invalid physical address, similar
+ * to the NULL pointer. Note that this value may actually be valid in
+ * some contexts.
+ */
+#define NIL_RTGCPHYS (~(RTGCPHYS)0U)
+/** Max guest physical memory address value. */
+#define RTGCPHYS_MAX UINT64_MAX
+
+
+/** Guest Physical Memory Address; limited to 32 bits.*/
+typedef uint32_t RTGCPHYS32;
+/** Pointer to Guest Physical Memory Address. */
+typedef RTGCPHYS32 *PRTGCPHYS32;
+/** Pointer to const Guest Physical Memory Address. */
+typedef const RTGCPHYS32 *PCRTGCPHYS32;
+/** @def NIL_RTGCPHYS32
+ * NIL GC Physical Address.
+ * NIL_RTGCPHYS32 is used to signal an invalid physical address, similar
+ * to the NULL pointer. Note that this value may actually be valid in
+ * some contexts.
+ */
+#define NIL_RTGCPHYS32 (~(RTGCPHYS32)0)
+
+
+/** Guest Physical Memory Address; limited to 64 bits.*/
+typedef uint64_t RTGCPHYS64;
+/** Pointer to Guest Physical Memory Address. */
+typedef RTGCPHYS64 *PRTGCPHYS64;
+/** Pointer to const Guest Physical Memory Address. */
+typedef const RTGCPHYS64 *PCRTGCPHYS64;
+/** @def NIL_RTGCPHYS64
+ * NIL GC Physical Address.
+ * NIL_RTGCPHYS64 is used to signal an invalid physical address, similar
+ * to the NULL pointer. Note that this value may actually be valid in
+ * some contexts.
+ */
+#define NIL_RTGCPHYS64 (~(RTGCPHYS64)0)
+
+/** Guest context pointer, 32 bits.
+ * Keep in mind that this type is an unsigned integer in
+ * HC and void pointer in GC.
+ */
+typedef RTGCUINTPTR32 RTGCPTR32;
+/** Pointer to a guest context pointer. */
+typedef RTGCPTR32 *PRTGCPTR32;
+/** Pointer to a const guest context pointer. */
+typedef const RTGCPTR32 *PCRTGCPTR32;
+/** @def NIL_RTGCPTR32
+ * NIL GC pointer.
+ */
+#define NIL_RTGCPTR32 ((RTGCPTR32)0)
+
+/** Guest context pointer, 64 bits.
+ */
+typedef RTGCUINTPTR64 RTGCPTR64;
+/** Pointer to a guest context pointer. */
+typedef RTGCPTR64 *PRTGCPTR64;
+/** Pointer to a const guest context pointer. */
+typedef const RTGCPTR64 *PCRTGCPTR64;
+/** @def NIL_RTGCPTR64
+ * NIL GC pointer.
+ */
+#define NIL_RTGCPTR64 ((RTGCPTR64)0)
+
+/** Guest context pointer.
+ * Keep in mind that this type is an unsigned integer in
+ * HC and void pointer in GC.
+ */
+#if GC_ARCH_BITS == 64
+typedef RTGCPTR64 RTGCPTR;
+/** Pointer to a guest context pointer. */
+typedef PRTGCPTR64 PRTGCPTR;
+/** Pointer to a const guest context pointer. */
+typedef PCRTGCPTR64 PCRTGCPTR;
+/** @def NIL_RTGCPTR
+ * NIL GC pointer.
+ */
+# define NIL_RTGCPTR NIL_RTGCPTR64
+/** Max RTGCPTR value. */
+# define RTGCPTR_MAX UINT64_MAX
+#elif GC_ARCH_BITS == 32
+typedef RTGCPTR32 RTGCPTR;
+/** Pointer to a guest context pointer. */
+typedef PRTGCPTR32 PRTGCPTR;
+/** Pointer to a const guest context pointer. */
+typedef PCRTGCPTR32 PCRTGCPTR;
+/** @def NIL_RTGCPTR
+ * NIL GC pointer.
+ */
+# define NIL_RTGCPTR NIL_RTGCPTR32
+/** Max RTGCPTR value. */
+# define RTGCPTR_MAX UINT32_MAX
+#else
+# error "Unsupported GC_ARCH_BITS!"
+#endif
+
+/** Unsigned integer register in the guest context. */
+typedef uint32_t RTGCUINTREG32;
+/** Pointer to an unsigned integer register in the guest context. */
+typedef RTGCUINTREG32 *PRTGCUINTREG32;
+/** Pointer to a const unsigned integer register in the guest context. */
+typedef const RTGCUINTREG32 *PCRTGCUINTREG32;
+
+typedef uint64_t RTGCUINTREG64;
+/** Pointer to an unsigned integer register in the guest context. */
+typedef RTGCUINTREG64 *PRTGCUINTREG64;
+/** Pointer to a const unsigned integer register in the guest context. */
+typedef const RTGCUINTREG64 *PCRTGCUINTREG64;
+
+#if GC_ARCH_BITS == 64
+typedef RTGCUINTREG64 RTGCUINTREG;
+#elif GC_ARCH_BITS == 32
+typedef RTGCUINTREG32 RTGCUINTREG;
+#else
+# error "Unsupported GC_ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the guest context. */
+typedef RTGCUINTREG *PRTGCUINTREG;
+/** Pointer to a const unsigned integer register in the guest context. */
+typedef const RTGCUINTREG *PCRTGCUINTREG;
+
+/** @} */
+
+/** @defgroup grp_rt_types_rc Raw mode Context Basic Types
+ * @ingroup grp_rt_types
+ * @{
+ */
+
+/** Raw mode context pointer; a 32 bits guest context pointer.
+ * Keep in mind that this type is an unsigned integer in
+ * HC and void pointer in RC.
+ */
+#ifdef IN_RC
+typedef void * RTRCPTR;
+#else
+typedef uint32_t RTRCPTR;
+#endif
+/** Pointer to a raw mode context pointer. */
+typedef RTRCPTR *PRTRCPTR;
+/** Pointer to a const raw mode context pointer. */
+typedef const RTRCPTR *PCRTRCPTR;
+/** @def NIL_RTGCPTR
+ * NIL RC pointer.
+ */
+#ifndef IN_RC
+# define NIL_RTRCPTR ((RTRCPTR)0)
+#else
+# define NIL_RTRCPTR (NULL)
+#endif
+/** @def RTRCPTR_MAX
+ * The maximum value a RTRCPTR can have. Mostly used as INVALID value.
+ */
+#define RTRCPTR_MAX ((RTRCPTR)UINT32_MAX)
+
+/** Raw mode context pointer, unsigned integer variant. */
+typedef int32_t RTRCINTPTR;
+/** @def RTRCUINTPTR_MAX
+ * The maximum value a RTRCUINPTR can have.
+ */
+#define RTRCUINTPTR_MAX ((RTRCUINTPTR)UINT32_MAX)
+
+/** Raw mode context pointer, signed integer variant. */
+typedef uint32_t RTRCUINTPTR;
+/** @def RTRCINTPTR_MIN
+ * The minimum value a RTRCINPTR can have.
+ */
+#define RTRCINTPTR_MIN ((RTRCINTPTR)INT32_MIN)
+/** @def RTRCINTPTR_MAX
+ * The maximum value a RTRCINPTR can have.
+ */
+#define RTRCINTPTR_MAX ((RTRCINTPTR)INT32_MAX)
+
+/** @} */
+
+
+/** @defgroup grp_rt_types_cc Current Context Basic Types
+ * @ingroup grp_rt_types
+ * @{
+ */
+
+/** Current Context Physical Memory Address.*/
+#ifdef IN_RC
+typedef RTGCPHYS RTCCPHYS;
+#else
+typedef RTHCPHYS RTCCPHYS;
+#endif
+/** Pointer to Current Context Physical Memory Address. */
+typedef RTCCPHYS *PRTCCPHYS;
+/** Pointer to const Current Context Physical Memory Address. */
+typedef const RTCCPHYS *PCRTCCPHYS;
+/** @def NIL_RTCCPHYS
+ * NIL CC Physical Address.
+ * NIL_RTCCPHYS is used to signal an invalid physical address, similar
+ * to the NULL pointer.
+ */
+#ifdef IN_RC
+# define NIL_RTCCPHYS NIL_RTGCPHYS
+#else
+# define NIL_RTCCPHYS NIL_RTHCPHYS
+#endif
+
+/** Unsigned integer register in the current context. */
+#if ARCH_BITS == 32
+typedef uint32_t RTCCUINTREG;
+#elif ARCH_BITS == 64
+typedef uint64_t RTCCUINTREG;
+#else
+# error "Unsupported ARCH_BITS!"
+#endif
+/** Pointer to an unsigned integer register in the current context. */
+typedef RTCCUINTREG *PRTCCUINTREG;
+/** Pointer to a const unsigned integer register in the current context. */
+typedef RTCCUINTREG const *PCRTCCUINTREG;
+
+/** Signed integer register in the current context. */
+#if ARCH_BITS == 32
+typedef int32_t RTCCINTREG;
+#elif ARCH_BITS == 64
+typedef int64_t RTCCINTREG;
+#endif
+/** Pointer to a signed integer register in the current context. */
+typedef RTCCINTREG *PRTCCINTREG;
+/** Pointer to a const signed integer register in the current context. */
+typedef RTCCINTREG const *PCRTCCINTREG;
+
+/** @} */
+
+
+/** Pointer to a critical section. */
+typedef struct RTCRITSECT *PRTCRITSECT;
+/** Pointer to a const critical section. */
+typedef const struct RTCRITSECT *PCRTCRITSECT;
+
+
+/** Condition variable handle. */
+typedef R3PTRTYPE(struct RTCONDVARINTERNAL *) RTCONDVAR;
+/** Pointer to a condition variable handle. */
+typedef RTCONDVAR *PRTCONDVAR;
+/** Nil condition variable handle. */
+#define NIL_RTCONDVAR 0
+
+/** File handle. */
+typedef R3R0PTRTYPE(struct RTFILEINT *) RTFILE;
+/** Pointer to file handle. */
+typedef RTFILE *PRTFILE;
+/** Nil file handle. */
+#define NIL_RTFILE ((RTFILE)~(RTHCINTPTR)0)
+
+/** Async I/O request handle. */
+typedef R3PTRTYPE(struct RTFILEAIOREQINTERNAL *) RTFILEAIOREQ;
+/** Pointer to an async I/O request handle. */
+typedef RTFILEAIOREQ *PRTFILEAIOREQ;
+/** Nil request handle. */
+#define NIL_RTFILEAIOREQ 0
+
+/** Async I/O completion context handle. */
+typedef R3PTRTYPE(struct RTFILEAIOCTXINTERNAL *) RTFILEAIOCTX;
+/** Pointer to an async I/O completion context handle. */
+typedef RTFILEAIOCTX *PRTFILEAIOCTX;
+/** Nil context handle. */
+#define NIL_RTFILEAIOCTX 0
+
+/** Loader module handle. */
+typedef R3PTRTYPE(struct RTLDRMODINTERNAL *) RTLDRMOD;
+/** Pointer to a loader module handle. */
+typedef RTLDRMOD *PRTLDRMOD;
+/** Nil loader module handle. */
+#define NIL_RTLDRMOD 0
+
+/** Lock validator class handle. */
+typedef R3R0PTRTYPE(struct RTLOCKVALCLASSINT *) RTLOCKVALCLASS;
+/** Pointer to a lock validator class handle. */
+typedef RTLOCKVALCLASS *PRTLOCKVALCLASS;
+/** Nil lock validator class handle. */
+#define NIL_RTLOCKVALCLASS ((RTLOCKVALCLASS)0)
+
+/** Ring-0 memory object handle. */
+typedef R0PTRTYPE(struct RTR0MEMOBJINTERNAL *) RTR0MEMOBJ;
+/** Pointer to a Ring-0 memory object handle. */
+typedef RTR0MEMOBJ *PRTR0MEMOBJ;
+/** Nil ring-0 memory object handle. */
+#define NIL_RTR0MEMOBJ 0
+
+/** Native thread handle. */
+typedef RTHCUINTPTR RTNATIVETHREAD;
+/** Pointer to an native thread handle. */
+typedef RTNATIVETHREAD *PRTNATIVETHREAD;
+/** Nil native thread handle. */
+#define NIL_RTNATIVETHREAD (~(RTNATIVETHREAD)0)
+
+/** Pipe handle. */
+typedef R3R0PTRTYPE(struct RTPIPEINTERNAL *) RTPIPE;
+/** Pointer to a pipe handle. */
+typedef RTPIPE *PRTPIPE;
+/** Nil pipe handle.
+ * @remarks This is not 0 because of UNIX and OS/2 handle values. Take care! */
+#define NIL_RTPIPE ((RTPIPE)RTHCUINTPTR_MAX)
+
+/** @typedef RTPOLLSET
+ * Poll set handle. */
+typedef R3R0PTRTYPE(struct RTPOLLSETINTERNAL *) RTPOLLSET;
+/** Pointer to a poll set handle. */
+typedef RTPOLLSET *PRTPOLLSET;
+/** Nil poll set handle handle. */
+#define NIL_RTPOLLSET ((RTPOLLSET)0)
+
+/** Process identifier. */
+typedef uint32_t RTPROCESS;
+/** Pointer to a process identifier. */
+typedef RTPROCESS *PRTPROCESS;
+/** Nil process identifier. */
+#define NIL_RTPROCESS (~(RTPROCESS)0)
+
+/** Process ring-0 handle. */
+typedef RTR0UINTPTR RTR0PROCESS;
+/** Pointer to a ring-0 process handle. */
+typedef RTR0PROCESS *PRTR0PROCESS;
+/** Nil ring-0 process handle. */
+#define NIL_RTR0PROCESS (~(RTR0PROCESS)0)
+
+/** @typedef RTSEMEVENT
+ * Event Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMEVENTINTERNAL *) RTSEMEVENT;
+/** Pointer to an event semaphore handle. */
+typedef RTSEMEVENT *PRTSEMEVENT;
+/** Nil event semaphore handle. */
+#define NIL_RTSEMEVENT 0
+
+/** @typedef RTSEMEVENTMULTI
+ * Event Multiple Release Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMEVENTMULTIINTERNAL *) RTSEMEVENTMULTI;
+/** Pointer to an event multiple release semaphore handle. */
+typedef RTSEMEVENTMULTI *PRTSEMEVENTMULTI;
+/** Nil multiple release event semaphore handle. */
+#define NIL_RTSEMEVENTMULTI 0
+
+/** @typedef RTSEMFASTMUTEX
+ * Fast mutex Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMFASTMUTEXINTERNAL *) RTSEMFASTMUTEX;
+/** Pointer to a fast mutex semaphore handle. */
+typedef RTSEMFASTMUTEX *PRTSEMFASTMUTEX;
+/** Nil fast mutex semaphore handle. */
+#define NIL_RTSEMFASTMUTEX 0
+
+/** @typedef RTSEMMUTEX
+ * Mutex Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMMUTEXINTERNAL *) RTSEMMUTEX;
+/** Pointer to a mutex semaphore handle. */
+typedef RTSEMMUTEX *PRTSEMMUTEX;
+/** Nil mutex semaphore handle. */
+#define NIL_RTSEMMUTEX 0
+
+/** @typedef RTSEMSPINMUTEX
+ * Spinning mutex Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMSPINMUTEXINTERNAL *) RTSEMSPINMUTEX;
+/** Pointer to a spinning mutex semaphore handle. */
+typedef RTSEMSPINMUTEX *PRTSEMSPINMUTEX;
+/** Nil spinning mutex semaphore handle. */
+#define NIL_RTSEMSPINMUTEX 0
+
+/** @typedef RTSEMRW
+ * Read/Write Semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMRWINTERNAL *) RTSEMRW;
+/** Pointer to a read/write semaphore handle. */
+typedef RTSEMRW *PRTSEMRW;
+/** Nil read/write semaphore handle. */
+#define NIL_RTSEMRW 0
+
+/** @typedef RTSEMXROADS
+ * Crossroads semaphore handle. */
+typedef R3R0PTRTYPE(struct RTSEMXROADSINTERNAL *) RTSEMXROADS;
+/** Pointer to a crossroads semaphore handle. */
+typedef RTSEMXROADS *PRTSEMXROADS;
+/** Nil crossroads semaphore handle. */
+#define NIL_RTSEMXROADS ((RTSEMXROADS)0)
+
+/** Spinlock handle. */
+typedef R3R0PTRTYPE(struct RTSPINLOCKINTERNAL *) RTSPINLOCK;
+/** Pointer to a spinlock handle. */
+typedef RTSPINLOCK *PRTSPINLOCK;
+/** Nil spinlock handle. */
+#define NIL_RTSPINLOCK 0
+
+/** Socket handle. */
+typedef R3R0PTRTYPE(struct RTSOCKETINT *) RTSOCKET;
+/** Pointer to socket handle. */
+typedef RTSOCKET *PRTSOCKET;
+/** Nil socket handle. */
+#define NIL_RTSOCKET ((RTSOCKET)0)
+
+/** Pointer to a RTTCPSERVER handle. */
+typedef struct RTTCPSERVER *PRTTCPSERVER;
+/** Pointer to a RTTCPSERVER handle. */
+typedef PRTTCPSERVER *PPRTTCPSERVER;
+/** Nil RTTCPSERVER handle. */
+#define NIL_RTTCPSERVER ((PRTTCPSERVER)0)
+
+/** Pointer to a RTUDPSERVER handle. */
+typedef struct RTUDPSERVER *PRTUDPSERVER;
+/** Pointer to a RTUDPSERVER handle. */
+typedef PRTUDPSERVER *PPRTUDPSERVER;
+/** Nil RTUDPSERVER handle. */
+#define NIL_RTUDPSERVER ((PRTUDPSERVER)0)
+
+/** Thread handle.*/
+typedef R3R0PTRTYPE(struct RTTHREADINT *) RTTHREAD;
+/** Pointer to thread handle. */
+typedef RTTHREAD *PRTTHREAD;
+/** Nil thread handle. */
+#define NIL_RTTHREAD 0
+
+/** A TLS index. */
+typedef RTHCINTPTR RTTLS;
+/** Pointer to a TLS index. */
+typedef RTTLS *PRTTLS;
+/** Pointer to a const TLS index. */
+typedef RTTLS const *PCRTTLS;
+/** NIL TLS index value. */
+#define NIL_RTTLS ((RTTLS)-1)
+
+/** Trace buffer handle.
+ * @remarks This is not a R3/R0 type like most other handles!
+ */
+typedef struct RTTRACEBUFINT *RTTRACEBUF;
+/** Poiner to a trace buffer handle. */
+typedef RTTRACEBUF *PRTTRACEBUF;
+/** Nil trace buffer handle. */
+#define NIL_RTTRACEBUF ((RTTRACEBUF)0)
+/** The handle of the default trace buffer.
+ * This can be used with any of the RTTraceBufAdd APIs. */
+#define RTTRACEBUF_DEFAULT ((RTTRACEBUF)-2)
+
+/** Handle to a simple heap. */
+typedef R3R0PTRTYPE(struct RTHEAPSIMPLEINTERNAL *) RTHEAPSIMPLE;
+/** Pointer to a handle to a simple heap. */
+typedef RTHEAPSIMPLE *PRTHEAPSIMPLE;
+/** NIL simple heap handle. */
+#define NIL_RTHEAPSIMPLE ((RTHEAPSIMPLE)0)
+
+/** Handle to an offset based heap. */
+typedef R3R0PTRTYPE(struct RTHEAPOFFSETINTERNAL *) RTHEAPOFFSET;
+/** Pointer to a handle to an offset based heap. */
+typedef RTHEAPOFFSET *PRTHEAPOFFSET;
+/** NIL offset based heap handle. */
+#define NIL_RTHEAPOFFSET ((RTHEAPOFFSET)0)
+
+/** Handle to an environment block. */
+typedef R3PTRTYPE(struct RTENVINTERNAL *) RTENV;
+/** Pointer to a handle to an environment block. */
+typedef RTENV *PRTENV;
+/** NIL simple heap handle. */
+#define NIL_RTENV ((RTENV)0)
+
+/** A CPU identifier.
+ * @remarks This doesn't have to correspond to the APIC ID (intel/amd). Nor
+ * does it have to correspond to the bits in the affinity mask, at
+ * least not until we've sorted out Windows NT. */
+typedef uint32_t RTCPUID;
+/** Pointer to a CPU identifier. */
+typedef RTCPUID *PRTCPUID;
+/** Pointer to a const CPU identifier. */
+typedef RTCPUID const *PCRTCPUID;
+/** Nil CPU Id. */
+#define NIL_RTCPUID ((RTCPUID)~0)
+
+/** The maximum number of CPUs a set can contain and IPRT is able
+ * to reference. (Should be max of support arch/platforms.)
+ * @remarks Must be a multiple of 64 (see RTCPUSET). */
+#if defined(RT_ARCH_X86) || defined(RT_ARCH_AMD64)
+# define RTCPUSET_MAX_CPUS 256
+#elif defined(RT_ARCH_SPARC) || defined(RT_ARCH_SPARC64)
+# define RTCPUSET_MAX_CPUS 1024
+#else
+# define RTCPUSET_MAX_CPUS 64
+#endif
+/** A CPU set.
+ * @note Treat this as an opaque type and always use RTCpuSet* for
+ * manupulating it. */
+typedef struct RTCPUSET
+{
+ /** The bitmap. */
+ uint64_t bmSet[RTCPUSET_MAX_CPUS / 64];
+} RTCPUSET;
+/** Pointer to a CPU set. */
+typedef RTCPUSET *PRTCPUSET;
+/** Pointer to a const CPU set. */
+typedef RTCPUSET const *PCRTCPUSET;
+
+/** A handle table handle. */
+typedef R3R0PTRTYPE(struct RTHANDLETABLEINT *) RTHANDLETABLE;
+/** A pointer to a handle table handle. */
+typedef RTHANDLETABLE *PRTHANDLETABLE;
+/** @def NIL_RTHANDLETABLE
+ * NIL handle table handle. */
+#define NIL_RTHANDLETABLE ((RTHANDLETABLE)0)
+
+/** A handle to a low resolution timer. */
+typedef R3R0PTRTYPE(struct RTTIMERLRINT *) RTTIMERLR;
+/** A pointer to a low resolution timer handle. */
+typedef RTTIMERLR *PRTTIMERLR;
+/** @def NIL_RTTIMERLR
+ * NIL low resolution timer handle value. */
+#define NIL_RTTIMERLR ((RTTIMERLR)0)
+
+/** Handle to a random number generator. */
+typedef R3R0PTRTYPE(struct RTRANDINT *) RTRAND;
+/** Pointer to a random number generator handle. */
+typedef RTRAND *PRTRAND;
+/** NIL random number genrator handle value. */
+#define NIL_RTRAND ((RTRAND)0)
+
+/** Debug address space handle. */
+typedef R3R0PTRTYPE(struct RTDBGASINT *) RTDBGAS;
+/** Pointer to a debug address space handle. */
+typedef RTDBGAS *PRTDBGAS;
+/** NIL debug address space handle. */
+#define NIL_RTDBGAS ((RTDBGAS)0)
+
+/** Debug module handle. */
+typedef R3R0PTRTYPE(struct RTDBGMODINT *) RTDBGMOD;
+/** Pointer to a debug module handle. */
+typedef RTDBGMOD *PRTDBGMOD;
+/** NIL debug module handle. */
+#define NIL_RTDBGMOD ((RTDBGMOD)0)
+
+/** Manifest handle. */
+typedef struct RTMANIFESTINT *RTMANIFEST;
+/** Pointer to a manifest handle. */
+typedef RTMANIFEST *PRTMANIFEST;
+/** NIL manifest handle. */
+#define NIL_RTMANIFEST ((RTMANIFEST)~(uintptr_t)0)
+
+/** Memory pool handle. */
+typedef R3R0PTRTYPE(struct RTMEMPOOLINT *) RTMEMPOOL;
+/** Pointer to a memory pool handle. */
+typedef RTMEMPOOL *PRTMEMPOOL;
+/** NIL memory pool handle. */
+#define NIL_RTMEMPOOL ((RTMEMPOOL)0)
+/** The default memory pool handle. */
+#define RTMEMPOOL_DEFAULT ((RTMEMPOOL)-2)
+
+/** String cache handle. */
+typedef R3R0PTRTYPE(struct RTSTRCACHEINT *) RTSTRCACHE;
+/** Pointer to a string cache handle. */
+typedef RTSTRCACHE *PRTSTRCACHE;
+/** NIL string cache handle. */
+#define NIL_RTSTRCACHE ((RTSTRCACHE)0)
+/** The default string cache handle. */
+#define RTSTRCACHE_DEFAULT ((RTSTRCACHE)-2)
+
+
+/** Virtual Filesystem handle. */
+typedef struct RTVFSINTERNAL *RTVFS;
+/** Pointer to a VFS handle. */
+typedef RTVFS *PRTVFS;
+/** A NIL VFS handle. */
+#define NIL_RTVFS ((RTVFS)~(uintptr_t)0)
+
+/** Virtual Filesystem base object handle. */
+typedef struct RTVFSOBJINTERNAL *RTVFSOBJ;
+/** Pointer to a VFS base object handle. */
+typedef RTVFSOBJ *PRTVFSOBJ;
+/** A NIL VFS base object handle. */
+#define NIL_RTVFSOBJ ((RTVFSOBJ)~(uintptr_t)0)
+
+/** Virtual Filesystem directory handle. */
+typedef struct RTVFSDIRINTERNAL *RTVFSDIR;
+/** Pointer to a VFS directory handle. */
+typedef RTVFSDIR *PRTVFSDIR;
+/** A NIL VFS directory handle. */
+#define NIL_RTVFSDIR ((RTVFSDIR)~(uintptr_t)0)
+
+/** Virtual Filesystem filesystem stream handle. */
+typedef struct RTVFSFSSTREAMINTERNAL *RTVFSFSSTREAM;
+/** Pointer to a VFS filesystem stream handle. */
+typedef RTVFSFSSTREAM *PRTVFSFSSTREAM;
+/** A NIL VFS filesystem stream handle. */
+#define NIL_RTVFSFSSTREAM ((RTVFSFSSTREAM)~(uintptr_t)0)
+
+/** Virtual Filesystem I/O stream handle. */
+typedef struct RTVFSIOSTREAMINTERNAL *RTVFSIOSTREAM;
+/** Pointer to a VFS I/O stream handle. */
+typedef RTVFSIOSTREAM *PRTVFSIOSTREAM;
+/** A NIL VFS I/O stream handle. */
+#define NIL_RTVFSIOSTREAM ((RTVFSIOSTREAM)~(uintptr_t)0)
+
+/** Virtual Filesystem file handle. */
+typedef struct RTVFSFILEINTERNAL *RTVFSFILE;
+/** Pointer to a VFS file handle. */
+typedef RTVFSFILE *PRTVFSFILE;
+/** A NIL VFS file handle. */
+#define NIL_RTVFSFILE ((RTVFSFILE)~(uintptr_t)0)
+
+/** Virtual Filesystem symbolic link handle. */
+typedef struct RTVFSSYMLINKINTERNAL *RTVFSSYMLINK;
+/** Pointer to a VFS symbolic link handle. */
+typedef RTVFSSYMLINK *PRTVFSSYMLINK;
+/** A NIL VFS symbolic link handle. */
+#define NIL_RTVFSSYMLINK ((RTVFSSYMLINK)~(uintptr_t)0)
+
+
+/**
+ * Handle type.
+ *
+ * This is usually used together with RTHANDLEUNION.
+ */
+typedef enum RTHANDLETYPE
+{
+ /** The invalid zero value. */
+ RTHANDLETYPE_INVALID = 0,
+ /** File handle. */
+ RTHANDLETYPE_FILE,
+ /** Pipe handle */
+ RTHANDLETYPE_PIPE,
+ /** Socket handle. */
+ RTHANDLETYPE_SOCKET,
+ /** Thread handle. */
+ RTHANDLETYPE_THREAD,
+ /** The end of the valid values. */
+ RTHANDLETYPE_END,
+ /** The 32-bit type blow up. */
+ RTHANDLETYPE_32BIT_HACK = 0x7fffffff
+} RTHANDLETYPE;
+/** Pointer to a handle type. */
+typedef RTHANDLETYPE *PRTHANDLETYPE;
+
+/**
+ * Handle union.
+ *
+ * This is usually used together with RTHANDLETYPE or as RTHANDLE.
+ */
+typedef union RTHANDLEUNION
+{
+ RTFILE hFile; /**< File handle. */
+ RTPIPE hPipe; /**< Pipe handle. */
+ RTSOCKET hSocket; /**< Socket handle. */
+ RTTHREAD hThread; /**< Thread handle. */
+ /** Generic integer handle value.
+ * Note that RTFILE is not yet pointer sized, so accessing it via this member
+ * isn't necessarily safe or fully portable. */
+ RTHCUINTPTR uInt;
+} RTHANDLEUNION;
+/** Pointer to a handle union. */
+typedef RTHANDLEUNION *PRTHANDLEUNION;
+/** Pointer to a const handle union. */
+typedef RTHANDLEUNION const *PCRTHANDLEUNION;
+
+/**
+ * Generic handle.
+ */
+typedef struct RTHANDLE
+{
+ /** The handle type. */
+ RTHANDLETYPE enmType;
+ /** The handle value. */
+ RTHANDLEUNION u;
+} RTHANDLE;
+/** Pointer to a generic handle. */
+typedef RTHANDLE *PRTHANDLE;
+/** Pointer to a const generic handle. */
+typedef RTHANDLE const *PCRTHANDLE;
+
+
+/**
+ * Standard handles.
+ *
+ * @remarks These have the correct file descriptor values for unixy systems and
+ * can be used directly in code specific to those platforms.
+ */
+typedef enum RTHANDLESTD
+{
+ /** Invalid standard handle. */
+ RTHANDLESTD_INVALID = -1,
+ /** The standard input handle. */
+ RTHANDLESTD_INPUT = 0,
+ /** The standard output handle. */
+ RTHANDLESTD_OUTPUT,
+ /** The standard error handle. */
+ RTHANDLESTD_ERROR,
+ /** The typical 32-bit type hack. */
+ RTHANDLESTD_32BIT_HACK = 0x7fffffff
+} RTHANDLESTD;
+
+
+/**
+ * Error info.
+ *
+ * See RTErrInfo*.
+ */
+typedef struct RTERRINFO
+{
+ /** Flags, see RTERRINFO_FLAGS_XXX. */
+ uint32_t fFlags;
+ /** The status code. */
+ int32_t rc;
+ /** The size of the message */
+ size_t cbMsg;
+ /** The error buffer. */
+ char *pszMsg;
+ /** Reserved for future use. */
+ void *apvReserved[2];
+} RTERRINFO;
+/** Pointer to an error info structure. */
+typedef RTERRINFO *PRTERRINFO;
+/** Pointer to a const error info structure. */
+typedef RTERRINFO const *PCRTERRINFO;
+
+/**
+ * Static error info structure, see RTErrInfoInitStatic.
+ */
+typedef struct RTERRINFOSTATIC
+{
+ /** The core error info. */
+ RTERRINFO Core;
+ /** The static message buffer. */
+ char szMsg[3072];
+} RTERRINFOSTATIC;
+/** Pointer to a error info buffer. */
+typedef RTERRINFOSTATIC *PRTERRINFOSTATIC;
+/** Pointer to a const static error info buffer. */
+typedef RTERRINFOSTATIC const *PCRTERRINFOSTATIC;
+
+
+/**
+ * UUID data type.
+ *
+ * See RTUuid*.
+ *
+ * @remarks IPRT defines that the first three integers in the @c Gen struct
+ * interpretation are in little endian representation. This is
+ * different to many other UUID implementation, and requires
+ * conversion if you need to achieve consistent results.
+ */
+typedef union RTUUID
+{
+ /** 8-bit view. */
+ uint8_t au8[16];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 32-bit view. */
+ uint32_t au32[4];
+ /** 64-bit view. */
+ uint64_t au64[2];
+ /** The way the UUID is declared by the DCE specification. */
+ struct
+ {
+ uint32_t u32TimeLow;
+ uint16_t u16TimeMid;
+ uint16_t u16TimeHiAndVersion;
+ uint8_t u8ClockSeqHiAndReserved;
+ uint8_t u8ClockSeqLow;
+ uint8_t au8Node[6];
+ } Gen;
+} RTUUID;
+/** Pointer to UUID data. */
+typedef RTUUID *PRTUUID;
+/** Pointer to readonly UUID data. */
+typedef const RTUUID *PCRTUUID;
+
+/** UUID string maximum length. */
+#define RTUUID_STR_LENGTH 37
+
+
+/** Compression handle. */
+typedef struct RTZIPCOMP *PRTZIPCOMP;
+/** Decompressor handle. */
+typedef struct RTZIPDECOMP *PRTZIPDECOMP;
+
+
+/**
+ * Unicode Code Point.
+ */
+typedef uint32_t RTUNICP;
+/** Pointer to an Unicode Code Point. */
+typedef RTUNICP *PRTUNICP;
+/** Pointer to an Unicode Code Point. */
+typedef const RTUNICP *PCRTUNICP;
+/** Max value a RTUNICP type can hold. */
+#define RTUNICP_MAX ( ~(RTUNICP)0 )
+/** Invalid code point.
+ * This is returned when encountered invalid encodings or invalid
+ * unicode code points. */
+#define RTUNICP_INVALID ( UINT32_C(0xfffffffe) )
+
+
+/**
+ * UTF-16 character.
+ * @remark wchar_t is not usable since it's compiler defined.
+ * @remark When we use the term character we're not talking about unicode code point, but
+ * the basic unit of the string encoding. Thus cwc - count of wide chars - means
+ * count of RTUTF16; cuc - count of unicode chars - means count of RTUNICP;
+ * and cch means count of the typedef 'char', which is assumed to be an octet.
+ */
+typedef uint16_t RTUTF16;
+/** Pointer to a UTF-16 character. */
+typedef RTUTF16 *PRTUTF16;
+/** Pointer to a const UTF-16 character. */
+typedef const RTUTF16 *PCRTUTF16;
+
+
+/**
+ * Wait for ever if we have to.
+ */
+#define RT_INDEFINITE_WAIT (~0U)
+
+
+/**
+ * Generic process callback.
+ *
+ * @returns VBox status code. Failure will cancel the operation.
+ * @param uPercentage The percentage of the operation which has been completed.
+ * @param pvUser The user specified argument.
+ */
+typedef DECLCALLBACK(int) FNRTPROGRESS(unsigned uPrecentage, void *pvUser);
+/** Pointer to a generic progress callback function, FNRTPROCESS(). */
+typedef FNRTPROGRESS *PFNRTPROGRESS;
+
+
+/**
+ * A point in a two dimentional coordinate system.
+ */
+typedef struct RTPOINT
+{
+ /** X coordinate. */
+ int32_t x;
+ /** Y coordinate. */
+ int32_t y;
+} RTPOINT;
+/** Pointer to a point. */
+typedef RTPOINT *PRTPOINT;
+/** Pointer to a const point. */
+typedef const RTPOINT *PCRTPOINT;
+
+
+/**
+ * Rectangle data type, double point.
+ */
+typedef struct RTRECT
+{
+ /** left X coordinate. */
+ int32_t xLeft;
+ /** top Y coordinate. */
+ int32_t yTop;
+ /** right X coordinate. (exclusive) */
+ int32_t xRight;
+ /** bottom Y coordinate. (exclusive) */
+ int32_t yBottom;
+} RTRECT;
+/** Pointer to a double point rectangle. */
+typedef RTRECT *PRTRECT;
+/** Pointer to a const double point rectangle. */
+typedef const RTRECT *PCRTRECT;
+
+
+/**
+ * Rectangle data type, point + size.
+ */
+typedef struct RTRECT2
+{
+ /** X coordinate.
+ * Unless stated otherwise, this is the top left corner. */
+ int32_t x;
+ /** Y coordinate.
+ * Unless stated otherwise, this is the top left corner. */
+ int32_t y;
+ /** The width.
+ * Unless stated otherwise, this is to the right of (x,y) and will not
+ * be a negative number. */
+ int32_t cx;
+ /** The height.
+ * Unless stated otherwise, this is down from (x,y) and will not be a
+ * negative number. */
+ int32_t cy;
+} RTRECT2;
+/** Pointer to a point + size rectangle. */
+typedef RTRECT2 *PRTRECT2;
+/** Pointer to a const point + size rectangle. */
+typedef const RTRECT2 *PCRTRECT2;
+
+
+/**
+ * The size of a rectangle.
+ */
+typedef struct RTRECTSIZE
+{
+ /** The width (along the x-axis). */
+ uint32_t cx;
+ /** The height (along the y-axis). */
+ uint32_t cy;
+} RTRECTSIZE;
+/** Pointer to a rectangle size. */
+typedef RTRECTSIZE *PRTRECTSIZE;
+/** Pointer to a const rectangle size. */
+typedef const RTRECTSIZE *PCRTRECTSIZE;
+
+
+/**
+ * Ethernet MAC address.
+ *
+ * The first 24 bits make up the Organisationally Unique Identifier (OUI),
+ * where the first bit (little endian) indicates multicast (set) / unicast,
+ * and the second bit indicates locally (set) / global administered. If all
+ * bits are set, it's a broadcast.
+ */
+typedef union RTMAC
+{
+ /** @todo add a bitfield view of this stuff. */
+ /** 8-bit view. */
+ uint8_t au8[6];
+ /** 16-bit view. */
+ uint16_t au16[3];
+} RTMAC;
+/** Pointer to a MAC address. */
+typedef RTMAC *PRTMAC;
+/** Pointer to a readonly MAC address. */
+typedef const RTMAC *PCRTMAC;
+
+
+/** Pointer to a lock validator record.
+ * The structure definition is found in iprt/lockvalidator.h. */
+typedef struct RTLOCKVALRECEXCL *PRTLOCKVALRECEXCL;
+/** Pointer to a lock validator source poisition.
+ * The structure definition is found in iprt/lockvalidator.h. */
+typedef struct RTLOCKVALSRCPOS *PRTLOCKVALSRCPOS;
+/** Pointer to a const lock validator source poisition.
+ * The structure definition is found in iprt/lockvalidator.h. */
+typedef struct RTLOCKVALSRCPOS const *PCRTLOCKVALSRCPOS;
+
+/** @name Special sub-class values.
+ * The range 16..UINT32_MAX is available to the user, the range 0..15 is
+ * reserved for the lock validator. In the user range the locks can only be
+ * taking in ascending order.
+ * @{ */
+/** Invalid value. */
+#define RTLOCKVAL_SUB_CLASS_INVALID UINT32_C(0)
+/** Not allowed to be taken with any other locks in the same class.
+ * This is the recommended value. */
+#define RTLOCKVAL_SUB_CLASS_NONE UINT32_C(1)
+/** Any order is allowed within the class. */
+#define RTLOCKVAL_SUB_CLASS_ANY UINT32_C(2)
+/** The first user value. */
+#define RTLOCKVAL_SUB_CLASS_USER UINT32_C(16)
+/** @} */
+
+
+/**
+ * Process exit codes.
+ */
+typedef enum RTEXITCODE
+{
+ /** Success. */
+ RTEXITCODE_SUCCESS = 0,
+ /** General failure. */
+ RTEXITCODE_FAILURE = 1,
+ /** Invalid arguments. */
+ RTEXITCODE_SYNTAX = 2,
+ /** Initialization failure (usually IPRT, but could be used for other
+ * components as well). */
+ RTEXITCODE_INIT = 3,
+ /** Test skipped. */
+ RTEXITCODE_SKIPPED = 4,
+ /** The end of valid exit codes. */
+ RTEXITCODE_END,
+ /** The usual 32-bit type hack. */
+ RTEXITCODE_32BIT_HACK = 0x7fffffff
+} RTEXITCODE;
+
+/**
+ * Range descriptor.
+ */
+typedef struct RTRANGE
+{
+ /** Start offset. */
+ uint64_t offStart;
+ /** Range size. */
+ size_t cbRange;
+} RTRANGE;
+/** Pointer to a range descriptor. */
+typedef RTRANGE *PRTRANGE;
+/** Pointer to a readonly range descriptor. */
+typedef const RTRANGE *PCRTRANGE;
+
+#ifdef __cplusplus
+/**
+ * Strict type validation helper class.
+ *
+ * See RTErrStrictType and RT_SUCCESS_NP.
+ */
+class RTErrStrictType2
+{
+protected:
+ /** The status code. */
+ int32_t m_rc;
+
+public:
+ /**
+ * Constructor.
+ * @param rc IPRT style status code.
+ */
+ RTErrStrictType2(int32_t rc) : m_rc(rc)
+ {
+ }
+
+ /**
+ * Get the status code.
+ * @returns IPRT style status code.
+ */
+ int32_t getValue() const
+ {
+ return m_rc;
+ }
+};
+#endif /* __cplusplus */
+/** @} */
+
+#endif
+
diff --git a/include/iprt/udp.h b/include/iprt/udp.h
new file mode 100644
index 00000000..543d73d6
--- /dev/null
+++ b/include/iprt/udp.h
@@ -0,0 +1,155 @@
+/** @file
+ * IPRT - UDP/IP.
+ */
+
+/*
+ * 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 ___iprt_udp_h
+#define ___iprt_udp_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/thread.h>
+#include <iprt/net.h>
+#include <iprt/sg.h>
+#include <iprt/socket.h>
+
+#ifdef IN_RING0
+# error "There are no RTFile APIs available Ring-0 Host Context!"
+#endif
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_udp RTUdp - UDP/IP
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Handle incoming UDP datagrams.
+ *
+ * @returns iprt status code.
+ * @returns VERR_UDP_SERVER_STOP to terminate the server loop forcing
+ * the RTUdpCreateServer() call to return.
+ * @param Sock The socket on which the datagram needs to be received.
+ * @param pvUser User argument.
+ */
+typedef DECLCALLBACK(int) FNRTUDPSERVE(RTSOCKET Sock, void *pvUser);
+/** Pointer to a RTUDPSERVE(). */
+typedef FNRTUDPSERVE *PFNRTUDPSERVE;
+
+/**
+ * Create single datagram at a time UDP Server in a separate thread.
+ *
+ * The thread will loop accepting datagrams and call pfnServe for
+ * each of the incoming datagrams in turn. The pfnServe function can
+ * return VERR_UDP_SERVER_STOP too terminate this loop. RTUdpServerDestroy()
+ * should be used to terminate the server.
+ *
+ * @returns iprt status code.
+ * @param pszAddress The address for creating a datagram socket.
+ * If NULL or empty string the server is bound to all interfaces.
+ * @param uPort The port for creating a datagram socket.
+ * @param enmType The thread type.
+ * @param pszThrdName The name of the worker thread.
+ * @param pfnServe The function which will handle incoming datagrams.
+ * @param pvUser User argument passed to pfnServe.
+ * @param ppServer Where to store the serverhandle.
+ */
+RTR3DECL(int) RTUdpServerCreate(const char *pszAddress, unsigned uPort, RTTHREADTYPE enmType, const char *pszThrdName,
+ PFNRTUDPSERVE pfnServe, void *pvUser, PPRTUDPSERVER ppServer);
+
+/**
+ * Create single datagram at a time UDP Server.
+ * The caller must call RTUdpServerReceive() to actually start the server.
+ *
+ * @returns iprt status code.
+ * @param pszAddress The address for creating a datagram socket.
+ * If NULL the server is bound to all interfaces.
+ * @param uPort The port for creating a datagram socket.
+ * @param ppServer Where to store the serverhandle.
+ */
+RTR3DECL(int) RTUdpServerCreateEx(const char *pszAddress, uint32_t uPort, PPRTUDPSERVER ppServer);
+
+/**
+ * Shuts down the server.
+ *
+ * @returns IPRT status code.
+ * @param pServer Handle to the server.
+ */
+RTR3DECL(int) RTUdpServerShutdown(PRTUDPSERVER pServer);
+
+/**
+ * Closes down and frees a UDP Server.
+ *
+ * @returns iprt status code.
+ * @param pServer Handle to the server.
+ */
+RTR3DECL(int) RTUdpServerDestroy(PRTUDPSERVER pServer);
+
+/**
+ * Listen for incoming datagrams.
+ *
+ * The function will loop waiting for datagrams and call pfnServe for
+ * each of the incoming datagrams in turn. The pfnServe function can
+ * return VERR_UDP_SERVER_STOP too terminate this loop. A stopped server
+ * can only be destroyed.
+ *
+ * @returns iprt status code.
+ * @param pServer The server handle as returned from RTUdpServerCreateEx().
+ * @param pfnServe The function which will handle incoming datagrams.
+ * @param pvUser User argument passed to pfnServe.
+ */
+RTR3DECL(int) RTUdpServerListen(PRTUDPSERVER pServer, PFNRTUDPSERVE pfnServe, void *pvUser);
+
+/**
+ * Receive data from a socket.
+ *
+ * @returns 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. Must be non-NULL.
+ */
+RTR3DECL(int) RTUdpRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead, PRTNETADDR pSrcAddr);
+
+/**
+ * Send data to a socket.
+ *
+ * @returns iprt status code.
+ * @retval VERR_INTERRUPTED if interrupted before anything was written.
+ *
+ * @param pServer Handle to the server.
+ * @param pvBuffer Buffer to write data to socket.
+ * @param cbBuffer How much to write.
+ * @param pDstAddr Destination address.
+ */
+RTR3DECL(int) RTUdpWrite(PRTUDPSERVER pServer, const void *pvBuffer,
+ size_t cbBuffer, PCRTNETADDR pDstAddr);
+
+/** @} */
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/uint128.h b/include/iprt/uint128.h
new file mode 100644
index 00000000..d5df1c4a
--- /dev/null
+++ b/include/iprt/uint128.h
@@ -0,0 +1,698 @@
+/** @file
+ * IPRT - RTUINT128U & uint128_t methods.
+ */
+
+/*
+ * 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 ___iprt_uint128_h
+#define ___iprt_uint128_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/err.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_once RTUInt128 - 128-bit Unsigned Integer Methods
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+/**
+ * Test if a 128-bit unsigned integer value is zero.
+ *
+ * @returns true if they are, false if they aren't.
+ * @param pValue The input and output value.
+ */
+DECLINLINE(bool) RTUInt128IsZero(PRTUINT128U pValue)
+{
+#if ARCH_BITS >= 64
+ return pValue->s.Hi == 0
+ && pValue->s.Lo == 0;
+#else
+ return pValue->DWords.dw0 == 0
+ && pValue->DWords.dw1 == 0
+ && pValue->DWords.dw2 == 0
+ && pValue->DWords.dw3 == 0;
+#endif
+}
+
+
+/**
+ * Set a 128-bit unsigned integer value to zero.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128SetZero(PRTUINT128U pResult)
+{
+#if ARCH_BITS >= 64
+ pResult->s.Hi = 0;
+ pResult->s.Lo = 0;
+#else
+ pResult->DWords.dw0 = 0;
+ pResult->DWords.dw1 = 0;
+ pResult->DWords.dw2 = 0;
+ pResult->DWords.dw3 = 0;
+#endif
+ return pResult;
+}
+
+
+/**
+ * Set a 128-bit unsigned integer value to the maximum value.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128SetMax(PRTUINT128U pResult)
+{
+#if ARCH_BITS >= 64
+ pResult->s.Hi = UINT64_MAX;
+ pResult->s.Lo = UINT64_MAX;
+#else
+ pResult->DWords.dw0 = UINT32_MAX;
+ pResult->DWords.dw1 = UINT32_MAX;
+ pResult->DWords.dw2 = UINT32_MAX;
+ pResult->DWords.dw3 = UINT32_MAX;
+#endif
+ return pResult;
+}
+
+
+RTDECL(PRTUINT128U) RTUInt128Add(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128Sub(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128Div(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128Mod(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128And(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128Or( PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128Xor(PRTUINT128U pResult, PCRTUINT128U pValue1, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128ShiftLeft( PRTUINT128U pResult, PCRTUINT128U pValue, int cBits);
+RTDECL(PRTUINT128U) RTUInt128ShiftRight(PRTUINT128U pResult, PCRTUINT128U pValue, int cBits);
+RTDECL(PRTUINT128U) RTUInt128BooleanNot(PRTUINT128U pResult, PCRTUINT128U pValue);
+RTDECL(PRTUINT128U) RTUInt128BitwiseNot(PRTUINT128U pResult, PCRTUINT128U pValue);
+
+
+/**
+ * Assigns one 128-bit unsigned integer value to another.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ * @param pValue The value to assign.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128Assign(PRTUINT128U pResult, PCRTUINT128U pValue)
+{
+#if ARCH_BITS >= 64
+ pResult->s.Hi = pValue->s.Hi;
+ pResult->s.Lo = pValue->s.Lo;
+#else
+ pResult->DWords.dw0 = pValue->DWords.dw0;
+ pResult->DWords.dw1 = pValue->DWords.dw1;
+ pResult->DWords.dw2 = pValue->DWords.dw2;
+ pResult->DWords.dw3 = pValue->DWords.dw3;
+#endif
+ return pResult;
+}
+
+
+/**
+ * Assigns a boolean value to 128-bit unsigned integer.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ * @param fValue The boolean value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignBoolean(PRTUINT128U pValueResult, bool fValue)
+{
+#if ARCH_BITS >= 64
+ pValueResult->s.Lo = fValue;
+ pValueResult->s.Hi = 0;
+#else
+ pValueResult->DWords.dw0 = fValue;
+ pValueResult->DWords.dw1 = 0;
+ pValueResult->DWords.dw2 = 0;
+ pValueResult->DWords.dw3 = 0;
+#endif
+ return pValueResult;
+}
+
+
+/**
+ * Assigns a 8-bit unsigned integer value to 128-bit unsigned integer.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ * @param u8Value The 8-bit unsigned integer value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignU8(PRTUINT128U pValueResult, uint8_t u8Value)
+{
+#if ARCH_BITS >= 64
+ pValueResult->s.Lo = u8Value;
+ pValueResult->s.Hi = 0;
+#else
+ pValueResult->DWords.dw0 = u8Value;
+ pValueResult->DWords.dw1 = 0;
+ pValueResult->DWords.dw2 = 0;
+ pValueResult->DWords.dw3 = 0;
+#endif
+ return pValueResult;
+}
+
+
+/**
+ * Assigns a 16-bit unsigned integer value to 128-bit unsigned integer.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ * @param u16Value The 16-bit unsigned integer value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignU16(PRTUINT128U pValueResult, uint16_t u16Value)
+{
+#if ARCH_BITS >= 64
+ pValueResult->s.Lo = u16Value;
+ pValueResult->s.Hi = 0;
+#else
+ pValueResult->DWords.dw0 = u16Value;
+ pValueResult->DWords.dw1 = 0;
+ pValueResult->DWords.dw2 = 0;
+ pValueResult->DWords.dw3 = 0;
+#endif
+ return pValueResult;
+}
+
+
+/**
+ * Assigns a 16-bit unsigned integer value to 128-bit unsigned integer.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ * @param u32Value The 32-bit unsigned integer value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignU32(PRTUINT128U pValueResult, uint32_t u32Value)
+{
+#if ARCH_BITS >= 64
+ pValueResult->s.Lo = u32Value;
+ pValueResult->s.Hi = 0;
+#else
+ pValueResult->DWords.dw0 = u32Value;
+ pValueResult->DWords.dw1 = 0;
+ pValueResult->DWords.dw2 = 0;
+ pValueResult->DWords.dw3 = 0;
+#endif
+ return pValueResult;
+}
+
+
+/**
+ * Assigns a 64-bit unsigned integer value to 128-bit unsigned integer.
+ *
+ * @returns pResult
+ * @param pResult The result variable.
+ * @param u32Value The 32-bit unsigned integer value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignU64(PRTUINT128U pValueResult, uint64_t u64Value)
+{
+ pValueResult->s.Lo = u64Value;
+ pValueResult->s.Hi = 0;
+ return pValueResult;
+}
+
+
+RTDECL(PRTUINT128U) RTUInt128AssignAdd(PRTUINT128U pValue1Result, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128AssignSub(PRTUINT128U pValue1Result, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128AssignDiv(PRTUINT128U pValue1Result, PCRTUINT128U pValue2);
+RTDECL(PRTUINT128U) RTUInt128AssignMod(PRTUINT128U pValue1Result, PCRTUINT128U pValue2);
+
+
+/**
+ * Performs a bitwise AND of two 128-bit unsigned integer values and assigned
+ * the result to the first one.
+ *
+ * @returns pValue1Result.
+ * @param pValue1Result The first value and result.
+ * @param pValue2 The second value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignAnd(PRTUINT128U pValue1Result, PCRTUINT128U pValue2)
+{
+#if ARCH_BITS >= 64
+ pValue1Result->s.Hi &= pValue2->s.Hi;
+ pValue1Result->s.Lo &= pValue2->s.Lo;
+#else
+ pValue1Result->DWords.dw0 &= pValue2->DWords.dw0;
+ pValue1Result->DWords.dw1 &= pValue2->DWords.dw1;
+ pValue1Result->DWords.dw2 &= pValue2->DWords.dw2;
+ pValue1Result->DWords.dw3 &= pValue2->DWords.dw3;
+#endif
+ return pValue1Result;
+}
+
+
+/**
+ * Performs a bitwise AND of a 128-bit unsigned integer value and a mask made
+ * up of the first N bits, assigning the result to the the 128-bit value.
+ *
+ * @returns pValueResult.
+ * @param pValueResult The value and result.
+ * @param cBits The number of bits to AND (counting from the first
+ * bit).
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignAndNFirstBits(PRTUINT128U pValueResult, unsigned cBits)
+{
+ if (cBits <= 64)
+ {
+ if (cBits != 64)
+ pValueResult->s.Lo &= (RT_BIT_64(cBits) - 1);
+ pValueResult->s.Hi = 0;
+ }
+ else if (cBits < 128)
+ pValueResult->s.Hi &= (RT_BIT_64(cBits - 64) - 1);
+/** @todo #if ARCH_BITS >= 64 */
+ return pValueResult;
+}
+
+
+/**
+ * Performs a bitwise OR of two 128-bit unsigned integer values and assigned
+ * the result to the first one.
+ *
+ * @returns pValue1Result.
+ * @param pValue1Result The first value and result.
+ * @param pValue2 The second value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignOr(PRTUINT128U pValue1Result, PCRTUINT128U pValue2)
+{
+#if ARCH_BITS >= 64
+ pValue1Result->s.Hi |= pValue2->s.Hi;
+ pValue1Result->s.Lo |= pValue2->s.Lo;
+#else
+ pValue1Result->DWords.dw0 |= pValue2->DWords.dw0;
+ pValue1Result->DWords.dw1 |= pValue2->DWords.dw1;
+ pValue1Result->DWords.dw2 |= pValue2->DWords.dw2;
+ pValue1Result->DWords.dw3 |= pValue2->DWords.dw3;
+#endif
+ return pValue1Result;
+}
+
+
+/**
+ * Performs a bitwise XOR of two 128-bit unsigned integer values and assigned
+ * the result to the first one.
+ *
+ * @returns pValue1Result.
+ * @param pValue1Result The first value and result.
+ * @param pValue2 The second value.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignXor(PRTUINT128U pValue1Result, PCRTUINT128U pValue2)
+{
+#if ARCH_BITS >= 64
+ pValue1Result->s.Hi ^= pValue2->s.Hi;
+ pValue1Result->s.Lo ^= pValue2->s.Lo;
+#else
+ pValue1Result->DWords.dw0 ^= pValue2->DWords.dw0;
+ pValue1Result->DWords.dw1 ^= pValue2->DWords.dw1;
+ pValue1Result->DWords.dw2 ^= pValue2->DWords.dw2;
+ pValue1Result->DWords.dw3 ^= pValue2->DWords.dw3;
+#endif
+ return pValue1Result;
+}
+
+
+/**
+ * Performs a bitwise left shift on a 128-bit unsigned integer value, assigning
+ * the result to it.
+ *
+ * @returns pValue1Result.
+ * @param pValue1Result The first value and result.
+ * @param cBits The number of bits to shift.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignShiftLeft(PRTUINT128U pValueResult, int cBits)
+{
+ RTUINT128U const InVal = *pValueResult;
+/** @todo #if ARCH_BITS >= 64 */
+ if (cBits > 0)
+ {
+ /* (left shift) */
+ if (cBits >= 128)
+ RTUInt128SetZero(pValueResult);
+ else if (cBits >= 64)
+ {
+ pValueResult->s.Lo = 0;
+ pValueResult->s.Hi = InVal.s.Lo << (cBits - 64);
+ }
+ else
+ {
+ pValueResult->s.Hi = InVal.s.Hi << cBits;
+ pValueResult->s.Hi |= InVal.s.Lo >> (64 - cBits);
+ pValueResult->s.Lo = InVal.s.Lo << cBits;
+ }
+ }
+ else if (cBits < 0)
+ {
+ /* (right shift) */
+ cBits = -cBits;
+ if (cBits >= 128)
+ RTUInt128SetZero(pValueResult);
+ else if (cBits >= 64)
+ {
+ pValueResult->s.Hi = 0;
+ pValueResult->s.Lo = InVal.s.Hi >> (cBits - 64);
+ }
+ else
+ {
+ pValueResult->s.Lo = InVal.s.Lo >> cBits;
+ pValueResult->s.Lo |= InVal.s.Hi << (64 - cBits);
+ pValueResult->s.Hi = InVal.s.Hi >> cBits;
+ }
+ }
+ return pValueResult;
+}
+
+
+/**
+ * Performs a bitwise left shift on a 128-bit unsigned integer value, assigning
+ * the result to it.
+ *
+ * @returns pValue1Result.
+ * @param pValue1Result The first value and result.
+ * @param cBits The number of bits to shift.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignShiftRight(PRTUINT128U pValueResult, int cBits)
+{
+ return RTUInt128AssignShiftLeft(pValueResult, -cBits);
+}
+
+
+/**
+ * Performs a bitwise NOT on a 128-bit unsigned integer value, assigning the
+ * result to it.
+ *
+ * @returns pValueResult
+ * @param pValueResult The value and result.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignBitwiseNot(PRTUINT128U pValueResult)
+{
+#if ARCH_BITS >= 64
+ pValueResult->s.Hi = ~pValueResult->s.Hi;
+ pValueResult->s.Lo = ~pValueResult->s.Lo;
+#else
+ pValueResult->DWords.dw0 = ~pValueResult->DWords.dw0;
+ pValueResult->DWords.dw1 = ~pValueResult->DWords.dw1;
+ pValueResult->DWords.dw2 = ~pValueResult->DWords.dw2;
+ pValueResult->DWords.dw3 = ~pValueResult->DWords.dw3;
+#endif
+ return pValueResult;
+}
+
+
+/**
+ * Performs a boolean NOT on a 128-bit unsigned integer value, assigning the
+ * result to it.
+ *
+ * @returns pValueResult
+ * @param pValueResult The value and result.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128AssignBooleanNot(PRTUINT128U pValueResult)
+{
+ return RTUInt128AssignBoolean(pValueResult, RTUInt128IsZero(pValueResult));
+}
+
+
+/**
+ * Compares two 128-bit unsigned integer values.
+ *
+ * @retval 0 if equal.
+ * @retval -1 if the first value is smaller than the second.
+ * @retval 1 if the first value is larger than the second.
+ *
+ * @param pValue1 The first value.
+ * @param pValue2 The second value.
+ */
+DECLINLINE(int) RTUInt128Compare(PCRTUINT128U pValue1, PCRTUINT128U pValue2)
+{
+#if ARCH_BITS >= 64
+ if (pValue1->s.Hi != pValue2->s.Hi)
+ return pValue1->s.Hi > pValue2->s.Hi ? 1 : -1;
+ if (pValue1->s.Lo != pValue2->s.Lo)
+ return pValue1->s.Lo > pValue2->s.Lo ? 1 : -1;
+ return 0;
+#else
+ if (pValue1->DWords.dw0 != pValue2->DWords.dw0)
+ return pValue1->DWords.dw0 > pValue2->DWords.dw0 ? 1 : -1;
+ if (pValue1->DWords.dw1 != pValue2->DWords.dw1)
+ return pValue1->DWords.dw1 > pValue2->DWords.dw1 ? 1 : -1;
+ if (pValue1->DWords.dw2 != pValue2->DWords.dw2)
+ return pValue1->DWords.dw2 > pValue2->DWords.dw2 ? 1 : -1;
+ if (pValue1->DWords.dw3 != pValue2->DWords.dw3)
+ return pValue1->DWords.dw3 > pValue2->DWords.dw3 ? 1 : -1;
+ return 0;
+#endif
+}
+
+
+/**
+ * Tests if two 128-bit unsigned integer values not equal.
+ *
+ * @returns true if equal, false if not equal.
+ * @param pValue1 The first value.
+ * @param pValue2 The second value.
+ */
+DECLINLINE(bool) RTUInt128IsEqual(PCRTUINT128U pValue1, PCRTUINT128U pValue2)
+{
+#if ARCH_BITS >= 64
+ return pValue1->s.Hi == pValue2->s.Hi
+ && pValue1->s.Lo == pValue2->s.Lo;
+#else
+ return pValue1->DWords.dw0 == pValue2->DWords.dw0
+ && pValue1->DWords.dw1 == pValue2->DWords.dw1
+ && pValue1->DWords.dw2 == pValue2->DWords.dw2
+ && pValue1->DWords.dw3 == pValue2->DWords.dw3;
+#endif
+}
+
+
+/**
+ * Tests if two 128-bit unsigned integer values are not equal.
+ *
+ * @returns true if not equal, false if equal.
+ * @param pValue1 The first value.
+ * @param pValue2 The second value.
+ */
+DECLINLINE(bool) RTUInt128IsNotEqual(PCRTUINT128U pValue1, PCRTUINT128U pValue2)
+{
+ return !RTUInt128IsEqual(pValue1, pValue2);
+}
+
+
+/**
+ * Sets a bit in a 128-bit unsigned integer type.
+ *
+ * @returns pValueResult.
+ * @param pValueResult The input and output value.
+ * @param iBit The bit to set.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128BitSet(PRTUINT128U pValueResult, unsigned iBit)
+{
+ if (iBit < 64)
+ {
+#if ARCH_BITS >= 64
+ pValueResult->s.Lo |= RT_BIT_64(iBit);
+#else
+ if (iBit < 32)
+ pValueResult->DWords.dw0 |= RT_BIT_32(iBit);
+ else
+ pValueResult->DWords.dw1 |= RT_BIT_32(iBit - 32);
+#endif
+ }
+ else if (iBit < 128)
+ {
+#if ARCH_BITS >= 64
+ pValueResult->s.Hi |= RT_BIT_64(iBit - 64);
+#else
+ if (iBit < 96)
+ pValueResult->DWords.dw2 |= RT_BIT_32(iBit - 64);
+ else
+ pValueResult->DWords.dw3 |= RT_BIT_32(iBit - 96);
+#endif
+ }
+ return pValueResult;
+}
+
+
+/**
+ * Sets a bit in a 128-bit unsigned integer type.
+ *
+ * @returns pValueResult.
+ * @param pValueResult The input and output value.
+ * @param iBit The bit to set.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128BitClear(PRTUINT128U pValueResult, unsigned iBit)
+{
+ if (iBit < 64)
+ {
+#if ARCH_BITS >= 64
+ pValueResult->s.Lo &= ~RT_BIT_64(iBit);
+#else
+ if (iBit < 32)
+ pValueResult->DWords.dw0 &= ~RT_BIT_32(iBit);
+ else
+ pValueResult->DWords.dw1 &= ~RT_BIT_32(iBit - 32);
+#endif
+ }
+ else if (iBit < 128)
+ {
+#if ARCH_BITS >= 64
+ pValueResult->s.Hi &= ~RT_BIT_64(iBit - 64);
+#else
+ if (iBit < 96)
+ pValueResult->DWords.dw2 &= ~RT_BIT_32(iBit - 64);
+ else
+ pValueResult->DWords.dw3 &= ~RT_BIT_32(iBit - 96);
+#endif
+ }
+ return pValueResult;
+}
+
+
+/**
+ * Tests if a bit in a 128-bit unsigned integer value is set.
+ *
+ * @returns pValueResult.
+ * @param pValueResult The input and output value.
+ * @param iBit The bit to test.
+ */
+DECLINLINE(bool) RTUInt128BitTest(PRTUINT128U pValueResult, unsigned iBit)
+{
+ bool fRc;
+ if (iBit < 64)
+ {
+#if ARCH_BITS >= 64
+ fRc = RT_BOOL(pValueResult->s.Lo & RT_BIT_64(iBit));
+#else
+ if (iBit < 32)
+ fRc = RT_BOOL(pValueResult->DWords.dw0 & RT_BIT_32(iBit));
+ else
+ fRc = RT_BOOL(pValueResult->DWords.dw1 & RT_BIT_32(iBit - 32));
+#endif
+ }
+ else if (iBit < 128)
+ {
+#if ARCH_BITS >= 64
+ fRc = RT_BOOL(pValueResult->s.Hi & RT_BIT_64(iBit - 64));
+#else
+ if (iBit < 96)
+ fRc = RT_BOOL(pValueResult->DWords.dw2 & RT_BIT_32(iBit - 64));
+ else
+ fRc = RT_BOOL(pValueResult->DWords.dw3 & RT_BIT_32(iBit - 96));
+#endif
+ }
+ else
+ fRc = false;
+ return fRc;
+}
+
+
+/**
+ * Set a range of bits a 128-bit unsigned integer value.
+ *
+ * @returns pValueResult.
+ * @param pValueResult The input and output value.
+ * @param iFirstBit The first bit to test.
+ * @param cBits The number of bits to set.
+ */
+DECLINLINE(PRTUINT128U) RTUInt128BitSetRange(PRTUINT128U pValueResult, unsigned iFirstBit, unsigned cBits)
+{
+ /* bounds check & fix. */
+ if (iFirstBit < 128)
+ {
+ if (iFirstBit + cBits > 128)
+ cBits = 128 - iFirstBit;
+
+#if ARCH_BITS >= 64
+ if (iFirstBit + cBits < 64)
+ pValueResult->s.Lo |= (RT_BIT_64(cBits) - 1) << iFirstBit;
+ else if (iFirstBit + cBits < 128 && iFirstBit >= 64)
+ pValueResult->s.Hi |= (RT_BIT_64(cBits) - 1) << (iFirstBit - 64);
+ else
+#else
+ if (iFirstBit + cBits < 32)
+ pValueResult->DWords.dw0 |= (RT_BIT_32(cBits) - 1) << iFirstBit;
+ else if (iFirstBit + cBits < 64 && iFirstBit >= 32)
+ pValueResult->DWords.dw1 |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 32);
+ else if (iFirstBit + cBits < 96 && iFirstBit >= 64)
+ pValueResult->DWords.dw2 |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 64);
+ else if (iFirstBit + cBits < 128 && iFirstBit >= 96)
+ pValueResult->DWords.dw3 |= (RT_BIT_32(cBits) - 1) << (iFirstBit - 96);
+ else
+#endif
+ while (cBits-- > 0)
+ RTUInt128BitSet(pValueResult, iFirstBit++);
+ }
+ return pValueResult;
+}
+
+
+/**
+ * Test if all the bits of a 128-bit unsigned integer value are set.
+ *
+ * @returns true if they are, false if they aren't.
+ * @param pValue The input and output value.
+ */
+DECLINLINE(bool) RTUInt128BitAreAllSet(PRTUINT128U pValue)
+{
+#if ARCH_BITS >= 64
+ return pValue->s.Hi == UINT64_MAX
+ && pValue->s.Lo == UINT64_MAX;
+#else
+ return pValue->DWords.dw0 == UINT32_MAX
+ && pValue->DWords.dw1 == UINT32_MAX
+ && pValue->DWords.dw2 == UINT32_MAX
+ && pValue->DWords.dw3 == UINT32_MAX;
+#endif
+}
+
+
+/**
+ * Test if all the bits of a 128-bit unsigned integer value are clear.
+ *
+ * @returns true if they are, false if they aren't.
+ * @param pValue The input and output value.
+ */
+DECLINLINE(bool) RTUInt128BitAreAllClear(PRTUINT128U pValue)
+{
+#if ARCH_BITS >= 64
+ return pValue->s.Hi == 0
+ && pValue->s.Lo == 0;
+#else
+ return pValue->DWords.dw0 == 0
+ && pValue->DWords.dw1 == 0
+ && pValue->DWords.dw2 == 0
+ && pValue->DWords.dw3 == 0;
+#endif
+}
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/uni.h b/include/iprt/uni.h
new file mode 100644
index 00000000..6f0c23ec
--- /dev/null
+++ b/include/iprt/uni.h
@@ -0,0 +1,397 @@
+/** @file
+ * IPRT - Unicode Code Points.
+ */
+
+/*
+ * 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 ___iprt_uni_h
+#define ___iprt_uni_h
+
+/** @defgroup grp_rt_uni RTUniCp - Unicode Code Points
+ * @ingroup grp_rt
+ * @{
+ */
+
+/** @def RTUNI_USE_WCTYPE
+ * Define RTUNI_USE_WCTYPE to not use the IPRT unicode data but the
+ * data which the C runtime library provides. */
+#ifdef DOXYGEN_RUNNING
+# define RTUNI_USE_WCTYPE
+#endif
+
+#include <iprt/types.h>
+#ifdef RTUNI_USE_WCTYPE
+# include <wctype.h>
+#endif
+
+RT_C_DECLS_BEGIN
+
+
+
+#ifndef RTUNI_USE_WCTYPE
+/**
+ * A unicode flags range.
+ * @internal
+ */
+typedef struct RTUNIFLAGSRANGE
+{
+ /** The first code point of the range. */
+ RTUNICP BeginCP;
+ /** The last + 1 code point of the range. */
+ RTUNICP EndCP;
+ /** Pointer to the array of case folded code points. */
+ const uint8_t *pafFlags;
+} RTUNIFLAGSRANGE;
+/** Pointer to a flags range.
+ * @internal */
+typedef RTUNIFLAGSRANGE *PRTUNIFLAGSRANGE;
+/** Pointer to a const flags range.
+ * @internal */
+typedef const RTUNIFLAGSRANGE *PCRTUNIFLAGSRANGE;
+
+/**
+ * A unicode case folded range.
+ * @internal
+ */
+typedef struct RTUNICASERANGE
+{
+ /** The first code point of the range. */
+ RTUNICP BeginCP;
+ /** The last + 1 code point of the range. */
+ RTUNICP EndCP;
+ /** Pointer to the array of case folded code points. */
+ PCRTUNICP paFoldedCPs;
+} RTUNICASERANGE;
+/** Pointer to a case folded range.
+ * @internal */
+typedef RTUNICASERANGE *PRTUNICASERANGE;
+/** Pointer to a const case folded range.
+ * @internal */
+typedef const RTUNICASERANGE *PCRTUNICASERANGE;
+
+/** @name Unicode Code Point Flags.
+ * @internal
+ * @{ */
+#define RTUNI_UPPER RT_BIT(0)
+#define RTUNI_LOWER RT_BIT(1)
+#define RTUNI_ALPHA RT_BIT(2)
+#define RTUNI_XDIGIT RT_BIT(3)
+#define RTUNI_DDIGIT RT_BIT(4)
+#define RTUNI_WSPACE RT_BIT(5)
+/*#define RTUNI_BSPACE RT_BIT(6) - later */
+/** When set, the codepoint requires further checking wrt NFC and NFD
+ * normalization. I.e. set when either of QC_NFD and QC_NFC are not Y. */
+#define RTUNI_QC_NFX RT_BIT(7)
+/** @} */
+
+
+/**
+ * Array of flags ranges.
+ * @internal
+ */
+extern RTDATADECL(const RTUNIFLAGSRANGE) g_aRTUniFlagsRanges[];
+
+/**
+ * Gets the flags for a unicode code point.
+ *
+ * @returns The flag mask. (RTUNI_*)
+ * @param CodePoint The unicode code point.
+ * @internal
+ */
+DECLINLINE(RTUNICP) rtUniCpFlags(RTUNICP CodePoint)
+{
+ PCRTUNIFLAGSRANGE pCur = &g_aRTUniFlagsRanges[0];
+ do
+ {
+ if (pCur->EndCP > CodePoint)
+ {
+ if (pCur->BeginCP <= CodePoint)
+ return pCur->pafFlags[CodePoint - pCur->BeginCP];
+ break;
+ }
+ pCur++;
+ } while (pCur->EndCP != RTUNICP_MAX);
+ return 0;
+}
+
+
+/**
+ * Checks if a unicode code point is upper case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsUpper(RTUNICP CodePoint)
+{
+ return (rtUniCpFlags(CodePoint) & RTUNI_UPPER) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is lower case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsLower(RTUNICP CodePoint)
+{
+ return (rtUniCpFlags(CodePoint) & RTUNI_LOWER) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is alphabetic.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsAlphabetic(RTUNICP CodePoint)
+{
+ return (rtUniCpFlags(CodePoint) & RTUNI_ALPHA) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is a decimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsDecDigit(RTUNICP CodePoint)
+{
+ return (rtUniCpFlags(CodePoint) & RTUNI_DDIGIT) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is a hexadecimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsHexDigit(RTUNICP CodePoint)
+{
+ return (rtUniCpFlags(CodePoint) & RTUNI_XDIGIT) != 0;
+}
+
+
+/**
+ * Checks if a unicode code point is white space.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsSpace(RTUNICP CodePoint)
+{
+ return (rtUniCpFlags(CodePoint) & RTUNI_WSPACE) != 0;
+}
+
+
+
+/**
+ * Array of uppercase ranges.
+ * @internal
+ */
+extern RTDATADECL(const RTUNICASERANGE) g_aRTUniUpperRanges[];
+
+/**
+ * Array of lowercase ranges.
+ * @internal
+ */
+extern RTDATADECL(const RTUNICASERANGE) g_aRTUniLowerRanges[];
+
+
+/**
+ * Folds a unicode code point using the specified range array.
+ *
+ * @returns FOlded code point.
+ * @param CodePoint The unicode code point to fold.
+ * @param pCur The case folding range to use.
+ */
+DECLINLINE(RTUNICP) rtUniCpFold(RTUNICP CodePoint, PCRTUNICASERANGE pCur)
+{
+ do
+ {
+ if (pCur->EndCP > CodePoint)
+ {
+ if (pCur->BeginCP <= CodePoint)
+ CodePoint = pCur->paFoldedCPs[CodePoint - pCur->BeginCP];
+ break;
+ }
+ pCur++;
+ } while (pCur->EndCP != RTUNICP_MAX);
+ return CodePoint;
+}
+
+
+/**
+ * Folds a unicode code point to upper case.
+ *
+ * @returns Folded code point.
+ * @param CodePoint The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToUpper(RTUNICP CodePoint)
+{
+ return rtUniCpFold(CodePoint, &g_aRTUniUpperRanges[0]);
+}
+
+
+/**
+ * Folds a unicode code point to lower case.
+ *
+ * @returns Folded code point.
+ * @param CodePoint The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToLower(RTUNICP CodePoint)
+{
+ return rtUniCpFold(CodePoint, &g_aRTUniLowerRanges[0]);
+}
+
+
+#else /* RTUNI_USE_WCTYPE */
+
+
+/**
+ * Checks if a unicode code point is upper case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsUpper(RTUNICP CodePoint)
+{
+ return !!iswupper(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is lower case.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsLower(RTUNICP CodePoint)
+{
+ return !!iswlower(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is alphabetic.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsAlphabetic(RTUNICP CodePoint)
+{
+ return !!iswalpha(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is a decimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsDecDigit(RTUNICP CodePoint)
+{
+ return !!iswdigit(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is a hexadecimal digit.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsHexDigit(RTUNICP CodePoint)
+{
+ return !!iswxdigit(CodePoint);
+}
+
+
+/**
+ * Checks if a unicode code point is white space.
+ *
+ * @returns true if it is.
+ * @returns false if it isn't.
+ * @param CodePoint The code point.
+ */
+DECLINLINE(bool) RTUniCpIsSpace(RTUNICP CodePoint)
+{
+ return !!iswspace(CodePoint);
+}
+
+
+/**
+ * Folds a unicode code point to upper case.
+ *
+ * @returns Folded code point.
+ * @param CodePoint The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToUpper(RTUNICP CodePoint)
+{
+ return towupper(CodePoint);
+}
+
+
+/**
+ * Folds a unicode code point to lower case.
+ *
+ * @returns Folded code point.
+ * @param CodePoint The unicode code point to fold.
+ */
+DECLINLINE(RTUNICP) RTUniCpToLower(RTUNICP CodePoint)
+{
+ return towlower(CodePoint);
+}
+
+
+#endif /* RTUNI_USE_WCTYPE */
+
+
+/**
+ * Frees a unicode string.
+ *
+ * @param pusz The string to free.
+ */
+RTDECL(void) RTUniFree(PRTUNICP pusz);
+
+
+RT_C_DECLS_END
+/** @} */
+
+
+#endif
+
diff --git a/include/iprt/uri.h b/include/iprt/uri.h
new file mode 100644
index 00000000..5696e5ae
--- /dev/null
+++ b/include/iprt/uri.h
@@ -0,0 +1,157 @@
+/** @file
+ * IPRT - Uniform Resource Identifier handling.
+ */
+
+/*
+ * 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 ___iprt_uri_h
+#define ___iprt_uri_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_uri RTUri - Uri parsing and creation
+ * URI parsing and creation based on RFC 3986.
+ * See http://datatracker.ietf.org/doc/rfc3986/ for the full specification.
+ * @note Currently it isn't the full specification implemented.
+ * @note Currently only some generic URI support and a minimum File(file:) URI
+ * support is implemented. Other specific scheme support, like html:, ldap:,
+ * data:, ..., is missing.
+ * @see grp_rt_uri_file
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Creates a generic URI.
+ *
+ * @returns the new URI on success, NULL otherwise.
+ * @param pszScheme The URI scheme.
+ * @param pszAuthority The authority part of the URI (optional).
+ * @param pszPath The path part of the URI (optional).
+ * @param pszQuery The query part of the URI (optional).
+ * @param pszFragment The fragment part of the URI (optional).
+ */
+RTR3DECL(char *) RTUriCreate(const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery, const char *pszFragment);
+
+/**
+ * Check an string for a specific URI scheme.
+ *
+ * @returns true if the scheme match, false if not.
+ * @param pszUri The URI to check.
+ * @param pszScheme The scheme to compare with.
+ */
+RTR3DECL(bool) RTUriHasScheme(const char *pszUri, const char *pszScheme);
+
+/**
+ * Extract the scheme out of an URI.
+ *
+ * @returns the scheme if the URI is valid, NULL otherwise.
+ * @param pszUri The URI to extract from.
+ */
+RTR3DECL(char *) RTUriScheme(const char *pszUri);
+
+/**
+ * Extract the authority out of an URI.
+ *
+ * @returns the authority if the URI contains one, NULL otherwise.
+ * @param pszUri The URI to extract from.
+ */
+RTR3DECL(char *) RTUriAuthority(const char *pszUri);
+
+/**
+ * Extract the path out of an URI.
+ *
+ * @returns the path if the URI contains one, NULL otherwise.
+ * @param pszUri The URI to extract from.
+ */
+RTR3DECL(char *) RTUriPath(const char *pszUri);
+
+/**
+ * Extract the query out of an URI.
+ *
+ * @returns the query if the URI contains one, NULL otherwise.
+ * @param pszUri The URI to extract from.
+ */
+RTR3DECL(char *) RTUriQuery(const char *pszUri);
+
+/**
+ * Extract the fragment out of an URI.
+ *
+ * @returns the fragment if the URI contains one, NULL otherwise.
+ * @param pszUri The URI to extract from.
+ */
+RTR3DECL(char *) RTUriFragment(const char *pszUri);
+
+/** @defgroup grp_rt_uri_file RTUriFile - Uri file parsing and creation
+ * Adds file: scheme support to the generic RTUri interface. This is partly
+ * documented in http://datatracker.ietf.org/doc/rfc1738/.
+ * @ingroup grp_rt_uri
+ * @{
+ */
+
+/** Auto detect in which format a path is returned. */
+#define URI_FILE_FORMAT_AUTO UINT32_C(0)
+/** Return a path in UNIX format style. */
+#define URI_FILE_FORMAT_UNIX UINT32_C(1)
+/** Return a path in Windows format style. */
+#define URI_FILE_FORMAT_WIN UINT32_C(2)
+
+/**
+ * Creates a file URI.
+ *
+ * @see RTUriCreate
+ *
+ * @returns the new URI on success, NULL otherwise.
+ * @param pszPath The path of the URI.
+ */
+RTR3DECL(char *) RTUriFileCreate(const char *pszPath);
+
+/**
+ * Returns the file path encoded in the URI.
+ *
+ * @returns the path if the URI contains one, NULL otherwise.
+ * @param pszUri The URI to extract from.
+ * @param uFormat In which format should the path returned.
+ */
+RTR3DECL(char *) RTUriFilePath(const char *pszUri, uint32_t uFormat);
+
+/**
+ * Returns the file path encoded in the URI, given a max string length.
+ *
+ * @returns the path if the URI contains one, NULL otherwise.
+ * @param pszUri The URI to extract from.
+ * @param uFormat In which format should the path returned.
+ * @param cbMax The max string length to inspect.
+ */
+RTR3DECL(char *) RTUriFileNPath(const char *pszUri, uint32_t uFormat, size_t cchMax);
+
+/** @} */
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/uuid.h b/include/iprt/uuid.h
new file mode 100644
index 00000000..94604e2b
--- /dev/null
+++ b/include/iprt/uuid.h
@@ -0,0 +1,185 @@
+/** @file
+ * IPRT - Universal Unique Identifiers (UUID).
+ */
+
+/*
+ * 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 ___iprt_uuid_h
+#define ___iprt_uuid_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_uuid RTUuid - Universally Unique Identifiers
+ * @ingroup grp_rt
+ * @{
+ */
+
+/**
+ * Generates new UUID value.
+ *
+ * @note IPRT uses little endian byte ordering in the UUID integer fields. If
+ * you want to pass IPRT UUIDs in binary representation to other UUID libraries
+ * and expect to get exactly the same string representation as in IPRT, you
+ * need to convert the first three integer fields (one 32 bit value, two 16 bit
+ * values) separately to big endian (also called network byte order).
+ *
+ * @sa RTUUID::Gen
+ *
+ * @returns iprt status code.
+ * @param pUuid Where to store generated uuid.
+ */
+RTDECL(int) RTUuidCreate(PRTUUID pUuid);
+
+/**
+ * Makes null UUID value.
+ *
+ * @returns iprt status code.
+ * @param pUuid Where to store generated null uuid.
+ */
+RTDECL(int) RTUuidClear(PRTUUID pUuid);
+
+/**
+ * Checks if UUID is null.
+ *
+ * @returns true if UUID is null.
+ * @param pUuid uuid to check.
+ */
+RTDECL(bool) RTUuidIsNull(PCRTUUID pUuid);
+
+/**
+ * Compares two UUID values.
+ *
+ * @returns 0 if eq, < 0 or > 0.
+ * @param pUuid1 First value to compare. NULL is treated like if
+ * RTUuidIsNull() return true.
+ * @param pUuid2 Second value to compare. NULL is treated like if
+ * RTUuidIsNull() return true.
+ */
+RTDECL(int) RTUuidCompare(PCRTUUID pUuid1, PCRTUUID pUuid2);
+
+/**
+ * Compares a UUID value with a UUID string.
+ *
+ * @note IPRT uses little endian byte ordering in the UUID integer fields. If
+ * you want to pass IPRT UUIDs in binary representation to other UUID libraries
+ * and expect to get exactly the same string representation as in IPRT, you need
+ * to convert the first three integer fields (one 32 bit value, two 16 bit
+ * values) separately to big endian (also called network byte order).
+ * Correspondingly, if you want to get the right result with UUIDs which are in
+ * big endian format, you need to convert them before using this function.
+ *
+ * @sa RTUUID::Gen
+ *
+ * @returns 0 if eq, < 0 or > 0.
+ * @param pUuid1 First value to compare. NULL is not allowed.
+ * @param pszString2 The 2nd UUID in string form. NULL or malformed
+ * string is not permitted.
+ */
+RTDECL(int) RTUuidCompareStr(PCRTUUID pUuid1, const char *pszString2);
+
+/**
+ * Compares two UUID strings.
+ *
+ * @returns 0 if eq, < 0 or > 0.
+ * @param pszString1 The 1st UUID in string from. NULL or malformed
+ * string is not permitted.
+ * @param pszString2 The 2nd UUID in string form. NULL or malformed
+ * string is not permitted.
+ */
+RTDECL(int) RTUuidCompare2Strs(const char *pszString1, const char *pszString2);
+
+/**
+ * Converts binary UUID to its string representation.
+ *
+ * @note IPRT uses little endian byte ordering in the UUID integer fields. If
+ * you want to pass IPRT UUIDs in binary representation to other UUID libraries
+ * and expect to get exactly the same string representation as in IPRT, you
+ * need to convert the first three integer fields (one 32 bit value, two 16 bit
+ * values) separately to big endian (also called network byte order).
+ * Correspondingly, if you want to get the right result with UUIDs which are in
+ * big endian format, you need to convert them before using this function.
+ *
+ * @sa RTUUID::Gen
+ *
+ * @returns iprt status code.
+ * @param pUuid Uuid to convert.
+ * @param pszString Where to store result string.
+ * @param cchString pszString buffer length, must be >= RTUUID_STR_LENGTH.
+ */
+RTDECL(int) RTUuidToStr(PCRTUUID pUuid, char *pszString, size_t cchString);
+
+/**
+ * Converts UUID from its string representation to binary format.
+ *
+ * @note IPRT uses little endian byte ordering in the UUID integer fields. If
+ * you want to pass IPRT UUIDs in binary representation to other UUID libraries
+ * and expect to get exactly the same string representation as in IPRT, you
+ * need to convert the first three integer fields (one 32 bit value, two 16 bit
+ * values) separately to big endian (also called network byte order).
+ * Correspondingly, if you want to get the right result with UUIDs which are in
+ * big endian format, you need to convert them before using this function.
+ *
+ * @sa RTUUID::Gen
+ *
+ * @returns iprt status code.
+ * @param pUuid Where to store result Uuid.
+ * @param pszString String with UUID text data.
+ */
+RTDECL(int) RTUuidFromStr(PRTUUID pUuid, const char *pszString);
+
+/**
+ * Converts binary UUID to its UTF-16 string representation.
+ *
+ * @note See note in RTUuidToStr.
+ *
+ * @sa RTUUID::Gen
+ *
+ * @returns iprt status code.
+ * @param pUuid Uuid to convert.
+ * @param pwszString Where to store result string.
+ * @param cwcString pszString buffer length, must be >=
+ * RTUUID_STR_LENGTH.
+ */
+RTDECL(int) RTUuidToUtf16(PCRTUUID pUuid, PRTUTF16 pwszString, size_t cwcString);
+
+/**
+ * Converts UUID from its UTF-16 string representation to binary format.
+ *
+ * @note See note in RTUuidFromStr.
+ *
+ * @sa RTUUID::Gen
+ *
+ * @returns iprt status code.
+ * @param pUuid Where to store result Uuid.
+ * @param pwszString String with UUID text data.
+ */
+RTDECL(int) RTUuidFromUtf16(PRTUUID pUuid, PCRTUTF16 pwszString);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+
diff --git a/include/iprt/vector.h b/include/iprt/vector.h
new file mode 100644
index 00000000..797fe192
--- /dev/null
+++ b/include/iprt/vector.h
@@ -0,0 +1,375 @@
+/** @file
+ * IPRT - Vector
+ * STL-inspired vector implementation in C
+ */
+
+/*
+ * 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.
+ */
+
+/**
+ * @todo the right Doxygen tag here
+ * This file defines a set of macros which provide a functionality and an
+ * interface roughly similar to the C++ STL vector container. To create a
+ * vector of a particular type one must first explicitly instantiate such a
+ * vector in the source file, e.g.
+ * RTVEC_DECL(TopLevels, Window *)
+ * without a semi-colon. This macro will define a structure (struct TopLevels)
+ * which contains a dynamically resizeable array of Window * elements. It
+ * will also define a number of inline methods for manipulating the structure,
+ * such as
+ * Window *TopLevelsPushBack(struct TopLevels *)
+ * which adds a new element to the end of the array and returns it, optionally
+ * reallocating the array if there is not enough space for the new element.
+ * (This particular method prototype differs from the STL equivalent -
+ * push_back - more than most of the other methods).
+ *
+ * To create a vector, one simply needs to declare the structure, in this case
+ * struct TopLevels = RTVEC_INITIALIZER;
+ *
+ * There are various other macros for declaring vectors with different
+ * allocators (e.g. RTVEC_DECL_ALLOCATOR) or with clean-up functions
+ * (e.g. RTVEC_DECL_DELETE). See the descriptions of the generic methods and
+ * the declarator macros below.
+ *
+ * One particular use of vectors is to assemble an array of a particular type
+ * in heap memory without knowing - or counting - the number of elements in
+ * advance. To do this, add the elements onto the array using PushBack, then
+ * extract the array from the vector using the (non-STL) Detach method.
+ *
+ * @note functions in this file are inline to prevent warnings about
+ * unused static functions. I assume that in this day and age a
+ * compiler makes its own decisions about whether to actually
+ * inline a function.
+ * @note since vector structures must be explicitly instanciated unlike the
+ * C++ vector template, care must be taken not to instanciate a
+ * particular type twice, e.g. once in a header and once in a code file.
+ * Only using vectors in code files and keeping them out of interfaces
+ * (or passing them as anonymously) makes it easier to take care of this.
+ */
+#ifndef ___iprt_vector_h
+# define ___iprt_vector_h
+
+/*******************************************************************************
+* Header Files *
+*******************************************************************************/
+
+#include <iprt/assert.h>
+#include <iprt/cdefs.h>
+#include <iprt/err.h>
+#include <iprt/mem.h> /** @todo Should the caller include this if they need
+ * it? */
+
+
+/**
+ * Generic vector structure
+ */
+/** @todo perhaps we should include an additional member for a parameter to
+ * three-argument reallocators, so that we can support e.g. mempools? */
+#define RTVEC_DECL_STRUCT(name, type) \
+struct name \
+{ \
+ /** The number of elements in the vector */ \
+ size_t mcElements; \
+ /** The current capacity of the vector */ \
+ size_t mcCapacity; \
+ /** The elements themselves */ \
+ type *mpElements; \
+};
+
+/** Initialiser for an empty vector structure */
+#define RTVEC_INITIALIZER { 0, 0, NULL }
+
+/** The unit by which the vector capacity is increased */
+#define RTVECIMPL_ALLOC_UNIT 16
+
+/**
+ * Generic method - get the size of a vector
+ */
+/** @todo What is the correct way to do doxygen for this sort of macro? */
+#define RTVEC_DECLFN_SIZE(name, type) \
+DECLINLINE(size_t) name ## Size(struct name *pVec) \
+{ \
+ return(pVec->mcElements); \
+}
+
+/**
+ * Generic method - expand a vector
+ */
+#define RTVEC_DECLFN_RESERVE(name, type, pfnRealloc) \
+DECLINLINE(int) name ## Reserve(struct name *pVec, size_t cNewCapacity) \
+{ \
+ void *pvNew; \
+ \
+ if (cNewCapacity <= pVec->mcCapacity) \
+ return VINF_SUCCESS; \
+ pvNew = pfnRealloc(pVec->mpElements, cNewCapacity * sizeof(type)); \
+ if (!pvNew) \
+ return VERR_NO_MEMORY; \
+ pVec->mcCapacity = cNewCapacity; \
+ pVec->mpElements = (type *)pvNew; \
+ return VINF_SUCCESS; \
+}
+
+/**
+ * Generic method - return a pointer to the first element in the vector.
+ */
+#define RTVEC_DECLFN_BEGIN(name, type) \
+DECLINLINE(type *) name ## Begin(struct name *pVec) \
+{ \
+ return(pVec->mpElements); \
+}
+
+/**
+ * Generic method - return a pointer to one past the last element in the
+ * vector.
+ */
+#define RTVEC_DECLFN_END(name, type) \
+DECLINLINE(type *) name ## End(struct name *pVec) \
+{ \
+ return(&pVec->mpElements[pVec->mcElements]); \
+}
+
+/**
+ * Generic method - add a new, uninitialised element onto a vector and return
+ * it.
+ * @note this method differs from the STL equivalent by letting the caller
+ * post-initialise the new element rather than copying it from its
+ * argument.
+ */
+#define RTVEC_DECLFN_PUSHBACK(name, type) \
+DECLINLINE(type *) name ## PushBack(struct name *pVec) \
+{ \
+ Assert(pVec->mcElements <= pVec->mcCapacity); \
+ if ( pVec->mcElements == pVec->mcCapacity \
+ && RT_FAILURE(name ## Reserve(pVec, pVec->mcCapacity \
+ + RTVECIMPL_ALLOC_UNIT))) \
+ return NULL; \
+ ++pVec->mcElements; \
+ return &pVec->mpElements[pVec->mcElements - 1]; \
+}
+
+/**
+ * Generic method - drop the last element from the vector.
+ */
+#define RTVEC_DECLFN_POPBACK(name) \
+DECLINLINE(void) name ## PopBack(struct name *pVec) \
+{ \
+ Assert(pVec->mcElements <= pVec->mcCapacity); \
+ --pVec->mcElements; \
+}
+
+/**
+ * Generic method - drop the last element from the vector, calling a clean-up
+ * method first.
+ *
+ * By taking an adapter function for the element to be dropped as an
+ * additional macro parameter we can support clean-up by pointer
+ * (pfnAdapter maps T* -> T*) or by value (maps T* -> T). pfnAdapter takes
+ * one argument of type @a type * and must return whatever type pfnDelete
+ * expects.
+ */
+/** @todo find a better name for pfnAdapter? */
+#define RTVEC_DECLFN_POPBACK_DELETE(name, type, pfnDelete, pfnAdapter) \
+DECLINLINE(void) name ## PopBack(struct name *pVec) \
+{ \
+ Assert(pVec->mcElements <= pVec->mcCapacity); \
+ --pVec->mcElements; \
+ pfnDelete(pfnAdapter(&pVec->mpElements[pVec->mcElements])); \
+}
+
+/**
+ * Generic method - reset a vector to empty.
+ * @note This function does not free any memory
+ */
+#define RTVEC_DECLFN_CLEAR(name) \
+DECLINLINE(void) name ## Clear(struct name *pVec) \
+{ \
+ Assert(pVec->mcElements <= pVec->mcCapacity); \
+ pVec->mcElements = 0; \
+}
+
+/**
+ * Generic method - reset a vector to empty, calling a clean-up method on each
+ * element first.
+ * @note See @a RTVEC_DECLFN_POPBACK_DELETE for an explanation of pfnAdapter
+ * @note This function does not free any memory
+ * @note The cleanup function is currently called on the elements from first
+ * to last. The testcase expects this.
+ */
+#define RTVEC_DECLFN_CLEAR_DELETE(name, pfnDelete, pfnAdapter) \
+DECLINLINE(void) name ## Clear(struct name *pVec) \
+{ \
+ size_t i; \
+ \
+ Assert(pVec->mcElements <= pVec->mcCapacity); \
+ for (i = 0; i < pVec->mcElements; ++i) \
+ pfnDelete(pfnAdapter(&pVec->mpElements[i])); \
+ pVec->mcElements = 0; \
+}
+
+/**
+ * Generic method - detach the array contained inside a vector and reset the
+ * vector to empty.
+ * @note This function does not free any memory
+ */
+#define RTVEC_DECLFN_DETACH(name, type) \
+DECLINLINE(type *) name ## Detach(struct name *pVec) \
+{ \
+ type *pArray = pVec->mpElements; \
+ \
+ Assert(pVec->mcElements <= pVec->mcCapacity); \
+ pVec->mcElements = 0; \
+ pVec->mpElements = NULL; \
+ pVec->mcCapacity = 0; \
+ return pArray; \
+}
+
+/** Common declarations for all vector types */
+#define RTVEC_DECL_COMMON(name, type, pfnRealloc) \
+ RTVEC_DECL_STRUCT(name, type) \
+ RTVEC_DECLFN_SIZE(name, type) \
+ RTVEC_DECLFN_RESERVE(name, type, pfnRealloc) \
+ RTVEC_DECLFN_BEGIN(name, type) \
+ RTVEC_DECLFN_END(name, type) \
+ RTVEC_DECLFN_PUSHBACK(name, type) \
+ RTVEC_DECLFN_DETACH(name, type)
+
+/**
+ * Declarator macro - declare a vector type
+ * @param name the name of the C struct type describing the vector as
+ * well as the prefix of the functions for manipulating it
+ * @param type the type of the objects contained in the vector
+ * @param pfnRealloc the memory reallocation function used for expanding the
+ * vector
+ */
+#define RTVEC_DECL_ALLOCATOR(name, type, pfnRealloc) \
+ RTVEC_DECL_COMMON(name, type, pfnRealloc) \
+ RTVEC_DECLFN_POPBACK(name) \
+ RTVEC_DECLFN_CLEAR(name)
+
+/**
+ * Generic method - inline id mapping delete adapter function - see the
+ * explanation of pfnAdapter in @a RTVEC_DECLFN_POPBACK_DELETE.
+ */
+#define RTVEC_DECLFN_DELETE_ADAPTER_ID(name, type) \
+DECLINLINE(type *) name ## DeleteAdapterId(type *arg) \
+{ \
+ return arg; \
+}
+
+/**
+ * Generic method - inline pointer-to-value mapping delete adapter function -
+ * see the explanation of pfnAdapter in @a RTVEC_DECLFN_POPBACK_DELETE.
+ */
+#define RTVEC_DECLFN_DELETE_ADAPTER_TO_VALUE(name, type) \
+DECLINLINE(type) name ## DeleteAdapterToValue(type *arg) \
+{ \
+ return *arg; \
+}
+
+/**
+ * Declarator macro - declare a vector type with a cleanup callback to be used
+ * when elements are dropped from the vector. The callback takes a pointer to
+ * @a type,
+ * NOT a value of type @a type.
+ * @param name the name of the C struct type describing the vector as
+ * well as the prefix of the functions for manipulating it
+ * @param type the type of the objects contained in the vector
+ * @param pfnRealloc the memory reallocation function used for expanding the
+ * vector
+ * @param pfnDelete the cleanup callback function - signature
+ * void pfnDelete(type *)
+ */
+#define RTVEC_DECL_ALLOCATOR_DELETE(name, type, pfnRealloc, pfnDelete) \
+ RTVEC_DECL_COMMON(name, type, pfnRealloc) \
+ RTVEC_DECLFN_DELETE_ADAPTER_ID(name, type) \
+ RTVEC_DECLFN_POPBACK_DELETE(name, type, pfnDelete, \
+ name ## DeleteAdapterId) \
+ RTVEC_DECLFN_CLEAR_DELETE(name, pfnDelete, name ## DeleteAdapterId)
+
+/**
+ * Declarator macro - declare a vector type with a cleanup callback to be used
+ * when elements are dropped from the vector. The callback takes a parameter
+ * of type @a type, NOT a pointer to @a type.
+ * @param name the name of the C struct type describing the vector as
+ * well as the prefix of the functions for manipulating it
+ * @param type the type of the objects contained in the vector
+ * @param pfnRealloc the memory reallocation function used for expanding the
+ * vector
+ * @param pfnDelete the cleanup callback function - signature
+ * void pfnDelete(type)
+ */
+#define RTVEC_DECL_ALLOCATOR_DELETE_BY_VALUE(name, type, pfnRealloc, \
+ pfnDelete) \
+ RTVEC_DECL_COMMON(name, type, pfnRealloc) \
+ RTVEC_DECLFN_DELETE_ADAPTER_TO_VALUE(name, type) \
+ RTVEC_DECLFN_POPBACK_DELETE(name, type, pfnDelete, \
+ name ## DeleteAdapterToValue) \
+ RTVEC_DECLFN_CLEAR_DELETE(name, pfnDelete, \
+ name ## DeleteAdapterToValue)
+
+/**
+ * Inline wrapper around RTMemRealloc macro to get a function usable as a
+ * callback.
+ */
+DECLINLINE(void *) rtvecReallocDefTag(void *pv, size_t cbNew)
+{
+ return RTMemRealloc(pv, cbNew);
+}
+
+/**
+ * Declarator macro - declare a vector type (see @a RTVEC_DECL_ALLOCATOR)
+ * using RTMemRealloc as a memory allocator
+ * @param name the name of the C struct type describing the vector as
+ * well as the prefix of the functions for manipulating it
+ * @param type the type of the objects contained in the vector
+ */
+#define RTVEC_DECL(name, type) \
+ RTVEC_DECL_ALLOCATOR(name, type, rtvecReallocDefTag)
+
+/**
+ * Declarator macro - declare a vector type with a cleanup by pointer callback
+ * (see @a RTVEC_DECL_ALLOCATOR_DELETE) using RTMemRealloc as a memory
+ * allocator
+ * @param name the name of the C struct type describing the vector as
+ * well as the prefix of the functions for manipulating it
+ * @param type the type of the objects contained in the vector
+ * @param pfnDelete the cleanup callback function - signature
+ * void pfnDelete(type *)
+ */
+#define RTVEC_DECL_DELETE(name, type, pfnDelete) \
+ RTVEC_DECL_ALLOCATOR_DELETE(name, type, rtvecReallocDefTag, pfnDelete)
+
+/**
+ * Declarator macro - declare a vector type with a cleanup by value callback
+ * (see @a RTVEC_DECL_ALLOCATOR_DELETE_BY_VALUE) using RTMemRealloc as a memory
+ * allocator
+ * @param name the name of the C struct type describing the vector as
+ * well as the prefix of the functions for manipulating it
+ * @param type the type of the objects contained in the vector
+ * @param pfnDelete the cleanup callback function - signature
+ * void pfnDelete(type)
+ */
+#define RTVEC_DECL_DELETE_BY_VALUE(name, type, pfnDelete) \
+ RTVEC_DECL_ALLOCATOR_DELETE_BY_VALUE(name, type, rtvecReallocDefTag, \
+ pfnDelete)
+
+#endif /* ___iprt_vector_h */
diff --git a/include/iprt/vfs.h b/include/iprt/vfs.h
new file mode 100644
index 00000000..6eefa01d
--- /dev/null
+++ b/include/iprt/vfs.h
@@ -0,0 +1,934 @@
+/** @file
+ * IPRT - Virtual Filesystem.
+ */
+
+/*
+ * 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 ___iprt_vfs_h
+#define ___iprt_vfs_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+#include <iprt/dir.h>
+#include <iprt/fs.h>
+#include <iprt/handle.h>
+#include <iprt/symlink.h>
+#include <iprt/sg.h>
+#include <iprt/time.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_vfs RTVfs - Virtual Filesystem
+ * @ingroup grp_rt
+ *
+ * The virtual filesystem APIs are intended to make it possible to work on
+ * container files, file system sub-trees, file system overlays and other custom
+ * filesystem configurations. It also makes it possible to create filters, like
+ * automatically gunzipping a tar.gz file before feeding it to the RTTar API for
+ * unpacking - or wise versa.
+ *
+ * The virtual filesystem APIs are intended to mirror the RTDir, RTFile, RTPath
+ * and RTFs APIs pretty closely so that rewriting a piece of code to work with
+ * it should be easy. However there are some differences to the way the APIs
+ * works and the user should heed the documentation. The differences are
+ * usually motivated by simplification and in some case to make the VFS more
+ * flexible.
+ *
+ * @{
+ */
+
+/**
+ * The object type.
+ */
+typedef enum RTVFSOBJTYPE
+{
+ /** Invalid type. */
+ RTVFSOBJTYPE_INVALID = 0,
+ /** Pure base object.
+ * This is returned by the filesystem stream to represent directories,
+ * devices, fifos and similar that needs to be created. */
+ RTVFSOBJTYPE_BASE,
+ /** Virtual filesystem. */
+ RTVFSOBJTYPE_VFS,
+ /** Filesystem stream. */
+ RTVFSOBJTYPE_FS_STREAM,
+ /** Pure I/O stream. */
+ RTVFSOBJTYPE_IO_STREAM,
+ /** Directory. */
+ RTVFSOBJTYPE_DIR,
+ /** File. */
+ RTVFSOBJTYPE_FILE,
+ /** Symbolic link. */
+ RTVFSOBJTYPE_SYMLINK,
+ /** End of valid object types. */
+ RTVFSOBJTYPE_END,
+ /** Pure I/O stream. */
+ RTVFSOBJTYPE_32BIT_HACK = 0x7fffffff
+} RTVFSOBJTYPE;
+/** Pointer to a VFS object type. */
+typedef RTVFSOBJTYPE *PRTVFSOBJTYPE;
+
+
+
+/** @name RTVfsCreate flags
+ * @{ */
+/** Whether the file system is read-only. */
+#define RTVFS_C_READONLY RT_BIT(0)
+/** Whether we the VFS should be thread safe (i.e. automaticaly employ
+ * locks). */
+#define RTVFS_C_THREAD_SAFE RT_BIT(1)
+/** @} */
+
+/**
+ * Creates an empty virtual filesystem.
+ *
+ * @returns IPRT status code.
+ * @param pszName Name, for logging and such.
+ * @param fFlags Flags, MBZ.
+ * @param phVfs Where to return the VFS handle. Release the returned
+ * reference by calling RTVfsRelease.
+ */
+RTDECL(int) RTVfsCreate(const char *pszName, uint32_t fFlags, PRTVFS phVfs);
+RTDECL(uint32_t) RTVfsRetain(RTVFS phVfs);
+RTDECL(uint32_t) RTVfsRelease(RTVFS phVfs);
+RTDECL(int) RTVfsAttach(RTVFS hVfs, const char *pszMountPoint, uint32_t fFlags, RTVFS hVfsAttach);
+RTDECL(int) RTVfsDetach(RTVFS hVfs, const char *pszMountPoint, RTVFS hVfsToDetach, PRTVFS *phVfsDetached);
+RTDECL(uint32_t) RTVfsGetAttachmentCount(RTVFS hVfs);
+RTDECL(int) RTVfsGetAttachment(RTVFS hVfs, uint32_t iOrdinal, PRTVFS *phVfsAttached, uint32_t *pfFlags,
+ char *pszMountPoint, size_t cbMountPoint);
+
+/**
+ * Checks whether a given range is in use by the virtual filesystem.
+ *
+ * @returns IPRT status code.
+ * @param hVfs VFS handle.
+ * @param off Start offset to check.
+ * @param cb Number of bytes to check.
+ * @param pfUsed Where to store the result.
+ */
+RTDECL(int) RTVfsIsRangeInUse(RTVFS hVfs, uint64_t off, size_t cb,
+ bool *pfUsed);
+
+/** @defgroup grp_vfs_dir VFS Base Object API
+ * @{
+ */
+
+/**
+ * Retains a reference to the VFS base object handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(uint32_t) RTVfsObjRetain(RTVFSOBJ hVfsObj);
+
+/**
+ * Releases a reference to the VFS base handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(uint32_t) RTVfsObjRelease(RTVFSOBJ hVfsObj);
+
+/**
+ * Query information about the object.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the @a enmAddAttr value is not handled by the
+ * implementation.
+ *
+ * @param hVfsObj The VFS object handle.
+ * @param pObjInfo Where to return the info.
+ * @param enmAddAttr Which additional attributes should be retrieved.
+ * @sa RTVfsIoStrmQueryInfo, RTVfsFileQueryInfo, RTFileQueryInfo,
+ * RTPathQueryInfo
+ */
+RTDECL(int) RTVfsObjQueryInfo(RTVFSOBJ hVfsObj, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+
+/**
+ * Converts a VFS base object handle to a VFS handle.
+ *
+ * @returns Referenced handle on success, NIL on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(RTVFS) RTVfsObjToVfs(RTVFSOBJ hVfsObj);
+
+/**
+ * Converts a VFS base object handle to a VFS filesystem stream handle.
+ *
+ * @returns Referenced handle on success, NIL on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(RTVFSFSSTREAM) RTVfsObjToFsStream(RTVFSOBJ hVfsObj);
+
+/**
+ * Converts a VFS base object handle to a VFS directory handle.
+ *
+ * @returns Referenced handle on success, NIL on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(RTVFSDIR) RTVfsObjToDir(RTVFSOBJ hVfsObj);
+
+/**
+ * Converts a VFS base object handle to a VFS I/O stream handle.
+ *
+ * @returns Referenced handle on success, NIL on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(RTVFSIOSTREAM) RTVfsObjToIoStream(RTVFSOBJ hVfsObj);
+
+/**
+ * Converts a VFS base object handle to a VFS file handle.
+ *
+ * @returns Referenced handle on success, NIL on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(RTVFSFILE) RTVfsObjToFile(RTVFSOBJ hVfsObj);
+
+/**
+ * Converts a VFS base object handle to a VFS symbolic link handle.
+ *
+ * @returns Referenced handle on success, NIL on failure.
+ * @param hVfsObj The VFS base object handle.
+ */
+RTDECL(RTVFSSYMLINK) RTVfsObjToSymlink(RTVFSOBJ hVfsObj);
+
+
+/**
+ * Converts a VFS handle to a VFS base object handle.
+ *
+ * @returns Referenced handle on success, NIL if the input handle was invalid.
+ * @param hVfs The VFS handle.
+ */
+RTDECL(RTVFSOBJ) RTVfsObjFromVfs(RTVFS hVfs);
+
+/**
+ * Converts a VFS filesystem stream handle to a VFS base object handle.
+ *
+ * @returns Referenced handle on success, NIL if the input handle was invalid.
+ * @param hVfsFSs The VFS filesystem stream handle.
+ */
+RTDECL(RTVFSOBJ) RTVfsObjFromFsStream(RTVFSFSSTREAM hVfsFss);
+
+/**
+ * Converts a VFS directory handle to a VFS base object handle.
+ *
+ * @returns Referenced handle on success, NIL if the input handle was invalid.
+ * @param hVfsDir The VFS directory handle.
+ */
+RTDECL(RTVFSOBJ) RTVfsObjFromDir(RTVFSDIR hVfsDir);
+
+/**
+ * Converts a VFS I/O stream handle to a VFS base object handle.
+ *
+ * @returns Referenced handle on success, NIL if the input handle was invalid.
+ * @param hVfsIos The VFS I/O stream handle.
+ */
+RTDECL(RTVFSOBJ) RTVfsObjFromIoStream(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Converts a VFS file handle to a VFS base object handle.
+ *
+ * @returns Referenced handle on success, NIL if the input handle was invalid.
+ * @param hVfsFile The VFS file handle.
+ */
+RTDECL(RTVFSOBJ) RTVfsObjFromFile(RTVFSFILE hVfsFile);
+
+/**
+ * Converts a VFS symbolic link handle to a VFS base object handle.
+ *
+ * @returns Referenced handle on success, NIL if the input handle was invalid.
+ * @param hVfsSym The VFS symbolic link handle.
+ */
+RTDECL(RTVFSOBJ) RTVfsObjFromSymlink(RTVFSSYMLINK hVfsSym);
+
+/** @} */
+
+
+/** @defgroup grp_vfs_fsstream VFS Filesystem Stream API
+ *
+ * Filesystem streams are for tar, cpio and similar. Any virtual filesystem can
+ * be turned into a filesystem stream using RTVfsFsStrmFromVfs.
+ *
+ * @{
+ */
+
+RTDECL(uint32_t) RTVfsFsStrmRetain(RTVFSFSSTREAM hVfsFss);
+RTDECL(uint32_t) RTVfsFsStrmRelease(RTVFSFSSTREAM hVfsFss);
+RTDECL(int) RTVfsFsStrmQueryInfo(RTVFSFSSTREAM hVfsFss, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+/**
+ * Gets the next object in the stream.
+ *
+ * This call may affect the stream posision of a previously returned object.
+ *
+ * The type of object returned here typically boils down to three types:
+ * - I/O streams (representing files),
+ * - symbolic links
+ * - base object
+ * The base objects represent anything not convered by the two other, i.e.
+ * directories, device nodes, fifos, sockets and whatnot. The details can be
+ * queried using RTVfsObjQueryInfo.
+ *
+ * That said, absolutely any object except for filesystem stream objects can be
+ * returned by this call. Any generic code is adviced to just deal with it all.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if a new object was retrieved.
+ * @retval VERR_EOF when there are no more objects.
+ *
+ * @param pvThis The implementation specific directory data.
+ * @param ppszName Where to return the object name. Must be freed by
+ * calling RTStrFree.
+ * @param penmType Where to return the object type.
+ * @param hVfsObj Where to return the object handle (referenced).
+ * This must be cast to the desired type before use.
+ */
+RTDECL(int) RTVfsFsStrmNext(RTVFSFSSTREAM hVfsFss, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj);
+
+/** @} */
+
+
+/** @defgroup grp_vfs_dir VFS Directory API
+ * @{
+ */
+
+/**
+ * Retains a reference to the VFS directory handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hVfsDir The VFS directory handle.
+ */
+RTDECL(uint32_t) RTVfsDirRetain(RTVFSDIR hVfsDir);
+
+/**
+ * Releases a reference to the VFS directory handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hVfsIos The VFS directory handle.
+ */
+RTDECL(uint32_t) RTVfsDirRelease(RTVFSDIR hVfsDir);
+
+/** @} */
+
+
+/** @defgroup grp_vfs_iostream VFS Symbolic Link API
+ *
+ * @remarks The TAR VFS and filesystem stream uses symbolic links for
+ * describing hard links as well. The users must use RTFS_IS_SYMLINK
+ * to check if it is a real symlink in those cases.
+ *
+ * @remarks Any VFS which is backed by a real file system may be subject to
+ * races with other processes or threads, so the user may get
+ * unexpected errors when this happends. This is a bit host specific,
+ * i.e. it might be prevent on windows if we care.
+ *
+ * @{
+ */
+
+
+/**
+ * Retains a reference to the VFS symbolic link handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hVfsSym The VFS symbolic link handle.
+ */
+RTDECL(uint32_t) RTVfsSymlinkRetain(RTVFSSYMLINK hVfsSym);
+
+/**
+ * Releases a reference to the VFS symbolic link handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hVfsSym The VFS symbolic link handle.
+ */
+RTDECL(uint32_t) RTVfsSymlinkRelease(RTVFSSYMLINK hVfsSym);
+
+/**
+ * Query information about the symbolic link.
+ *
+ * @returns IPRT status code.
+ * @param hVfsSym The VFS symbolic link handle.
+ * @param pObjInfo Where to return the info.
+ * @param enmAddAttr Which additional attributes should be retrieved.
+ *
+ * @sa RTFileQueryInfo, RTPathQueryInfo, RTPathQueryInfoEx
+ */
+RTDECL(int) RTVfsSymlinkQueryInfo(RTVFSSYMLINK hVfsSym, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+/**
+ * Set the unix style owner and group.
+ *
+ * @returns IPRT status code.
+ * @param hVfsSym The VFS symbolic link handle.
+ * @param fMode The new mode bits.
+ * @param fMask The mask indicating which bits we are changing.
+ * @sa RTFileSetMode, RTPathSetMode
+ */
+RTDECL(int) RTVfsSymlinkSetMode(RTVFSSYMLINK hVfsSym, RTFMODE fMode, RTFMODE fMask);
+
+/**
+ * Set the timestamps associated with the object.
+ *
+ * @returns IPRT status code.
+ * @param hVfsSym The VFS symbolic link handle.
+ * @param pAccessTime Pointer to the new access time. NULL if not
+ * to be changed.
+ * @param pModificationTime Pointer to the new modifcation time. NULL if
+ * not to be changed.
+ * @param pChangeTime Pointer to the new change time. NULL if not to be
+ * changed.
+ * @param pBirthTime Pointer to the new time of birth. NULL if not to be
+ * changed.
+ * @remarks See RTFileSetTimes for restrictions and behavior imposed by the
+ * host OS or underlying VFS provider.
+ * @sa RTFileSetTimes, RTPathSetTimes
+ */
+RTDECL(int) RTVfsSymlinkSetTimes(RTVFSSYMLINK hVfsSym, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+ PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
+
+/**
+ * Set the unix style owner and group.
+ *
+ * @returns IPRT status code.
+ * @param hVfsSym The VFS symbolic link handle.
+ * @param uid The user ID of the new owner. NIL_RTUID if
+ * unchanged.
+ * @param gid The group ID of the new owner group. NIL_RTGID if
+ * unchanged.
+ * @sa RTFileSetOwner, RTPathSetOwner.
+ */
+RTDECL(int) RTVfsSymlinkSetOwner(RTVFSSYMLINK hVfsSym, RTUID uid, RTGID gid);
+
+/**
+ * Read the symbolic link target.
+ *
+ * @returns IPRT status code.
+ * @param hVfsSym The VFS symbolic link handle.
+ * @param pszTarget The target buffer.
+ * @param cbTarget The size of the target buffer.
+ * @sa RTSymlinkRead
+ */
+RTDECL(int) RTVfsSymlinkRead(RTVFSSYMLINK hVfsSym, char *pszTarget, size_t cbTarget);
+
+/** @} */
+
+
+
+/** @defgroup grp_vfs_iostream VFS I/O Stream API
+ * @{
+ */
+
+/**
+ * Create a VFS I/O stream handle from a standard IPRT file handle (RTFILE).
+ *
+ * @returns IPRT status code.
+ * @param hFile The standard IPRT file handle.
+ * @param fOpen The flags the handle was opened with. Pass 0 to
+ * have these detected.
+ * @param fLeaveOpen Whether to leave the handle open when the VFS file
+ * is released, or to close it (@c false).
+ * @param phVfsIos Where to return the VFS I/O stream handle.
+ */
+RTDECL(int) RTVfsIoStrmFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSIOSTREAM phVfsIos);
+
+/**
+ * Create a VFS I/O stream handle from one of the standard handles.
+ *
+ * @returns IPRT status code.
+ * @param enmStdHandle The standard IPRT file handle.
+ * @param fOpen The flags the handle was opened with. Pass 0 to
+ * have these detected.
+ * @param fLeaveOpen Whether to leave the handle open when the VFS file
+ * is released, or to close it (@c false).
+ * @param phVfsIos Where to return the VFS I/O stream handle.
+ */
+RTDECL(int) RTVfsIoStrmFromStdHandle(RTHANDLESTD enmStdHandle, uint64_t fOpen, bool fLeaveOpen,
+ PRTVFSIOSTREAM phVfsIos);
+
+/**
+ * Retains a reference to the VFS I/O stream handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hVfsIos The VFS I/O stream handle.
+ */
+RTDECL(uint32_t) RTVfsIoStrmRetain(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Releases a reference to the VFS I/O stream handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hVfsIos The VFS I/O stream handle.
+ */
+RTDECL(uint32_t) RTVfsIoStrmRelease(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Convert the VFS I/O stream handle to a VFS file handle.
+ *
+ * @returns The VFS file handle on success, this must be released.
+ * NIL_RTVFSFILE if the I/O stream handle is invalid.
+ * @param hVfsIos The VFS I/O stream handle.
+ * @sa RTVfsFileToIoStream
+ */
+RTDECL(RTVFSFILE) RTVfsIoStrmToFile(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Query information about the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param pObjInfo Where to return the info.
+ * @param enmAddAttr Which additional attributes should be retrieved.
+ * @sa RTFileQueryInfo
+ */
+RTDECL(int) RTVfsIoStrmQueryInfo(RTVFSIOSTREAM hVfsIos, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+/**
+ * Read bytes from the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and the number of bytes read written to @a pcbRead.
+ * @retval VINF_TRY_AGAIN if @a fBlocking is @c false, @a pcbRead is not NULL,
+ * and no data was available. @a *pcbRead will be set to 0.
+ * @retval VINF_EOF when trying to read __beyond__ the end of the stream and
+ * @a pcbRead is not NULL (it will be set to the number of bytes read,
+ * or 0 if the end of the stream was reached before this call).
+ * When the last byte of the read request is the last byte in the
+ * stream, this status code will not be used. However, VINF_EOF is
+ * returned when attempting to read 0 bytes while standing at the end
+ * of the stream.
+ * @retval VERR_EOF when trying to read __beyond__ the end of the stream and
+ * @a pcbRead is NULL.
+ * @retval VERR_ACCESS_DENIED if the stream is not readable.
+ *
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param pvBuf Where to store the read bytes.
+ * @param cbToRead The number of bytes to read.
+ * @param fBlocking Whether the call is blocking (@c true) or not. If
+ * not, the @a pcbRead parameter must not be NULL.
+ * @param pcbRead Where to always store the number of bytes actually
+ * read. This can be NULL if @a fBlocking is true.
+ * @sa RTVfsFileRead, RTFileRead, RTPipeRead, RTPipeReadBlocking,
+ * RTSocketRead
+ */
+RTDECL(int) RTVfsIoStrmRead(RTVFSIOSTREAM hVfsIos, void *pvBuf, size_t cbToRead, bool fBlocking, size_t *pcbRead);
+RTDECL(int) RTVfsIoStrmReadAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, void *pvBuf, size_t cbToRead, bool fBlocking, size_t *pcbRead);
+
+/**
+ * Write bytes to the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_ACCESS_DENIED if the stream is not writable.
+ *
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param pvBuf The bytes to write.
+ * @param cbToWrite The number of bytes to write.
+ * @param fBlocking Whether the call is blocking (@c true) or not. If
+ * not, the @a pcbWritten parameter must not be NULL.
+ * @param pcbRead Where to always store the number of bytes actually
+ * written. This can be NULL if @a fBlocking is true.
+ * @sa RTVfsFileWrite, RTFileWrite, RTPipeWrite, RTPipeWriteBlocking,
+ * RTSocketWrite
+ */
+RTDECL(int) RTVfsIoStrmWrite(RTVFSIOSTREAM hVfsIos, const void *pvBuf, size_t cbToWrite, bool fBlocking, size_t *pcbWritten);
+RTDECL(int) RTVfsIoStrmWriteAt(RTVFSIOSTREAM hVfsIos, RTFOFF off, const void *pvBuf, size_t cbToWrite, bool fBlocking, size_t *pcbWritten);
+
+/**
+ * Reads bytes from the I/O stream into a scatter buffer.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and the number of bytes read written to @a pcbRead.
+ * @retval VINF_TRY_AGAIN if @a fBlocking is @c false, @a pcbRead is not NULL,
+ * and no data was available. @a *pcbRead will be set to 0.
+ * @retval VINF_EOF when trying to read __beyond__ the end of the stream and
+ * @a pcbRead is not NULL (it will be set to the number of bytes read,
+ * or 0 if the end of the stream was reached before this call).
+ * When the last byte of the read request is the last byte in the
+ * stream, this status code will not be used. However, VINF_EOF is
+ * returned when attempting to read 0 bytes while standing at the end
+ * of the stream.
+ * @retval VERR_EOF when trying to read __beyond__ the end of the stream and
+ * @a pcbRead is NULL.
+ * @retval VERR_ACCESS_DENIED if the stream is not readable.
+ *
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param pSgBuf Pointer to a scatter buffer descriptor. The number
+ * of bytes described by the segments is what will be
+ * attemted read.
+ * @param fBlocking Whether the call is blocking (@c true) or not. If
+ * not, the @a pcbRead parameter must not be NULL.
+ * @param pcbRead Where to always store the number of bytes actually
+ * read. This can be NULL if @a fBlocking is true.
+ * @sa RTFileSgRead, RTSocketSgRead, RTPipeRead, RTPipeReadBlocking
+ */
+RTDECL(int) RTVfsIoStrmSgRead(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
+
+/**
+ * Write bytes to the I/O stream from a gather buffer.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_ACCESS_DENIED if the stream is not writable.
+ *
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param pSgBuf Pointer to a gather buffer descriptor. The number
+ * of bytes described by the segments is what will be
+ * attemted written.
+ * @param fBlocking Whether the call is blocking (@c true) or not. If
+ * not, the @a pcbWritten parameter must not be NULL.
+ * @param pcbRead Where to always store the number of bytes actually
+ * written. This can be NULL if @a fBlocking is true.
+ * @sa RTFileSgWrite, RTSocketSgWrite
+ */
+RTDECL(int) RTVfsIoStrmSgWrite(RTVFSIOSTREAM hVfsIos, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten);
+
+/**
+ * Flush any buffered data to the I/O stream.
+ *
+ * @returns IPRT status code.
+ * @param hVfsIos The VFS I/O stream handle.
+ * @sa RTVfsFileFlush, RTFileFlush, RTPipeFlush
+ */
+RTDECL(int) RTVfsIoStrmFlush(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Poll for events.
+ *
+ * @returns IPRT status code.
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
+ * @param cMillies How long to wait for event to eventuate.
+ * @param fIntr Whether the wait is interruptible and can return
+ * VERR_INTERRUPTED (@c true) or if this condition
+ * should be hidden from the caller (@c false).
+ * @param pfRetEvents Where to return the event mask.
+ * @sa RTVfsFilePoll, RTPollSetAdd, RTPoll, RTPollNoResume.
+ */
+RTDECL(int) RTVfsIoStrmPoll(RTVFSIOSTREAM hVfsIos, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+ uint32_t *pfRetEvents);
+/**
+ * Tells the current I/O stream position.
+ *
+ * @returns Zero or higher - where to return the I/O stream offset. Values
+ * below zero are IPRT status codes (VERR_XXX).
+ * @param hVfsIos The VFS I/O stream handle.
+ * @sa RTFileTell
+ */
+RTDECL(RTFOFF) RTVfsIoStrmTell(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Skips @a cb ahead in the stream.
+ *
+ * @returns IPRT status code.
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param cb The number bytes to skip.
+ */
+RTDECL(int) RTVfsIoStrmSkip(RTVFSIOSTREAM hVfsIos, RTFOFF cb);
+
+/**
+ * Fills the stream with @a cb zeros.
+ *
+ * @returns IPRT status code.
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param cb The number of zero bytes to insert.
+ */
+RTDECL(int) RTVfsIoStrmZeroFill(RTVFSIOSTREAM hVfsIos, RTFOFF cb);
+
+/**
+ * Checks if we're at the end of the I/O stream.
+ *
+ * @returns true if at EOS, otherwise false.
+ * @param hVfsIos The VFS I/O stream handle.
+ */
+RTDECL(bool) RTVfsIoStrmIsAtEnd(RTVFSIOSTREAM hVfsIos);
+
+/**
+ * Process the rest of the stream, checking if it's all valid UTF-8 encoding.
+ *
+ * @returns VBox status cod.e
+ *
+ * @param hVfsIos The VFS I/O stream handle.
+ * @param fFlags Flags governing the validation, see
+ * RTVFS_VALIDATE_UTF8_XXX.
+ * @param poffError Where to return the error offset. Optional.
+ */
+RTDECL(int) RTVfsIoStrmValidateUtf8Encoding(RTVFSIOSTREAM hVfsIos, uint32_t fFlags, PRTFOFF poffError);
+
+/** @defgroup RTVFS_VALIDATE_UTF8_XXX RTVfsIoStrmValidateUtf8Encoding flags.
+ * @{ */
+/** The text must not contain any null terminator codepoints. */
+#define RTVFS_VALIDATE_UTF8_NO_NULL RT_BIT_32(0)
+/** The codepoints must be in the range covered by RTC-3629. */
+#define RTVFS_VALIDATE_UTF8_BY_RTC_3629 RT_BIT_32(1)
+/** Mask of valid flags. */
+#define RTVFS_VALIDATE_UTF8_VALID_MASK UINT32_C(0x00000003)
+/** @} */
+
+/** @} */
+
+
+/** @defgroup grp_vfs_file VFS File API
+ * @{
+ */
+RTDECL(int) RTVfsFileOpen(RTVFS hVfs, const char *pszFilename, uint64_t fOpen, PRTVFSFILE phVfsFile);
+
+/**
+ * Create a VFS file handle from a standard IPRT file handle (RTFILE).
+ *
+ * @returns IPRT status code.
+ * @param hFile The standard IPRT file handle.
+ * @param fOpen The flags the handle was opened with. Pass 0 to
+ * have these detected.
+ * @param fLeaveOpen Whether to leave the handle open when the VFS file
+ * is released, or to close it (@c false).
+ * @param phVfsFile Where to return the VFS file handle.
+ */
+RTDECL(int) RTVfsFileFromRTFile(RTFILE hFile, uint64_t fOpen, bool fLeaveOpen, PRTVFSFILE phVfsFile);
+RTDECL(RTHCUINTPTR) RTVfsFileToNative(RTFILE hVfsFile);
+
+/**
+ * Convert the VFS file handle to a VFS I/O stream handle.
+ *
+ * @returns The VFS I/O stream handle on success, this must be released.
+ * NIL_RTVFSIOSTREAM if the file handle is invalid.
+ * @param hVfsFile The VFS file handle.
+ * @sa RTVfsIoStrmToFile
+ */
+RTDECL(RTVFSIOSTREAM) RTVfsFileToIoStream(RTVFSFILE hVfsFile);
+
+/**
+ * Retains a reference to the VFS file handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hVfsFile The VFS file handle.
+ */
+RTDECL(uint32_t) RTVfsFileRetain(RTVFSFILE hVfsFile);
+
+/**
+ * Releases a reference to the VFS file handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hVfsFile The VFS file handle.
+ */
+RTDECL(uint32_t) RTVfsFileRelease(RTVFSFILE hVfsFile);
+
+/**
+ * Query information about the object.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_NOT_SUPPORTED if the @a enmAddAttr value is not handled by the
+ * implementation.
+ *
+ * @param hVfsObj The VFS object handle.
+ * @param pObjInfo Where to return the info.
+ * @param enmAddAttr Which additional attributes should be retrieved.
+ * @sa RTVfsObjQueryInfo, RTVfsFsStrmQueryInfo, RTVfsDirQueryInfo,
+ * RTVfsIoStrmQueryInfo, RTVfsFileQueryInfo, RTFileQueryInfo,
+ * RTPathQueryInfo.
+ */
+RTDECL(int) RTVfsFileQueryInfo(RTVFSFILE hVfsFile, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+/**
+ * Read bytes from the file at the current position.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS and the number of bytes read written to @a pcbRead.
+ * @retval VINF_TRY_AGAIN if @a fBlocking is @c false, @a pcbRead is not NULL,
+ * and no data was available. @a *pcbRead will be set to 0.
+ * @retval VINF_EOF when trying to read __beyond__ the end of the file and
+ * @a pcbRead is not NULL (it will be set to the number of bytes read,
+ * or 0 if the end of the file was reached before this call).
+ * When the last byte of the read request is the last byte in the
+ * file, this status code will not be used. However, VINF_EOF is
+ * returned when attempting to read 0 bytes while standing at the end
+ * of the file.
+ * @retval VERR_EOF when trying to read __beyond__ the end of the file and
+ * @a pcbRead is NULL.
+ * @retval VERR_ACCESS_DENIED if the file is not readable.
+ *
+ * @param hVfsFile The VFS file handle.
+ * @param pvBuf Where to store the read bytes.
+ * @param cbToRead The number of bytes to read.
+ * @param fBlocking Whether the call is blocking (@c true) or not. If
+ * not, the @a pcbRead parameter must not be NULL.
+ * @param pcbRead Where to always store the number of bytes actually
+ * read. This can be NULL if @a fBlocking is true.
+ * @sa RTVfsIoStrmRead, RTFileRead, RTPipeRead, RTPipeReadBlocking,
+ * RTSocketRead
+ */
+RTDECL(int) RTVfsFileRead(RTVFSFILE hVfsFile, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+RTDECL(int) RTVfsFileReadAt(RTVFSFILE hVfsFile, RTFOFF off, void *pvBuf, size_t cbToRead, size_t *pcbRead);
+
+/**
+ * Write bytes to the file at the current position.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_ACCESS_DENIED if the file is not writable.
+ *
+ * @param hVfsFile The VFS file handle.
+ * @param pvBuf The bytes to write.
+ * @param cbToWrite The number of bytes to write.
+ * @param fBlocking Whether the call is blocking (@c true) or not. If
+ * not, the @a pcbWritten parameter must not be NULL.
+ * @param pcbRead Where to always store the number of bytes actually
+ * written. This can be NULL if @a fBlocking is true.
+ * @sa RTVfsIoStrmRead, RTFileWrite, RTPipeWrite, RTPipeWriteBlocking,
+ * RTSocketWrite
+ */
+RTDECL(int) RTVfsFileWrite(RTVFSFILE hVfsFile, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+RTDECL(int) RTVfsFileWriteAt(RTVFSFILE hVfsFile, RTFOFF off, const void *pvBuf, size_t cbToWrite, size_t *pcbWritten);
+
+/**
+ * Flush any buffered data to the file.
+ *
+ * @returns IPRT status code.
+ * @param hVfsFile The VFS file handle.
+ * @sa RTVfsIoStrmFlush, RTFileFlush, RTPipeFlush
+ */
+RTDECL(int) RTVfsFileFlush(RTVFSFILE hVfsFile);
+
+/**
+ * Poll for events.
+ *
+ * @returns IPRT status code.
+ * @param hVfsFile The VFS file handle.
+ * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
+ * @param cMillies How long to wait for event to eventuate.
+ * @param fIntr Whether the wait is interruptible and can return
+ * VERR_INTERRUPTED (@c true) or if this condition
+ * should be hidden from the caller (@c false).
+ * @param pfRetEvents Where to return the event mask.
+ * @sa RTVfsIoStrmPoll, RTPollSetAdd, RTPoll, RTPollNoResume.
+ */
+RTDECL(RTFOFF) RTVfsFilePoll(RTVFSFILE hVfsFile, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+ uint32_t *pfRetEvents);
+
+/**
+ * Tells the current file position.
+ *
+ * @returns Zero or higher - where to return the file offset. Values
+ * below zero are IPRT status codes (VERR_XXX).
+ * @param hVfsFile The VFS file handle.
+ * @sa RTFileTell, RTVfsIoStrmTell.
+ */
+RTDECL(RTFOFF) RTVfsFileTell(RTVFSFILE hVfsFile);
+
+/**
+ * Changes the current read/write position of a file.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hVfsFile The VFS file handle.
+ * @param offSeek The seek offset.
+ * @param uMethod The seek emthod.
+ * @param poffActual Where to optionally return the new file offset.
+ *
+ * @sa RTFileSeek
+ */
+RTDECL(int) RTVfsFileSeek(RTVFSFILE hVfsFile, RTFOFF offSeek, uint32_t uMethod, uint64_t *poffActual);
+
+RTDECL(int) RTVfsFileSetSize(RTVFSFILE hVfsFile, uint64_t cbSize);
+RTDECL(int) RTVfsFileGetSize(RTVFSFILE hVfsFile, uint64_t *pcbSize);
+RTDECL(RTFOFF) RTVfsFileGetMaxSize(RTVFSFILE hVfsFile);
+RTDECL(int) RTVfsFileGetMaxSizeEx(RTVFSFILE hVfsFile, PRTFOFF pcbMax);
+
+/** @} */
+
+
+/** @defgroup grp_vfs_misc VFS Miscellaneous
+ * @{
+ */
+
+/**
+ * Memorizes the I/O stream as a file backed by memory.
+ *
+ * @returns VBox status code.
+ *
+ * @param hVfsIos The VFS I/O stream to memorize. This will be read
+ * to the end on success, on failure its position is
+ * undefined.
+ * @param fFlags A combination of RTFILE_O_READ and RTFILE_O_WRITE.
+ * @param phVfsFile Where to return the handle to the memory file on
+ * success.
+ */
+RTDECL(int) RTVfsMemorizeIoStreamAsFile(RTVFSIOSTREAM hVfsIos, uint32_t fFlags, PRTVFSFILE phVfsFile);
+
+
+/**
+ * Pumps data from one I/O stream to another.
+ *
+ * The data is read in chunks from @a hVfsIosSrc and written to @a hVfsIosDst
+ * until @hVfsIosSrc indicates end of stream.
+ *
+ * @returns IPRT status code
+ *
+ * @param hVfsIosSrc The input stream.
+ * @param hVfsIosDst The output stream.
+ * @param cbBufHint Hints at a good temporary buffer size, pass 0 if
+ * clueless.
+ */
+RTDECL(int) RTVfsUtilPumpIoStreams(RTVFSIOSTREAM hVfsIosSrc, RTVFSIOSTREAM hVfsIosDst, size_t cbBufHint);
+
+/** @} */
+
+
+/** @defgroup grp_rt_vfs_chain VFS Chains
+ *
+ * VFS chains is for doing pipe like things with VFS objects from the command
+ * line. Imagine you want to cat the readme.gz of an ISO you could do
+ * something like:
+ * RTCat :iprtvfs:vfs(isofs,./mycd.iso)|ios(open,readme.gz)|ios(gunzip)
+ * or
+ * RTCat :iprtvfs:ios(isofs,./mycd.iso,/readme.gz)|ios(gunzip)
+ *
+ * The "isofs", "open" and "gunzip" bits in the above examples are chain
+ * element providers registered with IPRT. See RTVFSCHAINELEMENTREG for how
+ * these works.
+ *
+ * @{ */
+
+/** The path prefix used to identify an VFS chain specification. */
+#define RTVFSCHAIN_SPEC_PREFIX ":iprtvfs:"
+
+RTDECL(int) RTVfsChainOpenVfs( const char *pszSpec, PRTVFS phVfs, const char **ppszError);
+RTDECL(int) RTVfsChainOpenFsStream( const char *pszSpec, PRTVFSFSSTREAM phVfsFss, const char **ppszError);
+RTDECL(int) RTVfsChainOpenDir( const char *pszSpec, uint64_t fOpen, PRTVFSDIR phVfsDir, const char **ppszError);
+RTDECL(int) RTVfsChainOpenFile( const char *pszSpec, uint64_t fOpen, PRTVFSFILE phVfsFile, const char **ppszError);
+RTDECL(int) RTVfsChainOpenSymlink( const char *pszSpec, PRTVFSSYMLINK phVfsSym, const char **ppszError);
+RTDECL(int) RTVfsChainOpenIoStream( const char *pszSpec, uint64_t fOpen, PRTVFSIOSTREAM phVfsIos, const char **ppszError);
+
+/**
+ * Tests if the given string is a chain specification or not.
+ *
+ * @returns true if it is, false if it isn't.
+ * @param pszSpec The alleged chain spec.
+ */
+RTDECL(bool) RTVfsChainIsSpec(const char *pszSpec);
+
+/** @} */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !___iprt_vfs_h */
+
diff --git a/include/iprt/vfslowlevel.h b/include/iprt/vfslowlevel.h
new file mode 100644
index 00000000..d5208cf4
--- /dev/null
+++ b/include/iprt/vfslowlevel.h
@@ -0,0 +1,1236 @@
+/** @file
+ * IPRT - Virtual Filesystem.
+ */
+
+/*
+ * 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 ___iprt_vfslowlevel_h
+#define ___iprt_vfslowlevel_h
+
+#include <iprt/vfs.h>
+#include <iprt/err.h>
+#include <iprt/list.h>
+#include <iprt/param.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_vfs_lowlevel RTVfs - Low-level Interface.
+ * @ingroup grp_rt_vfs
+ * @{
+ */
+
+
+/** @name VFS Lock Abstraction
+ * @todo This should be moved somewhere else as it is of general use.
+ * @{ */
+
+/**
+ * VFS lock types.
+ */
+typedef enum RTVFSLOCKTYPE
+{
+ /** Invalid lock type. */
+ RTVFSLOCKTYPE_INVALID = 0,
+ /** Read write semaphore. */
+ RTVFSLOCKTYPE_RW,
+ /** Fast mutex semaphore (critical section in ring-3). */
+ RTVFSLOCKTYPE_FASTMUTEX,
+ /** Full fledged mutex semaphore. */
+ RTVFSLOCKTYPE_MUTEX,
+ /** The end of valid lock types. */
+ RTVFSLOCKTYPE_END,
+ /** The customary 32-bit type hack. */
+ RTVFSLOCKTYPE_32BIT_HACK = 0x7fffffff
+} RTVFSLOCKTYPE;
+
+/** VFS lock handle. */
+typedef struct RTVFSLOCKINTERNAL *RTVFSLOCK;
+/** Pointer to a VFS lock handle. */
+typedef RTVFSLOCK *PRTVFSLOCK;
+/** Nil VFS lock handle. */
+#define NIL_RTVFSLOCK ((RTVFSLOCK)~(uintptr_t)0)
+
+/** Special handle value for creating a new read/write semaphore based lock. */
+#define RTVFSLOCK_CREATE_RW ((RTVFSLOCK)~(uintptr_t)1)
+/** Special handle value for creating a new fast mutex semaphore based lock. */
+#define RTVFSLOCK_CREATE_FASTMUTEX ((RTVFSLOCK)~(uintptr_t)2)
+/** Special handle value for creating a new mutex semaphore based lock. */
+#define RTVFSLOCK_CREATE_MUTEX ((RTVFSLOCK)~(uintptr_t)3)
+
+/**
+ * Retains a reference to the VFS lock handle.
+ *
+ * @returns New reference count on success, UINT32_MAX on failure.
+ * @param hLock The VFS lock handle.
+ */
+RTDECL(uint32_t) RTVfsLockRetain(RTVFSLOCK hLock);
+
+/**
+ * Releases a reference to the VFS lock handle.
+ *
+ * @returns New reference count on success (0 if closed), UINT32_MAX on failure.
+ * @param hLock The VFS lock handle.
+ */
+RTDECL(uint32_t) RTVfsLockRelease(RTVFSLOCK hLock);
+
+/**
+ * Gets the lock type.
+ *
+ * @returns The lock type on success, RTVFSLOCKTYPE_INVALID if the handle is
+ * not valid.
+ * @param hLock The lock handle.
+ */
+RTDECL(RTVFSLOCKTYPE) RTVfsLockGetType(RTVFSLOCK hLock);
+
+
+
+RTDECL(void) RTVfsLockAcquireReadSlow(RTVFSLOCK hLock);
+RTDECL(void) RTVfsLockReleaseReadSlow(RTVFSLOCK hLock);
+RTDECL(void) RTVfsLockAcquireWriteSlow(RTVFSLOCK hLock);
+RTDECL(void) RTVfsLockReleaseWriteSlow(RTVFSLOCK hLock);
+
+/**
+ * Acquire a read lock.
+ *
+ * @param hLock The lock handle, can be NIL.
+ */
+DECLINLINE(void) RTVfsLockAcquireRead(RTVFSLOCK hLock)
+{
+ if (hLock != NIL_RTVFSLOCK)
+ RTVfsLockAcquireReadSlow(hLock);
+}
+
+
+/**
+ * Release a read lock.
+ *
+ * @param hLock The lock handle, can be NIL.
+ */
+DECLINLINE(void) RTVfsLockReleaseRead(RTVFSLOCK hLock)
+{
+ if (hLock != NIL_RTVFSLOCK)
+ RTVfsLockReleaseReadSlow(hLock);
+}
+
+
+/**
+ * Acquire a write lock.
+ *
+ * @param hLock The lock handle, can be NIL.
+ */
+DECLINLINE(void) RTVfsLockAcquireWrite(RTVFSLOCK hLock)
+{
+ if (hLock != NIL_RTVFSLOCK)
+ RTVfsLockAcquireWriteSlow(hLock);
+}
+
+
+/**
+ * Release a write lock.
+ *
+ * @param hLock The lock handle, can be NIL.
+ */
+DECLINLINE(void) RTVfsLockReleaseWrite(RTVFSLOCK hLock)
+{
+ if (hLock != NIL_RTVFSLOCK)
+ RTVfsLockReleaseWriteSlow(hLock);
+}
+
+/** @} */
+
+/**
+ * The VFS operations.
+ */
+typedef struct RTVFSOPS
+{
+ /** The structure version (RTVFSOPS_VERSION). */
+ uint32_t uVersion;
+ /** The virtual file system feature mask. */
+ uint32_t fFeatures;
+ /** The name of the operations. */
+ const char *pszName;
+
+ /**
+ * Destructor.
+ *
+ * @param pvThis The implementation specific data.
+ */
+ DECLCALLBACKMEMBER(void, pfnDestroy)(void *pvThis);
+
+ /**
+ * Opens the root directory.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific data.
+ * @param phVfsDir Where to return the handle to the root directory.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenRoot)(void *pvThis, PRTVFSDIR phVfsDir);
+
+ /**
+ * Checks whether a given range in the underlying medium
+ * is in use by the virtual filesystem.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific data.
+ * @param off Start offset to check.
+ * @param cb Number of bytes to check.
+ * @param pfUsed Where to store whether the given range is in use.
+ */
+ DECLCALLBACKMEMBER(int, pfnIsRangeInUse)(void *pvThis, RTFOFF off, size_t cb,
+ bool *pfUsed);
+
+ /** @todo There will be more methods here to optimize opening and
+ * querying. */
+
+#if 0
+ /**
+ * Optional entry point for optimizing path traversal within the file system.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific data.
+ * @param pszPath The path to resolve.
+ * @param poffPath The current path offset on input, what we've
+ * traversed to on successful return.
+ * @param phVfs??? Return handle to what we've traversed.
+ * @param p??? Return other stuff...
+ */
+ DECLCALLBACKMEMBER(int, pfnTraverse)(void *pvThis, const char *pszPath, size_t *poffPath, PRTVFS??? phVfs?, ???* p???);
+#endif
+
+ /** Marks the end of the structure (RTVFSOPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSOPS;
+/** Pointer to constant VFS operations. */
+typedef RTVFSOPS const *PCRTVFSOPS;
+
+/** The RTVFSOPS structure version. */
+#define RTVFSOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x0f,1,0)
+
+/** @name RTVFSOPS::fFeatures
+ * @{ */
+/** The VFS supports attaching other systems. */
+#define RTVFSOPS_FEAT_ATTACH RT_BIT_32(0)
+/** @} */
+
+/**
+ * Creates a new VFS handle.
+ *
+ * @returns IPRT status code
+ * @param pVfs Ops The VFS operations.
+ * @param cbInstance The size of the instance data.
+ * @param hVfs The VFS handle to associate this VFS with.
+ * NIL_VFS is ok.
+ * @param hLock Handle to a custom lock to be used with the new
+ * object. The reference is consumed. NIL and
+ * special lock handles are fine.
+ * @param phVfs Where to return the new handle.
+ * @param ppvInstance Where to return the pointer to the instance data
+ * (size is @a cbInstance).
+ */
+RTDECL(int) RTVfsNew(PCRTVFSOPS pVfsOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
+ PRTVFS phVfs, void **ppvInstance);
+
+/**
+ * The basis for all virtual file system objects except RTVFS.
+ */
+typedef struct RTVFSOBJOPS
+{
+ /** The structure version (RTVFSOBJOPS_VERSION). */
+ uint32_t uVersion;
+ /** The object type for type introspection. */
+ RTVFSOBJTYPE enmType;
+ /** The name of the operations. */
+ const char *pszName;
+
+ /**
+ * Close the object.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ */
+ DECLCALLBACKMEMBER(int, pfnClose)(void *pvThis);
+
+ /**
+ * Get information about the file.
+ *
+ * @returns IPRT status code. See RTVfsObjQueryInfo.
+ * @param pvThis The implementation specific file data.
+ * @param pObjInfo Where to return the object info on success.
+ * @param enmAddAttr Which set of additional attributes to request.
+ * @sa RTVfsObjQueryInfo, RTFileQueryInfo, RTPathQueryInfo
+ */
+ DECLCALLBACKMEMBER(int, pfnQueryInfo)(void *pvThis, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAddAttr);
+
+ /** Marks the end of the structure (RTVFSOBJOPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSOBJOPS;
+/** Pointer to constant VFS object operations. */
+typedef RTVFSOBJOPS const *PCRTVFSOBJOPS;
+
+/** The RTVFSOBJOPS structure version. */
+#define RTVFSOBJOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x1f,1,0)
+
+
+/**
+ * Creates a new VFS base object handle.
+ *
+ * @returns IPRT status code
+ * @param pObjOps The base object operations.
+ * @param cbInstance The size of the instance data.
+ * @param hVfs The VFS handle to associate this base object
+ * with. NIL_VFS is ok.
+ * @param hLock Handle to a custom lock to be used with the new
+ * object. The reference is consumed. NIL and
+ * special lock handles are fine.
+ * @param phVfsFss Where to return the new handle.
+ * @param ppvInstance Where to return the pointer to the instance data
+ * (size is @a cbInstance).
+ */
+RTDECL(int) RTVfsNewBaseObj(PCRTVFSOBJOPS pObjOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
+ PRTVFSOBJ phVfsObj, void **ppvInstance);
+
+
+/**
+ * Additional operations for setting object attributes.
+ */
+typedef struct RTVFSOBJSETOPS
+{
+ /** The structure version (RTVFSOBJSETOPS_VERSION). */
+ uint32_t uVersion;
+ /** The offset to the RTVFSOBJOPS structure. */
+ int32_t offObjOps;
+
+ /**
+ * Set the unix style owner and group.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param fMode The new mode bits.
+ * @param fMask The mask indicating which bits we are
+ * changing.
+ * @sa RTFileSetMode
+ */
+ DECLCALLBACKMEMBER(int, pfnSetMode)(void *pvThis, RTFMODE fMode, RTFMODE fMask);
+
+ /**
+ * Set the timestamps associated with the object.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param pAccessTime Pointer to the new access time. NULL if not
+ * to be changed.
+ * @param pModificationTime Pointer to the new modifcation time. NULL if
+ * not to be changed.
+ * @param pChangeTime Pointer to the new change time. NULL if not
+ * to be changed.
+ * @param pBirthTime Pointer to the new time of birth. NULL if
+ * not to be changed.
+ * @remarks See RTFileSetTimes for restrictions and behavior imposed by the
+ * host OS or underlying VFS provider.
+ * @sa RTFileSetTimes
+ */
+ DECLCALLBACKMEMBER(int, pfnSetTimes)(void *pvThis, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime,
+ PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime);
+
+ /**
+ * Set the unix style owner and group.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param uid The user ID of the new owner. NIL_RTUID if
+ * unchanged.
+ * @param gid The group ID of the new owner group. NIL_RTGID if
+ * unchanged.
+ * @sa RTFileSetOwner
+ */
+ DECLCALLBACKMEMBER(int, pfnSetOwner)(void *pvThis, RTUID uid, RTGID gid);
+
+ /** Marks the end of the structure (RTVFSOBJSETOPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSOBJSETOPS;
+/** Pointer to const object attribute setter operations. */
+typedef RTVFSOBJSETOPS const *PCRTVFSOBJSETOPS;
+
+/** The RTVFSOBJSETOPS structure version. */
+#define RTVFSOBJSETOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x2f,1,0)
+
+
+/**
+ * The filesystem stream operations.
+ *
+ * @extends RTVFSOBJOPS
+ */
+typedef struct RTVFSFSSTREAMOPS
+{
+ /** The basic object operation. */
+ RTVFSOBJOPS Obj;
+ /** The structure version (RTVFSFSSTREAMOPS_VERSION). */
+ uint32_t uVersion;
+ /** Reserved field, MBZ. */
+ uint32_t fReserved;
+
+ /**
+ * Gets the next object in the stream.
+ *
+ * @returns IPRT status code.
+ * @retval VINF_SUCCESS if a new object was retrieved.
+ * @retval VERR_EOF when there are no more objects.
+ * @param pvThis The implementation specific directory data.
+ * @param ppszName Where to return the object name. Must be freed by
+ * calling RTStrFree.
+ * @param penmType Where to return the object type.
+ * @param hVfsObj Where to return the object handle (referenced).
+ * This must be cast to the desired type before use.
+ * @sa RTVfsFsStrmNext
+ */
+ DECLCALLBACKMEMBER(int, pfnNext)(void *pvThis, char **ppszName, RTVFSOBJTYPE *penmType, PRTVFSOBJ phVfsObj);
+
+ /** Marks the end of the structure (RTVFSFSSTREAMOPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSFSSTREAMOPS;
+/** Pointer to const object attribute setter operations. */
+typedef RTVFSFSSTREAMOPS const *PCRTVFSFSSTREAMOPS;
+
+/** The RTVFSFSSTREAMOPS structure version. */
+#define RTVFSFSSTREAMOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x3f,1,0)
+
+
+/**
+ * Creates a new VFS filesystem stream handle.
+ *
+ * @returns IPRT status code
+ * @param pFsStreamOps The filesystem stream operations.
+ * @param cbInstance The size of the instance data.
+ * @param hVfs The VFS handle to associate this filesystem
+ * stream with. NIL_VFS is ok.
+ * @param hLock Handle to a custom lock to be used with the new
+ * object. The reference is consumed. NIL and
+ * special lock handles are fine.
+ * @param phVfsFss Where to return the new handle.
+ * @param ppvInstance Where to return the pointer to the instance data
+ * (size is @a cbInstance).
+ */
+RTDECL(int) RTVfsNewFsStream(PCRTVFSFSSTREAMOPS pFsStreamOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
+ PRTVFSFSSTREAM phVfsFss, void **ppvInstance);
+
+
+/**
+ * The directory operations.
+ *
+ * @extends RTVFSOBJOPS
+ * @extends RTVFSOBJSETOPS
+ */
+typedef struct RTVFSDIROPS
+{
+ /** The basic object operation. */
+ RTVFSOBJOPS Obj;
+ /** The structure version (RTVFSDIROPS_VERSION). */
+ uint32_t uVersion;
+ /** Reserved field, MBZ. */
+ uint32_t fReserved;
+ /** The object setter operations. */
+ RTVFSOBJSETOPS ObjSet;
+
+ /**
+ * Opens a directory entry for traversal purposes.
+ *
+ * Method which sole purpose is helping the path traversal. Only one of
+ * the three output variables will be set, the others will left untouched
+ * (caller sets them to NIL).
+ *
+ * @returns IPRT status code.
+ * @retval VERR_PATH_NOT_FOUND if @a pszEntry was not found.
+ * @param pvThis The implementation specific directory data.
+ * @param pszEntry The name of the directory entry to remove.
+ * @param phVfsDir If not NULL and it is a directory, open it and
+ * return the handle here.
+ * @param phVfsSymlink If not NULL and it is a symbolic link, open it
+ * and return the handle here.
+ * @param phVfsMounted If not NULL and it is a mounted VFS directory,
+ * reference it and return the handle here.
+ * @todo Should com dir, symlinks and mount points using some common
+ * ancestor "class".
+ */
+ DECLCALLBACKMEMBER(int, pfnTraversalOpen)(void *pvThis, const char *pszEntry, PRTVFSDIR phVfsDir,
+ PRTVFSSYMLINK phVfsSymlink, PRTVFS phVfsMounted);
+
+ /**
+ * Open or create a file.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ * @param pszFilename The name of the immediate file to open or create.
+ * @param fOpen The open flags (RTFILE_O_XXX).
+ * @param phVfsFile Where to return the thandle to the opened file.
+ * @sa RTFileOpen.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenFile)(void *pvThis, const char *pszFilename, uint32_t fOpen, PRTVFSFILE phVfsFile);
+
+ /**
+ * Open an existing subdirectory.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ * @param pszSubDir The name of the immediate subdirectory to open.
+ * @param phVfsDir Where to return the handle to the opened directory.
+ * @sa RTDirOpen.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenDir)(void *pvThis, const char *pszSubDir, PRTVFSDIR phVfsDir);
+
+ /**
+ * Creates a new subdirectory.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ * @param pszSubDir The name of the immediate subdirectory to create.
+ * @param fMode The mode mask of the new directory.
+ * @param phVfsDir Where to optionally return the handle to the newly
+ * create directory.
+ * @sa RTDirCreate.
+ */
+ DECLCALLBACKMEMBER(int, pfnCreateDir)(void *pvThis, const char *pszSubDir, RTFMODE fMode, PRTVFSDIR phVfsDir);
+
+ /**
+ * Opens an existing symbolic link.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ * @param pszSymlink The name of the immediate symbolic link to open.
+ * @param phVfsSymlink Where to optionally return the handle to the
+ * newly create symbolic link.
+ * @sa RTSymlinkCreate.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenSymlink)(void *pvThis, const char *pszSymlink, PRTVFSSYMLINK phVfsSymlink);
+
+ /**
+ * Creates a new symbolic link.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ * @param pszSymlink The name of the immediate symbolic link to create.
+ * @param pszTarget The symbolic link target.
+ * @param enmType The symbolic link type.
+ * @param phVfsSymlink Where to optionally return the handle to the
+ * newly create symbolic link.
+ * @sa RTSymlinkCreate.
+ */
+ DECLCALLBACKMEMBER(int, pfnCreateSymlink)(void *pvThis, const char *pszSymlink, const char *pszTarget,
+ RTSYMLINKTYPE enmType, PRTVFSSYMLINK phVfsSymlink);
+
+ /**
+ * Removes a directory entry.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ * @param pszEntry The name of the directory entry to remove.
+ * @param fType If non-zero, this restricts the type of the entry to
+ * the object type indicated by the mask
+ * (RTFS_TYPE_XXX).
+ * @sa RTFileRemove, RTDirRemove, RTSymlinkRemove.
+ */
+ DECLCALLBACKMEMBER(int, pfnUnlinkEntry)(void *pvThis, const char *pszEntry, RTFMODE fType, PRTVFSDIR phVfsDir);
+
+ /**
+ * Rewind the directory stream so that the next read returns the first
+ * entry.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ */
+ DECLCALLBACKMEMBER(int, pfnRewindDir)(void *pvThis);
+
+ /**
+ * Rewind the directory stream so that the next read returns the first
+ * entry.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific directory data.
+ * @param pDirEntry Output buffer.
+ * @param pcbDirEntry Complicated, see RTDirReadEx.
+ * @param enmAddAttr Which set of additional attributes to request.
+ * @sa RTDirReadEx
+ */
+ DECLCALLBACKMEMBER(int, pfnReadDir)(void *pvThis, PRTDIRENTRYEX pDirEntry, size_t *pcbDirEntry, RTFSOBJATTRADD enmAddAttr);
+
+ /** Marks the end of the structure (RTVFSDIROPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSDIROPS;
+/** Pointer to const directory operations. */
+typedef RTVFSDIROPS const *PCRTVFSDIROPS;
+/** The RTVFSDIROPS structure version. */
+#define RTVFSDIROPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x4f,1,0)
+
+
+/**
+ * The symbolic link operations.
+ *
+ * @extends RTVFSOBJOPS
+ * @extends RTVFSOBJSETOPS
+ */
+typedef struct RTVFSSYMLINKOPS
+{
+ /** The basic object operation. */
+ RTVFSOBJOPS Obj;
+ /** The structure version (RTVFSSYMLINKOPS_VERSION). */
+ uint32_t uVersion;
+ /** Reserved field, MBZ. */
+ uint32_t fReserved;
+ /** The object setter operations. */
+ RTVFSOBJSETOPS ObjSet;
+
+ /**
+ * Read the symbolic link target.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific symbolic link data.
+ * @param pszTarget The target buffer.
+ * @param cbTarget The size of the target buffer.
+ * @sa RTSymlinkRead
+ */
+ DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, char *pszTarget, size_t cbTarget);
+
+ /** Marks the end of the structure (RTVFSSYMLINKOPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSSYMLINKOPS;
+/** Pointer to const symbolic link operations. */
+typedef RTVFSSYMLINKOPS const *PCRTVFSSYMLINKOPS;
+/** The RTVFSSYMLINKOPS structure version. */
+#define RTVFSSYMLINKOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x5f,1,0)
+
+
+/**
+ * Creates a new VFS symlink handle.
+ *
+ * @returns IPRT status code
+ * @param pSymlinkOps The symlink operations.
+ * @param cbInstance The size of the instance data.
+ * @param hVfs The VFS handle to associate this symlink object
+ * with. NIL_VFS is ok.
+ * @param hLock Handle to a custom lock to be used with the new
+ * object. The reference is consumed. NIL and
+ * special lock handles are fine.
+ * @param phVfsSym Where to return the new handle.
+ * @param ppvInstance Where to return the pointer to the instance data
+ * (size is @a cbInstance).
+ */
+RTDECL(int) RTVfsNewSymlink(PCRTVFSSYMLINKOPS pSymlinkOps, size_t cbInstance, RTVFS hVfs, RTVFSLOCK hLock,
+ PRTVFSSYMLINK phVfsSym, void **ppvInstance);
+
+
+/**
+ * The basis for all I/O objects (files, pipes, sockets, devices, ++).
+ *
+ * @extends RTVFSOBJOPS
+ */
+typedef struct RTVFSIOSTREAMOPS
+{
+ /** The basic object operation. */
+ RTVFSOBJOPS Obj;
+ /** The structure version (RTVFSIOSTREAMOPS_VERSION). */
+ uint32_t uVersion;
+ /** Feature field. */
+ uint32_t fFeatures;
+
+ /**
+ * Reads from the file/stream.
+ *
+ * @returns IPRT status code. See RTVfsIoStrmRead.
+ * @param pvThis The implementation specific file data.
+ * @param off Where to read at, -1 for the current position.
+ * @param pSgBuf Gather buffer describing the bytes that are to be
+ * written.
+ * @param fBlocking If @c true, the call is blocking, if @c false it
+ * should not block.
+ * @param pcbRead Where return the number of bytes actually read.
+ * This is set it 0 by the caller. If NULL, try read
+ * all and fail if incomplete.
+ * @sa RTVfsIoStrmRead, RTVfsIoStrmSgRead, RTVfsFileRead,
+ * RTVfsFileReadAt, RTFileRead, RTFileReadAt.
+ */
+ DECLCALLBACKMEMBER(int, pfnRead)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbRead);
+
+ /**
+ * Writes to the file/stream.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param off Where to start wrinting, -1 for the current
+ * position.
+ * @param pSgBuf Gather buffers describing the bytes that are to be
+ * written.
+ * @param fBlocking If @c true, the call is blocking, if @c false it
+ * should not block.
+ * @param pcbWritten Where to return the number of bytes actually
+ * written. This is set it 0 by the caller. If
+ * NULL, try write it all and fail if incomplete.
+ * @sa RTFileWrite, RTFileWriteAt.
+ */
+ DECLCALLBACKMEMBER(int, pfnWrite)(void *pvThis, RTFOFF off, PCRTSGBUF pSgBuf, bool fBlocking, size_t *pcbWritten);
+
+ /**
+ * Flushes any pending data writes to the stream.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @sa RTFileFlush.
+ */
+ DECLCALLBACKMEMBER(int, pfnFlush)(void *pvThis);
+
+ /**
+ * Poll for events.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
+ * @param cMillies How long to wait for event to eventuate.
+ * @param fIntr Whether the wait is interruptible and can return
+ * VERR_INTERRUPTED (@c true) or if this condition
+ * should be hidden from the caller (@c false).
+ * @param pfRetEvents Where to return the event mask.
+ * @sa RTPollSetAdd, RTPoll, RTPollNoResume.
+ */
+ DECLCALLBACKMEMBER(int, pfnPollOne)(void *pvThis, uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr,
+ uint32_t *pfRetEvents);
+
+ /**
+ * Tells the current file/stream position.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param poffActual Where to return the actual offset.
+ * @sa RTFileTell
+ */
+ DECLCALLBACKMEMBER(int, pfnTell)(void *pvThis, PRTFOFF poffActual);
+
+ /**
+ * Skips @a cb ahead in the stream.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param cb The number bytes to skip.
+ * @remarks This is optional and can be NULL.
+ */
+ DECLCALLBACKMEMBER(int, pfnSkip)(void *pvThis, RTFOFF cb);
+
+ /**
+ * Fills the stream with @a cb zeros.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param cb The number of zero bytes to insert.
+ * @remarks This is optional and can be NULL.
+ */
+ DECLCALLBACKMEMBER(int, pfnZeroFill)(void *pvThis, RTFOFF cb);
+
+ /** Marks the end of the structure (RTVFSIOSTREAMOPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSIOSTREAMOPS;
+/** Pointer to const I/O stream operations. */
+typedef RTVFSIOSTREAMOPS const *PCRTVFSIOSTREAMOPS;
+
+/** The RTVFSIOSTREAMOPS structure version. */
+#define RTVFSIOSTREAMOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x6f,1,0)
+
+/** @name RTVFSIOSTREAMOPS::fFeatures
+ * @{ */
+/** No scatter gather lists, thank you. */
+#define RTVFSIOSTREAMOPS_FEAT_NO_SG RT_BIT_32(0)
+/** Mask of the valid I/O stream feature flags. */
+#define RTVFSIOSTREAMOPS_FEAT_VALID_MASK UINT32_C(0x00000001)
+/** @} */
+
+
+/**
+ * Creates a new VFS I/O stream handle.
+ *
+ * @returns IPRT status code
+ * @param pIoStreamOps The I/O stream operations.
+ * @param cbInstance The size of the instance data.
+ * @param fOpen The open flags. The minimum is the access mask.
+ * @param hVfs The VFS handle to associate this I/O stream
+ * with. NIL_VFS is ok.
+ * @param hLock Handle to a custom lock to be used with the new
+ * object. The reference is consumed. NIL and
+ * special lock handles are fine.
+ * @param phVfsIos Where to return the new handle.
+ * @param ppvInstance Where to return the pointer to the instance data
+ * (size is @a cbInstance).
+ */
+RTDECL(int) RTVfsNewIoStream(PCRTVFSIOSTREAMOPS pIoStreamOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
+ PRTVFSIOSTREAM phVfsIos, void **ppvInstance);
+
+
+/**
+ * Gets the private data of an I/O stream.
+ *
+ * @returns Pointer to the private data. NULL if the handle is invalid in some
+ * way.
+ * @param hVfsIos The I/O stream handle.
+ * @param pIoStreamOps The I/O stream operations. This servers as a
+ * sort of password.
+ */
+RTDECL(void *) RTVfsIoStreamToPrivate(RTVFSIOSTREAM hVfsIos, PCRTVFSIOSTREAMOPS pIoStreamOps);
+
+
+/**
+ * The file operations.
+ *
+ * @extends RTVFSIOSTREAMOPS
+ * @extends RTVFSOBJSETOPS
+ */
+typedef struct RTVFSFILEOPS
+{
+ /** The I/O stream and basis object operations. */
+ RTVFSIOSTREAMOPS Stream;
+ /** The structure version (RTVFSFILEOPS_VERSION). */
+ uint32_t uVersion;
+ /** Reserved field, MBZ. */
+ uint32_t fReserved;
+ /** The object setter operations. */
+ RTVFSOBJSETOPS ObjSet;
+
+ /**
+ * Changes the current file position.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param offSeek The offset to seek.
+ * @param uMethod The seek method, i.e. what the seek is relative to.
+ * @param poffActual Where to return the actual offset.
+ * @sa RTFileSeek
+ */
+ DECLCALLBACKMEMBER(int, pfnSeek)(void *pvThis, RTFOFF offSeek, unsigned uMethod, PRTFOFF poffActual);
+
+ /**
+ * Get the current file/stream size.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param pcbFile Where to store the current file size.
+ * @sa RTFileGetSize
+ */
+ DECLCALLBACKMEMBER(int, pfnQuerySize)(void *pvThis, uint64_t *pcbFile);
+
+ /** @todo There will be more methods here. */
+
+ /** Marks the end of the structure (RTVFSFILEOPS_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSFILEOPS;
+/** Pointer to const file operations. */
+typedef RTVFSFILEOPS const *PCRTVFSFILEOPS;
+
+/** The RTVFSFILEOPS structure version. */
+#define RTVFSFILEOPS_VERSION RT_MAKE_U32_FROM_U8(0xff,0x7f,1,0)
+
+/**
+ * Creates a new VFS file handle.
+ *
+ * @returns IPRT status code
+ * @param pFileOps The file operations.
+ * @param cbInstance The size of the instance data.
+ * @param fOpen The open flags. The minimum is the access mask.
+ * @param hVfs The VFS handle to associate this file with.
+ * NIL_VFS is ok.
+ * @param hLock Handle to a custom lock to be used with the new
+ * object. The reference is consumed. NIL and
+ * special lock handles are fine.
+ * @param phVfsFile Where to return the new handle.
+ * @param ppvInstance Where to return the pointer to the instance data
+ * (size is @a cbInstance).
+ */
+RTDECL(int) RTVfsNewFile(PCRTVFSFILEOPS pFileOps, size_t cbInstance, uint32_t fOpen, RTVFS hVfs, RTVFSLOCK hLock,
+ PRTVFSFILE phVfsFile, void **ppvInstance);
+
+
+/** @defgroup grp_rt_vfs_ll_util VFS Utility APIs
+ * @{ */
+
+/**
+ * Parsed path.
+ */
+typedef struct RTVFSPARSEDPATH
+{
+ /** The length of the path in szCopy. */
+ uint16_t cch;
+ /** The number of path components. */
+ uint16_t cComponents;
+ /** Set if the path ends with slash, indicating that it's a directory
+ * reference and not a file reference. The slash has been removed from
+ * the copy. */
+ bool fDirSlash;
+ /** The offset where each path component starts, i.e. the char after the
+ * slash. The array has cComponents + 1 entries, where the final one is
+ * cch + 1 so that one can always terminate the current component by
+ * szPath[aoffComponent[i] - 1] = '\0'. */
+ uint16_t aoffComponents[RTPATH_MAX / 2 + 1];
+ /** A normalized copy of the path.
+ * Reserve some extra space so we can be more relaxed about overflow
+ * checks and terminator paddings, especially when recursing. */
+ char szPath[RTPATH_MAX];
+} RTVFSPARSEDPATH;
+/** Pointer to a parsed path. */
+typedef RTVFSPARSEDPATH *PRTVFSPARSEDPATH;
+
+/** The max accepted path length.
+ * This must be a few chars shorter than RTVFSPARSEDPATH::szPath because we
+ * use two terminators and wish be a little bit lazy with checking. */
+#define RTVFSPARSEDPATH_MAX (RTPATH_MAX - 4)
+
+/**
+ * Appends @a pszPath (relative) to the already parsed path @a pPath.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_FILENAME_TOO_LONG
+ * @retval VERR_INTERNAL_ERROR_4
+ * @param pPath The parsed path to append @a pszPath onto.
+ * This is both input and output.
+ * @param pszPath The path to append. This must be relative.
+ * @param piRestartComp The component to restart parsing at. This is
+ * input/output. The input does not have to be
+ * within the valid range. Optional.
+ */
+RTDECL(int) RTVfsParsePathAppend(PRTVFSPARSEDPATH pPath, const char *pszPath, uint16_t *piRestartComp);
+
+/**
+ * Parses a path.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_FILENAME_TOO_LONG
+ * @param pPath Where to store the parsed path.
+ * @param pszPath The path to parse. Absolute or relative to @a
+ * pszCwd.
+ * @param pszCwd The current working directory. Must be
+ * absolute.
+ */
+RTDECL(int) RTVfsParsePath(PRTVFSPARSEDPATH pPath, const char *pszPath, const char *pszCwd);
+
+/**
+ * Same as RTVfsParsePath except that it allocates a temporary buffer.
+ *
+ * @retval VINF_SUCCESS
+ * @retval VERR_NO_TMP_MEMORY
+ * @retval VERR_FILENAME_TOO_LONG
+ * @param pszPath The path to parse. Absolute or relative to @a
+ * pszCwd.
+ * @param pszCwd The current working directory. Must be
+ * absolute.
+ * @param ppPath Where to store the pointer to the allocated
+ * buffer containing the parsed path. This must
+ * be freed by calling RTVfsParsePathFree. NULL
+ * will be stored on failured.
+ */
+RTDECL(int) RTVfsParsePathA(const char *pszPath, const char *pszCwd, PRTVFSPARSEDPATH *ppPath);
+
+/**
+ * Frees a buffer returned by RTVfsParsePathA.
+ *
+ * @param pPath The parsed path buffer to free. NULL is fine.
+ */
+RTDECL(void) RTVfsParsePathFree(PRTVFSPARSEDPATH pPath);
+
+/**
+ * Dummy implementation of RTVFSIOSTREAMOPS::pfnPollOne.
+ *
+ * This handles the case where there is no chance any events my be raised and
+ * all that is required is to wait according to the parameters.
+ *
+ * @returns IPRT status code.
+ * @param pvThis The implementation specific file data.
+ * @param fEvents The events to poll for (RTPOLL_EVT_XXX).
+ * @param cMillies How long to wait for event to eventuate.
+ * @param fIntr Whether the wait is interruptible and can return
+ * VERR_INTERRUPTED (@c true) or if this condition
+ * should be hidden from the caller (@c false).
+ * @param pfRetEvents Where to return the event mask.
+ * @sa RTVFSIOSTREAMOPS::pfnPollOne, RTPollSetAdd, RTPoll, RTPollNoResume.
+ */
+RTDECL(int) RTVfsUtilDummyPollOne(uint32_t fEvents, RTMSINTERVAL cMillies, bool fIntr, uint32_t *pfRetEvents);
+
+/** @} */
+
+
+/** @defgroup grp_rt_vfs_lowlevel_chain VFS Chains
+ * @ref grp_rt_vfs_chain
+ * @{
+ */
+
+
+/**
+ * Chain element input actions.
+ */
+typedef enum RTVFSCHAINACTION
+{
+ /** Invalid action. */
+ RTVFSCHAINACTION_INVALID = 0,
+ /** No action (start of the chain). */
+ RTVFSCHAINACTION_NONE,
+ /** Passive filtering (expressed by pipe symbol). */
+ RTVFSCHAINACTION_PASSIVE,
+ /** Push filtering (expressed by redirection-out symbol). */
+ RTVFSCHAINACTION_PUSH,
+ /** The end of the valid actions. */
+ RTVFSCHAINACTION_END,
+ /** Make sure it's a 32-bit type. */
+ RTVFSCHAINACTION_32BIT_HACK = 0x7fffffff
+} RTVFSCHAINACTION;
+
+
+/**
+ * VFS chain element specification.
+ */
+typedef struct RTVFSCHAINELEMSPEC
+{
+ /** The provider name. */
+ char *pszProvider;
+ /** The input type. */
+ RTVFSOBJTYPE enmTypeIn;
+ /** The output type. */
+ RTVFSOBJTYPE enmTypeOut;
+ /** The action to take (or not). */
+ RTVFSCHAINACTION enmAction;
+ /** The number of arguments. */
+ uint32_t cArgs;
+ /** Arguments. */
+ char **papszArgs;
+} RTVFSCHAINELEMSPEC;
+/** Pointer to a chain element specification. */
+typedef RTVFSCHAINELEMSPEC *PRTVFSCHAINELEMSPEC;
+/** Pointer to a const chain element specification. */
+typedef RTVFSCHAINELEMSPEC const *PCRTVFSCHAINELEMSPEC;
+
+
+/**
+ * Parsed VFS chain specification.
+ */
+typedef struct RTVFSCHAINSPEC
+{
+ /** The action element, UINT32_MAX if none.
+ * Currently we only support one action element (RTVFSCHAINACTION_PASSIVE
+ * is not considered). */
+ uint32_t iActionElement;
+ /** The number of elements. */
+ uint32_t cElements;
+ /** The elements. */
+ PRTVFSCHAINELEMSPEC paElements;
+} RTVFSCHAINSPEC;
+/** Pointer to a parsed VFS chain specification. */
+typedef RTVFSCHAINSPEC *PRTVFSCHAINSPEC;
+/** Pointer to a const, parsed VFS chain specification. */
+typedef RTVFSCHAINSPEC const *PCRTVFSCHAINSPEC;
+
+
+/**
+ * A chain element provider registration record.
+ */
+typedef struct RTVFSCHAINELEMENTREG
+{
+ /** The version (RTVFSCHAINELEMENTREG_VERSION). */
+ uint32_t uVersion;
+ /** Reserved, MBZ. */
+ uint32_t fReserved;
+ /** The provider name (unique). */
+ const char *pszName;
+ /** For chaining the providers. */
+ RTLISTNODE ListEntry;
+
+ /**
+ * Create a VFS from the given chain element specficiation.
+ *
+ * @returns IPRT status code.
+ * @param pSpec The chain element specification.
+ * @param phVfs Where to returned the VFS handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenVfs)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFS phVfs);
+
+ /**
+ * Open a directory from the given chain element specficiation.
+ *
+ * @returns IPRT status code.
+ * @param pSpec The chain element specification.
+ * @param phVfsDir Where to returned the directory handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenDir)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFSDIR phVfsDir);
+
+ /**
+ * Open a file from the given chain element specficiation.
+ *
+ * @returns IPRT status code.
+ * @param pSpec The chain element specification.
+ * @param fOpen The open flag. Can be zero and the
+ * specification may modify it.
+ * @param phVfsFile Where to returned the file handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenFile)( PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSFILE phVfsFile);
+
+ /**
+ * Open a symlink from the given chain element specficiation.
+ *
+ * @returns IPRT status code.
+ * @param pSpec The chain element specification.
+ * @param phVfsSym Where to returned the symlink handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenSymlink)( PCRTVFSCHAINELEMSPEC pSpec, PRTVFSSYMLINK phVfsSym);
+
+ /**
+ * Open a I/O stream from the given chain element specficiation.
+ *
+ * @returns IPRT status code.
+ * @param pSpec The chain element specification.
+ * @param fOpen The open flag. Can be zero and the
+ * specification may modify it.
+ * @param phVfsIos Where to returned the I/O stream handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenIoStream)(PCRTVFSCHAINELEMSPEC pSpec, uint32_t fOpen, PRTVFSIOSTREAM phVfsIos);
+
+ /**
+ * Open a filesystem stream from the given chain element specficiation.
+ *
+ * @returns IPRT status code.
+ * @param pSpec The chain element specification.
+ * @param phVfsFss Where to returned the filesystem stream handle.
+ */
+ DECLCALLBACKMEMBER(int, pfnOpenFsStream)(PCRTVFSCHAINELEMSPEC pSpec, PRTVFSFSSTREAM phVfsFss);
+
+ /** End marker (RTVFSCHAINELEMENTREG_VERSION). */
+ uintptr_t uEndMarker;
+} RTVFSCHAINELEMENTREG;
+/** Pointer to a VFS chain element registration record. */
+typedef RTVFSCHAINELEMENTREG *PRTVFSCHAINELEMENTREG;
+/** Pointer to a const VFS chain element registration record. */
+typedef RTVFSCHAINELEMENTREG const *PCRTVFSCHAINELEMENTREG;
+
+/** The VFS chain element registration record version number. */
+#define RTVFSCHAINELEMENTREG_VERSION RT_MAKE_U32_FROM_U8(0xff, 0x7f, 1, 0)
+
+
+/**
+ * Parses the specification.
+ *
+ * @returns IPRT status code.
+ * @param pszSpec The specification string to parse.
+ * @param fFlags Flags, see RTVFSCHAIN_PF_XXX.
+ * @param enmLeadingAction The only allowed leading action type.
+ * @param enmTrailingAction The only allowed trailing action type.
+ * @param ppSpec Where to return the pointer to the parsed
+ * specification. This must be freed by calling
+ * RTVfsChainSpecFree. Will always be set (unless
+ * invalid parameters.)
+ * @param ppszError On failure, this will point at the error
+ * location in @a pszSpec. Optional.
+ */
+RTDECL(int) RTVfsChainSpecParse(const char *pszSpec, uint32_t fFlags, RTVFSCHAINACTION enmLeadingAction,
+ RTVFSCHAINACTION enmTrailingAction,
+ PRTVFSCHAINSPEC *ppSpec, const char **ppszError);
+
+/** @name RTVfsChainSpecParse
+ * @{ */
+/** No real action is permitted, i.e. only passive filtering (aka pipe). */
+#define RTVFSCHAIN_PF_NO_REAL_ACTION RT_BIT_32(0)
+/** The specified leading action is optional. */
+#define RTVFSCHAIN_PF_LEADING_ACTION_OPTIONAL RT_BIT_32(1)
+/** The specified trailing action is optional. */
+#define RTVFSCHAIN_PF_TRAILING_ACTION_OPTIONAL RT_BIT_32(2)
+/** Mask of valid flags. */
+#define RTVFSCHAIN_PF_VALID_MASK UINT32_C(0x00000007)
+/** @}*/
+
+/**
+ * Frees a parsed chain specification.
+ *
+ * @param pSpec What RTVfsChainSpecParse returned. NULL is
+ * quietly ignored.
+ */
+RTDECL(void) RTVfsChainSpecFree(PRTVFSCHAINSPEC pSpec);
+
+/**
+ * Registers a chain element provider.
+ *
+ * @returns IPRT status code
+ * @param pRegRec The registration record.
+ * @param fFromCtor Indicates where we're called from.
+ */
+RTDECL(int) RTVfsChainElementRegisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromCtor);
+
+/**
+ * Deregisters a chain element provider.
+ *
+ * @returns IPRT status code
+ * @param pRegRec The registration record.
+ * @param fFromDtor Indicates where we're called from.
+ */
+RTDECL(int) RTVfsChainElementDeregisterProvider(PRTVFSCHAINELEMENTREG pRegRec, bool fFromDtor);
+
+
+/** @def RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER
+ * Automatically registers a chain element provider using a global constructor
+ * and destructor hack.
+ *
+ * @param pRegRec Pointer to the registration record.
+ * @param name Some unique variable name prefix.
+ */
+
+#ifdef __cplusplus
+/**
+ * Class used for registering a VFS chain element provider.
+ */
+class RTVfsChainElementAutoRegisterHack
+{
+private:
+ /** The registration record, NULL if registration failed. */
+ PRTVFSCHAINELEMENTREG m_pRegRec;
+
+public:
+ RTVfsChainElementAutoRegisterHack(PRTVFSCHAINELEMENTREG a_pRegRec)
+ : m_pRegRec(a_pRegRec)
+ {
+ int rc = RTVfsChainElementRegisterProvider(m_pRegRec, true);
+ if (RT_FAILURE(rc))
+ m_pRegRec = NULL;
+ }
+
+ ~RTVfsChainElementAutoRegisterHack()
+ {
+ RTVfsChainElementDeregisterProvider(m_pRegRec, true);
+ m_pRegRec = NULL;
+ }
+};
+
+# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
+ static RTVfsChainElementAutoRegisterHack name ## AutoRegistrationHack(pRegRec)
+
+#else
+# define RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(pRegRec, name) \
+ extern void *name ## AutoRegistrationHack = \
+ &Sorry_but_RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER_does_not_work_in_c_source_files
+#endif
+
+
+/** @} */
+
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif /* !___iprt_vfslowlevel_h */
+
diff --git a/include/iprt/x86.h b/include/iprt/x86.h
new file mode 100644
index 00000000..22b0b952
--- /dev/null
+++ b/include/iprt/x86.h
@@ -0,0 +1,3194 @@
+/** @file
+ * IPRT - X86 and AMD64 Structures and Definitions.
+ *
+ * @note x86.mac is generated from this file by running 'kmk incs' in the root.
+ */
+
+/*
+ * 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 ___iprt_x86_h
+#define ___iprt_x86_h
+
+#ifndef VBOX_FOR_DTRACE_LIB
+# include <iprt/types.h>
+# include <iprt/assert.h>
+#else
+# pragma D depends_on library vbox-types.d
+#endif
+
+/* Workaround for Solaris sys/regset.h defining CS, DS */
+#ifdef RT_OS_SOLARIS
+# undef CS
+# undef DS
+#endif
+
+/** @defgroup grp_rt_x86 x86 Types and Definitions
+ * @ingroup grp_rt
+ * @{
+ */
+
+#ifndef VBOX_FOR_DTRACE_LIB
+/**
+ * EFLAGS Bits.
+ */
+typedef struct X86EFLAGSBITS
+{
+ /** Bit 0 - CF - Carry flag - Status flag. */
+ unsigned u1CF : 1;
+ /** Bit 1 - 1 - Reserved flag. */
+ unsigned u1Reserved0 : 1;
+ /** Bit 2 - PF - Parity flag - Status flag. */
+ unsigned u1PF : 1;
+ /** Bit 3 - 0 - Reserved flag. */
+ unsigned u1Reserved1 : 1;
+ /** Bit 4 - AF - Auxiliary carry flag - Status flag. */
+ unsigned u1AF : 1;
+ /** Bit 5 - 0 - Reserved flag. */
+ unsigned u1Reserved2 : 1;
+ /** Bit 6 - ZF - Zero flag - Status flag. */
+ unsigned u1ZF : 1;
+ /** Bit 7 - SF - Signed flag - Status flag. */
+ unsigned u1SF : 1;
+ /** Bit 8 - TF - Trap flag - System flag. */
+ unsigned u1TF : 1;
+ /** Bit 9 - IF - Interrupt flag - System flag. */
+ unsigned u1IF : 1;
+ /** Bit 10 - DF - Direction flag - Control flag. */
+ unsigned u1DF : 1;
+ /** Bit 11 - OF - Overflow flag - Status flag. */
+ unsigned u1OF : 1;
+ /** Bit 12-13 - IOPL - I/O prvilege level flag - System flag. */
+ unsigned u2IOPL : 2;
+ /** Bit 14 - NT - Nested task flag - System flag. */
+ unsigned u1NT : 1;
+ /** Bit 15 - 0 - Reserved flag. */
+ unsigned u1Reserved3 : 1;
+ /** Bit 16 - RF - Resume flag - System flag. */
+ unsigned u1RF : 1;
+ /** Bit 17 - VM - Virtual 8086 mode - System flag. */
+ unsigned u1VM : 1;
+ /** Bit 18 - AC - Alignment check flag - System flag. Works with CR0.AM. */
+ unsigned u1AC : 1;
+ /** Bit 19 - VIF - Virtual interrupt flag - System flag. */
+ unsigned u1VIF : 1;
+ /** Bit 20 - VIP - Virtual interrupt pending flag - System flag. */
+ unsigned u1VIP : 1;
+ /** Bit 21 - ID - CPUID flag - System flag. If this responds to flipping CPUID is supported. */
+ unsigned u1ID : 1;
+ /** Bit 22-31 - 0 - Reserved flag. */
+ unsigned u10Reserved4 : 10;
+} X86EFLAGSBITS;
+/** Pointer to EFLAGS bits. */
+typedef X86EFLAGSBITS *PX86EFLAGSBITS;
+/** Pointer to const EFLAGS bits. */
+typedef const X86EFLAGSBITS *PCX86EFLAGSBITS;
+#endif /* !VBOX_FOR_DTRACE_LIB */
+
+/**
+ * EFLAGS.
+ */
+typedef union X86EFLAGS
+{
+ /** The plain unsigned view. */
+ uint32_t u;
+#ifndef VBOX_FOR_DTRACE_LIB
+ /** The bitfield view. */
+ X86EFLAGSBITS Bits;
+#endif
+ /** The 8-bit view. */
+ uint8_t au8[4];
+ /** The 16-bit view. */
+ uint16_t au16[2];
+ /** The 32-bit view. */
+ uint32_t au32[1];
+ /** The 32-bit view. */
+ uint32_t u32;
+} X86EFLAGS;
+/** Pointer to EFLAGS. */
+typedef X86EFLAGS *PX86EFLAGS;
+/** Pointer to const EFLAGS. */
+typedef const X86EFLAGS *PCX86EFLAGS;
+
+/**
+ * RFLAGS (32 upper bits are reserved).
+ */
+typedef union X86RFLAGS
+{
+ /** The plain unsigned view. */
+ uint64_t u;
+#ifndef VBOX_FOR_DTRACE_LIB
+ /** The bitfield view. */
+ X86EFLAGSBITS Bits;
+#endif
+ /** The 8-bit view. */
+ uint8_t au8[8];
+ /** The 16-bit view. */
+ uint16_t au16[4];
+ /** The 32-bit view. */
+ uint32_t au32[2];
+ /** The 64-bit view. */
+ uint64_t au64[1];
+ /** The 64-bit view. */
+ uint64_t u64;
+} X86RFLAGS;
+/** Pointer to RFLAGS. */
+typedef X86RFLAGS *PX86RFLAGS;
+/** Pointer to const RFLAGS. */
+typedef const X86RFLAGS *PCX86RFLAGS;
+
+
+/** @name EFLAGS
+ * @{
+ */
+/** Bit 0 - CF - Carry flag - Status flag. */
+#define X86_EFL_CF RT_BIT(0)
+/** Bit 1 - Reserved, reads as 1. */
+#define X86_EFL_1 RT_BIT(1)
+/** Bit 2 - PF - Parity flag - Status flag. */
+#define X86_EFL_PF RT_BIT(2)
+/** Bit 4 - AF - Auxiliary carry flag - Status flag. */
+#define X86_EFL_AF RT_BIT(4)
+/** Bit 6 - ZF - Zero flag - Status flag. */
+#define X86_EFL_ZF RT_BIT(6)
+/** Bit 7 - SF - Signed flag - Status flag. */
+#define X86_EFL_SF RT_BIT(7)
+/** Bit 8 - TF - Trap flag - System flag. */
+#define X86_EFL_TF RT_BIT(8)
+/** Bit 9 - IF - Interrupt flag - System flag. */
+#define X86_EFL_IF RT_BIT(9)
+/** Bit 10 - DF - Direction flag - Control flag. */
+#define X86_EFL_DF RT_BIT(10)
+/** Bit 11 - OF - Overflow flag - Status flag. */
+#define X86_EFL_OF RT_BIT(11)
+/** Bit 12-13 - IOPL - I/O prvilege level flag - System flag. */
+#define X86_EFL_IOPL (RT_BIT(12) | RT_BIT(13))
+/** Bit 14 - NT - Nested task flag - System flag. */
+#define X86_EFL_NT RT_BIT(14)
+/** Bit 16 - RF - Resume flag - System flag. */
+#define X86_EFL_RF RT_BIT(16)
+/** Bit 17 - VM - Virtual 8086 mode - System flag. */
+#define X86_EFL_VM RT_BIT(17)
+/** Bit 18 - AC - Alignment check flag - System flag. Works with CR0.AM. */
+#define X86_EFL_AC RT_BIT(18)
+/** Bit 19 - VIF - Virtual interrupt flag - System flag. */
+#define X86_EFL_VIF RT_BIT(19)
+/** Bit 20 - VIP - Virtual interrupt pending flag - System flag. */
+#define X86_EFL_VIP RT_BIT(20)
+/** Bit 21 - ID - CPUID flag - System flag. If this responds to flipping CPUID is supported. */
+#define X86_EFL_ID RT_BIT(21)
+/** IOPL shift. */
+#define X86_EFL_IOPL_SHIFT 12
+/** The the IOPL level from the flags. */
+#define X86_EFL_GET_IOPL(efl) (((efl) >> X86_EFL_IOPL_SHIFT) & 3)
+/** Bits restored by popf */
+#define X86_EFL_POPF_BITS (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_AC | X86_EFL_ID)
+/** @} */
+
+
+/** CPUID Feature information - ECX.
+ * CPUID query with EAX=1.
+ */
+#ifndef VBOX_FOR_DTRACE_LIB
+typedef struct X86CPUIDFEATECX
+{
+ /** Bit 0 - SSE3 - Supports SSE3 or not. */
+ unsigned u1SSE3 : 1;
+ /** Bit 1 - PCLMULQDQ. */
+ unsigned u1PCLMULQDQ : 1;
+ /** Bit 2 - DS Area 64-bit layout. */
+ unsigned u1DTE64 : 1;
+ /** Bit 3 - MONITOR - Supports MONITOR/MWAIT. */
+ unsigned u1Monitor : 1;
+ /** Bit 4 - CPL-DS - CPL Qualified Debug Store. */
+ unsigned u1CPLDS : 1;
+ /** Bit 5 - VMX - Virtual Machine Technology. */
+ unsigned u1VMX : 1;
+ /** Bit 6 - SMX: Safer Mode Extensions. */
+ unsigned u1SMX : 1;
+ /** Bit 7 - EST - Enh. SpeedStep Tech. */
+ unsigned u1EST : 1;
+ /** Bit 8 - TM2 - Terminal Monitor 2. */
+ unsigned u1TM2 : 1;
+ /** Bit 9 - SSSE3 - Supplemental Streaming SIMD Extensions 3. */
+ unsigned u1SSSE3 : 1;
+ /** Bit 10 - CNTX-ID - L1 Context ID. */
+ unsigned u1CNTXID : 1;
+ /** Bit 11 - Reserved. */
+ unsigned u1Reserved1 : 1;
+ /** Bit 12 - FMA. */
+ unsigned u1FMA : 1;
+ /** Bit 13 - CX16 - CMPXCHG16B. */
+ unsigned u1CX16 : 1;
+ /** Bit 14 - xTPR Update Control. Processor supports changing IA32_MISC_ENABLES[bit 23]. */
+ unsigned u1TPRUpdate : 1;
+ /** Bit 15 - PDCM - Perf/Debug Capability MSR. */
+ unsigned u1PDCM : 1;
+ /** Bit 16 - Reserved. */
+ unsigned u1Reserved2 : 1;
+ /** Bit 17 - PCID - Process-context identifiers. */
+ unsigned u1PCID : 1;
+ /** Bit 18 - Direct Cache Access. */
+ unsigned u1DCA : 1;
+ /** Bit 19 - SSE4_1 - Supports SSE4_1 or not. */
+ unsigned u1SSE4_1 : 1;
+ /** Bit 20 - SSE4_2 - Supports SSE4_2 or not. */
+ unsigned u1SSE4_2 : 1;
+ /** Bit 21 - x2APIC. */
+ unsigned u1x2APIC : 1;
+ /** Bit 22 - MOVBE - Supports MOVBE. */
+ unsigned u1MOVBE : 1;
+ /** Bit 23 - POPCNT - Supports POPCNT. */
+ unsigned u1POPCNT : 1;
+ /** Bit 24 - TSC-Deadline. */
+ unsigned u1TSCDEADLINE : 1;
+ /** Bit 25 - AES. */
+ unsigned u1AES : 1;
+ /** Bit 26 - XSAVE - Supports XSAVE. */
+ unsigned u1XSAVE : 1;
+ /** Bit 27 - OSXSAVE - Supports OSXSAVE. */
+ unsigned u1OSXSAVE : 1;
+ /** Bit 28 - AVX - Supports AVX instruction extensions. */
+ unsigned u1AVX : 1;
+ /** Bit 29 - 30 - Reserved */
+ unsigned u2Reserved3 : 2;
+ /** Bit 31 - Hypervisor present (we're a guest). */
+ unsigned u1HVP : 1;
+} X86CPUIDFEATECX;
+#else /* VBOX_FOR_DTRACE_LIB */
+typedef uint32_t X86CPUIDFEATECX;
+#endif /* VBOX_FOR_DTRACE_LIB */
+/** Pointer to CPUID Feature Information - ECX. */
+typedef X86CPUIDFEATECX *PX86CPUIDFEATECX;
+/** Pointer to const CPUID Feature Information - ECX. */
+typedef const X86CPUIDFEATECX *PCX86CPUIDFEATECX;
+
+
+/** CPUID Feature Information - EDX.
+ * CPUID query with EAX=1.
+ */
+#ifndef VBOX_FOR_DTRACE_LIB /* DTrace different (brain-dead from a C pov) bitfield implementation */
+typedef struct X86CPUIDFEATEDX
+{
+ /** Bit 0 - FPU - x87 FPU on Chip. */
+ unsigned u1FPU : 1;
+ /** Bit 1 - VME - Virtual 8086 Mode Enhancements. */
+ unsigned u1VME : 1;
+ /** Bit 2 - DE - Debugging extensions. */
+ unsigned u1DE : 1;
+ /** Bit 3 - PSE - Page Size Extension. */
+ unsigned u1PSE : 1;
+ /** Bit 4 - TSC - Time Stamp Counter. */
+ unsigned u1TSC : 1;
+ /** Bit 5 - MSR - Model Specific Registers RDMSR and WRMSR Instructions. */
+ unsigned u1MSR : 1;
+ /** Bit 6 - PAE - Physical Address Extension. */
+ unsigned u1PAE : 1;
+ /** Bit 7 - MCE - Machine Check Exception. */
+ unsigned u1MCE : 1;
+ /** Bit 8 - CX8 - CMPXCHG8B instruction. */
+ unsigned u1CX8 : 1;
+ /** Bit 9 - APIC - APIC On-Chip. */
+ unsigned u1APIC : 1;
+ /** Bit 10 - Reserved. */
+ unsigned u1Reserved1 : 1;
+ /** Bit 11 - SEP - SYSENTER and SYSEXIT. */
+ unsigned u1SEP : 1;
+ /** Bit 12 - MTRR - Memory Type Range Registers. */
+ unsigned u1MTRR : 1;
+ /** Bit 13 - PGE - PTE Global Bit. */
+ unsigned u1PGE : 1;
+ /** Bit 14 - MCA - Machine Check Architecture. */
+ unsigned u1MCA : 1;
+ /** Bit 15 - CMOV - Conditional Move Instructions. */
+ unsigned u1CMOV : 1;
+ /** Bit 16 - PAT - Page Attribute Table. */
+ unsigned u1PAT : 1;
+ /** Bit 17 - PSE-36 - 36-bit Page Size Extention. */
+ unsigned u1PSE36 : 1;
+ /** Bit 18 - PSN - Processor Serial Number. */
+ unsigned u1PSN : 1;
+ /** Bit 19 - CLFSH - CLFLUSH Instruction. */
+ unsigned u1CLFSH : 1;
+ /** Bit 20 - Reserved. */
+ unsigned u1Reserved2 : 1;
+ /** Bit 21 - DS - Debug Store. */
+ unsigned u1DS : 1;
+ /** Bit 22 - ACPI - Thermal Monitor and Software Controlled Clock Facilities. */
+ unsigned u1ACPI : 1;
+ /** Bit 23 - MMX - Intel MMX 'Technology'. */
+ unsigned u1MMX : 1;
+ /** Bit 24 - FXSR - FXSAVE and FXRSTOR Instructions. */
+ unsigned u1FXSR : 1;
+ /** Bit 25 - SSE - SSE Support. */
+ unsigned u1SSE : 1;
+ /** Bit 26 - SSE2 - SSE2 Support. */
+ unsigned u1SSE2 : 1;
+ /** Bit 27 - SS - Self Snoop. */
+ unsigned u1SS : 1;
+ /** Bit 28 - HTT - Hyper-Threading Technology. */
+ unsigned u1HTT : 1;
+ /** Bit 29 - TM - Thermal Monitor. */
+ unsigned u1TM : 1;
+ /** Bit 30 - Reserved - . */
+ unsigned u1Reserved3 : 1;
+ /** Bit 31 - PBE - Pending Break Enabled. */
+ unsigned u1PBE : 1;
+} X86CPUIDFEATEDX;
+#else /* VBOX_FOR_DTRACE_LIB */
+typedef uint32_t X86CPUIDFEATEDX;
+#endif /* VBOX_FOR_DTRACE_LIB */
+/** Pointer to CPUID Feature Information - EDX. */
+typedef X86CPUIDFEATEDX *PX86CPUIDFEATEDX;
+/** Pointer to const CPUID Feature Information - EDX. */
+typedef const X86CPUIDFEATEDX *PCX86CPUIDFEATEDX;
+
+/** @name CPUID Vendor information.
+ * CPUID query with EAX=0.
+ * @{
+ */
+#define X86_CPUID_VENDOR_INTEL_EBX 0x756e6547 /* Genu */
+#define X86_CPUID_VENDOR_INTEL_ECX 0x6c65746e /* ntel */
+#define X86_CPUID_VENDOR_INTEL_EDX 0x49656e69 /* ineI */
+
+#define X86_CPUID_VENDOR_AMD_EBX 0x68747541 /* Auth */
+#define X86_CPUID_VENDOR_AMD_ECX 0x444d4163 /* cAMD */
+#define X86_CPUID_VENDOR_AMD_EDX 0x69746e65 /* enti */
+
+#define X86_CPUID_VENDOR_VIA_EBX 0x746e6543 /* Cent */
+#define X86_CPUID_VENDOR_VIA_ECX 0x736c7561 /* auls */
+#define X86_CPUID_VENDOR_VIA_EDX 0x48727561 /* aurH */
+/** @} */
+
+
+/** @name CPUID Feature information.
+ * CPUID query with EAX=1.
+ * @{
+ */
+/** ECX Bit 0 - SSE3 - Supports SSE3 or not. */
+#define X86_CPUID_FEATURE_ECX_SSE3 RT_BIT(0)
+/** ECX Bit 1 - PCLMUL - PCLMULQDQ support (for AES-GCM). */
+#define X86_CPUID_FEATURE_ECX_PCLMUL RT_BIT(1)
+/** ECX Bit 2 - DTES64 - DS Area 64-bit Layout. */
+#define X86_CPUID_FEATURE_ECX_DTES64 RT_BIT(2)
+/** ECX Bit 3 - MONITOR - Supports MONITOR/MWAIT. */
+#define X86_CPUID_FEATURE_ECX_MONITOR RT_BIT(3)
+/** ECX Bit 4 - CPL-DS - CPL Qualified Debug Store. */
+#define X86_CPUID_FEATURE_ECX_CPLDS RT_BIT(4)
+/** ECX Bit 5 - VMX - Virtual Machine Technology. */
+#define X86_CPUID_FEATURE_ECX_VMX RT_BIT(5)
+/** ECX Bit 6 - SMX - Safer Mode Extensions. */
+#define X86_CPUID_FEATURE_ECX_SMX RT_BIT(6)
+/** ECX Bit 7 - EST - Enh. SpeedStep Tech. */
+#define X86_CPUID_FEATURE_ECX_EST RT_BIT(7)
+/** ECX Bit 8 - TM2 - Terminal Monitor 2. */
+#define X86_CPUID_FEATURE_ECX_TM2 RT_BIT(8)
+/** ECX Bit 9 - SSSE3 - Supplemental Streaming SIMD Extensions 3. */
+#define X86_CPUID_FEATURE_ECX_SSSE3 RT_BIT(9)
+/** ECX Bit 10 - CNTX-ID - L1 Context ID. */
+#define X86_CPUID_FEATURE_ECX_CNTXID RT_BIT(10)
+/** ECX Bit 12 - FMA. */
+#define X86_CPUID_FEATURE_ECX_FMA RT_BIT(12)
+/** ECX Bit 13 - CX16 - CMPXCHG16B. */
+#define X86_CPUID_FEATURE_ECX_CX16 RT_BIT(13)
+/** ECX Bit 14 - xTPR Update Control. Processor supports changing IA32_MISC_ENABLES[bit 23]. */
+#define X86_CPUID_FEATURE_ECX_TPRUPDATE RT_BIT(14)
+/** ECX Bit 15 - PDCM - Perf/Debug Capability MSR. */
+#define X86_CPUID_FEATURE_ECX_PDCM RT_BIT(15)
+/** ECX Bit 17 - PCID - Process-context identifiers. */
+#define X86_CPUID_FEATURE_ECX_PCID RT_BIT(17)
+/** ECX Bit 18 - DCA - Direct Cache Access. */
+#define X86_CPUID_FEATURE_ECX_DCA RT_BIT(18)
+/** ECX Bit 19 - SSE4_1 - Supports SSE4_1 or not. */
+#define X86_CPUID_FEATURE_ECX_SSE4_1 RT_BIT(19)
+/** ECX Bit 20 - SSE4_2 - Supports SSE4_2 or not. */
+#define X86_CPUID_FEATURE_ECX_SSE4_2 RT_BIT(20)
+/** ECX Bit 21 - x2APIC support. */
+#define X86_CPUID_FEATURE_ECX_X2APIC RT_BIT(21)
+/** ECX Bit 22 - MOVBE instruction. */
+#define X86_CPUID_FEATURE_ECX_MOVBE RT_BIT(22)
+/** ECX Bit 23 - POPCNT instruction. */
+#define X86_CPUID_FEATURE_ECX_POPCNT RT_BIT(23)
+/** ECX Bir 24 - TSC-Deadline. */
+#define X86_CPUID_FEATURE_ECX_TSCDEADL RT_BIT(24)
+/** ECX Bit 25 - AES instructions. */
+#define X86_CPUID_FEATURE_ECX_AES RT_BIT(25)
+/** ECX Bit 26 - XSAVE instruction. */
+#define X86_CPUID_FEATURE_ECX_XSAVE RT_BIT(26)
+/** ECX Bit 27 - OSXSAVE instruction. */
+#define X86_CPUID_FEATURE_ECX_OSXSAVE RT_BIT(27)
+/** ECX Bit 28 - AVX. */
+#define X86_CPUID_FEATURE_ECX_AVX RT_BIT(28)
+/** ECX Bit 31 - Hypervisor Present (software only). */
+#define X86_CPUID_FEATURE_ECX_HVP RT_BIT(31)
+
+
+/** Bit 0 - FPU - x87 FPU on Chip. */
+#define X86_CPUID_FEATURE_EDX_FPU RT_BIT(0)
+/** Bit 1 - VME - Virtual 8086 Mode Enhancements. */
+#define X86_CPUID_FEATURE_EDX_VME RT_BIT(1)
+/** Bit 2 - DE - Debugging extensions. */
+#define X86_CPUID_FEATURE_EDX_DE RT_BIT(2)
+/** Bit 3 - PSE - Page Size Extension. */
+#define X86_CPUID_FEATURE_EDX_PSE RT_BIT(3)
+/** Bit 4 - TSC - Time Stamp Counter. */
+#define X86_CPUID_FEATURE_EDX_TSC RT_BIT(4)
+/** Bit 5 - MSR - Model Specific Registers RDMSR and WRMSR Instructions. */
+#define X86_CPUID_FEATURE_EDX_MSR RT_BIT(5)
+/** Bit 6 - PAE - Physical Address Extension. */
+#define X86_CPUID_FEATURE_EDX_PAE RT_BIT(6)
+/** Bit 7 - MCE - Machine Check Exception. */
+#define X86_CPUID_FEATURE_EDX_MCE RT_BIT(7)
+/** Bit 8 - CX8 - CMPXCHG8B instruction. */
+#define X86_CPUID_FEATURE_EDX_CX8 RT_BIT(8)
+/** Bit 9 - APIC - APIC On-Chip. */
+#define X86_CPUID_FEATURE_EDX_APIC RT_BIT(9)
+/** Bit 11 - SEP - SYSENTER and SYSEXIT Present. */
+#define X86_CPUID_FEATURE_EDX_SEP RT_BIT(11)
+/** Bit 12 - MTRR - Memory Type Range Registers. */
+#define X86_CPUID_FEATURE_EDX_MTRR RT_BIT(12)
+/** Bit 13 - PGE - PTE Global Bit. */
+#define X86_CPUID_FEATURE_EDX_PGE RT_BIT(13)
+/** Bit 14 - MCA - Machine Check Architecture. */
+#define X86_CPUID_FEATURE_EDX_MCA RT_BIT(14)
+/** Bit 15 - CMOV - Conditional Move Instructions. */
+#define X86_CPUID_FEATURE_EDX_CMOV RT_BIT(15)
+/** Bit 16 - PAT - Page Attribute Table. */
+#define X86_CPUID_FEATURE_EDX_PAT RT_BIT(16)
+/** Bit 17 - PSE-36 - 36-bit Page Size Extention. */
+#define X86_CPUID_FEATURE_EDX_PSE36 RT_BIT(17)
+/** Bit 18 - PSN - Processor Serial Number. */
+#define X86_CPUID_FEATURE_EDX_PSN RT_BIT(18)
+/** Bit 19 - CLFSH - CLFLUSH Instruction. */
+#define X86_CPUID_FEATURE_EDX_CLFSH RT_BIT(19)
+/** Bit 21 - DS - Debug Store. */
+#define X86_CPUID_FEATURE_EDX_DS RT_BIT(21)
+/** Bit 22 - ACPI - Termal Monitor and Software Controlled Clock Facilities. */
+#define X86_CPUID_FEATURE_EDX_ACPI RT_BIT(22)
+/** Bit 23 - MMX - Intel MMX Technology. */
+#define X86_CPUID_FEATURE_EDX_MMX RT_BIT(23)
+/** Bit 24 - FXSR - FXSAVE and FXRSTOR Instructions. */
+#define X86_CPUID_FEATURE_EDX_FXSR RT_BIT(24)
+/** Bit 25 - SSE - SSE Support. */
+#define X86_CPUID_FEATURE_EDX_SSE RT_BIT(25)
+/** Bit 26 - SSE2 - SSE2 Support. */
+#define X86_CPUID_FEATURE_EDX_SSE2 RT_BIT(26)
+/** Bit 27 - SS - Self Snoop. */
+#define X86_CPUID_FEATURE_EDX_SS RT_BIT(27)
+/** Bit 28 - HTT - Hyper-Threading Technology. */
+#define X86_CPUID_FEATURE_EDX_HTT RT_BIT(28)
+/** Bit 29 - TM - Therm. Monitor. */
+#define X86_CPUID_FEATURE_EDX_TM RT_BIT(29)
+/** Bit 31 - PBE - Pending Break Enabled. */
+#define X86_CPUID_FEATURE_EDX_PBE RT_BIT(31)
+/** @} */
+
+/** @name CPUID mwait/monitor information.
+ * CPUID query with EAX=5.
+ * @{
+ */
+/** ECX Bit 0 - MWAITEXT - Supports mwait/monitor extensions or not. */
+#define X86_CPUID_MWAIT_ECX_EXT RT_BIT(0)
+/** ECX Bit 1 - MWAITBREAK - Break mwait for external interrupt even if EFLAGS.IF=0. */
+#define X86_CPUID_MWAIT_ECX_BREAKIRQIF0 RT_BIT(1)
+/** @} */
+
+
+/** @name CPUID Extended Feature information.
+ * CPUID query with EAX=0x80000001.
+ * @{
+ */
+/** ECX Bit 0 - LAHF/SAHF support in 64-bit mode. */
+#define X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF RT_BIT(0)
+
+/** EDX Bit 11 - SYSCALL/SYSRET. */
+#define X86_CPUID_EXT_FEATURE_EDX_SYSCALL RT_BIT(11)
+/** EDX Bit 20 - No-Execute/Execute-Disable. */
+#define X86_CPUID_EXT_FEATURE_EDX_NX RT_BIT(20)
+/** EDX Bit 26 - 1 GB large page. */
+#define X86_CPUID_EXT_FEATURE_EDX_PAGE1GB RT_BIT(26)
+/** EDX Bit 27 - RDTSCP. */
+#define X86_CPUID_EXT_FEATURE_EDX_RDTSCP RT_BIT(27)
+/** EDX Bit 29 - AMD Long Mode/Intel-64 Instructions. */
+#define X86_CPUID_EXT_FEATURE_EDX_LONG_MODE RT_BIT(29)
+/** @}*/
+
+/** @name CPUID AMD Feature information.
+ * CPUID query with EAX=0x80000001.
+ * @{
+ */
+/** Bit 0 - FPU - x87 FPU on Chip. */
+#define X86_CPUID_AMD_FEATURE_EDX_FPU RT_BIT(0)
+/** Bit 1 - VME - Virtual 8086 Mode Enhancements. */
+#define X86_CPUID_AMD_FEATURE_EDX_VME RT_BIT(1)
+/** Bit 2 - DE - Debugging extensions. */
+#define X86_CPUID_AMD_FEATURE_EDX_DE RT_BIT(2)
+/** Bit 3 - PSE - Page Size Extension. */
+#define X86_CPUID_AMD_FEATURE_EDX_PSE RT_BIT(3)
+/** Bit 4 - TSC - Time Stamp Counter. */
+#define X86_CPUID_AMD_FEATURE_EDX_TSC RT_BIT(4)
+/** Bit 5 - MSR - K86 Model Specific Registers RDMSR and WRMSR Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_MSR RT_BIT(5)
+/** Bit 6 - PAE - Physical Address Extension. */
+#define X86_CPUID_AMD_FEATURE_EDX_PAE RT_BIT(6)
+/** Bit 7 - MCE - Machine Check Exception. */
+#define X86_CPUID_AMD_FEATURE_EDX_MCE RT_BIT(7)
+/** Bit 8 - CX8 - CMPXCHG8B instruction. */
+#define X86_CPUID_AMD_FEATURE_EDX_CX8 RT_BIT(8)
+/** Bit 9 - APIC - APIC On-Chip. */
+#define X86_CPUID_AMD_FEATURE_EDX_APIC RT_BIT(9)
+/** Bit 12 - MTRR - Memory Type Range Registers. */
+#define X86_CPUID_AMD_FEATURE_EDX_MTRR RT_BIT(12)
+/** Bit 13 - PGE - PTE Global Bit. */
+#define X86_CPUID_AMD_FEATURE_EDX_PGE RT_BIT(13)
+/** Bit 14 - MCA - Machine Check Architecture. */
+#define X86_CPUID_AMD_FEATURE_EDX_MCA RT_BIT(14)
+/** Bit 15 - CMOV - Conditional Move Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_CMOV RT_BIT(15)
+/** Bit 16 - PAT - Page Attribute Table. */
+#define X86_CPUID_AMD_FEATURE_EDX_PAT RT_BIT(16)
+/** Bit 17 - PSE-36 - 36-bit Page Size Extention. */
+#define X86_CPUID_AMD_FEATURE_EDX_PSE36 RT_BIT(17)
+/** Bit 22 - AXMMX - AMD Extensions to MMX Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_AXMMX RT_BIT(22)
+/** Bit 23 - MMX - Intel MMX Technology. */
+#define X86_CPUID_AMD_FEATURE_EDX_MMX RT_BIT(23)
+/** Bit 24 - FXSR - FXSAVE and FXRSTOR Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_FXSR RT_BIT(24)
+/** Bit 25 - FFXSR - AMD fast FXSAVE and FXRSTOR Instructions. */
+#define X86_CPUID_AMD_FEATURE_EDX_FFXSR RT_BIT(25)
+/** Bit 30 - 3DNOWEXT - AMD Extensions to 3DNow. */
+#define X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX RT_BIT(30)
+/** Bit 31 - 3DNOW - AMD 3DNow. */
+#define X86_CPUID_AMD_FEATURE_EDX_3DNOW RT_BIT(31)
+
+/** Bit 1 - CMPL - Core multi-processing legacy mode. */
+#define X86_CPUID_AMD_FEATURE_ECX_CMPL RT_BIT(1)
+/** Bit 2 - SVM - AMD VM extensions. */
+#define X86_CPUID_AMD_FEATURE_ECX_SVM RT_BIT(2)
+/** Bit 3 - EXTAPIC - AMD extended APIC registers starting at 0x400. */
+#define X86_CPUID_AMD_FEATURE_ECX_EXT_APIC RT_BIT(3)
+/** Bit 4 - CR8L - AMD LOCK MOV CR0 means MOV CR8. */
+#define X86_CPUID_AMD_FEATURE_ECX_CR8L RT_BIT(4)
+/** Bit 5 - ABM - AMD Advanced bit manipulation. LZCNT instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_ABM RT_BIT(5)
+/** Bit 6 - SSE4A - AMD EXTRQ, INSERTQ, MOVNTSS, and MOVNTSD instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_SSE4A RT_BIT(6)
+/** Bit 7 - MISALIGNSSE - AMD Misaligned SSE mode. */
+#define X86_CPUID_AMD_FEATURE_ECX_MISALNSSE RT_BIT(7)
+/** Bit 8 - 3DNOWPRF - AMD PREFETCH and PREFETCHW instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF RT_BIT(8)
+/** Bit 9 - OSVW - AMD OS visible workaround. */
+#define X86_CPUID_AMD_FEATURE_ECX_OSVW RT_BIT(9)
+/** Bit 10 - IBS - Instruct based sampling. */
+#define X86_CPUID_AMD_FEATURE_ECX_IBS RT_BIT(10)
+/** Bit 11 - SSE5 - SSE5 instruction support. */
+#define X86_CPUID_AMD_FEATURE_ECX_SSE5 RT_BIT(11)
+/** Bit 12 - SKINIT - AMD SKINIT: SKINIT, STGI, and DEV support. */
+#define X86_CPUID_AMD_FEATURE_ECX_SKINIT RT_BIT(12)
+/** Bit 13 - WDT - AMD Watchdog timer support. */
+#define X86_CPUID_AMD_FEATURE_ECX_WDT RT_BIT(13)
+
+/** @} */
+
+
+/** @name CPUID AMD Feature information.
+ * CPUID query with EAX=0x80000007.
+ * @{
+ */
+/** Bit 0 - TS - Temperature Sensor. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TS RT_BIT(0)
+/** Bit 1 - FID - Frequency ID Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_FID RT_BIT(1)
+/** Bit 2 - VID - Voltage ID Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_VID RT_BIT(2)
+/** Bit 3 - TTP - THERMTRIP. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TTP RT_BIT(3)
+/** Bit 4 - TM - Hardware Thermal Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TM RT_BIT(4)
+/** Bit 5 - STC - Software Thermal Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_STC RT_BIT(5)
+/** Bit 6 - MC - 100 Mhz Multiplier Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_MC RT_BIT(6)
+/** Bit 7 - HWPSTATE - Hardware P-State Control. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_HWPSTATE RT_BIT(7)
+/** Bit 8 - TSCINVAR - TSC Invariant. */
+#define X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR RT_BIT(8)
+/** @} */
+
+
+/** @name CR0
+ * @{ */
+/** Bit 0 - PE - Protection Enabled */
+#define X86_CR0_PE RT_BIT(0)
+#define X86_CR0_PROTECTION_ENABLE RT_BIT(0)
+/** Bit 1 - MP - Monitor Coprocessor */
+#define X86_CR0_MP RT_BIT(1)
+#define X86_CR0_MONITOR_COPROCESSOR RT_BIT(1)
+/** Bit 2 - EM - Emulation. */
+#define X86_CR0_EM RT_BIT(2)
+#define X86_CR0_EMULATE_FPU RT_BIT(2)
+/** Bit 3 - TS - Task Switch. */
+#define X86_CR0_TS RT_BIT(3)
+#define X86_CR0_TASK_SWITCH RT_BIT(3)
+/** Bit 4 - ET - Extension flag. ('hardcoded' to 1) */
+#define X86_CR0_ET RT_BIT(4)
+#define X86_CR0_EXTENSION_TYPE RT_BIT(4)
+/** Bit 5 - NE - Numeric error. */
+#define X86_CR0_NE RT_BIT(5)
+#define X86_CR0_NUMERIC_ERROR RT_BIT(5)
+/** Bit 16 - WP - Write Protect. */
+#define X86_CR0_WP RT_BIT(16)
+#define X86_CR0_WRITE_PROTECT RT_BIT(16)
+/** Bit 18 - AM - Alignment Mask. */
+#define X86_CR0_AM RT_BIT(18)
+#define X86_CR0_ALIGMENT_MASK RT_BIT(18)
+/** Bit 29 - NW - Not Write-though. */
+#define X86_CR0_NW RT_BIT(29)
+#define X86_CR0_NOT_WRITE_THROUGH RT_BIT(29)
+/** Bit 30 - WP - Cache Disable. */
+#define X86_CR0_CD RT_BIT(30)
+#define X86_CR0_CACHE_DISABLE RT_BIT(30)
+/** Bit 31 - PG - Paging. */
+#define X86_CR0_PG RT_BIT(31)
+#define X86_CR0_PAGING RT_BIT(31)
+/** @} */
+
+
+/** @name CR3
+ * @{ */
+/** Bit 3 - PWT - Page-level Writes Transparent. */
+#define X86_CR3_PWT RT_BIT(3)
+/** Bit 4 - PCD - Page-level Cache Disable. */
+#define X86_CR3_PCD RT_BIT(4)
+/** Bits 12-31 - - Page directory page number. */
+#define X86_CR3_PAGE_MASK (0xfffff000)
+/** Bits 5-31 - - PAE Page directory page number. */
+#define X86_CR3_PAE_PAGE_MASK (0xffffffe0)
+/** Bits 12-51 - - AMD64 Page directory page number. */
+#define X86_CR3_AMD64_PAGE_MASK UINT64_C(0x000ffffffffff000)
+/** @} */
+
+
+/** @name CR4
+ * @{ */
+/** Bit 0 - VME - Virtual-8086 Mode Extensions. */
+#define X86_CR4_VME RT_BIT(0)
+/** Bit 1 - PVI - Protected-Mode Virtual Interrupts. */
+#define X86_CR4_PVI RT_BIT(1)
+/** Bit 2 - TSD - Time Stamp Disable. */
+#define X86_CR4_TSD RT_BIT(2)
+/** Bit 3 - DE - Debugging Extensions. */
+#define X86_CR4_DE RT_BIT(3)
+/** Bit 4 - PSE - Page Size Extension. */
+#define X86_CR4_PSE RT_BIT(4)
+/** Bit 5 - PAE - Physical Address Extension. */
+#define X86_CR4_PAE RT_BIT(5)
+/** Bit 6 - MCE - Machine-Check Enable. */
+#define X86_CR4_MCE RT_BIT(6)
+/** Bit 7 - PGE - Page Global Enable. */
+#define X86_CR4_PGE RT_BIT(7)
+/** Bit 8 - PCE - Performance-Monitoring Counter Enable. */
+#define X86_CR4_PCE RT_BIT(8)
+/** Bit 9 - OSFSXR - Operating System Support for FXSAVE and FXRSTORE instruction. */
+#define X86_CR4_OSFSXR RT_BIT(9)
+/** Bit 10 - OSXMMEEXCPT - Operating System Support for Unmasked SIMD Floating-Point Exceptions. */
+#define X86_CR4_OSXMMEEXCPT RT_BIT(10)
+/** Bit 13 - VMXE - VMX mode is enabled. */
+#define X86_CR4_VMXE RT_BIT(13)
+/** Bit 14 - SMXE - Safer Mode Extensions Enabled. */
+#define X86_CR4_SMXE RT_BIT(14)
+/** Bit 17 - PCIDE - Process-Context Identifiers Enabled. */
+#define X86_CR4_PCIDE RT_BIT(17)
+/** Bit 18 - OSXSAVE - Operating System Support for XSAVE and processor
+ * extended states. */
+#define X86_CR4_OSXSAVE RT_BIT(18)
+/** Bit 20 - SMEP - Supervisor-mode Execution Prevention enabled. */
+#define X86_CR4_SMEP RT_BIT(20)
+/** @} */
+
+
+/** @name DR6
+ * @{ */
+/** Bit 0 - B0 - Breakpoint 0 condition detected. */
+#define X86_DR6_B0 RT_BIT(0)
+/** Bit 1 - B1 - Breakpoint 1 condition detected. */
+#define X86_DR6_B1 RT_BIT(1)
+/** Bit 2 - B2 - Breakpoint 2 condition detected. */
+#define X86_DR6_B2 RT_BIT(2)
+/** Bit 3 - B3 - Breakpoint 3 condition detected. */
+#define X86_DR6_B3 RT_BIT(3)
+/** Bit 13 - BD - Debug register access detected. Corresponds to the X86_DR7_GD bit. */
+#define X86_DR6_BD RT_BIT(13)
+/** Bit 14 - BS - Single step */
+#define X86_DR6_BS RT_BIT(14)
+/** Bit 15 - BT - Task switch. (TSS T bit.) */
+#define X86_DR6_BT RT_BIT(15)
+/** Value of DR6 after powerup/reset. */
+#define X86_DR6_INIT_VAL UINT64_C(0xFFFF0FF0)
+/** @} */
+
+
+/** @name DR7
+ * @{ */
+/** Bit 0 - L0 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L0 RT_BIT(0)
+/** Bit 1 - G0 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G0 RT_BIT(1)
+/** Bit 2 - L1 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L1 RT_BIT(2)
+/** Bit 3 - G1 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G1 RT_BIT(3)
+/** Bit 4 - L2 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L2 RT_BIT(4)
+/** Bit 5 - G2 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G2 RT_BIT(5)
+/** Bit 6 - L3 - Local breakpoint enable. Cleared on task switch. */
+#define X86_DR7_L3 RT_BIT(6)
+/** Bit 7 - G3 - Global breakpoint enable. Not cleared on task switch. */
+#define X86_DR7_G3 RT_BIT(7)
+/** Bit 8 - LE - Local breakpoint exact. (Not supported (read ignored) by P6 and later.) */
+#define X86_DR7_LE RT_BIT(8)
+/** Bit 9 - GE - Local breakpoint exact. (Not supported (read ignored) by P6 and later.) */
+#define X86_DR7_GE RT_BIT(9)
+
+/** Bit 13 - GD - General detect enable. Enables emulators to get exceptions when
+ * any DR register is accessed. */
+#define X86_DR7_GD RT_BIT(13)
+/** Bit 16 & 17 - R/W0 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW0_MASK (3 << 16)
+/** Bit 18 & 19 - LEN0 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN0_MASK (3 << 18)
+/** Bit 20 & 21 - R/W1 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW1_MASK (3 << 20)
+/** Bit 22 & 23 - LEN1 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN1_MASK (3 << 22)
+/** Bit 24 & 25 - R/W2 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW2_MASK (3 << 24)
+/** Bit 26 & 27 - LEN2 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN2_MASK (3 << 26)
+/** Bit 28 & 29 - R/W3 - Read write field 0. Values X86_DR7_RW_*. */
+#define X86_DR7_RW3_MASK (3 << 28)
+/** Bit 30 & 31 - LEN3 - Length field 0. Values X86_DR7_LEN_*. */
+#define X86_DR7_LEN3_MASK (3 << 30)
+
+/** Bits which must be 1s. */
+#define X86_DR7_MB1_MASK (RT_BIT(10))
+
+/** Calcs the L bit of Nth breakpoint.
+ * @param iBp The breakpoint number [0..3].
+ */
+#define X86_DR7_L(iBp) ( UINT32_C(1) << (iBp * 2) )
+
+/** Calcs the G bit of Nth breakpoint.
+ * @param iBp The breakpoint number [0..3].
+ */
+#define X86_DR7_G(iBp) ( UINT32_C(1) << (iBp * 2 + 1) )
+
+/** @name Read/Write values.
+ * @{ */
+/** Break on instruction fetch only. */
+#define X86_DR7_RW_EO 0U
+/** Break on write only. */
+#define X86_DR7_RW_WO 1U
+/** Break on I/O read/write. This is only defined if CR4.DE is set. */
+#define X86_DR7_RW_IO 2U
+/** Break on read or write (but not instruction fetches). */
+#define X86_DR7_RW_RW 3U
+/** @} */
+
+/** Shifts a X86_DR7_RW_* value to its right place.
+ * @param iBp The breakpoint number [0..3].
+ * @param fRw One of the X86_DR7_RW_* value.
+ */
+#define X86_DR7_RW(iBp, fRw) ( (fRw) << ((iBp) * 4 + 16) )
+
+/** @name Length values.
+ * @{ */
+#define X86_DR7_LEN_BYTE 0U
+#define X86_DR7_LEN_WORD 1U
+#define X86_DR7_LEN_QWORD 2U /**< AMD64 long mode only. */
+#define X86_DR7_LEN_DWORD 3U
+/** @} */
+
+/** Shifts a X86_DR7_LEN_* value to its right place.
+ * @param iBp The breakpoint number [0..3].
+ * @param cb One of the X86_DR7_LEN_* values.
+ */
+#define X86_DR7_LEN(iBp, cb) ( (cb) << ((iBp) * 4 + 18) )
+
+/** Fetch the breakpoint length bits from the DR7 value.
+ * @param uDR7 DR7 value
+ * @param iBp The breakpoint number [0..3].
+ */
+#define X86_DR7_GET_LEN(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 18) ) & 0x3U)
+
+/** Mask used to check if any breakpoints are enabled. */
+#define X86_DR7_ENABLED_MASK (RT_BIT(0) | RT_BIT(1) | RT_BIT(2) | RT_BIT(3) | RT_BIT(4) | RT_BIT(5) | RT_BIT(6) | RT_BIT(7))
+
+/** Mask used to check if any io breakpoints are set. */
+#define X86_DR7_IO_ENABLED_MASK (X86_DR7_RW(0, X86_DR7_RW_IO) | X86_DR7_RW(1, X86_DR7_RW_IO) | X86_DR7_RW(2, X86_DR7_RW_IO) | X86_DR7_RW(3, X86_DR7_RW_IO))
+
+/** Value of DR7 after powerup/reset. */
+#define X86_DR7_INIT_VAL 0x400
+/** @} */
+
+
+/** @name Machine Specific Registers
+ * @{
+ */
+
+/** Time Stamp Counter. */
+#define MSR_IA32_TSC 0x10
+
+#define MSR_IA32_PLATFORM_ID 0x17
+
+#ifndef MSR_IA32_APICBASE /* qemu cpu.h kludge */
+#define MSR_IA32_APICBASE 0x1b
+#endif
+
+/** CPU Feature control. */
+#define MSR_IA32_FEATURE_CONTROL 0x3A
+#define MSR_IA32_FEATURE_CONTROL_LOCK RT_BIT(0)
+#define MSR_IA32_FEATURE_CONTROL_VMXON RT_BIT(2)
+
+/** BIOS update trigger (microcode update). */
+#define MSR_IA32_BIOS_UPDT_TRIG 0x79
+
+/** BIOS update signature (microcode). */
+#define MSR_IA32_BIOS_SIGN_ID 0x8B
+
+/** General performance counter no. 0. */
+#define MSR_IA32_PMC0 0xC1
+/** General performance counter no. 1. */
+#define MSR_IA32_PMC1 0xC2
+/** General performance counter no. 2. */
+#define MSR_IA32_PMC2 0xC3
+/** General performance counter no. 3. */
+#define MSR_IA32_PMC3 0xC4
+
+/** Nehalem power control. */
+#define MSR_IA32_PLATFORM_INFO 0xCE
+
+/** Get FSB clock status (Intel-specific). */
+#define MSR_IA32_FSB_CLOCK_STS 0xCD
+
+/** MTRR Capabilities. */
+#define MSR_IA32_MTRR_CAP 0xFE
+
+
+#ifndef MSR_IA32_SYSENTER_CS /* qemu cpu.h kludge */
+/** SYSENTER_CS - the R0 CS, indirectly giving R0 SS, R3 CS and R3 DS.
+ * R0 SS == CS + 8
+ * R3 CS == CS + 16
+ * R3 SS == CS + 24
+ */
+#define MSR_IA32_SYSENTER_CS 0x174
+/** SYSENTER_ESP - the R0 ESP. */
+#define MSR_IA32_SYSENTER_ESP 0x175
+/** SYSENTER_EIP - the R0 EIP. */
+#define MSR_IA32_SYSENTER_EIP 0x176
+#endif
+
+/** Machine Check Global Capabilities Register. */
+#define MSR_IA32_MCP_CAP 0x179
+/** Machine Check Global Status Register. */
+#define MSR_IA32_MCP_STATUS 0x17A
+/** Machine Check Global Control Register. */
+#define MSR_IA32_MCP_CTRL 0x17B
+
+/** Trace/Profile Resource Control (R/W) */
+#define MSR_IA32_DEBUGCTL 0x1D9
+
+/** Page Attribute Table. */
+#define MSR_IA32_CR_PAT 0x277
+
+/** Performance counter MSRs. (Intel only) */
+#define MSR_IA32_PERFEVTSEL0 0x186
+#define MSR_IA32_PERFEVTSEL1 0x187
+#define MSR_IA32_FLEX_RATIO 0x194
+#define MSR_IA32_PERF_STATUS 0x198
+#define MSR_IA32_PERF_CTL 0x199
+#define MSR_IA32_THERM_STATUS 0x19c
+
+/** Enable misc. processor features (R/W). */
+#define MSR_IA32_MISC_ENABLE 0x1A0
+/** Enable fast-strings feature (for REP MOVS and REP STORS). */
+#define MSR_IA32_MISC_ENABLE_FAST_STRINGS RT_BIT(0)
+/** Automatic Thermal Control Circuit Enable (R/W). */
+#define MSR_IA32_MISC_ENABLE_TCC RT_BIT(3)
+/** Performance Monitoring Available (R). */
+#define MSR_IA32_MISC_ENABLE_PERF_MON RT_BIT(7)
+/** Branch Trace Storage Unavailable (R/O). */
+#define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL RT_BIT(11)
+/** Precise Event Based Sampling (PEBS) Unavailable (R/O). */
+#define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL RT_BIT(12)
+/** Enhanced Intel SpeedStep Technology Enable (R/W). */
+#define MSR_IA32_MISC_ENABLE_SST_ENABLE RT_BIT(16)
+/** If MONITOR/MWAIT is supported (R/W). */
+#define MSR_IA32_MISC_ENABLE_MONITOR RT_BIT(18)
+/** Limit CPUID Maxval to 3 leafs (R/W). */
+#define MSR_IA32_MISC_ENABLE_LIMIT_CPUID RT_BIT(22)
+/** When set to 1, xTPR messages are disabled (R/W). */
+#define MSR_IA32_MISC_ENABLE_XTPR_MSG_DISABLE RT_BIT(23)
+/** When set to 1, the Execute Disable Bit feature (XD Bit) is disabled (R/W). */
+#define MSR_IA32_MISC_ENABLE_XD_DISABLE RT_BIT(34)
+
+#define IA32_MTRR_PHYSBASE0 0x200
+#define IA32_MTRR_PHYSMASK0 0x201
+#define IA32_MTRR_PHYSBASE1 0x202
+#define IA32_MTRR_PHYSMASK1 0x203
+#define IA32_MTRR_PHYSBASE2 0x204
+#define IA32_MTRR_PHYSMASK2 0x205
+#define IA32_MTRR_PHYSBASE3 0x206
+#define IA32_MTRR_PHYSMASK3 0x207
+#define IA32_MTRR_PHYSBASE4 0x208
+#define IA32_MTRR_PHYSMASK4 0x209
+#define IA32_MTRR_PHYSBASE5 0x20a
+#define IA32_MTRR_PHYSMASK5 0x20b
+#define IA32_MTRR_PHYSBASE6 0x20c
+#define IA32_MTRR_PHYSMASK6 0x20d
+#define IA32_MTRR_PHYSBASE7 0x20e
+#define IA32_MTRR_PHYSMASK7 0x20f
+#define IA32_MTRR_PHYSBASE8 0x210
+#define IA32_MTRR_PHYSMASK8 0x211
+#define IA32_MTRR_PHYSBASE9 0x212
+#define IA32_MTRR_PHYSMASK9 0x213
+
+/** Fixed range MTRRs.
+ * @{ */
+#define IA32_MTRR_FIX64K_00000 0x250
+#define IA32_MTRR_FIX16K_80000 0x258
+#define IA32_MTRR_FIX16K_A0000 0x259
+#define IA32_MTRR_FIX4K_C0000 0x268
+#define IA32_MTRR_FIX4K_C8000 0x269
+#define IA32_MTRR_FIX4K_D0000 0x26a
+#define IA32_MTRR_FIX4K_D8000 0x26b
+#define IA32_MTRR_FIX4K_E0000 0x26c
+#define IA32_MTRR_FIX4K_E8000 0x26d
+#define IA32_MTRR_FIX4K_F0000 0x26e
+#define IA32_MTRR_FIX4K_F8000 0x26f
+/** @} */
+
+/** MTRR Default Range. */
+#define MSR_IA32_MTRR_DEF_TYPE 0x2FF
+
+#define MSR_IA32_MC0_CTL 0x400
+#define MSR_IA32_MC0_STATUS 0x401
+
+/** Basic VMX information. */
+#define MSR_IA32_VMX_BASIC_INFO 0x480
+/** Allowed settings for pin-based VM execution controls */
+#define MSR_IA32_VMX_PINBASED_CTLS 0x481
+/** Allowed settings for proc-based VM execution controls */
+#define MSR_IA32_VMX_PROCBASED_CTLS 0x482
+/** Allowed settings for the VMX exit controls. */
+#define MSR_IA32_VMX_EXIT_CTLS 0x483
+/** Allowed settings for the VMX entry controls. */
+#define MSR_IA32_VMX_ENTRY_CTLS 0x484
+/** Misc VMX info. */
+#define MSR_IA32_VMX_MISC 0x485
+/** Fixed cleared bits in CR0. */
+#define MSR_IA32_VMX_CR0_FIXED0 0x486
+/** Fixed set bits in CR0. */
+#define MSR_IA32_VMX_CR0_FIXED1 0x487
+/** Fixed cleared bits in CR4. */
+#define MSR_IA32_VMX_CR4_FIXED0 0x488
+/** Fixed set bits in CR4. */
+#define MSR_IA32_VMX_CR4_FIXED1 0x489
+/** Information for enumerating fields in the VMCS. */
+#define MSR_IA32_VMX_VMCS_ENUM 0x48A
+/** Allowed settings for secondary proc-based VM execution controls */
+#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48B
+/** EPT capabilities. */
+#define MSR_IA32_VMX_EPT_CAPS 0x48C
+/** DS Save Area (R/W). */
+#define MSR_IA32_DS_AREA 0x600
+/** X2APIC MSR ranges. */
+#define MSR_IA32_APIC_START 0x800
+#define MSR_IA32_APIC_END 0x900
+
+/** K6 EFER - Extended Feature Enable Register. */
+#define MSR_K6_EFER 0xc0000080
+/** @todo document EFER */
+/** Bit 0 - SCE - System call extensions (SYSCALL / SYSRET). (R/W) */
+#define MSR_K6_EFER_SCE RT_BIT(0)
+/** Bit 8 - LME - Long mode enabled. (R/W) */
+#define MSR_K6_EFER_LME RT_BIT(8)
+/** Bit 10 - LMA - Long mode active. (R) */
+#define MSR_K6_EFER_LMA RT_BIT(10)
+/** Bit 11 - NXE - No-Execute Page Protection Enabled. (R/W) */
+#define MSR_K6_EFER_NXE RT_BIT(11)
+/** Bit 12 - SVME - Secure VM Extension Enabled. (R/W) */
+#define MSR_K6_EFER_SVME RT_BIT(12)
+/** Bit 13 - LMSLE - Long Mode Segment Limit Enable. (R/W?) */
+#define MSR_K6_EFER_LMSLE RT_BIT(13)
+/** Bit 14 - FFXSR - Fast FXSAVE / FXRSTOR (skip XMM*). (R/W) */
+#define MSR_K6_EFER_FFXSR RT_BIT(14)
+/** K6 STAR - SYSCALL/RET targets. */
+#define MSR_K6_STAR 0xc0000081
+/** Shift value for getting the SYSRET CS and SS value. */
+#define MSR_K6_STAR_SYSRET_CS_SS_SHIFT 48
+/** Shift value for getting the SYSCALL CS and SS value. */
+#define MSR_K6_STAR_SYSCALL_CS_SS_SHIFT 32
+/** Selector mask for use after shifting. */
+#define MSR_K6_STAR_SEL_MASK 0xffff
+/** The mask which give the SYSCALL EIP. */
+#define MSR_K6_STAR_SYSCALL_EIP_MASK 0xffffffff
+/** K6 WHCR - Write Handling Control Register. */
+#define MSR_K6_WHCR 0xc0000082
+/** K6 UWCCR - UC/WC Cacheability Control Register. */
+#define MSR_K6_UWCCR 0xc0000085
+/** K6 PSOR - Processor State Observability Register. */
+#define MSR_K6_PSOR 0xc0000087
+/** K6 PFIR - Page Flush/Invalidate Register. */
+#define MSR_K6_PFIR 0xc0000088
+
+/** Performance counter MSRs. (AMD only) */
+#define MSR_K7_EVNTSEL0 0xc0010000
+#define MSR_K7_EVNTSEL1 0xc0010001
+#define MSR_K7_EVNTSEL2 0xc0010002
+#define MSR_K7_EVNTSEL3 0xc0010003
+#define MSR_K7_PERFCTR0 0xc0010004
+#define MSR_K7_PERFCTR1 0xc0010005
+#define MSR_K7_PERFCTR2 0xc0010006
+#define MSR_K7_PERFCTR3 0xc0010007
+
+/** K8 LSTAR - Long mode SYSCALL target (RIP). */
+#define MSR_K8_LSTAR 0xc0000082
+/** K8 CSTAR - Compatibility mode SYSCALL target (RIP). */
+#define MSR_K8_CSTAR 0xc0000083
+/** K8 SF_MASK - SYSCALL flag mask. (aka SFMASK) */
+#define MSR_K8_SF_MASK 0xc0000084
+/** K8 FS.base - The 64-bit base FS register. */
+#define MSR_K8_FS_BASE 0xc0000100
+/** K8 GS.base - The 64-bit base GS register. */
+#define MSR_K8_GS_BASE 0xc0000101
+/** K8 KernelGSbase - Used with SWAPGS. */
+#define MSR_K8_KERNEL_GS_BASE 0xc0000102
+/** K8 TSC_AUX - Used with RDTSCP. */
+#define MSR_K8_TSC_AUX 0xc0000103
+#define MSR_K8_SYSCFG 0xc0010010
+#define MSR_K8_HWCR 0xc0010015
+#define MSR_K8_IORRBASE0 0xc0010016
+#define MSR_K8_IORRMASK0 0xc0010017
+#define MSR_K8_IORRBASE1 0xc0010018
+#define MSR_K8_IORRMASK1 0xc0010019
+#define MSR_K8_TOP_MEM1 0xc001001a
+#define MSR_K8_TOP_MEM2 0xc001001d
+#define MSR_K8_VM_CR 0xc0010114
+#define MSR_K8_VM_CR_SVM_DISABLE RT_BIT(4)
+
+#define MSR_K8_IGNNE 0xc0010115
+#define MSR_K8_SMM_CTL 0xc0010116
+/** SVM - VM_HSAVE_PA - Physical address for saving and restoring
+ * host state during world switch.
+ */
+#define MSR_K8_VM_HSAVE_PA 0xc0010117
+
+/** @} */
+
+
+/** @name Page Table / Directory / Directory Pointers / L4.
+ * @{
+ */
+
+/** Page table/directory entry as an unsigned integer. */
+typedef uint32_t X86PGUINT;
+/** Pointer to a page table/directory table entry as an unsigned integer. */
+typedef X86PGUINT *PX86PGUINT;
+/** Pointer to an const page table/directory table entry as an unsigned integer. */
+typedef X86PGUINT const *PCX86PGUINT;
+
+/** Number of entries in a 32-bit PT/PD. */
+#define X86_PG_ENTRIES 1024
+
+
+/** PAE page table/page directory/pdpt/l4/l5 entry as an unsigned integer. */
+typedef uint64_t X86PGPAEUINT;
+/** Pointer to a PAE page table/page directory/pdpt/l4/l5 entry as an unsigned integer. */
+typedef X86PGPAEUINT *PX86PGPAEUINT;
+/** Pointer to an const PAE page table/page directory/pdpt/l4/l5 entry as an unsigned integer. */
+typedef X86PGPAEUINT const *PCX86PGPAEUINT;
+
+/** Number of entries in a PAE PT/PD. */
+#define X86_PG_PAE_ENTRIES 512
+/** Number of entries in a PAE PDPT. */
+#define X86_PG_PAE_PDPE_ENTRIES 4
+
+/** Number of entries in an AMD64 PT/PD/PDPT/L4/L5. */
+#define X86_PG_AMD64_ENTRIES X86_PG_PAE_ENTRIES
+/** Number of entries in an AMD64 PDPT.
+ * Just for complementing X86_PG_PAE_PDPE_ENTRIES, using X86_PG_AMD64_ENTRIES for this is fine too. */
+#define X86_PG_AMD64_PDPE_ENTRIES X86_PG_AMD64_ENTRIES
+
+/** The size of a 4KB page. */
+#define X86_PAGE_4K_SIZE _4K
+/** The page shift of a 4KB page. */
+#define X86_PAGE_4K_SHIFT 12
+/** The 4KB page offset mask. */
+#define X86_PAGE_4K_OFFSET_MASK 0xfff
+/** The 4KB page base mask for virtual addresses. */
+#define X86_PAGE_4K_BASE_MASK 0xfffffffffffff000ULL
+/** The 4KB page base mask for virtual addresses - 32bit version. */
+#define X86_PAGE_4K_BASE_MASK_32 0xfffff000U
+
+/** The size of a 2MB page. */
+#define X86_PAGE_2M_SIZE _2M
+/** The page shift of a 2MB page. */
+#define X86_PAGE_2M_SHIFT 21
+/** The 2MB page offset mask. */
+#define X86_PAGE_2M_OFFSET_MASK 0x001fffff
+/** The 2MB page base mask for virtual addresses. */
+#define X86_PAGE_2M_BASE_MASK 0xffffffffffe00000ULL
+/** The 2MB page base mask for virtual addresses - 32bit version. */
+#define X86_PAGE_2M_BASE_MASK_32 0xffe00000U
+
+/** The size of a 4MB page. */
+#define X86_PAGE_4M_SIZE _4M
+/** The page shift of a 4MB page. */
+#define X86_PAGE_4M_SHIFT 22
+/** The 4MB page offset mask. */
+#define X86_PAGE_4M_OFFSET_MASK 0x003fffff
+/** The 4MB page base mask for virtual addresses. */
+#define X86_PAGE_4M_BASE_MASK 0xffffffffffc00000ULL
+/** The 4MB page base mask for virtual addresses - 32bit version. */
+#define X86_PAGE_4M_BASE_MASK_32 0xffc00000U
+
+
+
+/** @name Page Table Entry
+ * @{
+ */
+/** Bit 0 - P - Present bit. */
+#define X86_PTE_BIT_P 0
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PTE_BIT_RW 1
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PTE_BIT_US 2
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PTE_BIT_PWT 3
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PTE_BIT_PCD 4
+/** Bit 5 - A - Access bit. */
+#define X86_PTE_BIT_A 5
+/** Bit 6 - D - Dirty bit. */
+#define X86_PTE_BIT_D 6
+/** Bit 7 - PAT - Page Attribute Table index bit. Reserved and 0 if not supported. */
+#define X86_PTE_BIT_PAT 7
+/** Bit 8 - G - Global flag. */
+#define X86_PTE_BIT_G 8
+
+/** Bit 0 - P - Present bit mask. */
+#define X86_PTE_P RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit mask. */
+#define X86_PTE_RW RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit mask. */
+#define X86_PTE_US RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit mask. */
+#define X86_PTE_PWT RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit mask. */
+#define X86_PTE_PCD RT_BIT(4)
+/** Bit 5 - A - Access bit mask. */
+#define X86_PTE_A RT_BIT(5)
+/** Bit 6 - D - Dirty bit mask. */
+#define X86_PTE_D RT_BIT(6)
+/** Bit 7 - PAT - Page Attribute Table index bit mask. Reserved and 0 if not supported. */
+#define X86_PTE_PAT RT_BIT(7)
+/** Bit 8 - G - Global bit mask. */
+#define X86_PTE_G RT_BIT(8)
+
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PTE_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-31 - - Physical Page number of the next level. */
+#define X86_PTE_PG_MASK ( 0xfffff000 )
+
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PTE_PAE_PG_MASK UINT64_C(0x000ffffffffff000)
+/** Bits 63 - NX - PAE/LM - No execution flag. */
+#define X86_PTE_PAE_NX RT_BIT_64(63)
+/** Bits 62-52 - - PAE - MBZ bits when NX is active. */
+#define X86_PTE_PAE_MBZ_MASK_NX UINT64_C(0x7ff0000000000000)
+/** Bits 63-52 - - PAE - MBZ bits when no NX. */
+#define X86_PTE_PAE_MBZ_MASK_NO_NX UINT64_C(0xfff0000000000000)
+/** No bits - - LM - MBZ bits when NX is active. */
+#define X86_PTE_LM_MBZ_MASK_NX UINT64_C(0x0000000000000000)
+/** Bits 63 - - LM - MBZ bits when no NX. */
+#define X86_PTE_LM_MBZ_MASK_NO_NX UINT64_C(0x8000000000000000)
+
+/**
+ * Page table entry.
+ */
+typedef struct X86PTEBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ unsigned u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ unsigned u1Write : 1;
+ /** User(=1) / Supervisor (=0) flag. */
+ unsigned u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ unsigned u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ unsigned u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page have been read or written to. */
+ unsigned u1Accessed : 1;
+ /** Dirty flag.
+ * Indicates that the page has been written to. */
+ unsigned u1Dirty : 1;
+ /** Reserved / If PAT enabled, bit 2 of the index. */
+ unsigned u1PAT : 1;
+ /** Global flag. (Ignored in all but final level.) */
+ unsigned u1Global : 1;
+ /** Available for use to system software. */
+ unsigned u3Available : 3;
+ /** Physical Page number of the next level. */
+ unsigned u20PageNo : 20;
+} X86PTEBITS;
+/** Pointer to a page table entry. */
+typedef X86PTEBITS *PX86PTEBITS;
+/** Pointer to a const page table entry. */
+typedef const X86PTEBITS *PCX86PTEBITS;
+
+/**
+ * Page table entry.
+ */
+typedef union X86PTE
+{
+ /** Unsigned integer view */
+ X86PGUINT u;
+ /** Bit field view. */
+ X86PTEBITS n;
+ /** 32-bit view. */
+ uint32_t au32[1];
+ /** 16-bit view. */
+ uint16_t au16[2];
+ /** 8-bit view. */
+ uint8_t au8[4];
+} X86PTE;
+/** Pointer to a page table entry. */
+typedef X86PTE *PX86PTE;
+/** Pointer to a const page table entry. */
+typedef const X86PTE *PCX86PTE;
+
+
+/**
+ * PAE page table entry.
+ */
+typedef struct X86PTEPAEBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ uint32_t u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ uint32_t u1Write : 1;
+ /** User(=1) / Supervisor(=0) flag. */
+ uint32_t u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ uint32_t u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ uint32_t u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page have been read or written to. */
+ uint32_t u1Accessed : 1;
+ /** Dirty flag.
+ * Indicates that the page has been written to. */
+ uint32_t u1Dirty : 1;
+ /** Reserved / If PAT enabled, bit 2 of the index. */
+ uint32_t u1PAT : 1;
+ /** Global flag. (Ignored in all but final level.) */
+ uint32_t u1Global : 1;
+ /** Available for use to system software. */
+ uint32_t u3Available : 3;
+ /** Physical Page number of the next level - Low Part. Don't use this. */
+ uint32_t u20PageNoLow : 20;
+ /** Physical Page number of the next level - High Part. Don't use this. */
+ uint32_t u20PageNoHigh : 20;
+ /** MBZ bits */
+ uint32_t u11Reserved : 11;
+ /** No Execute flag. */
+ uint32_t u1NoExecute : 1;
+} X86PTEPAEBITS;
+/** Pointer to a page table entry. */
+typedef X86PTEPAEBITS *PX86PTEPAEBITS;
+/** Pointer to a page table entry. */
+typedef const X86PTEPAEBITS *PCX86PTEPAEBITS;
+
+/**
+ * PAE Page table entry.
+ */
+typedef union X86PTEPAE
+{
+ /** Unsigned integer view */
+ X86PGPAEUINT u;
+ /** Bit field view. */
+ X86PTEPAEBITS n;
+ /** 32-bit view. */
+ uint32_t au32[2];
+ /** 16-bit view. */
+ uint16_t au16[4];
+ /** 8-bit view. */
+ uint8_t au8[8];
+} X86PTEPAE;
+/** Pointer to a PAE page table entry. */
+typedef X86PTEPAE *PX86PTEPAE;
+/** Pointer to a const PAE page table entry. */
+typedef const X86PTEPAE *PCX86PTEPAE;
+/** @} */
+
+/**
+ * Page table.
+ */
+typedef struct X86PT
+{
+ /** PTE Array. */
+ X86PTE a[X86_PG_ENTRIES];
+} X86PT;
+/** Pointer to a page table. */
+typedef X86PT *PX86PT;
+/** Pointer to a const page table. */
+typedef const X86PT *PCX86PT;
+
+/** The page shift to get the PT index. */
+#define X86_PT_SHIFT 12
+/** The PT index mask (apply to a shifted page address). */
+#define X86_PT_MASK 0x3ff
+
+
+/**
+ * Page directory.
+ */
+typedef struct X86PTPAE
+{
+ /** PTE Array. */
+ X86PTEPAE a[X86_PG_PAE_ENTRIES];
+} X86PTPAE;
+/** Pointer to a page table. */
+typedef X86PTPAE *PX86PTPAE;
+/** Pointer to a const page table. */
+typedef const X86PTPAE *PCX86PTPAE;
+
+/** The page shift to get the PA PTE index. */
+#define X86_PT_PAE_SHIFT 12
+/** The PAE PT index mask (apply to a shifted page address). */
+#define X86_PT_PAE_MASK 0x1ff
+
+
+/** @name 4KB Page Directory Entry
+ * @{
+ */
+/** Bit 0 - P - Present bit. */
+#define X86_PDE_P RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PDE_RW RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PDE_US RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PDE_PWT RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PDE_PCD RT_BIT(4)
+/** Bit 5 - A - Access bit. */
+#define X86_PDE_A RT_BIT(5)
+/** Bit 7 - PS - Page size attribute.
+ * Clear mean 4KB pages, set means large pages (2/4MB). */
+#define X86_PDE_PS RT_BIT(7)
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PDE_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-31 - - Physical Page number of the next level. */
+#define X86_PDE_PG_MASK ( 0xfffff000 )
+
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PDE_PAE_PG_MASK UINT64_C(0x000ffffffffff000)
+/** Bits 63 - NX - PAE/LM - No execution flag. */
+#define X86_PDE_PAE_NX RT_BIT_64(63)
+/** Bits 62-52, 7 - - PAE - MBZ bits when NX is active. */
+#define X86_PDE_PAE_MBZ_MASK_NX UINT64_C(0x7ff0000000000080)
+/** Bits 63-52, 7 - - PAE - MBZ bits when no NX. */
+#define X86_PDE_PAE_MBZ_MASK_NO_NX UINT64_C(0xfff0000000000080)
+/** Bit 7 - - LM - MBZ bits when NX is active. */
+#define X86_PDE_LM_MBZ_MASK_NX UINT64_C(0x0000000000000080)
+/** Bits 63, 7 - - LM - MBZ bits when no NX. */
+#define X86_PDE_LM_MBZ_MASK_NO_NX UINT64_C(0x8000000000000080)
+
+/**
+ * Page directory entry.
+ */
+typedef struct X86PDEBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ unsigned u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ unsigned u1Write : 1;
+ /** User(=1) / Supervisor (=0) flag. */
+ unsigned u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ unsigned u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ unsigned u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page has been read or written to. */
+ unsigned u1Accessed : 1;
+ /** Reserved / Ignored (dirty bit). */
+ unsigned u1Reserved0 : 1;
+ /** Size bit if PSE is enabled - in any event it's 0. */
+ unsigned u1Size : 1;
+ /** Reserved / Ignored (global bit). */
+ unsigned u1Reserved1 : 1;
+ /** Available for use to system software. */
+ unsigned u3Available : 3;
+ /** Physical Page number of the next level. */
+ unsigned u20PageNo : 20;
+} X86PDEBITS;
+/** Pointer to a page directory entry. */
+typedef X86PDEBITS *PX86PDEBITS;
+/** Pointer to a const page directory entry. */
+typedef const X86PDEBITS *PCX86PDEBITS;
+
+
+/**
+ * PAE page directory entry.
+ */
+typedef struct X86PDEPAEBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ uint32_t u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ uint32_t u1Write : 1;
+ /** User(=1) / Supervisor (=0) flag. */
+ uint32_t u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ uint32_t u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ uint32_t u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page has been read or written to. */
+ uint32_t u1Accessed : 1;
+ /** Reserved / Ignored (dirty bit). */
+ uint32_t u1Reserved0 : 1;
+ /** Size bit if PSE is enabled - in any event it's 0. */
+ uint32_t u1Size : 1;
+ /** Reserved / Ignored (global bit). / */
+ uint32_t u1Reserved1 : 1;
+ /** Available for use to system software. */
+ uint32_t u3Available : 3;
+ /** Physical Page number of the next level - Low Part. Don't use! */
+ uint32_t u20PageNoLow : 20;
+ /** Physical Page number of the next level - High Part. Don't use! */
+ uint32_t u20PageNoHigh : 20;
+ /** MBZ bits */
+ uint32_t u11Reserved : 11;
+ /** No Execute flag. */
+ uint32_t u1NoExecute : 1;
+} X86PDEPAEBITS;
+/** Pointer to a page directory entry. */
+typedef X86PDEPAEBITS *PX86PDEPAEBITS;
+/** Pointer to a const page directory entry. */
+typedef const X86PDEPAEBITS *PCX86PDEPAEBITS;
+
+/** @} */
+
+
+/** @name 2/4MB Page Directory Entry
+ * @{
+ */
+/** Bit 0 - P - Present bit. */
+#define X86_PDE4M_P RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PDE4M_RW RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PDE4M_US RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PDE4M_PWT RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PDE4M_PCD RT_BIT(4)
+/** Bit 5 - A - Access bit. */
+#define X86_PDE4M_A RT_BIT(5)
+/** Bit 6 - D - Dirty bit. */
+#define X86_PDE4M_D RT_BIT(6)
+/** Bit 7 - PS - Page size attribute. Clear mean 4KB pages, set means large pages (2/4MB). */
+#define X86_PDE4M_PS RT_BIT(7)
+/** Bit 8 - G - Global flag. */
+#define X86_PDE4M_G RT_BIT(8)
+/** Bits 9-11 - AVL - Available for use to system software. */
+#define X86_PDE4M_AVL (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bit 12 - PAT - Page Attribute Table index bit. Reserved and 0 if not supported. */
+#define X86_PDE4M_PAT RT_BIT(12)
+/** Shift to get from X86_PTE_PAT to X86_PDE4M_PAT. */
+#define X86_PDE4M_PAT_SHIFT (12 - 7)
+/** Bits 22-31 - - Physical Page number. */
+#define X86_PDE4M_PG_MASK ( 0xffc00000 )
+/** Bits 20-13 - - Physical Page number high part (32-39 bits). AMD64 hack. */
+#define X86_PDE4M_PG_HIGH_MASK ( 0x001fe000 )
+/** The number of bits to the high part of the page number. */
+#define X86_PDE4M_PG_HIGH_SHIFT 19
+/** Bit 21 - - MBZ bits for AMD CPUs, no PSE36. */
+#define X86_PDE4M_MBZ_MASK RT_BIT_32(21)
+
+/** Bits 21-51 - - PAE/LM - Physical Page number.
+ * (Bits 40-51 (long mode) & bits 36-51 (pae legacy) are reserved according to the Intel docs; AMD allows for more.) */
+#define X86_PDE2M_PAE_PG_MASK UINT64_C(0x000fffffffe00000)
+/** Bits 63 - NX - PAE/LM - No execution flag. */
+#define X86_PDE2M_PAE_NX RT_BIT_64(63)
+/** Bits 62-52, 20-13 - - PAE - MBZ bits when NX is active. */
+#define X86_PDE2M_PAE_MBZ_MASK_NX UINT64_C(0x7ff00000001fe000)
+/** Bits 63-52, 20-13 - - PAE - MBZ bits when no NX. */
+#define X86_PDE2M_PAE_MBZ_MASK_NO_NX UINT64_C(0xfff00000001fe000)
+/** Bits 20-13 - - LM - MBZ bits when NX is active. */
+#define X86_PDE2M_LM_MBZ_MASK_NX UINT64_C(0x00000000001fe000)
+/** Bits 63, 20-13 - - LM - MBZ bits when no NX. */
+#define X86_PDE2M_LM_MBZ_MASK_NO_NX UINT64_C(0x80000000001fe000)
+
+/**
+ * 4MB page directory entry.
+ */
+typedef struct X86PDE4MBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ unsigned u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ unsigned u1Write : 1;
+ /** User(=1) / Supervisor (=0) flag. */
+ unsigned u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ unsigned u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ unsigned u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page have been read or written to. */
+ unsigned u1Accessed : 1;
+ /** Dirty flag.
+ * Indicates that the page has been written to. */
+ unsigned u1Dirty : 1;
+ /** Page size flag - always 1 for 4MB entries. */
+ unsigned u1Size : 1;
+ /** Global flag. */
+ unsigned u1Global : 1;
+ /** Available for use to system software. */
+ unsigned u3Available : 3;
+ /** Reserved / If PAT enabled, bit 2 of the index. */
+ unsigned u1PAT : 1;
+ /** Bits 32-39 of the page number on AMD64.
+ * This AMD64 hack allows accessing 40bits of physical memory without PAE. */
+ unsigned u8PageNoHigh : 8;
+ /** Reserved. */
+ unsigned u1Reserved : 1;
+ /** Physical Page number of the page. */
+ unsigned u10PageNo : 10;
+} X86PDE4MBITS;
+/** Pointer to a page table entry. */
+typedef X86PDE4MBITS *PX86PDE4MBITS;
+/** Pointer to a const page table entry. */
+typedef const X86PDE4MBITS *PCX86PDE4MBITS;
+
+
+/**
+ * 2MB PAE page directory entry.
+ */
+typedef struct X86PDE2MPAEBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ uint32_t u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ uint32_t u1Write : 1;
+ /** User(=1) / Supervisor(=0) flag. */
+ uint32_t u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ uint32_t u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ uint32_t u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page have been read or written to. */
+ uint32_t u1Accessed : 1;
+ /** Dirty flag.
+ * Indicates that the page has been written to. */
+ uint32_t u1Dirty : 1;
+ /** Page size flag - always 1 for 2MB entries. */
+ uint32_t u1Size : 1;
+ /** Global flag. */
+ uint32_t u1Global : 1;
+ /** Available for use to system software. */
+ uint32_t u3Available : 3;
+ /** Reserved / If PAT enabled, bit 2 of the index. */
+ uint32_t u1PAT : 1;
+ /** Reserved. */
+ uint32_t u9Reserved : 9;
+ /** Physical Page number of the next level - Low part. Don't use! */
+ uint32_t u10PageNoLow : 10;
+ /** Physical Page number of the next level - High part. Don't use! */
+ uint32_t u20PageNoHigh : 20;
+ /** MBZ bits */
+ uint32_t u11Reserved : 11;
+ /** No Execute flag. */
+ uint32_t u1NoExecute : 1;
+} X86PDE2MPAEBITS;
+/** Pointer to a 2MB PAE page table entry. */
+typedef X86PDE2MPAEBITS *PX86PDE2MPAEBITS;
+/** Pointer to a 2MB PAE page table entry. */
+typedef const X86PDE2MPAEBITS *PCX86PDE2MPAEBITS;
+
+/** @} */
+
+/**
+ * Page directory entry.
+ */
+typedef union X86PDE
+{
+ /** Unsigned integer view. */
+ X86PGUINT u;
+ /** Normal view. */
+ X86PDEBITS n;
+ /** 4MB view (big). */
+ X86PDE4MBITS b;
+ /** 8 bit unsigned integer view. */
+ uint8_t au8[4];
+ /** 16 bit unsigned integer view. */
+ uint16_t au16[2];
+ /** 32 bit unsigned integer view. */
+ uint32_t au32[1];
+} X86PDE;
+/** Pointer to a page directory entry. */
+typedef X86PDE *PX86PDE;
+/** Pointer to a const page directory entry. */
+typedef const X86PDE *PCX86PDE;
+
+/**
+ * PAE page directory entry.
+ */
+typedef union X86PDEPAE
+{
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** Normal view. */
+ X86PDEPAEBITS n;
+ /** 2MB page view (big). */
+ X86PDE2MPAEBITS b;
+ /** 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];
+} X86PDEPAE;
+/** Pointer to a page directory entry. */
+typedef X86PDEPAE *PX86PDEPAE;
+/** Pointer to a const page directory entry. */
+typedef const X86PDEPAE *PCX86PDEPAE;
+
+/**
+ * Page directory.
+ */
+typedef struct X86PD
+{
+ /** PDE Array. */
+ X86PDE a[X86_PG_ENTRIES];
+} X86PD;
+/** Pointer to a page directory. */
+typedef X86PD *PX86PD;
+/** Pointer to a const page directory. */
+typedef const X86PD *PCX86PD;
+
+/** The page shift to get the PD index. */
+#define X86_PD_SHIFT 22
+/** The PD index mask (apply to a shifted page address). */
+#define X86_PD_MASK 0x3ff
+
+
+/**
+ * PAE page directory.
+ */
+typedef struct X86PDPAE
+{
+ /** PDE Array. */
+ X86PDEPAE a[X86_PG_PAE_ENTRIES];
+} X86PDPAE;
+/** Pointer to a PAE page directory. */
+typedef X86PDPAE *PX86PDPAE;
+/** Pointer to a const PAE page directory. */
+typedef const X86PDPAE *PCX86PDPAE;
+
+/** The page shift to get the PAE PD index. */
+#define X86_PD_PAE_SHIFT 21
+/** The PAE PD index mask (apply to a shifted page address). */
+#define X86_PD_PAE_MASK 0x1ff
+
+
+/** @name Page Directory Pointer Table Entry (PAE)
+ * @{
+ */
+/** Bit 0 - P - Present bit. */
+#define X86_PDPE_P RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. Long Mode only. */
+#define X86_PDPE_RW RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. Long Mode only. */
+#define X86_PDPE_US RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PDPE_PWT RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PDPE_PCD RT_BIT(4)
+/** Bit 5 - A - Access bit. Long Mode only. */
+#define X86_PDPE_A RT_BIT(5)
+/** Bit 7 - PS - Page size (1GB). Long Mode only. */
+#define X86_PDPE_LM_PS RT_BIT(7)
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PDPE_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PDPE_PG_MASK UINT64_C(0x000ffffffffff000)
+/** Bits 63-52, 8-5, 2-1 - - PAE - MBZ bits (NX is long mode only). */
+#define X86_PDPE_PAE_MBZ_MASK UINT64_C(0xfff00000000001e6)
+/** Bits 63 - NX - LM - No execution flag. Long Mode only. */
+#define X86_PDPE_LM_NX RT_BIT_64(63)
+/** Bits 8, 7 - - LM - MBZ bits when NX is active. */
+#define X86_PDPE_LM_MBZ_MASK_NX UINT64_C(0x0000000000000180)
+/** Bits 63, 8, 7 - - LM - MBZ bits when no NX. */
+#define X86_PDPE_LM_MBZ_MASK_NO_NX UINT64_C(0x8000000000000180)
+/** Bits 29-13 - - LM - MBZ bits for 1GB page entry when NX is active. */
+#define X86_PDPE1G_LM_MBZ_MASK_NX UINT64_C(0x000000003fffe000)
+/** Bits 63, 29-13 - - LM - MBZ bits for 1GB page entry when no NX. */
+#define X86_PDPE1G_LM_MBZ_MASK_NO_NX UINT64_C(0x800000003fffe000)
+
+
+/**
+ * Page directory pointer table entry.
+ */
+typedef struct X86PDPEBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ uint32_t u1Present : 1;
+ /** Chunk of reserved bits. */
+ uint32_t u2Reserved : 2;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ uint32_t u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ uint32_t u1CacheDisable : 1;
+ /** Chunk of reserved bits. */
+ uint32_t u4Reserved : 4;
+ /** Available for use to system software. */
+ uint32_t u3Available : 3;
+ /** Physical Page number of the next level - Low Part. Don't use! */
+ uint32_t u20PageNoLow : 20;
+ /** Physical Page number of the next level - High Part. Don't use! */
+ uint32_t u20PageNoHigh : 20;
+ /** MBZ bits */
+ uint32_t u12Reserved : 12;
+} X86PDPEBITS;
+/** Pointer to a page directory pointer table entry. */
+typedef X86PDPEBITS *PX86PTPEBITS;
+/** Pointer to a const page directory pointer table entry. */
+typedef const X86PDPEBITS *PCX86PTPEBITS;
+
+/**
+ * Page directory pointer table entry. AMD64 version
+ */
+typedef struct X86PDPEAMD64BITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ uint32_t u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ uint32_t u1Write : 1;
+ /** User(=1) / Supervisor (=0) flag. */
+ uint32_t u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ uint32_t u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ uint32_t u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page have been read or written to. */
+ uint32_t u1Accessed : 1;
+ /** Chunk of reserved bits. */
+ uint32_t u3Reserved : 3;
+ /** Available for use to system software. */
+ uint32_t u3Available : 3;
+ /** Physical Page number of the next level - Low Part. Don't use! */
+ uint32_t u20PageNoLow : 20;
+ /** Physical Page number of the next level - High Part. Don't use! */
+ uint32_t u20PageNoHigh : 20;
+ /** MBZ bits */
+ uint32_t u11Reserved : 11;
+ /** No Execute flag. */
+ uint32_t u1NoExecute : 1;
+} X86PDPEAMD64BITS;
+/** Pointer to a page directory pointer table entry. */
+typedef X86PDPEAMD64BITS *PX86PDPEAMD64BITS;
+/** Pointer to a const page directory pointer table entry. */
+typedef const X86PDPEAMD64BITS *PCX86PDPEAMD64BITS;
+
+/**
+ * Page directory pointer table entry.
+ */
+typedef union X86PDPE
+{
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** Normal view. */
+ X86PDPEBITS n;
+ /** AMD64 view. */
+ X86PDPEAMD64BITS lm;
+ /** 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];
+} X86PDPE;
+/** Pointer to a page directory pointer table entry. */
+typedef X86PDPE *PX86PDPE;
+/** Pointer to a const page directory pointer table entry. */
+typedef const X86PDPE *PCX86PDPE;
+
+
+/**
+ * Page directory pointer table.
+ */
+typedef struct X86PDPT
+{
+ /** PDE Array. */
+ X86PDPE a[X86_PG_AMD64_PDPE_ENTRIES];
+} X86PDPT;
+/** Pointer to a page directory pointer table. */
+typedef X86PDPT *PX86PDPT;
+/** Pointer to a const page directory pointer table. */
+typedef const X86PDPT *PCX86PDPT;
+
+/** The page shift to get the PDPT index. */
+#define X86_PDPT_SHIFT 30
+/** The PDPT index mask (apply to a shifted page address). (32 bits PAE) */
+#define X86_PDPT_MASK_PAE 0x3
+/** The PDPT index mask (apply to a shifted page address). (64 bits PAE)*/
+#define X86_PDPT_MASK_AMD64 0x1ff
+
+/** @} */
+
+
+/** @name Page Map Level-4 Entry (Long Mode PAE)
+ * @{
+ */
+/** Bit 0 - P - Present bit. */
+#define X86_PML4E_P RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) / Write (set) bit. */
+#define X86_PML4E_RW RT_BIT(1)
+/** Bit 2 - U/S - User (set) / Supervisor (clear) bit. */
+#define X86_PML4E_US RT_BIT(2)
+/** Bit 3 - PWT - Page level write thru bit. */
+#define X86_PML4E_PWT RT_BIT(3)
+/** Bit 4 - PCD - Page level cache disable bit. */
+#define X86_PML4E_PCD RT_BIT(4)
+/** Bit 5 - A - Access bit. */
+#define X86_PML4E_A RT_BIT(5)
+/** Bits 9-11 - - Available for use to system software. */
+#define X86_PML4E_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bits 12-51 - - PAE - Physical Page number of the next level. */
+#define X86_PML4E_PG_MASK UINT64_C(0x000ffffffffff000)
+/** Bits 8, 7 - - MBZ bits when NX is active. */
+#define X86_PML4E_MBZ_MASK_NX UINT64_C(0x0000000000000080)
+/** Bits 63, 7 - - MBZ bits when no NX. */
+#define X86_PML4E_MBZ_MASK_NO_NX UINT64_C(0x8000000000000080)
+/** Bits 63 - NX - PAE - No execution flag. */
+#define X86_PML4E_NX RT_BIT_64(63)
+
+/**
+ * Page Map Level-4 Entry
+ */
+typedef struct X86PML4EBITS
+{
+ /** Flags whether(=1) or not the page is present. */
+ uint32_t u1Present : 1;
+ /** Read(=0) / Write(=1) flag. */
+ uint32_t u1Write : 1;
+ /** User(=1) / Supervisor (=0) flag. */
+ uint32_t u1User : 1;
+ /** Write Thru flag. If PAT enabled, bit 0 of the index. */
+ uint32_t u1WriteThru : 1;
+ /** Cache disabled flag. If PAT enabled, bit 1 of the index. */
+ uint32_t u1CacheDisable : 1;
+ /** Accessed flag.
+ * Indicates that the page have been read or written to. */
+ uint32_t u1Accessed : 1;
+ /** Chunk of reserved bits. */
+ uint32_t u3Reserved : 3;
+ /** Available for use to system software. */
+ uint32_t u3Available : 3;
+ /** Physical Page number of the next level - Low Part. Don't use! */
+ uint32_t u20PageNoLow : 20;
+ /** Physical Page number of the next level - High Part. Don't use! */
+ uint32_t u20PageNoHigh : 20;
+ /** MBZ bits */
+ uint32_t u11Reserved : 11;
+ /** No Execute flag. */
+ uint32_t u1NoExecute : 1;
+} X86PML4EBITS;
+/** Pointer to a page map level-4 entry. */
+typedef X86PML4EBITS *PX86PML4EBITS;
+/** Pointer to a const page map level-4 entry. */
+typedef const X86PML4EBITS *PCX86PML4EBITS;
+
+/**
+ * Page Map Level-4 Entry.
+ */
+typedef union X86PML4E
+{
+ /** Unsigned integer view. */
+ X86PGPAEUINT u;
+ /** Normal view. */
+ X86PML4EBITS n;
+ /** 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];
+} X86PML4E;
+/** Pointer to a page map level-4 entry. */
+typedef X86PML4E *PX86PML4E;
+/** Pointer to a const page map level-4 entry. */
+typedef const X86PML4E *PCX86PML4E;
+
+
+/**
+ * Page Map Level-4.
+ */
+typedef struct X86PML4
+{
+ /** PDE Array. */
+ X86PML4E a[X86_PG_PAE_ENTRIES];
+} X86PML4;
+/** Pointer to a page map level-4. */
+typedef X86PML4 *PX86PML4;
+/** Pointer to a const page map level-4. */
+typedef const X86PML4 *PCX86PML4;
+
+/** The page shift to get the PML4 index. */
+#define X86_PML4_SHIFT 39
+/** The PML4 index mask (apply to a shifted page address). */
+#define X86_PML4_MASK 0x1ff
+
+/** @} */
+
+/** @} */
+
+
+/**
+ * 80-bit MMX/FPU register type.
+ */
+typedef struct X86FPUMMX
+{
+ uint8_t reg[10];
+} X86FPUMMX;
+/** Pointer to a 80-bit MMX/FPU register type. */
+typedef X86FPUMMX *PX86FPUMMX;
+/** Pointer to a const 80-bit MMX/FPU register type. */
+typedef const X86FPUMMX *PCX86FPUMMX;
+
+/**
+ * 32-bit FPU state (aka FSAVE/FRSTOR Memory Region).
+ * @todo verify this...
+ */
+#pragma pack(1)
+typedef struct X86FPUSTATE
+{
+ /** 0x00 - Control word. */
+ uint16_t FCW;
+ /** 0x02 - Alignment word */
+ uint16_t Dummy1;
+ /** 0x04 - Status word. */
+ uint16_t FSW;
+ /** 0x06 - Alignment word */
+ uint16_t Dummy2;
+ /** 0x08 - Tag word */
+ uint16_t FTW;
+ /** 0x0a - Alignment word */
+ uint16_t Dummy3;
+
+ /** 0x0c - Instruction pointer. */
+ uint32_t FPUIP;
+ /** 0x10 - Code selector. */
+ uint16_t CS;
+ /** 0x12 - Opcode. */
+ uint16_t FOP;
+ /** 0x14 - FOO. */
+ uint32_t FPUOO;
+ /** 0x18 - FOS. */
+ uint32_t FPUOS;
+ /** 0x1c */
+ union
+ {
+ /** MMX view. */
+ uint64_t mmx;
+ /** FPU view - todo. */
+ X86FPUMMX fpu;
+ /** Extended precision floating point view. */
+ RTFLOAT80U r80;
+ /** Extended precision floating point view v2. */
+ RTFLOAT80U2 r80Ex;
+ /** 8-bit view. */
+ uint8_t au8[16];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 32-bit view. */
+ uint32_t au32[4];
+ /** 64-bit view. */
+ uint64_t au64[2];
+ /** 128-bit view. (yeah, very helpful) */
+ uint128_t au128[1];
+ } regs[8];
+} X86FPUSTATE;
+#pragma pack()
+/** Pointer to a FPU state. */
+typedef X86FPUSTATE *PX86FPUSTATE;
+/** Pointer to a const FPU state. */
+typedef const X86FPUSTATE *PCX86FPUSTATE;
+
+/**
+ * FPU Extended state (aka FXSAVE/FXRSTORE Memory Region).
+ */
+#pragma pack(1)
+typedef struct X86FXSTATE
+{
+ /** 0x00 - Control word. */
+ uint16_t FCW;
+ /** 0x02 - Status word. */
+ uint16_t FSW;
+ /** 0x04 - Tag word. (The upper byte is always zero.) */
+ uint16_t FTW;
+ /** 0x06 - Opcode. */
+ uint16_t FOP;
+ /** 0x08 - Instruction pointer. */
+ uint32_t FPUIP;
+ /** 0x0c - Code selector. */
+ uint16_t CS;
+ uint16_t Rsrvd1;
+ /** 0x10 - Data pointer. */
+ uint32_t FPUDP;
+ /** 0x14 - Data segment */
+ uint16_t DS;
+ /** 0x16 */
+ uint16_t Rsrvd2;
+ /** 0x18 */
+ uint32_t MXCSR;
+ /** 0x1c */
+ uint32_t MXCSR_MASK;
+ /** 0x20 */
+ union
+ {
+ /** MMX view. */
+ uint64_t mmx;
+ /** FPU view - todo. */
+ X86FPUMMX fpu;
+ /** Extended precision floating point view. */
+ RTFLOAT80U r80;
+ /** Extended precision floating point view v2 */
+ RTFLOAT80U2 r80Ex;
+ /** 8-bit view. */
+ uint8_t au8[16];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 32-bit view. */
+ uint32_t au32[4];
+ /** 64-bit view. */
+ uint64_t au64[2];
+ /** 128-bit view. (yeah, very helpful) */
+ uint128_t au128[1];
+ } aRegs[8];
+ /* - offset 160 - */
+ union
+ {
+ /** XMM Register view *. */
+ uint128_t xmm;
+ /** 8-bit view. */
+ uint8_t au8[16];
+ /** 16-bit view. */
+ uint16_t au16[8];
+ /** 32-bit view. */
+ uint32_t au32[4];
+ /** 64-bit view. */
+ uint64_t au64[2];
+ /** 128-bit view. (yeah, very helpful) */
+ uint128_t au128[1];
+ } aXMM[16]; /* 8 registers in 32 bits mode; 16 in long mode */
+ /* - offset 416 - */
+ uint32_t au32RsrvdRest[(512 - 416) / sizeof(uint32_t)];
+} X86FXSTATE;
+#pragma pack()
+/** Pointer to a FPU Extended state. */
+typedef X86FXSTATE *PX86FXSTATE;
+/** Pointer to a const FPU Extended state. */
+typedef const X86FXSTATE *PCX86FXSTATE;
+
+/** @name FPU status word flags.
+ * @{ */
+/** Exception Flag: Invalid operation. */
+#define X86_FSW_IE RT_BIT(0)
+/** Exception Flag: Denormalized operand. */
+#define X86_FSW_DE RT_BIT(1)
+/** Exception Flag: Zero divide. */
+#define X86_FSW_ZE RT_BIT(2)
+/** Exception Flag: Overflow. */
+#define X86_FSW_OE RT_BIT(3)
+/** Exception Flag: Underflow. */
+#define X86_FSW_UE RT_BIT(4)
+/** Exception Flag: Precision. */
+#define X86_FSW_PE RT_BIT(5)
+/** Stack fault. */
+#define X86_FSW_SF RT_BIT(6)
+/** Error summary status. */
+#define X86_FSW_ES RT_BIT(7)
+/** Mask of exceptions flags, excluding the summary bit. */
+#define X86_FSW_XCPT_MASK UINT16_C(0x007f)
+/** Mask of exceptions flags, including the summary bit. */
+#define X86_FSW_XCPT_ES_MASK UINT16_C(0x00ff)
+/** Condition code 0. */
+#define X86_FSW_C0 RT_BIT(8)
+/** Condition code 1. */
+#define X86_FSW_C1 RT_BIT(9)
+/** Condition code 2. */
+#define X86_FSW_C2 RT_BIT(10)
+/** Top of the stack mask. */
+#define X86_FSW_TOP_MASK UINT16_C(0x3800)
+/** TOP shift value. */
+#define X86_FSW_TOP_SHIFT 11
+/** Mask for getting TOP value after shifting it right. */
+#define X86_FSW_TOP_SMASK UINT16_C(0x0007)
+/** Get the TOP value. */
+#define X86_FSW_TOP_GET(a_uFsw) (((a_uFsw) >> X86_FSW_TOP_SHIFT) & X86_FSW_TOP_SMASK)
+/** Condition code 3. */
+#define X86_FSW_C3 RT_BIT(14)
+/** Mask of exceptions flags, including the summary bit. */
+#define X86_FSW_C_MASK UINT16_C(0x4700)
+/** FPU busy. */
+#define X86_FSW_B RT_BIT(15)
+/** @} */
+
+
+/** @name FPU control word flags.
+ * @{ */
+/** Exception Mask: Invalid operation. */
+#define X86_FCW_IM RT_BIT(0)
+/** Exception Mask: Denormalized operand. */
+#define X86_FCW_DM RT_BIT(1)
+/** Exception Mask: Zero divide. */
+#define X86_FCW_ZM RT_BIT(2)
+/** Exception Mask: Overflow. */
+#define X86_FCW_OM RT_BIT(3)
+/** Exception Mask: Underflow. */
+#define X86_FCW_UM RT_BIT(4)
+/** Exception Mask: Precision. */
+#define X86_FCW_PM RT_BIT(5)
+/** Mask all exceptions, the value typically loaded (by for instance fninit).
+ * @remarks This includes reserved bit 6. */
+#define X86_FCW_MASK_ALL UINT16_C(0x007f)
+/** Mask all exceptions. Same as X86_FSW_XCPT_MASK. */
+#define X86_FCW_XCPT_MASK UINT16_C(0x003f)
+/** Precision control mask. */
+#define X86_FCW_PC_MASK UINT16_C(0x0300)
+/** Precision control: 24-bit. */
+#define X86_FCW_PC_24 UINT16_C(0x0000)
+/** Precision control: Reserved. */
+#define X86_FCW_PC_RSVD UINT16_C(0x0100)
+/** Precision control: 53-bit. */
+#define X86_FCW_PC_53 UINT16_C(0x0200)
+/** Precision control: 64-bit. */
+#define X86_FCW_PC_64 UINT16_C(0x0300)
+/** Rounding control mask. */
+#define X86_FCW_RC_MASK UINT16_C(0x0c00)
+/** Rounding control: To nearest. */
+#define X86_FCW_RC_NEAREST UINT16_C(0x0000)
+/** Rounding control: Down. */
+#define X86_FCW_RC_DOWN UINT16_C(0x0400)
+/** Rounding control: Up. */
+#define X86_FCW_RC_UP UINT16_C(0x0800)
+/** Rounding control: Towards zero. */
+#define X86_FCW_RC_ZERO UINT16_C(0x0c00)
+/** Bits which should be zero, apparently. */
+#define X86_FCW_ZERO_MASK UINT16_C(0xf080)
+/** @} */
+
+
+/** @name Selector Descriptor
+ * @{
+ */
+
+#ifndef VBOX_FOR_DTRACE_LIB
+/**
+ * Descriptor attributes.
+ */
+typedef struct X86DESCATTRBITS
+{
+ /** 00 - Segment Type. */
+ unsigned u4Type : 4;
+ /** 04 - Descriptor Type. System(=0) or code/data selector */
+ unsigned u1DescType : 1;
+ /** 05 - Descriptor Privelege level. */
+ unsigned u2Dpl : 2;
+ /** 07 - Flags selector present(=1) or not. */
+ unsigned u1Present : 1;
+ /** 08 - Segment limit 16-19. */
+ unsigned u4LimitHigh : 4;
+ /** 0c - Available for system software. */
+ unsigned u1Available : 1;
+ /** 0d - 32 bits mode: Reserved - 0, long mode: Long Attribute Bit. */
+ unsigned u1Long : 1;
+ /** 0e - This flags meaning depends on the segment type. Try make sense out
+ * of the intel manual yourself. */
+ unsigned u1DefBig : 1;
+ /** 0f - Granularity of the limit. If set 4KB granularity is used, if
+ * clear byte. */
+ unsigned u1Granularity : 1;
+} X86DESCATTRBITS;
+#endif /* !VBOX_FOR_DTRACE_LIB */
+
+#pragma pack(1)
+typedef union X86DESCATTR
+{
+ /** Unsigned integer view. */
+ uint32_t u;
+#ifndef VBOX_FOR_DTRACE_LIB
+ /** Normal view. */
+ X86DESCATTRBITS n;
+#endif
+} X86DESCATTR;
+#pragma pack()
+/** Pointer to descriptor attributes. */
+typedef X86DESCATTR *PX86DESCATTR;
+/** Pointer to const descriptor attributes. */
+typedef const X86DESCATTR *PCX86DESCATTR;
+
+#ifndef VBOX_FOR_DTRACE_LIB
+
+/**
+ * Generic descriptor table entry
+ */
+#pragma pack(1)
+typedef struct X86DESCGENERIC
+{
+ /** Limit - Low word. */
+ unsigned u16LimitLow : 16;
+ /** Base address - lowe word.
+ * Don't try set this to 24 because MSC is doing stupid things then. */
+ unsigned u16BaseLow : 16;
+ /** Base address - first 8 bits of high word. */
+ unsigned u8BaseHigh1 : 8;
+ /** Segment Type. */
+ unsigned u4Type : 4;
+ /** Descriptor Type. System(=0) or code/data selector */
+ unsigned u1DescType : 1;
+ /** Descriptor Privelege level. */
+ unsigned u2Dpl : 2;
+ /** Flags selector present(=1) or not. */
+ unsigned u1Present : 1;
+ /** Segment limit 16-19. */
+ unsigned u4LimitHigh : 4;
+ /** Available for system software. */
+ unsigned u1Available : 1;
+ /** 32 bits mode: Reserved - 0, long mode: Long Attribute Bit. */
+ unsigned u1Long : 1;
+ /** This flags meaning depends on the segment type. Try make sense out
+ * of the intel manual yourself. */
+ unsigned u1DefBig : 1;
+ /** Granularity of the limit. If set 4KB granularity is used, if
+ * clear byte. */
+ unsigned u1Granularity : 1;
+ /** Base address - highest 8 bits. */
+ unsigned u8BaseHigh2 : 8;
+} X86DESCGENERIC;
+#pragma pack()
+/** Pointer to a generic descriptor entry. */
+typedef X86DESCGENERIC *PX86DESCGENERIC;
+/** Pointer to a const generic descriptor entry. */
+typedef const X86DESCGENERIC *PCX86DESCGENERIC;
+
+/** @name Bit offsets of X86DESCGENERIC members.
+ * @{*/
+#define X86DESCGENERIC_BIT_OFF_LIMIT_LOW (0) /**< Bit offset of X86DESCGENERIC::u16LimitLow. */
+#define X86DESCGENERIC_BIT_OFF_BASE_LOW (16) /**< Bit offset of X86DESCGENERIC::u16BaseLow. */
+#define X86DESCGENERIC_BIT_OFF_BASE_HIGH1 (32) /**< Bit offset of X86DESCGENERIC::u8BaseHigh1. */
+#define X86DESCGENERIC_BIT_OFF_TYPE (40) /**< Bit offset of X86DESCGENERIC::u4Type. */
+#define X86DESCGENERIC_BIT_OFF_DESC_TYPE (44) /**< Bit offset of X86DESCGENERIC::u1DescType. */
+#define X86DESCGENERIC_BIT_OFF_DPL (45) /**< Bit offset of X86DESCGENERIC::u2Dpl. */
+#define X86DESCGENERIC_BIT_OFF_PRESENT (47) /**< Bit offset of X86DESCGENERIC::uu1Present. */
+#define X86DESCGENERIC_BIT_OFF_LIMIT_HIGH (48) /**< Bit offset of X86DESCGENERIC::u4LimitHigh. */
+#define X86DESCGENERIC_BIT_OFF_AVAILABLE (52) /**< Bit offset of X86DESCGENERIC::u1Available. */
+#define X86DESCGENERIC_BIT_OFF_LONG (53) /**< Bit offset of X86DESCGENERIC::u1Long. */
+#define X86DESCGENERIC_BIT_OFF_DEF_BIG (54) /**< Bit offset of X86DESCGENERIC::u1DefBig. */
+#define X86DESCGENERIC_BIT_OFF_GRANULARITY (55) /**< Bit offset of X86DESCGENERIC::u1Granularity. */
+#define X86DESCGENERIC_BIT_OFF_BASE_HIGH2 (56) /**< Bit offset of X86DESCGENERIC::u8BaseHigh2. */
+/** @} */
+
+/**
+ * Call-, Interrupt-, Trap- or Task-gate descriptor (legacy).
+ */
+typedef struct X86DESCGATE
+{
+ /** 00 - Target code segment offset - Low word.
+ * Ignored if task-gate. */
+ unsigned u16OffsetLow : 16;
+ /** 10 - Target code segment selector for call-, interrupt- and trap-gates,
+ * TSS selector if task-gate. */
+ unsigned u16Sel : 16;
+ /** 20 - Number of parameters for a call-gate.
+ * Ignored if interrupt-, trap- or task-gate. */
+ unsigned u4ParmCount : 4;
+ /** 24 - Reserved / ignored. */
+ unsigned u4Reserved : 4;
+ /** 28 - Segment Type. */
+ unsigned u4Type : 4;
+ /** 2c - Descriptor Type (0 = system). */
+ unsigned u1DescType : 1;
+ /** 2d - Descriptor Privelege level. */
+ unsigned u2Dpl : 2;
+ /** 2f - Flags selector present(=1) or not. */
+ unsigned u1Present : 1;
+ /** 30 - Target code segment offset - High word.
+ * Ignored if task-gate. */
+ unsigned u16OffsetHigh : 16;
+} X86DESCGATE;
+/** Pointer to a Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef X86DESCGATE *PX86DESCGATE;
+/** Pointer to a const Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef const X86DESCGATE *PCX86DESCGATE;
+
+#endif /* VBOX_FOR_DTRACE_LIB */
+
+/**
+ * Descriptor table entry.
+ */
+#pragma pack(1)
+typedef union X86DESC
+{
+#ifndef VBOX_FOR_DTRACE_LIB
+ /** Generic descriptor view. */
+ X86DESCGENERIC Gen;
+ /** Gate descriptor view. */
+ X86DESCGATE Gate;
+#endif
+
+ /** 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[1];
+ /** Unsigned integer view. */
+ uint64_t u;
+} X86DESC;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86DESC, 8);
+#endif
+#pragma pack()
+/** Pointer to descriptor table entry. */
+typedef X86DESC *PX86DESC;
+/** Pointer to const descriptor table entry. */
+typedef const X86DESC *PCX86DESC;
+
+/** @def X86DESC_BASE
+ * Return the base address of a descriptor.
+ */
+#define X86DESC_BASE(a_pDesc) /*ASM-NOINC*/ \
+ ( ((uint32_t)((a_pDesc)->Gen.u8BaseHigh2) << 24) \
+ | ( (a_pDesc)->Gen.u8BaseHigh1 << 16) \
+ | ( (a_pDesc)->Gen.u16BaseLow ) )
+
+/** @def X86DESC_LIMIT
+ * Return the limit of a descriptor.
+ */
+#define X86DESC_LIMIT(a_pDesc) /*ASM-NOINC*/ \
+ ( ((uint32_t)((a_pDesc)->Gen.u4LimitHigh) << 16) \
+ | ( (a_pDesc)->Gen.u16LimitLow ) )
+
+/** @def X86DESC_LIMIT_G
+ * Return the limit of a descriptor with the granularity bit taken into account.
+ * @returns Selector limit (uint32_t).
+ * @param a_pDesc Pointer to the descriptor.
+ */
+#define X86DESC_LIMIT_G(a_pDesc) /*ASM-NOINC*/ \
+ ( (a_pDesc)->Gen.u1Granularity \
+ ? ( ( ((uint32_t)(a_pDesc)->Gen.u4LimitHigh << 16) | (a_pDesc)->Gen.u16LimitLow ) << 12 ) | UINT32_C(0xfff) \
+ : ((uint32_t)(a_pDesc)->Gen.u4LimitHigh << 16) | (a_pDesc)->Gen.u16LimitLow \
+ )
+
+/** @def X86DESC_GET_HID_ATTR
+ * Get the descriptor attributes for the hidden register.
+ */
+#define X86DESC_GET_HID_ATTR(a_pDesc) /*ASM-NOINC*/ \
+ ( ((a_pDesc)->u >> (16+16+8)) & UINT32_C(0xf0ff) ) /** @todo do we have a define for 0xf0ff? */
+
+#ifndef VBOX_FOR_DTRACE_LIB
+
+/**
+ * 64 bits generic descriptor table entry
+ * Note: most of these bits have no meaning in long mode.
+ */
+#pragma pack(1)
+typedef struct X86DESC64GENERIC
+{
+ /** Limit - Low word - *IGNORED*. */
+ unsigned u16LimitLow : 16;
+ /** Base address - low word. - *IGNORED*
+ * Don't try set this to 24 because MSC is doing stupid things then. */
+ unsigned u16BaseLow : 16;
+ /** Base address - first 8 bits of high word. - *IGNORED* */
+ unsigned u8BaseHigh1 : 8;
+ /** Segment Type. */
+ unsigned u4Type : 4;
+ /** Descriptor Type. System(=0) or code/data selector */
+ unsigned u1DescType : 1;
+ /** Descriptor Privelege level. */
+ unsigned u2Dpl : 2;
+ /** Flags selector present(=1) or not. */
+ unsigned u1Present : 1;
+ /** Segment limit 16-19. - *IGNORED* */
+ unsigned u4LimitHigh : 4;
+ /** Available for system software. - *IGNORED* */
+ unsigned u1Available : 1;
+ /** Long mode flag. */
+ unsigned u1Long : 1;
+ /** This flags meaning depends on the segment type. Try make sense out
+ * of the intel manual yourself. */
+ unsigned u1DefBig : 1;
+ /** Granularity of the limit. If set 4KB granularity is used, if
+ * clear byte. - *IGNORED* */
+ unsigned u1Granularity : 1;
+ /** Base address - highest 8 bits. - *IGNORED* */
+ unsigned u8BaseHigh2 : 8;
+ /** Base address - bits 63-32. */
+ unsigned u32BaseHigh3 : 32;
+ unsigned u8Reserved : 8;
+ unsigned u5Zeros : 5;
+ unsigned u19Reserved : 19;
+} X86DESC64GENERIC;
+#pragma pack()
+/** Pointer to a generic descriptor entry. */
+typedef X86DESC64GENERIC *PX86DESC64GENERIC;
+/** Pointer to a const generic descriptor entry. */
+typedef const X86DESC64GENERIC *PCX86DESC64GENERIC;
+
+/**
+ * System descriptor table entry (64 bits)
+ *
+ * @remarks This is, save a couple of comments, identical to X86DESC64GENERIC...
+ */
+#pragma pack(1)
+typedef struct X86DESC64SYSTEM
+{
+ /** Limit - Low word. */
+ unsigned u16LimitLow : 16;
+ /** Base address - lowe word.
+ * Don't try set this to 24 because MSC is doing stupid things then. */
+ unsigned u16BaseLow : 16;
+ /** Base address - first 8 bits of high word. */
+ unsigned u8BaseHigh1 : 8;
+ /** Segment Type. */
+ unsigned u4Type : 4;
+ /** Descriptor Type. System(=0) or code/data selector */
+ unsigned u1DescType : 1;
+ /** Descriptor Privelege level. */
+ unsigned u2Dpl : 2;
+ /** Flags selector present(=1) or not. */
+ unsigned u1Present : 1;
+ /** Segment limit 16-19. */
+ unsigned u4LimitHigh : 4;
+ /** Available for system software. */
+ unsigned u1Available : 1;
+ /** Reserved - 0. */
+ unsigned u1Reserved : 1;
+ /** This flags meaning depends on the segment type. Try make sense out
+ * of the intel manual yourself. */
+ unsigned u1DefBig : 1;
+ /** Granularity of the limit. If set 4KB granularity is used, if
+ * clear byte. */
+ unsigned u1Granularity : 1;
+ /** Base address - bits 31-24. */
+ unsigned u8BaseHigh2 : 8;
+ /** Base address - bits 63-32. */
+ unsigned u32BaseHigh3 : 32;
+ unsigned u8Reserved : 8;
+ unsigned u5Zeros : 5;
+ unsigned u19Reserved : 19;
+} X86DESC64SYSTEM;
+#pragma pack()
+/** Pointer to a system descriptor entry. */
+typedef X86DESC64SYSTEM *PX86DESC64SYSTEM;
+/** Pointer to a const system descriptor entry. */
+typedef const X86DESC64SYSTEM *PCX86DESC64SYSTEM;
+
+/**
+ * Call-, Interrupt-, Trap- or Task-gate descriptor (64-bit).
+ */
+typedef struct X86DESC64GATE
+{
+ /** Target code segment offset - Low word. */
+ unsigned u16OffsetLow : 16;
+ /** Target code segment selector. */
+ unsigned u16Sel : 16;
+ /** Interrupt stack table for interrupt- and trap-gates.
+ * Ignored by call-gates. */
+ unsigned u3IST : 3;
+ /** Reserved / ignored. */
+ unsigned u5Reserved : 5;
+ /** Segment Type. */
+ unsigned u4Type : 4;
+ /** Descriptor Type (0 = system). */
+ unsigned u1DescType : 1;
+ /** Descriptor Privelege level. */
+ unsigned u2Dpl : 2;
+ /** Flags selector present(=1) or not. */
+ unsigned u1Present : 1;
+ /** Target code segment offset - High word.
+ * Ignored if task-gate. */
+ unsigned u16OffsetHigh : 16;
+ /** Target code segment offset - Top dword.
+ * Ignored if task-gate. */
+ unsigned u32OffsetTop : 32;
+ /** Reserved / ignored / must be zero.
+ * For call-gates bits 8 thru 12 must be zero, the other gates ignores this. */
+ unsigned u32Reserved : 32;
+} X86DESC64GATE;
+AssertCompileSize(X86DESC64GATE, 16);
+/** Pointer to a Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef X86DESC64GATE *PX86DESC64GATE;
+/** Pointer to a const Call-, Interrupt-, Trap- or Task-gate descriptor entry. */
+typedef const X86DESC64GATE *PCX86DESC64GATE;
+
+#endif /* VBOX_FOR_DTRACE_LIB */
+
+/**
+ * Descriptor table entry.
+ */
+#pragma pack(1)
+typedef union X86DESC64
+{
+#ifndef VBOX_FOR_DTRACE_LIB
+ /** Generic descriptor view. */
+ X86DESC64GENERIC Gen;
+ /** System descriptor view. */
+ X86DESC64SYSTEM System;
+ /** Gate descriptor view. */
+ X86DESC64GATE Gate;
+#endif
+
+ /** 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];
+} X86DESC64;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86DESC64, 16);
+#endif
+#pragma pack()
+/** Pointer to descriptor table entry. */
+typedef X86DESC64 *PX86DESC64;
+/** Pointer to const descriptor table entry. */
+typedef const X86DESC64 *PCX86DESC64;
+
+/** @def X86DESC64_BASE
+ * Return the base of a 64-bit descriptor.
+ */
+#define X86DESC64_BASE(a_pDesc) /*ASM-NOINC*/ \
+ ( ((uint64_t)((a_pDesc)->Gen.u32BaseHigh3) << 32) \
+ | ((uint32_t)((a_pDesc)->Gen.u8BaseHigh2) << 24) \
+ | ( (a_pDesc)->Gen.u8BaseHigh1 << 16) \
+ | ( (a_pDesc)->Gen.u16BaseLow ) )
+
+
+
+/** @name Host system descriptor table entry - Use with care!
+ * @{ */
+/** Host system descriptor table entry. */
+#if HC_ARCH_BITS == 64
+typedef X86DESC64 X86DESCHC;
+#else
+typedef X86DESC X86DESCHC;
+#endif
+/** Pointer to a host system descriptor table entry. */
+#if HC_ARCH_BITS == 64
+typedef PX86DESC64 PX86DESCHC;
+#else
+typedef PX86DESC PX86DESCHC;
+#endif
+/** Pointer to a const host system descriptor table entry. */
+#if HC_ARCH_BITS == 64
+typedef PCX86DESC64 PCX86DESCHC;
+#else
+typedef PCX86DESC PCX86DESCHC;
+#endif
+/** @} */
+
+
+/** @name Selector Descriptor Types.
+ * @{
+ */
+
+/** @name Non-System Selector Types.
+ * @{ */
+/** Code(=set)/Data(=clear) bit. */
+#define X86_SEL_TYPE_CODE 8
+/** Memory(=set)/System(=clear) bit. */
+#define X86_SEL_TYPE_MEMORY RT_BIT(4)
+/** Accessed bit. */
+#define X86_SEL_TYPE_ACCESSED 1
+/** Expand down bit (for data selectors only). */
+#define X86_SEL_TYPE_DOWN 4
+/** Conforming bit (for code selectors only). */
+#define X86_SEL_TYPE_CONF 4
+/** Write bit (for data selectors only). */
+#define X86_SEL_TYPE_WRITE 2
+/** Read bit (for code selectors only). */
+#define X86_SEL_TYPE_READ 2
+/** The bit number of the code segment read bit (relative to u4Type). */
+#define X86_SEL_TYPE_READ_BIT 1
+
+/** Read only selector type. */
+#define X86_SEL_TYPE_RO 0
+/** Accessed read only selector type. */
+#define X86_SEL_TYPE_RO_ACC (0 | X86_SEL_TYPE_ACCESSED)
+/** Read write selector type. */
+#define X86_SEL_TYPE_RW 2
+/** Accessed read write selector type. */
+#define X86_SEL_TYPE_RW_ACC (2 | X86_SEL_TYPE_ACCESSED)
+/** Expand down read only selector type. */
+#define X86_SEL_TYPE_RO_DOWN 4
+/** Accessed expand down read only selector type. */
+#define X86_SEL_TYPE_RO_DOWN_ACC (4 | X86_SEL_TYPE_ACCESSED)
+/** Expand down read write selector type. */
+#define X86_SEL_TYPE_RW_DOWN 6
+/** Accessed expand down read write selector type. */
+#define X86_SEL_TYPE_RW_DOWN_ACC (6 | X86_SEL_TYPE_ACCESSED)
+/** Execute only selector type. */
+#define X86_SEL_TYPE_EO (0 | X86_SEL_TYPE_CODE)
+/** Accessed execute only selector type. */
+#define X86_SEL_TYPE_EO_ACC (0 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** Execute and read selector type. */
+#define X86_SEL_TYPE_ER (2 | X86_SEL_TYPE_CODE)
+/** Accessed execute and read selector type. */
+#define X86_SEL_TYPE_ER_ACC (2 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** Conforming execute only selector type. */
+#define X86_SEL_TYPE_EO_CONF (4 | X86_SEL_TYPE_CODE)
+/** Accessed Conforming execute only selector type. */
+#define X86_SEL_TYPE_EO_CONF_ACC (4 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** Conforming execute and write selector type. */
+#define X86_SEL_TYPE_ER_CONF (6 | X86_SEL_TYPE_CODE)
+/** Accessed Conforming execute and write selector type. */
+#define X86_SEL_TYPE_ER_CONF_ACC (6 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+/** @} */
+
+
+/** @name System Selector Types.
+ * @{ */
+/** The TSS busy bit mask. */
+#define X86_SEL_TYPE_SYS_TSS_BUSY_MASK 2
+
+/** Undefined system selector type. */
+#define X86_SEL_TYPE_SYS_UNDEFINED 0
+/** 286 TSS selector. */
+#define X86_SEL_TYPE_SYS_286_TSS_AVAIL 1
+/** LDT selector. */
+#define X86_SEL_TYPE_SYS_LDT 2
+/** 286 TSS selector - Busy. */
+#define X86_SEL_TYPE_SYS_286_TSS_BUSY 3
+/** 286 Callgate selector. */
+#define X86_SEL_TYPE_SYS_286_CALL_GATE 4
+/** Taskgate selector. */
+#define X86_SEL_TYPE_SYS_TASK_GATE 5
+/** 286 Interrupt gate selector. */
+#define X86_SEL_TYPE_SYS_286_INT_GATE 6
+/** 286 Trapgate selector. */
+#define X86_SEL_TYPE_SYS_286_TRAP_GATE 7
+/** Undefined system selector. */
+#define X86_SEL_TYPE_SYS_UNDEFINED2 8
+/** 386 TSS selector. */
+#define X86_SEL_TYPE_SYS_386_TSS_AVAIL 9
+/** Undefined system selector. */
+#define X86_SEL_TYPE_SYS_UNDEFINED3 0xA
+/** 386 TSS selector - Busy. */
+#define X86_SEL_TYPE_SYS_386_TSS_BUSY 0xB
+/** 386 Callgate selector. */
+#define X86_SEL_TYPE_SYS_386_CALL_GATE 0xC
+/** Undefined system selector. */
+#define X86_SEL_TYPE_SYS_UNDEFINED4 0xD
+/** 386 Interruptgate selector. */
+#define X86_SEL_TYPE_SYS_386_INT_GATE 0xE
+/** 386 Trapgate selector. */
+#define X86_SEL_TYPE_SYS_386_TRAP_GATE 0xF
+/** @} */
+
+/** @name AMD64 System Selector Types.
+ * @{ */
+/** LDT selector. */
+#define AMD64_SEL_TYPE_SYS_LDT 2
+/** TSS selector - Busy. */
+#define AMD64_SEL_TYPE_SYS_TSS_AVAIL 9
+/** TSS selector - Busy. */
+#define AMD64_SEL_TYPE_SYS_TSS_BUSY 0xB
+/** Callgate selector. */
+#define AMD64_SEL_TYPE_SYS_CALL_GATE 0xC
+/** Interruptgate selector. */
+#define AMD64_SEL_TYPE_SYS_INT_GATE 0xE
+/** Trapgate selector. */
+#define AMD64_SEL_TYPE_SYS_TRAP_GATE 0xF
+/** @} */
+
+/** @} */
+
+
+/** @name Descriptor Table Entry Flag Masks.
+ * These are for the 2nd 32-bit word of a descriptor.
+ * @{ */
+/** Bits 8-11 - TYPE - Descriptor type mask. */
+#define X86_DESC_TYPE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+/** Bit 12 - S - System (=0) or Code/Data (=1). */
+#define X86_DESC_S RT_BIT(12)
+/** Bits 13-14 - DPL - Descriptor Privilege Level. */
+#define X86_DESC_DPL (RT_BIT(13) | RT_BIT(14))
+/** Bit 15 - P - Present. */
+#define X86_DESC_P RT_BIT(15)
+/** Bit 20 - AVL - Available for system software. */
+#define X86_DESC_AVL RT_BIT(20)
+/** Bit 22 - DB - Default operation size. 0 = 16 bit, 1 = 32 bit. */
+#define X86_DESC_DB RT_BIT(22)
+/** Bit 23 - G - Granularity of the limit. If set 4KB granularity is
+ * used, if clear byte. */
+#define X86_DESC_G RT_BIT(23)
+/** @} */
+
+/** @} */
+
+
+/** @name Task Segments.
+ * @{
+ */
+
+/**
+ * 16-bit Task Segment (TSS).
+ */
+#pragma pack(1)
+typedef struct X86TSS16
+{
+ /** Back link to previous task. (static) */
+ RTSEL selPrev;
+ /** Ring-0 stack pointer. (static) */
+ uint16_t sp0;
+ /** Ring-0 stack segment. (static) */
+ RTSEL ss0;
+ /** Ring-1 stack pointer. (static) */
+ uint16_t sp1;
+ /** Ring-1 stack segment. (static) */
+ RTSEL ss1;
+ /** Ring-2 stack pointer. (static) */
+ uint16_t sp2;
+ /** Ring-2 stack segment. (static) */
+ RTSEL ss2;
+ /** IP before task switch. */
+ uint16_t ip;
+ /** FLAGS before task switch. */
+ uint16_t flags;
+ /** AX before task switch. */
+ uint16_t ax;
+ /** CX before task switch. */
+ uint16_t cx;
+ /** DX before task switch. */
+ uint16_t dx;
+ /** BX before task switch. */
+ uint16_t bx;
+ /** SP before task switch. */
+ uint16_t sp;
+ /** BP before task switch. */
+ uint16_t bp;
+ /** SI before task switch. */
+ uint16_t si;
+ /** DI before task switch. */
+ uint16_t di;
+ /** ES before task switch. */
+ RTSEL es;
+ /** CS before task switch. */
+ RTSEL cs;
+ /** SS before task switch. */
+ RTSEL ss;
+ /** DS before task switch. */
+ RTSEL ds;
+ /** LDTR before task switch. */
+ RTSEL selLdt;
+} X86TSS16;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86TSS16, 44);
+#endif
+#pragma pack()
+/** Pointer to a 16-bit task segment. */
+typedef X86TSS16 *PX86TSS16;
+/** Pointer to a const 16-bit task segment. */
+typedef const X86TSS16 *PCX86TSS16;
+
+
+/**
+ * 32-bit Task Segment (TSS).
+ */
+#pragma pack(1)
+typedef struct X86TSS32
+{
+ /** Back link to previous task. (static) */
+ RTSEL selPrev;
+ uint16_t padding1;
+ /** Ring-0 stack pointer. (static) */
+ uint32_t esp0;
+ /** Ring-0 stack segment. (static) */
+ RTSEL ss0;
+ uint16_t padding_ss0;
+ /** Ring-1 stack pointer. (static) */
+ uint32_t esp1;
+ /** Ring-1 stack segment. (static) */
+ RTSEL ss1;
+ uint16_t padding_ss1;
+ /** Ring-2 stack pointer. (static) */
+ uint32_t esp2;
+ /** Ring-2 stack segment. (static) */
+ RTSEL ss2;
+ uint16_t padding_ss2;
+ /** Page directory for the task. (static) */
+ uint32_t cr3;
+ /** EIP before task switch. */
+ uint32_t eip;
+ /** EFLAGS before task switch. */
+ uint32_t eflags;
+ /** EAX before task switch. */
+ uint32_t eax;
+ /** ECX before task switch. */
+ uint32_t ecx;
+ /** EDX before task switch. */
+ uint32_t edx;
+ /** EBX before task switch. */
+ uint32_t ebx;
+ /** ESP before task switch. */
+ uint32_t esp;
+ /** EBP before task switch. */
+ uint32_t ebp;
+ /** ESI before task switch. */
+ uint32_t esi;
+ /** EDI before task switch. */
+ uint32_t edi;
+ /** ES before task switch. */
+ RTSEL es;
+ uint16_t padding_es;
+ /** CS before task switch. */
+ RTSEL cs;
+ uint16_t padding_cs;
+ /** SS before task switch. */
+ RTSEL ss;
+ uint16_t padding_ss;
+ /** DS before task switch. */
+ RTSEL ds;
+ uint16_t padding_ds;
+ /** FS before task switch. */
+ RTSEL fs;
+ uint16_t padding_fs;
+ /** GS before task switch. */
+ RTSEL gs;
+ uint16_t padding_gs;
+ /** LDTR before task switch. */
+ RTSEL selLdt;
+ uint16_t padding_ldt;
+ /** Debug trap flag */
+ uint16_t fDebugTrap;
+ /** Offset relative to the TSS of the start of the I/O Bitmap
+ * and the end of the interrupt redirection bitmap. */
+ uint16_t offIoBitmap;
+ /** 32 bytes for the virtual interrupt redirection bitmap. (VME) */
+ uint8_t IntRedirBitmap[32];
+} X86TSS32;
+#pragma pack()
+/** Pointer to task segment. */
+typedef X86TSS32 *PX86TSS32;
+/** Pointer to const task segment. */
+typedef const X86TSS32 *PCX86TSS32;
+
+
+/**
+ * 64-bit Task segment.
+ */
+#pragma pack(1)
+typedef struct X86TSS64
+{
+ /** Reserved. */
+ uint32_t u32Reserved;
+ /** Ring-0 stack pointer. (static) */
+ uint64_t rsp0;
+ /** Ring-1 stack pointer. (static) */
+ uint64_t rsp1;
+ /** Ring-2 stack pointer. (static) */
+ uint64_t rsp2;
+ /** Reserved. */
+ uint32_t u32Reserved2[2];
+ /* IST */
+ uint64_t ist1;
+ uint64_t ist2;
+ uint64_t ist3;
+ uint64_t ist4;
+ uint64_t ist5;
+ uint64_t ist6;
+ uint64_t ist7;
+ /* Reserved. */
+ uint16_t u16Reserved[5];
+ /** Offset relative to the TSS of the start of the I/O Bitmap
+ * and the end of the interrupt redirection bitmap. */
+ uint16_t offIoBitmap;
+ /** 32 bytes for the virtual interrupt redirection bitmap. (VME) */
+ uint8_t IntRedirBitmap[32];
+} X86TSS64;
+#pragma pack()
+/** Pointer to a 64-bit task segment. */
+typedef X86TSS64 *PX86TSS64;
+/** Pointer to a const 64-bit task segment. */
+typedef const X86TSS64 *PCX86TSS64;
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompileSize(X86TSS64, 136);
+#endif
+
+/** @} */
+
+
+/** @name Selectors.
+ * @{
+ */
+
+/**
+ * The shift used to convert a selector from and to index an index (C).
+ */
+#define X86_SEL_SHIFT 3
+
+/**
+ * The mask used to mask off the table indicator and RPL of an selector.
+ */
+#define X86_SEL_MASK 0xfff8U
+
+/**
+ * The mask used to mask off the RPL of an selector.
+ * This is suitable for checking for NULL selectors.
+ */
+#define X86_SEL_MASK_OFF_RPL 0xfffcU
+
+/**
+ * The bit indicating that a selector is in the LDT and not in the GDT.
+ */
+#define X86_SEL_LDT 0x0004U
+
+/**
+ * The bit mask for getting the RPL of a selector.
+ */
+#define X86_SEL_RPL 0x0003U
+
+/**
+ * The mask covering both RPL and LDT.
+ * This is incidentally the same as sizeof(X86DESC) - 1, so good for limit
+ * checks.
+ */
+#define X86_SEL_RPL_LDT 0x0007U
+
+/** @} */
+
+
+/**
+ * x86 Exceptions/Faults/Traps.
+ */
+typedef enum X86XCPT
+{
+ /** \#DE - Divide error. */
+ X86_XCPT_DE = 0x00,
+ /** \#DB - Debug event (single step, DRx, ..) */
+ X86_XCPT_DB = 0x01,
+ /** NMI - Non-Maskable Interrupt */
+ X86_XCPT_NMI = 0x02,
+ /** \#BP - Breakpoint (INT3). */
+ X86_XCPT_BP = 0x03,
+ /** \#OF - Overflow (INTO). */
+ X86_XCPT_OF = 0x04,
+ /** \#BR - Bound range exceeded (BOUND). */
+ X86_XCPT_BR = 0x05,
+ /** \#UD - Undefined opcode. */
+ X86_XCPT_UD = 0x06,
+ /** \#NM - Device not available (math coprocessor device). */
+ X86_XCPT_NM = 0x07,
+ /** \#DF - Double fault. */
+ X86_XCPT_DF = 0x08,
+ /** ??? - Coprocessor segment overrun (obsolete). */
+ X86_XCPT_CO_SEG_OVERRUN = 0x09,
+ /** \#TS - Taskswitch (TSS). */
+ X86_XCPT_TS = 0x0a,
+ /** \#NP - Segment no present. */
+ X86_XCPT_NP = 0x0b,
+ /** \#SS - Stack segment fault. */
+ X86_XCPT_SS = 0x0c,
+ /** \#GP - General protection fault. */
+ X86_XCPT_GP = 0x0d,
+ /** \#PF - Page fault. */
+ X86_XCPT_PF = 0x0e,
+ /* 0x0f is reserved. */
+ /** \#MF - Math fault (FPU). */
+ X86_XCPT_MF = 0x10,
+ /** \#AC - Alignment check. */
+ X86_XCPT_AC = 0x11,
+ /** \#MC - Machine check. */
+ X86_XCPT_MC = 0x12,
+ /** \#XF - SIMD Floating-Pointer Exception. */
+ X86_XCPT_XF = 0x13
+} X86XCPT;
+/** Pointer to a x86 exception code. */
+typedef X86XCPT *PX86XCPT;
+/** Pointer to a const x86 exception code. */
+typedef const X86XCPT *PCX86XCPT;
+
+
+/** @name Trap Error Codes
+ * @{
+ */
+/** External indicator. */
+#define X86_TRAP_ERR_EXTERNAL 1
+/** IDT indicator. */
+#define X86_TRAP_ERR_IDT 2
+/** Descriptor table indicator - If set LDT, if clear GDT. */
+#define X86_TRAP_ERR_TI 4
+/** Mask for getting the selector. */
+#define X86_TRAP_ERR_SEL_MASK 0xfff8
+/** Shift for getting the selector table index (C type index). */
+#define X86_TRAP_ERR_SEL_SHIFT 3
+/** @} */
+
+
+/** @name \#PF Trap Error Codes
+ * @{
+ */
+/** Bit 0 - P - Not present (clear) or page level protection (set) fault. */
+#define X86_TRAP_PF_P RT_BIT(0)
+/** Bit 1 - R/W - Read (clear) or write (set) access. */
+#define X86_TRAP_PF_RW RT_BIT(1)
+/** Bit 2 - U/S - CPU executing in user mode (set) or supervisor mode (clear). */
+#define X86_TRAP_PF_US RT_BIT(2)
+/** Bit 3 - RSVD- Reserved bit violation (set), i.e. reserved bit was set to 1. */
+#define X86_TRAP_PF_RSVD RT_BIT(3)
+/** Bit 4 - I/D - Instruction fetch (set) / Data access (clear) - PAE + NXE. */
+#define X86_TRAP_PF_ID RT_BIT(4)
+/** @} */
+
+#pragma pack(1)
+/**
+ * 32-bit IDTR/GDTR.
+ */
+typedef struct X86XDTR32
+{
+ /** Size of the descriptor table. */
+ uint16_t cb;
+ /** Address of the descriptor table. */
+#ifndef VBOX_FOR_DTRACE_LIB
+ uint32_t uAddr;
+#else
+ uint16_t au16Addr[2];
+#endif
+} X86XDTR32, *PX86XDTR32;
+#pragma pack()
+
+#pragma pack(1)
+/**
+ * 64-bit IDTR/GDTR.
+ */
+typedef struct X86XDTR64
+{
+ /** Size of the descriptor table. */
+ uint16_t cb;
+ /** Address of the descriptor table. */
+#ifndef VBOX_FOR_DTRACE_LIB
+ uint64_t uAddr;
+#else
+ uint16_t au16Addr[4];
+#endif
+} X86XDTR64, *PX86XDTR64;
+#pragma pack()
+
+
+/** @name ModR/M
+ * @{ */
+#define X86_MODRM_RM_MASK UINT8_C(0x07)
+#define X86_MODRM_REG_MASK UINT8_C(0x38)
+#define X86_MODRM_REG_SMASK UINT8_C(0x07)
+#define X86_MODRM_REG_SHIFT 3
+#define X86_MODRM_MOD_MASK UINT8_C(0xc0)
+#define X86_MODRM_MOD_SMASK UINT8_C(0x03)
+#define X86_MODRM_MOD_SHIFT 6
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompile((X86_MODRM_RM_MASK | X86_MODRM_REG_MASK | X86_MODRM_MOD_MASK) == 0xff);
+AssertCompile((X86_MODRM_REG_MASK >> X86_MODRM_REG_SHIFT) == X86_MODRM_REG_SMASK);
+AssertCompile((X86_MODRM_MOD_MASK >> X86_MODRM_MOD_SHIFT) == X86_MODRM_MOD_SMASK);
+#endif
+/** @} */
+
+/** @name SIB
+ * @{ */
+#define X86_SIB_BASE_MASK UINT8_C(0x07)
+#define X86_SIB_INDEX_MASK UINT8_C(0x38)
+#define X86_SIB_INDEX_SMASK UINT8_C(0x07)
+#define X86_SIB_INDEX_SHIFT 3
+#define X86_SIB_SCALE_MASK UINT8_C(0xc0)
+#define X86_SIB_SCALE_SMASK UINT8_C(0x03)
+#define X86_SIB_SCALE_SHIFT 6
+#ifndef VBOX_FOR_DTRACE_LIB
+AssertCompile((X86_SIB_BASE_MASK | X86_SIB_INDEX_MASK | X86_SIB_SCALE_MASK) == 0xff);
+AssertCompile((X86_SIB_INDEX_MASK >> X86_SIB_INDEX_SHIFT) == X86_SIB_INDEX_SMASK);
+AssertCompile((X86_SIB_SCALE_MASK >> X86_SIB_SCALE_SHIFT) == X86_SIB_SCALE_SMASK);
+#endif
+/** @} */
+
+/** @name General register indexes
+ * @{ */
+#define X86_GREG_xAX 0
+#define X86_GREG_xCX 1
+#define X86_GREG_xDX 2
+#define X86_GREG_xBX 3
+#define X86_GREG_xSP 4
+#define X86_GREG_xBP 5
+#define X86_GREG_xSI 6
+#define X86_GREG_xDI 7
+#define X86_GREG_x8 8
+#define X86_GREG_x9 9
+#define X86_GREG_x10 10
+#define X86_GREG_x11 11
+#define X86_GREG_x12 12
+#define X86_GREG_x13 13
+#define X86_GREG_x14 14
+#define X86_GREG_x15 15
+/** @} */
+
+/** @name X86_SREG_XXX - Segment register indexes.
+ * @{ */
+#define X86_SREG_ES 0
+#define X86_SREG_CS 1
+#define X86_SREG_SS 2
+#define X86_SREG_DS 3
+#define X86_SREG_FS 4
+#define X86_SREG_GS 5
+/** @} */
+/** Segment register count. */
+#define X86_SREG_COUNT 6
+
+
+/** @} */
+
+#endif
+
diff --git a/include/iprt/x86.mac b/include/iprt/x86.mac
new file mode 100644
index 00000000..d9765261
--- /dev/null
+++ b/include/iprt/x86.mac
@@ -0,0 +1,706 @@
+%ifndef ___iprt_x86_h
+%define ___iprt_x86_h
+%ifndef VBOX_FOR_DTRACE_LIB
+%else
+%endif
+%ifdef RT_OS_SOLARIS
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%define X86_EFL_CF RT_BIT(0)
+%define X86_EFL_1 RT_BIT(1)
+%define X86_EFL_PF RT_BIT(2)
+%define X86_EFL_AF RT_BIT(4)
+%define X86_EFL_ZF RT_BIT(6)
+%define X86_EFL_SF RT_BIT(7)
+%define X86_EFL_TF RT_BIT(8)
+%define X86_EFL_IF RT_BIT(9)
+%define X86_EFL_DF RT_BIT(10)
+%define X86_EFL_OF RT_BIT(11)
+%define X86_EFL_IOPL (RT_BIT(12) | RT_BIT(13))
+%define X86_EFL_NT RT_BIT(14)
+%define X86_EFL_RF RT_BIT(16)
+%define X86_EFL_VM RT_BIT(17)
+%define X86_EFL_AC RT_BIT(18)
+%define X86_EFL_VIF RT_BIT(19)
+%define X86_EFL_VIP RT_BIT(20)
+%define X86_EFL_ID RT_BIT(21)
+%define X86_EFL_IOPL_SHIFT 12
+%define X86_EFL_GET_IOPL(efl) (((efl) >> X86_EFL_IOPL_SHIFT) & 3)
+%define X86_EFL_POPF_BITS (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_AC | X86_EFL_ID)
+%ifndef VBOX_FOR_DTRACE_LIB
+%else
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%else
+%endif
+%define X86_CPUID_VENDOR_INTEL_EBX 0x756e6547
+%define X86_CPUID_VENDOR_INTEL_ECX 0x6c65746e
+%define X86_CPUID_VENDOR_INTEL_EDX 0x49656e69
+%define X86_CPUID_VENDOR_AMD_EBX 0x68747541
+%define X86_CPUID_VENDOR_AMD_ECX 0x444d4163
+%define X86_CPUID_VENDOR_AMD_EDX 0x69746e65
+%define X86_CPUID_VENDOR_VIA_EBX 0x746e6543
+%define X86_CPUID_VENDOR_VIA_ECX 0x736c7561
+%define X86_CPUID_VENDOR_VIA_EDX 0x48727561
+%define X86_CPUID_FEATURE_ECX_SSE3 RT_BIT(0)
+%define X86_CPUID_FEATURE_ECX_PCLMUL RT_BIT(1)
+%define X86_CPUID_FEATURE_ECX_DTES64 RT_BIT(2)
+%define X86_CPUID_FEATURE_ECX_MONITOR RT_BIT(3)
+%define X86_CPUID_FEATURE_ECX_CPLDS RT_BIT(4)
+%define X86_CPUID_FEATURE_ECX_VMX RT_BIT(5)
+%define X86_CPUID_FEATURE_ECX_SMX RT_BIT(6)
+%define X86_CPUID_FEATURE_ECX_EST RT_BIT(7)
+%define X86_CPUID_FEATURE_ECX_TM2 RT_BIT(8)
+%define X86_CPUID_FEATURE_ECX_SSSE3 RT_BIT(9)
+%define X86_CPUID_FEATURE_ECX_CNTXID RT_BIT(10)
+%define X86_CPUID_FEATURE_ECX_FMA RT_BIT(12)
+%define X86_CPUID_FEATURE_ECX_CX16 RT_BIT(13)
+%define X86_CPUID_FEATURE_ECX_TPRUPDATE RT_BIT(14)
+%define X86_CPUID_FEATURE_ECX_PDCM RT_BIT(15)
+%define X86_CPUID_FEATURE_ECX_PCID RT_BIT(17)
+%define X86_CPUID_FEATURE_ECX_DCA RT_BIT(18)
+%define X86_CPUID_FEATURE_ECX_SSE4_1 RT_BIT(19)
+%define X86_CPUID_FEATURE_ECX_SSE4_2 RT_BIT(20)
+%define X86_CPUID_FEATURE_ECX_X2APIC RT_BIT(21)
+%define X86_CPUID_FEATURE_ECX_MOVBE RT_BIT(22)
+%define X86_CPUID_FEATURE_ECX_POPCNT RT_BIT(23)
+%define X86_CPUID_FEATURE_ECX_TSCDEADL RT_BIT(24)
+%define X86_CPUID_FEATURE_ECX_AES RT_BIT(25)
+%define X86_CPUID_FEATURE_ECX_XSAVE RT_BIT(26)
+%define X86_CPUID_FEATURE_ECX_OSXSAVE RT_BIT(27)
+%define X86_CPUID_FEATURE_ECX_AVX RT_BIT(28)
+%define X86_CPUID_FEATURE_ECX_HVP RT_BIT(31)
+%define X86_CPUID_FEATURE_EDX_FPU RT_BIT(0)
+%define X86_CPUID_FEATURE_EDX_VME RT_BIT(1)
+%define X86_CPUID_FEATURE_EDX_DE RT_BIT(2)
+%define X86_CPUID_FEATURE_EDX_PSE RT_BIT(3)
+%define X86_CPUID_FEATURE_EDX_TSC RT_BIT(4)
+%define X86_CPUID_FEATURE_EDX_MSR RT_BIT(5)
+%define X86_CPUID_FEATURE_EDX_PAE RT_BIT(6)
+%define X86_CPUID_FEATURE_EDX_MCE RT_BIT(7)
+%define X86_CPUID_FEATURE_EDX_CX8 RT_BIT(8)
+%define X86_CPUID_FEATURE_EDX_APIC RT_BIT(9)
+%define X86_CPUID_FEATURE_EDX_SEP RT_BIT(11)
+%define X86_CPUID_FEATURE_EDX_MTRR RT_BIT(12)
+%define X86_CPUID_FEATURE_EDX_PGE RT_BIT(13)
+%define X86_CPUID_FEATURE_EDX_MCA RT_BIT(14)
+%define X86_CPUID_FEATURE_EDX_CMOV RT_BIT(15)
+%define X86_CPUID_FEATURE_EDX_PAT RT_BIT(16)
+%define X86_CPUID_FEATURE_EDX_PSE36 RT_BIT(17)
+%define X86_CPUID_FEATURE_EDX_PSN RT_BIT(18)
+%define X86_CPUID_FEATURE_EDX_CLFSH RT_BIT(19)
+%define X86_CPUID_FEATURE_EDX_DS RT_BIT(21)
+%define X86_CPUID_FEATURE_EDX_ACPI RT_BIT(22)
+%define X86_CPUID_FEATURE_EDX_MMX RT_BIT(23)
+%define X86_CPUID_FEATURE_EDX_FXSR RT_BIT(24)
+%define X86_CPUID_FEATURE_EDX_SSE RT_BIT(25)
+%define X86_CPUID_FEATURE_EDX_SSE2 RT_BIT(26)
+%define X86_CPUID_FEATURE_EDX_SS RT_BIT(27)
+%define X86_CPUID_FEATURE_EDX_HTT RT_BIT(28)
+%define X86_CPUID_FEATURE_EDX_TM RT_BIT(29)
+%define X86_CPUID_FEATURE_EDX_PBE RT_BIT(31)
+%define X86_CPUID_MWAIT_ECX_EXT RT_BIT(0)
+%define X86_CPUID_MWAIT_ECX_BREAKIRQIF0 RT_BIT(1)
+%define X86_CPUID_EXT_FEATURE_ECX_LAHF_SAHF RT_BIT(0)
+%define X86_CPUID_EXT_FEATURE_EDX_SYSCALL RT_BIT(11)
+%define X86_CPUID_EXT_FEATURE_EDX_NX RT_BIT(20)
+%define X86_CPUID_EXT_FEATURE_EDX_PAGE1GB RT_BIT(26)
+%define X86_CPUID_EXT_FEATURE_EDX_RDTSCP RT_BIT(27)
+%define X86_CPUID_EXT_FEATURE_EDX_LONG_MODE RT_BIT(29)
+%define X86_CPUID_AMD_FEATURE_EDX_FPU RT_BIT(0)
+%define X86_CPUID_AMD_FEATURE_EDX_VME RT_BIT(1)
+%define X86_CPUID_AMD_FEATURE_EDX_DE RT_BIT(2)
+%define X86_CPUID_AMD_FEATURE_EDX_PSE RT_BIT(3)
+%define X86_CPUID_AMD_FEATURE_EDX_TSC RT_BIT(4)
+%define X86_CPUID_AMD_FEATURE_EDX_MSR RT_BIT(5)
+%define X86_CPUID_AMD_FEATURE_EDX_PAE RT_BIT(6)
+%define X86_CPUID_AMD_FEATURE_EDX_MCE RT_BIT(7)
+%define X86_CPUID_AMD_FEATURE_EDX_CX8 RT_BIT(8)
+%define X86_CPUID_AMD_FEATURE_EDX_APIC RT_BIT(9)
+%define X86_CPUID_AMD_FEATURE_EDX_MTRR RT_BIT(12)
+%define X86_CPUID_AMD_FEATURE_EDX_PGE RT_BIT(13)
+%define X86_CPUID_AMD_FEATURE_EDX_MCA RT_BIT(14)
+%define X86_CPUID_AMD_FEATURE_EDX_CMOV RT_BIT(15)
+%define X86_CPUID_AMD_FEATURE_EDX_PAT RT_BIT(16)
+%define X86_CPUID_AMD_FEATURE_EDX_PSE36 RT_BIT(17)
+%define X86_CPUID_AMD_FEATURE_EDX_AXMMX RT_BIT(22)
+%define X86_CPUID_AMD_FEATURE_EDX_MMX RT_BIT(23)
+%define X86_CPUID_AMD_FEATURE_EDX_FXSR RT_BIT(24)
+%define X86_CPUID_AMD_FEATURE_EDX_FFXSR RT_BIT(25)
+%define X86_CPUID_AMD_FEATURE_EDX_3DNOW_EX RT_BIT(30)
+%define X86_CPUID_AMD_FEATURE_EDX_3DNOW RT_BIT(31)
+%define X86_CPUID_AMD_FEATURE_ECX_CMPL RT_BIT(1)
+%define X86_CPUID_AMD_FEATURE_ECX_SVM RT_BIT(2)
+%define X86_CPUID_AMD_FEATURE_ECX_EXT_APIC RT_BIT(3)
+%define X86_CPUID_AMD_FEATURE_ECX_CR8L RT_BIT(4)
+%define X86_CPUID_AMD_FEATURE_ECX_ABM RT_BIT(5)
+%define X86_CPUID_AMD_FEATURE_ECX_SSE4A RT_BIT(6)
+%define X86_CPUID_AMD_FEATURE_ECX_MISALNSSE RT_BIT(7)
+%define X86_CPUID_AMD_FEATURE_ECX_3DNOWPRF RT_BIT(8)
+%define X86_CPUID_AMD_FEATURE_ECX_OSVW RT_BIT(9)
+%define X86_CPUID_AMD_FEATURE_ECX_IBS RT_BIT(10)
+%define X86_CPUID_AMD_FEATURE_ECX_SSE5 RT_BIT(11)
+%define X86_CPUID_AMD_FEATURE_ECX_SKINIT RT_BIT(12)
+%define X86_CPUID_AMD_FEATURE_ECX_WDT RT_BIT(13)
+%define X86_CPUID_AMD_ADVPOWER_EDX_TS RT_BIT(0)
+%define X86_CPUID_AMD_ADVPOWER_EDX_FID RT_BIT(1)
+%define X86_CPUID_AMD_ADVPOWER_EDX_VID RT_BIT(2)
+%define X86_CPUID_AMD_ADVPOWER_EDX_TTP RT_BIT(3)
+%define X86_CPUID_AMD_ADVPOWER_EDX_TM RT_BIT(4)
+%define X86_CPUID_AMD_ADVPOWER_EDX_STC RT_BIT(5)
+%define X86_CPUID_AMD_ADVPOWER_EDX_MC RT_BIT(6)
+%define X86_CPUID_AMD_ADVPOWER_EDX_HWPSTATE RT_BIT(7)
+%define X86_CPUID_AMD_ADVPOWER_EDX_TSCINVAR RT_BIT(8)
+%define X86_CR0_PE RT_BIT(0)
+%define X86_CR0_PROTECTION_ENABLE RT_BIT(0)
+%define X86_CR0_MP RT_BIT(1)
+%define X86_CR0_MONITOR_COPROCESSOR RT_BIT(1)
+%define X86_CR0_EM RT_BIT(2)
+%define X86_CR0_EMULATE_FPU RT_BIT(2)
+%define X86_CR0_TS RT_BIT(3)
+%define X86_CR0_TASK_SWITCH RT_BIT(3)
+%define X86_CR0_ET RT_BIT(4)
+%define X86_CR0_EXTENSION_TYPE RT_BIT(4)
+%define X86_CR0_NE RT_BIT(5)
+%define X86_CR0_NUMERIC_ERROR RT_BIT(5)
+%define X86_CR0_WP RT_BIT(16)
+%define X86_CR0_WRITE_PROTECT RT_BIT(16)
+%define X86_CR0_AM RT_BIT(18)
+%define X86_CR0_ALIGMENT_MASK RT_BIT(18)
+%define X86_CR0_NW RT_BIT(29)
+%define X86_CR0_NOT_WRITE_THROUGH RT_BIT(29)
+%define X86_CR0_CD RT_BIT(30)
+%define X86_CR0_CACHE_DISABLE RT_BIT(30)
+%define X86_CR0_PG RT_BIT(31)
+%define X86_CR0_PAGING RT_BIT(31)
+%define X86_CR3_PWT RT_BIT(3)
+%define X86_CR3_PCD RT_BIT(4)
+%define X86_CR3_PAGE_MASK (0xfffff000)
+%define X86_CR3_PAE_PAGE_MASK (0xffffffe0)
+%define X86_CR3_AMD64_PAGE_MASK 0x000ffffffffff000
+%define X86_CR4_VME RT_BIT(0)
+%define X86_CR4_PVI RT_BIT(1)
+%define X86_CR4_TSD RT_BIT(2)
+%define X86_CR4_DE RT_BIT(3)
+%define X86_CR4_PSE RT_BIT(4)
+%define X86_CR4_PAE RT_BIT(5)
+%define X86_CR4_MCE RT_BIT(6)
+%define X86_CR4_PGE RT_BIT(7)
+%define X86_CR4_PCE RT_BIT(8)
+%define X86_CR4_OSFSXR RT_BIT(9)
+%define X86_CR4_OSXMMEEXCPT RT_BIT(10)
+%define X86_CR4_VMXE RT_BIT(13)
+%define X86_CR4_SMXE RT_BIT(14)
+%define X86_CR4_PCIDE RT_BIT(17)
+%define X86_CR4_OSXSAVE RT_BIT(18)
+%define X86_CR4_SMEP RT_BIT(20)
+%define X86_DR6_B0 RT_BIT(0)
+%define X86_DR6_B1 RT_BIT(1)
+%define X86_DR6_B2 RT_BIT(2)
+%define X86_DR6_B3 RT_BIT(3)
+%define X86_DR6_BD RT_BIT(13)
+%define X86_DR6_BS RT_BIT(14)
+%define X86_DR6_BT RT_BIT(15)
+%define X86_DR6_INIT_VAL 0xFFFF0FF0
+%define X86_DR7_L0 RT_BIT(0)
+%define X86_DR7_G0 RT_BIT(1)
+%define X86_DR7_L1 RT_BIT(2)
+%define X86_DR7_G1 RT_BIT(3)
+%define X86_DR7_L2 RT_BIT(4)
+%define X86_DR7_G2 RT_BIT(5)
+%define X86_DR7_L3 RT_BIT(6)
+%define X86_DR7_G3 RT_BIT(7)
+%define X86_DR7_LE RT_BIT(8)
+%define X86_DR7_GE RT_BIT(9)
+%define X86_DR7_GD RT_BIT(13)
+%define X86_DR7_RW0_MASK (3 << 16)
+%define X86_DR7_LEN0_MASK (3 << 18)
+%define X86_DR7_RW1_MASK (3 << 20)
+%define X86_DR7_LEN1_MASK (3 << 22)
+%define X86_DR7_RW2_MASK (3 << 24)
+%define X86_DR7_LEN2_MASK (3 << 26)
+%define X86_DR7_RW3_MASK (3 << 28)
+%define X86_DR7_LEN3_MASK (3 << 30)
+%define X86_DR7_MB1_MASK (RT_BIT(10))
+%define X86_DR7_L(iBp) ( 1 << (iBp * 2) )
+%define X86_DR7_G(iBp) ( 1 << (iBp * 2 + 1) )
+%define X86_DR7_RW_EO 0
+%define X86_DR7_RW_WO 1
+%define X86_DR7_RW_IO 2
+%define X86_DR7_RW_RW 3
+%define X86_DR7_RW(iBp, fRw) ( (fRw) << ((iBp) * 4 + 16) )
+%define X86_DR7_LEN_BYTE 0
+%define X86_DR7_LEN_WORD 1
+%define X86_DR7_LEN_QWORD 2
+%define X86_DR7_LEN_DWORD 3
+%define X86_DR7_LEN(iBp, cb) ( (cb) << ((iBp) * 4 + 18) )
+%define X86_DR7_GET_LEN(uDR7, iBp) ( ( (uDR7) >> ((iBp) * 4 + 18) ) & 0x3)
+%define X86_DR7_ENABLED_MASK (RT_BIT(0) | RT_BIT(1) | RT_BIT(2) | RT_BIT(3) | RT_BIT(4) | RT_BIT(5) | RT_BIT(6) | RT_BIT(7))
+%define X86_DR7_IO_ENABLED_MASK (X86_DR7_RW(0, X86_DR7_RW_IO) | X86_DR7_RW(1, X86_DR7_RW_IO) | X86_DR7_RW(2, X86_DR7_RW_IO) | X86_DR7_RW(3, X86_DR7_RW_IO))
+%define X86_DR7_INIT_VAL 0x400
+%define MSR_IA32_TSC 0x10
+%define MSR_IA32_PLATFORM_ID 0x17
+%ifndef MSR_IA32_APICBASE
+%define MSR_IA32_APICBASE 0x1b
+%endif
+%define MSR_IA32_FEATURE_CONTROL 0x3A
+%define MSR_IA32_FEATURE_CONTROL_LOCK RT_BIT(0)
+%define MSR_IA32_FEATURE_CONTROL_VMXON RT_BIT(2)
+%define MSR_IA32_BIOS_UPDT_TRIG 0x79
+%define MSR_IA32_BIOS_SIGN_ID 0x8B
+%define MSR_IA32_PMC0 0xC1
+%define MSR_IA32_PMC1 0xC2
+%define MSR_IA32_PMC2 0xC3
+%define MSR_IA32_PMC3 0xC4
+%define MSR_IA32_PLATFORM_INFO 0xCE
+%define MSR_IA32_FSB_CLOCK_STS 0xCD
+%define MSR_IA32_MTRR_CAP 0xFE
+%ifndef MSR_IA32_SYSENTER_CS
+%define MSR_IA32_SYSENTER_CS 0x174
+%define MSR_IA32_SYSENTER_ESP 0x175
+%define MSR_IA32_SYSENTER_EIP 0x176
+%endif
+%define MSR_IA32_MCP_CAP 0x179
+%define MSR_IA32_MCP_STATUS 0x17A
+%define MSR_IA32_MCP_CTRL 0x17B
+%define MSR_IA32_DEBUGCTL 0x1D9
+%define MSR_IA32_CR_PAT 0x277
+%define MSR_IA32_PERFEVTSEL0 0x186
+%define MSR_IA32_PERFEVTSEL1 0x187
+%define MSR_IA32_FLEX_RATIO 0x194
+%define MSR_IA32_PERF_STATUS 0x198
+%define MSR_IA32_PERF_CTL 0x199
+%define MSR_IA32_THERM_STATUS 0x19c
+%define MSR_IA32_MISC_ENABLE 0x1A0
+%define MSR_IA32_MISC_ENABLE_FAST_STRINGS RT_BIT(0)
+%define MSR_IA32_MISC_ENABLE_TCC RT_BIT(3)
+%define MSR_IA32_MISC_ENABLE_PERF_MON RT_BIT(7)
+%define MSR_IA32_MISC_ENABLE_BTS_UNAVAIL RT_BIT(11)
+%define MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL RT_BIT(12)
+%define MSR_IA32_MISC_ENABLE_SST_ENABLE RT_BIT(16)
+%define MSR_IA32_MISC_ENABLE_MONITOR RT_BIT(18)
+%define MSR_IA32_MISC_ENABLE_LIMIT_CPUID RT_BIT(22)
+%define MSR_IA32_MISC_ENABLE_XTPR_MSG_DISABLE RT_BIT(23)
+%define MSR_IA32_MISC_ENABLE_XD_DISABLE RT_BIT(34)
+%define IA32_MTRR_PHYSBASE0 0x200
+%define IA32_MTRR_PHYSMASK0 0x201
+%define IA32_MTRR_PHYSBASE1 0x202
+%define IA32_MTRR_PHYSMASK1 0x203
+%define IA32_MTRR_PHYSBASE2 0x204
+%define IA32_MTRR_PHYSMASK2 0x205
+%define IA32_MTRR_PHYSBASE3 0x206
+%define IA32_MTRR_PHYSMASK3 0x207
+%define IA32_MTRR_PHYSBASE4 0x208
+%define IA32_MTRR_PHYSMASK4 0x209
+%define IA32_MTRR_PHYSBASE5 0x20a
+%define IA32_MTRR_PHYSMASK5 0x20b
+%define IA32_MTRR_PHYSBASE6 0x20c
+%define IA32_MTRR_PHYSMASK6 0x20d
+%define IA32_MTRR_PHYSBASE7 0x20e
+%define IA32_MTRR_PHYSMASK7 0x20f
+%define IA32_MTRR_PHYSBASE8 0x210
+%define IA32_MTRR_PHYSMASK8 0x211
+%define IA32_MTRR_PHYSBASE9 0x212
+%define IA32_MTRR_PHYSMASK9 0x213
+%define IA32_MTRR_FIX64K_00000 0x250
+%define IA32_MTRR_FIX16K_80000 0x258
+%define IA32_MTRR_FIX16K_A0000 0x259
+%define IA32_MTRR_FIX4K_C0000 0x268
+%define IA32_MTRR_FIX4K_C8000 0x269
+%define IA32_MTRR_FIX4K_D0000 0x26a
+%define IA32_MTRR_FIX4K_D8000 0x26b
+%define IA32_MTRR_FIX4K_E0000 0x26c
+%define IA32_MTRR_FIX4K_E8000 0x26d
+%define IA32_MTRR_FIX4K_F0000 0x26e
+%define IA32_MTRR_FIX4K_F8000 0x26f
+%define MSR_IA32_MTRR_DEF_TYPE 0x2FF
+%define MSR_IA32_MC0_CTL 0x400
+%define MSR_IA32_MC0_STATUS 0x401
+%define MSR_IA32_VMX_BASIC_INFO 0x480
+%define MSR_IA32_VMX_PINBASED_CTLS 0x481
+%define MSR_IA32_VMX_PROCBASED_CTLS 0x482
+%define MSR_IA32_VMX_EXIT_CTLS 0x483
+%define MSR_IA32_VMX_ENTRY_CTLS 0x484
+%define MSR_IA32_VMX_MISC 0x485
+%define MSR_IA32_VMX_CR0_FIXED0 0x486
+%define MSR_IA32_VMX_CR0_FIXED1 0x487
+%define MSR_IA32_VMX_CR4_FIXED0 0x488
+%define MSR_IA32_VMX_CR4_FIXED1 0x489
+%define MSR_IA32_VMX_VMCS_ENUM 0x48A
+%define MSR_IA32_VMX_PROCBASED_CTLS2 0x48B
+%define MSR_IA32_VMX_EPT_CAPS 0x48C
+%define MSR_IA32_DS_AREA 0x600
+%define MSR_IA32_APIC_START 0x800
+%define MSR_IA32_APIC_END 0x900
+%define MSR_K6_EFER 0xc0000080
+%define MSR_K6_EFER_SCE RT_BIT(0)
+%define MSR_K6_EFER_LME RT_BIT(8)
+%define MSR_K6_EFER_LMA RT_BIT(10)
+%define MSR_K6_EFER_NXE RT_BIT(11)
+%define MSR_K6_EFER_SVME RT_BIT(12)
+%define MSR_K6_EFER_LMSLE RT_BIT(13)
+%define MSR_K6_EFER_FFXSR RT_BIT(14)
+%define MSR_K6_STAR 0xc0000081
+%define MSR_K6_STAR_SYSRET_CS_SS_SHIFT 48
+%define MSR_K6_STAR_SYSCALL_CS_SS_SHIFT 32
+%define MSR_K6_STAR_SEL_MASK 0xffff
+%define MSR_K6_STAR_SYSCALL_EIP_MASK 0xffffffff
+%define MSR_K6_WHCR 0xc0000082
+%define MSR_K6_UWCCR 0xc0000085
+%define MSR_K6_PSOR 0xc0000087
+%define MSR_K6_PFIR 0xc0000088
+%define MSR_K7_EVNTSEL0 0xc0010000
+%define MSR_K7_EVNTSEL1 0xc0010001
+%define MSR_K7_EVNTSEL2 0xc0010002
+%define MSR_K7_EVNTSEL3 0xc0010003
+%define MSR_K7_PERFCTR0 0xc0010004
+%define MSR_K7_PERFCTR1 0xc0010005
+%define MSR_K7_PERFCTR2 0xc0010006
+%define MSR_K7_PERFCTR3 0xc0010007
+%define MSR_K8_LSTAR 0xc0000082
+%define MSR_K8_CSTAR 0xc0000083
+%define MSR_K8_SF_MASK 0xc0000084
+%define MSR_K8_FS_BASE 0xc0000100
+%define MSR_K8_GS_BASE 0xc0000101
+%define MSR_K8_KERNEL_GS_BASE 0xc0000102
+%define MSR_K8_TSC_AUX 0xc0000103
+%define MSR_K8_SYSCFG 0xc0010010
+%define MSR_K8_HWCR 0xc0010015
+%define MSR_K8_IORRBASE0 0xc0010016
+%define MSR_K8_IORRMASK0 0xc0010017
+%define MSR_K8_IORRBASE1 0xc0010018
+%define MSR_K8_IORRMASK1 0xc0010019
+%define MSR_K8_TOP_MEM1 0xc001001a
+%define MSR_K8_TOP_MEM2 0xc001001d
+%define MSR_K8_VM_CR 0xc0010114
+%define MSR_K8_VM_CR_SVM_DISABLE RT_BIT(4)
+%define MSR_K8_IGNNE 0xc0010115
+%define MSR_K8_SMM_CTL 0xc0010116
+%define MSR_K8_VM_HSAVE_PA 0xc0010117
+%define X86_PG_ENTRIES 1024
+%define X86_PG_PAE_ENTRIES 512
+%define X86_PG_PAE_PDPE_ENTRIES 4
+%define X86_PG_AMD64_ENTRIES X86_PG_PAE_ENTRIES
+%define X86_PG_AMD64_PDPE_ENTRIES X86_PG_AMD64_ENTRIES
+%define X86_PAGE_4K_SIZE _4K
+%define X86_PAGE_4K_SHIFT 12
+%define X86_PAGE_4K_OFFSET_MASK 0xfff
+%define X86_PAGE_4K_BASE_MASK 0xfffffffffffff000
+%define X86_PAGE_4K_BASE_MASK_32 0xfffff000
+%define X86_PAGE_2M_SIZE _2M
+%define X86_PAGE_2M_SHIFT 21
+%define X86_PAGE_2M_OFFSET_MASK 0x001fffff
+%define X86_PAGE_2M_BASE_MASK 0xffffffffffe00000
+%define X86_PAGE_2M_BASE_MASK_32 0xffe00000
+%define X86_PAGE_4M_SIZE _4M
+%define X86_PAGE_4M_SHIFT 22
+%define X86_PAGE_4M_OFFSET_MASK 0x003fffff
+%define X86_PAGE_4M_BASE_MASK 0xffffffffffc00000
+%define X86_PAGE_4M_BASE_MASK_32 0xffc00000
+%define X86_PTE_BIT_P 0
+%define X86_PTE_BIT_RW 1
+%define X86_PTE_BIT_US 2
+%define X86_PTE_BIT_PWT 3
+%define X86_PTE_BIT_PCD 4
+%define X86_PTE_BIT_A 5
+%define X86_PTE_BIT_D 6
+%define X86_PTE_BIT_PAT 7
+%define X86_PTE_BIT_G 8
+%define X86_PTE_P RT_BIT(0)
+%define X86_PTE_RW RT_BIT(1)
+%define X86_PTE_US RT_BIT(2)
+%define X86_PTE_PWT RT_BIT(3)
+%define X86_PTE_PCD RT_BIT(4)
+%define X86_PTE_A RT_BIT(5)
+%define X86_PTE_D RT_BIT(6)
+%define X86_PTE_PAT RT_BIT(7)
+%define X86_PTE_G RT_BIT(8)
+%define X86_PTE_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+%define X86_PTE_PG_MASK ( 0xfffff000 )
+%define X86_PTE_PAE_PG_MASK 0x000ffffffffff000
+%define X86_PTE_PAE_NX RT_BIT_64(63)
+%define X86_PTE_PAE_MBZ_MASK_NX 0x7ff0000000000000
+%define X86_PTE_PAE_MBZ_MASK_NO_NX 0xfff0000000000000
+%define X86_PTE_LM_MBZ_MASK_NX 0x0000000000000000
+%define X86_PTE_LM_MBZ_MASK_NO_NX 0x8000000000000000
+%define X86_PT_SHIFT 12
+%define X86_PT_MASK 0x3ff
+%define X86_PT_PAE_SHIFT 12
+%define X86_PT_PAE_MASK 0x1ff
+%define X86_PDE_P RT_BIT(0)
+%define X86_PDE_RW RT_BIT(1)
+%define X86_PDE_US RT_BIT(2)
+%define X86_PDE_PWT RT_BIT(3)
+%define X86_PDE_PCD RT_BIT(4)
+%define X86_PDE_A RT_BIT(5)
+%define X86_PDE_PS RT_BIT(7)
+%define X86_PDE_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+%define X86_PDE_PG_MASK ( 0xfffff000 )
+%define X86_PDE_PAE_PG_MASK 0x000ffffffffff000
+%define X86_PDE_PAE_NX RT_BIT_64(63)
+%define X86_PDE_PAE_MBZ_MASK_NX 0x7ff0000000000080
+%define X86_PDE_PAE_MBZ_MASK_NO_NX 0xfff0000000000080
+%define X86_PDE_LM_MBZ_MASK_NX 0x0000000000000080
+%define X86_PDE_LM_MBZ_MASK_NO_NX 0x8000000000000080
+%define X86_PDE4M_P RT_BIT(0)
+%define X86_PDE4M_RW RT_BIT(1)
+%define X86_PDE4M_US RT_BIT(2)
+%define X86_PDE4M_PWT RT_BIT(3)
+%define X86_PDE4M_PCD RT_BIT(4)
+%define X86_PDE4M_A RT_BIT(5)
+%define X86_PDE4M_D RT_BIT(6)
+%define X86_PDE4M_PS RT_BIT(7)
+%define X86_PDE4M_G RT_BIT(8)
+%define X86_PDE4M_AVL (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+%define X86_PDE4M_PAT RT_BIT(12)
+%define X86_PDE4M_PAT_SHIFT (12 - 7)
+%define X86_PDE4M_PG_MASK ( 0xffc00000 )
+%define X86_PDE4M_PG_HIGH_MASK ( 0x001fe000 )
+%define X86_PDE4M_PG_HIGH_SHIFT 19
+%define X86_PDE4M_MBZ_MASK RT_BIT_32(21)
+%define X86_PDE2M_PAE_PG_MASK 0x000fffffffe00000
+%define X86_PDE2M_PAE_NX RT_BIT_64(63)
+%define X86_PDE2M_PAE_MBZ_MASK_NX 0x7ff00000001fe000
+%define X86_PDE2M_PAE_MBZ_MASK_NO_NX 0xfff00000001fe000
+%define X86_PDE2M_LM_MBZ_MASK_NX 0x00000000001fe000
+%define X86_PDE2M_LM_MBZ_MASK_NO_NX 0x80000000001fe000
+%define X86_PD_SHIFT 22
+%define X86_PD_MASK 0x3ff
+%define X86_PD_PAE_SHIFT 21
+%define X86_PD_PAE_MASK 0x1ff
+%define X86_PDPE_P RT_BIT(0)
+%define X86_PDPE_RW RT_BIT(1)
+%define X86_PDPE_US RT_BIT(2)
+%define X86_PDPE_PWT RT_BIT(3)
+%define X86_PDPE_PCD RT_BIT(4)
+%define X86_PDPE_A RT_BIT(5)
+%define X86_PDPE_LM_PS RT_BIT(7)
+%define X86_PDPE_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+%define X86_PDPE_PG_MASK 0x000ffffffffff000
+%define X86_PDPE_PAE_MBZ_MASK 0xfff00000000001e6
+%define X86_PDPE_LM_NX RT_BIT_64(63)
+%define X86_PDPE_LM_MBZ_MASK_NX 0x0000000000000180
+%define X86_PDPE_LM_MBZ_MASK_NO_NX 0x8000000000000180
+%define X86_PDPE1G_LM_MBZ_MASK_NX 0x000000003fffe000
+%define X86_PDPE1G_LM_MBZ_MASK_NO_NX 0x800000003fffe000
+%define X86_PDPT_SHIFT 30
+%define X86_PDPT_MASK_PAE 0x3
+%define X86_PDPT_MASK_AMD64 0x1ff
+%define X86_PML4E_P RT_BIT(0)
+%define X86_PML4E_RW RT_BIT(1)
+%define X86_PML4E_US RT_BIT(2)
+%define X86_PML4E_PWT RT_BIT(3)
+%define X86_PML4E_PCD RT_BIT(4)
+%define X86_PML4E_A RT_BIT(5)
+%define X86_PML4E_AVL_MASK (RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+%define X86_PML4E_PG_MASK 0x000ffffffffff000
+%define X86_PML4E_MBZ_MASK_NX 0x0000000000000080
+%define X86_PML4E_MBZ_MASK_NO_NX 0x8000000000000080
+%define X86_PML4E_NX RT_BIT_64(63)
+%define X86_PML4_SHIFT 39
+%define X86_PML4_MASK 0x1ff
+%define X86_FSW_IE RT_BIT(0)
+%define X86_FSW_DE RT_BIT(1)
+%define X86_FSW_ZE RT_BIT(2)
+%define X86_FSW_OE RT_BIT(3)
+%define X86_FSW_UE RT_BIT(4)
+%define X86_FSW_PE RT_BIT(5)
+%define X86_FSW_SF RT_BIT(6)
+%define X86_FSW_ES RT_BIT(7)
+%define X86_FSW_XCPT_MASK 0x007f
+%define X86_FSW_XCPT_ES_MASK 0x00ff
+%define X86_FSW_C0 RT_BIT(8)
+%define X86_FSW_C1 RT_BIT(9)
+%define X86_FSW_C2 RT_BIT(10)
+%define X86_FSW_TOP_MASK 0x3800
+%define X86_FSW_TOP_SHIFT 11
+%define X86_FSW_TOP_SMASK 0x0007
+%define X86_FSW_TOP_GET(a_uFsw) (((a_uFsw) >> X86_FSW_TOP_SHIFT) & X86_FSW_TOP_SMASK)
+%define X86_FSW_C3 RT_BIT(14)
+%define X86_FSW_C_MASK 0x4700
+%define X86_FSW_B RT_BIT(15)
+%define X86_FCW_IM RT_BIT(0)
+%define X86_FCW_DM RT_BIT(1)
+%define X86_FCW_ZM RT_BIT(2)
+%define X86_FCW_OM RT_BIT(3)
+%define X86_FCW_UM RT_BIT(4)
+%define X86_FCW_PM RT_BIT(5)
+%define X86_FCW_MASK_ALL 0x007f
+%define X86_FCW_XCPT_MASK 0x003f
+%define X86_FCW_PC_MASK 0x0300
+%define X86_FCW_PC_24 0x0000
+%define X86_FCW_PC_RSVD 0x0100
+%define X86_FCW_PC_53 0x0200
+%define X86_FCW_PC_64 0x0300
+%define X86_FCW_RC_MASK 0x0c00
+%define X86_FCW_RC_NEAREST 0x0000
+%define X86_FCW_RC_DOWN 0x0400
+%define X86_FCW_RC_UP 0x0800
+%define X86_FCW_RC_ZERO 0x0c00
+%define X86_FCW_ZERO_MASK 0xf080
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%define X86DESCGENERIC_BIT_OFF_LIMIT_LOW (0)
+%define X86DESCGENERIC_BIT_OFF_BASE_LOW (16)
+%define X86DESCGENERIC_BIT_OFF_BASE_HIGH1 (32)
+%define X86DESCGENERIC_BIT_OFF_TYPE (40)
+%define X86DESCGENERIC_BIT_OFF_DESC_TYPE (44)
+%define X86DESCGENERIC_BIT_OFF_DPL (45)
+%define X86DESCGENERIC_BIT_OFF_PRESENT (47)
+%define X86DESCGENERIC_BIT_OFF_LIMIT_HIGH (48)
+%define X86DESCGENERIC_BIT_OFF_AVAILABLE (52)
+%define X86DESCGENERIC_BIT_OFF_LONG (53)
+%define X86DESCGENERIC_BIT_OFF_DEF_BIG (54)
+%define X86DESCGENERIC_BIT_OFF_GRANULARITY (55)
+%define X86DESCGENERIC_BIT_OFF_BASE_HIGH2 (56)
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%if HC_ARCH_BITS == 64
+%else
+%endif
+%if HC_ARCH_BITS == 64
+%else
+%endif
+%if HC_ARCH_BITS == 64
+%else
+%endif
+%define X86_SEL_TYPE_CODE 8
+%define X86_SEL_TYPE_MEMORY RT_BIT(4)
+%define X86_SEL_TYPE_ACCESSED 1
+%define X86_SEL_TYPE_DOWN 4
+%define X86_SEL_TYPE_CONF 4
+%define X86_SEL_TYPE_WRITE 2
+%define X86_SEL_TYPE_READ 2
+%define X86_SEL_TYPE_READ_BIT 1
+%define X86_SEL_TYPE_RO 0
+%define X86_SEL_TYPE_RO_ACC (0 | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_RW 2
+%define X86_SEL_TYPE_RW_ACC (2 | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_RO_DOWN 4
+%define X86_SEL_TYPE_RO_DOWN_ACC (4 | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_RW_DOWN 6
+%define X86_SEL_TYPE_RW_DOWN_ACC (6 | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_EO (0 | X86_SEL_TYPE_CODE)
+%define X86_SEL_TYPE_EO_ACC (0 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_ER (2 | X86_SEL_TYPE_CODE)
+%define X86_SEL_TYPE_ER_ACC (2 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_EO_CONF (4 | X86_SEL_TYPE_CODE)
+%define X86_SEL_TYPE_EO_CONF_ACC (4 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_ER_CONF (6 | X86_SEL_TYPE_CODE)
+%define X86_SEL_TYPE_ER_CONF_ACC (6 | X86_SEL_TYPE_CODE | X86_SEL_TYPE_ACCESSED)
+%define X86_SEL_TYPE_SYS_TSS_BUSY_MASK 2
+%define X86_SEL_TYPE_SYS_UNDEFINED 0
+%define X86_SEL_TYPE_SYS_286_TSS_AVAIL 1
+%define X86_SEL_TYPE_SYS_LDT 2
+%define X86_SEL_TYPE_SYS_286_TSS_BUSY 3
+%define X86_SEL_TYPE_SYS_286_CALL_GATE 4
+%define X86_SEL_TYPE_SYS_TASK_GATE 5
+%define X86_SEL_TYPE_SYS_286_INT_GATE 6
+%define X86_SEL_TYPE_SYS_286_TRAP_GATE 7
+%define X86_SEL_TYPE_SYS_UNDEFINED2 8
+%define X86_SEL_TYPE_SYS_386_TSS_AVAIL 9
+%define X86_SEL_TYPE_SYS_UNDEFINED3 0xA
+%define X86_SEL_TYPE_SYS_386_TSS_BUSY 0xB
+%define X86_SEL_TYPE_SYS_386_CALL_GATE 0xC
+%define X86_SEL_TYPE_SYS_UNDEFINED4 0xD
+%define X86_SEL_TYPE_SYS_386_INT_GATE 0xE
+%define X86_SEL_TYPE_SYS_386_TRAP_GATE 0xF
+%define AMD64_SEL_TYPE_SYS_LDT 2
+%define AMD64_SEL_TYPE_SYS_TSS_AVAIL 9
+%define AMD64_SEL_TYPE_SYS_TSS_BUSY 0xB
+%define AMD64_SEL_TYPE_SYS_CALL_GATE 0xC
+%define AMD64_SEL_TYPE_SYS_INT_GATE 0xE
+%define AMD64_SEL_TYPE_SYS_TRAP_GATE 0xF
+%define X86_DESC_TYPE_MASK (RT_BIT(8) | RT_BIT(9) | RT_BIT(10) | RT_BIT(11))
+%define X86_DESC_S RT_BIT(12)
+%define X86_DESC_DPL (RT_BIT(13) | RT_BIT(14))
+%define X86_DESC_P RT_BIT(15)
+%define X86_DESC_AVL RT_BIT(20)
+%define X86_DESC_DB RT_BIT(22)
+%define X86_DESC_G RT_BIT(23)
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%define X86_SEL_SHIFT 3
+%define X86_SEL_MASK 0xfff8
+%define X86_SEL_MASK_OFF_RPL 0xfffc
+%define X86_SEL_LDT 0x0004
+%define X86_SEL_RPL 0x0003
+%define X86_SEL_RPL_LDT 0x0007
+%define X86_TRAP_ERR_EXTERNAL 1
+%define X86_TRAP_ERR_IDT 2
+%define X86_TRAP_ERR_TI 4
+%define X86_TRAP_ERR_SEL_MASK 0xfff8
+%define X86_TRAP_ERR_SEL_SHIFT 3
+%define X86_TRAP_PF_P RT_BIT(0)
+%define X86_TRAP_PF_RW RT_BIT(1)
+%define X86_TRAP_PF_US RT_BIT(2)
+%define X86_TRAP_PF_RSVD RT_BIT(3)
+%define X86_TRAP_PF_ID RT_BIT(4)
+%ifndef VBOX_FOR_DTRACE_LIB
+%else
+%endif
+%ifndef VBOX_FOR_DTRACE_LIB
+%else
+%endif
+%define X86_MODRM_RM_MASK 0x07
+%define X86_MODRM_REG_MASK 0x38
+%define X86_MODRM_REG_SMASK 0x07
+%define X86_MODRM_REG_SHIFT 3
+%define X86_MODRM_MOD_MASK 0xc0
+%define X86_MODRM_MOD_SMASK 0x03
+%define X86_MODRM_MOD_SHIFT 6
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%define X86_SIB_BASE_MASK 0x07
+%define X86_SIB_INDEX_MASK 0x38
+%define X86_SIB_INDEX_SMASK 0x07
+%define X86_SIB_INDEX_SHIFT 3
+%define X86_SIB_SCALE_MASK 0xc0
+%define X86_SIB_SCALE_SMASK 0x03
+%define X86_SIB_SCALE_SHIFT 6
+%ifndef VBOX_FOR_DTRACE_LIB
+%endif
+%define X86_GREG_xAX 0
+%define X86_GREG_xCX 1
+%define X86_GREG_xDX 2
+%define X86_GREG_xBX 3
+%define X86_GREG_xSP 4
+%define X86_GREG_xBP 5
+%define X86_GREG_xSI 6
+%define X86_GREG_xDI 7
+%define X86_GREG_x8 8
+%define X86_GREG_x9 9
+%define X86_GREG_x10 10
+%define X86_GREG_x11 11
+%define X86_GREG_x12 12
+%define X86_GREG_x13 13
+%define X86_GREG_x14 14
+%define X86_GREG_x15 15
+%define X86_SREG_ES 0
+%define X86_SREG_CS 1
+%define X86_SREG_SS 2
+%define X86_SREG_DS 3
+%define X86_SREG_FS 4
+%define X86_SREG_GS 5
+%define X86_SREG_COUNT 6
+%endif
+%include "iprt/x86extra.mac"
diff --git a/include/iprt/x86extra.mac b/include/iprt/x86extra.mac
new file mode 100644
index 00000000..f705984c
--- /dev/null
+++ b/include/iprt/x86extra.mac
@@ -0,0 +1,103 @@
+;; @file
+; IPRT - X86 and AMD64 Structures and Definitions that are not automatically
+; converted from the C header file.
+;
+
+;
+; 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 ___iprt_x86extra_mac
+%define ___iprt_x86extra_mac
+
+
+%define X86_XCPT_UD 6
+%define X86_XCPT_GP 13
+%define X86_XCPT_PF 14
+%define X86_XCPT_MF 16
+
+%define PAGE_SIZE 0x1000
+
+
+;;
+; 32-bit protected mode fstenv image.
+;
+struc X86FSTENV32P
+ .FCW resw 1
+ .padding1 resw 1
+ .FSW resw 1
+ .padding2 resw 1
+ .FTW resw 1
+ .padding3 resw 1
+ .FPUIP resd 1
+ .FPUCS resw 1
+ .FOP resw 1
+ .FPUDP resd 1
+ .FPUDS resw 1
+ .padding4 resw 1
+endstruc
+
+
+;;
+; The image saved by FXSAVE.
+;
+struc X86FXSTATE
+ .FCW resw 1
+ .FSW resw 1
+ .FTW resw 1
+ .FOP resw 1
+ .FPUIP resd 1
+ .FPUCS resw 1
+ .Rsrvd1 resw 1
+ .FPUDP resd 1
+ .FPUDS resw 1
+ .Rsrvd2 resw 1
+ .MXCSR resd 1
+ .MXCSR_MASK resd 1
+ .st0 resd 4
+ .st1 resd 4
+ .st2 resd 4
+ .st3 resd 4
+ .st4 resd 4
+ .st5 resd 4
+ .st6 resd 4
+ .st7 resd 4
+ .xmm0 resd 4
+ .xmm1 resd 4
+ .xmm2 resd 4
+ .xmm3 resd 4
+ .xmm4 resd 4
+ .xmm5 resd 4
+ .xmm6 resd 4
+ .xmm7 resd 4
+ .xmm8 resd 4
+ .xmm9 resd 4
+ .xmm10 resd 4
+ .xmm11 resd 4
+ .xmm12 resd 4
+ .xmm13 resd 4
+ .xmm14 resd 4
+ .xmm15 resd 4
+ .au32RsrvdRest resd 24
+endstruc
+
+
+%endif
+
diff --git a/include/iprt/zip.h b/include/iprt/zip.h
new file mode 100644
index 00000000..f3bfd4bd
--- /dev/null
+++ b/include/iprt/zip.h
@@ -0,0 +1,263 @@
+/** @file
+ * IPRT - Compression.
+ */
+
+/*
+ * 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 ___iprt_zip_h
+#define ___iprt_zip_h
+
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+
+RT_C_DECLS_BEGIN
+
+/** @defgroup grp_rt_zip RTZip - Compression
+ * @ingroup grp_rt
+ * @{
+ */
+
+
+
+/**
+ * Callback function for consuming compressed data during compression.
+ *
+ * @returns iprt status code.
+ * @param pvUser User argument.
+ * @param pvBuf Compressed data.
+ * @param cbBuf Size of the compressed data.
+ */
+typedef DECLCALLBACK(int) FNRTZIPOUT(void *pvUser, const void *pvBuf, size_t cbBuf);
+/** Pointer to FNRTZIPOUT() function. */
+typedef FNRTZIPOUT *PFNRTZIPOUT;
+
+/**
+ * Callback function for supplying compressed data during decompression.
+ *
+ * @returns iprt status code.
+ * @param pvUser User argument.
+ * @param pvBuf Where to store the compressed data.
+ * @param cbBuf Size of the buffer.
+ * @param pcbBuf Number of bytes actually stored in the buffer.
+ */
+typedef DECLCALLBACK(int) FNRTZIPIN(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbBuf);
+/** Pointer to FNRTZIPIN() function. */
+typedef FNRTZIPIN *PFNRTZIPIN;
+
+/**
+ * Compression type.
+ * (Be careful with these they are stored in files!)
+ */
+typedef enum RTZIPTYPE
+{
+ /** Invalid. */
+ RTZIPTYPE_INVALID = 0,
+ /** Choose best fitting one. */
+ RTZIPTYPE_AUTO,
+ /** Store the data. */
+ RTZIPTYPE_STORE,
+ /** Zlib compression the data. */
+ RTZIPTYPE_ZLIB,
+ /** BZlib compress. */
+ RTZIPTYPE_BZLIB,
+ /** libLZF compress. */
+ RTZIPTYPE_LZF,
+ /** Lempel-Ziv-Jeff-Bonwick compression. */
+ RTZIPTYPE_LZJB,
+ /** Lempel-Ziv-Oberhumer compression. */
+ RTZIPTYPE_LZO,
+ /** End of valid the valid compression types. */
+ RTZIPTYPE_END
+} RTZIPTYPE;
+
+/**
+ * Compression level.
+ */
+typedef enum RTZIPLEVEL
+{
+ /** Store, don't compress. */
+ RTZIPLEVEL_STORE = 0,
+ /** Fast compression. */
+ RTZIPLEVEL_FAST,
+ /** Default compression. */
+ RTZIPLEVEL_DEFAULT,
+ /** Maximal compression. */
+ RTZIPLEVEL_MAX
+} RTZIPLEVEL;
+
+
+/**
+ * Create a stream compressor instance.
+ *
+ * @returns iprt status code.
+ * @param ppZip Where to store the instance handle.
+ * @param pvUser User argument which will be passed on to pfnOut and pfnIn.
+ * @param pfnOut Callback for consuming output of compression.
+ * @param enmType Type of compressor to create.
+ * @param enmLevel Compression level.
+ */
+RTDECL(int) RTZipCompCreate(PRTZIPCOMP *ppZip, void *pvUser, PFNRTZIPOUT pfnOut, RTZIPTYPE enmType, RTZIPLEVEL enmLevel);
+
+/**
+ * Compresses a chunk of memory.
+ *
+ * @returns iprt status code.
+ * @param pZip The compressor instance.
+ * @param pvBuf Pointer to buffer containing the bits to compress.
+ * @param cbBuf Number of bytes to compress.
+ */
+RTDECL(int) RTZipCompress(PRTZIPCOMP pZip, const void *pvBuf, size_t cbBuf);
+
+/**
+ * Finishes the compression.
+ * This will flush all data and terminate the compression data stream.
+ *
+ * @returns iprt status code.
+ * @param pZip The stream compressor instance.
+ */
+RTDECL(int) RTZipCompFinish(PRTZIPCOMP pZip);
+
+/**
+ * Destroys the stream compressor instance.
+ *
+ * @returns iprt status code.
+ * @param pZip The compressor instance.
+ */
+RTDECL(int) RTZipCompDestroy(PRTZIPCOMP pZip);
+
+
+/**
+ * Create a stream decompressor instance.
+ *
+ * @returns iprt status code.
+ * @param ppZip Where to store the instance handle.
+ * @param pvUser User argument which will be passed on to pfnOut and pfnIn.
+ * @param pfnIn Callback for producing input for decompression.
+ */
+RTDECL(int) RTZipDecompCreate(PRTZIPDECOMP *ppZip, void *pvUser, PFNRTZIPIN pfnIn);
+
+/**
+ * Decompresses a chunk of memory.
+ *
+ * @returns iprt status code.
+ * @param pZip The stream decompressor instance.
+ * @param pvBuf Where to store the decompressed data.
+ * @param cbBuf Number of bytes to produce. If pcbWritten is set
+ * any number of bytes up to cbBuf might be returned.
+ * @param pcbWritten Number of bytes actually written to the buffer. If NULL
+ * cbBuf number of bytes must be written.
+ */
+RTDECL(int) RTZipDecompress(PRTZIPDECOMP pZip, void *pvBuf, size_t cbBuf, size_t *pcbWritten);
+
+/**
+ * Destroys the stream decompressor instance.
+ *
+ * @returns iprt status code.
+ * @param pZip The decompressor instance.
+ */
+RTDECL(int) RTZipDecompDestroy(PRTZIPDECOMP pZip);
+
+
+/**
+ * Compress a chunk of memory into a block.
+ *
+ * @returns IPRT status code.
+ *
+ * @param enmType The compression type.
+ * @param enmLevel The compression level.
+ * @param fFlags Flags reserved for future extensions, MBZ.
+ * @param pvSrc Pointer to the input block.
+ * @param cbSrc Size of the input block.
+ * @param pvDst Pointer to the output buffer.
+ * @param cbDst The size of the output buffer.
+ * @param pcbDstActual Where to return the compressed size.
+ */
+RTDECL(int) RTZipBlockCompress(RTZIPTYPE enmType, RTZIPLEVEL enmLevel, uint32_t fFlags,
+ void const *pvSrc, size_t cbSrc,
+ void *pvDst, size_t cbDst, size_t *pcbDstActual) RT_NO_THROW;
+
+
+/**
+ * Decompress a block.
+ *
+ * @returns IPRT status code.
+ *
+ * @param enmType The compression type.
+ * @param fFlags Flags reserved for future extensions, MBZ.
+ * @param pvSrc Pointer to the input block.
+ * @param cbSrc Size of the input block.
+ * @param pcbSrcActual Where to return the compressed size.
+ * @param pvDst Pointer to the output buffer.
+ * @param cbDst The size of the output buffer.
+ * @param pcbDstActual Where to return the decompressed size.
+ */
+RTDECL(int) RTZipBlockDecompress(RTZIPTYPE enmType, uint32_t fFlags,
+ void const *pvSrc, size_t cbSrc, size_t *pcbSrcActual,
+ void *pvDst, size_t cbDst, size_t *pcbDstActual) RT_NO_THROW;
+
+
+/**
+ * Opens a gzip decompression I/O stream.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hVfsIosIn The compressed input stream. The reference is
+ * not consumed, instead another one is retained.
+ * @param fFlags Flags, MBZ.
+ * @param phVfsIosOut Where to return the handle to the gzip I/O
+ * stream.
+ */
+RTDECL(int) RTZipGzipDecompressIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSIOSTREAM phVfsIosOut);
+
+/**
+ * Opens a TAR filesystem stream.
+ *
+ * This is used to extract, list or check a TAR archive.
+ *
+ * @returns IPRT status code.
+ *
+ * @param hVfsIosIn The compressed input stream. The reference is
+ * not consumed, instead another one is retained.
+ * @param fFlags Flags, MBZ.
+ * @param phVfsFss Where to return the handle to the TAR
+ * filesystem stream.
+ */
+RTDECL(int) RTZipTarFsStreamFromIoStream(RTVFSIOSTREAM hVfsIosIn, uint32_t fFlags, PRTVFSFSSTREAM phVfsFss);
+
+/**
+ * A mini TAR program.
+ *
+ * @returns Program exit code.
+ *
+ * @param cArgs The number of arguments.
+ * @param papszArgs The argument vector. (Note that this may be
+ * reordered, so the memory must be writable.)
+ */
+RTDECL(RTEXITCODE) RTZipTarCmd(unsigned cArgs, char **papszArgs);
+
+/** @} */
+
+RT_C_DECLS_END
+
+#endif
+