Index: /trunk/include/iprt/err.h
===================================================================
--- /trunk/include/iprt/err.h	(revision 75878)
+++ /trunk/include/iprt/err.h	(revision 75879)
@@ -3395,4 +3395,11 @@
 /** @} */
 
+
+/** @name RTShMem status codes
+ * @{ */
+/** Maximum number of mappings reached. */
+#define VERR_SHMEM_MAXIMUM_MAPPINGS_REACHED                     (-26000)
+/** @} */
+
 /* SED-END */
 
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 75878)
+++ /trunk/include/iprt/mangling.h	(revision 75879)
@@ -1942,4 +1942,11 @@
 # define RTSha512t256ToString                           RT_MANGLER(RTSha512t256ToString)
 # define RTSha512t256Update                             RT_MANGLER(RTSha512t256Update)
+# define RTShMemClose                                   RT_MANGLER(RTShMemClose)
+# define RTShMemMapRegion                               RT_MANGLER(RTShMemMapRegion)
+# define RTShMemOpen                                    RT_MANGLER(RTShMemOpen)
+# define RTShMemQuerySize                               RT_MANGLER(RTShMemQuerySize)
+# define RTShMemRefCount                                RT_MANGLER(RTShMemRefCount)
+# define RTShMemSetSize                                 RT_MANGLER(RTShMemSetSize)
+# define RTShMemUnmapRegion                             RT_MANGLER(RTShMemUnmapRegion)
 # define RTSocketClose                                  RT_MANGLER(RTSocketClose)
 # define RTSocketFromNative                             RT_MANGLER(RTSocketFromNative)
Index: /trunk/include/iprt/shmem.h
===================================================================
--- /trunk/include/iprt/shmem.h	(revision 75879)
+++ /trunk/include/iprt/shmem.h	(revision 75879)
@@ -0,0 +1,152 @@
+/** @file
+ * IPRT - Named shared memory.
+ */
+
+/*
+ * Copyright (C) 2018 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You 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_shmem_h
+#define ___iprt_shmem_h
+
+#include <iprt/types.h>
+
+RT_C_DECLS_BEGIN
+
+/** Open flags for RTShMemOpen().
+ * @{
+ */
+/** Creates a new shared memory object or opens an already existing one. */
+#define RTSHMEM_O_F_CREATE            RT_BIT_32(0)
+/** Creates a new shared memory object failing if one with the same name exists already. */
+#define RTSHMEM_O_F_CREATE_EXCL       (RTSHMEM_O_F_CREATE | RT_BIT_32(1))
+/** Opens the shared memory object for read access. */
+#define RTSHMEM_O_F_READ              RT_BIT_32(2)
+/** Opens the shared memory object for write access. */
+#define RTSHMEM_O_F_WRITE             RT_BIT_32(3)
+/** Opens the shared memory object for read and write access. */
+#define RTSHMEM_O_F_READWRITE         (RTSHMEM_O_F_READ | RTSHMEM_O_F_WRITE)
+/** Truncates the shared memory object to 0 bytes on open. */
+#define RTSHMEM_O_F_TRUNCATE          RT_BIT_32(4)
+/** Mappings may be created with executable access right (required to be known on Windows beforehand). */
+#define RTSHMEM_O_F_MAYBE_EXEC        RT_BIT_32(5)
+/** Mask of all valid flags. */
+#define RTSHMEM_O_F_VALID_MASK        UINT32_C(0x0000003f)
+/** @} */
+
+/**
+ * Creates or opens a new shared memory object with the given name.
+ *
+ * @returns IPRT status code.
+ * @retval VERR_OUT_OF_RANGE if the mapping hint count is too big.
+ * @param   phShMem         Where to store the handle to the shared memory object on success.
+ * @param   pszName         Name of the shared memory object to open or create.
+ * @param   fFlags          Combination of RTSHMEM_O_F_* flags.
+ * @param   cbMax           Maximum number of bytes to reserve for the shared memory object.
+ *                          On some platforms this can be 0 and set to another value using RTShMemSetSize() afterwards.
+ *                          Giving 0 on Windows results in an error as shared memory objects there do not support
+ *                          changing the size afterwards.
+ * @param   cMappingsHint   Hint about the possible number of mappings created later on, set to 0 for a default value.
+ */
+RTDECL(int) RTShMemOpen(PRTSHMEM phShMem, const char *pszName, uint32_t fFlags, size_t cbMax, uint32_t cMappingsHint);
+
+/**
+ * Closes the given shared memory object.
+ *
+ * @returns IPRT status code.
+ * @reval   VERR_INVALID_STATE if there is still a mapping active for the given shared memory object.
+ * @param   hShMem          The shared memory object handle.
+ *
+ * @note The shared memory object will be deleted if the creator closes it.
+ */
+RTDECL(int) RTShMemClose(RTSHMEM hShMem);
+
+/**
+ * Returns the number of references (i.e. mappings) held for the given shared memory object.
+ *
+ * @returns Reference count or 0 on invalid handle.
+ * @param   hShMem          The shared memory object handle.
+ */
+RTDECL(uint32_t) RTShMemRefCount(RTSHMEM hShMem);
+
+/**
+ * Sets the size of the given shared memory object.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_INVALID_STATE if there are mappings active for the given shared memory object.
+ * @retval  VERR_NOT_SUPPORTED on some hosts which do not support changing the size after creation.
+ * @param   hShMem          The shared memory object handle.
+ * @param   cbMem           Size of the memory object handle in bytes.
+ */
+RTDECL(int) RTShMemSetSize(RTSHMEM hShMem, size_t cbMem);
+
+/**
+ * Queries the current size of the shared memory object.
+ *
+ * @returns IPRT status code.
+ * @param   hShMem          The shared memory object handle.
+ * @param   pcbMem          Where to store the size of the shared memory object on success.
+ */
+RTDECL(int) RTShMemQuerySize(RTSHMEM hShMem, size_t *pcbMem);
+
+/** Region mapping flags for RTShMemMapRegion().
+ * @{
+ */
+/** Read access. */
+#define RTSHMEM_MAP_F_READ            RT_BIT_32(0)
+/** Write access. */
+#define RTSHMEM_MAP_F_WRITE           RT_BIT_32(1)
+/** Execute access. */
+#define RTSHMEM_MAP_F_EXEC            RT_BIT_32(2)
+/** Copy on write, any write creates a new page private to the callers address space and changes
+ * in that area are not shared with other processes using the hsared memory object. */
+#define RTSHMEM_MAP_F_COW             RT_BIT_32(3)
+/** Mask of all valid flags. */
+#define RTSHMEM_MAP_F_VALID_MASK      UINT32_C(0x0000000f)
+/** @} */
+
+/**
+ * Maps a region of the given shared memory object into the callers address space.
+ *
+ * @returns IPRT status code.
+ * @retval  VERR_SHMEM_MAXIMUM_MAPPINGS_REACHED if the maximum number of mappings was reached (host dependent).
+ * @retval  VERR_ACCESS_DENIED if the requested memory access rights do not line up with the flags given when opening
+ *          the memory object (requesting write access for a readonly shared memory object for example).
+ * @param   hShMem          The shared memory object handle.
+ * @param   offRegion       Offset into the shared memory object to start mapping at.
+ * @param   cbRegion        Size of the region to map.
+ * @param   fFlags          Desired properties of the mapped region, combination of RTSHMEM_MAP_F_* defines.
+ * @param   ppv             Where to store the start address of the mapped region on success.
+ */
+RTDECL(int) RTShMemMapRegion(RTSHMEM hShMem, size_t offRegion, size_t cbRegion, uint32_t fFlags, void **ppv);
+
+/**
+ * Unmaps the given region of the shared memory object.
+ *
+ * @returns IPRT status code.
+ * @param   hShMem          The shared memory object handle.
+ * @param   pv              Pointer to the mapped region obtained with RTShMemMapRegion() earlier on.
+ */
+RTDECL(int) RTShMemUnmapRegion(RTSHMEM hShMem, void *pv);
+
+RT_C_DECLS_END
+
+#endif
+
Index: /trunk/include/iprt/types.h
===================================================================
--- /trunk/include/iprt/types.h	(revision 75878)
+++ /trunk/include/iprt/types.h	(revision 75879)
@@ -2528,4 +2528,11 @@
 #define NIL_RTKRNLMODINFO                          ((RTKRNLMODINFO)~(uintptr_t)0);
 
