Index: /trunk/include/VBox/shflsvc.h
===================================================================
--- /trunk/include/VBox/shflsvc.h	(revision 78466)
+++ /trunk/include/VBox/shflsvc.h	(revision 78467)
@@ -148,6 +148,10 @@
  * @since VBox 6.0.6  */
 #define SHFL_FN_COPY_FILE_PART      (27)
+/** Close handle to (optional) and remove object by path.
+ * This function is tailored for Windows guests.
+ * @since VBox 6.0.8  */
+#define SHFL_FN_CLOSE_AND_REMOVE    (28)
 /** The last function number. */
-#define SHFL_FN_LAST                SHFL_FN_COPY_FILE_PART
+#define SHFL_FN_LAST                SHFL_FN_CLOSE_AND_REMOVE
 /** @} */
 
@@ -1780,4 +1784,26 @@
 
 
+/** @name SHFL_FN_CLOSE_AND_REMOVE
+ * Extends SHFL_FN_REMOVE with a 4th handle parameter that can be nil.
+ * @{
+ */
+/** SHFL_FN_CLOSE_AND_REMOVE parameters. */
+typedef struct VBoxSFParmCloseAndRemove
+#ifdef __cplusplus
+    : public VBoxSFParmRemove
+#endif
+{
+#ifndef __cplusplus
+    VBoxSFParmRemove      Core;
+#endif
+    /** value64, in: SHFLHANDLE to the object to be removed & close, optional. */
+    HGCMFunctionParameter u64Handle;
+} VBoxSFParmCloseAndRemove;
+/** Number of parameters */
+#define SHFL_CPARMS_CLOSE_AND_REMOVE    (4)
+AssertCompileSize(VBoxSFParmCloseAndRemove, SHFL_CPARMS_CLOSE_AND_REMOVE * sizeof(HGCMFunctionParameter));
+/** @} */
+
+
 /** @name SHFL_FN_RENAME
  * @{
Index: /trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp	(revision 78466)
+++ /trunk/src/VBox/HostServices/SharedFolders/VBoxSharedFoldersSvc.cpp	(revision 78467)
@@ -86,4 +86,6 @@
 static STAMPROFILE g_StatRemove;
 static STAMPROFILE g_StatRemoveFail;
+static STAMPROFILE g_StatCloseAndRemove;
+static STAMPROFILE g_StatCloseAndRemoveFail;
 static STAMPROFILE g_StatRename;
 static STAMPROFILE g_StatRenameFail;
@@ -1214,39 +1216,44 @@
 
             /* Verify parameter count and types. */
