Index: trunk/include/VBox/GuestHost/SharedClipboard-uri.h
===================================================================
--- trunk/include/VBox/GuestHost/SharedClipboard-uri.h	(revision 78949)
+++ trunk/include/VBox/GuestHost/SharedClipboard-uri.h	(revision 78950)
@@ -48,9 +48,11 @@
 #define NIL_SHAREDCLIPBOARDAREAID       UINT32_MAX
 
-/** SharedClipboardArea flags. */
-typedef uint32_t SHAREDCLIPBOARDAREAFLAGS;
-
-/** No flags specified. */
-#define SHAREDCLIPBOARDAREA_FLAGS_NONE     0
+/** SharedClipboardArea open flags. */
+typedef uint32_t SHAREDCLIPBOARDAREAOPENFLAGS;
+
+/** No open flags specified. */
+#define SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE               0
+/** The clipboard area must not exist yet. */
+#define SHAREDCLIPBOARDAREA_OPEN_FLAGS_MUST_NOT_EXIST     RT_BIT(0)
 
 /**
@@ -68,5 +70,5 @@
     SharedClipboardArea(void);
     SharedClipboardArea(const char *pszPath, SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
-                        SHAREDCLIPBOARDAREAFLAGS fFlags = SHAREDCLIPBOARDAREA_FLAGS_NONE);
+                        SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
     virtual ~SharedClipboardArea(void);
 
@@ -84,7 +86,7 @@
     bool IsOpen(void) const;
     int OpenEx(const char *pszPath, SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
-               SHAREDCLIPBOARDAREAFLAGS fFlags = SHAREDCLIPBOARDAREA_FLAGS_NONE);
+               SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
     int OpenTemp(SHAREDCLIPBOARDAREAID uID = NIL_SHAREDCLIPBOARDAREAID,
-                 SHAREDCLIPBOARDAREAFLAGS fFlags = SHAREDCLIPBOARDAREA_FLAGS_NONE);
+                 SHAREDCLIPBOARDAREAOPENFLAGS fFlags = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE);
     SHAREDCLIPBOARDAREAID GetID(void) const;
     const char *GetDirAbs(void) const;
Index: trunk/src/VBox/GuestHost/SharedClipboard/ClipboardArea.cpp
===================================================================
--- trunk/src/VBox/GuestHost/SharedClipboard/ClipboardArea.cpp	(revision 78949)
+++ trunk/src/VBox/GuestHost/SharedClipboard/ClipboardArea.cpp	(revision 78950)
@@ -47,5 +47,5 @@
 SharedClipboardArea::SharedClipboardArea(const char *pszPath,
                                          SHAREDCLIPBOARDAREAID uID /* = NIL_SHAREDCLIPBOARDAREAID */,
-                                         SHAREDCLIPBOARDAREAFLAGS fFlags /* = SHAREDCLIPBOARDAREA_FLAGS_NONE */)
+                                         SHAREDCLIPBOARDAREAOPENFLAGS fFlags /* = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE */)
     : m_tsCreatedMs(0)
     , m_cRefs(0)
@@ -158,5 +158,5 @@
     if (RT_SUCCESS(rc))
     {
-        this->m_fOpen = SHAREDCLIPBOARDAREA_FLAGS_NONE;
+        this->m_fOpen = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE;
         this->m_uID   = NIL_SHAREDCLIPBOARDAREAID;
     }