+/** Shared memory object handle. */
+typedef struct RTSHMEMINT                   RT_FAR *RTSHMEM;
+/** Pointer to a shared memory object handle. */
+typedef RTSHMEM                             RT_FAR *PRTSHMEM;
+/** A NIL shared memory object handle. */
+#define NIL_RTSHMEM                                ((RTSHMEM)~(uintptr_t)0)
+
 /**
  * Handle type.
Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 75878)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 75879)
@@ -877,4 +877,5 @@
 	r3/win/semmutex-win.cpp \
 	r3/win/serialport-win.cpp \
+	r3/win/shmem-win.cpp \
 	r3/win/symlink-win.cpp \
 	r3/win/thread-win.cpp \
@@ -965,4 +966,5 @@
 	r3/posix/semrw-posix.cpp \
 	r3/posix/serialport-posix.cpp \
+	r3/posix/shmem-posix.cpp \
 	r3/posix/symlink-posix.cpp \
 	r3/posix/thread-posix.cpp \
@@ -1148,4 +1150,5 @@
 	r3/posix/serialport-posix.cpp \
 	r3/posix/symlink-posix.cpp \
+	r3/posix/shmem-posix.cpp \
 	r3/posix/thread-posix.cpp \
 	r3/posix/thread2-posix.cpp \
@@ -1229,4 +1232,5 @@
 	r3/posix/serialport-posix.cpp \
 	r3/posix/symlink-posix.cpp \
+	r3/posix/shmem-posix.cpp \
 	r3/posix/thread-posix.cpp \
 	r3/posix/thread2-posix.cpp \
@@ -1305,4 +1309,5 @@
 	r3/posix/serialport-posix.cpp \
 	r3/posix/symlink-posix.cpp \
+	r3/posix/shmem-posix.cpp \
 	r3/posix/thread-posix.cpp \
 	r3/posix/thread2-posix.cpp \
@@ -1374,4 +1379,5 @@
 	r3/posix/serialport-posix.cpp \
 	r3/posix/symlink-posix.cpp \
+	r3/posix/shmem-posix.cpp \
 	r3/posix/thread-posix.cpp \
 	r3/posix/thread2-posix.cpp \
Index: /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def
===================================================================
--- /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 75878)
+++ /trunk/src/VBox/Runtime/VBox/VBoxRTImp.def	(revision 75879)
@@ -1662,4 +1662,11 @@
     RTSha512ToString
     RTSha512Update
+    RTShMemClose
+    RTShMemMapRegion
+    RTShMemOpen
+    RTShMemQuerySize
+    RTShMemRefCount
+    RTShMemSetSize
+    RTShMemUnmapRegion
     RTSocketClose
     RTSocketFromNative
Index: /trunk/src/VBox/Runtime/include/internal/magics.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/magics.h	(revision 75878)
+++ /trunk/src/VBox/Runtime/include/internal/magics.h	(revision 75879)
@@ -191,4 +191,8 @@
 /** RTSERIALPORTINTERNAL::u32Magic value after RTSerialPortClose. */
 #define RTSERIALPORT_MAGIC_DEAD         UINT32_C(0x19050324)
+/** RTSHMEMINT::u32Magic value (Stephen William Hawking) */
+#define RTSHMEM_MAGIC                   UINT32_C(0x19420108)
+/** RTSHMEMINT::u32Magic value after RTShMemClose */
+#define RTSHMEM_MAGIC_DEAD              UINT32_C(0x20180314)
 /** The magic value for RTSOCKETINT::u32Magic. (Stanislaw Lem) */
 #define RTSOCKET_MAGIC                  UINT32_C(0x19210912)
