How to check if a Raw(unmounted) Windows Drive exists in Python

1.5k views Asked by At

How would I check if a raw(Windows) drive exists in python? i.e. "\\.\PhysicalDriveN" where N in the disk number

Right now I can check if a raw drive exists(as admin) by opening and immediately closing it. If there is an exception, then the raw device may not exist, otherwise it does. I know that's not very pythonic. Is there a better way?

os.access(drive_name, os.F_OK) always returns False. Same with with os.path.exists(drive_name). I'd prefer just to use the python standard library. os.stat(drive_name) cannot find the device either.

Example of my working code:

drive_name = r"\\.\PhysicalDrive1"
try:
    open(drive_name).close()
except FileNotFoundError:
    print("The device does not exist")
else:
    print("The device exists")
2

There are 2 answers

0
Bryce Guinta On BEST ANSWER

As eryksun pointed out in the comments, ctypes.windll.kernel32.QueryDosDeviceW can be used to test for whether the device symbolic link exists(PhysicalDrive1 is a symbolic link to the actual device location). The ctypes module allows one to access this API function, through a Dynamically-linked library.

QueryDosDeviceW requires the drive name as a string, a character array, and the character array's length. The character array stores the raw device that the drive name maps to. The function returns the amount of characters stored in the character array, which would be zero if the drive doesn't exist.

import ctypes
drive_name = "PhysicalDrive1"
target = (ctypes.c_wchar * 32768)(); # Creates an instance of a character array
target_len = ctypes.windll.kernel32.QueryDosDeviceW(drive_name, target, len(target))
if not target_len:
     print("The device does not exist")
else:
     print("The device exists")

The target character array object might have the value "\Device\Harddisk2\DR10" stored in it

Note In python 3 strings are unicode by default, which is why QueryDosDeviceW(above) works. For Python 2, ctypes.windll.kernel32.QueryDosDeviceA would work in place of QueryDocDeviceW for byte strings.

0
alercelik On

Without importing ctypes etc.

os.path.exists("C:")

works correctly. Driver argument should have a trailing ":" character.

>>> os.path.exists("C:")
True
>>> os.path.exists("D:")
True
>>> os.path.exists("A:")
False
>>> os.path.exists("X:")
True  # i have mounted a local directory here
>>> os.path.exists("C")
False  # without trailing ":"