Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6137275
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T17:42:16+00:00 2026-05-23T17:42:16+00:00

In Python 3.2 I am creating a Structure object from the data returned by

  • 0

In Python 3.2 I am creating a Structure object from the data returned by the ctypes.windll.kernel32.DeviceIoControl function. After this is done I can access the Structure fields and return the data. However, if i do something the uses a memory, such as opening a file the data inside the structure is modified. In the first part of the output that I have pasted in the results are what is to be expected. However, after a file is opened and the structures fields printed again values have been changed. I am not sure why the data is being modified or how to stop it from happening.

Structures:

class DISK_GEOMETRY(ctypes.Structure):
    '''
    Disk Geometry Data Structure
    http://msdn.microsoft.com/en-us/library/aa363972(v=vs.85).aspx
    '''
    _fields_ = [("Cylinders", wintypes.LARGE_INTEGER),
                ("MediaType", wintypes.BYTE), #MEDIA_TYPE
                ("TracksPerCylinder", wintypes.DWORD),
                ("SectorsPerTrack", wintypes.DWORD),
                ("BytesPerSector", wintypes.DWORD)]


class DISK_GEOMETRY_EX(ctypes.Structure):
    '''
    Disk Geometry EX Data Structure
    http://msdn.microsoft.com/en-us/library/aa363970(v=vs.85).aspx
    '''
    _fields_ = [("Geometry", DISK_GEOMETRY),
                ("DiskSize", wintypes.LARGE_INTEGER),
                ("Data[1]", wintypes.BYTE)]

DeviceIoControl:

class DeviceIoControl:
    def __init__(self, path):
        self.path = path

    def __DeviceIoControl(self, devicehandle, IoControlCode, input, output):
        '''
        DeviceIoControl Function
        http://msdn.microsoft.com/en-us/library/aa363216(v=vs.85).aspx
        '''
        DevIoCtl = ctypes.windll.kernel32.DeviceIoControl
        DevIoCtl.argtypes = [
            wintypes.HANDLE, #HANDLE hDevice
            wintypes.DWORD, #DWORD dwIoControlCode
            wintypes.LPVOID, #LPVOID lpInBuffer
            wintypes.DWORD, #DWORD nInBufferSize
            wintypes.LPVOID, #LPVOID lpOutBuffer
            wintypes.DWORD, #DWORD nOutBufferSize
            ctypes.POINTER(wintypes.DWORD), #LPDWORD lpBytesReturned
            wintypes.LPVOID] #LPOVERLAPPED lpOverlapped
        DevIoCtl.restype = wintypes.BOOL

        if isinstance(output, int):
            output = ctypes.create_string_buffer(output)

        input_size = len(input) if input is not None else 0
        output_size = len(output)
        assert isinstance(output, ctypes.Array)

        BytesReturned = wintypes.DWORD()

        status = DevIoCtl(devicehandle, IoControlCode, input, input_size, output, output_size, BytesReturned, None)
        return output[:BytesReturned.value] if status is not 0 else -1

    def GetDriveGeometry(self):
        diskhandle = winapi.CreateHandle(
                self.path,
                winapi.NULL,
                winapi.FILE_SHARE_READ|winapi.FILE_SHARE_WRITE,
                winapi.LPSECURITY_ATTRIBUTES(),
                winapi.OPEN_EXISTING,
                winapi.FILE_ATTRIBUTE_NORMAL,
                winapi.NULL)
        if diskhandle == winapi.INVALID_HANDLE_VALUE:
            return -1

        temp = ctypes.cast(self.__DeviceIoControl(diskhandle, winioctl.IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, None, 1024), ctypes.POINTER(winioctl.DISK_GEOMETRY_EX)).contents
        winapi.CloseHandle(diskhandle)
        return temp

Main:

device = DeviceIoControl(r"\\.\PhysicalDrive0")
devicegeo = device.GetDriveGeometry()
print("Disk Size: " +str(devicegeo.DiskSize))
print("BytesPerSector: "+str(devicegeo.Geometry.BytesPerSector))
print("Cylinders: "+str(devicegeo.Geometry.Cylinders))
print("MediaType: "+str(hex(devicegeo.Geometry.MediaType)))
print("CtypesAddressOf: "+str(ctypes.addressof(devicegeo)))

with open(r"\\.\PhysicalDrive0", 'rb') as f:
    f.seek(0)
    MBRdata = f.read(512)
print("\nOpened a file\n")        

print("Disk Size: "+str(devicegeo.DiskSize))
print("BytesPerSector: "+str(devicegeo.Geometry.BytesPerSector))
print("Cylinders: "+str(devicegeo.Geometry.Cylinders))
print("MediaType: "+str(hex(devicegeo.Geometry.MediaType)))
print("CtypesAddressOf: "+str(ctypes.addressof(devicegeo)))

Output:

Disk Size: 80000000000
BytesPerSector: 512
Cylinders: 9726
MediaType: 0xc
CtypesAddressOf: 12322040

Opened a file

Disk Size: 0
BytesPerSector: 1
Cylinders: 2170477562872987649
MediaType: -0x40
CtypesAddressOf: 12322040
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T17:42:21+00:00Added an answer on May 23, 2026 at 5:42 pm

    Some observations:

    1. DevIoCtl should be called with byref(BytesReturned).
    2. ctypes.cast‘s first argument must be an “object that can be interpreted as a pointer”.
      What you are casting, however, is a raw bytes object (from output[:BytesReturned.value]).
    3. At this point, what you returned from __DeviceIoControl is a new Python bytes object. The original reference to ctypes array object has gone out of scope. So, it’s entirely possible that it has been garbage collected and/or reused.

    FWIW, I played around with Windows IOCTL dispatch using ctypes just for the heck of it. Also using \\.\PysicalDrive0 and IOCTL_DISK_GET_DRIVE_GEOMETRY.

    I made this gist.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

When creating a simple object hierarchy in Python, I'd like to be able to
In some Python (v3) code I am creating lists of Decimals from user input,
I'm programming a complex tree structure in Python and I'm tired of creating tree
Python is creating a folder in my directory every time I call this method.
In Python, is there any difference between creating a generator object through a generator
Is there a well maintained package available in Python for creating and validating HTML
I am creating a Python script within which I am executing UNIX system commands.
I have got a python script which is creating an ODBC connection. The ODBC
i am creating ( researching possibility of ) a highly customizable python client and
I'm creating a networked server for a boggle-clone I wrote in python, which accepts

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.