-
-
Notifications
You must be signed in to change notification settings - Fork 31.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add os.listdrives
on Windows
#102519
Comments
Ping @eryksun in case you have any thoughts :) |
This would really be a The mountpoint manager was added to the Windows kernel over 20 years ago, but there are still some legacy drivers that don't support it. Instead, they manually create their own drive-letter names. The ImDisk RAM disk driver does this, IIRC, which makes I presume if a volume has no DOS path name, then it won't be included in the list, unless
A volume can only be assigned one drive-letter name, a policy that's enforced by If you don't mind diverging from the latter, then use the first path that exists. The problem is that it's possible to mount a volume on a directory that a standard user is allowed to delete. Regarding drives in general Logical drives "[A-Z]:" are an abstraction implemented by symbolic links in the object namespace. A logical drive can target an object path that traverses only directory objects and symbolic link objects up to a named device object, with possibly a remaining path that's traversed by the I/O manager (via Every thread has an associated logon session based on its effective token (either the process token or an impersonation token). Every logon session has an associated device mapping, which currently has the following structure:
A logon session's device mapping contains references to
It also contains
The bitmap of defined logical drives can be queried via
For example: >>> logical_drives = win32api.GetLogicalDriveStrings().split('\0')
>>> 'W:\\' in logical_drives
False
>>> win32file.DefineDosDevice(0, 'W:', 'C:\\Windows')
>>> logical_drives = win32api.GetLogicalDriveStrings().split('\0')
>>> 'W:\\' in logical_drives
True Note that a defined drive doesn't necessarily resolve to an existing path. The following example creates an "X:" drive that resolves to a path that doesn't exist. >>> 'Z:\\' in logical_drives
False
>>> win32file.DefineDosDevice(0, 'X:', 'Z:\\')
>>> logical_drives = win32api.GetLogicalDriveStrings().split('\0')
>>> 'X:\\' in logical_drives
True Footnotes
|
I agree, but I think user expectations win out. What if
Surely the use depends on the user's intent? I'm keen to include the mount point so that code like this can find the longest matching segment (in particular, because this enables user-friendly path handling that
You could write something similar with stat() and return the last parent with the same st_dev as the full path, I guess. (I know you didn't suggest this, but I'm quite happy to leave defining aliases to other libraries. We only really need querying, since without this it's impossible to enumerate all files on the system.) |
That seems reasonable.
If |
I thought you would, and on some level I'd prefer it too 😄 But I definitely don't want changing return types from a Boolean argument, and the Maybe it should just be a three part API? |
I first considered returning a list of tuples I suppose listing all of the mountpoints without grouping is similar to what you'd get on Linux, listing mountpoints via glibc |
A
|
POSIX doesn't specify a way to list mountpoints. As mentioned, glibc on Linux provides an abstraction for iterating the contents of the mount table, "/proc/self/mounts" (or use the old name, "/etc/mtab", which is a symlink now). Open a I haven't tested, but BSD and macOS apparently support similar functionality via In common on Windows, Linux, and macOS/BSD, we could return the device name, mount path, and filesystem type. Extra platform data could also be returned, such as the mount options on Linux; flags on macOS/BSD; and filesystem flags on Windows. |
Hi there, the bigmem buildbot is failing funnily with:
See example failure: |
Lines 2684 to 2691 in d77c487
This test should ignore The test should also ignore an error due to a raw volume that has no filesystem (i.e. |
Yeah, that's real weird. I'll handle errors in the test for now, because I'm not sure what the right errors to suppress in the function would be. Seems like unsupported volumes ought to raise an error, but we definitely want to just skip over those for the test. |
This latest PR fixed the problem, thanks! |
We don't currently have a way to get all the root directories on Windows, since
os.listdir('/')
doesn't contain everything.I propose a very simple API:
Basically,
listdrives(uuids=True)
would return everything found byFindNextVolume
, whilelistdrives()
would applyGetVolumePathNamesForVolumeName
to each GUID and return all of those. (This may return the same volume multiple times under different names, which is fine -os.stat
can be used to see if they're the samest_dev
.)There's an endless amount of variations we could also apply here, but the most important functionality in my mind is to expose the OS API. App developers at least then have a starting point to do whatever they may need.
Linked PRs
The text was updated successfully, but these errors were encountered: