Skip to content

Commit 16cf82a

Browse files
committed
Add support for nativeParentHint
1 parent 0981102 commit 16cf82a

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

dissect/hypervisor/disk/vmdk.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,11 @@ def __init__(self, fh: BinaryIO | Path, parent: BinaryIO | VMDK | None = None):
7777
fh.close()
7878

7979
# The descriptor file determines the parent
80-
if self.parent is None and self.descriptor.attributes["parentCID"] != "ffffffff":
81-
self.parent = open_parent(path.parent, self.descriptor.attributes["parentFileNameHint"])
80+
if self.parent is None:
81+
if self.descriptor.attributes["parentCID"] != "ffffffff":
82+
self.parent = open_parent(path.parent, self.descriptor.attributes["parentFileNameHint"])
83+
elif self.descriptor.attributes.get("ddb.nativeParentCID", "ffffffff") != "ffffffff":
84+
self.parent = open_parent(path.parent, self.descriptor.attributes["ddb.nativeParentHint"])
8285

8386
# Open all extents listed in the descriptor
8487
for extent_descriptor in self.descriptor.extents:
@@ -91,8 +94,11 @@ def __init__(self, fh: BinaryIO | Path, parent: BinaryIO | VMDK | None = None):
9194
extent = Extent.from_fh(fh, path)
9295

9396
# The single file VMDK may have a parent in the embedded descriptor
94-
if extent.descriptor and extent.descriptor.attributes["parentCID"] != "ffffffff":
95-
self.parent = open_parent(path.parent, extent.descriptor.attributes["parentFileNameHint"])
97+
if extent.descriptor:
98+
if extent.descriptor.attributes["parentCID"] != "ffffffff":
99+
self.parent = open_parent(path.parent, extent.descriptor.attributes["parentFileNameHint"])
100+
elif extent.descriptor.attributes.get("ddb.nativeParentCID", "ffffffff") != "ffffffff":
101+
self.parent = open_parent(path.parent, extent.descriptor.attributes["ddb.nativeParentHint"])
96102

97103
self.extents.append(extent)
98104

tests/disk/test_vmdk.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,3 +254,19 @@ def mock_exists(path: Path) -> bool:
254254
# Case: Fallback to sibling — try ../sibling/hint.vmdk
255255
vmdk = open_parent(Path("base"), "sibling/hint.vmdk")
256256
assert str(vmdk.path) == "mocked-path"
257+
258+
259+
def test_native_parent_hint(tmp_path: Path) -> None:
260+
"""Test that we correctly handle the ddb.nativeParentHint attribute for both descriptor and extent descriptors."""
261+
262+
descriptor = b"""# Disk DescriptorFile
263+
parentCID=ffffffff
264+
265+
ddb.nativeParentCID = "8c5389b7"
266+
ddb.nativeParentHint = "disk-name.vmdk"
267+
"""
268+
tmp_path.joinpath("descriptor.vmdk").write_bytes(descriptor)
269+
270+
with patch("dissect.hypervisor.disk.vmdk.open_parent") as mock_open_parent:
271+
VMDK(tmp_path.joinpath("descriptor.vmdk"))
272+
mock_open_parent.assert_called_with(tmp_path, "disk-name.vmdk")

0 commit comments

Comments
 (0)