dissect.hypervisor 3.21.dev4__py3-none-any.whl → 3.22.dev1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,90 +2,97 @@ from __future__ import annotations
2
2
 
3
3
  from dissect.cstruct import cstruct
4
4
 
5
- # https://www.virtualbox.org/browser/vbox/trunk/src/VBox/Storage/VDICore.h
6
- # https://forums.virtualbox.org/viewtopic.php?t=8046
7
- # 0000 3C 3C 3C 20 53 75 6E 20 78 56 4D 20 56 69 72 74 <<< Sun xVM Virt
8
- # 0010 75 61 6C 42 6F 78 20 44 69 73 6B 20 49 6D 61 67 ualBox Disk Imag
9
- # 0020 65 20 3E 3E 3E 0A 00 00 00 00 00 00 00 00 00 00 e >>>
10
- # 0030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
11
- #
12
- # 0040 7F 10 DA BE Image Signature
13
- # 01 00 01 00 Version 1.1
14
- # 90 01 00 00 Size of Header(0x190)
15
- # 01 00 00 00 Image Type (Dynamic VDI)
16
- # 0050 00 00 00 00 Image Flags
17
- # 00 00 00 00 00 00 00 00 00 00 00 00 Image Description
18
- # 0060-001F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
19
- # 0150 00 00 00 00
20
- # 00 02 00 00 offsetBlocks
21
- # 00 20 00 00 offsetData
22
- # 00 00 00 00 #Cylinders (0)
23
- # 0160 00 00 00 00 #Heads (0)
24
- # 00 00 00 00 #Sectors (0)
25
- # 00 02 00 00 SectorSize (512)
26
- # 00 00 00 00 -- unused --
27
- # 0170 00 00 00 78 00 00 00 00 DiskSize (Bytes)
28
- # 00 00 10 00 BlockSize
29
- # 00 00 00 00 Block Extra Data (0)
30
- # 0180 80 07 00 00 #BlocksInHDD
31
- # 0B 02 00 00 #BlocksAllocated
32
- # 5A 08 62 27 A8 B6 69 44 UUID of this VDI
33
- # 0190 A1 57 E2 B2 43 A5 8F CB
34
- # 0C 5C B1 E3 C5 73 ED 40 UUID of last SNAP
35
- # 01A0 AE F7 06 D6 20 69 0C 96
36
- # 00 00 00 00 00 00 00 00 UUID link
37
- # 01B0 00 00 00 00 00 00 00 00
38
- # 00 00 00 00 00 00 00 00 UUID Parent
39
- # 01C0 00 00 00 00 00 00 00 00
40
- # CF 03 00 00 00 00 00 00 -- garbage / unused --
41
- # 01D0 3F 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 -- garbage / unused --
42
- # 01E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -- unused --
43
- # 01F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -- unused --
44
-
5
+ # https://github.com/VirtualBox/virtualbox/blob/main/src/VBox/Storage/VDICore.h
45
6
  vdi_def = """
46
- enum ImageType : uint32 {
47
- Dynamic = 0x01,
48
- Fixed = 0x02,
49
- Undo = 0x03,
50
- Differencing = 0x04
7
+ enum VDI_IMAGE_TYPE {
8
+ /** Normal dynamically growing base image file. */
9
+ NORMAL = 1,
10
+ /** Preallocated base image file of a fixed size. */
11
+ FIXED,
12
+ /** Dynamically growing image file for undo/commit changes support. */
13
+ UNDO,
14
+ /** Dynamically growing image file for differencing support. */
15
+ DIFF,
51
16
  };
52
17
 
53
- flag ImageFlags : uint32 {
54
- None = 0x00000000,
55
- Split2G = 0x00000001,
56
- ZeroExpand = 0x00000002
18
+ flag VDI_IMAGE_FLAGS {
19
+ /** Fill new blocks with zeroes while expanding image file. Only valid
20
+ * for newly created images, never set for opened existing images. */
21
+ ZERO_EXPAND = 0x0100,
57
22
  };
58
23
 
59
- struct HeaderDescriptor {
60
- char FileInfo[64];
61
- uint32 Signature;
62
- uint32 Version;
63
- uint32 HeaderSize;
64
- ImageType ImageType;
65
- ImageFlags ImageFlags;
66
- char ImageDescription[256];
67
- uint32 BlocksOffset;
68
- uint32 DataOffset;
69
- uint32 NumCylinders;
70
- uint32 NumHeads;
71
- uint32 NumSectors;
72
- uint32 SectorSize;
73
- uint32 Unused1;
74
- uint64 DiskSize;
75
- uint32 BlockSize;
76
- uint32 BlockExtraData;
77
- uint32 BlocksInHDD;
78
- uint32 BlocksAllocated;
79
- char UUIDVDI[16];
80
- char UUIDSNAP[16];
81
- char UUIDLink[16];
82
- char UUIDParent[16];
83
- };
24
+ typedef struct VDIDISKGEOMETRY {
25
+ /** Cylinders. */
26
+ uint32_t Cylinders;
27
+ /** Heads. */
28
+ uint32_t Heads;
29
+ /** Sectors per track. */
30
+ uint32_t Sectors;
31
+ /** Sector size. (bytes per sector) */
32
+ uint32_t Sector;
33
+ } VDIDISKGEOMETRY, *PVDIDISKGEOMETRY;
34
+
35
+ typedef struct VDIPREHEADER {
36
+ /** Just text info about image type, for eyes only. */
37
+ char szFileInfo[64];
38
+ /** The image signature (VDI_IMAGE_SIGNATURE). */
39
+ uint32_t u32Signature;
40
+ /** The image version (VDI_IMAGE_VERSION). */
41
+ uint32_t u32Version;
42
+ } VDIPREHEADER, *PVDIPREHEADER;
43
+
44
+ /**
45
+ * Size of Comment field of HDD image header.
46
+ */
47
+ #define VDI_IMAGE_COMMENT_SIZE 256
48
+
49
+ /* NOTE: All the header versions are additive, so just use the latest one. */
50
+ typedef struct VDIHEADER1PLUS {
51
+ /** Size of this structure in bytes. */
52
+ uint32_t cbHeader;
53
+ /** The image type (VDI_IMAGE_TYPE_*). */
54
+ VDI_IMAGE_TYPE u32Type;
55
+ /** Image flags (VDI_IMAGE_FLAGS_*). */
56
+ VDI_IMAGE_FLAGS fFlags;
57
+ /** Image comment. (UTF-8) */
58
+ char szComment[VDI_IMAGE_COMMENT_SIZE];
59
+ /** Offset of blocks array from the beginning of image file.
60
+ * Should be sector-aligned for HDD access optimization. */
61
+ uint32_t offBlocks;
62
+ /** Offset of image data from the beginning of image file.
63
+ * Should be sector-aligned for HDD access optimization. */
64
+ uint32_t offData;
65
+ /** Legacy image geometry (previous code stored PCHS there). */
66
+ VDIDISKGEOMETRY LegacyGeometry;
67
+ /** Was BIOS HDD translation mode, now unused. */
68
+ uint32_t u32Dummy;
69
+ /** Size of disk (in bytes). */
70
+ uint64_t cbDisk;
71
+ /** Block size. (For instance VDI_IMAGE_BLOCK_SIZE.) Should be a power of 2! */
72
+ uint32_t cbBlock;
73
+ /** Size of additional service information of every data block.
74
+ * Prepended before block data. May be 0.
75
+ * Should be a power of 2 and sector-aligned for optimization reasons. */
76
+ uint32_t cbBlockExtra;
77
+ /** Number of blocks. */
78
+ uint32_t cBlocks;
79
+ /** Number of allocated blocks. */
80
+ uint32_t cBlocksAllocated;
81
+ /** UUID of image. */
82
+ char uuidCreate[16];
83
+ /** UUID of image's last modification. */
84
+ char uuidModify[16];
85
+ /** Only for secondary images - UUID of previous image. */
86
+ char uuidLinkage[16];
87
+ /** Only for secondary images - UUID of previous image's last modification. */
88
+ char uuidParentModify[16];
89
+ /** LCHS image geometry (new field in VDI1.2 version. */
90
+ VDIDISKGEOMETRY Geometry;
91
+ } VDIHEADER1PLUS, *PVDIHEADER1PLUS;
84
92
  """
