VirtualBox

Ignore:
Timestamp:
Feb 14, 2014 9:46:58 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
92295
Message:

DnD: Update.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/DragAndDrop/Makefile.kmk

    r42261 r50460  
    4343        $(LIB_VMM) \
    4444        $(LIB_RUNTIME) \
    45         $(LIB_REM)
     45        $(LIB_REM) \
     46        $(PATH_STAGE_LIB)/VBoxDnDHostR3Lib$(VBOX_SUFF_LIB)
    4647
    4748VBoxDragAndDropSvc_LDFLAGS.darwin = \
  • trunk/src/VBox/HostServices/DragAndDrop/dndmanager.cpp

    r50316 r50460  
    55
    66/*
    7  * Copyright (C) 2011-2013 Oracle Corporation
     7 * Copyright (C) 2011-2014 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4848{
    4949public:
    50     DnDHGSendDirPrivate(const RTCString &strPath, uint32_t fMode, uint64_t cbSize, PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser)
    51       : m_strPath(strPath)
    52       , m_cbSize(cbSize)
    53       , m_pfnProgressCallback(pfnProgressCallback)
    54       , m_pvProgressUser(pvProgressUser)
     50
     51    DnDHGSendDirPrivate(const RTCString &strPath,
     52                        uint32_t fMode, uint64_t cbSize,
     53                        PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser)
     54        : m_strPath(strPath)
     55        , m_cbSize(cbSize)
     56        , m_pfnProgressCallback(pfnProgressCallback)
     57        , m_pvProgressUser(pvProgressUser)
    5558    {
    5659        VBOXHGCMSVCPARM paTmpParms[3];
    5760        paTmpParms[0].setString(m_strPath.c_str());
    58         paTmpParms[1].setUInt32(m_strPath.length() + 1);
     61        paTmpParms[1].setUInt32((uint32_t)(m_strPath.length() + 1));
    5962        paTmpParms[2].setUInt32(fMode);
    6063
     
    7477
    7578protected:
    76     RTCString m_strPath;
     79    RTCString              m_strPath;
    7780
    7881    /* Progress stuff */
     
    9093{
    9194public:
    92     DnDHGSendFilePrivate(const RTCString &strHostPath, const RTCString &strGuestPath, uint32_t fMode, uint64_t cbSize, PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser);
    93     virtual ~DnDHGSendFilePrivate();
     95
     96    DnDHGSendFilePrivate(const RTCString &strHostPath,
     97                         const RTCString &strGuestPath,
     98                         uint32_t fMode, uint64_t cbSize,
     99                         PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser);
     100    virtual ~DnDHGSendFilePrivate(void);
    94101
    95102    int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     
    117124{
    118125public:
    119     DnDHGSendDataMessagePrivate(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser);
     126
     127    DnDHGSendDataMessagePrivate(uint32_t uMsg, uint32_t cParms,
     128                                VBOXHGCMSVCPARM paParms[],
     129                                PFNDNDPRIVATEPROGRESS pfnProgressCallback, void *pvProgressUser);
    120130    int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    121131
     
    149159{
    150160    m_paSkelParms[0].setString(m_strGuestPath.c_str());
    151     m_paSkelParms[1].setUInt32(m_strGuestPath.length() + 1);
     161    m_paSkelParms[1].setUInt32((uint32_t)(m_strGuestPath.length() + 1));
    152162    m_paSkelParms[2].setPointer(NULL, 0);
    153163    m_paSkelParms[3].setUInt32(0);
     
    198208
    199209            /* Tell the guest the actual size. */
    200             paParms[3].setUInt32(cbRead);
     210            paParms[3].setUInt32((uint32_t)cbRead);
    201211        }
    202212    }
     
    205215    {
    206216        /* Check if we are done. */
     217        Assert(m_cbFileProcessed <= m_cbFileSize);
    207218        bool fDone = m_cbFileSize == m_cbFileProcessed;
    208219        if (!fDone)
     
    231242        {
    232243            RTFileClose(m_hCurFile);
    233             m_hCurFile = 0;
     244            m_hCurFile = NIL_RTFILE;
    234245        }
    235246    }
     
    325336                                           PFNDNDPROGRESS pfnProgressCallback,
    326337                                           void *pvProgressUser)
    327     : m_cbAll(0)
     338    : m_cbTotal(0)
    328339    , m_cbTransfered(0)
    329340    , m_pfnProgressCallback(pfnProgressCallback)
    330341    , m_pvProgressUser(pvProgressUser)
    331342{
     343    if (cParms < 5) /* Paranoia. */
     344        return;
     345
     346    const char *pszFormat = static_cast<const char*>(paParms[1].u.pointer.addr);
     347    uint32_t cbFormat = paParms[1].u.pointer.size;
     348
     349    int rc = VINF_SUCCESS;
    332350    RTCString strNewURIs;
    333351
    334     /* Check the format for any uri type. */
    335     if (hasFileUrls(static_cast<const char*>(paParms[1].u.pointer.addr),
    336                     paParms[1].u.pointer.size))
    337     {
    338         LogFlowFunc(("Old data: '%s'\n", (char*)paParms[3].u.pointer.addr));
     352    /* Do we need to build up a file tree? */
     353    if (DnDMIMEHasFileURLs(pszFormat, cbFormat))
     354    {
     355        const char *pszList = static_cast<const char*>(paParms[3].u.pointer.addr);
     356        AssertPtr(pszList);
     357        uint32_t cbList = paParms[3].u.pointer.size;
     358        Assert(cbList);
     359
     360        LogFlowFunc(("Old data: '%s'\n", pszList));
    339361
    340362        /* The list is separated by newline (even if only one file is listed). */
    341         RTCList<RTCString> lstURIOrg = RTCString(static_cast<const char*>(paParms[3].u.pointer.addr),
    342                                                  paParms[3].u.pointer.size).split("\r\n");
     363        RTCList<RTCString> lstURIOrg
     364            = RTCString(pszList, cbList).split("\r\n");
    343365        if (!lstURIOrg.isEmpty())
    344366        {
    345             RTCList<RTCString> lstURINew;
    346             for (size_t i = 0; i < lstURIOrg.size(); ++i)
    347             {
    348                 const RTCString &strURI = lstURIOrg.at(i);
    349 
    350                 /* Query the path component of a file URI. If this hasn't a
    351                  * file scheme NULL is returned. */
    352                 char *pszFilePath;
    353                 if ((pszFilePath = RTUriFilePath(strURI.c_str(), URI_FILE_FORMAT_AUTO)))
    354                 {
    355                     /* Add the path to our internal file list (recursive in
    356                      * the case of a directory). */
    357                     char *pszFilename;
    358                     if ((pszFilename = RTPathFilename(pszFilePath)))
    359                     {
    360                         char *pszNewURI = RTUriFileCreate(pszFilename);
    361                         if (pszNewURI)
    362                         {
    363                             lstURINew.append(pszNewURI);
    364                             RTStrFree(pszNewURI);
    365 
    366                             buildFileTree(pszFilePath, pszFilename - pszFilePath);
    367                         }
    368                     }
    369 
    370                     RTStrFree(pszFilePath);
    371                 }
    372                 else /* Just append the raw data. */
    373                     lstURINew.append(strURI);
    374             }
    375 
    376             /* We have to change the actual DnD data. Remove any host paths and
    377              * just decode the filename into the new data. The guest tools will
    378              * add the correct path again, before sending the DnD drop event to
    379              * some window. */
    380             strNewURIs = RTCString::join(lstURINew, "\r\n") + "\r\n";
    381 
    382             /* Note: We don't delete the old pointer here, cause this is done
    383              *       by the caller. We just use the RTString data, which has the
    384              *       scope of this ctor. This is enough cause the data is copied in
    385              *       the DnDHGSendDataMessagePrivate anyway. */
    386             paParms[3].u.pointer.addr = (void*)strNewURIs.c_str();
    387             paParms[3].u.pointer.size = strNewURIs.length() + 1;
    388             paParms[4].u.uint32       = strNewURIs.length() + 1;
     367            rc = m_lstURI.AppendPathsFromList(lstURIOrg, 0 /* fFlags */);
     368            if (RT_SUCCESS(rc))
     369            {
     370                /* Add the total size of all meta data + files transferred to
     371                 * the message's total count. */
     372                m_cbTotal += m_lstURI.TotalBytes();
     373
     374                /* We have to change the actual DnD data. Remove any host paths and
     375                 * just decode the filename into the new data. The guest tools will
     376                 * add the correct path again, before sending the DnD drop event to
     377                 * some window. */
     378                strNewURIs = m_lstURI.RootToString();
     379
     380                /* Note: We don't delete the old pointer here, cause this is done
     381                 *       by the caller. We just use the RTString data, which has the
     382                 *       scope of this ctor. This is enough cause the data is copied in
     383                 *       the DnDHGSendDataMessagePrivate anyway. */
     384                paParms[3].u.pointer.addr = (void *)strNewURIs.c_str();
     385                paParms[3].u.pointer.size = (uint32_t)(strNewURIs.length() + 1);
     386                paParms[4].u.uint32       = (uint32_t)(strNewURIs.length() + 1);
     387
     388                LogFlowFunc(("Set new data: '%s'\n", (char*)paParms[3].u.pointer.addr));
     389            }
    389390        }
    390391    }
    391392
    392393    /* Add the size of the data to the todo list. */
    393     m_cbAll += paParms[4].u.uint32;
     394    m_cbTotal += paParms[4].u.uint32;
     395    LogFlowFunc(("cbTotal=%zu\n", m_cbTotal));
    394396
    395397    /* The first message is the meta info for the data and the data itself. */
    396398    m_pNextPathMsg = new DnDHGSendDataMessagePrivate(uMsg, cParms, paParms,
    397399                                                     &DnDHGSendDataMessage::progressCallback, this);
    398 #ifdef DEBUG
    399     LogFlowFunc(("new data '%s'\n", (char*)paParms[3].u.pointer.addr));
    400     LogFlowFunc(("cbAll: %zu\n", m_cbAll));
    401     LogFlowFunc(("cbData: %RU32\n", paParms[4].u.uint32));
    402 
    403     for (size_t i = 0; i < m_uriList.size(); ++i)
    404         LogFlowFunc(("file: %s : %s - %o - %ld\n",
    405                      m_uriList.at(i).m_strHostPath.c_str(), m_uriList.at(i).m_strGuestPath.c_str(),
    406                      m_uriList.at(i).m_fMode, m_uriList.at(i).m_cbSize));
    407 #endif
    408400}
    409401
     
    430422}
    431423
    432 int DnDHGSendDataMessage::currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     424int DnDHGSendDataMessage::currentMessage(uint32_t uMsg,
     425                                         uint32_t cParms, VBOXHGCMSVCPARM paParms[])
    433426{
    434427    if (!m_pNextPathMsg)
     
    444437    }
    445438
    446     /* File data to send? */
     439    /* File/directory data to send? */
    447440    if (!m_pNextPathMsg)
    448441    {
    449         if (m_uriList.isEmpty())
     442        if (m_lstURI.IsEmpty())
    450443            return rc;
     444
    451445        /* Create new messages based on our internal path list. Currently
    452446         * this could be directories or regular files. */
    453         PathEntry nextPath = m_uriList.first();
     447        const DnDURIPath &nextPath = m_lstURI.First();
    454448        try
    455449        {
     450            LogFlowFunc(("Processing srcPath=%s, dstPath=%s, fMode=0x%x, cbSize=%RU32, fIsDir=%RTbool, fIsFile=%RTbool\n",
     451                         nextPath.m_strSrcPath.c_str(), nextPath.m_strDstPath.c_str(),
     452                         nextPath.m_fMode, nextPath.m_cbSize,
     453                         RTFS_IS_DIRECTORY(nextPath.m_fMode), RTFS_IS_FILE(nextPath.m_fMode)));
     454
    456455            if (RTFS_IS_DIRECTORY(nextPath.m_fMode))
    457                 m_pNextPathMsg = new DnDHGSendDirPrivate(nextPath.m_strGuestPath,
     456                m_pNextPathMsg = new DnDHGSendDirPrivate(nextPath.m_strDstPath,
    458457                                                         nextPath.m_fMode, nextPath.m_cbSize,
    459                                                          &DnDHGSendDataMessage::progressCallback, this);
     458                                                         &DnDHGSendDataMessage::progressCallback,
     459                                                         this /* pvProgressUser */);
    460460            else if (RTFS_IS_FILE(nextPath.m_fMode))
    461                 m_pNextPathMsg = new DnDHGSendFilePrivate(nextPath.m_strHostPath, nextPath.m_strGuestPath,
     461                m_pNextPathMsg = new DnDHGSendFilePrivate(nextPath.m_strSrcPath, nextPath.m_strDstPath,
    462462                                                          nextPath.m_fMode, nextPath.m_cbSize,
    463                                                           &DnDHGSendDataMessage::progressCallback, this);
     463                                                          &DnDHGSendDataMessage::progressCallback,
     464                                                          this /* pvProgressUser */);
    464465            else
    465                 AssertMsgFailedReturn(("type '%d' is not supported for path '%s'",
    466                                        nextPath.m_fMode, nextPath.m_strHostPath.c_str()), VERR_NO_DATA);
    467 
    468             m_uriList.removeFirst();
     466                AssertMsgFailedReturn(("fMode=0x%x is not supported for srcPath=%s, dstPath=%s\n",
     467                                       nextPath.m_fMode, nextPath.m_strSrcPath.c_str(), nextPath.m_strDstPath),
     468                                       VERR_NO_DATA);
     469
     470            m_lstURI.RemoveFirst();
    469471        }
    470472        catch(std::bad_alloc &)
     
    473475        }
    474476    }
    475 
    476     return rc;
    477 }
    478 
    479 bool DnDHGSendDataMessage::hasFileUrls(const char *pcszFormat, size_t cbMax) const
    480 {
    481     LogFlowFunc(("format %s\n", pcszFormat));
    482 
    483     /** @todo text/uri also an official variant? */
    484     return (   RTStrNICmp(pcszFormat, "text/uri-list", cbMax)             == 0
    485             || RTStrNICmp(pcszFormat, "x-special/gnome-icon-list", cbMax) == 0);
    486 }
    487 
    488 int DnDHGSendDataMessage::buildFileTree(const char *pcszPath, size_t cbBaseLen)
    489 {
    490     RTFSOBJINFO objInfo;
    491     int rc = RTPathQueryInfo(pcszPath, &objInfo, RTFSOBJATTRADD_NOTHING);
    492     if (RT_FAILURE(rc))
    493         return rc;
    494 
    495     /*
    496      * These are the types we currently support. Symlinks are not directly
    497      * supported. First the guest could be an OS which doesn't support it and
    498      * second the symlink could point to a file which is out of the base tree.
    499      * Both things are hard to support. For now we just copy the target file in
    500      * this case.
    501      */
    502     if (!(   RTFS_IS_DIRECTORY(objInfo.Attr.fMode)
    503           || RTFS_IS_FILE(objInfo.Attr.fMode)
    504           || RTFS_IS_SYMLINK(objInfo.Attr.fMode)))
    505         return VINF_SUCCESS;
    506 
    507     uint64_t cbSize = 0;
    508     rc = RTFileQuerySize(pcszPath, &cbSize);
    509     if (rc == VERR_IS_A_DIRECTORY)
    510         rc = VINF_SUCCESS;
    511 
    512     if (RT_FAILURE(rc))
    513         return rc;
    514 
    515     m_uriList.append(PathEntry(pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize));
    516     m_cbAll += cbSize;
    517     LogFlowFunc(("cbFile: %RU64\n", cbSize));
    518 
    519     PRTDIR hDir;
    520     /* We have to try to open even symlinks, cause they could be symlinks
    521      * to directories. */
    522     rc = RTDirOpen(&hDir, pcszPath);
    523     /* The following error happens when this was a symlink to an file or a
    524      * regular file. */
    525     if (rc == VERR_PATH_NOT_FOUND)
    526         return VINF_SUCCESS;
    527     if (RT_FAILURE(rc))
    528         return rc;
    529 
    530     while (RT_SUCCESS(rc))
    531     {
    532         RTDIRENTRY DirEntry;
    533         rc = RTDirRead(hDir, &DirEntry, NULL);
    534         if (RT_FAILURE(rc))
    535         {
    536             if (rc == VERR_NO_MORE_FILES)
    537                 rc = VINF_SUCCESS;
    538             break;
    539         }
    540         switch (DirEntry.enmType)
    541         {
    542             case RTDIRENTRYTYPE_DIRECTORY:
    543             {
    544                 /* Skip "." and ".." entries. */
    545                 if (   RTStrCmp(DirEntry.szName, ".")  == 0
    546                     || RTStrCmp(DirEntry.szName, "..") == 0)
    547                     break;
    548                 if (char *pszRecDir = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName))
    549                 {
    550                     rc = buildFileTree(pszRecDir, cbBaseLen);
    551                     RTStrFree(pszRecDir);
    552                 }
    553                 else
    554                     rc = VERR_NO_MEMORY;
    555                 break;
    556             }
    557             case RTDIRENTRYTYPE_SYMLINK:
    558             case RTDIRENTRYTYPE_FILE:
    559             {
    560                 char *pszNewFile;
    561                 if ((pszNewFile = RTStrAPrintf2("%s%c%s", pcszPath, RTPATH_DELIMITER, DirEntry.szName)))
    562                 {
    563                     /* We need the size and the mode of the file. */
    564                     RTFSOBJINFO objInfo1;
    565                     rc = RTPathQueryInfo(pszNewFile, &objInfo1, RTFSOBJATTRADD_NOTHING);
    566                     if (RT_FAILURE(rc))
    567                         return rc;
    568                     rc = RTFileQuerySize(pszNewFile, &cbSize);
    569                     if (RT_FAILURE(rc))
    570                         break;
    571 
    572                     m_uriList.append(PathEntry(pszNewFile, &pszNewFile[cbBaseLen],
    573                                                objInfo1.Attr.fMode, cbSize));
    574                     m_cbAll += cbSize;
    575 
    576                     RTStrFree(pszNewFile);
    577                 }
    578                 else
    579                     rc = VERR_NO_MEMORY;
    580                 break;
    581             }
    582 
    583             default:
    584                 break;
    585         }
    586     }
    587 
    588     RTDirClose(hDir);
    589477
    590478    return rc;
     
    601489    pSelf->m_cbTransfered += cbDone;
    602490
    603     /* Advance progress info */
     491    /* Advance progress info. */
    604492    int rc = VINF_SUCCESS;
    605493    if (   pSelf->m_pfnProgressCallback
    606         && pSelf->m_cbAll)
    607     {
    608         rc = pSelf->m_pfnProgressCallback((uint64_t)pSelf->m_cbTransfered * 100 / pSelf->m_cbAll,
     494        && pSelf->m_cbTotal)
     495    {
     496        AssertMsg(pSelf->m_cbTransfered <= pSelf->m_cbTotal,
     497                  ("More bytes transferred (%zu) than expected (%zu), cbDone=%zu\n",
     498                   pSelf->m_cbTransfered, pSelf->m_cbTotal, cbDone));
     499
     500        unsigned uPercentage = (unsigned)((uint64_t)pSelf->m_cbTransfered * 100 / pSelf->m_cbTotal);
     501        rc = pSelf->m_pfnProgressCallback(RT_CLAMP(uPercentage, 0, 100),
    609502                                          DragAndDropSvc::DND_PROGRESS_RUNNING,
    610503                                          VINF_SUCCESS /* rc */, pSelf->m_pvProgressUser);
  • trunk/src/VBox/HostServices/DragAndDrop/dndmanager.h

    r50308 r50460  
    44
    55/*
    6  * Copyright (C) 2011-2012 Oracle Corporation
     6 * Copyright (C) 2011-2014 Oracle Corporation
    77 *
    88 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1818#define ___VBox_HostService_DnD_dndmanager_h
    1919
     20#include <VBox/GuestHost/DragAndDrop.h>
    2021#include <VBox/HostServices/Service.h>
    2122#include <VBox/HostServices/DragAndDropSvc.h>
     
    3435{
    3536public:
    36     DnDMessage()
    37       : m_pNextMsg(NULL)
    38     {
    39     }
    40     virtual ~DnDMessage()
     37
     38    DnDMessage(void)
     39        : m_pNextMsg(NULL)
     40    {
     41    }
     42
     43    virtual ~DnDMessage(void)
    4144    {
    4245        clearNextMsg();
    4346    }
    4447
    45     virtual HGCM::Message* nextHGCMMessage()
     48    virtual HGCM::Message* nextHGCMMessage(void)
    4649    {
    4750        return m_pNextMsg;
    4851    }
     52
    4953    virtual int currentMessageInfo(uint32_t *puMsg, uint32_t *pcParms)
    5054    {
     
    6064        return VINF_SUCCESS;
    6165    }
    62     virtual int currentMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[])
     66
     67    virtual int currentMessage(uint32_t uMsg, uint32_t cParms,
     68                               VBOXHGCMSVCPARM paParms[])
    6369    {
    6470        if (!m_pNextMsg)
     
    7177        return rc;
    7278    }
    73     virtual void clearNextMsg()
     79
     80    virtual void clearNextMsg(void)
    7481    {
    7582        if (m_pNextMsg)
     
    8087    }
    8188
    82     virtual bool isMessageWaiting() const { return m_pNextMsg != NULL; }
     89    virtual bool isMessageWaiting(void) const { return m_pNextMsg != NULL; }
    8390
    8491protected:
     92
    8593    HGCM::Message *m_pNextMsg;
    8694};
     
    106114public:
    107115
    108     DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[], PFNDNDPROGRESS pfnProgressCallback, void *pvProgressUser);
     116    DnDHGSendDataMessage(uint32_t uMsg, uint32_t cParms,
     117                         VBOXHGCMSVCPARM paParms[],
     118                         PFNDNDPROGRESS pfnProgressCallback, void *pvProgressUser);
     119
    109120    virtual ~DnDHGSendDataMessage(void);
    110121
     
    117128protected:
    118129
    119     struct PathEntry
    120     {
    121         PathEntry(const RTCString &strHostPath, const RTCString &strGuestPath, uint32_t fMode, uint64_t cbSize)
    122             : m_strHostPath(strHostPath)
    123             , m_strGuestPath(strGuestPath)
    124             , m_fMode(fMode)
    125             , m_cbSize(cbSize) {}
    126         RTCString m_strHostPath;
    127         RTCString m_strGuestPath;
    128         uint32_t  m_fMode;
    129         uint64_t  m_cbSize;
    130     };
    131 
    132     bool hasFileUrls(const char *pcszFormat, size_t cbMax) const;
    133     int buildFileTree(const char *pcszPath, size_t cbBaseLen);
    134130    static DECLCALLBACK(int) progressCallback(size_t cbDone, void *pvUser);
    135131
    136     RTCList<PathEntry>  m_uriList;
    137132    DnDMessage         *m_pNextPathMsg;
    138133
    139     /* Total size (in bytes). */
    140     size_t              m_cbAll;
    141     /* Transferred size (in bytes). */
     134    DnDURIList          m_lstURI;
     135    /* Total message size (in bytes). */
     136    size_t              m_cbTotal;
     137    /* Transferred message size (in bytes). */
    142138    size_t              m_cbTransfered;
     139
    143140    PFNDNDPROGRESS      m_pfnProgressCallback;
    144141    void               *m_pvProgressUser;
     
    152149{
    153150public:
    154     DnDHGCancelMessage()
    155     {
    156         m_pNextMsg = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_EVT_CANCEL, 0, 0);
     151
     152    DnDHGCancelMessage(void)
     153    {
     154        m_pNextMsg
     155            = new HGCM::Message(DragAndDropSvc::HOST_DND_HG_EVT_CANCEL,
     156                                0 /* cParms */, 0 /* aParms */);
    157157    }
    158158};
     
    165165{
    166166public:
     167
    167168    DnDManager(PFNDNDPROGRESS pfnProgressCallback, void *pvProgressUser)
    168       : m_pCurMsg(0)
    169       , m_fOpInProcess(false)
    170       , m_pfnProgressCallback(pfnProgressCallback)
    171       , m_pvProgressUser(pvProgressUser)
     169        : m_pCurMsg(0)
     170        , m_fOpInProcess(false)
     171        , m_pfnProgressCallback(pfnProgressCallback)
     172        , m_pvProgressUser(pvProgressUser)
    172173    {}
    173     virtual ~DnDManager()
     174
     175    virtual ~DnDManager(void)
    174176    {
    175177        clear();
     
    178180    int addMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    179181
    180     HGCM::Message *nextHGCMMessage();
     182    HGCM::Message *nextHGCMMessage(void);
    181183    int nextMessageInfo(uint32_t *puMsg, uint32_t *pcParms);
    182184    int nextMessage(uint32_t uMsg, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
    183185
    184     void clear();
    185 
    186     bool hasActiveOperation() const { return m_fOpInProcess; }
     186    void clear(void);
     187
     188    bool hasActiveOperation(void) const { return m_fOpInProcess; }
    187189
    188190private:
     
    196198    void                 *m_pvProgressUser;
    197199};
    198 
    199200#endif /* ___VBox_HostService_DnD_dndmanager_h */
    200201
  • trunk/src/VBox/HostServices/DragAndDrop/service.cpp

    r50308 r50460  
    470470        DragAndDropSvc::VBOXDNDCBHGEVTPROGRESSDATA data;
    471471        data.hdr.u32Magic = DragAndDropSvc::CB_MAGIC_DND_HG_EVT_PROGRESS;
    472         data.uPercentage  = uPercentage;
     472        data.uPercentage  = RT_CLAMP(uPercentage, 0, 100);
    473473        data.uState       = uState;
    474474        data.rc           = rc;
Note: See TracChangeset for help on using the changeset viewer.

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