How to get raw disk or device block size in Windows using Python

How to get the size from a block device or raw disk in Windows, if I only know the name of the device, is it "\. \ PhysicalDrive0" without the file system on it or the volume label?

I tried the following:

fd = os.open (r "\. \ PhysicalDrive0", os.O_RDONLY)

os.lseek (fd, 0, os.SEEK_END)

it works fine on Linux, but always returns "OSError: [Errno 22] Invalid Argument" on Windows.

I also tried ctypes.windll.kernel32.GetDiskFreeSpaceExW (), but it seems to work only on a disk with a file system and assigned a volume label.

What is the right way to do this for a raw disk or block device?

Thanks in advance.

+4
source share
2 answers

I have a solution .. but it is not very. Use diskpart. Unfortunately, it does not give you the exact size of the byte if necessary, but it gives the user readable string.

import tempfile import subprocess import re import os def query_diskpart(command): """Run command script for diskpart. Args: command(str): String of all commands to run against diskpart Returns: String of all diskpart standard output Size Effects: Creates a temporary file(and then deletes it) Creates a subprocess to run diskpart """ with tempfile.NamedTemporaryFile(mode='w', delete=False) as temp_handle: temp_handle.write(command) # The temporary file needs to be closed before opening with diskpart diskpart_handle = subprocess.Popen(["diskpart", '/s', temp_handle.name], stdout=subprocess.PIPE) output, _ = diskpart_handle.communicate() os.remove(temp_handle.name) return output def match_drive_size(diskpart_output, disk_num): """Get drive size from diskpart output. Args: diskpart_output(str): String of diskpart standard output disk_num(int): Number of PhysicalDrive to match against Returns: Human readable size of drive. Raises: ValueError if drive doesn't exist. """ # Break up gigantic output string output_lines = diskpart_output.decode().split(os.linesep) # Apply regular expression to every line, but it should only match one matches = [re.match(".*Disk %s\s*(.*)" % disk_num, line) for line in output_lines] size = None for match in matches: if match: # Get first subgroup (parens above) size_line = match.group(1) # Split by whitespace size_list = re.split("\s*", size_line) # Merge numerical value + units # ['256', 'GB'] becomes 256GB size = ''.join(size_list[1:3]) break else: raise ValueError("PHYSICALDRIVE%s does not exist", disk_num) return size def get_drive_size(disk_num): """Get Windows Drive size. Args: disk_num(int): The Physical Drive Number eg for PHYSICALDRIVE0 put 0 Returns: Human readable string of the drive size """ output = query_diskpart("list disk\n") drive_size = match_drive_size(output, disk_num) return drive_size if __name__ == "__main__": print(get_drive_size(0)) 
0
source

Using wmi module

 import wmi c = wmi.WMI() [drive] = c.Win32_DiskDrive(Index=0) print("The disk has %s bytes" % drive.size) print("Or %s GB" % int(int(drive.size) / 1024**3)) 

The disk has 320070320640 bytes
Or 298 GB

This code queries the WMI interface for Win32_DiskDrive objects with an index of 0 (so there is only one result and this result is PHYSICALDRIVE0 ). The drive object has a size attribute, which is a string containing the size of the disk in bytes.

0
source

Source: https://habr.com/ru/post/1488783/


All Articles