85
93
 
86
94
  c_vdi = cstruct().load(vdi_def)
87
95
 
88
- VDI_SIGNATURE = 0xBEDA107F
89
-
90
- UNALLOCATED = -1
91
- SPARSE = -2
96
+ VDI_IMAGE_SIGNATURE = 0xBEDA107F
97
+ VDI_IMAGE_BLOCK_FREE = ~0
98
+ VDI_IMAGE_BLOCK_ZERO = ~1
@@ -0,0 +1,100 @@
1
+ # Generated by cstruct-stubgen
2
+ from typing import BinaryIO, Literal, TypeAlias, overload
3
+
4
+ import dissect.cstruct as __cs__
5
+
6
+ class _c_vdi(__cs__.cstruct):
7
+ VDI_IMAGE_COMMENT_SIZE: Literal[256] = ...
8
+ class VDI_IMAGE_TYPE(__cs__.Enum):
9
+ NORMAL = ...
10
+ FIXED = ...
11
+ UNDO = ...
12
+ DIFF = ...
13
+
14
+ class VDI_IMAGE_FLAGS(__cs__.Flag):
15
+ ZERO_EXPAND = ...
16
+
17
+ class VDIDISKGEOMETRY(__cs__.Structure):
18
+ Cylinders: _c_vdi.uint32
19
+ Heads: _c_vdi.uint32
20
+ Sectors: _c_vdi.uint32
21
+ Sector: _c_vdi.uint32
22
+ @overload
23
+ def __init__(
24
+ self,
25
+ Cylinders: _c_vdi.uint32 | None = ...,
26
+ Heads: _c_vdi.uint32 | None = ...,
27
+ Sectors: _c_vdi.uint32 | None = ...,
28
+ Sector: _c_vdi.uint32 | None = ...,
29
+ ): ...
30
+ @overload
31
+ def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...
32
+
33
+ PVDIDISKGEOMETRY: TypeAlias = __cs__.Pointer[_c_vdi.VDIDISKGEOMETRY]
34
+ class VDIPREHEADER(__cs__.Structure):
35
+ szFileInfo: __cs__.CharArray
36
+ u32Signature: _c_vdi.uint32
37
+ u32Version: _c_vdi.uint32
38
+ @overload
39
+ def __init__(
40
+ self,
41
+ szFileInfo: __cs__.CharArray | None = ...,
42
+ u32Signature: _c_vdi.uint32 | None = ...,
43
+ u32Version: _c_vdi.uint32 | None = ...,
44
+ ): ...
45
+ @overload
46
+ def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...
47
+
48
+ PVDIPREHEADER: TypeAlias = __cs__.Pointer[_c_vdi.VDIPREHEADER]
49
+ class VDIHEADER1PLUS(__cs__.Structure):
50
+ cbHeader: _c_vdi.uint32
51
+ u32Type: _c_vdi.VDI_IMAGE_TYPE
52
+ fFlags: _c_vdi.VDI_IMAGE_FLAGS
53
+ szComment: __cs__.CharArray
54
+ offBlocks: _c_vdi.uint32
55
+ offData: _c_vdi.uint32
56
+ LegacyGeometry: _c_vdi.VDIDISKGEOMETRY
57
+ u32Dummy: _c_vdi.uint32
58
+ cbDisk: _c_vdi.uint64
59
+ cbBlock: _c_vdi.uint32
60
+ cbBlockExtra: _c_vdi.uint32
61
+ cBlocks: _c_vdi.uint32
62
+ cBlocksAllocated: _c_vdi.uint32
63
+ uuidCreate: __cs__.CharArray
64
+ uuidModify: __cs__.CharArray
65
+ uuidLinkage: __cs__.CharArray
66
+ uuidParentModify: __cs__.CharArray
67
+ Geometry: _c_vdi.VDIDISKGEOMETRY
68
+ @overload
69
+ def __init__(
70
+ self,
71
+ cbHeader: _c_vdi.uint32 | None = ...,
72
+ u32Type: _c_vdi.VDI_IMAGE_TYPE | None = ...,
73
+ fFlags: _c_vdi.VDI_IMAGE_FLAGS | None = ...,
74
+ szComment: __cs__.CharArray | None = ...,
75
+ offBlocks: _c_vdi.uint32 | None = ...,
76
+ offData: _c_vdi.uint32 | None = ...,
77
+ LegacyGeometry: _c_vdi.VDIDISKGEOMETRY | None = ...,
78
+ u32Dummy: _c_vdi.uint32 | None = ...,
79
+ cbDisk: _c_vdi.uint64 | None = ...,
80
+ cbBlock: _c_vdi.uint32 | None = ...,
81
+ cbBlockExtra: _c_vdi.uint32 | None = ...,
82
+ cBlocks: _c_vdi.uint32 | None = ...,
83
+ cBlocksAllocated: _c_vdi.uint32 | None = ...,
84
+ uuidCreate: __cs__.CharArray | None = ...,
85
+ uuidModify: __cs__.CharArray | None = ...,
86
+ uuidLinkage: __cs__.CharArray | None = ...,
87
+ uuidParentModify: __cs__.CharArray | None = ...,
88
+ Geometry: _c_vdi.VDIDISKGEOMETRY | None = ...,
89
+ ): ...
90
+ @overload
91
+ def __init__(self, fh: bytes | memoryview | bytearray | BinaryIO, /): ...
92
+
93
+ PVDIHEADER1PLUS: TypeAlias = __cs__.Pointer[_c_vdi.VDIHEADER1PLUS]
94
+
95
+ # Technically `c_vdi` is an instance of `_c_vdi`, but then we can't use it in type hints
96
+ c_vdi: TypeAlias = _c_vdi
97
+
98
+ VDI_IMAGE_SIGNATURE: int
99
+ VDI_IMAGE_BLOCK_FREE: int
100
+ VDI_IMAGE_BLOCK_ZERO: int
@@ -176,7 +176,7 @@ class QCow2:
176
176
  return data_file
