# 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