VirtualBox

忽略:
時間撮記:
2014-2-19 下午03:45:58 (11 年 以前)
作者:
vboxsync
訊息:

DnD: Update.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp

    r50460 r50508  
    3434#include <VBox/GuestHost/DragAndDrop.h>
    3535
     36DnDURIObject::DnDURIObject(Type type,
     37                           const RTCString &strSrcPath,
     38                           const RTCString &strDstPath,
     39                           uint32_t fMode, uint64_t cbSize)
     40    : m_Type(type)
     41    , m_strSrcPath(strSrcPath)
     42    , m_strDstPath(strDstPath)
     43    , m_fMode(fMode)
     44    , m_cbSize(cbSize)
     45    , m_cbProcessed(0)
     46{
     47    RT_ZERO(u);
     48}
     49
     50DnDURIObject::~DnDURIObject(void)
     51{
     52    closeInternal();
     53}
     54
     55void DnDURIObject::closeInternal(void)
     56{
     57    if (m_Type == File)
     58    {
     59        if (u.m_hFile)
     60        {
     61            RTFileClose(u.m_hFile);
     62            u.m_hFile = NULL;
     63        }
     64    }
     65}
     66
     67bool DnDURIObject::IsComplete(void) const
     68{
     69    bool fComplete = false;
     70
     71    Assert(m_cbProcessed <= m_cbSize);
     72    if (m_cbProcessed == m_cbSize)
     73        fComplete = true;
     74
     75    switch (m_Type)
     76    {
     77        case File:
     78            if (!fComplete)
     79                fComplete = !u.m_hFile;
     80            break;
     81
     82        case Directory:
     83            fComplete = true;
     84            break;
     85
     86        default:
     87            break;
     88    }
     89
     90    return fComplete;
     91}
     92
     93/* static */
     94/** @todo Put this into an own class like DnDURIPath : public RTCString? */
     95int DnDURIObject::RebaseURIPath(RTCString &strPath,
     96                                const RTCString &strBaseOld,
     97                                const RTCString &strBaseNew)
     98{
     99    int rc;
     100    const char *pszPath = RTUriPath(strPath.c_str());
     101    if (pszPath)
     102    {
     103        const char *pszPathStart = pszPath;
     104        const char *pszBaseOld = strBaseOld.c_str();
     105        if (   pszBaseOld
     106            && RTPathStartsWith(pszPath, pszBaseOld))
     107        {
     108            pszPathStart += strlen(pszBaseOld);
     109        }
     110
     111        rc = VINF_SUCCESS;
     112
     113        if (RT_SUCCESS(rc))
     114        {
     115            char *pszPathNew = RTPathJoinA(strBaseNew.c_str(), pszPathStart);
     116            if (pszPathNew)
     117            {
     118                char *pszPathURI = RTUriCreate("file" /* pszScheme */, "/" /* pszAuthority */,
     119                                               pszPathNew /* pszPath */,
     120                                               NULL /* pszQuery */, NULL /* pszFragment */);
     121                if (pszPathURI)
     122                {
     123#ifdef DEBUG_andy
     124                    LogFlowFunc(("Rebasing \"%s\" to \"%s\"", strPath.c_str(), pszPathURI));
     125#endif
     126                    strPath = RTCString(pszPathURI) + "\r\n";
     127                    RTStrFree(pszPathURI);
     128
     129                    rc = VINF_SUCCESS;
     130                }
     131                else
     132                    rc = VERR_INVALID_PARAMETER;
     133
     134                RTStrFree(pszPathNew);
     135            }
     136            else
     137                rc = VERR_NO_MEMORY;
     138        }
     139    }
     140    else
     141        rc = VERR_INVALID_PARAMETER;
     142
     143#ifdef DEBUG_andy
     144    LogFlowFuncLeaveRC(rc);
     145#endif
     146    return rc;
     147}
     148
     149int DnDURIObject::Read(void *pvBuf, uint32_t cbToRead, uint32_t *pcbRead)
     150{
     151    AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
     152    AssertReturn(cbToRead, VERR_INVALID_PARAMETER);
     153    /* pcbRead is optional. */
     154
     155    int rc;
     156    switch (m_Type)
     157    {
     158        case File:
     159        {
     160            if (!u.m_hFile)
     161            {
     162                /* Open files on the source with RTFILE_O_DENY_WRITE to prevent races
     163                 * where the OS writes to the file while the destination side transfers
     164                 * it over. */
     165                rc = RTFileOpen(&u.m_hFile, m_strSrcPath.c_str(),
     166                                RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
     167            }
     168            else
     169                rc = VINF_SUCCESS;
     170
     171            bool fDone = false;
     172            if (RT_SUCCESS(rc))
     173            {
     174                size_t cbRead;
     175                rc = RTFileRead(u.m_hFile, pvBuf, cbToRead, &cbRead);
     176                if (RT_SUCCESS(rc))
     177                {
     178                    if (pcbRead)
     179                        *pcbRead = (uint32_t)cbRead;
     180
     181                    m_cbProcessed += cbRead;
     182                    Assert(m_cbProcessed <= m_cbSize);
     183
     184                    /* End of file reached or error occurred? */
     185                    if (   cbRead < cbToRead
     186                        || RT_FAILURE(rc))
     187                        closeInternal();
     188                }
     189            }
     190
     191            break;
     192        }
     193
     194        case Directory:
     195        {
     196            rc = VINF_SUCCESS;
     197            break;
     198        }
     199
     200        default:
     201            rc = VERR_NOT_IMPLEMENTED;
     202            break;
     203    }
     204
     205    LogFlowFunc(("Returning strSourcePath=%s, rc=%Rrc\n",
     206                 m_strSrcPath.c_str(), rc));
     207    return rc;
     208}
     209
     210/*** */
     211
    36212DnDURIList::DnDURIList(void)
    37213    : m_cbTotal(0)
     
    47223{
    48224    AssertPtrReturn(pcszPath, VERR_INVALID_POINTER);
    49     AssertReturn(cbBaseLen, VERR_INVALID_PARAMETER);
    50225
    51226    RTFSOBJINFO objInfo;
     
    74249        return rc;
    75250
    76     m_lstTree.append(DnDURIPath(pcszPath, &pcszPath[cbBaseLen],
    77                                 objInfo.Attr.fMode, cbSize));
     251    m_lstTree.append(DnDURIObject(  RTFS_IS_DIRECTORY(objInfo.Attr.fMode)
     252                                  ? DnDURIObject::Directory
     253                                  : DnDURIObject::File,
     254                                  pcszPath, &pcszPath[cbBaseLen],
     255                                  objInfo.Attr.fMode, cbSize));
    78256    m_cbTotal += cbSize;
    79257#ifdef DEBUG_andy
    80     LogFlowFunc(("strHostPath=%s, strGuestPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n",
     258    LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n",
    81259                 pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize, m_cbTotal));
    82260#endif
     
    140318                        break;
    141319
    142                     m_lstTree.append(DnDURIPath(pszNewFile, &pszNewFile[cbBaseLen],
    143                                                 objInfo1.Attr.fMode, cbSize));
     320                    m_lstTree.append(DnDURIObject(DnDURIObject::File,
     321                                                  pszNewFile, &pszNewFile[cbBaseLen],
     322                                                  objInfo1.Attr.fMode, cbSize));
    144323                    m_cbTotal += cbSize;
    145324#ifdef DEBUG_andy
    146                     LogFlowFunc(("strHostPath=%s, strGuestPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n",
     325                    LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cbTotal=%zu\n",
    147326                                 pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize, m_cbTotal));
    148327#endif
     
    163342}
    164343
    165 int DnDURIList::AppendPath(const char *pszPath, uint32_t fFlags)
     344int DnDURIList::AppendNativePath(const char *pszPath, uint32_t fFlags)
    166345{
    167346    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
    168347
     348    char *pszPathURI = RTUriCreate("file" /* pszScheme */, "/" /* pszAuthority */,
     349                                   pszPath, NULL /* pszQuery */, NULL /* pszFragment */);
     350    int rc;
     351    if (pszPathURI)
     352    {
     353        rc = AppendURIPath(pszPathURI, fFlags);
     354        RTStrFree(pszPathURI);
     355    }
     356    else
     357        rc = VERR_INVALID_PARAMETER;
     358
     359    return rc;
     360}
     361
     362int DnDURIList::AppendNativePathsFromList(const char *pszNativePaths, size_t cbNativePaths,
     363                                          uint32_t fFlags)
     364{
     365    AssertPtrReturn(pszNativePaths, VERR_INVALID_POINTER);
     366    AssertReturn(cbNativePaths, VERR_INVALID_PARAMETER);
     367
     368    RTCList<RTCString> lstPaths
     369        = RTCString(pszNativePaths, cbNativePaths - 1).split("\r\n");
     370    return AppendNativePathsFromList(lstPaths, fFlags);
     371}
     372
     373int DnDURIList::AppendNativePathsFromList(const RTCList<RTCString> &lstNativePaths,
     374                                          uint32_t fFlags)
     375{
     376    int rc = VINF_SUCCESS;
     377
     378    for (size_t i = 0; i < lstNativePaths.size(); i++)
     379    {
     380        const RTCString &strPath = lstNativePaths.at(i);
     381        rc = AppendNativePath(strPath.c_str(), fFlags);
     382        if (RT_FAILURE(rc))
     383            break;
     384    }
     385
     386    LogFlowFuncLeaveRC(rc);
     387    return rc;
     388}
     389
     390int DnDURIList::AppendURIPath(const char *pszURI, uint32_t fFlags)
     391{
     392    AssertPtrReturn(pszURI, VERR_INVALID_POINTER);
     393
    169394#ifdef DEBUG_andy
    170     LogFlowFunc(("pszPath=%s, fFlags=0x%x\n", pszPath, fFlags));
     395    LogFlowFunc(("pszPath=%s, fFlags=0x%x\n", pszURI, fFlags));
    171396#endif
    172397    int rc = VINF_SUCCESS;
     
    174399    /* Query the path component of a file URI. If this hasn't a
    175400     * file scheme NULL is returned. */
    176     char *pszFilePath = RTUriFilePath(pszPath, URI_FILE_FORMAT_AUTO);
     401    char *pszFilePath = RTUriFilePath(pszURI, URI_FILE_FORMAT_AUTO);
    177402    if (pszFilePath)
    178403    {
     
    182407        if (pszFileName)
    183408        {
    184             char *pszNewURI = RTUriFileCreate(pszFileName);
    185             if (pszNewURI)
    186             {
    187                 m_lstRoot.append(pszNewURI);
    188                 RTStrFree(pszNewURI);
    189 
    190                 rc = appendPathRecursive(pszFilePath,
    191                                          pszFileName - pszFilePath,
    192                                          fFlags);
    193             }
    194         }
     409            Assert(pszFileName >= pszFilePath);
     410            char *pszRoot = &pszFilePath[pszFileName - pszFilePath];
     411            m_lstRoot.append(pszRoot);
     412#ifdef DEBUG_andy
     413            LogFlowFunc(("pszFilePath=%s, pszFileName=%s, pszRoot=%s\n",
     414                         pszFilePath, pszFileName, pszRoot));
     415#endif
     416            rc = appendPathRecursive(pszFilePath,
     417                                     pszFileName - pszFilePath,
     418                                     fFlags);
     419        }
     420        else
     421            rc = VERR_NOT_FOUND;
    195422
    196423        RTStrFree(pszFilePath);
    197424    }
    198     else /* Just append the raw data. */
    199         m_lstRoot.append(pszPath);
     425    else
     426        rc = VERR_INVALID_PARAMETER;
    200427
    201428    LogFlowFuncLeaveRC(rc);
     
    203430}
    204431
    205 int DnDURIList::AppendPathsFromList(const RTCList<RTCString> &lstURI,
    206                                     uint32_t fFlags)
     432int DnDURIList::AppendURIPathsFromList(const char *pszURIPaths, size_t cbURIPaths,
     433                                       uint32_t fFlags)
     434{
     435    AssertPtrReturn(pszURIPaths, VERR_INVALID_POINTER);
     436    AssertReturn(cbURIPaths, VERR_INVALID_PARAMETER);
     437
     438    RTCList<RTCString> lstPaths
     439        = RTCString(pszURIPaths, cbURIPaths - 1).split("\r\n");
     440    return AppendURIPathsFromList(lstPaths, fFlags);
     441}
     442
     443int DnDURIList::AppendURIPathsFromList(const RTCList<RTCString> &lstURI,
     444                                       uint32_t fFlags)
    207445{
    208446    int rc = VINF_SUCCESS;
     
    210448    for (size_t i = 0; i < lstURI.size(); i++)
    211449    {
    212         const RTCString &strURI = lstURI.at(i);
    213         rc = AppendPath(strURI.c_str(), fFlags);
     450        RTCString strURI = lstURI.at(i);
     451        rc = AppendURIPath(strURI.c_str(), fFlags);
     452
    214453        if (RT_FAILURE(rc))
    215454            break;
     
    228467}
    229468
     469#if 0
     470int DnDURIList::FromData(const void *pvData, size_t cbData,
     471
     472                         uint32_t fFlags)
     473{
     474    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     475    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     476
     477    RTCList<RTCString> lstURI =
     478        RTCString(static_cast<const char*>(pvData), cbData - 1).split("\r\n");
     479    if (lstURI.isEmpty())
     480        return VINF_SUCCESS;
     481
     482    int rc = VINF_SUCCESS;
     483
     484    for (size_t i = 0; i < lstURI.size(); ++i)
     485    {
     486        const RTCString &strUri = lstURI.at(i);
     487        /* Query the path component of a file URI. If this hasn't a
     488         * file scheme, null is returned. */
     489        char *pszFilePath = RTUriFilePath(strUri.c_str(), URI_FILE_FORMAT_AUTO);
     490        if (pszFilePath)
     491        {
     492            rc = DnDPathSanitize(pszFilePath, strlen(pszFilePath));
     493            if (RT_SUCCESS(rc))
     494            {
     495                /** @todo Use RTPathJoin? */
     496                RTCString strFullPath;
     497                if (strBasePath.isNotEmpty())
     498                    strFullPath = RTCString().printf("%s%c%s", strBasePath.c_str(),
     499                                                     RTPATH_SLASH, pszFilePath);
     500                else
     501                    strFullPath = pszFilePath;
     502
     503                char *pszNewUri = RTUriFileCreate(strFullPath.c_str());
     504                if (pszNewUri)
     505                {
     506                    m_lstRoot.append(pszNewUri);
     507                    RTStrFree(pszNewUri);
     508                }
     509            }
     510        }
     511        else
     512            rc = VERR_INVALID_PARAMETER;
     513
     514        if (RT_FAILURE(rc))
     515            break;
     516    }
     517
     518    return rc;
     519}
     520#endif
     521
    230522void DnDURIList::RemoveFirst(void)
    231523{
    232     const DnDURIPath &curPath = m_lstTree.first();
    233 
    234     Assert(m_cbTotal >= curPath.m_cbSize);
    235     m_cbTotal -= curPath.m_cbSize; /* Adjust total size. */
     524    DnDURIObject &curPath = m_lstTree.first();
     525
     526    uint64_t cbSize = curPath.GetSize();
     527    Assert(m_cbTotal >= cbSize);
     528    m_cbTotal -= cbSize; /* Adjust total size. */
    236529
    237530    m_lstTree.removeFirst();
    238531}
    239532
     533int DnDURIList::RootFromURIData(const void *pvData, size_t cbData,
     534                                uint32_t fFlags)
     535{
     536    AssertPtrReturn(pvData, VERR_INVALID_POINTER);
     537    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     538
     539    RTCList<RTCString> lstURI =
     540        RTCString(static_cast<const char*>(pvData), cbData - 1).split("\r\n");
     541    if (lstURI.isEmpty())
     542        return VINF_SUCCESS;
     543
     544    int rc = VINF_SUCCESS;
     545
     546    for (size_t i = 0; i < lstURI.size(); ++i)
     547    {
     548        /* Query the path component of a file URI. If this hasn't a
     549         * file scheme, NULL is returned. */
     550        const char *pszURI = lstURI.at(i).c_str();
     551        char *pszFilePath = RTUriFilePath(pszURI,
     552                                          URI_FILE_FORMAT_AUTO);
     553#ifdef DEBUG_andy
     554        LogFlowFunc(("pszURI=%s, pszFilePath=%s\n", pszURI, pszFilePath));
     555#endif
     556        if (pszFilePath)
     557        {
     558            rc = DnDPathSanitize(pszFilePath, strlen(pszFilePath));
     559            if (RT_SUCCESS(rc))
     560                m_lstRoot.append(pszFilePath);
     561
     562            RTStrFree(pszFilePath);
     563        }
     564        else
     565            rc = VERR_INVALID_PARAMETER;
     566
     567        if (RT_FAILURE(rc))
     568            break;
     569    }
     570
     571    return rc;
     572}
     573
     574RTCString DnDURIList::RootToString(const RTCString &strBasePath /* = "" */)
     575{
     576    RTCString strRet;
     577    for (size_t i = 0; i < m_lstRoot.size(); i++)
     578    {
     579        const char *pszCurRoot = m_lstRoot.at(i).c_str();
     580        if (strBasePath.isNotEmpty())
     581        {
     582            char *pszPath = RTPathJoinA(strBasePath.c_str(), pszCurRoot);
     583            if (pszPath)
     584            {
     585                char *pszPathURI = RTUriFileCreate(pszPath);
     586                if (pszPathURI)
     587                {
     588                    strRet += RTCString(pszPathURI) + "\r\n";
     589                    RTStrFree(pszPathURI);
     590                }
     591                RTStrFree(pszPath);
     592            }
     593            else
     594                break;
     595        }
     596        else
     597        {
     598            char *pszPathURI = RTUriFileCreate(pszCurRoot);
     599            if (pszPathURI)
     600            {
     601                strRet += RTCString(pszPathURI) + "\r\n";
     602                RTStrFree(pszPathURI);
     603            }
     604            else
     605                break;
     606        }
     607    }
     608
     609    return strRet;
     610}
     611
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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