177
177
 
178
178
  if self.path:
179
- if (data_file_path := self.path.with_name(self.image_data_file)).exists():
179
+ if (data_file_path := self.path.parent.joinpath(self.image_data_file)).exists():
180
180
  return data_file_path.open("rb")
181
181
 
182
182
  if not allow_no_data_file:
@@ -190,7 +190,7 @@ class QCow2:
190
190
  backing_file_path = None
191
191
  if backing_file is None:
192
192
  if self.path:
193
- if (backing_file_path := self.path.with_name(self.auto_backing_file)).exists():
193
+ if (backing_file_path := self.path.parent.joinpath(self.auto_backing_file)).exists():
194
194
  backing_file = backing_file_path.open("rb")
195
195
  elif not allow_no_backing_file:
196
196
  raise Error(
@@ -1,62 +1,140 @@
1
1
  from __future__ import annotations
2
2
 
3
- import array
4
- from typing import BinaryIO
3
+ from pathlib import Path
4
+ from typing import TYPE_CHECKING, BinaryIO
5
5
 
6
6
  from dissect.util.stream import AlignedStream
7
+ from dissect.util.xmemoryview import xmemoryview
7
8
 
8
- from dissect.hypervisor.disk.c_vdi import SPARSE, UNALLOCATED, VDI_SIGNATURE, c_vdi
9
+ from dissect.hypervisor.disk.c_vdi import VDI_IMAGE_BLOCK_FREE, VDI_IMAGE_BLOCK_ZERO, VDI_IMAGE_SIGNATURE, c_vdi
9
10
  from dissect.hypervisor.exceptions import Error
10
11
 
12
+ if TYPE_CHECKING:
13
+ from types import TracebackType
14
+
15
+ from typing_extensions import Self
11
16
 
12
- class VDI(AlignedStream):
13
- def __init__(self, fh: BinaryIO, parent: VDI | None = None):
14
- self.fh = fh
15
- self.parent = parent
16
- self.header = c_vdi.HeaderDescriptor(fh)
17
17
 
18
- if self.header.Signature != VDI_SIGNATURE:
19
- raise Error("Not a VDI header")
18
+ class VDI:
19
+ """VirtualBox Virtual Disk Image (VDI) implementation.
20
20
 
21
- fh.seek(-1, 2)
22
- self.file_size = fh.tell()
21
+ Use :method:`open` to get a stream for reading from the VDI file. The stream will handle reading
22
+ from the parent disk if necessary (and provided).
23
23
 
24
- self.fh.seek(self.header.BlocksOffset)
24
+ If provided with a file-like object, the caller is responsible for closing it.
25
+ When provided with a path, the VDI class will manage the file handle.
25
26
 
26
- mapbuf = self.fh.read(4 * self.header.BlocksInHDD)
27
- self.map = array.array("i")
28
- try:
29
- self.map.frombytes(mapbuf)
30
- except AttributeError:
31
- self.map.fromstring(mapbuf)
27
+ If providing a parent file-like object, the caller is responsible for the lifecycle of that object.
32
28
 
33
- self.data_offset = self.header.DataOffset
34
- self.block_size = self.header.BlockSize
35
- self.sector_size = self.header.SectorSize
36
- super().__init__(size=self.header.DiskSize)
29
+ Args:
30
+ fh: File-like object or path of the VDI file.
31
+ parent: Optional file-like object for the parent disk (for differencing disks).
32
+ """
33
+
34
+ def __init__(self, fh: BinaryIO | Path, parent: BinaryIO | None = None):
35
+ if isinstance(fh, Path):
36
+ self.path = fh
37
+ self.fh = self.path.open("rb")
38
+ else:
39
+ self.path = None
40
+ self.fh = fh
41
+
42
+ self.parent = parent
43
+
44
+ self.fh.seek(0)
45
+ self.preheader = c_vdi.VDIPREHEADER(self.fh)
46
+ if self.preheader.u32Signature != VDI_IMAGE_SIGNATURE:
47
+ raise Error(
48
+ f"Invalid VDI signature, expected {VDI_IMAGE_SIGNATURE:#08X}, got {self.preheader.u32Signature:#08X}"
49
+ )
50
+
51
+ self.header = c_vdi.VDIHEADER1PLUS(self.fh)
52
+
53
+ def __enter__(self) -> Self:
54
+ return self
55
+
56
+ def __exit__(
57
+ self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None
58
+ ) -> None:
59
+ self.close()
60
+
61
+ @property
62
+ def type(self) -> c_vdi.VDI_IMAGE_TYPE:
63
+ """The type of the VDI file."""
64
+ return self.header.u32Type
65
+
66
+ @property
67
+ def flags(self) -> c_vdi.VDI_IMAGE_FLAGS:
68
+ """The flags of the VDI file."""
69
+ return self.header.fFlags
70
+
71
+ @property
72
+ def size(self) -> int:
73
+ """The size of the virtual disk."""
74
+ return self.header.cbDisk
75
+
76
+ @property
77
+ def block_size(self) -> int:
78
+ """The size of each block in the VDI file."""
79
+ return self.header.cbBlock
80
+
81
+ @property
82
+ def data_offset(self) -> int:
83
+ """The offset to the data blocks."""
84
+ return self.header.offData
85
+
86
+ @property
87
+ def blocks_offset(self) -> int:
88
+ """The offset to the block allocation table."""
89
+ return self.header.offBlocks
90
+
91
+ @property
92
+ def number_of_blocks(self) -> int:
93
+ """The number of blocks in the VDI file."""
94
+ return self.header.cBlocks
95
+
96
+ def open(self) -> VDIStream:
97
+ """Open a stream to read from the VDI file."""
98
+ return VDIStream(self)
99
+
100
+ def close(self) -> None:
101
+ """Close the VDI file handle."""
102
+ if self.path is not None:
103
+ self.fh.close()
104
+
105
+
106
+ class VDIStream(AlignedStream):
107
+ def __init__(self, vdi: VDI):
108
+ self.vdi = vdi
109
+ self.block_size = vdi.block_size
110
+
111
+ self.fh = self.vdi.fh
112
+ self.fh.seek(self.vdi.blocks_offset)
113
+ self.map = xmemoryview(self.fh.read(4 * self.vdi.number_of_blocks), "<i")
114
+ super().__init__(vdi.size, align=self.block_size)
37
115
 
38
116
  def _read(self, offset: int, length: int) -> bytes:
39
- block_idx, block_offset = divmod(offset, self.block_size)
117
+ result = []
40
118
 
41
- bytes_read = []
119
+ block_idx, offset_in_block = divmod(offset, self.block_size)
42
120
  while length > 0:
43
- read_len = min(length, max(length, self.block_size))
121
+ read_len = min(length, max(length, self.block_size - offset_in_block))
44
122
 
45
123
  block = self.map[block_idx]
46
-
47
- if block == UNALLOCATED:
48
- if self.parent:
49
- bytes_read.append(self.parent._read(offset, read_len))
124
+ if block == VDI_IMAGE_BLOCK_FREE:
125
+ if self.vdi.parent is not None:
126
+ self.vdi.parent.seek(offset)
127
+ result.append(self.vdi.parent.read(read_len))
50
128
  else:
51
- bytes_read.append(b"\x00" * read_len)
52
- elif block == SPARSE:
53
- bytes_read.append(b"\x00" * read_len)
129
+ result.append(b"\x00" * read_len)
130
+ elif block == VDI_IMAGE_BLOCK_ZERO:
131
+ result.append(b"\x00" * read_len)
54
132
  else:
55
- self.fh.seek(self.data_offset + (block * self.block_size) + block_offset)
56
- bytes_read.append(self.fh.read(read_len))
133
+ self.fh.seek(self.vdi.data_offset + (block * self.block_size) + offset_in_block)
134
+ result.append(self.fh.read(read_len))
57
135
 
58
136
  offset += read_len
59
137
  length -= read_len
60
138
  block_idx += 1
61
139
 
62
- return b"".join(bytes_read)
140
+ return b"".join(result)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dissect.hypervisor
3
- Version: 3.21.dev4
3
+ Version: 3.22.dev1
4
4
  Summary: A Dissect module implementing parsers for various hypervisor disk, backup and configuration files
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -14,13 +14,14 @@ dissect/hypervisor/disk/c_asif.pyi,sha256=XlFattLWlcRLQTCCzKThgANsW9JwUOi_utWjPr
14
14
  dissect/hypervisor/disk/c_hdd.py,sha256=wrJ5qwyf7QCZ3Pl-I8eYDR4CUUo4pAFhjzs8huRGqs8,2235
15
15
  dissect/hypervisor/disk/c_qcow2.py,sha256=jOr2fQmDQuegbE1qDX2x2xaA4RS0LKMsOCI5UwKJxhg,5071
16
16
  dissect/hypervisor/disk/c_qcow2.pyi,sha256=OAEQzYoexjUpyApO0I-JQe22qBPzej_KC4r_77jAo3U,7867
17
- dissect/hypervisor/disk/c_vdi.py,sha256=lKk5MnCImdfyUyGDe_yY_ntLd1ITkKEvMGIMCHiHC2w,3843
17
+ dissect/hypervisor/disk/c_vdi.py,sha256=I900-qEvbS7dvtVIqbRcyF47OhTiyoA1Y6TtT-tlUv8,3514
18
+ dissect/hypervisor/disk/c_vdi.pyi,sha256=7c3eU3MeZlvbZbOJixe_JEVpuQsIZs2mxP1iH2fV4pQ,3661
18
19
  dissect/hypervisor/disk/c_vhd.py,sha256=gYOwOdvhMKNLflugkpjmdn__ZUJBlxeByx6P0ePNQ00,1493
19
20
  dissect/hypervisor/disk/c_vhdx.py,sha256=4yNU51jfYPEBFXEZAvaF8cFdHBRlmCe_OU5ZU83-kco,2920
20
21
  dissect/hypervisor/disk/c_vmdk.py,sha256=lfObMyD9r-20DCDwVDm9xT98cq3aE4MCJF5TpDBNdd4,5988
21
22
  dissect/hypervisor/disk/hdd.py,sha256=ChKtQIQrssIgZyUv86JE9-n4XdjDT14pc6EO6mZllQg,12981
22
- dissect/hypervisor/disk/qcow2.py,sha256=cQbmvOr76SWZmMNuFAWaecvGObZ2BsaVzUBB4ncfjNg,24318
23
- dissect/hypervisor/disk/vdi.py,sha256=Ezm_vmi6ZKLTgPx5chXmtBzkBOCxilBWUrdqQdq_4KA,1958
23
+ dissect/hypervisor/disk/qcow2.py,sha256=Em628ixzU6Wey8yIhTlKbp4O8LSksR7Ive3knbX0dnc,24330
24
+ dissect/hypervisor/disk/vdi.py,sha256=URS0JNvBZVEWnZQYV6nrgsMBXmumDIIem5Eqmv-VVG0,4479
24
25
  dissect/hypervisor/disk/vhd.py,sha256=GfEfFp5g8OlV0MrTXqSfBRzMMvIZO_T1A8d05SeGiBk,3948
25
26
  dissect/hypervisor/disk/vhdx.py,sha256=kgxS81oG4J3RPsDput-t3QhbF1vDCdjfPqY__sWbX6g,13215
26
27
  dissect/hypervisor/disk/vmdk.py,sha256=8jK35fbowlX8jRlj_Xsk5mc2VXwt_NJ0PK_dHE-NIzA,19672
@@ -30,10 +31,10 @@ dissect/hypervisor/tools/vmtar.py,sha256=bAf_rEhqUmeI8my22p7L9uV3SgB5C_61YQKfD3t
30
31
  dissect/hypervisor/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
32
  dissect/hypervisor/util/envelope.py,sha256=EhZjZh3EezqxkJ84OgqpptHIhpVWPcUkFMjdYU-iAnU,10442
32
33
  dissect/hypervisor/util/vmtar.py,sha256=pktC1mZIhh1E2uSyb2Z_pvn9H9LebJ6hTmZlYcdGrOA,4038
33
- dissect_hypervisor-3.21.dev4.dist-info/licenses/COPYRIGHT,sha256=EOOoIwk_inOMUD4c1ylpzMtYLjGzmc-MLEVAEdLLr20,305
34
- dissect_hypervisor-3.21.dev4.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
35
- dissect_hypervisor-3.21.dev4.dist-info/METADATA,sha256=GXN5D04t8S6CseMRCjkEGIiAm5iO3GZUueFka6NjEWQ,3470
36
- dissect_hypervisor-3.21.dev4.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
37
- dissect_hypervisor-3.21.dev4.dist-info/entry_points.txt,sha256=kW36GnJ3G1dSRYFL4r8Bj32Al_CkGqST3bdHvo3pyiY,120
38
- dissect_hypervisor-3.21.dev4.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
39
- dissect_hypervisor-3.21.dev4.dist-info/RECORD,,
34
+ dissect_hypervisor-3.22.dev1.dist-info/licenses/COPYRIGHT,sha256=EOOoIwk_inOMUD4c1ylpzMtYLjGzmc-MLEVAEdLLr20,305
35
+ dissect_hypervisor-3.22.dev1.dist-info/licenses/LICENSE,sha256=DZak_2itbUtvHzD3E7GNUYSRK6jdOJ-GqncQ2weavLA,34523
36
+ dissect_hypervisor-3.22.dev1.dist-info/METADATA,sha256=vrcemw95XPR9v2Yn1Y4k3rKJ60bL4uW9DcdsmBKTJR4,3470
37
+ dissect_hypervisor-3.22.dev1.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
38
+ dissect_hypervisor-3.22.dev1.dist-info/entry_points.txt,sha256=kW36GnJ3G1dSRYFL4r8Bj32Al_CkGqST3bdHvo3pyiY,120
39
+ dissect_hypervisor-3.22.dev1.dist-info/top_level.txt,sha256=Mn-CQzEYsAbkxrUI0TnplHuXnGVKzxpDw_po_sXpvv4,8
40
+ dissect_hypervisor-3.22.dev1.dist-info/RECORD,,