-            if (cParms != SHFL_CPARMS_REMOVE)
-            {
-                rc = VERR_INVALID_PARAMETER;
-            }
-            else if (   paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT   /* root */
-                     || paParms[1].type != VBOX_HGCM_SVC_PARM_PTR   /* path */
-                     || paParms[2].type != VBOX_HGCM_SVC_PARM_32BIT /* flags */
-                    )
-            {
-                rc = VERR_INVALID_PARAMETER;
-            }
-            else
-            {
-                /* Fetch parameters. */
-                SHFLROOT  root          = (SHFLROOT)paParms[0].u.uint32;
-                SHFLSTRING *pPath       = (SHFLSTRING *)paParms[1].u.pointer.addr;
-                uint32_t cbPath         = paParms[1].u.pointer.size;
-                uint32_t flags          = paParms[2].u.uint32;
-
-                /* Verify parameters values. */
-                if (!ShflStringIsValidIn(pPath, cbPath, RT_BOOL(pClient->fu32Flags & SHFL_CF_UTF8)))
-                {
-                    rc = VERR_INVALID_PARAMETER;
-                }
-                else
-                {
-                    /* Execute the function. */
-                    rc = vbsfRemove (pClient, root, pPath, cbPath, flags);
-                    if (RT_SUCCESS(rc))
-                    {
-                        /* Update parameters.*/
-                        ; /* none */
-                    }
-                }
-            }
+            ASSERT_GUEST_STMT_BREAK(cParms == SHFL_CPARMS_REMOVE, rc = VERR_WRONG_PARAMETER_COUNT);
+            ASSERT_GUEST_STMT_BREAK(paParms[0].type == VBOX_HGCM_SVC_PARM_32BIT, rc = VERR_WRONG_PARAMETER_TYPE); /* root */
+            ASSERT_GUEST_STMT_BREAK(paParms[1].type == VBOX_HGCM_SVC_PARM_PTR,   rc = VERR_WRONG_PARAMETER_TYPE); /* path */
+            PCSHFLSTRING pStrPath = (PCSHFLSTRING)paParms[1].u.pointer.addr;
+            ASSERT_GUEST_STMT_BREAK(ShflStringIsValidIn(pStrPath, paParms[1].u.pointer.size,
+                                                        RT_BOOL(pClient->fu32Flags & SHFL_CF_UTF8)),
+                                    rc = VERR_INVALID_PARAMETER);
+            ASSERT_GUEST_STMT_BREAK(paParms[2].type == VBOX_HGCM_SVC_PARM_32BIT, rc = VERR_WRONG_PARAMETER_TYPE); /* flags */
+            uint32_t const fFlags = paParms[2].u.uint32;
+            ASSERT_GUEST_STMT_BREAK(!(fFlags & ~(SHFL_REMOVE_FILE | SHFL_REMOVE_DIR | SHFL_REMOVE_SYMLINK)),
+                                    rc = VERR_INVALID_FLAGS);
+
+            /* Execute the function. */
+            rc = vbsfRemove(pClient, paParms[0].u.uint32, pStrPath, paParms[1].u.pointer.size, fFlags, SHFL_HANDLE_NIL);
+            break;
+        }
+
+        case SHFL_FN_CLOSE_AND_REMOVE:
+        {
+            pStat     = &g_StatCloseAndRemove;
+            pStatFail = &g_StatCloseAndRemoveFail;
+            Log(("SharedFolders host service: svcCall: SHFL_FN_CLOSE_AND_REMOVE\n"));
+
+            /* Verify parameter count and types. */
+            ASSERT_GUEST_STMT_BREAK(cParms == SHFL_CPARMS_CLOSE_AND_REMOVE, rc = VERR_WRONG_PARAMETER_COUNT);
+            ASSERT_GUEST_STMT_BREAK(paParms[0].type == VBOX_HGCM_SVC_PARM_32BIT, rc = VERR_WRONG_PARAMETER_TYPE); /* root */
+            ASSERT_GUEST_STMT_BREAK(paParms[1].type == VBOX_HGCM_SVC_PARM_PTR,   rc = VERR_WRONG_PARAMETER_TYPE); /* path */
+            PCSHFLSTRING pStrPath = (PCSHFLSTRING)paParms[1].u.pointer.addr;
+            ASSERT_GUEST_STMT_BREAK(ShflStringIsValidIn(pStrPath, paParms[1].u.pointer.size,
+                                                        RT_BOOL(pClient->fu32Flags & SHFL_CF_UTF8)),
+                                    rc = VERR_INVALID_PARAMETER);
+            ASSERT_GUEST_STMT_BREAK(paParms[2].type == VBOX_HGCM_SVC_PARM_32BIT, rc = VERR_WRONG_PARAMETER_TYPE); /* flags */
+            uint32_t const fFlags = paParms[2].u.uint32;
+            ASSERT_GUEST_STMT_BREAK(!(fFlags & ~(SHFL_REMOVE_FILE | SHFL_REMOVE_DIR | SHFL_REMOVE_SYMLINK)),
+                                    rc = VERR_INVALID_FLAGS);
+            SHFLHANDLE const hToClose = paParms[3].u.uint64;
+            ASSERT_GUEST_STMT_BREAK(hToClose != SHFL_HANDLE_ROOT, rc = VERR_INVALID_HANDLE);
+
+            /* Execute the function. */
+            rc = vbsfRemove(pClient, paParms[0].u.uint32, pStrPath, paParms[1].u.pointer.size, fFlags, hToClose);
             break;
         }
@@ -1860,4 +1867,6 @@
              HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRemove,                    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "SHFL_FN_REMOVE successes",                  "/HGCM/VBoxSharedFolders/FnRemove");
              HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRemoveFail,                STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "SHFL_FN_REMOVE failures",                   "/HGCM/VBoxSharedFolders/FnRemoveFail");
+             HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCloseAndRemove,            STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "SHFL_FN_CLOSE_AND_REMOVE successes",        "/HGCM/VBoxSharedFolders/FnCloseAndRemove");
+             HGCMSvcHlpStamRegister(g_pHelpers, &g_StatCloseAndRemoveFail,        STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "SHFL_FN_CLOSE_AND_REMOVE failures",         "/HGCM/VBoxSharedFolders/FnCloseAndRemoveFail");
              HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRename,                    STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "SHFL_FN_RENAME successes",                  "/HGCM/VBoxSharedFolders/FnRename");
              HGCMSvcHlpStamRegister(g_pHelpers, &g_StatRenameFail,                STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_CALLS, "SHFL_FN_RENAME failures",                   "/HGCM/VBoxSharedFolders/FnRenameFail");
