VirtualBox

Ignore:
Timestamp:
Jul 13, 2020 9:07:41 PM (4 years ago)
Author:
vboxsync
Message:

HostServices: Clang 11++ adjustments. Eliminated pointless auto_ptr. Added a whole bunch of RT_NOEXCEPT to the DnD service abstraction. Misc cleanups. bugref:9790

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/DragAndDrop/VBoxDragAndDropSvc.cpp

    r85145 r85318  
    5050{
    5151public:
    52 
    53     DragAndDropClient(uint32_t uClientID)
    54         : HGCM::Client(uClientID)
     52    DragAndDropClient(uint32_t idClient)
     53        : HGCM::Client(idClient)
    5554    {
    5655        RT_ZERO(m_SvcCtx);
     
    6362
    6463public:
    65 
    66     void disconnect(void);
     64    void disconnect(void) RT_NOEXCEPT;
    6765};
    6866
     
    7977{
    8078public:
    81 
    8279    explicit DragAndDropService(PVBOXHGCMSVCHELPERS pHelpers)
    8380        : HGCM::AbstractService<DragAndDropService>(pHelpers)
    84         , m_pManager(NULL) {}
     81        , m_pManager(NULL)
     82        , m_u32Mode(VBOX_DRAG_AND_DROP_MODE_OFF)
     83    {}
    8584
    8685protected:
    87 
    88     int  init(VBOXHGCMSVCFNTABLE *pTable);
    89     int  uninit(void);
    90     int  clientConnect(uint32_t u32ClientID, void *pvClient);
    91     int  clientDisconnect(uint32_t u32ClientID, void *pvClient);
    92     void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID, void *pvClient, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    93     int  hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    94 
    95     int modeSet(uint32_t u32Mode);
    96     inline uint32_t modeGet(void) const { return m_u32Mode; };
    97 
    98 protected:
     86    int  init(VBOXHGCMSVCFNTABLE *pTable) RT_NOEXCEPT RT_OVERRIDE;
     87    int  uninit(void) RT_NOEXCEPT RT_OVERRIDE;
     88    int  clientConnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT RT_OVERRIDE;
     89    int  clientDisconnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT RT_OVERRIDE;
     90    void guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t idClient, void *pvClient, uint32_t u32Function,
     91                   uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT RT_OVERRIDE;
     92    int  hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT RT_OVERRIDE;
     93
     94private:
     95    int  modeSet(uint32_t u32Mode) RT_NOEXCEPT;
     96    inline uint32_t modeGet(void) const RT_NOEXCEPT
     97    { return m_u32Mode; };
    9998
    10099    static DECLCALLBACK(int) progressCallback(uint32_t uStatus, uint32_t uPercentage, int rc, void *pvUser);
    101100
    102 protected:
    103 
     101private:
    104102    /** Pointer to our DnD manager instance. */
    105103    DnDManager                        *m_pManager;
     
    112110     *  to process new commands. The key is the (unique) client ID. */
    113111    DnDClientQueue                     m_clientQueue;
    114     /** Current drag and drop mode. */
     112    /** Current drag and drop mode, VBOX_DRAG_AND_DROP_MODE_XXX. */
    115113    uint32_t                           m_u32Mode;
    116114};
     
    123121/**
    124122 * Called when the HGCM client disconnected on the guest side.
     123 *
    125124 * This function takes care of the client's data cleanup and also lets the host
    126125 * know that the client has been disconnected.
    127  *
    128126 */
    129 void DragAndDropClient::disconnect(void)
     127void DragAndDropClient::disconnect(void) RT_NOEXCEPT
    130128{
    131     LogFlowThisFunc(("uClient=%RU32\n", m_uClientID));
     129    LogFlowThisFunc(("uClient=%RU32\n", m_idClient));
    132130
    133131    if (IsDeferred())
     
    146144        int rc2 = m_SvcCtx.pfnHostCallback(m_SvcCtx.pvHostData, GUEST_DND_DISCONNECT, &data, sizeof(data));
    147145        if (RT_FAILURE(rc2))
    148             LogFlowFunc(("Warning: Unable to notify host about client %RU32 disconnect, rc=%Rrc\n", m_uClientID, rc2));
     146            LogFlowFunc(("Warning: Unable to notify host about client %RU32 disconnect, rc=%Rrc\n", m_idClient, rc2));
    149147        /* Not fatal. */
    150148    }
     
    156154*********************************************************************************************************************************/
    157155
    158 int DragAndDropService::init(VBOXHGCMSVCFNTABLE *pTable)
     156int DragAndDropService::init(VBOXHGCMSVCFNTABLE *pTable) RT_NOEXCEPT
    159157{
    160158    /* Register functions. */
     
    174172        m_pManager = new DnDManager(&DragAndDropService::progressCallback, this);
    175173    }
    176     catch(std::bad_alloc &)
     174    catch (std::bad_alloc &)
    177175    {
    178176        rc = VERR_NO_MEMORY;
     
    183181}
    184182
    185 int DragAndDropService::uninit(void)
     183int DragAndDropService::uninit(void) RT_NOEXCEPT
    186184{
    187185    LogFlowFuncEnter();
     
    205203}
    206204
    207 int DragAndDropService::clientConnect(uint32_t u32ClientID, void *pvClient)
     205int DragAndDropService::clientConnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT
    208206{
    209207    RT_NOREF1(pvClient);
     
    214212    }
    215213
    216     int rc = VINF_SUCCESS;
    217214
    218215    /*
    219216     * Add client to our client map.
    220217     */
    221     if (m_clientMap.find(u32ClientID) != m_clientMap.end())
    222         rc = VERR_ALREADY_EXISTS;
    223 
    224     if (RT_SUCCESS(rc))
    225     {
    226         try
    227         {
    228             DragAndDropClient *pClient = new DragAndDropClient(u32ClientID);
    229             pClient->SetSvcContext(m_SvcCtx);
    230             m_clientMap[u32ClientID] = pClient;
    231         }
    232         catch(std::bad_alloc &)
    233         {
    234             rc = VERR_NO_MEMORY;
    235         }
    236 
    237         if (RT_SUCCESS(rc))
    238         {
    239             /*
    240              * Reset the message queue as soon as a new clients connect
    241              * to ensure that every client has the same state.
    242              */
    243             if (m_pManager)
    244                 m_pManager->Reset();
    245         }
    246     }
    247 
    248     LogFlowFunc(("Client %RU32 connected, rc=%Rrc\n", u32ClientID, rc));
    249     return rc;
     218    if (m_clientMap.find(idClient) != m_clientMap.end())
     219    {
     220        LogFunc(("Client %RU32 is already connected!\n", idClient));
     221        return VERR_ALREADY_EXISTS;
     222    }
     223
     224    try
     225    {
     226        DragAndDropClient *pClient = new DragAndDropClient(idClient);
     227        pClient->SetSvcContext(m_SvcCtx);
     228        m_clientMap[idClient] = pClient;
     229    }
     230    catch (std::bad_alloc &)
     231    {
     232        LogFunc(("Client %RU32 - VERR_NO_MEMORY!\n", idClient));
     233        return VERR_NO_MEMORY;
     234    }
     235
     236    /*
     237     * Reset the message queue as soon as a new clients connect
     238     * to ensure that every client has the same state.
     239     */
     240    if (m_pManager)
     241        m_pManager->Reset();
     242
     243    LogFlowFunc(("Client %RU32 connected (VINF_SUCCESS)\n", idClient));
     244    return VINF_SUCCESS;
    250245}
    251246
    252 int DragAndDropService::clientDisconnect(uint32_t u32ClientID, void *pvClient)
     247int DragAndDropService::clientDisconnect(uint32_t idClient, void *pvClient) RT_NOEXCEPT
    253248{
    254249    RT_NOREF1(pvClient);
    255250
    256251    /* Client not found? Bail out early. */
    257     DnDClientMap::iterator itClient =  m_clientMap.find(u32ClientID);
     252    DnDClientMap::iterator itClient =  m_clientMap.find(idClient);
    258253    if (itClient == m_clientMap.end())
     254    {
     255        LogFunc(("Client %RU32 not found!\n", idClient));
    259256        return VERR_NOT_FOUND;
     257    }
    260258
    261259    /*
    262260     * Remove from waiters queue.
    263261     */
    264     m_clientQueue.remove(u32ClientID);
     262    m_clientQueue.remove(idClient);
    265263
    266264    /*
     
    272270    m_clientMap.erase(itClient);
    273271
    274     LogFlowFunc(("Client %RU32 disconnected\n", u32ClientID));
     272    LogFlowFunc(("Client %RU32 disconnected\n", idClient));
    275273    return VINF_SUCCESS;
    276274}
    277275
    278 int DragAndDropService::modeSet(uint32_t u32Mode)
     276int DragAndDropService::modeSet(uint32_t u32Mode) RT_NOEXCEPT
    279277{
    280278#ifndef VBOX_WITH_DRAG_AND_DROP_GH
     
    304302}
    305303
    306 void DragAndDropService::guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t u32ClientID,
     304void DragAndDropService::guestCall(VBOXHGCMCALLHANDLE callHandle, uint32_t idClient,
    307305                                   void *pvClient, uint32_t u32Function,
    308                                    uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     306                                   uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT
    309307{
    310308    RT_NOREF1(pvClient);
    311     LogFlowFunc(("u32ClientID=%RU32, u32Function=%RU32, cParms=%RU32\n",
    312                  u32ClientID, u32Function, cParms));
     309    LogFlowFunc(("idClient=%RU32, u32Function=%RU32, cParms=%RU32\n", idClient, u32Function, cParms));
    313310
    314311    /* Check if we've the right mode set. */
     
    319316        {
    320317            if (modeGet() != VBOX_DRAG_AND_DROP_MODE_OFF)
    321             {
    322318                rc = VINF_SUCCESS;
    323             }
    324319            else
    325320            {
     
    341336            break;
    342337        }
     338
    343339        case GUEST_DND_HG_ACK_OP:
    344340        case GUEST_DND_HG_REQ_DATA:
     
    347343            if (   modeGet() == VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
    348344                || modeGet() == VBOX_DRAG_AND_DROP_MODE_HOST_TO_GUEST)
    349             {
    350345                rc = VINF_SUCCESS;
    351             }
    352346            else
    353                 LogFlowFunc(("Host -> Guest DnD mode disabled, ignoring request\n"));
     347                LogFlowFunc(("Host -> Guest DnD mode disabled, failing request\n"));
    354348            break;
    355349        }
     
    366360            if (   modeGet() == VBOX_DRAG_AND_DROP_MODE_BIDIRECTIONAL
    367361                || modeGet() == VBOX_DRAG_AND_DROP_MODE_GUEST_TO_HOST)
    368             {
    369362                rc = VINF_SUCCESS;
    370             }
    371363            else
    372364#endif
    373                 LogFlowFunc(("Guest -> Host DnD mode disabled, ignoring request\n"));
     365                LogFlowFunc(("Guest -> Host DnD mode disabled, failing request\n"));
    374366            break;
    375367        }
     
    397389    DragAndDropClient *pClient = NULL;
    398390
    399     DnDClientMap::iterator itClient =  m_clientMap.find(u32ClientID);
     391    DnDClientMap::iterator itClient =  m_clientMap.find(idClient);
    400392    if (itClient != m_clientMap.end())
    401393    {
     
    405397    else
    406398    {
    407         LogFunc(("Client %RU32 was not found\n", u32ClientID));
     399        LogFunc(("Client %RU32 was not found\n", idClient));
    408400        rc = VERR_NOT_FOUND;
    409401    }
     
    412404 * Will set rc to VERR_INVALID_PARAMETER otherwise. See #9777. */
    413405#define VERIFY_BUFFER_SIZE_UINT32(a_ParmUInt32, a_SizeExpected) \
    414 { \
     406do { \
    415407    uint32_t cbTemp = 0; \
    416408    rc = HGCMSvcGetU32(&a_ParmUInt32, &cbTemp); \
    417409    ASSERT_GUEST_STMT(RT_SUCCESS(rc) && cbTemp == a_SizeExpected, rc = VERR_INVALID_PARAMETER); \
    418 }
     410} while (0)
    419411
    420412    if (rc == VINF_SUCCESS) /* Note: rc might be VINF_HGCM_ASYNC_EXECUTE! */
     
    990982            AssertPtr(pClient);
    991983            pClient->SetDeferred(callHandle, u32Function, cParms, paParms);
    992             m_clientQueue.push_back(u32ClientID);
     984            m_clientQueue.push_back(idClient);
    993985        }
    994986        catch (std::bad_alloc &)
     
    10101002
    10111003int DragAndDropService::hostCall(uint32_t u32Function,
    1012                                  uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     1004                                 uint32_t cParms, VBOXHGCMSVCPARM paParms[]) RT_NOEXCEPT
    10131005{
    10141006    LogFlowFunc(("u32Function=%RU32, cParms=%RU32, cClients=%zu, cQueue=%zu\n",
     
    10161008
    10171009    int rc;
    1018 
    1019     do
    1020     {
    1021         bool fSendToGuest = false; /* Whether to send the message down to the guest side or not. */
    1022 
    1023         switch (u32Function)
     1010    bool fSendToGuest = false; /* Whether to send the message down to the guest side or not. */
     1011
     1012    switch (u32Function)
     1013    {
     1014        case HOST_DND_SET_MODE:
    10241015        {
    1025             case HOST_DND_SET_MODE:
    1026             {
    1027                 if (cParms != 1)
    1028                     rc = VERR_INVALID_PARAMETER;
    1029                 else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
    1030                     rc = VERR_INVALID_PARAMETER;
    1031                 else
    1032                     rc = modeSet(paParms[0].u.uint32);
    1033                 break;
    1034             }
    1035 
    1036             case HOST_DND_CANCEL:
    1037             {
    1038                 LogFlowFunc(("Cancelling all waiting clients ...\n"));
    1039 
    1040                 /* Reset the message queue as the host cancelled the whole operation. */
    1041                 m_pManager->Reset();
    1042 
    1043                 rc = m_pManager->AddMsg(u32Function, cParms, paParms, true /* fAppend */);
    1044                 if (RT_FAILURE(rc))
    1045                 {
    1046                     AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n", u32Function, rc));
    1047                     break;
    1048                 }
    1049 
    1050                 /*
    1051                  * Wake up all deferred clients and tell them to process
    1052                  * the cancelling message next.
    1053                  */
    1054                 DnDClientQueue::iterator itQueue = m_clientQueue.begin();
    1055                 while (itQueue != m_clientQueue.end())
    1056                 {
    1057                     DnDClientMap::iterator itClient = m_clientMap.find(*itQueue);
    1058                     Assert(itClient != m_clientMap.end());
    1059 
    1060                     DragAndDropClient *pClient = itClient->second;
    1061                     AssertPtr(pClient);
    1062 
    1063                     int rc2 = pClient->SetDeferredMsgInfo(HOST_DND_CANCEL,
    1064                                                           /* Protocol v3+ also contains the context ID. */
    1065                                                           pClient->GetProtocolVer() >= 3 ? 1 : 0);
    1066                     pClient->CompleteDeferred(rc2);
    1067 
    1068                     m_clientQueue.erase(itQueue);
    1069                     itQueue = m_clientQueue.begin();
    1070                 }
    1071 
    1072                 Assert(m_clientQueue.empty());
    1073 
    1074                 /* Tell the host that everything went well. */
    1075                 rc = VINF_SUCCESS;
    1076                 break;
    1077             }
    1078 
    1079             case HOST_DND_HG_EVT_ENTER:
    1080             {
    1081                 /* Reset the message queue as a new DnD operation just began. */
    1082                 m_pManager->Reset();
    1083 
    1084                 fSendToGuest = true;
    1085                 rc = VINF_SUCCESS;
    1086                 break;
    1087             }
    1088 
    1089             default:
    1090             {
    1091                 fSendToGuest = true;
    1092                 rc = VINF_SUCCESS;
    1093                 break;
    1094             }
     1016            if (cParms != 1)
     1017                rc = VERR_INVALID_PARAMETER;
     1018            else if (paParms[0].type != VBOX_HGCM_SVC_PARM_32BIT)
     1019                rc = VERR_INVALID_PARAMETER;
     1020            else
     1021                rc = modeSet(paParms[0].u.uint32);
     1022            break;
    10951023        }
    10961024
     1025        case HOST_DND_CANCEL:
     1026        {
     1027            LogFlowFunc(("Cancelling all waiting clients ...\n"));
     1028
     1029            /* Reset the message queue as the host cancelled the whole operation. */
     1030            m_pManager->Reset();
     1031
     1032            rc = m_pManager->AddMsg(u32Function, cParms, paParms, true /* fAppend */);
     1033            if (RT_FAILURE(rc))
     1034            {
     1035                AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n", u32Function, rc));
     1036                break;
     1037            }
     1038
     1039            /*
     1040             * Wake up all deferred clients and tell them to process
     1041             * the cancelling message next.
     1042             */
     1043            DnDClientQueue::iterator itQueue = m_clientQueue.begin();
     1044            while (itQueue != m_clientQueue.end())
     1045            {
     1046                DnDClientMap::iterator itClient = m_clientMap.find(*itQueue);
     1047                Assert(itClient != m_clientMap.end());
     1048
     1049                DragAndDropClient *pClient = itClient->second;
     1050                AssertPtr(pClient);
     1051
     1052                int rc2 = pClient->SetDeferredMsgInfo(HOST_DND_CANCEL,
     1053                                                      /* Protocol v3+ also contains the context ID. */
     1054                                                      pClient->GetProtocolVer() >= 3 ? 1 : 0);
     1055                pClient->CompleteDeferred(rc2);
     1056
     1057                m_clientQueue.erase(itQueue);
     1058                itQueue = m_clientQueue.begin();
     1059            }
     1060
     1061            Assert(m_clientQueue.empty());
     1062
     1063            /* Tell the host that everything went well. */
     1064            rc = VINF_SUCCESS;
     1065            break;
     1066        }
     1067
     1068        case HOST_DND_HG_EVT_ENTER:
     1069        {
     1070            /* Reset the message queue as a new DnD operation just began. */
     1071            m_pManager->Reset();
     1072
     1073            fSendToGuest = true;
     1074            rc = VINF_SUCCESS;
     1075            break;
     1076        }
     1077
     1078        default:
     1079        {
     1080            fSendToGuest = true;
     1081            rc = VINF_SUCCESS;
     1082            break;
     1083        }
     1084    }
     1085
     1086    do /* goto avoidance break-loop. */
     1087    {
    10971088        if (fSendToGuest)
    10981089        {
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