VirtualBox

Changeset 28006 in vbox


Ignore:
Timestamp:
Apr 6, 2010 1:54:06 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
59713
Message:

Guest Control: Update (protocol hacking, untested).

File:
1 edited

Legend:

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

    r27976 r28006  
    5151
    5252namespace guestControl {
     53
     54struct Client
     55{
     56    VBOXGUESTCTRPARAMBUFFER parmBuf;
     57    VBOXHGCMCALLHANDLE callHandle;
     58    uint32_t uClientID;
     59};
     60
     61struct HostCmd
     62{
     63    VBOXGUESTCTRPARAMBUFFER parmBuf;
     64    uint32_t uAssignedToClientID;
     65};
     66
     67/** The client list list type */
     68typedef std::list <Client> ClientList;
     69/** The host cmd list type */
     70typedef std::list <HostCmd> HostCmdList;
    5371
    5472/**
     
    7694    /** User data pointer to be supplied to the host callback function */
    7795    void *mpvHostData;
    78     /** The execution data to hold (atm only one buffer!) */
    79     VBOXGUESTCTRPARAMBUFFER mExec;
     96    /** The client list */
     97    ClientList mClients;
     98    /** The host command list */
     99    HostCmdList mHostCmds;
    80100    RTCRITSECT critsect;
    81101
     
    95115                                "GuestCtrlReq");
    96116#endif
    97         mExec.uParmCount = 0;
    98         mExec.pParms = NULL;
    99 
    100117        if (RT_SUCCESS(rc))
    101118            rc = RTCritSectInit(&critsect);
     
    124141     * Stub implementation of pfnConnect and pfnDisconnect.
    125142     */
    126     static DECLCALLBACK(int) svcConnectDisconnect (void * /* pvService */,
    127                                                    uint32_t /* u32ClientID */,
    128                                                    void * /* pvClient */)
    129     {
    130         return VINF_SUCCESS;
     143    static DECLCALLBACK(int) svcConnect (void *pvService,
     144                                         uint32_t u32ClientID,
     145                                         void *pvClient)
     146    {
     147        AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
     148        LogFlowFunc (("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));
     149        SELF *pSelf = reinterpret_cast<SELF *>(pvService);
     150        int rc = pSelf->clientConnect(u32ClientID, pvClient);
     151        LogFlowFunc (("rc=%Rrc\n", rc));
     152        return rc;
     153    }
     154
     155    /**
     156     * @copydoc VBOXHGCMSVCHELPERS::pfnConnect
     157     * Stub implementation of pfnConnect and pfnDisconnect.
     158     */
     159    static DECLCALLBACK(int) svcDisconnect (void *pvService,
     160                                            uint32_t u32ClientID,
     161                                            void *pvClient)
     162    {
     163        AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
     164        LogFlowFunc (("pvService=%p, u32ClientID=%u, pvClient=%p\n", pvService, u32ClientID, pvClient));
     165        SELF *pSelf = reinterpret_cast<SELF *>(pvService);
     166        int rc = pSelf->clientDisconnect(u32ClientID, pvClient);
     167        LogFlowFunc (("rc=%Rrc\n", rc));
     168        return rc;
    131169    }
    132170
     
    187225    int prepareExecute(uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    188226    static DECLCALLBACK(int) reqThreadFn(RTTHREAD ThreadSelf, void *pvUser);
    189     void call (VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
    190                void *pvClient, uint32_t eFunction, uint32_t cParms,
    191                VBOXHGCMSVCPARM paParms[]);
    192     int hostCall (uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    193     int uninit ();
     227    int clientConnect(uint32_t u32ClientID, void *pvClient);
     228    int clientDisconnect(uint32_t u32ClientID, void *pvClient);
     229    void call(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
     230              void *pvClient, uint32_t eFunction, uint32_t cParms,
     231              VBOXHGCMSVCPARM paParms[]);
     232    int hostCall(uint32_t eFunction, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     233    int uninit();
    194234};
    195235
     
    341381}
    342382
     383int Service::clientConnect(uint32_t u32ClientID, void *pvClient)
     384{
     385ASMBreakpoint();
     386
     387    bool bFound = false;
     388    for (ClientList::const_iterator it = mClients.begin();
     389         !bFound && it != mClients.end(); ++it)
     390    {
     391        if (it->uClientID == u32ClientID)
     392            bFound = true;
     393    }
     394
     395    if (!bFound)
     396    {
     397        Client newClient;
     398
     399        /** @todo Use a constructor here! */
     400        newClient.uClientID = u32ClientID;
     401        newClient.parmBuf.uParmCount = 0;
     402        newClient.parmBuf.pParms = NULL;
     403
     404        mClients.push_back(newClient);
     405        LogFlowFunc(("New client = %ld connected\n", u32ClientID));
     406    }
     407    else
     408    {
     409        LogFlowFunc(("Exising client (%ld) connected another instance\n", u32ClientID));
     410    }
     411    return VINF_SUCCESS;
     412}
     413
     414int Service::clientDisconnect(uint32_t u32ClientID, void *pvClient)
     415{
     416ASMBreakpoint();
     417
     418    bool bFound = false;
     419    for (ClientList::iterator it = mClients.begin();
     420         !bFound && it != mClients.end(); ++it)
     421    {
     422        if (it->uClientID == u32ClientID)
     423        {
     424            mClients.erase(it);
     425            bFound = true;
     426        }
     427    }
     428    Assert(bFound);
     429
     430    LogFlowFunc(("Client (%ld) disconnected\n", u32ClientID));
     431    return VINF_SUCCESS;
     432}
     433
    343434/**
    344435 * Handle an HGCM service call.
     
    366457            /* The guest asks the host for the next messsage to process. */
    367458            case GUEST_GET_HOST_MSG:
    368                 LogFlowFunc(("GUEST_GET_HOST_MSG\n"));
    369                 paParms[0].setUInt32(HOST_EXEC_CMD); /* msg id */
    370                 paParms[1].setUInt32(12); /* parms count */
     459                LogFlowFunc(("GUEST_GET_HOST_MSG\n"));               
     460
     461/** @todo !!!!! LOCKING !!!!!!!!! */
     462
     463                if (cParms < 2)
     464                {
     465                    LogFlowFunc(("Parameter buffer is too small!\n"));
     466                    rc = VERR_INVALID_PARAMETER;
     467                }
     468                else
     469                {     
     470                    /*
     471                     * If host command list is empty (nothing to do right now) just
     472                     * defer the call until we got something to do (makes the client
     473                     * wait, depending on the flags set).
     474                     */
     475                    if (mHostCmds.empty())
     476                        rc = VINF_HGCM_ASYNC_EXECUTE;
     477   
     478                    if (RT_SUCCESS(rc))
     479                    {
     480                        /*
     481                         * Get the next unassigned host command in the list.
     482                         */
     483                        bool bFound = false;
     484                        HostCmdList::iterator it;
     485                        for (it = mHostCmds.begin();
     486                             !bFound && it != mHostCmds.end(); ++it)
     487                        {
     488                            if (it->uAssignedToClientID == 0)
     489                                bFound = true;
     490                        }
     491                        if (!bFound) /* No new command found, defer ... */
     492                            rc = VINF_HGCM_ASYNC_EXECUTE;
     493
     494                        /*
     495                         * Okay we got a host command which is unassigned at the moment.                   
     496                         */
     497                        if (RT_SUCCESS(rc))
     498                        {
     499                            /*
     500                             * Do *not* pop the most recent (front) command here yet, because
     501                             * the client could fail in retrieving the GUEST_GET_HOST_MSG_DATA message
     502                             * below.
     503                             */
     504                            uint32_t uCmd = 0;
     505                            if (it->parmBuf.uParmCount)
     506                                it->parmBuf.pParms[0].getUInt32(&uCmd);
     507                            paParms[0].setUInt32(uCmd); /* msg id */
     508                            paParms[1].setUInt32(it->parmBuf.uParmCount); /* parms count */
     509   
     510                            /* Assign this command to the specific client ID. */
     511                            it->uAssignedToClientID = u32ClientID;
     512                        }
     513                    }
     514                }
    371515                break;
    372516
    373517            case GUEST_GET_HOST_MSG_DATA:
    374                 LogFlowFunc(("GUEST_GET_HOST_MSG_DATA\n"));
    375                 rc = execBufferAssign(&mExec, cParms, paParms);
     518                {
     519                    LogFlowFunc(("GUEST_GET_HOST_MSG_DATA\n"));
     520
     521/** @todo !!!!! LOCKING !!!!!!!!! */
     522
     523                    /*
     524                     * Get host command assigned to incoming client ID.                           
     525                     */
     526                    bool bFound = false;
     527                    HostCmdList::iterator it;
     528                    for (it = mHostCmds.begin();
     529                         !bFound && it != mHostCmds.end(); ++it)
     530                    {
     531                        if (it->uAssignedToClientID == u32ClientID)                     
     532                            bFound = true;
     533                    }
     534                    Assert(bFound);
     535
     536                    /*
     537                     * Assign buffered data to client HGCM parms.
     538                     */
     539                    rc = execBufferAssign(&it->parmBuf, cParms, paParms);
     540       
     541                    /*
     542                     * Finally remove the command from the list.
     543                     */
     544                    mHostCmds.erase(it);
     545                }
    376546                break;
    377547
     
    402572    if (rc != VINF_HGCM_ASYNC_EXECUTE)
    403573    {
    404         mpHelpers->pfnCallComplete (callHandle, rc);
     574        mpHelpers->pfnCallComplete(callHandle, rc);
    405575    }
    406576}
     
    424594            case HOST_EXEC_CMD:
    425595                LogFlowFunc(("HOST_EXEC_CMD\n"));
    426                 rc = execBufferAllocate(&mExec, cParms, paParms);
     596
     597/** @todo !!!!! LOCKING !!!!!!!!! */
     598
     599                HostCmd newCmd;
     600                execBufferAllocate(&newCmd.parmBuf, cParms, paParms);
     601                newCmd.uAssignedToClientID = 0;
     602                mHostCmds.push_back(newCmd);
    427603                break;
    428604
     
    504680                /* Register functions. */
    505681                ptable->pfnUnload             = Service::svcUnload;
    506                 ptable->pfnConnect            = Service::svcConnectDisconnect;
    507                 ptable->pfnDisconnect         = Service::svcConnectDisconnect;
     682                ptable->pfnConnect            = Service::svcConnect;
     683                ptable->pfnDisconnect         = Service::svcDisconnect;
    508684                ptable->pfnCall               = Service::svcCall;
    509685                ptable->pfnHostCall           = Service::svcHostCall;
Note: See TracChangeset for help on using the changeset viewer.

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