finally:
os.chdir(orig_dir)
+ @unittest.skipUnless(os.path.lexists(r'C:\Users\All Users')
+ and os.path.exists(r'C:\ProgramData'),
+ 'Test directories not found')
+ def test_29248(self):
+ # os.symlink() calls CreateSymbolicLink, which creates
+ # the reparse data buffer with the print name stored
+ # first, so the offset is always 0. CreateSymbolicLink
+ # stores the "PrintName" DOS path (e.g. "C:\") first,
+ # with an offset of 0, followed by the "SubstituteName"
+ # NT path (e.g. "\??\C:\"). The "All Users" link, on
+ # the other hand, seems to have been created manually
+ # with an inverted order.
+ target = os.readlink(r'C:\Users\All Users')
+ self.assertTrue(os.path.samefile(target, r'C:\ProgramData'))
+
@unittest.skipUnless(sys.platform == "win32", "Win32 specific tests")
class Win32JunctionTests(unittest.TestCase):
--- /dev/null
+Fix :func:`os.readlink` on Windows, which was mistakenly treating the\r
+``PrintNameOffset`` field of the reparse data buffer as a number of\r
+characters instead of bytes. Patch by Craig Holmquist and SSE4.\r
"not a symbolic link");
return NULL;
}
- print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
- rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
+ print_name = (wchar_t *)((char*)rdb->SymbolicLinkReparseBuffer.PathBuffer +
+ rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
result = PyUnicode_FromWideChar(print_name,
- rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
+ rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(wchar_t));
return result;
}