summaryrefslogtreecommitdiff
path: root/include/iprt
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/iprt
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/iprt')
-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
131 files changed, 69151 insertions, 0 deletions
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
+