282 lines
7.5 KiB
Python
282 lines
7.5 KiB
Python
# Copyright 2017 Cloudbase Solutions Srl
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import ctypes
|
|
|
|
from os_win.utils.winapi import wintypes
|
|
|
|
lib_handle = None
|
|
|
|
|
|
class VIRTUAL_STORAGE_TYPE(ctypes.Structure):
|
|
_fields_ = [
|
|
('DeviceId', wintypes.DWORD),
|
|
('VendorId', wintypes.GUID)
|
|
]
|
|
|
|
|
|
PVIRTUAL_STORAGE_TYPE = ctypes.POINTER(VIRTUAL_STORAGE_TYPE)
|
|
|
|
|
|
class _RESIZE_VIRTUAL_DISK_PARAMETERS_V1(ctypes.Structure):
|
|
_fields_ = [
|
|
('NewSize', wintypes.ULONGLONG)
|
|
]
|
|
|
|
|
|
# Only V1 is used, we avoid defining a union.
|
|
class RESIZE_VIRTUAL_DISK_PARAMETERS(ctypes.Structure):
|
|
_fields_ = [
|
|
('Version', wintypes.DWORD),
|
|
('Version1', _RESIZE_VIRTUAL_DISK_PARAMETERS_V1)
|
|
]
|
|
|
|
|
|
PRESIZE_VIRTUAL_DISK_PARAMETERS = ctypes.POINTER(
|
|
RESIZE_VIRTUAL_DISK_PARAMETERS)
|
|
|
|
|
|
class _OPEN_VIRTUAL_DISK_PARAMETERS_V1(ctypes.Structure):
|
|
_fields_ = [
|
|
('RWDepth', wintypes.ULONG),
|
|
]
|
|
|
|
|
|
class _OPEN_VIRTUAL_DISK_PARAMETERS_V2(ctypes.Structure):
|
|
_fields_ = [
|
|
('GetInfoOnly', wintypes.BOOL),
|
|
('ReadOnly', wintypes.BOOL),
|
|
('ResiliencyGuid', wintypes.GUID)
|
|
]
|
|
|
|
|
|
class _OPEN_VIRTUAL_DISK_PARAMETERS_U(ctypes.Union):
|
|
_fields_ = [
|
|
('Version1', _OPEN_VIRTUAL_DISK_PARAMETERS_V1),
|
|
('Version2', _OPEN_VIRTUAL_DISK_PARAMETERS_V2)
|
|
]
|
|
|
|
|
|
class OPEN_VIRTUAL_DISK_PARAMETERS(ctypes.Structure):
|
|
_anonymous_ = ['_parameters']
|
|
_fields_ = [
|
|
('Version', wintypes.DWORD),
|
|
('_parameters', _OPEN_VIRTUAL_DISK_PARAMETERS_U)
|
|
]
|
|
|
|
|
|
POPEN_VIRTUAL_DISK_PARAMETERS = ctypes.POINTER(
|
|
OPEN_VIRTUAL_DISK_PARAMETERS)
|
|
|
|
|
|
class _MERGE_VIRTUAL_DISK_PARAMETERS_V1(ctypes.Structure):
|
|
_fields_ = [
|
|
('MergeDepth', wintypes.ULONG)
|
|
]
|
|
|
|
|
|
# Only V1 is used, we avoid defining a union.
|
|
class MERGE_VIRTUAL_DISK_PARAMETERS(ctypes.Structure):
|
|
_fields_ = [
|
|
('Version', wintypes.DWORD),
|
|
('Version1', _MERGE_VIRTUAL_DISK_PARAMETERS_V1)
|
|
]
|
|
|
|
|
|
PMERGE_VIRTUAL_DISK_PARAMETERS = ctypes.POINTER(
|
|
MERGE_VIRTUAL_DISK_PARAMETERS)
|
|
|
|
|
|
class _CREATE_VIRTUAL_DISK_PARAMETERS_V2(ctypes.Structure):
|
|
_fields_ = [
|
|
('UniqueId', wintypes.GUID),
|
|
('MaximumSize', wintypes.ULONGLONG),
|
|
('BlockSizeInBytes', wintypes.ULONG),
|
|
('SectorSizeInBytes', wintypes.ULONG),
|
|
('PhysicalSectorSizeInBytes', wintypes.ULONG),
|
|
('ParentPath', wintypes.LPCWSTR),
|
|
('SourcePath', wintypes.LPCWSTR),
|
|
('OpenFlags', wintypes.DWORD),
|
|
('ParentVirtualStorageType', VIRTUAL_STORAGE_TYPE),
|
|
('SourceVirtualStorageType', VIRTUAL_STORAGE_TYPE),
|
|
('ResiliencyGuid', wintypes.GUID)
|
|
]
|
|
|
|
|
|
# Only V2 is used, we avoid defining a union.
|
|
class CREATE_VIRTUAL_DISK_PARAMETERS(ctypes.Structure):
|
|
_fields_ = [
|
|
('Version', wintypes.DWORD),
|
|
('Version2', _CREATE_VIRTUAL_DISK_PARAMETERS_V2)
|
|
]
|
|
|
|
|
|
PCREATE_VIRTUAL_DISK_PARAMETERS = ctypes.POINTER(
|
|
CREATE_VIRTUAL_DISK_PARAMETERS)
|
|
|
|
|
|
class _VHD_INFO_SIZE(ctypes.Structure):
|
|
_fields_ = [
|
|
("VirtualSize", wintypes.ULARGE_INTEGER),
|
|
("PhysicalSize", wintypes.ULARGE_INTEGER),
|
|
("BlockSize", wintypes.ULONG),
|
|
("SectorSize", wintypes.ULONG)
|
|
]
|
|
|
|
|
|
class _VHD_INFO_PARENT_LOCATION(ctypes.Structure):
|
|
_fields_ = [
|
|
('ParentResolved', wintypes.BOOL),
|
|
('ParentPath', wintypes.WCHAR * 512)
|
|
]
|
|
|
|
|
|
class _VHD_INFO_PHYSICAL_DISK(ctypes.Structure):
|
|
_fields_ = [
|
|
("LogicalSectorSize", wintypes.ULONG),
|
|
("PhysicalSectorSize", wintypes.ULONG),
|
|
("IsRemote", wintypes.BOOL)
|
|
]
|
|
|
|
|
|
class _VHD_INFO(ctypes.Union):
|
|
_fields_ = [
|
|
("Size", _VHD_INFO_SIZE),
|
|
("Identifier", wintypes.GUID),
|
|
("ParentLocation", _VHD_INFO_PARENT_LOCATION),
|
|
("ParentIdentifier", wintypes.GUID),
|
|
("ParentTimestamp", wintypes.ULONG),
|
|
("VirtualStorageType", VIRTUAL_STORAGE_TYPE),
|
|
("ProviderSubtype", wintypes.ULONG),
|
|
("Is4kAligned", wintypes.BOOL),
|
|
("IsLoaded", wintypes.BOOL),
|
|
("PhysicalDisk", _VHD_INFO_PHYSICAL_DISK),
|
|
("VhdPhysicalSectorSize", wintypes.ULONG),
|
|
("SmallestSafeVirtualSize", wintypes.ULARGE_INTEGER),
|
|
("FragmentationPercentage", wintypes.ULONG)
|
|
]
|
|
|
|
|
|
class GET_VIRTUAL_DISK_INFO(ctypes.Structure):
|
|
_anonymous_ = ['_vhdinfo']
|
|
_fields_ = [
|
|
("Version", wintypes.UINT),
|
|
("_vhdinfo", _VHD_INFO)
|
|
]
|
|
|
|
|
|
PGET_VIRTUAL_DISK_INFO = ctypes.POINTER(GET_VIRTUAL_DISK_INFO)
|
|
|
|
|
|
class _SET_VIRTUAL_DISK_INFO_U(ctypes.Union):
|
|
_fields_ = [
|
|
('ParentFilePath', wintypes.LPCWSTR),
|
|
('UniqueIdentifier', wintypes.GUID),
|
|
('VirtualDiskId', wintypes.GUID),
|
|
]
|
|
|
|
|
|
class SET_VIRTUAL_DISK_INFO(ctypes.Structure):
|
|
_anonymous_ = ['_setinfo']
|
|
_fields_ = [
|
|
('Version', wintypes.DWORD),
|
|
('_setinfo', _SET_VIRTUAL_DISK_INFO_U)
|
|
]
|
|
|
|
|
|
PSET_VIRTUAL_DISK_INFO = ctypes.POINTER(SET_VIRTUAL_DISK_INFO)
|
|
|
|
|
|
def register():
|
|
global lib_handle
|
|
lib_handle = ctypes.windll.virtdisk
|
|
|
|
lib_handle.CreateVirtualDisk.argtypes = [
|
|
PVIRTUAL_STORAGE_TYPE,
|
|
wintypes.LPCWSTR,
|
|
wintypes.INT,
|
|
wintypes.PVOID,
|
|
wintypes.INT,
|
|
wintypes.ULONG,
|
|
PCREATE_VIRTUAL_DISK_PARAMETERS,
|
|
wintypes.LPOVERLAPPED,
|
|
wintypes.PHANDLE
|
|
]
|
|
lib_handle.CreateVirtualDisk.restype = wintypes.DWORD
|
|
|
|
lib_handle.GetVirtualDiskInformation.argtypes = [
|
|
wintypes.HANDLE,
|
|
wintypes.PULONG,
|
|
PGET_VIRTUAL_DISK_INFO,
|
|
wintypes.PULONG
|
|
]
|
|
lib_handle.GetVirtualDiskInformation.restype = wintypes.DWORD
|
|
|
|
lib_handle.MergeVirtualDisk.argtypes = [
|
|
wintypes.HANDLE,
|
|
wintypes.INT,
|
|
PMERGE_VIRTUAL_DISK_PARAMETERS,
|
|
wintypes.LPOVERLAPPED
|
|
]
|
|
lib_handle.MergeVirtualDisk.restype = wintypes.DWORD
|
|
|
|
lib_handle.OpenVirtualDisk.argtypes = [
|
|
PVIRTUAL_STORAGE_TYPE,
|
|
wintypes.LPCWSTR,
|
|
wintypes.INT,
|
|
wintypes.INT,
|
|
POPEN_VIRTUAL_DISK_PARAMETERS,
|
|
wintypes.PHANDLE
|
|
]
|
|
lib_handle.OpenVirtualDisk.restype = wintypes.DWORD
|
|
|
|
lib_handle.ResizeVirtualDisk.argtypes = [
|
|
wintypes.HANDLE,
|
|
wintypes.INT,
|
|
PRESIZE_VIRTUAL_DISK_PARAMETERS,
|
|
wintypes.LPOVERLAPPED
|
|
]
|
|
lib_handle.ResizeVirtualDisk.restype = wintypes.DWORD
|
|
|
|
lib_handle.SetVirtualDiskInformation.argtypes = [
|
|
wintypes.HANDLE,
|
|
PSET_VIRTUAL_DISK_INFO
|
|
]
|
|
lib_handle.SetVirtualDiskInformation.restype = wintypes.DWORD
|
|
|
|
lib_handle.AttachVirtualDisk.argtypes = [
|
|
wintypes.HANDLE,
|
|
wintypes.PVOID,
|
|
wintypes.INT,
|
|
wintypes.ULONG,
|
|
wintypes.PVOID,
|
|
wintypes.LPOVERLAPPED
|
|
]
|
|
lib_handle.AttachVirtualDisk.restype = wintypes.DWORD
|
|
|
|
lib_handle.DetachVirtualDisk.argtypes = [
|
|
wintypes.HANDLE,
|
|
wintypes.INT,
|
|
wintypes.ULONG
|
|
]
|
|
lib_handle.DetachVirtualDisk.restype = wintypes.DWORD
|
|
|
|
lib_handle.GetVirtualDiskPhysicalPath.argtypes = [
|
|
wintypes.HANDLE,
|
|
wintypes.PULONG,
|
|
wintypes.PWSTR
|
|
]
|
|
lib_handle.GetVirtualDiskPhysicalPath.restype = wintypes.DWORD
|