Adds extend volume plugin files
This patch includes the VDS Python wrapper.
This commit is contained in:
parent
100e5b6650
commit
083cae60da
168
cloudbaseinit/plugins/windows/extendvolumes.py
Normal file
168
cloudbaseinit/plugins/windows/extendvolumes.py
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2013 Cloudbase Solutions Srl
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
import re
|
||||||
|
|
||||||
|
from cloudbaseinit.openstack.common import cfg
|
||||||
|
from cloudbaseinit.openstack.common import log as logging
|
||||||
|
from cloudbaseinit.plugins import base
|
||||||
|
from cloudbaseinit.plugins.windows import vds
|
||||||
|
|
||||||
|
ole32 = ctypes.windll.ole32
|
||||||
|
ole32.CoTaskMemFree.restype = None
|
||||||
|
ole32.CoTaskMemFree.argtypes = [ctypes.c_void_p]
|
||||||
|
|
||||||
|
opts = [
|
||||||
|
cfg.ListOpt('volumes_to_extend',
|
||||||
|
default=None,
|
||||||
|
help='List of volumes that need to be extended '
|
||||||
|
'if contiguous space is available on the disk. By default '
|
||||||
|
'all the available volumes can be extended. Volumes must '
|
||||||
|
'be specified using a comma separated list of volume indexes, '
|
||||||
|
'e.g.: "1,2"'),
|
||||||
|
]
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
CONF.register_opts(opts)
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ExtendVolumesPlugin(base.BasePlugin):
|
||||||
|
def _extend_volumes(self, pack, volume_idxs=None):
|
||||||
|
enum = pack.QueryVolumes()
|
||||||
|
while True:
|
||||||
|
(unk, c) = enum.Next(1)
|
||||||
|
if not c:
|
||||||
|
break
|
||||||
|
volume = unk.QueryInterface(vds.IVdsVolume)
|
||||||
|
volume_prop = volume.GetProperties()
|
||||||
|
try:
|
||||||
|
extend_volume = True
|
||||||
|
if volume_idxs is not None:
|
||||||
|
volume_name = ctypes.wstring_at(volume_prop.pwszName)
|
||||||
|
volume_idx = self._get_volume_index(volume_name)
|
||||||
|
if not volume_idx in volume_idxs:
|
||||||
|
extend_volume = False
|
||||||
|
|
||||||
|
if extend_volume:
|
||||||
|
self._extend_volume(pack, volume, volume_prop)
|
||||||
|
finally:
|
||||||
|
ole32.CoTaskMemFree(volume_prop.pwszName)
|
||||||
|
|
||||||
|
def _get_volume_index(self, volume_name):
|
||||||
|
m = re.match(r"[^0-9]+([0-9]+)$", volume_name)
|
||||||
|
if m:
|
||||||
|
return int(m.group(1))
|
||||||
|
|
||||||
|
def _extend_volume(self, pack, volume, volume_prop):
|
||||||
|
volume_extents = self._get_volume_extents_to_resize(pack,
|
||||||
|
volume_prop.id)
|
||||||
|
input_disks = []
|
||||||
|
|
||||||
|
for (volume_extent, volume_extend_size) in volume_extents:
|
||||||
|
input_disk = vds.VDS_INPUT_DISK()
|
||||||
|
input_disks.append(input_disk)
|
||||||
|
|
||||||
|
input_disk.diskId = volume_extent.diskId
|
||||||
|
input_disk.memberIdx = volume_extent.memberIdx
|
||||||
|
input_disk.plexId = volume_extent.plexId
|
||||||
|
input_disk.ullSize = volume_extend_size
|
||||||
|
|
||||||
|
if input_disks:
|
||||||
|
extend_size = sum([i.ullSize for i in input_disks])
|
||||||
|
volume_name = ctypes.wstring_at(volume_prop.pwszName)
|
||||||
|
LOG.info('Extending volume "%s" with %s bytes' %
|
||||||
|
(volume_name, extend_size))
|
||||||
|
|
||||||
|
input_disks_ar = (vds.VDS_INPUT_DISK *
|
||||||
|
len(input_disks))(*input_disks)
|
||||||
|
async = volume.Extend(input_disks_ar, len(input_disks))
|
||||||
|
async.Wait()
|
||||||
|
|
||||||
|
def _get_volume_extents_to_resize(self, pack, volume_id):
|
||||||
|
volume_extents = []
|
||||||
|
|
||||||
|
enum = pack.QueryDisks()
|
||||||
|
while True:
|
||||||
|
(unk, c) = enum.Next(1)
|
||||||
|
if not c:
|
||||||
|
break
|
||||||
|
disk = unk.QueryInterface(vds.IVdsDisk)
|
||||||
|
|
||||||
|
(extents_p, num_extents) = disk.QueryExtents()
|
||||||
|
try:
|
||||||
|
extents_array_type = vds.VDS_DISK_EXTENT * num_extents
|
||||||
|
extents_array = extents_array_type.from_address(
|
||||||
|
ctypes.addressof(extents_p.contents))
|
||||||
|
|
||||||
|
volume_extent_extend_size = None
|
||||||
|
|
||||||
|
for extent in extents_array:
|
||||||
|
if extent.volumeId == volume_id:
|
||||||
|
# Copy the extent in order to return it safely
|
||||||
|
# after the source is deallocated
|
||||||
|
extent_copy = vds.VDS_DISK_EXTENT()
|
||||||
|
ctypes.pointer(extent_copy)[0] = extent
|
||||||
|
|
||||||
|
volume_extent_extend_size = [extent_copy, 0]
|
||||||
|
volume_extents.append(volume_extent_extend_size)
|
||||||
|
elif (volume_extent_extend_size and
|
||||||
|
extent.type == vds.VDS_DET_FREE):
|
||||||
|
volume_extent_extend_size[1] += extent.ullSize
|
||||||
|
else:
|
||||||
|
volume_extent_extend_size = None
|
||||||
|
finally:
|
||||||
|
ole32.CoTaskMemFree(extents_p)
|
||||||
|
|
||||||
|
# Return only the extents that need to be resized
|
||||||
|
return [ve for ve in volume_extents if ve[1] > 0]
|
||||||
|
|
||||||
|
def _query_providers(self, svc):
|
||||||
|
providers = []
|
||||||
|
enum = svc.QueryProviders(vds.VDS_QUERY_SOFTWARE_PROVIDERS)
|
||||||
|
while True:
|
||||||
|
(unk, c) = enum.Next(1)
|
||||||
|
if not c:
|
||||||
|
break
|
||||||
|
providers.append(unk.QueryInterface(vds.IVdsSwProvider))
|
||||||
|
return providers
|
||||||
|
|
||||||
|
def _query_packs(self, provider):
|
||||||
|
packs = []
|
||||||
|
enum = provider.QueryPacks()
|
||||||
|
while True:
|
||||||
|
(unk, c) = enum.Next(1)
|
||||||
|
if not c:
|
||||||
|
break
|
||||||
|
packs.append(unk.QueryInterface(vds.IVdsPack))
|
||||||
|
return packs
|
||||||
|
|
||||||
|
def _get_volumes_to_extend(self):
|
||||||
|
if CONF.volumes_to_extend is not None:
|
||||||
|
return map(int, CONF.volumes_to_extend)
|
||||||
|
|
||||||
|
def execute(self, service):
|
||||||
|
svc = vds.load_vds_service()
|
||||||
|
providers = self._query_providers(svc)
|
||||||
|
|
||||||
|
volumes_to_extend = self._get_volumes_to_extend()
|
||||||
|
|
||||||
|
for provider in providers:
|
||||||
|
packs = self._query_packs(provider)
|
||||||
|
for pack in packs:
|
||||||
|
self._extend_volumes(pack, volumes_to_extend)
|
325
cloudbaseinit/plugins/windows/vds.py
Normal file
325
cloudbaseinit/plugins/windows/vds.py
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
|
# Copyright (c) 2013 Cloudbase Solutions Srl
|
||||||
|
#
|
||||||
|
# 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 comtypes
|
||||||
|
import ctypes
|
||||||
|
|
||||||
|
from comtypes import client
|
||||||
|
from ctypes import wintypes
|
||||||
|
|
||||||
|
VDS_QUERY_SOFTWARE_PROVIDERS = 1
|
||||||
|
VDS_DET_FREE = 1
|
||||||
|
|
||||||
|
CLSID_VdsLoader = '{9C38ED61-D565-4728-AEEE-C80952F0ECDE}'
|
||||||
|
|
||||||
|
msvcrt = ctypes.cdll.msvcrt
|
||||||
|
msvcrt.memcmp.restype = ctypes.c_int
|
||||||
|
msvcrt.memcmp.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint]
|
||||||
|
|
||||||
|
|
||||||
|
class GUID(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("data1", ctypes.wintypes.DWORD),
|
||||||
|
("data2", ctypes.wintypes.WORD),
|
||||||
|
("data3", ctypes.wintypes.WORD),
|
||||||
|
("data4", ctypes.c_byte * 8)]
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if type(other) != GUID:
|
||||||
|
return False
|
||||||
|
return not msvcrt.memcmp(ctypes.addressof(self),
|
||||||
|
ctypes.addressof(other),
|
||||||
|
ctypes.sizeof(GUID))
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return not self.__eq__(other)
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_DISK_PROP_SWITCH_TYPE(ctypes.Union):
|
||||||
|
_fields_ = [
|
||||||
|
("dwSignature", wintypes.DWORD),
|
||||||
|
("DiskGuid", GUID),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_DISK_PROP(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("id", GUID),
|
||||||
|
("status", ctypes.c_int),
|
||||||
|
("ReserveMode", ctypes.c_int),
|
||||||
|
("health", ctypes.c_int),
|
||||||
|
("dwDeviceType", wintypes.DWORD),
|
||||||
|
("dwMediaType", wintypes.DWORD),
|
||||||
|
("ullSize", wintypes.ULARGE_INTEGER),
|
||||||
|
("ulBytesPerSector", wintypes.ULONG),
|
||||||
|
("ulSectorsPerTrack", wintypes.ULONG),
|
||||||
|
("ulTracksPerCylinder", wintypes.ULONG),
|
||||||
|
("ulFlags", wintypes.ULONG),
|
||||||
|
("BusType", ctypes.c_int),
|
||||||
|
("PartitionStyle", ctypes.c_int),
|
||||||
|
("switch_type", VDS_DISK_PROP_SWITCH_TYPE),
|
||||||
|
("pwszDiskAddress", wintypes.c_void_p),
|
||||||
|
("pwszName", wintypes.c_void_p),
|
||||||
|
("pwszFriendlyName", wintypes.c_void_p),
|
||||||
|
("pwszAdaptorName", wintypes.c_void_p),
|
||||||
|
("pwszDevicePath", wintypes.c_void_p),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_DISK_EXTENT(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("diskId", GUID),
|
||||||
|
("type", ctypes.c_int),
|
||||||
|
("ullOffset", wintypes.ULARGE_INTEGER),
|
||||||
|
("ullSize", wintypes.ULARGE_INTEGER),
|
||||||
|
("volumeId", GUID),
|
||||||
|
("plexId", GUID),
|
||||||
|
("memberIdx", wintypes.ULONG),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_VOLUME_PROP(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("id", GUID),
|
||||||
|
("type", ctypes.c_int),
|
||||||
|
("status", ctypes.c_int),
|
||||||
|
("health", ctypes.c_int),
|
||||||
|
("TransitionState", ctypes.c_int),
|
||||||
|
("ullSize", wintypes.ULARGE_INTEGER),
|
||||||
|
("ulFlags", wintypes.ULONG),
|
||||||
|
("RecommendedFileSystemType", ctypes.c_int),
|
||||||
|
("pwszName", wintypes.c_void_p),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_INPUT_DISK(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("diskId", GUID),
|
||||||
|
("ullSize", wintypes.ULARGE_INTEGER),
|
||||||
|
("plexId", GUID),
|
||||||
|
("memberIdx", wintypes.ULONG),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_cp(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("ullOffset", wintypes.ULARGE_INTEGER),
|
||||||
|
("volumeId", GUID),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_cv(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("pVolumeUnk", wintypes.ULARGE_INTEGER),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_bvp(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("pVolumeUnk", ctypes.POINTER(comtypes.IUnknown)),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_sv(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("ullReclaimedBytes", wintypes.ULARGE_INTEGER),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_cl(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("pLunUnk", ctypes.POINTER(comtypes.IUnknown)),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_ct(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("pTargetUnk", ctypes.POINTER(comtypes.IUnknown)),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_cpg(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("pPortalGroupUnk", ctypes.POINTER(comtypes.IUnknown)),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT_SWITCH_TYPE(ctypes.Union):
|
||||||
|
_fields_ = [
|
||||||
|
("cp", VDS_ASYNC_OUTPUT_cp),
|
||||||
|
("cv", VDS_ASYNC_OUTPUT_cv),
|
||||||
|
("bvp", VDS_ASYNC_OUTPUT_bvp),
|
||||||
|
("sv", VDS_ASYNC_OUTPUT_sv),
|
||||||
|
("cl", VDS_ASYNC_OUTPUT_cl),
|
||||||
|
("ct", VDS_ASYNC_OUTPUT_ct),
|
||||||
|
("cpg", VDS_ASYNC_OUTPUT_cpg),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class VDS_ASYNC_OUTPUT(ctypes.Structure):
|
||||||
|
_fields_ = [
|
||||||
|
("type", ctypes.c_int),
|
||||||
|
("switch_type", VDS_ASYNC_OUTPUT_SWITCH_TYPE),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IEnumVdsObject(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{118610b7-8d94-4030-b5b8-500889788e4e}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'Next',
|
||||||
|
(['in'], wintypes.ULONG, 'celt'),
|
||||||
|
(['out'], ctypes.POINTER(ctypes.POINTER(
|
||||||
|
comtypes.IUnknown)),
|
||||||
|
'ppObjectArray'),
|
||||||
|
(['out'], ctypes.POINTER(wintypes.ULONG),
|
||||||
|
'pcFetched')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IVdsService(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{0818a8ef-9ba9-40d8-a6f9-e22833cc771e}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'IsServiceReady'),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'WaitForServiceReady'),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetProperties',
|
||||||
|
(['out'], ctypes.c_void_p, 'pServiceProp')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryProviders',
|
||||||
|
(['in'], wintypes.DWORD, 'masks'),
|
||||||
|
(['out'],
|
||||||
|
ctypes.POINTER(ctypes.POINTER(IEnumVdsObject)),
|
||||||
|
'ppEnum'))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IVdsServiceLoader(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{e0393303-90d4-4a97-ab71-e9b671ee2729}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'LoadService',
|
||||||
|
(['in'], wintypes.LPCWSTR, 'pwszMachineName'),
|
||||||
|
(['out'],
|
||||||
|
ctypes.POINTER(ctypes.POINTER(IVdsService)),
|
||||||
|
'ppService'))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IVdsSwProvider(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{9aa58360-ce33-4f92-b658-ed24b14425b8}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryPacks',
|
||||||
|
(['out'],
|
||||||
|
ctypes.POINTER(ctypes.POINTER(IEnumVdsObject)),
|
||||||
|
'ppEnum'))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IVdsPack(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{3b69d7f5-9d94-4648-91ca-79939ba263bf}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetProperties',
|
||||||
|
(['out'], ctypes.c_void_p, 'pPackProp')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetProvider',
|
||||||
|
(['out'],
|
||||||
|
ctypes.POINTER(ctypes.POINTER(comtypes.IUnknown)),
|
||||||
|
'ppProvider')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryVolumes',
|
||||||
|
(['out'],
|
||||||
|
ctypes.POINTER(ctypes.POINTER(IEnumVdsObject)),
|
||||||
|
'ppEnum')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryDisks',
|
||||||
|
(['out'],
|
||||||
|
ctypes.POINTER(ctypes.POINTER(IEnumVdsObject)),
|
||||||
|
'ppEnum'))
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IVdsDisk(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{07e5c822-f00c-47a1-8fce-b244da56fd06}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetProperties',
|
||||||
|
(['out'], ctypes.POINTER(VDS_DISK_PROP),
|
||||||
|
'pDiskProperties')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetPack',
|
||||||
|
(['out'], ctypes.POINTER(ctypes.POINTER(IVdsPack)),
|
||||||
|
'ppPack')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetIdentificationData',
|
||||||
|
(['out'], ctypes.c_void_p, 'pLunInfo')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryExtents',
|
||||||
|
(['out'], ctypes.POINTER(ctypes.POINTER(
|
||||||
|
VDS_DISK_EXTENT)),
|
||||||
|
'ppExtentArray'),
|
||||||
|
(['out'], ctypes.POINTER(wintypes.LONG),
|
||||||
|
'plNumberOfExtents')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IVdsAsync(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{d5d23b6d-5a55-4492-9889-397a3c2d2dbc}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'Cancel'),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'Wait',
|
||||||
|
(['out'], ctypes.POINTER(
|
||||||
|
wintypes.HRESULT), 'pHrResult'),
|
||||||
|
(['out'], ctypes.POINTER(VDS_ASYNC_OUTPUT),
|
||||||
|
'pAsyncOut')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryStatus',
|
||||||
|
(['out'], ctypes.POINTER(
|
||||||
|
wintypes.HRESULT), 'pHrResult'),
|
||||||
|
(['out'], ctypes.POINTER(wintypes.ULONG),
|
||||||
|
'pulPercentCompleted')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IVdsVolume(comtypes.IUnknown):
|
||||||
|
_iid_ = comtypes.GUID("{88306bb2-e71f-478c-86a2-79da200a0f11}")
|
||||||
|
|
||||||
|
_methods_ = [
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetProperties',
|
||||||
|
(['out'], ctypes.POINTER(VDS_VOLUME_PROP),
|
||||||
|
'pVolumeProperties')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'GetPack',
|
||||||
|
(['out'], ctypes.POINTER(ctypes.POINTER(IVdsPack)),
|
||||||
|
'ppPack')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'QueryPlexes',
|
||||||
|
(['out'],
|
||||||
|
ctypes.POINTER(ctypes.POINTER(IEnumVdsObject)),
|
||||||
|
'ppEnum')),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'Extend',
|
||||||
|
(['in'], ctypes.POINTER(
|
||||||
|
VDS_INPUT_DISK), 'pInputDiskArray'),
|
||||||
|
(['in'], wintypes.LONG, 'lNumberOfDisks'),
|
||||||
|
(['out'], ctypes.POINTER(
|
||||||
|
ctypes.POINTER(IVdsAsync)), 'ppAsync'),
|
||||||
|
),
|
||||||
|
comtypes.COMMETHOD([], comtypes.HRESULT, 'Shrink',
|
||||||
|
(['in'], wintypes.ULARGE_INTEGER,
|
||||||
|
'ullNumberOfBytesToRemove'),
|
||||||
|
(['out'], ctypes.POINTER(ctypes.POINTER(IVdsAsync)),
|
||||||
|
'ppAsync')),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def load_vds_service():
|
||||||
|
loader = client.CreateObject(CLSID_VdsLoader, interface=IVdsServiceLoader)
|
||||||
|
svc = loader.LoadService(None)
|
||||||
|
svc.WaitForServiceReady()
|
||||||
|
return svc
|
Loading…
x
Reference in New Issue
Block a user