Index: /trunk/src/VBox/Runtime/r3/posix/shmem-posix.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/posix/shmem-posix.cpp	(revision 75879)
+++ /trunk/src/VBox/Runtime/r3/posix/shmem-posix.cpp	(revision 75879)
@@ -0,0 +1,386 @@
+/* $Id$ */
+/** @file
+ * IPRT - Named shared memory object, POSIX Implementation.
+ */
+
+/*
+ * Copyright (C) 2018 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/shmem.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/cdefs.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include "internal/magics.h"
+
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+
+/** Workaround on systems which do not provide this. */
+#ifndef NAME_MAX
+# define NAME_MAX 255
+#endif
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+
+/**
+ * Shared memory object mapping descriptor.
+ */
+typedef struct RTSHMEMMAPPINGDESC
+{
+    /** Number of references held to this mapping, 0 if the descriptor is free. */
+    volatile uint32_t   cMappings;
+    /** Pointer to the region mapping. */
+    void                *pvMapping;
+    /** Start offset */
+    size_t              offRegion;
+    /** Size of the region. */
+    size_t              cbRegion;
+    /** Access flags for this region .*/
+    uint32_t            fFlags;
+} RTSHMEMMAPPINGDESC;
+/** Pointer to a shared memory object mapping descriptor. */
+typedef RTSHMEMMAPPINGDESC *PRTSHMEMMAPPINGDESC;
+/** Pointer to a constant shared memory object mapping descriptor. */
+typedef const RTSHMEMMAPPINGDESC *PCRTSHMEMMAPPINGDESC;
+
+
+/**
+ * Internal shared memory object state.
+ */
+typedef struct RTSHMEMINT
+{
+    /** Magic value (RTSHMEM_MAGIC). */
+    uint32_t            u32Magic;
+    /** Pointer to the shared memory object name. */
+    char                *pszName;
+    /** File descriptor for the underlying shared memory object. */
+    int                 iFdShm;
+    /** Flag whether this instance created the named shared memory object. */
+    bool                fCreate;
+    /** Overall number of mappings active for this shared memory object. */
+    volatile uint32_t   cMappings;
+    /** Maximum number of mapping descriptors allocated. */
+    uint32_t            cMappingDescsMax;
+    /** Number of mapping descriptors used. */
+    volatile uint32_t   cMappingDescsUsed;
+    /** Array of mapping descriptors - variable in size. */
+    RTSHMEMMAPPINGDESC  aMappingDescs[1];
+} RTSHMEMINT;
+/** Pointer to the internal shared memory object state. */
+typedef RTSHMEMINT *PRTSHMEMINT;
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+
+
+/**
+ * Returns a mapping descriptor matching the given region properties or NULL if none was found.
+ *
+ * @returns Pointer to the matching mapping descriptor or NULL if not found.
+ * @param   pThis           Pointer to the shared memory object instance.
+ * @param   offRegion       Offset into the shared memory object to start mapping at.
+ * @param   cbRegion        Size of the region to map.
+ * @param   fFlags          Desired properties of the mapped region, combination of RTSHMEM_MAP_F_* defines.
+ */
+DECLINLINE(PRTSHMEMMAPPINGDESC) rtShMemMappingDescFindByProp(PRTSHMEMINT pThis, size_t offRegion, size_t cbRegion, uint32_t fFlags)
+{
+    for (uint32_t i = 0; i < pThis->cMappingDescsMax; i++)
+    {
+        if (   pThis->aMappingDescs[i].offRegion == offRegion
+            && pThis->aMappingDescs[i].cbRegion == cbRegion
+            && pThis->aMappingDescs[i].fFlags == fFlags)
+            return &pThis->aMappingDescs[i];
+    }
+
+    return NULL;
+}
+
+
+RTDECL(int) RTShMemOpen(PRTSHMEM phShMem, const char *pszName, uint32_t fFlags, size_t cbMax, uint32_t cMappingsHint)
+{
+    AssertPtrReturn(phShMem, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pszName, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~RTSHMEM_O_F_VALID_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(cMappingsHint < 64, VERR_OUT_OF_RANGE);
+
+    size_t cchName = strlen(pszName);
+    AssertReturn(cchName, VERR_INVALID_PARAMETER);
+    AssertReturn(cchName < NAME_MAX - 1, VERR_INVALID_PARAMETER); /* account for the / we add later on. */
+    cMappingsHint = cMappingsHint == 0 ? 5 : cMappingsHint;
+    int rc = VINF_SUCCESS;
+    PRTSHMEMINT pThis = (PRTSHMEMINT)RTMemAllocZ(RT_UOFFSETOF_DYN(RTSHMEMINT, aMappingDescs[cMappingsHint]) + cchName + 2); /* '/' + terminator. */
+    if (RT_LIKELY(pThis))
+    {
+        pThis->u32Magic            = RTSHMEM_MAGIC;
+        pThis->pszName             = (char *)&pThis->aMappingDescs[cMappingsHint];
+        /*pThis->fCreate           = false; */
+        /*pThis->cMappings         = 0; */
+        pThis->cMappingDescsMax    = cMappingsHint;
+        /*pThis->cMappingDescsUsed = 0; */
+        pThis->pszName[0]          = '/';
+        memcpy(&pThis->pszName[1], pszName, cchName);
+        int fShmFlags = 0;
+        if (fFlags & RTSHMEM_O_F_CREATE)
+        {
+            fShmFlags |= O_CREAT;
+            pThis->fCreate = true;
+        }
+        if ((fFlags & RTSHMEM_O_F_CREATE_EXCL) == RTSHMEM_O_F_CREATE_EXCL)
+            fShmFlags |= O_EXCL;
+        if (   (fFlags & RTSHMEM_O_F_READWRITE) == RTSHMEM_O_F_READWRITE
+            || (fFlags & RTSHMEM_O_F_WRITE))
+            fShmFlags |= O_RDWR;
+        else
+            fShmFlags |= O_RDONLY;
+        if (fFlags & RTSHMEM_O_F_TRUNCATE)
+            fShmFlags |= O_TRUNC;
+        pThis->iFdShm = shm_open(pThis->pszName, fShmFlags , 0600);
+        if (pThis->iFdShm > 0)
+        {
+            if (cbMax)
+                rc = RTShMemSetSize(pThis, cbMax);
+            if (RT_SUCCESS(rc))
+            {
+                *phShMem = pThis;
+                return VINF_SUCCESS;
+            }
+
+            close(pThis->iFdShm);
+        }
+        else
+            rc = RTErrConvertFromErrno(errno);
+
+        RTMemFree(pThis);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    return rc;
+}
+
+
+RTDECL(int) RTShMemClose(RTSHMEM hShMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(!pThis->cMappings, VERR_INVALID_STATE);
+
+    int rc = VINF_SUCCESS;
+    if (!close(pThis->iFdShm))
+    {
+        if (pThis->fCreate)
+            shm_unlink(pThis->pszName); /* Ignore any error here. */
+        pThis->u32Magic = RTSHMEM_MAGIC_DEAD;
+        RTMemFree(pThis);
+    }
+    else
+        rc = RTErrConvertFromErrno(errno);
+
+    return rc;
+}
+
+
+RTDECL(uint32_t) RTShMemRefCount(RTSHMEM hShMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, 0);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, 0);
+
+    return pThis->cMappings;
+}
+
+
+RTDECL(int) RTShMemSetSize(RTSHMEM hShMem, size_t cbMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(!pThis->cMappings, VERR_INVALID_STATE);
+
+    int rc = VINF_SUCCESS;
+    if (ftruncate(pThis->iFdShm, (off_t)cbMem))
+        rc = RTErrConvertFromErrno(errno);
+
+    return rc;
+}
+
+
+RTDECL(int) RTShMemQuerySize(RTSHMEM hShMem, size_t *pcbMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtrReturn(pcbMem, VERR_INVALID_PARAMETER);
+
+    struct stat st;
+    if (!fstat(pThis->iFdShm, &st))
+    {
+        *pcbMem = st.st_size;
+        return VINF_SUCCESS;
+    }
+    return RTErrConvertFromErrno(errno);
+}
+
+
+RTDECL(int) RTShMemMapRegion(RTSHMEM hShMem, size_t offRegion, size_t cbRegion, uint32_t fFlags, void **ppv)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtrReturn(ppv, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~RTSHMEM_MAP_F_VALID_MASK), VERR_INVALID_PARAMETER);
+
+    /* Try to find a mapping with compatible parameters first. */
+    PRTSHMEMMAPPINGDESC pMappingDesc = NULL;
+    for (uint32_t iTry = 0; iTry < 10; iTry++)
+    {
+        pMappingDesc = rtShMemMappingDescFindByProp(pThis, offRegion, cbRegion, fFlags);
+        if (!pMappingDesc)
+            break;
+
+        /* Increase the mapping count and check that the region is still accessible by us. */
+        if (   ASMAtomicIncU32(&pMappingDesc->cMappings) > 1
+            && pMappingDesc->offRegion == offRegion
+            && pMappingDesc->cbRegion  == cbRegion
+            && pMappingDesc->fFlags    == fFlags)
+            break;
+        /* Mapping was freed inbetween, next round. */
+    }
+
+    int rc = VINF_SUCCESS;
+    if (!pMappingDesc)
+    {
+        /* Find an empty region descriptor and map the region. */
+        for (uint32_t i = 0; i < pThis->cMappingDescsMax && !pMappingDesc; i++)
+        {
+            if (!pThis->aMappingDescs[i].cMappings)
+            {
+                /* Try to grab this one. */
+                if (ASMAtomicIncU32(&pMappingDesc->cMappings) == 1)
+                    break;
+
+                /* Somebody raced us, drop reference and continue. */
+                ASMAtomicDecU32(&pMappingDesc->cMappings);
+            }
+        }
+
+        if (RT_LIKELY(pMappingDesc))
+        {
+            /* Try to map it. */
+            int fMmapFlags = 0;
+            int fProt = 0;
+            if (fFlags & RTSHMEM_MAP_F_READ)
+                fProt |= PROT_READ;
+            if (fFlags & RTSHMEM_MAP_F_WRITE)
+                fProt |= PROT_WRITE;
+            if (fFlags & RTSHMEM_MAP_F_EXEC)
+                fProt |= PROT_EXEC;
+            if (fFlags & RTSHMEM_MAP_F_COW)
+                fMmapFlags |= MAP_PRIVATE;
+            else
+                fMmapFlags |= MAP_SHARED;
+
+            void *pv = mmap(NULL, cbRegion, fProt, fMmapFlags, pThis->iFdShm, (off_t)offRegion);
+            if (pv != MAP_FAILED)
+            {
+                pMappingDesc->pvMapping = pv;
+                pMappingDesc->offRegion = offRegion;
+                pMappingDesc->cbRegion  = cbRegion;
+                pMappingDesc->fFlags    = fFlags;
+            }
+            else
+            {
+                rc = RTErrConvertFromErrno(errno);
+                ASMAtomicDecU32(&pMappingDesc->cMappings);
+            }
+        }
+        else
+            rc = VERR_SHMEM_MAXIMUM_MAPPINGS_REACHED;
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        *ppv = pMappingDesc->pvMapping;
+        ASMAtomicIncU32(&pThis->cMappings);
+    }
+
+    return rc;
+}
+
+
+RTDECL(int) RTShMemUnmapRegion(RTSHMEM hShMem, void *pv)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtrReturn(pv, VERR_INVALID_PARAMETER);
+
+    /* Find the mapping descriptor by the given region address. */
+    PRTSHMEMMAPPINGDESC pMappingDesc = NULL;
+    for (uint32_t i = 0; i < pThis->cMappingDescsMax && !pMappingDesc; i++)
+    {
+        if (pThis->aMappingDescs[i].pvMapping == pv)
+        {
+            pMappingDesc = &pThis->aMappingDescs[i];
+            break;
+        }
+    }
+
+    AssertPtrReturn(pMappingDesc, VERR_INVALID_PARAMETER);
+
+    int rc = VINF_SUCCESS;
+    size_t cbRegion = pMappingDesc->cMappings;
+    if (!ASMAtomicDecU32(&pMappingDesc->cMappings))
+    {
+        /* Last mapping of this region was unmapped, so do the real unmapping now. */
+        if (munmap(pv, cbRegion))
+        {
+            ASMAtomicIncU32(&pMappingDesc->cMappings);
+            rc = RTErrConvertFromErrno(errno);
+        }
+        else
+        {
+            ASMAtomicDecU32(&pThis->cMappingDescsUsed);
+            ASMAtomicDecU32(&pThis->cMappings);
+        }
+    }
+
+    return rc;
+}
+
Index: /trunk/src/VBox/Runtime/r3/win/shmem-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/shmem-win.cpp	(revision 75879)
+++ /trunk/src/VBox/Runtime/r3/win/shmem-win.cpp	(revision 75879)
@@ -0,0 +1,455 @@
+/* $Id$ */
+/** @file
+ * IPRT - Named shared memory object, Windows Implementation.
+ */
+
+/*
+ * Copyright (C) 2018 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/nt/nt-and-windows.h>
+
+#include <iprt/shmem.h>
+#include "internal/iprt.h"
+
+#include <iprt/asm.h>
+#include <iprt/assert.h>
+#include <iprt/cdefs.h>
+#include <iprt/err.h>
+#include <iprt/mem.h>
+#include <iprt/string.h>
+#include "internal/magics.h"
+#include "internal/path.h"
+#include "internal-r3-win.h" /* For g_enmWinVer + kRTWinOSType_XXX */
+
+/*
+ * Define values ourselves in case the compiling host is too old.
+ * See https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createfilemappinga
+ * for when these were introduced.
+ */
+#ifndef PAGE_EXECUTE_READ
+# define PAGE_EXECUTE_READ 0x20
+#endif
+#ifndef PAGE_EXECUTE_READWRITE
+# define PAGE_EXECUTE_READWRITE 0x40
+#endif
+#ifndef PAGE_EXECUTE_WRITECOPY
+# define PAGE_EXECUTE_WRITECOPY 0x80
+#endif
+#ifndef FILE_MAP_EXECUTE
+# define FILE_MAP_EXECUTE 0x20
+#endif
+
+/*********************************************************************************************************************************
+*   Structures and Typedefs                                                                                                      *
+*********************************************************************************************************************************/
+
+/**
+ * Shared memory object mapping descriptor.
+ */
+typedef struct RTSHMEMMAPPINGDESC
+{
+    /** Number of references held to this mapping, 0 if the descriptor is free. */
+    volatile uint32_t   cMappings;
+    /** Pointer to the region mapping. */
+    void                *pvMapping;
+    /** Start offset */
+    size_t              offRegion;
+    /** Size of the region. */
+    size_t              cbRegion;
+    /** Access flags for this region .*/
+    uint32_t            fFlags;
+} RTSHMEMMAPPINGDESC;
+/** Pointer to a shared memory object mapping descriptor. */
+typedef RTSHMEMMAPPINGDESC *PRTSHMEMMAPPINGDESC;
+/** Pointer to a constant shared memory object mapping descriptor. */
+typedef const RTSHMEMMAPPINGDESC *PCRTSHMEMMAPPINGDESC;
+
+
+/**
+ * Internal shared memory object state.
+ */
+typedef struct RTSHMEMINT
+{
+    /** Magic value (RTSHMEM_MAGIC). */
+    uint32_t            u32Magic;
+    /** Handle to the underlying mapping object. */
+    HANDLE              hShmObj;
+    /** Flag whether this instance created the named shared memory object. */
+    bool                fCreate;
+    /** Size of the mapping object in bytes. */
+    size_t              cbMax;
+    /** Overall number of mappings active for this shared memory object. */
+    volatile uint32_t   cMappings;
+    /** Maximum number of mapping descriptors allocated. */
+    uint32_t            cMappingDescsMax;
+    /** Number of mapping descriptors used. */
+    volatile uint32_t   cMappingDescsUsed;
+    /** Array of mapping descriptors - variable in size. */
+    RTSHMEMMAPPINGDESC  aMappingDescs[1];
+} RTSHMEMINT;
+/** Pointer to the internal shared memory object state. */
+typedef RTSHMEMINT *PRTSHMEMINT;
+
+
+/*********************************************************************************************************************************
+*   Internal Functions                                                                                                           *
+*********************************************************************************************************************************/
+
+
+/**
+ * Returns a mapping descriptor matching the given region properties or NULL if none was found.
+ *
+ * @returns Pointer to the matching mapping descriptor or NULL if not found.
+ * @param   pThis           Pointer to the shared memory object instance.
+ * @param   offRegion       Offset into the shared memory object to start mapping at.
+ * @param   cbRegion        Size of the region to map.
+ * @param   fFlags          Desired properties of the mapped region, combination of RTSHMEM_MAP_F_* defines.
+ */
+DECLINLINE(PRTSHMEMMAPPINGDESC) rtShMemMappingDescFindByProp(PRTSHMEMINT pThis, size_t offRegion, size_t cbRegion, uint32_t fFlags)
+{
+    for (uint32_t i = 0; i < pThis->cMappingDescsMax; i++)
+    {
+        if (   pThis->aMappingDescs[i].offRegion == offRegion
+            && pThis->aMappingDescs[i].cbRegion == cbRegion
+            && pThis->aMappingDescs[i].fFlags == fFlags)
+            return &pThis->aMappingDescs[i];
+    }
+
+    return NULL;
+}
+
+
+RTDECL(int) RTShMemOpen(PRTSHMEM phShMem, const char *pszName, uint32_t fFlags, size_t cbMax, uint32_t cMappingsHint)
+{
+    AssertPtrReturn(phShMem, VERR_INVALID_PARAMETER);
+    AssertPtrReturn(pszName, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~RTSHMEM_O_F_VALID_MASK), VERR_INVALID_PARAMETER);
+    AssertReturn(cMappingsHint < 64, VERR_OUT_OF_RANGE);
+    AssertReturn(cbMax > 0 || !(fFlags & RTSHMEM_O_F_CREATE), VERR_NOT_SUPPORTED);
+
+    if (fFlags & RTSHMEM_O_F_TRUNCATE)
+        return VERR_NOT_SUPPORTED;
+
+    /*
+     * The executable access was introduced with Windows XP SP2 and Windows Server 2003 SP1,
+     * PAGE_EXECUTE_WRITECOPY was not available until Windows Vista SP1.
+     * Allow execute mappings only starting from Windows 7 to keep the checks simple here (lazy coder).
+     */
+    if (   (fFlags & RTSHMEM_O_F_MAYBE_EXEC)
+        && g_enmWinVer < kRTWinOSType_7)
+        return VERR_NOT_SUPPORTED;
+
+    cMappingsHint = cMappingsHint == 0 ? 5 : cMappingsHint;
+    int rc = VINF_SUCCESS;
+    PRTSHMEMINT pThis = (PRTSHMEMINT)RTMemAllocZ(RT_UOFFSETOF_DYN(RTSHMEMINT, aMappingDescs[cMappingsHint]));
+    if (RT_LIKELY(pThis))
+    {
+        pThis->u32Magic            = RTSHMEM_MAGIC;
+        /*pThis->fCreate           = false; */
+        /*pThis->cMappings         = 0; */
+        pThis->cMappingDescsMax    = cMappingsHint;
+        /*pThis->cMappingDescsUsed = 0; */
+        /* Construct the filename, always use the local namespace, global requires special privileges. */
+        char szName[RTPATH_MAX];
+        ssize_t cch = RTStrPrintf2(&szName[0], sizeof(szName), "Local\\%s", pszName);
+        if (cch > 0)
+        {
+            PRTUTF16 pwszName = NULL;
+            rc = RTStrToUtf16Ex(&szName[0], RTSTR_MAX, &pwszName, 0, NULL);
+            if (RT_SUCCESS(rc))
+            {
+                if (fFlags & RTSHMEM_O_F_CREATE)
+                {
+#if HC_ARCH_BITS == 64
+                    DWORD dwSzMaxHigh = cbMax >> 32;
+#elif HC_ARCH_BITS == 32
+                    DWORD dwSzMaxHigh = 0;
+#else
+# error "Port me"
+#endif
+                    DWORD dwSzMaxLow = cbMax & UINT32_C(0xffffffff);
+                    DWORD fProt = 0;
+
+                    if (fFlags & RTSHMEM_O_F_MAYBE_EXEC)
+                    {
+                        if ((fFlags & RTSHMEM_O_F_READWRITE) == RTSHMEM_O_F_READ)
+                            fProt |= PAGE_EXECUTE_READ;
+                        else
+                            fProt |= PAGE_EXECUTE_READWRITE;
+                    }
+                    else
+                    {
+                        if ((fFlags & RTSHMEM_O_F_READWRITE) == RTSHMEM_O_F_READ)
+                            fProt |= PAGE_READONLY;
+                        else
+                            fProt |= PAGE_READWRITE;
+                    }
+                    pThis->hShmObj = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, fProt,
+                                                        dwSzMaxHigh, dwSzMaxLow, pwszName);
+                }
+                else
+                {
+                    DWORD fProt = SECTION_QUERY;
+                    if (fFlags & RTSHMEM_O_F_MAYBE_EXEC)
+                        fProt |= FILE_MAP_EXECUTE;
+                    if (fFlags & RTSHMEM_O_F_READ)
+                        fProt |= FILE_MAP_READ;
+                    if (fFlags & RTSHMEM_O_F_WRITE)
+                        fProt |= FILE_MAP_WRITE;
+
+                    pThis->hShmObj = OpenFileMappingW(fProt, FALSE, pwszName);
+                }
+                RTUtf16Free(pwszName);
+                if (pThis->hShmObj != NULL)
+                {
+                    *phShMem = pThis;
+                    return VINF_SUCCESS;
+                }
+                else
+                    rc = RTErrConvertFromWin32(GetLastError());
+            }
+        }
+        else
+            rc = VERR_BUFFER_OVERFLOW;
+
+        RTMemFree(pThis);
+    }
+    else
+        rc = VERR_NO_MEMORY;
+
+    return rc;
+}
+
+
+RTDECL(int) RTShMemClose(RTSHMEM hShMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(!pThis->cMappings, VERR_INVALID_STATE);
+
+    int rc = VINF_SUCCESS;
+    if (CloseHandle(pThis->hShmObj))
+    {
+        pThis->u32Magic = RTSHMEM_MAGIC_DEAD;
+        RTMemFree(pThis);
+    }
+    else
+        rc = RTErrConvertFromWin32(GetLastError());
+
+    return rc;
+}
+
+
+RTDECL(uint32_t) RTShMemRefCount(RTSHMEM hShMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, 0);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, 0);
+
+    return pThis->cMappings;
+}
+
+
+RTDECL(int) RTShMemSetSize(RTSHMEM hShMem, size_t cbMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertReturn(!pThis->cMappings, VERR_INVALID_STATE);
+    AssertReturn(cbMem, VERR_NOT_SUPPORTED);
+
+    return VERR_NOT_SUPPORTED;
+}
+
+
+RTDECL(int) RTShMemQuerySize(RTSHMEM hShMem, size_t *pcbMem)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtrReturn(pcbMem, VERR_INVALID_PARAMETER);
+
+    int rc = VINF_SUCCESS;
+    SECTION_BASIC_INFORMATION SecInf;
+    SIZE_T cbRet;
+    NTSTATUS rcNt = NtQuerySection(pThis->hShmObj, SectionBasicInformation, &SecInf, sizeof(SecInf), &cbRet);
+    if (NT_SUCCESS(rcNt))
+    {
+        AssertReturn(cbRet == sizeof(SecInf), VERR_INTERNAL_ERROR);
+#if HC_ARCH_BITS == 32
+        AssertReturn(SecInf.MaximumSize.HighPart == 0, VERR_INTERNAL_ERROR_2);
+        *pcbMem = SecInf.MaximumSize.LowPart;
+#elif HC_ARCH_BITS == 64
+        *pcbMem = SecInf.MaximumSize.QuadPart;
+#else
+# error "Port me"
+#endif
+    }
+    else
+        rc = RTErrConvertFromNtStatus(rcNt);
+
+    return rc;
+}
+
+
+RTDECL(int) RTShMemMapRegion(RTSHMEM hShMem, size_t offRegion, size_t cbRegion, uint32_t fFlags, void **ppv)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtrReturn(ppv, VERR_INVALID_PARAMETER);
+    AssertReturn(!(fFlags & ~RTSHMEM_MAP_F_VALID_MASK), VERR_INVALID_PARAMETER);
+
+    /* See comment in RTShMemOpen(). */
+    if (   (fFlags & RTSHMEM_MAP_F_EXEC)
+        && g_enmWinVer < kRTWinOSType_7)
+        return VERR_NOT_SUPPORTED;
+
+    /* Try to find a mapping with compatible parameters first. */
+    PRTSHMEMMAPPINGDESC pMappingDesc = NULL;
+    for (uint32_t iTry = 0; iTry < 10; iTry++)
+    {
+        pMappingDesc = rtShMemMappingDescFindByProp(pThis, offRegion, cbRegion, fFlags);
+        if (!pMappingDesc)
+            break;
+
+        /* Increase the mapping count and check that the region is still accessible by us. */
+        if (   ASMAtomicIncU32(&pMappingDesc->cMappings) > 1
+            && pMappingDesc->offRegion == offRegion
+            && pMappingDesc->cbRegion  == cbRegion
+            && pMappingDesc->fFlags    == fFlags)
+            break;
+        /* Mapping was freed inbetween, next round. */
+    }
+
+    int rc = VINF_SUCCESS;
+    if (!pMappingDesc)
+    {
+        /* Find an empty region descriptor and map the region. */
+        for (uint32_t i = 0; i < pThis->cMappingDescsMax && !pMappingDesc; i++)
+        {
+            if (!pThis->aMappingDescs[i].cMappings)
+            {
+                pMappingDesc = &pThis->aMappingDescs[i];
+
+                /* Try to grab this one. */
+                if (ASMAtomicIncU32(&pMappingDesc->cMappings) == 1)
+                    break;
+
+                /* Somebody raced us, drop reference and continue. */
+                ASMAtomicDecU32(&pMappingDesc->cMappings);
+                pMappingDesc = NULL;
+            }
+        }
+
+        if (RT_LIKELY(pMappingDesc))
+        {
+            /* Try to map it. */
+            DWORD fProt = 0;
+            DWORD offLow = offRegion & UINT32_C(0xffffffff);
+#if HC_ARCH_BITS == 64
+            DWORD offHigh = offRegion >> 32;
+#elif HC_ARCH_BITS == 32
+            DWORD offHigh = 0;
+#else
+# error "Port me"
+#endif
+            if (fFlags & RTSHMEM_MAP_F_READ)
+                fProt |= FILE_MAP_READ;
+            if (fFlags & RTSHMEM_MAP_F_WRITE)
+                fProt |= FILE_MAP_WRITE;
+            if (fFlags & RTSHMEM_MAP_F_EXEC)
+                fProt |= FILE_MAP_EXECUTE;
+            if (fFlags & RTSHMEM_MAP_F_COW)
+                fProt |= FILE_MAP_COPY;
+
+            void *pv = MapViewOfFile(pThis->hShmObj, fProt, offHigh, offLow, cbRegion);
+            if (pv != NULL)
+            {
+                pMappingDesc->pvMapping = pv;
+                pMappingDesc->offRegion = offRegion;
+                pMappingDesc->cbRegion  = cbRegion;
+                pMappingDesc->fFlags    = fFlags;
+            }
+            else
+            {
+                rc = RTErrConvertFromWin32(GetLastError());
+                ASMAtomicDecU32(&pMappingDesc->cMappings);
+            }
+        }
+        else
+            rc = VERR_SHMEM_MAXIMUM_MAPPINGS_REACHED;
+    }
+
+    if (RT_SUCCESS(rc))
+    {
+        *ppv = pMappingDesc->pvMapping;
+        ASMAtomicIncU32(&pThis->cMappings);
+    }
+
+    return rc;
+}
+
+
+RTDECL(int) RTShMemUnmapRegion(RTSHMEM hShMem, void *pv)
+{
+    PRTSHMEMINT pThis = hShMem;
+    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
+    AssertReturn(pThis->u32Magic == RTSHMEM_MAGIC, VERR_INVALID_HANDLE);
+    AssertPtrReturn(pv, VERR_INVALID_PARAMETER);
+
+    /* Find the mapping descriptor by the given region address. */
+    PRTSHMEMMAPPINGDESC pMappingDesc = NULL;
+    for (uint32_t i = 0; i < pThis->cMappingDescsMax && !pMappingDesc; i++)
+    {
+        if (pThis->aMappingDescs[i].pvMapping == pv)
+        {
+            pMappingDesc = &pThis->aMappingDescs[i];
+            break;
+        }
+    }
+
+    AssertPtrReturn(pMappingDesc, VERR_INVALID_PARAMETER);
+
+    int rc = VINF_SUCCESS;
+    if (!ASMAtomicDecU32(&pMappingDesc->cMappings))
+    {
+        /* Last mapping of this region was unmapped, so do the real unmapping now. */
+        if (UnmapViewOfFile(pv))
+        {
+            ASMAtomicDecU32(&pThis->cMappingDescsUsed);
+            ASMAtomicDecU32(&pThis->cMappings);
+        }
+        else
+        {
+            ASMAtomicIncU32(&pMappingDesc->cMappings);
+            rc = RTErrConvertFromWin32(GetLastError());
+        }
+    }
+
+    return rc;
+}
+
Index: /trunk/src/VBox/Runtime/testcase/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/testcase/Makefile.kmk	(revision 75878)
+++ /trunk/src/VBox/Runtime/testcase/Makefile.kmk	(revision 75879)
@@ -151,5 +151,6 @@
 	tstRTVfs \
 	tstRTZip \