@@ -238,5 +238,5 @@
 int SharedClipboardArea::OpenEx(const char *pszPath,
                                 SHAREDCLIPBOARDAREAID uID /* = NIL_SHAREDCLIPBOARDAREAID */,
-                                SHAREDCLIPBOARDAREAFLAGS fFlags /* = SHAREDCLIPBOARDAREA_FLAGS_NONE */)
+                                SHAREDCLIPBOARDAREAOPENFLAGS fFlags /* = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE */)
 {
     AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
@@ -247,6 +247,11 @@
     if (RT_SUCCESS(rc))
     {
-        if (!RTDirExists(szAreaDir))
-            rc = RTDirCreateFullPath(szAreaDir, RTFS_UNIX_IRWXU);
+        if (   RTDirExists(szAreaDir)
+            && (fFlags & SHAREDCLIPBOARDAREA_OPEN_FLAGS_MUST_NOT_EXIST))
+        {
+            rc = VERR_ALREADY_EXISTS;
+        }
+        else
+            rc = RTDirCreateFullPath(szAreaDir, RTFS_UNIX_IRWXU); /** @todo Tweak path mode? */
 
         if (RT_SUCCESS(rc))
@@ -270,5 +275,5 @@
 
 int SharedClipboardArea::OpenTemp(SHAREDCLIPBOARDAREAID uID,
-                                  SHAREDCLIPBOARDAREAFLAGS fFlags /* = SHAREDCLIPBOARDAREA_FLAGS_NONE */)
+                                  SHAREDCLIPBOARDAREAOPENFLAGS fFlags /* = SHAREDCLIPBOARDAREA_OPEN_FLAGS_NONE */)
 {
     AssertReturn(fFlags == 0, VERR_INVALID_PARAMETER); /* Flags not supported yet. */
Index: trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp
===================================================================
--- trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp	(revision 78949)
+++ trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-uri.cpp	(revision 78950)
@@ -114,15 +114,11 @@
     AssertPtrReturn(pState,    VERR_INVALID_POINTER);
 
-    int rc = pTransfer->Area.OpenTemp(SHAREDCLIPBOARDAREA_FLAGS_NONE);
+    int rc = SharedClipboardMetaDataInit(&pTransfer->Meta);
     if (RT_SUCCESS(rc))
     {
-        rc = SharedClipboardMetaDataInit(&pTransfer->Meta);
+        vboxClipboardSvcURIObjCtxInit(&pTransfer->ObjCtx);
         if (RT_SUCCESS(rc))
         {
-            vboxClipboardSvcURIObjCtxInit(&pTransfer->ObjCtx);
-            if (RT_SUCCESS(rc))
-            {
-                pTransfer->pState = pState;
-            }
+            pTransfer->pState = pState;
         }
     }
@@ -472,4 +468,5 @@
                             RT_ZERO(parms);
 
+                            parms.uID                  = NIL_SHAREDCLIPBOARDAREAID;
                             parms.u.fn_register.pvData = pvMeta;
                             parms.u.fn_register.cbData = (uint32_t)cbMeta;
@@ -477,8 +474,10 @@
                             /* As the meta data is now complete, register a new clipboard on the host side. */
                             rc = g_pfnExtension(g_pvExtension, VBOX_CLIPBOARD_EXT_FN_AREA_REGISTER, &parms, sizeof(parms));
+                            if (RT_SUCCESS(rc))
+                                rc = pTransfer->Area.OpenTemp(parms.uID /* Area ID */);
 #ifdef LOG_ENABLED
                             AssertPtr(pTransfer->pState);
-                            LogFlowFunc(("Registered new clipboard area by client %RU32 with rc=%Rrc\n",
-                                         pTransfer->pState->u32ClientID, rc));
+                            LogFlowFunc(("Registered new clipboard area (%RU32) by client %RU32 with rc=%Rrc\n",
+                                         parms.uID, pTransfer->pState->u32ClientID, rc));
 #endif
                         }
Index: trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 78949)
+++ trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 78950)
@@ -8461,4 +8461,5 @@
 
             VBOXCLIPBOARDEXTPARMS *pParms = (VBOXCLIPBOARDEXTPARMS *)pvParms;
+            AssertPtr(pParms);
 
             /* The guest announces clipboard formats. This must be delivered to all clients. */
@@ -8476,4 +8477,5 @@
 
             VBOXCLIPBOARDEXTPARMS *pParms = (VBOXCLIPBOARDEXTPARMS *)pvParms;
+            AssertPtr(pParms);
 
             /* The clipboard service expects that the pvData buffer will be filled
@@ -8494,4 +8496,5 @@
 
             VBOXCLIPBOARDEXTPARMS *pParms = (VBOXCLIPBOARDEXTPARMS *)pvParms;
+            AssertPtr(pParms);
 
             if (pThis->mConsoleVRDPServer)
@@ -8509,4 +8512,12 @@
             ULONG uID;
             hrc = pControl->ClipboardAreaRegister(ComSafeArrayAsInParam(abstrParms), &uID);      H();
+            if (SUCCEEDED(hrc))
+            {
+                 PVBOXCLIPBOARDEXTAREAPARMS pParms = (PVBOXCLIPBOARDEXTAREAPARMS)pvParms;
+                 AssertPtr(pParms);
+
+                 /* Return the registered area ID back to the caller. */
+                 pParms->uID = uID;
+            }
         } break;
 
