Changeset 85929 in vbox
- Timestamp:
- Aug 28, 2020 2:40:55 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 19 edited
-
doc/manual/en_US/user_AdvancedTopics.xml (modified) (7 diffs)
-
doc/manual/en_US/user_VBoxManage.xml (modified) (3 diffs)
-
include/VBox/com/Guid.h (modified) (1 diff)
-
include/VBox/log.h (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp (modified) (8 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp (modified) (2 diffs)
-
src/VBox/Frontends/VBoxManage/VBoxManageList.cpp (modified) (5 diffs)
-
src/VBox/Main/Makefile.kmk (modified) (2 diffs)
-
src/VBox/Main/idl/VirtualBox.xidl (modified) (3 diffs)
-
src/VBox/Main/include/AutoCaller.h (modified) (1 diff)
-
src/VBox/Main/include/HostHardwareLinux.h (modified) (4 diffs)
-
src/VBox/Main/include/HostImpl.h (modified) (5 diffs)
-
src/VBox/Main/src-all/AutoCaller.cpp (modified) (1 diff)
-
src/VBox/Main/src-all/GlobalStatusConversion.cpp (modified) (1 diff)
-
src/VBox/Main/src-server/HostDriveImpl.cpp (added)
-
src/VBox/Main/src-server/HostDrivePartitionImpl.cpp (added)
-
src/VBox/Main/src-server/HostImpl.cpp (modified) (12 diffs)
-
src/VBox/Main/src-server/darwin/iokit.cpp (modified) (2 diffs)
-
src/VBox/Main/src-server/darwin/iokit.h (modified) (3 diffs)
-
src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp (modified) (19 diffs)
-
src/VBox/Main/src-server/linux/HostHardwareLinux.cpp (modified) (46 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/doc/manual/en_US/user_AdvancedTopics.xml
r84012 r85929 1421 1421 </para> 1422 1422 1423 <screen>$ VBoxManage internalcommands createrawvmdk -filename \1424 /path/to/file.vmdk -rawdisk/dev/sda</screen>1423 <screen>$ VBoxManage createmedium disk --filename /path/to/file.vmdk --format=VMDK 1424 --variant RawDisk --property RawDrive=/dev/sda</screen> 1425 1425 1426 1426 <para> … … 1435 1435 for example use <filename>\\.\PhysicalDrive0</filename>. On a 1436 1436 Mac OS X host, instead of the above device specification use 1437 for example <filename>/dev/ disk1</filename>. Note that on Mac1438 OS X you can only get access to anentire disk if no volume is1437 for example <filename>/dev/rdisk1</filename>. Note that on Mac 1438 OS X you can only get access to entire disk if no volume is 1439 1439 mounted from it. 1440 1440 </para> … … 1488 1488 </para> 1489 1489 1490 <screen>$ VBoxManage internalcommands createrawvmdk -filename \1491 /path/to/file.vmdk -rawdisk /dev/sda -partitions1,5</screen>1490 <screen>$ VBoxManage createmedium disk --filename /path/to/file.vmdk --format=VMDK 1491 --variant RawDisk --property RawDrive=/dev/sda --property Partitions=1,5</screen> 1492 1492 1493 1493 <para> 1494 1494 The command is identical to the one for full hard disk access, 1495 except for the additional <option>-partitions</option> 1495 except for the additional 1496 <option>--property Partitions=1,5</option> 1496 1497 parameter. This example would create the image 1497 <filename>/ <replaceable>path-to-file</replaceable>.vmdk</filename>,1498 <filename>/path/to/file.vmdk</filename>, 1498 1499 which must be absolute, and partitions 1 and 5 of 1499 1500 <filename>/dev/sda</filename> would be made accessible to the … … 1512 1513 use for example <filename>\\.\PhysicalDrive0</filename>. On a 1513 1514 Mac OS X host, instead of the above device specification use 1514 <filename>/dev/disk1</filename>, for example. Note that on OS 1515 X you can only use partitions which are not mounted. Eject the 1516 respective volume first. Partition numbers are the same on 1517 Linux, Windows, and Mac OS X hosts. 1515 <filename>/dev/rdisk1</filename>, for example. Note that on OS 1516 X you can only use partitions which are not mounted. Unmount 1517 the respective disk first using 1518 <emphasis>diskutil unmountDisk <filename>/dev/diskX</filename></emphasis>. 1519 Partition numbers are the same on Linux, Windows, and Mac OS X hosts. 1518 1520 </para> 1519 1521 … … 1523 1525 </para> 1524 1526 1525 <screen>$ VBoxManage internalcommands listpartitions -rawdisk /dev/sda</screen>1526 1527 <para> 1528 The output lists the partition types and sizes to give the1529 user enough information to identify the partitions necessary1530 for the guest.1527 <screen>$ VBoxManage list hostdrives</screen> 1528 1529 <para> 1530 The output lists available drives and their partitions with 1531 the partition types and sizes to give the user enough information 1532 to identify the partitions necessary for the guest. 1531 1533 </para> 1532 1534 … … 1548 1550 </para> 1549 1551 1550 <screen>$ VBoxManage internalcommands createrawvmdk -filename \ 1551 /path/to/file.vmdk -rawdisk /dev/sda -partitions 1,5 -relative</screen> 1552 <screen>$ VBoxManage createmedium disk --filename /path/to/file.vmdk --format=VMDK 1553 --variant RawDisk --property RawDrive=/dev/sda --property Partitions=1,5 1554 --property Relative=1</screen> 1552 1555 1553 1556 <para> … … 1568 1571 This enables for example the guest to boot directly to 1569 1572 Windows, while the host boots Linux from the "same" disk. For 1570 this purpose the <option>-mbr</option> option is provided. It 1571 specifies a file name from which to take the MBR code. The 1572 partition table is not modified at all, so a MBR file from a 1573 system with totally different partitioning can be used. An 1574 example of this is: 1575 </para> 1576 1577 <screen>$ VBoxManage internalcommands createrawvmdk -filename 1578 /path/to/file.vmdk -rawdisk /dev/sda -partitions 1,5 -mbr winxp.mbr</screen> 1573 this purpose the <option>--property-file 1574 BootSector=/path/to/file/with/boot_sector</option> 1575 parameter is provided. It specifies a file name from which to 1576 take the MBR code. The partition table is not modified at all, 1577 so a MBR file from a system with totally different 1578 partitioning can be used. An example of this is: 1579 </para> 1580 1581 <screen>$ VBoxManage createmedium disk --filename /path/to/file.vmdk --format=VMDK 1582 --variant RawDisk --property RawDrive=/dev/sda --property Partitions=1,5 1583 --property-file BootSector=winxp.mbr</screen> 1579 1584 1580 1585 <para> -
trunk/doc/manual/en_US/user_VBoxManage.xml
r85770 r85929 480 480 Cloud profiles are used when exporting VMs to a cloud service. 481 481 See <xref linkend="cloud-export-oci"/>. 482 </para> 483 </listitem> 484 485 <listitem> 486 <para> 487 <command>hostdrives</command>: Displays a list of host fixed 488 drives with their partitions. If you also specify 489 <option>--long</option> or <option>-l</option> the sizes and 490 offsets will be in bytes. 482 491 </para> 483 492 </listitem> … … 5294 5303 [--diffparent <uuid>|<filename> 5295 5304 [--format VDI|VMDK|VHD] (default: VDI) 5296 [--variant Standard,Fixed,Split2G,Stream,ESX]</screen> 5305 [--variant Standard,Fixed,Split2G,Stream,ESX,RawDisk] 5306 [[--property <name>=<value>] 5307 --property <name>=<value>]... 5308 [[--property-file <name>=</path/to/file/with/value>] 5309 --property-file <name>=</path/to/file/with/value>]...</screen> 5297 5310 5298 5311 <para> … … 5369 5382 combinations are supported, and specifying mutually 5370 5383 incompatible flags results in an error message. Optional. 5384 </para> 5385 </listitem> 5386 </varlistentry> 5387 5388 <varlistentry> 5389 <term> 5390 <computeroutput>--property <name>=<value></computeroutput> 5391 </term> 5392 5393 <listitem> 5394 <para> 5395 Specifies any required file format dependent parameters in 5396 <literal>key=value</literal> form. Optional. 5397 </para> 5398 </listitem> 5399 </varlistentry> 5400 5401 <varlistentry> 5402 <term> 5403 <computeroutput>--property-file <name>=</path/to/file/with/value></computeroutput> 5404 </term> 5405 5406 <listitem> 5407 <para> 5408 Specifies any required file format dependent parameters in 5409 <literal>key=file/with/value</literal> form. The value is 5410 taken from the file. Optional. 5371 5411 </para> 5372 5412 </listitem> -
trunk/include/VBox/com/Guid.h
r82968 r85929 324 324 bool operator<(const RTUUID &guid) const { return ::RTUuidCompare(&mUuid, &guid) < 0; } 325 325 326 /** Compare with a UUID string representation. 327 * @note Not an operator as that could lead to confusion. */ 328 bool equalsString(const char *pszUuid2) const { return ::RTUuidCompareStr(&mUuid, pszUuid2) == 0; } 329 326 330 /** 327 331 * To directly copy the contents to a GUID, or for passing it as an input -
trunk/include/VBox/log.h
r85841 r85929 477 477 /** Main group, IHost. */ 478 478 LOG_GROUP_MAIN_HOST, 479 /** Main group, IHostDrive. */ 480 LOG_GROUP_MAIN_HOSTDRIVE, 481 /** Main group, IHostDriveList. */ 482 LOG_GROUP_MAIN_HOSTDRIVELIST, 483 /** Main group, IHostDrivePartition. */ 484 LOG_GROUP_MAIN_HOSTDRIVEPARTITION, 479 485 /** Main group, IHostNetworkInterface. */ 480 486 LOG_GROUP_MAIN_HOSTNETWORKINTERFACE, … … 981 987 "MAIN_GUESTSESSIONEVENT", \ 982 988 "MAIN_HOST", \ 989 "MAIN_HOSTDRIVE", \ 990 "MAIN_HOSTDRIVELIST", \ 991 "MAIN_HOSTDRIVEPARTITION", \ 983 992 "MAIN_HOSTNETWORKINTERFACE", \ 984 993 "MAIN_HOSTUPDATE", \ -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
r82968 r85929 29 29 30 30 #include <iprt/asm.h> 31 #include <iprt/base64.h> 31 32 #include <iprt/file.h> 32 33 #include <iprt/path.h> … … 38 39 #include <VBox/log.h> 39 40 #include <VBox/vd.h> 41 42 #include <list> 40 43 41 44 #include "VBoxManage.h" … … 96 99 else if (!RTStrNICmp(psz, "formatted", len)) 97 100 uMediumVariant |= MediumVariant_Formatted; 101 else if ( !RTStrNICmp(psz, "raw", len) 102 || !RTStrNICmp(psz, "rawdisk", len)) 103 uMediumVariant |= MediumVariant_VmdkRawDisk; 98 104 else 99 105 rc = VERR_PARSE_ERROR; … … 244 250 { "--variant", 'm', RTGETOPT_REQ_STRING }, 245 251 { "-variant", 'm', RTGETOPT_REQ_STRING }, // deprecated 246 { "--property", 'p', RTGETOPT_REQ_STRING } 252 { "--property", 'p', RTGETOPT_REQ_STRING }, 253 { "--property-file",'P', RTGETOPT_REQ_STRING }, 247 254 }; 248 255 249 256 RTEXITCODE handleCreateMedium(HandlerArg *a) 250 257 { 258 class MediumProperty 259 { 260 public: 261 const char *m_pszKey; 262 const char *m_pszValue; /**< Can be binary too. */ 263 size_t m_cbValue; 264 char *m_pszFreeValue; 265 MediumProperty() : m_pszKey(NULL), m_pszValue(NULL), m_cbValue(0), m_pszFreeValue(NULL) { } 266 MediumProperty(MediumProperty const &a_rThat) 267 : m_pszKey(a_rThat.m_pszKey) 268 , m_pszValue(a_rThat.m_pszValue) 269 , m_cbValue(a_rThat.m_cbValue) 270 , m_pszFreeValue(NULL) 271 { 272 Assert(a_rThat.m_pszFreeValue == NULL); /* not expected here! */ 273 } 274 ~MediumProperty() 275 { 276 RTMemFree(m_pszFreeValue); 277 m_pszFreeValue = NULL; 278 } 279 280 private: 281 MediumProperty &operator=(MediumProperty const &a_rThat) 282 { 283 m_pszKey = a_rThat.m_pszKey; 284 m_pszValue = a_rThat.m_pszValue; 285 m_cbValue = a_rThat.m_cbValue; 286 m_pszFreeValue = a_rThat.m_pszFreeValue; 287 if (a_rThat.m_pszFreeValue != NULL) 288 { 289 m_pszFreeValue = (char *)RTMemAlloc(m_cbValue + 1); 290 if (m_pszFreeValue) 291 { 292 memcpy(m_pszFreeValue, m_pszValue, m_cbValue + 1); 293 m_pszValue = m_pszFreeValue; 294 } 295 else 296 RTMsgError("Out of memory copying '%s'", m_pszValue); 297 } 298 return *this; 299 } 300 }; 301 std::list<MediumProperty> lstProperties; 302 251 303 HRESULT rc; 252 304 int vrc; … … 254 306 const char *diffparent = NULL; 255 307 uint64_t size = 0; 256 typedef struct MEDIUMPROPERTY_LIST257 {258 struct MEDIUMPROPERTY_LIST *next;259 const char *key;260 const char *value;261 } MEDIUMPROPERTY, *PMEDIUMPROPERTY;262 PMEDIUMPROPERTY pMediumProps = NULL;263 308 enum 264 309 { … … 322 367 323 368 case 'p': // --property 369 case 'P': // --property-file 324 370 { 325 371 /* allocate property kvp, parse, and append to end of singly linked list */ 326 # define PROP_MAXLEN 256 327 PMEDIUMPROPERTY pNewProp = (PMEDIUMPROPERTY)RTMemAlloc(sizeof(MEDIUMPROPERTY)); 328 if (!pNewProp) 329 return errorArgument("Can't allocate memory for property '%s'", ValueUnion.psz); 330 size_t cchKvp = RTStrNLen(ValueUnion.psz, PROP_MAXLEN); 331 char *pszEqual = (char *)memchr(ValueUnion.psz, '=', cchKvp); 332 if (pszEqual) 372 char *pszValue = (char *)strchr(ValueUnion.psz, '='); 373 if (!pszValue) 374 return RTMsgErrorExitFailure("Invalid key value pair: No '='."); 375 376 lstProperties.push_back(MediumProperty()); 377 MediumProperty &rNewProp = lstProperties.back(); 378 *pszValue++ = '\0'; /* Warning! Modifies argument string. */ 379 rNewProp.m_pszKey = ValueUnion.psz; 380 if (c == 'p') 333 381 { 334 *pszEqual = '\0'; /* Warning! Modifies argument string. */ 335 pNewProp->next = NULL; 336 pNewProp->key = (char *)ValueUnion.psz; 337 pNewProp->value = pszEqual + 1; 382 rNewProp.m_pszValue = pszValue; 383 rNewProp.m_cbValue = strlen(pszValue); 338 384 } 339 if (pMediumProps)385 else // 'P' 340 386 { 341 PMEDIUMPROPERTY pProp; 342 for (pProp = pMediumProps; pProp->next; pProp = pProp->next) 343 continue; 344 pProp->next = pNewProp; 387 RTFILE hValueFile = NIL_RTFILE; 388 vrc = RTFileOpen(&hValueFile, pszValue, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 389 if (RT_FAILURE(vrc)) 390 return RTMsgErrorExitFailure("Cannot open replacement value file '%s': %Rrc", pszValue, vrc); 391 392 uint64_t cbValue = 0; 393 vrc = RTFileQuerySize(hValueFile, &cbValue); 394 if (RT_SUCCESS(vrc)) 395 { 396 if (cbValue <= _16M) 397 { 398 rNewProp.m_cbValue = (size_t)cbValue; 399 rNewProp.m_pszValue = rNewProp.m_pszFreeValue = (char *)RTMemAlloc(rNewProp.m_cbValue + 1); 400 if (rNewProp.m_pszFreeValue) 401 { 402 vrc = RTFileReadAt(hValueFile, 0, rNewProp.m_pszFreeValue, cbValue, NULL); 403 if (RT_SUCCESS(vrc)) 404 rNewProp.m_pszFreeValue[rNewProp.m_cbValue] = '\0'; 405 else 406 RTMsgError("Error reading replacement MBR file '%s': %Rrc", pszValue, vrc); 407 } 408 else 409 vrc = RTMsgErrorRc(VERR_NO_MEMORY, "Out of memory reading '%s': %Rrc", pszValue, vrc); 410 } 411 else 412 vrc = RTMsgErrorRc(VERR_OUT_OF_RANGE, "Replacement value file '%s' is to big: %Rhcb, max 16MiB", pszValue, cbValue); 413 } 414 else 415 RTMsgError("Cannot get the size of the value file '%s': %Rrc", pszValue, vrc); 416 RTFileClose(hValueFile); 417 if (RT_FAILURE(vrc)) 418 return RTEXITCODE_FAILURE; 345 419 } 346 else347 pMediumProps = pNewProp;348 420 break; 349 421 } … … 389 461 if (fBase) 390 462 { 391 if ( !filename392 || !*filename393 ||size == 0)394 return errorSyntax(USAGE_CREATEMEDIUM, "Parameters -- filename and --size arerequired");463 if (!filename || !*filename) 464 return errorSyntax(USAGE_CREATEMEDIUM, "Parameters --filename is required"); 465 if ((enmMediumVariant & MediumVariant_VmdkRawDisk) == 0 && size == 0) 466 return errorSyntax(USAGE_CREATEMEDIUM, "Parameters --size is required"); 395 467 if (!format || !*format) 396 468 { … … 482 554 if (SUCCEEDED(rc) && pMedium) 483 555 { 484 if (pMediumProps) 485 for (PMEDIUMPROPERTY pProp = pMediumProps; pProp;) 556 if (lstProperties.size() > 0) 557 { 558 ComPtr<IMediumFormat> pMediumFormat; 559 CHECK_ERROR2I_RET(pMedium, COMGETTER(MediumFormat)(pMediumFormat.asOutParam()), RTEXITCODE_FAILURE); 560 com::SafeArray<BSTR> propertyNames; 561 com::SafeArray<BSTR> propertyDescriptions; 562 com::SafeArray<DataType_T> propertyTypes; 563 com::SafeArray<ULONG> propertyFlags; 564 com::SafeArray<BSTR> propertyDefaults; 565 CHECK_ERROR2I_RET(pMediumFormat, 566 DescribeProperties(ComSafeArrayAsOutParam(propertyNames), 567 ComSafeArrayAsOutParam(propertyDescriptions), 568 ComSafeArrayAsOutParam(propertyTypes), 569 ComSafeArrayAsOutParam(propertyFlags), 570 ComSafeArrayAsOutParam(propertyDefaults)), 571 RTEXITCODE_FAILURE); 572 573 for (std::list<MediumProperty>::iterator it = lstProperties.begin(); 574 it != lstProperties.end(); 575 ++it) 486 576 { 487 CHECK_ERROR(pMedium, SetProperty(Bstr(pProp->key).raw(), Bstr(pProp->value).raw())); 488 PMEDIUMPROPERTY next = pProp->next; 489 RTMemFree(pProp); 490 pProp = next; 577 const char * const pszKey = it->m_pszKey; 578 bool fBinary = true; 579 for (size_t i = 0; i < propertyNames.size(); ++i) 580 if (RTUtf16CmpUtf8(propertyNames[i], pszKey) == 0) 581 { 582 fBinary = propertyTypes[i] == DataType_Int8; 583 break; 584 } 585 if (!fBinary) 586 CHECK_ERROR2I_RET(pMedium, SetProperty(Bstr(pszKey).raw(), Bstr(it->m_pszValue).raw()), 587 RTEXITCODE_FAILURE); 588 else 589 { 590 com::Bstr bstrBase64Value; 591 HRESULT hrc = bstrBase64Value.base64Encode(it->m_pszValue, it->m_cbValue); 592 if (FAILED(hrc)) 593 return RTMsgErrorExit(RTEXITCODE_FAILURE, "Base64 encoding of the property %s failed. (%Rhrc)", 594 pszKey, hrc); 595 CHECK_ERROR2I_RET(pMedium, SetProperty(Bstr(pszKey).raw(), bstrBase64Value.raw()), RTEXITCODE_FAILURE); 596 } 491 597 } 598 } 492 599 493 600 ComPtr<IProgress> pProgress; -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
r85778 r85929 480 480 " groups|webcams|screenshotformats|cloudproviders|\n" 481 481 #if defined(VBOX_WITH_CLOUD_NET) 482 " cloudprofiles|cloudnets|cpu-profiles \n"482 " cloudprofiles|cloudnets|cpu-profiles|hostdrives\n" 483 483 #else 484 " cloudprofiles|cpu-profiles \n"484 " cloudprofiles|cpu-profiles|hostdrives\n" 485 485 #endif 486 486 "\n", SEP); … … 1011 1011 " [--format VDI|VMDK|VHD] (default: VDI)]\n" 1012 1012 " [--variant Standard,Fixed,Split2G,Stream,ESX,\n" 1013 " Formatted]\n" 1014 " [[--property <name>=<value>] --property <name>=<value]...\n" 1013 " Formatted,RawDisk]\n" 1014 " [[--property <name>=<value>] --property <name>=<value>\n" 1015 " --property-file <name>=</path/to/file/with/value>]...\n" 1015 1016 "\n", SEP); 1016 1017 -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageList.cpp
r85769 r85929 1415 1415 1416 1416 /** 1417 * Translates PartitionType_T to a string if possible. 1418 * @returns read-only string if known value, @a pszUnknown if not. 1419 */ 1420 static const char *PartitionTypeToString(PartitionType_T enmType, const char *pszUnknown) 1421 { 1422 #define MY_CASE_STR(a_Type) case RT_CONCAT(PartitionType_,a_Type): return #a_Type 1423 switch (enmType) 1424 { 1425 MY_CASE_STR(Empty); 1426 MY_CASE_STR(FAT12); 1427 MY_CASE_STR(FAT16); 1428 MY_CASE_STR(FAT); 1429 MY_CASE_STR(IFS); 1430 MY_CASE_STR(FAT32CHS); 1431 MY_CASE_STR(FAT32LBA); 1432 MY_CASE_STR(FAT16B); 1433 MY_CASE_STR(Extended); 1434 MY_CASE_STR(WindowsRE); 1435 MY_CASE_STR(LinuxSwapOld); 1436 MY_CASE_STR(LinuxOld); 1437 MY_CASE_STR(DragonFlyBSDSlice); 1438 MY_CASE_STR(LinuxSwap); 1439 MY_CASE_STR(Linux); 1440 MY_CASE_STR(LinuxExtended); 1441 MY_CASE_STR(LinuxLVM); 1442 MY_CASE_STR(BSDSlice); 1443 MY_CASE_STR(AppleUFS); 1444 MY_CASE_STR(AppleHFS); 1445 MY_CASE_STR(Solaris); 1446 MY_CASE_STR(GPT); 1447 MY_CASE_STR(EFI); 1448 MY_CASE_STR(Unknown); 1449 MY_CASE_STR(MBR); 1450 MY_CASE_STR(iFFS); 1451 MY_CASE_STR(SonyBoot); 1452 MY_CASE_STR(LenovoBoot); 1453 MY_CASE_STR(WindowsMSR); 1454 MY_CASE_STR(WindowsBasicData); 1455 MY_CASE_STR(WindowsLDMMeta); 1456 MY_CASE_STR(WindowsLDMData); 1457 MY_CASE_STR(WindowsRecovery); 1458 MY_CASE_STR(WindowsStorageSpaces); 1459 MY_CASE_STR(WindowsStorageReplica); 1460 MY_CASE_STR(IBMGPFS); 1461 MY_CASE_STR(LinuxData); 1462 MY_CASE_STR(LinuxRAID); 1463 MY_CASE_STR(LinuxRootX86); 1464 MY_CASE_STR(LinuxRootAMD64); 1465 MY_CASE_STR(LinuxRootARM32); 1466 MY_CASE_STR(LinuxRootARM64); 1467 MY_CASE_STR(LinuxHome); 1468 MY_CASE_STR(LinuxSrv); 1469 MY_CASE_STR(LinuxPlainDmCrypt); 1470 MY_CASE_STR(LinuxLUKS); 1471 MY_CASE_STR(LinuxReserved); 1472 MY_CASE_STR(FreeBSDBoot); 1473 MY_CASE_STR(FreeBSDData); 1474 MY_CASE_STR(FreeBSDSwap); 1475 MY_CASE_STR(FreeBSDUFS); 1476 MY_CASE_STR(FreeBSDVinum); 1477 MY_CASE_STR(FreeBSDZFS); 1478 MY_CASE_STR(FreeBSDUnknown); 1479 MY_CASE_STR(AppleHFSPlus); 1480 MY_CASE_STR(AppleAPFS); 1481 MY_CASE_STR(AppleRAID); 1482 MY_CASE_STR(AppleRAIDOffline); 1483 MY_CASE_STR(AppleBoot); 1484 MY_CASE_STR(AppleLabel); 1485 MY_CASE_STR(AppleTvRecovery); 1486 MY_CASE_STR(AppleCoreStorage); 1487 MY_CASE_STR(SoftRAIDStatus); 1488 MY_CASE_STR(SoftRAIDScratch); 1489 MY_CASE_STR(SoftRAIDVolume); 1490 MY_CASE_STR(SoftRAIDCache); 1491 MY_CASE_STR(AppleUnknown); 1492 MY_CASE_STR(SolarisBoot); 1493 MY_CASE_STR(SolarisRoot); 1494 MY_CASE_STR(SolarisSwap); 1495 MY_CASE_STR(SolarisBackup); 1496 MY_CASE_STR(SolarisUsr); 1497 MY_CASE_STR(SolarisVar); 1498 MY_CASE_STR(SolarisHome); 1499 MY_CASE_STR(SolarisAltSector); 1500 MY_CASE_STR(SolarisReserved); 1501 MY_CASE_STR(SolarisUnknown); 1502 MY_CASE_STR(NetBSDSwap); 1503 MY_CASE_STR(NetBSDFFS); 1504 MY_CASE_STR(NetBSDLFS); 1505 MY_CASE_STR(NetBSDRAID); 1506 MY_CASE_STR(NetBSDConcatenated); 1507 MY_CASE_STR(NetBSDEncrypted); 1508 MY_CASE_STR(NetBSDUnknown); 1509 MY_CASE_STR(ChromeOSKernel); 1510 MY_CASE_STR(ChromeOSRootFS); 1511 MY_CASE_STR(ChromeOSFuture); 1512 MY_CASE_STR(ContLnxUsr); 1513 MY_CASE_STR(ContLnxRoot); 1514 MY_CASE_STR(ContLnxReserved); 1515 MY_CASE_STR(ContLnxRootRAID); 1516 MY_CASE_STR(HaikuBFS); 1517 MY_CASE_STR(MidntBSDBoot); 1518 MY_CASE_STR(MidntBSDData); 1519 MY_CASE_STR(MidntBSDSwap); 1520 MY_CASE_STR(MidntBSDUFS); 1521 MY_CASE_STR(MidntBSDVium); 1522 MY_CASE_STR(MidntBSDZFS); 1523 MY_CASE_STR(MidntBSDUnknown); 1524 MY_CASE_STR(OpenBSDData); 1525 MY_CASE_STR(QNXPowerSafeFS); 1526 MY_CASE_STR(Plan9); 1527 MY_CASE_STR(VMWareVMKCore); 1528 MY_CASE_STR(VMWareVMFS); 1529 MY_CASE_STR(VMWareReserved); 1530 MY_CASE_STR(VMWareUnknown); 1531 MY_CASE_STR(AndroidX86Bootloader); 1532 MY_CASE_STR(AndroidX86Bootloader2); 1533 MY_CASE_STR(AndroidX86Boot); 1534 MY_CASE_STR(AndroidX86Recovery); 1535 MY_CASE_STR(AndroidX86Misc); 1536 MY_CASE_STR(AndroidX86Metadata); 1537 MY_CASE_STR(AndroidX86System); 1538 MY_CASE_STR(AndroidX86Cache); 1539 MY_CASE_STR(AndroidX86Data); 1540 MY_CASE_STR(AndroidX86Persistent); 1541 MY_CASE_STR(AndroidX86Vendor); 1542 MY_CASE_STR(AndroidX86Config); 1543 MY_CASE_STR(AndroidX86Factory); 1544 MY_CASE_STR(AndroidX86FactoryAlt); 1545 MY_CASE_STR(AndroidX86Fastboot); 1546 MY_CASE_STR(AndroidX86OEM); 1547 MY_CASE_STR(AndroidARMMeta); 1548 MY_CASE_STR(AndroidARMExt); 1549 MY_CASE_STR(ONIEBoot); 1550 MY_CASE_STR(ONIEConfig); 1551 MY_CASE_STR(PowerPCPrep); 1552 MY_CASE_STR(XDGShrBootConfig); 1553 MY_CASE_STR(CephBlock); 1554 MY_CASE_STR(CephBlockDB); 1555 MY_CASE_STR(CephBlockDBDmc); 1556 MY_CASE_STR(CephBlockDBDmcLUKS); 1557 MY_CASE_STR(CephBlockDmc); 1558 MY_CASE_STR(CephBlockDmcLUKS); 1559 MY_CASE_STR(CephBlockWALog); 1560 MY_CASE_STR(CephBlockWALogDmc); 1561 MY_CASE_STR(CephBlockWALogDmcLUKS); 1562 MY_CASE_STR(CephDisk); 1563 MY_CASE_STR(CephDiskDmc); 1564 MY_CASE_STR(CephJournal); 1565 MY_CASE_STR(CephJournalDmc); 1566 MY_CASE_STR(CephJournalDmcLUKS); 1567 MY_CASE_STR(CephLockbox); 1568 MY_CASE_STR(CephMultipathBlock1); 1569 MY_CASE_STR(CephMultipathBlock2); 1570 MY_CASE_STR(CephMultipathBlockDB); 1571 MY_CASE_STR(CephMultipathBLockWALog); 1572 MY_CASE_STR(CephMultipathJournal); 1573 MY_CASE_STR(CephMultipathOSD); 1574 MY_CASE_STR(CephOSD); 1575 MY_CASE_STR(CephOSDDmc); 1576 MY_CASE_STR(CephOSDDmcLUKS); 1577 #ifdef VBOX_WITH_XPCOM_CPP_ENUM_HACK 1578 case PartitionType_32BitHack: break; 1579 #endif 1580 /* no default! */ 1581 } 1582 #undef MY_CASE_STR 1583 return pszUnknown; 1584 } 1585 1586 1587 /** 1588 * List all available host drives with their partitions. 1589 * 1590 * @returns See produceList. 1591 * @param pVirtualBox Reference to the IVirtualBox pointer. 1592 * @param fOptLong Long listing or human readable. 1593 */ 1594 static HRESULT listHostDrives(const ComPtr<IVirtualBox> pVirtualBox, bool fOptLong) 1595 { 1596 HRESULT rc = S_OK; 1597 ComPtr<IHost> pHost; 1598 CHECK_ERROR2I_RET(pVirtualBox, COMGETTER(Host)(pHost.asOutParam()), hrcCheck); 1599 com::SafeIfaceArray<IHostDrive> apHostDrives; 1600 CHECK_ERROR2I_RET(pHost, COMGETTER(HostDrives)(ComSafeArrayAsOutParam(apHostDrives)), hrcCheck); 1601 for (size_t i = 0; i < apHostDrives.size(); ++i) 1602 { 1603 ComPtr<IHostDrive> pHostDrive = apHostDrives[i]; 1604 1605 com::Bstr bstrDrivePath; 1606 CHECK_ERROR(pHostDrive,COMGETTER(DrivePath)(bstrDrivePath.asOutParam())); 1607 RTPrintf("%sDrive: %ls\n", i > 0 ? "\n" : "", bstrDrivePath.raw()); 1608 1609 com::Bstr bstrModel; 1610 com::Bstr bstrUuidDisk; 1611 ULONG cbSectorSize = 0; 1612 LONG64 cbSize = 0; 1613 PartitioningType_T partitioningType; 1614 HRESULT hrc; 1615 if ( SUCCEEDED(hrc = pHostDrive->COMGETTER(Model)(bstrModel.asOutParam())) 1616 && SUCCEEDED(hrc = pHostDrive->COMGETTER(Uuid)(bstrUuidDisk.asOutParam())) 1617 && SUCCEEDED(hrc = pHostDrive->COMGETTER(SectorSize)(&cbSectorSize)) 1618 && SUCCEEDED(hrc = pHostDrive->COMGETTER(Size)(&cbSize)) 1619 && SUCCEEDED(hrc = pHostDrive->COMGETTER(PartitioningType)(&partitioningType))) 1620 { 1621 if (bstrModel.isNotEmpty()) 1622 RTPrintf("Model: %ls\n", bstrModel.raw()); 1623 else 1624 RTPrintf("Model: Unknown\n"); 1625 1626 if (partitioningType == PartitioningType_GPT || com::Guid(bstrUuidDisk).isZero()) 1627 RTPrintf("UUID: %ls\n", bstrUuidDisk.raw()); 1628 if (fOptLong) 1629 RTPrintf("Size: %llu bytes (%Rhcb)\n", cbSize, cbSize); 1630 else 1631 RTPrintf("Size: %Rhcb\n", cbSize); 1632 RTPrintf("Sector Size: %u bytes\n", cbSectorSize); 1633 RTPrintf("Scheme: %s\n", partitioningType == PartitioningType_MBR ? "MBR" : "GPT"); 1634 1635 com::SafeIfaceArray<IHostDrivePartition> apHostDrivesPartitions; 1636 CHECK_ERROR(pHostDrive, COMGETTER(Partitions)(ComSafeArrayAsOutParam(apHostDrivesPartitions))); 1637 1638 if (partitioningType == PartitioningType_MBR) 1639 { 1640 if (fOptLong) 1641 RTPrintf("Partitions: First Last\n" 1642 "## Type Byte Size Byte Offset Cyl/Head/Sec Cyl/Head/Sec Active\n"); 1643 else 1644 RTPrintf("Partitions: First Last\n" 1645 "## Type Size Start Cyl/Head/Sec Cyl/Head/Sec Active\n"); 1646 for (size_t j = 0; j < apHostDrivesPartitions.size(); ++j) 1647 { 1648 ComPtr<IHostDrivePartition> pHostDrivePartition = apHostDrivesPartitions[j]; 1649 1650 ULONG idx = 0; 1651 CHECK_ERROR(pHostDrivePartition, COMGETTER(Number)(&idx)); 1652 ULONG uType = 0; 1653 CHECK_ERROR(pHostDrivePartition, COMGETTER(TypeMBR)(&uType)); 1654 ULONG uStartCylinder = 0; 1655 CHECK_ERROR(pHostDrivePartition, COMGETTER(StartCylinder)(&uStartCylinder)); 1656 ULONG uStartHead = 0; 1657 CHECK_ERROR(pHostDrivePartition, COMGETTER(StartHead)(&uStartHead)); 1658 ULONG uStartSector = 0; 1659 CHECK_ERROR(pHostDrivePartition, COMGETTER(StartSector)(&uStartSector)); 1660 ULONG uEndCylinder = 0; 1661 CHECK_ERROR(pHostDrivePartition, COMGETTER(EndCylinder)(&uEndCylinder)); 1662 ULONG uEndHead = 0; 1663 CHECK_ERROR(pHostDrivePartition, COMGETTER(EndHead)(&uEndHead)); 1664 ULONG uEndSector = 0; 1665 CHECK_ERROR(pHostDrivePartition, COMGETTER(EndSector)(&uEndSector)); 1666 cbSize = 0; 1667 CHECK_ERROR(pHostDrivePartition, COMGETTER(Size)(&cbSize)); 1668 LONG64 offStart = 0; 1669 CHECK_ERROR(pHostDrivePartition, COMGETTER(Start)(&offStart)); 1670 BOOL fActive = 0; 1671 CHECK_ERROR(pHostDrivePartition, COMGETTER(Active)(&fActive)); 1672 PartitionType_T enmType = PartitionType_Unknown; 1673 CHECK_ERROR(pHostDrivePartition, COMGETTER(Type)(&enmType)); 1674 1675 /* Max size & offset here is around 16TiB with 4KiB sectors. */ 1676 if (fOptLong) /* cb/off: max 16TiB; idx: max 64. */ 1677 RTPrintf("%2u %02x %14llu %14llu %4u/%3u/%2u %4u/%3u/%2u %s %s\n", 1678 idx, uType, cbSize, offStart, 1679 uStartCylinder, uStartHead, uStartSector, uEndCylinder, uEndHead, uEndSector, 1680 fActive ? "yes" : "no", PartitionTypeToString(enmType, "")); 1681 else 1682 RTPrintf("%2u %02x %8Rhcb %8Rhcb %4u/%3u/%2u %4u/%3u/%2u %s %s\n", 1683 idx, uType, (uint64_t)cbSize, (uint64_t)offStart, 1684 uStartCylinder, uStartHead, uStartSector, uEndCylinder, uEndHead, uEndSector, 1685 fActive ? "yes" : "no", PartitionTypeToString(enmType, "")); 1686 } 1687 } 1688 else /* GPT */ 1689 { 1690 /* Determin the max partition type length to try reduce the table width: */ 1691 size_t cchMaxType = 0; 1692 for (size_t j = 0; j < apHostDrivesPartitions.size(); ++j) 1693 { 1694 ComPtr<IHostDrivePartition> pHostDrivePartition = apHostDrivesPartitions[j]; 1695 PartitionType_T enmType = PartitionType_Unknown; 1696 CHECK_ERROR(pHostDrivePartition, COMGETTER(Type)(&enmType)); 1697 size_t const cchTypeNm = strlen(PartitionTypeToString(enmType, "e530bf6d-2754-4e9d-b260-60a5d0b80457")); 1698 cchMaxType = RT_MAX(cchTypeNm, cchMaxType); 1699 } 1700 cchMaxType = RT_MIN(cchMaxType, RTUUID_STR_LENGTH); 1701 1702 if (fOptLong) 1703 RTPrintf("Partitions:\n" 1704 "## %-*s Uuid Byte Size Byte Offset Active Name\n", 1705 (int)cchMaxType, "Type"); 1706 else 1707 RTPrintf("Partitions:\n" 1708 "## %-*s Uuid Size Start Active Name\n", 1709 (int)cchMaxType, "Type"); 1710 1711 for (size_t j = 0; j < apHostDrivesPartitions.size(); ++j) 1712 { 1713 ComPtr<IHostDrivePartition> pHostDrivePartition = apHostDrivesPartitions[j]; 1714 1715 ULONG idx = 0; 1716 CHECK_ERROR(pHostDrivePartition, COMGETTER(Number)(&idx)); 1717 com::Bstr bstrUuidType; 1718 CHECK_ERROR(pHostDrivePartition, COMGETTER(TypeUuid)(bstrUuidType.asOutParam())); 1719 com::Bstr bstrUuidPartition; 1720 CHECK_ERROR(pHostDrivePartition, COMGETTER(Uuid)(bstrUuidPartition.asOutParam())); 1721 cbSize = 0; 1722 CHECK_ERROR(pHostDrivePartition, COMGETTER(Size)(&cbSize)); 1723 LONG64 offStart = 0; 1724 CHECK_ERROR(pHostDrivePartition, COMGETTER(Start)(&offStart)); 1725 BOOL fActive = 0; 1726 CHECK_ERROR(pHostDrivePartition, COMGETTER(Active)(&fActive)); 1727 com::Bstr bstrName; 1728 CHECK_ERROR(pHostDrivePartition, COMGETTER(Name)(bstrName.asOutParam())); 1729 1730 PartitionType_T enmType = PartitionType_Unknown; 1731 CHECK_ERROR(pHostDrivePartition, COMGETTER(Type)(&enmType)); 1732 1733 Utf8Str strTypeConv; 1734 const char *pszTypeNm = PartitionTypeToString(enmType, NULL); 1735 if (!pszTypeNm) 1736 pszTypeNm = (strTypeConv = bstrUuidType).c_str(); 1737 else if (strlen(pszTypeNm) >= RTUUID_STR_LENGTH /* includes '\0' */) 1738 pszTypeNm -= RTUUID_STR_LENGTH - 1 - strlen(pszTypeNm); 1739 1740 if (fOptLong) 1741 RTPrintf("%2u %-*s %36ls %19llu %19llu %-3s %ls\n", idx, cchMaxType, pszTypeNm, 1742 bstrUuidPartition.raw(), cbSize, offStart, fActive ? "on" : "off", bstrName.raw()); 1743 else 1744 RTPrintf("%2u %-*s %36ls %8Rhcb %8Rhcb %-3s %ls\n", idx, cchMaxType, pszTypeNm, 1745 bstrUuidPartition.raw(), cbSize, offStart, fActive ? "on" : "off", bstrName.raw()); 1746 } 1747 } 1748 } 1749 else 1750 RTPrintf("Partitions and disk info for the drive %ls are not available. Error %Rhrc (%#RX32)\n", 1751 bstrDrivePath.raw(), hrc, hrc); 1752 } 1753 return rc; 1754 } 1755 1756 1757 /** 1417 1758 * The type of lists we can produce. 1418 1759 */ … … 1450 1791 kListCloudProviders, 1451 1792 kListCloudProfiles, 1452 kListCPUProfiles 1793 kListCPUProfiles, 1794 kListHostDrives 1453 1795 }; 1454 1796 … … 1807 2149 break; 1808 2150 2151 case kListHostDrives: 2152 rc = listHostDrives(pVirtualBox, fOptLong); 2153 break; 1809 2154 /* No default here, want gcc warnings. */ 1810 2155 … … 1865 2210 { "cloudprofiles", kListCloudProfiles, RTGETOPT_REQ_NOTHING }, 1866 2211 { "cpu-profiles", kListCPUProfiles, RTGETOPT_REQ_NOTHING }, 2212 { "hostdrives", kListHostDrives, RTGETOPT_REQ_NOTHING }, 1867 2213 }; 1868 2214 … … 1922 2268 case kListCloudProfiles: 1923 2269 case kListCPUProfiles: 2270 case kListHostDrives: 1924 2271 enmOptCommand = (enum ListType_T)ch; 1925 2272 if (fOptMultiple) -
trunk/src/VBox/Main/Makefile.kmk
r85737 r85929 582 582 src-server/HostUpdateImpl.cpp \ 583 583 src-server/HostVideoInputDeviceImpl.cpp \ 584 src-server/HostDrivePartitionImpl.cpp \ 585 src-server/HostDriveImpl.cpp \ 584 586 src-server/MachineImpl.cpp \ 585 587 src-all/MachineLaunchVMCommonWorker.cpp \ … … 653 655 src-server/freebsd/HostHardwareFreeBSD.cpp \ 654 656 src-server/HostDnsServiceResolvConf.cpp 657 658 VBoxSVC_LDFLAGS.freebsd += -lcam 655 659 656 660 -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r85769 r85929 1535 1535 </const> 1536 1536 </enum> 1537 1538 <enum 1539 name="PartitioningType" 1540 uuid="64c4c806-8908-4c0b-9a51-2d7a0151321f" 1541 > 1542 <desc> 1543 The type of the disk partition. 1544 </desc> 1545 1546 <const name="MBR" value="0"/> 1547 <const name="GPT" value="1"/> 1548 </enum> 1549 1550 <enum 1551 name="PartitionType" 1552 uuid="84a6629c-8e9c-474c-adbb-21995671597f" 1553 > 1554 <desc></desc> 1555 1556 <!-- MBR partition IDs using the same value: --> 1557 <const name="Empty" value="0"><desc>Empty partition entry</desc></const> 1558 <const name="FAT12" value="1"> <desc>FAT12 if partition size less than 65536 sectors</desc></const> 1559 <const name="FAT16" value="4"> <desc>FAT16 if partition size less than 65536 sectors</desc></const> 1560 <const name="FAT" value="6"> <desc>FAT12 or FAT16 if partition size greater or equal than 65536 sectors</desc></const> 1561 <const name="IFS" value="7"> <desc>NT and OS/2 installable file system, e.g. NTFS, exFAT, HPFS.</desc></const> 1562 <const name="FAT32CHS" value="11"> <desc>The FAT32 with CHS addressing.</desc></const> 1563 <const name="FAT32LBA" value="12"> <desc>The FAT32 with LBA addressing.</desc></const> 1564 <const name="FAT16B" value="14"> <desc>The FAT16 with LBA addressing.</desc></const> 1565 <const name="Extended" value="15"> <desc>The extended partition with LBA addressing.</desc></const> 1566 <const name="WindowsRE" value="39"> <desc>Windows Recovery Environment (RE) partition (hidden NTFS partition).</desc></const> 1567 <const name="LinuxSwapOld" value="66"> <desc>The linux swap partition (old versions).</desc></const> 1568 <const name="LinuxOld" value="67"> <desc>The linux native partition (old versions).</desc></const> 1569 <const name="DragonFlyBSDSlice" value="108"><desc>The BSD slice.</desc></const> 1570 <const name="LinuxSwap" value="130"><desc>The linux swap partition.</desc></const> 1571 <const name="Linux" value="131"><desc>The linux native partition.</desc></const> 1572 <const name="LinuxExtended" value="133"><desc>The linux extended partition.</desc></const> 1573 <const name="LinuxLVM" value="142"><desc>The linux LVM partition.</desc></const> 1574 <const name="BSDSlice" value="165"><desc>The BSD slice.</desc></const> 1575 <const name="AppleUFS" value="168"><desc>The Apple UFS partition.</desc></const> 1576 <const name="AppleHFS" value="175"><desc>The Apple HFS partition.</desc></const> 1577 <const name="Solaris" value="191"><desc>The Apple HFS partition.</desc></const> 1578 <const name="GPT" value="238"><desc>The GPT protective MBR partition.</desc></const> 1579 <const name="EFI" value="239"><desc>The EFI system partition.</desc></const> 1580 1581 <!-- Dummy value: --> 1582 <const name="Unknown" value="256"><desc>Unknown partition type.</desc></const> 1583 1584 <!-- GPT partition types: --> 1585 <const name="MBR" value="257"><desc>MBR partition scheme.</desc></const> 1586 <const name="iFFS" value="258"><desc>Intel Fast Flash (iFFS) partition.</desc></const> 1587 <const name="SonyBoot" value="259"><desc>Sony boot partition.</desc></const> 1588 <const name="LenovoBoot" value="260"><desc>Lenovo boot partition.</desc></const> 1589 1590 <const name="WindowsMSR" value="270"><desc>Microsoft Reserved Partition (MSR).</desc></const> 1591 <const name="WindowsBasicData" value="271"><desc>Windows Basic data partition</desc></const> 1592 <const name="WindowsLDMMeta" value="272"><desc>Windows Logical Disk Manager (LDM) metadata partition.</desc></const> 1593 <const name="WindowsLDMData" value="273"><desc>Windows Logical Disk Manager data partition.</desc></const> 1594 <const name="WindowsRecovery" value="274"><desc>Windows Recovery Environment.</desc></const> 1595 <const name="WindowsStorageSpaces" value="276"><desc>Windows Storage Spaces partition.</desc></const> 1596 <const name="WindowsStorageReplica" value="277"><desc>Windows Storage Replica partition.</desc></const> 1597 <const name="IBMGPFS" value="275"><desc>IBM General Parallel File System (GPFS) partition.</desc></const> 1598 1599 <const name="LinuxData" value="300"><desc>Linux filesystem data.</desc></const> 1600 <const name="LinuxRAID" value="301"><desc>Linux RAID partition.</desc></const> 1601 <const name="LinuxRootX86" value="302"><desc>Linux root partition for x86.</desc></const> 1602 <const name="LinuxRootAMD64" value="303"><desc>Linux root partition for AMD64.</desc></const> 1603 <const name="LinuxRootARM32" value="304"><desc>Linux root partition for ARM32.</desc></const> 1604 <const name="LinuxRootARM64" value="305"><desc>Linux root partition for ARM64 / AArch64.</desc></const> 1605 <const name="LinuxHome" value="306"><desc>Linux /home partition.</desc></const> 1606 <const name="LinuxSrv" value="307"><desc>Linux /srv partition..</desc></const> 1607 <const name="LinuxPlainDmCrypt" value="308"><desc>Linux plain dm-crypt partition.</desc></const> 1608 <const name="LinuxLUKS" value="309"><desc>Linux unitified key setup (LUKS) partition.</desc></const> 1609 <const name="LinuxReserved" value="310"><desc>Linux reserved partition.</desc></const> 1610 1611 <const name="FreeBSDBoot" value="330"><desc>FreeBSD boot partition.</desc></const> 1612 <const name="FreeBSDData" value="331"><desc>FreeBSD data partition.</desc></const> 1613 <const name="FreeBSDSwap" value="332"><desc>FreeBSD swap partition.</desc></const> 1614 <const name="FreeBSDUFS" value="333"><desc>FreeBSD unix file system (UFS) partition.</desc></const> 1615 <const name="FreeBSDVinum" value="334"><desc>FreeBSD Vinum volume manager partition.</desc></const> 1616 <const name="FreeBSDZFS" value="335"><desc>FreeBSD ZFS partition.</desc></const> 1617 <const name="FreeBSDUnknown" value="359"><desc>Unknown FreeBSD partition.</desc></const> 1618 1619 <const name="AppleHFSPlus" value="360"><desc>Apple hierarchical file system plus (HFS+) partition.</desc></const> 1620 <const name="AppleAPFS" value="361"><desc>Apple APFS/FileFault container partition.</desc></const> 1621 <const name="AppleRAID" value="362"><desc>Apple RAID partition.</desc></const> 1622 <const name="AppleRAIDOffline" value="363"><desc>Apple RAID partition, offline.</desc></const> 1623 <const name="AppleBoot" value="364"><desc>Apple boot partition.</desc></const> 1624 <const name="AppleLabel" value="365"><desc>Apple label.</desc></const> 1625 <const name="AppleTvRecovery" value="366"><desc>Apple TV recovery partition.</desc></const> 1626 <const name="AppleCoreStorage" value="367"><desc>Apple Core Storage Containe.</desc></const> 1627 <const name="SoftRAIDStatus" value="370"><desc>SoftRAID status.</desc></const> 1628 <const name="SoftRAIDScratch" value="371"><desc>SoftRAID scratch.</desc></const> 1629 <const name="SoftRAIDVolume" value="372"><desc>SoftRAID volume.</desc></const> 1630 <const name="SoftRAIDCache" value="373"><desc>SoftRAID cache.</desc></const> 1631 <const name="AppleUnknown" value="389"><desc>Unknown Apple partition.</desc></const> 1632 1633 <const name="SolarisBoot" value="390"><desc>Solaris boot partition.</desc></const> 1634 <const name="SolarisRoot" value="391"><desc>Solaris root partition.</desc></const> 1635 <const name="SolarisSwap" value="392"><desc>Solaris swap partition.</desc></const> 1636 <const name="SolarisBackup" value="393"><desc>Solaris backup partition.</desc></const> 1637 <const name="SolarisUsr" value="394"><desc>Solaris /usr partition.</desc></const> 1638 <const name="SolarisVar" value="395"><desc>Solaris /var partition.</desc></const> 1639 <const name="SolarisHome" value="396"><desc>Solaris /home partition.</desc></const> 1640 <const name="SolarisAltSector" value="397"><desc>Solaris alternate sector.</desc></const> 1641 <const name="SolarisReserved" value="398"><desc>Solaris reserved partition.</desc></const> 1642 <const name="SolarisUnknown" value="419"><desc>Unknown Solaris partition.</desc></const> 1643 1644 <const name="NetBSDSwap" value="420"><desc>NetBSD swap partition.</desc></const> 1645 <const name="NetBSDFFS" value="421"><desc>NetBSD fast file system (FFS) partition.</desc></const> 1646 <const name="NetBSDLFS" value="422"><desc>NetBSD log structured file system (LFS) partition.</desc></const> 1647 <const name="NetBSDRAID" value="423"><desc>NetBSD RAID partition.</desc></const> 1648 <const name="NetBSDConcatenated" value="424"><desc>NetBSD concatenated partition.</desc></const> 1649 <const name="NetBSDEncrypted" value="425"><desc>NetBSD encrypted partition.</desc></const> 1650 <const name="NetBSDUnknown" value="449"><desc>Unknown NetBSD partition.</desc></const> 1651 1652 <const name="ChromeOSKernel" value="450"><desc>Chrome OS kernel partition.</desc></const> 1653 <const name="ChromeOSRootFS" value="451"><desc>Chrome OS root file system partition.</desc></const> 1654 <const name="ChromeOSFuture" value="452"><desc>Chrome OS partition reserved for future.</desc></const> 1655 1656 <const name="ContLnxUsr" value="480"><desc>Container Linux /usr partition.</desc></const> 1657 <const name="ContLnxRoot" value="481"><desc>Container Linux resizable root filesystem partition.</desc></const> 1658 <const name="ContLnxReserved" value="482"><desc>Container Linux OEM customization partition.</desc></const> 1659 <const name="ContLnxRootRAID" value="483"><desc>Container Linux root filesystem on RAID partition.</desc></const> 1660 1661 <const name="HaikuBFS" value="510"><desc>Haiku BFS</desc></const> 1662 1663 <const name="MidntBSDBoot" value="540"><desc>MidnightBSD boot partition.</desc></const> 1664 <const name="MidntBSDData" value="541"><desc>MidnightBSD data partition.</desc></const> 1665 <const name="MidntBSDSwap" value="542"><desc>MidnightBSD swap partition.</desc></const> 1666 <const name="MidntBSDUFS" value="543"><desc>MidnightBSD unix file system (UFS) partition.</desc></const> 1667 <const name="MidntBSDVium" value="544"><desc>MidnightBSD Vinum volume manager partition.</desc></const> 1668 <const name="MidntBSDZFS" value="545"><desc>MidnightBSD ZFS partition.</desc></const> 1669 <const name="MidntBSDUnknown" value="569"><desc>Unknown MidnightBSD partition.</desc></const> 1670 1671 <const name="OpenBSDData" value="570"><desc>OpenBSD data partition.</desc></const> 1672 1673 <const name="QNXPowerSafeFS" value="600"><desc>QNX power-safe file system partition.</desc></const> 1674 1675 <const name="Plan9" value="630"><desc>Plan 9 partition.</desc></const> 1676 1677 <const name="VMWareVMKCore" value="660"><desc>VMWare ESX coredump partition.</desc></const> 1678 <const name="VMWareVMFS" value="661"><desc>VMWare ESX virtual machine file system (VMFS) partition.</desc></const> 1679 <const name="VMWareReserved" value="662"><desc>VMWare ESX reserved partition.</desc></const> 1680 <const name="VMWareUnknown" value="689"><desc>Unknown VMWare partition.</desc></const> 1681 1682 <const name="AndroidX86Bootloader" value="690"><desc>Android x86 bootloader partition.</desc></const> 1683 <const name="AndroidX86Bootloader2" value="691"><desc>Android x86 bootloader2 partition.</desc></const> 1684 <const name="AndroidX86Boot" value="692"><desc>Android x86 boot partition.</desc></const> 1685 <const name="AndroidX86Recovery" value="693"><desc>Android x86 recovery partition.</desc></const> 1686 <const name="AndroidX86Misc" value="694"><desc>Android x86 misc partition.</desc></const> 1687 <const name="AndroidX86Metadata" value="695"><desc>Android x86 metadata partition.</desc></const> 1688 <const name="AndroidX86System" value="696"><desc>Android x86 system partition.</desc></const> 1689 <const name="AndroidX86Cache" value="697"><desc>Android x86 cache partition.</desc></const> 1690 <const name="AndroidX86Data" value="698"><desc>Android x86 data partition.</desc></const> 1691 <const name="AndroidX86Persistent" value="699"><desc>Android x86 persistent data partition.</desc></const> 1692 <const name="AndroidX86Vendor" value="700"><desc>Android x86 vendor partition.</desc></const> 1693 <const name="AndroidX86Config" value="701"><desc>Android x86 config partition.</desc></const> 1694 <const name="AndroidX86Factory" value="702"><desc>Android x86 factory partition.</desc></const> 1695 <const name="AndroidX86FactoryAlt" value="703"><desc>Android x86 alternative factory partition.</desc></const> 1696 <const name="AndroidX86Fastboot" value="704"><desc>Android x86 fastboot partition.</desc></const> 1697 <const name="AndroidX86OEM" value="705"><desc>Android x86 OEM partition.</desc></const> 1698 1699 <const name="AndroidARMMeta" value="720"><desc>Android ARM meta partition.</desc></const> 1700 <const name="AndroidARMExt" value="721"><desc>Android ARM EXT partition.</desc></const> 1701 1702 <const name="ONIEBoot" value="750"><desc>Open Network Install Environment (ONIE) boot partition.</desc></const> 1703 <const name="ONIEConfig" value="751"><desc>Open Network Install Environment (ONIE) config partition.</desc></const> 1704 1705 <const name="PowerPCPrep" value="780"><desc>PowerPC PReP boot partition.</desc></const> 1706 1707 <const name="XDGShrBootConfig" value="810"><desc>freedesktop.org shared boot loader configuration partition.</desc></const> 1708 1709 <const name="CephBlock" value="830"><desc>Ceph block partition.</desc></const> 1710 <const name="CephBlockDB" value="831"><desc>Ceph block DB partition.</desc></const> 1711 <const name="CephBlockDBDmc" value="832"><desc>Ceph dm-crypt block DB partition.</desc></const> 1712 <const name="CephBlockDBDmcLUKS" value="833"><desc>Ceph dm-crypt Linux unitified key setup (LUKS) block DB partition.</desc></const> 1713 <const name="CephBlockDmc" value="834"><desc>Ceph dm-crypt block partition.</desc></const> 1714 <const name="CephBlockDmcLUKS" value="835"><desc>Ceph dm-crypt Linux unitified key setup (LUKS) block partition.</desc></const> 1715 <const name="CephBlockWALog" value="836"><desc>Ceph block write-ahead log partition.</desc></const> 1716 <const name="CephBlockWALogDmc" value="837"><desc>Ceph dm-crypt block write-ahead log partition.</desc></const> 1717 <const name="CephBlockWALogDmcLUKS" value="838"><desc>Ceph dm-crypt Linux unitified key setup (LUKS) block write-ahead log partition.</desc></const> 1718 <const name="CephDisk" value="839"><desc>Ceph disk in creation partition.</desc></const> 1719 <const name="CephDiskDmc" value="840"><desc>Ceph dm-crypt disk in creation partition.</desc></const> 1720 <const name="CephJournal" value="841"><desc>Ceph Journal partition.</desc></const> 1721 <const name="CephJournalDmc" value="842"><desc>Ceph dm-crypt journal partition.</desc></const> 1722 <const name="CephJournalDmcLUKS" value="843"><desc>Ceph dm-crypt Linux unitified key setup (LUKS) journal partition.</desc></const> 1723 <const name="CephLockbox" value="844"><desc>Ceph Lockbox for dm-crypt keys partition.</desc></const> 1724 <const name="CephMultipathBlock1" value="845"><desc>Ceph multipath block 1 partition.</desc></const> 1725 <const name="CephMultipathBlock2" value="846"><desc>Ceph multipath block 2 partition.</desc></const> 1726 <const name="CephMultipathBlockDB" value="847"><desc>Ceph multipath block DB partition.</desc></const> 1727 <const name="CephMultipathBLockWALog" value="848"><desc>Ceph multipath block write-ahead log partition.</desc></const> 1728 <const name="CephMultipathJournal" value="849"><desc>Ceph multipath journal partition.</desc></const> 1729 <const name="CephMultipathOSD" value="851"><desc>Ceph multipath object storage deamon (OSD) partition.</desc></const> 1730 <const name="CephOSD" value="852"><desc>Ceph object storage deamon (OSD) partition.</desc></const> 1731 <const name="CephOSDDmc" value="853"><desc>Ceph dm-crypt object storage deamon (OSD) partition.</desc></const> 1732 <const name="CephOSDDmcLUKS" value="854"><desc>Ceph dm-crypt Linux unitified key setup (LUKS) object storage deamon (OSD) partition.</desc></const> 1733 </enum> 1734 1537 1735 1538 1736 <!-- … … 10300 10498 10301 10499 <interface 10500 name="IHostDrivePartition" extends="$unknown" 10501 uuid="4f529a14-ace3-407c-9c49-066e8e8027f0" 10502 wsmap="struct" 10503 > 10504 <desc> 10505 The IHostDrivePartition interface represents the partition of the host drive. 10506 To enumerate all available drives partitions in the host, use the 10507 <link to="IHost::hostDrives"/> attribute. 10508 </desc> 10509 10510 <attribute name="number" type="unsigned long" readonly="yes"> 10511 <desc> 10512 The number of the partition. 10513 <!-- @todo r=bird: This is weird numbering scheme for MBR disk as it goes 1,2,3,4,5,7,9,11,... 10514 And has no practical use. It would be better to use the system specific device node numbering here. --> 10515 </desc> 10516 </attribute> 10517 10518 <attribute name="size" type="long long" readonly="yes"> 10519 <desc> 10520 The partition size in bytes. 10521 </desc> 10522 </attribute> 10523 10524 <attribute name="start" type="long long" readonly="yes"> 10525 <desc> 10526 The start byte offset of this partition in bytes relative to the 10527 beginning of the hard disk. 10528 </desc> 10529 </attribute> 10530 10531 <attribute name="type" type="PartitionType" readonly="yes"> 10532 <desc> 10533 A translation of <link to="IHostDrivePartition::typeMBR"/> and 10534 <link to="IHostDrivePartition::typeUuid"/> when possible, otherwise 10535 set to <link to="PartitionType::Unknown" />. 10536 </desc> 10537 </attribute> 10538 10539 <attribute name="active" type="boolean" readonly="yes"> 10540 <desc> 10541 The partition is bootable when TRUE. 10542 </desc> 10543 </attribute> 10544 10545 <!-- MBR: --> 10546 10547 <attribute name="typeMBR" type="unsigned long" readonly="yes"> 10548 <desc> 10549 The raw MBR partition type, 0 for non-MBR disks. 10550 </desc> 10551 </attribute> 10552 10553 <attribute name="startCylinder" type="unsigned long" readonly="yes"> 10554 <desc> 10555 The cylinder (0..1023) of the first sector in the partition on an MBR disk, zero for not an MBR disk. 10556 </desc> 10557 </attribute> 10558 10559 <attribute name="startHead" type="unsigned long" readonly="yes"> 10560 <desc> 10561 The head (0..255) of the first sector in the partition on an MBR disk, zero for not an MBR disk. 10562 </desc> 10563 </attribute> 10564 10565 <attribute name="startSector" type="unsigned long" readonly="yes"> 10566 <desc> 10567 The sector (0..63) of the first sector in the partition on an MBR disk, zero for not an MBR disk. 10568 </desc> 10569 </attribute> 10570 10571 <attribute name="endCylinder" type="unsigned long" readonly="yes"> 10572 <desc> 10573 The cylinder (0..1023) of the last sector (inclusive) in the partition on an MBR disk, zero for not an MBR disk. 10574 </desc> 10575 </attribute> 10576 10577 <attribute name="endHead" type="unsigned long" readonly="yes"> 10578 <desc> 10579 The head (0..255) of the last sector (inclusive) in the partition on an MBR disk, zero for not an MBR disk. 10580 </desc> 10581 </attribute> 10582 10583 <attribute name="endSector" type="unsigned long" readonly="yes"> 10584 <desc> 10585 The sector (1..63) of the last sector (inclusive) in the partition on an MBR disk, zero for not an MBR disk. 10586 </desc> 10587 </attribute> 10588 10589 <!-- GPT: --> 10590 <attribute name="typeUuid" type="uuid" mod="string" readonly="yes"> 10591 <!-- @todo r=bird: Not sure about the casing here. typeUUID Klaus? --> 10592 <desc> 10593 The partition type when GUID partitioning scheme is used, NULL UUID value for not a GPT disks. 10594 </desc> 10595 </attribute> 10596 10597 <attribute name="uuid" type="uuid" mod="string" readonly="yes"> 10598 <desc> 10599 The GUID of the partition when GUID partitioning scheme is used, NULL UUID value for not a GPT disks. 10600 </desc> 10601 </attribute> 10602 10603 <attribute name="name" type="wstring" readonly="yes"> 10604 <desc> 10605 The name of the partition if GPT partitioning is used, empty if not a GPT disk. 10606 </desc> 10607 </attribute> 10608 10609 </interface> 10610 10611 <interface 10612 name="IHostDrive" extends="$unknown" 10613 uuid="70e2e0c3-332c-4d72-b822-2db16e2cb31b" 10614 wsmap="managed" 10615 > 10616 <desc> 10617 The IHostDrive interface represents the drive of the physical machine. 10618 It is not complete medium description and, therefore, it is not IMedium 10619 based. The interface is used just for getting a host drive partitions info. 10620 </desc> 10621 10622 <attribute name="drivePath" type="wstring" readonly="yes" wrap-hint-server="limitedcaller"> 10623 <desc> 10624 The path of the drive. Platform dependent. 10625 </desc> 10626 </attribute> 10627 10628 <attribute name="partitioningType" type="PartitioningType" readonly="yes"> 10629 <desc> 10630 The scheme of the partitions the disk has. 10631 </desc> 10632 </attribute> 10633 10634 <attribute name="uuid" type="uuid" mod="string" readonly="yes"> 10635 <desc> 10636 The GUID of the disk. 10637 </desc> 10638 </attribute> 10639 10640 <attribute name="sectorSize" type="unsigned long" readonly="yes"> 10641 <desc> 10642 The size of the sector in bytes. 10643 </desc> 10644 </attribute> 10645 10646 <attribute name="size" type="long long" readonly="yes"> 10647 <desc> 10648 The size of the disk in bytes. 10649 </desc> 10650 </attribute> 10651 10652 <attribute name="model" type="wstring" readonly="yes"> 10653 <desc> 10654 The model string of the drive if available. 10655 </desc> 10656 </attribute> 10657 10658 <attribute name="partitions" type="IHostDrivePartition" readonly="yes" safearray="yes"> 10659 <desc>List of partitions available on the host drive.</desc> 10660 </attribute> 10661 10662 </interface> 10663 10664 <interface 10302 10665 name="IHost" extends="$unknown" 10303 uuid=" 16ced992-5fdc-4aba-aff5-6a39bbd7c38b"10666 uuid="fc0759a6-a5e2-41e1-93ca-64776335eb2d" 10304 10667 wsmap="managed" 10305 10668 reservedMethods="6" reservedAttributes="12" … … 10391 10754 <attribute name="processorOnlineCoreCount" type="unsigned long" readonly="yes"> 10392 10755 <desc>Number of physical processor cores online in the host system.</desc> 10756 </attribute> 10757 10758 <attribute name="hostDrives" type="IHostDrive" readonly="yes" safearray="yes"> 10759 <desc>List of the host drive available to use in the VirtualBox.</desc> 10393 10760 </attribute> 10394 10761 -
trunk/src/VBox/Main/include/AutoCaller.h
r82968 r85929 333 333 334 334 /** 335 * Sets the initialization status to Succeeded to indicate limited 336 * (partly successful) initialization but also adds the initialization 337 * error if required for further reporting. The AutoInitSpan destructor 338 * will place the managed VirtualBoxBase object to the Limited state. 339 */ 340 void setLimited(HRESULT rc) 341 { 342 mResult = Limited; 343 mFailedRC = rc; 344 mpFailedEI = new ErrorInfo(); 345 } 346 347 /** 335 348 * Sets the initialization status to Failure to indicates failed 336 349 * initialization. The AutoInitSpan destructor will place the managed -
trunk/src/VBox/Main/include/HostHardwareLinux.h
r82968 r85929 69 69 * @returns iprt status code 70 70 */ 71 int updateFloppies() ;71 int updateFloppies() RT_NOEXCEPT; 72 72 73 73 /** … … 76 76 * @returns iprt status code 77 77 */ 78 int updateDVDs(); 78 int updateDVDs() RT_NOEXCEPT; 79 80 /** 81 * Search for fixed disks (HDDs) and rebuild the list, which remains empty until 82 * the first time this method is called. 83 * @returns iprt status code 84 */ 85 int updateFixedDrives() RT_NOEXCEPT; 79 86 80 87 /** Get the first element in the list of floppy drives. */ … … 101 108 return mDVDList.end(); 102 109 } 110 111 /** Get the first element in the list of fixed drives. */ 112 DriveInfoList::const_iterator FixedDriveBegin() 113 { 114 return mFixedDriveList.begin(); 115 } 116 117 /** Get the last element in the list of fixed drives. */ 118 DriveInfoList::const_iterator FixedDriveEnd() 119 { 120 return mFixedDriveList.end(); 121 } 103 122 private: 104 123 /** The list of currently available floppy drives */ … … 106 125 /** The list of currently available DVD drives */ 107 126 DriveInfoList mDVDList; 127 /** The list of currently available fixed drives */ 128 DriveInfoList mFixedDriveList; 108 129 }; 109 130 -
trunk/src/VBox/Main/include/HostImpl.h
r85683 r85929 29 29 class Progress; 30 30 class PerformanceCollector; 31 class HostDrive; 32 class HostDrivePartition; 31 33 32 34 namespace settings … … 109 111 HRESULT getProcessorCoreCount(ULONG *aProcessorCoreCount); 110 112 HRESULT getProcessorOnlineCoreCount(ULONG *aProcessorOnlineCoreCount); 113 HRESULT getHostDrives(std::vector<ComPtr<IHostDrive> > &aHostDrives); 111 114 HRESULT getMemorySize(ULONG *aMemorySize); 112 115 HRESULT getMemoryAvailable(ULONG *aMemoryAvailable); … … 177 180 bool i_getDVDInfoFromHal(std::list< ComObjPtr<Medium> > &list); 178 181 bool i_getFloppyInfoFromHal(std::list< ComObjPtr<Medium> > &list); 182 HRESULT i_getFixedDrivesFromHal(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &list) RT_NOEXCEPT; 179 183 #endif 180 184 … … 183 187 void i_parseMountTable(char *mountTable, std::list< ComObjPtr<Medium> > &list); 184 188 bool i_validateDevice(const char *deviceNode, bool isCDROM); 189 HRESULT i_getFixedDrivesFromDevTree(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &list) RT_NOEXCEPT; 185 190 #endif 186 191 … … 199 204 #endif /* VBOX_WITH_RESOURCE_USAGE_API */ 200 205 206 HRESULT i_getDrivesPathsList(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &aDriveList) RT_NOEXCEPT; 207 201 208 struct Data; // opaque data structure, defined in HostImpl.cpp 202 209 Data *m; -
trunk/src/VBox/Main/src-all/AutoCaller.cpp
r82968 r85929 294 294 } 295 295 296 if (aNewState == InitFailed )296 if (aNewState == InitFailed || aNewState == Limited) 297 297 { 298 298 mFailedRC = aFailedRC; 299 /* apFailedEI may be NULL, when there is no explicit setFailed() call, 300 * which also implies that aFailedRC is S_OK. This case is used by 301 * objects (the majority) which don't want delayed error signalling. */ 299 /* apFailedEI may be NULL, when there is no explicit setFailed() or 300 * setLimited() call, which also implies that aFailedRC is S_OK. 301 * This case is used by objects (the majority) which don't want 302 * delayed error signalling. */ 302 303 mpFailedEI = apFailedEI; 303 304 } -
trunk/src/VBox/Main/src-all/GlobalStatusConversion.cpp
r82968 r85929 108 108 case VERR_NOT_EQUAL: return VBOX_E_FILE_ERROR; 109 109 case VERR_FILE_NOT_FOUND: return VBOX_E_OBJECT_NOT_FOUND; 110 case VERR_IO_NOT_READY: return VBOX_E_INVALID_OBJECT_STATE; 110 111 111 112 /* Guest Control errors. */ -
trunk/src/VBox/Main/src-server/HostImpl.cpp
r85769 r85929 113 113 typedef SOLARISDVD *PSOLARISDVD; 114 114 115 /** Solaris fixed drive (SSD, HDD, ++) descriptor list entry as returned by the 116 * solarisWalkDeviceNodeForFixedDrive callback. */ 117 typedef SOLARISDVD SOLARISFIXEDDISK; 118 /** Pointer to a Solaris fixed drive (SSD, HDD, ++) descriptor. */ 119 typedef SOLARISFIXEDDISK *PSOLARISFIXEDDISK; 115 120 116 121 … … 136 141 137 142 #include <iprt/asm-amd64-x86.h> 138 #include <iprt/string.h> 143 #ifdef RT_OS_SOLARIS 144 # include <iprt/ctype.h> 145 #endif 146 #if defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) 147 # include <iprt/file.h> 148 #endif 139 149 #include <iprt/mp.h> 140 #include <iprt/time.h>141 #include <iprt/param.h>142 150 #include <iprt/env.h> 143 151 #include <iprt/mem.h> 152 #include <iprt/param.h> 153 #include <iprt/string.h> 144 154 #include <iprt/system.h> 145 155 #ifndef RT_OS_WINDOWS 146 156 # include <iprt/path.h> 147 157 #endif 148 #ifdef RT_OS_SOLARIS 149 # include <iprt/ctype.h> 150 #endif 158 #include <iprt/time.h> 159 151 160 #ifdef VBOX_WITH_HOSTNETIF_API 152 161 # include "netif.h" … … 169 178 170 179 #include "HostDnsService.h" 180 #include "HostDriveImpl.h" 181 #include "HostDrivePartitionImpl.h" 171 182 172 183 //////////////////////////////////////////////////////////////////////////////// … … 1971 1982 1972 1983 1984 HRESULT Host::getHostDrives(std::vector<ComPtr<IHostDrive> > &aHostDrives) 1985 { 1986 std::list<std::pair<com::Utf8Str, com::Utf8Str> > llDrivesPathsList; 1987 HRESULT hrc = i_getDrivesPathsList(llDrivesPathsList); 1988 if (SUCCEEDED(hrc)) 1989 { 1990 for (std::list<std::pair<com::Utf8Str, com::Utf8Str> >::const_iterator it = llDrivesPathsList.begin(); 1991 it != llDrivesPathsList.end(); 1992 ++it) 1993 { 1994 ComObjPtr<HostDrive> pHostDrive; 1995 hrc = pHostDrive.createObject(); 1996 if (SUCCEEDED(hrc)) 1997 hrc = pHostDrive->initFromPathAndModel(it->first, it->second); 1998 if (FAILED(hrc)) 1999 break; 2000 aHostDrives.push_back(pHostDrive); 2001 } 2002 } 2003 return hrc; 2004 } 2005 2006 1973 2007 // public methods only for internal purposes 1974 2008 //////////////////////////////////////////////////////////////////////////////// … … 2558 2592 static char *solarisGetSliceFromPath(const char *pszDevLinkPath) 2559 2593 { 2560 char *psz Found = NULL;2561 char *psz Slice = strrchr(pszDevLinkPath, 's');2562 char *psz Disk = strrchr(pszDevLinkPath, 'd');2563 if (pszSlice && pszSlice >pszDisk)2594 char *pszSlice = (char *)strrchr(pszDevLinkPath, 's'); 2595 char *pszDisk = (char *)strrchr(pszDevLinkPath, 'd'); 2596 char *pszFound; 2597 if (pszSlice && (uintptr_t)pszSlice > (uintptr_t)pszDisk) 2564 2598 pszFound = pszSlice; 2565 2599 else … … 2576 2610 * 2577 2611 * @param DevLink Handle to the device link being walked. 2578 * @param pvArg Opaque data containing the pointer to the path. 2579 * @returns Pointer to an allocated device path string. 2612 * @param pvArg Opaque pointer that we use to point to the return 2613 * variable (char *). Caller must call RTStrFree on it. 2614 * @returns DI_WALK_TERMINATE to stop the walk. 2580 2615 */ 2581 2616 static int solarisWalkDevLink(di_devlink_t DevLink, void *pvArg) 2582 2617 { 2583 2618 char **ppszPath = (char **)pvArg; 2584 *ppszPath = strdup(di_devlink_path(DevLink));2619 *ppszPath = RTStrDup(di_devlink_path(DevLink)); 2585 2620 return DI_WALK_TERMINATE; 2586 2621 } … … 2655 2690 RTStrPrintf(pDrive->szDescription, sizeof(pDrive->szDescription), 2656 2691 "%s %s", pszVendor, pszProduct); 2692 RTStrPurgeEncoding(pDrive->szDescription); 2657 2693 RTStrCopy(pDrive->szRawDiskPath, sizeof(pDrive->szRawDiskPath), pszDevLinkPath); 2658 2694 if (*ppDrives) … … 2661 2697 2662 2698 /* We're not interested in any of the other slices, stop minor nodes traversal. */ 2663 free(pszDevLinkPath);2699 RTStrFree(pszDevLinkPath); 2664 2700 break; 2665 2701 } 2666 2702 } 2667 free(pszDevLinkPath);2703 RTStrFree(pszDevLinkPath); 2668 2704 } 2669 2705 } … … 2703 2739 } 2704 2740 2741 2742 /** 2743 * Walk all devices in the system and enumerate fixed drives. 2744 * @param Node Handle to the current node. 2745 * @param pvArg Opaque data (holds list pointer). 2746 * @returns Solaris specific code whether to continue walking or not. 2747 */ 2748 static int solarisWalkDeviceNodeForFixedDrive(di_node_t Node, void *pvArg) RT_NOEXCEPT 2749 { 2750 PSOLARISFIXEDDISK *ppDrives = (PSOLARISFIXEDDISK *)pvArg; 2751 2752 int *pInt = NULL; 2753 if ( di_prop_lookup_ints(DDI_DEV_T_ANY, Node, "inquiry-device-type", &pInt) > 0 2754 && *pInt == DTYPE_DIRECT) /* Fixed drive */ 2755 { 2756 char *pszProduct = NULL; 2757 if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "inquiry-product-id", &pszProduct) > 0) 2758 { 2759 char *pszVendor = NULL; 2760 if (di_prop_lookup_strings(DDI_DEV_T_ANY, Node, "inquiry-vendor-id", &pszVendor) > 0) 2761 { 2762 /* 2763 * Found a fixed drive, we need to scan the minor nodes to find the correct 2764 * slice that represents the whole drive. 2765 */ 2766 int Major = di_driver_major(Node); 2767 di_minor_t Minor = DI_MINOR_NIL; 2768 di_devlink_handle_t DevLink = di_devlink_init(NULL /* name */, 0 /* flags */); 2769 if (DevLink) 2770 { 2771 /* 2772 * The device name we have to select depends on drive type. For fixed drives, the 2773 * name without slice or partition should be selected, for USB flash drive the 2774 * partition 0 should be selected and slice 0 for other cases. 2775 */ 2776 char *pszDisk = NULL; 2777 char *pszPartition0 = NULL; 2778 char *pszSlice0 = NULL; 2779 while ((Minor = di_minor_next(Node, Minor)) != DI_MINOR_NIL) 2780 { 2781 dev_t Dev = di_minor_devt(Minor); 2782 if ( Major != (int)major(Dev) 2783 || di_minor_spectype(Minor) == S_IFBLK 2784 || di_minor_type(Minor) != DDM_MINOR) 2785 continue; 2786 2787 char *pszMinorPath = di_devfs_minor_path(Minor); 2788 if (!pszMinorPath) 2789 continue; 2790 2791 char *pszDevLinkPath = NULL; 2792 di_devlink_walk(DevLink, NULL, pszMinorPath, DI_PRIMARY_LINK, &pszDevLinkPath, solarisWalkDevLink); 2793 di_devfs_path_free(pszMinorPath); 2794 2795 if (pszDevLinkPath) 2796 { 2797 char const *pszCurSlice = strrchr(pszDevLinkPath, 's'); 2798 char const *pszCurDisk = strrchr(pszDevLinkPath, 'd'); 2799 char const *pszCurPart = strrchr(pszDevLinkPath, 'p'); 2800 char **ppszDst = NULL; 2801 if (pszCurSlice && (uintptr_t)pszCurSlice > (uintptr_t)pszCurDisk && !strcmp(pszCurSlice, "s0")) 2802 ppszDst = &pszSlice0; 2803 else if (pszCurPart && (uintptr_t)pszCurPart > (uintptr_t)pszCurDisk && !strcmp(pszCurPart, "p0")) 2804 ppszDst = &pszPartition0; 2805 else if ( (!pszCurSlice || (uintptr_t)pszCurSlice < (uintptr_t)pszCurDisk) 2806 && (!pszCurPart || (uintptr_t)pszCurPart < (uintptr_t)pszCurDisk) 2807 && *pszDevLinkPath != '\0') 2808 ppszDst = &pszDisk; 2809 else 2810 RTStrFree(pszDevLinkPath); 2811 if (ppszDst) 2812 { 2813 if (*ppszDst != NULL) 2814 RTStrFree(*ppszDst); 2815 *ppszDst = pszDevLinkPath; 2816 } 2817 } 2818 } 2819 di_devlink_fini(&DevLink); 2820 if (pszDisk || pszPartition0 || pszSlice0) 2821 { 2822 PSOLARISFIXEDDISK pDrive = (PSOLARISFIXEDDISK)RTMemAllocZ(sizeof(*pDrive)); 2823 if (RT_LIKELY(pDrive)) 2824 { 2825 RTStrPrintf(pDrive->szDescription, sizeof(pDrive->szDescription), "%s %s", pszVendor, pszProduct); 2826 RTStrPurgeEncoding(pDrive->szDescription); 2827 2828 const char *pszDevPath = pszDisk ? pszDisk : pszPartition0 ? pszPartition0 : pszSlice0; 2829 int rc = RTStrCopy(pDrive->szRawDiskPath, sizeof(pDrive->szRawDiskPath), pszDevPath); 2830 AssertRC(rc); 2831 2832 if (*ppDrives) 2833 pDrive->pNext = *ppDrives; 2834 *ppDrives = pDrive; 2835 } 2836 RTStrFree(pszDisk); 2837 RTStrFree(pszPartition0); 2838 RTStrFree(pszSlice0); 2839 } 2840 } 2841 } 2842 } 2843 } 2844 return DI_WALK_CONTINUE; 2845 } 2846 2847 2848 /** 2849 * Solaris specific function to enumerate fixed drives via the device tree. 2850 * Works on Solaris 10 as well as OpenSolaris without depending on libhal. 2851 * 2852 * @returns COM status, either S_OK or E_OUTOFMEMORY. 2853 * @param list Reference to list where the the path/model pairs are to 2854 * be returned. 2855 */ 2856 HRESULT Host::i_getFixedDrivesFromDevTree(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &list) RT_NOEXCEPT 2857 { 2858 PSOLARISFIXEDDISK pDrives = NULL; 2859 di_node_t RootNode = di_init("/", DINFOCPYALL); 2860 if (RootNode != DI_NODE_NIL) 2861 di_walk_node(RootNode, DI_WALK_CLDFIRST, &pDrives, solarisWalkDeviceNodeForFixedDrive); 2862 di_fini(RootNode); 2863 2864 HRESULT hrc = S_OK; 2865 try 2866 { 2867 for (PSOLARISFIXEDDISK pCurDrv = pDrives; pCurDrv; pCurDrv = pCurDrv->pNext) 2868 list.push_back(std::pair<com::Utf8Str, com::Utf8Str>(pCurDrv->szRawDiskPath, pCurDrv->szDescription)); 2869 } 2870 catch (std::bad_alloc &) 2871 { 2872 LogRelFunc(("Out of memory!\n")); 2873 list.clear(); 2874 hrc = E_OUTOFMEMORY; 2875 } 2876 2877 while (pDrives) 2878 { 2879 PSOLARISFIXEDDISK pFreeMe = pDrives; 2880 pDrives = pDrives->pNext; 2881 ASMCompilerBarrier(); 2882 RTMemFree(pFreeMe); 2883 } 2884 2885 return hrc; 2886 } 2887 2888 2705 2889 /* Solaris hosts, loading libhal at runtime */ 2706 2890 … … 2710 2894 * 2711 2895 * @returns true if information was successfully obtained, false otherwise 2712 * @ retval list drives found will be attached to this list2896 * @param list Reference to list where the DVDs drives are to be returned. 2713 2897 */ 2714 2898 bool Host::i_getDVDInfoFromHal(std::list<ComObjPtr<Medium> > &list) … … 3021 3205 return halSuccess; 3022 3206 } 3207 3208 3209 /** 3210 * Helper function to query the hal subsystem for information about fixed drives attached to the 3211 * system. 3212 * 3213 * @returns COM status code. (setError is not called on failure as we only fail 3214 * with E_OUTOFMEMORY.) 3215 * @retval S_OK on success. 3216 * @retval S_FALSE if HAL cannot be used. 3217 * @param list Reference to list to return the path/model string pairs. 3218 */ 3219 HRESULT Host::i_getFixedDrivesFromHal(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &list) RT_NOEXCEPT 3220 { 3221 HRESULT hrc = S_FALSE; 3222 if (!gLibHalCheckPresence()) 3223 return hrc; 3224 3225 DBusError dbusError; 3226 gDBusErrorInit(&dbusError); 3227 DBusConnection *dbusConnection = gDBusBusGet(DBUS_BUS_SYSTEM, &dbusError); 3228 if (dbusConnection != 0) 3229 { 3230 LibHalContext *halContext = gLibHalCtxNew(); 3231 if (halContext != 0) 3232 { 3233 if (gLibHalCtxSetDBusConnection(halContext, dbusConnection)) 3234 { 3235 if (gLibHalCtxInit(halContext, &dbusError)) 3236 { 3237 int cDevices; 3238 char **halDevices = gLibHalFindDeviceStringMatch(halContext, "storage.drive_type", "disk", 3239 &cDevices, &dbusError); 3240 if (halDevices != 0) 3241 { 3242 /* Hal is installed and working, so if no devices are reported, assume 3243 that there are none. */ 3244 hrc = S_OK; 3245 for (int i = 0; i < cDevices && hrc == S_OK; i++) 3246 { 3247 char *pszDevNode = gLibHalDeviceGetPropertyString(halContext, halDevices[i], "block.device", 3248 &dbusError); 3249 /* The fixed drive ioctls work only for raw device nodes. */ 3250 char *pszTmp = getfullrawname(pszDevNode); 3251 gLibHalFreeString(pszDevNode); 3252 pszDevNode = pszTmp; 3253 if (pszDevNode != 0) 3254 { 3255 /* We do not check the error here, as this field may 3256 not even exist. */ 3257 char *pszVendor = gLibHalDeviceGetPropertyString(halContext, halDevices[i], "info.vendor", 0); 3258 char *pszProduct = gLibHalDeviceGetPropertyString(halContext, halDevices[i], "info.product", 3259 &dbusError); 3260 Utf8Str strDescription; 3261 if (pszProduct != NULL && pszProduct[0] != '\0') 3262 { 3263 int rc; 3264 if (pszVendor != NULL && pszVendor[0] != '\0') 3265 vrc = strDescription.printfNoThrow("%s %s", pszVendor, pszProduct); 3266 else 3267 vrc = strDescription.assignNoThrow(pszProduct); 3268 AssertRCStmt(vrc, hrc = E_OUTOFMEMORY); 3269 } 3270 if (pszVendor != NULL) 3271 gLibHalFreeString(pszVendor); 3272 if (pszProduct != NULL) 3273 gLibHalFreeString(pszProduct); 3274 3275 /* Correct device/partition/slice already choosen. Just add it to the return list */ 3276 if (hrc == S_OK) 3277 try 3278 { 3279 list.push_back(std::pair<com::Utf8Str, com::Utf8Str>(pszDevNode, strDescription)); 3280 } 3281 catch (std::bad_alloc &) 3282 { 3283 AssertFailedStmt(hrc = E_OUTOFMEMORY); 3284 } 3285 gLibHalFreeString(pszDevNode); 3286 } 3287 else 3288 { 3289 LogRel(("Host::COMGETTER(HostDrives): failed to get property \"block.device\" for device %s. dbus error: %s (%s)\n", 3290 halDevices[i], dbusError.name, dbusError.message)); 3291 gDBusErrorFree(&dbusError); 3292 } 3293 } 3294 gLibHalFreeStringArray(halDevices); 3295 } 3296 else 3297 { 3298 LogRel(("Host::COMGETTER(HostDrives): failed to get devices with capability \"storage.disk\". dbus error: %s (%s)\n", dbusError.name, dbusError.message)); 3299 gDBusErrorFree(&dbusError); 3300 } 3301 if (!gLibHalCtxShutdown(halContext, &dbusError)) /* what now? */ 3302 { 3303 LogRel(("Host::COMGETTER(HostDrives): failed to shutdown the libhal context. dbus error: %s (%s)\n", 3304 dbusError.name, dbusError.message)); 3305 gDBusErrorFree(&dbusError); 3306 } 3307 } 3308 else 3309 { 3310 LogRel(("Host::COMGETTER(HostDrives): failed to initialise libhal context. dbus error: %s (%s)\n", 3311 dbusError.name, dbusError.message)); 3312 gDBusErrorFree(&dbusError); 3313 } 3314 gLibHalCtxFree(halContext); 3315 } 3316 else 3317 LogRel(("Host::COMGETTER(HostDrives): failed to set libhal connection to dbus.\n")); 3318 } 3319 else 3320 LogRel(("Host::COMGETTER(HostDrives): failed to get a libhal context - out of memory?\n")); 3321 gDBusConnectionUnref(dbusConnection); 3322 } 3323 else 3324 { 3325 LogRel(("Host::COMGETTER(HostDrives): failed to connect to dbus. dbus error: %s (%s)\n", 3326 dbusError.name, dbusError.message)); 3327 gDBusErrorFree(&dbusError); 3328 } 3329 return hrc; 3330 } 3331 3023 3332 #endif /* RT_OS_SOLARIS and VBOX_USE_HAL */ 3024 3333 … … 3574 3883 } 3575 3884 3885 /** 3886 * @throws nothing 3887 */ 3888 HRESULT Host::i_getDrivesPathsList(std::list<std::pair<com::Utf8Str, com::Utf8Str> > &aDriveList) RT_NOEXCEPT 3889 { 3890 #ifdef RT_OS_WINDOWS 3891 /** @todo r=bird: This approach is seriously flawed. The "Count" value refers to 3892 * the registry entries next to it and as little if anything to do with 3893 * PhysicalDriveX numbering. The registry entries doesn't immediately give 3894 * you the PhysicalDrive address either. 3895 * 3896 * One option would be to enumerate the \Device or \GLOBAL?? directories looking 3897 * for Harddisk* directories and PhysicalDrive* symlinks respectively. This can 3898 * be explored using 3899 * - "out\win.amd64\debug\bin\tools\RTLs.exe -la \\:iprtnt:\Device" 3900 * - "out\win.amd64\debug\bin\tools\RTLs.exe -la \\:iprtnt:\GLOBAL??" 3901 * - WinObj from sysinternals. 3902 * 3903 * "wmic diskdrive list" somehow gets the info too. There is more here: 3904 * https://stackoverflow.com/questions/327718/how-to-list-physical-disks 3905 * 3906 * A third option would be to just be to go significantly higher than what 3907 * "Count" indicates, to span gaps and stuff. 3908 * 3909 * 3910 * How to create gaps in the PhysicalDriveX numbers: 3911 * 1. Insert 2 USB sticks to you box. 3912 * 2. Remove the first USB stick you inserted. 3913 * 3. You've got a gap: RTLs -la \\:iprtnt:\GLOBAL?? | grep PhysicalDrive 3914 */ 3915 HKEY hKeyEnum = (HKEY)INVALID_HANDLE_VALUE; 3916 LONG lRc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 3917 L"SYSTEM\\CurrentControlSet\\Services\\Disk\\Enum", 3918 0, 3919 KEY_READ | KEY_QUERY_VALUE, 3920 &hKeyEnum); 3921 if (lRc != ERROR_SUCCESS) 3922 return setError(E_FAIL, tr("Failed to open key Disk\\Enum (error %u/%#x)"), lRc, lRc); 3923 3924 DWORD cCount = 0; 3925 DWORD cBufSize = sizeof(cCount); 3926 lRc = RegQueryValueExW(hKeyEnum, L"Count", NULL, NULL, (PBYTE)&cCount, &cBufSize); 3927 RegCloseKey(hKeyEnum); 3928 if (lRc != ERROR_SUCCESS) 3929 return setError(E_FAIL, tr("Failed to get physical drives count (error %u/%#x)"), lRc, lRc); 3930 3931 for (uint32_t i = 0; i < cCount; ++i) 3932 { 3933 char szPhysicalDrive[64]; 3934 RTStrPrintf(szPhysicalDrive, sizeof(szPhysicalDrive), "\\\\.\\PhysicalDrive%d", i); 3935 3936 /** @todo r=bird: Why RTFILE_O_DENY_WRITE? */ 3937 RTFILE hRawFile = NIL_RTFILE; 3938 int vrc = RTFileOpen(&hRawFile, szPhysicalDrive, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE); 3939 if (RT_FAILURE(vrc)) 3940 continue; /** @todo r=bird: you might not be able to open all disks... */ 3941 3942 DWORD cbBytesReturned = 0; 3943 uint8_t abBuffer[1024]; 3944 RT_ZERO(abBuffer); 3945 3946 STORAGE_PROPERTY_QUERY query; 3947 RT_ZERO(query); 3948 query.PropertyId = StorageDeviceProperty; 3949 query.QueryType = PropertyStandardQuery; 3950 3951 BOOL fRc = DeviceIoControl((HANDLE)RTFileToNative(hRawFile), 3952 IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), 3953 abBuffer, sizeof(abBuffer), &cbBytesReturned, NULL); 3954 RTFileClose(hRawFile); 3955 char szModel[1024]; 3956 if (fRc) 3957 { 3958 PSTORAGE_DEVICE_DESCRIPTOR pDevDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)abBuffer; 3959 char *pszProduct = pDevDescriptor->ProductIdOffset ? (char *)&abBuffer[pDevDescriptor->ProductIdOffset] : NULL; 3960 if (pszProduct) 3961 { 3962 RTStrPurgeEncoding(pszProduct); 3963 if (*pszProduct != '\0') 3964 { 3965 char *pszVendor = pDevDescriptor->VendorIdOffset ? (char *)&abBuffer[pDevDescriptor->VendorIdOffset] : NULL; 3966 if (pszVendor) 3967 RTStrPurgeEncoding(pszVendor); 3968 if (pszVendor && *pszVendor) 3969 RTStrPrintf(szModel, sizeof(szModel), "%s %s", pszVendor, pszProduct); 3970 else 3971 RTStrCopy(szModel, sizeof(szModel), pszProduct); 3972 } 3973 } 3974 } 3975 try 3976 { 3977 aDriveList.push_back(std::pair<com::Utf8Str, com::Utf8Str>(szPhysicalDrive, szModel)); 3978 } 3979 catch (std::bad_alloc &) 3980 { 3981 aDriveList.clear(); 3982 return E_OUTOFMEMORY; 3983 } 3984 } 3985 3986 return S_OK; 3987 3988 #elif defined(RT_OS_DARWIN) 3989 /* 3990 * Get the list of fixed drives from iokit.cpp and transfer it to aDriveList. 3991 */ 3992 PDARWINFIXEDDRIVE pDrives = DarwinGetFixedDrives(); 3993 HRESULT hrc; 3994 try 3995 { 3996 for (PDARWINFIXEDDRIVE pCurDrv = pDrives; pCurDrv; pCurDrv = pCurDrv->pNext) 3997 aDriveList.push_back(std::pair<com::Utf8Str, com::Utf8Str>(pCurDrv->szName, pCurDrv->pszModel)); 3998 hrc = S_OK; 3999 } 4000 catch (std::bad_alloc &) 4001 { 4002 aDriveList.clear(); 4003 hrc = E_OUTOFMEMORY; 4004 } 4005 4006 while (pDrives) 4007 { 4008 PDARWINFIXEDDRIVE pFreeMe = pDrives; 4009 pDrives = pDrives->pNext; 4010 ASMCompilerBarrier(); 4011 RTMemFree(pFreeMe); 4012 } 4013 return hrc; 4014 4015 #elif defined(RT_OS_LINUX) || defined(RT_OS_FREEBSD) 4016 /* 4017 * The list of fixed drives is kept in the VBoxMainDriveInfo instance, so 4018 * update it and tranfer the info to aDriveList. 4019 * 4020 * This obviously requires us to write lock the object! 4021 */ 4022 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); 4023 int vrc = m->hostDrives.updateFixedDrives(); /* nothrow */ 4024 if (RT_FAILURE(vrc)) 4025 return setErrorBoth(E_FAIL, vrc, tr("Failed to update fixed drive list (%Rrc)"), vrc); 4026 4027 try 4028 { 4029 for (DriveInfoList::const_iterator it = m->hostDrives.FixedDriveBegin(); it != m->hostDrives.FixedDriveEnd(); ++it) 4030 aDriveList.push_back(std::pair<com::Utf8Str, com::Utf8Str>(it->mDevice, it->mDescription)); 4031 } 4032 catch (std::bad_alloc &) 4033 { 4034 aDriveList.clear(); 4035 return E_OUTOFMEMORY; 4036 } 4037 return S_OK; 4038 4039 #elif defined(RT_OS_SOLARIS) 4040 /* 4041 * We can get the info from HAL, if not present/working we'll get by 4042 * walking the device tree. 4043 */ 4044 # ifdef VBOX_USE_LIBHAL 4045 HRESULT hrc = i_getFixedDrivesFromHal(aDriveList); 4046 if (hrc != S_FALSE) 4047 return hrc; 4048 aDriveList.clear(); /* just in case */ 4049 # endif 4050 return i_getFixedDrivesFromDevTree(aDriveList); 4051 4052 #else 4053 /* PORTME */ 4054 RT_NOREF(aDriveList); 4055 return E_NOTIMPL; 4056 #endif 4057 } 4058 3576 4059 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/src-server/darwin/iokit.cpp
r85272 r85929 31 31 #include <mach/mach.h> 32 32 #include <Carbon/Carbon.h> 33 #include <CoreFoundation/CFBase.h> 33 34 #include <IOKit/IOKitLib.h> 35 #include <IOKit/IOBSD.h> 34 36 #include <IOKit/storage/IOStorageDeviceCharacteristics.h> 37 #include <IOKit/storage/IOBlockStorageDevice.h> 38 #include <IOKit/storage/IOMedia.h> 39 #include <IOKit/storage/IOCDMedia.h> 35 40 #include <IOKit/scsi/SCSITaskLib.h> 36 41 #include <SystemConfiguration/SystemConfiguration.h> 37 42 #include <mach/mach_error.h> 43 #include <sys/param.h> 44 #include <paths.h> 38 45 #ifdef VBOX_WITH_USB 39 46 # include <IOKit/usb/IOUSBLib.h> 40 47 # include <IOKit/IOCFPlugIn.h> 41 # include <IOKit/storage/IOMedia.h>42 48 #endif 43 49 … … 1570 1576 1571 1577 IOObjectRelease(DVDServices); 1578 1579 return pHead; 1580 } 1581 1582 1583 /** 1584 * Enumerate the fixed drives (HDDs, SSD, ++) returning a FIFO of device paths 1585 * strings and model strings separated by ':'. 1586 * 1587 * @returns Pointer to the head. 1588 * The caller is responsible for calling RTMemFree() on each of the nodes. 1589 */ 1590 PDARWINFIXEDDRIVE DarwinGetFixedDrives(void) 1591 { 1592 AssertReturn(darwinOpenMasterPort(), NULL); 1593 1594 /* 1595 * Create a matching dictionary for searching drives in the IOKit. 1596 * 1597 * The idea is to find all the IOMedia objects with "Whole"="True" which identify the disks but 1598 * not partitions. 1599 */ 1600 CFMutableDictionaryRef RefMatchingDict = IOServiceMatching("IOMedia"); 1601 AssertReturn(RefMatchingDict, NULL); 1602 CFDictionaryAddValue(RefMatchingDict, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); 1603 1604 /* 1605 * Perform the search and get a collection of IOMedia objects. 1606 */ 1607 io_iterator_t MediaServices = IO_OBJECT_NULL; 1608 IOReturn rc = IOServiceGetMatchingServices(g_MasterPort, RefMatchingDict, &MediaServices); 1609 AssertMsgReturn(rc == kIOReturnSuccess, ("rc=%d\n", rc), NULL); 1610 RefMatchingDict = NULL; /* the reference is consumed by IOServiceGetMatchingServices. */ 1611 1612 /* 1613 * Enumerate the matching services. 1614 * (This enumeration must be identical to the one performed in DrvHostBase.cpp.) 1615 */ 1616 PDARWINFIXEDDRIVE pHead = NULL; 1617 PDARWINFIXEDDRIVE pTail = NULL; 1618 unsigned i = 0; 1619 io_object_t MediaService; 1620 while ((MediaService = IOIteratorNext(MediaServices)) != IO_OBJECT_NULL) 1621 { 1622 DARWIN_IOKIT_DUMP_OBJ(MediaService); 1623 1624 /* 1625 * Find the IOMedia parents having the IOBlockStorageDevice type and check they have "device-type" = "Generic". 1626 * If the IOMedia object hasn't IOBlockStorageDevices with such device-type in parents the one is not general 1627 * disk but either CDROM-like device or some another device which has no interest for the function. 1628 */ 1629 1630 /* 1631 * Just avoid parents enumeration if the IOMedia is IOCDMedia, i.e. CDROM-like disk 1632 */ 1633 if (IOObjectConformsTo(MediaService, kIOCDMediaClass)) 1634 { 1635 IOObjectRelease(MediaService); 1636 continue; 1637 } 1638 1639 bool fIsGenericStorage = false; 1640 io_registry_entry_t ChildEntry = MediaService; 1641 io_registry_entry_t ParentEntry = IO_OBJECT_NULL; 1642 kern_return_t krc = KERN_SUCCESS; 1643 while ( !fIsGenericStorage 1644 && (krc = IORegistryEntryGetParentEntry(ChildEntry, kIOServicePlane, &ParentEntry)) == KERN_SUCCESS) 1645 { 1646 if (!IOObjectIsEqualTo(ChildEntry, MediaService)) 1647 IOObjectRelease(ChildEntry); 1648 1649 DARWIN_IOKIT_DUMP_OBJ(ParentEntry); 1650 if (IOObjectConformsTo(ParentEntry, kIOBlockStorageDeviceClass)) 1651 { 1652 CFTypeRef DeviceTypeValueRef = IORegistryEntryCreateCFProperty(ParentEntry, 1653 CFSTR("device-type"), 1654 kCFAllocatorDefault, 0); 1655 if ( DeviceTypeValueRef 1656 && CFGetTypeID(DeviceTypeValueRef) == CFStringGetTypeID() 1657 && CFStringCompare((CFStringRef)DeviceTypeValueRef, CFSTR("Generic"), 1658 kCFCompareCaseInsensitive) == kCFCompareEqualTo) 1659 fIsGenericStorage = true; 1660 1661 if (DeviceTypeValueRef != NULL) 1662 CFRelease(DeviceTypeValueRef); 1663 } 1664 ChildEntry = ParentEntry; 1665 } 1666 if (ChildEntry != IO_OBJECT_NULL && !IOObjectIsEqualTo(ChildEntry, MediaService)) 1667 IOObjectRelease(ChildEntry); 1668 1669 if (!fIsGenericStorage) 1670 { 1671 IOObjectRelease(MediaService); 1672 continue; 1673 } 1674 1675 CFTypeRef DeviceName; 1676 DeviceName = IORegistryEntryCreateCFProperty(MediaService, 1677 CFSTR(kIOBSDNameKey), 1678 kCFAllocatorDefault,0); 1679 if (DeviceName) 1680 { 1681 char szDeviceFilePath[MAXPATHLEN]; 1682 strcpy(szDeviceFilePath, _PATH_DEV); 1683 size_t cchPathSize = strlen(szDeviceFilePath); 1684 if (CFStringGetCString((CFStringRef)DeviceName, 1685 &szDeviceFilePath[cchPathSize], 1686 (CFIndex)(sizeof(szDeviceFilePath) - cchPathSize), 1687 kCFStringEncodingUTF8)) 1688 { 1689 PDARWINFIXEDDRIVE pDuplicate = pHead; 1690 while (pDuplicate && strcmp(szDeviceFilePath, pDuplicate->szName) != 0) 1691 pDuplicate = pDuplicate->pNext; 1692 if (pDuplicate == NULL) 1693 { 1694 /* Get model for the IOMedia object. 1695 * 1696 * Due to vendor and product property names are different and 1697 * depend on interface and device type, the best way to get a drive 1698 * model is get IORegistry name for the IOMedia object. Usually, 1699 * it takes "<vendor> <product> <revision> Media" form. Noticed, 1700 * such naming are used by only IOMedia objects having 1701 * "Whole" = True and "BSDName" properties set. 1702 */ 1703 io_name_t szEntryName = { 0 }; 1704 if ((krc = IORegistryEntryGetName(MediaService, szEntryName)) == KERN_SUCCESS) 1705 { 1706 /* remove " Media" from the end of the name */ 1707 char *pszMedia = strrchr(szEntryName, ' '); 1708 if ( pszMedia != NULL 1709 && (uintptr_t)pszMedia < (uintptr_t)&szEntryName[sizeof(szEntryName)] 1710 && strcmp(pszMedia, " Media") == 0) 1711 { 1712 *pszMedia = '\0'; 1713 RTStrPurgeEncoding(szEntryName); 1714 } 1715 } 1716 /* Create the device path and model name in form "/device/path:model". */ 1717 cchPathSize = strlen(szDeviceFilePath); 1718 size_t const cchModelSize = strlen(szEntryName); 1719 size_t const cbExtra = cchPathSize + 1 + cchModelSize + !!cchModelSize; 1720 PDARWINFIXEDDRIVE pNew = (PDARWINFIXEDDRIVE)RTMemAlloc(RT_UOFFSETOF_DYN(DARWINFIXEDDRIVE, szName[cbExtra])); 1721 if (pNew) 1722 { 1723 pNew->pNext = NULL; 1724 memcpy(pNew->szName, szDeviceFilePath, cchPathSize + 1); 1725 pNew->pszModel = NULL; 1726 if (cchModelSize) 1727 pNew->pszModel = (const char *)memcpy(&pNew->szName[cchPathSize + 1], szEntryName, cchModelSize + 1); 1728 1729 if (pTail) 1730 pTail = pTail->pNext = pNew; 1731 else 1732 pTail = pHead = pNew; 1733 } 1734 } 1735 } 1736 CFRelease(DeviceName); 1737 } 1738 IOObjectRelease(MediaService); 1739 i++; 1740 } 1741 IOObjectRelease(MediaServices); 1572 1742 1573 1743 return pHead; -
trunk/src/VBox/Main/src-server/darwin/iokit.h
r82968 r85929 24 24 #include <iprt/cdefs.h> 25 25 #include <iprt/types.h> 26 #include <iprt/cpp/ministring.h> 26 27 #ifdef VBOX_WITH_USB 27 28 # include <VBox/usb.h> … … 40 41 /** Pointer to a Darwin DVD descriptor. */ 41 42 typedef DARWINDVD *PDARWINDVD; 43 44 /** Darwin fixed drive (SSD, HDD, ++) descriptor as returned by 45 * DarwinGetFixedDrives(). */ 46 typedef struct DARWINFIXEDDRIVE 47 { 48 /** Pointer to the next DVD. */ 49 struct DARWINFIXEDDRIVE *pNext; 50 /** Pointer to the model name, NULL if none. 51 * This points after szName and needs not be freed separately. */ 52 const char *pszModel; 53 /** Variable length name / identifier. */ 54 char szName[1]; 55 } DARWINFIXEDDRIVE; 56 /** Pointer to a Darwin fixed drive. */ 57 typedef DARWINFIXEDDRIVE *PDARWINFIXEDDRIVE; 42 58 43 59 … … 85 101 #endif /* VBOX_WITH_USB */ 86 102 PDARWINDVD DarwinGetDVDDrives(void); 103 PDARWINFIXEDDRIVE DarwinGetFixedDrives(void); 87 104 PDARWINETHERNIC DarwinGetEthernetControllers(void); 88 105 RT_C_DECLS_END -
trunk/src/VBox/Main/src-server/freebsd/HostHardwareFreeBSD.cpp
r82968 r85929 1 1 /* $Id$ */ 2 2 /** @file 3 * Classes for handling hardware detection under FreeBSD.3 * VirtualBox Main - Code for handling hardware detection under FreeBSD, VBoxSVC. 4 4 */ 5 5 … … 16 16 */ 17 17 18 #define LOG_GROUP LOG_GROUP_MAIN19 20 18 21 19 /********************************************************************************************************************************* 22 20 * Header Files * 23 21 *********************************************************************************************************************************/ 24 25 #include <HostHardwareLinux.h>22 #define LOG_GROUP LOG_GROUP_MAIN 23 #include "HostHardwareLinux.h" 26 24 27 25 #include <VBox/log.h> … … 35 33 #include <iprt/string.h> 36 34 37 #i fdef RT_OS_FREEBSD38 # include <sys/param.h>39 # include <sys/types.h>40 # include <sys/stat.h>41 # include <unistd.h>42 # include <stdio.h>43 # include <sys/ioctl.h>44 # include <fcntl.h>45 # include <cam/cam.h>46 # include <cam/cam_ccb.h>47 # include <cam/scsi/scsi_pass.h>48 #endif /* RT_OS_FREEBSD */ 35 #include <sys/param.h> 36 #include <sys/types.h> 37 #include <sys/stat.h> 38 #include <unistd.h> 39 #include <stdio.h> 40 #include <sys/ioctl.h> 41 #include <fcntl.h> 42 #include <cam/cam.h> 43 #include <cam/cam_ccb.h> 44 #include <camlib.h> 45 #include <cam/scsi/scsi_pass.h> 46 49 47 #include <vector> 50 48 … … 53 51 * Typedefs and Defines * 54 52 *********************************************************************************************************************************/ 55 56 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, 57 bool isDVD, bool *pfSuccess); 58 static int getDVDInfoFromCAM(DriveInfoList *pList, bool *pfSuccess); 53 typedef enum DriveType_T 54 { 55 Fixed, 56 DVD, 57 Any 58 } DriveType_T; 59 60 61 /********************************************************************************************************************************* 62 * Internal Functions * 63 *********************************************************************************************************************************/ 64 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, bool isDVD, bool *pfSuccess) RT_NOTHROW_PROTP; 65 static int getDriveInfoFromCAM(DriveInfoList *pList, DriveType_T enmDriveType, bool *pfSuccess) RT_NOTHROW_PROTP; 66 59 67 60 68 /** Find the length of a string, ignoring trailing non-ascii or control 61 * characters */ 62 static size_t strLenStripped(const char *pcsz) 69 * characters 70 * @note Code duplicated in HostHardwareLinux.cpp */ 71 static size_t strLenStripped(const char *pcsz) RT_NOTHROW_DEF 63 72 { 64 73 size_t cch = 0; 65 74 for (size_t i = 0; pcsz[i] != '\0'; ++i) 66 if (pcsz[i] > 32 && pcsz[i] < 127)75 if (pcsz[i] > 32 /*space*/ && pcsz[i] < 127 /*delete*/) 67 76 cch = i; 68 77 return cch + 1; 69 78 } 70 79 71 static void strLenRemoveTrailingWhiteSpace(char *psz, size_t cchStr)72 {73 while ( (cchStr > 0)74 && (psz[cchStr -1] == ' '))75 psz[--cchStr] = '\0';76 }77 80 78 81 /** 79 * Initialise the device description for a DVD drive based on 80 * vendor and model name strings. 81 * @param pcszVendor the vendor ID string 82 * @param pcszModel the product ID string 83 * @param pszDesc where to store the description string (optional) 84 * @param cchDesc the size of the buffer in @pszDesc 82 * Initialize the device description for a drive based on vendor and model name 83 * strings. 84 * 85 * @param pcszVendor The raw vendor ID string. 86 * @param pcszModel The raw product ID string. 87 * @param pszDesc Where to store the description string (optional) 88 * @param cbDesc The size of the buffer in @pszDesc 89 * 90 * @note Used for disks as well as DVDs. 85 91 */ 86 92 /* static */ 87 void dvdCreateDeviceString(const char *pcszVendor, const char *pcszModel, 88 char *pszDesc, size_t cchDesc) 93 void dvdCreateDeviceString(const char *pcszVendor, const char *pcszModel, char *pszDesc, size_t cbDesc) RT_NOTHROW_DEF 89 94 { 90 95 AssertPtrReturnVoid(pcszVendor); 91 96 AssertPtrReturnVoid(pcszModel); 92 97 AssertPtrNullReturnVoid(pszDesc); 93 AssertReturnVoid(!pszDesc || c chDesc > 0);98 AssertReturnVoid(!pszDesc || cbDesc > 0); 94 99 size_t cchVendor = strLenStripped(pcszVendor); 95 100 size_t cchModel = strLenStripped(pcszModel); … … 99 104 { 100 105 if (cchVendor > 0) 101 RTStrPrintf(pszDesc, c chDesc, "%.*s %s", cchVendor, pcszVendor,106 RTStrPrintf(pszDesc, cbDesc, "%.*s %s", cchVendor, pcszVendor, 102 107 cchModel > 0 ? pcszModel : "(unknown drive model)"); 103 108 else 104 RTStrPrintf(pszDesc, cchDesc, "%s", pcszModel); 105 } 106 } 107 108 109 int VBoxMainDriveInfo::updateDVDs () 109 RTStrPrintf(pszDesc, cbDesc, "%s", pcszModel); 110 RTStrPurgeEncoding(pszDesc); 111 } 112 } 113 114 115 int VBoxMainDriveInfo::updateDVDs() RT_NOEXCEPT 110 116 { 111 117 LogFlowThisFunc(("entered\n")); 112 int rc = VINF_SUCCESS; 113 bool fSuccess = false; /* Have we succeeded in finding anything yet? */ 114 118 int rc; 115 119 try 116 120 { 117 mDVDList.clear ();121 mDVDList.clear(); 118 122 /* Always allow the user to override our auto-detection using an 119 123 * environment variable. */ 124 bool fSuccess = false; /* Have we succeeded in finding anything yet? */ 125 rc = getDriveInfoFromEnv("VBOX_CDROM", &mDVDList, true /* isDVD */, &fSuccess); 120 126 if (RT_SUCCESS(rc) && !fSuccess) 121 rc = getDriveInfoFromEnv("VBOX_CDROM", &mDVDList, true /* isDVD */, 122 &fSuccess); 123 if (RT_SUCCESS(rc) && !fSuccess) 124 rc = getDVDInfoFromCAM(&mDVDList, &fSuccess); 125 } 126 catch(std::bad_alloc &e) 127 rc = getDriveInfoFromCAM(&mDVDList, DVD, &fSuccess); 128 } 129 catch (std::bad_alloc &) 127 130 { 128 131 rc = VERR_NO_MEMORY; … … 132 135 } 133 136 134 int VBoxMainDriveInfo::updateFloppies ()137 int VBoxMainDriveInfo::updateFloppies() RT_NOEXCEPT 135 138 { 136 139 LogFlowThisFunc(("entered\n")); 137 int rc = VINF_SUCCESS; 138 bool fSuccess = false; /* Have we succeeded in finding anything yet? */ 139 140 int rc; 140 141 try 141 142 { 142 mFloppyList.clear (); 143 /* Always allow the user to override our auto-detection using an 144 * environment variable. */ 145 if (RT_SUCCESS(rc) && !fSuccess) 146 rc = getDriveInfoFromEnv("VBOX_FLOPPY", &mFloppyList, false /* isDVD */, 147 &fSuccess); 148 } 149 catch(std::bad_alloc &e) 143 /* Only got the enviornment variable here... */ 144 mFloppyList.clear(); 145 bool fSuccess = false; /* ignored */ 146 rc = getDriveInfoFromEnv("VBOX_FLOPPY", &mFloppyList, false /* isDVD */, &fSuccess); 147 } 148 catch (std::bad_alloc &) 150 149 { 151 150 rc = VERR_NO_MEMORY; … … 155 154 } 156 155 156 int VBoxMainDriveInfo::updateFixedDrives() RT_NOEXCEPT 157 { 158 LogFlowThisFunc(("entered\n")); 159 int rc; 160 try 161 { 162 mFixedDriveList.clear(); 163 bool fSuccess = false; /* ignored */ 164 rc = getDriveInfoFromCAM(&mFixedDriveList, Fixed, &fSuccess); 165 } 166 catch (std::bad_alloc &) 167 { 168 rc = VERR_NO_MEMORY; 169 } 170 LogFlowThisFunc(("rc=%Rrc\n", rc)); 171 return rc; 172 } 173 174 static void strDeviceStringSCSI(device_match_result *pDevResult, char *pszDesc, size_t cbDesc) RT_NOTHROW_DEF 175 { 176 char szVendor[128]; 177 cam_strvis((uint8_t *)szVendor, (const uint8_t *)pDevResult->inq_data.vendor, 178 sizeof(pDevResult->inq_data.vendor), sizeof(szVendor)); 179 char szProduct[128]; 180 cam_strvis((uint8_t *)szProduct, (const uint8_t *)pDevResult->inq_data.product, 181 sizeof(pDevResult->inq_data.product), sizeof(szProduct)); 182 dvdCreateDeviceString(szVendor, szProduct, pszDesc, cbDesc); 183 } 184 185 static void strDeviceStringATA(device_match_result *pDevResult, char *pszDesc, size_t cbDesc) RT_NOTHROW_DEF 186 { 187 char szProduct[256]; 188 cam_strvis((uint8_t *)szProduct, (const uint8_t *)pDevResult->ident_data.model, 189 sizeof(pDevResult->ident_data.model), sizeof(szProduct)); 190 dvdCreateDeviceString("", szProduct, pszDesc, cbDesc); 191 } 192 193 static void strDeviceStringSEMB(device_match_result *pDevResult, char *pszDesc, size_t cbDesc) RT_NOTHROW_DEF 194 { 195 sep_identify_data *pSid = (sep_identify_data *)&pDevResult->ident_data; 196 197 char szVendor[128]; 198 cam_strvis((uint8_t *)szVendor, (const uint8_t *)pSid->vendor_id, 199 sizeof(pSid->vendor_id), sizeof(szVendor)); 200 char szProduct[128]; 201 cam_strvis((uint8_t *)szProduct, (const uint8_t *)pSid->product_id, 202 sizeof(pSid->product_id), sizeof(szProduct)); 203 dvdCreateDeviceString(szVendor, szProduct, pszDesc, cbDesc); 204 } 205 206 static void strDeviceStringMMCSD(device_match_result *pDevResult, char *pszDesc, size_t cbDesc) RT_NOTHROW_DEF 207 { 208 struct cam_device *pDev = cam_open_btl(pDevResult->path_id, pDevResult->target_id, 209 pDevResult->target_lun, O_RDWR, NULL); 210 if (pDev == NULL) 211 { 212 Log(("Error while opening drive device. Error: %s\n", cam_errbuf)); 213 return; 214 } 215 216 union ccb *pCcb = cam_getccb(pDev); 217 if (pCcb != NULL) 218 { 219 struct mmc_params mmcIdentData; 220 RT_ZERO(mmcIdentData); 221 222 struct ccb_dev_advinfo *pAdvi = &pCcb->cdai; 223 pAdvi->ccb_h.flags = CAM_DIR_IN; 224 pAdvi->ccb_h.func_code = XPT_DEV_ADVINFO; 225 pAdvi->flags = CDAI_FLAG_NONE; 226 pAdvi->buftype = CDAI_TYPE_MMC_PARAMS; 227 pAdvi->bufsiz = sizeof(mmcIdentData); 228 pAdvi->buf = (uint8_t *)&mmcIdentData; 229 230 if (cam_send_ccb(pDev, pCcb) >= 0) 231 { 232 if (strlen((char *)mmcIdentData.model) > 0) 233 dvdCreateDeviceString("", (const char *)mmcIdentData.model, pszDesc, cbDesc); 234 else 235 dvdCreateDeviceString("", mmcIdentData.card_features & CARD_FEATURE_SDIO ? "SDIO card" : "Unknown card", 236 pszDesc, cbDesc); 237 } 238 else 239 Log(("error sending XPT_DEV_ADVINFO CCB\n")); 240 241 cam_freeccb(pCcb); 242 } 243 else 244 Log(("Could not allocate CCB\n")); 245 cam_close_device(pDev); 246 } 247 248 /** @returns boolean success indicator (true/false). */ 249 static int nvmeGetCData(struct cam_device *pDev, struct nvme_controller_data *pCData) RT_NOTHROW_DEF 250 { 251 bool fSuccess = false; 252 union ccb *pCcb = cam_getccb(pDev); 253 if (pCcb != NULL) 254 { 255 struct ccb_dev_advinfo *pAdvi = &pCcb->cdai; 256 pAdvi->ccb_h.flags = CAM_DIR_IN; 257 pAdvi->ccb_h.func_code = XPT_DEV_ADVINFO; 258 pAdvi->flags = CDAI_FLAG_NONE; 259 pAdvi->buftype = CDAI_TYPE_NVME_CNTRL; 260 pAdvi->bufsiz = sizeof(struct nvme_controller_data); 261 pAdvi->buf = (uint8_t *)pCData; 262 RT_BZERO(pAdvi->buf, pAdvi->bufsiz); 263 264 if (cam_send_ccb(pDev, pCcb) >= 0) 265 { 266 if (pAdvi->ccb_h.status == CAM_REQ_CMP) 267 fSuccess = true; 268 else 269 Log(("Got CAM error %#x\n", pAdvi->ccb_h.status)); 270 } 271 else 272 Log(("Error sending XPT_DEV_ADVINFO CC\n")); 273 cam_freeccb(pCcb); 274 } 275 else 276 Log(("Could not allocate CCB\n")); 277 return fSuccess; 278 } 279 280 static void strDeviceStringNVME(device_match_result *pDevResult, char *pszDesc, size_t cbDesc) RT_NOTHROW_DEF 281 { 282 struct cam_device *pDev = cam_open_btl(pDevResult->path_id, pDevResult->target_id, 283 pDevResult->target_lun, O_RDWR, NULL); 284 if (pDev) 285 { 286 struct nvme_controller_data CData; 287 if (nvmeGetCData(pDev, &CData)) 288 { 289 char szVendor[128]; 290 cam_strvis((uint8_t *)szVendor, CData.mn, sizeof(CData.mn), sizeof(szVendor)); 291 char szProduct[128]; 292 cam_strvis((uint8_t *)szProduct, CData.fr, sizeof(CData.fr), sizeof(szProduct)); 293 dvdCreateDeviceString(szVendor, szProduct, pszDesc, cbDesc); 294 } 295 else 296 Log(("Error while getting NVME drive info\n")); 297 cam_close_device(pDev); 298 } 299 else 300 Log(("Error while opening drive device. Error: %s\n", cam_errbuf)); 301 } 302 303 157 304 /** 158 * Search for available CD/DVDdrives using the CAM layer.305 * Search for available drives using the CAM layer. 159 306 * 160 307 * @returns iprt status code 161 * @param pList the list to append the drives found to 162 * @param pfSuccess this will be set to true if we found at least one drive 163 * and to false otherwise. Optional. 308 * @param pList the list to append the drives found to 309 * @param enmDriveType search drives of specified type 310 * @param pfSuccess this will be set to true if we found at least one drive 311 * and to false otherwise. Optional. 164 312 */ 165 static int getDVDInfoFromCAM(DriveInfoList *pList, bool *pfSuccess) 166 { 167 int rc = VINF_SUCCESS; 168 RTFILE FileXpt; 169 170 rc = RTFileOpen(&FileXpt, "/dev/xpt0", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); 313 static int getDriveInfoFromCAM(DriveInfoList *pList, DriveType_T enmDriveType, bool *pfSuccess) RT_NOTHROW_DEF 314 { 315 RTFILE hFileXpt = NIL_RTFILE; 316 int rc = RTFileOpen(&hFileXpt, "/dev/xpt0", RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); 171 317 if (RT_SUCCESS(rc)) 172 318 { … … 196 342 #define INQ_PAT inq_pat 197 343 #endif 198 DeviceMatchPattern.pattern.device_pattern.INQ_PAT.type = T_CDROM; 344 DeviceMatchPattern.pattern.device_pattern.INQ_PAT.type = enmDriveType == Fixed ? T_DIRECT 345 : enmDriveType == DVD ? T_CDROM : T_ANY; 199 346 DeviceMatchPattern.pattern.device_pattern.INQ_PAT.media_type = SIP_MEDIA_REMOVABLE | SIP_MEDIA_FIXED; 200 347 DeviceMatchPattern.pattern.device_pattern.INQ_PAT.vendor[0] = '*'; /* Matches anything */ … … 220 367 do 221 368 { 222 rc = RTFileIoCtl( FileXpt, CAMIOCOMMAND, &DeviceCCB, sizeof(union ccb), NULL);369 rc = RTFileIoCtl(hFileXpt, CAMIOCOMMAND, &DeviceCCB, sizeof(union ccb), NULL); 223 370 if (RT_FAILURE(rc)) 224 371 { … … 231 378 if (paMatches[i].type == DEV_MATCH_DEVICE) 232 379 { 380 /* 381 * The result list can contain some empty entries with DEV_RESULT_UNCONFIGURED 382 * flag set, e.g. in case of T_DIRECT. Ignore them. 383 */ 384 if ( (paMatches[i].result.device_result.flags & DEV_RESULT_UNCONFIGURED) 385 == DEV_RESULT_UNCONFIGURED) 386 continue; 387 233 388 /* We have the drive now but need the appropriate device node */ 234 389 struct device_match_result *pDevResult = &paMatches[i].result.device_result; … … 254 409 PeriphMatchPattern.pattern.periph_pattern.target_id = paMatches[i].result.device_result.target_id; 255 410 PeriphMatchPattern.pattern.periph_pattern.target_lun = paMatches[i].result.device_result.target_lun; 256 PeriphMatchPattern.pattern.periph_pattern.flags = (periph_pattern_flags)( PERIPH_MATCH_PATH | PERIPH_MATCH_TARGET 411 PeriphMatchPattern.pattern.periph_pattern.flags = (periph_pattern_flags)( PERIPH_MATCH_PATH 412 | PERIPH_MATCH_TARGET 257 413 | PERIPH_MATCH_LUN); 258 414 PeriphCCB.cdm.num_patterns = 1; … … 265 421 do 266 422 { 267 rc = RTFileIoCtl( FileXpt, CAMIOCOMMAND, &PeriphCCB, sizeof(union ccb), NULL);423 rc = RTFileIoCtl(hFileXpt, CAMIOCOMMAND, &PeriphCCB, sizeof(union ccb), NULL); 268 424 if (RT_FAILURE(rc)) 269 425 { … … 274 430 for (iPeriphMatch = 0; iPeriphMatch < PeriphCCB.cdm.num_matches; iPeriphMatch++) 275 431 { 276 if ( (aPeriphMatches[iPeriphMatch].type == DEV_MATCH_PERIPH) 277 && (!strcmp(aPeriphMatches[iPeriphMatch].result.periph_result.periph_name, "cd"))) 432 /* Ignore "passthrough mode" paths */ 433 if ( aPeriphMatches[iPeriphMatch].type == DEV_MATCH_PERIPH 434 && strcmp(aPeriphMatches[iPeriphMatch].result.periph_result.periph_name, "pass")) 278 435 { 279 436 pPeriphResult = &aPeriphMatches[iPeriphMatch].result.periph_result; … … 285 442 break; 286 443 287 } while ( (DeviceCCB.ccb_h.status == CAM_REQ_CMP)288 && (DeviceCCB.cdm.status == CAM_DEV_MATCH_MORE));444 } while ( DeviceCCB.ccb_h.status == CAM_REQ_CMP 445 && DeviceCCB.cdm.status == CAM_DEV_MATCH_MORE); 289 446 290 447 if (pPeriphResult) 291 448 { 292 449 char szPath[RTPATH_MAX]; 293 char szDesc[256];294 295 450 RTStrPrintf(szPath, sizeof(szPath), "/dev/%s%d", 296 451 pPeriphResult->periph_name, pPeriphResult->unit_number); 297 452 298 /* Remove trailing white space. */ 299 strLenRemoveTrailingWhiteSpace(pDevResult->inq_data.vendor, 300 sizeof(pDevResult->inq_data.vendor)); 301 strLenRemoveTrailingWhiteSpace(pDevResult->inq_data.product, 302 sizeof(pDevResult->inq_data.product)); 303 304 dvdCreateDeviceString(pDevResult->inq_data.vendor, 305 pDevResult->inq_data.product, 306 szDesc, sizeof(szDesc)); 307 308 pList->push_back(DriveInfo(szPath, "", szDesc)); 453 char szDesc[256] = { 0 }; 454 switch (pDevResult->protocol) 455 { 456 case PROTO_SCSI: strDeviceStringSCSI( pDevResult, szDesc, sizeof(szDesc)); break; 457 case PROTO_ATA: strDeviceStringATA( pDevResult, szDesc, sizeof(szDesc)); break; 458 case PROTO_MMCSD: strDeviceStringMMCSD(pDevResult, szDesc, sizeof(szDesc)); break; 459 case PROTO_SEMB: strDeviceStringSEMB( pDevResult, szDesc, sizeof(szDesc)); break; 460 case PROTO_NVME: strDeviceStringNVME( pDevResult, szDesc, sizeof(szDesc)); break; 461 default: break; 462 } 463 464 try 465 { 466 pList->push_back(DriveInfo(szPath, "", szDesc)); 467 } 468 catch (std::bad_alloc &) 469 { 470 pList->clear(); 471 rc = VERR_NO_MEMORY; 472 break; 473 } 309 474 if (pfSuccess) 310 475 *pfSuccess = true; … … 312 477 } 313 478 } 314 } while ( (DeviceCCB.ccb_h.status == CAM_REQ_CMP) 315 && (DeviceCCB.cdm.status == CAM_DEV_MATCH_MORE)); 479 } while ( DeviceCCB.ccb_h.status == CAM_REQ_CMP 480 && DeviceCCB.cdm.status == CAM_DEV_MATCH_MORE 481 && RT_SUCCESS(rc)); 316 482 317 483 RTMemFree(paMatches); … … 320 486 rc = VERR_NO_MEMORY; 321 487 322 RTFileClose( FileXpt);488 RTFileClose(hFileXpt); 323 489 } 324 490 325 491 return rc; 326 492 } 493 327 494 328 495 /** 329 496 * Extract the names of drives from an environment variable and add them to a 330 497 * list if they are valid. 498 * 331 499 * @returns iprt status code 332 500 * @param pcszVar the name of the environment variable. The variable … … 337 505 * @param pfSuccess this will be set to true if we found at least one drive 338 506 * and to false otherwise. Optional. 507 * 508 * @note This is duplicated in HostHardwareLinux.cpp. 339 509 */ 340 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, 341 bool isDVD, bool *pfSuccess) 510 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, bool isDVD, bool *pfSuccess) RT_NOTHROW_DEF 342 511 { 343 512 AssertPtrReturn(pcszVar, VERR_INVALID_POINTER); 344 513 AssertPtrReturn(pList, VERR_INVALID_POINTER); 345 514 AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); 346 LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar, 347 pList, isDVD, pfSuccess)); 515 LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar, pList, isDVD, pfSuccess)); 348 516 int rc = VINF_SUCCESS; 349 517 bool success = false; … … 352 520 try 353 521 { 354 c onst char *pcszCurrent = pszFreeMe;355 while (p cszCurrent && *pcszCurrent != '\0')522 char *pszCurrent = pszFreeMe; 523 while (pszCurrent && *pszCurrent != '\0') 356 524 { 357 const char *pcszNext = strchr(pcszCurrent, ':'); 358 char szPath[RTPATH_MAX], szReal[RTPATH_MAX]; 359 char szDesc[256], szUdi[256]; 360 if (pcszNext) 361 RTStrPrintf(szPath, sizeof(szPath), "%.*s", 362 pcszNext - pcszCurrent - 1, pcszCurrent); 363 else 364 RTStrPrintf(szPath, sizeof(szPath), "%s", pcszCurrent); 365 if (RT_SUCCESS(RTPathReal(szPath, szReal, sizeof(szReal)))) 525 char *pszNext = strchr(pszCurrent, ':'); 526 if (pszNext) 527 *pszNext++ = '\0'; 528 529 char szReal[RTPATH_MAX]; 530 char szDesc[1] = "", szUdi[1] = ""; /* differs on freebsd because no devValidateDevice */ 531 if ( RT_SUCCESS(RTPathReal(pszCurrent, szReal, sizeof(szReal))) 532 /*&& devValidateDevice(szReal, isDVD, NULL, szDesc, sizeof(szDesc), szUdi, sizeof(szUdi)) - linux only */) 366 533 { 367 szUdi[0] = '\0'; /** @todo r=bird: missing a call to devValidateDevice() here and szUdi wasn't368 * initialized because of that. Need proper fixing. */369 534 pList->push_back(DriveInfo(szReal, szUdi, szDesc)); 370 535 success = true; 371 536 } 372 p cszCurrent = pcszNext ? pcszNext + 1 : NULL;537 pszCurrent = pszNext; 373 538 } 374 539 if (pfSuccess != NULL) 375 540 *pfSuccess = success; 376 541 } 377 catch (std::bad_alloc &e)542 catch (std::bad_alloc &) 378 543 { 379 544 rc = VERR_NO_MEMORY; … … 383 548 return rc; 384 549 } 550 -
trunk/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp
r82968 r85929 1 1 /* $Id$ */ 2 2 /** @file 3 * Classes for handling hardware detection under Linux. Please feel free to 4 * expand these to work for other systems (Solaris!) or to add new ones for 5 * other systems. 3 * VirtualBox Main - Code for handling hardware detection under Linux, VBoxSVC. 6 4 */ 7 5 … … 18 16 */ 19 17 20 #define LOG_GROUP LOG_GROUP_MAIN21 22 18 23 19 /********************************************************************************************************************************* 24 20 * Header Files * 25 21 *********************************************************************************************************************************/ 26 27 #include <HostHardwareLinux.h> 28 #include <vector.h> 22 #define LOG_GROUP LOG_GROUP_MAIN 23 #include "HostHardwareLinux.h" 29 24 30 25 #include <VBox/err.h> … … 71 66 * Global Variables * 72 67 *********************************************************************************************************************************/ 73 74 68 #ifdef TESTCASE 75 69 static bool testing() { return true; } … … 87 81 * Typedefs and Defines * 88 82 *********************************************************************************************************************************/ 89 90 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, 91 bool isDVD, bool *pfSuccess); 92 static int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD, 93 bool *pfSuccess); 83 typedef enum SysfsWantDevice_T 84 { 85 DVD, 86 Floppy, 87 FixedDisk 88 } SysfsWantDevice_T; 89 90 91 /********************************************************************************************************************************* 92 * Internal Functions * 93 *********************************************************************************************************************************/ 94 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, bool isDVD, bool *pfSuccess) RT_NOTHROW_PROTO; 95 static int getDriveInfoFromSysfs(DriveInfoList *pList, SysfsWantDevice_T wantDevice, bool *pfSuccess) RT_NOTHROW_PROTO; 96 94 97 95 98 /** Find the length of a string, ignoring trailing non-ascii or control 96 * characters */ 97 static size_t strLenStripped(const char *pcsz) 99 * characters 100 * @note Code duplicated in HostHardwareFreeBSD.cpp */ 101 static size_t strLenStripped(const char *pcsz) RT_NOTHROW_DEF 98 102 { 99 103 size_t cch = 0; 100 104 for (size_t i = 0; pcsz[i] != '\0'; ++i) 101 if (pcsz[i] > 32 && pcsz[i] < 127)105 if (pcsz[i] > 32 /*space*/ && pcsz[i] < 127 /*delete*/) 102 106 cch = i; 103 107 return cch + 1; … … 114 118 * @param pszName where to store the name retrieved 115 119 */ 116 static bool floppyGetName(const char *pcszNode, unsigned Number, 117 floppy_drive_name pszName) 120 static bool floppyGetName(const char *pcszNode, unsigned Number, floppy_drive_name pszName) RT_NOTHROW_DEF 118 121 { 119 122 AssertPtrReturn(pcszNode, false); … … 145 148 * FDC 1) 146 149 * @param pszDesc where to store the device description (optional) 147 * @param c chDescthe size of the buffer in @a pszDesc150 * @param cbDesc the size of the buffer in @a pszDesc 148 151 * @param pszUdi where to store the device UDI (optional) 149 * @param c chUdithe size of the buffer in @a pszUdi152 * @param cbUdi the size of the buffer in @a pszUdi 150 153 */ 151 static void floppyCreateDeviceStrings(const floppy_drive_name pcszName, 152 unsigned Number, char *pszDesc, 153 size_t cchDesc, char *pszUdi, 154 size_t cchUdi) 154 static void floppyCreateDeviceStrings(const floppy_drive_name pcszName, unsigned Number, 155 char *pszDesc, size_t cbDesc, char *pszUdi, size_t cbUdi) RT_NOTHROW_DEF 155 156 { 156 157 AssertPtrNullReturnVoid(pcszName); 157 158 AssertPtrNullReturnVoid(pszDesc); 158 AssertReturnVoid(!pszDesc || c chDesc > 0);159 AssertReturnVoid(!pszDesc || cbDesc > 0); 159 160 AssertPtrNullReturnVoid(pszUdi); 160 AssertReturnVoid(!pszUdi || c chUdi > 0);161 AssertReturnVoid(!pszUdi || cbUdi > 0); 161 162 AssertReturnVoid(Number <= 7); 162 163 if (pcszName) … … 175 176 } 176 177 if (pszDesc) 177 RTStrPrintf(pszDesc, c chDesc, "%s %s K%s", pcszSize, &pcszName[1],178 RTStrPrintf(pszDesc, cbDesc, "%s %s K%s", pcszSize, &pcszName[1], 178 179 Number > 3 ? ", FDC 2" : ""); 179 180 } … … 181 182 { 182 183 if (pszDesc) 183 RTStrPrintf(pszDesc, c chDesc, "FDD %d%s", (Number & 4) + 1,184 RTStrPrintf(pszDesc, cbDesc, "FDD %d%s", (Number & 4) + 1, 184 185 Number > 3 ? ", FDC 2" : ""); 185 186 } 186 187 if (pszUdi) 187 RTStrPrintf(pszUdi, c chUdi,188 RTStrPrintf(pszUdi, cbUdi, 188 189 "/org/freedesktop/Hal/devices/platform_floppy_%u_storage", 189 190 Number); … … 194 195 * Check whether a device number might correspond to a CD-ROM device according 195 196 * to Documentation/devices.txt in the Linux kernel source. 197 * 196 198 * @returns true if it might, false otherwise 197 199 * @param Number the device number (major and minor combination) 198 200 */ 199 static bool isCdromDevNum(dev_t Number) 201 static bool isCdromDevNum(dev_t Number) RT_NOTHROW_DEF 200 202 { 201 203 int major = major(Number); 202 204 int minor = minor(Number); 203 if ( (major == IDE0_MAJOR)&& !(minor & 0x3f))205 if (major == IDE0_MAJOR && !(minor & 0x3f)) 204 206 return true; 205 207 if (major == SCSI_CDROM_MAJOR) … … 215 217 if (major == MITSUMI_X_CDROM_MAJOR) 216 218 return true; 217 if ( (major == IDE1_MAJOR)&& !(minor & 0x3f))219 if (major == IDE1_MAJOR && !(minor & 0x3f)) 218 220 return true; 219 221 if (major == MITSUMI_CDROM_MAJOR) … … 235 237 if (major == CM206_CDROM_MAJOR) 236 238 return true; 237 if ( (major == IDE3_MAJOR)&& !(minor & 0x3f))239 if (major == IDE3_MAJOR && !(minor & 0x3f)) 238 240 return true; 239 241 if (major == 46 /* Parallel port ATAPI CD-ROM */) /* no #define */ 240 242 return true; 241 if ( (major == IDE4_MAJOR)&& !(minor & 0x3f))242 return true; 243 if ( (major == IDE5_MAJOR)&& !(minor & 0x3f))244 return true; 245 if ( (major == IDE6_MAJOR)&& !(minor & 0x3f))246 return true; 247 if ( (major == IDE7_MAJOR)&& !(minor & 0x3f))248 return true; 249 if ( (major == IDE8_MAJOR)&& !(minor & 0x3f))250 return true; 251 if ( (major == IDE9_MAJOR)&& !(minor & 0x3f))243 if (major == IDE4_MAJOR && !(minor & 0x3f)) 244 return true; 245 if (major == IDE5_MAJOR && !(minor & 0x3f)) 246 return true; 247 if (major == IDE6_MAJOR && !(minor & 0x3f)) 248 return true; 249 if (major == IDE7_MAJOR && !(minor & 0x3f)) 250 return true; 251 if (major == IDE8_MAJOR && !(minor & 0x3f)) 252 return true; 253 if (major == IDE9_MAJOR && !(minor & 0x3f)) 252 254 return true; 253 255 if (major == 113 /* VIOCD_MAJOR */) … … 259 261 /** 260 262 * Send an SCSI INQUIRY command to a device and return selected information. 263 * 261 264 * @returns iprt status code 262 * @ret urnsVERR_TRY_AGAIN if the query failed but might succeed next time265 * @retval VERR_TRY_AGAIN if the query failed but might succeed next time 263 266 * @param pcszNode the full path to the device node 264 * @param p u8Typewhere to store the SCSI device type on success (optional)265 * @param p chVendor where to store the vendor id string on success (optional)266 * @param c chVendor the size of the @a pchVendor buffer267 * @param p chModel where to store the product id string on success (optional)268 * @param cchModel the size of the @a p chModel buffer267 * @param pbType where to store the SCSI device type on success (optional) 268 * @param pszVendor where to store the vendor id string on success (optional) 269 * @param cbVendor the size of the @a pszVendor buffer 270 * @param pszModel where to store the product id string on success (optional) 271 * @param cchModel the size of the @a pszModel buffer 269 272 * @note check documentation on the SCSI INQUIRY command and the Linux kernel 270 273 * SCSI headers included above if you want to understand what is going 271 274 * on in this method. 272 275 */ 273 static int cdromDoInquiry(const char *pcszNode, uint8_t *pu8Type, 274 char *pchVendor, size_t cchVendor, char *pchModel, 275 size_t cchModel) 276 { 277 LogRelFlowFunc(("pcszNode=%s, pu8Type=%p, pchVendor=%p, cchVendor=%llu, pchModel=%p, cchModel=%llu\n", 278 pcszNode, pu8Type, pchVendor, cchVendor, pchModel, 279 cchModel)); 276 static int cdromDoInquiry(const char *pcszNode, uint8_t *pbType, char *pszVendor, size_t cbVendor, 277 char *pszModel, size_t cbModel) RT_NOTHROW_DEF 278 { 279 LogRelFlowFunc(("pcszNode=%s, pbType=%p, pszVendor=%p, cbVendor=%zu, pszModel=%p, cbModel=%zu\n", 280 pcszNode, pbType, pszVendor, cbVendor, pszModel, cbModel)); 280 281 AssertPtrReturn(pcszNode, VERR_INVALID_POINTER); 281 AssertPtrNullReturn(p u8Type, VERR_INVALID_POINTER);282 AssertPtrNullReturn(p chVendor, VERR_INVALID_POINTER);283 AssertPtrNullReturn(p chModel, VERR_INVALID_POINTER);284 285 RTFILE hFile ;282 AssertPtrNullReturn(pbType, VERR_INVALID_POINTER); 283 AssertPtrNullReturn(pszVendor, VERR_INVALID_POINTER); 284 AssertPtrNullReturn(pszModel, VERR_INVALID_POINTER); 285 286 RTFILE hFile = NIL_RTFILE; 286 287 int rc = RTFileOpen(&hFile, pcszNode, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE | RTFILE_O_NON_BLOCK); 287 288 if (RT_SUCCESS(rc)) 288 289 { 289 int rcIoCtl = 0;290 unsigned char u8Response[96] = { 0 };290 int rcIoCtl = 0; 291 unsigned char auchResponse[96] = { 0 }; 291 292 struct cdrom_generic_command CdromCommandReq; 292 293 RT_ZERO(CdromCommandReq); 293 294 CdromCommandReq.cmd[0] = INQUIRY; 294 CdromCommandReq.cmd[4] = sizeof( u8Response);295 CdromCommandReq.buffer = u8Response;296 CdromCommandReq.buflen = sizeof( u8Response);295 CdromCommandReq.cmd[4] = sizeof(auchResponse); 296 CdromCommandReq.buffer = auchResponse; 297 CdromCommandReq.buflen = sizeof(auchResponse); 297 298 CdromCommandReq.data_direction = CGC_DATA_READ; 298 299 CdromCommandReq.timeout = 5000; /* ms */ … … 304 305 if (RT_SUCCESS(rc)) 305 306 { 306 if (pu8Type) 307 *pu8Type = u8Response[0] & 0x1f; 308 if (pchVendor) 309 RTStrPrintf(pchVendor, cchVendor, "%.8s", 310 &u8Response[8] /* vendor id string */); 311 if (pchModel) 312 RTStrPrintf(pchModel, cchModel, "%.16s", 313 &u8Response[16] /* product id string */); 307 if (pbType) 308 *pbType = auchResponse[0] & 0x1f; 309 if (pszVendor) 310 { 311 RTStrPrintf(pszVendor, cbVendor, "%.8s", &auchResponse[8] /* vendor id string */); 312 RTStrPurgeEncoding(pszVendor); 313 } 314 if (pszModel) 315 { 316 RTStrPrintf(pszModel, cbModel, "%.16s", &auchResponse[16] /* product id string */); 317 RTStrPurgeEncoding(pszModel); 318 } 314 319 LogRelFlowFunc(("returning success: type=%u, vendor=%.8s, product=%.16s\n", 315 u8Response[0] & 0x1f, &u8Response[8], &u8Response[16]));320 auchResponse[0] & 0x1f, &auchResponse[8], &auchResponse[16])); 316 321 return VINF_SUCCESS; 317 322 } … … 328 333 * @param pcszModel the product ID string 329 334 * @param pszDesc where to store the description string (optional) 330 * @param c chDescthe size of the buffer in @a pszDesc335 * @param cbDesc the size of the buffer in @a pszDesc 331 336 * @param pszUdi where to store the UDI string (optional) 332 * @param cchUdi the size of the buffer in @a pszUdi 337 * @param cbUdi the size of the buffer in @a pszUdi 338 * 339 * @note Used for more than DVDs these days. 333 340 */ 334 /* static */ 335 void dvdCreateDeviceStrings(const char *pcszVendor, const char *pcszModel, 336 char *pszDesc, size_t cchDesc, char *pszUdi, 337 size_t cchUdi) 341 static void dvdCreateDeviceStrings(const char *pcszVendor, const char *pcszModel, 342 char *pszDesc, size_t cbDesc, char *pszUdi, size_t cbUdi) RT_NOEXCEPT 338 343 { 339 344 AssertPtrReturnVoid(pcszVendor); 340 345 AssertPtrReturnVoid(pcszModel); 341 346 AssertPtrNullReturnVoid(pszDesc); 342 AssertReturnVoid(!pszDesc || c chDesc > 0);347 AssertReturnVoid(!pszDesc || cbDesc > 0); 343 348 AssertPtrNullReturnVoid(pszUdi); 344 AssertReturnVoid(!pszUdi || c chUdi > 0);345 char szCleaned[128]; 349 AssertReturnVoid(!pszUdi || cbUdi > 0); 350 346 351 size_t cchVendor = strLenStripped(pcszVendor); 347 352 size_t cchModel = strLenStripped(pcszModel); 348 353 349 354 /* Create a cleaned version of the model string for the UDI string. */ 355 char szCleaned[128]; 350 356 for (unsigned i = 0; i < sizeof(szCleaned) && pcszModel[i] != '\0'; ++i) 351 357 if ( (pcszModel[i] >= '0' && pcszModel[i] <= '9') … … 360 366 { 361 367 if (cchVendor > 0) 362 RTStrPrintf(pszDesc, cchDesc, "%.*s %s", cchVendor, pcszVendor, 363 cchModel > 0 ? pcszModel : "(unknown drive model)"); 368 { 369 RTStrPrintf(pszDesc, cbDesc, "%.*s %s", cchVendor, pcszVendor, cchModel > 0 ? pcszModel : "(unknown drive model)"); 370 RTStrPurgeEncoding(pszDesc); 371 } 364 372 else 365 RTStr Printf(pszDesc, cchDesc, "%s", pcszModel);373 RTStrCopy(pszDesc, cbDesc, pcszModel); 366 374 } 367 375 /* Construct the UDI string */ … … 369 377 { 370 378 if (cchModel > 0) 371 RTStrPrintf(pszUdi, cchUdi, 372 "/org/freedesktop/Hal/devices/storage_model_%s", 373 szCleaned); 379 RTStrPrintf(pszUdi, cbUdi, "/org/freedesktop/Hal/devices/storage_model_%s", szCleaned); 374 380 else 375 381 pszUdi[0] = '\0'; … … 381 387 * Check whether a device node points to a valid device and create a UDI and 382 388 * a description for it, and store the device number, if it does. 389 * 383 390 * @returns true if the device is valid, false otherwise 384 391 * @param pcszNode the path to the device node … … 386 393 * @param pDevice where to store the device node (optional) 387 394 * @param pszDesc where to store the device description (optional) 388 * @param c chDescthe size of the buffer in @a pszDesc395 * @param cbDesc the size of the buffer in @a pszDesc 389 396 * @param pszUdi where to store the device UDI (optional) 390 * @param c chUdithe size of the buffer in @a pszUdi397 * @param cbUdi the size of the buffer in @a pszUdi 391 398 */ 392 399 static bool devValidateDevice(const char *pcszNode, bool isDVD, dev_t *pDevice, 393 char *pszDesc, size_t cchDesc, char *pszUdi, 394 size_t cchUdi) 400 char *pszDesc, size_t cbDesc, char *pszUdi, size_t cbUdi) RT_NOTHROW_DEF 395 401 { 396 402 AssertPtrReturn(pcszNode, false); 397 403 AssertPtrNullReturn(pDevice, false); 398 404 AssertPtrNullReturn(pszDesc, false); 399 AssertReturn(!pszDesc || c chDesc > 0, false);405 AssertReturn(!pszDesc || cbDesc > 0, false); 400 406 AssertPtrNullReturn(pszUdi, false); 401 AssertReturn(!pszUdi || cchUdi > 0, false); 407 AssertReturn(!pszUdi || cbUdi > 0, false); 408 402 409 RTFSOBJINFO ObjInfo; 403 410 if (RT_FAILURE(RTPathQueryInfo(pcszNode, &ObjInfo, RTFSOBJATTRADD_UNIX))) … … 407 414 if (pDevice) 408 415 *pDevice = ObjInfo.Attr.u.Unix.Device; 416 409 417 if (isDVD) 410 418 { … … 419 427 if (u8Type != TYPE_ROM) 420 428 return false; 421 dvdCreateDeviceStrings(szVendor, szModel, pszDesc, cchDesc, 422 pszUdi, cchUdi); 429 dvdCreateDeviceStrings(szVendor, szModel, pszDesc, cbDesc, pszUdi, cbUdi); 423 430 } 424 431 else 425 432 { 426 /* Floppies on Linux are legacy devices with hardcoded majors and 427 * minors */ 428 unsigned Number; 429 floppy_drive_name szName; 433 /* Floppies on Linux are legacy devices with hardcoded majors and minors */ 430 434 if (major(ObjInfo.Attr.u.Unix.Device) != FLOPPY_MAJOR) 431 435 return false; 436 437 unsigned Number; 432 438 switch (minor(ObjInfo.Attr.u.Unix.Device)) 433 439 { … … 441 447 return false; 442 448 } 449 450 floppy_drive_name szName; 443 451 if (!floppyGetName(pcszNode, Number, szName)) 444 452 return false; 445 floppyCreateDeviceStrings(szName, Number, pszDesc, cchDesc, pszUdi, 446 cchUdi); 453 floppyCreateDeviceStrings(szName, Number, pszDesc, cbDesc, pszUdi, cbUdi); 447 454 } 448 455 return true; … … 450 457 451 458 452 int VBoxMainDriveInfo::updateDVDs ()459 int VBoxMainDriveInfo::updateDVDs() RT_NOEXCEPT 453 460 { 454 461 LogFlowThisFunc(("entered\n")); 455 int rc = VINF_SUCCESS; 456 bool success = false; /* Have we succeeded in finding anything yet? */ 462 int rc; 457 463 try 458 464 { 459 mDVDList.clear ();465 mDVDList.clear(); 460 466 /* Always allow the user to override our auto-detection using an 461 467 * environment variable. */ 462 if (RT_SUCCESS(rc) && (!success || testing())) 463 rc = getDriveInfoFromEnv ("VBOX_CDROM", &mDVDList, true /* isDVD */, 464 &success); 468 bool fSuccess = false; /* Have we succeeded in finding anything yet? */ 469 rc = getDriveInfoFromEnv("VBOX_CDROM", &mDVDList, true /* isDVD */, &fSuccess); 465 470 setNoProbe(false); 466 if (RT_SUCCESS(rc) && (! success || testing()))467 rc = getDriveInfoFromSysfs(&mDVDList, true /* isDVD */, &success);471 if (RT_SUCCESS(rc) && (!fSuccess || testing())) 472 rc = getDriveInfoFromSysfs(&mDVDList, DVD, &fSuccess); 468 473 if (RT_SUCCESS(rc) && testing()) 469 474 { 470 475 setNoProbe(true); 471 rc = getDriveInfoFromSysfs(&mDVDList, true /* isDVD */, &success);472 } 473 } 474 catch (std::bad_alloc &e)476 rc = getDriveInfoFromSysfs(&mDVDList, DVD, &fSuccess); 477 } 478 } 479 catch (std::bad_alloc &e) 475 480 { 476 481 rc = VERR_NO_MEMORY; … … 480 485 } 481 486 482 int VBoxMainDriveInfo::updateFloppies ()487 int VBoxMainDriveInfo::updateFloppies() RT_NOEXCEPT 483 488 { 484 489 LogFlowThisFunc(("entered\n")); 485 int rc = VINF_SUCCESS; 486 bool success = false; /* Have we succeeded in finding anything yet? */ 490 int rc; 487 491 try 488 492 { 489 mFloppyList.clear (); 490 if (RT_SUCCESS(rc) && (!success || testing())) 491 rc = getDriveInfoFromEnv("VBOX_FLOPPY", &mFloppyList, 492 false /* isDVD */, &success); 493 mFloppyList.clear(); 494 bool fSuccess = false; /* Have we succeeded in finding anything yet? */ 495 rc = getDriveInfoFromEnv("VBOX_FLOPPY", &mFloppyList, false /* isDVD */, &fSuccess); 493 496 setNoProbe(false); 494 if ( RT_SUCCESS(rc) && (!success || testing())) 495 rc = getDriveInfoFromSysfs(&mFloppyList, false /* isDVD */, 496 &success); 497 if (RT_SUCCESS(rc) && (!fSuccess || testing())) 498 rc = getDriveInfoFromSysfs(&mFloppyList, Floppy, &fSuccess); 497 499 if (RT_SUCCESS(rc) && testing()) 498 500 { 499 501 setNoProbe(true); 500 rc = getDriveInfoFromSysfs(&mFloppyList, false /* isDVD */, &success);501 } 502 } 503 catch (std::bad_alloc &e)502 rc = getDriveInfoFromSysfs(&mFloppyList, Floppy, &fSuccess); 503 } 504 } 505 catch (std::bad_alloc &) 504 506 { 505 507 rc = VERR_NO_MEMORY; … … 507 509 LogFlowThisFunc(("rc=%Rrc\n", rc)); 508 510 return rc; 511 } 512 513 int VBoxMainDriveInfo::updateFixedDrives() RT_NOEXCEPT 514 { 515 LogFlowThisFunc(("entered\n")); 516 int vrc; 517 try 518 { 519 mFixedDriveList.clear(); 520 setNoProbe(false); 521 bool fSuccess = false; /* Have we succeeded in finding anything yet? */ 522 vrc = getDriveInfoFromSysfs(&mFixedDriveList, FixedDisk, &fSuccess); 523 if (RT_SUCCESS(vrc) && testing()) 524 { 525 setNoProbe(true); 526 vrc = getDriveInfoFromSysfs(&mFixedDriveList, FixedDisk, &fSuccess); 527 } 528 } 529 catch (std::bad_alloc &) 530 { 531 vrc = VERR_NO_MEMORY; 532 } 533 LogFlowThisFunc(("vrc=%Rrc\n", vrc)); 534 return vrc; 509 535 } 510 536 … … 513 539 * Extract the names of drives from an environment variable and add them to a 514 540 * list if they are valid. 541 * 515 542 * @returns iprt status code 516 543 * @param pcszVar the name of the environment variable. The variable … … 521 548 * @param pfSuccess this will be set to true if we found at least one drive 522 549 * and to false otherwise. Optional. 550 * 551 * @note This is duplicated in HostHardwareFreeBSD.cpp. 523 552 */ 524 /* static */ 525 int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, 526 bool isDVD, bool *pfSuccess) 553 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList, bool isDVD, bool *pfSuccess) RT_NOTHROW_DEF 527 554 { 528 555 AssertPtrReturn(pcszVar, VERR_INVALID_POINTER); 529 556 AssertPtrReturn(pList, VERR_INVALID_POINTER); 530 557 AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); 531 LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar, 532 pList, isDVD, pfSuccess)); 558 LogFlowFunc(("pcszVar=%s, pList=%p, isDVD=%d, pfSuccess=%p\n", pcszVar, pList, isDVD, pfSuccess)); 533 559 int rc = VINF_SUCCESS; 534 560 bool success = false; … … 537 563 try 538 564 { 539 const char *pcszCurrent = pszFreeMe; 540 while (pcszCurrent && *pcszCurrent != '\0') 541 { 542 const char *pcszNext = strchr(pcszCurrent, ':'); 543 char szPath[RTPATH_MAX], szReal[RTPATH_MAX]; 565 char *pszCurrent = pszFreeMe; 566 while (pszCurrent && *pszCurrent != '\0') 567 { 568 char *pszNext = strchr(pszCurrent, ':'); 569 if (pszNext) 570 *pszNext++ = '\0'; 571 572 char szReal[RTPATH_MAX]; 544 573 char szDesc[256], szUdi[256]; 545 if (pcszNext) 546 RTStrPrintf(szPath, sizeof(szPath), "%.*s", 547 pcszNext - pcszCurrent - 1, pcszCurrent); 548 else 549 RTStrPrintf(szPath, sizeof(szPath), "%s", pcszCurrent); 550 if ( RT_SUCCESS(RTPathReal(szPath, szReal, sizeof(szReal))) 551 && devValidateDevice(szReal, isDVD, NULL, szDesc, 552 sizeof(szDesc), szUdi, sizeof(szUdi))) 574 if ( RT_SUCCESS(RTPathReal(pszCurrent, szReal, sizeof(szReal))) 575 && devValidateDevice(szReal, isDVD, NULL, szDesc, sizeof(szDesc), szUdi, sizeof(szUdi))) 553 576 { 554 577 pList->push_back(DriveInfo(szReal, szUdi, szDesc)); 555 578 success = true; 556 579 } 557 p cszCurrent = pcszNext ? pcszNext + 1 : NULL;580 pszCurrent = pszNext; 558 581 } 559 582 if (pfSuccess != NULL) 560 583 *pfSuccess = success; 561 584 } 562 catch (std::bad_alloc &e)585 catch (std::bad_alloc &) 563 586 { 564 587 rc = VERR_NO_MEMORY; … … 570 593 571 594 572 class sysfsBlockDev595 class SysfsBlockDev 573 596 { 574 597 public: 575 sysfsBlockDev(const char *pcszName, bool wantDVD) 576 : mpcszName(pcszName), mwantDVD(wantDVD), misConsistent(true), 577 misValid(false) 598 SysfsBlockDev(const char *pcszName, SysfsWantDevice_T wantDevice) RT_NOEXCEPT 599 : mpcszName(pcszName), mWantDevice(wantDevice), misConsistent(true), misValid(false) 578 600 { 579 601 if (findDeviceNode()) 580 602 { 581 if (mwantDVD) 582 validateAndInitForDVD(); 583 else 584 validateAndInitForFloppy(); 603 switch (mWantDevice) 604 { 605 case DVD: validateAndInitForDVD(); break; 606 case Floppy: validateAndInitForFloppy(); break; 607 default: validateAndInitForFixedDisk(); break; 608 } 585 609 } 586 610 } … … 588 612 /** The name of the subdirectory of /sys/block for this device */ 589 613 const char *mpcszName; 590 /** Are we looking for a floppy or a DVDdevice? */591 bool mwantDVD;614 /** Are we looking for a floppy, a DVD or a fixed disk device? */ 615 SysfsWantDevice_T mWantDevice; 592 616 /** The device node for the device */ 593 617 char mszNode[RTPATH_MAX]; … … 609 633 * @returns boolean success value 610 634 */ 611 bool findDeviceNode() 635 bool findDeviceNode() RT_NOEXCEPT 612 636 { 613 637 dev_t dev = 0; … … 618 642 return false; 619 643 } 620 rc = RTLinuxCheckDevicePath(dev, RTFS_TYPE_DEV_BLOCK, mszNode, 621 sizeof(mszNode), "%s", mpcszName); 622 if (RT_FAILURE(rc)) 623 return false; 624 return true; 644 rc = RTLinuxCheckDevicePath(dev, RTFS_TYPE_DEV_BLOCK, mszNode, sizeof(mszNode), "%s", mpcszName); 645 return RT_SUCCESS(rc); 625 646 } 626 647 … … 630 651 * poking the device, and if that fails we fall back to an SCSI INQUIRY 631 652 * command. */ 632 void validateAndInitForDVD() 633 { 634 char szVendor[128], szModel[128]; 653 void validateAndInitForDVD() RT_NOEXCEPT 654 { 635 655 int64_t type = 0; 636 656 int rc = RTLinuxSysFsReadIntFile(10, &type, "block/%s/device/type", mpcszName); … … 639 659 if (type == TYPE_ROM) 640 660 { 641 rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), NULL,642 "block/%s/device/vendor", mpcszName);661 char szVendor[128]; 662 rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), NULL, "block/%s/device/vendor", mpcszName); 643 663 if (RT_SUCCESS(rc)) 644 664 { 645 rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), NULL,646 "block/%s/device/model", mpcszName);665 char szModel[128]; 666 rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), NULL, "block/%s/device/model", mpcszName); 647 667 if (RT_SUCCESS(rc)) 648 668 { 649 669 misValid = true; 650 dvdCreateDeviceStrings(szVendor, szModel, 651 mszDesc, sizeof(mszDesc), 652 mszUdi, sizeof(mszUdi)); 670 dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi)); 653 671 return; 654 672 } … … 663 681 * data members for the object based on the returned data. 664 682 */ 665 void probeAndInitForDVD() 683 void probeAndInitForDVD() RT_NOEXCEPT 666 684 { 667 685 AssertReturnVoid(mszNode[0] != '\0'); 668 uint8_t u8Type = 0;686 uint8_t bType = 0; 669 687 char szVendor[128] = ""; 670 688 char szModel[128] = ""; 671 int rc = cdromDoInquiry(mszNode, &u8Type, szVendor, 672 sizeof(szVendor), szModel, 673 sizeof(szModel)); 674 if (RT_SUCCESS(rc) && (u8Type == TYPE_ROM)) 689 int rc = cdromDoInquiry(mszNode, &bType, szVendor, sizeof(szVendor), szModel, sizeof(szModel)); 690 if (RT_SUCCESS(rc) && bType == TYPE_ROM) 675 691 { 676 692 misValid = true; 677 dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), 678 mszUdi, sizeof(mszUdi)); 693 dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi)); 679 694 } 680 695 } … … 684 699 * support floppies using the basic "floppy" driver, we check the driver 685 700 * using the entry name and a driver-specific ioctl. */ 686 void validateAndInitForFloppy() 687 { 688 bool haveName = false; 701 void validateAndInitForFloppy() RT_NOEXCEPT 702 { 689 703 floppy_drive_name szName; 690 704 char szDriver[8]; … … 695 709 || mpcszName[3] != '\0') 696 710 return; 711 bool fHaveName = false; 697 712 if (!noProbe()) 698 haveName = floppyGetName(mszNode, mpcszName[2] - '0', szName);713 fHaveName = floppyGetName(mszNode, mpcszName[2] - '0', szName); 699 714 int rc = RTLinuxSysFsGetLinkDest(szDriver, sizeof(szDriver), NULL, "block/%s/%s", 700 715 mpcszName, "device/driver"); … … 704 719 return; 705 720 } 706 else if (! haveName)721 else if (!fHaveName) 707 722 return; 708 floppyCreateDeviceStrings( haveName ? szName : NULL,723 floppyCreateDeviceStrings(fHaveName ? szName : NULL, 709 724 mpcszName[2] - '0', mszDesc, 710 725 sizeof(mszDesc), mszUdi, sizeof(mszUdi)); … … 712 727 } 713 728 729 void validateAndInitForFixedDisk() RT_NOEXCEPT 730 { 731 /* 732 * For current task only device path is needed. Therefore, device probing 733 * is skipped and other fields are empty if there aren't files in the 734 * device entry. 735 */ 736 int64_t type = 0; 737 int rc = RTLinuxSysFsReadIntFile(10, &type, "block/%s/device/type", mpcszName); 738 if (RT_SUCCESS(rc) && type != TYPE_DISK) 739 return; 740 char szVendor[128]; 741 rc = RTLinuxSysFsReadStrFile(szVendor, sizeof(szVendor), NULL, "block/%s/device/vendor", mpcszName); 742 if (RT_SUCCESS(rc)) 743 { 744 char szModel[128]; 745 rc = RTLinuxSysFsReadStrFile(szModel, sizeof(szModel), NULL, "block/%s/device/model", mpcszName); 746 if (RT_SUCCESS(rc)) 747 { 748 misValid = true; 749 dvdCreateDeviceStrings(szVendor, szModel, mszDesc, sizeof(mszDesc), mszUdi, sizeof(mszUdi)); 750 return; 751 } 752 } 753 } 754 714 755 public: 715 bool isConsistent() 756 bool isConsistent() const RT_NOEXCEPT 716 757 { 717 758 return misConsistent; 718 759 } 719 bool isValid() 760 bool isValid() const RT_NOEXCEPT 720 761 { 721 762 return misValid; 722 763 } 723 const char *getDesc() 764 const char *getDesc() const RT_NOEXCEPT 724 765 { 725 766 return mszDesc; 726 767 } 727 const char *getUdi() 768 const char *getUdi() const RT_NOEXCEPT 728 769 { 729 770 return mszUdi; 730 771 } 731 const char *getNode() 772 const char *getNode() const RT_NOEXCEPT 732 773 { 733 774 return mszNode; … … 739 780 * drives attached to the system. 740 781 * @returns iprt status code 741 * @param pList where to add information about the drives detected742 * @param isDVD are we looking for DVDs or floppies?743 * @param pfSuccess Did we find anything?782 * @param pList where to add information about the drives detected 783 * @param wantDevice The kind of devices we're looking for. 784 * @param pfSuccess Did we find anything? 744 785 * 745 786 * @returns IPRT status code 787 * @throws Nothing. 746 788 */ 747 /* static */ 748 int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD, bool *pfSuccess) 789 static int getDriveInfoFromSysfs(DriveInfoList *pList, SysfsWantDevice_T wantDevice, bool *pfSuccess) RT_NOTHROW_DEF 749 790 { 750 791 AssertPtrReturn(pList, VERR_INVALID_POINTER); 751 792 AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER); /* Valid or Null */ 752 LogFlowFunc (("pList=%p, isDVD=%u, pfSuccess=%p\n", 753 pList, (unsigned) isDVD, pfSuccess)); 754 RTDIR hDir; 755 int rc; 756 bool fSuccess = false; 757 unsigned cFound = 0; 758 793 LogFlowFunc (("pList=%p, wantDevice=%u, pfSuccess=%p\n", 794 pList, (unsigned)wantDevice, pfSuccess)); 759 795 if (!RTPathExists("/sys")) 760 796 return VINF_SUCCESS; 761 rc = RTDirOpen(&hDir, "/sys/block"); 797 798 bool fSuccess = true; 799 unsigned cFound = 0; 800 RTDIR hDir = NIL_RTDIR; 801 int rc = RTDirOpen(&hDir, "/sys/block"); 762 802 /* This might mean that sysfs semantics have changed */ 763 803 AssertReturn(rc != VERR_FILE_NOT_FOUND, VINF_SUCCESS); 764 fSuccess = true;765 804 if (RT_SUCCESS(rc)) 766 805 { … … 774 813 if (entry.szName[0] == '.') 775 814 continue; 776 sysfsBlockDev dev(entry.szName, isDVD);815 SysfsBlockDev dev(entry.szName, wantDevice); 777 816 /* This might mean that sysfs semantics have changed */ 778 817 AssertBreakStmt(dev.isConsistent(), fSuccess = false); … … 783 822 pList->push_back(DriveInfo(dev.getNode(), dev.getUdi(), dev.getDesc())); 784 823 } 785 catch (std::bad_alloc &e)824 catch (std::bad_alloc &e) 786 825 { 787 826 rc = VERR_NO_MEMORY; … … 794 833 if (rc == VERR_NO_MORE_FILES) 795 834 rc = VINF_SUCCESS; 796 if (RT_FAILURE(rc))835 else if (RT_FAILURE(rc)) 797 836 /* Clean up again */ 798 for (unsigned i = 0; i < cFound; ++i)837 while (cFound-- > 0) 799 838 pList->pop_back(); 800 839 if (pfSuccess) 801 840 *pfSuccess = fSuccess; 802 LogFlow (("rc=%Rrc, fSuccess=%u\n", rc, (unsigned) fSuccess));841 LogFlow (("rc=%Rrc, fSuccess=%u\n", rc, (unsigned)fSuccess)); 803 842 return rc; 804 843 } … … 807 846 /** Helper for readFilePathsFromDir(). Adds a path to the vector if it is not 808 847 * NULL and not a dotfile (".", "..", ".*"). */ 809 static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry, 810 VECTOR_PTR(char *) *pvecpchDevs) 811 { 812 char *pszPath; 813 848 static int maybeAddPathToVector(const char *pcszPath, const char *pcszEntry, VECTOR_PTR(char *) *pvecpchDevs) RT_NOTHROW_DEF 849 { 814 850 if (!pcszPath) 815 851 return 0; 816 852 if (pcszEntry[0] == '.') 817 853 return 0; 818 pszPath = RTStrDup(pcszPath); 819 if (!pszPath) 820 return ENOMEM; 821 if (RT_FAILURE(VEC_PUSH_BACK_PTR(pvecpchDevs, char *, pszPath))) 822 return ENOMEM; 823 return 0; 824 } 825 826 /** Helper for readFilePaths(). Adds the entries from the open directory 827 * @a pDir to the vector @a pvecpchDevs using either the full path or the 828 * realpath() and skipping hidden files and files on which realpath() fails. */ 829 static int readFilePathsFromDir(const char *pcszPath, DIR *pDir, 830 VECTOR_PTR(char *) *pvecpchDevs, int withRealPath) 854 char *pszPath = RTStrDup(pcszPath); 855 if (pszPath) 856 { 857 int vrc = VEC_PUSH_BACK_PTR(pvecpchDevs, char *, pszPath); 858 if (RT_SUCCESS(vrc)) 859 return 0; 860 } 861 return ENOMEM; 862 } 863 864 /** 865 * Helper for readFilePaths(). 866 * 867 * Adds the entries from the open directory @a pDir to the vector @a pvecpchDevs 868 * using either the full path or the realpath() and skipping hidden files 869 * and files on which realpath() fails. 870 */ 871 static int readFilePathsFromDir(const char *pcszPath, DIR *pDir, VECTOR_PTR(char *) *pvecpchDevs, int withRealPath) RT_NOTHROW_DEF 831 872 { 832 873 struct dirent entry, *pResult; … … 837 878 # pragma GCC diagnostic ignored "-Wdeprecated-declarations" 838 879 #endif 839 for (err = readdir_r(pDir, &entry, &pResult); pResult; 880 for (err = readdir_r(pDir, &entry, &pResult); 881 pResult /** @todo r=bird: && err == 0 ? */; 840 882 err = readdir_r(pDir, &entry, &pResult)) 841 883 #if RT_GNUC_PREREQ(4, 6) … … 869 911 * @param withRealPath whether to canonicalise the filename with realpath 870 912 */ 871 static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvecpchDevs, 872 int withRealPath) 873 { 874 DIR *pDir; 875 int err; 876 913 static int readFilePaths(const char *pcszPath, VECTOR_PTR(char *) *pvecpchDevs, int withRealPath) RT_NOTHROW_DEF 914 { 877 915 AssertPtrReturn(pvecpchDevs, EINVAL); 878 916 AssertReturn(VEC_SIZE_PTR(pvecpchDevs) == 0, EINVAL); 879 917 AssertPtrReturn(pcszPath, EINVAL); 880 918 881 pDir = opendir(pcszPath);919 DIR *pDir = opendir(pcszPath); 882 920 if (!pDir) 883 921 return RTErrConvertFromErrno(errno); 884 err = readFilePathsFromDir(pcszPath, pDir, pvecpchDevs, withRealPath);922 int err = readFilePathsFromDir(pcszPath, pDir, pvecpchDevs, withRealPath); 885 923 if (closedir(pDir) < 0 && !err) 886 924 err = errno; … … 1262 1300 mImpl = new hotplugNullImpl(pcszDevicesRoot); 1263 1301 } 1264 catch (std::bad_alloc &e)1302 catch (std::bad_alloc &e) 1265 1303 { } 1266 1304 }
Note:
See TracChangeset
for help on using the changeset viewer.

