VirtualBox

Ignore:
Timestamp:
Feb 24, 2014 9:07:22 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92425
Message:

DnD: Update, bugfixes.

Location:
trunk/src/VBox/HostServices/DragAndDrop
Files:
2 edited

Legend:

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

    r50508 r50561  
    4141
    4242/**
    43  * Internal DnD message class for informing the guest about a new directory.
     43 * Internal DnD message class for informing the
     44 * guest about a new directory.
    4445 *
    4546 * @see DnDHGSendDataMessage
     
    5556        , m_pvProgressUser(pvProgressUser)
    5657    {
     58        RTCString strPath = m_URIObject.GetDestPath();
     59        LogFlowFunc(("strPath=%s (%zu)\n", strPath.c_str(), strPath.length()));
     60
    5761        VBOXHGCMSVCPARM paTmpParms[3];
    58         paTmpParms[0].setString(m_URIObject.GetDestPath().c_str());
    59         paTmpParms[1].setUInt32((uint32_t)(m_URIObject.GetDestPath().length() + 1));
     62        paTmpParms[0].setString(strPath.c_str());
     63        paTmpParms[1].setUInt32((uint32_t)(strPath.length() + 1));
    6064        paTmpParms[2].setUInt32(m_URIObject.GetMode());
    6165
    6266        m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_DIR, 3, paTmpParms);
    6367    }
     68
     69public:
    6470
    6571    int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     
    7884    DnDURIObject           m_URIObject;
    7985
    80     /* Progress stuff */
     86    /* Progress stuff. */
    8187    PFNDNDPRIVATEPROGRESS  m_pfnProgressCallback;
    8288    void                  *m_pvProgressUser;
     
    96102    virtual ~DnDHGSendFilePrivate(void);
    97103
     104public:
     105
    98106    int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    99107
     
    101109
    102110    DnDURIObject           m_URIObject;
    103     VBOXHGCMSVCPARM        m_paSkelParms[5];
    104 
    105     /* Progress stuff */
     111    /** Skeleton parameters for the next upcoming message in case
     112     *  the file data didn't fit completely into the first one. */
     113    VBOXHGCMSVCPARM        m_aSkelParms[5];
     114
     115    /* Progress stuff. */
    106116    PFNDNDPRIVATEPROGRESS  m_pfnProgressCallback;
    107117    void                  *m_pvProgressUser;
     
    127137    size_t                 m_cbDone;
    128138
    129     /* Progress stuff */
     139    /* Progress stuff. */
    130140    PFNDNDPRIVATEPROGRESS  m_pfnProgressCallback;
    131141    void                  *m_pvProgressUser;
     
    146156    , m_pvProgressUser(pvProgressUser)
    147157{
    148     m_paSkelParms[0].setString(m_URIObject.GetDestPath().c_str());
    149     m_paSkelParms[1].setUInt32((uint32_t)(m_URIObject.GetDestPath().length() + 1));
    150     m_paSkelParms[2].setPointer(NULL, 0);
    151     m_paSkelParms[3].setUInt32(0);
    152     m_paSkelParms[4].setUInt32(m_URIObject.GetMode());
    153 
    154     m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_paSkelParms);
     158    LogFlowFunc(("strPath=%s (%zu)\n",
     159                 m_URIObject.GetDestPath().c_str(), m_URIObject.GetDestPath().length()));
     160
     161    m_aSkelParms[0].setString(m_URIObject.GetDestPath().c_str()); /* pvName */
     162    m_aSkelParms[1].setUInt32((uint32_t)(m_URIObject.GetDestPath().length() + 1)); /* cbName */
     163    m_aSkelParms[2].setPointer(NULL, 0); /* pvData */
     164    m_aSkelParms[3].setUInt32(0); /* cbData */
     165    m_aSkelParms[4].setUInt32(m_URIObject.GetMode()); /* fMode */
     166
     167    m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5, m_aSkelParms);
    155168}
    156169
     
    174187    {
    175188        /* Get buffer size + pointer to buffer from guest side. */
    176         uint32_t cbToRead = paParms[2].u.pointer.size;
     189        uint32_t cbToRead = paParms[2].u.pointer.size; /* cbData */
    177190        Assert(cbToRead);
    178         void *pvBuf = paParms[2].u.pointer.addr;
     191        void *pvBuf = paParms[2].u.pointer.addr; /* pvData */
    179192        AssertPtr(pvBuf);
    180193
    181194        rc = m_URIObject.Read(pvBuf, cbToRead, &cbRead);
     195        LogFlowFunc(("Read %RU32 bytes (%RU32 bytes buffer) for \"%s\", rc=%Rrc\n",
     196                     cbRead, cbToRead, m_URIObject.GetDestPath().c_str(), rc));
     197
    182198        if (RT_LIKELY(RT_SUCCESS(rc)))
    183199        {
    184             /* Tell the guest the actual size. */
    185             paParms[3].setUInt32((uint32_t)cbRead);
     200            /* Tell the guest the actual size read. */
     201            paParms[3].setUInt32((uint32_t)cbRead); /* cbData */
    186202        }
    187203    }
     
    195211                /* More data needed to send over. Prepare the next message. */
    196212                m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_SND_FILE, 5 /* cParms */,
    197                                                m_paSkelParms);
     213                                               m_aSkelParms);
    198214            }
    199215            catch(std::bad_alloc &)
     
    323339        Assert(cbList);
    324340
    325         LogFlowFunc(("Old data: '%s'\n", pszList));
     341        LogFlowFunc(("Old data (%RU32 bytes): '%s'\n", cbList, pszList));
    326342
    327343        /* The list is separated by newline (even if only one file is listed). */
     
    330346        if (!lstURIOrg.isEmpty())
    331347        {
    332             rc = m_lstURI.AppendNativePathsFromList(lstURIOrg, 0 /* fFlags */);
     348            rc = m_lstURI.AppendURIPathsFromList(lstURIOrg, 0 /* fFlags */);
    333349            if (RT_SUCCESS(rc))
    334350            {
     
    351367                paParms[4].u.uint32       = (uint32_t)(strNewURIs.length() + 1);
    352368
    353                 LogFlowFunc(("Set new data: '%s'\n", (char*)paParms[3].u.pointer.addr));
     369                LogFlowFunc(("Set new data (%RU32 bytes): '%s'\n",
     370                            paParms[3].u.pointer.size,
     371                            (const char*)paParms[3].u.pointer.addr));
    354372            }
    355373        }
  • trunk/src/VBox/HostServices/DragAndDrop/service.cpp

    r50508 r50561  
    7272{
    7373public:
     74
    7475    explicit DragAndDropService(PVBOXHGCMSVCHELPERS pHelpers)
    75       : HGCM::AbstractService<DragAndDropService>(pHelpers)
    76       , m_pManager(0)
    77       , m_cClients(0)
     76        : HGCM::AbstractService<DragAndDropService>(pHelpers)
     77        , m_pManager(0)
     78        , m_cClients(0)
    7879    {}
    7980
     
    8889
    8990    static DECLCALLBACK(int) progressCallback(uint32_t uPercentage, uint32_t uState, int rc, void *pvUser);
    90     int      hostMessage(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    91     void     modeSet(uint32_t u32Mode);
     91    int modeSet(uint32_t u32Mode);
    9292    inline uint32_t modeGet() { return m_u32Mode; };
    9393
     
    110110    pTable->pfnLoadState         = NULL;  /* construction done before restoring suffices */
    111111    pTable->pfnRegisterExtension = svcRegisterExtension;
     112
     113    /* Drag'n drop mode is disabled by default. */
    112114    modeSet(VBOX_DRAG_AND_DROP_MODE_OFF);
    113115
     
    117119}
    118120
    119 int DragAndDropService::uninit()
     121int DragAndDropService::uninit(void)
    120122{
    121123    delete m_pManager;
     
    131133    else
    132134        AssertMsgFailed(("Maximum number of clients reached\n"));
     135
     136    /*
     137     * Clear the message queue as soon as a new clients connect
     138     * to ensure that every client has the same state.
     139     */
     140    if (m_pManager)
     141        m_pManager->clear();
     142
    133143    return VINF_SUCCESS;
    134144}
     
    136146int DragAndDropService::clientDisconnect(uint32_t u32ClientID, void *pvClient)
    137147{
    138     /* Remove all waiters with this clientId. */
     148    /* Remove all waiters with this u32ClientID. */
    139149    for (size_t i = 0; i < m_clientQueue.size(); )
    140150    {
     
    142152        if (pClient->clientId() == u32ClientID)
    143153        {
    144             m_pHelpers->pfnCallComplete(pClient->handle(), VERR_INTERRUPTED);
     154            if (m_pHelpers)
     155                m_pHelpers->pfnCallComplete(pClient->handle(), VERR_INTERRUPTED);
     156
    145157            m_clientQueue.removeAt(i);
    146158            delete pClient;
     
    153165}
    154166
    155 void DragAndDropService::modeSet(uint32_t u32Mode)
    156 {
     167int DragAndDropService::modeSet(uint32_t u32Mode)
     168{
     169    /** @todo Validate mode. */
    157170    switch (u32Mode)
    158171    {
     
    166179        default:
    167180            m_u32Mode = VBOX_DRAG_AND_DROP_MODE_OFF;
    168     }
     181            break;
     182    }
     183
     184    return VINF_SUCCESS;
    169185}
    170186
     
    222238    if (!fIgnoreRequest)
    223239    {
    224         rc = VINF_SUCCESS;
    225240        switch (u32Function)
    226241        {
     
    244259                        && paParms[2].u.uint32) /* Blocking? */
    245260                    {
    246                         m_clientQueue.append(new HGCM::Client(u32ClientID, callHandle, u32Function, cParms, paParms));
     261                        m_clientQueue.append(new HGCM::Client(u32ClientID, callHandle,
     262                                                              u32Function, cParms, paParms));
    247263                        rc = VINF_HGCM_ASYNC_EXECUTE;
    248264                    }
     
    393409                    DragAndDropSvc::VBOXDNDCBEVTERRORDATA data;
    394410                    data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_GH_EVT_ERROR;
     411
    395412                    uint32_t rcOp;
    396413                    paParms[0].getUInt32(&rcOp);
    397414                    data.rc = rcOp;
     415
    398416                    if (m_pfnHostCallback)
    399417                        rc = m_pfnHostCallback(m_pvHostData, u32Function, &data, sizeof(data));
     
    411429    }
    412430    else
    413         rc = VERR_NOT_SUPPORTED;
     431        rc = VERR_ACCESS_DENIED;
    414432
    415433    /* If async execute is requested, we didn't notify the guest about
    416434     * completion. The client is queued into the waiters list and will be
    417435     * notified as soon as a new event is available. */
    418     if (rc != VINF_HGCM_ASYNC_EXECUTE)
     436    if (   rc != VINF_HGCM_ASYNC_EXECUTE
     437        && m_pHelpers)
     438    {
    419439        m_pHelpers->pfnCallComplete(callHandle, rc);
     440    }
     441
    420442    LogFlowFunc(("Returning rc=%Rrc\n", rc));
    421443}
    422444
    423 int DragAndDropService::hostMessage(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    424 {
    425     int rc = VINF_SUCCESS;
    426 #if 0
    427     HGCM::Message *pMessage = new HGCM::Message(u32Function, cParms, paParms);
    428     m_hostQueue.push(pMessage);
    429 //    bool fPush = true;
    430     RTPrintf("client queue %u\n", m_clientQueue.size());
    431     RTPrintf("host   queue %u\n", m_hostQueue.size());
    432     if (!m_clientQueue.empty())
    433     {
    434         pMessage = m_hostQueue.front();
    435         HGCM::Client *pClient = m_clientQueue.front();
    436         /* Check if this was a request for getting the next host
    437          * message. If so, return the message id and the parameter
    438          * count. The message itself has to be queued. */
    439         if (pClient->message() == DragAndDropSvc::GUEST_GET_NEXT_HOST_MSG)
    440         {
    441             RTPrintf("client is waiting for next host msg\n");
    442 //            rc = VERR_TOO_MUCH_DATA;
    443             pClient->addMessageInfo(pMessage);
    444             /* temp */
    445 //        m_pHelpers->pfnCallComplete(pClient->handle(), rc);
    446 //        m_clientQueue.pop();
    447 //        delete pClient;
    448         }
    449         else
    450         {
    451             RTPrintf("client is waiting for host msg (%d)\n", u32Function);
    452             /* There is a request for a host message pending. Check
    453              * if this is the correct message and if so deliver. If
    454              * not the message will be queued. */
    455             rc = pClient->addMessage(pMessage);
    456             m_hostQueue.pop();
    457             delete pMessage;
    458 //            if (RT_SUCCESS(rc))
    459 //                fPush = false;
    460         }
    461         /* In any case mark this client request as done. */
    462         m_pHelpers->pfnCallComplete(pClient->handle(), rc);
    463         m_clientQueue.pop_front();
    464         delete pClient;
    465     }
    466 //    if (fPush)
    467 //    {
    468 //        RTPrintf("push message\n");
    469 //        m_hostQueue.push(pMessage);
    470 //    }
    471 //    else
    472 //        delete pMessage;
    473 #endif
    474 
    475     return rc;
    476 }
    477 
    478 int DragAndDropService::hostCall(uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     445int DragAndDropService::hostCall(uint32_t u32Function,
     446                                 uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    479447{
    480448    LogFlowFunc(("u32Function=%RU32, cParms=%RU32\n", u32Function, cParms));
    481449
    482     int rc = VINF_SUCCESS;
     450    int rc;
    483451    if (u32Function == DragAndDropSvc::HOST_DND_SET_MODE)
    484452    {
     
    488456            rc = VERR_INVALID_PARAMETER;
    489457        else
    490             modeSet(paParms[0].u.uint32);
     458            rc = modeSet(paParms[0].u.uint32);
    491459    }
    492460    else if (modeGet() != VBOX_DRAG_AND_DROP_MODE_OFF)
    493461    {
    494         rc = m_pManager->addMessage(u32Function, cParms, paParms);
    495         if (   RT_SUCCESS(rc)
    496             && !m_clientQueue.isEmpty())
     462        if (!m_clientQueue.isEmpty()) /* At least one client on the guest connected? */
    497463        {
    498             HGCM::Client *pClient = m_clientQueue.first();
    499             AssertPtr(pClient);
    500             /* Check if this was a request for getting the next host
    501              * message. If so, return the message id and the parameter
    502              * count. The message itself has to be queued. */
    503             if (pClient->message() == DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG)
    504             {
    505                 LogFlowFunc(("Client %RU32 is waiting for next host msg\n", pClient->clientId()));
    506 
    507                 uint32_t uMsg1;
    508                 uint32_t cParms1;
    509                 rc = m_pManager->nextMessageInfo(&uMsg1, &cParms1);
    510                 if (RT_SUCCESS(rc))
    511                 {
    512                     pClient->addMessageInfo(uMsg1, cParms1);
    513                     m_pHelpers->pfnCallComplete(pClient->handle(), rc);
    514                     m_clientQueue.removeFirst();
    515                     delete pClient;
    516                 }
    517                 else
    518                     AssertMsgFailed(("Should not happen!"));
     464            rc = m_pManager->addMessage(u32Function, cParms, paParms);
     465            if (RT_SUCCESS(rc))
     466            {
     467                HGCM::Client *pClient = m_clientQueue.first();
     468                AssertPtr(pClient);
     469
     470                /* Check if this was a request for getting the next host
     471                 * message. If so, return the message id and the parameter
     472                 * count. The message itself has to be queued. */
     473                uint32_t uMsg = pClient->message();
     474                if (uMsg == DragAndDropSvc::GUEST_DND_GET_NEXT_HOST_MSG)
     475                {
     476                    LogFlowFunc(("Client %RU32 is waiting for next host msg\n", pClient->clientId()));
     477
     478                    uint32_t uMsg1;
     479                    uint32_t cParms1;
     480                    rc = m_pManager->nextMessageInfo(&uMsg1, &cParms1);
     481                    if (RT_SUCCESS(rc))
     482                    {
     483                        pClient->addMessageInfo(uMsg1, cParms1);
     484                        if (m_pHelpers)
     485                            m_pHelpers->pfnCallComplete(pClient->handle(), rc);
     486
     487                        m_clientQueue.removeFirst();
     488                        delete pClient;
     489                    }
     490                    else
     491                        AssertMsgFailed(("m_pManager::nextMessageInfo failed with rc=%Rrc\n", rc));
     492                }
     493                else
     494                    AssertMsgFailed(("Client ID=%RU32 in wrong state with uMsg=%RU32\n",
     495                                     pClient->clientId(), uMsg));
    519496            }
    520497            else
    521                 AssertMsgFailed(("Should not happen!"));
     498                AssertMsgFailed(("Adding new message of type=%RU32 failed with rc=%Rrc\n",
     499                                 u32Function, rc));
    522500        }
    523 //      else
    524 //          AssertMsgFailed(("Should not happen %Rrc!", rc));
     501        else
     502        {
     503            /* Tell the host that the guest does not support drag'n drop.
     504             * This might happen due to not installed Guest Additions or
     505             * not running VBoxTray/VBoxClient. */
     506            rc = VERR_NOT_SUPPORTED;
     507        }
     508    }
     509    else
     510    {
     511        /* Tell the host that a wrong drag'n drop mode is set. */
     512        rc = VERR_ACCESS_DENIED;
    525513    }
    526514
     
    534522
    535523    DragAndDropService *pSelf = static_cast<DragAndDropService *>(pvUser);
     524    AssertPtr(pSelf);
    536525
    537526    if (pSelf->m_pfnHostCallback)
     
    545534        data.rc           = rc;
    546535
    547         return pSelf->m_pfnHostCallback(pSelf->m_pvHostData, DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS, &data, sizeof(data));
     536        return pSelf->m_pfnHostCallback(pSelf->m_pvHostData,
     537                                        DragAndDropSvc::GUEST_DND_HG_EVT_PROGRESS,
     538                                        &data, sizeof(data));
    548539    }
    549540
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