Skip to content

Instantly share code, notes, and snippets.

@Obbut
Last active January 23, 2024 08:06
Show Gist options
  • Save Obbut/b0a94d96bf2a8069f1c470696ab7f9f2 to your computer and use it in GitHub Desktop.
Save Obbut/b0a94d96bf2a8069f1c470696ab7f9f2 to your computer and use it in GitHub Desktop.
Adding a second physical disk to Parallels

Adding a second physical disk to Parallels Desktop 14

I wanted my (NTFS) data disk to be accessible from my boot camp Parallels VM. Parallels provides no support for this, so I tried it myself.

I duplicated the disk file that Parallels created and started poking around, and after half an hour or so, had success. This is what you need to do.

My boot camp disk is at /dev/disk0. My data disk is at /dev/disk1.

These instructions are provided for educational use only and without guarantees. If you lose data because of this, blame yourself, and only follow them if you know what you are doing.

Gathering info on the disk

You'll need some info on the position of partitions on the disk. Run sudo gpt -r show /dev/disk1 in the terminal, replacing disk1 with the disk you want to add.

I'll refer to the info from this command later. My output:

$ sudo gpt -r show /dev/disk1
      start       size  index  contents
          0          1         PMBR
          1          1         Pri GPT header
          2         32         Pri GPT table
         34      32734      1  GPT part - E3C9E316-0B5C-4DB8-817D-F92DF00215AE
      32768  976738304      2  GPT part - EBD0A0A2-B9E5-4433-87C0-68B6B72699C7
  976771072       2063         
  976773135         32         Sec GPT table
  976773167          1         Sec GPT header

Changing DiskDescriptor.xml

You'll need to start by changing DiskDescriptor.xml. I have included my original xml and the changed xml in this gist for reference.

Changing GUIDs

Generate a new guid for the disk and placing it between <UID> and </UID> under <Disk_Parameters>. You can easily generate a UIID using DuckDuckGo by searching for "guid generator". DuckDuckGo should provide a new GUID as instant answer.

Also generate another guid for the <Image> entries under <StorageData>. It seems that Parallels uses the same GUID for all <Image> entries across different <Storage> entries.

Change the <Name>

You probably renamed your disk file (the .hdd file). If not, you should. Also update the name of your disk in the xml file.

Correcting <Storage> entries

For the <Storage> entries with <Type>Bootcamp_UID</Type>, change the UID to the UID of the target partitions. For me these partitions are disk1s1 and disk1s2

You can get the UID of the partitions by running diskutil info disk1s2. Example output:

$ diskutil info /dev/disk1s2
   Device Identifier:         disk1s2
   Device Node:               /dev/disk1s2
   Whole:                     No
   Part of Whole:             disk1

   Volume Name:               Data
   Mounted:                   No

   Partition Type:            Microsoft Basic Data
   File System Personality:   NTFS
   Type (Bundle):             ntfs
   Name (User Visible):       Windows NT File System (NTFS)

   OS Can Be Installed:       No
   Media Type:                Generic
   Protocol:                  SATA
   SMART Status:              Verified
   Volume UUID:               0B5D2D8C-80FB-4AA7-B33B-DAEF0C568E22
   Disk / Partition UUID:     A5B8DEFC-5B16-499C-B8C8-97B3A8287427
   Partition Offset:          16777216 Bytes (32768 512-Byte-Device-Blocks)

   Disk Size:                 500.1 GB (500090011648 Bytes) (exactly 976738304 512-Byte-Units)
   Device Block Size:         512 Bytes

   Volume Total Space:        0 B (0 Bytes) (exactly 0 512-Byte-Units)
   Volume Free Space:         0 B (0 Bytes) (exactly 0 512-Byte-Units)

   Read-Only Media:           No
   Read-Only Volume:          Not applicable (not mounted)

   Device Location:           Internal
   Removable Media:           Fixed

   Solid State:               Yes
   Hardware AES Support:      No

The ID will be under Disk / Partition UUID. Note that this is different for every partition. You should make sure there are Storage entries for every partition on the disk. Place the UID under <File>.

You also need to change the <Start> and <End> values for each <Storage> entry, except for PhysicalMbr.hds and PhysicalGpt.hds. You can find these in your gpt -r show output. The value for <End> can be calculated by adding the start and size values in the command output for the given partition.

For PhysicalGptCopy.hds, you need to set <Start> to the value listed as start in your gpt -r show output, and set <End> to the value of <Start> + 33.

This is my finished <Storage> entry for my data partition:

