VirtualBox

Changeset 50561 in vbox


Ignore:
Timestamp:
Feb 24, 2014 9:07:22 PM (11 years ago)
Author:
vboxsync
Message:

DnD: Update, bugfixes.

Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/GuestHost/DragAndDrop.h

    r50508 r50561  
    5656public:
    5757
    58     RTCString GetSourcePath(void) const { return m_strSrcPath; }
    59     RTCString GetDestPath(void) const { return m_strDstPath; }
     58    const RTCString &GetSourcePath(void) const { return m_strSrcPath; }
     59    const RTCString &GetDestPath(void) const { return m_strDstPath; }
    6060    uint32_t GetMode(void) const { return m_fMode; }
    6161    uint64_t GetSize(void) const { return m_cbSize; }
     
    110110    void RemoveFirst(void);
    111111    int RootFromURIData(const void *pvData, size_t cbData, uint32_t fFlags);
    112     RTCString RootToString(const RTCString &strBasePath = "");
     112    RTCString RootToString(const RTCString &strBasePath = "", const RTCString &strSeparator = "\r\n");
    113113    size_t RootCount(void) { return m_lstRoot.size(); }
    114114    size_t TotalBytes(void) { return m_cbTotal; }
  • trunk/include/VBox/HostServices/DragAndDropSvc.h

    r50508 r50561  
    7373
    7474    HOST_DND_HG_EVT_ENTER              = 200,
    75     HOST_DND_HG_EVT_MOVE,
    76     HOST_DND_HG_EVT_LEAVE,
    77     HOST_DND_HG_EVT_DROPPED,
    78     HOST_DND_HG_EVT_CANCEL,
     75    HOST_DND_HG_EVT_MOVE               = 201,
     76    HOST_DND_HG_EVT_LEAVE              = 202,
     77    HOST_DND_HG_EVT_DROPPED            = 203,
     78    HOST_DND_HG_EVT_CANCEL             = 204,
    7979    /** Gets the actual MIME data, based on
    8080     *  the format(s) specified by HOST_DND_HG_EVT_ENTER. */
    81     HOST_DND_HG_SND_DATA,
     81    HOST_DND_HG_SND_DATA               = 205,
    8282    /** Sent when the actual buffer for HOST_DND_HG_SND_DATA
    8383     *  was too small, issued by the DnD host service. */
    84     HOST_DND_HG_SND_MORE_DATA,
     84    HOST_DND_HG_SND_MORE_DATA          = 206,
    8585    /** Directory entry to be handled on the guest. */
    86     HOST_DND_HG_SND_DIR,
     86    HOST_DND_HG_SND_DIR                = 207,
    8787    /** File entry to be handled on the guest. */
    88     HOST_DND_HG_SND_FILE,
     88    HOST_DND_HG_SND_FILE               = 208,
    8989
    9090    /*
     
    101101
    102102    HOST_DND_GH_RECV_DIR               = 650,
    103     HOST_DND_GH_RECV_FILE
     103    HOST_DND_GH_RECV_FILE              = 670
    104104};
    105105
     
    124124    /** The guest requests the actual DnD data to be sent
    125125     *  from the host. */
    126     GUEST_DND_HG_REQ_DATA,
    127     GUEST_DND_HG_EVT_PROGRESS,
     126    GUEST_DND_HG_REQ_DATA              = 401,
     127    GUEST_DND_HG_EVT_PROGRESS          = 402,
    128128
    129129    /* G->H */
     
    135135    GUEST_DND_GH_ACK_PENDING           = 500,
    136136    /**
    137      * Sends data of the requsted MIME type to the host. There can
     137     * Sends data of the requested format to the host. There can
    138138     * be more than one message if the actual data does not fit
    139139     * into one.
    140140     */
    141     GUEST_DND_GH_SND_DATA,
    142     GUEST_DND_GH_EVT_ERROR,
     141    GUEST_DND_GH_SND_DATA              = 501,
     142    GUEST_DND_GH_EVT_ERROR             = 502,
    143143
    144144    GUEST_DND_GH_SND_DIR               = 700,
    145     GUEST_DND_GH_SND_FILE
     145    GUEST_DND_GH_SND_FILE              = 701
    146146};
    147147
     
    376376    /** Total bytes to send. This can be more than
    377377     *  the data block specified in pvData above, e.g.
    378      *  when sending over file objects. */
     378     *  when sending over file objects afterwards. */
    379379    HGCMFunctionParameter cbTotalBytes; /* OUT uint32_t */
    380380} VBOXDNDGHSENDDATAMSG;
     
    417417
    418418    /**
    419      * GH Cancel Data event.
    420      *
    421      * Used by:
    422      * GUEST_DND_GH_EVT_CANCEL
     419     * GH Error event.
     420     *
     421     * Used by:
     422     * GUEST_DND_GH_EVT_ERROR
    423423     */
    424424    HGCMFunctionParameter uRC;          /* OUT uint32_t */
  • trunk/include/VBox/HostServices/Service.h

    r44529 r50561  
    4343public:
    4444    Message(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM aParms[])
    45       : m_uMsg(0)
    46       , m_cParms(0)
    47       , m_paParms(0)
     45        : m_uMsg(0)
     46        , m_cParms(0)
     47        , m_paParms(0)
    4848    {
    4949        setData(uMsg, cParms, aParms);
  • trunk/include/VBox/VBoxGuestLib.h

    r50508 r50561  
    724724VBGLR3DECL(int)     VbglR3DnDGHAcknowledgePending(uint32_t u32ClientId, uint32_t uDefAction, uint32_t uAllActions, const char* pcszFormats);
    725725VBGLR3DECL(int)     VbglR3DnDGHSendData(uint32_t u32ClientId, const char *pszFormat, void *pvData, uint32_t cbData);
    726 VBGLR3DECL(int)     VbglR3DnDGHErrorEvent(uint32_t u32ClientId, int rcOp);
     726VBGLR3DECL(int)     VbglR3DnDGHSendError(uint32_t u32ClientId, int rcOp);
    727727#  endif /* VBOX_WITH_DRAG_AND_DROP_GH */
    728728/** @} */
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.cpp

    r50508 r50561  
    6060VBoxDnDWnd::VBoxDnDWnd(void)
    6161    : hWnd(NULL),
     62      uAllActions(DND_IGNORE_ACTION),
    6263      mfMouseButtonDown(false),
    6364#ifdef VBOX_WITH_DRAG_AND_DROP_GH
     
    6970{
    7071    RT_ZERO(startupInfo);
    71 
    72     reset();
    7372}
    7473
     
    209208    else
    210209    {
    211         LogRelFunc(("Unable to initialize OLE, hr=%Rhrc\n", hr));
     210        LogRel(("DnD: Unable to initialize OLE, hr=%Rhrc\n", hr));
    212211        rc = VERR_COM_UNEXPECTED;
    213212    }
     
    380379            else if (mMode == GH) /* Guest to host. */
    381380            {
    382                 //hide();
    383 
    384381                /* Starting here VBoxDnDDropTarget should
    385382                 * take over; was instantiated when registering
     
    405402        {
    406403            VBOXDNDEVENT *pEvent = (PVBOXDNDEVENT)lParam;
    407             AssertPtr(pEvent);
     404            if (!pEvent)
     405                break; /* No event received, bail out. */
    408406
    409407            LogFlowThisFunc(("Received uType=%RU32, uScreenID=%RU32\n",
     
    416414                {
    417415                    LogFlowThisFunc(("HOST_DND_HG_EVT_ENTER\n"));
    418 
    419                     reset();
    420 
    421                     mMode = HG;
    422416
    423417                    if (pEvent->Event.cbFormats)
     
    484478                    LogFlowThisFunc(("HOST_DND_GH_REQ_PENDING\n"));
    485479#ifdef VBOX_WITH_DRAG_AND_DROP_GH
    486                     if (   mMode == Unknown
    487                         /* There can be more than one HOST_DND_GH_REQ_PENDING
    488                          * messages coming in. */
    489                         || mMode == GH)
    490                     {
    491                         mMode = GH;
    492                         rc = OnGhIsDnDPending(pEvent->Event.uScreenId);
    493                     }
    494                     else
    495                         rc = VERR_WRONG_ORDER;
     480                    rc = OnGhIsDnDPending(pEvent->Event.uScreenId);
     481
    496482#else
    497483                    rc = VERR_NOT_SUPPORTED;
     
    504490                    LogFlowThisFunc(("HOST_DND_GH_EVT_DROPPED\n"));
    505491#ifdef VBOX_WITH_DRAG_AND_DROP_GH
    506                     if (mMode == GH)
    507                     {
    508                         rc = OnGhDropped(pEvent->Event.pszFormats,
    509                                          pEvent->Event.cbFormats,
    510                                          pEvent->Event.u.a.uDefAction);
    511                     }
    512                     else
    513                         rc = VERR_WRONG_ORDER;
    514 #else
    515                     rc = VERR_NOT_SUPPORTED;
    516 #endif
    517                     break;
    518                 }
    519 
    520                 case DragAndDropSvc::GUEST_DND_GH_EVT_ERROR:
    521                 {
    522                     LogFlowThisFunc(("GUEST_DND_GH_EVT_ERROR\n"));
    523 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
    524                     reset();
    525                     rc = VINF_SUCCESS; /** @todo GUEST_DND_GH_EVT_ERROR */
    526 #else
    527                     rc = VERR_NOT_SUPPORTED;
    528 #endif
    529                     break;
    530                 }
    531 
    532                 case DragAndDropSvc::HOST_DND_GH_RECV_DIR:
    533                 {
    534                     LogFlowThisFunc(("HOST_DND_GH_RECV_DIR\n"));
    535 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
    536                     if (mMode == GH)
    537                     {
    538                         rc = OnGhSendDir(pEvent->Event.pszFormats,
    539                                          pEvent->Event.cbFormats,
    540                                          pEvent->Event.u.a.uDefAction);
    541                     }
    542                     else
    543                         rc = VERR_WRONG_ORDER;
    544 #else
    545                     rc = VERR_NOT_SUPPORTED;
    546 #endif
    547                     break;
    548                 }
    549 
    550                 case DragAndDropSvc::HOST_DND_GH_RECV_FILE:
    551                 {
    552                     LogFlowThisFunc(("HOST_DND_GH_RECV_FILE\n"));
    553 #ifdef VBOX_WITH_DRAG_AND_DROP_GH
    554                     if (mMode == GH)
    555                     {
    556                         rc = OnGhSendFile(pEvent->Event.pszFormats,
    557                                           pEvent->Event.cbFormats,
    558                                           pEvent->Event.u.a.uDefAction);
    559                     }
    560                     else
    561                         rc = VERR_WRONG_ORDER;
     492                    rc = OnGhDropped(pEvent->Event.pszFormats,
     493                                     pEvent->Event.cbFormats,
     494                                     pEvent->Event.u.a.uDefAction);
    562495#else
    563496                    rc = VERR_NOT_SUPPORTED;
     
    600533            }
    601534
    602             LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n",
    603                              pEvent->Event.uType, rc));
    604535            if (pEvent)
     536            {
     537                LogFlowThisFunc(("Processing event %RU32 resulted in rc=%Rrc\n",
     538                                 pEvent->Event.uType, rc));
     539
    605540                RTMemFree(pEvent);
     541            }
    606542            return 0;
    607543        }
     
    702638int VBoxDnDWnd::OnHgEnter(const RTCList<RTCString> &lstFormats, uint32_t uAllActions)
    703639{
     640    if (mMode == GH) /* Wrong mode? Bail out. */
     641        return VERR_WRONG_ORDER;
     642
    704643#ifdef DEBUG
    705644    LogFlowThisFunc(("uActions=0x%x, lstFormats=%zu: ", uAllActions, lstFormats.size()));
     
    708647    LogFlow(("\n"));
    709648#endif
     649
     650    reset();
     651    setMode(HG);
    710652
    711653    /* Save all allowed actions. */
     
    779721int VBoxDnDWnd::OnHgMove(uint32_t u32xPos, uint32_t u32yPos, uint32_t uAction)
    780722{
    781     LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n",
    782                      u32xPos, u32yPos, uAction));
    783 
    784     int rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN);
     723    int rc;
    785724
    786725    uint32_t uActionNotify = DND_IGNORE_ACTION;
    787     if (RT_SUCCESS(rc))
    788         rc = RTCritSectEnter(&mCritSect);
    789     if (RT_SUCCESS(rc))
    790     {
    791         if (   (Dragging == mState)
    792             && startupInfo.pDropSource)
    793             uActionNotify = startupInfo.pDropSource->GetCurrentAction();
    794 
    795         RTCritSectLeave(&mCritSect);
    796     }
     726    if (mMode == HG)
     727    {
     728        LogFlowThisFunc(("u32xPos=%RU32, u32yPos=%RU32, uAction=0x%x\n",
     729                         u32xPos, u32yPos, uAction));
     730
     731        rc = mouseMove(u32xPos, u32yPos, MOUSEEVENTF_LEFTDOWN);
     732
     733        if (RT_SUCCESS(rc))
     734            rc = RTCritSectEnter(&mCritSect);
     735        if (RT_SUCCESS(rc))
     736        {
     737            if (   (Dragging == mState)
     738                && startupInfo.pDropSource)
     739                uActionNotify = startupInfo.pDropSource->GetCurrentAction();
     740
     741            RTCritSectLeave(&mCritSect);
     742        }
     743    }
     744    else /* Just acknowledge the operation with an ignore action. */
     745        rc = VINF_SUCCESS;
    797746
    798747    if (RT_SUCCESS(rc))
     
    809758int VBoxDnDWnd::OnHgLeave(void)
    810759{
     760    if (mMode == GH) /* Wrong mode? Bail out. */
     761        return VERR_WRONG_ORDER;
     762
    811763    LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState));
    812764    LogRel(("DnD: Drag'n drop operation aborted\n"));
     
    826778int VBoxDnDWnd::OnHgDrop(void)
    827779{
     780    if (mMode == GH)
     781        return VERR_WRONG_ORDER;
     782
    828783    LogFlowThisFunc(("mMode=%ld, mState=%RU32\n", mMode, mState));
    829784
     
    917872                     mMode, mState, uScreenID));
    918873
     874    if (mMode == Unknown)
     875        setMode(GH);
     876
     877    if (mMode != GH)
     878        return VERR_WRONG_ORDER;
     879
    919880    if (mState == Uninitialized)
    920         reset();
     881    {
     882        /* Nothing to do here yet. */
     883        mState = Initialized;
     884    }
    921885
    922886    int rc;
     
    954918
    955919    if (   RT_SUCCESS(rc)
    956         && (mState == Dragging))
     920        && mState == Dragging)
    957921    {
    958922        /** @todo Put this block into a function! */
     
    987951        {
    988952            uDefAction = DND_COPY_ACTION;
     953            /** @todo Support more than one action at a time. */
    989954            uAllActions = uDefAction;
    990955
     
    993958            rc = VbglR3DnDGHAcknowledgePending(mClientID,
    994959                                               uDefAction, uAllActions, strFormats.c_str());
     960            if (RT_FAILURE(rc))
     961            {
     962                char szMsg[256]; /* Sizes according to MSDN. */
     963                char szTitle[64];
     964
     965                /** @todo Add some translation macros here. */
     966                RTStrPrintf(szTitle, sizeof(szTitle), "VirtualBox Guest Additions Drag'n Drop");
     967                RTStrPrintf(szMsg, sizeof(szMsg), "Drag'n drop to the host either is not supported or disabled. "
     968                                                  "Pleas enable Guest to Host or Bidirectional drag'n drop mode "
     969                                                  "or re-install the VirtualBox Guest Additions.");
     970                switch (rc)
     971                {
     972                    case VERR_ACCESS_DENIED:
     973                        rc = hlpShowBalloonTip(ghInstance, ghwndToolWindow, ID_TRAYICON,
     974                                               szMsg, szTitle,
     975                                               15 * 1000 /* Time to display in msec */, NIIF_INFO);
     976                        AssertRC(rc);
     977                        break;
     978
     979                    default:
     980                        break;
     981                }
     982            }
    995983        }
    996984        else
     
    1010998    LogFlowThisFunc(("mMode=%ld, mState=%ld, pDropTarget=0x%p, pszFormat=%s, uDefAction=0x%x\n",
    1011999                     mMode, mState, pDropTarget, pszFormat, uDefAction));
    1012 
    10131000    int rc;
    1014     if (mState == Dragging)
    1015     {
    1016         AssertPtr(pDropTarget);
    1017         rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
     1001    if (mMode == GH)
     1002    {
     1003        if (mState == Dragging)
     1004        {
     1005            AssertPtr(pDropTarget);
     1006            rc = pDropTarget->WaitForDrop(30 * 1000 /* Timeout in ms */);
     1007
     1008            reset();
     1009        }
     1010        else if (mState == Dropped)
     1011        {
     1012            rc = VINF_SUCCESS;
     1013        }
     1014        else
     1015            rc = VERR_WRONG_ORDER;
     1016
    10181017        if (RT_SUCCESS(rc))
    10191018        {
     
    10271026            LogFlowFunc(("Sent pvData=0x%p, cbData=%RU32, rc=%Rrc\n",
    10281027                         pvData, cbData, rc));
    1029         }
    1030 
    1031         reset();
     1028
     1029
     1030        }
    10321031    }
    10331032    else
    10341033        rc = VERR_WRONG_ORDER;
    10351034
    1036     LogFlowFuncLeaveRC(rc);
    1037     return rc;
    1038 }
    1039 
    1040 int VBoxDnDWnd::OnGhSendDir(const char *pszFormats, uint32_t cbFormats,
    1041                             uint32_t uDefAction)
    1042 {
    1043     int rc = 0;
    1044     LogFlowFuncLeaveRC(rc);
    1045     return rc;
    1046 }
    1047 
    1048 int VBoxDnDWnd::OnGhSendFile(const char *pszFormats, uint32_t cbFormats,
    1049                              uint32_t uDefAction)
    1050 {
    1051     int rc = 0;
    10521035    LogFlowFuncLeaveRC(rc);
    10531036    return rc;
     
    12131196void VBoxDnDWnd::reset(void)
    12141197{
    1215     LogFlowThisFunc(("Old mState=%ld\n", mState));
     1198    LogFlowThisFunc(("Resetting, old mMode=%ld, mState=%ld\n",
     1199                     mMode, mState));
    12161200
    12171201    lstAllowedFormats.clear();
     
    12191203    uAllActions = DND_IGNORE_ACTION;
    12201204
    1221     mMode = Unknown;
     1205    int rc2 = setMode(Unknown);
     1206    AssertRC(rc2);
     1207
     1208    hide();
     1209}
     1210
     1211int VBoxDnDWnd::setMode(Mode enmMode)
     1212{
     1213    LogFlowThisFunc(("Old mode=%ld, new mode=%ld\n",
     1214                     mMode, enmMode));
     1215
     1216    mMode = enmMode;
    12221217    mState = Initialized;
     1218
     1219    return VINF_SUCCESS;
    12231220}
    12241221
     
    14251422            if (RT_FAILURE(rc2))
    14261423                LogFlowFunc(("Cancelling failed with rc=%Rrc\n", rc2));
     1424            break;
    14271425        }
    14281426        else
     
    14331431             * don't support the stuff we do on the guest side, so make sure we
    14341432             * don't process invalid messages forever. */
    1435             if (rc == VERR_INVALID_PARAMETER)
    1436                 cMsgSkippedInvalid++;
    1437             if (cMsgSkippedInvalid > 3)
     1433            if (cMsgSkippedInvalid++ > 3)
    14381434            {
    1439                 LogFlowFunc(("Too many invalid/skipped messages from host, exiting ...\n"));
     1435                LogRel(("DnD: Too many invalid/skipped messages from host, exiting ...\n"));
    14401436                break;
    14411437            }
     1438
     1439            int rc2 = VbglR3DnDGHSendError(uClientID, rc);
     1440            AssertRC(rc2);
    14421441        }
    14431442
     
    14451444            break;
    14461445
     1446        if (RT_FAILURE(rc)) /* Don't hog the CPU on errors. */
     1447            RTThreadSleep(1000 /* ms */);
     1448
    14471449    } while (true);
    14481450
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnD.h

    r50508 r50561  
    340340    int OnGhIsDnDPending(uint32_t uScreenID);
    341341    int OnGhDropped(const char *pszFormat, uint32_t cbFormats, uint32_t uDefAction);
    342     int OnGhSendDir(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
    343     int OnGhSendFile(const char *pszFormats, uint32_t cbFormats, uint32_t uDefAction);
    344342#endif
    345343
     
    353351
    354352    int makeFullscreen(void);
    355     void reset(void);
    356353    int mouseMove(int x, int y, DWORD dwMouseInputFlags);
    357354    int mouseRelease(void);
     355    void reset(void);
     356    int setMode(Mode enmMode);
    358357
    359358public: /** @todo Make protected! */
     
    396395    /** The current state. */
    397396    State                      mState;
     397    bool                       mInFlight;
    398398    RTCString                  mFormatRequested;
    399399    RTCList<RTCString>         mLstFormats;
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxDnDDropTarget.cpp

    r50508 r50561  
    120120    else
    121121    {
    122         LogFlowFunc(("CF_HDROP not supported, hr=%Rhrc\n", hr));
     122        LogFlowFunc(("CF_HDROP not wanted, hr=%Rhrc\n", hr));
    123123
    124124        /* So we couldn't retrieve the data in CF_HDROP format; try with
    125          * CF_TEXT format now. Rest stays the same. */
    126         fmtEtc.cfFormat = CF_TEXT;
     125         * CF_UNICODETEXT + CF_TEXT formats now. Rest stays the same. */
     126        fmtEtc.cfFormat = CF_UNICODETEXT;
    127127        hr = pDataObject->QueryGetData(&fmtEtc);
    128         if (hr != S_OK)
     128        if (hr == S_OK)
    129129        {
    130             LogFlowFunc(("CF_TEXT not supported, hr=%Rhrc\n", hr));
    131             fmtEtc.cfFormat = 0; /* Mark it to not supported. */
     130            mFormats = "text/plain;charset=utf-8";
    132131        }
    133132        else
    134133        {
    135             mFormats = "text/plain;charset=utf-8";
     134            LogFlowFunc(("CF_UNICODETEXT not wanted, hr=%Rhrc\n", hr));
     135
     136            fmtEtc.cfFormat = CF_TEXT;
     137            hr = pDataObject->QueryGetData(&fmtEtc);
     138            if (hr == S_OK)
     139            {
     140                mFormats = "text/plain;charset=utf-8";
     141            }
     142            else
     143            {
     144                LogFlowFunc(("CF_TEXT not wanted, hr=%Rhrc\n", hr));
     145                fmtEtc.cfFormat = 0; /* Mark it to not supported. */
     146            }
    136147        }
    137148    }
     
    306317                switch (mFormatEtc.cfFormat)
    307318                {
    308                     /* Handling CF_TEXT means that the system already did some marshalling
    309                      * to convert RTF or unicode text to plain ANSI text. */
     319                    case CF_UNICODETEXT:
     320                    {
     321                        AssertPtr(pvData);
     322                        size_t cbSize = GlobalSize(pvData);
     323                        LogFlowFunc(("CF_UNICODETEXT 0x%p got %zu bytes\n", pvData, cbSize));
     324                        if (cbSize)
     325                        {
     326                            char *pszText = NULL;
     327                            rc = RTUtf16ToUtf8((PCRTUTF16)pvData, &pszText);
     328                            if (RT_SUCCESS(rc))
     329                            {
     330                                mpvData = (void *)pszText;
     331                                mcbData = strlen(pszText) + 1; /* Include termination. */
     332
     333                                /* Note: Don't free data of pszText, mpvData now owns it. */
     334                            }
     335                        }
     336
     337                        break;
     338                    }
     339
    310340                    case CF_TEXT:
    311341                    {
     
    320350                            {
    321351                                mpvData = (void *)pszText;
    322                                 mcbData = strlen(pszText) + 1;
     352                                mcbData = strlen(pszText) + 1; /* Include termination. */
     353
     354                                /* Note: Don't free data of pszText, mpvData now owns it. */
    323355                            }
    324356                        }
     
    412444                            /* Add separation between filenames.
    413445                             * Note: Also do this for the last element of the list. */
    414                             if (i > 0)
    415                             {
    416                                 rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
    417                                                      "\r\n", 2 /* Bytes */);
    418                                 if (RT_SUCCESS(rc))
    419                                     cchFiles += 2; /* Include \r\n */
    420                             }
     446                            rc = RTStrAAppendExN(&pszFiles, 1 /* cPairs */,
     447                                                 "\r\n", 2 /* Bytes */);
     448                            if (RT_SUCCESS(rc))
     449                                cchFiles += 2; /* Include \r\n */
    421450                        }
    422451
  • trunk/src/VBox/Additions/common/VBoxGuestLib/VBoxGuestR3LibDragAndDrop.cpp

    r50508 r50561  
    278278
    279279    /* Allocate temp buffer. */
    280     uint32_t cbTmpData = _1M * 10; /** @todo r=andy 10MB, uh, really?? */
     280    uint32_t cbTmpData = _64K; /** @todo Make this configurable? */
    281281    void *pvTmpData = RTMemAlloc(cbTmpData);
    282282    if (!pvTmpData)
     
    311311    RTCList<RTCString> guestDirList;
    312312    RTCList<RTCString> guestFileList;
    313     char pszPathName[RTPATH_MAX];
    314     uint32_t cbPathname = 0;
     313
     314    char szPathName[RTPATH_MAX];
     315    uint32_t cbPathName = 0;
     316
    315317    bool fLoop = RT_SUCCESS(rc); /* No error occurred yet? */
    316318    while (fLoop)
     
    327329                    uint32_t fMode = 0;
    328330                    rc = vbglR3DnDHGProcessSendDirMessage(uClientId,
    329                                                           pszPathName,
    330                                                           sizeof(pszPathName),
    331                                                           &cbPathname,
     331                                                          szPathName,
     332                                                          sizeof(szPathName),
     333                                                          &cbPathName,
    332334                                                          &fMode);
     335#ifdef DEBUG_andy
     336                    LogFlowFunc(("HOST_DND_HG_SND_DIR pszPathName=%s, cbPathName=%RU32, fMode=0x%x, rc=%Rrc\n",
     337                                 szPathName, cbPathName, fMode, rc));
     338#endif
    333339                    if (RT_SUCCESS(rc))
    334                         rc = DnDPathSanitize(pszPathName, sizeof(pszPathName));
     340                        rc = DnDPathSanitize(szPathName, sizeof(szPathName));
    335341                    if (RT_SUCCESS(rc))
    336342                    {
    337                         char *pszNewDir = RTPathJoinA(pszDropDir, pszPathName);
     343                        char *pszNewDir = RTPathJoinA(pszDropDir, szPathName);
    338344                        if (pszNewDir)
    339345                        {
     
    354360                    uint32_t fMode = 0;
    355361                    rc = vbglR3DnDHGProcessSendFileMessage(uClientId,
    356                                                            pszPathName,
    357                                                            sizeof(pszPathName),
    358                                                            &cbPathname,
     362                                                           szPathName,
     363                                                           sizeof(szPathName),
     364                                                           &cbPathName,
    359365                                                           pvTmpData,
    360366                                                           cbTmpData,
    361367                                                           &cbDataRecv,
    362368                                                           &fMode);
     369#ifdef DEBUG_andy
     370                    LogFlowFunc(("HOST_DND_HG_SND_FILE pszPathName=%s, cbPathName=%RU32, pvData=0x%p, cbDataRecv=%RU32, fMode=0x%x, rc=%Rrc\n",
     371                                 szPathName, cbPathName, pvTmpData, cbDataRecv, fMode, rc));
     372#endif
    363373                    if (RT_SUCCESS(rc))
    364                         rc = DnDPathSanitize(pszPathName, sizeof(pszPathName));
     374                        rc = DnDPathSanitize(szPathName, sizeof(szPathName));
    365375                    if (RT_SUCCESS(rc))
    366376                    {
    367                         char *pszNewFile = RTPathJoinA(pszDropDir, pszPathName);
    368                         if (pszNewFile)
     377                        char *pszPathAbs = RTPathJoinA(pszDropDir, szPathName);
     378                        if (pszPathAbs)
    369379                        {
    370380                            RTFILE hFile;
     
    372382                             *               create all sorts of funny races because we don't know if the guest has
    373383                             *               modified the file in between the file data send calls. */
    374                             rc = RTFileOpen(&hFile, pszNewFile,
     384                            rc = RTFileOpen(&hFile, pszPathAbs,
    375385                                            RTFILE_O_WRITE | RTFILE_O_APPEND | RTFILE_O_DENY_ALL | RTFILE_O_OPEN_CREATE);
    376386                            if (RT_SUCCESS(rc))
     
    386396                                        rc = RTFileSetMode(hFile, (fMode & RTFS_UNIX_MASK) | RTFS_UNIX_IRUSR | RTFS_UNIX_IWUSR);
    387397                                }
     398
    388399                                RTFileClose(hFile);
    389                                 if (!guestFileList.contains(pszNewFile))
    390                                     guestFileList.append(pszNewFile);
     400
     401                                if (!guestFileList.contains(pszPathAbs))
     402                                    guestFileList.append(pszPathAbs);
    391403                            }
    392 
    393                             RTStrFree(pszNewFile);
     404#ifdef DEBUG
     405                            else
     406                                LogFlowFunc(("Opening file failed with rc=%Rrc\n", rc));
     407#endif
     408                            RTStrFree(pszPathAbs);
    394409                        }
    395410                        else
     
    416431            break;
    417432        }
     433
     434        if (RT_FAILURE(rc))
     435            break;
     436
    418437    } /* while */
    419438
     
    430449            RTDirRemove(guestDirList.at(i).c_str());
    431450        RTDirRemove(pszDropDir);
     451
     452        LogFlowFunc(("Failed with rc=%Rrc\n", rc));
    432453    }
    433454
     
    473494            rc = Msg.uScreenId.GetUInt32(puScreenId);  AssertRC(rc);
    474495            rc = Msg.cFormat.GetUInt32(pcbFormatRecv); AssertRC(rc);
    475             rc = Msg.cbData.GetUInt32(pcbDataTotal);     AssertRC(rc);
     496            rc = Msg.cbData.GetUInt32(pcbDataTotal);   AssertRC(rc);
    476497
    477498            AssertReturn(cbFormat >= *pcbFormatRecv, VERR_TOO_MUCH_DATA);
     
    789810                break;
    790811            }
     812            case DragAndDropSvc::HOST_DND_HG_SND_MORE_DATA:
     813            case DragAndDropSvc::HOST_DND_HG_SND_DIR:
     814            case DragAndDropSvc::HOST_DND_HG_SND_FILE:
     815            {
     816                pEvent->uType = uMsg;
     817
     818                /* All messages in this case are handled internally
     819                 * by vbglR3DnDHGProcessSendDataMessage() and must
     820                 * be specified by a preceding HOST_DND_HG_SND_DATA call. */
     821                rc = VERR_WRONG_ORDER;
     822                break;
     823            }
    791824            case DragAndDropSvc::HOST_DND_HG_EVT_CANCEL:
    792825            {
     
    11071140        rc = vbglR3DnDGHSendDataInternal(u32ClientId, pvData, cbData,
    11081141                                         0 /* cbAdditionalData */);
    1109 
    1110     return rc;
    1111 }
    1112 
    1113 VBGLR3DECL(int) VbglR3DnDGHErrorEvent(uint32_t u32ClientId, int rcOp)
     1142    if (RT_FAILURE(rc))
     1143    {
     1144        int rc2 = VbglR3DnDGHSendError(u32ClientId, rc);
     1145        if (RT_SUCCESS(rc2))
     1146            rc2 = rc;
     1147    }
     1148
     1149    return rc;
     1150}
     1151
     1152VBGLR3DECL(int) VbglR3DnDGHSendError(uint32_t u32ClientId, int rcErr)
    11141153{
    11151154    DragAndDropSvc::VBOXDNDGHEVTERRORMSG Msg;
     
    11201159    Msg.hdr.cParms      = 1;
    11211160
    1122     Msg.uRC.SetUInt32(rcOp);
    1123 
    1124     int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
    1125     if (RT_SUCCESS(rc))
    1126         rc = Msg.hdr.result;
    1127 
    1128     return rc;
    1129 }
    1130 
     1161    Msg.uRC.SetUInt32((uint32_t)rcErr); /* uint32_t vs. int. */
     1162
     1163    int rc = vbglR3DoIOCtl(VBOXGUEST_IOCTL_HGCM_CALL(sizeof(Msg)), &Msg, sizeof(Msg));
     1164    if (RT_SUCCESS(rc))
     1165        rc = Msg.hdr.result;
     1166
     1167    LogFlowFunc(("Sending error %Rrc returned with rc=%Rrc\n", rcErr, rc));
     1168    return rc;
     1169}
     1170
  • trunk/src/VBox/Additions/x11/VBoxClient/draganddrop.cpp

    r50478 r50561  
    13171317    /* Inform the host on error */
    13181318    if (RT_FAILURE(rc))
    1319         VbglR3DnDGHErrorEvent(rc);
     1319        VbglR3DnDGHSendError(rc);
    13201320
    13211321    /* At this point, we have either successfully transfered any data or not.
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.cpp

    r50508 r50561  
    231231    if (mStatus == Dropped)
    232232    {
    233 #ifdef VBOX_DND_DEBUG_FORMATS
    234233        LogFlowFunc(("cfFormat=%RI16, sFormat=%s, tyMed=%RU32, dwAspect=%RU32\n",
    235234                     pThisFormat->cfFormat, UIDnDDataObject::ClipboardFormatToString(pFormatEtc->cfFormat),
     
    237236        LogFlowFunc(("Got strFormat=%s, pvData=%p, cbData=%RU32\n",
    238237                     mstrFormat.toAscii().constData(), mpvData, mcbData));
    239 #endif
     238
    240239        QVariant::Type vaType;
    241240        QString strMIMEType;
     
    256255            vaType = QVariant::StringList;
    257256        }
    258 #if 0
     257#if 0 /* More formats; not needed right now. */
    259258        else if (   (pFormatEtc->tymed & TYMED_ISTREAM)
    260259                && (pFormatEtc->dwAspect == DVASPECT_CONTENT)
     
    285284                     strMIMEType.toAscii().constData(), vaType));
    286285
    287         QVariant va;
    288         int rc = mpParent->RetrieveData(strMIMEType, vaType, va);
     286        int rc;
     287        if (!mVaData.isValid())
     288            rc = mpParent->RetrieveData(strMIMEType, vaType, mVaData);
     289        else
     290            rc = VINF_SUCCESS; /* Data already retrieved. */
     291
    289292        if (RT_SUCCESS(rc))
    290293        {
    291294            if (   strMIMEType.startsWith("text/uri-list")
    292295                       /* One item. */
    293                 && (   va.canConvert(QVariant::String)
     296                && (   mVaData.canConvert(QVariant::String)
    294297                       /* Multiple items. */
    295                     || va.canConvert(QVariant::StringList))
     298                    || mVaData.canConvert(QVariant::StringList))
    296299               )
    297300            {
    298                 QStringList lstFilesURI = va.toStringList();
     301                QStringList lstFilesURI = mVaData.toStringList();
    299302                QStringList lstFiles;
    300303                for (size_t i = 0; i < lstFilesURI.size(); i++)
     
    326329
    327330                size_t cbBuf = sizeof(DROPFILES) + ((cchFiles + 1) * sizeof(RTUTF16));
    328                 DROPFILES *pBuf = (DROPFILES *)RTMemAllocZ(cbBuf);
    329                 if (pBuf)
     331                DROPFILES *pDropFiles = (DROPFILES *)RTMemAllocZ(cbBuf);
     332                if (pDropFiles)
    330333                {
    331                     pBuf->pFiles = sizeof(DROPFILES);
    332                     pBuf->fWide = 1; /* We use unicode. Always. */
    333 
    334                     uint8_t *pCurFile = (uint8_t *)pBuf + pBuf->pFiles;
     334                    pDropFiles->pFiles = sizeof(DROPFILES);
     335                    pDropFiles->fWide = 1; /* We use unicode. Always. */
     336
     337                    uint8_t *pCurFile = (uint8_t *)pDropFiles + pDropFiles->pFiles;
    335338                    AssertPtr(pCurFile);
    336339
     
    368371                        if (pMedium->hGlobal)
    369372                        {
    370                             LPVOID pMem = GlobalLock(pMedium->hGlobal);
    371                             if (pMem)
     373                            LPVOID pvMem = GlobalLock(pMedium->hGlobal);
     374                            if (pvMem)
    372375                            {
    373                                 memcpy(pMem, pBuf, cbBuf);
     376                                memcpy(pvMem, pDropFiles, cbBuf);
    374377                                GlobalUnlock(pMedium->hGlobal);
    375378
     
    383386                    }
    384387
    385                     RTMemFree(pBuf);
     388                    RTMemFree(pDropFiles);
    386389                }
    387390            }
    388391            else if (   strMIMEType.startsWith("text/plain")
    389                      && va.canConvert(QVariant::String))
     392                     && mVaData.canConvert(QVariant::String))
    390393            {
    391394                bool fUnicode = pFormatEtc->cfFormat == CF_UNICODETEXT;
    392                 int cbch = fUnicode
     395                int cbCh = fUnicode
    393396                         ? sizeof(WCHAR) : sizeof(char);
    394397
    395                 QString strText = va.toString();
    396                 size_t cbSrc = (strText.length() + 1) * cbch;
     398                QString strText = mVaData.toString();
     399                size_t cbSrc = strText.length() * cbCh;
    397400                Assert(cbSrc);
    398401                LPCVOID pvSrc = fUnicode
     
    400403                              : (void *)strText.toAscii().constData();
    401404                AssertPtr(pvSrc);
    402 #ifdef DEBUG_andy
     405
    403406                LogFlowFunc(("pvSrc=0x%p, cbSrc=%zu, cbch=%d, fUnicode=%RTbool\n",
    404                              pvSrc, cbSrc, cbch, fUnicode));
    405 #endif
     407                             pvSrc, cbSrc, cbCh, fUnicode));
     408
    406409                pMedium->tymed = TYMED_HGLOBAL;
    407410                pMedium->pUnkForRelease = NULL;
    408411                pMedium->hGlobal = GlobalAlloc(  GMEM_ZEROINIT
    409412                                               | GMEM_MOVEABLE
    410                                                | GMEM_DDESHARE, cbSrc);
     413                                               | GMEM_DDESHARE,
     414                                               cbSrc);
    411415                if (pMedium->hGlobal)
    412416                {
     
    423427                }
    424428                else
    425                     hr  = E_OUTOFMEMORY;
     429                    hr  = VERR_NO_MEMORY;
    426430            }
    427431            else
     
    445449        case TYMED_HGLOBAL:
    446450            pMedium->hGlobal = (HGLOBAL)OleDuplicateData(pThisMedium->hGlobal,
    447                                                          pThisFormat->cfFormat, NULL);
     451                                                         pThisFormat->cfFormat,
     452                                                         0 /* Flags */);
    448453            break;
    449454
     
    452457        }
    453458
    454         pMedium->tymed          = pThisFormat->tymed;
     459        pMedium->tymed          = pFormatEtc->tymed;
    455460        pMedium->pUnkForRelease = NULL;
    456461    }
    457462
    458     LogFlowFunc(("hr=%Rhrc\n", hr));
     463    LogFlowFunc(("Returning hr=%Rhrc\n", hr));
    459464    return hr;
    460465}
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDataObject_win.h

    r50460 r50561  
    2525#include <QString>
    2626#include <QStringList>
     27#include <QVariant>
    2728
    2829/* Forward declarations: */
     
    9293    QStringList mlstFormats;
    9394    QString     mstrFormat;
     95    /** The retrieved data as a QVariant. Needed
     96     *  for buffering in case a second format needs
     97     *  the same data, e.g. CF_TEXT and CF_UNICODETEXT. */
     98    QVariant    mVaData;
     99    /** The retrieved data as a raw buffer. */
    94100    void       *mpvData;
     101    /** Raw buffer size (in bytes). */
    95102    uint32_t    mcbData;
    96103};
  • trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIDnDDrag.cpp

    r50460 r50561  
    8989        HRESULT hr = ::DoDragDrop(pDataObject, pDropSource,
    9090                                  dwOKEffects, &dwEffect);
    91         LogFlowThisFunc(("hr=%Rhrc, dwEffect=%RI32\n", hr, dwEffect));
     91        LogFlowThisFunc(("DoDragDrop ended with hr=%Rhrc, dwEffect=%RI32\n",
     92                         hr, dwEffect));
    9293
    9394        if (pDropSource)
     
    150151    {
    151152        msgCenter().showModalProgressDialog(progress,
    152                                             tr("Retrieving metadata ..."), ":/progress_dnd_gh_90px.png",
     153                                            tr("Retrieving data ..."), ":/progress_dnd_gh_90px.png",
    153154                                            m_pParent);
    154155        if (!progress.GetCanceled())
     
    161162            {
    162163                /* After the data successfully arrived from the guest, we query it from Main. */
    163                 QVector<uint8_t> data = guest.DragGHGetData();
    164                 if (!data.isEmpty())
     164                QVector<uint8_t> vecData = guest.DragGHGetData();
     165                if (!vecData.isEmpty())
    165166                {
    166167                    switch (vaType)
     
    168169                        case QVariant::String:
    169170                        {
    170                             vaData = QVariant(QString(reinterpret_cast<const char*>(data.data())));
     171                            vaData = QVariant(QString(reinterpret_cast<const char*>(vecData.constData())));
    171172                            break;
    172173                        }
     
    174175                        case QVariant::ByteArray:
    175176                        {
    176                             QByteArray ba(reinterpret_cast<const char*>(data.constData()), data.size());
     177                            QByteArray ba(reinterpret_cast<const char*>(vecData.constData()), vecData.size());
    177178                            vaData = QVariant(ba);
    178179                            break;
     
    181182                        case QVariant::StringList:
    182183                        {
    183                             QString strData = QString(reinterpret_cast<const char*>(data.data()));
     184                            QString strData = QString(reinterpret_cast<const char*>(vecData.constData()));
    184185                            QStringList lstString = strData.split("\r\n", QString::SkipEmptyParts);
    185186
  • trunk/src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp

    r50508 r50561  
    183183
    184184                    /* End of file reached or error occurred? */
    185                     if (   cbRead < cbToRead
     185                    if (   m_cbProcessed == m_cbSize
    186186                        || RT_FAILURE(rc))
     187                    {
    187188                        closeInternal();
     189                    }
    188190                }
    189191            }
     
    572574}
    573575
    574 RTCString DnDURIList::RootToString(const RTCString &strBasePath /* = "" */)
     576RTCString DnDURIList::RootToString(const RTCString &strBasePath /* = "" */,
     577                                   const RTCString &strSeparator /* = "\r\n" */)
    575578{
    576579    RTCString strRet;
     
    586589                if (pszPathURI)
    587590                {
    588                     strRet += RTCString(pszPathURI) + "\r\n";
     591                    strRet += RTCString(pszPathURI) + strSeparator;
    589592                    RTStrFree(pszPathURI);
    590593                }
     594                else
     595                    break;
    591596                RTStrFree(pszPath);
    592597            }
     
    599604            if (pszPathURI)
    600605            {
    601                 strRet += RTCString(pszPathURI) + "\r\n";
     606                strRet += RTCString(pszPathURI) + strSeparator;
    602607                RTStrFree(pszPathURI);
    603608            }
  • 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
  • trunk/src/VBox/Main/src-client/GuestDnDImpl.cpp

    r50508 r50561  
    239239    DnDGuestResponse *response(void) const { return m_pDnDResponse; }
    240240
    241     void adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const;
    242     void hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;
     241    HRESULT adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const;
     242    int hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const;
    243243
    244244    /* Static helpers. */
     
    310310int DnDGuestResponse::waitForGuestResponse(RTMSINTERVAL msTimeout /*= 500 */)
    311311{
    312     int vrc = RTSemEventWait(m_EventSem, msTimeout);
     312    int rc = RTSemEventWait(m_EventSem, msTimeout);
    313313#ifdef DEBUG_andy
    314     LogFlowFunc(("msTimeout=%RU32, rc=%Rrc\n", msTimeout, vrc));
     314    LogFlowFunc(("msTimeout=%RU32, rc=%Rrc\n", msTimeout, rc));
    315315#endif
    316     return vrc;
     316    return rc;
    317317}
    318318
     
    350350        m_pvData = NULL;
    351351    }
    352 
    353352    m_cbData = 0;
     353
     354    m_cbDataCurrent = 0;
     355    m_cbDataTotal = 0;
    354356}
    355357
     
    377379    {
    378380        BOOL fCompleted;
    379         HRESULT rc = m_progress->COMGETTER(Completed)(&fCompleted);
     381        HRESULT hr = m_progress->COMGETTER(Completed)(&fCompleted);
    380382        if (!fCompleted)
    381383        {
    382384            if (uState == DragAndDropSvc::DND_PROGRESS_ERROR)
    383385            {
    384                 rc = m_progress->notifyComplete(E_FAIL,
     386                hr = m_progress->notifyComplete(E_FAIL,
    385387                                                COM_IIDOF(IGuest),
    386388                                                m_parent->getComponentName(),
    387389                                                m_parent->tr("Drag'n drop guest error (%Rrc)"), rcOp);
     390                reset();
    388391            }
    389392            else if (uState == DragAndDropSvc::DND_PROGRESS_CANCELLED)
    390393            {
    391                 rc = m_progress->Cancel();
    392                 vrc = VERR_CANCELLED;
     394                hr = m_progress->Cancel();
     395                if (SUCCEEDED(hr))
     396                    vrc = VERR_CANCELLED;
     397
     398                reset();
    393399            }
    394400            else /* uState == DragAndDropSvc::DND_PROGRESS_RUNNING */
    395401            {
    396                 rc = m_progress->SetCurrentOperationProgress(uPercentage);
    397 #ifndef DEBUG_andy
    398                 Assert(SUCCEEDED(rc));
    399 #endif
     402                hr = m_progress->SetCurrentOperationProgress(uPercentage);
     403                AssertComRC(hr);
    400404                if (   uState      == DragAndDropSvc::DND_PROGRESS_COMPLETE
    401405                    || uPercentage >= 100)
    402                     rc = m_progress->notifyComplete(S_OK);
     406                    hr = m_progress->notifyComplete(S_OK);
    403407            }
     408        }
     409    }
     410
     411    return vrc;
     412}
     413
     414int DnDGuestResponse::dataSetStatus(size_t cbDataAdd, size_t cbDataTotal /* = 0 */)
     415{
     416    if (cbDataTotal)
     417    {
    404418#ifndef DEBUG_andy
    405             Assert(SUCCEEDED(rc));
     419        AssertMsg(m_cbDataTotal <= cbDataTotal, ("New data size must not be smaller (%zu) than old value (%zu)\n",
     420                                                 cbDataTotal, m_cbDataTotal));
    406421#endif
    407         }
    408     }
    409 
    410     return vrc;
    411 }
    412 
    413 int DnDGuestResponse::dataSetStatus(size_t cbDataAdd, size_t cbDataTotal /* = 0 */)
    414 {
    415     if (cbDataTotal)
    416     {
    417         AssertMsg(m_cbDataTotal <= cbDataTotal, ("New data size size must not be smaller (%zu) than old value (%zu)\n",
    418                                                  cbDataTotal, m_cbDataTotal));
     422        LogFlowFunc(("Updating total data size from %zu to %zu\n", m_cbDataTotal, cbDataTotal));
    419423        m_cbDataTotal = cbDataTotal;
    420         LogFlowFunc(("Updating total data size to: %zu\n", m_cbDataTotal));
    421424    }
    422425    AssertMsg(m_cbDataTotal, ("m_cbDataTotal must not be <= 0\n"));
     
    433436    LogFlowFunc(("Updating transfer status (%zu/%zu), status=%ld\n",
    434437                 m_cbDataCurrent, m_cbDataTotal, uStatus));
    435 #endif
    436 
     438#else
    437439    AssertMsg(m_cbDataCurrent <= m_cbDataTotal,
    438440              ("More data transferred (%RU32) than initially announced (%RU32)\n",
    439441              m_cbDataCurrent, m_cbDataTotal));
    440 
     442#endif
    441443    int rc = setProgress(cPercentage, uStatus);
    442444
     
    455457}
    456458
    457 void GuestDnDPrivate::adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const
     459HRESULT GuestDnDPrivate::adjustCoords(ULONG uScreenId, ULONG *puX, ULONG *puY) const
    458460{
    459461    /* For multi-monitor support we need to add shift values to the coordinates
    460462     * (depending on the screen number). */
    461463    ComPtr<IDisplay> pDisplay;
    462     HRESULT rc = p->mParent->COMGETTER(Display)(pDisplay.asOutParam());
    463     if (FAILED(rc))
    464         throw rc;
     464    HRESULT hr = p->mParent->COMGETTER(Display)(pDisplay.asOutParam());
     465    if (FAILED(hr))
     466        return hr;
    465467
    466468    ComPtr<IFramebuffer> pFramebuffer;
    467469    LONG xShift, yShift;
    468     rc = pDisplay->GetFramebuffer(uScreenId, pFramebuffer.asOutParam(),
     470    hr = pDisplay->GetFramebuffer(uScreenId, pFramebuffer.asOutParam(),
    469471                                  &xShift, &yShift);
    470     if (FAILED(rc))
    471         throw rc;
     472    if (FAILED(hr))
     473        return hr;
    472474
    473475    *puX += xShift;
    474476    *puY += yShift;
    475 }
    476 
    477 void GuestDnDPrivate::hostCall(uint32_t u32Function, uint32_t cParms, PVBOXHGCMSVCPARM paParms) const
    478 {
    479     VMMDev *vmmDev = NULL;
     477
     478    return hr;
     479}
     480
     481int GuestDnDPrivate::hostCall(uint32_t u32Function, uint32_t cParms,
     482                              PVBOXHGCMSVCPARM paParms) const
     483{
     484    VMMDev *pVMMDev = NULL;
    480485    {
    481486        /* Make sure mParent is valid, so set the read lock while using.
     
    486491        /* Forward the information to the VMM device. */
    487492        AssertPtr(p->mParent);
    488         vmmDev = p->mParent->getVMMDev();
    489     }
    490 
    491     if (!vmmDev)
     493        pVMMDev = p->mParent->getVMMDev();
     494    }
     495
     496    if (!pVMMDev)
    492497        throw p->setError(VBOX_E_VM_ERROR,
    493498                          p->tr("VMM device is not available (is the VM running?)"));
    494499
    495500    LogFlowFunc(("hgcmHostCall msg=%RU32, numParms=%RU32\n", u32Function, cParms));
    496     int vrc = vmmDev->hgcmHostCall("VBoxDragAndDropSvc",
     501    int rc = pVMMDev->hgcmHostCall("VBoxDragAndDropSvc",
    497502                                   u32Function,
    498503                                   cParms, paParms);
    499     if (RT_FAILURE(vrc))
    500     {
    501         LogFlowFunc(("hgcmHostCall error: %Rrc\n", vrc));
     504    if (RT_FAILURE(rc))
     505    {
     506        LogFlowFunc(("hgcmHostCall error: %Rrc\n", rc));
    502507        throw p->setError(VBOX_E_VM_ERROR,
    503                           p->tr("hgcmHostCall failed (%Rrc)"), vrc);
    504     }
     508                          p->tr("hgcmHostCall failed (%Rrc)"), rc);
     509    }
     510
     511    return rc;
    505512}
    506513
     
    653660        return S_OK;
    654661
    655     HRESULT rc = S_OK;
     662    HRESULT hr = S_OK;
    656663
    657664    try
     
    674681                    paParms);
    675682
    676         DnDGuestResponse *pDnD = d->response();
     683        DnDGuestResponse *pResp = d->response();
    677684        /* This blocks until the request is answered (or timeout). */
    678         if (pDnD->waitForGuestResponse() == VERR_TIMEOUT)
     685        if (pResp->waitForGuestResponse() == VERR_TIMEOUT)
    679686            return S_OK;
    680687
    681688        /* Copy the response info */
    682         *pResultAction = d->toMainAction(pDnD->defAction());
     689        *pResultAction = d->toMainAction(pResp->defAction());
    683690        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    684691    }
    685     catch (HRESULT rc2)
    686     {
    687         rc = rc2;
    688     }
    689 
    690     return rc;
     692    catch (HRESULT hr2)
     693    {
     694        hr = hr2;
     695    }
     696
     697    return hr;
    691698}
    692699
     
    717724        return S_OK;
    718725
    719     HRESULT rc = S_OK;
     726    HRESULT hr = S_OK;
    720727
    721728    try
     
    738745                    paParms);
    739746
    740         DnDGuestResponse *pDnD = d->response();
     747        DnDGuestResponse *pResp = d->response();
    741748        /* This blocks until the request is answered (or timeout). */
    742         if (pDnD->waitForGuestResponse() == VERR_TIMEOUT)
     749        if (pResp->waitForGuestResponse() == VERR_TIMEOUT)
    743750            return S_OK;
    744751
    745752        /* Copy the response info */
    746         *pResultAction = d->toMainAction(pDnD->defAction());
     753        *pResultAction = d->toMainAction(pResp->defAction());
    747754        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    748755    }
    749     catch (HRESULT rc2)
    750     {
    751         rc = rc2;
    752     }
    753 
    754     return rc;
     756    catch (HRESULT hr2)
     757    {
     758        hr = hr2;
     759    }
     760
     761    return hr;
    755762}
    756763
     
    760767    const ComObjPtr<Guest> &p = d->p;
    761768
    762     HRESULT rc = S_OK;
     769    HRESULT hr = S_OK;
    763770
    764771    try
     
    768775                    NULL);
    769776
    770         DnDGuestResponse *pDnD = d->response();
     777        DnDGuestResponse *pResp = d->response();
    771778        /* This blocks until the request is answered (or timeout). */
    772         pDnD->waitForGuestResponse();
    773     }
    774     catch (HRESULT rc2)
    775     {
    776         rc = rc2;
    777     }
    778 
    779     return rc;
     779        pResp->waitForGuestResponse();
     780    }
     781    catch (HRESULT hr2)
     782    {
     783        hr = hr2;
     784    }
     785
     786    return hr;
    780787}
    781788
     
    807814        return S_OK;
    808815
    809     HRESULT rc = S_OK;
     816    HRESULT hr = S_OK;
    810817
    811818    try
     
    828835                    paParms);
    829836
    830         DnDGuestResponse *pDnD = d->response();
     837        DnDGuestResponse *pResp = d->response();
    831838        /* This blocks until the request is answered (or timeout). */
    832         if (pDnD->waitForGuestResponse() == VERR_TIMEOUT)
     839        if (pResp->waitForGuestResponse() == VERR_TIMEOUT)
    833840            return S_OK;
    834841
    835842        /* Copy the response info */
    836         *pResultAction = d->toMainAction(pDnD->defAction());
    837         Bstr(pDnD->format()).cloneTo(pstrFormat);
     843        *pResultAction = d->toMainAction(pResp->defAction());
     844        Bstr(pResp->format()).cloneTo(pstrFormat);
    838845
    839846        LogFlowFunc(("*pResultAction=%ld\n", *pResultAction));
    840847    }
    841     catch (HRESULT rc2)
    842     {
    843         rc = rc2;
    844     }
    845 
    846     return rc;
     848    catch (HRESULT hr2)
     849    {
     850        hr = hr2;
     851    }
     852
     853    return hr;
    847854}
    848855
     
    853860    const ComObjPtr<Guest> &p = d->p;
    854861
    855     HRESULT rc = S_OK;
     862    HRESULT hr = S_OK;
    856863
    857864    try
     
    868875        paParms[i++].setUInt32((uint32_t)sfaData.size());
    869876
    870         DnDGuestResponse *pDnD = d->response();
     877        DnDGuestResponse *pResp = d->response();
    871878        /* Reset any old progress status. */
    872         pDnD->resetProgress(p);
     879        pResp->resetProgress(p);
    873880
    874881        /* Note: The actual data transfer of files/directoies is performed by the
     
    879886
    880887        /* Query the progress object to the caller. */
    881         pDnD->queryProgressTo(ppProgress);
    882     }
    883     catch (HRESULT rc2)
    884     {
    885         rc = rc2;
    886     }
    887 
    888     return rc;
     888        pResp->queryProgressTo(ppProgress);
     889    }
     890    catch (HRESULT hr2)
     891    {
     892        hr = hr2;
     893    }
     894
     895    return hr;
    889896}
    890897
     
    901908    *pDefaultAction = DragAndDropAction_Ignore;
    902909
    903     HRESULT rc = S_OK;
     910    HRESULT hr = S_OK;
    904911
    905912    try
     
    913920                    paParms);
    914921
    915         DnDGuestResponse *pDnD = d->response();
    916         /* This blocks until the request is answered (or timeout). */
    917         if (pDnD->waitForGuestResponse() == VERR_TIMEOUT)
     922        /* This blocks until the request is answered (or timed out). */
     923        DnDGuestResponse *pResp = d->response();
     924        if (pResp->waitForGuestResponse() == VERR_TIMEOUT)
    918925            return S_OK;
    919926
    920         if (isDnDIgnoreAction(pDnD->defAction()))
     927        if (isDnDIgnoreAction(pResp->defAction()))
    921928            return S_OK;
    922929
    923930        /* Fetch the default action to use. */
    924         *pDefaultAction = d->toMainAction(pDnD->defAction());
    925         /* Convert the formats strings to a vector of strings. */
    926         d->toFormatSafeArray(pDnD->format(), ComSafeArrayOutArg(formats));
    927         /* Convert the action bit field to a vector of actions. */
    928         d->toMainActions(pDnD->allActions(), ComSafeArrayOutArg(allowedActions));
     931        *pDefaultAction = d->toMainAction(pResp->defAction());
     932        d->toFormatSafeArray(pResp->format(), ComSafeArrayOutArg(formats));
     933        d->toMainActions(pResp->allActions(), ComSafeArrayOutArg(allowedActions));
    929934
    930935        LogFlowFunc(("*pDefaultAction=0x%x\n", *pDefaultAction));
    931936    }
    932     catch (HRESULT rc2)
    933     {
    934         rc = rc2;
    935     }
    936 
    937     return rc;
     937    catch (HRESULT hr2)
     938    {
     939        hr = hr2;
     940    }
     941
     942    return hr;
    938943}
    939944
     
    957962                 pcszFormat, uAction, fNeedsDropDir));
    958963
    959     DnDGuestResponse *pDnD = d->response();
    960     AssertPtr(pDnD);
     964    DnDGuestResponse *pResp = d->response();
     965    AssertPtr(pResp);
     966
     967    pResp->reset();
    961968
    962969    if (fNeedsDropDir)
     
    970977        LogFlowFunc(("Dropped files directory on the host is: %s\n", szDropDir));
    971978
    972         pDnD->setDropDir(szDropDir);
     979        pResp->setDropDir(szDropDir);
    973980    }
    974981
     
    982989
    983990        /* Reset any old data and the progress status. */
    984         pDnD->reset();
    985         pDnD->resetProgress(p);
     991        pResp->reset();
     992        pResp->resetProgress(p);
    986993
    987994        d->hostCall(DragAndDropSvc::HOST_DND_GH_EVT_DROPPED,
     
    990997
    991998        /* Query the progress object to the caller. */
    992         pDnD->queryProgressTo(ppProgress);
    993     }
    994     catch (HRESULT rc2)
    995     {
    996         hr = rc2;
     999        pResp->queryProgressTo(ppProgress);
     1000    }
     1001    catch (HRESULT hr2)
     1002    {
     1003        hr = hr2;
    9971004    }
    9981005
     
    10191026
    10201027            Utf8Str strFormat = pResp->format();
    1021             LogFlowFunc(("strFormat=%s, strDropDir=%s\n",
    1022                          strFormat.c_str(), pResp->dropDir().c_str()));
     1028            LogFlowFunc(("strFormat=%s, cbData=%zu, pvData=0x%p\n",
     1029                         strFormat.c_str(), cbData, pvData));
    10231030
    10241031            if (DnDMIMEHasFileURLs(strFormat.c_str(), strFormat.length()))
    10251032            {
     1033                LogFlowFunc(("strDropDir=%s\n", pResp->dropDir().c_str()));
     1034
    10261035                DnDURIList lstURI;
    10271036                int rc2 = lstURI.RootFromURIData(pvData, cbData, 0 /* fFlags */);
     
    10291038                {
    10301039                    Utf8Str strURIs = lstURI.RootToString(pResp->dropDir());
    1031                     if (sfaData.resize(strURIs.length()))
    1032                         memcpy(sfaData.raw(), strURIs.c_str(), strURIs.length());
     1040                    size_t cbURIs = strURIs.length();
     1041                    if (sfaData.resize(cbURIs + 1 /* Include termination */))
     1042                        memcpy(sfaData.raw(), strURIs.c_str(), cbURIs);
    10331043                    else
    10341044                        hr = E_OUTOFMEMORY;
     
    10491059        }
    10501060
    1051         LogFlowFunc(("cbData=%zu\n", cbData));
    1052 
    10531061        /* Detach in any case, regardless of data size. */
    10541062        sfaData.detachTo(ComSafeArrayOutArg(data));
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