This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients eryksun, fstorino, paul.moore, steve.dower, tim.golden, zach.ware
Date 2021-11-04.18:36:09
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1636050969.24.0.100293931768.issue45710@roundup.psfhosted.org>
In-reply-to
Content
It's not completely surprising that attempting to traverse a name-surrogate reparse point under "%UserProfile%\AppData" fails when using the store app. If you can't or won't move the mountpoint up to %UserProfile%, or anywhere else outside of the application-data tree, then I suggest using a regular Python installation from python.org.

The error in Windows 11 is ERROR_MOUNT_POINT_NOT_RESOLVED (649), based on the NT status code STATUS_MOUNT_POINT_NOT_RESOLVED. This error status is associated with the kernel routines IoCreateFileSpecifyDeviceObjectHint() [1] and IoCreateFileEx() [2]:

    IoCreateFileEx returns this status value if the DriverContext
    parameter is not NULL and if the file or directory name contains
    a mount point that resolves to a volume other than the one to
    which the specified device object is attached. This device 
    object is specified by the DeviceObjectHint member of the 
    IO_DRIVER_CREATE_CONTEXT structure.

A filter driver can use this feature to open a path on a particular volume or filesystem device (i.e. the device hint) and bypass other filter drivers that are attached to the device stack. However, if path parsing traverses a reparse point to another filesystem, it has to fail with STATUS_MOUNT_POINT_NOT_RESOLVED. Note that a reparse point that targets a path in the same filesystem works fine. For example:

    >>> path = os.path.join(os.environ['appdata'], 'spam')
    >>> os.lstat(path).st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT
    True
    >>> os.path.realpath(path)
    'C:\\Temp\\spam'
    >>> os.path.exists(os.path.join(path, 'eggs.py'))
    True
    >>> subprocess.call(['python', os.path.join(path, 'eggs.py')])
    works fine
    0

The case of a cross-device mountpoint or symlink under "%UserProfile%\AppData" also fails when using the store app in Windows 10. However, the error in Windows 10 is ERROR_INVALID_FUNCTION (1), from the status code STATUS_NOT_IMPLEMENTED, so the underlying implementation details must be quite different. I was able to work around the limitation somewhat in Windows 10 (but not Windows 11) by first changing to the mountpoint directory and accessing relative paths. This doesn't work when running a script, however, since the interpreter tries to open the fully-qualified path, which has to traverse the mountpoint or symlink.

---
[1 https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-iocreatefilespecifydeviceobjecthint
[2] https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-iocreatefileex.
History
Date User Action Args
2021-11-04 18:36:09eryksunsetrecipients: + eryksun, paul.moore, tim.golden, zach.ware, steve.dower, fstorino
2021-11-04 18:36:09eryksunsetmessageid: <1636050969.24.0.100293931768.issue45710@roundup.psfhosted.org>
2021-11-04 18:36:09eryksunlinkissue45710 messages
2021-11-04 18:36:09eryksuncreate