Index: trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp
===================================================================
--- trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 78949)
+++ trunk/src/VBox/Main/src-server/VirtualBoxImpl.cpp	(revision 78950)
@@ -230,7 +230,8 @@
 {
     SharedClipboardAreaData()
-        : uID(0) { }
-
-    /** The area's (unique) ID. */
+        : uID(NIL_SHAREDCLIPBOARDAREAID) { }
+
+    /** The area's (unique) ID.
+     *  Set to NIL_SHAREDCLIPBOARDAREAID if not initialized yet. */
     ULONG               uID;
     /** The actual Shared Clipboard area assigned to this ID. */
@@ -247,6 +248,6 @@
 {
     SharedClipboardData()
-        : uNextClipboardAreaID(0)
-        , uMaxClipboardAreas(32)
+        : uMostRecentClipboardAreaID(NIL_SHAREDCLIPBOARDAREAID)
+        , uMaxClipboardAreas(32) /** @todo Make this configurable. */
     {
         int rc2 = RTCritSectInit(&CritSect);
@@ -259,8 +260,32 @@
     }
 
+    /**
+     * Generates a new clipboard area ID.
+     * Currently does *not* check for collisions and stuff.
+     *
+     * @returns New clipboard area ID.
+     */
+    ULONG GenerateAreaID(void)
+    {
+        ULONG uID = NIL_SHAREDCLIPBOARDAREAID;
+
+        int rc = RTCritSectEnter(&CritSect);
+        if (RT_SUCCESS(rc))
+        {
+            uID = RTRandU32Ex(1, UINT32_MAX - 1); /** @todo Make this a bit more sophisticated. Later. */
+
+            int rc2 = RTCritSectLeave(&CritSect);
+            AssertRC(rc2);
+        }
+
+        LogFlowFunc(("uID=%RU32\n", uID));
+        return uID;
+    }
+
     /** Critical section to serialize access. */
     RTCRITSECT                          CritSect;
-    /** The next (free) clipboard area ID. */
-    ULONG                               uNextClipboardAreaID;
+    /** The most recent (last created) clipboard area ID.
+     *  NIL_SHAREDCLIPBOARDAREAID if not initialized yet. */
+    ULONG                               uMostRecentClipboardAreaID;
     /** Maximum of concurrent clipboard areas.
      *  @todo Make this configurable. */
@@ -3353,15 +3378,25 @@
 
 #ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
+/**
+ * Generates a new clipboard area on the host by opening (and locking) a new, temporary directory.
+ *
+ * @returns HRESULT
+ * @param   AreaData            Area data to use for clipboard area creation.
+ * @param   fFlags              Additional creation flags; currently unused and ignored.
+ */
 int VirtualBox::i_clipboardAreaCreate(SharedClipboardAreaData &AreaData, uint32_t fFlags)
 {
     RT_NOREF(fFlags);
-    int vrc = AreaData.Area.OpenTemp(AreaData.uID);
-    if (RT_SUCCESS(vrc))
-    {
-    }
+    int vrc = AreaData.Area.OpenTemp(AreaData.uID, SHAREDCLIPBOARDAREA_OPEN_FLAGS_MUST_NOT_EXIST);
     LogFlowFunc(("uID=%RU32, rc=%Rrc\n", AreaData.uID, vrc));
     return vrc;
 }
 
+/**
+ * Destroys a formerly created clipboard area.
+ *
+ * @returns HRESULT
+ * @param   AreaData            Area data to use for clipboard area destruction.
+ */
 int VirtualBox::i_clipboardAreaDestroy(SharedClipboardAreaData &AreaData)
 {
@@ -3373,4 +3408,11 @@
 }
 
+/**
+ * Registers and creates a new clipboard area on the host (for all VMs), returned the clipboard area ID for it.
+ *
+ * @returns HRESULT
+ * @param   aParms              Creation parameters. Currently unused.
+ * @param   aID                 Where to return the clipboard area ID on success.
+ */
 HRESULT VirtualBox::i_onClipboardAreaRegister(const std::vector<com::Utf8Str> &aParms, ULONG *aID)
 {
@@ -3386,31 +3428,40 @@
             if (m->SharedClipboard.mapClipboardAreas.size() >= m->SharedClipboard.uMaxClipboardAreas)
             {
-                const ULONG uAreaID = m->SharedClipboard.uNextClipboardAreaID;
-
-                SharedClipboardAreaData AreaData;
-                AreaData.uID = uAreaID;
-
-                vrc = i_clipboardAreaCreate(AreaData, 0 /* fFlags */);
-                if (RT_SUCCESS(vrc))
+                for (unsigned uTries = 0; uTries < 32; uTries++) /* Don't try too hard. */
                 {
-                    m->SharedClipboard.mapClipboardAreas[uAreaID] = AreaData;
-                    m->SharedClipboard.uNextClipboardAreaID++;
-
-                    /** @todo Implement collision detection / wrap-around. */
-
-                    if (aID)
-                        *aID = uAreaID;
-
-                    LogThisFunc(("Registered new clipboard area %RU32: '%s'\n",
-                                 uAreaID, AreaData.Area.GetDirAbs()));
+                    const ULONG uAreaID = m->SharedClipboard.GenerateAreaID();
+
+                    /* Area ID already taken? */
+                    if (m->SharedClipboard.mapClipboardAreas.find(uAreaID) != m->SharedClipboard.mapClipboardAreas.end())
+                        continue;
+
+                    SharedClipboardAreaData AreaData;
+                    AreaData.uID = uAreaID;
+
+                    vrc = i_clipboardAreaCreate(AreaData, 0 /* fFlags */);
+                    if (RT_SUCCESS(vrc))
+                    {
+                        m->SharedClipboard.mapClipboardAreas[uAreaID] = AreaData;
+                        m->SharedClipboard.uMostRecentClipboardAreaID = uAreaID;
+
+                        /** @todo Implement collision detection / wrap-around. */
+
+                        if (aID)
+                            *aID = uAreaID;
+
+                        LogThisFunc(("Registered new clipboard area %RU32: '%s'\n",
+                                     uAreaID, AreaData.Area.GetDirAbs()));
+                        break;
+                    }
                 }
-                else
+
+                if (RT_FAILURE(vrc))
                     rc = setError(E_FAIL, /** @todo Find a better rc. */
-                                  tr("Failed to create new clipboard area %RU32 (%Rrc)"), aID, vrc);
+                                  tr("Failed to create new clipboard area (%Rrc)"), vrc);
             }
             else
             {
                 rc = setError(E_FAIL, /** @todo Find a better rc. */
-                              tr("Maximum number of conucurrent clipboard areas reached (%RU32)"),
+                              tr("Maximum number of concurrent clipboard areas reached (%RU32)"),
                               m->SharedClipboard.uMaxClipboardAreas);
             }
@@ -3428,4 +3479,10 @@
 }
 
+/**
+ * Unregisters (destroys) a formerly created clipboard area.
+ *
+ * @returns HRESULT
+ * @param   aID                 ID of clipboard area to destroy.
+ */
 HRESULT VirtualBox::i_onClipboardAreaUnregister(ULONG aID)
 {
@@ -3461,4 +3518,10 @@
 }
 
+/**
+ * Attaches to an existing clipboard area.
+ *
+ * @returns HRESULT
+ * @param   aID                 ID of clipboard area to attach.
+ */
 HRESULT VirtualBox::i_onClipboardAreaAttach(ULONG aID)
 {
@@ -3486,4 +3549,10 @@
 }
 
+/**
+ * Detaches from an existing clipboard area.
+ *
+ * @returns HRESULT
+ * @param   aID                 ID of clipboard area to detach from.
+ */
 HRESULT VirtualBox::i_onClipboardAreaDetach(ULONG aID)
 {
@@ -3511,4 +3580,10 @@
 }
 
+/**
+ * Returns the ID of the most recent (last created) clipboard area,
+ * or NIL_SHAREDCLIPBOARDAREAID if no clipboard area has been created yet.
+ *
+ * @returns Most recent clipboard area ID.
+ */
 ULONG VirtualBox::i_onClipboardAreaGetMostRecent(void)
 {
@@ -3517,6 +3592,5 @@
     if (RT_SUCCESS(vrc2))
     {
-        aID = m->SharedClipboard.uNextClipboardAreaID
-            ? m->SharedClipboard.uNextClipboardAreaID - 1 : 0;
+        aID = m->SharedClipboard.uMostRecentClipboardAreaID;
 
         vrc2 = RTCritSectLeave(&m->SharedClipboard.CritSect);
@@ -3527,4 +3601,9 @@
 }
 
+/**
+ * Returns the current reference count of a clipboard area.
+ *
+ * @returns Reference count of given clipboard area ID.
+ */
 ULONG VirtualBox::i_onClipboardAreaGetRefCount(ULONG aID)
 {
