VirtualBox

Ignore:
Timestamp:
Apr 26, 2010 7:37:29 AM (15 years ago)
Author:
vboxsync
Message:

Main/Console: clean up CFGM handling for medium attachments, make one implementation out of 2.5 previous ones

File:
1 edited

Legend:

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

    r28698 r28727  
    17941794    CFGMR3Dump(pInst);
    17951795
     1796#undef RC_CHECK
     1797
    17961798    return VINF_SUCCESS;
    17971799}
     
    30433045    HRESULT rc = S_OK;
    30443046    const char *pszDevice = NULL;
    3045     unsigned uInstance = 0;
    3046     unsigned uLun = 0;
    3047     BOOL fHostDrive = FALSE;
    3048     Utf8Str location;
    3049     Utf8Str format;
    3050     BOOL fPassthrough = FALSE;
    30513047
    30523048    SafeIfaceArray<IStorageController> ctrls;
    30533049    rc = mMachine->COMGETTER(StorageControllers)(ComSafeArrayAsOutParam(ctrls));
    30543050    AssertComRC(rc);
     3051    IMedium *pMedium;
     3052    rc = aMediumAttachment->COMGETTER(Medium)(&pMedium);
     3053    AssertComRC(rc);
     3054    Bstr mediumLocation;
     3055    if (pMedium)
     3056    {
     3057        rc = pMedium->COMGETTER(Location)(mediumLocation.asOutParam());
     3058        AssertComRC(rc);
     3059    }
     3060
    30553061    Bstr attCtrlName;
    30563062    rc = aMediumAttachment->COMGETTER(Controller)(attCtrlName.asOutParam());
     
    30783084    pszDevice = convertControllerTypeToDev(enmCtrlType);
    30793085
    3080     /** @todo support multiple instances of a controller */
    3081     uInstance = 0;
    3082 
    3083     LONG device;
    3084     rc = aMediumAttachment->COMGETTER(Device)(&device);
    3085     AssertComRC(rc);
    3086     LONG port;
    3087     rc = aMediumAttachment->COMGETTER(Port)(&port);
    3088     AssertComRC(rc);
    30893086    StorageBus_T enmBus;
    30903087    rc = ctrl->COMGETTER(Bus)(&enmBus);
    30913088    AssertComRC(rc);
    3092     rc = convertBusPortDeviceToLun(enmBus, port, device, uLun);
    3093     AssertComRCReturnRC(rc);
    3094 
    3095     ComPtr<IMedium> medium;
    3096     rc = aMediumAttachment->COMGETTER(Medium)(medium.asOutParam());
    3097     if (SUCCEEDED(rc) && !medium.isNull())
    3098     {
    3099         Bstr loc;
    3100         rc = medium->COMGETTER(Location)(loc.asOutParam());
    3101         AssertComRC(rc);
    3102         location = loc;
    3103         Bstr fmt;
    3104         rc = medium->COMGETTER(Format)(fmt.asOutParam());
    3105         AssertComRC(rc);
    3106         format = fmt;
    3107         rc = medium->COMGETTER(HostDrive)(&fHostDrive);
    3108         AssertComRC(rc);
    3109     }
    3110     rc = aMediumAttachment->COMGETTER(Passthrough)(&fPassthrough);
     3089    ULONG uInstance;
     3090    rc = ctrl->COMGETTER(Instance)(&uInstance);
    31113091    AssertComRC(rc);
    31123092
     
    31223102    PVMREQ pReq;
    31233103    int vrc = VMR3ReqCall(mpVM, VMCPUID_ANY, &pReq, 0 /* no wait! */, VMREQFLAGS_VBOX_STATUS,
    3124                           (PFNRT)Console::changeDrive, 9,
    3125                           this, pszDevice, uInstance, uLun, !!fHostDrive, location.raw(), format.raw(), !!fPassthrough, fForce);
     3104                          (PFNRT)Console::changeRemovableMedium, 6,
     3105                          this, pszDevice, uInstance, enmBus, aMediumAttachment, fForce);
    31263106
    31273107    /* leave the lock before waiting for a result (EMT will call us back!) */
     
    31433123    }
    31443124
    3145     if (!location.isEmpty())
     3125    if (!pMedium)
    31463126        return setError(E_FAIL,
    3147             tr("Could not mount the media/drive '%s' (%Rrc)"),
    3148             location.raw(), vrc);
     3127            tr("Could not mount the media/drive '%ls' (%Rrc)"),
     3128            mediumLocation.raw(), vrc);
    31493129
    31503130    return setError(E_FAIL,
     
    31593139 *
    31603140 * @param   pThis           Pointer to the Console object.
    3161  * @param   pszDevice       The PDM device name.
     3141 * @param   pcszDevice      The PDM device name.
    31623142 * @param   uInstance       The PDM device instance.
    31633143 * @param   uLun            The PDM LUN number of the drive.
     
    31713151 *
    31723152 * @thread  EMT
    3173  * @note Locks the Console object for writing.
    3174  * @todo the error handling in this method needs to be improved seriously - what if mounting fails...
    31753153 */
    3176 DECLCALLBACK(int) Console::changeDrive(Console *pThis, const char *pszDevice, unsigned uInstance, unsigned uLun,
    3177                                        bool fHostDrive, const char *pszPath, const char *pszFormat, bool fPassthrough, bool fForce)
    3178 {
    3179 /// @todo change this to use the same code as in ConsoleImpl2.cpp
    3180     LogFlowFunc(("pThis=%p pszDevice=%p:{%s} uInstance=%u uLun=%u fHostDrive=%d pszPath=%p:{%s} pszFormat=%p:{%s} fPassthrough=%d fForce=%d\n",
    3181                  pThis, pszDevice, pszDevice, uInstance, uLun, fHostDrive, pszPath, pszPath, pszFormat, pszFormat, fPassthrough, fForce));
     3154DECLCALLBACK(int) Console::changeRemovableMedium(Console *pThis,
     3155                                                 const char *pcszDevice,
     3156                                                 unsigned uInstance,
     3157                                                 StorageBus_T enmBus,
     3158                                                 IMediumAttachment *aMediumAtt,
     3159                                                 bool fForce)
     3160{
     3161    LogFlowFunc(("pThis=%p uInstance=%u pszDevice=%p:{%s} enmBus=%u, aMediumAtt=%p, fForce=%d\n",
     3162                 pThis, uInstance, pcszDevice, enmBus, fForce));
    31823163
    31833164    AssertReturn(pThis, VERR_INVALID_PARAMETER);
     
    31853166    AutoCaller autoCaller(pThis);
    31863167    AssertComRCReturn(autoCaller.rc(), VERR_ACCESS_DENIED);
    3187 
    3188     /* protect mpVM */
    3189     AutoVMCaller autoVMCaller(pThis);
    3190     if (FAILED(autoVMCaller.rc())) return autoVMCaller.rc();
    31913168
    31923169    PVM pVM = pThis->mpVM;
     
    32283205    }
    32293206
     3207    /* Determine the base path for the device instance. */
     3208    PCFGMNODE pCtlInst;
     3209    pCtlInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/", pcszDevice,
     3210 uInstance);
     3211    AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
     3212
    32303213    int rc = VINF_SUCCESS;
    32313214    int rcRet = VINF_SUCCESS;
    32323215
    3233     /*
    3234        In general locking the object before doing VMR3* calls is quite safe
    3235        here, since we're on EMT. Anyway we lock for write after eventually
    3236        suspending the vm. The reason is that in the vmstateChangeCallback the
    3237        var mVMStateChangeCallbackDisabled is checked under a lock also, which
    3238        can lead to an dead lock. The write lock is necessary because we
    3239        indirectly modify the meDVDState/meFloppyState members (pointed to by
    3240        peState).
    3241      */
    3242     AutoWriteLock alock(pThis COMMA_LOCKVAL_SRC_POS);
    3243 
    3244     do
    3245     {
    3246         /*
    3247          * Unmount existing media / detach host drive.
    3248          */
    3249         PPDMIBASE pBase;
    3250         rc = PDMR3QueryLun(pVM, pszDevice, uInstance, uLun, &pBase);
    3251         if (RT_FAILURE(rc))
    3252         {
    3253             if (rc == VERR_PDM_LUN_NOT_FOUND || rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
    3254                 rc = VINF_SUCCESS;
    3255             AssertRC(rc);
    3256         }
    3257         else
    3258         {
    3259             PPDMIMOUNT pIMount = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMOUNT);
    3260             AssertBreakStmt(pIMount, rc = VERR_INVALID_POINTER);
    3261 
    3262             /*
    3263              * Unmount the media.
    3264              */
    3265             rc = pIMount->pfnUnmount(pIMount, fForce);
    3266             if (rc == VERR_PDM_MEDIA_NOT_MOUNTED)
    3267                 rc = VINF_SUCCESS;
    3268 
    3269             if (RT_SUCCESS(rc))
    3270             {
    3271                 rc = PDMR3DeviceDetach(pVM, pszDevice, uInstance, uLun, PDM_TACH_FLAGS_NOT_HOT_PLUG);
    3272                 if (rc == VERR_PDM_NO_DRIVER_ATTACHED_TO_LUN)
    3273                     rc = VINF_SUCCESS;
    3274             }
    3275         }
    3276 
    3277         if (RT_FAILURE(rc))
    3278         {
    3279             rcRet = rc;
    3280             break;
    3281         }
    3282 
    3283         /** @todo this does a very thorough job. usually it's too much,
    3284          * as a simple medium change (without changing between host attachment
    3285          * and image) could be done with a lot less effort, by just using the
    3286          * pfnUnmount and pfnMount interfaces. Later. */
    3287 
    3288         /*
    3289          * Construct a new driver configuration.
    3290          */
    3291         PCFGMNODE pInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%d/", pszDevice, uInstance);
    3292         AssertRelease(pInst);
    3293         /* nuke anything which might have been left behind. */
    3294         CFGMR3RemoveNode(CFGMR3GetChildF(pInst, "LUN#%d", uLun));
    3295 
    3296 #define RC_CHECK() do { if (RT_FAILURE(rc)) { AssertReleaseRC(rc); break; } } while (0)
    3297 
    3298         PCFGMNODE pLunL0;
    3299         PCFGMNODE pCfg;
    3300         rc = CFGMR3InsertNodeF(pInst, &pLunL0, "LUN#%d", uLun);     RC_CHECK();
    3301 
    3302         if (fHostDrive)
    3303         {
    3304             rc = CFGMR3InsertString(pLunL0, "Driver",       !strcmp(pszDevice, "i82078") ? "HostFloppy" : "HostDVD");   RC_CHECK();
    3305             rc = CFGMR3InsertNode(pLunL0,   "Config",       &pCfg);     RC_CHECK();
    3306             Assert(pszPath && *pszPath);
    3307             rc = CFGMR3InsertString(pCfg,   "Path",         pszPath);   RC_CHECK();
    3308             if (strcmp(pszDevice, "i82078"))
    3309             {
    3310                 rc = CFGMR3InsertInteger(pCfg, "Passthrough", fPassthrough); RC_CHECK();
    3311             }
    3312         }
    3313         else
    3314         {
    3315             /* create a new block driver config */
    3316             rc = CFGMR3InsertString(pLunL0, "Driver",       "Block");   RC_CHECK();
    3317             rc = CFGMR3InsertNode(pLunL0,   "Config",       &pCfg);     RC_CHECK();
    3318             rc = CFGMR3InsertString(pCfg,   "Type",         !strcmp(pszDevice, "i82078") ? "Floppy 1.44" : "DVD"); RC_CHECK();
    3319             rc = CFGMR3InsertInteger(pCfg,  "Mountable",    1);         RC_CHECK();
    3320         }
    3321 
    3322         /*
    3323          * Attach the driver.
    3324          */
    3325         rc = PDMR3DeviceAttach(pVM, pszDevice, uInstance, uLun, PDM_TACH_FLAGS_NOT_HOT_PLUG, &pBase); RC_CHECK();
    3326 
    3327         if (!fHostDrive && pszPath && *pszPath)
    3328         {
    3329             PCFGMNODE pLunL1;
    3330             rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1); RC_CHECK();
    3331             rc = CFGMR3InsertString(pLunL1, "Driver",       "VD");      RC_CHECK();
    3332             rc = CFGMR3InsertNode(pLunL1,   "Config",       &pCfg);     RC_CHECK();
    3333             rc = CFGMR3InsertString(pCfg,   "Path",         pszPath);   RC_CHECK();
    3334             rc = CFGMR3InsertString(pCfg,   "Format",       pszFormat); RC_CHECK();
    3335             if (strcmp(pszDevice, "i82078"))
    3336             {
    3337                 rc = CFGMR3InsertInteger(pCfg, "ReadOnly",  1);         RC_CHECK();
    3338             }
    3339             /** @todo later pass full VDConfig information and parent images */
    3340         }
    3341 
    3342         /* Dump the new controller configuration. */
    3343         CFGMR3Dump(pInst);
    3344 
    3345         if (!fHostDrive && pszPath && *pszPath)
    3346         {
    3347             PPDMIMOUNT pIMount = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMOUNT);
    3348             if (!pIMount)
    3349             {
    3350                 AssertFailed();
    3351                 return rc;
    3352             }
    3353 
    3354             rc = pIMount->pfnMount(pIMount, NULL , NULL);
    3355         }
    3356 
    3357 #undef RC_CHECK
    3358 
    3359         if (RT_FAILURE(rc) && RT_SUCCESS(rcRet))
    3360             rcRet = rc;
    3361 
    3362     }
    3363     while (0);
    3364 
    3365     /*
    3366        Unlock before resuming because the vmstateChangeCallback problem
    3367        described above.
    3368      */
    3369     alock.release();
     3216    rcRet = Console::configMediumAttachment(pCtlInst, pcszDevice, uInstance,
     3217                                            enmBus, aMediumAtt,
     3218                                            pThis->mMachineState,
     3219                                            NULL /* phrc */,
     3220                                            true /* fAttachDetach */,
     3221                                            fForce /* fForceUnmount */,
     3222                                            pVM, NULL /* paLedDevType */);
     3223    /** @todo this dumps everything attached to this device instance, which
     3224     * is more than necessary. Dumping the changed LUN would be enough. */
     3225    CFGMR3Dump(pCtlInst);
    33703226
    33713227    /*
     
    36773533    AssertRelease(pInst);
    36783534
    3679     rcRet = configNetwork(pThis, pszDevice, uInstance, uLun, aNetworkAdapter, pCfg, pLunL0, pInst, true);
     3535    rcRet = pThis->configNetwork(pszDevice, uInstance, uLun, aNetworkAdapter, pCfg, pLunL0, pInst, true);
    36803536
    36813537    /*
     
    73507206 * @param   pVM           The VM handle.
    73517207 * @param   lInstance     The instance of the controller.
    7352  * @param   enmController The type of the controller.
     7208 * @param   pcszDevice    The name of the controller type.
    73537209 * @param   enmBus        The storage bus type of the controller.
    73547210 * @param   aMediumAtt    The medium attachment.
     7211 * @param   aMachineState The current machine state.
    73557212 * @param   phrc          Where to store com error - only valid if we return VERR_GENERAL_FAILURE.
    73567213 * @return  VBox status code.
    73577214 */
    7358 static DECLCALLBACK(int) reconfigureMedium(PVM pVM, ULONG lInstance,
    7359                                            StorageControllerType_T enmController,
    7360                                            StorageBus_T enmBus,
    7361                                            IMediumAttachment *aMediumAtt,
    7362                                            HRESULT *phrc)
     7215/* static */
     7216DECLCALLBACK(int) Console::reconfigureMediumAttachment(PVM pVM,
     7217                                                       const char *pcszDevice,
     7218                                                       unsigned uInstance,
     7219                                                       StorageBus_T enmBus,
     7220                                                       IMediumAttachment *aMediumAtt,
     7221                                                       MachineState_T aMachineState,
     7222                                                       HRESULT *phrc)
    73637223{
    73647224    LogFlowFunc(("pVM=%p aMediumAtt=%p phrc=%p\n", pVM, aMediumAtt, phrc));
     
    73717231#define H() do { if (FAILED(hrc)) { AssertMsgFailed(("hrc=%Rhrc (%#x)\n", hrc, hrc)); *phrc = hrc; return VERR_GENERAL_FAILURE; } } while (0)
    73727232
    7373     /*
    7374      * Figure out medium and other attachment details.
    7375      */
    7376     ComPtr<IMedium> medium;
    7377     hrc = aMediumAtt->COMGETTER(Medium)(medium.asOutParam());                   H();
    7378     LONG lDev;
    7379     hrc = aMediumAtt->COMGETTER(Device)(&lDev);                                 H();
    7380     LONG lPort;
    7381     hrc = aMediumAtt->COMGETTER(Port)(&lPort);                                  H();
     7233    /* Ignore attachments other than hard disks, since at the moment they are
     7234     * not subject to snapshotting in general. */
    73827235    DeviceType_T lType;
    73837236    hrc = aMediumAtt->COMGETTER(Type)(&lType);                                  H();
    7384 
    7385     unsigned iLUN;
    7386     const char *pcszDevice = Console::convertControllerTypeToDev(enmController);
    7387     AssertMsgReturn(pcszDevice, ("invalid disk controller type: %d\n", enmController), VERR_GENERAL_FAILURE);
    7388     hrc = Console::convertBusPortDeviceToLun(enmBus, lPort, lDev, iLUN);        H();
    7389 
    7390     /* Ignore attachments other than hard disks, since at the moment they are
    7391      * not subject to snapshotting in general. */
    7392     if (lType != DeviceType_HardDisk || medium.isNull())
     7237    if (lType != DeviceType_HardDisk)
    73937238        return VINF_SUCCESS;
    73947239
    7395     /** @todo this should be unified with the relevant part of
    7396     * Console::configConstructor to avoid inconsistencies. */
    7397 
    7398     /*
    7399      * Is there an existing LUN? If not create it.
    7400      */
    7401     PCFGMNODE pCfg;
    7402     PCFGMNODE pLunL1;
    7403 
    7404     /* SCSI has an extra driver between the device and the block driver. */
    7405     if (enmBus == StorageBus_SCSI)
    7406         pLunL1 = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/LUN#%u/AttachedDriver/AttachedDriver/", pcszDevice, lInstance, iLUN);
    7407     else
    7408         pLunL1 = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/LUN#%u/AttachedDriver/", pcszDevice, lInstance, iLUN);
    7409 
    7410     if (!pLunL1)
    7411     {
    7412         PCFGMNODE pInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/", pcszDevice, lInstance);
    7413         AssertReturn(pInst, VERR_INTERNAL_ERROR);
    7414 
    7415         PCFGMNODE pLunL0;
    7416         rc = CFGMR3InsertNodeF(pInst, &pLunL0, "LUN#%u", iLUN);                     RC_CHECK();
    7417 
    7418         if (enmBus == StorageBus_SCSI)
    7419         {
    7420             rc = CFGMR3InsertString(pLunL0, "Driver",              "SCSI");             RC_CHECK();
    7421             rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                           RC_CHECK();
    7422 
    7423             rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL0);                 RC_CHECK();
    7424         }
    7425 
    7426         rc = CFGMR3InsertString(pLunL0, "Driver",              "Block");            RC_CHECK();
    7427         rc = CFGMR3InsertNode(pLunL0,   "Config", &pCfg);                           RC_CHECK();
    7428         rc = CFGMR3InsertString(pCfg,   "Type",                "HardDisk");         RC_CHECK();
    7429         rc = CFGMR3InsertInteger(pCfg,  "Mountable",            0);                 RC_CHECK();
    7430 
    7431         rc = CFGMR3InsertNode(pLunL0,   "AttachedDriver", &pLunL1);                 RC_CHECK();
    7432         rc = CFGMR3InsertString(pLunL1, "Driver",              "VD");               RC_CHECK();
    7433         rc = CFGMR3InsertNode(pLunL1,   "Config", &pCfg);                           RC_CHECK();
    7434     }
    7435     else
    7436     {
    7437 #ifdef VBOX_STRICT
    7438         char *pszDriver;
    7439         rc = CFGMR3QueryStringAlloc(pLunL1, "Driver", &pszDriver);                  RC_CHECK();
    7440         Assert(!strcmp(pszDriver, "VD"));
    7441         MMR3HeapFree(pszDriver);
    7442 #endif
    7443 
    7444         pCfg = CFGMR3GetChild(pLunL1, "Config");
    7445         AssertReturn(pCfg, VERR_INTERNAL_ERROR);
    7446 
    7447         /* Here used to be a lot of code checking if things have changed,
    7448          * but that's not really worth it, as with snapshots there is always
    7449          * some change, so the code was just logging useless information in
    7450          * a hard to analyze form. */
    7451 
    7452         /*
    7453          * Detach the driver and replace the config node.
    7454          */
    7455         rc = PDMR3DeviceDetach(pVM, pcszDevice, 0, iLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG); RC_CHECK();
    7456         CFGMR3RemoveNode(pCfg);
    7457         rc = CFGMR3InsertNode(pLunL1, "Config", &pCfg);                             RC_CHECK();
    7458     }
    7459 
    7460     /*
    7461      * Create the driver configuration.
    7462      */
    7463     hrc = medium->COMGETTER(Location)(bstr.asOutParam());                       H();
    7464     LogFlowFunc(("LUN#%u: leaf location '%ls'\n", iLUN, bstr.raw()));
    7465     rc = CFGMR3InsertString(pCfg, "Path", Utf8Str(bstr).c_str());                       RC_CHECK();
    7466     hrc = medium->COMGETTER(Format)(bstr.asOutParam());                         H();
    7467     LogFlowFunc(("LUN#%u: leaf format '%ls'\n", iLUN, bstr.raw()));
    7468     rc = CFGMR3InsertString(pCfg, "Format", Utf8Str(bstr).c_str());                     RC_CHECK();
    7469 
    7470     /* Pass all custom parameters. */
    7471     bool fHostIP = true;
    7472     SafeArray<BSTR> names;
    7473     SafeArray<BSTR> values;
    7474     hrc = medium->GetProperties(NULL,
    7475                                 ComSafeArrayAsOutParam(names),
    7476                                 ComSafeArrayAsOutParam(values));        H();
    7477 
    7478     if (names.size() != 0)
    7479     {
    7480         PCFGMNODE pVDC;
    7481         rc = CFGMR3InsertNode(pCfg, "VDConfig", &pVDC);                 RC_CHECK();
    7482         for (size_t i = 0; i < names.size(); ++ i)
    7483         {
    7484             if (values[i] && *values[i])
    7485             {
    7486                 Utf8Str name = names[i];
    7487                 Utf8Str value = values[i];
    7488                 rc = CFGMR3InsertString(pVDC, name.c_str(), value.c_str());
    7489                 if (    !(name.compare("HostIPStack"))
    7490                     &&  !(value.compare("0")))
    7491                     fHostIP = false;
    7492             }
    7493         }
    7494     }
    7495 
    7496     /* Create an inversed tree of parents. */
    7497     ComPtr<IMedium> parentMedium = medium;
    7498     for (PCFGMNODE pParent = pCfg;;)
    7499     {
    7500         hrc = parentMedium->COMGETTER(Parent)(medium.asOutParam());             H();
    7501         if (medium.isNull())
    7502             break;
    7503 
    7504         PCFGMNODE pCur;
    7505         rc = CFGMR3InsertNode(pParent, "Parent", &pCur);                        RC_CHECK();
    7506         hrc = medium->COMGETTER(Location)(bstr.asOutParam());                   H();
    7507         rc = CFGMR3InsertString(pCur,  "Path", Utf8Str(bstr).c_str());          RC_CHECK();
    7508 
    7509         hrc = medium->COMGETTER(Format)(bstr.asOutParam());                     H();
    7510         rc = CFGMR3InsertString(pCur,  "Format", Utf8Str(bstr).c_str());        RC_CHECK();
    7511 
    7512         /* Pass all custom parameters. */
    7513         SafeArray<BSTR> aNames;
    7514         SafeArray<BSTR> aValues;
    7515         hrc = medium->GetProperties(NULL,
    7516                                     ComSafeArrayAsOutParam(aNames),
    7517                                     ComSafeArrayAsOutParam(aValues));            H();
    7518 
    7519         if (aNames.size() != 0)
    7520         {
    7521             PCFGMNODE pVDC;
    7522             rc = CFGMR3InsertNode(pCur, "VDConfig", &pVDC);             RC_CHECK();
    7523             for (size_t i = 0; i < aNames.size(); ++ i)
    7524             {
    7525                 if (aValues[i] && *aValues[i])
    7526                 {
    7527                     Utf8Str name = aNames[i];
    7528                     Utf8Str value = aValues[i];
    7529                     rc = CFGMR3InsertString(pVDC, name.c_str(), value.c_str()); RC_CHECK();
    7530                     if (    !(name.compare("HostIPStack"))
    7531                         &&  !(value.compare("0")))
    7532                         fHostIP = false;
    7533                 }
    7534             }
    7535         }
    7536 
    7537         /* Custom code: put marker to not use host IP stack to driver
    7538         * configuration node. Simplifies life of DrvVD a bit. */
    7539         if (!fHostIP)
    7540         {
    7541             rc = CFGMR3InsertInteger(pCfg, "HostIPStack", 0);           RC_CHECK();
    7542         }
    7543 
    7544 
    7545         /* next */
    7546         pParent = pCur;
    7547         parentMedium = medium;
    7548     }
    7549 
    7550     CFGMR3Dump(CFGMR3GetRoot(pVM));
    7551 
    7552     /*
    7553      * Attach the new driver.
    7554      */
    7555     rc = PDMR3DeviceAttach(pVM, pcszDevice, 0, iLUN, PDM_TACH_FLAGS_NOT_HOT_PLUG, NULL /*ppBase*/); RC_CHECK();
     7240    /* Determine the base path for the device instance. */
     7241    PCFGMNODE pCtlInst;
     7242    pCtlInst = CFGMR3GetChildF(CFGMR3GetRoot(pVM), "Devices/%s/%u/", pcszDevice, uInstance);
     7243    AssertReturn(pCtlInst, VERR_INTERNAL_ERROR);
     7244
     7245    /* Update the device instance configuration. */
     7246    rc = Console::configMediumAttachment(pCtlInst, pcszDevice, uInstance,
     7247                                         enmBus, aMediumAtt, aMachineState,
     7248                                         phrc, true /* fAttachDetach */,
     7249                                         false /* fForceUnmount */, pVM,
     7250                                         NULL /* paLedDevType */);
     7251    /** @todo this dumps everything attached to this device instance, which
     7252     * is more than necessary. Dumping the changed LUN would be enough. */
     7253    CFGMR3Dump(pCtlInst);
     7254    RC_CHECK();
     7255
     7256#undef RC_CHECK
     7257#undef H
    75567258
    75577259    LogFlowFunc(("Returns success\n"));
    7558     return rc;
     7260    return VINF_SUCCESS;
    75597261}
    75607262
     
    75967298        that->mptrCancelableProgress.setNull();
    75977299        return autoCaller.rc();
     7300    }
     7301
     7302    /* protect mpVM */
     7303    AutoVMCaller autoVMCaller(that);
     7304    if (FAILED(autoVMCaller.rc()))
     7305    {
     7306        that->mptrCancelableProgress.setNull();
     7307        return autoVMCaller.rc();
    75987308    }
    75997309
     
    77057415                if (FAILED(rc))
    77067416                    throw rc;
     7417                const char *pcszDevice = Console::convertControllerTypeToDev(enmController);
    77077418
    77087419                /*
    7709                  * don't leave the lock since reconfigureMedium isn't going
    7710                  * to access Console.
     7420                 * don't leave the lock since reconfigureMediumAttachment
     7421                 * isn't going to need the Console lock.
    77117422                 */
    77127423                vrc = VMR3ReqCallWait(that->mpVM,
    77137424                                      VMCPUID_ANY,
    7714                                       (PFNRT)reconfigureMedium,
    7715                                       6,
     7425                                      (PFNRT)reconfigureMediumAttachment,
     7426                                      7,
    77167427                                      that->mpVM,
     7428                                      pcszDevice,
    77177429                                      lInstance,
    7718                                       enmController,
    77197430                                      enmBus,
    77207431                                      atts[i],
     7432                                      that->mMachineState,
    77217433                                      &rc);
    77227434                if (RT_FAILURE(vrc))
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