Changeset 14272 in vbox for trunk/src/VBox/Main
- Timestamp:
- Nov 18, 2008 12:22:15 AM (16 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/HardDisk2Impl.cpp
r14225 r14272 22 22 #include "HardDisk2Impl.h" 23 23 24 #include "VirtualBoxImpl.h"25 24 #include "ProgressImpl.h" 26 25 #include "SystemPropertiesImpl.h" … … 492 491 m.state = MediaState_NotCreated; 493 492 493 /* No storage unit is created yet, no need to queryInfo() */ 494 495 rc = setFormat (aFormat); 496 CheckComRCReturnRC (rc); 497 494 498 rc = setLocation (aLocation); 495 499 CheckComRCReturnRC (rc); 496 497 /* No storage unit is created yet, no need to queryInfo() */498 499 /// @todo NEWMEDIA check the format ID is valid500 unconst (mm.format) = aFormat;501 500 502 501 /* Confirm a successful initialization when it's the case */ … … 553 552 rc = setError (E_FAIL, Utf8Str (m.lastAccessError)); 554 553 } 555 } 556 557 /* storage format must be detected by queryInfo() if the medium is 558 * accessible */ 559 AssertReturn (m.state == MediaState_Inaccessible || 560 (!m.id.isEmpty() && !mm.format.isNull()), 561 E_FAIL); 554 555 /* storage format must be detected by queryInfo() if the medium is 556 * accessible */ 557 AssertReturn (!m.id.isEmpty() && !mm.format.isNull(), E_FAIL); 558 } 562 559 563 560 /* Confirm a successful initialization when it's the case */ … … 613 610 /* required */ 614 611 unconst (m.id) = aNode.value <Guid> ("uuid"); 612 613 /* optional */ 614 { 615 settings::Key descNode = aNode.findKey ("Description"); 616 if (!descNode.isNull()) 617 m.description = descNode.keyStringValue(); 618 } 619 620 /* required */ 621 Bstr format = aNode.stringValue ("format"); 622 AssertReturn (!format.isNull(), E_FAIL); 623 rc = setFormat (format); 624 CheckComRCReturnRC (rc); 625 615 626 /* required */ 616 627 Bstr location = aNode.stringValue ("location"); 617 628 rc = setLocation (location); 618 629 CheckComRCReturnRC (rc); 619 /* optional */ 620 { 621 settings::Key descNode = aNode.findKey ("Description"); 622 if (!descNode.isNull()) 623 m.description = descNode.keyStringValue(); 624 } 625 626 /* required */ 627 unconst (mm.format) = aNode.stringValue ("format"); 628 AssertReturn (!mm.format.isNull(), E_FAIL); 629 630 /* only for base hard disks */ 630 631 /* type is only for base hard disks */ 631 632 if (mParent.isNull()) 632 633 { … … 691 692 return; 692 693 694 if (!mm.formatObj.isNull()) 695 { 696 /* remove the caller reference we added in setFormat() */ 697 mm.formatObj->releaseCaller(); 698 mm.formatObj.setNull(); 699 } 700 693 701 if (m.state == MediaState_Deleting) 694 702 { … … 1311 1319 /// @todo NEWMEDIA delegate the comparison to the backend? 1312 1320 1313 if ( isFileLocation (locationFull))1321 if (mm.formatObj->capabilities() & HardDiskFormatCapabilities_File) 1314 1322 { 1315 1323 Utf8Str location (aLocation); … … 1356 1364 return name; 1357 1365 } 1366 1367 /// @todo NEWMEDIA remove, should not need anymore 1368 #if 0 1358 1369 1359 1370 /** … … 1398 1409 return true; 1399 1410 } 1411 1412 #endif /* if 0 */ 1400 1413 1401 1414 /** … … 1669 1682 1670 1683 /* check that our own format supports diffs */ 1671 1672 /* lock system properties now to make the format check atomic with 1673 * defaultHardDiskFormat() */ 1674 AutoReadLock propsLock (mVirtualBox->systemProperties()); 1675 1676 ComObjPtr <HardDiskFormat> formatObj = 1677 mVirtualBox->systemProperties()->hardDiskFormat (format); 1678 AssertReturn (!formatObj.isNull(), format); 1679 1680 if (!(formatObj->capabilities() & HardDiskFormatCapabilities_Differencing)) 1684 if (!(mm.formatObj->capabilities() & HardDiskFormatCapabilities_Differencing)) 1685 { 1686 /* use the default format if not */ 1687 AutoReadLock propsLock (mVirtualBox->systemProperties()); 1681 1688 format = mVirtualBox->systemProperties()->defaultHardDiskFormat(); 1689 } 1682 1690 1683 1691 return format; … … 2243 2251 return E_INVALIDARG; 2244 2252 2245 /// @todo NEWMEDIA treat non-FS-paths specially! (may require to request 2246 /// this information from the VD backend) 2247 2248 Utf8Str location (aLocation); 2249 2250 Guid id; 2251 2252 if (RTPathFilename (location) == NULL) 2253 { 2254 /* no file name is given (either an empty string or ends with a slash), 2255 * generate a new UUID + file name if the state allows this */ 2253 AutoCaller autoCaller (this); 2254 AssertComRCReturnRC (autoCaller.rc()); 2255 2256 /* formatObj may be null only when initializing from an existing path and 2257 * no format is known yet */ 2258 AssertReturn ((!mm.format.isNull() && !mm.formatObj.isNull()) || 2259 (autoCaller.state() == InInit && 2260 m.state != MediaState_NotCreated && m.id.isEmpty() && 2261 mm.format.isNull() && mm.formatObj.isNull()), 2262 E_FAIL); 2263 2264 /* are we dealing with a hard disk opened from the existing path? */ 2265 bool isNew = mm.format.isNull(); 2266 2267 if (isNew || 2268 (mm.formatObj->capabilities() & HardDiskFormatCapabilities_File)) 2269 { 2270 Guid id; 2271 2272 Utf8Str location (aLocation); 2256 2273 2257 2274 if (m.state == MediaState_NotCreated) 2258 2275 { 2259 id.create(); 2260 2261 /// @todo NEWMEDIA use the default extension for the given VD backend 2262 location = Utf8StrFmt ("%s{%RTuuid}.vdi", location.raw(), id.raw()); 2276 /* must be a file (formatObj must be already known) */ 2277 Assert (mm.formatObj->capabilities() & HardDiskFormatCapabilities_File); 2278 2279 if (RTPathFilename (location) == NULL) 2280 { 2281 /* no file name is given (either an empty string or ends with a 2282 * slash), generate a new UUID + file name if the state allows 2283 * this */ 2284 2285 ComAssertMsgRet (!mm.formatObj->fileExtensions().empty(), 2286 ("Must be at least one extension if it is " 2287 "HardDiskFormatCapabilities_File\n"), 2288 E_FAIL); 2289 2290 Bstr ext = mm.formatObj->fileExtensions().front(); 2291 ComAssertMsgRet (!ext.isEmpty(), 2292 ("Default extension must not be empty\n"), 2293 E_FAIL); 2294 2295 id.create(); 2296 2297 location = Utf8StrFmt ("%s{%RTuuid}.%ls", 2298 location.raw(), id.raw(), ext.raw()); 2299 } 2300 } 2301 2302 /* append the default folder if no path is given */ 2303 if (!RTPathHavePath (location)) 2304 { 2305 AutoReadLock propsLock (mVirtualBox->systemProperties()); 2306 location = Utf8StrFmt ("%ls%c%s", 2307 mVirtualBox->systemProperties()->defaultHardDiskFolder().raw(), 2308 RTPATH_DELIMITER, 2309 location.raw()); 2310 } 2311 2312 /* get the full file name */ 2313 Utf8Str locationFull; 2314 int vrc = mVirtualBox->calculateFullPath (location, locationFull); 2315 if (RT_FAILURE (vrc)) 2316 return setError (E_FAIL, 2317 tr ("Invalid hard disk storage file location '%s' (%Rrc)"), 2318 location.raw(), vrc); 2319 2320 /* detect the backend from the storage unit if new */ 2321 if (isNew) 2322 { 2323 char *backendName = NULL; 2324 2325 /* is it a file? */ 2326 { 2327 RTFILE file; 2328 vrc = RTFileOpen (&file, locationFull, RTFILE_O_READ); 2329 if (RT_SUCCESS (vrc)) 2330 RTFileClose (file); 2331 } 2332 if (RT_SUCCESS (vrc)) 2333 { 2334 vrc = VDGetFormat (locationFull, &backendName); 2335 } 2336 else if (vrc != VERR_FILE_NOT_FOUND && vrc != VERR_PATH_NOT_FOUND) 2337 { 2338 /* assume it's not a file, restore the original location */ 2339 location = locationFull = aLocation; 2340 vrc = VDGetFormat (locationFull, &backendName); 2341 } 2342 2343 if (RT_FAILURE (vrc)) 2344 return setError (E_FAIL, 2345 tr ("Could not get the storage format of the hard disk " 2346 "'%s' (%Rrc)"), locationFull.raw(), vrc); 2347 2348 ComAssertRet (backendName != NULL && *backendName != '\0', E_FAIL); 2349 2350 HRESULT rc = setFormat (Bstr (backendName)); 2351 RTStrFree (backendName); 2352 2353 /* setFormat() must not fail since we've just used the backend so 2354 * the format object must be there */ 2355 AssertComRCReturnRC (rc); 2356 } 2357 2358 /* is it still a file? */ 2359 if (mm.formatObj->capabilities() & HardDiskFormatCapabilities_File) 2360 { 2361 m.location = location; 2362 m.locationFull = locationFull; 2363 2364 /* assign a new UUID if we generated it */ 2365 if (!id.isEmpty()) 2366 unconst (m.id) = id; 2263 2367 } 2264 2368 else 2265 2369 { 2266 /* it's an error to not have a file name :) */ 2370 m.location = locationFull; 2371 m.locationFull = locationFull; 2372 } 2373 } 2374 else 2375 { 2376 m.location = aLocation; 2377 m.locationFull = aLocation; 2378 } 2379 2380 return S_OK; 2381 } 2382 2383 /** 2384 * Checks that the format ID is valid and sets it on success. 2385 * 2386 * Note that this method will caller-reference the format object on success! 2387 * This reference must be released somewhere to let the HardDiskFormat object be 2388 * uninitialized. 2389 * 2390 * @note Must be called from under this object's write lock. 2391 */ 2392 HRESULT HardDisk2::setFormat (const BSTR aFormat) 2393 { 2394 /* get the format object first */ 2395 { 2396 AutoReadLock propsLock (mVirtualBox->systemProperties()); 2397 2398 unconst (mm.formatObj) 2399 = mVirtualBox->systemProperties()->hardDiskFormat (aFormat); 2400 if (mm.formatObj.isNull()) 2267 2401 return setError (E_FAIL, 2268 tr ("Hard disk storage file location '%s' does not contain " 2269 "a file name"), 2270 location.raw()); 2271 } 2272 } 2273 2274 /* append the default folder if no path is given */ 2275 if (!RTPathHavePath (location)) 2276 { 2277 AutoReadLock propsLock (mVirtualBox->systemProperties()); 2278 location = Utf8StrFmt ("%ls%c%s", 2279 mVirtualBox->systemProperties()->defaultHardDiskFolder().raw(), 2280 RTPATH_DELIMITER, 2281 location.raw()); 2282 } 2283 2284 /* get the full file name */ 2285 Utf8Str locationFull; 2286 int vrc = mVirtualBox->calculateFullPath (location, locationFull); 2287 if (RT_FAILURE (vrc)) 2288 return setError (E_FAIL, 2289 tr ("Invalid hard disk storage file location '%s' (%Rrc)"), 2290 location.raw(), vrc); 2291 2292 m.location = location; 2293 m.locationFull = locationFull; 2294 2295 /* assign a new UUID if we generated it */ 2296 if (!id.isEmpty()) 2297 unconst (m.id) = id; 2402 tr ("Invalid hard disk storage format '%ls'"), aFormat); 2403 2404 /* reference the format permanently to prevent its unexpected 2405 * uninitialization */ 2406 HRESULT rc = mm.formatObj->addCaller(); 2407 AssertComRCReturnRC (rc); 2408 } 2409 2410 unconst (mm.format) = aFormat; 2298 2411 2299 2412 return S_OK; 2300 2413 } 2414 2301 2415 /** 2302 2416 * Queries information from the image file. … … 2381 2495 Utf8Str location (m.locationFull); 2382 2496 2383 /* are we dealing with an unknown (just opened) image? */ 2384 bool isNew = mm.format.isNull(); 2385 2386 if (isNew) 2387 { 2388 /* detect the backend from the storage unit */ 2389 char *backendName = NULL; 2390 vrc = VDGetFormat (location, &backendName); 2391 if (RT_FAILURE (vrc)) 2392 { 2393 lastAccessError = Utf8StrFmt ( 2394 tr ("Could not get the storage format of the hard disk " 2395 "'%ls'%s"), m.locationFull.raw(), vdError (vrc).raw()); 2396 throw S_OK; 2397 } 2398 2399 ComAssertThrow (backendName != NULL, E_FAIL); 2400 2401 unconst (mm.format) = backendName; 2402 RTStrFree (backendName); 2403 } 2497 /* are we dealing with a hard disk opened from the existing path? */ 2498 bool isNew = m.id.isEmpty(); 2404 2499 2405 2500 PVBOXHDD hdd; … … 2409 2504 try 2410 2505 { 2411 vrc = VDOpen (hdd, Utf8Str (mm.format), location, 2412 VD_OPEN_FLAGS_READONLY | VD_OPEN_FLAGS_INFO, 2413 NULL); 2506 unsigned flags = VD_OPEN_FLAGS_INFO; 2507 2508 /* Note that we don't use VD_OPEN_FLAGS_READONLY when opening new 2509 * hard disks because that would prevent necessary modifications 2510 * when opening hard disks of some third-party formats for the first 2511 * time in VirtualBox (such as VMDK for which VDOpen() needs to 2512 * generate an UUID if it is missing) */ 2513 if (!isNew) 2514 flags |= VD_OPEN_FLAGS_READONLY; 2515 2516 vrc = VDOpen (hdd, Utf8Str (mm.format), location, flags, NULL); 2414 2517 if (RT_FAILURE (vrc)) 2415 2518 { -
trunk/src/VBox/Main/VirtualBoxImpl.cpp
r14224 r14272 247 247 CheckComRCThrowRC (rc); 248 248 249 /* create the system properties object */249 /* create the system properties object, someone may need it too */ 250 250 unconst (mData.mSystemProperties).createObject(); 251 251 rc = mData.mSystemProperties->init (this); … … 375 375 } 376 376 377 if (mData.mSystemProperties)378 {379 mData.mSystemProperties->uninit();380 unconst (mData.mSystemProperties).setNull();381 }382 383 if (mData.mHost)384 {385 mData.mHost->uninit();386 unconst (mData.mHost).setNull();387 }388 389 #ifdef VBOX_WITH_RESOURCE_USAGE_API390 if (mData.mPerformanceCollector)391 {392 mData.mPerformanceCollector->uninit();393 unconst (mData.mPerformanceCollector).setNull();394 }395 #endif /* VBOX_WITH_RESOURCE_USAGE_API */396 397 377 /* Uninit all other children still referenced by clients (unregistered 398 378 * machines, hard disks, DVD/floppy images, server-side progress … … 409 389 410 390 mData.mGuestOSTypes.clear(); 391 392 /* Note that we release singleton children after we've all other children. 393 * In some cases this is important because these other children may use 394 * some resources of the singletons which would prevent them from 395 * uninitializing (as for example, mSystemProperties which owns 396 * HardDiskFormat objects which HardDisk2 objects refer to) */ 397 if (mData.mSystemProperties) 398 { 399 mData.mSystemProperties->uninit(); 400 unconst (mData.mSystemProperties).setNull(); 401 } 402 403 if (mData.mHost) 404 { 405 mData.mHost->uninit(); 406 unconst (mData.mHost).setNull(); 407 } 408 409 #ifdef VBOX_WITH_RESOURCE_USAGE_API 410 if (mData.mPerformanceCollector) 411 { 412 mData.mPerformanceCollector->uninit(); 413 unconst (mData.mPerformanceCollector).setNull(); 414 } 415 #endif /* VBOX_WITH_RESOURCE_USAGE_API */ 411 416 412 417 /* unlock the config file */ -
trunk/src/VBox/Main/include/HardDisk2Impl.h
r14225 r14272 28 28 29 29 #include "VirtualBoxImpl.h" 30 #include "HardDiskFormatImpl.h" 30 31 #include "MediumImpl.h" 31 32 … … 174 175 Utf8Str name(); 175 176 176 static bool isFileLocation (const char *aLocation);177 178 177 HRESULT prepareDiscard (MergeChain * &aChain); 179 178 HRESULT discard (ComObjPtr <Progress> &aProgress, MergeChain *aChain); … … 225 224 226 225 HRESULT setLocation (const BSTR aLocation); 226 HRESULT setFormat (const BSTR aFormat); 227 227 228 HRESULT queryInfo(); 228 229 … … 256 257 257 258 const Bstr format; 259 ComObjPtr <HardDiskFormat> formatObj; 258 260 259 261 HardDiskType_T type; -
trunk/src/VBox/Main/include/HardDiskFormatImpl.h
r14225 r14272 33 33 struct VDBACKENDINFO; 34 34 35 /** 36 * The HardDiskFormat class represents the backend used to store hard disk data 37 * (IHardDiskFormat interface). 38 * 39 * @note Instances of this class are permanently caller-referenced by HardDisk2 40 * objects (through addCaller()) so that an attempt to uninitialize or delete 41 * them before all HardDisk2 objects are uninitialized will produce an endless 42 * wait! 43 */ 35 44 class ATL_NO_VTABLE HardDiskFormat : 36 45 public VirtualBoxBaseNEXT, … … 40 49 { 41 50 public: 51 52 struct Property 53 { 54 Bstr name; 55 Bstr description; 56 DataType_T type; 57 ULONG flags; 58 Bstr defaultValue; 59 }; 60 61 typedef std::list <Bstr> BstrList; 62 typedef std::list <Property> PropertyList; 63 64 struct Data 65 { 66 Data() : capabilities (0) {} 67 68 const Bstr id; 69 const Bstr name; 70 const BstrList fileExtensions; 71 const uint64_t capabilities; 72 const PropertyList properties; 73 }; 42 74 43 75 VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (HardDiskFormat) … … 84 116 const Bstr &id() { return m.id; } 85 117 /** Const, no need to lock */ 118 const BstrList &fileExtensions() { return m.fileExtensions; } 119 /** Const, no need to lock */ 86 120 uint64_t capabilities() { return m.capabilities; } 87 121 … … 91 125 private: 92 126 93 typedef std::list <Bstr> BstrList;94 95 struct Property96 {97 Bstr name;98 Bstr description;99 DataType_T type;100 ULONG flags;101 Bstr defaultValue;102 };103 typedef std::list <Property> PropertyList;104 105 struct Data106 {107 Data() : capabilities (0) {}108 109 const Bstr id;110 const Bstr name;111 const BstrList fileExtensions;112 const uint64_t capabilities;113 const PropertyList properties;114 };115 116 127 Data m; 117 128 };
Note:
See TracChangeset
for help on using the changeset viewer.