VirtualBox

Changeset 4041 in vbox


Ignore:
Timestamp:
Aug 6, 2007 12:47:18 PM (17 years ago)
Author:
vboxsync
Message:

Main: Shared Folders (#2130):

  • Solved folder name unicity problems by introducing scope precedence (transient, then permanent, then global).
  • Implemented VM process notification on permanent (machine) shared folder change.
Location:
trunk/src/VBox/Main
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r4034 r4041  
    174174    PFNCFGMCONSTRUCTOR mConfigConstructor;
    175175    Utf8Str mSavedStateFile;
    176     std::map <Bstr, ComPtr <ISharedFolder> > mSharedFolders;
     176    Console::SharedFolderDataMap mSharedFolders;
    177177};
    178178
     
    266266
    267267    rc = mMachine->COMGETTER(State) (&mMachineState);
    268     AssertComRCReturn (rc, rc);
     268    AssertComRCReturnRC (rc);
    269269
    270270#ifdef VBOX_VRDP
    271271    rc = mMachine->COMGETTER(VRDPServer) (unconst (mVRDPServer).asOutParam());
    272     AssertComRCReturn (rc, rc);
     272    AssertComRCReturnRC (rc);
    273273#endif
    274274
    275275    rc = mMachine->COMGETTER(DVDDrive) (unconst (mDVDDrive).asOutParam());
    276     AssertComRCReturn (rc, rc);
     276    AssertComRCReturnRC (rc);
    277277
    278278    rc = mMachine->COMGETTER(FloppyDrive) (unconst (mFloppyDrive).asOutParam());
    279     AssertComRCReturn (rc, rc);
     279    AssertComRCReturnRC (rc);
    280280
    281281    /* Create associated child COM objects */
     
    283283    unconst (mGuest).createObject();
    284284    rc = mGuest->init (this);
    285     AssertComRCReturn (rc, rc);
     285    AssertComRCReturnRC (rc);
    286286
    287287    unconst (mKeyboard).createObject();
    288288    rc = mKeyboard->init (this);
    289     AssertComRCReturn (rc, rc);
     289    AssertComRCReturnRC (rc);
    290290
    291291    unconst (mMouse).createObject();
    292292    rc = mMouse->init (this);
    293     AssertComRCReturn (rc, rc);
     293    AssertComRCReturnRC (rc);
    294294
    295295    unconst (mDisplay).createObject();
    296296    rc = mDisplay->init (this);
    297     AssertComRCReturn (rc, rc);
     297    AssertComRCReturnRC (rc);
    298298
    299299    unconst (mRemoteDisplayInfo).createObject();
    300300    rc = mRemoteDisplayInfo->init (this);
    301     AssertComRCReturn (rc, rc);
     301    AssertComRCReturnRC (rc);
     302
     303    /* Grab global and machine shared folder lists */
     304
     305    rc = fetchSharedFolders (true /* aGlobal */);
     306    AssertComRCReturnRC (rc);
     307    rc = fetchSharedFolders (false /* aGlobal */);
     308    AssertComRCReturnRC (rc);
    302309
    303310    /* Create other child objects */
     
    378385        unconst (mVMMDev) = NULL;
    379386    }
     387
     388    mGlobalSharedFolders.clear();
     389    mMachineSharedFolders.clear();
    380390
    381391    mSharedFolders.clear();
     
    936946    AssertRC (vrc);
    937947
    938     for (SharedFolderList::const_iterator it = that->mSharedFolders.begin();
     948    for (SharedFolderMap::const_iterator it = that->mSharedFolders.begin();
    939949         it != that->mSharedFolders.end();
    940950         ++ it)
    941951    {
    942         ComObjPtr <SharedFolder> folder = (*it);
    943         AutoLock folderLock (folder);
     952        ComObjPtr <SharedFolder> folder = (*it).second;
     953        // don't lock the folder because methods we access are const
    944954
    945955        Utf8Str name = folder->name();
     
    10271037        HRESULT rc = sharedFolder->init (that, name, hostPath);
    10281038        AssertComRCReturn (rc, VERR_INTERNAL_ERROR);
    1029         if (FAILED (rc))
    1030             return rc;
    1031 
    1032         that->mSharedFolders.push_back (sharedFolder);
     1039
     1040        that->mSharedFolders.insert (std::make_pair (name, sharedFolder));
    10331041    }
    10341042
     
    12361244
    12371245    if (mMachineState >= MachineState_Running)
    1238         return setError(E_FAIL, tr ("Cannot power up the machine as it is already running.  (Machine state: %d)"), mMachineState);
     1246        return setError(E_FAIL, tr ("Cannot power up the machine as it is "
     1247                                    "already running (machine state: %d)"),
     1248                        mMachineState);
    12391249
    12401250    /*
     
    13721382
    13731383    /* Check all types of shared folders and compose a single list */
    1374     std::map <Bstr, ComPtr <ISharedFolder> > sharedFolders;
    1375     {
    1376         /// @todo (dmik) check and add globally shared folders when they are
    1377         //  done
    1378 
    1379         ComPtr <ISharedFolderCollection> coll;
    1380         HRESULT rc = mMachine->COMGETTER(SharedFolders) (coll.asOutParam());
    1381         CheckComRCReturnRC (rc);
    1382         ComPtr <ISharedFolderEnumerator> en;
    1383         rc = coll->Enumerate (en.asOutParam());
    1384         CheckComRCReturnRC (rc);
    1385 
    1386         BOOL hasMore = FALSE;
    1387         while (SUCCEEDED (en->HasMore (&hasMore)) && hasMore)
    1388         {
    1389             ComPtr <ISharedFolder> folder;
    1390             en->GetNext (folder.asOutParam());
    1391 
    1392             Bstr name;
    1393             rc = folder->COMGETTER(Name) (name.asOutParam());
    1394             CheckComRCReturnRC (rc);
    1395 
    1396             BOOL accessible = FALSE;
    1397             rc = folder->COMGETTER(Accessible) (&accessible);
    1398             CheckComRCReturnRC (rc);
    1399 
    1400             if (!accessible)
    1401             {
    1402                 Bstr hostPath;
    1403                 folder->COMGETTER(HostPath) (hostPath.asOutParam());
    1404                 return setError (E_FAIL,
    1405                     tr ("Host path '%ls' of the shared folder '%ls' is not accessible"),
    1406                     hostPath.raw(), name.raw());
    1407             }
    1408 
    1409             sharedFolders.insert (std::make_pair (name, folder));
    1410             /// @todo (dmik) later, do this:
    1411 //            if (!sharedFolders.insert (std::pair <name, folder>).second)
    1412 //                return setError (E_FAIL,
    1413 //                    tr ("Could not accept a permanently shared folder named '%ls' "
    1414 //                       "because a globally shared folder with the same name "
    1415 //                       "already exists"),
    1416 //                    name.raw());
    1417         }
    1418 
    1419         for (SharedFolderList::const_iterator it = mSharedFolders.begin();
     1384    SharedFolderDataMap sharedFolders;
     1385    {
     1386        /* first, insert global folders */
     1387        for (SharedFolderDataMap::const_iterator it = mGlobalSharedFolders.begin();
     1388             it != mGlobalSharedFolders.end(); ++ it)
     1389            sharedFolders [it->first] = it->second;
     1390
     1391        /* second, insert machine folders */
     1392        for (SharedFolderDataMap::const_iterator it = mMachineSharedFolders.begin();
     1393             it != mMachineSharedFolders.end(); ++ it)
     1394            sharedFolders [it->first] = it->second;
     1395
     1396        /* third, insert console folders */
     1397        for (SharedFolderMap::const_iterator it = mSharedFolders.begin();
    14201398             it != mSharedFolders.end(); ++ it)
    1421         {
    1422             ComPtr <ISharedFolder> folder = static_cast <SharedFolder *> (*it);
    1423 
    1424             if (!sharedFolders.insert (std::make_pair ((*it)->name(), folder)).second)
    1425                 return setError (E_FAIL,
    1426                     tr ("Could not create a transient shared folder named '%ls' "
    1427                        "because a global or a permanent shared folder with "
    1428                        "the same name already exists"),
    1429                     (*it)->name().raw());
    1430         }
     1399            sharedFolders [it->first] = it->second->hostPath();
    14311400    }
    14321401
     
    15091478            return setError(E_FAIL, tr ("Cannot power off a saved machine"));
    15101479        else
    1511             return setError(E_FAIL, tr ("Cannot power off the machine as it is not running or paused.  (Machine state: %d)"), mMachineState);
     1480            return setError(E_FAIL, tr ("Cannot power off the machine as it is "
     1481                                        "not running or paused (machine state: %d)"),
     1482                            mMachineState);
    15121483    }
    15131484
     
    15321503
    15331504    if (mMachineState != MachineState_Running)
    1534         return setError(E_FAIL, tr ("Cannot reset the machine as it is not running.  (Machine state: %d)"), mMachineState);
     1505        return setError(E_FAIL, tr ("Cannot reset the machine as it is "
     1506                                    "not running (machine state: %d)"),
     1507                        mMachineState);
    15351508
    15361509    /* protect mpVM */
     
    15441517
    15451518    HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK :
    1546         setError (E_FAIL, tr ("Could not reset the machine.  (Error: %Vrc)"), vrc);
     1519        setError (E_FAIL, tr ("Could not reset the machine (%Vrc)"), vrc);
    15471520
    15481521    LogFlowThisFunc (("mMachineState=%d, rc=%08X\n", mMachineState, rc));
     
    15611534
    15621535    if (mMachineState != MachineState_Running)
    1563         return setError (E_FAIL, tr ("Cannot pause the machine as it is not running.  (Machine state: %d)"), mMachineState);
     1536        return setError (E_FAIL, tr ("Cannot pause the machine as it is "
     1537                                     "not running (machine state: %d)"),
     1538                         mMachineState);
    15641539
    15651540    /* protect mpVM */
     
    15761551    HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK :
    15771552        setError (E_FAIL,
    1578             tr ("Could not suspend the machine execution.  (Error: %Vrc)"), vrc);
     1553            tr ("Could not suspend the machine execution (%Vrc)"), vrc);
    15791554
    15801555    LogFlowThisFunc (("rc=%08X\n", rc));
     
    15931568
    15941569    if (mMachineState != MachineState_Paused)
    1595         return setError (E_FAIL, tr ("Cannot resume the machine as it is not paused.  (Machine state: %d)"), mMachineState);
     1570        return setError (E_FAIL, tr ("Cannot resume the machine as it is "
     1571                                     "not paused (machine state: %d)"),
     1572                         mMachineState);
    15961573
    15971574    /* protect mpVM */
     
    16081585    HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK :
    16091586        setError (E_FAIL,
    1610             tr ("Could not resume the machine execution.  (Error: %Vrc)"), vrc);
     1587            tr ("Could not resume the machine execution (%Vrc)"), vrc);
    16111588
    16121589    LogFlowThisFunc (("rc=%08X\n", rc));
     
    16251602
    16261603    if (mMachineState != MachineState_Running)
    1627         return setError (E_FAIL, tr ("Cannot power off the machine as it is not running.  (Machine state: %d)"), mMachineState);
     1604        return setError (E_FAIL, tr ("Cannot power off the machine as it is "
     1605                                     "not running (machine state: %d)"),
     1606                         mMachineState);
    16281607
    16291608    /* protect mpVM */
     
    16431622    HRESULT rc = VBOX_SUCCESS (vrc) ? S_OK :
    16441623        setError (E_FAIL,
    1645             tr ("Controlled power off failed.  (Error: %Vrc)"), vrc);
     1624            tr ("Controlled power off failed (%Vrc)"), vrc);
    16461625
    16471626    LogFlowThisFunc (("rc=%08X\n", rc));
     
    17341713                {
    17351714                    rc = setError (E_FAIL,
    1736                         tr ("Could not create a directory '%s' to save the state to.  (Error: %Vrc)"),
     1715                        tr ("Could not create a directory '%s' to save the state to (%Vrc)"),
    17371716                        dir.raw(), vrc);
    17381717                    break;
     
    18021781    if (mMachineState != MachineState_Saved)
    18031782        return setError (E_FAIL,
    1804             tr ("Cannot discard the machine state as the machine is not in the saved state.  (Machine state: %d"), mMachineState);
     1783            tr ("Cannot discard the machine state as the machine is "
     1784                "not in the saved state (machine state: %d)"),
     1785            mMachineState);
    18051786
    18061787    /*
     
    20252006        return setError (E_FAIL,
    20262007            tr ("Cannot create a transient shared folder on a "
    2027                 "machine in the saved state."));
    2028 
    2029     /// @todo (dmik) check globally shared folders when they are done
    2030 
    2031     /* check machine's shared folders */
    2032     {
    2033         ComPtr <ISharedFolderCollection> coll;
    2034         HRESULT rc = mMachine->COMGETTER(SharedFolders) (coll.asOutParam());
    2035         if (FAILED (rc))
    2036             return rc;
    2037 
    2038         ComPtr <ISharedFolder> machineSharedFolder;
    2039         rc = coll->FindByName (aName, machineSharedFolder.asOutParam());
    2040         if (SUCCEEDED (rc))
    2041             return setError (E_FAIL,
    2042                 tr ("A permanent shared folder named '%ls' already "
    2043                     "exists."), aName);
    2044     }
     2008                "machine in the saved state"));
    20452009
    20462010    ComObjPtr <SharedFolder> sharedFolder;
     
    20482012    if (SUCCEEDED (rc))
    20492013        return setError (E_FAIL,
    2050             tr ("A shared folder named '%ls' already exists."), aName);
     2014            tr ("Shared folder named '%ls' already exists"), aName);
    20512015
    20522016    sharedFolder.createObject();
     
    20602024    if (!accessible)
    20612025        return setError (E_FAIL,
    2062             tr ("The shared folder path '%ls' on the host is not accessible."), aHostPath);
    2063 
    2064     /// @todo (r=sander?) should move this into the shared folder class */
    2065     if (mpVM && mVMMDev->isShFlActive())
    2066     {
    2067         /*
    2068          *  if the VM is online and supports shared folders, share this folder
    2069          *  under the specified name. On error, return it to the caller.
    2070          */
    2071 
    2072         /* protect mpVM */
    2073         AutoVMCaller autoVMCaller (this);
    2074         CheckComRCReturnRC (autoVMCaller.rc());
    2075 
    2076         VBOXHGCMSVCPARM  parms[2];
    2077         SHFLSTRING      *pFolderName, *pMapName;
    2078         int              cbString;
    2079 
    2080         Log (("Add shared folder %ls -> %ls\n", aName, aHostPath));
    2081 
    2082         cbString = (RTStrUcs2Len(aHostPath) + 1) * sizeof(RTUCS2);
    2083         pFolderName = (SHFLSTRING *)RTMemAllocZ(sizeof(SHFLSTRING) + cbString);
    2084         Assert(pFolderName);
    2085         memcpy(pFolderName->String.ucs2, aHostPath, cbString);
    2086 
    2087         pFolderName->u16Size   = cbString;
    2088         pFolderName->u16Length = cbString - sizeof(RTUCS2);
    2089 
    2090         parms[0].type = VBOX_HGCM_SVC_PARM_PTR;
    2091         parms[0].u.pointer.addr = pFolderName;
    2092         parms[0].u.pointer.size = sizeof(SHFLSTRING) + cbString;
    2093 
    2094         cbString = (RTStrUcs2Len(aName) + 1) * sizeof(RTUCS2);
    2095         pMapName = (SHFLSTRING *)RTMemAllocZ(sizeof(SHFLSTRING) + cbString);
    2096         Assert(pMapName);
    2097         memcpy(pMapName->String.ucs2, aName, cbString);
    2098 
    2099         pMapName->u16Size   = cbString;
    2100         pMapName->u16Length = cbString - sizeof(RTUCS2);
    2101 
    2102         parms[1].type = VBOX_HGCM_SVC_PARM_PTR;
    2103         parms[1].u.pointer.addr = pMapName;
    2104         parms[1].u.pointer.size = sizeof(SHFLSTRING) + cbString;
    2105 
    2106         int vrc = mVMMDev->hgcmHostCall ("VBoxSharedFolders",
    2107                                          SHFL_FN_ADD_MAPPING,
    2108                                          2, &parms[0]);
    2109         RTMemFree(pFolderName);
    2110         RTMemFree(pMapName);
    2111         if (vrc != VINF_SUCCESS)
    2112             return setError (E_FAIL,
    2113                 tr ("Could not create a shared folder '%ls' mapped to '%ls' (%Vrc)"),
    2114                 aName, aHostPath, vrc);
    2115     }
    2116 
    2117     mSharedFolders.push_back (sharedFolder);
    2118     return S_OK;
     2026            tr ("Shared folder host path '%ls' is not accessible"), aHostPath);
     2027
     2028    /* protect mpVM (if not NULL) */
     2029    AutoVMCallerQuietWeak autoVMCaller (this);
     2030
     2031    if (mpVM && autoVMCaller.isOk() && mVMMDev->isShFlActive())
     2032    {
     2033        /* If the VM is online and supports shared folders, share this folder
     2034         * under the specified name. */
     2035
     2036        /* first, remove the machine or the global folder if there is any */
     2037        SharedFolderDataMap::const_iterator it;
     2038        if (findOtherSharedFolder (aName, it))
     2039        {
     2040            rc = removeSharedFolder (aName);
     2041            CheckComRCReturnRC (rc);
     2042        }
     2043
     2044        /* second, create the given folder */
     2045        rc = createSharedFolder (aName, aHostPath);
     2046        CheckComRCReturnRC (rc);
     2047    }
     2048
     2049    mSharedFolders.insert (std::make_pair (aName, sharedFolder));
     2050
     2051    return rc;
    21192052}
    21202053
     
    21382071    CheckComRCReturnRC (rc);
    21392072
    2140     /* protect mpVM */
    2141     AutoVMCaller autoVMCaller (this);
    2142     CheckComRCReturnRC (autoVMCaller.rc());
    2143 
    2144     if (mpVM && mVMMDev->isShFlActive())
    2145     {
    2146         /*
    2147          *  if the VM is online and supports shared folders, UNshare this folder.
    2148          *  On error, return it to the caller.
    2149          */
    2150         VBOXHGCMSVCPARM  parms;
    2151         SHFLSTRING      *pMapName;
    2152         int              cbString;
    2153 
    2154         cbString = (RTStrUcs2Len(aName) + 1) * sizeof(RTUCS2);
    2155         pMapName = (SHFLSTRING *)RTMemAllocZ(sizeof(SHFLSTRING) + cbString);
    2156         Assert(pMapName);
    2157         memcpy(pMapName->String.ucs2, aName, cbString);
    2158 
    2159         pMapName->u16Size   = cbString;
    2160         pMapName->u16Length = cbString - sizeof(RTUCS2);
    2161 
    2162         parms.type = VBOX_HGCM_SVC_PARM_PTR;
    2163         parms.u.pointer.addr = pMapName;
    2164         parms.u.pointer.size = sizeof(SHFLSTRING) + cbString;
    2165 
    2166         int vrc = mVMMDev->hgcmHostCall ("VBoxSharedFolders",
    2167                                          SHFL_FN_REMOVE_MAPPING,
    2168                                          1, &parms);
    2169         RTMemFree(pMapName);
    2170         if (vrc != VINF_SUCCESS)
    2171             rc = setError (E_FAIL,
    2172                 tr ("Could not remove the shared folder '%ls' (%Vrc)"),
    2173                 aName, vrc);
    2174     }
    2175 
    2176     mSharedFolders.remove (sharedFolder);
     2073    /* protect mpVM (if not NULL) */
     2074    AutoVMCallerQuietWeak autoVMCaller (this);
     2075
     2076    if (mpVM && autoVMCaller.isOk() && mVMMDev->isShFlActive())
     2077    {
     2078        /* if the VM is online and supports shared folders, UNshare this
     2079         * folder. */
     2080
     2081        /* first, remove the given folder */
     2082        rc = removeSharedFolder (aName);
     2083        CheckComRCReturnRC (rc);
     2084
     2085        /* first, remove the machine or the global folder if there is any */
     2086        SharedFolderDataMap::const_iterator it;
     2087        if (findOtherSharedFolder (aName, it))
     2088        {
     2089            rc = createSharedFolder (aName, it->second);
     2090            /* don't check rc here because we need to remove the console
     2091             * folder from the collection even on failure */
     2092        }
     2093    }
     2094
     2095    mSharedFolders.erase (aName);
     2096
    21772097    return rc;
    21782098}
     
    32503170
    32513171/**
     3172 *  Called by IInternalSessionControl::OnSharedFolderChange().
     3173 *
     3174 *  @note Locks this object for writing.
     3175 */
     3176HRESULT Console::onSharedFolderChange (BOOL aGlobal)
     3177{
     3178    LogFlowThisFunc (("aGlobal=%RTbool\n", aGlobal));
     3179
     3180    AutoCaller autoCaller (this);
     3181    AssertComRCReturnRC (autoCaller.rc());
     3182
     3183    AutoLock alock (this);
     3184
     3185    return fetchSharedFolders (aGlobal);
     3186}
     3187
     3188/**
    32523189 *  Called by IInternalSessionControl::OnUSBDeviceAttach() or locally by
    32533190 *  processRemoteUSBDevices() after IInternalMachineControl::RunUSBDeviceFilters()
     
    40664003    AssertReturn (isLockedOnCurrentThread(), E_FAIL);
    40674004
    4068     bool found = false;
    4069     for (SharedFolderList::const_iterator it = mSharedFolders.begin();
    4070         !found && it != mSharedFolders.end();
    4071         ++ it)
    4072     {
    4073         AutoLock alock (*it);
    4074         found = (*it)->name() == aName;
    4075         if (found)
    4076             aSharedFolder = *it;
    4077     }
    4078 
    4079     HRESULT rc = found ? S_OK : E_INVALIDARG;
    4080 
    4081     if (aSetError && !found)
    4082         setError (rc, tr ("Could not find a shared folder named '%ls'."), aName);
     4005    SharedFolderMap::const_iterator it = mSharedFolders.find (aName);
     4006    if (it != mSharedFolders.end())
     4007    {
     4008        aSharedFolder = it->second;
     4009        return S_OK;
     4010    }
     4011
     4012    if (aSetError)
     4013        setError (E_INVALIDARG,
     4014                  tr ("Could not find a shared folder named '%ls'."), aName);
     4015
     4016    return E_INVALIDARG;
     4017}
     4018
     4019/**
     4020 *  Fetches the list of global or machine shared folders from the server.
     4021 *
     4022 *  @param aGlobal true to fetch global folders.
     4023 *
     4024 *  @note The caller must lock this object for writing.
     4025 */
     4026HRESULT Console::fetchSharedFolders (BOOL aGlobal)
     4027{
     4028    /* sanity check */
     4029    AssertReturn (AutoCaller (this).state() == InInit ||
     4030                  isLockedOnCurrentThread(), E_FAIL);
     4031
     4032    /* protect mpVM (if not NULL) */
     4033    AutoVMCallerQuietWeak autoVMCaller (this);
     4034
     4035    HRESULT rc = S_OK;
     4036
     4037    bool online = mpVM && autoVMCaller.isOk() && mVMMDev->isShFlActive();
     4038
     4039    if (aGlobal)
     4040    {
     4041        /// @todo grab & process global folders when they are done
     4042    }
     4043    else
     4044    {
     4045        SharedFolderDataMap oldFolders;
     4046        if (online)
     4047            oldFolders = mMachineSharedFolders;
     4048       
     4049        mMachineSharedFolders.clear();
     4050
     4051        ComPtr <ISharedFolderCollection> coll;
     4052        rc = mMachine->COMGETTER(SharedFolders) (coll.asOutParam());
     4053        AssertComRCReturnRC (rc);
     4054
     4055        ComPtr <ISharedFolderEnumerator> en;
     4056        rc = coll->Enumerate (en.asOutParam());
     4057        AssertComRCReturnRC (rc);
     4058
     4059        BOOL hasMore = FALSE;
     4060        while (SUCCEEDED (rc = en->HasMore (&hasMore)) && hasMore)
     4061        {
     4062            ComPtr <ISharedFolder> folder;
     4063            rc = en->GetNext (folder.asOutParam());
     4064            CheckComRCBreakRC (rc);
     4065
     4066            Bstr name;
     4067            Bstr hostPath;
     4068
     4069            rc = folder->COMGETTER(Name) (name.asOutParam());
     4070            CheckComRCBreakRC (rc);
     4071            rc = folder->COMGETTER(HostPath) (hostPath.asOutParam());
     4072            CheckComRCBreakRC (rc);
     4073
     4074            mMachineSharedFolders.insert (std::make_pair (name, hostPath));
     4075
     4076            /* send changes to HGCM if the VM is running */
     4077            /// @todo report errors as runtime warnings through VMSetError
     4078            if (online)
     4079            {
     4080                SharedFolderDataMap::iterator it = oldFolders.find (name);
     4081                if (it == oldFolders.end() || it->second != hostPath)
     4082                {
     4083                    /* a new machine folder is added or
     4084                    /* the existing machine folder is changed */
     4085                    if (mSharedFolders.find (name) != mSharedFolders.end())
     4086                        ; /* the console folder exists, nothing to do */
     4087                    else
     4088                    {
     4089                        /* remove the old machhine folder (when changed)
     4090                         * or the global folder if any (when new) */
     4091                        if (it != oldFolders.end() ||
     4092                            mGlobalSharedFolders.find (name) !=
     4093                                mGlobalSharedFolders.end())
     4094                            rc = removeSharedFolder (name);
     4095                        /* create the new machine folder */
     4096                        rc = createSharedFolder (name, hostPath);
     4097                    }
     4098                }
     4099                /* forget the processed (or identical) folder */
     4100                if (it != oldFolders.end())
     4101                    oldFolders.erase (it);
     4102
     4103                rc = S_OK;
     4104            }
     4105        }
     4106
     4107        AssertComRCReturnRC (rc);
     4108
     4109        /* process outdated (removed) folders */
     4110        /// @todo report errors as runtime warnings through VMSetError
     4111        if (online)
     4112        {
     4113            for (SharedFolderDataMap::const_iterator it = oldFolders.begin();
     4114                 it != oldFolders.end(); ++ it)
     4115            {
     4116                if (mSharedFolders.find (it->first) != mSharedFolders.end())
     4117                    ; /* the console folder exists, nothing to do */
     4118                else
     4119                {
     4120                    /* remove the outdated machine folder */
     4121                    rc = removeSharedFolder (it->first);
     4122                    /* create the global folder if there is any */
     4123                    SharedFolderDataMap::const_iterator it =
     4124                        mGlobalSharedFolders.find (it->first);
     4125                    if (it != mGlobalSharedFolders.end())
     4126                        rc = createSharedFolder (it->first, it->second);
     4127                }
     4128            }
     4129
     4130            rc = S_OK;
     4131        }
     4132    }
    40834133
    40844134    return rc;
     4135}
     4136
     4137/**
     4138 *  Searches for a shared folder with the given name in the list of machine
     4139 *  shared folders and then in the list of the global shared folders.
     4140 *
     4141 *  @param aName    Name of the folder to search for.
     4142 *  @param aIt      Where to store the pointer to the found folder.
     4143 *  @return         @c true if the folder was found and @c false otherwise.
     4144 *
     4145 *  @note The caller must lock this object for reading.
     4146 */
     4147bool Console::findOtherSharedFolder (INPTR BSTR aName,
     4148                                     SharedFolderDataMap::const_iterator &aIt)
     4149{
     4150    /* sanity check */
     4151    AssertReturn (isLockedOnCurrentThread(), false);
     4152
     4153    /* first, search machine folders */
     4154    aIt = mMachineSharedFolders.find (aName);
     4155    if (aIt != mMachineSharedFolders.end())
     4156        return true;
     4157
     4158    /* second, search machine folders */
     4159    aIt = mGlobalSharedFolders.find (aName);
     4160    if (aIt != mGlobalSharedFolders.end())
     4161        return true;
     4162
     4163    return false;
     4164}
     4165
     4166/**
     4167 *  Calls the HGCM service to add a shared folder definition.
     4168 *
     4169 *  @param aName        Shared folder name.
     4170 *  @param aHostPath    Shared folder path.
     4171 *
     4172 *  @note Must be called from under AutoVMCaller and when mpVM != NULL!
     4173 *  @note Doesn't lock anything.
     4174 */
     4175HRESULT Console::createSharedFolder (INPTR BSTR aName, INPTR BSTR aHostPath)
     4176{
     4177    ComAssertRet (aName && *aName, E_FAIL);
     4178    ComAssertRet (aHostPath && *aHostPath, E_FAIL);
     4179
     4180    /* sanity checks */
     4181    AssertReturn (mpVM, E_FAIL);
     4182    AssertReturn (mVMMDev->isShFlActive(), E_FAIL);
     4183
     4184    VBOXHGCMSVCPARM  parms[2];
     4185    SHFLSTRING      *pFolderName, *pMapName;
     4186    int              cbString;
     4187
     4188    Log (("Adding shared folder '%ls' -> '%ls'\n", aName, aHostPath));
     4189
     4190    cbString = (RTStrUcs2Len (aHostPath) + 1) * sizeof (RTUCS2);
     4191    pFolderName = (SHFLSTRING *) RTMemAllocZ (sizeof (SHFLSTRING) + cbString);
     4192    Assert (pFolderName);
     4193    memcpy (pFolderName->String.ucs2, aHostPath, cbString);
     4194
     4195    pFolderName->u16Size   = cbString;
     4196    pFolderName->u16Length = cbString - sizeof(RTUCS2);
     4197
     4198    parms[0].type = VBOX_HGCM_SVC_PARM_PTR;
     4199    parms[0].u.pointer.addr = pFolderName;
     4200    parms[0].u.pointer.size = sizeof (SHFLSTRING) + cbString;
     4201
     4202    cbString = (RTStrUcs2Len (aName) + 1) * sizeof (RTUCS2);
     4203    pMapName = (SHFLSTRING *) RTMemAllocZ (sizeof(SHFLSTRING) + cbString);
     4204    Assert (pMapName);
     4205    memcpy (pMapName->String.ucs2, aName, cbString);
     4206
     4207    pMapName->u16Size   = cbString;
     4208    pMapName->u16Length = cbString - sizeof (RTUCS2);
     4209
     4210    parms[1].type = VBOX_HGCM_SVC_PARM_PTR;
     4211    parms[1].u.pointer.addr = pMapName;
     4212    parms[1].u.pointer.size = sizeof (SHFLSTRING) + cbString;
     4213
     4214    int vrc = mVMMDev->hgcmHostCall ("VBoxSharedFolders",
     4215                                     SHFL_FN_ADD_MAPPING,
     4216                                     2, &parms[0]);
     4217    RTMemFree (pFolderName);
     4218    RTMemFree (pMapName);
     4219
     4220    if (VBOX_FAILURE (vrc))
     4221        return setError (E_FAIL,
     4222                         tr ("Could not create a shared folder '%ls' "
     4223                             "mapped to '%ls' (%Vrc)"),
     4224                         aName, aHostPath, vrc);
     4225
     4226    return S_OK;
     4227}
     4228
     4229/**
     4230 *  Calls the HGCM service to remove the shared folder definition.
     4231 *
     4232 *  @param aName        Shared folder name.
     4233 *
     4234 *  @note Must be called from under AutoVMCaller and when mpVM != NULL!
     4235 *  @note Doesn't lock anything.
     4236 */
     4237HRESULT Console::removeSharedFolder (INPTR BSTR aName)
     4238{
     4239    ComAssertRet (aName && *aName, E_FAIL);
     4240
     4241    /* sanity checks */
     4242    AssertReturn (mpVM, E_FAIL);
     4243    AssertReturn (mVMMDev->isShFlActive(), E_FAIL);
     4244
     4245    VBOXHGCMSVCPARM  parms;
     4246    SHFLSTRING      *pMapName;
     4247    int              cbString;
     4248
     4249    Log (("Removing shared folder '%ls'\n", aName));
     4250
     4251    cbString = (RTStrUcs2Len (aName) + 1) * sizeof (RTUCS2);
     4252    pMapName = (SHFLSTRING *) RTMemAllocZ (sizeof (SHFLSTRING) + cbString);
     4253    Assert (pMapName);
     4254    memcpy (pMapName->String.ucs2, aName, cbString);
     4255
     4256    pMapName->u16Size   = cbString;
     4257    pMapName->u16Length = cbString - sizeof (RTUCS2);
     4258
     4259    parms.type = VBOX_HGCM_SVC_PARM_PTR;
     4260    parms.u.pointer.addr = pMapName;
     4261    parms.u.pointer.size = sizeof (SHFLSTRING) + cbString;
     4262
     4263    int vrc = mVMMDev->hgcmHostCall ("VBoxSharedFolders",
     4264                                     SHFL_FN_REMOVE_MAPPING,
     4265                                     1, &parms);
     4266    RTMemFree(pMapName);
     4267    if (VBOX_FAILURE (vrc))
     4268        return setError (E_FAIL,
     4269                         tr ("Could not remove the shared folder '%ls' (%Vrc)"),
     4270                         aName, vrc);
     4271
     4272    return S_OK;
    40854273}
    40864274
     
    69107098                }
    69117099
     7100                /*
     7101                 * Shared Folders
     7102                 */
    69127103                if (console->getVMMDev()->isShFlActive())
    69137104                {
     
    69177108                    alock.leave();
    69187109
    6919                     /*
    6920                      * Shared Folders
    6921                      */
    6922                     for (std::map <Bstr, ComPtr <ISharedFolder> >::const_iterator
    6923                          it = task->mSharedFolders.begin();
     7110                    for (SharedFolderDataMap::const_iterator
     7111                             it = task->mSharedFolders.begin();
    69247112                         it != task->mSharedFolders.end();
    69257113                         ++ it)
    69267114                    {
    6927                         Bstr name = (*it).first;
    6928                         ComPtr <ISharedFolder> folder = (*it).second;
    6929 
    6930                         Bstr hostPath;
    6931                         hrc = folder->COMGETTER(HostPath) (hostPath.asOutParam());
     7115                        hrc = console->createSharedFolder ((*it).first, (*it).second);
    69327116                        CheckComRCBreakRC (hrc);
    6933 
    6934                         LogFlowFunc (("Adding shared folder '%ls' -> '%ls'\n",
    6935                                       name.raw(), hostPath.raw()));
    6936                         ComAssertBreak (!name.isEmpty() && !hostPath.isEmpty(),
    6937                                         hrc = E_FAIL);
    6938 
    6939                         /** @todo should move this into the shared folder class */
    6940                         VBOXHGCMSVCPARM  parms[2];
    6941                         SHFLSTRING      *pFolderName, *pMapName;
    6942                         int              cbString;
    6943 
    6944                         cbString = (hostPath.length() + 1) * sizeof(RTUCS2);
    6945                         pFolderName = (SHFLSTRING *)RTMemAllocZ(sizeof(SHFLSTRING) + cbString);
    6946                         Assert(pFolderName);
    6947                         memcpy(pFolderName->String.ucs2, hostPath.raw(), cbString);
    6948 
    6949                         pFolderName->u16Size   = cbString;
    6950                         pFolderName->u16Length = cbString - sizeof(RTUCS2);
    6951 
    6952                         parms[0].type = VBOX_HGCM_SVC_PARM_PTR;
    6953                         parms[0].u.pointer.addr = pFolderName;
    6954                         parms[0].u.pointer.size = sizeof(SHFLSTRING) + cbString;
    6955 
    6956                         cbString = (name.length() + 1) * sizeof(RTUCS2);
    6957                         pMapName = (SHFLSTRING *)RTMemAllocZ(sizeof(SHFLSTRING) + cbString);
    6958                         Assert(pMapName);
    6959                         memcpy(pMapName->String.ucs2, name.raw(), cbString);
    6960 
    6961                         pMapName->u16Size   = cbString;
    6962                         pMapName->u16Length = cbString - sizeof(RTUCS2);
    6963 
    6964                         parms[1].type = VBOX_HGCM_SVC_PARM_PTR;
    6965                         parms[1].u.pointer.addr = pMapName;
    6966                         parms[1].u.pointer.size = sizeof(SHFLSTRING) + cbString;
    6967 
    6968                         vrc = console->getVMMDev()->hgcmHostCall("VBoxSharedFolders",
    6969                             SHFL_FN_ADD_MAPPING, 2, &parms[0]);
    6970 
    6971                         RTMemFree(pFolderName);
    6972                         RTMemFree(pMapName);
    6973 
    6974                         if (VBOX_FAILURE (vrc))
    6975                         {
    6976                             hrc = setError (E_FAIL,
    6977                                 tr ("Could not create a shared folder '%ls' mapped to '%ls' (%Vrc)"),
    6978                                 name.raw(), hostPath.raw(), vrc);
    6979                             break;
    6980                         }
    69817117                    }
    69827118
  • trunk/src/VBox/Main/MachineImpl.cpp

    r3861 r4041  
    23392339    CheckComRCReturnRC (rc);
    23402340
    2341     /// @todo (dmik) check global shared folders when they are done
    2342 
    23432341    ComObjPtr <SharedFolder> sharedFolder;
    23442342    rc = findSharedFolder (aName, sharedFolder, false /* aSetError */);
     
    23572355    if (!accessible)
    23582356        return setError (E_FAIL,
    2359             tr ("Shared folder path '%ls' is not accessible"), aHostPath);
     2357            tr ("Shared folder host path '%ls' is not accessible"), aHostPath);
    23602358
    23612359    mHWData.backup();
    23622360    mHWData->mSharedFolders.push_back (sharedFolder);
     2361
     2362    /* inform the direct session if any */
     2363    alock.leave();
     2364    onSharedFolderChange();
    23632365
    23642366    return S_OK;
     
    23842386    mHWData.backup();
    23852387    mHWData->mSharedFolders.remove (sharedFolder);
     2388
     2389    /* inform the direct session if any */
     2390    alock.leave();
     2391    onSharedFolderChange();
    23862392
    23872393    return S_OK;
     
    72787284    AutoLock alock (this);
    72797285
     7286    /* check for changes in own data */
     7287
     7288    bool sharedFoldersChanged = false;
     7289
     7290    if (aNotify && mHWData.isBackedUp())
     7291    {
     7292        if (mHWData->mSharedFolders.size() !=
     7293            mHWData.backedUpData()->mSharedFolders.size())
     7294            sharedFoldersChanged = true;
     7295        else
     7296        {
     7297            for (HWData::SharedFolderList::iterator rit =
     7298                     mHWData->mSharedFolders.begin();
     7299                 rit != mHWData->mSharedFolders.end() && !sharedFoldersChanged;
     7300                 ++ rit)
     7301            {
     7302                for (HWData::SharedFolderList::iterator cit =
     7303                         mHWData.backedUpData()->mSharedFolders.begin();
     7304                     cit != mHWData.backedUpData()->mSharedFolders.end();
     7305                     ++ cit)
     7306                {
     7307                    if ((*cit)->name() != (*rit)->name() ||
     7308                        (*cit)->hostPath() != (*rit)->hostPath())
     7309                    {
     7310                        sharedFoldersChanged = true;
     7311                        break;
     7312                    }
     7313                }
     7314            }
     7315        }
     7316    }
     7317
    72807318    mUserData.rollback();
    72817319
     
    72857323        fixupHardDisks (false /* aCommit */);
    72867324
     7325    /* check for changes in child objects */
     7326
    72877327    bool vrdpChanged = false, dvdChanged = false, floppyChanged = false,
    72887328         usbChanged = false;
     7329
    72897330    ComPtr <INetworkAdapter> networkAdapters [ELEMENTS (mNetworkAdapters)];
    72907331    ComPtr <ISerialPort> serialPorts [ELEMENTS (mSerialPorts)];
     
    73287369    if (aNotify)
    73297370    {
    7330         // inform the direct session about changes
     7371        /* inform the direct session about changes */
    73317372
    73327373        ComObjPtr <Machine> that = this;
    73337374        alock.leave();
     7375
     7376        if (sharedFoldersChanged)
     7377            that->onSharedFolderChange();
    73347378
    73357379        if (vrdpChanged)
     
    73417385        if (usbChanged)
    73427386            that->onUSBControllerChange();
     7387
    73437388        for (ULONG slot = 0; slot < ELEMENTS (networkAdapters); slot ++)
    73447389            if (networkAdapters [slot])
     
    88928937 *  @note Locks this object for reading.
    88938938 */
     8939HRESULT SessionMachine::onSharedFolderChange()
     8940{
     8941    LogFlowThisFunc (("\n"));
     8942
     8943    AutoCaller autoCaller (this);
     8944    AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
     8945
     8946    ComPtr <IInternalSessionControl> directControl;
     8947    {
     8948        AutoReaderLock alock (this);
     8949        directControl = mData->mSession.mDirectControl;
     8950    }
     8951
     8952    /* ignore notifications sent after #OnSessionEnd() is called */
     8953    if (!directControl)
     8954        return S_OK;
     8955
     8956    return directControl->OnSharedFolderChange (FALSE /* aGlobal */);
     8957}
     8958
     8959/**
     8960 *  @note Locks this object for reading.
     8961 */
    88948962HRESULT SessionMachine::onUSBDeviceAttach (IUSBDevice *aDevice,
    88958963                                           IVirtualBoxErrorInfo *aError)
  • trunk/src/VBox/Main/SessionImpl.cpp

    r3668 r4041  
    593593
    594594    return mConsole->onUSBControllerChange();
     595}
     596
     597STDMETHODIMP Session::OnSharedFolderChange (BOOL aGlobal)
     598{
     599    LogFlowThisFunc (("\n"));
     600
     601    AutoCaller autoCaller (this);
     602    AssertComRCReturn (autoCaller.rc(), autoCaller.rc());
     603
     604    AutoReaderLock alock (this);
     605    AssertReturn (mState == SessionState_SessionOpen &&
     606                  mType == SessionType_DirectSession, E_FAIL);
     607
     608    return mConsole->onSharedFolderChange (aGlobal);
    595609}
    596610
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r4019 r4041  
    735735    <attribute name="sharedFolders" type="ISharedFolderCollection" readonly="yes">
    736736      <desc>
    737         Collection of globally shared folders. These folders
    738         are shared automatically upon VirtualBox server startup and
    739         available only to every virtual machine.
    740 
    741         New folders to share are added to the collection using
    742         <link to="#createSharedFolder"/>. An existing shared folder can
    743         be removed using <link to="#removeSharedFolder"/>.
     737        Collection of global shared folders. Global shared folders are
     738        available to all virtual machines.
     739
     740        New shared folders are added to the collection using
     741        <link to="#createSharedFolder"/>. Existing shared folders can be
     742        removed using <link to="#removeSharedFolder"/>.
    744743      </desc>
    745744    </attribute>
     
    13831382    <method name="createSharedFolder">
    13841383      <desc>
    1385         Creates a new shared folder by associating the given logical
    1386         name with the given host path, adds it to the collection of
    1387         shared folders and starts sharing it.
    1388         Refer to the description of <link to="ISharedFolder"/> to read
    1389         about logical name unicity.
     1384        Creates a new shared folder by associating the given logical name with
     1385        the given host path, adds it to the collection of shared folders and
     1386        starts sharing it. Refer to the description of
     1387        <link to="ISharedFolder"/> to read more about logical names.
    13901388      </desc>
    13911389      <param name="name" type="wstring" dir="in">
     
    22842282    <attribute name="sharedFolders" type="ISharedFolderCollection" readonly="yes">
    22852283      <desc>
    2286         Collection of shared folders for this machine. These folders
    2287         are shared automatically upon machine startup and available only
    2288         to the guest OS installed within this machine.
    2289 
    2290         New folders to share are added to the collection using
    2291         <link to="#createSharedFolder"/>. An existing shared folder can
    2292         be removed using <link to="#removeSharedFolder"/>.
     2284        Collection of shared folders for this machine (permanent shared
     2285        folders). These folders are shared automatically at machine startup
     2286        and available only to the guest OS installed within this machine.
     2287
     2288        New shared folders are added to the collection using
     2289        <link to="#createSharedFolder"/>. Existing shared folders can be
     2290        removed using <link to="#removeSharedFolder"/>.
    22932291      </desc>
    22942292    </attribute>
     
    26022600    <method name="createSharedFolder">
    26032601      <desc>
    2604         Creates a new shared folder by associating the given logical
    2605         name with the given host path, adds it to the collection of
    2606         shared folders and starts sharing it.
    2607         Refer to the description of <link to="ISharedFolder"/> to read
    2608         about logical name unicity.
     2602        Creates a new shared folder by associating the given logical name with
     2603        the given host path, adds it to the collection of shared folders and
     2604        starts sharing it. Refer to the description of
     2605        <link to="ISharedFolder"/> to read more about logical names.
    26092606      </desc>
    26102607      <param name="name" type="wstring" dir="in">
     
    31523149    <attribute name="sharedFolders" type="ISharedFolderCollection" readonly="yes">
    31533150      <desc>
    3154         Collection of shared folders for the current session.
    3155         This collection is initially empty and is cleared once the
    3156         session is closed. On other words, this collection represents
    3157         transient shares (as opposed to <link to="IMachine::sharedFolders"/>
    3158         that stores permanent shares stored in the settings file).
    3159 
    3160         New folders to share are added to the collection using
    3161         <link to="#createSharedFolder"/>. An existing shared folder can
    3162         be removed using <link to="#removeSharedFolder"/>.
     3151        Collection of shared folders for the current session.  These folders
     3152        are called transient shared folders because they are available to the
     3153        guest OS running inside the associated virtual machine only for the
     3154        duration of the session (as opposed to
     3155        <link to="IMachine::sharedFolders"/> which represent permanent shared
     3156        folders). When the session is closed (e.g. the machine is powered down),
     3157        these folders are automatically discarded.
     3158
     3159        New shared folders are added to the collection using
     3160        <link to="#createSharedFolder"/>. Existing shared folders can be
     3161        removed using <link to="#removeSharedFolder"/>.
    31633162      </desc>
    31643163    </attribute>
     
    33183317    <method name="createSharedFolder">
    33193318      <desc>
    3320         Creates a new shared folder by associating the given logical
    3321         name with the given host path, adds it to the collection of
    3322         shared folders and starts sharing it.
    3323         Refer to the description of <link to="ISharedFolder"/> to read
    3324         about logical name unicity.
     3319        Creates a new shared folder by associating the given logical name with
     3320        the given host path, adds it to the collection of shared folders and
     3321        starts sharing it. Refer to the description of
     3322        <link to="ISharedFolder"/> to read more about logical names.
    33253323      </desc>
    33263324      <param name="name" type="wstring" dir="in">
     
    77687766    <method name="findByName">
    77697767      <desc>
    7770         Searches this collection for a shared folder drive with the
    7771         given logical name.
    7772         <note>
    7773           The method returns an error if the given name does not
    7774           correspond to any shared folder in the collection.
     7768        Searches this collection for a shared folder with the given logical
     7769        name.
     7770        <note>
     7771          The method returns an error if the given name does not correspond to
     7772          any shared folder in the collection.
    77757773        </note>
    77767774      </desc>
     
    77917789     >
    77927790    <desc>
    7793       The ISharedFolder interface represents a folder in the host
    7794       computer's file system accessible from a guest OS running inside a
    7795       virtual machine using an associated logical name.
     7791      The ISharedFolder interface represents a folder in the host computer's
     7792      file system accessible from the guest OS running inside a virtual
     7793      machine using an associated logical name.
    77967794
    77977795      There are three types of shared folders:
    77987796      <ul>
    7799         <li>permanent (<link to="IMachine::sharedFolders"/>)</li>
    7800         <li>transient (<link to="IConsole::sharedFolders"/>)</li>
    7801         <li>global (<link to="IVirtualBox::sharedFolders"/>)</li>
     7797        <li><i>Global</i> (<link to="IVirtualBox::sharedFolders"/>), shared
     7798        folders available to all virtual machines.</li>
     7799        <li><i>Permanent</i> (<link to="IMachine::sharedFolders"/>),
     7800        VM-specific shared folders available to the given virtual machine at
     7801        startup.</li>
     7802        <li><i>Transient</i> (<link to="IConsole::sharedFolders"/>),
     7803        VM-specific shared folders created in the session context (for
     7804        example, when the virtual machine is running) and automatically
     7805        discarded when the session is closed (the VM is powered off).</li>
    78027806      </ul>
    78037807
    7804       For a given virtual machine, both permanently and transiently
    7805       shared folders have the same logical name space which also includes
    7806       all globally shared folders. Thus, every folder in this name space
    7807       must have an unique logical name. Note that permanent and transient
    7808       shares of other machines are in different name spaces, so they don't
    7809       have to have unique names.
     7808      Logical names of shared folders must be unique within the given scope
     7809      (global, permanent or transient). However, they do not need to be unique
     7810      across scopes. In this case, the definitioin of the shared folder in a
     7811      more specific scope takes precedence over definitions in all other
     7812      scopes. The order of precedence is (more specific to more general):
     7813      <ol>
     7814        <li>Transient definitions</li>
     7815        <li>Permanent definitions</li>
     7816        <li>Global definitions</li>
     7817      </ol>
     7818     
     7819      For example, if MyMachine has a shared folder named
     7820      <tt>C_DRIVE</tt> (that points to <tt>C:\\</tt>), then cretaing a
     7821      transient shared folder named <tt>C_DRIVE</tt> (that points
     7822      to <tt>C:\\\\WINDOWS</tt>) will change the definition
     7823      of <tt>C_DRIVE</tt> in the guest OS so
     7824      that <tt>\\\\VBOXSVR\\C_DRIVE</tt> will give access
     7825      to <tt>C:\\WINDOWS</tt> instead of <tt>C:\\</tt> on the host
     7826      PC. Removing the transient shared folder <tt>C_DRIVE</tt> will restore
     7827      the prevoious (permanent) definition of <tt>C_DRIVE</tt> that points
     7828      to <tt>C:\\</tt> if it still exists.
     7829     
     7830      Note that permanent and transient shared folders of different machines
     7831      are in different name spaces, so they don't overlap and don't need to
     7832      have unique logical names.
     7833
     7834      <note>
     7835        Global shared folders are not implemented in the current vesion of the
     7836        product.
     7837      </note>
    78107838    </desc>
    78117839
     
    78377865  <interface
    78387866     name="IInternalSessionControl" extends="$unknown"
    7839      uuid="80a9b698-cc60-48cf-ab88-a7c2ea4013a6"
     7867     uuid="e25a28b0-a58a-4582-b7c8-40abaa1f5d5b"
    78407868     internal="yes"
    78417869     wsmap="suppress"
     
    79377965        associated virtual machine have changed.
    79387966      </desc>
     7967    </method>
     7968
     7969    <method name="onSharedFolderChange">
     7970      <desc>
     7971        Triggered when a permanent (global or machine) shared folder has been
     7972        created or removed.
     7973        <note>
     7974          We don't pass shared folder parameters in this notification because
     7975          the order in which parallel notifications are delivered is not defined,
     7976          therefore it could happen that these parameters were outdated by the
     7977          time of processing this notification.
     7978        </note>
     7979      </desc>
     7980      <param name="global" type="boolean" dir="in"/>
    79397981    </method>
    79407982
  • trunk/src/VBox/Main/include/ConsoleImpl.h

    r4034 r4041  
    176176    HRESULT onVRDPServerChange();
    177177    HRESULT onUSBControllerChange();
     178    HRESULT onSharedFolderChange (BOOL aGlobal);
    178179    HRESULT onUSBDeviceAttach (IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError);
    179180    HRESULT onUSBDeviceDetach (INPTR GUIDPARAM aId, IVirtualBoxErrorInfo *aError);
     
    288289
    289290    /**
     291     *  Same as AutoVMCaller but allows a null VM pointer (to trigger an error
     292     *  instead of assertion).
     293     */
     294    typedef AutoVMCallerBase <false, true> AutoVMCallerWeak;
     295
     296    /**
     297     *  Same as AutoVMCaller but doesn't set extended error info on failure
     298     *  and allows a null VM pointer (to trigger an error instead of
     299     *  assertion).
     300     */
     301    typedef AutoVMCallerBase <true, true> AutoVMCallerQuietWeak;
     302
     303    /**
    290304     *  Base template for SaveVMPtr and SaveVMPtrQuiet.
    291305     */
     
    344358    typedef SafeVMPtrBase <true> SafeVMPtrQuiet;
    345359
     360    typedef std::map <Bstr, ComObjPtr <SharedFolder> > SharedFolderMap;
     361    typedef std::map <Bstr, Bstr> SharedFolderDataMap;
     362
    346363private:
    347364
    348365    typedef std::list <ComObjPtr <OUSBDevice> > USBDeviceList;
    349366    typedef std::list <ComObjPtr <RemoteUSBDevice> > RemoteUSBDeviceList;
    350     typedef std::list <ComObjPtr <SharedFolder> > SharedFolderList;
    351367
    352368    HRESULT addVMCaller (bool aQuiet = false, bool aAllowNullVM = false);
     
    370386                              ComObjPtr <SharedFolder> &aSharedFolder,
    371387                              bool aSetError = false);
     388
     389    HRESULT fetchSharedFolders (BOOL aGlobal);
     390    bool findOtherSharedFolder (INPTR BSTR aName,
     391                                SharedFolderDataMap::const_iterator &aIt);
     392
     393    HRESULT createSharedFolder (INPTR BSTR aName, INPTR BSTR aHostPath);
     394    HRESULT removeSharedFolder (INPTR BSTR aName);
    372395
    373396    static DECLCALLBACK(int) configConstructor(PVM pVM, void *pvConsole);
     
    470493    USBDeviceList mUSBDevices;
    471494    RemoteUSBDeviceList mRemoteUSBDevices;
    472     SharedFolderList mSharedFolders;
     495
     496    SharedFolderMap mSharedFolders;
     497    SharedFolderDataMap mMachineSharedFolders;
     498    SharedFolderDataMap mGlobalSharedFolders;
    473499
    474500    /** The VM instance handle. */
  • trunk/src/VBox/Main/include/MachineImpl.h

    r3668 r4041  
    534534    virtual HRESULT onVRDPServerChange() { return S_OK; }
    535535    virtual HRESULT onUSBControllerChange() { return S_OK; }
     536    virtual HRESULT onSharedFolderChange() { return S_OK; }
    536537
    537538    int calculateFullPath (const char *aPath, Utf8Str &aResult);
     
    783784    HRESULT onUSBDeviceDetach (INPTR GUIDPARAM aId,
    784785                               IVirtualBoxErrorInfo *aError);
     786    HRESULT onSharedFolderChange();
    785787
    786788private:
  • trunk/src/VBox/Main/include/SessionImpl.h

    r3668 r4041  
    102102    STDMETHOD(OnVRDPServerChange)();
    103103    STDMETHOD(OnUSBControllerChange)();
     104    STDMETHOD(OnSharedFolderChange) (BOOL aGlobal);
    104105    STDMETHOD(OnUSBDeviceAttach) (IUSBDevice *aDevice, IVirtualBoxErrorInfo *aError);
    105106    STDMETHOD(OnUSBDeviceDetach) (INPTR GUIDPARAM aId, IVirtualBoxErrorInfo *aError);
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