Index: /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp	(revision 78466)
+++ /trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp	(revision 78467)
@@ -2181,47 +2181,49 @@
 }
 #endif
-int vbsfRemove(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, uint32_t flags)
-{
+int vbsfRemove(SHFLCLIENTDATA *pClient, SHFLROOT root, PCSHFLSTRING pPath, uint32_t cbPath, uint32_t flags, SHFLHANDLE hToClose)
+{
+
+    /* Validate input */
+    Assert(pPath);
+    AssertReturn(pPath->u16Size > 0, VERR_INVALID_PARAMETER);
+
+    /*
+     * Close the handle if specified.
+     */
     int rc = VINF_SUCCESS;
-
-    /* Validate input */
-    if (   flags & ~(SHFL_REMOVE_FILE|SHFL_REMOVE_DIR|SHFL_REMOVE_SYMLINK)
-        || cbPath == 0
-        || pPath == 0)
-    {
-        AssertFailed();
-        return VERR_INVALID_PARAMETER;
-    }
-
-    /* Build a host full path for the given path
-     * and convert ucs2 to utf8 if necessary.
-     */
-    char *pszFullPath = NULL;
-
-    rc = vbsfBuildFullPath(pClient, root, pPath, cbPath, &pszFullPath, NULL);
+    if (hToClose != SHFL_HANDLE_NIL)
+        rc = vbsfClose(pClient, root, hToClose);
     if (RT_SUCCESS(rc))
     {
-        /* is the guest allowed to write to this share? */
-        bool fWritable;
-        rc = vbsfMappingsQueryWritable(pClient, root, &fWritable);
-        if (RT_FAILURE(rc) || !fWritable)
-            rc = VERR_WRITE_PROTECT;
-
+        /*
+         * Build a host full path for the given path and convert ucs2 to utf8 if necessary.
+         */
+        char *pszFullPath = NULL;
+        rc = vbsfBuildFullPath(pClient, root, pPath, cbPath, &pszFullPath, NULL);
         if (RT_SUCCESS(rc))
         {
-            if (flags & SHFL_REMOVE_SYMLINK)
-                rc = RTSymlinkDelete(pszFullPath, 0);
-            else if (flags & SHFL_REMOVE_FILE)
-                rc = RTFileDelete(pszFullPath);
+            /*
+             * Is the guest allowed to write to this share?
+             */
+            bool fWritable;
+            rc = vbsfMappingsQueryWritable(pClient, root, &fWritable);
+            if (RT_SUCCESS(rc) && fWritable)
+            {
+                /*
+                 * Do the removal/deletion according to the type flags.
+                 */
+                if (flags & SHFL_REMOVE_SYMLINK)
+                    rc = RTSymlinkDelete(pszFullPath, 0);
+                else if (flags & SHFL_REMOVE_FILE)
+                    rc = RTFileDelete(pszFullPath);
+                else
+                    rc = RTDirRemove(pszFullPath);
+            }
             else
-                rc = RTDirRemove(pszFullPath);
-        }
-
-#ifndef DEBUG_dmik
-        // VERR_ACCESS_DENIED for example?
-        // Assert(rc == VINF_SUCCESS || rc == VERR_DIR_NOT_EMPTY);
-#endif
-        /* free the path string */
-        vbsfFreeFullPath(pszFullPath);
+                rc = VERR_WRITE_PROTECT;
+
+            /* free the path string */
+            vbsfFreeFullPath(pszFullPath);
+        }
     }
     return rc;
Index: /trunk/src/VBox/HostServices/SharedFolders/vbsf.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedFolders/vbsf.h	(revision 78466)
+++ /trunk/src/VBox/HostServices/SharedFolders/vbsf.h	(revision 78467)
@@ -40,5 +40,5 @@
 int vbsfLock(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint64_t offset, uint64_t length, uint32_t flags);
 int vbsfUnlock(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLHANDLE Handle, uint64_t offset, uint64_t length, uint32_t flags);
-int vbsfRemove(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pPath, uint32_t cbPath, uint32_t flags);
+int vbsfRemove(SHFLCLIENTDATA *pClient, SHFLROOT root, PCSHFLSTRING pPath, uint32_t cbPath, uint32_t flags, SHFLHANDLE hToClose);
 int vbsfRename(SHFLCLIENTDATA *pClient, SHFLROOT root, SHFLSTRING *pSrc, SHFLSTRING *pDest, uint32_t flags);
 int vbsfCopyFile(SHFLCLIENTDATA *pClient, SHFLROOT idRootSrc, PCSHFLSTRING pStrPathSrc,
