VirtualBox

Ignore:
Timestamp:
Dec 1, 2018 10:53:50 PM (6 years ago)
Author:
vboxsync
Message:

GuestControl: Preps for using the pvClient data area and have the mClientStateMap only contain pointers. bugref:9313

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/GuestControl/service.cpp

    r75853 r75859  
    6060*   Header Files                                                                                                                 *
    6161*********************************************************************************************************************************/
     62//#define USE_PVCLIENT
    6263#define LOG_GROUP LOG_GROUP_GUEST_CONTROL
    6364#include <VBox/HostServices/GuestControlSvc.h>
     
    190191     * duplicated as well.
    191192     *
    192      * @return  IPRT status code.
     193     * @returns VBox status code.
    193194     * @param   idFunction  The host function (message) number, eHostFn.
    194195     * @param   cParms      Number of parameters in the HGCM request.
     
    309310     * current HGCM request.
    310311     *
    311      * @return  IPRT status code.
     312     * @returns VBox status code.
    312313     * @param   paDstParms              Array of parameters of HGCM request to fill the data into.
    313314     * @param   cDstParms               Number of parameters the HGCM request can handle.
     
    867868    /** @} */
    868869} ClientState;
     870#ifdef USE_PVCLIENT
     871typedef std::map< uint32_t, ClientState *> ClientStateMap;
     872typedef std::map< uint32_t, ClientState *>::iterator ClientStateMapIter;
     873typedef std::map< uint32_t, ClientState *>::const_iterator ClientStateMapIterConst;
     874#else
    869875typedef std::map< uint32_t, ClientState > ClientStateMap;
    870876typedef std::map< uint32_t, ClientState >::iterator ClientStateMapIter;
    871877typedef std::map< uint32_t, ClientState >::const_iterator ClientStateMapIterConst;
     878#endif
    872879
    873880/**
     
    930937
    931938    static DECLCALLBACK(int)  svcUnload(void *pvService);
    932     static DECLCALLBACK(int)  svcConnect(void *pvService, uint32_t u32ClientID, void *pvClient,
     939    static DECLCALLBACK(int)  svcConnect(void *pvService, uint32_t idClient, void *pvClient,
    933940                                         uint32_t fRequestor, bool fRestoring);
    934     static DECLCALLBACK(int)  svcDisconnect(void *pvService, uint32_t u32ClientID, void *pvClient);
    935     static DECLCALLBACK(void) svcCall(void *pvService, VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient,
     941    static DECLCALLBACK(int)  svcDisconnect(void *pvService, uint32_t idClient, void *pvClient);
     942    static DECLCALLBACK(void) svcCall(void *pvService, VBOXHGCMCALLHANDLE callHandle, uint32_t idClient, void *pvClient,
    936943                                      uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival);
    937944    static DECLCALLBACK(int)  svcHostCall(void *pvService, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     
    941948
    942949private:
    943     int clientMakeMeMaster(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms);
    944     int clientMsgPeek(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fWait);
    945     int clientMsgGet(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    946     int clientMsgCancel(uint32_t idClient, uint32_t cParms);
    947     int clientMsgSkip(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    948     int clientSessionPrepare(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    949     int clientSessionCancelPrepared(uint32_t idClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    950     int clientSessionAccept(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    951     int clientSessionCloseOther(uint32_t idClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    952 
    953     int clientMsgOldGet(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    954     int clientMsgOldFilterSet(uint32_t u32ClientID, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    955     int clientMsgOldSkip(uint32_t u32ClientID, uint32_t cParms);
    956 
    957     int hostCallback(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    958     int hostProcessCommand(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     950    int clientMakeMeMaster(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms);
     951    int clientMsgPeek(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fWait);
     952    int clientMsgGet(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     953    int clientMsgCancel(ClientState *pClient, uint32_t cParms);
     954    int clientMsgSkip(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     955    int clientSessionPrepare(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     956    int clientSessionCancelPrepared(ClientState *pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     957    int clientSessionAccept(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     958    int clientSessionCloseOther(ClientState *pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     959    int clientToMain(ClientState *pClient, uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     960
     961    int clientMsgOldGet(ClientState *pClient, VBOXHGCMCALLHANDLE callHandle, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     962    int clientMsgOldFilterSet(ClientState *pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     963    int clientMsgOldSkip(ClientState *pClient, uint32_t cParms);
     964
     965    int hostCallback(uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     966    int hostProcessCommand(uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    959967
    960968    DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(GstCtrlService);
     
    10001008     * Create client state.
    10011009     */
     1010    ClientState *pClient;
     1011#ifdef USE_PVCLIENT
    10021012    try
    10031013    {
     1014        pClient = new (pvClient) ClientState(pThis->mpHelpers, idClient);
     1015    }
     1016    catch (std::bad_alloc &)
     1017    {
     1018        return VERR_NO_MEMORY;
     1019    }
     1020    try
     1021    {
     1022        pThis->mClientStateMap[idClient] = pClient;
     1023    }
     1024    catch (std::bad_alloc &)
     1025    {
     1026        pClient->~ClientState();
     1027        return VERR_NO_MEMORY;
     1028    }
     1029#else
     1030    try
     1031    {
    10041032        pThis->mClientStateMap[idClient] = ClientState(pThis->mpHelpers, idClient);
     1033        pClient = &pThis->mClientStateMap[idClient];
    10051034    }
    10061035    catch (std::bad_alloc &)
     
    10081037        return VERR_NO_MEMORY;
    10091038    }
    1010     ClientState &rClientState = pThis->mClientStateMap[idClient];
     1039#endif
    10111040
    10121041    /*
     
    10241053            LogFunc(("Picking %u as master for now.\n", idClient));
    10251054            pThis->m_idMasterClient = idClient;
    1026             rClientState.m_fIsMaster = true;
     1055            pClient->m_fIsMaster = true;
    10271056        }
    10281057    }
     
    10421071GstCtrlService::svcDisconnect(void *pvService, uint32_t idClient, void *pvClient)
    10431072{
    1044     RT_NOREF(pvClient);
    1045     AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
    10461073    SELF *pThis = reinterpret_cast<SELF *>(pvService);
    10471074    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     1075#ifdef USE_PVCLIENT
     1076    ClientState *pClient = reinterpret_cast<ClientState *>(pvClient);
     1077    AssertPtrReturn(pClient, VERR_INVALID_POINTER);
     1078#else
     1079    RT_NOREF(pvClient);
     1080#endif
    10481081    LogFlowFunc(("[Client %RU32] Disconnected (%zu clients total)\n", idClient, pThis->mClientStateMap.size()));
    10491082
     1083#ifndef USE_PVCLIENT
    10501084    ClientStateMapIter ItClientState = pThis->mClientStateMap.find(idClient);
    10511085    AssertMsgReturn(ItClientState != pThis->mClientStateMap.end(),
    10521086                    ("Client ID=%RU32 not found in client list when it should be there\n", idClient),
    10531087                    VINF_SUCCESS);
     1088    ClientState *pClient = ItClientState->second;
     1089#endif
    10541090
    10551091    /*
    10561092     * Cancel all pending host commands, replying with GUEST_DISCONNECTED if final recipient.
    10571093     */
    1058     {
    1059         ClientState &rClientState = ItClientState->second;
    1060 
    1061         while (!rClientState.mHostCmdList.empty())
    1062         {
    1063             HostCommand *pHostCmd = *rClientState.mHostCmdList.begin();
    1064             rClientState.mHostCmdList.pop_front();
    1065 
    1066             uint32_t idFunction = pHostCmd->mMsgType;
    1067             uint32_t idContext  = pHostCmd->m_idContext;
    1068             if (pHostCmd->SaneRelease() == 0)
    1069             {
    1070                 VBOXHGCMSVCPARM Parm;
    1071                 HGCMSvcSetU32(&Parm, idContext);
    1072                 int rc2 = pThis->hostCallback(GUEST_DISCONNECTED, 1, &Parm);
    1073                 LogFlowFunc(("Cancelled host command %u (%s) with idContext=%#x -> %Rrc\n",
    1074                              idFunction, GstCtrlHostFnName((eHostFn)idFunction), idContext, rc2));
    1075                 RT_NOREF(rc2, idFunction);
    1076             }
     1094    while (!pClient->mHostCmdList.empty())
     1095    {
     1096        HostCommand *pHostCmd = *pClient->mHostCmdList.begin();
     1097        pClient->mHostCmdList.pop_front();
     1098
     1099        uint32_t idFunction = pHostCmd->mMsgType;
     1100        uint32_t idContext  = pHostCmd->m_idContext;
     1101        if (pHostCmd->SaneRelease() == 0)
     1102        {
     1103            VBOXHGCMSVCPARM Parm;
     1104            HGCMSvcSetU32(&Parm, idContext);
     1105            int rc2 = pThis->hostCallback(GUEST_DISCONNECTED, 1, &Parm);
     1106            LogFlowFunc(("Cancelled host command %u (%s) with idContext=%#x -> %Rrc\n",
     1107                         idFunction, GstCtrlHostFnName((eHostFn)idFunction), idContext, rc2));
     1108            RT_NOREF(rc2, idFunction);
    10771109        }
    10781110    }
     
    10811113     * Delete the client state.
    10821114     */
     1115#ifdef USE_PVCLIENT
     1116    pThis->mClientStateMap.erase(idClient);
     1117    pClient->~ClientState();
     1118#else
    10831119    pThis->mClientStateMap.erase(ItClientState);
     1120#endif
     1121    pClient = NULL;
    10841122
    10851123    /*
     
    11161154 * or defers the guest call until we have something from the host.
    11171155 *
    1118  * @return  IPRT status code.
    1119  * @param   u32ClientID                 The client's ID.
    1120  * @param   callHandle                  The client's call handle.
    1121  * @param   cParms                      Number of parameters.
    1122  * @param   paParms                     Array of parameters.
    1123  */
    1124 int GstCtrlService::clientMsgOldGet(uint32_t u32ClientID, VBOXHGCMCALLHANDLE callHandle,
    1125                                     uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    1126 {
    1127     /*
    1128      * Lookup client in our map so that we can assign the context ID of
    1129      * a command to that client.
    1130      */
    1131     ClientStateMapIter itClientState = mClientStateMap.find(u32ClientID);
    1132     AssertMsg(itClientState != mClientStateMap.end(), ("Client with ID=%RU32 not found when it should be present\n",
    1133                                                        u32ClientID));
    1134     if (itClientState == mClientStateMap.end())
    1135     {
    1136         /* Should never happen. Complete the call on the guest side though. */
    1137         AssertPtr(mpHelpers);
    1138         mpHelpers->pfnCallComplete(callHandle, VERR_NOT_FOUND);
    1139 
    1140         return VERR_NOT_FOUND;
    1141     }
    1142 
    1143     ClientState &clientState = itClientState->second;
     1156 * @returns VBox status code.
     1157 * @param   pClient         The client state.
     1158 * @param   hCall           The client's call handle.
     1159 * @param   cParms          Number of parameters.
     1160 * @param   paParms         Array of parameters.
     1161 */
     1162int GstCtrlService::clientMsgOldGet(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1163{
     1164    ASSERT_GUEST(pClient->m_idSession != UINT32_MAX || pClient->m_fIsMaster);
    11441165
    11451166    /* Use the current (inbound) connection. */
    11461167    ClientConnection thisCon;
    1147     thisCon.mHandle   = callHandle;
     1168    thisCon.mHandle   = hCall;
    11481169    thisCon.mNumParms = cParms;
    11491170    thisCon.mParms    = paParms;
    11501171
    1151     return clientState.OldRunCurrent(&thisCon);
     1172    return pClient->OldRunCurrent(&thisCon);
    11521173}
    11531174
     
    11611182 * @retval  VERR_RESOURCE_BUSY if there is already a master.
    11621183 * @retval  VERR_VERSION_MISMATCH if VBoxGuest didn't supply requestor info.
    1163  * @retval  VERR_INVALID_CLIENT_ID
    11641184 * @retval  VERR_WRONG_PARAMETER_COUNT
    11651185 *
    1166  * @param   idClient    The client's ID.
     1186 * @param   pClient     The client state.
    11671187 * @param   hCall       The client's call handle.
    11681188 * @param   cParms      Number of parameters.
    11691189 */
    1170 int GstCtrlService::clientMakeMeMaster(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms)
     1190int GstCtrlService::clientMakeMeMaster(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms)
    11711191{
    11721192    /*
     
    11821202                                   VERR_ACCESS_DENIED);
    11831203
    1184     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1185     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1186     ClientState &rClientState = ItClientState->second;
    1187 
    11881204    /*
    11891205     * Do the work.
    11901206     */
    1191     ASSERT_GUEST_MSG_RETURN(m_idMasterClient == idClient || m_idMasterClient == UINT32_MAX,
    1192                             ("Already have master session %RU32, refusing %RU32.\n", m_idMasterClient, idClient),
     1207    ASSERT_GUEST_MSG_RETURN(m_idMasterClient == pClient->mID || m_idMasterClient == UINT32_MAX,
     1208                            ("Already have master session %RU32, refusing %RU32.\n", m_idMasterClient, pClient->mID),
    11931209                            VERR_RESOURCE_BUSY);
    11941210    int rc = mpHelpers->pfnCallComplete(hCall, VINF_SUCCESS);
    11951211    if (RT_SUCCESS(rc))
    11961212    {
    1197         m_idMasterClient = idClient;
     1213        m_idMasterClient = pClient->mID;
    11981214        m_fLegacyMode    = false;
    1199         rClientState.m_fIsMaster = true;
    1200         Log(("[Client %RU32] is master.\n", idClient));
     1215        pClient->m_fIsMaster = true;
     1216        Log(("[Client %RU32] is master.\n", pClient->mID));
    12011217    }
    12021218    else
     
    12151231 * @retval  VINF_HGCM_ASYNC_EXECUTE if message wait is pending.
    12161232 *
    1217  * @param   idClient    The client's ID.
     1233 * @param   pClient     The client state.
    12181234 * @param   hCall       The client's call handle.
    12191235 * @param   cParms      Number of parameters.
     
    12221238 *                      immediately.
    12231239 */
    1224 int GstCtrlService::clientMsgPeek(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fWait)
     1240int GstCtrlService::clientMsgPeek(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[], bool fWait)
    12251241{
    12261242    /*
     
    12441260    }
    12451261
    1246     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1247     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1248     ClientState &rClientState = ItClientState->second;
    1249 
    12501262    /*
    12511263     * Check restore session ID.
     
    12581270            paParms[0].u.uint32 = idRestore;
    12591271            LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_XXXX -> VERR_VM_RESTORED (%#RX64 -> %#RX64)\n",
    1260                          idClient, idRestoreCheck, idRestore));
     1272                         pClient->mID, idRestoreCheck, idRestore));
    12611273            return VERR_VM_RESTORED;
    12621274        }
     
    12671279     * Return information about the first command if one is pending in the list.
    12681280     */
    1269     HostCmdListIter itFirstCmd = rClientState.mHostCmdList.begin();
    1270     if (itFirstCmd != rClientState.mHostCmdList.end())
     1281    HostCmdListIter itFirstCmd = pClient->mHostCmdList.begin();
     1282    if (itFirstCmd != pClient->mHostCmdList.end())
    12711283    {
    12721284        HostCommand *pFirstCmd = *itFirstCmd;
    12731285        pFirstCmd->setPeekReturn(paParms, cParms);
    12741286        LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_XXXX -> VINF_SUCCESS (idMsg=%u (%s), cParms=%u)\n",
    1275                      idClient, pFirstCmd->mMsgType, GstCtrlHostFnName((eHostFn)pFirstCmd->mMsgType), pFirstCmd->mParmCount));
     1287                     pClient->mID, pFirstCmd->mMsgType, GstCtrlHostFnName((eHostFn)pFirstCmd->mMsgType), pFirstCmd->mParmCount));
    12761288        return VINF_SUCCESS;
    12771289    }
     
    12821294    if (!fWait)
    12831295    {
    1284         LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_NOWAIT -> VERR_TRY_AGAIN\n", idClient));
     1296        LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_NOWAIT -> VERR_TRY_AGAIN\n", pClient->mID));
    12851297        return VERR_TRY_AGAIN;
    12861298    }
     
    12891301     * Wait for the host to queue a message for this client.
    12901302     */
    1291     ASSERT_GUEST_MSG_RETURN(rClientState.mIsPending == 0, ("Already pending! (idClient=%RU32)\n", idClient), VERR_RESOURCE_BUSY);
    1292     rClientState.mPendingCon.mHandle    = hCall;
    1293     rClientState.mPendingCon.mNumParms  = cParms;
    1294     rClientState.mPendingCon.mParms     = paParms;
    1295     rClientState.mIsPending             = GUEST_MSG_PEEK_WAIT;
    1296     LogFlowFunc(("[Client %RU32] Is now in pending mode\n", idClient));
     1303    ASSERT_GUEST_MSG_RETURN(pClient->mIsPending == 0, ("Already pending! (idClient=%RU32)\n", pClient->mID), VERR_RESOURCE_BUSY);
     1304    pClient->mPendingCon.mHandle    = hCall;
     1305    pClient->mPendingCon.mNumParms  = cParms;
     1306    pClient->mPendingCon.mParms     = paParms;
     1307    pClient->mIsPending             = GUEST_MSG_PEEK_WAIT;
     1308    LogFlowFunc(("[Client %RU32] Is now in pending mode\n", pClient->mID));
    12971309    return VINF_HGCM_ASYNC_EXECUTE;
    12981310}
     
    13111323 * @retval  VINF_HGCM_ASYNC_EXECUTE if message was completed already.
    13121324 *
    1313  * @param   idClient    The client's ID.
     1325 * @param   pClient     The client state.
    13141326 * @param   hCall       The client's call handle.
    13151327 * @param   cParms      Number of parameters.
    13161328 * @param   paParms     Array of parameters.
    13171329 */
    1318 int GstCtrlService::clientMsgGet(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1330int GstCtrlService::clientMsgGet(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    13191331{
    13201332    /*
     
    13281340                                 : UINT32_MAX;
    13291341
    1330     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1331     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1332 
    1333     ClientState &rClientState = ItClientState->second;
    1334 
    13351342    /*
    13361343     * Return information aobut the first command if one is pending in the list.
    13371344     */
    1338     HostCmdListIter itFirstCmd = rClientState.mHostCmdList.begin();
    1339     if (itFirstCmd != rClientState.mHostCmdList.end())
     1345    HostCmdListIter itFirstCmd = pClient->mHostCmdList.begin();
     1346    if (itFirstCmd != pClient->mHostCmdList.end())
    13401347    {
    13411348        HostCommand *pFirstCmd = *itFirstCmd;
     
    14051412            if (rc != VERR_CANCELLED)
    14061413            {
    1407                 rClientState.mHostCmdList.erase(itFirstCmd);
     1414                pClient->mHostCmdList.erase(itFirstCmd);
    14081415                pFirstCmd->SaneRelease();
    14091416            }
     
    14171424    paParms[0].u.uint32 = 0;
    14181425    paParms[1].u.uint32 = 0;
    1419     LogFlowFunc(("[Client %RU32] GUEST_MSG_GET -> VERR_TRY_AGAIN\n", idClient));
     1426    LogFlowFunc(("[Client %RU32] GUEST_MSG_GET -> VERR_TRY_AGAIN\n", pClient->mID));
    14201427    return VERR_TRY_AGAIN;
    14211428}
     
    14291436 * @retval  VINF_HGCM_ASYNC_EXECUTE if message wait is pending.
    14301437 *
    1431  * @param   idClient    The client's ID.
     1438 * @param   pClient     The client state.
    14321439 * @param   cParms      Number of parameters.
    14331440 */
    1434 int GstCtrlService::clientMsgCancel(uint32_t idClient, uint32_t cParms)
     1441int GstCtrlService::clientMsgCancel(ClientState *pClient, uint32_t cParms)
    14351442{
    14361443    /*
     
    14391446    ASSERT_GUEST_MSG_RETURN(cParms == 0, ("cParms=%u!\n", cParms), VERR_WRONG_PARAMETER_COUNT);
    14401447
    1441     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1442     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1443     ClientState &rClientState = ItClientState->second;
    1444 
    1445     if (rClientState.mIsPending != 0)
    1446     {
    1447         rClientState.CancelWaiting();
     1448    /*
     1449     * Execute.
     1450     */
     1451    if (pClient->mIsPending != 0)
     1452    {
     1453        pClient->CancelWaiting();
    14481454        return VINF_SUCCESS;
    14491455    }
     
    14591465 * @retval  VERR_NOT_FOUND if no message pending.
    14601466 *
    1461  * @param   idClient    The client's ID.
     1467 * @param   pClient     The client state.
    14621468 * @param   hCall       The call handle for completing it.
    14631469 * @param   cParms      Number of parameters.
    14641470 * @param   paParms     The parameters.
    14651471 */
    1466 int GstCtrlService::clientMsgSkip(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1472int GstCtrlService::clientMsgSkip(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    14671473{
    14681474    /*
     
    14851491    }
    14861492
    1487     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1488     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1489     ClientState &rClientState = ItClientState->second;
    1490 
    14911493    /*
    14921494     * Do the job.
    14931495     */
    1494     if (!rClientState.mHostCmdList.empty())
    1495     {
    1496         HostCommand *pFirstCmd = *rClientState.mHostCmdList.begin();
     1496    if (!pClient->mHostCmdList.empty())
     1497    {
     1498        HostCommand *pFirstCmd = *pClient->mHostCmdList.begin();
    14971499        if (   pFirstCmd->mMsgType == idMsg
    14981500            || idMsg == UINT32_MAX)
     
    15041506                 * Remove the command from the queue.
    15051507                 */
    1506                 Assert(*rClientState.mHostCmdList.begin() == pFirstCmd);
    1507                 rClientState.mHostCmdList.pop_front();
     1508                Assert(*pClient->mHostCmdList.begin() == pFirstCmd);
     1509                pClient->mHostCmdList.pop_front();
    15081510
    15091511                /*
     
    15191521                        HGCMSvcSetU32(&aReplyParams[3], rcSkip);         /* flags / whatever */
    15201522                        HGCMSvcSetPv(&aReplyParams[4], NULL, 0);         /* data buffer */
    1521                         GstCtrlService::hostCallback(GUEST_EXEC_STATUS, 5, aReplyParams);
     1523                        hostCallback(GUEST_EXEC_STATUS, 5, aReplyParams);
    15221524                        break;
    15231525
     
    15251527                        HGCMSvcSetU32(&aReplyParams[1], GUEST_SESSION_NOTIFYTYPE_ERROR);    /* type */
    15261528                        HGCMSvcSetU32(&aReplyParams[2], rcSkip);                            /* result */
    1527                         GstCtrlService::hostCallback(GUEST_SESSION_NOTIFY, 3, aReplyParams);
     1529                        hostCallback(GUEST_SESSION_NOTIFY, 3, aReplyParams);
    15281530                        break;
    15291531
     
    15331535                        HGCMSvcSetU32(&aReplyParams[3], rcSkip);            /* flags / whatever */
    15341536                        HGCMSvcSetU32(&aReplyParams[4], 0);                 /* bytes consumed */
    1535                         GstCtrlService::hostCallback(GUEST_EXEC_INPUT_STATUS, 5, aReplyParams);
     1537                        hostCallback(GUEST_EXEC_INPUT_STATUS, 5, aReplyParams);
    15361538                        break;
    15371539
     
    15401542                        HGCMSvcSetU32(&aReplyParams[2], rcSkip);                     /* rc */
    15411543                        HGCMSvcSetU32(&aReplyParams[3], VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pFirstCmd->m_idContext)); /* handle */
    1542                         GstCtrlService::hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
     1544                        hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
    15431545                        break;
    15441546                    case HOST_FILE_CLOSE:
    15451547                        HGCMSvcSetU32(&aReplyParams[1], GUEST_FILE_NOTIFYTYPE_ERROR); /* type*/
    15461548                        HGCMSvcSetU32(&aReplyParams[2], rcSkip);                      /* rc */
    1547                         GstCtrlService::hostCallback(GUEST_FILE_NOTIFY, 3, aReplyParams);
     1549                        hostCallback(GUEST_FILE_NOTIFY, 3, aReplyParams);
    15481550                        break;
    15491551                    case HOST_FILE_READ:
     
    15521554                        HGCMSvcSetU32(&aReplyParams[2], rcSkip);                      /* rc */
    15531555                        HGCMSvcSetPv(&aReplyParams[3], NULL, 0);                      /* data buffer */
    1554                         GstCtrlService::hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
     1556                        hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
    15551557                        break;
    15561558                    case HOST_FILE_WRITE:
     
    15591561                        HGCMSvcSetU32(&aReplyParams[2], rcSkip);                      /* rc */
    15601562                        HGCMSvcSetU32(&aReplyParams[3], 0);                           /* bytes written */
    1561                         GstCtrlService::hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
     1563                        hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
    15621564                        break;
    15631565                    case HOST_FILE_SEEK:
     
    15651567                        HGCMSvcSetU32(&aReplyParams[2], rcSkip);                      /* rc */
    15661568                        HGCMSvcSetU64(&aReplyParams[3], 0);                           /* actual */
    1567                         GstCtrlService::hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
     1569                        hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
    15681570                        break;
    15691571                    case HOST_FILE_TELL:
     
    15711573                        HGCMSvcSetU32(&aReplyParams[2], rcSkip);                      /* rc */
    15721574                        HGCMSvcSetU64(&aReplyParams[3], 0);                           /* actual */
    1573                         GstCtrlService::hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
     1575                        hostCallback(GUEST_FILE_NOTIFY, 4, aReplyParams);
    15741576                        break;
    15751577
     
    15851587                        HGCMSvcSetU32(&aReplyParams[2], (uint32_t)rcSkip);
    15861588                        HGCMSvcSetPv(&aReplyParams[3], NULL, 0);
    1587                         GstCtrlService::hostCallback(GUEST_MSG_REPLY, 4, aReplyParams);
     1589                        hostCallback(GUEST_MSG_REPLY, 4, aReplyParams);
    15881590                        break;
    15891591                }
     
    16171619 * @retval  VERR_DUPLICATE if the session ID has been prepared already.
    16181620 *
    1619  * @param   idClient    The client's ID.
     1621 * @param   pClient     The client state.
    16201622 * @param   hCall       The call handle for completing it.
    16211623 * @param   cParms      Number of parameters.
    16221624 * @param   paParms     The parameters.
    16231625 */
    1624 int GstCtrlService::clientSessionPrepare(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1626int GstCtrlService::clientSessionPrepare(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    16251627{
    16261628    /*
     
    16391641    ASSERT_GUEST_RETURN(cbKey <= _16K, VERR_BUFFER_OVERFLOW);
    16401642
    1641     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1642     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1643     ClientState &rClientState = ItClientState->second;
    1644     ASSERT_GUEST_RETURN(rClientState.m_fIsMaster, VERR_ACCESS_DENIED);
     1643    ASSERT_GUEST_RETURN(pClient->m_fIsMaster, VERR_ACCESS_DENIED);
    16451644    ASSERT_GUEST_RETURN(!m_fLegacyMode, VERR_ACCESS_DENIED);
    1646     Assert(m_idMasterClient == idClient);
     1645    Assert(m_idMasterClient == pClient->mID);
    16471646
    16481647    /* Now that we know it's the master, we can check for session ID duplicates. */
     
    16921691 * @retval  VERR_ACCESS_DENIED if not master or in legacy mode.
    16931692 *
    1694  * @param   idClient    The client's ID.
     1693 * @param   pClient     The client state.
    16951694 * @param   cParms      Number of parameters.
    16961695 * @param   paParms     The parameters.
    16971696 */
    1698 int GstCtrlService::clientSessionCancelPrepared(uint32_t idClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1697int GstCtrlService::clientSessionCancelPrepared(ClientState *pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    16991698{
    17001699    /*
     
    17051704    uint32_t const idSession = paParms[0].u.uint32;
    17061705
    1707     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1708     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1709     ClientState &rClientState = ItClientState->second;
    1710     ASSERT_GUEST_RETURN(rClientState.m_fIsMaster, VERR_ACCESS_DENIED);
     1706    ASSERT_GUEST_RETURN(pClient->m_fIsMaster, VERR_ACCESS_DENIED);
    17111707    ASSERT_GUEST_RETURN(!m_fLegacyMode, VERR_ACCESS_DENIED);
    1712     Assert(m_idMasterClient == idClient);
     1708    Assert(m_idMasterClient == pClient->mID);
    17131709
    17141710    /*
     
    17571753 *          session.
    17581754 *
    1759  * @param   idClient    The client's ID.
     1755 * @param   pClient     The client state.
    17601756 * @param   hCall       The call handle for completing it.
    17611757 * @param   cParms      Number of parameters.
    17621758 * @param   paParms     The parameters.
    17631759 */
    1764 int GstCtrlService::clientSessionAccept(uint32_t idClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1760int GstCtrlService::clientSessionAccept(ClientState *pClient, VBOXHGCMCALLHANDLE hCall, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    17651761{
    17661762    /*
     
    17791775    ASSERT_GUEST_RETURN(cbKey <= _16K, VERR_BUFFER_OVERFLOW);
    17801776
    1781     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1782     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1783     ClientState &rClientState = ItClientState->second;
    1784     ASSERT_GUEST_RETURN(!rClientState.m_fIsMaster, VERR_ACCESS_DENIED);
     1777    ASSERT_GUEST_RETURN(!pClient->m_fIsMaster, VERR_ACCESS_DENIED);
    17851778    ASSERT_GUEST_RETURN(!m_fLegacyMode, VERR_ACCESS_DENIED);
    1786     Assert(m_idMasterClient != idClient);
    1787     ASSERT_GUEST_RETURN(rClientState.m_idSession == UINT32_MAX, VERR_RESOURCE_BUSY);
     1779    Assert(m_idMasterClient != pClient->mID);
     1780    ASSERT_GUEST_RETURN(pClient->m_idSession == UINT32_MAX, VERR_RESOURCE_BUSY);
    17881781
    17891782    /*
     
    18041797                if (RT_SUCCESS(rc))
    18051798                {
    1806                     rClientState.m_idSession = idSession;
     1799                    pClient->m_idSession = idSession;
    18071800
    18081801                    RTListNodeRemove(&pCur->ListEntry);
    18091802                    RTMemFree(pCur);
    18101803                    m_cPreparedSessions -= 1;
    1811                     Log(("[Client %RU32] accepted session id %u.\n", idClient, idSession));
     1804                    Log(("[Client %RU32] accepted session id %u.\n", pClient->mID, idSession));
    18121805                }
    18131806                else
     
    18151808                return VINF_HGCM_ASYNC_EXECUTE; /* The caller must not complete it. */
    18161809            }
    1817             LogFunc(("Key mismatch for %u!\n", idClient));
     1810            LogFunc(("Key mismatch for %u!\n", pClient->mID));
    18181811            return VERR_MISMATCH;
    18191812        }
    18201813    }
    18211814
    1822     LogFunc(("No client prepared for %u!\n", idClient));
     1815    LogFunc(("No client prepared for %u!\n", pClient->mID));
    18231816    return VERR_NOT_FOUND;
    18241817}
     
    18281821 * Client asks another client (guest) session to close.
    18291822 *
    1830  * @return  IPRT status code.
    1831  * @param   idClient        The client's ID.
     1823 * @returns VBox status code.
     1824 * @param   pClient         The client state.
    18321825 * @param   cParms          Number of parameters.
    18331826 * @param   paParms         Array of parameters.
    18341827 */
    1835 int GstCtrlService::clientSessionCloseOther(uint32_t idClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1828int GstCtrlService::clientSessionCloseOther(ClientState *pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    18361829{
    18371830    /*
     
    18451838    uint32_t const fFlags = paParms[1].u.uint32;
    18461839
    1847     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1848     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1849     ClientState &rClientState = ItClientState->second;
    1850     ASSERT_GUEST_RETURN(rClientState.m_fIsMaster, VERR_ACCESS_DENIED);
     1840    ASSERT_GUEST_RETURN(pClient->m_fIsMaster, VERR_ACCESS_DENIED);
    18511841
    18521842    /*
     
    18591849    int rc = hostProcessCommand(HOST_SESSION_CLOSE, RT_ELEMENTS(aParms), aParms);
    18601850
    1861     LogFlowFunc(("Closing guest context ID=%RU32 (from client ID=%RU32) returned with rc=%Rrc\n", idContext, idClient, rc));
     1851    LogFlowFunc(("Closing guest context ID=%RU32 (from client ID=%RU32) returned with rc=%Rrc\n", idContext, pClient->mID, rc));
    18621852    return rc;
    18631853}
     
    18671857 * For compatiblity with old additions only - filtering / set session ID.
    18681858 *
    1869  * @return VBox status code.
    1870  * @param  idClient     The client's HGCM ID.
    1871  * @param  cParms       Number of parameters.
    1872  * @param  paParms      Array of parameters.
    1873  */
    1874 int GstCtrlService::clientMsgOldFilterSet(uint32_t idClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1859 * @return  VBox status code.
     1860 * @param   pClient     The client state.
     1861 * @param   cParms      Number of parameters.
     1862 * @param   paParms     Array of parameters.
     1863 */
     1864int GstCtrlService::clientMsgOldFilterSet(ClientState *pClient, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    18751865{
    18761866    /*
     
    18861876    ASSERT_GUEST_RETURN(paParms[3].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_TYPE); /* flags, unused */
    18871877
    1888     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1889     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1890     ClientState &rClientState = ItClientState->second;
    1891 
    18921878    /*
    18931879     * We have a bunch of expectations here:
     
    18991885     */
    19001886    ASSERT_GUEST_LOGREL_RETURN(m_fLegacyMode, VERR_WRONG_ORDER);
    1901     ASSERT_GUEST_LOGREL_MSG_RETURN(rClientState.m_idSession == UINT32_MAX, ("m_idSession=%#x\n", rClientState.m_idSession),
     1887    ASSERT_GUEST_LOGREL_MSG_RETURN(pClient->m_idSession == UINT32_MAX, ("m_idSession=%#x\n", pClient->m_idSession),
    19021888                                   VERR_WRONG_ORDER);
    1903     ASSERT_GUEST_LOGREL_RETURN(!rClientState.m_fIsMaster, VERR_WRONG_ORDER);
     1889    ASSERT_GUEST_LOGREL_RETURN(!pClient->m_fIsMaster, VERR_WRONG_ORDER);
    19041890
    19051891    if (uValue == 0)
     
    19181904
    19191905        for (ClientStateMapIter It = mClientStateMap.begin(); It != mClientStateMap.end(); ++It)
     1906#ifdef USE_PVCLIENT
     1907            ASSERT_GUEST_LOGREL_MSG_RETURN(It->second->m_idSession != idSession,
     1908                                           ("idSession=%u uValue=%#x idClient=%u; conflicting with client %u\n",
     1909                                            idSession, uValue, pClient->mID, It->second->mID),
     1910                                           VERR_DUPLICATE);
     1911#else
    19201912            ASSERT_GUEST_LOGREL_MSG_RETURN(It->second.m_idSession != idSession,
    19211913                                           ("idSession=%u uValue=%#x idClient=%u; conflicting with client %u\n",
    1922                                             idSession, uValue, idClient, It->second.mID),
     1914                                            idSession, uValue, pClient->mID, It->second.mID),
    19231915                                           VERR_DUPLICATE);
     1916#endif
    19241917        /* Commit it. */
    1925         rClientState.m_idSession = idSession;
     1918        pClient->m_idSession = idSession;
    19261919    }
    19271920    return VINF_SUCCESS;
     
    19361929 * old additions code didn't give damn about VERR_INTERRUPT.
    19371930 *
    1938  * @return VBox status code.
    1939  * @param  idClient     The client's HGCM ID.
    1940  * @param  cParms       Number of parameters.
    1941  */
    1942 int GstCtrlService::clientMsgOldSkip(uint32_t idClient, uint32_t cParms)
     1931 * @return  VBox status code.
     1932 * @param   pClient     The client state.
     1933 * @param   cParms      Number of parameters.
     1934 */
     1935int GstCtrlService::clientMsgOldSkip(ClientState *pClient, uint32_t cParms)
    19431936{
    19441937    /*
     
    19471940    ASSERT_GUEST_RETURN(cParms == 1, VERR_WRONG_PARAMETER_COUNT);
    19481941
    1949     ClientStateMapIter ItClientState = mClientStateMap.find(idClient);
    1950     ASSERT_GUEST_MSG_RETURN(ItClientState != mClientStateMap.end(), ("idClient=%RU32\n", idClient), VERR_INVALID_CLIENT_ID);
    1951     ClientState &rClientState = ItClientState->second;
    1952 
    19531942    /*
    19541943     * Execute the request.
    19551944     */
    1956     if (!rClientState.mHostCmdList.empty())
    1957         rClientState.OldDitchFirstHostCmd();
    1958 
    1959     LogFlowFunc(("[Client %RU32] Skipped current message - leagcy function\n", idClient));
     1945    if (!pClient->mHostCmdList.empty())
     1946        pClient->OldDitchFirstHostCmd();
     1947
     1948    LogFlowFunc(("[Client %RU32] Skipped current message - leagcy function\n", pClient->mID));
    19601949    return VINF_SUCCESS;
    19611950}
     
    19631952
    19641953/**
    1965  * Notifies the host (using low-level HGCM callbacks) about an event
    1966  * which was sent from the client.
    1967  *
    1968  * @return  IPRT status code.
     1954 * Forwards client call to the Main API.
     1955 *
     1956 * This is typically notifications and replys.
     1957 *
     1958 * @returns VBox status code.
     1959 * @param   pClient         The client state.
    19691960 * @param   idFunction      Function (event) that occured.
    19701961 * @param   cParms          Number of parameters.
    19711962 * @param   paParms         Array of parameters.
    19721963 */
    1973 int GstCtrlService::hostCallback(uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    1974 {
    1975     LogFlowFunc(("idFunction=%u (%s), cParms=%ld, paParms=%p\n", idFunction, GstCtrlGuestFnName((eGuestFn)idFunction), cParms, paParms));
    1976 
    1977     int rc;
    1978     if (mpfnHostCallback)
    1979     {
    1980         VBOXGUESTCTRLHOSTCALLBACK data(cParms, paParms);
    1981         /** @todo Not sure if this try/catch is necessary, I pushed it down here from
    1982          * GstCtrlService::call where it was not needed for anything else that I
    1983          * could spot.  I know this might be a tough, but I expect someone writing
    1984          * this kind of code to know what can throw errors and handle them where it
    1985          * is appropriate, rather than grand catch-all-at-the-top crap like this.
    1986          * The reason why it is utter crap, is that you have no state cleanup code
    1987          * where you might need it, which is why I despise exceptions in general */
    1988         try
    1989         {
    1990             rc = mpfnHostCallback(mpvHostData, idFunction, (void *)(&data), sizeof(data));
    1991         }
    1992         catch (std::bad_alloc &)
    1993         {
    1994             rc = VERR_NO_MEMORY;
    1995         }
    1996     }
    1997     else
    1998         rc = VERR_NOT_SUPPORTED;
    1999 
    2000     LogFlowFunc(("Returning rc=%Rrc\n", rc));
    2001     return rc;
    2002 }
    2003 
    2004 
    2005 /**
    2006  * Processes a command received from the host side and re-routes it to
    2007  * a connect client on the guest.
    2008  *
    2009  * @return  IPRT status code.
    2010  * @param   idFunction  Function code to process.
    2011  * @param   cParms      Number of parameters.
    2012  * @param   paParms     Array of parameters.
    2013  */
    2014 int GstCtrlService::hostProcessCommand(uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    2015 {
    2016     /*
    2017      * If no client is connected at all we don't buffer any host commands
    2018      * and immediately return an error to the host. This avoids the host
    2019      * waiting for a response from the guest side in case VBoxService on
    2020      * the guest is not running/system is messed up somehow.
    2021      */
    2022     if (mClientStateMap.empty())
    2023     {
    2024         LogFlow(("GstCtrlService::hostProcessCommand: VERR_NOT_FOUND!\n"));
    2025         return VERR_NOT_FOUND;
    2026     }
    2027 
    2028     HostCommand *pHostCmd = new (std::nothrow) HostCommand();
    2029     AssertReturn(pHostCmd, VERR_NO_MEMORY);
    2030 
    2031     int rc = pHostCmd->Init(idFunction, cParms, paParms);
    2032     if (RT_SUCCESS(rc))
    2033     {
    2034         RTListAppend(&mHostCmdList, &pHostCmd->m_ListEntry);
    2035         LogFlowFunc(("Handling host command m_idContextAndDst=%#RX64, idFunction=%RU32, cParms=%RU32, paParms=%p, cClients=%zu\n",
    2036                      pHostCmd->m_idContextAndDst, idFunction, cParms, paParms, mClientStateMap.size()));
    2037 
    2038         /*
    2039          * Find the message destination and post it to the client.  If the
    2040          * session ID doesn't match any particular client it goes to the master.
    2041          */
    2042         AssertMsg(!mClientStateMap.empty(), ("Client state map is empty when it should not be!\n"));
    2043 
    2044         /* Dispatch to the session. */
    2045         if (pHostCmd->m_idContextAndDst & VBOX_GUESTCTRL_DST_SESSION)
    2046         {
    2047             rc = VWRN_NOT_FOUND;
    2048             uint32_t const idSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHostCmd->m_idContext);
    2049             for (ClientStateMapIter It = mClientStateMap.begin(); It != mClientStateMap.end(); ++It)
    2050             {
    2051                 ClientState &rClientState = It->second;
    2052                 if (rClientState.m_idSession == idSession)
    2053                 {
    2054                     rc = rClientState.EnqueueCommand(pHostCmd);
    2055                     if (RT_SUCCESS(rc))
    2056                     {
    2057                         int rc2 = rClientState.Wakeup();
    2058                         LogFlowFunc(("Woke up client ID=%RU32 -> rc=%Rrc\n", rClientState.mID, rc2));
    2059                         RT_NOREF(rc2);
    2060                     }
    2061                     break;
    2062                 }
    2063             }
    2064         }
    2065 
    2066         /* Does the message go to the root service? */
    2067         if (   (pHostCmd->m_idContextAndDst & VBOX_GUESTCTRL_DST_ROOT_SVC)
    2068             && RT_SUCCESS(rc))
    2069         {
    2070             ClientStateMapIter It = mClientStateMap.find(m_idMasterClient);
    2071             if (It != mClientStateMap.end())
    2072             {
    2073                 ClientState &rClientState = It->second;
    2074                 int rc2 = rClientState.EnqueueCommand(pHostCmd);
    2075                 if (RT_SUCCESS(rc2))
    2076                 {
    2077                     rc2 = rClientState.Wakeup();
    2078                     LogFlowFunc(("Woke up client ID=%RU32 (master) -> rc=%Rrc\n", rClientState.mID, rc2));
    2079                 }
    2080                 else
    2081                     rc = rc2;
    2082             }
    2083             else
    2084                 rc = VERR_NOT_FOUND;
    2085         }
    2086     }
    2087 
    2088     /* Drop our command reference. */
    2089     pHostCmd->SaneRelease();
    2090 
    2091     if (RT_FAILURE(rc))
    2092         LogFunc(("Failed %Rrc (idFunction=%u, cParms=%u)\n", rc, idFunction, cParms));
    2093     return rc;
    2094 }
    2095 
    2096 
    2097 /**
    2098  * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnHostCall,
    2099  *  Wraps to the hostProcessCommand() member function.}
    2100  */
    2101 /*static*/ DECLCALLBACK(int)
    2102 GstCtrlService::svcHostCall(void *pvService, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    2103 {
    2104     AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
    2105     SELF *pThis = reinterpret_cast<SELF *>(pvService);
    2106     AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    2107 
    2108     LogFlowFunc(("fn=%RU32, cParms=%RU32, paParms=0x%p\n", u32Function, cParms, paParms));
    2109     AssertReturn(u32Function != HOST_CANCEL_PENDING_WAITS, VERR_INVALID_FUNCTION);
    2110     return pThis->hostProcessCommand(u32Function, cParms, paParms);
     1964int GstCtrlService::clientToMain(ClientState *pClient, uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1965{
     1966    /*
     1967     * Do input validation.  This class of messages all have a 32-bit context ID as
     1968     * the first parameter, so make sure it is there and appropriate for the caller.
     1969     */
     1970    ASSERT_GUEST_RETURN(cParms >= 1, VERR_WRONG_PARAMETER_COUNT);
     1971    ASSERT_GUEST_RETURN(paParms[0].type == VBOX_HGCM_SVC_PARM_32BIT, VERR_WRONG_PARAMETER_COUNT);
     1972    uint32_t const idContext = paParms[0].u.uint32;
     1973    uint32_t const idSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(idContext);
     1974
     1975    ASSERT_GUEST_MSG_RETURN(   pClient->m_idSession == idSession
     1976                            || pClient->m_fIsMaster
     1977                            || (   m_fLegacyMode                                /* (see bugref:9313#c16) */
     1978                                && pClient->m_idSession == UINT32_MAX
     1979                                && (   idFunction == GUEST_EXEC_STATUS
     1980                                    || idFunction == GUEST_SESSION_NOTIFY)),
     1981                            ("idSession=%u (CID=%#x) m_idSession=%u idClient=%u idFunction=%u (%s)\n", idSession, idContext,
     1982                             pClient->m_idSession, pClient->mID, idFunction, GstCtrlGuestFnName((eGuestFn)idFunction)),
     1983                            VERR_ACCESS_DENIED);
     1984
     1985    /*
     1986     * It seems okay, so make the call.
     1987     */
     1988    return hostCallback(idFunction, cParms, paParms);
    21111989}
    21121990
     
    21262004    LogFlowFunc(("[Client %RU32] idFunction=%RU32 (%s), cParms=%RU32, paParms=0x%p\n",
    21272005                 idClient, idFunction, GstCtrlGuestFnName((eGuestFn)idFunction), cParms, paParms));
    2128     RT_NOREF(tsArrival, pvClient);
    2129 
    2130     AssertLogRelReturnVoid(VALID_PTR(pvService));
    2131     SELF *pThis= reinterpret_cast<SELF *>(pvService);
    2132     AssertPtrReturnVoid(pThis);
    2133 
     2006    RT_NOREF(tsArrival);
     2007
     2008    /*
     2009     * Convert opaque pointers to typed ones.
     2010     */
     2011    SELF *pThis = reinterpret_cast<SELF *>(pvService);
     2012    AssertReturnVoidStmt(pThis, pThis->mpHelpers->pfnCallComplete(hCall, VERR_INTERNAL_ERROR_5));
     2013#ifdef USE_PVCLIENT
     2014    ClientState *pClient = reinterpret_cast<ClientState *>(pvClient);
     2015    AssertReturnVoidStmt(pClient, pThis->mpHelpers->pfnCallComplete(hCall, VERR_INVALID_CLIENT_ID));
     2016#else
     2017    ClientStateMapIter ItClientState = pThis->mClientStateMap.find(idClient);
     2018    AssertReturnVoidStmt(ItClientState != pThis->mClientStateMap.end(),
     2019                         pThis->mpHelpers->pfnCallComplete(hCall, VERR_INVALID_CLIENT_ID))
     2020    ClientState *pClient = ItClientState->second;
     2021    RT_NOREF(pvClient);
     2022#endif
     2023
     2024    /*
     2025     * Do the dispatching.
     2026     */
    21342027    int rc;
    21352028    switch (idFunction)
     
    21372030        case GUEST_MAKE_ME_MASTER:
    21382031            LogFlowFunc(("[Client %RU32] GUEST_MAKE_ME_MASTER\n", idClient));
    2139             rc = pThis->clientMakeMeMaster(idClient, hCall, cParms);
     2032            rc = pThis->clientMakeMeMaster(pClient, hCall, cParms);
    21402033            break;
    21412034        case GUEST_MSG_PEEK_NOWAIT:
    21422035            LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_NOWAIT\n", idClient));
    2143             rc = pThis->clientMsgPeek(idClient, hCall, cParms, paParms, false /*fWait*/);
     2036            rc = pThis->clientMsgPeek(pClient, hCall, cParms, paParms, false /*fWait*/);
    21442037            break;
    21452038        case GUEST_MSG_PEEK_WAIT:
    21462039            LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_WAIT\n", idClient));
    2147             rc = pThis->clientMsgPeek(idClient, hCall, cParms, paParms, true /*fWait*/);
     2040            rc = pThis->clientMsgPeek(pClient, hCall, cParms, paParms, true /*fWait*/);
    21482041            break;
    21492042        case GUEST_MSG_GET:
    21502043            LogFlowFunc(("[Client %RU32] GUEST_MSG_GET\n", idClient));
    2151             rc = pThis->clientMsgGet(idClient, hCall, cParms, paParms);
     2044            rc = pThis->clientMsgGet(pClient, hCall, cParms, paParms);
    21522045            break;
    21532046        case GUEST_MSG_CANCEL:
    21542047            LogFlowFunc(("[Client %RU32] GUEST_MSG_CANCEL\n", idClient));
    2155             rc = pThis->clientMsgCancel(idClient, cParms);
     2048            rc = pThis->clientMsgCancel(pClient, cParms);
    21562049            break;
    21572050        case GUEST_MSG_SKIP:
    21582051            LogFlowFunc(("[Client %RU32] GUEST_MSG_SKIP\n", idClient));
    2159             rc = pThis->clientMsgSkip(idClient, hCall, cParms, paParms);
     2052            rc = pThis->clientMsgSkip(pClient, hCall, cParms, paParms);
    21602053            break;
    21612054        case GUEST_SESSION_PREPARE:
    21622055            LogFlowFunc(("[Client %RU32] GUEST_SESSION_PREPARE\n", idClient));
    2163             rc = pThis->clientSessionPrepare(idClient, hCall, cParms, paParms);
     2056            rc = pThis->clientSessionPrepare(pClient, hCall, cParms, paParms);
    21642057            break;
    21652058        case GUEST_SESSION_CANCEL_PREPARED:
    21662059            LogFlowFunc(("[Client %RU32] GUEST_SESSION_CANCEL_PREPARED\n", idClient));
    2167             rc = pThis->clientSessionCancelPrepared(idClient, cParms, paParms);
     2060            rc = pThis->clientSessionCancelPrepared(pClient, cParms, paParms);
    21682061            break;
    21692062        case GUEST_SESSION_ACCEPT:
    21702063            LogFlowFunc(("[Client %RU32] GUEST_SESSION_ACCEPT\n", idClient));
    2171             rc = pThis->clientSessionAccept(idClient, hCall, cParms, paParms);
     2064            rc = pThis->clientSessionAccept(pClient, hCall, cParms, paParms);
    21722065            break;
    21732066        case GUEST_SESSION_CLOSE:
    21742067            LogFlowFunc(("[Client %RU32] GUEST_SESSION_CLOSE\n", idClient));
    2175             rc = pThis->clientSessionCloseOther(idClient, cParms, paParms);
     2068            rc = pThis->clientSessionCloseOther(pClient, cParms, paParms);
    21762069            break;
    21772070
     
    21792072         * Stuff the goes to various main objects:
    21802073         */
    2181         case GUEST_DISCONNECTED:
    21822074        case GUEST_MSG_REPLY:
    21832075        case GUEST_MSG_PROGRESS_UPDATE:
     
    21892081        case GUEST_DIR_NOTIFY:
    21902082        case GUEST_FILE_NOTIFY:
    2191             rc = pThis->hostCallback(idFunction, cParms, paParms);
     2083            LogFlowFunc(("[Client %RU32] %s\n", idClient, GstCtrlGuestFnName((eGuestFn)idFunction)));
     2084            rc = pThis->clientToMain(pClient, idFunction, cParms, paParms);
    21922085            Assert(rc != VINF_HGCM_ASYNC_EXECUTE);
    21932086            break;
     
    21992092        case GUEST_MSG_WAIT:
    22002093            LogFlowFunc(("[Client %RU32] GUEST_MSG_WAIT\n", idClient));
    2201             pThis->clientMsgOldGet(idClient, hCall, cParms, paParms);
     2094            pThis->clientMsgOldGet(pClient, hCall, cParms, paParms);
    22022095            rc = VINF_HGCM_ASYNC_EXECUTE;
    22032096            break;
     
    22052098        case GUEST_MSG_SKIP_OLD:
    22062099            LogFlowFunc(("[Client %RU32] GUEST_MSG_SKIP_OLD\n", idClient));
    2207             rc = pThis->clientMsgOldSkip(idClient, cParms);
     2100            rc = pThis->clientMsgOldSkip(pClient, cParms);
    22082101            break;
    22092102
    22102103        case GUEST_MSG_FILTER_SET:
    22112104            LogFlowFunc(("[Client %RU32] GUEST_MSG_FILTER_SET\n", idClient));
    2212             rc = pThis->clientMsgOldFilterSet(idClient, cParms, paParms);
     2105            rc = pThis->clientMsgOldFilterSet(pClient, cParms, paParms);
    22132106            break;
    22142107
     
    22412134
    22422135/**
    2243  * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnSaveState}
     2136 * Notifies the host (using low-level HGCM callbacks) about an event
     2137 * which was sent from the client.
     2138 *
     2139 * @returns VBox status code.
     2140 * @param   idFunction      Function (event) that occured.
     2141 * @param   cParms          Number of parameters.
     2142 * @param   paParms         Array of parameters.
     2143 */
     2144int GstCtrlService::hostCallback(uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     2145{
     2146    LogFlowFunc(("idFunction=%u (%s), cParms=%ld, paParms=%p\n", idFunction, GstCtrlGuestFnName((eGuestFn)idFunction), cParms, paParms));
     2147
     2148    int rc;
     2149    if (mpfnHostCallback)
     2150    {
     2151        VBOXGUESTCTRLHOSTCALLBACK data(cParms, paParms);
     2152        /** @todo Not sure if this try/catch is necessary, I pushed it down here from
     2153         * GstCtrlService::call where it was not needed for anything else that I
     2154         * could spot.  I know this might be a tough, but I expect someone writing
     2155         * this kind of code to know what can throw errors and handle them where it
     2156         * is appropriate, rather than grand catch-all-at-the-top crap like this.
     2157         * The reason why it is utter crap, is that you have no state cleanup code
     2158         * where you might need it, which is why I despise exceptions in general */
     2159        try
     2160        {
     2161            rc = mpfnHostCallback(mpvHostData, idFunction, &data, sizeof(data));
     2162        }
     2163        catch (std::bad_alloc &)
     2164        {
     2165            rc = VERR_NO_MEMORY;
     2166        }
     2167    }
     2168    else
     2169        rc = VERR_NOT_SUPPORTED;
     2170
     2171    LogFlowFunc(("Returning rc=%Rrc\n", rc));
     2172    return rc;
     2173}
     2174
     2175
     2176/**
     2177 * Processes a command received from the host side and re-routes it to
     2178 * a connect client on the guest.
     2179 *
     2180 * @returns VBox status code.
     2181 * @param   idFunction  Function code to process.
     2182 * @param   cParms      Number of parameters.
     2183 * @param   paParms     Array of parameters.
     2184 */
     2185int GstCtrlService::hostProcessCommand(uint32_t idFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     2186{
     2187    /*
     2188     * If no client is connected at all we don't buffer any host commands
     2189     * and immediately return an error to the host. This avoids the host
     2190     * waiting for a response from the guest side in case VBoxService on
     2191     * the guest is not running/system is messed up somehow.
     2192     */
     2193    if (mClientStateMap.empty())
     2194    {
     2195        LogFlow(("GstCtrlService::hostProcessCommand: VERR_NOT_FOUND!\n"));
     2196        return VERR_NOT_FOUND;
     2197    }
     2198
     2199    HostCommand *pHostCmd = new (std::nothrow) HostCommand();
     2200    AssertReturn(pHostCmd, VERR_NO_MEMORY);
     2201
     2202    int rc = pHostCmd->Init(idFunction, cParms, paParms);
     2203    if (RT_SUCCESS(rc))
     2204    {
     2205        RTListAppend(&mHostCmdList, &pHostCmd->m_ListEntry);
     2206        LogFlowFunc(("Handling host command m_idContextAndDst=%#RX64, idFunction=%RU32, cParms=%RU32, paParms=%p, cClients=%zu\n",
     2207                     pHostCmd->m_idContextAndDst, idFunction, cParms, paParms, mClientStateMap.size()));
     2208
     2209        /*
     2210         * Find the message destination and post it to the client.  If the
     2211         * session ID doesn't match any particular client it goes to the master.
     2212         */
     2213        AssertMsg(!mClientStateMap.empty(), ("Client state map is empty when it should not be!\n"));
     2214
     2215        /* Dispatch to the session. */
     2216        if (pHostCmd->m_idContextAndDst & VBOX_GUESTCTRL_DST_SESSION)
     2217        {
     2218            rc = VWRN_NOT_FOUND;
     2219            uint32_t const idSession = VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(pHostCmd->m_idContext);
     2220            for (ClientStateMapIter It = mClientStateMap.begin(); It != mClientStateMap.end(); ++It)
     2221            {
     2222#ifdef USE_PVCLIENT
     2223                ClientState *pClient = It->second;
     2224#else
     2225                ClientState *pClient = &It->second;
     2226#endif
     2227                if (pClient->m_idSession == idSession)
     2228                {
     2229                    rc = pClient->EnqueueCommand(pHostCmd);
     2230                    if (RT_SUCCESS(rc))
     2231                    {
     2232                        int rc2 = pClient->Wakeup();
     2233                        LogFlowFunc(("Woke up client ID=%RU32 -> rc=%Rrc\n", pClient->mID, rc2));
     2234                        RT_NOREF(rc2);
     2235                    }
     2236                    break;
     2237                }
     2238            }
     2239        }
     2240
     2241        /* Does the message go to the root service? */
     2242        if (   (pHostCmd->m_idContextAndDst & VBOX_GUESTCTRL_DST_ROOT_SVC)
     2243            && RT_SUCCESS(rc))
     2244        {
     2245            ClientStateMapIter It = mClientStateMap.find(m_idMasterClient);
     2246            if (It != mClientStateMap.end())
     2247            {
     2248#ifdef USE_PVCLIENT
     2249                ClientState *pClient = It->second;
     2250#else
     2251                ClientState *pClient = &It->second;
     2252#endif
     2253                int rc2 = pClient->EnqueueCommand(pHostCmd);
     2254                if (RT_SUCCESS(rc2))
     2255                {
     2256                    rc2 = pClient->Wakeup();
     2257                    LogFlowFunc(("Woke up client ID=%RU32 (master) -> rc=%Rrc\n", pClient->mID, rc2));
     2258                }
     2259                else
     2260                    rc = rc2;
     2261            }
     2262            else
     2263                rc = VERR_NOT_FOUND;
     2264        }
     2265    }
     2266
     2267    /* Drop our command reference. */
     2268    pHostCmd->SaneRelease();
     2269
     2270    if (RT_FAILURE(rc))
     2271        LogFunc(("Failed %Rrc (idFunction=%u, cParms=%u)\n", rc, idFunction, cParms));
     2272    return rc;
     2273}
     2274
     2275
     2276/**
     2277 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnHostCall,
     2278 *  Wraps to the hostProcessCommand() member function.}
    22442279 */
    22452280/*static*/ DECLCALLBACK(int)
    2246 GstCtrlService::svcSaveState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM)
    2247 {
    2248     RT_NOREF(pvClient);
     2281GstCtrlService::svcHostCall(void *pvService, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     2282{
    22492283    AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
    22502284    SELF *pThis = reinterpret_cast<SELF *>(pvService);
    22512285    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
    22522286
     2287    LogFlowFunc(("fn=%RU32, cParms=%RU32, paParms=0x%p\n", u32Function, cParms, paParms));
     2288    AssertReturn(u32Function != HOST_CANCEL_PENDING_WAITS, VERR_INVALID_FUNCTION);
     2289    return pThis->hostProcessCommand(u32Function, cParms, paParms);
     2290}
     2291
     2292
     2293
     2294
     2295/**
     2296 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnSaveState}
     2297 */
     2298/*static*/ DECLCALLBACK(int)
     2299GstCtrlService::svcSaveState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM)
     2300{
     2301    RT_NOREF(pvClient);
     2302    SELF *pThis = reinterpret_cast<SELF *>(pvService);
     2303    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2304
    22532305    SSMR3PutU32(pSSM, 1);
    2254     SSMR3PutBool(pSSM, idClient == pThis->m_idMasterClient);
    2255     return SSMR3PutBool(pSSM, pThis->m_fLegacyMode);
     2306    SSMR3PutBool(pSSM, pThis->m_fLegacyMode);
     2307    return SSMR3PutBool(pSSM, idClient == pThis->m_idMasterClient);
    22562308}
    22572309
     
    22642316{
    22652317    RT_NOREF(pvClient);
    2266     AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
    22672318    SELF *pThis = reinterpret_cast<SELF *>(pvService);
    22682319    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     
    22882339        ClientStateMapIter It = pThis->mClientStateMap.find(idClient);
    22892340        if (It != pThis->mClientStateMap.end())
     2341#ifdef USE_PVCLIENT
     2342            It->second->m_fIsMaster = fIsMaster;
     2343#else
    22902344            It->second.m_fIsMaster = fIsMaster;
     2345#endif
    22912346        else
    22922347            AssertFailed();
     
    23162371/*static*/ DECLCALLBACK(int) GstCtrlService::svcRegisterExtension(void *pvService, PFNHGCMSVCEXT pfnExtension, void *pvExtension)
    23172372{
    2318     AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
    23192373    SELF *pThis = reinterpret_cast<SELF *>(pvService);
    23202374    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2375    AssertPtrNullReturn(pfnExtension, VERR_INVALID_POINTER);
    23212376
    23222377    pThis->mpfnHostCallback = pfnExtension;
    2323     pThis->mpvHostData = pvExtension;
     2378    pThis->mpvHostData      = pvExtension;
    23242379    return VINF_SUCCESS;
    23252380}
     
    23712426                 * because we're a class which can have members for that :-).
    23722427                 */
    2373                 pTable->cbClient = 0;  /** @todo this is where ClientState should live, isn't it? */
     2428                pTable->cbClient = sizeof(ClientState);
    23742429
    23752430                /* Register functions. */
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