Index: trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp	(revision 99088)
+++ trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp	(revision 99120)
@@ -1391,4 +1391,5 @@
  * @param   pStartupInfo        Process startup info to initializes.
  * @param   cbCmd               Size (in bytes) to use for the command buffer.
+ * @param   cbCwd               Size (in bytes) to use for the current working directory.
  * @param   cbUser              Size (in bytes) to use for the user name buffer.
  * @param   cbPassword          Size (in bytes) to use for the password buffer.
@@ -1399,4 +1400,5 @@
 VBGLR3DECL(int) VbglR3GuestCtrlProcStartupInfoInitEx(PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo,
                                                      size_t cbCmd,
+                                                     size_t cbCwd,
                                                      size_t cbUser, size_t cbPassword, size_t cbDomain,
                                                      size_t cbArgs, size_t cbEnv)
@@ -1404,4 +1406,5 @@
     AssertPtrReturn(pStartupInfo, VERR_INVALID_POINTER);
     AssertReturn(cbCmd,           VERR_INVALID_PARAMETER);
+    AssertReturn(cbCwd,           VERR_INVALID_PARAMETER);
     AssertReturn(cbUser,          VERR_INVALID_PARAMETER);
     AssertReturn(cbPassword,      VERR_INVALID_PARAMETER);
@@ -1423,4 +1426,5 @@
     {
         ALLOC_STR(Cmd,      cbCmd);
+        ALLOC_STR(Cwd,      cbCwd);
         ALLOC_STR(Args,     cbArgs);
         ALLOC_STR(Env,      cbEnv);
@@ -1448,4 +1452,5 @@
     return VbglR3GuestCtrlProcStartupInfoInitEx(pStartupInfo,
                                                 GUEST_PROC_DEF_CMD_LEN,
+                                                GUEST_PROC_DEF_CWD_LEN,
                                                 GUEST_PROC_DEF_USER_LEN     /* Deprecated, now handled via session creation. */,
                                                 GUEST_PROC_DEF_PASSWORD_LEN /* Ditto. */,
@@ -1465,4 +1470,5 @@
 
     RTStrFree(pStartupInfo->pszCmd);
+    RTStrFree(pStartupInfo->pszCwd);
     RTStrFree(pStartupInfo->pszArgs);
     RTStrFree(pStartupInfo->pszEnv);
@@ -1605,4 +1611,7 @@
             VbglHGCMParmUInt32Set(&Msg.u.v2.num_affinity, 0);
             VbglHGCMParmPtrSet(&Msg.u.v2.affinity, pStartupInfo->uAffinity, sizeof(pStartupInfo->uAffinity));
+            /* v2.cwd was added in 7.1.  If the host is older, the Msg struct it sends is
+             * shorter and these fields are zero-filled, which equals 'no cwd requested'. */
+            VbglHGCMParmPtrSet(&Msg.u.v2.cwd, pStartupInfo->pszCwd, pStartupInfo->cbCwd);
         }
 
@@ -1610,6 +1619,6 @@
         if (RT_FAILURE(rc))
         {
-            LogRel(("VbglR3GuestCtrlProcGetStart: 1 - %Rrc (retry %u, cbCmd=%RU32, cbArgs=%RU32, cbEnv=%RU32)\n",
-                    rc, cRetries, pStartupInfo->cbCmd, pStartupInfo->cbArgs, pStartupInfo->cbEnv));
+            LogRel(("VbglR3GuestCtrlProcGetStart: 1 - %Rrc (retry %u, cbCmd=%RU32, cbCwd=%RU32, cbArgs=%RU32, cbEnv=%RU32)\n",
+                    rc, cRetries, pStartupInfo->cbCmd, pStartupInfo->cbCwd, pStartupInfo->cbArgs, pStartupInfo->cbEnv));
 
             if (   rc == VERR_BUFFER_OVERFLOW
@@ -1624,10 +1633,11 @@
                 /* We can't tell which parameter doesn't fit, so we have to resize all. */
                 GROW_STR(Cmd , GUEST_PROC_MAX_CMD_LEN);
+                GROW_STR(Cwd,  GUEST_PROC_MAX_CWD_LEN);
                 GROW_STR(Args, GUEST_PROC_MAX_ARGS_LEN);
                 GROW_STR(Env,  GUEST_PROC_MAX_ENV_LEN);
 
 #undef GROW_STR
-                LogRel(("VbglR3GuestCtrlProcGetStart: 2 - %Rrc (retry %u, cbCmd=%RU32, cbArgs=%RU32, cbEnv=%RU32)\n",
-                        rc, cRetries, pStartupInfo->cbCmd, pStartupInfo->cbArgs, pStartupInfo->cbEnv));
+                LogRel(("VbglR3GuestCtrlProcGetStart: 2 - %Rrc (retry %u, cbCmd=%RU32, cbCwd=%RU32, cbArgs=%RU32, cbEnv=%RU32)\n",
+                        rc, cRetries, pStartupInfo->cbCmd, pStartupInfo->cbCwd, pStartupInfo->cbArgs, pStartupInfo->cbEnv));
                 LogRel(("g_fVbglR3GuestCtrlHavePeekGetCancel=%RTbool\n", RT_BOOL(g_fVbglR3GuestCtrlHavePeekGetCancel)));
             }
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp	(revision 99088)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp	(revision 99120)
@@ -258,4 +258,5 @@
                                       | VBOX_GUESTCTRL_GF_0_PROCESS_ARGV0
                                       | VBOX_GUESTCTRL_GF_0_PROCESS_DYNAMIC_SIZES
+                                      | VBOX_GUESTCTRL_GF_0_PROCESS_CWD
 #ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
                                       | VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp	(revision 99088)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp	(revision 99120)
@@ -1254,4 +1254,6 @@
  * @param   pszPassword                 Password of the specified user.
  * @param   pszDomain                   Domain to use for authentication.
+ * @param   pszCwd                      Current working directory to use for the created process.
+ *                                      Set to NULL if not being used.
  * @param   phProcess                   Pointer which will receive the process handle after
  *                                      successful process start.
@@ -1260,5 +1262,5 @@
                                             PCRTHANDLE phStdIn, PCRTHANDLE phStdOut, PCRTHANDLE phStdErr,
                                             const char *pszAsUser, const char *pszPassword, const char *pszDomain,
-                                            PRTPROCESS phProcess)
+                                            const char *pszCwd, PRTPROCESS phProcess)
 {
 #ifndef RT_OS_WINDOWS
@@ -1272,4 +1274,5 @@
     /* pszPassword is optional. */
     /* pszDomain is optional. */
+    /* pszCwd is optional. */
     AssertPtrReturn(phProcess, VERR_INVALID_PARAMETER);
 
@@ -1411,4 +1414,8 @@
                     fProcCreateFlags |= RTPROC_FLAGS_UNQUOTED_ARGS;
             }
