VirtualBox

Changeset 44863 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Feb 28, 2013 12:18:17 PM (12 years ago)
Author:
vboxsync
Message:

GuestCtrl: Infrastructure changes for handling and executing dedicated guest sessions and protocol versioning (untested, work in progress).

Location:
trunk/src/VBox
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox

    • Property svn:mergeinfo set to (toggle deleted branches)
      /branches/VBox-3.0/src/VBox58652,​70973
      /branches/VBox-3.2/src/VBox66309,​66318
      /branches/VBox-4.0/src/VBox70873
      /branches/VBox-4.1/src/VBox74233,​78414,​78691,​81841,​82127
      /branches/andy/guestctrl20/src/VBox78916,​78930
      /branches/dsen/gui/src/VBox79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
      /branches/dsen/gui2/src/VBox79224,​79228,​79233,​79235,​79258,​79262-79263,​79273,​79341,​79345,​79354,​79357,​79387-79388,​79559-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
      /branches/dsen/gui3/src/VBox79645-79692
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibGuestCtrl.cpp

    r44528 r44863  
    55
    66/*
    7  * Copyright (C) 2010-2012 Oracle Corporation
     7 * Copyright (C) 2010-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    5050 *
    5151 * @returns VBox status code
    52  * @param   pu32ClientId    Where to put the client id on success. The client id
    53  *                          must be passed to all the other calls to the service.
    54  */
    55 VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *pu32ClientId)
     52 * @param   puClientId    Where to put the client id on success. The client id
     53 *                        must be passed to all the other calls to the service.
     54 */
     55VBGLR3DECL(int) VbglR3GuestCtrlConnect(uint32_t *puClientId)
    5656{
    5757    VBoxGuestHGCMConnectInfo Info;
     
    6767        rc = Info.result;
    6868        if (RT_SUCCESS(rc))
    69             *pu32ClientId = Info.u32ClientID;
     69            *puClientId = Info.u32ClientID;
    7070    }
    7171    return rc;
     
    7777 *
    7878 * @returns VBox status code.
    79  * @param   u32ClientId     The client id returned by VbglR3GuestCtrlConnect().
    80  */
    81 VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t u32ClientId)
     79 * @param   uClientId     The client id returned by VbglR3GuestCtrlConnect().
     80 */
     81VBGLR3DECL(int) VbglR3GuestCtrlDisconnect(uint32_t uClientId)
    8282{
    8383    VBoxGuestHGCMDisconnectInfo Info;
    8484    Info.result = VERR_WRONG_ORDER;
    85     Info.u32ClientID = u32ClientId;
     85    Info.u32ClientID = uClientId;
    8686
    8787    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, &Info, sizeof(Info));
     
    9797 *
    9898 * @returns VBox status code.
    99  * @param   u32ClientId     The client id returned by VbglR3GuestCtrlConnect().
     99 * @param   uClientId       The client id returned by VbglR3GuestCtrlConnect().
    100100 * @param   puMsg           Where to store the message id.
    101101 * @param   puNumParms      Where to store the number  of parameters which will be received
    102102 *                          in a second call to the host.
    103103 */
    104 VBGLR3DECL(int) VbglR3GuestCtrlWaitForHostMsg(uint32_t u32ClientId, uint32_t *puMsg, uint32_t *puNumParms)
     104VBGLR3DECL(int) VbglR3GuestCtrlMsgWaitFor(uint32_t uClientId, uint32_t *puMsg, uint32_t *puNumParms)
    105105{
    106106    AssertPtrReturn(puMsg, VERR_INVALID_POINTER);
    107107    AssertPtrReturn(puNumParms, VERR_INVALID_POINTER);
    108108
    109     VBoxGuestCtrlHGCMMsgType Msg;
    110 
    111     Msg.hdr.result      = VERR_WRONG_ORDER;
    112     Msg.hdr.u32ClientID = u32ClientId;
    113     Msg.hdr.u32Function = GUEST_GET_HOST_MSG; /* Tell the host we want our next command. */
    114     Msg.hdr.cParms      = 2;                  /* Just peek for the next message! */
     109    HGCMMsgCmdWaitFor Msg;
     110
     111    Msg.hdr.result      = VERR_WRONG_ORDER;
     112    Msg.hdr.u32ClientID = uClientId;
     113    Msg.hdr.u32Function = GUEST_MSG_WAIT; /* Tell the host we want our next command. */
     114    Msg.hdr.cParms      = 2;              /* Just peek for the next message! */
    115115
    116116    VbglHGCMParmUInt32Set(&Msg.msg, 0);
     
    132132
    133133/**
     134 * Asks the host guest control service to set a command filter to this
     135 * client so that it only will receive certain commands in the future.
     136 *
     137 * @return  IPRT status code.
     138 * @param   uClientId       The client id returned by VbglR3GuestCtrlConnect().
     139 * @param   uFilterAdd      Filter mask to add.
     140 * @param   uFilterRemove   Filter mask to remove.
     141 */
     142VBGLR3DECL(int) VbglR3GuestCtrlMsgSetFilter(uint32_t uClientId,
     143                                            uint32_t uFilterAdd, uint32_t uFilterRemove)
     144{
     145    HGCMMsgCmdSetFilter Msg;
     146
     147    Msg.hdr.result      = VERR_WRONG_ORDER;
     148    Msg.hdr.u32ClientID = uClientId;
     149    Msg.hdr.u32Function = GUEST_MSG_FILTER; /* Tell the host we want to set a filter. */
     150    Msg.hdr.cParms      = 2;
     151
     152    VbglHGCMParmUInt32Set(&Msg.add, uFilterAdd);
     153    VbglHGCMParmUInt32Set(&Msg.remove, uFilterRemove);
     154
     155    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     156    if (RT_SUCCESS(rc))
     157        rc = Msg.hdr.result;
     158    return rc;
     159}
     160
     161
     162/**
    134163 * Asks the host to cancel (release) all pending waits which were deferred.
    135164 *
    136165 * @returns VBox status code.
    137  * @param   u32ClientId     The client id returned by VbglR3GuestCtrlConnect().
    138  */
    139 VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t u32ClientId)
    140 {
    141     VBoxGuestCtrlHGCMMsgCancelPendingWaits Msg;
    142 
    143     Msg.hdr.result      = VERR_WRONG_ORDER;
    144     Msg.hdr.u32ClientID = u32ClientId;
     166 * @param   uClientId     The client id returned by VbglR3GuestCtrlConnect().
     167 */
     168VBGLR3DECL(int) VbglR3GuestCtrlCancelPendingWaits(uint32_t uClientId)
     169{
     170    HGCMMsgCancelPendingWaits Msg;
     171
     172    Msg.hdr.result      = VERR_WRONG_ORDER;
     173    Msg.hdr.u32ClientID = uClientId;
    145174    Msg.hdr.u32Function = GUEST_CANCEL_PENDING_WAITS;
    146175    Msg.hdr.cParms      = 0;
     
    157186
    158187
     188VBGLR3DECL(int) VbglR3GuestCtrlSessionNotify(uint32_t uClientId, uint32_t uContext,
     189                                             uint32_t uType, uint32_t uResult)
     190{
     191    HGCMMsgSessionNotify Msg;
     192
     193    Msg.hdr.result      = VERR_WRONG_ORDER;
     194    Msg.hdr.u32ClientID = uClientId;
     195    Msg.hdr.u32Function = GUEST_SESSION_NOTIFY;
     196    Msg.hdr.cParms      = 3;
     197
     198    VbglHGCMParmUInt32Set(&Msg.context, uContext);
     199    VbglHGCMParmUInt32Set(&Msg.type, uType);
     200    VbglHGCMParmUInt32Set(&Msg.result, uResult);
     201
     202    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     203    if (RT_SUCCESS(rc))
     204    {
     205        int rc2 = Msg.hdr.result;
     206        if (RT_FAILURE(rc2))
     207            rc = rc2;
     208    }
     209    return rc;
     210}
     211
     212
     213/**
     214 * Retrieves the request to create a new guest session.
     215 *
     216 * @return  IPRT status code.
     217 * @param   pHostCtx                    Host context.
     218 ** @todo Docs!
     219 */
     220VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLHOSTCTX pHostCtx,
     221                                              uint32_t *puProtocol,
     222                                              char     *pszUser,     uint32_t  cbUser,
     223                                              char     *pszPassword, uint32_t  cbPassword,
     224                                              char     *pszDomain,   uint32_t  cbDomain,
     225                                              uint32_t *puFlags,     uint32_t *puSessionID)
     226{
     227    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     228    AssertReturn(pHostCtx->uNumParms == 6, VERR_INVALID_PARAMETER);
     229
     230    AssertPtrReturn(puProtocol, VERR_INVALID_POINTER);
     231    AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
     232    AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
     233    AssertPtrReturn(pszDomain, VERR_INVALID_POINTER);
     234    AssertPtrReturn(puFlags, VERR_INVALID_POINTER);
     235
     236    HGCMMsgSessionOpen Msg;
     237
     238    Msg.hdr.result      = VERR_WRONG_ORDER;
     239    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     240    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     241    Msg.hdr.cParms      = pHostCtx->uNumParms;
     242
     243    VbglHGCMParmUInt32Set(&Msg.context, 0);
     244    VbglHGCMParmUInt32Set(&Msg.protocol, 0);
     245    VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
     246    VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
     247    VbglHGCMParmPtrSet(&Msg.domain, pszDomain, cbDomain);
     248    VbglHGCMParmUInt32Set(&Msg.flags, 0);
     249
     250    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     251    if (RT_SUCCESS(rc))
     252    {
     253        int rc2 = Msg.hdr.result;
     254        if (RT_FAILURE(rc2))
     255        {
     256            rc = rc2;
     257        }
     258        else
     259        {
     260            Msg.context.GetUInt32(&pHostCtx->uContextID);
     261            Msg.protocol.GetUInt32(puProtocol);
     262            Msg.flags.GetUInt32(puFlags);
     263
     264            if (puSessionID)
     265                *puSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHostCtx->uContextID);
     266        }
     267    }
     268
     269    return rc;
     270}
     271
     272
     273/**
     274 * Retrieves the request to terminate an existing guest session.
     275 *
     276 * @return  IPRT status code.
     277 * @param   pHostCtx                    Host context.
     278 ** @todo Docs!
     279 */
     280VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puFlags, uint32_t *puSessionID)
     281{
     282    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     283    AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
     284
     285    AssertPtrReturn(puFlags, VERR_INVALID_POINTER);
     286
     287    HGCMMsgSessionClose Msg;
     288
     289    Msg.hdr.result      = VERR_WRONG_ORDER;
     290    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     291    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     292    Msg.hdr.cParms      = pHostCtx->uNumParms;
     293
     294    VbglHGCMParmUInt32Set(&Msg.context, 0);
     295    VbglHGCMParmUInt32Set(&Msg.flags, 0);
     296
     297    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     298    if (RT_SUCCESS(rc))
     299    {
     300        int rc2 = Msg.hdr.result;
     301        if (RT_FAILURE(rc2))
     302        {
     303            rc = rc2;
     304        }
     305        else
     306        {
     307            Msg.context.GetUInt32(&pHostCtx->uContextID);
     308            Msg.flags.GetUInt32(puFlags);
     309
     310            if (puSessionID)
     311                *puSessionID = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHostCtx->uContextID);
     312        }
     313    }
     314
     315    return rc;
     316}
     317
     318
    159319/**
    160320 * Allocates and gets host data, based on the message id.
     
    163323 *
    164324 * @returns VBox status code.
    165  * @param   u32ClientId     The client id returned by VbglR3GuestCtrlConnect().
    166  * @param   uNumParms
    167325 ** @todo Docs!
    168  */
    169 VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdExec(uint32_t  u32ClientId,    uint32_t  cParms,
    170                                                   uint32_t *puContext,
    171                                                   char     *pszCmd,         uint32_t  cbCmd,
    172                                                   uint32_t *puFlags,
    173                                                   char     *pszArgs,        uint32_t  cbArgs,   uint32_t *pcArgs,
    174                                                   char     *pszEnv,         uint32_t *pcbEnv,   uint32_t *pcEnvVars,
    175                                                   char     *pszUser,        uint32_t  cbUser,
    176                                                   char     *pszPassword,    uint32_t  cbPassword,
    177                                                   uint32_t *pcMsTimeLimit)
    178 {
    179     AssertReturn(cParms == 11, VERR_INVALID_PARAMETER);
    180 
    181     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     326 ** @todo Move the parameters in an own struct!
     327 */
     328VBGLR3DECL(int) VbglR3GuestCtrlProcGetStart(PVBGLR3GUESTCTRLHOSTCTX   pHostCtx,
     329                                            char     *pszCmd,         uint32_t  cbCmd,
     330                                            uint32_t *puFlags,
     331                                            char     *pszArgs,        uint32_t  cbArgs,     uint32_t *pcArgs,
     332                                            char     *pszEnv,         uint32_t *pcbEnv,     uint32_t *pcEnvVars,
     333                                            char     *pszUser,        uint32_t  cbUser,
     334                                            char     *pszPassword,    uint32_t  cbPassword,
     335                                            uint32_t *puTimeoutMS,
     336                                            uint32_t *puPriority,
     337                                            uint64_t *puAffinity,     uint32_t  cbAffinity, uint32_t *pcAffinity)
     338{
     339    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     340
    182341    AssertPtrReturn(pszCmd, VERR_INVALID_POINTER);
    183342    AssertPtrReturn(puFlags, VERR_INVALID_POINTER);
     
    187346    AssertPtrReturn(pcbEnv, VERR_INVALID_POINTER);
    188347    AssertPtrReturn(pcEnvVars, VERR_INVALID_POINTER);
    189     AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
    190     AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
    191     AssertPtrReturn(pcMsTimeLimit, VERR_INVALID_POINTER);
    192 
    193     VBoxGuestCtrlHGCMMsgExecCmd Msg;
    194 
    195     Msg.hdr.result      = VERR_WRONG_ORDER;
    196     Msg.hdr.u32ClientID = u32ClientId;
    197     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    198     Msg.hdr.cParms      = 11;
     348    AssertPtrReturn(puTimeoutMS, VERR_INVALID_POINTER);
     349
     350    HGCMMsgProcExec Msg;
     351
     352    Msg.hdr.result      = VERR_WRONG_ORDER;
     353    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     354    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     355    Msg.hdr.cParms      = pHostCtx->uNumParms;
    199356
    200357    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    206363    VbglHGCMParmUInt32Set(&Msg.cb_env, 0);
    207364    VbglHGCMParmPtrSet(&Msg.env, pszEnv, *pcbEnv);
    208     VbglHGCMParmPtrSet(&Msg.username, pszUser, cbUser);
    209     VbglHGCMParmPtrSet(&Msg.password, pszPassword, cbPassword);
    210     VbglHGCMParmUInt32Set(&Msg.timeout, 0);
    211 
    212     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    213     if (RT_SUCCESS(rc))
    214     {
    215         int rc2 = Msg.hdr.result;
    216         if (RT_FAILURE(rc2))
    217         {
    218             rc = rc2;
    219         }
    220         else
    221         {
    222             Msg.context.GetUInt32(puContext);
     365    if (pHostCtx->uProtocol < 2)
     366    {
     367        AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
     368        AssertReturn(cbUser, VERR_INVALID_PARAMETER);
     369        AssertPtrReturn(pszPassword, VERR_INVALID_POINTER);
     370        AssertReturn(pszPassword, VERR_INVALID_PARAMETER);
     371
     372        VbglHGCMParmPtrSet(&Msg.u.v1.username, pszUser, cbUser);
     373        VbglHGCMParmPtrSet(&Msg.u.v1.password, pszPassword, cbPassword);
     374        VbglHGCMParmUInt32Set(&Msg.u.v1.timeout, 0);
     375    }
     376    else
     377    {
     378        AssertPtrReturn(puAffinity, VERR_INVALID_POINTER);
     379        AssertReturn(cbAffinity, VERR_INVALID_PARAMETER);
     380
     381        VbglHGCMParmUInt32Set(&Msg.u.v2.timeout, 0);
     382        VbglHGCMParmUInt32Set(&Msg.u.v2.priority, 0);
     383        VbglHGCMParmUInt32Set(&Msg.u.v2.num_affinity, 0);
     384        VbglHGCMParmPtrSet(&Msg.u.v2.affinity, puAffinity, cbAffinity);
     385    }
     386
     387    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     388    if (RT_SUCCESS(rc))
     389    {
     390        int rc2 = Msg.hdr.result;
     391        if (RT_FAILURE(rc2))
     392        {
     393            rc = rc2;
     394        }
     395        else
     396        {
     397            Msg.context.GetUInt32(&pHostCtx->uContextID);
    223398            Msg.flags.GetUInt32(puFlags);
    224399            Msg.num_args.GetUInt32(pcArgs);
    225400            Msg.num_env.GetUInt32(pcEnvVars);
    226401            Msg.cb_env.GetUInt32(pcbEnv);
    227             Msg.timeout.GetUInt32(pcMsTimeLimit);
     402            if (pHostCtx->uProtocol < 2)
     403            {
     404                Msg.u.v1.timeout.GetUInt32(puTimeoutMS);
     405            }
     406            else
     407            {
     408                Msg.u.v2.timeout.GetUInt32(puTimeoutMS);
     409                Msg.u.v2.priority.GetUInt32(puPriority);
     410                Msg.u.v2.num_affinity.GetUInt32(pcAffinity);
     411            }
    228412        }
    229413    }
     
    238422 *
    239423 * @returns VBox status code.
    240  * @param   u32ClientId     The client id returned by VbglR3GuestCtrlConnect().
    241  * @param   cParms
    242424 ** @todo Docs!
    243425 */
    244 VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdOutput(uint32_t  u32ClientId,    uint32_t  cParms,
    245                                                     uint32_t *puContext,      uint32_t *puPID,
    246                                                     uint32_t *puHandle,       uint32_t *puFlags)
    247 {
    248     AssertReturn(cParms == 4, VERR_INVALID_PARAMETER);
    249 
    250     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     426VBGLR3DECL(int) VbglR3GuestCtrlProcGetOutput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx,
     427                                             uint32_t *puPID, uint32_t *puHandle, uint32_t *puFlags)
     428{
     429    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     430    AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
     431
    251432    AssertPtrReturn(puPID, VERR_INVALID_POINTER);
    252433    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    253434    AssertPtrReturn(puFlags, VERR_INVALID_POINTER);
    254435
    255     VBoxGuestCtrlHGCMMsgExecOut Msg;
     436    HGCMMsgProcOutput Msg;
    256437
    257438    Msg.hdr.result = VERR_WRONG_ORDER;
    258     Msg.hdr.u32ClientID = u32ClientId;
    259     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    260     Msg.hdr.cParms = 4;
     439    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     440    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     441    Msg.hdr.cParms      = pHostCtx->uNumParms;
    261442
    262443    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    275456        else
    276457        {
    277             Msg.context.GetUInt32(puContext);
     458            Msg.context.GetUInt32(&pHostCtx->uContextID);
    278459            Msg.pid.GetUInt32(puPID);
    279460            Msg.handle.GetUInt32(puHandle);
     
    292473 *
    293474 * @returns VBox status code.
    294  * @param   u32ClientId     The client id returned by VbglR3GuestCtrlConnect().
    295  * @param   cParms
    296475 ** @todo Docs!
    297476 */
    298 VBGLR3DECL(int) VbglR3GuestCtrlExecGetHostCmdInput(uint32_t  u32ClientId,    uint32_t   cParms,
    299                                                    uint32_t *puContext,      uint32_t  *puPID,
    300                                                    uint32_t *puFlags,
    301                                                    void     *pvData,         uint32_t  cbData,
    302                                                    uint32_t *pcbSize)
    303 {
    304     AssertReturn(cParms == 5, VERR_INVALID_PARAMETER);
    305 
    306     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     477VBGLR3DECL(int) VbglR3GuestCtrlProcGetInput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx,
     478                                            uint32_t  *puPID,       uint32_t *puFlags,
     479                                            void      *pvData,      uint32_t  cbData,
     480                                            uint32_t  *pcbSize)
     481{
     482    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     483    AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
     484
    307485    AssertPtrReturn(puPID, VERR_INVALID_POINTER);
    308486    AssertPtrReturn(puFlags, VERR_INVALID_POINTER);
     
    310488    AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
    311489
    312     VBoxGuestCtrlHGCMMsgExecIn Msg;
    313 
    314     Msg.hdr.result      = VERR_WRONG_ORDER;
    315     Msg.hdr.u32ClientID = u32ClientId;
    316     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    317     Msg.hdr.cParms      = 5;
     490    HGCMMsgProcInput Msg;
     491
     492    Msg.hdr.result      = VERR_WRONG_ORDER;
     493    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     494    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     495    Msg.hdr.cParms      = pHostCtx->uNumParms;
    318496
    319497    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    333511        else
    334512        {
    335             Msg.context.GetUInt32(puContext);
     513            Msg.context.GetUInt32(&pHostCtx->uContextID);
    336514            Msg.pid.GetUInt32(puPID);
    337515            Msg.flags.GetUInt32(puFlags);
     
    343521
    344522
    345 /**
    346  * Reports the process status (along with some other stuff) to the host.
    347  *
    348  * @returns VBox status code.
    349  ** @todo Docs!
    350  */
    351 VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatus(uint32_t     u32ClientId,
    352                                                 uint32_t     u32Context,
    353                                                 uint32_t     u32PID,
    354                                                 uint32_t     u32Status,
    355                                                 uint32_t     u32Flags,
    356                                                 void        *pvData,
    357                                                 uint32_t     cbData)
    358 {
    359     VBoxGuestCtrlHGCMMsgExecStatus Msg;
    360 
    361     Msg.hdr.result = VERR_WRONG_ORDER;
    362     Msg.hdr.u32ClientID = u32ClientId;
    363     Msg.hdr.u32Function = GUEST_EXEC_SEND_STATUS;
    364     Msg.hdr.cParms = 5;
    365 
    366     VbglHGCMParmUInt32Set(&Msg.context, u32Context);
    367     VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
    368     VbglHGCMParmUInt32Set(&Msg.status, u32Status);
    369     VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
    370     VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
    371 
    372     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    373     if (RT_SUCCESS(rc))
    374     {
    375         int rc2 = Msg.hdr.result;
    376         if (RT_FAILURE(rc2))
    377             rc = rc2;
    378     }
    379     return rc;
    380 }
    381 
    382 
    383 /**
    384  * Sends output (from stdout/stderr) from a running process.
    385  *
    386  * @returns VBox status code.
    387  ** @todo Docs!
    388  */
    389 VBGLR3DECL(int) VbglR3GuestCtrlExecSendOut(uint32_t     u32ClientId,
    390                                            uint32_t     u32Context,
    391                                            uint32_t     u32PID,
    392                                            uint32_t     u32Handle,
    393                                            uint32_t     u32Flags,
    394                                            void        *pvData,
    395                                            uint32_t     cbData)
    396 {
    397     VBoxGuestCtrlHGCMMsgExecOut Msg;
    398 
    399     Msg.hdr.result = VERR_WRONG_ORDER;
    400     Msg.hdr.u32ClientID = u32ClientId;
    401     Msg.hdr.u32Function = GUEST_EXEC_SEND_OUTPUT;
    402     Msg.hdr.cParms = 5;
    403 
    404     VbglHGCMParmUInt32Set(&Msg.context, u32Context);
    405     VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
    406     VbglHGCMParmUInt32Set(&Msg.handle, u32Handle);
    407     VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
    408     VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
    409 
    410     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    411     if (RT_SUCCESS(rc))
    412     {
    413         int rc2 = Msg.hdr.result;
    414         if (RT_FAILURE(rc2))
    415             rc = rc2;
    416     }
    417     return rc;
    418 }
    419 
    420 
    421 /**
    422  * Reports back the input status to the host.
    423  *
    424  * @returns VBox status code.
    425  ** @todo Docs!
    426  */
    427 VBGLR3DECL(int) VbglR3GuestCtrlExecReportStatusIn(uint32_t     u32ClientId,
    428                                                   uint32_t     u32Context,
    429                                                   uint32_t     u32PID,
    430                                                   uint32_t     u32Status,
    431                                                   uint32_t     u32Flags,
    432                                                   uint32_t     cbWritten)
    433 {
    434     VBoxGuestCtrlHGCMMsgExecStatusIn Msg;
    435 
    436     Msg.hdr.result = VERR_WRONG_ORDER;
    437     Msg.hdr.u32ClientID = u32ClientId;
    438     Msg.hdr.u32Function = GUEST_EXEC_SEND_INPUT_STATUS;
    439     Msg.hdr.cParms = 5;
    440 
    441     VbglHGCMParmUInt32Set(&Msg.context, u32Context);
    442     VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
    443     VbglHGCMParmUInt32Set(&Msg.status, u32Status);
    444     VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
    445     VbglHGCMParmUInt32Set(&Msg.written, cbWritten);
    446 
    447     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    448     if (RT_SUCCESS(rc))
    449     {
    450         int rc2 = Msg.hdr.result;
    451         if (RT_FAILURE(rc2))
    452             rc = rc2;
    453     }
    454     return rc;
    455 }
    456 
    457 
    458 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdOpen(uint32_t     uClientId,           uint32_t cParms,
    459                                                   uint32_t    *puContext,
    460                                                   char        *pszFileName,         uint32_t cbFileName,
    461                                                   char        *pszOpenMode,         uint32_t cbOpenMode,
    462                                                   char        *pszDisposition,      uint32_t cbDisposition,
    463                                                   uint32_t    *puCreationMode,
    464                                                   uint64_t    *puOffset)
    465 {
    466     AssertReturn(cParms == 6, VERR_INVALID_PARAMETER);
    467     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     523VBGLR3DECL(int) VbglR3GuestCtrlFileGetOpen(PVBGLR3GUESTCTRLHOSTCTX      pHostCtx,
     524                                           char     *pszFileName,       uint32_t cbFileName,
     525                                           char     *pszOpenMode,       uint32_t cbOpenMode,
     526                                           char     *pszDisposition,    uint32_t cbDisposition,
     527                                           uint32_t *puCreationMode,
     528                                           uint64_t *puOffset)
     529{
     530    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     531    AssertReturn(pHostCtx->uNumParms == 6, VERR_INVALID_PARAMETER);
     532
    468533    AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
    469534    AssertReturn(cbFileName, VERR_INVALID_PARAMETER);
     
    475540    AssertPtrReturn(puOffset, VERR_INVALID_POINTER);
    476541
    477     VBoxGuestCtrlHGCMMsgFileOpen Msg;
    478 
    479     Msg.hdr.result      = VERR_WRONG_ORDER;
    480     Msg.hdr.u32ClientID = uClientId;
    481     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    482     Msg.hdr.cParms      = 6;
     542    HGCMMsgFileOpen Msg;
     543
     544    Msg.hdr.result      = VERR_WRONG_ORDER;
     545    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     546    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     547    Msg.hdr.cParms      = pHostCtx->uNumParms;
    483548
    484549    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    499564        else
    500565        {
    501             Msg.context.GetUInt32(puContext);
     566            Msg.context.GetUInt32(&pHostCtx->uContextID);
    502567            Msg.creationmode.GetUInt32(puCreationMode);
    503568            Msg.offset.GetUInt64(puOffset);
     
    508573
    509574
    510 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdClose(uint32_t     uClientId,           uint32_t cParms,
    511                                                    uint32_t    *puContext,
    512                                                    uint32_t    *puHandle)
    513 {
    514     AssertReturn(cParms == 2, VERR_INVALID_PARAMETER);
    515     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     575VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle)
     576{
     577    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     578
     579    AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
    516580    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    517581
    518     VBoxGuestCtrlHGCMMsgFileClose Msg;
    519 
    520     Msg.hdr.result      = VERR_WRONG_ORDER;
    521     Msg.hdr.u32ClientID = uClientId;
    522     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    523     Msg.hdr.cParms      = 2;
     582    HGCMMsgFileClose Msg;
     583
     584    Msg.hdr.result      = VERR_WRONG_ORDER;
     585    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     586    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     587    Msg.hdr.cParms      = pHostCtx->uNumParms;
    524588
    525589    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    536600        else
    537601        {
    538             Msg.context.GetUInt32(puContext);
     602            Msg.context.GetUInt32(&pHostCtx->uContextID);
    539603            Msg.handle.GetUInt32(puHandle);
    540604        }
     
    544608
    545609
    546 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdRead(uint32_t     uClientId,           uint32_t     cParms,
    547                                                   uint32_t    *puContext,
    548                                                   uint32_t    *puHandle,            uint32_t    *puToRead)
    549 {
    550     AssertReturn(cParms == 4, VERR_INVALID_PARAMETER);
    551     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     610VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLHOSTCTX pHostCtx,
     611                                           uint32_t *puHandle, uint32_t *puToRead)
     612{
     613    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     614
     615    AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
    552616    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    553617    AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
    554618
    555     VBoxGuestCtrlHGCMMsgFileRead Msg;
    556 
    557     Msg.hdr.result      = VERR_WRONG_ORDER;
    558     Msg.hdr.u32ClientID = uClientId;
    559     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    560     Msg.hdr.cParms      = 4;
     619    HGCMMsgFileRead Msg;
     620
     621    Msg.hdr.result      = VERR_WRONG_ORDER;
     622    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     623    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     624    Msg.hdr.cParms      = pHostCtx->uNumParms;
    561625
    562626    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    574638        else
    575639        {
    576             Msg.context.GetUInt32(puContext);
     640            Msg.context.GetUInt32(&pHostCtx->uContextID);
    577641            Msg.handle.GetUInt32(puHandle);
    578642            Msg.size.GetUInt32(puToRead);
     
    582646}
    583647
    584 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdWrite(uint32_t     uClientId,           uint32_t    cParms,
    585                                                    uint32_t    *puContext,
    586                                                    uint32_t    *puHandle,
    587                                                    void        *pvData,              uint32_t    cbData,
    588                                                    uint32_t    *pcbSize)
    589 {
    590     AssertReturn(cParms == 4, VERR_INVALID_PARAMETER);
    591     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     648
     649VBGLR3DECL(int) VbglR3GuestCtrlFileGetReadAt(PVBGLR3GUESTCTRLHOSTCTX pHostCtx,
     650                                             uint32_t *puHandle, uint32_t *puToRead, uint64_t *puOffset)
     651{
     652    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     653
     654    AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
     655    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
     656    AssertPtrReturn(puToRead, VERR_INVALID_POINTER);
     657
     658    HGCMMsgFileRead Msg;
     659
     660    Msg.hdr.result      = VERR_WRONG_ORDER;
     661    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     662    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     663    Msg.hdr.cParms      = pHostCtx->uNumParms;
     664
     665    VbglHGCMParmUInt32Set(&Msg.context, 0);
     666    VbglHGCMParmUInt32Set(&Msg.handle, 0);
     667    VbglHGCMParmUInt32Set(&Msg.size, 0);
     668
     669    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     670    if (RT_SUCCESS(rc))
     671    {
     672        int rc2 = Msg.hdr.result;
     673        if (RT_FAILURE(rc2))
     674        {
     675            rc = rc2;
     676        }
     677        else
     678        {
     679            Msg.context.GetUInt32(&pHostCtx->uContextID);
     680            Msg.handle.GetUInt32(puHandle);
     681            Msg.size.GetUInt32(puToRead);
     682        }
     683    }
     684    return rc;
     685}
     686
     687
     688VBGLR3DECL(int) VbglR3GuestCtrlFileGetWrite(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle,
     689                                            void *pvData, uint32_t cbData, uint32_t *pcbSize)
     690{
     691    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     692
     693    AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
    592694    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    593695    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     
    595697    AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
    596698
    597     VBoxGuestCtrlHGCMMsgFileWrite Msg;
    598 
    599     Msg.hdr.result      = VERR_WRONG_ORDER;
    600     Msg.hdr.u32ClientID = uClientId;
    601     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    602     Msg.hdr.cParms      = 4;
     699    HGCMMsgFileWrite Msg;
     700
     701    Msg.hdr.result      = VERR_WRONG_ORDER;
     702    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     703    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     704    Msg.hdr.cParms      = pHostCtx->uNumParms;
    603705
    604706    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    617719        else
    618720        {
    619             Msg.context.GetUInt32(puContext);
     721            Msg.context.GetUInt32(&pHostCtx->uContextID);
    620722            Msg.handle.GetUInt32(puHandle);
    621723            Msg.size.GetUInt32(pcbSize);
     
    626728
    627729
    628 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdSeek(uint32_t     uClientId,           uint32_t  cParms,
    629                                                   uint32_t    *puContext,
    630                                                   uint32_t    *puHandle,
    631                                                   uint32_t    *puSeekMethod,        uint64_t *puOffset)
    632 {
    633     AssertReturn(cParms == 4, VERR_INVALID_PARAMETER);
    634     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     730VBGLR3DECL(int) VbglR3GuestCtrlFileGetWriteAt(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle,
     731                                              void *pvData, uint32_t cbData, uint32_t *pcbSize, uint64_t *puOffset)
     732{
     733    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     734
     735    AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
     736    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
     737    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     738    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     739    AssertPtrReturn(pcbSize, VERR_INVALID_POINTER);
     740
     741    HGCMMsgFileWriteAt Msg;
     742
     743    Msg.hdr.result      = VERR_WRONG_ORDER;
     744    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     745    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     746    Msg.hdr.cParms      = pHostCtx->uNumParms;
     747
     748    VbglHGCMParmUInt32Set(&Msg.context, 0);
     749    VbglHGCMParmUInt32Set(&Msg.handle, 0);
     750    VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
     751    VbglHGCMParmUInt32Set(&Msg.size, 0);
     752    VbglHGCMParmUInt32Set(&Msg.offset, 0);
     753
     754    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     755    if (RT_SUCCESS(rc))
     756    {
     757        int rc2 = Msg.hdr.result;
     758        if (RT_FAILURE(rc2))
     759        {
     760            rc = rc2;
     761        }
     762        else
     763        {
     764            Msg.context.GetUInt32(&pHostCtx->uContextID);
     765            Msg.handle.GetUInt32(puHandle);
     766            Msg.size.GetUInt32(pcbSize);
     767        }
     768    }
     769    return rc;
     770}
     771
     772
     773VBGLR3DECL(int) VbglR3GuestCtrlFileGetSeek(PVBGLR3GUESTCTRLHOSTCTX pHostCtx,
     774                                           uint32_t *puHandle, uint32_t *puSeekMethod, uint64_t *puOffset)
     775{
     776    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     777
     778    AssertReturn(pHostCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
    635779    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    636780    AssertPtrReturn(puSeekMethod, VERR_INVALID_POINTER);
    637781    AssertPtrReturn(puOffset, VERR_INVALID_POINTER);
    638782
    639     VBoxGuestCtrlHGCMMsgFileSeek Msg;
    640 
    641     Msg.hdr.result      = VERR_WRONG_ORDER;
    642     Msg.hdr.u32ClientID = uClientId;
    643     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    644     Msg.hdr.cParms      = 4;
     783    HGCMMsgFileSeek Msg;
     784
     785    Msg.hdr.result      = VERR_WRONG_ORDER;
     786    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     787    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     788    Msg.hdr.cParms      = pHostCtx->uNumParms;
    645789
    646790    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    659803        else
    660804        {
    661             Msg.context.GetUInt32(puContext);
     805            Msg.context.GetUInt32(&pHostCtx->uContextID);
    662806            Msg.handle.GetUInt32(puHandle);
    663807            Msg.method.GetUInt32(puSeekMethod);
     
    669813
    670814
    671 VBGLR3DECL(int) VbglR3GuestCtrlFileGetHostCmdTell(uint32_t     uClientId,           uint32_t  cParms,
    672                                                   uint32_t    *puContext,
    673                                                   uint32_t    *puHandle)
    674 {
    675     AssertReturn(cParms == 2, VERR_INVALID_PARAMETER);
    676     AssertPtrReturn(puContext, VERR_INVALID_POINTER);
     815VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puHandle)
     816{
     817    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     818
     819    AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
    677820    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
    678821
    679     VBoxGuestCtrlHGCMMsgFileTell Msg;
    680 
    681     Msg.hdr.result      = VERR_WRONG_ORDER;
    682     Msg.hdr.u32ClientID = uClientId;
    683     Msg.hdr.u32Function = GUEST_GET_HOST_MSG;
    684     Msg.hdr.cParms      = 2;
     822    HGCMMsgFileTell Msg;
     823
     824    Msg.hdr.result      = VERR_WRONG_ORDER;
     825    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     826    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     827    Msg.hdr.cParms      = pHostCtx->uNumParms;
    685828
    686829    VbglHGCMParmUInt32Set(&Msg.context, 0);
     
    697840        else
    698841        {
    699             Msg.context.GetUInt32(puContext);
     842            Msg.context.GetUInt32(&pHostCtx->uContextID);
    700843            Msg.handle.GetUInt32(puHandle);
    701844        }
     
    705848
    706849
    707 VBGLR3DECL(int) VbglR3GuestCtrlFileNotify(uint32_t     uClientId,
    708                                           uint32_t     uContext,        uint32_t      uHandle,
     850VBGLR3DECL(int) VbglR3GuestCtrlProcGetTerminate(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puPID)
     851{
     852    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     853
     854    AssertReturn(pHostCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
     855    AssertPtrReturn(puPID, VERR_INVALID_POINTER);
     856
     857    HGCMMsgProcTerminate Msg;
     858
     859    Msg.hdr.result      = VERR_WRONG_ORDER;
     860    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     861    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     862    Msg.hdr.cParms      = pHostCtx->uNumParms;
     863
     864    VbglHGCMParmUInt32Set(&Msg.context, 0);
     865    VbglHGCMParmUInt32Set(&Msg.pid, 0);
     866
     867    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     868    if (RT_SUCCESS(rc))
     869    {
     870        int rc2 = Msg.hdr.result;
     871        if (RT_FAILURE(rc2))
     872        {
     873            rc = rc2;
     874        }
     875        else
     876        {
     877            Msg.context.GetUInt32(&pHostCtx->uContextID);
     878            Msg.pid.GetUInt32(puPID);
     879        }
     880    }
     881    return rc;
     882}
     883
     884
     885VBGLR3DECL(int) VbglR3GuestCtrlProcGetWaitFor(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, uint32_t *puPID, uint32_t *puWaitFlags, uint32_t *puTimeoutMS)
     886{
     887    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     888
     889    AssertReturn(pHostCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
     890    AssertPtrReturn(puPID, VERR_INVALID_POINTER);
     891
     892    HGCMMsgProcWaitFor Msg;
     893
     894    Msg.hdr.result      = VERR_WRONG_ORDER;
     895    Msg.hdr.u32ClientID = pHostCtx->uClientID;
     896    Msg.hdr.u32Function = GUEST_MSG_WAIT;
     897    Msg.hdr.cParms      = pHostCtx->uNumParms;
     898
     899    VbglHGCMParmUInt32Set(&Msg.context, 0);
     900    VbglHGCMParmUInt32Set(&Msg.pid, 0);
     901    VbglHGCMParmUInt32Set(&Msg.flags, 0);
     902    VbglHGCMParmUInt32Set(&Msg.timeout, 0);
     903
     904    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     905    if (RT_SUCCESS(rc))
     906    {
     907        int rc2 = Msg.hdr.result;
     908        if (RT_FAILURE(rc2))
     909        {
     910            rc = rc2;
     911        }
     912        else
     913        {
     914            Msg.context.GetUInt32(&pHostCtx->uContextID);
     915            Msg.pid.GetUInt32(puPID);
     916            Msg.flags.GetUInt32(puWaitFlags);
     917            Msg.timeout.GetUInt32(puTimeoutMS);
     918        }
     919    }
     920    return rc;
     921}
     922
     923
     924VBGLR3DECL(int) VbglR3GuestCtrlFileNotify(uint32_t     uClientId,    uint32_t     uContext,
    709925                                          uint32_t     uType,
    710                                           void        *pvPayload,       uint32_t      cbPayload)
     926                                          void        *pvPayload,    uint32_t     cbPayload)
    711927{
    712928    AssertPtrReturn(uContext, VERR_INVALID_POINTER);
    713     AssertPtrReturn(uHandle, VERR_INVALID_POINTER);
    714929    AssertPtrReturn(pvPayload, VERR_INVALID_POINTER);
    715930    AssertReturn(cbPayload, VERR_INVALID_PARAMETER);
    716931
    717     VBoxGuestCtrlHGCMMsgFileNotify Msg;
     932    HGCMMsgFileNotify Msg;
    718933
    719934    Msg.hdr.result      = VERR_WRONG_ORDER;
    720935    Msg.hdr.u32ClientID = uClientId;
    721     Msg.hdr.u32Function = GUEST_FILE_NOTIFY;
    722     Msg.hdr.cParms      = 4;
     936    //Msg.hdr.u32Function = GUEST_FILE_NOTIFY;
     937    Msg.hdr.cParms      = 3;
    723938
    724939    VbglHGCMParmUInt32Set(&Msg.context, uContext);
    725     VbglHGCMParmUInt32Set(&Msg.handle, uHandle);
    726940    VbglHGCMParmUInt32Set(&Msg.type, uType);
    727941    VbglHGCMParmPtrSet(&Msg.payload, pvPayload, cbPayload);
     
    737951}
    738952
     953
     954/**
     955 * Callback for reporting a guest process status (along with some other stuff) to the host.
     956 *
     957 * @returns VBox status code.
     958 ** @todo Docs!
     959 */
     960VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(uint32_t     u32ClientID,
     961                                            uint32_t     u32Context,
     962                                            uint32_t     u32PID,
     963                                            uint32_t     u32Status,
     964                                            uint32_t     u32Flags,
     965                                            void        *pvData,
     966                                            uint32_t     cbData)
     967{
     968    HGCMMsgProcStatus Msg;
     969
     970    Msg.hdr.result = VERR_WRONG_ORDER;
     971    Msg.hdr.u32ClientID = u32ClientID;
     972    Msg.hdr.u32Function = GUEST_EXEC_STATUS;
     973    Msg.hdr.cParms = 5;
     974
     975    VbglHGCMParmUInt32Set(&Msg.context, u32Context);
     976    VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
     977    VbglHGCMParmUInt32Set(&Msg.status, u32Status);
     978    VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
     979    VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
     980
     981    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     982    if (RT_SUCCESS(rc))
     983    {
     984        int rc2 = Msg.hdr.result;
     985        if (RT_FAILURE(rc2))
     986            rc = rc2;
     987    }
     988    return rc;
     989}
     990
     991
     992/**
     993 * Sends output (from stdout/stderr) from a running process.
     994 *
     995 * @returns VBox status code.
     996 ** @todo Docs!
     997 */
     998VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(uint32_t     u32ClientID,
     999                                            uint32_t     u32Context,
     1000                                            uint32_t     u32PID,
     1001                                            uint32_t     u32Handle,
     1002                                            uint32_t     u32Flags,
     1003                                            void        *pvData,
     1004                                            uint32_t     cbData)
     1005{
     1006    HGCMMsgProcOutput Msg;
     1007
     1008    Msg.hdr.result = VERR_WRONG_ORDER;
     1009    Msg.hdr.u32ClientID = u32ClientID;
     1010    Msg.hdr.u32Function = GUEST_EXEC_OUTPUT;
     1011    Msg.hdr.cParms = 5;
     1012
     1013    VbglHGCMParmUInt32Set(&Msg.context, u32Context);
     1014    VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
     1015    VbglHGCMParmUInt32Set(&Msg.handle, u32Handle);
     1016    VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
     1017    VbglHGCMParmPtrSet(&Msg.data, pvData, cbData);
     1018
     1019    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     1020    if (RT_SUCCESS(rc))
     1021    {
     1022        int rc2 = Msg.hdr.result;
     1023        if (RT_FAILURE(rc2))
     1024            rc = rc2;
     1025    }
     1026    return rc;
     1027}
     1028
     1029
     1030/**
     1031 * Callback for reporting back the input status of a guest process to the host.
     1032 *
     1033 * @returns VBox status code.
     1034 ** @todo Docs!
     1035 */
     1036VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(uint32_t     u32ClientID,
     1037                                                 uint32_t     u32Context,
     1038                                                 uint32_t     u32PID,
     1039                                                 uint32_t     u32Status,
     1040                                                 uint32_t     u32Flags,
     1041                                                 uint32_t     cbWritten)
     1042{
     1043    HGCMMsgProcStatusInput Msg;
     1044
     1045    Msg.hdr.result = VERR_WRONG_ORDER;
     1046    Msg.hdr.u32ClientID = u32ClientID;
     1047    Msg.hdr.u32Function = GUEST_EXEC_INPUT_STATUS;
     1048    Msg.hdr.cParms = 5;
     1049
     1050    VbglHGCMParmUInt32Set(&Msg.context, u32Context);
     1051    VbglHGCMParmUInt32Set(&Msg.pid, u32PID);
     1052    VbglHGCMParmUInt32Set(&Msg.status, u32Status);
     1053    VbglHGCMParmUInt32Set(&Msg.flags, u32Flags);
     1054    VbglHGCMParmUInt32Set(&Msg.written, cbWritten);
     1055
     1056    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     1057    if (RT_SUCCESS(rc))
     1058    {
     1059        int rc2 = Msg.hdr.result;
     1060        if (RT_FAILURE(rc2))
     1061            rc = rc2;
     1062    }
     1063    return rc;
     1064}
     1065
  • trunk/src/VBox/Additions/common/VBoxService

    • Property svn:mergeinfo set to (toggle deleted branches)
      /branches/VBox-3.0/src/VBox/Additions/common/VBoxService58652,​70973
      /branches/VBox-3.2/src/VBox/Additions/common/VBoxService66309,​66318
      /branches/VBox-4.0/src/VBox/Additions/common/VBoxService70873
      /branches/VBox-4.1/src/VBox/Additions/common/VBoxService74233,​78414,​78691
      /branches/VBox-4.2/src/VBox/Additions/common/VBoxService82653,​83625-83626,​83665,​83678
      /branches/dsen/gui/src/VBox/Additions/common/VBoxService79076-79078,​79089,​79109-79110,​79112-79113,​79127-79130,​79134,​79141,​79151,​79155,​79157-79159,​79193,​79197
      /branches/dsen/gui2/src/VBox/Additions/common/VBoxService79224,​79228,​79233,​79235,​79258,​79262-79263,​79273,​79341,​79345,​79354,​79357,​79387-79388,​79559-79569,​79572-79573,​79578,​79581-79582,​79590-79591,​79598-79599,​79602-79603,​79605-79606,​79632,​79635,​79637,​79644
      /branches/dsen/gui3/src/VBox/Additions/common/VBoxService79645-79692
  • trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk

    r43791 r44863  
    55
    66#
    7 # Copyright (C) 2007-2012 Oracle Corporation
     7# Copyright (C) 2007-2013 Oracle Corporation
    88#
    99# This file is part of VirtualBox Open Source Edition (OSE), as
     
    7474 VBoxService_SOURCES    += \
    7575        VBoxServiceControl.cpp \
    76         VBoxServiceControlThread.cpp
     76        VBoxServiceControlThread.cpp \
     77        VBoxServiceControlSession.cpp
    7778endif
    7879
  • trunk/src/VBox/Additions/common/VBoxService/VBoxService.cpp

    r44528 r44863  
    5757
    5858#include "VBoxServiceInternal.h"
     59#ifdef VBOX_WITH_GUEST_CONTROL
     60# include "VBoxServiceControl.h"
     61#endif
    5962
    6063
     
    6669/** The current verbosity level. */
    6770int                  g_cVerbosity = 0;
     71char                 g_szLogFile[RTPATH_MAX + 128] = "";
    6872/** Logging parameters. */
    6973/** @todo Make this configurable later. */
     
    216220 * @param   pszLogFile              Filename for log output.  Optional.
    217221 */
    218 static int VBoxServiceLogCreate(const char *pszLogFile)
     222int VBoxServiceLogCreate(const char *pszLogFile)
    219223{
    220224    /* Create release logger (stdout + file). */
     
    242246}
    243247
    244 static void VBoxServiceLogDestroy(void)
     248
     249void VBoxServiceLogDestroy(void)
    245250{
    246251    RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
     
    634639        }
    635640
     641    VBoxServiceVerbose(3, "All stop functions for services called\n");
     642
    636643    /*
    637644     * Wait for all the service threads to complete.
     
    792799     */
    793800    if (    argc == 2
    794         &&  !strcmp(argv[1], "--pagefusionfork"))
     801        &&  !RTStrICmp(argv[1], "pagefusion"))
    795802        return VBoxServicePageSharingInitFork();
    796803#endif
    797804
    798     char szLogFile[RTPATH_MAX + 128] = "";
     805    /*
     806     * Check if we're the specially spawned VBoxService.exe process that
     807     * handles a guest control session.
     808     */
     809    if (    argc >= 2
     810        &&  !RTStrICmp(argv[1], "guestsession"))
     811        return VBoxServiceControlSessionForkInit(argc, argv);
    799812
    800813    /*
     
    926939                {
    927940                    rc = VBoxServiceArgString(argc, argv, psz + 1, &i,
    928                                               szLogFile, sizeof(szLogFile));
     941                                              g_szLogFile, sizeof(g_szLogFile));
    929942                    if (rc)
    930943                        return rc;
     
    961974        return RTMsgErrorExit(RTEXITCODE_SYNTAX, "At least one service must be enabled\n");
    962975
    963     rc = VBoxServiceLogCreate(strlen(szLogFile) ? szLogFile : NULL);
     976    rc = VBoxServiceLogCreate(strlen(g_szLogFile) ? g_szLogFile : NULL);
    964977    if (RT_FAILURE(rc))
    965978        return RTMsgErrorExit(RTEXITCODE_FAILURE, "Failed to create release log (%s, %Rrc)",
    966                               strlen(szLogFile) ? szLogFile : "<None>", rc);
     979                              strlen(g_szLogFile) ? g_szLogFile : "<None>", rc);
    967980
    968981    /* Call pre-init if we didn't do it already. */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp

    r44248 r44863  
    2222#include <iprt/asm.h>
    2323#include <iprt/assert.h>
     24#include <iprt/env.h>
    2425#include <iprt/file.h>
    2526#include <iprt/getopt.h>
    2627#include <iprt/mem.h>
    2728#include <iprt/path.h>
     29#include <iprt/process.h>
    2830#include <iprt/semaphore.h>
    2931#include <iprt/thread.h>
     
    3133#include <VBox/HostServices/GuestControlSvc.h>
    3234#include "VBoxServiceInternal.h"
     35#include "VBoxServiceControl.h"
    3336#include "VBoxServiceUtils.h"
    3437
     
    4245/** The semaphore we're blocking our main control thread on. */
    4346static RTSEMEVENTMULTI      g_hControlEvent = NIL_RTSEMEVENTMULTI;
     47/** The VM session ID. Changes whenever the VM is restored or reset. */
     48static uint64_t             g_idControlSession;
    4449/** The guest control service client ID. */
    4550static uint32_t             g_uControlSvcClientID = 0;
     
    5863/** Critical section protecting g_GuestControlExecThreads. */
    5964static RTCRITSECT           g_csControlThreads;
    60 /** List of guest control files (VBOXSERVICECTRLFILE).
    61  **@todo Use a map (later). */
    62 static RTLISTANCHOR         g_lstControlFiles;
    63 /** The internal file count for building our internal file handles.
    64  *  Should be enough for now. */
    65 static uint32_t             g_uControlFileCount = 0;
    66 
     65/** List of guest control sessions (VBOXSERVICECTRLSESSION). */
     66RTLISTANCHOR                g_lstControlSessions;
    6767
    6868/*******************************************************************************
    6969*   Internal Functions                                                         *
    7070*******************************************************************************/
    71 /** @todo Shorten "VBoxServiceControl" to "gstsvcCntl". */
    72 static int gstcntlReapThreads(void);
    73 static int gstcntlStartAllowed(bool *pbAllowed);
    74 static int gstcntlHandleCmdStartProc(uint32_t u32ClientId, uint32_t uNumParms);
    75 static int gstcntlHandleCmdSetInput(uint32_t u32ClientId, uint32_t uNumParms, void *pvScratchBuf, size_t cbScratchBuf);
    76 static int gstcntlHandleCmdGetOutput(uint32_t u32ClientId, uint32_t uNumParms);
    77 static int gstcntlHandleFileOpen(uint32_t idClient, uint32_t cParms);
    78 static int gstcntlHandleFileClose(uint32_t idClient, uint32_t cParms);
    79 static int gstcntlHandleFileRead(uint32_t idClient, uint32_t cParms);
    80 static int gstcntlHandleFileWrite(uint32_t idClient, uint32_t cParms, void *pvScratchBuf, size_t cbScratchBuf);
    81 static int gstcntlHandleFileSeek(uint32_t idClient, uint32_t cParms);
    82 static int gstcntlHandleFileTell(uint32_t idClient, uint32_t cParms);
     71static int  gstcntlHandleSessionOpen(PVBGLR3GUESTCTRLHOSTCTX pHostCtx);
     72static int  gstcntlHandleSessionClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx);
     73static int  gstcntlHandleProcExec(PVBGLR3GUESTCTRLHOSTCTX pHostCtx);
     74static int  gstcntlHandleProcInput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf);
     75static int  gstcntlHandleProcOutput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx);
     76static int  gstcntlHandleProcTerminate(PVBGLR3GUESTCTRLHOSTCTX pHostCtx);
     77static int  gstcntlHandleProcWaitFor(PVBGLR3GUESTCTRLHOSTCTX pHostCtx);
     78static int  gstcntlReapThreads(void);
     79static void VBoxServiceControlShutdown(void);
     80static int  vboxServiceControlProcessCloseAll(void);
     81static int  gstcntlStartAllowed(bool *pbAllowed);
    8382
    8483#ifdef DEBUG
     
    137136    else
    138137    {
    139         rc = VBoxServiceReadPropUInt32(uGuestPropSvcClientID, "/VirtualBox/GuestAdd/VBoxService/--control-procs-max-kept",
    140                                        &g_uControlProcsMaxKept, 0, UINT32_MAX - 1);
    141 
    142138        VbglR3GuestPropDisconnect(uGuestPropSvcClientID);
    143139    }
     
    162158        rc = VBoxServiceArgUInt32(argc, argv, "", pi,
    163159                                  &g_uControlIntervalMS, 1, UINT32_MAX - 1);
    164     else if (!strcmp(argv[*pi], "--control-procs-max-kept"))
    165         rc = VBoxServiceArgUInt32(argc, argv, "", pi,
    166                                   &g_uControlProcsMaxKept, 0, UINT32_MAX - 1);
    167160#ifdef DEBUG
    168161    else if (!strcmp(argv[*pi], "--control-dump-stderr"))
     
    194187    AssertRCReturn(rc, rc);
    195188
     189    VbglR3GetSessionId(&g_idControlSession);
     190    /* The status code is ignored as this information is not available with VBox < 3.2.10. */
     191
    196192    rc = VbglR3GuestCtrlConnect(&g_uControlSvcClientID);
    197193    if (RT_SUCCESS(rc))
     
    202198        RTListInit(&g_lstControlThreadsActive);
    203199        RTListInit(&g_lstControlThreadsInactive);
    204         RTListInit(&g_lstControlFiles);
     200        RTListInit(&g_lstControlSessions);
    205201
    206202        /* Init critical section for protecting the thread lists. */
     
    245241    AssertPtrReturn(pvScratchBuf, VERR_NO_MEMORY);
    246242
    247     /*
    248      * Execution loop.
    249      *
    250      * @todo
    251      */
     243    VBGLR3GUESTCTRLHOSTCTX ctxHost = { g_uControlSvcClientID,
     244                                       1 /* Default protocol version */ };
    252245    for (;;)
    253246    {
     
    255248        uint32_t uMsg = 0;
    256249        uint32_t cParms = 0;
    257         rc = VbglR3GuestCtrlWaitForHostMsg(g_uControlSvcClientID, &uMsg, &cParms);
     250        rc = VbglR3GuestCtrlMsgWaitFor(g_uControlSvcClientID, &uMsg, &cParms);
    258251        if (rc == VERR_TOO_MUCH_DATA)
    259252        {
     
    266259        {
    267260            VBoxServiceVerbose(3, "Msg=%u (%u parms) retrieved\n", uMsg, cParms);
     261
     262            /* Set number of parameters for current host context. */
     263            ctxHost.uNumParms = cParms;
     264
     265            /* Check for VM session change. */
     266            uint64_t idNewSession = g_idControlSession;
     267            int rc2 = VbglR3GetSessionId(&idNewSession);
     268            if (   RT_SUCCESS(rc2)
     269                && (idNewSession != g_idControlSession))
     270            {
     271                VBoxServiceVerbose(1, "The VM session ID changed\n");
     272                g_idControlSession = idNewSession;
     273
     274                /* Close all opened guest sessions -- all context IDs, sessions etc.
     275                 * are now invalid. */
     276                rc2 = vboxServiceControlProcessCloseAll();
     277                AssertRC(rc2);
     278            }
     279
    268280            switch (uMsg)
    269281            {
    270282                case HOST_CANCEL_PENDING_WAITS:
    271                     VBoxServiceVerbose(3, "Host asked us to quit ...\n");
     283                    VBoxServiceVerbose(1, "We were asked to quit ...\n");
    272284                    break;
    273285
     286                case HOST_SESSION_CREATE:
     287                    rc = gstcntlHandleSessionOpen(&ctxHost);
     288                    break;
     289
     290                case HOST_SESSION_CLOSE:
     291                    rc = gstcntlHandleSessionClose(&ctxHost);
     292                    break;
     293
    274294                case HOST_EXEC_CMD:
    275                     rc = gstcntlHandleCmdStartProc(g_uControlSvcClientID, cParms);
     295                    rc = gstcntlHandleProcExec(&ctxHost);
    276296                    break;
    277297
    278298                case HOST_EXEC_SET_INPUT:
    279                     rc = gstcntlHandleCmdSetInput(g_uControlSvcClientID, cParms,
    280                                                              pvScratchBuf, cbScratchBuf);
     299                    rc = gstcntlHandleProcInput(&ctxHost,
     300                                                pvScratchBuf, cbScratchBuf);
    281301                    break;
    282302
    283303                case HOST_EXEC_GET_OUTPUT:
    284                     rc = gstcntlHandleCmdGetOutput(g_uControlSvcClientID, cParms);
     304                    rc = gstcntlHandleProcOutput(&ctxHost);
    285305                    break;
    286306
    287                case HOST_FILE_OPEN:
    288                     rc = gstcntlHandleFileOpen(g_uControlSvcClientID, cParms);
     307                case HOST_EXEC_TERMINATE:
     308                    rc = gstcntlHandleProcTerminate(&ctxHost);
    289309                    break;
    290310
    291                 case HOST_FILE_CLOSE:
    292                     rc = gstcntlHandleFileClose(g_uControlSvcClientID, cParms);
    293                     break;
    294 
    295                 case HOST_FILE_READ:
    296                     rc = gstcntlHandleFileRead(g_uControlSvcClientID, cParms);
    297                     break;
    298 
    299                 case HOST_FILE_WRITE:
    300                     rc = gstcntlHandleFileWrite(g_uControlSvcClientID, cParms,
    301                                                            pvScratchBuf, cbScratchBuf);
    302                     break;
    303 
    304                 case HOST_FILE_SEEK:
    305                     rc = gstcntlHandleFileSeek(g_uControlSvcClientID, cParms);
    306                     break;
    307 
    308                 case HOST_FILE_TELL:
    309                     rc = gstcntlHandleFileTell(g_uControlSvcClientID, cParms);
     311                case HOST_EXEC_WAIT_FOR:
     312                    rc = gstcntlHandleProcWaitFor(&ctxHost);
    310313                    break;
    311314
     
    321324            || (RT_SUCCESS(rc) && uMsg == HOST_CANCEL_PENDING_WAITS))
    322325        {
    323             rc = VINF_SUCCESS;
    324326            break;
    325327        }
     
    328330        RTThreadYield();
    329331    }
     332
     333    VBoxServiceVerbose(0, "Guest control service stopped\n");
    330334
    331335    /* Delete scratch buffer. */
     
    333337        RTMemFree(pvScratchBuf);
    334338
     339    VBoxServiceVerbose(0, "Guest control worker returned with rc=%Rrc\n", rc);
    335340    return rc;
    336341}
     
    344349 * @param   cParms          The number of parameters the host is offering.
    345350 */
    346 static int gstcntlHandleCmdStartProc(uint32_t uClientID, uint32_t cParms)
    347 {
    348     uint32_t uContextID = 0;
     351static int gstcntlHandleProcExec(PVBGLR3GUESTCTRLHOSTCTX pHostCtx)
     352{
     353    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
    349354
    350355    int rc;
    351356    bool fStartAllowed = false; /* Flag indicating whether starting a process is allowed or not. */
    352     if (cParms == 11)
    353     {
    354         VBOXSERVICECTRLPROCESS proc;
     357
     358    if (   (pHostCtx->uProtocol < 2  && pHostCtx->uNumParms == 11)
     359        || (pHostCtx->uProtocol >= 2 && pHostCtx->uNumParms == 12)
     360       )
     361    {
     362        VBOXSERVICECTRLPROCSTARTUPINFO proc;
    355363        RT_ZERO(proc);
    356364
     
    360368        proc.cbEnv = sizeof(proc.szEnv);
    361369
    362         rc = VbglR3GuestCtrlExecGetHostCmdExec(uClientID,
    363                                                cParms,
    364                                                &uContextID,
    365                                                /* Command */
    366                                                proc.szCmd,      sizeof(proc.szCmd),
    367                                                /* Flags */
    368                                                &proc.uFlags,
    369                                                /* Arguments */
    370                                                proc.szArgs,     sizeof(proc.szArgs), &proc.uNumArgs,
    371                                                /* Environment */
    372                                                proc.szEnv, &proc.cbEnv, &proc.uNumEnvVars,
    373                                                /* Credentials */
    374                                                proc.szUser,     sizeof(proc.szUser),
    375                                                proc.szPassword, sizeof(proc.szPassword),
    376                                                /* Timelimit */
    377                                                &proc.uTimeLimitMS);
    378         if (RT_SUCCESS(rc))
    379         {
    380             VBoxServiceVerbose(3, "Request to start process szCmd=%s, uFlags=0x%x, szArgs=%s, szEnv=%s, szUser=%s, szPassword=%s, uTimeout=%u\n",
     370        rc = VbglR3GuestCtrlProcGetStart(pHostCtx,
     371                                         /* Command */
     372                                         proc.szCmd,      sizeof(proc.szCmd),
     373                                         /* Flags */
     374                                         &proc.uFlags,
     375                                         /* Arguments */
     376                                         proc.szArgs,     sizeof(proc.szArgs), &proc.uNumArgs,
     377                                         /* Environment */
     378                                         proc.szEnv, &proc.cbEnv, &proc.uNumEnvVars,
     379                                         /* Credentials; for hosts with VBox < 4.3. */
     380                                         proc.szUser,     sizeof(proc.szUser),
     381                                         proc.szPassword, sizeof(proc.szPassword),
     382                                         /* Timelimit */
     383                                         &proc.uTimeLimitMS,
     384                                         /* Process priority */
     385                                         &proc.uPriority,
     386                                         /* Process affinity */
     387                                         proc.uAffinity,  sizeof(proc.uAffinity), &proc.uNumAffinity);
     388        if (RT_SUCCESS(rc))
     389        {
     390            VBoxServiceVerbose(3, "Request to start process szCmd=%s, uFlags=0x%x, szArgs=%s, szEnv=%s, szUser=%s, szPassword=%s, uTimeout=%RU32\n",
    381391                               proc.szCmd, proc.uFlags,
    382392                               proc.uNumArgs ? proc.szArgs : "<None>",
     
    400410                if (fStartAllowed)
    401411                {
    402                     rc = GstCntlProcessStart(uContextID, &proc);
     412                    rc = GstCntlProcessStart(pHostCtx->uContextID, &proc);
    403413                }
    404414                else
     
    408418    }
    409419    else
    410         rc = VERR_INVALID_PARAMETER; /* Incorrect number of parameters. */
     420        rc = VERR_NOT_SUPPORTED; /* Unsupported number of parameters. */
    411421
    412422    /* In case of an error we need to notify the host to not wait forever for our response. */
     
    419429         *       from the host. The host in case has to deal with that!
    420430         */
    421         int rc2 = VbglR3GuestCtrlExecReportStatus(uClientID, uContextID /* Might be 0 */, 0 /* PID, invalid */,
    422                                                   PROC_STS_ERROR, rc,
    423                                                   NULL /* pvData */, 0 /* cbData */);
     431        int rc2 = VbglR3GuestCtrlProcCbStatus(pHostCtx->uClientID, pHostCtx->uContextID,
     432                                              0 /* PID, invalid */,
     433                                              PROC_STS_ERROR, rc,
     434                                              NULL /* pvData */, 0 /* cbData */);
    424435        if (RT_FAILURE(rc2))
    425436        {
     
    427438            if (RT_SUCCESS(rc))
    428439                rc = rc2;
     440        }
     441    }
     442
     443    return rc;
     444}
     445
     446
     447static int gstcntlHandleProcTerminate(PVBGLR3GUESTCTRLHOSTCTX pHostCtx)
     448{
     449    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     450
     451    uint32_t uPID;
     452    int rc = VbglR3GuestCtrlProcGetTerminate(pHostCtx, &uPID);
     453    if (RT_SUCCESS(rc))
     454    {
     455        PVBOXSERVICECTRLREQUEST pRequest;
     456        rc = GstCntlProcessRequestAllocEx(&pRequest, VBOXSERVICECTRLREQUEST_PROC_TERM,
     457                                          NULL /* pvBuf */, NULL /* cbBuf */, pHostCtx->uContextID);
     458        if (RT_SUCCESS(rc))
     459        {
     460            rc = GstCntlProcessPerform(uPID, pRequest);
     461            GstCntlProcessRequestFree(pRequest);
     462        }
     463    }
     464
     465    return rc;
     466}
     467
     468
     469static int gstcntlHandleProcWaitFor(PVBGLR3GUESTCTRLHOSTCTX pHostCtx)
     470{
     471    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     472
     473    uint32_t uPID;
     474    uint32_t uWaitFlags; uint32_t uTimeoutMS;
     475
     476    int rc = VbglR3GuestCtrlProcGetWaitFor(pHostCtx, &uPID, &uWaitFlags, &uTimeoutMS);
     477    if (RT_SUCCESS(rc))
     478    {
     479        PVBOXSERVICECTRLREQUEST pRequest;
     480        VBOXSERVICECTRLREQDATA_WAIT_FOR reqData = { uWaitFlags, uTimeoutMS };
     481        rc = GstCntlProcessRequestAllocEx(&pRequest, VBOXSERVICECTRLREQUEST_WAIT_FOR,
     482                                          &reqData, sizeof(reqData), pHostCtx->uContextID);
     483        if (RT_SUCCESS(rc))
     484        {
     485            rc = GstCntlProcessPerform(uPID, pRequest);
     486            GstCntlProcessRequestFree(pRequest);
    429487        }
    430488    }
     
    439497 * @return  IPRT status code.
    440498 * @param   uPID                    PID of process to retrieve the output from.
     499 * @param   uCID                    Context ID.
    441500 * @param   uHandleId               Stream ID (stdout = 0, stderr = 2) to get the output from.
    442501 * @param   cMsTimeout              Timeout (in ms) to wait for output becoming
     
    459518    {
    460519        case OUTPUT_HANDLE_ID_STDERR:
    461             reqType = VBOXSERVICECTRLREQUEST_STDERR_READ;
     520            reqType = VBOXSERVICECTRLREQUEST_PROC_STDERR;
    462521            break;
    463522
    464523        case OUTPUT_HANDLE_ID_STDOUT:
    465524        case OUTPUT_HANDLE_ID_STDOUT_DEPRECATED:
    466             reqType = VBOXSERVICECTRLREQUEST_STDOUT_READ;
     525            reqType = VBOXSERVICECTRLREQUEST_PROC_STDOUT;
    467526            break;
    468527
     
    505564    if (RT_SUCCESS(rc))
    506565    {
    507         VBoxServiceVerbose(3, "Setting thread (PID %u) to list %d\n",
     566        VBoxServiceVerbose(3, "Setting thread (PID %RU32) to list %d\n",
    508567                           pThread->uPID, enmList);
    509568
     
    572631    int rc = GstCntlProcessRequestAllocEx(&pRequest,
    573632                                          fPendingClose
    574                                           ? VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF
    575                                           : VBOXSERVICECTRLREQUEST_STDIN_WRITE,
     633                                          ? VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF
     634                                          : VBOXSERVICECTRLREQUEST_PROC_STDIN,
    576635                                          pvBuf, cbBuf, uCID);
    577636    if (RT_SUCCESS(rc))
     
    596655 *
    597656 * @returns IPRT status code.
    598  * @param   idClient                    The HGCM client session ID.
    599  * @param   cParms                      The number of parameters the host is
    600  *                                      offering.
    601657 * @param   pvScratchBuf                The scratch buffer.
    602658 * @param   cbScratchBuf                The scratch buffer size for retrieving the input data.
    603659 */
    604 static int gstcntlHandleCmdSetInput(uint32_t idClient, uint32_t cParms,
    605                                     void *pvScratchBuf, size_t cbScratchBuf)
    606 {
     660static int gstcntlHandleProcInput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx,
     661                                  void *pvScratchBuf, size_t cbScratchBuf)
     662{
     663    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
    607664    AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);
    608665    AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
    609666
    610     uint32_t uContextID;
    611667    uint32_t uPID;
    612668    uint32_t uFlags;
     
    619675     * Ask the host for the input data.
    620676     */
    621     int rc = VbglR3GuestCtrlExecGetHostCmdInput(idClient, cParms,
    622                                                 &uContextID, &uPID, &uFlags,
    623                                                 pvScratchBuf, cbScratchBuf, &cbSize);
     677    int rc = VbglR3GuestCtrlProcGetInput(pHostCtx, &uPID, &uFlags,
     678                                         pvScratchBuf, cbScratchBuf, &cbSize);
    624679    if (RT_FAILURE(rc))
    625680    {
    626         VBoxServiceError("[PID %u]: Failed to retrieve exec input command! Error: %Rrc\n",
     681        VBoxServiceError("[PID %RU32]: Failed to retrieve exec input command! Error: %Rrc\n",
    627682                         uPID, rc);
    628683    }
    629684    else if (cbSize > cbScratchBuf)
    630685    {
    631         VBoxServiceError("[PID %u]: Too much input received! cbSize=%u, cbScratchBuf=%u\n",
     686        VBoxServiceError("[PID %RU32]: Too much input received! cbSize=%u, cbScratchBuf=%u\n",
    632687                         uPID, cbSize, cbScratchBuf);
    633688        rc = VERR_INVALID_PARAMETER;
     
    642697        {
    643698            fPendingClose = true;
    644             VBoxServiceVerbose(4, "[PID %u]: Got last input block of size %u ...\n",
     699            VBoxServiceVerbose(4, "[PID %RU32]: Got last input block of size %u ...\n",
    645700                               uPID, cbSize);
    646701        }
    647702
    648         rc = VBoxServiceControlSetInput(uPID, uContextID, fPendingClose, pvScratchBuf,
     703        rc = VBoxServiceControlSetInput(uPID, pHostCtx->uContextID, fPendingClose, pvScratchBuf,
    649704                                        cbSize, &cbWritten);
    650         VBoxServiceVerbose(4, "[PID %u]: Written input, CID=%u, rc=%Rrc, uFlags=0x%x, fPendingClose=%d, cbSize=%u, cbWritten=%u\n",
    651                            uPID, uContextID, rc, uFlags, fPendingClose, cbSize, cbWritten);
     705        VBoxServiceVerbose(4, "[PID %RU32]: Written input, CID=%u, rc=%Rrc, uFlags=0x%x, fPendingClose=%d, cbSize=%u, cbWritten=%u\n",
     706                           uPID, pHostCtx->uContextID, rc, uFlags, fPendingClose, cbSize, cbWritten);
    652707        if (RT_SUCCESS(rc))
    653708        {
     
    676731    Assert(uStatus > INPUT_STS_UNDEFINED);
    677732
    678     VBoxServiceVerbose(3, "[PID %u]: Input processed, CID=%u, uStatus=%u, uFlags=0x%x, cbWritten=%u\n",
    679                        uPID, uContextID, uStatus, uFlags, cbWritten);
     733    VBoxServiceVerbose(3, "[PID %RU32]: Input processed, CID=%u, uStatus=%u, uFlags=0x%x, cbWritten=%u\n",
     734                       uPID, pHostCtx->uContextID, uStatus, uFlags, cbWritten);
    680735
    681736    /* Note: Since the context ID is unique the request *has* to be completed here,
    682737     *       regardless whether we got data or not! Otherwise the progress object
    683738     *       on the host never will get completed! */
    684     rc = VbglR3GuestCtrlExecReportStatusIn(idClient, uContextID, uPID,
    685                                            uStatus, uFlags, (uint32_t)cbWritten);
     739    rc = VbglR3GuestCtrlProcCbStatusInput(pHostCtx->uClientID, pHostCtx->uContextID, uPID,
     740                                          uStatus, uFlags, (uint32_t)cbWritten);
    686741
    687742    if (RT_FAILURE(rc))
    688         VBoxServiceError("[PID %u]: Failed to report input status! Error: %Rrc\n",
     743        VBoxServiceError("[PID %RU32]: Failed to report input status! Error: %Rrc\n",
    689744                         uPID, rc);
    690     return rc;
    691 }
    692 
    693 
    694 static PVBOXSERVICECTRLFILE gstcntlGetFile(uint32_t uHandle)
    695 {
    696     PVBOXSERVICECTRLFILE pFileCur = NULL;
    697     /** @todo Use a map later! */
    698     RTListForEach(&g_lstControlFiles, pFileCur, VBOXSERVICECTRLFILE, Node)
    699     {
    700         if (pFileCur->uHandle == uHandle)
    701             return pFileCur;
    702     }
    703 
    704     return NULL;
    705 }
    706 
    707 
    708 static int gstcntlHandleFileOpen(uint32_t idClient, uint32_t cParms)
    709 {
    710     uint32_t uContextID;
    711 
    712     char szFile[RTPATH_MAX];
    713     char szOpenMode[64];
    714     char szDisposition[64];
    715     uint32_t uCreationMode;
    716     uint64_t uOffset;
    717 
    718     int rc = VbglR3GuestCtrlFileGetHostCmdOpen(idClient, cParms, &uContextID,
    719                                                /* File to open. */
    720                                                szFile, sizeof(szFile),
    721                                                /* Open mode. */
    722                                                szOpenMode, sizeof(szOpenMode),
    723                                                /* Disposition. */
    724                                                szDisposition, sizeof(szDisposition),
    725                                                /* Creation mode. */
    726                                                &uCreationMode,
    727                                                /* Offset. */
    728                                                &uOffset);
    729     if (RT_SUCCESS(rc))
    730     {
    731         PVBOXSERVICECTRLFILE pFile = (PVBOXSERVICECTRLFILE)RTMemAlloc(sizeof(VBOXSERVICECTRLFILE));
    732         if (!pFile)
    733             return VERR_NO_MEMORY;
    734 
    735         if (!RTStrPrintf(pFile->szName, sizeof(pFile->szName), "%s", szFile))
    736             rc = VERR_BUFFER_UNDERFLOW;
    737 
    738         if (RT_SUCCESS(rc))
    739         {
    740             uint64_t fFlags = RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_WRITE; /** @todo Modes! */
    741             rc = RTFileOpen(&pFile->hFile, pFile->szName, fFlags);
    742             if (   RT_SUCCESS(rc)
    743                 && uOffset)
    744             {
    745                 /* Seeking is optional. */
    746                 int rc2 = RTFileSeek(pFile->hFile, (int64_t)uOffset, RTFILE_SEEK_BEGIN, NULL /* Current offset */);
    747                 if (RT_FAILURE(rc2))
    748                     VBoxServiceVerbose(3, "[File %s]: Seeking to offset %RU64 failed; rc=%Rrc\n",
    749                                        pFile->szName, uOffset, rc);
    750             }
    751             else
    752                 VBoxServiceVerbose(3, "[File %s]: Opening failed; rc=%Rrc\n",
    753                                    pFile->szName, rc);
    754         }
    755 
    756         uint32_t uHandle = 0;
    757         if (RT_SUCCESS(rc))
    758         {
    759             VBoxServiceVerbose(3, "[File %s]: Opened.\n", pFile->szName);
    760 
    761             uHandle = g_uControlFileCount++;
    762             pFile->uHandle = uHandle;
    763             /* rc = */ RTListAppend(&g_lstControlFiles, &pFile->Node);
    764         }
    765 
    766         if (RT_FAILURE(rc))
    767             RTMemFree(pFile);
    768 
    769         /* Report back in any case. */
    770         int rc2 = VbglR3GuestCtrlFileNotify(idClient, uContextID, uHandle,
    771                                             GUESTFILENOTIFYTYPE_OPEN, &rc, sizeof(rc));
    772         if (RT_FAILURE(rc2))
    773             VBoxServiceError("[File %s]: Failed to report open status, rc=%Rrc\n",
    774                              szFile, rc2);
    775         if (RT_SUCCESS(rc))
    776             rc = rc2;
    777     }
    778     return rc;
    779 }
    780 
    781 
    782 static int gstcntlHandleFileClose(uint32_t idClient, uint32_t cParms)
    783 {
    784     uint32_t uContextID;
    785     uint32_t uHandle;
    786 
    787     int rc = VbglR3GuestCtrlFileGetHostCmdClose(idClient, cParms, &uContextID,
    788                                                 /* File handle to close. */
    789                                                 &uHandle);
    790     if (RT_SUCCESS(rc))
    791     {
    792         PVBOXSERVICECTRLFILE pFile = gstcntlGetFile(uHandle);
    793         if (pFile)
    794         {
    795             rc = RTFileClose(pFile->hFile);
    796         }
    797         else
    798             rc = VERR_NOT_FOUND;
    799 
    800         /* Report back in any case. */
    801         int rc2 = VbglR3GuestCtrlFileNotify(idClient, uContextID, uHandle,
    802                                             GUESTFILENOTIFYTYPE_CLOSE, &rc, sizeof(rc));
    803         if (RT_FAILURE(rc2))
    804             VBoxServiceError("Failed to report close status, rc=%Rrc\n", rc2);
    805         if (RT_SUCCESS(rc))
    806             rc = rc2;
    807     }
    808     return rc;
    809 }
    810 
    811 
    812 static int gstcntlHandleFileRead(uint32_t idClient, uint32_t cParms)
    813 {
    814     uint32_t uContextID;
    815     uint32_t uHandle;
    816     uint32_t cbToRead;
    817 
    818     int rc = VbglR3GuestCtrlFileGetHostCmdRead(idClient, cParms, &uContextID,
    819                                                &uHandle, &cbToRead);
    820     if (RT_SUCCESS(rc))
    821     {
    822 
    823     }
    824     return rc;
    825 }
    826 
    827 
    828 static int gstcntlHandleFileWrite(uint32_t idClient, uint32_t cParms,
    829                                              void *pvScratchBuf, size_t cbScratchBuf)
    830 {
    831     AssertPtrReturn(cbScratchBuf, VERR_INVALID_PARAMETER);
    832     AssertPtrReturn(pvScratchBuf, VERR_INVALID_POINTER);
    833 
    834     uint32_t uContextID;
    835     uint32_t uHandle;
    836     uint32_t cbToWrite;
    837 
    838     int rc = VbglR3GuestCtrlFileGetHostCmdWrite(idClient, cParms, &uContextID,
    839                                                 &uHandle, pvScratchBuf, cbScratchBuf,
    840                                                 &cbToWrite);
    841     if (RT_SUCCESS(rc))
    842     {
    843 
    844     }
    845     return rc;
    846 }
    847 
    848 
    849 static int gstcntlHandleFileSeek(uint32_t idClient, uint32_t cParms)
    850 {
    851     uint32_t uContextID;
    852     uint32_t uHandle;
    853     uint32_t uSeekMethod;
    854     uint64_t uOffset; /* Will be converted to int64_t. */
    855 
    856     int rc = VbglR3GuestCtrlFileGetHostCmdSeek(idClient, cParms, &uContextID,
    857                                                &uHandle, &uSeekMethod, &uOffset);
    858     if (RT_SUCCESS(rc))
    859     {
    860 
    861     }
    862     return rc;
    863 }
    864 
    865 
    866 static int gstcntlHandleFileTell(uint32_t idClient, uint32_t cParms)
    867 {
    868     uint32_t uContextID;
    869     uint32_t uHandle;
    870 
    871     int rc = VbglR3GuestCtrlFileGetHostCmdTell(idClient, cParms, &uContextID,
    872                                                &uHandle);
    873     if (RT_SUCCESS(rc))
    874     {
    875 
    876     }
    877745    return rc;
    878746}
     
    883751 *
    884752 * @return  IPRT status code.
    885  * @param   idClient        The HGCM client session ID.
    886  * @param   cParms          The number of parameters the host is offering.
    887  */
    888 static int gstcntlHandleCmdGetOutput(uint32_t idClient, uint32_t cParms)
    889 {
    890     uint32_t uContextID;
     753 */
     754static int gstcntlHandleProcOutput(PVBGLR3GUESTCTRLHOSTCTX pHostCtx)
     755{
     756    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     757
    891758    uint32_t uPID;
    892759    uint32_t uHandleID;
    893760    uint32_t uFlags;
    894761
    895     int rc = VbglR3GuestCtrlExecGetHostCmdOutput(idClient, cParms,
    896                                                  &uContextID, &uPID, &uHandleID, &uFlags);
     762    int rc = VbglR3GuestCtrlProcGetOutput(pHostCtx, &uPID, &uHandleID, &uFlags);
    897763    if (RT_SUCCESS(rc))
    898764    {
     
    901767        {
    902768            uint32_t cbRead = 0;
    903             rc = VBoxServiceControlExecGetOutput(uPID, uContextID, uHandleID, RT_INDEFINITE_WAIT /* Timeout */,
     769            rc = VBoxServiceControlExecGetOutput(uPID, pHostCtx->uContextID, uHandleID, RT_INDEFINITE_WAIT /* Timeout */,
    904770                                                 pBuf, _64K /* cbSize */, &cbRead);
    905             VBoxServiceVerbose(3, "[PID %u]: Got output, rc=%Rrc, CID=%u, cbRead=%u, uHandle=%u, uFlags=%u\n",
    906                                uPID, rc, uContextID, cbRead, uHandleID, uFlags);
     771            VBoxServiceVerbose(3, "[PID %RU32]: Got output, rc=%Rrc, CID=%u, cbRead=%u, uHandle=%u, uFlags=%u\n",
     772                               uPID, rc, pHostCtx->uContextID, cbRead, uHandleID, uFlags);
    907773
    908774#ifdef DEBUG
     
    934800             *       regardless whether we got data or not! Otherwise the progress object
    935801             *       on the host never will get completed! */
    936             int rc2 = VbglR3GuestCtrlExecSendOut(idClient, uContextID, uPID, uHandleID, uFlags,
    937                                                  pBuf, cbRead);
     802            int rc2 = VbglR3GuestCtrlProcCbOutput(pHostCtx->uClientID, pHostCtx->uContextID, uPID, uHandleID, uFlags,
     803                                                  pBuf, cbRead);
    938804            if (RT_SUCCESS(rc))
    939805                rc = rc2;
     
    948814
    949815    if (RT_FAILURE(rc))
    950         VBoxServiceError("[PID %u]: Error handling output command! Error: %Rrc\n",
     816        VBoxServiceError("[PID %RU32]: Error handling output command! Error: %Rrc\n",
    951817                         uPID, rc);
     818    return rc;
     819}
     820
     821
     822static int gstcntlHandleSessionOpen(PVBGLR3GUESTCTRLHOSTCTX pHostCtx)
     823{
     824    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     825
     826    VBOXSERVICECTRLSESSIONSTARTUPINFO ssInfo = { 0 };
     827    int rc = VbglR3GuestCtrlSessionGetOpen(pHostCtx,
     828                                           &ssInfo.uProtocol,
     829                                           ssInfo.szUser,     sizeof(ssInfo.szUser),
     830                                           ssInfo.szPassword, sizeof(ssInfo.szPassword),
     831                                           ssInfo.szDomain,   sizeof(ssInfo.szDomain),
     832                                           &ssInfo.uFlags,    &ssInfo.uSessionID);
     833    if (RT_SUCCESS(rc))
     834    {
     835        /* The session open call has the protocol version the host
     836         * wants to use. Store it in the host context for later calls. */
     837        pHostCtx->uProtocol = ssInfo.uProtocol;
     838
     839        rc = GstCntlSessionOpen(&ssInfo, NULL /* Node */);
     840    }
     841
     842    /* Report back session opening status in any case. */
     843    int rc2 = VbglR3GuestCtrlSessionNotify(pHostCtx->uClientID, pHostCtx->uContextID,
     844                                           GUEST_SESSION_NOTIFYTYPE_OPEN, rc /* uint32_t vs. int */);
     845    if (RT_FAILURE(rc2))
     846    {
     847        VBoxServiceError("Reporting session opening status failed with rc=%Rrc\n", rc2);
     848        if (RT_SUCCESS(rc))
     849            rc = rc2;
     850    }
     851
     852    VBoxServiceVerbose(3, "Opening a new guest session returned rc=%Rrc\n", rc);
     853    return rc;
     854}
     855
     856
     857static int gstcntlHandleSessionClose(PVBGLR3GUESTCTRLHOSTCTX pHostCtx)
     858{
     859    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     860
     861    uint32_t uSessionID, uFlags;
     862
     863    int rc = VbglR3GuestCtrlSessionGetClose(pHostCtx, &uFlags, &uSessionID);
     864    if (RT_SUCCESS(rc))
     865    {
     866        rc = VERR_NOT_FOUND;
     867
     868        PVBOXSERVICECTRLSESSION pSession;
     869        RTListForEach(&g_lstControlSessions, pSession, VBOXSERVICECTRLSESSION, Node)
     870        {
     871            if (pSession->StartupInfo.uSessionID == uSessionID)
     872            {
     873                rc = GstCntlSessionClose(pSession, uFlags);
     874                break;
     875            }
     876        }
     877    }
     878
     879    /* Report back session closing status in any case. */
     880    int rc2 = VbglR3GuestCtrlSessionNotify(pHostCtx->uClientID, pHostCtx->uContextID,
     881                                           GUEST_SESSION_NOTIFYTYPE_CLOSE, rc /* uint32_t vs. int */);
     882    if (RT_FAILURE(rc2))
     883    {
     884        VBoxServiceError("Reporting session closing status failed with rc=%Rrc\n", rc2);
     885        if (RT_SUCCESS(rc))
     886            rc = rc2;
     887    }
     888
     889    VBoxServiceVerbose(2, "Closing guest session %RU32 returned rc=%Rrc\n",
     890                       uSessionID, rc);
    952891    return rc;
    953892}
     
    1030969
    1031970
    1032 /**
    1033  * Destroys all guest process threads which are still active.
    1034  */
    1035 static void VBoxServiceControlShutdown(void)
    1036 {
    1037     VBoxServiceVerbose(2, "Shutting down ...\n");
     971static int vboxServiceControlProcessClose()
     972{
     973    /** Note: This will be a guest tsession task later. */
    1038974
    1039975    /* Signal all threads in the active list that we want to shutdown. */
     
    1053989                                     NULL /* rc */);
    1054990        if (RT_FAILURE(rc2))
     991        {
    1055992            VBoxServiceError("Guest process thread failed to stop; rc=%Rrc\n", rc2);
     993            /* Keep going. */
     994        }
    1056995
    1057996        if (fLast)
     
    10611000    }
    10621001
    1063     int rc2 = gstcntlReapThreads();
    1064     if (RT_FAILURE(rc2))
    1065         VBoxServiceError("Reaping inactive threads failed with rc=%Rrc\n", rc2);
     1002    int rc = gstcntlReapThreads();
     1003    if (RT_FAILURE(rc))
     1004        VBoxServiceError("Reaping inactive threads failed with rc=%Rrc\n", rc);
    10661005
    10671006    AssertMsg(RTListIsEmpty(&g_lstControlThreadsActive),
     
    10701009              ("Guest process inactive thread list still contains entries when it should not\n"));
    10711010
     1011    return rc;
     1012}
     1013
     1014
     1015static int vboxServiceControlProcessCloseAll(void)
     1016{
     1017    return vboxServiceControlProcessClose();
     1018}
     1019
     1020
     1021/**
     1022 * Destroys all guest process threads which are still active.
     1023 */
     1024static void VBoxServiceControlShutdown(void)
     1025{
     1026    VBoxServiceVerbose(2, "Shutting down ...\n");
     1027
     1028    int rc2 = vboxServiceControlProcessCloseAll();
     1029    AssertRC(rc2);
     1030
    10721031    /* Destroy critical section. */
    10731032    RTCritSectDelete(&g_csControlThreads);
    1074 
    1075     /* Close all left guest files. */
    1076     PVBOXSERVICECTRLFILE pFile;
    1077     pFile = RTListGetFirst(&g_lstControlFiles, VBOXSERVICECTRLFILE, Node);
    1078     while (pFile)
    1079     {
    1080         PVBOXSERVICECTRLFILE pNext = RTListNodeGetNext(&pFile->Node, VBOXSERVICECTRLFILE, Node);
    1081         bool fLast = RTListNodeIsLast(&g_lstControlFiles, &pFile->Node);
    1082 
    1083         rc2 = RTFileClose(pFile->hFile);
    1084         if (RT_FAILURE(rc2))
    1085         {
    1086             VBoxServiceError("Unable to close file \"%s\"; rc=%Rrc\n",
    1087                              pFile->szName, rc2);
    1088             /* Keep going. */
    1089         }
    1090 
    1091         RTListNodeRemove(&pFile->Node);
    1092 
    1093         if (fLast)
    1094             break;
    1095 
    1096         pFile = pNext;
    1097     }
    1098 
    1099     AssertMsg(RTListIsEmpty(&g_lstControlFiles),
    1100               ("Guest file list still contains entries when it should not\n"));
    11011033
    11021034    VBoxServiceVerbose(2, "Shutting down complete\n");
     
    12511183                    uint32_t uTriedPID = uPID;
    12521184                    uPID += 391939;
    1253                     VBoxServiceVerbose(2, "PID %u was used before, trying again with %u ...\n",
     1185                    VBoxServiceVerbose(2, "PID %RU32 was used before, trying again with %u ...\n",
    12541186                                       uTriedPID, uPID);
    12551187                    fTryAgain = true;
     
    12831215    "              [--control-dump-stderr] [--control-dump-stdout]\n"
    12841216#endif
    1285     "              [--control-interval <ms>] [--control-procs-max-kept <x>]\n"
     1217    "              [--control-interval <ms>]\n"
    12861218    "              [--control-procs-mem-std[in|out|err] <KB>]"
    12871219    ,
     
    12951227    "    --control-interval      Specifies the interval at which to check for\n"
    12961228    "                            new control commands. The default is 1000 ms.\n"
    1297     "    --control-procs-max-kept\n"
    1298     "                            Specifies how many started guest processes are\n"
    1299     "                            kept into memory to work with. Default is 256.\n"
    13001229    ,
    13011230    /* methods */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlThread.cpp

    r44248 r44863  
    11/* $Id$ */
    22/** @file
    3  * VBoxServiceControlExecThread - Thread for every started guest process.
     3 * VBoxServiceControlThread - Guest process handling.
    44 */
    55
     
    3939
    4040#include "VBoxServiceInternal.h"
     41#include "VBoxServiceControl.h"
    4142
    4243using namespace guestControl;
     
    423424
    424425
     426/**
     427 * Signals the given request.
     428 *
     429 * @return  IPRT status code.
     430 * @param   pRequest                Pointer to request to signal.
     431 * @param   rc                      rc to set request result to.
     432 */
     433static int gstcntlProcessSignalRequest(PVBOXSERVICECTRLREQUEST pRequest, int rc)
     434{
     435    AssertPtrReturn(pRequest, VERR_INVALID_POINTER);
     436
     437    /* Assign overall result. */
     438    pRequest->rc = rc;
     439
     440#ifdef _DEBUG
     441    VBoxServiceVerbose(4, "Handled req=%u, CID=%u, rc=%Rrc, cbData=%u, pvData=%p\n",
     442                       pRequest->enmType, pRequest->uCID, pRequest->rc,
     443                       pRequest->cbData, pRequest->pvData);
     444#endif
     445
     446    /* In any case, regardless of the result, we notify
     447     * the main guest control to unblock it. */
     448    int rc2 = RTSemEventMultiSignal(pRequest->Event);
     449    AssertRC(rc2);
     450
     451    return rc2;
     452}
     453
     454
    425455static int gstcntlProcessHandleRequest(RTPOLLSET hPollSet, uint32_t fPollEvt,
    426456                                       PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR,
    427                                        PVBOXSERVICECTRLTHREAD pThread)
    428 {
    429     AssertPtrReturn(pThread, VERR_INVALID_POINTER);
     457                                       PVBOXSERVICECTRLTHREAD pThread, PVBOXSERVICECTRLREQUEST pRequest)
     458{
    430459    AssertPtrReturn(phStdInW, VERR_INVALID_POINTER);
    431460    AssertPtrReturn(phStdOutR, VERR_INVALID_POINTER);
    432461    AssertPtrReturn(phStdErrR, VERR_INVALID_POINTER);
     462    AssertPtrReturn(pThread, VERR_INVALID_POINTER);
     463    AssertPtrReturn(pRequest, VERR_INVALID_POINTER);
    433464
    434465    /* Drain the notification pipe. */
     
    439470        VBoxServiceError("Draining IPC notification pipe failed with rc=%Rrc\n", rc);
    440471
     472    bool fDefer = false; /* Whether the request completion should be deferred or not. */
    441473    int rcReq = VINF_SUCCESS; /* Actual request result. */
    442 
    443     PVBOXSERVICECTRLREQUEST pRequest = pThread->pRequest;
    444     if (!pRequest)
    445     {
    446         VBoxServiceError("IPC request is invalid\n");
    447         return VERR_INVALID_POINTER;
    448     }
    449474
    450475    switch (pRequest->enmType)
     
    459484        }
    460485
    461         case VBOXSERVICECTRLREQUEST_STDIN_WRITE:
    462         case VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF:
     486        case VBOXSERVICECTRLREQUEST_PROC_STDIN:
     487        case VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF:
    463488        {
    464489            size_t cbWritten = 0;
     
    480505             * the poll set.
    481506             */
    482             if (   pRequest->enmType == VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF
     507            if (   pRequest->enmType == VBOXSERVICECTRLREQUEST_PROC_STDIN_EOF
    483508                && pRequest->cbData  == cbWritten)
    484509            {
     
    491516        }
    492517
    493         case VBOXSERVICECTRLREQUEST_STDOUT_READ:
    494         case VBOXSERVICECTRLREQUEST_STDERR_READ:
     518        case VBOXSERVICECTRLREQUEST_PROC_STDOUT:
     519        case VBOXSERVICECTRLREQUEST_PROC_STDERR:
    495520        {
    496521            AssertPtrReturn(pRequest->pvData, VERR_INVALID_POINTER);
    497522            AssertReturn(pRequest->cbData, VERR_INVALID_PARAMETER);
    498523
    499             PRTPIPE pPipeR = pRequest->enmType == VBOXSERVICECTRLREQUEST_STDERR_READ
     524            PRTPIPE pPipeR = pRequest->enmType == VBOXSERVICECTRLREQUEST_PROC_STDERR
    500525                           ? phStdErrR : phStdOutR;
    501526            AssertPtr(pPipeR);
     
    508533                if (RT_FAILURE(rcReq))
    509534                {
    510                     RTPollSetRemove(hPollSet, pRequest->enmType == VBOXSERVICECTRLREQUEST_STDERR_READ
     535                    RTPollSetRemove(hPollSet, pRequest->enmType == VBOXSERVICECTRLREQUEST_PROC_STDERR
    511536                                              ? VBOXSERVICECTRLPIPEID_STDERR : VBOXSERVICECTRLPIPEID_STDOUT);
    512537                    RTPipeClose(*pPipeR);
     
    524549        }
    525550
     551        case VBOXSERVICECTRLREQUEST_PROC_TERM:
     552            ASMAtomicXchgBool(&pThread->fShutdown, true);
     553            fDefer = true;
     554            break;
     555
    526556        default:
    527557            rcReq = VERR_NOT_IMPLEMENTED;
     
    529559    }
    530560
    531     /* Assign overall result. */
    532     pRequest->rc = RT_SUCCESS(rc)
    533                  ? rcReq : rc;
    534 
    535     VBoxServiceVerbose(2, "[PID %u]: Handled req=%u, CID=%u, rc=%Rrc, cbData=%u\n",
    536                        pThread->uPID, pRequest->enmType, pRequest->uCID, pRequest->rc, pRequest->cbData);
    537 
    538     /* In any case, regardless of the result, we notify
    539      * the main guest control to unblock it. */
    540     int rc2 = RTSemEventMultiSignal(pRequest->Event);
    541     AssertRC(rc2);
    542 
    543     /* No access to pRequest here anymore -- could be out of scope
    544      * or modified already! */
    545     pThread->pRequest = pRequest = NULL;
     561    if (   RT_FAILURE(rc)
     562        || !fDefer)
     563    {
     564        rc = gstcntlProcessSignalRequest(pRequest,
     565                                         RT_SUCCESS(rc) ? rcReq : rc);
     566
     567        /* No access to pRequest here anymore -- could be out of scope
     568         * or modified already! */
     569        pThread->pRequest = pRequest = NULL;
     570    }
     571    else /* Completing the request defered. */
     572        rc = VINF_AIO_TASK_PENDING; /** @todo Find an own rc! */
    546573
    547574    return rc;
     
    601628    VBoxServiceVerbose(2, "[PID %u]: Process \"%s\" started, CID=%u, User=%s\n",
    602629                       pThread->uPID, pThread->pszCmd, pThread->uContextID, pThread->pszUser);
    603     rc = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
    604                                          pThread->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
    605                                          NULL /* pvData */, 0 /* cbData */);
     630    rc = VbglR3GuestCtrlProcCbStatus(pThread->uClientID, pThread->uContextID,
     631                                     pThread->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
     632                                     NULL /* pvData */, 0 /* cbData */);
    606633
    607634    /*
    608635     * Process input, output, the test pipe and client requests.
    609636     */
     637    PVBOXSERVICECTRLREQUEST pReq = NULL;
    610638    while (   RT_SUCCESS(rc)
    611639           && RT_UNLIKELY(!pThread->fShutdown))
     
    642670
    643671                case VBOXSERVICECTRLPIPEID_IPC_NOTIFY:
     672                    pReq = pThread->pRequest; /** @todo Implement request queue. */
    644673                    rc = gstcntlProcessHandleRequest(hPollSet, fPollEvt,
    645                                                      phStdInW, phStdOutR, phStdErrR, pThread);
     674                                                     phStdInW, phStdOutR, phStdErrR,
     675                                                     pThread, pReq);
     676                    if (rc != VINF_AIO_TASK_PENDING)
     677                        pReq = NULL;
    646678                    break;
    647679
     
    707739            if (cMsElapsed >= cMsTimeout)
    708740            {
    709                 VBoxServiceVerbose(3, "[PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...",
     741                VBoxServiceVerbose(3, "[PID %u]: Timed out (%ums elapsed > %ums timeout), killing ...\n",
    710742                                   pThread->uPID, cMsElapsed, cMsTimeout);
    711743
     
    787819        if (fProcessAlive)
    788820            VBoxServiceVerbose(3, "[PID %u]: Could not be killed\n", pThread->uPID);
     821
     822        if (   pReq /* Handle deferred termination request. */
     823            && pReq->enmType == VBOXSERVICECTRLREQUEST_PROC_TERM)
     824        {
     825            rc2 = gstcntlProcessSignalRequest(pReq,
     826                                              fProcessAlive ? VINF_SUCCESS : VERR_PROCESS_RUNNING);
     827            pReq = NULL;
     828        }
     829        else if (pReq)
     830            AssertMsgFailed(("Unable to handle unknown deferred request (type: %RU32)\n", pReq->enmType));
    789831    }
    790832
     
    861903        if (!(pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_START))
    862904        {
    863             rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID,
    864                                                  pThread->uPID, uStatus, uFlags,
    865                                                  NULL /* pvData */, 0 /* cbData */);
     905            rc2 = VbglR3GuestCtrlProcCbStatus(pThread->uClientID, pThread->uContextID,
     906                                              pThread->uPID, uStatus, uFlags,
     907                                              NULL /* pvData */, 0 /* cbData */);
    866908            if (RT_FAILURE(rc2))
    867909                VBoxServiceError("[PID %u]: Error reporting final status to host; rc=%Rrc\n",
     
    10501092 *                              should service.
    10511093 */
    1052 static int gstcntlProcessSetupPipe(const char *pszHowTo, int fd,
    1053                                    PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe)
     1094int GstcntlProcessSetupPipe(const char *pszHowTo, int fd,
     1095                            PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe)
    10541096{
    10551097    AssertPtrReturn(ph, VERR_INVALID_POINTER);
     
    14861528            RTHANDLE    hStdIn;
    14871529            PRTHANDLE   phStdIn;
    1488             rc = gstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/,
     1530            rc = GstcntlProcessSetupPipe("|", 0 /*STDIN_FILENO*/,
    14891531                                         &hStdIn, &phStdIn, &pThread->pipeStdInW);
    14901532            if (RT_SUCCESS(rc))
     
    14931535                PRTHANDLE   phStdOut;
    14941536                RTPIPE      pipeStdOutR;
    1495                 rc = gstcntlProcessSetupPipe(  (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT)
     1537                rc = GstcntlProcessSetupPipe(  (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDOUT)
    14961538                                             ? "|" : "/dev/null",
    14971539                                             1 /*STDOUT_FILENO*/,
     
    15021544                    PRTHANDLE   phStdErr;
    15031545                    RTPIPE      pipeStdErrR;
    1504                     rc = gstcntlProcessSetupPipe(  (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR)
     1546                    rc = GstcntlProcessSetupPipe(  (pThread->uFlags & EXECUTEPROCESSFLAG_WAIT_STDERR)
    15051547                                                 ? "|" : "/dev/null",
    15061548                                                 2 /*STDERR_FILENO*/,
     
    16271669        if (RT_FAILURE(rc))
    16281670        {
    1629             rc2 = VbglR3GuestCtrlExecReportStatus(pThread->uClientID, pThread->uContextID, pThread->uPID,
    1630                                                   PROC_STS_ERROR, rc,
    1631                                                   NULL /* pvData */, 0 /* cbData */);
     1671            rc2 = VbglR3GuestCtrlProcCbStatus(pThread->uClientID, pThread->uContextID, pThread->uPID,
     1672                                              PROC_STS_ERROR, rc,
     1673                                              NULL /* pvData */, 0 /* cbData */);
    16321674            if (RT_FAILURE(rc2))
    16331675                VBoxServiceError("Could not report process failure error; rc=%Rrc (process error %Rrc)\n",
     
    16351677        }
    16361678
    1637         VBoxServiceVerbose(3, "[PID %u]: Cancelling pending host requests (client ID=%u)\n",
    1638                            pThread->uPID, pThread->uClientID);
    1639         rc2 = VbglR3GuestCtrlCancelPendingWaits(pThread->uClientID);
    1640         if (RT_FAILURE(rc2))
    1641         {
    1642             VBoxServiceError("[PID %u]: Cancelling pending host requests failed; rc=%Rrc\n",
    1643                              pThread->uPID, rc2);
    1644             if (RT_SUCCESS(rc))
    1645                 rc = rc2;
    1646         }
    1647 
    1648         /* Disconnect from guest control service. */
     1679        /* Disconnect this client from the guest control service. This also cancels all
     1680         * outstanding host requests. */
    16491681        VBoxServiceVerbose(3, "[PID %u]: Disconnecting (client ID=%u) ...\n",
    16501682                           pThread->uPID, pThread->uClientID);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r44528 r44863  
    108108#endif /* RT_OS_WINDOWS */
    109109
    110 #ifdef VBOX_WITH_GUEST_CONTROL
    111 /**
    112  * Pipe IDs for handling the guest process poll set.
    113  */
    114 typedef enum VBOXSERVICECTRLPIPEID
    115 {
    116     VBOXSERVICECTRLPIPEID_UNKNOWN           = 0,
    117     VBOXSERVICECTRLPIPEID_STDIN             = 10,
    118     VBOXSERVICECTRLPIPEID_STDIN_WRITABLE    = 11,
    119     /** Pipe for reading from guest process' stdout. */
    120     VBOXSERVICECTRLPIPEID_STDOUT            = 40,
    121     /** Pipe for reading from guest process' stderr. */
    122     VBOXSERVICECTRLPIPEID_STDERR            = 50,
    123     /** Notification pipe for waking up the guest process
    124      *  control thread. */
    125     VBOXSERVICECTRLPIPEID_IPC_NOTIFY        = 100
    126 } VBOXSERVICECTRLPIPEID;
    127 
    128 /**
    129  * Request types to perform on a started guest process.
    130  */
    131 typedef enum VBOXSERVICECTRLREQUESTTYPE
    132 {
    133     /** Unknown request. */
    134     VBOXSERVICECTRLREQUEST_UNKNOWN          = 0,
    135     /** Main control thread asked used to quit. */
    136     VBOXSERVICECTRLREQUEST_QUIT             = 1,
    137     /** Performs reading from stdout. */
    138     VBOXSERVICECTRLREQUEST_STDOUT_READ      = 50,
    139     /** Performs reading from stderr. */
    140     VBOXSERVICECTRLREQUEST_STDERR_READ      = 60,
    141     /** Performs writing to stdin. */
    142     VBOXSERVICECTRLREQUEST_STDIN_WRITE      = 70,
    143     /** Same as VBOXSERVICECTRLREQUEST_STDIN_WRITE, but
    144      *  marks the end of input. */
    145     VBOXSERVICECTRLREQUEST_STDIN_WRITE_EOF  = 71,
    146     /** Kill/terminate process.
    147      *  @todo Implement this! */
    148     VBOXSERVICECTRLREQUEST_KILL             = 90,
    149     /** Gently ask process to terminate.
    150      *  @todo Implement this! */
    151     VBOXSERVICECTRLREQUEST_HANGUP           = 91,
    152     /** Ask the process in which status it
    153      *  currently is.
    154      *  @todo Implement this! */
    155     VBOXSERVICECTRLREQUEST_STATUS           = 100
    156 } VBOXSERVICECTRLREQUESTTYPE;
    157 
    158 /**
    159  * Thread list types.
    160  */
    161 typedef enum VBOXSERVICECTRLTHREADLISTTYPE
    162 {
    163     /** Unknown list -- uncool to use. */
    164     VBOXSERVICECTRLTHREADLIST_UNKNOWN       = 0,
    165     /** Stopped list: Here all guest threads end up
    166      *  when they reached the stopped state and can
    167      *  be shut down / free'd safely. */
    168     VBOXSERVICECTRLTHREADLIST_STOPPED       = 1,
    169     /**
    170      * Started list: Here all threads are registered
    171      * when they're up and running (that is, accepting
    172      * commands).
    173      */
    174     VBOXSERVICECTRLTHREADLIST_RUNNING       = 2
    175 } VBOXSERVICECTRLTHREADLISTTYPE;
    176 
    177 /**
    178  * Structure to perform a request on a started guest
    179  * process. Needed for letting the main guest control thread
    180  * to communicate (and wait) for a certain operation which
    181  * will be done in context of the started guest process thread.
    182  */
    183 typedef struct VBOXSERVICECTRLREQUEST
    184 {
    185     /** Event semaphore to serialize access. */
    186     RTSEMEVENTMULTI            Event;
    187     /** The request type to handle. */
    188     VBOXSERVICECTRLREQUESTTYPE enmType;
    189     /** Payload size; on input, this contains the (maximum) amount
    190      *  of data the caller  wants to write or to read. On output,
    191      *  this show the actual amount of data read/written. */
    192     size_t                     cbData;
    193     /** Payload data; a pre-allocated data buffer for input/output. */
    194     void                      *pvData;
    195     /** The context ID which is required to complete the
    196      *  request. Not used at the moment. */
    197     uint32_t                   uCID;
    198     /** The overall result of the operation. */
    199     int                        rc;
    200 } VBOXSERVICECTRLREQUEST;
    201 /** Pointer to request. */
    202 typedef VBOXSERVICECTRLREQUEST *PVBOXSERVICECTRLREQUEST;
    203 
    204 /**
    205  * Structure holding information for starting a guest
    206  * process.
    207  */
    208 typedef struct VBOXSERVICECTRLPROCESS
    209 {
    210     /** Full qualified path of process to start (without arguments). */
    211     char szCmd[GUESTPROCESS_MAX_CMD_LEN];
    212     /** Process execution flags. @sa */
    213     uint32_t uFlags;
    214     /** Command line arguments. */
    215     char szArgs[GUESTPROCESS_MAX_ARGS_LEN];
    216     /** Number of arguments specified in pszArgs. */
    217     uint32_t uNumArgs;
    218     /** String of environment variables ("FOO=BAR") to pass to the process
    219       * to start. */
    220     char szEnv[GUESTPROCESS_MAX_ENV_LEN];
    221     /** Size (in bytes) of environment variables block. */
    222     uint32_t cbEnv;
    223     /** Number of environment variables specified in pszEnv. */
    224     uint32_t uNumEnvVars;
    225     /** User name (account) to start the process under. */
    226     char szUser[GUESTPROCESS_MAX_USER_LEN];
    227     /** Password of specified user name (account). */
    228     char szPassword[GUESTPROCESS_MAX_PASSWORD_LEN];
    229     /** Time limit (in ms) of the process' life time. */
    230     uint32_t uTimeLimitMS;
    231 } VBOXSERVICECTRLPROCESS;
    232 /** Pointer to a guest process block. */
    233 typedef VBOXSERVICECTRLPROCESS *PVBOXSERVICECTRLPROCESS;
    234 
    235 /**
    236  * Structure for holding data for one (started) guest process.
    237  */
    238 typedef struct VBOXSERVICECTRLTHREAD
    239 {
    240     /** Pointer to list archor of following
    241      *  list node.
    242      *  @todo Would be nice to have a RTListGetAnchor(). */
    243     PRTLISTANCHOR                   pAnchor;
    244     /** Node. */
    245     RTLISTNODE                      Node;
    246     /** The worker thread. */
    247     RTTHREAD                        Thread;
    248     /** Shutdown indicator; will be set when the thread
    249       * needs (or is asked) to shutdown. */
    250     bool volatile                   fShutdown;
    251     /** Indicator set by the service thread exiting. */
    252     bool volatile                   fStopped;
    253     /** Whether the service was started or not. */
    254     bool                            fStarted;
    255     /** Client ID. */
    256     uint32_t                        uClientID;
    257     /** Context ID. */
    258     uint32_t                        uContextID;
    259     /** Critical section for thread-safe use. */
    260     RTCRITSECT                      CritSect;
    261     /** @todo Document me! */
    262     uint32_t                        uPID;
    263     char                           *pszCmd;
    264     uint32_t                        uFlags;
    265     char                          **papszArgs;
    266     uint32_t                        uNumArgs;
    267     char                          **papszEnv;
    268     uint32_t                        uNumEnvVars;
    269     /** Name of specified user account to run the
    270      *  guest process under. */
    271     char                           *pszUser;
    272     /** Password of specified user account. */
    273     char                           *pszPassword;
    274     /** Overall time limit (in ms) that the guest process
    275      *  is allowed to run. 0 for indefinite time. */
    276     uint32_t                        uTimeLimitMS;
    277     /** Pointer to the current IPC request being
    278      *  processed. */
    279     PVBOXSERVICECTRLREQUEST         pRequest;
    280     /** StdIn pipe for addressing writes to the
    281      *  guest process' stdin.*/
    282     RTPIPE                          pipeStdInW;
    283     /** The notification pipe associated with this guest process.
    284      *  This is NIL_RTPIPE for output pipes. */
    285     RTPIPE                          hNotificationPipeW;
    286     /** The other end of hNotificationPipeW. */
    287     RTPIPE                          hNotificationPipeR;
    288 } VBOXSERVICECTRLTHREAD;
    289 /** Pointer to thread data. */
    290 typedef VBOXSERVICECTRLTHREAD *PVBOXSERVICECTRLTHREAD;
    291 
    292 /**
    293  * Structure for one (opened) guest file.
    294  */
    295 typedef struct VBOXSERVICECTRLFILE
    296 {
    297     /** Pointer to list archor of following
    298      *  list node.
    299      *  @todo Would be nice to have a RTListGetAnchor(). */
    300     PRTLISTANCHOR                   pAnchor;
    301     /** Node. */
    302     RTLISTNODE                      Node;
    303     /** The file name. */
    304     char                            szName[RTPATH_MAX];
    305     /** The file handle on the guest. */
    306     RTFILE                          hFile;
    307     /** File handle to identify this file. */
    308     uint32_t                        uHandle;
    309     /** Context ID. */
    310     uint32_t                        uContextID;
    311 } VBOXSERVICECTRLFILE;
    312 /** Pointer to thread data. */
    313 typedef VBOXSERVICECTRLFILE *PVBOXSERVICECTRLFILE;
    314 #endif /* VBOX_WITH_GUEST_CONTROL */
    315110#ifdef VBOX_WITH_GUEST_PROPS
    316 
    317111/**
    318112 * A guest property cache.
     
    359153extern char        *g_pszProgName;
    360154extern int          g_cVerbosity;
     155extern char         g_szLogFile[RTPATH_MAX + 128];
    361156extern uint32_t     g_DefaultInterval;
    362157extern VBOXSERVICE  g_TimeSync;
     
    406201#endif /* RT_OS_WINDOWS */
    407202
    408 #ifdef VBOX_WITH_GUEST_CONTROL
    409 /* Guest control main thread functions. */
    410 extern int                      GstCntlAssignPID(PVBOXSERVICECTRLTHREAD pThread, uint32_t uPID);
    411 extern int                      GstCntlListSet(VBOXSERVICECTRLTHREADLISTTYPE enmList,
    412                                                           PVBOXSERVICECTRLTHREAD pThread);
    413 extern PVBOXSERVICECTRLTHREAD   GstCntlLockThread(uint32_t uPID);
    414 extern void                     GstCntlUnlockThread(const PVBOXSERVICECTRLTHREAD pThread);
    415 extern int                      GstCntlSetInactive(PVBOXSERVICECTRLTHREAD pThread);
    416 /* Per-thread guest process functions. */
    417 extern int                      GstCntlProcessStart(uint32_t uContext,
    418                                                               PVBOXSERVICECTRLPROCESS pProcess);
    419 extern int                      GstCntlProcessPerform(uint32_t uPID, PVBOXSERVICECTRLREQUEST pRequest);
    420 extern int                      GstCntlProcessStop(const PVBOXSERVICECTRLTHREAD pThread);
    421 extern int                      GstCntlProcessWait(const PVBOXSERVICECTRLTHREAD pThread,
    422                                                    RTMSINTERVAL msTimeout, int *prc);
    423 extern int                      GstCntlProcessFree(PVBOXSERVICECTRLTHREAD pThread);
    424 /* Request handling. */
    425 extern int                      GstCntlProcessRequestAlloc(PVBOXSERVICECTRLREQUEST   *ppReq,
    426                                                            VBOXSERVICECTRLREQUESTTYPE enmType);
    427 extern int                      GstCntlProcessRequestAllocEx(PVBOXSERVICECTRLREQUEST    *ppReq,
    428                                                              VBOXSERVICECTRLREQUESTTYPE  enmType,
    429                                                              void                       *pvData,
    430                                                              size_t                      cbData,
    431                                                              uint32_t                    uCID);
    432 extern void                     GstCntlProcessRequestFree(PVBOXSERVICECTRLREQUEST pReq);
    433 #endif /* VBOX_WITH_GUEST_CONTROL */
    434 
    435203#ifdef VBOXSERVICE_MANAGEMENT
    436204extern uint32_t                 VBoxServiceBalloonQueryPages(uint32_t cbPage);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServicePageSharing.cpp

    r44528 r44863  
    696696                char const *papszArgs[3];
    697697                papszArgs[0] = pszExeName;
    698                 papszArgs[1] = "--pagefusionfork";
     698                papszArgs[1] = "pagefusion";
    699699                papszArgs[2] = NULL;
    700700                rc = RTProcCreate(pszExeName, papszArgs, RTENV_DEFAULT, 0 /* normal child */, &hProcess);
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceToolBox.cpp

    r43877 r44863  
    15261526
    15271527    while (   (ch = RTGetOpt(&GetState, &ValueUnion))
    1528               && RT_SUCCESS(rc))
     1528           && RT_SUCCESS(rc))
    15291529    {
    15301530        /* For options that require an argument, ValueUnion has received the value. */
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette