Index: /trunk/include/VBox/GuestHost/GuestControl.h
===================================================================
--- /trunk/include/VBox/GuestHost/GuestControl.h	(revision 84146)
+++ /trunk/include/VBox/GuestHost/GuestControl.h	(revision 84147)
@@ -135,5 +135,5 @@
 /** @} */
 
-/** @name Defines for guest process array lengths.
+/** @name Defines for maximum guest process buffer lengths.
  * @{
  */
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp	(revision 84146)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp	(revision 84147)
@@ -395,11 +395,15 @@
      * Retrieve the message parameters.
      */
-    VBOXSERVICECTRLSESSIONSTARTUPINFO ssInfo = { 0 };
-    int rc = VbglR3GuestCtrlSessionGetOpen(pHostCtx,
-                                           &ssInfo.uProtocol,
-                                           ssInfo.szUser,     sizeof(ssInfo.szUser),
-                                           ssInfo.szPassword, sizeof(ssInfo.szPassword),
-                                           ssInfo.szDomain,   sizeof(ssInfo.szDomain),
-                                           &ssInfo.fFlags,    &ssInfo.uSessionID);
+    VBOXSERVICECTRLSESSIONSTARTUPINFO startupInfo;
+    int rc = VgsvcGstCtrlSessionStartupInfoInit(&startupInfo);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    rc = VbglR3GuestCtrlSessionGetOpen(pHostCtx,
+                                       &startupInfo.uProtocol,
+                                       startupInfo.pszUser,     startupInfo.cbUser,
+                                       startupInfo.pszPassword, startupInfo.cbPassword,
+                                       startupInfo.pszDomain,   startupInfo.cbDomain,
+                                       &startupInfo.fFlags,    &startupInfo.uSessionID);
     if (RT_SUCCESS(rc))
     {
@@ -407,16 +411,16 @@
          * Flat out refuse to work with protocol v1 hosts.
          */
-        if (ssInfo.uProtocol == 2)
-        {
-            pHostCtx->uProtocol = ssInfo.uProtocol;
+        if (startupInfo.uProtocol == 2)
+        {
+            pHostCtx->uProtocol = startupInfo.uProtocol;
             VGSvcVerbose(3, "Client ID=%RU32 now is using protocol %RU32\n", pHostCtx->uClientID, pHostCtx->uProtocol);
 
 /** @todo Someone explain why this code isn't in this file too?  v1 support? */
-            rc = VGSvcGstCtrlSessionThreadCreate(&g_lstControlSessionThreads, &ssInfo, NULL /* ppSessionThread */);
+            rc = VGSvcGstCtrlSessionThreadCreate(&g_lstControlSessionThreads, &startupInfo, NULL /* ppSessionThread */);
             /* Report failures to the host (successes are taken care of by the session thread). */
         }
         else
         {
-            VGSvcError("The host wants to use protocol v%u, we only support v2!\n", ssInfo.uProtocol);
+            VGSvcError("The host wants to use protocol v%u, we only support v2!\n", startupInfo.uProtocol);
             rc = VERR_VERSION_MISMATCH;
         }
@@ -433,4 +437,7 @@
         VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     }
+
+    VgsvcGstCtrlSessionStartupInfoDestroy(&startupInfo);
+
     VGSvcVerbose(3, "Opening a new guest session returned rc=%Rrc\n", rc);
     return rc;
@@ -452,5 +459,6 @@
         RTListForEach(&g_lstControlSessionThreads, pThread, VBOXSERVICECTRLSESSIONTHREAD, Node)
         {
-            if (pThread->StartupInfo.uSessionID == idSession)
+            if (   pThread->pStartupInfo
+                && pThread->pStartupInfo->uSessionID == idSession)
             {
                 rc = VGSvcGstCtrlSessionThreadDestroy(pThread, fFlags);
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h	(revision 84146)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h	(revision 84147)
@@ -81,9 +81,15 @@
     uint32_t                        uSessionID;
     /** User name (account) to start the guest session under. */
-    char                            szUser[GUESTPROCESS_MAX_USER_LEN];
+    char                           *pszUser;
+    /** Size (in bytes) of allocated pszUser. */
+    uint32_t                        cbUser;
     /** Password of specified user name (account). */
-    char                            szPassword[GUESTPROCESS_MAX_PASSWORD_LEN];
+    char                           *pszPassword;
+    /** Size (in bytes) of allocated pszPassword. */
+    uint32_t                        cbPassword;
     /** Domain of the user account. */
-    char                            szDomain[GUESTPROCESS_MAX_DOMAIN_LEN];
+    char                           *pszDomain;
+    /** Size (in bytes) of allocated pszDomain. */
+    uint32_t                        cbDomain;
     /** Session creation flags.
      *  @sa VBOXSERVICECTRLSESSIONSTARTUPFLAG_* flags. */
@@ -104,5 +110,6 @@
     RTLISTNODE                      Node;
     /** The sessions's startup info. */
-    VBOXSERVICECTRLSESSIONSTARTUPINFO StartupInfo;
+    PVBOXSERVICECTRLSESSIONSTARTUPINFO
+                                    pStartupInfo;
     /** Critical section for thread-safe use. */
     RTCRITSECT                      CritSect;
@@ -207,25 +214,36 @@
 typedef struct VBOXSERVICECTRLPROCSTARTUPINFO
 {
-    /** Full qualified path of process to start (without arguments). */
-    char szCmd[GUESTPROCESS_MAX_CMD_LEN];
+    /** Full qualified path of process to start (without arguments).
+     *  Note: This is *not* argv[0]! */
+    char *pszCmd;
+    /** Size (in bytes) of allocated pszCmd. */
+    uint32_t cbCmd;
     /** Process execution flags. @sa */
-    uint32_t uFlags;
+    uint32_t fFlags;
     /** Command line arguments. */
-    char szArgs[GUESTPROCESS_MAX_ARGS_LEN];
+    char *pszArgs;
+    /** Size (in bytes) of allocated pszArgs. */
+    uint32_t cbArgs;
     /** Number of arguments specified in pszArgs. */
-    uint32_t uNumArgs;
+    uint32_t cArgs;
     /** String of environment variables ("FOO=BAR") to pass to the process
       * to start. */
-    char szEnv[GUESTPROCESS_MAX_ENV_LEN];
+    char *pszEnv;
     /** Size (in bytes) of environment variables block. */
     uint32_t cbEnv;
     /** Number of environment variables specified in pszEnv. */
-    uint32_t uNumEnvVars;
+    uint32_t cEnvVars;
     /** User name (account) to start the process under. */
-    char szUser[GUESTPROCESS_MAX_USER_LEN];
+    char *pszUser;
+    /** Size (in bytes) of allocated pszUser. */
+    uint32_t cbUser;
     /** Password of specified user name (account). */
-    char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN];
+    char *pszPassword;
+    /** Size (in bytes) of allocated pszPassword. */
+    uint32_t cbPassword;
     /** Domain to be used for authenticating the specified user name (account). */
-    char szDomain[GUESTPROCESS_MAX_DOMAIN_LEN];
+    char *pszDomain;
+    /** Size (in bytes) of allocated pszDomain. */
+    uint32_t cbDomain;
     /** Time limit (in ms) of the process' life time. */
     uint32_t uTimeLimitMS;
@@ -269,6 +287,6 @@
     RTCRITSECT                      CritSect;
     /** Process startup information. */
-    VBOXSERVICECTRLPROCSTARTUPINFO
-                                    StartupInfo;
+    PVBOXSERVICECTRLPROCSTARTUPINFO
+                                    pStartupInfo;
     /** The process' PID assigned by the guest OS. */
     uint32_t                        uPID;
@@ -318,4 +336,7 @@
 /** @name Per-session functions.
  * @{ */
+extern int                      VgsvcGstCtrlSessionStartupInfoInit(PVBOXSERVICECTRLSESSIONSTARTUPINFO pStartupInfo);
+extern void                     VgsvcGstCtrlSessionStartupInfoDestroy(PVBOXSERVICECTRLSESSIONSTARTUPINFO pStartupInfo);
+
 extern PVBOXSERVICECTRLPROCESS  VGSvcGstCtrlSessionRetainProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID);
 extern int                      VGSvcGstCtrlSessionClose(PVBOXSERVICECTRLSESSION pSession);
@@ -330,4 +351,9 @@
 /** @name Per-guest process functions.
  * @{ */
+extern int                      VgsvcGstCtrlProcessStartupInfoInit(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo);
+extern int                      VgsvcGstCtrlProcessStartupInfoInitEx(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo, size_t cbEnv, size_t cbArgs);
+extern void                     VgsvcGstCtrlProcessStartupInfoDestroy(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo);
+extern void                     VgsvcGstCtrlProcessStartupInfoFree(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo);
+
 extern int                      VGSvcGstCtrlProcessFree(PVBOXSERVICECTRLPROCESS pProcess);
 extern int                      VGSvcGstCtrlProcessHandleInput(PVBOXSERVICECTRLPROCESS pProcess, PVBGLR3GUESTCTRLCMDCTX pHostCtx, bool fPendingClose, void *pvBuf, uint32_t cbBuf);
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp	(revision 84146)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp	(revision 84147)
@@ -62,4 +62,146 @@
 
 /**
+ * Initializes a process startup info, extended version.
+ *
+ * @returns VBox status code.
+ * @param   pStartupInfo        Process startup info to initializes.
+ * @param   cbArgs              Size (in bytes) to use for the arguments buffer.
+ * @param   cbEnv               Size (in bytes) to use for the environment buffer.
+ */
+int VgsvcGstCtrlProcessStartupInfoInitEx(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo,
+                                         size_t cbArgs, size_t cbEnv)
+{
+    AssertPtrReturn(pStartupInfo, VERR_INVALID_POINTER);
+    AssertReturn(cbArgs,          VERR_INVALID_PARAMETER);
+    AssertReturn(cbEnv,           VERR_INVALID_PARAMETER);
+
+    RT_BZERO(pStartupInfo, sizeof(VBOXSERVICECTRLPROCSTARTUPINFO));
+
+#define ALLOC_STR(a_Str, a_cb) \
+    if ((a_cb) > 0) \
+    { \
+        pStartupInfo->psz##a_Str = RTStrAlloc(a_cb); \
+        AssertPtrBreak(pStartupInfo->psz##a_Str); \
+        pStartupInfo->cb##a_Str  = a_cb; \
+    }
+
+    do
+    {
+        ALLOC_STR(Cmd,      sizeof(char) * GUESTPROCESS_MAX_CMD_LEN);
+        ALLOC_STR(Args,     cbArgs);
+        ALLOC_STR(Env,      cbEnv);
+        ALLOC_STR(User,     sizeof(char) * GUESTPROCESS_MAX_USER_LEN);
+        ALLOC_STR(Password, sizeof(char) * GUESTPROCESS_MAX_PASSWORD_LEN);
+        ALLOC_STR(Domain,   sizeof(char) * GUESTPROCESS_MAX_DOMAIN_LEN);
+
+        return VINF_SUCCESS;
+
+    } while (0);
+
+#undef ALLOC_STR
+
+    VgsvcGstCtrlProcessStartupInfoDestroy(pStartupInfo);
+    return VERR_NO_MEMORY;
+}
+
+/**
+ * Initializes a process startup info with default values.
+ *
+ * @param   pStartupInfo        Process startup info to initializes.
+ */
+int VgsvcGstCtrlProcessStartupInfoInit(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo)
+{
+    return VgsvcGstCtrlProcessStartupInfoInitEx(pStartupInfo,
+                                                GUESTPROCESS_MAX_ARGS_LEN, GUESTPROCESS_MAX_ENV_LEN);
+}
+
+/**
+ * Destroys a process startup info.
+ *
+ * @param   pStartupInfo        Process startup info to destroy.
+ */
+void VgsvcGstCtrlProcessStartupInfoDestroy(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo)
+{
+    if (!pStartupInfo)
+        return;
+
+    RTStrFree(pStartupInfo->pszCmd);
+    RTStrFree(pStartupInfo->pszArgs);
+    RTStrFree(pStartupInfo->pszEnv);
+    RTStrFree(pStartupInfo->pszUser);
+    RTStrFree(pStartupInfo->pszPassword);
+    RTStrFree(pStartupInfo->pszDomain);
+
+    RT_BZERO(pStartupInfo, sizeof(VBOXSERVICECTRLPROCSTARTUPINFO));
+}
+
+/**
+ * Free's a process startup info.
+ *
+ * @param   pStartupInfo        Process startup info to free.
+ *                              The pointer will not be valid anymore after return.
+ */
+void VgsvcGstCtrlProcessStartupInfoFree(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo)
+{
+    if (!pStartupInfo)
+        return;
+
+    VgsvcGstCtrlProcessStartupInfoDestroy(pStartupInfo);
+
+    RTMemFree(pStartupInfo);
+    pStartupInfo = NULL;
+}
+
+/**
+ * Duplicates a process startup info.
+ *
+ * @returns Duplicated process startup info on success, or NULL on error.
+ * @param   pStartupInfo        Process startup info to duplicate.
+ */
+static PVBOXSERVICECTRLPROCSTARTUPINFO vgsvcGstCtrlProcessStartupInfoDup(PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfo)
+{
+    AssertPtrReturn(pStartupInfo, NULL);
+
+    PVBOXSERVICECTRLPROCSTARTUPINFO pStartupInfoDup = (PVBOXSERVICECTRLPROCSTARTUPINFO)
+                                                            RTMemDup(pStartupInfo, sizeof(VBOXSERVICECTRLPROCSTARTUPINFO));
+    if (pStartupInfoDup)
+    {
+        do
+        {
+            pStartupInfoDup->pszCmd      = NULL;
+            pStartupInfoDup->pszArgs     = NULL;
+            pStartupInfoDup->pszEnv      = NULL;
+            pStartupInfoDup->pszUser     = NULL;
+            pStartupInfoDup->pszPassword = NULL;
+            pStartupInfoDup->pszDomain   = NULL;
+
+#define DUP_STR(a_Str) \
+    if (pStartupInfo->cb##a_Str) \
+    { \
+        pStartupInfoDup->psz##a_Str = (char *)RTMemDup(pStartupInfo->psz##a_Str, pStartupInfo->cb##a_Str); \
+        AssertPtrBreak(pStartupInfoDup->psz##a_Str); \
+        pStartupInfoDup->cb##a_Str  = pStartupInfo->cb##a_Str; \
+    }
+
+            DUP_STR(Cmd);
+            DUP_STR(Args);
+            DUP_STR(Env);
+            DUP_STR(User);
+            DUP_STR(Password);
+            DUP_STR(Domain);
+
+#undef DUP_STR
+
+            return pStartupInfoDup;
+
+        } while (0); /* To use break macros above. */
+
+        VgsvcGstCtrlProcessStartupInfoFree(pStartupInfoDup);
+    }
+
+    return NULL;
+}
+
+/**
  * Initialies the passed in thread data structure with the parameters given.
  *
@@ -117,11 +259,12 @@
     AssertReleaseRC(rc);
 
-    /* Copy over startup info. */
-    memcpy(&pProcess->StartupInfo, pStartupInfo, sizeof(VBOXSERVICECTRLPROCSTARTUPINFO));
+    /* Duplicate startup info. */
+    pProcess->pStartupInfo = vgsvcGstCtrlProcessStartupInfoDup(pStartupInfo);
+    AssertPtrReturn(pProcess->pStartupInfo, VERR_NO_MEMORY);
 
     /* Adjust timeout value. */
-    if (   pProcess->StartupInfo.uTimeLimitMS == UINT32_MAX
-        || pProcess->StartupInfo.uTimeLimitMS == 0)
-        pProcess->StartupInfo.uTimeLimitMS = RT_INDEFINITE_WAIT;
+    if (   pProcess->pStartupInfo->uTimeLimitMS == UINT32_MAX
+        || pProcess->pStartupInfo->uTimeLimitMS == 0)
+        pProcess->pStartupInfo->uTimeLimitMS = RT_INDEFINITE_WAIT;
 
     if (RT_FAILURE(rc)) /* Clean up on failure. */
@@ -151,4 +294,7 @@
         AssertReturn(pProcess->fStopped, VERR_WRONG_ORDER);
         AssertReturn(pProcess->fShutdown, VERR_WRONG_ORDER);
+
+        VgsvcGstCtrlProcessStartupInfoFree(pProcess->pStartupInfo);
+        pProcess->pStartupInfo = NULL;
 
         /*
@@ -527,6 +673,6 @@
      */
     VGSvcVerbose(2, "[PID %RU32]: Process '%s' started, CID=%u, User=%s, cMsTimeout=%RU32\n",
-                       pProcess->uPID, pProcess->StartupInfo.szCmd, pProcess->uContextID,
-                       pProcess->StartupInfo.szUser, pProcess->StartupInfo.uTimeLimitMS);
+                       pProcess->uPID, pProcess->pStartupInfo->pszCmd, pProcess->uContextID,
+                       pProcess->pStartupInfo->pszUser, pProcess->pStartupInfo->uTimeLimitMS);
     VBGLR3GUESTCTRLCMDCTX ctxStart = { g_idControlSvcClient, pProcess->uContextID };
     rc = VbglR3GuestCtrlProcCbStatus(&ctxStart,
@@ -670,10 +816,10 @@
          */
         uint32_t cMilliesLeft = RT_INDEFINITE_WAIT;
-        if (   pProcess->StartupInfo.uTimeLimitMS != RT_INDEFINITE_WAIT
-            && pProcess->StartupInfo.uTimeLimitMS != 0)
+        if (   pProcess->pStartupInfo->uTimeLimitMS != RT_INDEFINITE_WAIT
+            && pProcess->pStartupInfo->uTimeLimitMS != 0)
         {
             uint64_t u64Now = RTTimeMilliTS();
             uint64_t cMsElapsed = u64Now - uMsStart;
-            if (cMsElapsed >= pProcess->StartupInfo.uTimeLimitMS)
+            if (cMsElapsed >= pProcess->pStartupInfo->uTimeLimitMS)
             {
                 fProcessTimedOut = true;
@@ -685,5 +831,5 @@
 
                     VGSvcVerbose(3, "[PID %RU32]: Timed out (%RU64ms elapsed > %RU32ms timeout), killing ...\n",
-                                 pProcess->uPID, cMsElapsed, pProcess->StartupInfo.uTimeLimitMS);
+                                 pProcess->uPID, cMsElapsed, pProcess->pStartupInfo->uTimeLimitMS);
 
                     rc2 = RTProcTerminate(pProcess->hProcess);
@@ -696,5 +842,5 @@
             }
             else
-                cMilliesLeft = pProcess->StartupInfo.uTimeLimitMS - (uint32_t)cMsElapsed;
+                cMilliesLeft = pProcess->pStartupInfo->uTimeLimitMS - (uint32_t)cMsElapsed;
         }
 
@@ -816,5 +962,5 @@
             VGSvcVerbose(3, "[PID %RU32]: Got terminated because system/service is about to shutdown\n", pProcess->uPID);
             uStatus = PROC_STS_DWN; /* Service is stopping, process was killed. */
-            fFlags  = pProcess->StartupInfo.uFlags; /* Return handed-in execution flags back to the host. */
+            fFlags  = pProcess->pStartupInfo->fFlags; /* Return handed-in execution flags back to the host. */
         }
         else if (fProcessAlive)
@@ -1507,7 +1653,7 @@
 {
     AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
-    VGSvcVerbose(3, "Thread of process pThread=0x%p = '%s' started\n", pProcess, pProcess->StartupInfo.szCmd);
-
-    VGSvcVerbose(3, "Guest process '%s', flags=0x%x\n", pProcess->StartupInfo.szCmd, pProcess->StartupInfo.uFlags);
+    VGSvcVerbose(3, "Thread of process pThread=0x%p = '%s' started\n", pProcess, pProcess->pStartupInfo->pszCmd);
+
+    VGSvcVerbose(3, "Guest process '%s', flags=0x%x\n", pProcess->pStartupInfo->pszCmd, pProcess->pStartupInfo->fFlags);
 
     int rc = VGSvcGstCtrlSessionProcessAdd(pProcess->pSession, pProcess);
@@ -1515,5 +1661,5 @@
     {
         VGSvcError("Error while adding guest process '%s' (%p) to session process list, rc=%Rrc\n",
-                   pProcess->StartupInfo.szCmd, pProcess, rc);
+                   pProcess->pStartupInfo->pszCmd, pProcess, rc);
         RTThreadUserSignal(RTThreadSelf());
         return rc;
@@ -1526,8 +1672,8 @@
      */
     VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: fHostFeatures0       = %#x\n",     g_fControlHostFeatures0);
-    VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.szCmd    = '%s'\n",    pProcess->StartupInfo.szCmd);
-    VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.uNumArgs = '%RU32'\n", pProcess->StartupInfo.uNumArgs);
+    VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.szCmd    = '%s'\n",    pProcess->pStartupInfo->pszCmd);
+    VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.uNumArgs = '%RU32'\n", pProcess->pStartupInfo->cArgs);
 #ifdef DEBUG /* Never log this stuff in release mode! */
-    VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.szArgs   = '%s'\n",    pProcess->StartupInfo.szArgs);
+    VGSvcVerbose(3, "vgsvcGstCtrlProcessProcessWorker: StartupInfo.szArgs   = '%s'\n",    pProcess->pStartupInfo->pszArgs);
 #endif
 
@@ -1535,5 +1681,5 @@
     int cArgs = 0; /* Initialize in case of RTGetOptArgvFromString() is failing ... */
     rc = RTGetOptArgvFromString(&papszArgs, &cArgs,
-                                pProcess->StartupInfo.uNumArgs > 0 ? pProcess->StartupInfo.szArgs : "",
+                                pProcess->pStartupInfo->cArgs > 0 ? pProcess->pStartupInfo->pszArgs : "",
                                 RTGETOPTARGV_CNV_QUOTE_BOURNE_SH, NULL);
 
@@ -1548,7 +1694,7 @@
     /* Did we get the same result?
      * Take into account that we might not have supplied a (correct) argv[0] from the host. */
-    AssertMsg((int)pProcess->StartupInfo.uNumArgs == cArgsToCheck,
+    AssertMsg((int)pProcess->pStartupInfo->cArgs == cArgsToCheck,
               ("rc=%Rrc, StartupInfo.uNumArgs=%RU32 != cArgsToCheck=%d, cArgs=%d, fHostFeatures0=%#x\n",
-               rc, pProcess->StartupInfo.uNumArgs, cArgsToCheck, cArgs, g_fControlHostFeatures0));
+               rc, pProcess->pStartupInfo->cArgs, cArgsToCheck, cArgs, g_fControlHostFeatures0));
 #endif
 
@@ -1556,8 +1702,8 @@
      * Create the environment.
      */
-    uint32_t const cbEnv = pProcess->StartupInfo.cbEnv;
+    uint32_t const cbEnv = pProcess->pStartupInfo->cbEnv;
     if (RT_SUCCESS(rc))
-        AssertStmt(   cbEnv <= sizeof(pProcess->StartupInfo.szEnv)
-                   || pProcess->StartupInfo.uNumEnvVars == 0,
+        AssertStmt(   cbEnv <= GUESTPROCESS_MAX_ENV_LEN
+                   || pProcess->pStartupInfo->cEnvVars == 0,
                    rc = VERR_INVALID_PARAMETER);
     if (RT_SUCCESS(rc))
@@ -1568,7 +1714,7 @@
         {
             VGSvcVerbose(3, "Additional environment variables: %RU32 (%RU32 bytes)\n",
-                         pProcess->StartupInfo.uNumEnvVars, cbEnv);
-
-            if (   pProcess->StartupInfo.uNumEnvVars /** @todo r=bird: s/uNumEnvVars/cEnvVars/g */
+                         pProcess->pStartupInfo->cEnvVars, cbEnv);
+
+            if (   pProcess->pStartupInfo->cEnvVars
                 && cbEnv > 0)
             {
@@ -1576,5 +1722,5 @@
                 while (offCur < cbEnv)
                 {
-                    const char * const pszCur = &pProcess->StartupInfo.szEnv[offCur];
+                    const char * const pszCur = &pProcess->pStartupInfo->pszEnv[offCur];
                     size_t const       cchCur = RTStrNLen(pszCur, cbEnv - offCur);
                     AssertBreakStmt(cchCur < cbEnv - offCur, rc = VERR_INVALID_PARAMETER);
@@ -1605,5 +1751,5 @@
                     RTHANDLE    hStdOut;
                     PRTHANDLE   phStdOut;
-                    rc = vgsvcGstCtrlProcessSetupPipe(  (pProcess->StartupInfo.uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT)
+                    rc = vgsvcGstCtrlProcessSetupPipe(  (pProcess->pStartupInfo->fFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT)
                                                  ? "|" : "/dev/null",
                                                  1 /*STDOUT_FILENO*/,
@@ -1613,5 +1759,5 @@
                         RTHANDLE    hStdErr;
                         PRTHANDLE   phStdErr;
-                        rc = vgsvcGstCtrlProcessSetupPipe(  (pProcess->StartupInfo.uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR)
+                        rc = vgsvcGstCtrlProcessSetupPipe(  (pProcess->pStartupInfo->fFlags & EXECUTEPROCESSFLAG_WAIT_STDERR)
                                                      ? "|" : "/dev/null",
                                                      2 /*STDERR_FILENO*/,
@@ -1654,10 +1800,10 @@
                                     bool fNeedsImpersonation = !(pProcess->pSession->fFlags & VBOXSERVICECTRLSESSION_FLAG_SPAWN);
 
-                                    rc = vgsvcGstCtrlProcessCreateProcess(pProcess->StartupInfo.szCmd, papszArgs, hEnv,
-                                                                     pProcess->StartupInfo.uFlags,
+                                    rc = vgsvcGstCtrlProcessCreateProcess(pProcess->pStartupInfo->pszCmd, papszArgs, hEnv,
+                                                                     pProcess->pStartupInfo->fFlags,
                                                                      phStdIn, phStdOut, phStdErr,
-                                                                     fNeedsImpersonation ? pProcess->StartupInfo.szUser     : NULL,
-                                                                     fNeedsImpersonation ? pProcess->StartupInfo.szPassword : NULL,
-                                                                     fNeedsImpersonation ? pProcess->StartupInfo.szDomain   : NULL,
+                                                                     fNeedsImpersonation ? pProcess->pStartupInfo->pszUser     : NULL,
+                                                                     fNeedsImpersonation ? pProcess->pStartupInfo->pszPassword : NULL,
+                                                                     fNeedsImpersonation ? pProcess->pStartupInfo->pszDomain   : NULL,
                                                                      &pProcess->hProcess);
                                     if (RT_FAILURE(rc))
@@ -1772,5 +1918,5 @@
 
     VGSvcVerbose(3, "[PID %RU32]: Thread of process '%s' ended with rc=%Rrc (fSignalled=%RTbool)\n",
-                 pProcess->uPID, pProcess->StartupInfo.szCmd, rc, fSignalled);
+                 pProcess->uPID, pProcess->pStartupInfo->pszCmd, rc, fSignalled);
 
     return rc;
@@ -1845,5 +1991,5 @@
         {
             VGSvcError("Creating thread for guest process '%s' failed: rc=%Rrc, pProcess=%p\n",
-                       pStartupInfo->szCmd, rc, pProcess);
+                       pStartupInfo->pszCmd, rc, pProcess);
 
             VGSvcGstCtrlProcessFree(pProcess);
@@ -1860,5 +2006,5 @@
                 || RT_FAILURE(rc))
             {
-                VGSvcError("Thread for process '%s' failed to start, rc=%Rrc\n", pStartupInfo->szCmd, rc);
+                VGSvcError("Thread for process '%s' failed to start, rc=%Rrc\n", pStartupInfo->pszCmd, rc);
                 int rc2 = RTThreadWait(pProcess->Thread, RT_MS_1SEC * 30, NULL);
                 if (RT_SUCCESS(rc2))
Index: /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
===================================================================
--- /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp	(revision 84146)
+++ /trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp	(revision 84147)
@@ -1026,4 +1026,116 @@
 }
 
+/**
+ * Initializes a session startup info.
+ *
+ * @returns VBox status code.
+ * @param   pStartupInfo        Session startup info to initializes.
+ */
+int VgsvcGstCtrlSessionStartupInfoInit(PVBOXSERVICECTRLSESSIONSTARTUPINFO pStartupInfo)
+{
+    AssertPtrReturn(pStartupInfo, VERR_INVALID_POINTER);
+
+    RT_BZERO(pStartupInfo, sizeof(VBOXSERVICECTRLSESSIONSTARTUPINFO));
+
+#define ALLOC_STR(a_Str, a_cb) \
+    if ((a_cb) > 0) \
+    { \
+        pStartupInfo->psz##a_Str = RTStrAlloc(a_cb); \
+        AssertPtrBreak(pStartupInfo->psz##a_Str); \
+        pStartupInfo->cb##a_Str  = a_cb; \
+    }
+
+    do
+    {
+        ALLOC_STR(User,     sizeof(char) * GUESTPROCESS_MAX_USER_LEN);
+        ALLOC_STR(Password, sizeof(char) * GUESTPROCESS_MAX_PASSWORD_LEN);
+        ALLOC_STR(Domain,   sizeof(char) * GUESTPROCESS_MAX_DOMAIN_LEN);
+
+        return VINF_SUCCESS;
+
+    } while (0);
+
+#undef ALLOC_STR
+
+    VgsvcGstCtrlSessionStartupInfoDestroy(pStartupInfo);
+    return VERR_NO_MEMORY;
+}
+
+/**
+ * Destroys a session startup info.
+ *
+ * @param   pStartupInfo        Session startup info to destroy.
+ */
+void VgsvcGstCtrlSessionStartupInfoDestroy(PVBOXSERVICECTRLSESSIONSTARTUPINFO pStartupInfo)
+{
+    if (!pStartupInfo)
+        return;
+
+    RTStrFree(pStartupInfo->pszUser);
+    RTStrFree(pStartupInfo->pszPassword);
+    RTStrFree(pStartupInfo->pszDomain);
+
+    RT_BZERO(pStartupInfo, sizeof(VBOXSERVICECTRLSESSIONSTARTUPINFO));
+}
+
+/**
+ * Free's a session startup info.
+ *
+ * @param   pStartupInfo        Session startup info to free.
+ *                              The pointer will not be valid anymore after return.
+ */
+static void vgsvcGstCtrlSessionStartupInfoFree(PVBOXSERVICECTRLSESSIONSTARTUPINFO pStartupInfo)
+{
+    if (!pStartupInfo)
+        return;
+
+    VgsvcGstCtrlSessionStartupInfoDestroy(pStartupInfo);
+
+    RTMemFree(pStartupInfo);
+    pStartupInfo = NULL;
+}
+
+/**
+ * Duplicates a session startup info.
+ *
+ * @returns Duplicated session startup info on success, or NULL on error.
+ * @param   pStartupInfo        Session startup info to duplicate.
+ */
+static PVBOXSERVICECTRLSESSIONSTARTUPINFO vgsvcGstCtrlSessionStartupInfoDup(PVBOXSERVICECTRLSESSIONSTARTUPINFO pStartupInfo)
+{
+    AssertPtrReturn(pStartupInfo, NULL);
+
+    PVBOXSERVICECTRLSESSIONSTARTUPINFO pStartupInfoDup = (PVBOXSERVICECTRLSESSIONSTARTUPINFO)
+                                                                RTMemDup(pStartupInfo, sizeof(VBOXSERVICECTRLSESSIONSTARTUPINFO));
+    if (pStartupInfoDup)
+    {
+        do
+        {
+            pStartupInfoDup->pszUser     = NULL;
+            pStartupInfoDup->pszPassword = NULL;
+            pStartupInfoDup->pszDomain   = NULL;
+
+#define DUP_STR(a_Str) \
+    if (pStartupInfo->cb##a_Str) \
+    { \
+        pStartupInfoDup->psz##a_Str = (char *)RTMemDup(pStartupInfo->psz##a_Str, pStartupInfo->cb##a_Str); \
+        AssertPtrBreak(pStartupInfoDup->psz##a_Str); \
+        pStartupInfoDup->cb##a_Str  = pStartupInfo->cb##a_Str; \
+    }
+            DUP_STR(User);
+            DUP_STR(Password);
+            DUP_STR(Domain);
+
+#undef DUP_STR
+
+            return pStartupInfoDup;
+
+        } while (0); /* To use break macros above. */
+
+        vgsvcGstCtrlSessionStartupInfoFree(pStartupInfoDup);
+    }
+
+    return NULL;
+}
 
 /**
@@ -1045,33 +1157,34 @@
      * will contain the actual block size. */
     VBOXSERVICECTRLPROCSTARTUPINFO startupInfo;
-    RT_ZERO(startupInfo);
-    startupInfo.cbEnv = sizeof(startupInfo.szEnv);
-
-    int rc = VbglR3GuestCtrlProcGetStart(pHostCtx,
-                                         /* Command */
-                                         startupInfo.szCmd,      sizeof(startupInfo.szCmd),
-                                         /* Flags */
-                                         &startupInfo.uFlags,
-                                         /* Arguments */
-                                         startupInfo.szArgs,     sizeof(startupInfo.szArgs),    &startupInfo.uNumArgs,
-                                         /* Environment */
-                                         startupInfo.szEnv,      &startupInfo.cbEnv,            &startupInfo.uNumEnvVars,
-                                         /* Credentials; for hosts with VBox < 4.3 (protocol version 1).
-                                          * For protocol v2 and up the credentials are part of the session
-                                          * opening call. */
-                                         startupInfo.szUser,     sizeof(startupInfo.szUser),
-                                         startupInfo.szPassword, sizeof(startupInfo.szPassword),
-                                         /* Timeout (in ms) */
-                                         &startupInfo.uTimeLimitMS,
-                                         /* Process priority */
-                                         &startupInfo.uPriority,
-                                         /* Process affinity */
-                                         startupInfo.uAffinity,  sizeof(startupInfo.uAffinity), &startupInfo.uNumAffinity);
+    int rc = VgsvcGstCtrlProcessStartupInfoInit(&startupInfo);
+    if (RT_FAILURE(rc))
+        return rc;
+
+    rc = VbglR3GuestCtrlProcGetStart(pHostCtx,
+                                     /* Command */
+                                     startupInfo.pszCmd,      startupInfo.cbCmd,
+                                     /* Flags */
+                                     &startupInfo.fFlags,
+                                     /* Arguments */
+                                     startupInfo.pszArgs,     startupInfo.cbArgs,     &startupInfo.cArgs,
+                                     /* Environment */
+                                     startupInfo.pszEnv,      &startupInfo.cbEnv,     &startupInfo.cEnvVars,
+                                     /* Credentials; for hosts with VBox < 4.3 (protocol version 1).
+                                      * For protocol v2 and up the credentials are part of the session
+                                      * opening call. */
+                                     startupInfo.pszUser,     startupInfo.cbUser,
+                                     startupInfo.pszPassword, startupInfo.cbPassword,
+                                     /* Timeout (in ms) */
+                                     &startupInfo.uTimeLimitMS,
+                                     /* Process priority */
+                                     &startupInfo.uPriority,
+                                     /* Process affinity */
+                                     startupInfo.uAffinity,  sizeof(startupInfo.uAffinity), &startupInfo.uNumAffinity);
     if (RT_SUCCESS(rc))
     {
         VGSvcVerbose(3, "Request to start process szCmd=%s, fFlags=0x%x, szArgs=%s, szEnv=%s, uTimeout=%RU32\n",
-                     startupInfo.szCmd, startupInfo.uFlags,
-                     startupInfo.uNumArgs ? startupInfo.szArgs : "<None>",
-                     startupInfo.uNumEnvVars ? startupInfo.szEnv : "<None>",
+                     startupInfo.pszCmd, startupInfo.fFlags,
+                     startupInfo.cArgs ? startupInfo.pszArgs : "<None>",
+                     startupInfo.cEnvVars ? startupInfo.pszEnv : "<None>",
                      startupInfo.uTimeLimitMS);
 
@@ -1103,4 +1216,7 @@
         VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     }
+
+    VgsvcGstCtrlProcessStartupInfoDestroy(&startupInfo);
+
     return rc;
 }
@@ -1465,5 +1581,5 @@
     AssertPtrReturn(pThread, VERR_INVALID_POINTER);
 
-    uint32_t const idSession = pThread->StartupInfo.uSessionID;
+    uint32_t const idSession = pThread->pStartupInfo->uSessionID;
     uint32_t const idClient  = g_idControlSvcClient;
     VGSvcVerbose(3, "Session ID=%RU32 thread running\n", idSession);
@@ -1518,5 +1634,5 @@
                     /* .idClient  = */  idClient,
                     /* .idContext = */  VBOX_GUESTCTRL_CONTEXTID_MAKE_SESSION(idSession),
-                    /* .uProtocol = */  pThread->StartupInfo.uProtocol,
+                    /* .uProtocol = */  pThread->pStartupInfo->uProtocol,
                     /* .cParams   = */  2
                 };
@@ -2180,9 +2296,10 @@
      * privileges as the main VBoxService executable.
      */
-    bool const fAnonymous = pSessionThread->StartupInfo.szUser[0] == '\0';
+    bool const fAnonymous =    pSessionThread->pStartupInfo->pszUser
+                            && pSessionThread->pStartupInfo->pszUser[0] == '\0';
     if (fAnonymous)
     {
-        Assert(!strlen(pSessionThread->StartupInfo.szPassword));
-        Assert(!strlen(pSessionThread->StartupInfo.szDomain));
+        Assert(!strlen(pSessionThread->pStartupInfo->pszPassword));
+        Assert(!strlen(pSessionThread->pStartupInfo->pszDomain));
 
         VGSvcVerbose(3, "New anonymous guest session ID=%RU32 created, fFlags=%x, using protocol %RU32\n",
@@ -2195,11 +2312,11 @@
         VGSvcVerbose(3, "Spawning new guest session ID=%RU32, szUser=%s, szPassword=%s, szDomain=%s, fFlags=%x, using protocol %RU32\n",
                      pSessionStartupInfo->uSessionID,
-                     pSessionStartupInfo->szUser,
+                     pSessionStartupInfo->pszUser,
 #ifdef DEBUG
-                     pSessionStartupInfo->szPassword,
+                     pSessionStartupInfo->pszPassword,
 #else
                      "XXX", /* Never show passwords in release mode. */
 #endif
-                     pSessionStartupInfo->szDomain,
+                     pSessionStartupInfo->pszDomain,
                      pSessionStartupInfo->fFlags,
                      pSessionStartupInfo->uProtocol);
@@ -2215,9 +2332,9 @@
 
     char szParmSessionID[32];
-    RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32", pSessionThread->StartupInfo.uSessionID);
+    RTStrPrintf(szParmSessionID, sizeof(szParmSessionID), "--session-id=%RU32", pSessionThread->pStartupInfo->uSessionID);
 
     char szParmSessionProto[32];
     RTStrPrintf(szParmSessionProto, sizeof(szParmSessionProto), "--session-proto=%RU32",
-                pSessionThread->StartupInfo.uProtocol);
+                pSessionThread->pStartupInfo->uProtocol);
 #ifdef DEBUG
     char szParmThreadId[32];
@@ -2237,10 +2354,10 @@
     {
         apszArgs[idxArg++] = "--user";
-        apszArgs[idxArg++] = pSessionThread->StartupInfo.szUser;
-
-        if (strlen(pSessionThread->StartupInfo.szDomain))
+        apszArgs[idxArg++] = pSessionThread->pStartupInfo->pszUser;
+
+        if (strlen(pSessionThread->pStartupInfo->pszDomain))
         {
             apszArgs[idxArg++] = "--domain";
-            apszArgs[idxArg++] = pSessionThread->StartupInfo.szDomain;
+            apszArgs[idxArg++] = pSessionThread->pStartupInfo->pszDomain;
         }
     }
@@ -2290,9 +2407,9 @@
 #ifndef DEBUG
         RTStrPrintf(szParmLogFile, sizeof(szParmLogFile), "%.*s-%RU32-%s-%s%s",
-                    cchBase, g_szLogFile, pSessionStartupInfo->uSessionID, pSessionStartupInfo->szUser, szTime, pszSuffix);
+                    cchBase, g_szLogFile, pSessionStartupInfo->uSessionID, pSessionStartupInfo->pszUser, szTime, pszSuffix);
 #else
         RTStrPrintf(szParmLogFile, sizeof(szParmLogFile), "%.*s-%RU32-%RU32-%s-%s%s",
                     cchBase, g_szLogFile, pSessionStartupInfo->uSessionID, uCtrlSessionThread,
-                    pSessionStartupInfo->szUser, szTime, pszSuffix);
+                    pSessionStartupInfo->pszUser, szTime, pszSuffix);
 #endif
         apszArgs[idxArg++] = "--logfile";
@@ -2345,12 +2462,12 @@
              *          with the domain name built-in, e.g. "joedoe@example.com".
              */
-            const char *pszUser    = pSessionThread->StartupInfo.szUser;
+            const char *pszUser    = pSessionThread->pStartupInfo->pszUser;
 #ifdef RT_OS_WINDOWS
             char       *pszUserUPN = NULL;
-            if (pSessionThread->StartupInfo.szDomain[0])
+            if (pSessionThread->pStartupInfo->pszDomain[0])
             {
                 int cchbUserUPN = RTStrAPrintf(&pszUserUPN, "%s@%s",
-                                               pSessionThread->StartupInfo.szUser,
-                                               pSessionThread->StartupInfo.szDomain);
+                                               pSessionThread->pStartupInfo->pszUser,
+                                               pSessionThread->pStartupInfo->pszDomain);
                 if (cchbUserUPN > 0)
                 {
@@ -2370,5 +2487,5 @@
                                     &hStdIn, &hStdOutAndErr, &hStdOutAndErr,
                                     !fAnonymous ? pszUser : NULL,
-                                    !fAnonymous ? pSessionThread->StartupInfo.szPassword : NULL,
+                                    !fAnonymous ? pSessionThread->pStartupInfo->pszPassword : NULL,
                                     NULL /*pvExtraData*/,
                                     &pSessionThread->hProcess);
@@ -2413,7 +2530,7 @@
     {
         AssertMsgReturn(   pSessionCur->fStopped == true
-                        || pSessionCur->StartupInfo.uSessionID != pSessionStartupInfo->uSessionID,
+                        || pSessionCur->pStartupInfo->uSessionID != pSessionStartupInfo->uSessionID,
                         ("Guest session thread ID=%RU32 already exists (fStopped=%RTbool)\n",
-                         pSessionCur->StartupInfo.uSessionID, pSessionCur->fStopped), VERR_ALREADY_EXISTS);
+                         pSessionCur->pStartupInfo->uSessionID, pSessionCur->fStopped), VERR_ALREADY_EXISTS);
     }
 #endif
@@ -2436,6 +2553,7 @@
         pSessionThread->hProcess  = NIL_RTPROCESS;
 
-        /* Copy over session startup info. */
-        memcpy(&pSessionThread->StartupInfo, pSessionStartupInfo, sizeof(VBOXSERVICECTRLSESSIONSTARTUPINFO));
+        /* Duplicate startup info. */
+        pSessionThread->pStartupInfo = vgsvcGstCtrlSessionStartupInfoDup(pSessionStartupInfo);
+        AssertPtrReturn(pSessionThread->pStartupInfo, VERR_NO_MEMORY);
 
         /* Generate the secret key. */
@@ -2482,5 +2600,5 @@
                             && !ASMAtomicReadBool(&pSessionThread->fShutdown))
                         {
-                            VGSvcVerbose(2, "Thread for session ID=%RU32 started\n", pSessionThread->StartupInfo.uSessionID);
+                            VGSvcVerbose(2, "Thread for session ID=%RU32 started\n", pSessionThread->pStartupInfo->uSessionID);
 
                             ASMAtomicXchgBool(&pSessionThread->fStarted, true);
@@ -2497,5 +2615,5 @@
                          */
                         VGSvcError("Thread for session ID=%RU32 failed to start, rc=%Rrc\n",
-                                   pSessionThread->StartupInfo.uSessionID, rc);
+                                   pSessionThread->pStartupInfo->uSessionID, rc);
                         if (RT_SUCCESS_NP(rc))
                             rc = VERR_CANT_CREATE; /** @todo Find a better rc. */
@@ -2563,5 +2681,5 @@
 
         VGSvcVerbose(3, "Waiting for session thread ID=%RU32 to close (%RU32ms) ...\n",
-                     pThread->StartupInfo.uSessionID, uTimeoutMS);
+                     pThread->pStartupInfo->uSessionID, uTimeoutMS);
 
         int rcThread;
@@ -2570,13 +2688,13 @@
         {
             AssertMsg(pThread->fStopped, ("Thread of session ID=%RU32 not in stopped state when it should\n",
-                      pThread->StartupInfo.uSessionID));
-
-            VGSvcVerbose(3, "Session thread ID=%RU32 ended with rc=%Rrc\n", pThread->StartupInfo.uSessionID, rcThread);
+                      pThread->pStartupInfo->uSessionID));
+
+            VGSvcVerbose(3, "Session thread ID=%RU32 ended with rc=%Rrc\n", pThread->pStartupInfo->uSessionID, rcThread);
         }
         else
-            VGSvcError("Waiting for session thread ID=%RU32 to close failed with rc=%Rrc\n", pThread->StartupInfo.uSessionID, rc);
+            VGSvcError("Waiting for session thread ID=%RU32 to close failed with rc=%Rrc\n", pThread->pStartupInfo->uSessionID, rc);
     }
     else
-        VGSvcVerbose(3, "Thread for session ID=%RU32 not in started state, skipping wait\n", pThread->StartupInfo.uSessionID);
+        VGSvcVerbose(3, "Thread for session ID=%RU32 not in started state, skipping wait\n", pThread->pStartupInfo->uSessionID);
 
     LogFlowFuncLeaveRC(rc);
@@ -2595,6 +2713,7 @@
 {
     AssertPtrReturn(pThread, VERR_INVALID_POINTER);
-
-    const uint32_t uSessionID = pThread->StartupInfo.uSessionID;
+    AssertPtrReturn(pThread->pStartupInfo, VERR_WRONG_ORDER);
+
+    const uint32_t uSessionID = pThread->pStartupInfo->uSessionID;
 
     VGSvcVerbose(3, "Destroying session ID=%RU32 ...\n", uSessionID);
@@ -2603,4 +2722,7 @@
     if (RT_SUCCESS(rc))
     {
+        vgsvcGstCtrlSessionStartupInfoFree(pThread->pStartupInfo);
+        pThread->pStartupInfo = NULL;
+
         /* Remove session from list and destroy object. */
         RTListNodeRemove(&pThread->Node);
