<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span title="" style="margin:0px;background-color:rgb(255, 255, 255)">Thanks</span><span style="background-color:rgb(255, 255, 255);display:inline !important"> again, Eryk.</span></div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="background-color:rgb(255, 255, 255);display:inline !important"><br>
</span></div>
<div style="font-family: Calibri, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<span style="background-color:rgb(255, 255, 255);display:inline !important">I was able to play around today with the code you provided below and was able to tweak it to list the volumes, find the one that matched the disk/partition combination I was searching
 for and return its offset on the disk.  Very helpful!</span><br>
</div>
<div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Eryk Sun <eryksun@gmail.com><br>
<b>Sent:</b> Tuesday, February 9, 2021 11:32 PM<br>
<b>To:</b> python-win32@python.org <python-win32@python.org><br>
<b>Cc:</b> Doug Campbell <wdouglascampbell@hotmail.com><br>
<b>Subject:</b> Re: [python-win32] DeviceIOControl using IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS fails with 'Incorrect function.'</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt">
<div class="PlainText">On 2/9/21, Doug Campbell <wdouglascampbell@hotmail.com> wrote:<br>
><br>
> Again, you expand my knowledge!  It seems so obvious now after reading what<br>
> you wrote that I would not be able to get volume disk extents for a physical<br>
> partition but yet this is what I wanted to do because I was attempting to<br>
> find out the partition's offset on the disk.<br>
<br>
In the case of a basic disk device, it can have multiple partitions<br>
that each correspond to a volume device, \Device\HarddiskVolume<N>. In<br>
this case, each volume device consists of a single extent on a single<br>
disk.<br>
<br>
> The only way I can find to accomplish this is to iterate through each volume<br>
<br>
You can get the list of volume GUID names of volume devices that are<br>
registered with the mountpoint manager via FindFirstVolumeW /<br>
FindNextVolumeW. Unfortunately, PyWin32 doesn't wrap the volume-find<br>
functions. They can be called using ctypes. For example:<br>
<br>
import ctypes<br>
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)<br>
<br>
class HANDLE(ctypes.c_void_p):<br>
    def __eq__(self, other):<br>
        if hasattr(other, 'value'):<br>
            return self.value == other.value<br>
        return False<br>
<br>
INVALID_HANDLE_VALUE = HANDLE(-1)<br>
ERROR_NO_MORE_FILES = 18<br>
<br>
kernel32.FindFirstVolumeW.restype = HANDLE<br>
<br>
def list_volumes():<br>
    volumes = []<br>
    buf = (ctypes.c_wchar * 260)()<br>
    hfind = kernel32.FindFirstVolumeW(buf, len(buf))<br>
    if hfind == INVALID_HANDLE_VALUE:<br>
        raise ctypes.WinError(ctypes.get_last_error())<br>
    try:<br>
        while True:<br>
            # Strip the trailing backslash that FindNextVolumeW appends.<br>
            # The trailing backslash is the mountpoint of the filesystem<br>
            # that mounts the volume device, but we only want the GUID<br>
            # device name.<br>
            volumes.append(buf.value.rstrip('\\'))<br>
            if not kernel32.FindNextVolumeW(hfind, buf, len(buf)):<br>
                error = ctypes.get_last_error()<br>
                if error != ERROR_NO_MORE_FILES:<br>
                    raise ctypes.WinError(error)<br>
                break<br>
    finally:<br>
        kernel32.FindVolumeClose(hfind)<br>
    return volumes<br>
<br>
I subclassed c_void_p to create the HANDLE type in order to avoid the<br>
otherwise automatic conversion of the return value to a builtin Python<br>
type. This is a simple way around needing to declare argtypes for the<br>
functions that take the find handle (actually a pointer to memory) as<br>
an argument.<br>
</div>
</span></font></div>
</div>
</body>
</html>