-	tstRTJson
+	tstRTJson \
+	tstRTShMem
 
 PROGRAMS.win += \
@@ -731,4 +732,7 @@
 tstRTJson_SOURCES = tstRTJson.cpp
 
+tstRTShMem_TEMPLATE = VBOXR3TSTEXE
+tstRTShMem_SOURCES = tstRTShMem.cpp
+
 #
 # Ring-0 testcases.
Index: /trunk/src/VBox/Runtime/testcase/tstRTShMem.cpp
===================================================================
--- /trunk/src/VBox/Runtime/testcase/tstRTShMem.cpp	(revision 75879)
+++ /trunk/src/VBox/Runtime/testcase/tstRTShMem.cpp	(revision 75879)
@@ -0,0 +1,141 @@
+/* $Id$ */
+/** @file
+ * IPRT Testcase - RTShMem.
+ */
+
+/*
+ * Copyright (C) 2018 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ *
+ * The contents of this file may alternatively be used under the terms
+ * of the Common Development and Distribution License Version 1.0
+ * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+ * VirtualBox OSE distribution, in which case the provisions of the
+ * CDDL are applicable instead of those of the GPL.
+ *
+ * You may elect to license modified versions of this file under the
+ * terms and conditions of either the GPL or the CDDL or both.
+ */
+
+
+/*********************************************************************************************************************************
+*   Header Files                                                                                                                 *
+*********************************************************************************************************************************/
+#include <iprt/shmem.h>
+
+#include <iprt/err.h>
+#include <iprt/log.h>
+#include <iprt/string.h>
+#include <iprt/test.h>
+
+
+/*********************************************************************************************************************************
+*   Global Variables                                                                                                             *
+*********************************************************************************************************************************/
+/** Global shared memory object used across all tests. */
+static RTSHMEM g_hShMem = NIL_RTSHMEM;
+/** Data to read/write initially. */
+static char g_szDataBefore[] = "Data before modification!";
+/** Data to read/write for the modification. */
+static char g_szDataAfter[] = "Data after modification!";
+
+
+
+static void tstRTShMem2(void)
+{
+    RTTestISub("Negative");
+
+    /** @todo */
+}
+
+
+static void tstRTShMem1(void)
+{
+    RTTestISub("Basics");
+
+    /* create and destroy. */
+
+    RTTESTI_CHECK_RC_RETV(RTShMemOpen(&g_hShMem, "tstRTShMem-Share", RTSHMEM_O_F_CREATE | RTSHMEM_O_F_READWRITE | RTSHMEM_O_F_MAYBE_EXEC,
+                                      _512K, 0),
+                          VINF_SUCCESS);
+    RTTESTI_CHECK_RETV(g_hShMem != NIL_RTSHMEM);
+
+    /* Query the size. */
+    size_t cbShMem = 0;
+    RTTESTI_CHECK_RC(RTShMemQuerySize(g_hShMem, &cbShMem), VINF_SUCCESS);
+    RTTESTI_CHECK(cbShMem == _512K);
+
+    /* Create a mapping. */
+    void *pvMap;
+    RTTESTI_CHECK_RC_RETV(RTShMemMapRegion(g_hShMem, 0, cbShMem, RTSHMEM_MAP_F_READ | RTSHMEM_MAP_F_WRITE, &pvMap), VINF_SUCCESS);
+    memset(pvMap, 0, cbShMem);
+    memcpy(pvMap, &g_szDataBefore[0], sizeof(g_szDataBefore));
+
+    /* Open the shared memory object and create a second mapping. */
+    RTSHMEM hShMemRead = NIL_RTSHMEM;
+    RTTESTI_CHECK_RC_RETV(RTShMemOpen(&hShMemRead, "tstRTShMem-Share", RTSHMEM_O_F_READWRITE | RTSHMEM_O_F_MAYBE_EXEC,
+                                      0, 0),
+                          VINF_SUCCESS);
+    RTTESTI_CHECK_RETV(hShMemRead != NIL_RTSHMEM);
+
+    void *pvMapRead = NULL;
+    RTTESTI_CHECK_RC(RTShMemQuerySize(hShMemRead, &cbShMem), VINF_SUCCESS);
+    RTTESTI_CHECK(cbShMem == _512K);
+    RTTESTI_CHECK_RC_RETV(RTShMemMapRegion(hShMemRead, 0, cbShMem, RTSHMEM_MAP_F_READ | RTSHMEM_MAP_F_WRITE, &pvMapRead), VINF_SUCCESS);
+    RTTESTI_CHECK(!memcmp(pvMapRead, &g_szDataBefore[0], sizeof(g_szDataBefore)));
+    RTTESTI_CHECK(!memcmp(pvMapRead, pvMap, cbShMem));
+
+    /* Alter the data in the first mapping and check that it is visible in the second one. */
+    memcpy(pvMap, &g_szDataAfter[0], sizeof(g_szDataAfter));
+    RTTESTI_CHECK(!memcmp(pvMapRead, &g_szDataAfter[0], sizeof(g_szDataAfter)));
+    RTTESTI_CHECK(!memcmp(pvMapRead, pvMap, cbShMem));
+
+    RTTESTI_CHECK_RC(RTShMemUnmapRegion(hShMemRead, pvMapRead), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTShMemClose(hShMemRead), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTShMemUnmapRegion(g_hShMem, pvMap), VINF_SUCCESS);
+    RTTESTI_CHECK_RC(RTShMemClose(g_hShMem), VINF_SUCCESS);
+    g_hShMem = NIL_RTSHMEM;
+}
+
+int main()
+{
+    RTTEST hTest;
+    int rc = RTTestInitAndCreate("tstRTShMem", &hTest);
+    if (rc)
+        return rc;
+    RTTestBanner(hTest);
+
+    /*
+     * The tests.
+     */
+    tstRTShMem1();
+    if (RTTestErrorCount(hTest) == 0)
+    {
+        bool fMayPanic = RTAssertMayPanic();
+        bool fQuiet    = RTAssertAreQuiet();
+        RTAssertSetMayPanic(false);
+        RTAssertSetQuiet(true);
+        tstRTShMem2();
+        RTAssertSetQuiet(fQuiet);
+        RTAssertSetMayPanic(fMayPanic);
+    }
+
+    if (g_hShMem != NIL_RTSHMEM)
+    {
+        RTTESTI_CHECK_RC(RTShMemClose(g_hShMem), VINF_SUCCESS);
+        g_hShMem = NIL_RTSHMEM;
+    }
+
+    /*
+     * Summary.
+     */
+    return RTTestSummaryAndDestroy(hTest);
+}
+