<Storage>
    <Start>32768</Start>
    <End>976771072</End>
    <Blocksize>2048</Blocksize>
    <Image>
        <GUID>{b0f161f5-b065-4d7c-8df0-b2dc974922fa}</GUID>
        <Type>Bootcamp_UID</Type>
        <File>A5B8DEFC-5B16-499C-B8C8-97B3A8287427</File>
    </Image>
</Storage>

Dump PhysicalMbr.hds, PhysicalGpt.hds and PhysicalGptCopy.hds

Parallels stores a copy of the MBR and GPT, I think to protect the real MBR & GPT. You need to dump these for the disk you want to add.

In the last command, replace the skip value (976773135 in my case) with the start value in your gpt -r show command.

sudo dd if=/dev/disk1 bs=512 count=1 of=./PhysicalMbr.hds
sudo dd if=/dev/disk1 bs=512 count=33 skip=1 of=./PhysicalGpt.hds
sudo dd if=/dev/disk1 bs=512 count=33 skip=976773135 of=./PhysicalGptCopy.hds

Adding the disk to parallels

  1. Open the configuration of your Boot Camp VM (make sure it is not powered on)
  2. Go to "Hardware"
  3. Click the + button to add a new device, and choose "Hard Disk"
  4. Choose "Existing image file" as type
  5. Choose your edited disk file
  6. Click "OK" to add the file to your VM. You will get an error stating that the disk file is invalid. This is expected.
  7. Quit Parallels
  8. Locate the <Hdd> entry for your disk in the config.pvs file of your VM using a text editor.
  9. Change it to look like mine (see below). Note the added <Partition> entry, and also make sure to change the other properties like needed.
<Hdd dyn_lists="Partition 4" id="4" InterfaceType_patch="0">
   <Uuid>{991ec375-1215-40bf-826e-48d45f53b16d}</Uuid>
   <Index>1</Index>
   <Enabled>1</Enabled>
   <Connected>1</Connected>
   <EmulatedType>3</EmulatedType>
   <SystemName>Samsung SSD 860 EVO 500GB Media (disk1).hdd.hdd</SystemName>
   <UserFriendlyName>Samsung SSD 860 EVO 500GB Media (disk1).hdd</UserFriendlyName>
   <Remote>0</Remote>
   <InterfaceType>2</InterfaceType>
   <StackIndex>1</StackIndex>
   <DiskType>0</DiskType>
   <Size>476940</Size>
   <SizeOnDisk>0</SizeOnDisk>
   <Passthrough>0</Passthrough>
   <SubType>0</SubType>
   <Splitted>1</Splitted>
   <DiskVersion>0</DiskVersion>
   <CompatLevel>level2</CompatLevel>
   <Partition dyn_lists="" id="3">
      <SystemName>/dev/disk1s2</SystemName>
   </Partition>
   <DeviceDescription></DeviceDescription>
   <AutoCompressEnabled>1</AutoCompressEnabled>
   <OnlineCompactMode>0</OnlineCompactMode>
</Hdd>

That was it for me – my boot camp VM now has access to my data partition.

