2

This short function is simply getting the available free space of a storage device, however I am getting the above error when running the code.

The function is:

def disk_space1(drive):
    freespace = ctypes.c_ulonglong()
    calcspace = ctypes.windll.kernel32.GetDiskFreeSpaceExA
    calcspace(drive, ctypes.byref(freespace))
    disk_size = freespace.value
    return disk_size

This function worked perfectly until today when it has stopped working for no reason, I haven't changed anything. What's baffling me the most is that the function works properly, if I print out the value of 'freespace' once running it, it has gone and found the correct value, but still gives the error.

What could have caused this issue?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
mattymanza365
  • 45
  • 1
  • 1
  • 5
  • Consider using pywin32 - it is thin wrapper around Win32 API. I.e.: http://docs.activestate.com/activepython/2.7/pywin32/win32file__GetDiskFreeSpaceEx_meth.html – myaut Feb 20 '15 at 14:22

1 Answers1

5

You are not calling the full function signature which I believe is leading to access violations (due to random memory writes) and errors. The full function signature is (fully documented here):

BOOL WINAPI GetDiskFreeSpaceEx(
  _In_opt_   LPCTSTR lpDirectoryName,
  _Out_opt_  PULARGE_INTEGER lpFreeBytesAvailable,
  _Out_opt_  PULARGE_INTEGER lpTotalNumberOfBytes,
  _Out_opt_  PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

By changing the function to:

def disk_space(drive):
    freespace = ctypes.c_ulonglong()
    calcspace = ctypes.windll.kernel32.GetDiskFreeSpaceExA
    err = calcspace(drive,
                    ctypes.byref(freespace),
                    None,
                    None)
    assert err != 0, 'calcspace failed'
    disk_size = freespace.value
    return disk_size

I was able to run it without intermittent error.

cziemba
  • 664
  • 5
  • 10
  • 2
    Well, just pass the `NULL` (i.e. `None`) values to ensure that the stack has allocated zeros for the last two 'optional' parameters: `calcspace(drive, ctypes.byref(freespace), None, None)`. Then the stack won't get corrupted by the cleanup code in `GetDiskFreeSpaceExA` (i.e. x86 stdcall callee cleanup). – Eryk Sun Feb 20 '15 at 14:49
  • Gonna try this now, I originally took those out since I wasn't using those values for anything, had no problems up until now! – mattymanza365 Feb 20 '15 at 14:56
  • And it was a success! Thanks for the help guys! – mattymanza365 Feb 20 '15 at 14:57