+            if (pszCwd && *pszCwd)
+                fProcCreateFlags |= RTPROC_FLAGS_CWD;
+            else
+                pszCwd = NULL;
 
             /* If no user name specified run with current credentials (e.g.
@@ -1447,5 +1454,5 @@
                                     pszAsUser,
                                     pszPassword && *pszPassword ? pszPassword : NULL,
-                                    NULL /*pvExtraData*/,
+                                    (void *)pszCwd /*pvExtraData*/,
                                     phProcess);
 
@@ -1545,4 +1552,6 @@
     VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: fHostFeatures0       = %#x\n",     g_fControlHostFeatures0);
     VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.szCmd    = '%s'\n",    pProcess->pStartupInfo->pszCmd);
+    VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.szCwd    = '%s'\n",    pProcess->pStartupInfo->pszCwd
+                                                                                        ? pProcess->pStartupInfo->pszCwd : "<None>");
     VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.uNumArgs = '%RU32'\n", pProcess->pStartupInfo->cArgs);
 #ifdef DEBUG /* Never log this stuff in release mode! */
@@ -1678,5 +1687,5 @@
                                                                      fNeedsImpersonation ? pProcess->pStartupInfo->pszPassword : NULL,
                                                                      fNeedsImpersonation ? pProcess->pStartupInfo->pszDomain   : NULL,
-                                                                     &pProcess->hProcess);
+                                                                     pProcess->pStartupInfo->pszCwd, &pProcess->hProcess);
                                     if (RT_FAILURE(rc))
                                         VGSvcError("Error starting process, rc=%Rrc\n", rc);
Index: trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp	(revision 99088)
+++ trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp	(revision 99120)
@@ -1692,8 +1692,9 @@
     if (RT_SUCCESS(rc))
     {
-        VGSvcVerbose(3, "Request to start process szCmd=%s, fFlags=0x%x, szArgs=%s, szEnv=%s, uTimeout=%RU32\n",
+        VGSvcVerbose(3, "Request to start process szCmd=%s, fFlags=0x%x, szArgs=%s, szEnv=%s, szCwd=%s, uTimeout=%RU32\n",
                      pStartupInfo->pszCmd, pStartupInfo->fFlags,
                      pStartupInfo->cArgs    ? pStartupInfo->pszArgs : "<None>",
                      pStartupInfo->cEnvVars ? pStartupInfo->pszEnv  : "<None>",
+                     pStartupInfo->cbCwd    ? pStartupInfo->pszCwd  : "<None>",
                      pStartupInfo->uTimeLimitMS);
 
