9

I have a list of valid drive letters, and I want to present a choice to the end user. I'd like to show them the names of the drives. Here's some code that should show me the name of drive F:\:

import ctypes

kernel32 = ctypes.windll.kernel32
buf = ctypes.create_unicode_buffer(1024)

kernel32.GetVolumeNameForVolumeMountPointW(
    ctypes.c_wchar_p("F:\\"),
    buf,
    ctypes.sizeof(buf)
)

print buf.value

However, this outputs \\?\Volume{a8b6b3df-1a63-11e1-9f6f-0007e9ebdfbf}\. How can I get the string that windows shows in explorer (eg, KINGSTON, for a certain flash drive I own)?


EDIT:

Still not working:

volumeNameBuffer = ctypes.create_unicode_buffer(1024)
fileSystemNameBuffer = ctypes.create_unicode_buffer(1024)

kernel32.GetVolumeInformationW(
    ctypes.c_wchar_p("C:\\"),
    volumeNameBuffer,
    ctypes.sizeof(volumeNameBuffer),
    fileSystemNameBuffer,
    ctypes.sizeof(fileSystemNameBuffer)
)

This gives me this error:

WindowsError: exception: access violation reading 0x3A353FA0
Community
  • 1
  • 1
Eric
  • 95,302
  • 53
  • 242
  • 374

7 Answers7

16

Why don't you use win32api.GetVolumeInformation?

import win32api
win32api.GetVolumeInformation("C:\\")

outputs

('WINDOWS', 1992293715, 255, 65470719, 'NTFS')
Felix Heide
  • 163
  • 1
  • 4
8

Using the above fragment, I filled in the missing(optional, null) arguments as a quick helper:

import ctypes
kernel32 = ctypes.windll.kernel32
volumeNameBuffer = ctypes.create_unicode_buffer(1024)
fileSystemNameBuffer = ctypes.create_unicode_buffer(1024)
serial_number = None
max_component_length = None
file_system_flags = None

rc = kernel32.GetVolumeInformationW(
    ctypes.c_wchar_p("F:\\"),
    volumeNameBuffer,
    ctypes.sizeof(volumeNameBuffer),
    serial_number,
    max_component_length,
    file_system_flags,
    fileSystemNameBuffer,
    ctypes.sizeof(fileSystemNameBuffer)
)

print volumeNameBuffer.value
print fileSystemNameBuffer.value

This should be copy-and-paste-able.

7

Try the GetVolumeInformation function instead. It returns the volume label directly.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 1
    There are three other parameters you haven't passed: `lpVolumeSerialNumber`, `lpMaximumComponentLength`, and `lpFileSystemFlags`. The "optional" designation in the documentation doesn't mean that you can simply leave them out, but that you can pass `NULL` as a pointer to that information if you're not interested in the value. – Greg Hewgill Nov 29 '11 at 23:52
  • @GregHewgill: Awesome. Thanks! – Eric Nov 29 '11 at 23:57
2

You can execute windows shell cmd and parse the output.

in Python 3.x:

import subprocess 
def getDriveName(driveletter):
    return subprocess.check_output(["cmd","/c vol "+driveletter]).decode().split("\r\n")[0].split(" ").pop()

print (getDriveName("d:"))

in Python 2.7:

import subprocess 
def getDriveName(driveletter):
    return subprocess.check_output(["cmd","/c vol "+driveletter]).split("\r\n")[0].split(" ").pop()

print getDriveName("d:")
bergee
  • 111
  • 5
2
  • returns driveLetter for the given driveLabel
  • returns "notfound" if driveLabel was not found

def findDriveByDriveLabel(driveLabel):

drvArr = ['c:', 'd:', 'e:', 'f:', 'g:', 'h:', 'i:', 'j:', 'k:', 'l:']
for dl in drvArr:
    try:
        if (os.path.isdir(dl) != 0):
            val = subprocess.check_output(["cmd", "/c vol " + dl])
            if (driveLabel in str(val)):
                return dl + "/"
    except:
        print("Error: findDriveByDriveLabel(): exception")

return "notfound"
Louie
  • 91
  • 4
1
import win32api
import win32file
drives = win32api.GetLogicalDriveStrings()
drives =  drives.split('\000')[:-1]

for drive in drives:
    if win32file.GetDriveType(drive)==win32file.DRIVE_REMOVABLE:
        label,fs,serial,c,d = win32api.GetVolumeInformation(drive)
        print(label)
Keith E. Truesdell
  • 552
  • 11
  • 21
James
  • 11
  • 1
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 25 '23 at 17:14
  • Coule you format the code using back ticks to make it more readable – Keith E. Truesdell Jan 29 '23 at 16:36
0

You can below code to get your drive name if you find useful

import win32api
import win32con
import win32file

def get_removable_drives():
    drives = [i for i in win32api.GetLogicalDriveStrings().split('\x00') if i]
    #print(drives)
    rdrives = [d for d in drives if win32file.GetDriveType(d) == win32con.DRIVE_REMOVABLE]
    return rdrives

drive_list = get_removable_drives()

for i in drive_list:
    print(win32api.GetVolumeInformation(i)[0]+'('+i+')')