<?xml version='1.0' encoding='UTF-8'?>
<Parallels_disk_image Version="1.0">
<Disk_Parameters>
<Disk_size>976773168</Disk_size>
<Cylinders>969021</Cylinders>
<PhysicalSectorSize>512</PhysicalSectorSize>
<LogicSectorSize>512</LogicSectorSize>
<Heads>16</Heads>
<Sectors>63</Sectors>
<Padding>0</Padding>
<Encryption>
<Engine>{00000000-0000-0000-0000-000000000000}</Engine>
<Data></Data>
</Encryption>
<UID>{f2025fdb-9c86-4964-ba93-3ad17aa48deb}</UID>
<Name>Samsung SSD 860 EVO 500GB Media (disk1).hdd</Name>
<Miscellaneous>
<CompatLevel>level2</CompatLevel>
<Bootable>0</Bootable>
<DupBlocksCnt>0</DupBlocksCnt>
<CorruptBlocksCnt>0</CorruptBlocksCnt>
<UnrefBlocksCnt>0</UnrefBlocksCnt>
<OutOfDiskBlocksCnt>0</OutOfDiskBlocksCnt>
<SuspendState>0</SuspendState>
<ChangeState>0</ChangeState>
<ShutdownState>0</ShutdownState>
</Miscellaneous>
</Disk_Parameters>
<StorageData>
<Storage Protected="True">
<Start>0</Start>
<End>1</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{b0f161f5-b065-4d7c-8df0-b2dc974922fa}</GUID>
<Type>Plain</Type>
<File>PhysicalMbr.hds</File>
</Image>
</Storage>
<Storage Protected="True">
<Start>1</Start>
<End>34</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{b0f161f5-b065-4d7c-8df0-b2dc974922fa}</GUID>
<Type>Plain</Type>
<File>PhysicalGpt.hds</File>
</Image>
</Storage>
<Storage>
<Start>34</Start>
<End>32768</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{b0f161f5-b065-4d7c-8df0-b2dc974922fa}</GUID>
<Type>Bootcamp_UID</Type>
<File>3B40E677-F439-45DA-B28C-BA8456664756</File>
</Image>
</Storage>
<Storage>
<Start>32768</Start>
<End>976771072</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{b0f161f5-b065-4d7c-8df0-b2dc974922fa}</GUID>
<Type>Bootcamp_UID</Type>
<File>A5B8DEFC-5B16-499C-B8C8-97B3A8287427</File>
</Image>
</Storage>
<Storage Protected="True">
<Start>976773135</Start>
<End>976773168</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{b0f161f5-b065-4d7c-8df0-b2dc974922fa}</GUID>
<Type>Plain</Type>
<File>PhysicalGptCopy.hds</File>
</Image>
</Storage>
</StorageData>
<Snapshots>
<Shot>
<GUID>{b0f161f5-b065-4d7c-8df0-b2dc974922fa}</GUID>
<ParentGUID>{00000000-0000-0000-0000-000000000000}</ParentGUID>
</Shot>
</Snapshots>
</Parallels_disk_image>
<?xml version='1.0' encoding='UTF-8'?>
<Parallels_disk_image Version="1.0">
<Disk_Parameters>
<Disk_size>976773168</Disk_size>
<Cylinders>969021</Cylinders>
<PhysicalSectorSize>512</PhysicalSectorSize>
<LogicSectorSize>512</LogicSectorSize>
<Heads>16</Heads>
<Sectors>63</Sectors>
<Padding>0</Padding>
<Encryption>
<Engine>{00000000-0000-0000-0000-000000000000}</Engine>
<Data></Data>
</Encryption>
<UID>{631365f5-35af-43ae-a911-aeddf03d7444}</UID>
<Name>Samsung SSD 970 EVO 500GB Media (disk0).hdd</Name>
<Miscellaneous>
<CompatLevel>level2</CompatLevel>
<Bootable>1</Bootable>
<DupBlocksCnt>0</DupBlocksCnt>
<CorruptBlocksCnt>0</CorruptBlocksCnt>
<UnrefBlocksCnt>0</UnrefBlocksCnt>
<OutOfDiskBlocksCnt>0</OutOfDiskBlocksCnt>
<SuspendState>0</SuspendState>
<ChangeState>0</ChangeState>
<ShutdownState>0</ShutdownState>
</Miscellaneous>
</Disk_Parameters>
<StorageData>
<Storage Protected="True">
<Start>0</Start>
<End>1</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{5fbaabe3-6958-40ff-92a7-860e329aab41}</GUID>
<Type>Plain</Type>
<File>PhysicalMbr.hds</File>
</Image>
</Storage>
<Storage Protected="True">
<Start>1</Start>
<End>34</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{5fbaabe3-6958-40ff-92a7-860e329aab41}</GUID>
<Type>Plain</Type>
<File>PhysicalGpt.hds</File>
</Image>
</Storage>
<Storage>
<Start>1024000</Start>
<End>1226752</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{5fbaabe3-6958-40ff-92a7-860e329aab41}</GUID>
<Type>Bootcamp_UID</Type>
<File>AD55BF00-12E6-40D6-A22C-B7EFA3AF8442</File>
</Image>
</Storage>
<Storage>
<Start>1259520</Start>
<End>976773120</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{5fbaabe3-6958-40ff-92a7-860e329aab41}</GUID>
<Type>Bootcamp_UID</Type>
<File>6F7BF837-3DE7-4070-B244-30E8D72CBD33</File>
</Image>
</Storage>
<Storage Protected="True">
<Start>976773135</Start>
<End>976773168</End>
<Blocksize>2048</Blocksize>
<Image>
<GUID>{5fbaabe3-6958-40ff-92a7-860e329aab41}</GUID>
<Type>Plain</Type>
<File>PhysicalGptCopy.hds</File>
</Image>
</Storage>
</StorageData>
<Snapshots>
<Shot>
<GUID>{5fbaabe3-6958-40ff-92a7-860e329aab41}</GUID>
<ParentGUID>{00000000-0000-0000-0000-000000000000}</ParentGUID>
</Shot>
</Snapshots>
</Parallels_disk_image>
@SdotVdot
Copy link

You can use Parallels 12 to generate this .xml. Have you tried?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment