[python-win32] DeviceIOControl using IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS fails with 'Incorrect function.'
Eryk Sun
eryksun at gmail.com
Wed Feb 10 04:32:13 EST 2021
On 2/9/21, Doug Campbell <wdouglascampbell at hotmail.com> wrote:
>
> Again, you expand my knowledge! It seems so obvious now after reading what
> you wrote that I would not be able to get volume disk extents for a physical
> partition but yet this is what I wanted to do because I was attempting to
> find out the partition's offset on the disk.
In the case of a basic disk device, it can have multiple partitions
that each correspond to a volume device, \Device\HarddiskVolume<N>. In
this case, each volume device consists of a single extent on a single
disk.
> The only way I can find to accomplish this is to iterate through each volume
You can get the list of volume GUID names of volume devices that are
registered with the mountpoint manager via FindFirstVolumeW /
FindNextVolumeW. Unfortunately, PyWin32 doesn't wrap the volume-find
functions. They can be called using ctypes. For example:
import ctypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
class HANDLE(ctypes.c_void_p):
def __eq__(self, other):
if hasattr(other, 'value'):
return self.value == other.value
return False
INVALID_HANDLE_VALUE = HANDLE(-1)
ERROR_NO_MORE_FILES = 18
kernel32.FindFirstVolumeW.restype = HANDLE
def list_volumes():
volumes = []
buf = (ctypes.c_wchar * 260)()
hfind = kernel32.FindFirstVolumeW(buf, len(buf))
if hfind == INVALID_HANDLE_VALUE:
raise ctypes.WinError(ctypes.get_last_error())
try:
while True:
# Strip the trailing backslash that FindNextVolumeW appends.
# The trailing backslash is the mountpoint of the filesystem
# that mounts the volume device, but we only want the GUID
# device name.
volumes.append(buf.value.rstrip('\\'))
if not kernel32.FindNextVolumeW(hfind, buf, len(buf)):
error = ctypes.get_last_error()
if error != ERROR_NO_MORE_FILES:
raise ctypes.WinError(error)
break
finally:
kernel32.FindVolumeClose(hfind)
return volumes
I subclassed c_void_p to create the HANDLE type in order to avoid the
otherwise automatic conversion of the return value to a builtin Python
type. This is a simple way around needing to declare argtypes for the
functions that take the find handle (actually a pointer to memory) as
an argument.
More information about the python-win32
mailing list